commit 836e3215499ee59142a7e640523cf6c00df09848 Author: EmanuelFeru Date: Fri Feb 7 14:57:44 2020 +0100 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f5f549b --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +.pio/ +.pioenvs/ +.vscode/ +MDK-ARM/Listing/ +MDK-ARM/Objects/ +MDK-ARM/*.uvgui +!build/VARIANT_DEBUG/firmware.hex +!build/VARIANT_DEBUG/firmware.bin +!build/VARIANT_DEBUG/firmware.elf +!build/VARIANT_DEBUG/firmware.axf +!build/VARIANT_HOVERBOARD/firmware.hex +!build/VARIANT_HOVERBOARD/firmware.bin +!build/VARIANT_HOVERBOARD/firmware.elf +!build/VARIANT_HOVERBOARD/firmware.axf \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..88295c7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,47 @@ +notifications: + email: true + +os: linux + +jobs: + fast_finish: true + include: + + - name: make (gcc-arm-none-eabi-7) + script: make + env: VARIANT=VARIANT_DEBUG + language: c + addons: + apt: + packages: + - libc6-i386 + install: + - pushd . + - cd ~ + - mkdir arm-gcc-toolchain + - wget -O $HOME/arm-gcc-toolchain/gcc.tar.bz2 https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2?revision=bc2c96c0-14b5-4bb4-9f18-bceb4050fee7?product=GNU%20Arm%20Embedded%20Toolchain,64-bit,,Linux,7-2018-q2-update + - cd arm-gcc-toolchain + - tar -jxf gcc.tar.bz2 --strip=1 + - popd + - export PATH=$HOME/arm-gcc-toolchain/bin:$PATH + before_script: arm-none-eabi-gcc --version + + - name: make (gcc-arm-none-eabi-5) + script: make + env: VARIANT=VARIANT_DEBUG + language: c + addons: + apt: + packages: + - libc6-i386 + install: + - pushd . + - cd ~ + - mkdir arm-gcc-toolchain + - wget -O $HOME/arm-gcc-toolchain/gcc.tar.bz2 https://developer.arm.com/-/media/Files/downloads/gnu-rm/5_4-2016q3/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2?revision=111dee36-f88b-4672-8ac6-48cf41b4d375?product=GNU%20Arm%20Embedded%20Toolchain,32-bit,,Linux,5-2016-q3-update + - cd arm-gcc-toolchain + - tar -jxf gcc.tar.bz2 --strip=1 + - popd + - export PATH=$HOME/arm-gcc-toolchain/bin:$PATH + before_script: arm-none-eabi-gcc --version + diff --git a/Drivers/CMSIS/Include/gd32f1x0.h b/Drivers/CMSIS/Include/gd32f1x0.h new file mode 100644 index 0000000..a2ca5f4 --- /dev/null +++ b/Drivers/CMSIS/Include/gd32f1x0.h @@ -0,0 +1,236 @@ +/*! + \file gd32f1x0.h + \brief general definitions for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_H +#define GD32F1X0_H + +#ifdef cplusplus + extern "C" { +#endif + +/* define GD32F1x0 */ +#if !defined (GD32F1x0) + #define GD32F1x0 +#endif /* define GD32F1x0 */ +#if !defined (GD32F1x0) + #error "Please select the target GD32F1x0 device used in your application (in gd32f1x0.h file)" +#endif /* undefine GD32F1x0 tip */ + +/* define GD32F1x0 device category */ +#if (!defined (GD32F170_190))&&(!defined (GD32F130_150)) + #error "Please select GD32F1x0 device category( GD32F130_150 or GD32F170_190 )" +#endif /* undefine GD32F170_190 or GD32F130_150 tip */ +#if (defined (GD32F170_190))&&(defined (GD32F130_150)) + #error "Please select one GD32F1x0 device category( GD32F130_150 or GD32F170_190 )" +#endif /* define GD32F170_190 and GD32F130_150 tip */ + +/* define value of high speed crystal oscillator (HXTAL) in Hz */ +#if !defined (HXTAL_VALUE) +#define HXTAL_VALUE ((uint32_t)8000000) +#endif /* high speed crystal oscillator value */ + +/* define startup timeout value of high speed crystal oscillator (HXTAL) */ +#if !defined (HXTAL_STARTUP_TIMEOUT) +#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0x0800) +#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 RC oscillator for ADC in Hz */ +#ifdef GD32F170_190 +#if !defined (IRC28M_VALUE) +#define IRC28M_VALUE ((uint32_t)28000000) +#endif /* IRC28M for GD32F170_190 */ +#else +#if !defined (IRC14M_VALUE) +#define IRC14M_VALUE ((uint32_t)14000000) +#endif /* IRC14M for GD32F130_150 */ +#endif /* GD32F170_190 */ + +/* 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 */ + +/* GD32F1x0 firmware library version number V3.0 */ +#define __GD32F1x0_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:24] main version */ +#define __GD32F1x0_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __GD32F1x0_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __GD32F1x0_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __GD32F1x0_STDPERIPH_VERSION ((__GD32F1x0_STDPERIPH_VERSION_MAIN << 24)\ + |(__GD32F1x0_STDPERIPH_VERSION_SUB1 << 16)\ + |(__GD32F1x0_STDPERIPH_VERSION_SUB2 << 8)\ + |(__GD32F1x0_STDPERIPH_VERSION_RC)) + +/* configuration of the Cortex-M3 processor and core peripherals */ +#define __MPU_PRESENT 1 /*!< GD32F1x0 do not provide MPU */ +#define __NVIC_PRIO_BITS 4 /*!< GD32F1x0 uses 4 bits for the priority levels */ +#define __Vendor_SysTickConfig 0 /*!< set to 1 if different sysTick config is used */ + +/* define interrupt number */ +typedef enum IRQn +{ + /* Cortex-M3 processor exceptions numbers */ + NonMaskableInt_IRQn = -14, /*!< 2 non maskable interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 memory management interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 bus fault interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 usage fault interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV call interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 debug monitor interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 pend SV interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 system tick interrupt */ + /* interruput numbers */ + WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */ + LVD_IRQn = 1, /*!< LVD through EXTI line detect interrupt */ + RTC_IRQn = 2, /*!< RTC through EXTI line interrupt */ + FMC_IRQn = 3, /*!< FMC interrupt */ + RCU_IRQn = 4, /*!< RCU interrupt */ + EXTI0_1_IRQn = 5, /*!< EXTI line 0 and 1 interrupts */ + EXTI2_3_IRQn = 6, /*!< EXTI line 2 and 3 interrupts */ + EXTI4_15_IRQn = 7, /*!< EXTI line 4 to 15 interrupts */ + TSI_IRQn = 8, /*!< TSI Interrupt */ + DMA_Channel0_IRQn = 9, /*!< DMA channel 0 interrupt */ + DMA_Channel1_2_IRQn = 10, /*!< DMA channel 1 and channel 2 interrupts */ + DMA_Channel3_4_IRQn = 11, /*!< DMA channel 3 and channel 4 interrupts */ + ADC_CMP_IRQn = 12, /*!< ADC, CMP0 and CMP1 interrupts */ + TIMER0_BRK_UP_TRG_COM_IRQn = 13, /*!< TIMER0 break, update, trigger and commutation interrupts */ + TIMER0_Channel_IRQn = 14, /*!< TIMER0 channel interrupt */ + TIMER1_IRQn = 15, /*!< TIMER1 interrupt */ + TIMER2_IRQn = 16, /*!< TIMER2 interrupt */ + TIMER5_DAC_IRQn = 17, /*!< TIMER5 and DAC interrupts */ + TIMER13_IRQn = 19, /*!< TIMER13 interrupt */ + TIMER14_IRQn = 20, /*!< TIMER14 interrupt */ + TIMER15_IRQn = 21, /*!< TIMER15 interrupt */ + TIMER16_IRQn = 22, /*!< TIMER16 interrupt */ + I2C0_EV_IRQn = 23, /*!< I2C0 event interrupt */ + I2C1_EV_IRQn = 24, /*!< I2C1 event interrupt */ + SPI0_IRQn = 25, /*!< SPI0 interrupt */ + SPI1_IRQn = 26, /*!< SPI1 interrupt */ + USART0_IRQn = 27, /*!< USART0 interrupt */ + USART1_IRQn = 28, /*!< USART1 interrupt */ + CEC_IRQn = 30, /*!< CEC interrupt */ + I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */ + I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */ + I2C2_EV_IRQn = 35, /*!< I2C2 event interrupt */ + I2C2_ER_IRQn = 36, /*!< I2C2 error interrupt */ + USBD_LP_IRQn = 37, /*!< USBD_LP interrupt */ + USBD_HP_IRQn = 38, /*!< USBD_HP interrupt */ + USBDWakeUp_IRQChannel = 42, /*!< USBD_WKUP interrupt */ + CAN0_TX_IRQn = 43, /*!< CAN0 TX interrupt */ + CAN0_RX0_IRQn = 44, /*!< CAN0 RX0 interrupt */ + CAN0_RX1_IRQn = 45, /*!< CAN0 RX1 interrupt */ + CAN0_SCE_IRQn = 46, /*!< CAN0 SCE interrupt */ + SLCD_IRQn = 47, /*!< SLCD interrupt */ + DMA_Channel5_6_IRQn = 48, /*!< DMA1 channel 5 and channel 6 interrupts */ + SPI2_IRQn = 51, /*!< SPI2 global interrupt */ + CAN1_TX_IRQn = 70, /*!< CAN1 TX interrupt */ + CAN1_RX0_IRQn = 71, /*!< CAN1 RX0 interrupt */ + CAN1_RX1_IRQn = 72, /*!< CAN1 RX1 interrupt */ + CAN1_SCE_IRQn = 73, /*!< CAN1 SCE interrupt */ +} IRQn_Type; + +/* includes */ +#include "core_cm3.h" +#include "system_gd32f1x0.h" +#include + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {FALSE = 0, TRUE = !FALSE} bool; +typedef enum {RESET = 0, SET = !RESET} FlagStatus; +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus; + +/* bit operations */ +#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr)) +#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr)) +#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr)) +#define BIT(x) ((uint32_t)((uint32_t)0x01U<<(x))) +#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) +#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start)) + +/* main flash and SRAM memory map */ +#define FLASH_BASE ((uint32_t)0x08000000U) /*!< main FLASH base address */ +#define SRAM_BASE ((uint32_t)0x20000000U) /*!< SRAM base address */ +/* SRAM and peripheral base bit-band region */ +#define SRAM_BB_BASE ((uint32_t)0x22000000U) /*!< SRAM bit-band base address */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000U) /*!< peripheral bit-band base address */ +/* peripheral memory map */ +#define APB1_BUS_BASE ((uint32_t)0x40000000U) /*!< apb1 base address */ +#define APB2_BUS_BASE ((uint32_t)0x40010000U) /*!< apb2 base address */ +#define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */ +#define AHB2_BUS_BASE ((uint32_t)0x48000000U) /*!< ahb2 base address */ +/* advanced peripheral bus 1 memory map */ +#define TIMER_BASE (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address */ +#define SLCD_BASE (APB1_BUS_BASE + 0x00002400U) /*!< SLCD 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 USART_BASE (APB1_BUS_BASE + 0x00004400U) /*!< USART base address */ +#define SPI_BASE (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address */ +#define I2C_BASE (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address */ +#define USBD_BASE (APB1_BUS_BASE + 0x00005C00U) /*!< USBD base address */ +#define USBD_RAM_BASE (APB1_BUS_BASE + 0x00006000U) /*!< USBD RAM base address */ +#define CAN_BASE (APB1_BUS_BASE + 0x00006400U) /*!< CAN base address */ +#define PMU_BASE (APB1_BUS_BASE + 0x00007000U) /*!< PMU base address */ +#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */ +#define CEC_BASE (APB1_BUS_BASE + 0x00007800U) /*!< CEC base address */ +#define OPA_BASE (APB1_BUS_BASE + 0x00007C5CU) /*!< OPA base address */ +#define IVREF_BASE (APB1_BUS_BASE + 0x00007C00U) /*!< IVREF base address */ +/* advanced peripheral bus 2 memory map */ +#define SYSCFG_BASE (APB2_BUS_BASE + 0x00000000U) /*!< SYSCFG base address */ +#define CMP_BASE (APB2_BUS_BASE + 0x0000001CU) /*!< CMP base address */ +#define EXTI_BASE (APB2_BUS_BASE + 0x00000400U) /*!< EXTI base address */ +#define ADC_BASE (APB2_BUS_BASE + 0x00002400U) /*!< ADC base address */ +/* advanced high performance bus 1 memory map */ +#define DMA_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< DMA base address */ +#define DMA_CHANNEL_BASE (DMA_BASE + 0x00000008U) /*!< DMA channel base address */ +#define 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 TSI_BASE (AHB1_BUS_BASE + 0x00004000U) /*!< TSI 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)0xE0042000U) /*!< DBG base address */ + +/* define marco USE_STDPERIPH_DRIVER */ +#if !defined USE_STDPERIPH_DRIVER +#define USE_STDPERIPH_DRIVER +#endif +#ifdef USE_STDPERIPH_DRIVER +#include "gd32f1x0_libopt.h" +#endif /* USE_STDPERIPH_DRIVER */ + +#ifdef cplusplus +} +#endif +#endif + + + + diff --git a/Drivers/CMSIS/Include/system_gd32f1x0.h b/Drivers/CMSIS/Include/system_gd32f1x0.h new file mode 100644 index 0000000..7de2a68 --- /dev/null +++ b/Drivers/CMSIS/Include/system_gd32f1x0.h @@ -0,0 +1,58 @@ +/*! + \file system_gd32f1x0.h + \brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File for + GD32F1x0 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_GD32F1X0_H +#define SYSTEM_GD32F1X0_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_GD32F1X0_H */ diff --git a/Drivers/CMSIS/Source/system_gd32f1x0.c b/Drivers/CMSIS/Source/system_gd32f1x0.c new file mode 100644 index 0000000..68deef0 --- /dev/null +++ b/Drivers/CMSIS/Source/system_gd32f1x0.c @@ -0,0 +1,333 @@ +/*! + \file system_gd32f1x0.c + \brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File for + GD32F1x0 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 "gd32f1x0.h" + +/* system frequency define */ +#define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */ +#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ +#define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */ + +/* select a system clock by uncommenting the following line */ +//#define __SYSTEM_CLOCK_8M_HXTAL (__HXTAL) +//#define __SYSTEM_CLOCK_8M_IRC8M (__IRC8M) +//#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) +#define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2 (uint32_t)(72000000) + +#define SEL_IRC8M 0x00 +#define SEL_HXTAL 0x01 +#define SEL_PLL 0x02 + +/* set the system clock frequency and declare the system clock configuration function */ +#ifdef __SYSTEM_CLOCK_8M_HXTAL +uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_HXTAL; +static void system_clock_8m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL; +static void system_clock_72m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2; +static void system_clock_72m_irc8m(void); +#else +uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_IRC8M; +static void system_clock_8m_irc8m(void); +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ + +/* configure the system clock */ +static void system_clock_config(void); + +/*! + \brief setup the microcontroller system, initialize the system + \param[in] none + \param[out] none + \retval none +*/ +void SystemInit (void) +{ + /* enable IRC8M */ + RCU_CTL0 |= RCU_CTL0_IRC8MEN; + while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){ + } + /* reset RCU */ +#ifdef GD32F130_150 + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); +#elif defined (GD32F170_190) + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV | RCU_CFG0_PLLDV); +#endif /* GD32F130_150 */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV); +#ifdef GD32F130_150 + RCU_CFG0 &= ~(RCU_CFG0_USBDPSC); +#endif /* GD32F130_150 */ + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS); + RCU_CFG1 &= ~RCU_CFG1_HXTALPREDV; + RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_CECSEL | RCU_CFG2_ADCSEL); +#ifdef GD32F130_150 + RCU_CTL1 &= ~RCU_CTL1_IRC14MEN; +#elif defined (GD32F170_190) + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CTL1 &= ~RCU_CTL1_IRC28MEN; + RCU_CFG3 &= ~RCU_CFG3_CKOUT1SRC; + RCU_CFG3 &= ~RCU_CFG3_CKOUT1DIV; +#endif /* GD32F130_150 */ + RCU_INT = 0x00000000U; + + /* configure system clock */ + system_clock_config(); +} + +/*! + \brief configure the system clock + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_config(void) +{ +#ifdef __SYSTEM_CLOCK_8M_HXTAL + system_clock_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) + system_clock_72m_hxtal(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) + system_clock_72m_irc8m(); +#else + system_clock_8m_irc8m(); +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ +} + +#ifdef __SYSTEM_CLOCK_8M_HXTAL +/*! + \brief configure the system clock to 8M by HXTAL + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_8m_hxtal(void) +{ + uint32_t timeout = 0; + + /* enable HXTAL */ + RCU_CTL0 |= RCU_CTL0_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + while((0 == (RCU_CTL0 & RCU_CTL0_HXTALSTB)) && (HXTAL_STARTUP_TIMEOUT != timeout++)); + + /* if fail */ + if(0 == (RCU_CTL0 & RCU_CTL0_HXTALSTB)) + return; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select HXTAL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_HXTAL; + + /* wait until HXTAL is selected as system clock */ + while(0 == (RCU_CFG0 & RCU_SCSS_HXTAL)); +} + +#elif defined (__SYSTEM_CLOCK_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_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL0 |= RCU_CTL0_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)){ + return; + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* PLL = HXTAL * 9 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL9); + + /* enable PLL */ + RCU_CTL0 |= RCU_CTL0_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL0 & RCU_CTL0_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(0U == (RCU_CFG0 & RCU_SCSS_PLL)){ + } +} + +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) +/*! + \brief configure the system clock to 72M by PLL which selects IRC8M/2 as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_72m_irc8m(void) +{ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + /* PLL = (IRC8M/2) * 18 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF); + RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL18); + + /* enable PLL */ + RCU_CTL0 |= RCU_CTL0_PLLEN; + + /* wait until PLL is stable */ + while(0 == (RCU_CTL0 & RCU_CTL0_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(0 == (RCU_CFG0 & RCU_SCSS_PLL)); +} + +#else +/*! + \brief configure the system clock to 8M by IRC8M + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_8m_irc8m(void) +{ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select IRC8M as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_IRC8M; + + /* wait until IRC8M is selected as system clock */ + while(0 != (RCU_CFG0 & RCU_SCSS_IRC8M)); +} +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ + +/*! + \brief update the SystemCoreClock with current core clock retrieved from cpu registers + \param[in] none + \param[out] none + \retval none +*/ +void SystemCoreClockUpdate (void) +{ + uint32_t sws = 0U; + uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U; + /* exponent of AHB clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC8M is selected as CK_SYS */ + case SEL_IRC8M: + SystemCoreClock = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + SystemCoreClock = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case SEL_PLL: + /* get the value of PLLMF[3:0] */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf4 = GET_BITS(RCU_CFG0, 27, 27); + /* high 16 bits */ + if(1U == pllmf4){ + pllmf += 17U; + }else{ + pllmf += 2U; + } + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = GET_BITS(RCU_CFG0, 16, 16); + if(0U != pllsel){ + prediv = (GET_BITS(RCU_CFG1, 0, 3) + 1U); + SystemCoreClock = (HXTAL_VALUE / prediv) * pllmf; + }else{ + SystemCoreClock = (IRC8M_VALUE >> 1) * 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/Drivers/CMSIS/arm_common_tables.h b/Drivers/CMSIS/arm_common_tables.h new file mode 100644 index 0000000..8742a56 --- /dev/null +++ b/Drivers/CMSIS/arm_common_tables.h @@ -0,0 +1,136 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 19. October 2015 +* $Revision: V.1.4.5 a +* +* Project: CMSIS DSP Library +* Title: arm_common_tables.h +* +* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* 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 LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (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 _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +extern const uint16_t armBitRevTable[1024]; +extern const q15_t armRecipTableQ15[64]; +extern const q31_t armRecipTableQ31[64]; +/* extern const q31_t realCoefAQ31[1024]; */ +/* extern const q31_t realCoefBQ31[1024]; */ +extern const float32_t twiddleCoef_16[32]; +extern const float32_t twiddleCoef_32[64]; +extern const float32_t twiddleCoef_64[128]; +extern const float32_t twiddleCoef_128[256]; +extern const float32_t twiddleCoef_256[512]; +extern const float32_t twiddleCoef_512[1024]; +extern const float32_t twiddleCoef_1024[2048]; +extern const float32_t twiddleCoef_2048[4096]; +extern const float32_t twiddleCoef_4096[8192]; +#define twiddleCoef twiddleCoef_4096 +extern const q31_t twiddleCoef_16_q31[24]; +extern const q31_t twiddleCoef_32_q31[48]; +extern const q31_t twiddleCoef_64_q31[96]; +extern const q31_t twiddleCoef_128_q31[192]; +extern const q31_t twiddleCoef_256_q31[384]; +extern const q31_t twiddleCoef_512_q31[768]; +extern const q31_t twiddleCoef_1024_q31[1536]; +extern const q31_t twiddleCoef_2048_q31[3072]; +extern const q31_t twiddleCoef_4096_q31[6144]; +extern const q15_t twiddleCoef_16_q15[24]; +extern const q15_t twiddleCoef_32_q15[48]; +extern const q15_t twiddleCoef_64_q15[96]; +extern const q15_t twiddleCoef_128_q15[192]; +extern const q15_t twiddleCoef_256_q15[384]; +extern const q15_t twiddleCoef_512_q15[768]; +extern const q15_t twiddleCoef_1024_q15[1536]; +extern const q15_t twiddleCoef_2048_q15[3072]; +extern const q15_t twiddleCoef_4096_q15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; + + +/* floating-point bit reversal tables */ +#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 ) +#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 ) +#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 ) +#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 ) +#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 ) +#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800) +#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808) +#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH]; + +/* fixed-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 ) +#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 ) +#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 ) +#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 ) +#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 ) +#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 ) +#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) +#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + +/* Tables for Fast Math Sine and Cosine */ +extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; +extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; +extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/Drivers/CMSIS/arm_const_structs.h b/Drivers/CMSIS/arm_const_structs.h new file mode 100644 index 0000000..726d06e --- /dev/null +++ b/Drivers/CMSIS/arm_const_structs.h @@ -0,0 +1,79 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 19. March 2015 +* $Revision: V.1.4.5 +* +* Project: CMSIS DSP Library +* Title: arm_const_structs.h +* +* Description: This file has constant structs that are initialized for +* user convenience. For example, some can be given as +* arguments to the arm_cfft_f32() function. +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* 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 LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (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 _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; + + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; + + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; + +#endif diff --git a/Drivers/CMSIS/arm_math.h b/Drivers/CMSIS/arm_math.h new file mode 100644 index 0000000..d33f8a9 --- /dev/null +++ b/Drivers/CMSIS/arm_math.h @@ -0,0 +1,7154 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2015 ARM Limited. All rights reserved. +* +* $Date: 20. October 2015 +* $Revision: V1.4.5 b +* +* Project: CMSIS DSP Library +* Title: arm_math.h +* +* Description: Public header file for CMSIS DSP Library +* +* Target Processor: Cortex-M7/Cortex-M4/Cortex-M3/Cortex-M0 +* +* 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 LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. + * -------------------------------------------------------------------- */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM7lfdp_math.lib (Little endian and Double Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7bfdp_math.lib (Big endian and Double Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7lfsp_math.lib (Little endian and Single Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7bfsp_math.lib (Big endian and Single Precision Floating Point Unit on Cortex-M7) + * - arm_cortexM7l_math.lib (Little endian on Cortex-M7) + * - arm_cortexM7b_math.lib (Big endian on Cortex-M7) + * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) + * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) + * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) + * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) + * - arm_cortexM0l_math.lib (Little endian on Cortex-M0 / CortexM0+) + * - arm_cortexM0b_math.lib (Big endian on Cortex-M0 / CortexM0+) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M7/M4/M3/M0/M0+ with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library has been developed and tested with MDK-ARM version 5.14.0.0 + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Building the Library + * ------------ + * + * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. + * + * Pre-processor Macros + * ------------ + * + * Each library project have differant pre-processor macros. + * + * - UNALIGNED_SUPPORT_DISABLE: + * + * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_CMx: + * + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and + * ARM_MATH_CM7 for building the library on cortex-M7. + * + * - __FPU_PRESENT: + * + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries + * + *
+ * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | + * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | + * + *
+ * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + * + * Copyright Notice + * ------------ + * + * Copyright (C) 2010-2015 ARM Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +/* ignore some GCC warnings */ +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined(ARM_MATH_CM7) + #include "core_cm7.h" +#elif defined (ARM_MATH_CM4) + #include "core_cm4.h" +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_CM0PLUS) + #include "core_cm0plus.h" + #define ARM_MATH_CM0_FAMILY +#else + #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0" +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI +#define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SIZE 256 +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined __CC_ARM + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined __GNUC__ + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined __ICCARM__ + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED + +#elif defined __CSMC__ + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED + +#elif defined __TASKING__ + #define __SIMD32_TYPE __unaligned int32_t + #define CMSIS_UNUSED + +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +#endif + + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + static __INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + static __INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + static __INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + static __INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + static __INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + +/* + #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) + #define __CLZ __clz + #endif + */ +/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */ +#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ) + static __INLINE uint32_t __CLZ( + q31_t data); + + static __INLINE uint32_t __CLZ( + q31_t data) + { + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + + return (count); + } +#endif + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + + static __INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if(in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1u); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + static __INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if(in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + + + /* + * @brief C custom defined intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0_FAMILY) + static __INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if(x > 0) + { + posMax = (posMax - 1); + + if(x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if(x < negMin) + { + x = negMin; + } + } + return (x); + } +#endif /* end of ARM_MATH_CM0_FAMILY */ + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + static __INLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + static __INLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + static __INLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + static __INLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + static __INLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + static __INLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + static __INLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + static __INLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + static __INLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + static __INLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + static __INLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + static __INLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + static __INLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + static __INLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + static __INLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + static __INLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + static __INLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + static __INLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + static __INLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + static __INLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + static __INLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + static __INLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + +#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * numTaps is not a supported value. + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#ifdef ARM_MATH_CM0_FAMILY + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q15; + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q31; + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] S points to an instance of the floating-point FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + static __INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + static __INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31u); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + static __INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#ifndef ARM_MATH_CM0_FAMILY + __SIMD32_TYPE *vstate; + + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + vstate = __SIMD32_CONST(S->state); + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + */ + static __INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + static __INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + */ + static __INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + static __INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * The function implements the forward Park transform. + * + */ + static __INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + static __INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + */ + static __INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + static __INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + static __INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if(i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + static __INLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1u); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + static __INLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + static __INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if(index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + static __INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if(in >= 0.0f) + { + +#if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); +#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined(__GNUC__) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000) + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + static __INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + static __INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + static __INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + static __INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + static __INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + static __INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + static __INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__GNUC__) + #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__ICCARM__) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__CSMC__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__TASKING__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + +#ifdef __cplusplus +} +#endif + + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/Drivers/CMSIS/cmsis_armcc.h b/Drivers/CMSIS/cmsis_armcc.h new file mode 100644 index 0000000..74c49c6 --- /dev/null +++ b/Drivers/CMSIS/cmsis_armcc.h @@ -0,0 +1,734 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS Cortex-M Core Function/Instruction Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1); +} + +#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */ + + +#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return(result); +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */ + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* (__CORTEX_M >= 0x04) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/Drivers/CMSIS/cmsis_armcc_V6.h b/Drivers/CMSIS/cmsis_armcc_V6.h new file mode 100644 index 0000000..cd13240 --- /dev/null +++ b/Drivers/CMSIS/cmsis_armcc_V6.h @@ -0,0 +1,1800 @@ +/**************************************************************************//** + * @file cmsis_armcc_V6.h + * @brief CMSIS Cortex-M Core Function/Instruction Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#ifndef __CMSIS_ARMCC_V6_H +#define __CMSIS_ARMCC_V6_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get IPSR Register (non-secure) + \details Returns the content of the non-secure IPSR Register when in secure state. + \return IPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_IPSR_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get APSR Register (non-secure) + \details Returns the content of the non-secure APSR Register when in secure state. + \return APSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_APSR_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get xPSR Register (non-secure) + \details Returns the content of the non-secure xPSR Register when in secure state. + \return xPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_xPSR_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : "sp"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : "sp"); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : "sp"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : "sp"); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */ + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t value) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (value) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Base Priority with condition (non_secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_MAX_NS(uint32_t value) +{ + __ASM volatile ("MSR basepri_max_ns, %0" : : "r" (value) : "memory"); +} +#endif + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + + +#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */ + + +#if (__ARM_ARCH_8M__ == 1U) + +/** + \brief Get Process Stack Pointer Limit + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Get Process Stack Pointer Limit (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Get Main Stack Pointer Limit (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Set Main Stack Pointer Limit (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +} +#endif + +#endif /* (__ARM_ARCH_8M__ == 1U) */ + + +#if ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=4 */ + +/** + \brief Get FPSCR + \details eturns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#define __get_FPSCR __builtin_arm_get_fpscr +#if 0 +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + uint32_t result; + + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} +#endif + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get FPSCR (non-secure) + \details Returns the current value of the non-secure Floating Point Status/Control register when in secure state. + \return Floating Point Status/Control register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FPSCR_NS(void) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + uint32_t result; + + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMRS %0, fpscr_ns" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} +#endif + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#define __set_FPSCR __builtin_arm_set_fpscr +#if 0 +__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} +#endif + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set FPSCR (non-secure) + \details Assigns the given value to the non-secure Floating Point Status/Control register when in secure state. + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FPSCR_NS(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMSR fpscr_ns, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} +#endif + +#endif /* ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF); + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF); + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF); + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __builtin_bswap32 + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16 __builtin_bswap16 /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */ +#if 0 +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} +#endif + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ + /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ + int32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ + /* ToDo: ARMCC_V6: check if __builtin_arm_rbit is supported */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */ + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return(result); +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz + + +#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */ + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +/*#define __SSAT __builtin_arm_ssat*/ +#define __SSAT(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat +#if 0 +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) +#endif + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */ + + +#if (__ARM_ARCH_8M__ == 1U) + +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* (__ARM_ARCH_8M__ == 1U) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (__ARM_FEATURE_DSP == 1U) /* ToDo: ARMCC_V6: This should be ARCH >= ARMv7-M + SIMD */ + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1U) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_V6_H */ diff --git a/Drivers/CMSIS/cmsis_gcc.h b/Drivers/CMSIS/cmsis_gcc.h new file mode 100644 index 0000000..bb89fbb --- /dev/null +++ b/Drivers/CMSIS/cmsis_gcc.h @@ -0,0 +1,1373 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS Cortex-M Core Function/Instruction Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__CORTEX_M >= 0x03U) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + +#endif /* (__CORTEX_M >= 0x03U) */ + + +#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + uint32_t result; + + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} + +#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +__attribute__((always_inline)) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__((always_inline)) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__((always_inline)) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__attribute__((always_inline)) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__((always_inline)) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__((always_inline)) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + int32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return(result); +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz + + +#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) ); +} + +#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */ + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x04) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +#endif /* __CMSIS_GCC_H */ diff --git a/Drivers/CMSIS/core_cm0.h b/Drivers/CMSIS/core_cm0.h new file mode 100644 index 0000000..711dad5 --- /dev/null +++ b/Drivers/CMSIS/core_cm0.h @@ -0,0 +1,798 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M0 + @{ + */ + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M0 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/core_cm0plus.h b/Drivers/CMSIS/core_cm0plus.h new file mode 100644 index 0000000..b04aa39 --- /dev/null +++ b/Drivers/CMSIS/core_cm0plus.h @@ -0,0 +1,914 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M0+ Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/core_cm3.h b/Drivers/CMSIS/core_cm3.h new file mode 100644 index 0000000..b4ac4c7 --- /dev/null +++ b/Drivers/CMSIS/core_cm3.h @@ -0,0 +1,1763 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M3 + @{ + */ + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x03U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if (__CM3_REV < 0x0201U) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if ((defined __CM3_REV) && (__CM3_REV >= 0x200U)) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1U]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in NVIC and returns the active bit. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/core_cm4.h b/Drivers/CMSIS/core_cm4.h new file mode 100644 index 0000000..dc840eb --- /dev/null +++ b/Drivers/CMSIS/core_cm4.h @@ -0,0 +1,1937 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ +#include "core_cmSimd.h" /* Compiler specific SIMD Intrinsics */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1U) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in NVIC and returns the active bit. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/core_cm7.h b/Drivers/CMSIS/core_cm7.h new file mode 100644 index 0000000..3b7530a --- /dev/null +++ b/Drivers/CMSIS/core_cm7.h @@ -0,0 +1,2512 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x07U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ +#include "core_cmSimd.h" /* Compiler specific SIMD Intrinsics */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1U) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in NVIC and returns the active bit. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & 0x00000FF0UL) == 0x220UL) + { + return 2UL; /* Double + Single precision FPU */ + } + else if ((mvfr0 & 0x00000FF0UL) == 0x020UL) + { + return 1UL; /* Single precision FPU */ + } + else + { + return 0UL; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## Cache functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_INLINE void SCB_EnableICache (void) +{ + #if (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_INLINE void SCB_DisableICache (void) +{ + #if (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_INLINE void SCB_InvalidateICache (void) +{ + #if (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_INLINE void SCB_EnableDCache (void) +{ + #if (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways--); + } while(sets--); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_INLINE void SCB_DisableDCache (void) +{ + #if (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways--); + } while(sets--); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_INLINE void SCB_InvalidateDCache (void) +{ + #if (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways--); + } while(sets--); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_INLINE void SCB_CleanDCache (void) +{ + #if (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways--); + } while(sets--); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_INLINE void SCB_CleanInvalidateDCache (void) +{ + #if (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways--); + } while(sets--); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t)addr; + int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCIMVAC = op_addr; + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if (__DCACHE_PRESENT == 1) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCMVAC = op_addr; + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCIMVAC = op_addr; + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/*@} end of CMSIS_Core_CacheFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/core_cmFunc.h b/Drivers/CMSIS/core_cmFunc.h new file mode 100644 index 0000000..652a48a --- /dev/null +++ b/Drivers/CMSIS/core_cmFunc.h @@ -0,0 +1,87 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ +*/ + +/*------------------ RealView Compiler -----------------*/ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armcc_V6.h" + +/*------------------ GNU Compiler ----------------------*/ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + +/*------------------ ICC Compiler ----------------------*/ +#elif defined ( __ICCARM__ ) + #include + +/*------------------ TI CCS Compiler -------------------*/ +#elif defined ( __TMS470__ ) + #include + +/*------------------ TASKING Compiler ------------------*/ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +/*------------------ COSMIC Compiler -------------------*/ +#elif defined ( __CSMC__ ) + #include + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + +#endif /* __CORE_CMFUNC_H */ diff --git a/Drivers/CMSIS/core_cmInstr.h b/Drivers/CMSIS/core_cmInstr.h new file mode 100644 index 0000000..f474b0e --- /dev/null +++ b/Drivers/CMSIS/core_cmInstr.h @@ -0,0 +1,87 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/*------------------ RealView Compiler -----------------*/ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armcc_V6.h" + +/*------------------ GNU Compiler ----------------------*/ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + +/*------------------ ICC Compiler ----------------------*/ +#elif defined ( __ICCARM__ ) + #include + +/*------------------ TI CCS Compiler -------------------*/ +#elif defined ( __TMS470__ ) + #include + +/*------------------ TASKING Compiler ------------------*/ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +/*------------------ COSMIC Compiler -------------------*/ +#elif defined ( __CSMC__ ) + #include + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/Drivers/CMSIS/core_cmSimd.h b/Drivers/CMSIS/core_cmSimd.h new file mode 100644 index 0000000..66bf5c2 --- /dev/null +++ b/Drivers/CMSIS/core_cmSimd.h @@ -0,0 +1,96 @@ +/**************************************************************************//** + * @file core_cmSimd.h + * @brief CMSIS Cortex-M SIMD Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CMSIMD_H +#define __CORE_CMSIMD_H + +#ifdef __cplusplus + extern "C" { +#endif + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +/*------------------ RealView Compiler -----------------*/ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armcc_V6.h" + +/*------------------ GNU Compiler ----------------------*/ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + +/*------------------ ICC Compiler ----------------------*/ +#elif defined ( __ICCARM__ ) + #include + +/*------------------ TI CCS Compiler -------------------*/ +#elif defined ( __TMS470__ ) + #include + +/*------------------ TASKING Compiler ------------------*/ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +/*------------------ COSMIC Compiler -------------------*/ +#elif defined ( __CSMC__ ) + #include + +#endif + +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CMSIMD_H */ diff --git a/Drivers/CMSIS/core_sc000.h b/Drivers/CMSIS/core_sc000.h new file mode 100644 index 0000000..514dbd8 --- /dev/null +++ b/Drivers/CMSIS/core_sc000.h @@ -0,0 +1,926 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC000_H_GENERIC +#define __CORE_SC000_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC000 + @{ + */ + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_SC (000U) /*!< Cortex secure core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000U + #warning "__SC000_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC000 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the SC000 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of SC000 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/core_sc300.h b/Drivers/CMSIS/core_sc300.h new file mode 100644 index 0000000..8bd18aa --- /dev/null +++ b/Drivers/CMSIS/core_sc300.h @@ -0,0 +1,1745 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC300_H_GENERIC +#define __CORE_SC300_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC3000 + @{ + */ + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_SC (300U) /*!< Cortex secure core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000U + #warning "__SC300_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED1[129U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + uint32_t RESERVED1[1U]; +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in NVIC and returns the active bit. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_adc.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_adc.h new file mode 100644 index 0000000..d0e1c2d --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_adc.h @@ -0,0 +1,339 @@ +/*! + \file gd32f1x0_adc.h + \brief definitions for the ADC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_ADC_H +#define GD32F1X0_ADC_H + +#include "gd32f1x0.h" + +/* ADC definitions */ +#define ADC ADC_BASE + +/* registers definitions */ +#define ADC_STAT REG32(ADC + 0x00U) /*!< ADC status register */ +#define ADC_CTL0 REG32(ADC + 0x04U) /*!< ADC control register 0 */ +#define ADC_CTL1 REG32(ADC + 0x08U) /*!< ADC control register 1 */ +#define ADC_SAMPT0 REG32(ADC + 0x0CU) /*!< ADC sampling time register 0 */ +#define ADC_SAMPT1 REG32(ADC + 0x10U) /*!< ADC sampling time register 1 */ +#define ADC_IOFF0 REG32(ADC + 0x14U) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1 REG32(ADC + 0x18U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2 REG32(ADC + 0x1CU) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3 REG32(ADC + 0x20U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WDHT REG32(ADC + 0x24U) /*!< ADC watchdog high threshold register */ +#define ADC_WDLT REG32(ADC + 0x28U) /*!< ADC watchdog low threshold register */ +#define ADC_RSQ0 REG32(ADC + 0x2CU) /*!< ADC regular sequence register 0 */ +#define ADC_RSQ1 REG32(ADC + 0x30U) /*!< ADC regular sequence register 1 */ +#define ADC_RSQ2 REG32(ADC + 0x34U) /*!< ADC regular sequence register 2 */ +#define ADC_ISQ REG32(ADC + 0x38U) /*!< ADC inserted sequence register */ +#define ADC_IDATA0 REG32(ADC + 0x3CU) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1 REG32(ADC + 0x40U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2 REG32(ADC + 0x44U) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3 REG32(ADC + 0x48U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA REG32(ADC + 0x4CU) /*!< ADC regular data register */ + +#ifdef GD32F170_190 +#define ADC_OVSAMPCTL REG32(ADC + 0x80U) /*!< ADC oversampling control register */ +#endif /* GD32F170_190 */ + +/* bits definitions */ +/* ADC_STAT */ +#define ADC_STAT_WDE BIT(0) /*!< analog watchdog flag */ +#define ADC_STAT_EOC BIT(1) /*!< end of conversion */ +#define ADC_STAT_EOIC BIT(2) /*!< injected channel end of conversion */ +#define ADC_STAT_STIC BIT(3) /*!< injected channel start flag */ +#define ADC_STAT_STRC BIT(4) /*!< regular channel start flag */ + +/* ADC_CTL0 */ +#define ADC_CTL0_WDCHSEL BITS(0,4) /*!< analog watchdog channel select bits */ +#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ +#define ADC_CTL0_WDEIE BIT(6) /*!< analog watchdog interrupt enable */ +#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for injected channels */ +#define ADC_CTL0_SM BIT(8) /*!< scan mode */ +#define ADC_CTL0_WDSC BIT(9) /*!< enable the watchdog on a single channel in scan mode */ +#define ADC_CTL0_ICA BIT(10) /*!< automatic injected group conversion */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on injected channels */ +#define ADC_CTL0_DISNUM BITS(13,15) /*!< discontinuous mode channel count */ +#define ADC_CTL0_IWDEN BIT(22) /*!< inserted channel analog watchdog enable */ +#define ADC_CTL0_RWDEN BIT(23) /*!< regular channel analog watchdog enable */ + +#ifdef GD32F170_190 +#define ADC_CTL0_DRES BITS(24,25) /*!< ADC resolution */ +#endif /* GD32F170_190 */ + +/* ADC_CTL1 */ +#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter ON */ +#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */ +#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ +#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ +#define ADC_CTL1_DMA BIT(8) /*!< direct memory access mode */ +#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ +#define ADC_CTL1_ETSIC BITS(12,14) /*!< external event select for injected group */ +#define ADC_CTL1_ETEIC BIT(15) /*!< external trigger conversion mode for injected channels */ +#define ADC_CTL1_ETSRC BITS(17,19) /*!< external event select for regular group */ +#define ADC_CTL1_ETERC BIT(20) /*!< external trigger conversion mode for regular channels */ +#define ADC_CTL1_SWICST BIT(21) /*!< start conversion of injected channels */ +#define ADC_CTL1_SWRCST BIT(22) /*!< start conversion of regular channels */ +#define ADC_CTL1_TSVREN BIT(23) /*!< temperature sensor and VREFINT enable */ +#define ADC_CTL1_VBETEN BIT(24) /*!< VBAT enable */ + +/* ADC_SAMPTx x=0..1 */ +#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel x sample time selection */ + +/* ADC_IOFFx x=0..3 */ +#define ADC_IOFFX_IOFF BITS(0,11) /*!< data offset for injected channel x */ + +/* ADC_WHT */ +#define ADC_WDHT_WDHT BITS(0,11) /*!< analog watchdog high threshold */ + +/* ADC_WLT */ +#define ADC_WDLT_WDLT BITS(0,11) /*!< analog watchdog low threshold */ + +/* ADC_RSQx */ +#define ADC_RSQX_RSQN BITS(0,4) /*!< x conversion in regular sequence */ +#define ADC_RSQ0_RL BITS(20,23) /*!< regular channel sequence length */ + +/* ADC_ISQ */ +#define ADC_ISQ_ISQN BITS(0,4) /*!< x conversion in regular sequence */ +#define ADC_ISQ_IL BITS(20,21) /*!< injected sequence length */ + +/* ADC_IDTx x=0..3*/ +#define ADC_IDATAX_IDATAN BITS(0,15) /*!< injected data x */ + +/* ADC_RDT */ +#define ADC_RDATA_RDATA BITS(0,15) /*!< regular data */ + +#ifdef GD32F170_190 +/* ADC_OVCTL */ +#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 */ +#endif /* GD32F170_190 */ + +/* constants definitions */ +/* ADC channel group definitions */ +#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< adc regular channel group */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< adc injected channel group */ +#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and injected channel group */ + +/* ADC inserted channel definitions */ +#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< adc injected channel 0 */ +#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< adc injected channel 1 */ +#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< adc injected channel 2 */ +#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< adc injected channel 3 */ + +/* 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 channel definitions */ +#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC Channel 0 */ +#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC Channel 1 */ +#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC Channel 2 */ +#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC Channel 3 */ +#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC Channel 4 */ +#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC Channel 5 */ +#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC Channel 6 */ +#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC Channel 7 */ +#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC Channel 8 */ +#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC Channel 9 */ +#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC Channel 10 */ +#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC Channel 11 */ +#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC Channel 12 */ +#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC Channel 13 */ +#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC Channel 14 */ +#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC Channel 15 */ +#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC Channel 16 */ +#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC Channel 17 */ +#define ADC_CHANNEL_18 ((uint8_t)0x12U) /*!< ADC Channel 18 */ + +/* ADC channel sample time */ +#define SAMPTX_SPT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define ADC_SAMPLETIME_1POINT5 SAMPTX_SPT(0) /*!< 1.5 sampling cycles */ +#define ADC_SAMPLETIME_7POINT5 SAMPTX_SPT(1) /*!< 7.5 sampling cycles */ +#define ADC_SAMPLETIME_13POINT5 SAMPTX_SPT(2) /*!< 13.5 sampling cycles */ +#define ADC_SAMPLETIME_28POINT5 SAMPTX_SPT(3) /*!< 28.5 sampling cycles */ +#define ADC_SAMPLETIME_41POINT5 SAMPTX_SPT(4) /*!< 41.5 sampling cycles */ +#define ADC_SAMPLETIME_55POINT5 SAMPTX_SPT(5) /*!< 55.5 sampling cycles */ +#define ADC_SAMPLETIME_71POINT5 SAMPTX_SPT(6) /*!< 71.5 sampling cycles */ +#define ADC_SAMPLETIME_239POINT5 SAMPTX_SPT(7) /*!< 239.5 sampling cycles */ + +/* ADC data alignment */ +#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00U) /*!< LSB alignment */ +#define ADC_DATAALIGN_LEFT ((uint32_t)0x01U) /*!< MSB alignment */ + +/* ADC status flag */ +#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of conversion */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< injected channel end of conversion */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< injected channel start flag */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< regular channel start flag */ + +/* ADC interrupt flag */ +#define ADC_INT_WDE ADC_STAT_WDE /*!< analog watchdog 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 */ + +/* ADC interrupt flag */ +#define ADC_INT_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog 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 */ + +/* ADC resolution definitions */ +#define CTL0_DRES(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) +#define ADC_RESOLUTION_12B CTL0_DRES(0) /*!< 12-bit ADC resolution */ +#define ADC_RESOLUTION_10B CTL0_DRES(1) /*!< 10-bit ADC resolution */ +#define ADC_RESOLUTION_8B CTL0_DRES(2) /*!< 8-bit ADC resolution */ +#define ADC_RESOLUTION_6B CTL0_DRES(3) /*!< 6-bit ADC resolution */ + +/* ADC external trigger select for regular channel */ +#define CTL1_ETSRC(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) +#define ADC_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< external trigger timer 0 CH0 event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< external trigger timer 0 CH1 event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< external trigger timer 0 CH2 event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_T1_CH1 CTL1_ETSRC(3) /*!< external trigger timer 1 CH1 event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(4) /*!< external trigger timer 2 TRGO event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_T14_CH0 CTL1_ETSRC(5) /*!< external trigger timer 14 CH0 event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_EXT_IT11 CTL1_ETSRC(6) /*!< external trigger extiline 11 select for regular channel */ +#define ADC_EXTTRIG_REGULAR_SWRCST CTL1_ETSRC(7) /*!< software trigger select for regular channel */ + +/* ADC external trigger select for inserted channel */ +#define CTL1_ETSIC(regval) (BITS(12,14) & ((uint32_t)(regval) << 12)) +#define ADC_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(0) /*!< external trigger timer0 TRGO event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(1) /*!< external trigger timer0 CH3 event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_T1_TRGO CTL1_ETSIC(2) /*!< external trigger timer1 TRGO event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(3) /*!< external trigger timer1 CH0 event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(4) /*!< external trigger timer2 CH3 event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_T14_TRGO CTL1_ETSIC(5) /*!< external trigger timer14 TRGO event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_EXT_IT15 CTL1_ETSIC(6) /*!< external interrupt line 15 select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_SWRCST CTL1_ETSIC(7) /*!< software trigger select for inserted channel */ + +/* adc_ioffx register value */ +#define IOFFX_IOFF(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +#ifdef GD32F170_190 +/* ADC oversampling mode */ +#define ADC_OVERSAMPLING_ALL_CONVERT 0 /*!< all oversampled conversions for a channel are done consecutively after a trigger */ +#define ADC_OVERSAMPLING_ONE_CONVERT 1 /*!< each oversampled conversion for a channel needs a trigger */ + +/* ADC oversampling shift */ +#define OVSAMPCTL_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) +#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 */ + +/* ADC oversampling ratio */ +#define OVSAMPCTL_OVSR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) +#define ADC_OVERSAMPLING_RATIO_MUL2 OVSAMPCTL_OVSR(0) /*!< oversampling ratio X2 */ +#define ADC_OVERSAMPLING_RATIO_MUL4 OVSAMPCTL_OVSR(1) /*!< oversampling ratio X4 */ +#define ADC_OVERSAMPLING_RATIO_MUL8 OVSAMPCTL_OVSR(2) /*!< oversampling ratio X8 */ +#define ADC_OVERSAMPLING_RATIO_MUL16 OVSAMPCTL_OVSR(3) /*!< oversampling ratio X16 */ +#define ADC_OVERSAMPLING_RATIO_MUL32 OVSAMPCTL_OVSR(4) /*!< oversampling ratio X32 */ +#define ADC_OVERSAMPLING_RATIO_MUL64 OVSAMPCTL_OVSR(5) /*!< oversampling ratio X64 */ +#define ADC_OVERSAMPLING_RATIO_MUL128 OVSAMPCTL_OVSR(6) /*!< oversampling ratio X128 */ +#define ADC_OVERSAMPLING_RATIO_MUL256 OVSAMPCTL_OVSR(7) /*!< oversampling ratio X256 */ +#endif /* GD32F170_190 */ + +/* function declarations */ +/* ADC reset */ +void adc_deinit(void); +/* enable ADC interface */ +void adc_enable(void); +/* disable ADC interface */ +void adc_disable(void); +/* ADC calibration and reset calibration */ +void adc_calibration_enable(void); +/* enable DMA request */ +void adc_dma_mode_enable(void); +/* disable DMA request */ +void adc_dma_mode_disable(void); +/* enable the temperature sensor and Vrefint channel */ +void adc_tempsensor_vrefint_enable(void); +/* disable the temperature sensor and Vrefint channel */ +void adc_tempsensor_vrefint_disable(void); +/* enable the vbat channel */ +void adc_vbat_enable(void); +/* disable the vbat channel */ +void adc_vbat_disable(void); + +/* ADC discontinuous mode */ +void adc_discontinuous_mode_config(uint8_t channel_group,uint8_t length); +/* ADC special function config */ +void adc_special_function_config(uint32_t function, ControlStatus newvalue); +/* ADC data alignment config */ +void adc_data_alignment_config(uint32_t data_alignment); +/* ADC channel length config */ + +void adc_channel_length_config(uint8_t channel_group,uint32_t length); +/* ADC regular channel config */ +void adc_regular_channel_config(uint8_t rank,uint8_t channel,uint32_t sample_time); +/* ADC inserted channel config */ +void adc_inserted_channel_config(uint8_t rank,uint8_t channel,uint32_t sample_time); +/* ADC inserted channel offset config */ +void adc_inserted_channel_offset_config(uint8_t inserted_channel,uint16_t offset); + +/* ADC external trigger enable */ +void adc_external_trigger_config(uint8_t channel_group,ControlStatus newvalue); +/* ADC external trigger source config */ +void adc_external_trigger_source_config(uint8_t channel_group,uint32_t external_trigger_source); +/* ADC software trigger enable */ +void adc_software_trigger_enable(uint8_t channel_group); + +/* ADC regular group data register read */ +uint16_t adc_regular_data_read(void); +/* ADC inserted group data register read */ +uint16_t adc_inserted_data_read(uint8_t inserted_channel); + +/* get the ADC status flag */ +FlagStatus adc_flag_get(uint32_t flag); +/* clear the ADC status flag */ +void adc_flag_clear(uint32_t flag); +/* get the ADC interrupt flag */ +FlagStatus adc_interrupt_flag_get(uint32_t flag); +/* clear the ADC interrupt or status flag */ +void adc_interrupt_flag_clear(uint32_t flag); +/* ADC interrupt enable */ +void adc_interrupt_enable(uint32_t interrupt); +/* ADC interrupt disable */ +void adc_interrupt_disable(uint32_t interrupt); + +/* ADC analog watchdog single channel config */ +void adc_watchdog_single_channel_enable(uint8_t channel); +/* ADC analog watchdog group channel config */ +void adc_watchdog_group_channel_enable(uint8_t channel_group); +/* ADC analog watchdog disable */ +void adc_watchdog_disable(void); +/* ADC analog watchdog threshold config */ +void adc_watchdog_threshold_config(uint16_t low_threshold,uint16_t high_threshold); + +#ifdef GD32F170_190 +/* ADC resolution config */ +void adc_resolution_config(uint32_t resolution); +/* ADC oversample mode config */ +void adc_oversample_mode_config(uint8_t mode,uint16_t shift,uint8_t ratio); +/* enable ADC oversample mode */ +void adc_oversample_mode_enable(void); +/* disable ADC oversample mode */ +void adc_oversample_mode_disable(void); +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_ADC_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_can.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_can.h new file mode 100644 index 0000000..aab19bc --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_can.h @@ -0,0 +1,706 @@ +/*! + \file gd32f1x0_can.h + \brief definitions for the CAN +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 +#ifndef GD32F1X0_CAN_H +#define GD32F1X0_CAN_H + +#include "gd32f1x0.h" + +/* CAN definitions */ +#define CAN0 CAN_BASE /*!< CAN0 base address */ +#define CAN1 (CAN0 + 0x00000400U) /*!< CAN1 base address */ + +/* registers definitions */ +#define CAN_CTL(canx) REG32((canx) + 0x00U) /*!< CAN control register */ +#define CAN_STAT(canx) REG32((canx) + 0x04U) /*!< CAN status register */ +#define CAN_TSTAT(canx) REG32((canx) + 0x08U) /*!< CAN transmit status register*/ +#define CAN_RFIFO0(canx) REG32((canx) + 0x0CU) /*!< CAN receive FIFO0 register */ +#define CAN_RFIFO1(canx) REG32((canx) + 0x10U) /*!< CAN receive FIFO1 register */ +#define CAN_INTEN(canx) REG32((canx) + 0x14U) /*!< CAN interrupt enable register */ +#define CAN_ERR(canx) REG32((canx) + 0x18U) /*!< CAN error register */ +#define CAN_BT(canx) REG32((canx) + 0x1CU) /*!< CAN bit timing register */ +#define CAN_TMI0(canx) REG32((canx) + 0x180U) /*!< CAN transmit mailbox0 identifier register */ +#define CAN_TMP0(canx) REG32((canx) + 0x184U) /*!< CAN transmit mailbox0 property register */ +#define CAN_TMDATA00(canx) REG32((canx) + 0x188U) /*!< CAN transmit mailbox0 data0 register */ +#define CAN_TMDATA10(canx) REG32((canx) + 0x18CU) /*!< CAN transmit mailbox0 data1 register */ +#define CAN_TMI1(canx) REG32((canx) + 0x190U) /*!< CAN transmit mailbox1 identifier register */ +#define CAN_TMP1(canx) REG32((canx) + 0x194U) /*!< CAN transmit mailbox1 property register */ +#define CAN_TMDATA01(canx) REG32((canx) + 0x198U) /*!< CAN transmit mailbox1 data0 register */ +#define CAN_TMDATA11(canx) REG32((canx) + 0x19CU) /*!< CAN transmit mailbox1 data1 register */ +#define CAN_TMI2(canx) REG32((canx) + 0x1A0U) /*!< CAN transmit mailbox2 identifier register */ +#define CAN_TMP2(canx) REG32((canx) + 0x1A4U) /*!< CAN transmit mailbox2 property register */ +#define CAN_TMDATA02(canx) REG32((canx) + 0x1A8U) /*!< CAN transmit mailbox2 data0 register */ +#define CAN_TMDATA12(canx) REG32((canx) + 0x1ACU) /*!< CAN transmit mailbox2 data1 register */ +#define CAN_RFIFOMI0(canx) REG32((canx) + 0x1B0U) /*!< CAN receive FIFO0 mailbox identifier register */ +#define CAN_RFIFOMP0(canx) REG32((canx) + 0x1B4U) /*!< CAN receive FIFO0 mailbox property register */ +#define CAN_RFIFOMDATA00(canx) REG32((canx) + 0x1B8U) /*!< CAN receive FIFO0 mailbox data0 register */ +#define CAN_RFIFOMDATA10(canx) REG32((canx) + 0x1CCU) /*!< CAN receive FIFO0 mailbox data1 register */ +#define CAN_RFIFOMI1(canx) REG32((canx) + 0x1C0U) /*!< CAN receive FIFO1 mailbox identifier register */ +#define CAN_RFIFOMP1(canx) REG32((canx) + 0x1C4U) /*!< CAN receive FIFO1 mailbox property register */ +#define CAN_RFIFOMDATA01(canx) REG32((canx) + 0x1C8U) /*!< CAN receive FIFO1 mailbox data0 register */ +#define CAN_RFIFOMDATA11(canx) REG32((canx) + 0x1CCU) /*!< CAN receive FIFO1 mailbox data1 register */ +#define CAN_FCTL(canx) REG32((canx) + 0x200U) /*!< CAN filter control register */ +#define CAN_FMCFG(canx) REG32((canx) + 0x204U) /*!< CAN filter mode register */ +#define CAN_FSCFG(canx) REG32((canx) + 0x20CU) /*!< CAN filter scale register */ +#define CAN_FAFIFO(canx) REG32((canx) + 0x214U) /*!< CAN filter associated FIFO register */ +#define CAN_FW(canx) REG32((canx) + 0x21CU) /*!< CAN filter working register */ +#define CAN_F0DATA0(canx) REG32((canx) + 0x240U) /*!< CAN filter 0 data 0 register */ +#define CAN_F1DATA0(canx) REG32((canx) + 0x248U) /*!< CAN filter 1 data 0 register */ +#define CAN_F2DATA0(canx) REG32((canx) + 0x250U) /*!< CAN filter 2 data 0 register */ +#define CAN_F3DATA0(canx) REG32((canx) + 0x258U) /*!< CAN filter 3 data 0 register */ +#define CAN_F4DATA0(canx) REG32((canx) + 0x260U) /*!< CAN filter 4 data 0 register */ +#define CAN_F5DATA0(canx) REG32((canx) + 0x268U) /*!< CAN filter 5 data 0 register */ +#define CAN_F6DATA0(canx) REG32((canx) + 0x270U) /*!< CAN filter 6 data 0 register */ +#define CAN_F7DATA0(canx) REG32((canx) + 0x278U) /*!< CAN filter 7 data 0 register */ +#define CAN_F8DATA0(canx) REG32((canx) + 0x280U) /*!< CAN filter 8 data 0 register */ +#define CAN_F9DATA0(canx) REG32((canx) + 0x288U) /*!< CAN filter 9 data 0 register */ +#define CAN_F10DATA0(canx) REG32((canx) + 0x290U) /*!< CAN filter 10 data 0 register */ +#define CAN_F11DATA0(canx) REG32((canx) + 0x298U) /*!< CAN filter 11 data 0 register */ +#define CAN_F12DATA0(canx) REG32((canx) + 0x2A0U) /*!< CAN filter 12 data 0 register */ +#define CAN_F13DATA0(canx) REG32((canx) + 0x2A8U) /*!< CAN filter 13 data 0 register */ +#define CAN_F14DATA0(canx) REG32((canx) + 0x2B0U) /*!< CAN filter 14 data 0 register */ +#define CAN_F15DATA0(canx) REG32((canx) + 0x2B8U) /*!< CAN filter 15 data 0 register */ +#define CAN_F16DATA0(canx) REG32((canx) + 0x2C0U) /*!< CAN filter 16 data 0 register */ +#define CAN_F17DATA0(canx) REG32((canx) + 0x2C8U) /*!< CAN filter 17 data 0 register */ +#define CAN_F18DATA0(canx) REG32((canx) + 0x2D0U) /*!< CAN filter 18 data 0 register */ +#define CAN_F19DATA0(canx) REG32((canx) + 0x2D8U) /*!< CAN filter 19 data 0 register */ +#define CAN_F20DATA0(canx) REG32((canx) + 0x2E0U) /*!< CAN filter 20 data 0 register */ +#define CAN_F21DATA0(canx) REG32((canx) + 0x2E8U) /*!< CAN filter 21 data 0 register */ +#define CAN_F22DATA0(canx) REG32((canx) + 0x2F0U) /*!< CAN filter 22 data 0 register */ +#define CAN_F23DATA0(canx) REG32((canx) + 0x3F8U) /*!< CAN filter 23 data 0 register */ +#define CAN_F24DATA0(canx) REG32((canx) + 0x300U) /*!< CAN filter 24 data 0 register */ +#define CAN_F25DATA0(canx) REG32((canx) + 0x308U) /*!< CAN filter 25 data 0 register */ +#define CAN_F26DATA0(canx) REG32((canx) + 0x310U) /*!< CAN filter 26 data 0 register */ +#define CAN_F27DATA0(canx) REG32((canx) + 0x318U) /*!< CAN filter 27 data 0 register */ +#define CAN_F0DATA1(canx) REG32((canx) + 0x244U) /*!< CAN filter 0 data 1 register */ +#define CAN_F1DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 1 data 1 register */ +#define CAN_F2DATA1(canx) REG32((canx) + 0x254U) /*!< CAN filter 2 data 1 register */ +#define CAN_F3DATA1(canx) REG32((canx) + 0x25CU) /*!< CAN filter 3 data 1 register */ +#define CAN_F4DATA1(canx) REG32((canx) + 0x264U) /*!< CAN filter 4 data 1 register */ +#define CAN_F5DATA1(canx) REG32((canx) + 0x26CU) /*!< CAN filter 5 data 1 register */ +#define CAN_F6DATA1(canx) REG32((canx) + 0x274U) /*!< CAN filter 6 data 1 register */ +#define CAN_F7DATA1(canx) REG32((canx) + 0x27CU) /*!< CAN filter 7 data 1 register */ +#define CAN_F8DATA1(canx) REG32((canx) + 0x284U) /*!< CAN filter 8 data 1 register */ +#define CAN_F9DATA1(canx) REG32((canx) + 0x28CU) /*!< CAN filter 9 data 1 register */ +#define CAN_F10DATA1(canx) REG32((canx) + 0x294U) /*!< CAN filter 10 data 1 register */ +#define CAN_F11DATA1(canx) REG32((canx) + 0x29CU) /*!< CAN filter 11 data 1 register */ +#define CAN_F12DATA1(canx) REG32((canx) + 0x2A4U) /*!< CAN filter 12 data 1 register */ +#define CAN_F13DATA1(canx) REG32((canx) + 0x2ACU) /*!< CAN filter 13 data 1 register */ +#define CAN_F14DATA1(canx) REG32((canx) + 0x2B4U) /*!< CAN filter 14 data 1 register */ +#define CAN_F15DATA1(canx) REG32((canx) + 0x2BCU) /*!< CAN filter 15 data 1 register */ +#define CAN_F16DATA1(canx) REG32((canx) + 0x2C4U) /*!< CAN filter 16 data 1 register */ +#define CAN_F17DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 17 data 1 register */ +#define CAN_F18DATA1(canx) REG32((canx) + 0x2D4U) /*!< CAN filter 18 data 1 register */ +#define CAN_F19DATA1(canx) REG32((canx) + 0x2DCU) /*!< CAN filter 19 data 1 register */ +#define CAN_F20DATA1(canx) REG32((canx) + 0x2E4U) /*!< CAN filter 20 data 1 register */ +#define CAN_F21DATA1(canx) REG32((canx) + 0x2ECU) /*!< CAN filter 21 data 1 register */ +#define CAN_F22DATA1(canx) REG32((canx) + 0x2F4U) /*!< CAN filter 22 data 1 register */ +#define CAN_F23DATA1(canx) REG32((canx) + 0x2FCU) /*!< CAN filter 23 data 1 register */ +#define CAN_F24DATA1(canx) REG32((canx) + 0x304U) /*!< CAN filter 24 data 1 register */ +#define CAN_F25DATA1(canx) REG32((canx) + 0x30CU) /*!< CAN filter 25 data 1 register */ +#define CAN_F26DATA1(canx) REG32((canx) + 0x314U) /*!< CAN filter 26 data 1 register */ +#define CAN_F27DATA1(canx) REG32((canx) + 0x31CU) /*!< CAN filter 27 data 1 register */ +#define CAN_PHYCTL(canx) REG32((canx) + 0x3FCU) /*!< CAN PHY control register */ + +/* CAN transmit mailbox bank */ +#define CAN_TMI(canx, bank) REG32((canx) + 0x180U + ((bank) * 0x10U)) /*!< CAN transmit mailbox identifier register */ +#define CAN_TMP(canx, bank) REG32((canx) + 0x184U + ((bank) * 0x10U)) /*!< CAN transmit mailbox property register */ +#define CAN_TMDATA0(canx, bank) REG32((canx) + 0x188U + ((bank) * 0x10U)) /*!< CAN transmit mailbox data0 register */ +#define CAN_TMDATA1(canx, bank) REG32((canx) + 0x18CU + ((bank) * 0x10U)) /*!< CAN transmit mailbox data1 register */ + +/* CAN filter bank */ +#define CAN_FDATA0(canx, bank) REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x0U) /*!< CAN filter data 0 register */ +#define CAN_FDATA1(canx, bank) REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x4U) /*!< CAN filter data 1 register */ + +/* CAN receive fifo mailbox bank */ +#define CAN_RFIFOMI(canx, bank) REG32((canx) + 0x1B0U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox identifier register */ +#define CAN_RFIFOMP(canx, bank) REG32((canx) + 0x1B4U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox property register */ +#define CAN_RFIFOMDATA0(canx, bank) REG32((canx) + 0x1B8U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox data0 register */ +#define CAN_RFIFOMDATA1(canx, bank) REG32((canx) + 0x1BCU + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox data1 register */ + +/* bits definitions */ +/* CAN_CTL */ +#define CAN_CTL_IWMOD BIT(0) /*!< initial working mode */ +#define CAN_CTL_SLPWMOD BIT(1) /*!< sleep working mode */ +#define CAN_CTL_TFO BIT(2) /*!< transmit FIFO order */ +#define CAN_CTL_RFOD BIT(3) /*!< receive FIFO overwrite disable */ +#define CAN_CTL_ARD BIT(4) /*!< automatic retransmission disable */ +#define CAN_CTL_AWU BIT(5) /*!< automatic wakeup */ +#define CAN_CTL_ABOR BIT(6) /*!< automatic bus-off recovery */ +#define CAN_CTL_TTC BIT(7) /*!< time triggered communication */ +#define CAN_CTL_SWRST BIT(15) /*!< CAN software reset */ +#define CAN_CTL_DFZ BIT(16) /*!< CAN debug freeze */ + +/* CAN_STAT */ +#define CAN_STAT_IWS BIT(0) /*!< initial working state */ +#define CAN_STAT_SLPWS BIT(1) /*!< sleep working state */ +#define CAN_STAT_ERRIF BIT(2) /*!< error interrupt flag*/ +#define CAN_STAT_WUIF BIT(3) /*!< status change interrupt flag of wakeup from sleep working mode */ +#define CAN_STAT_SLPIF BIT(4) /*!< status change interrupt flag of sleep working mode entering */ +#define CAN_STAT_TS BIT(8) /*!< transmitting state */ +#define CAN_STAT_RS BIT(9) /*!< receiving state */ +#define CAN_STAT_LASTRX BIT(10) /*!< last sample value of rx pin */ +#define CAN_STAT_RXL BIT(11) /*!< CAN rx signal */ + +/* CAN_TSTAT */ +#define CAN_TSTAT_MTF0 BIT(0) /*!< mailbox0 transmit finished */ +#define CAN_TSTAT_MTFNERR0 BIT(1) /*!< mailbox0 transmit finished and no error */ +#define CAN_TSTAT_MAL0 BIT(2) /*!< mailbox0 arbitration lost */ +#define CAN_TSTAT_MTE0 BIT(3) /*!< mailbox0 transmit error */ +#define CAN_TSTAT_MST0 BIT(7) /*!< mailbox0 stop transmitting */ +#define CAN_TSTAT_MTF1 BIT(8) /*!< mailbox1 transmit finished */ +#define CAN_TSTAT_MTFNERR1 BIT(9) /*!< mailbox1 transmit finished and no error */ +#define CAN_TSTAT_MAL1 BIT(10) /*!< mailbox1 arbitration lost */ +#define CAN_TSTAT_MTE1 BIT(11) /*!< mailbox1 transmit error */ +#define CAN_TSTAT_MST1 BIT(15) /*!< mailbox1 stop transmitting */ +#define CAN_TSTAT_MTF2 BIT(16) /*!< mailbox2 transmit finished */ +#define CAN_TSTAT_MTFNERR2 BIT(17) /*!< mailbox2 transmit finished and no error */ +#define CAN_TSTAT_MAL2 BIT(18) /*!< mailbox2 arbitration lost */ +#define CAN_TSTAT_MTE2 BIT(19) /*!< mailbox2 transmit error */ +#define CAN_TSTAT_MST2 BIT(23) /*!< mailbox2 stop transmitting */ +#define CAN_TSTAT_NUM BITS(24,25) /*!< mailbox number */ +#define CAN_TSTAT_TME0 BIT(26) /*!< transmit mailbox0 empty */ +#define CAN_TSTAT_TME1 BIT(27) /*!< transmit mailbox1 empty */ +#define CAN_TSTAT_TME2 BIT(28) /*!< transmit mailbox2 empty */ +#define CAN_TSTAT_TMLS0 BIT(29) /*!< last sending priority flag for mailbox0 */ +#define CAN_TSTAT_TMLS1 BIT(30) /*!< last sending priority flag for mailbox1 */ +#define CAN_TSTAT_TMLS2 BIT(31) /*!< last sending priority flag for mailbox2 */ + +/* CAN_RFIFO0 */ +#define CAN_RFIFO0_RFL0 BITS(0,1) /*!< receive FIFO0 length */ +#define CAN_RFIFO0_RFF0 BIT(3) /*!< receive FIFO0 full */ +#define CAN_RFIFO0_RFO0 BIT(4) /*!< receive FIFO0 overfull */ +#define CAN_RFIFO0_RFD0 BIT(5) /*!< receive FIFO0 dequeue */ + +/* CAN_RFIFO1 */ +#define CAN_RFIFO1_RFL1 BITS(0,1) /*!< receive FIFO1 length */ +#define CAN_RFIFO1_RFF1 BIT(3) /*!< receive FIFO1 full */ +#define CAN_RFIFO1_RFO1 BIT(4) /*!< receive FIFO1 overfull */ +#define CAN_RFIFO1_RFD1 BIT(5) /*!< receive FIFO1 dequeue */ + +/* CAN_INTEN */ +#define CAN_INTEN_TMEIE BIT(0) /*!< transmit mailbox empty interrupt enable */ +#define CAN_INTEN_RFNEIE0 BIT(1) /*!< receive FIFO0 not empty interrupt enable */ +#define CAN_INTEN_RFFIE0 BIT(2) /*!< receive FIFO0 full interrupt enable */ +#define CAN_INTEN_RFOIE0 BIT(3) /*!< receive FIFO0 overfull interrupt enable */ +#define CAN_INTEN_RFNEIE1 BIT(4) /*!< receive FIFO1 not empty interrupt enable */ +#define CAN_INTEN_RFFIE1 BIT(5) /*!< receive FIFO1 full interrupt enable */ +#define CAN_INTEN_RFOIE1 BIT(6) /*!< receive FIFO1 overfull interrupt enable */ +#define CAN_INTEN_WERRIE BIT(8) /*!< warning error interrupt enable */ +#define CAN_INTEN_PERRIE BIT(9) /*!< passive error interrupt enable */ +#define CAN_INTEN_BOIE BIT(10) /*!< bus-off interrupt enable */ +#define CAN_INTEN_ERRNIE BIT(11) /*!< error number interrupt enable */ +#define CAN_INTEN_ERRIE BIT(15) /*!< error interrupt enable */ +#define CAN_INTEN_WIE BIT(16) /*!< wakeup interrupt enable */ +#define CAN_INTEN_SLPWIE BIT(17) /*!< sleep working interrupt enable */ + +/* CAN_ERR */ +#define CAN_ERR_WERR BIT(0) /*!< warning error */ +#define CAN_ERR_PERR BIT(1) /*!< passive error */ +#define CAN_ERR_BOERR BIT(2) /*!< bus-off error */ +#define CAN_ERR_ERRN BITS(4,6) /*!< error number */ +#define CAN_ERR_TECNT BITS(16,23) /*!< transmit error count */ +#define CAN_ERR_RECNT BITS(24,31) /*!< receive error count */ + +/* CAN_BT */ +#define CAN_BT_BAUDPSC BITS(0,9) /*!< baudrate prescaler */ +#define CAN_BT_BS1 BITS(16,19) /*!< bit segment 1 */ +#define CAN_BT_BS2 BITS(20,22) /*!< bit segment 2 */ +#define CAN_BT_SJW BITS(24,25) /*!< resynchronization jump width */ +#define CAN_BT_LCMOD BIT(30) /*!< loopback communication mode */ +#define CAN_BT_SCMOD BIT(31) /*!< silent communication mode */ + +/* CAN_TMIx */ +#define CAN_TMI_TEN BIT(0) /*!< transmit enable */ +#define CAN_TMI_FT BIT(1) /*!< frame type */ +#define CAN_TMI_FF BIT(2) /*!< frame format */ +#define CAN_TMI_EFID BITS(3,31) /*!< the frame identifier */ +#define CAN_TMI_SFID BITS(21,31) /*!< the frame identifier */ + +/* CAN_TMPx */ +#define CAN_TMP_DLENC BITS(0,3) /*!< data length code */ +#define CAN_TMP_TSEN BIT(8) /*!< time stamp enable */ +#define CAN_TMP_TS BITS(16,31) /*!< time stamp */ + +/* CAN_TMDATA0x */ +#define CAN_TMDATA0_DB0 BITS(0,7) /*!< transmit data byte 0 */ +#define CAN_TMDATA0_DB1 BITS(8,15) /*!< transmit data byte 1 */ +#define CAN_TMDATA0_DB2 BITS(16,23) /*!< transmit data byte 2 */ +#define CAN_TMDATA0_DB3 BITS(24,31) /*!< transmit data byte 3 */ + +/* CAN_TMDATA1x */ +#define CAN_TMDATA1_DB4 BITS(0,7) /*!< transmit data byte 4 */ +#define CAN_TMDATA1_DB5 BITS(8,15) /*!< transmit data byte 5 */ +#define CAN_TMDATA1_DB6 BITS(16,23) /*!< transmit data byte 6 */ +#define CAN_TMDATA1_DB7 BITS(24,31) /*!< transmit data byte 7 */ + +/* CAN_RFIFOMIx */ +#define CAN_RFIFOMI_FT BIT(1) /*!< frame type */ +#define CAN_RFIFOMI_FF BIT(2) /*!< frame format */ +#define CAN_RFIFOMI_EFID BITS(3,31) /*!< the frame identifier */ +#define CAN_RFIFOMI_SFID BITS(21,31) /*!< the frame identifier */ + +/* CAN_RFIFOMPx */ +#define CAN_RFIFOMP_DLENC BITS(0,3) /*!< receive data length code */ +#define CAN_RFIFOMP_FI BITS(8,15) /*!< filter index */ +#define CAN_RFIFOMP_TS BITS(16,31) /*!< time stamp */ + +/* CAN_RFIFOMDATA0x */ +#define CAN_RFIFOMDATA0_DB0 BITS(0,7) /*!< receive data byte 0 */ +#define CAN_RFIFOMDATA0_DB1 BITS(8,15) /*!< receive data byte 1 */ +#define CAN_RFIFOMDATA0_DB2 BITS(16,23) /*!< receive data byte 2 */ +#define CAN_RFIFOMDATA0_DB3 BITS(24,31) /*!< receive data byte 3 */ + +/* CAN_RFIFOMDATA1x */ +#define CAN_RFIFOMDATA1_DB4 BITS(0,7) /*!< receive data byte 4 */ +#define CAN_RFIFOMDATA1_DB5 BITS(8,15) /*!< receive data byte 5 */ +#define CAN_RFIFOMDATA1_DB6 BITS(16,23) /*!< receive data byte 6 */ +#define CAN_RFIFOMDATA1_DB7 BITS(24,31) /*!< receive data byte 7 */ + +/* CAN_FCTL */ +#define CAN_FCTL_FLD BIT(0) /*!< filter lock disable */ +#define CAN_FCTL_HBC1F BITS(8,13) /*!< header bank of CAN1 filter */ + +/* CAN_FMCFG */ +#define CAN_FMCFG_FMOD(regval) BIT(regval) /*!< filter mode, list or mask*/ + +/* CAN_FSCFG */ +#define CAN_FSCFG_FS(regval) BIT(regval) /*!< filter scale, 32 bits or 16 bits*/ + +/* CAN_FAFIFO */ +#define CAN_FAFIFOR_FAF(regval) BIT(regval) /*!< filter associated with FIFO */ + +/* CAN_FW */ +#define CAN_FW_FW(regval) BIT(regval) /*!< filter working */ + +/* CAN_FxDATAy */ +#define CAN_FDATA_FD BITS(0,31) /*!< filter data */ + +/* CAN_PHYCTL */ +#define CAN_PHYCTL_PHYEN BIT(0) /*!< PHY enable */ +#define CAN_PHYCTL_POMOD BITS(8,9) /*!< PHY mode */ + +/* consts definitions */ +/* define the CAN bit position and its register index offset */ +#define CAN_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define CAN_REG_VAL(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 6))) +#define CAN_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +#define CAN_REGIDX_BITS(regidx, bitpos0, bitpos1) (((uint32_t)(regidx) << 12) | ((uint32_t)(bitpos0) << 6) | (uint32_t)(bitpos1)) +#define CAN_REG_VALS(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 12))) +#define CAN_BIT_POS0(val) (((uint32_t)(val) >> 6) & 0x1FU) +#define CAN_BIT_POS1(val) ((uint32_t)(val) & 0x1FU) + +/* register offset */ +#define STAT_REG_OFFSET ((uint8_t)0x04U) /*!< STAT register offset */ +#define TSTAT_REG_OFFSET ((uint8_t)0x08U) /*!< TSTAT register offset */ +#define RFIFO0_REG_OFFSET ((uint8_t)0x0CU) /*!< RFIFO0 register offset */ +#define RFIFO1_REG_OFFSET ((uint8_t)0x10U) /*!< RFIFO1 register offset */ +#define ERR_REG_OFFSET ((uint8_t)0x18U) /*!< ERR register offset */ + +/* CAN flags */ +typedef enum +{ + /* flags in TSTAT register */ + CAN_FLAG_MTE2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 19U), /*!< mailbox 2 transmit error */ + CAN_FLAG_MTE1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 11U), /*!< mailbox 1 transmit error */ + CAN_FLAG_MTE0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 3U), /*!< mailbox 0 transmit error */ + CAN_FLAG_MTF2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 16U), /*!< mailbox 2 transmit finished */ + CAN_FLAG_MTF1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 8U), /*!< mailbox 1 transmit finished */ + CAN_FLAG_MTF0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 0U), /*!< mailbox 0 transmit finished */ + /* flags in RFIFO0 register */ + CAN_FLAG_RFO0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 4U), /*!< receive FIFO0 overfull */ + CAN_FLAG_RFF0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 3U), /*!< receive FIFO0 full */ + /* flags in RFIFO1 register */ + CAN_FLAG_RFO1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 4U), /*!< receive FIFO1 overfull */ + CAN_FLAG_RFF1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 3U), /*!< receive FIFO1 full */ + /* flags in ERR register */ + CAN_FLAG_BOERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 2U), /*!< bus-off error */ + CAN_FLAG_PERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 1U), /*!< passive error */ + CAN_FLAG_WERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 0U), /*!< warning error */ +}can_flag_enum; + +/* CAN interrupt flags */ +typedef enum +{ + /* interrupt flags in STAT register */ + CAN_INT_FLAG_SLPIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 4U, 17U), /*!< status change interrupt flag of sleep working mode entering */ + CAN_INT_FLAG_WUIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 3U, 16), /*!< status change interrupt flag of wakeup from sleep working mode */ + CAN_INT_FLAG_ERRIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 2U, 15), /*!< error interrupt flag */ + /* interrupt flags in TSTAT register */ + CAN_INT_FLAG_MTF2 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 16U, 0U), /*!< mailbox 2 transmit finished interrupt flag */ + CAN_INT_FLAG_MTF1 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 8U, 0U), /*!< mailbox 1 transmit finished interrupt flag */ + CAN_INT_FLAG_MTF0 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 0U, 0U), /*!< mailbox 0 transmit finished interrupt flag */ + /* interrupt flags in RFIFO0 register */ + CAN_INT_FLAG_RFO0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 4U, 3U), /*!< receive FIFO0 overfull interrupt flag */ + CAN_INT_FLAG_RFF0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 3U, 2U), /*!< receive FIFO0 full interrupt flag */ + /* interrupt flags in RFIFO0 register */ + CAN_INT_FLAG_RFO1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 4U, 6U), /*!< receive FIFO1 overfull interrupt flag */ + CAN_INT_FLAG_RFF1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 3U, 5U), /*!< receive FIFO1 full interrupt flag */ +}can_interrupt_flag_enum; + +/* CAN initiliaze parameters struct */ +typedef struct +{ + uint8_t working_mode; /*!< CAN working mode */ + uint8_t resync_jump_width; /*!< CAN resynchronization jump width */ + uint8_t time_segment_1; /*!< time segment 1 */ + uint8_t time_segment_2; /*!< time segment 2 */ + ControlStatus time_triggered; /*!< time triggered communication mode */ + ControlStatus auto_bus_off_recovery; /*!< automatic bus-off recovery */ + ControlStatus auto_wake_up; /*!< automatic wake-up mode */ + ControlStatus auto_retrans; /*!< automatic retransmission mode */ + ControlStatus rec_fifo_overwrite; /*!< receive FIFO overwrite mode */ + ControlStatus trans_fifo_order; /*!< transmit FIFO order */ + uint16_t prescaler; /*!< baudrate prescaler */ +}can_parameter_struct; + +/* CAN transmit message struct */ +typedef struct +{ + uint32_t tx_sfid; /*!< standard format frame identifier */ + uint32_t tx_efid; /*!< extended format frame identifier */ + uint8_t tx_ff; /*!< format of frame, standard or extended format */ + uint8_t tx_ft; /*!< type of frame, data or remote */ + uint8_t tx_dlen; /*!< data length */ + uint8_t tx_data[8]; /*!< transmit data */ +}can_trasnmit_message_struct; + +/* CAN receive message struct */ +typedef struct +{ + uint32_t rx_sfid; /*!< standard format frame identifier */ + uint32_t rx_efid; /*!< extended format frame identifier */ + uint8_t rx_ff; /*!< format of frame, standard or extended format */ + uint8_t rx_ft; /*!< type of frame, data or remote */ + uint8_t rx_dlen; /*!< data length */ + uint8_t rx_data[8]; /*!< receive data */ + uint8_t rx_fi; /*!< filtering index */ +} can_receive_message_struct; + +/* CAN filter parameters struct */ +typedef struct +{ + uint16_t filter_list_high; /*!< filter list number high bits*/ + uint16_t filter_list_low; /*!< filter list number low bits */ + uint16_t filter_mask_high; /*!< filter mask number high bits */ + uint16_t filter_mask_low; /*!< filter mask number low bits */ + uint16_t filter_fifo_number; /*!< receive FIFO associated with the filter */ + uint16_t filter_number; /*!< filter number */ + uint16_t filter_mode; /*!< filter mode, list or mask */ + uint16_t filter_bits; /*!< filter scale */ + ControlStatus filter_enable; /*!< filter work or not */ +}can_filter_parameter_struct; + +/* CAN errors */ +typedef enum +{ + CAN_ERROR_NONE = 0, /*!< no error */ + CAN_ERROR_FILL, /*!< fill error */ + CAN_ERROR_FORMATE, /*!< format error */ + CAN_ERROR_ACK, /*!< ACK error */ + CAN_ERROR_BITRECESSIVE, /*!< bit recessive error */ + CAN_ERROR_BITDOMINANTER, /*!< bit dominant error */ + CAN_ERROR_CRC, /*!< CRC error */ + CAN_ERROR_SOFTWARECFG, /*!< software configure */ +}can_error_enum; + +/* transmit states */ +typedef enum +{ + CAN_TRANSMIT_FAILED = 0, /*!< CAN transmitted failure */ + CAN_TRANSMIT_OK = 1, /*!< CAN transmitted success */ + CAN_TRANSMIT_PENDING = 2, /*!< CAN transmitted pending */ + CAN_TRANSMIT_NOMAILBOX = 4, /*!< no empty mailbox to be used for CAN */ +}can_transmit_state_enum; + +/* CAN baudrate prescaler*/ +#define BT_BAUDPSC(regval) (BITS(0,9) & ((uint32_t)(regval) << 0)) + +/* CAN bit segment 1*/ +#define BT_BS1(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) + +/* CAN bit segment 2*/ +#define BT_BS2(regval) (BITS(20,22) & ((uint32_t)(regval) << 20)) + +/* CAN resynchronization jump width*/ +#define BT_SJW(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) + +/* CAN communication mode*/ +#define BT_MODE(regval) (BITS(30,31) & ((uint32_t)(regval) << 30)) + +/* CAN FDATA high 16 bits */ +#define FDATA_MASK_HIGH(regval) (BITS(16,31) & ((uint32_t)(regval) << 16)) + +/* CAN FDATA low 16 bits */ +#define FDATA_MASK_LOW(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) + +/* CAN1 filter start bank_number*/ +#define FCTL_HBC1F(regval) (BITS(8,13) & ((uint32_t)(regval) << 8)) + +/* CAN transmit mailbox extended identifier*/ +#define TMI_EFID(regval) (BITS(3,31) & ((uint32_t)(regval) << 3)) + +/* CAN transmit mailbox standard identifier*/ +#define TMI_SFID(regval) (BITS(21,31) & ((uint32_t)(regval) << 21)) + +/* transmit data byte 0 */ +#define TMDATA0_DB0(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* transmit data byte 1 */ +#define TMDATA0_DB1(regval) (BITS(8,15) & ((uint32_t)(regval) << 8)) + +/* transmit data byte 2 */ +#define TMDATA0_DB2(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) + +/* transmit data byte 3 */ +#define TMDATA0_DB3(regval) (BITS(24,31) & ((uint32_t)(regval) << 24)) + +/* transmit data byte 4 */ +#define TMDATA1_DB4(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* transmit data byte 5 */ +#define TMDATA1_DB5(regval) (BITS(8,15) & ((uint32_t)(regval) << 8)) + +/* transmit data byte 6 */ +#define TMDATA1_DB6(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) + +/* transmit data byte 7 */ +#define TMDATA1_DB7(regval) (BITS(24,31) & ((uint32_t)(regval) << 24)) + +/* receive mailbox extended identifier*/ +#define RFIFOMI_EFID(regval) GET_BITS((uint32_t)(regval), 3, 31) + +/* receive mailbox standrad identifier*/ +#define RFIFOMI_SFID(regval) GET_BITS((uint32_t)(regval), 21, 31) + +/* receive data length */ +#define RFIFOMP_DLENC(regval) GET_BITS((uint32_t)(regval), 0, 3) + +/* the index of the filter by which the frame is passed */ +#define RFIFOMP_FI(regval) GET_BITS((uint32_t)(regval), 8, 15) + +/* receive data byte 0 */ +#define RFIFOMDATA0_DB0(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* receive data byte 1 */ +#define RFIFOMDATA0_DB1(regval) GET_BITS((uint32_t)(regval), 8, 15) + +/* receive data byte 2 */ +#define RFIFOMDATA0_DB2(regval) GET_BITS((uint32_t)(regval), 16, 23) + +/* receive data byte 3 */ +#define RFIFOMDATA0_DB3(regval) GET_BITS((uint32_t)(regval), 24, 31) + +/* receive data byte 4 */ +#define RFIFOMDATA1_DB4(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* receive data byte 5 */ +#define RFIFOMDATA1_DB5(regval) GET_BITS((uint32_t)(regval), 8, 15) + +/* receive data byte 6 */ +#define RFIFOMDATA1_DB6(regval) GET_BITS((uint32_t)(regval), 16, 23) + +/* receive data byte 7 */ +#define RFIFOMDATA1_DB7(regval) GET_BITS((uint32_t)(regval), 24, 31) + +/* CAN errors */ +#define ERR_ERRN(regval) (BITS(4,6) & ((uint32_t)(regval) << 4)) +#define CAN_ERRN_0 ERR_ERRN(0) /* no error */ +#define CAN_ERRN_1 ERR_ERRN(1) /*!< fill error */ +#define CAN_ERRN_2 ERR_ERRN(2) /*!< format error */ +#define CAN_ERRN_3 ERR_ERRN(3) /*!< ACK error */ +#define CAN_ERRN_4 ERR_ERRN(4) /*!< bit recessive error */ +#define CAN_ERRN_5 ERR_ERRN(5) /*!< bit dominant error */ +#define CAN_ERRN_6 ERR_ERRN(6) /*!< CRC error */ +#define CAN_ERRN_7 ERR_ERRN(7) /*!< software error */ + +/* CAN phy mode bits */ +#define PHYCTL_POMOD(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) + +#define CAN_PHYCTL_POMODE_0 PHYCTL_POMOD(0) /*!< low slope mode */ +#define CAN_PHYCTL_POMODE_1 PHYCTL_POMOD(1) /*!< middle slope mode */ +#define CAN_PHYCTL_POMODE_2 PHYCTL_POMOD(2) /*!< high slope mode */ +#define CAN_PHYCTL_POMODE_3 PHYCTL_POMOD(3) /*!< high speed mode */ +#define CAN_PHYCTL_POMODE_MASK PHYCTL_POMOD(3) /*!< mask of phy mode */ + +#define CAN_STATE_PENDING ((uint32_t)0x00000000U) /*!< CAN pending */ + +/* CAN communication mode */ +#define CAN_NORMAL_MODE ((uint8_t)0x00U) /*!< normal communication mode */ +#define CAN_LOOPBACK_MODE ((uint8_t)0x01U) /*!< loopback communication mode */ +#define CAN_SILENT_MODE ((uint8_t)0x02U) /*!< silent communication mode */ +#define CAN_SILENT_LOOPBACK_MODE ((uint8_t)0x03U) /*!< loopback and silent communication mode */ + +/* CAN resynchronisation jump width */ +#define CAN_BT_SJW_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_SJW_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_SJW_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_SJW_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ + +/* CAN time segment 1 */ +#define CAN_BT_BS1_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_BS1_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_BS1_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_BS1_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ +#define CAN_BT_BS1_5TQ ((uint8_t)0x04U) /*!< 5 time quanta */ +#define CAN_BT_BS1_6TQ ((uint8_t)0x05U) /*!< 6 time quanta */ +#define CAN_BT_BS1_7TQ ((uint8_t)0x06U) /*!< 7 time quanta */ +#define CAN_BT_BS1_8TQ ((uint8_t)0x07U) /*!< 8 time quanta */ +#define CAN_BT_BS1_9TQ ((uint8_t)0x08U) /*!< 9 time quanta */ +#define CAN_BT_BS1_10TQ ((uint8_t)0x09U) /*!< 10 time quanta */ +#define CAN_BT_BS1_11TQ ((uint8_t)0x0AU) /*!< 11 time quanta */ +#define CAN_BT_BS1_12TQ ((uint8_t)0x0BU) /*!< 12 time quanta */ +#define CAN_BT_BS1_13TQ ((uint8_t)0x0CU) /*!< 13 time quanta */ +#define CAN_BT_BS1_14TQ ((uint8_t)0x0DU) /*!< 14 time quanta */ +#define CAN_BT_BS1_15TQ ((uint8_t)0x0EU) /*!< 15 time quanta */ +#define CAN_BT_BS1_16TQ ((uint8_t)0x0FU) /*!< 16 time quanta */ + +/* CAN time segment 2 */ +#define CAN_BT_BS2_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_BS2_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_BS2_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_BS2_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ +#define CAN_BT_BS2_5TQ ((uint8_t)0x04U) /*!< 5 time quanta */ +#define CAN_BT_BS2_6TQ ((uint8_t)0x05U) /*!< 6 time quanta */ +#define CAN_BT_BS2_7TQ ((uint8_t)0x06U) /*!< 7 time quanta */ +#define CAN_BT_BS2_8TQ ((uint8_t)0x07U) /*!< 8 time quanta */ + +/* CAN mailbox number */ +#define CAN_MAILBOX0 ((uint8_t)0x00U) /*!< mailbox0 */ +#define CAN_MAILBOX1 ((uint8_t)0x01U) /*!< mailbox1 */ +#define CAN_MAILBOX2 ((uint8_t)0x02U) /*!< mailbox2 */ +#define CAN_NOMAILBOX ((uint8_t)0x03U) /*!< no mailbox empty */ + +/* CAN frame format */ +#define CAN_FF_STANDARD ((uint32_t)0x00000000U) /*!< standard frame */ +#define CAN_FF_EXTENDED ((uint32_t)0x00000004U) /*!< extended frame */ + +/* CAN receive fifo */ +#define CAN_FIFO0 ((uint8_t)0x00U) /*!< receive FIFO0 */ +#define CAN_FIFO1 ((uint8_t)0x01U) /*!< receive FIFO1 */ + +/* frame number of receive fifo */ +#define CAN_RFIF_RFL_MASK ((uint32_t)0x00000003U) /*!< mask for frame number in receive FIFOx */ + +#define CAN_SFID_MASK ((uint32_t)0x000007FFU) /*!< mask of standard identifier */ +#define CAN_EFID_MASK ((uint32_t)0x1FFFFFFFU) /*!< mask of extended identifier */ + +/* CAN working mode */ +#define CAN_MODE_INITIALIZE ((uint8_t)0x01U) /*!< CAN initialize mode */ +#define CAN_MODE_NORMAL ((uint8_t)0x02U) /*!< CAN normal mode */ +#define CAN_MODE_SLEEP ((uint8_t)0x04U) /*!< CAN sleep mode */ + +/* filter bits */ +#define CAN_FILTERBITS_16BIT ((uint8_t)0x00U) /*!< CAN filter 16 bits */ +#define CAN_FILTERBITS_32BIT ((uint8_t)0x01U) /*!< CAN filter 32 bits */ + +/* filter mode */ +#define CAN_FILTERMODE_MASK ((uint8_t)0x00U) /*!< mask mode */ +#define CAN_FILTERMODE_LIST ((uint8_t)0x01U) /*!< list mode */ + +/* filter 16 bits mask */ +#define CAN_FILTER_MASK_16BITS ((uint32_t)0x0000FFFFU) + +/* frame type */ +#define CAN_FT_DATA ((uint32_t)0x00000000U) /*!< data frame */ +#define CAN_FT_REMOTE ((uint32_t)0x00000002U) /*!< remote frame */ + +/* CAN timeout */ +#define CAN_TIMEOUT ((uint32_t)0x0000FFFFU) /*!< timeout value */ + +/* interrupt enable bits */ +#define CAN_INT_TME CAN_INTEN_TMEIE /*!< transmit mailbox empty interrupt enable */ +#define CAN_INT_RFNE0 CAN_INTEN_RFNEIE0 /*!< receive FIFO0 not empty interrupt enable */ +#define CAN_INT_RFF0 CAN_INTEN_RFFIE0 /*!< receive FIFO0 full interrupt enable */ +#define CAN_INT_RFO0 CAN_INTEN_RFOIE0 /*!< receive FIFO0 overfull interrupt enable */ +#define CAN_INT_RFNE1 CAN_INTEN_RFNEIE1 /*!< receive FIFO1 not empty interrupt enable */ +#define CAN_INT_RFF1 CAN_INTEN_RFFIE1 /*!< receive FIFO1 full interrupt enable */ +#define CAN_INT_RFO1 CAN_INTEN_RFOIE1 /*!< receive FIFO1 overfull interrupt enable */ +#define CAN_INT_WERR CAN_INTEN_WERRIE /*!< warning error interrupt enable */ +#define CAN_INT_PERR CAN_INTEN_PERRIE /*!< passive error interrupt enable */ +#define CAN_INT_BO CAN_INTEN_BOIE /*!< bus-off interrupt enable */ +#define CAN_INT_ERRN CAN_INTEN_ERRNIE /*!< error number interrupt enable */ +#define CAN_INT_ERR CAN_INTEN_ERRIE /*!< error interrupt enable */ +#define CAN_INT_WAKEUP CAN_INTEN_WIE /*!< wakeup interrupt enable */ +#define CAN_INT_SLPW CAN_INTEN_SLPWIE /*!< sleep working interrupt enable */ + +/* function declarations */ +/* deinitialize CAN */ +void can_deinit(uint32_t can_periph); +/* initialize CAN */ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init); +/* CAN filter init */ +void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init); +/* set can1 fliter start bank number */ +void can1_filter_start_bank(uint8_t start_bank); +/* enable functions */ +/* CAN debug freeze enable */ +void can_debug_freeze_enable(uint32_t can_periph); +/* CAN debug freeze disable */ +void can_debug_freeze_disable(uint32_t can_periph); +/* CAN time triggle mode enable */ +void can_time_trigger_mode_enable(uint32_t can_periph); +/* CAN time triggle mode disable */ +void can_time_trigger_mode_disable(uint32_t can_periph); + +/* transmit functions */ +/* transmit CAN message */ +uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message); +/* get CAN transmit state */ +can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number); +/* stop CAN transmission */ +void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number); +/* CAN receive message */ +void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message); +/* CAN release fifo */ +void can_fifo_release(uint32_t can_periph, uint8_t fifo_number); +/* CAN receive message length */ +uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number); +/* CAN working mode */ +ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode); +/* CAN wakeup from sleep mode */ +ErrStatus can_wakeup(uint32_t can_periph); + +/* CAN get error */ +can_error_enum can_error_get(uint32_t can_periph); +/* get CAN receive error number */ +uint8_t can_receive_error_number_get(uint32_t can_periph); +/* get CAN transmit error number */ +uint8_t can_transmit_error_number_get(uint32_t can_periph); + +/* CAN interrupt enable */ +void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt); +/* CAN interrupt disable */ +void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt); +/* CAN get flag state */ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag); +/* CAN clear flag state */ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag); +/* CAN get interrupt flag state */ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag); +/* CAN clear interrupt flag state */ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag); + +/* enable CAN phy */ +void can_phy_enable(uint32_t can_periph); +/* disable CAN phy */ +void can_phy_disable(uint32_t can_periph); +/* set CAN PHY mode */ +void can_phy_mode(uint32_t can_periph, uint32_t phy_mode); + +#endif /* GD32F1X0_CAN_H */ + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_cec.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_cec.h new file mode 100644 index 0000000..859c4de --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_cec.h @@ -0,0 +1,226 @@ +/*! + \file gd32f1x0_cec.h + \brief definitions for the CEC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_CEC_H +#define GD32F1X0_CEC_H + +#include "gd32f1x0.h" + +/* CEC definitions */ +#define CEC CEC_BASE /*!< CEC base address */ + +/* registers definitions */ +#define CEC_CTL REG32(CEC + 0x00U) /*!< CEC control register */ +#define CEC_CFG REG32(CEC + 0x04U) /*!< CEC configuration register */ +#define CEC_TDATA REG32(CEC + 0x08U) /*!< CEC transmit data register */ +#define CEC_RDATA REG32(CEC + 0x0CU) /*!< CEC receive data register */ +#define CEC_INTF REG32(CEC + 0x10U) /*!< CEC interrupt flag Register */ +#define CEC_INTEN REG32(CEC + 0x14U) /*!< CEC interrupt enable register */ + +/* bits definitions */ +/* CEC_CTL */ +#define CEC_CTL_CECEN BIT(0) /*!< enable or disable HDMI-CEC controller bit */ +#define CEC_CTL_STAOM BIT(1) /*!< start of sending a message. */ +#define CEC_CTL_ENDOM BIT(2) /*!< ENDOM bit value in the next frame in Tx mode */ + +/* CEC_CFG */ +#define CEC_CFG_SFT BITS(0,2) /*!< signal free time */ +#define CEC_CFG_RTOL BIT(3) /*!< reception bit timing tolerance */ +#define CEC_CFG_BRES BIT(4) /*!< whether stop receive message when detected BRE */ +#define CEC_CFG_BREG BIT(5) /*!< generate Error-bit when detected BRE in singlecast */ +#define CEC_CFG_BPLEG BIT(6) /*!< generate Error-bit when detected BPLE in singlecast */ +#define CEC_CFG_BCNG BIT(7) /*!< do not generate Error-bit in broadcast message */ +#define CEC_CFG_SFTOPT BIT(8) /*!< the SFT start option bit */ +#define CEC_CFG_OAD BITS(16,30) /*!< own address */ +#define CEC_CFG_LMEN BIT(31) /*!< listen mode enable bit */ + +/* CEC_TDATA */ +#define CEC_TDATA_TDATA BITS(0,7) /*!< Tx data register */ + +/* CEC_RDATA */ +#define CEC_RDATA_RDATA BITS(0,7) /*!< Rx data register */ + +/* CEC_INTF */ +#define CEC_INTF_BR BIT(0) /*!< Rx-byte data received */ +#define CEC_INTF_REND BIT(1) /*!< end of reception */ +#define CEC_INTF_RO BIT(2) /*!< Rx overrun */ +#define CEC_INTF_BRE BIT(3) /*!< bit rising error */ +#define CEC_INTF_BPSE BIT(4) /*!< short bit period error */ +#define CEC_INTF_BPLE BIT(5) /*!< long bit period error */ +#define CEC_INTF_RAE BIT(6) /*!< Rx ACK error */ +#define CEC_INTF_ARBF BIT(7) /*!< arbitration fail */ +#define CEC_INTF_TBR BIT(8) /*!< Tx-byte data request */ +#define CEC_INTF_TEND BIT(9) /*!< transmission successfully end */ +#define CEC_INTF_TU BIT(10) /*!< Tx data buffer underrun */ +#define CEC_INTF_TERR BIT(11) /*!< Tx-error */ +#define CEC_INTF_TAERR BIT(12) /*!< Tx ACK error flag */ + +/* CEC_INTEN */ +#define CEC_INTEN_BRIE BIT(0) /*!< BR interrupt enable */ +#define CEC_INTEN_RENDIE BIT(1) /*!< REND interrupt enable */ +#define CEC_INTEN_ROIE BIT(2) /*!< RO interrupt enable */ +#define CEC_INTEN_BREIE BIT(3) /*!< BRE interrupt enable. */ +#define CEC_INTEN_BPSEIE BIT(4) /*!< BPSE interrupt enable */ +#define CEC_INTEN_BPLEIE BIT(5) /*!< BPLE interrupt enable. */ +#define CEC_INTEN_RAEIE BIT(6) /*!< RAE interrupt enable */ +#define CEC_INTEN_ARBFIE BIT(7) /*!< ARBF interrupt enable */ +#define CEC_INTEN_TBRIE BIT(8) /*!< TBR interrupt enable */ +#define CEC_INTEN_TENDIE BIT(9) /*!< TEND interrupt enable */ +#define CEC_INTEN_TUIE BIT(10) /*!< TU interrupt enable */ +#define CEC_INTEN_TERRIE BIT(11) /*!< TE interrupt enable */ +#define CEC_INTEN_TAERRIE BIT(12) /*!< TAE interrupt enable */ + +/* constants definitions */ +/* signal free time */ +#define CFG_SFT(regval) (BITS(0, 2) & ((regval) << 0U)) +#define CEC_SFT_PROTOCOL_PERIOD CFG_SFT(0) /*!< the signal free time will perform as HDMI-CEC protocol description */ +#define CEC_SFT_1POINT5_PERIOD CFG_SFT(1) /*!< 1.5 nominal data bit periods */ +#define CEC_SFT_2POINT5_PERIOD CFG_SFT(2) /*!< 2.5 nominal data bit periods */ +#define CEC_SFT_3POINT5_PERIOD CFG_SFT(3) /*!< 3.5 nominal data bit periods */ +#define CEC_SFT_4POINT5_PERIOD CFG_SFT(4) /*!< 4.5 nominal data bit periods */ +#define CEC_SFT_5POINT5_PERIOD CFG_SFT(5) /*!< 5.5 nominal data bit periods */ +#define CEC_SFT_6POINT5_PERIOD CFG_SFT(6) /*!< 6.5 nominal data bit periods */ +#define CEC_SFT_7POINT5_PERIOD CFG_SFT(7) /*!< 7.5 nominal data bit periods */ + +/* signal free time start option */ +#define CEC_SFT_START_STAOM ((uint32_t)0x00000000U) /*!< signal free time counter starts counting when STAOM is asserted */ +#define CEC_SFT_START_LAST CEC_CFG_SFTOPT /*!< signal free time counter starts automatically after transmission/reception end */ + +/* own address */ +#define CEC_OWN_ADDRESS_CLEAR ((uint32_t)0x00000000U) /*!< own address is cleared */ +#define CEC_OWN_ADDRESS0 BIT(16) /*!< own address is 0 */ +#define CEC_OWN_ADDRESS1 BIT(17) /*!< own address is 1 */ +#define CEC_OWN_ADDRESS2 BIT(18) /*!< own address is 2 */ +#define CEC_OWN_ADDRESS3 BIT(19) /*!< own address is 3 */ +#define CEC_OWN_ADDRESS4 BIT(20) /*!< own address is 4 */ +#define CEC_OWN_ADDRESS5 BIT(21) /*!< own address is 5 */ +#define CEC_OWN_ADDRESS6 BIT(22) /*!< own address is 6 */ +#define CEC_OWN_ADDRESS7 BIT(23) /*!< own address is 7 */ +#define CEC_OWN_ADDRESS8 BIT(24) /*!< own address is 8 */ +#define CEC_OWN_ADDRESS9 BIT(25) /*!< own address is 9 */ +#define CEC_OWN_ADDRESS10 BIT(26) /*!< own address is 10 */ +#define CEC_OWN_ADDRESS11 BIT(27) /*!< own address is 11 */ +#define CEC_OWN_ADDRESS12 BIT(28) /*!< own address is 12 */ +#define CEC_OWN_ADDRESS13 BIT(29) /*!< own address is 13 */ +#define CEC_OWN_ADDRESS14 BIT(30) /*!< own address is 14 */ + +/* error-bit generate */ +#define CEC_BROADCAST_ERROR_BIT_ON ((uint32_t)0x00000000U) /*!< generate Error-bit in broadcast */ +#define CEC_BROADCAST_ERROR_BIT_OFF CEC_CFG_BCNG /*!< do not generate Error-bit in broadcast */ +#define CEC_LONG_PERIOD_ERROR_BIT_OFF ((uint32_t)0x00000000U) /*!< generate Error-bit on long bit period error */ +#define CEC_LONG_PERIOD_ERROR_BIT_ON CEC_CFG_BPLEG /*!< do not generate Error-bit on long bit period error */ +#define CEC_RISING_PERIOD_ERROR_BIT_OFF ((uint32_t)0x00000000U) /*!< generate Error-bit on bit rising error */ +#define CEC_RISING_PERIOD_ERROR_BIT_ON CEC_CFG_BREG /*!< do not generate Error-bit on bit rising error */ + +/* whether stop receive message when detected bit rising error */ +#define CEC_STOP_RISING_ERROR_BIT_ON ((uint32_t)0x00000000U) /*!< stop reception when detected bit rising error */ +#define CEC_STOP_RISING_ERROR_BIT_OFF ((uint32_t)0x00000001U) /*!< do not stop reception when detected bit rising error */ + +/* flag bits */ +#define CEC_FLAG_BR CEC_INTF_BR /*!< RX-byte data received */ +#define CEC_FLAG_REND CEC_INTF_REND /*!< end of reception */ +#define CEC_FLAG_RO CEC_INTF_RO /*!< RX overrun */ +#define CEC_FLAG_BRE CEC_INTF_BRE /*!< bit rising error */ +#define CEC_FLAG_BPSE CEC_INTF_BPSE /*!< short bit period error */ +#define CEC_FLAG_BPLE CEC_INTF_BPLE /*!< long bit period error */ +#define CEC_FLAG_RAE CEC_INTF_RAE /*!< RX ACK error */ +#define CEC_FLAG_ARBF CEC_INTF_ARBF /*!< arbitration lost */ +#define CEC_FLAG_TBR CEC_INTF_TBR /*!< TX-byte data request */ +#define CEC_FLAG_TEND CEC_INTF_TEND /*!< transmission successfully end */ +#define CEC_FLAG_TU CEC_INTF_TU /*!< TX data buffer underrun */ +#define CEC_FLAG_TERR CEC_INTF_TERR /*!< TX-error */ +#define CEC_FLAG_TAERR CEC_INTF_TAERR /*!< TX ACK error flag */ + +/* interrupt flag bits */ +#define CEC_INT_FLAG_BR CEC_INTF_BR /*!< RX-byte data received */ +#define CEC_INT_FLAG_REND CEC_INTF_REND /*!< end of reception */ +#define CEC_INT_FLAG_RO CEC_INTF_RO /*!< RX overrun */ +#define CEC_INT_FLAG_BRE CEC_INTF_BRE /*!< bit rising error */ +#define CEC_INT_FLAG_BPSE CEC_INTF_BPSE /*!< short bit period error */ +#define CEC_INT_FLAG_BPLE CEC_INTF_BPLE /*!< long bit period error */ +#define CEC_INT_FLAG_RAE CEC_INTF_RAE /*!< RX ACK error */ +#define CEC_INT_FLAG_ARBF CEC_INTF_ARBF /*!< arbitration lost */ +#define CEC_INT_FLAG_TBR CEC_INTF_TBR /*!< TX-byte data request */ +#define CEC_INT_FLAG_TEND CEC_INTF_TEND /*!< transmission successfully end */ +#define CEC_INT_FLAG_TU CEC_INTF_TU /*!< TX data buffer underrun */ +#define CEC_INT_FLAG_TERR CEC_INTF_TERR /*!< TX-error */ +#define CEC_INT_FLAG_TAERR CEC_INTF_TAERR /*!< TX ACK error flag */ + +/* interrupt enable bits */ +#define CEC_INT_BR CEC_INTEN_BRIE /*!< BR interrupt enable */ +#define CEC_INT_REND CEC_INTEN_RENDIE /*!< REND interrupt enable */ +#define CEC_INT_RO CEC_INTEN_ROIE /*!< RO interrupt enable */ +#define CEC_INT_BRE CEC_INTEN_BREIE /*!< BRE interrupt enable. */ +#define CEC_INT_BPSE CEC_INTEN_BPSEIE /*!< BPSE interrupt enable */ +#define CEC_INT_BPLE CEC_INTEN_BPLEIE /*!< BPLE interrupt enable. */ +#define CEC_INT_RAE CEC_INTEN_RAEIE /*!< RAE interrupt enable */ +#define CEC_INT_ARBF CEC_INTEN_ARBFIE /*!< ALRLST interrupt enable */ +#define CEC_INT_TBR CEC_INTEN_TBRIE /*!< TBR interrupt enable */ +#define CEC_INT_TEND CEC_INTEN_TENDIE /*!< TEND interrupt enable */ +#define CEC_INT_TU CEC_INTEN_TUIE /*!< TU interrupt enable */ +#define CEC_INT_TERR CEC_INTEN_TERRIE /*!< TE interrupt enable */ +#define CEC_INT_TAERR CEC_INTEN_TAERRIE /*!< TAE interrupt enable */ + +/* function declarations */ +/* reset HDMI-CEC controller */ +void cec_deinit(void); +/* configure signal free time,the signal free time counter start option,own address */ +void cec_init(uint32_t sftmopt, uint32_t sft, uint32_t address); +/* configure generate Error-bit, whether stop receive message when detected bit rising error */ +void cec_error_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre, uint32_t rxbrestp); +/* enable HDMI-CEC controller */ +void cec_enable(void); +/* disable HDMI-CEC controller */ +void cec_disable(void); + +/* start CEC message transmission */ +void cec_transmission_start(void); +/* end CEC message transmission */ +void cec_transmission_end(void); +/* enable CEC listen mode */ +void cec_listen_mode_enable(void); +/* disable CEC listen mode */ +void cec_listen_mode_disable(void); +/* configure and clear own address */ +void cec_own_address_config(uint32_t address); +/* configure signal free time and the signal free time counter start option */ +void cec_sft_config(uint32_t sftmopt,uint32_t sft); +/* configure generate Error-bit when detected some abnormal situation or not */ +void cec_generate_errorbit_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre); +/* whether stop receive message when detected bit rising error */ +void cec_stop_receive_bre_config(uint32_t rxbrestp); +/* enable reception bit timing tolerance */ +void cec_reception_tolerance_enable(void); +/* disable reception bit timing tolerance */ +void cec_reception_tolerance_disable(void); +/* send a data by the CEC peripheral */ +void cec_data_send(uint8_t data); +/* receive a data by the CEC peripheral */ +uint8_t cec_data_receive(void); + +/* clear CEC int flag and status */ +FlagStatus cec_interrupt_flag_get(uint32_t flag); +/* clear CEC flag */ +void cec_interrupt_flag_clear(uint32_t flag); +/* enable interrupt */ +void cec_interrupt_enable(uint32_t flag); +/* disable interrupt */ +void cec_interrupt_disable(uint32_t flag); +/* get CEC status */ +FlagStatus cec_flag_get(uint32_t flag); +/* clear CEC status */ +void cec_flag_clear(uint32_t flag); + +#endif /* GD32F1X0_CEC_H */ + diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_cmp.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_cmp.h new file mode 100644 index 0000000..6d88bee --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_cmp.h @@ -0,0 +1,212 @@ +/*! + \file gd32f1x0_cmp.h + \brief definitions for the CMP +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5,9) +*/ + +#ifndef GD32F1X0_CMP_H +#define GD32F1X0_CMP_H + +#include "gd32f1x0.h" + +/* CMP definitions */ +#define CMP CMP_BASE /*!< CMP base address */ + +/* registers definitions */ +#define CMP_CS REG32((CMP) + 0x00U) /*!< CMP control and status register */ + +/* CMP_CS bits definitions */ +#define CMP_CS_CMP0EN BIT(0) /*!< CMP0 enable */ +#define CMP_CS_CMP0SW BIT(1) /*!< CMP0 switch */ +#define CMP_CS_CMP0M BITS(2,3) /*!< CMP0 mode */ +#define CMP_CS_CMP0MSEL BITS(4,6) /*!< COMP0_M input selection */ +#define CMP_CS_CMP0OSEL BITS(8,10) /*!< CMP0 output selection */ +#define CMP_CS_CMP0PL BIT(11) /*!< polarity of CMP0 output */ +#define CMP_CS_CMP0HST BITS(12,13) /*!< CMP0 hysteresis */ +#define CMP_CS_CMP0O BIT(14) /*!< CMP0 output */ +#define CMP_CS_CMP0LK BIT(15) /*!< CMP0 lock */ +#define CMP_CS_CMP1EN BIT(16) /*!< CMP1 enable */ +#define CMP_CS_CMP1M BITS(18,19) /*!< CMP1 mode */ +#define CMP_CS_CMP1MSEL BITS(20,22) /*!< CMP1_M input selection */ +#define CMP_CS_WNDEN BIT(23) /*!< window mode enable */ +#define CMP_CS_CMP1OSEL BITS(24,26) /*!< CMP1 output selection */ +#define CMP_CS_CMP1PL BIT(27) /*!< polarity of CMP1 output */ +#define CMP_CS_CMP1HST BITS(28,29) /*!< CMP1 hysteresis */ +#define CMP_CS_CMP1O BIT(30) /*!< CMP1 output */ +#define CMP_CS_CMP1LK BIT(31) /*!< CMP1 lock */ + +/* consts definitions */ +/* operating mode */ +typedef enum{ + CMP_HIGHSPEED = 0, /*!< high speed mode */ + CMP_MIDDLESPEED, /*!< medium speed mode */ + CMP_LOWSPEED, /*!< low speed mode */ + CMP_VERYLOWSPEED /*!< very-low speed mode */ +}operating_mode_enum; + +/* inverting input */ +typedef enum{ + CMP_1_4VREFINT = 0, /*!< VREFINT /4 input */ + CMP_1_2VREFINT, /*!< VREFINT /2 input */ + CMP_3_4VREFINT, /*!< VREFINT *3/4 input */ + CMP_VREFINT, /*!< VREFINT input */ + CMP_DAC0, /*!< PA4 (DAC0) input */ +#ifdef GD32F170_190 + CMP_DAC1, /*!< DAC1 input */ +#else + CMP_PA5, /*!< PA5 input */ +#endif + CMP_PA_0_2 /*!< PA0 input when CMP0 is selected, PA2 input when CMP1 is selected */ +}inverting_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_TIMER0BKIN, /*!< TIMER 0 break input */ + CMP_OUTPUT_TIMER0IC0, /*!< TIMER 0 channel0 input capture */ + CMP_OUTPUT_TIMER0OCPRECLR, /*!< TIMER 0 OCPRE_CLR input */ + CMP_OUTPUT_TIMER1IC3, /*!< TIMER 1 channel3 input capture */ + CMP_OUTPUT_TIMER1OCPRECLR, /*!< TIMER 1 OCPRE_CLR input */ + CMP_OUTPUT_TIMER2IC0, /*!< TIMER 2 channel0 input capture */ + CMP_OUTPUT_TIMER2OCPRECLR /*!< TIMER 2 OCPRE_CLR input */ +}cmp_output_enum; + +/* CMP0 mode */ +#define CS_CMP0M(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define CS_CMP0M_HIGHSPEED CS_CMP0M(0) /*!< CMP0 mode high speed */ +#define CS_CMP0M_MIDDLESPEED CS_CMP0M(1) /*!< CMP0 mode middle speed */ +#define CS_CMP0M_LOWSPEED CS_CMP0M(2) /*!< CMP0 mode low speed */ +#define CS_CMP0M_VERYLOWSPEED CS_CMP0M(3) /*!< CMP0 mode very low speed */ + +/* comparator 0 inverting input */ +#define CS_CMP0MSEL(regval) (BITS(4,6) & ((uint32_t)(regval) << 4)) + +#define CS_CMP0MSEL_1_4VREFINT CS_CMP0MSEL(0) /*!< CMP0 inverting input 1/4 Vrefint */ +#define CS_CMP0MSEL_1_2VREFINT CS_CMP0MSEL(1) /*!< CMP0 inverting input 1/2 Vrefint */ +#define CS_CMP0MSEL_3_4VREFINT CS_CMP0MSEL(2) /*!< CMP0 inverting input 3/4 Vrefint */ +#define CS_CMP0MSEL_VREFINT CS_CMP0MSEL(3) /*!< CMP0 inverting input Vrefint */ +#define CS_CMP0MSEL_DAC0 CS_CMP0MSEL(4) /*!< CMP0 inverting input DAC0*/ +#define CS_CMP0MSEL_PA5 CS_CMP0MSEL(5) /*!< CMP0 inverting input PA5*/ +#define CS_CMP0MSEL_PA0 CS_CMP0MSEL(6) /*!< CMP0 inverting input PA0*/ + +/* CMP0 output */ +#define CS_CMP0OSEL(regval) (BITS(8,10) & ((uint32_t)(regval) << 8)) + +#define CS_CMP0OSEL_OUTPUT_NONE CS_CMP0OSEL(0) /*!< CMP0 output none */ +#define CS_CMP0OSEL_OUTPUT_TIMER0BKIN CS_CMP0OSEL(1) /*!< CMP0 output TIMER 0 break input */ +#define CS_CMP0OSEL_OUTPUT_TIMER0IC0 CS_CMP0OSEL(2) /*!< CMP0 output TIMER 0 channel 0 input capture */ +#define CS_CMP0OSEL_OUTPUT_TIMER0OCPRECLR CS_CMP0OSEL(3) /*!< CMP0 output TIMER 0 ocpreclear input */ +#define CS_CMP0OSEL_OUTPUT_TIMER1IC3 CS_CMP0OSEL(4) /*!< CMP0 output TIMER 1 channel 3 input capture */ +#define CS_CMP0OSEL_OUTPUT_TIMER1OCPRECLR CS_CMP0OSEL(5) /*!< CMP0 output TIMER 1 ocpreclear input */ +#define CS_CMP0OSEL_OUTPUT_TIMER2IC0 CS_CMP0OSEL(6) /*!< CMP0 output TIMER 2 channle 0 input capture */ +#define CS_CMP0OSEL_OUTPUT_TIMER2OCPRECLR CS_CMP0OSEL(7) /*!< CMP0 output TIMER 2 ocpreclear input */ + +/* CMP0 hysteresis */ +#define CS_CMP0HST(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define CS_CMP0HST_HYSTERESIS_NO CS_CMP0HST(0) /*!< CMP0 output no hysteresis */ +#define CS_CMP0HST_HYSTERESIS_LOW CS_CMP0HST(1) /*!< CMP0 output low hysteresis */ +#define CS_CMP0HST_HYSTERESIS_MIDDLE CS_CMP0HST(2) /*!< CMP0 output middle hysteresis */ +#define CS_CMP0HST_HYSTERESIS_HIGH CS_CMP0HST(3) /*!< CMP0 output high hysteresis */ + +/* CMP1 mode */ +#define CS_CMP1M(regval) (BITS(18,19) & ((uint32_t)(regval) << 18)) +#define CS_CMP1M_HIGHSPEED CS_CMP1M(0) /*!< CMP1 mode high speed */ +#define CS_CMP1M_MIDDLESPEED CS_CMP1M(1) /*!< CMP1 mode middle speed */ +#define CS_CMP1M_LOWSPEED CS_CMP1M(2) /*!< CMP1 mode low speed */ +#define CS_CMP1M_VERYLOWSPEED CS_CMP1M(3) /*!< CMP1 mode very low speed */ + +/* CMP1 inverting input */ +#define CS_CMP1MSEL(regval) (BITS(20,22) & ((uint32_t)(regval) << 20)) + +#define CS_CMP1MSEL_1_4VREFINT CS_CMP1MSEL(0) /*!< CMP1 inverting input 1/4 Vrefint */ +#define CS_CMP1MSEL_1_2VREFINT CS_CMP1MSEL(1) /*!< CMP1 inverting input 1/2 Vrefint */ +#define CS_CMP1MSEL_3_4VREFINT CS_CMP1MSEL(2) /*!< CMP1 inverting input 3/4 Vrefint */ +#define CS_CMP1MSEL_VREFINT CS_CMP1MSEL(3) /*!< CMP1 inverting input Vrefint */ +#define CS_CMP1MSEL_DAC0 CS_CMP1MSEL(4) /*!< CMP1 inverting input DAC0*/ +#ifdef GD32F170_190 +#define CS_CMP1MSEL_PA5 CS_CMP1MSEL(5) /*!< CMP1 inverting input PA5*/ +#else +#define CS_CMP1MSEL_DAC1 CS_CMP1MSEL(5) /*!< CMP1 inverting input DAC1*/ +#endif +#define CS_CMP1MSEL_PA2 CS_CMP1MSEL(6) /*!< CMP1 inverting input PA2*/ + +/* comparator channel1 output */ +#define CS_CMP1OSEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) + +#define CS_CMP1OSEL_OUTPUT_NONE CS_CMP1OSEL(0) /*!< CMP1 output none */ +#define CS_CMP1OSEL_OUTPUT_TIMER0BKIN CS_CMP1OSEL(1) /*!< CMP1 output TIMER 0 break input */ +#define CS_CMP1OSEL_OUTPUT_TIMER0IC0 CS_CMP1OSEL(2) /*!< CMP1 output TIMER 0 channel 0 input capture */ +#define CS_CMP1OSEL_OUTPUT_TIMER0OCPRECLR CS_CMP1OSEL(3) /*!< CMP1 output TIMER 0 ocpreclear input */ +#define CS_CMP1OSEL_OUTPUT_TIMER1IC3 CS_CMP1OSEL(4) /*!< CMP1 output TIMER 1 channel 3 input capture */ +#define CS_CMP1OSEL_OUTPUT_TIMER1OCPRECLR CS_CMP1OSEL(5) /*!< CMP1 output TIMER 1 ocpreclear input */ +#define CS_CMP1OSEL_OUTPUT_TIMER2IC0 CS_CMP1OSEL(6) /*!< CMP1 output TIMER 2 channle 0 input capture */ +#define CS_CMP1OSEL_OUTPUT_TIMER2OCPRECLR CS_CMP1OSEL(7) /*!< CMP1 output TIMER 2 ocpreclear input */ + +/* CMP1 hysteresis */ +#define CS_CMP1HST(regval) (BITS(28,29) & ((uint32_t)(regval) << 28)) +#define CS_CMP1HST_HSTHYSTERESIS_NO CS_CMP1HST(0) /*!< CMP1 output no hysteresis */ +#define CS_CMP1HST_HYSTERESIS_LOW CS_CMP1HST(1) /*!< CMP1 output low hysteresis */ +#define CS_CMP1HST_HYSTERESIS_MIDDLE CS_CMP1HST(2) /*!< CMP1 output middle hysteresis */ +#define CS_CMP1HST_HYSTERESIS_HIGH CS_CMP1HST(3) /*!< CMP1 output high hysteresis */ + +/* comparator x definitions */ +#define CMP0 ((uint32_t)0x00000000) /*!< comparator 0 */ +#define CMP1 ((uint32_t)0x00000010) /*!< comparator 1 */ + +/* comparator output level */ +#define CMP_OUTPUTLEVEL_HIGH ((uint32_t)0x00000001) /*!< comparator output high */ +#define CMP_OUTPUTLEVEL_LOW ((uint32_t)0x00000000) /*!< comparator output low */ + +/* output polarity of comparator */ +#define CMP_OUTPUT_POLARITY_INVERTED ((uint32_t)0x00000001) /*!< output is inverted */ +#define CMP_OUTPUT_POLARITY_NOINVERTED ((uint32_t)0x00000000) /*!< output is not inverted */ + +/* function declarations */ + +/* initialization functions */ +/* CMP deinit */ +void cmp_deinit(void); +/* CMP mode init */ +void cmp_mode_init(uint32_t cmp_periph, operating_mode_enum cmp_operating_mode, inverting_input_enum cmp_inverting_input, cmp_hysteresis_enum output_hysteresis); +/* CMP output init */ +void cmp_output_init(uint32_t cmp_periph, cmp_output_enum cmp_output_slection, uint32_t cmp_output_polarity); + +/* enable functions */ +/* enable CMP */ +void cmp_enable(uint32_t cmp_periph); +/* disable CMP */ +void cmp_disable(uint32_t cmp_periph); +/* enable CMP switch */ +void cmp_switch_enable(void); +/* disable CMP switch */ +void cmp_switch_disable(void); +/* enable the window mode */ +void cmp_window_enable(void); +/* disable the window mode */ +void cmp_window_disable(void); +/* lock the CMP */ +void cmp_lock_enable(uint32_t cmp_periph); +/* unlock the CMP */ +void cmp_lock_disable(uint32_t cmp_periph); + +/* output functions */ +/* get output level */ +uint32_t cmp_output_level_get(uint32_t cmp_periph); + +#endif /* GD32F1X0_CMP_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_crc.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_crc.h new file mode 100644 index 0000000..425c17f --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_crc.h @@ -0,0 +1,84 @@ +/*! + \file gd32f1x0_crc.h + \brief definitions for the CRC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_CRC_H +#define GD32F1X0_CRC_H + +#include "gd32f1x0.h" + +/* CRC definitions */ +#define CRC CRC_BASE + +/* registers definitions */ +#define CRC_DATA REG32(CRC + 0x00U) /*!< CRC data register */ +#define CRC_FDATA REG32(CRC + 0x04U) /*!< CRC free data register */ +#define CRC_CTL REG32(CRC + 0x08U) /*!< CRC control register */ +#define CRC_IDATA REG32(CRC + 0x10U) /*!< CRC initialization data register */ + +/* bits definitions */ + +/* CRC_DATA */ +#define CRC_DATA_DATA BITS(0,31) /*!< CRC calculation result bits */ + +/* CRC_FDATA */ +#define CRC_FDATA_FDATA BITS(0,7) /*!< CRC free data bits */ + +/* CRC_CTL */ +#define CRC_CTL_RST BIT(0) /*!< CRC reset bit */ +#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_IDATA */ +#define CRC_IDATA_IDATA BITS(0,31) /*!< CRC initialization data bits */ + +/* constants definitions */ + +/* 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 */ + +/* 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 initializaiton 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 initializaiton data 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); + +/* CRC calculate a 32-bit data */ +uint32_t crc_single_data_calculate(uint32_t sdata); +/* CRC calculate a 32-bit data array */ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size); + +#endif /* GD32F1X0_CRC_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_dac.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_dac.h new file mode 100644 index 0000000..d8cd18c --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_dac.h @@ -0,0 +1,243 @@ +/*! + \file gd32f1x0_dac.h + \brief definitions for the DAC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + +#ifndef GD32F1X0_DAC_H +#define GD32F1X0_DAC_H + +#include "gd32f1x0.h" + +/* DACx(x=0,1) definitions */ +#define DAC DAC_BASE +#define DAC0 0U +#ifdef GD32F170_190 +#define DAC1 1U +#endif /* GD32F170_190 */ + +/* registers definitions */ +#define DAC_CTL REG32(DAC + 0x00U) /*!< DAC control register */ +#define DAC_SWT REG32(DAC + 0x04U) /*!< DAC software trigger register */ +#define DAC0_R12DH REG32(DAC + 0x08U) /*!< DAC0 12-bit right-aligned data holding register */ +#define DAC0_L12DH REG32(DAC + 0x0CU) /*!< DAC0 12-bit left-aligned data holding register */ +#define DAC0_R8DH REG32(DAC + 0x10U) /*!< DAC0 8-bit right-aligned data holding register */ +#ifdef GD32F170_190 +#define DAC1_R12DH REG32(DAC + 0x14U) /*!< DAC1 12-bit right-aligned data holding register */ +#define DAC1_L12DH REG32(DAC + 0x18U) /*!< DAC1 12-bit left-aligned data holding register */ +#define DAC1_R8DH REG32(DAC + 0x1CU) /*!< DAC1 8-bit right-aligned data holding register */ +#define DACC_R12DH REG32(DAC + 0x20U) /*!< DAC concurrent mode 12-bit right-aligned data holding register */ +#define DACC_L12DH REG32(DAC + 0x24U) /*!< DAC concurrent mode 12-bit left-aligned data holding register */ +#define DACC_R8DH REG32(DAC + 0x28U) /*!< DAC concurrent mode 8-bit right-aligned data holding register */ +#endif /* GD32F170_190 */ +#define DAC0_DO REG32(DAC + 0x2CU) /*!< DAC0 output data register */ +#ifdef GD32F170_190 +#define DAC1_DO REG32(DAC + 0x30U) /*!< DAC1 output data register */ +#endif /* GD32F170_190 */ +#define DAC_STAT REG32(DAC + 0x34U) /*!< DAC status register */ + +/* bits definitions */ +/* DAC_CTL */ +#define DAC_CTL_DEN0 BIT(0) /*!< DAC0 enable/disable bit */ +#define DAC_CTL_DBOFF0 BIT(1) /*!< DAC0 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN0 BIT(2) /*!< DAC0 trigger enable/disable bit */ +#define DAC_CTL_DTSEL0 BITS(3,5) /*!< DAC0 trigger source selection enable/disable bits */ +#define DAC_CTL_DDMAEN0 BIT(12) /*!< DAC0 DMA enable/disanle bit */ +#define DAC_CTL_DDUDRIE0 BIT(13) /*!< DAC0 DMA underrun Interrupt enable/disable bit */ +#ifdef GD32F170_190 +#define DAC_CTL_DEN1 BIT(16) /*!< DAC1 enable/disable bit */ +#define DAC_CTL_DBOFF1 BIT(17) /*!< DAC1 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN1 BIT(18) /*!< DAC1 trigger enable/disable bit */ +#define DAC_CTL_DTSEL1 BITS(19,21) /*!< DAC1 trigger source selection enable/disable bits */ +#define DAC_CTL_DDMAEN1 BIT(28) /*!< DAC1 DMA enable/disable bit */ +#define DAC_CTL_DDUDRIE1 BIT(29) /*!< DAC1 DMA underrun interrupt enable/disable bit */ +#endif /* GD32F170_190 */ + +/* DAC_SWT */ +#define DAC_SWT_SWTR0 BIT(0) /*!< DAC0 software trigger bit,cleared by hardware */ +#ifdef GD32F170_190 +#define DAC_SWT_SWTR1 BIT(1) /*!< DAC1 software trigger bit,cleared by hardware */ +#endif /* GD32F170_190 */ + +/* DAC0_R12DH */ +#define DAC0_R12DH_DAC0_DH BITS(0,11) /*!< DAC0 12-bit right-aligned data bits */ + +/* DAC0_L12DH */ +#define DAC0_L12DH_DAC0_DH BITS(4,15) /*!< DAC0 12-bit left-aligned data bits */ + +/* DAC0_R8DH */ +#define DAC0_R8DH_DAC0_DH BITS(0,7) /*!< DAC0 8-bit right-aligned data bits */ + +#ifdef GD32F170_190 +/* DAC1_R12DH */ +#define DAC1_R12DH_DAC1_DH BITS(0,11) /*!< DAC1 12-bit right-aligned data bits */ + +/* DAC1_L12DH */ +#define DAC1_L12DH_DAC1_DH BITS(4,15) /*!< DAC1 12-bit left-aligned data bits */ + +/* DAC1_R8DH */ +#define DAC1_R8DH_DAC1_DH BITS(0,7) /*!< DAC1 8-bit right-aligned data bits */ + +/* DACC_R12DH */ +#define DACC_R12DH_DAC0_DH BITS(0,11) /*!< DAC concurrent mode DAC0 12-bit right-aligned data bits */ +#define DACC_R12DH_DAC1_DH BITS(16,27) /*!< DAC concurrent mode DAC1 12-bit right-aligned data bits */ + +/* DACC_L12DH */ +#define DACC_L12DH_DAC0_DH BITS(4,15) /*!< DAC concurrent mode DAC0 12-bit left-aligned data bits */ +#define DACC_L12DH_DAC1_DH BITS(20,31) /*!< DAC concurrent mode DAC1 12-bit left-aligned data bits */ + +/* DACC_R8DH */ +#define DACC_R8DH_DAC0_DH BITS(0,7) /*!< DAC concurrent mode DAC0 8-bit right-aligned data bits */ +#define DACC_R8DH_DAC1_DH BITS(8,15) /*!< DAC concurrent mode DAC1 8-bit right-aligned data bits */ +#endif /* GD32F170_190 */ + +/* DAC0_DO */ +#define DAC0_DO_DAC0_DO BITS(0,11) /*!< DAC0 12-bit output data bits */ + +#ifdef GD32F170_190 +/* DAC1_DO */ +#define DAC1_DO_DAC1_DO BITS(0,11) /*!< DAC1 12-bit output data bits */ +#endif /* GD32F170_190 */ + +/* DAC_STAT */ +#define DAC_STAT_DDUDR0 BIT(13) /*!< DAC0 DMA underrun flag */ +#ifdef GD32F170_190 +#define DAC_STAT_DDUDR1 BIT(29) /*!< DAC1 DMA underrun flag */ +#endif /* GD32F170_190 */ + +/* constants definitions */ +/* DAC trigger source */ +#define CTL_DTSEL(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) +#define DAC_TRIGGER_T5_TRGO CTL_DTSEL(0) /*!< TIMER5 TRGO */ +#define DAC_TRIGGER_T2_TRGO CTL_DTSEL(1) /*!< TIMER2 TRGO */ +#define DAC_TRIGGER_T14_TRGO CTL_DTSEL(3) /*!< TIMER14 TRGO */ +#define DAC_TRIGGER_T1_TRGO CTL_DTSEL(4) /*!< TIMER1 TRGO */ +#define DAC_TRIGGER_EXTI_9 CTL_DTSEL(6) /*!< EXTI interrupt line9 event */ +#define DAC_TRIGGER_SOFTWARE CTL_DTSEL(7) /*!< software trigger */ + +/* dac data alignment */ +#define DATA_ALIGN(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define DAC_ALIGN_12B_R DATA_ALIGN(0) /*!< data right 12b alignment */ +#define DAC_ALIGN_12B_L DATA_ALIGN(1) /*!< data left 12b alignment */ +#define DAC_ALIGN_8B_R DATA_ALIGN(2) /*!< data right 8b alignment */ + +/* function declarations */ +/* deinit DAC */ +void dac_deinit(void); + +/* enable DAC0 function */ +void dac0_enable(void); +/* disable DAC0 function */ +void dac0_disable(void); +/* enable DAC0 DMA function */ +void dac0_dma_enable(void); +/* disable DAC0 DMA function */ +void dac0_dma_disable(void); +/* enable DAC0 output buffer function */ +void dac0_output_buffer_enable(void); +/* disable DAC0 output buffer function */ +void dac0_output_buffer_disable(void); +/* enable DAC0 trigger function */ +void dac0_trigger_enable(void); +/* disable DAC0 trigger function */ +void dac0_trigger_disable(void); +/* enable DAC0 software trigger function */ +void dac0_software_trigger_enable(void); +/* disable DAC0 software trigger function */ +void dac0_software_trigger_disable(void); +/* enable DAC0 interrupt(DAC0 DMA underrun interrupt) */ +void dac0_interrupt_enable(void); +/* disable DAC0 interrupt(DAC0 DMA underrun interrupt) */ +void dac0_interrupt_disable(void); + +/* set DAC0 tgigger source function */ +void dac0_trigger_source_config(uint32_t triggersource); +/* get the last data output value */ +uint16_t dac0_output_value_get(void); + +/* get the specified DAC0 flag(DAC0 DMA underrun flag) */ +FlagStatus dac0_flag_get(void); +/* clear the specified DAC0 flag(DAC0 DMA underrun flag) */ +void dac0_flag_clear(void); +/* get the specified DAC0 interrupt flag(DAC0 DMA underrun interrupt flag) */ +FlagStatus dac0_interrupt_flag_get(void); +/* clear the specified DAC0 interrupt flag(DAC0 DMA underrun interrupt flag) */ +void dac0_interrupt_flag_clear(void); + +/* set DAC0 data holding register value */ +void dac0_data_set(uint32_t dac_align, uint16_t data); + +#ifdef GD32F170_190 +/* enable DAC */ +void dac_enable(uint32_t dac_periph); +/* disable DAC */ +void dac_disable(uint32_t dac_periph); +/* enable DAC DMA */ +void dac_dma_enable(uint32_t dac_periph); +/* disable DAC DMA */ +void dac_dma_disable(uint32_t dac_periph); +/* enable DAC output buffer */ +void dac_output_buffer_enable(uint32_t dac_periph); +/* disable DAC output buffer */ +void dac_output_buffer_disable(uint32_t dac_periph); +/* enable DAC trigger */ +void dac_trigger_enable(uint32_t dac_periph); +/* disable DAC trigger */ +void dac_trigger_disable(uint32_t dac_periph); +/* enable DAC software trigger */ +void dac_software_trigger_enable(uint32_t dac_periph); +/* disable DAC software trigger */ +void dac_software_trigger_disable(uint32_t dac_periph); +/* enable DAC interrupt(DAC0 DMA underrun interrupt) */ +void dac_interrupt_enable(uint32_t dac_periph); +/* disable DAC interrupt(DAC0 DMA underrun interrupt) */ +void dac_interrupt_disable(uint32_t dac_periph); + +/* set DAC tgigger source */ +void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource); +/* get the last data output value */ +uint16_t dac_output_value_get(uint32_t dac_periph); + +/* get the specified DAC flag(DAC DMA underrun flag) */ +FlagStatus dac_flag_get(uint32_t dac_periph); +/* clear the specified DAC flag(DAC DMA underrun flag) */ +void dac_flag_clear(uint32_t dac_periph); +/* get the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */ +FlagStatus dac_interrupt_flag_get(uint32_t dac_periph); +/* clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */ +void dac_interrupt_flag_clear(uint32_t dac_periph); + +/* enable DAC concurrent mode */ +void dac_concurrent_enable(void); +/* disable DAC concurrent mode */ +void dac_concurrent_disable(void); +/* enable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_enable(void); +/* disable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_disable(void); +/* enable DAC concurrent buffer */ +void dac_concurrent_output_buffer_enable(void); +/* disable DAC concurrent buffer */ +void dac_concurrent_output_buffer_disable(void); +/* enable DAC concurrent interrupt */ +void dac_concurrent_interrupt_enable(void); +/* disable DAC concurrent interrupt */ +void dac_concurrent_interrupt_disable(void); + +/* set DAC data holding register value */ +void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data); +/* set DAC concurrent mode data holding register value */ +void dac_concurrent_data_set(uint32_t dac_align, uint16_t data1, uint16_t data2); + +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_DAC_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_dbg.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_dbg.h new file mode 100644 index 0000000..48cf175 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_dbg.h @@ -0,0 +1,116 @@ +/*! + \file gd32f1x0_dbg.h + \brief definitions for the DBG +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_DBG_H +#define GD32F1X0_DBG_H + +#include "gd32f1x0.h" + +/* DBG definitions */ +#define DBG DBG_BASE + +/* registers definitions */ +#define DBG_ID REG32(DBG + 0x00U) /*!< DBG_ID code register */ +#define DBG_CTL0 REG32(DBG + 0x04U) /*!< DBG control register 0 */ +#define DBG_CTL1 REG32(DBG + 0x08U) /*!< DBG control register 1 */ + +/* bits definitions */ +/* DBG_ID */ +#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG ID code values */ + +/* DBG_CTL0 */ +#define DBG_CTL0_SLP_HOLD BIT(0) /*!< keep debugger connection during sleep mode */ +#define DBG_CTL0_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */ +#define DBG_CTL0_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */ +#define DBG_CTL0_FWDGT_HOLD BIT(8) /*!< debug FWDGT kept when core is halted */ +#define DBG_CTL0_WWDGT_HOLD BIT(9) /*!< debug WWDGT kept when core is halted */ +#define DBG_CTL0_TIMER0_HOLD BIT(10) /*!< TIMER0 counter kept when core is halted */ +#define DBG_CTL0_TIMER1_HOLD BIT(11) /*!< TIMER1 counter kept when core is halted */ +#define DBG_CTL0_TIMER2_HOLD BIT(12) /*!< TIMER2 counter kept when core is halted */ +#define DBG_CTL0_I2C0_HOLD BIT(15) /*!< hold I2C0 smbus when core is halted */ +#define DBG_CTL0_I2C1_HOLD BIT(16) /*!< hold I2C1 smbus when core is halted */ +#define DBG_CTL0_I2C2_HOLD BIT(17) /*!< hold I2C2 smbus when core is halted */ +#ifdef GD32F170_190 +#define DBG_CTL0_CAN0_HOLD BIT(18) /*!< CAN0 counter kept when core is halted */ +#endif /* GD32F170_190 */ +#define DBG_CTL0_TIMER5_HOLD BIT(19) /*!< hold TIMER5 counter when core is halted */ +#ifdef GD32F170_190 +#define DBG_CTL0_CAN1_HOLD BIT(21) /*!< hold CAN1 counter when core is halted */ +#endif /* GD32F170_190 */ +#define DBG_CTL0_TIMER13_HOLD BIT(27) /*!< hold TIMER13 counter when core is halted */ + +/* DBG_CTL1 */ +#define DBG_CTL1_RTC_HOLD BIT(10) /*!< hold RTC calendar and wakeup counter when core is halted */ +#define DBG_CTL1_TIMER14_HOLD BIT(16) /*!< hold TIMER14 counter when core is halted */ +#define DBG_CTL1_TIMER15_HOLD BIT(17) /*!< hold TIMER15 counter when core is halted */ +#define DBG_CTL1_TIMER16_HOLD BIT(18) /*!< hold TIMER16 counter when core is halted */ + +/* constants definitions */ +#define DBG_LOW_POWER_SLEEP DBG_CTL0_SLP_HOLD /*!< keep debugger connection during sleep mode */ +#define DBG_LOW_POWER_DEEPSLEEP DBG_CTL0_DSLP_HOLD /*!< keep debugger connection during deepsleep mode */ +#define DBG_LOW_POWER_STANDBY DBG_CTL0_STB_HOLD /*!< keep debugger connection during standby mode */ + +/* define the peripheral debug hold bit position and its register index offset */ +#define DBG_REGIDX_BIT(regidx, bitpos) (((regidx) << 6) | (bitpos)) +#define DBG_REG_VAL(periph) (REG32(DBG + ((uint32_t)(periph) >> 6))) +#define DBG_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +/* register index */ +enum dbg_reg_idx +{ + DBG_IDX_CTL0 = 0x04U, + DBG_IDX_CTL1 = 0x08U, +}; + +/* peripherals hold bit */ +typedef enum +{ + DBG_FWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 8U), /*!< FWDGT hold bit */ + DBG_WWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 9U), /*!< WWDGT hold bit */ + DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 10U), /*!< TIMER0 hold bit */ + DBG_TIMER1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 11U), /*!< TIMER1 hold bit */ + DBG_TIMER2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 12U), /*!< TIMER2 hold bit */ +#ifdef GD32F170_190 + DBG_CAN0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 14U), /*!< CAN0 hold bit */ +#endif /* GD32F170_190 */ + DBG_I2C0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 15U), /*!< I2C0 hold bit */ + DBG_I2C1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 16U), /*!< I2C1 hold bit */ + DBG_I2C2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 17U), /*!< I2C2 hold bit */ + DBG_TIMER5_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 19U), /*!< TIMER5 hold bit */ +#ifdef GD32F170_190 + DBG_CAN1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 21U), /*!< CAN1 hold bit */ +#endif /* GD32F170_190 */ + DBG_TIMER13_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 27U), /*!< TIMER13 hold bit */ + DBG_RTC_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 10U), /*!< RTC hold bit */ + DBG_TIMER14_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 16U), /*!< TIMER14 hold bit */ + DBG_TIMER15_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 17U), /*!< TIMER15 hold bit */ + DBG_TIMER16_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 18U), /*!< TIMER16 hold bit */ +}dbg_periph_enum; + +/* function declarations */ +/* deinitialize the DBG */ +void dbg_deinit(void); +/* read DBG_ID code register */ +uint32_t dbg_id_get(void); + +/* enable low power behavior when the MCU is in debug mode */ +void dbg_low_power_enable(uint32_t dbg_low_power); +/* disable low power behavior when the MCU is in debug mode */ +void dbg_low_power_disable(uint32_t dbg_low_power); + +/* enable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_enable(dbg_periph_enum dbg_periph); +/* disable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_disable(dbg_periph_enum dbg_periph); +#endif /* GD32F1X0_DBG_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_dma.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_dma.h new file mode 100644 index 0000000..d9cb553 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_dma.h @@ -0,0 +1,249 @@ +/*! + \file gd32f1x0_dma.h + \brief definitions for the DMA +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_DMA_H +#define GD32F1X0_DMA_H + +#include "gd32f1x0.h" + +/* DMA definitions */ +#define DMA DMA_BASE /*!< DMA base address */ + +/* registers definitions */ +#define DMA_INTF REG32(DMA + 0x00U) /*!< DMA interrupt flag register */ +#define DMA_INTC REG32(DMA + 0x04U) /*!< DMA interrupt flag clear register */ + +#define DMA_CH0CTL REG32(DMA + 0x08U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT REG32(DMA + 0x0CU) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR REG32(DMA + 0x10U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0MADDR REG32(DMA + 0x14U) /*!< DMA channel 0 memory base address register */ + +#define DMA_CH1CTL REG32(DMA + 0x1CU) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT REG32(DMA + 0x20U) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR REG32(DMA + 0x24U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1MADDR REG32(DMA + 0x28U) /*!< DMA channel 1 memory base address register */ + +#define DMA_CH2CTL REG32(DMA + 0x30U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT REG32(DMA + 0x34U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR REG32(DMA + 0x38U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2MADDR REG32(DMA + 0x3CU) /*!< DMA channel 2 memory base address register */ + +#define DMA_CH3CTL REG32(DMA + 0x44U) /*!< DMA channel 3 control register */ +#define DMA_CH3CNT REG32(DMA + 0x48U) /*!< DMA channel 3 counter register */ +#define DMA_CH3PADDR REG32(DMA + 0x4CU) /*!< DMA channel 3 peripheral base address register */ +#define DMA_CH3MADDR REG32(DMA + 0x50U) /*!< DMA channel 3 memory base address register */ + +#define DMA_CH4CTL REG32(DMA + 0x58U) /*!< DMA channel 4 control register */ +#define DMA_CH4CNT REG32(DMA + 0x5CU) /*!< DMA channel 4 counter register */ +#define DMA_CH4PADDR REG32(DMA + 0x60U) /*!< DMA channel 4 peripheral base address register */ +#define DMA_CH4MADDR REG32(DMA + 0x64U) /*!< DMA channel 4 memory base address register */ + +#define DMA_CH5CTL REG32(DMA + 0x6CU) /*!< DMA channel 5 control register */ +#define DMA_CH5CNT REG32(DMA + 0x70U) /*!< DMA channel 5 counter register */ +#define DMA_CH5PADDR REG32(DMA + 0x74U) /*!< DMA channel 5 peripheral base address register */ +#define DMA_CH5MADDR REG32(DMA + 0x78U) /*!< DMA channel 5 memory base address register */ + +#define DMA_CH6CTL REG32(DMA + 0x80U) /*!< DMA channel 6 control register */ +#define DMA_CH6CNT REG32(DMA + 0x84U) /*!< DMA channel 6 counter register */ +#define DMA_CH6PADDR REG32(DMA + 0x88U) /*!< DMA channel 6 peripheral base address register */ +#define DMA_CH6MADDR REG32(DMA + 0x8CU) /*!< DMA channel 6 memory base address register */ + +/* bits definitions */ +/* DMA_INTF */ +#define DMA_INTF_GIF BIT(0) /*!< global interrupt flag of channel */ +#define DMA_INTF_FTFIF BIT(1) /*!< transfer complete flag of channel */ +#define DMA_INTF_HTFIF BIT(2) /*!< half transfer complete flag of channel */ +#define DMA_INTF_ERRIF BIT(3) /*!< error flag of channel */ + +/* DMA_INTC */ +#define DMA_INTFC_GIFC BIT(0) /*!< clear global interrupt flag of channel */ +#define DMA_INTFC_FTFIFC BIT(1) /*!< clear transfer complete flag of channel */ +#define DMA_INTFC_HTFIFC BIT(2) /*!< clear half transfer complete flag of channel */ +#define DMA_INTFC_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) /*!< transfer direction */ +#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 */ + +/* constants definitions */ +/* DMA channel select */ +typedef enum +{ + DMA_CH0 = 0, /*!< DMA Channel0 */ + DMA_CH1, /*!< DMA Channel1 */ + DMA_CH2, /*!< DMA Channel2 */ + DMA_CH3, /*!< DMA Channel3 */ + DMA_CH4, /*!< DMA Channel4 */ + DMA_CH5, /*!< DMA Channel5 */ + DMA_CH6 /*!< DMA Channel6 */ +} dma_channel_enum; + +/* DMA initialize struct */ +typedef struct +{ + uint32_t periph_addr; /*!< peripheral base address */ + uint32_t periph_width; /*!< transfer data size of peripheral */ + uint32_t periph_inc; /*!< peripheral increasing mode */ + uint32_t memory_addr; /*!< memory base address */ + uint32_t memory_width; /*!< transfer data size of memory */ + uint32_t memory_inc; /*!< memory increasing mode */ + uint32_t direction; /*!< channel data transfer direction */ + uint32_t number; /*!< channel transfer number */ + uint32_t priority; /*!< channel priority level */ +} dma_parameter_struct; + +/* 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 */ + +/* 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 */ + +/* 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_CHCTL base address */ +#define DMA_CHXCTL_BASE (DMA + 0x08U) /*!< the base address of DMA channel CHXCTL register */ +#define DMA_CHXCNT_BASE (DMA + 0x0CU) /*!< the base address of DMA channel CHXCNT register */ +#define DMA_CHXPADDR_BASE (DMA + 0x10U) /*!< the base address of DMA channel CHXPADDR register */ +#define DMA_CHXMADDR_BASE (DMA + 0x14U) /*!< the base address of DMA channel CHXMADDR 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(channel) REG32(DMA_CHXCTL_BASE + 0x14U*(channel)) /*!< the address of DMA channel CHXCTL register */ +#define DMA_CHCNT(channel) REG32(DMA_CHXCNT_BASE + 0x14U*(channel)) /*!< the address of DMA channel CHXCNT register */ +#define DMA_CHPADDR(channel) REG32(DMA_CHXPADDR_BASE + 0x14U*(channel)) /*!< the address of DMA channel CHXPADDR register */ +#define DMA_CHMADDR(channel) REG32(DMA_CHXMADDR_BASE + 0x14U*(channel)) /*!< the address of DMA channel CHXMADDR register */ + +/* channel priority level */ +#define CHCTL_PRIO(regval) (BITS(12,13) & ((regval) << 12U)) /*!< DMA channel priority level */ +#define DMA_PRIORITY_LOW CHCTL_PRIO(0) /*!< low priority */ +#define DMA_PRIORITY_MEDIUM CHCTL_PRIO(1) /*!< medium priority */ +#define DMA_PRIORITY_HIGH CHCTL_PRIO(2) /*!< high priority */ +#define DMA_PRIORITY_ULTRA_HIGH CHCTL_PRIO(3) /*!< ultra high priority */ + +/* transfer data size of memory */ +#define CHCTL_MSIZE(regval) (BITS(10,11) & ((regval) << 10U)) /*!< transfer data size of memory */ +#define DMA_MEMORY_WIDTH_8BIT CHCTL_MSIZE(0) /*!< transfer data size of memory is 8-bit */ +#define DMA_MEMORY_WIDTH_16BIT CHCTL_MSIZE(1) /*!< transfer data size of memory is 16-bit */ +#define DMA_MEMORY_WIDTH_32BIT CHCTL_MSIZE(2) /*!< transfer data size of memory is 32-bit */ + +/* transfer data size of peripheral */ +#define CHCTL_PSIZE(regval) (BITS(8,9) & ((regval) << 8U)) /*!< transfer data size of peripheral */ +#define DMA_PERIPHERAL_WIDTH_8BIT CHCTL_PSIZE(0) /*!< transfer data size of peripheral is 8-bit */ +#define DMA_PERIPHERAL_WIDTH_16BIT CHCTL_PSIZE(1) /*!< transfer data size of peripheral is 16-bit */ +#define DMA_PERIPHERAL_WIDTH_32BIT CHCTL_PSIZE(2) /*!< transfer data size of peripheral is 32-bit */ + +/* channel data transfer direction */ +#define DMA_PERIPHERAL_TO_MEMORY ((uint32_t)0x00000000U) /*!< read from peripheral and write to memory */ +#define DMA_MEMORY_TO_PERIPHERAL ((uint32_t)0x00000001U) /*!< read from memory and write to peripheral */ + +/* peripheral increasing mode */ +#define DMA_PERIPH_INCREASE_ENABLE ((uint32_t)0x00000000U) /*!< next address of peripheral is increasing address mode */ +#define DMA_PERIPH_INCREASE_DISABLE ((uint32_t)0x00000001U) /*!< next address of peripheral is fixed address mode */ + +/* memory increasing mode */ +#define DMA_MEMORY_INCREASE_ENABLE ((uint32_t)0x00000000U) /*!< next address of memory is increasing address mode */ +#define DMA_MEMORY_INCREASE_DISABLE ((uint32_t)0x00000001U) /*!< next address of memory is fixed address mode */ + +/* DMA reset value */ +#define DMA_CHCTL_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCTL register */ +#define DMA_CHCNT_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCNT register */ +#define DMA_CHPADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXPADDR register */ +#define DMA_CHMADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXMADDR register */ +#define DMA_CHINTF_RESET_VALUE ((uint32_t)0x0000000FU) /*!< clear DMA channel CHXINTFS register */ + +/* function declarations */ +/* deinitialize DMA a channel registers */ +void dma_deinit(dma_channel_enum channelx); +/* initialize DMA channel */ +void dma_init(dma_channel_enum channelx, dma_parameter_struct init_struct); +/* enable DMA circulation mode */ +void dma_circulation_enable(dma_channel_enum channelx); +/* disable DMA circulation mode */ +void dma_circulation_disable(dma_channel_enum channelx); +/* enable memory to memory mode */ +void dma_memory_to_memory_enable(dma_channel_enum channelx); +/* disable memory to memory mode */ +void dma_memory_to_memory_disable(dma_channel_enum channelx); +/* enable DMA channel */ +void dma_channel_enable(dma_channel_enum channelx); +/* disable DMA channel */ +void dma_channel_disable(dma_channel_enum channelx); + +/* set DMA peripheral base address */ +void dma_periph_address_config(dma_channel_enum channelx, uint32_t address); +/* set DMA Memory base address */ +void dma_memory_address_config(dma_channel_enum channelx, uint32_t address); +/* set the number of remaining data to be transferred by the DMA */ +void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number); +/* get the number of remaining data to be transferred by the DMA */ +uint32_t dma_transfer_number_get(dma_channel_enum channelx); +/* configure priority level of DMA channel */ +void dma_priority_config(dma_channel_enum channelx, uint32_t priority); +/* configure transfer data size of memory */ +void dma_memory_width_config (dma_channel_enum channelx, uint32_t msize); +/* configure transfer data size of peripheral */ +void dma_periph_width_config (dma_channel_enum channelx, uint32_t psize); +/* enable next address increasement algorithm of memory */ +void dma_memory_increase_enable(dma_channel_enum channelx); +/* disable next address increasement algorithm of memory */ +void dma_memory_increase_disable(dma_channel_enum channelx); +/* enable next address increasement algorithm of peripheral */ +void dma_periph_increase_enable(dma_channel_enum channelx); +/* disable next address increasement algorithm of peripheral */ +void dma_periph_increase_disable(dma_channel_enum channelx); +/* configure the direction of data transfer on the channel */ +void dma_transfer_direction_config(dma_channel_enum channelx, uint8_t direction); + +/* check DMA flag is set or not */ +FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag); +/* clear DMA a channel flag */ +void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag); +/* enable DMA interrupt */ +void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source); +/* disable DMA interrupt */ +void dma_interrupt_disable(dma_channel_enum channelx,uint32_t source); +/* check DMA flag is set or not */ +FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag); +/* clear DMA a channel flag */ +void dma_flag_clear(dma_channel_enum channelx, uint32_t flag); + +#endif /* GD32F1X0_DMA_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_exti.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_exti.h new file mode 100644 index 0000000..ee2c067 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_exti.h @@ -0,0 +1,262 @@ +/*! + \file gd32f1x0_exti.h + \brief definitions for the EXTI +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_EXTI_H +#define GD32F1X0_EXTI_H + +#include "gd32f1x0.h" + +/* EXTI definitions */ +#define EXTI EXTI_BASE + +/* registers definitions */ +#define EXTI_INTEN REG32(EXTI + 0x00U) /*!< interrupt enable register */ +#define EXTI_EVEN REG32(EXTI + 0x04U) /*!< event enable register */ +#define EXTI_RTEN REG32(EXTI + 0x08U) /*!< rising edge trigger enable register */ +#define EXTI_FTEN REG32(EXTI + 0x0CU) /*!< falling trigger enable register */ +#define EXTI_SWIEV REG32(EXTI + 0x10U) /*!< software interrupt event register */ +#define EXTI_PD REG32(EXTI + 0x14U) /*!< pending register */ + +/* bits definitions */ +/* EXTI_INTEN */ +#define EXTI_INTEN_INTEN0 BIT(0) /*!< interrupt from line 0 */ +#define EXTI_INTEN_INTEN1 BIT(1) /*!< interrupt from line 1 */ +#define EXTI_INTEN_INTEN2 BIT(2) /*!< interrupt from line 2 */ +#define EXTI_INTEN_INTEN3 BIT(3) /*!< interrupt from line 3 */ +#define EXTI_INTEN_INTEN4 BIT(4) /*!< interrupt from line 4 */ +#define EXTI_INTEN_INTEN5 BIT(5) /*!< interrupt from line 5 */ +#define EXTI_INTEN_INTEN6 BIT(6) /*!< interrupt from line 6 */ +#define EXTI_INTEN_INTEN7 BIT(7) /*!< interrupt from line 7 */ +#define EXTI_INTEN_INTEN8 BIT(8) /*!< interrupt from line 8 */ +#define EXTI_INTEN_INTEN9 BIT(9) /*!< interrupt from line 9 */ +#define EXTI_INTEN_INTEN10 BIT(10) /*!< interrupt from line 10 */ +#define EXTI_INTEN_INTEN11 BIT(11) /*!< interrupt from line 11 */ +#define EXTI_INTEN_INTEN12 BIT(12) /*!< interrupt from line 12 */ +#define EXTI_INTEN_INTEN13 BIT(13) /*!< interrupt from line 13 */ +#define EXTI_INTEN_INTEN14 BIT(14) /*!< interrupt from line 14 */ +#define EXTI_INTEN_INTEN15 BIT(15) /*!< interrupt from line 15 */ +#define EXTI_INTEN_INTEN16 BIT(16) /*!< interrupt from line 16 */ +#define EXTI_INTEN_INTEN17 BIT(17) /*!< interrupt from line 17 */ +#define EXTI_INTEN_INTEN18 BIT(18) /*!< interrupt from line 18 */ +#define EXTI_INTEN_INTEN19 BIT(19) /*!< interrupt from line 19 */ +#define EXTI_INTEN_INTEN20 BIT(20) /*!< interrupt from line 20 */ +#define EXTI_INTEN_INTEN21 BIT(21) /*!< interrupt from line 21 */ +#define EXTI_INTEN_INTEN22 BIT(22) /*!< interrupt from line 22 */ +#define EXTI_INTEN_INTEN23 BIT(23) /*!< interrupt from line 23 */ +#define EXTI_INTEN_INTEN24 BIT(24) /*!< interrupt from line 24 */ +#define EXTI_INTEN_INTEN25 BIT(25) /*!< interrupt from line 25 */ +#define EXTI_INTEN_INTEN26 BIT(26) /*!< interrupt from line 26 */ +#define EXTI_INTEN_INTEN27 BIT(27) /*!< interrupt from line 27 */ + +/* 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 */ +#define EXTI_EVEN_EVEN25 BIT(25) /*!< event from line 25 */ +#define EXTI_EVEN_EVEN26 BIT(26) /*!< event from line 26 */ +#define EXTI_EVEN_EVEN27 BIT(27) /*!< event from line 27 */ + +/* 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_RTEN21 BIT(21) /*!< rising edge from line 21 */ +#define EXTI_RTEN_RTEN22 BIT(22) /*!< rising edge from line 22 */ + +/* EXTI_FTEN */ +#define EXTI_FTEN_FTEN0 BIT(0) /*!< falling edge from line 0 */ +#define EXTI_FTEN_FTEN1 BIT(1) /*!< falling edge from line 1 */ +#define EXTI_FTEN_FTEN2 BIT(2) /*!< falling edge from line 2 */ +#define EXTI_FTEN_FTEN3 BIT(3) /*!< falling edge from line 3 */ +#define EXTI_FTEN_FTEN4 BIT(4) /*!< falling edge from line 4 */ +#define EXTI_FTEN_FTEN5 BIT(5) /*!< falling edge from line 5 */ +#define EXTI_FTEN_FTEN6 BIT(6) /*!< falling edge from line 6 */ +#define EXTI_FTEN_FTEN7 BIT(7) /*!< falling edge from line 7 */ +#define EXTI_FTEN_FTEN8 BIT(8) /*!< falling edge from line 8 */ +#define EXTI_FTEN_FTEN9 BIT(9) /*!< falling edge from line 9 */ +#define EXTI_FTEN_FTEN10 BIT(10) /*!< falling edge from line 10 */ +#define EXTI_FTEN_FTEN11 BIT(11) /*!< falling edge from line 11 */ +#define EXTI_FTEN_FTEN12 BIT(12) /*!< falling edge from line 12 */ +#define EXTI_FTEN_FTEN13 BIT(13) /*!< falling edge from line 13 */ +#define EXTI_FTEN_FTEN14 BIT(14) /*!< falling edge from line 14 */ +#define EXTI_FTEN_FTEN15 BIT(15) /*!< falling edge from line 15 */ +#define EXTI_FTEN_FTEN16 BIT(16) /*!< falling edge from line 16 */ +#define EXTI_FTEN_FTEN17 BIT(17) /*!< falling edge from line 17 */ +#define EXTI_FTEN_FTEN18 BIT(18) /*!< falling edge from line 18 */ +#define EXTI_FTEN_FTEN19 BIT(19) /*!< falling edge from line 19 */ +#define EXTI_FTEN_FTEN21 BIT(21) /*!< falling edge from line 21 */ +#define EXTI_FTEN_FTEN22 BIT(22) /*!< falling edge from line 22 */ + +/* EXTI_SWIEV */ +#define EXTI_SWIEV_SWIEV0 BIT(0) /*!< software interrupt/event request from line 0 */ +#define EXTI_SWIEV_SWIEV1 BIT(1) /*!< software interrupt/event request from line 1 */ +#define EXTI_SWIEV_SWIEV2 BIT(2) /*!< software interrupt/event request from line 2 */ +#define EXTI_SWIEV_SWIEV3 BIT(3) /*!< software interrupt/event request from line 3 */ +#define EXTI_SWIEV_SWIEV4 BIT(4) /*!< software interrupt/event request from line 4 */ +#define EXTI_SWIEV_SWIEV5 BIT(5) /*!< software interrupt/event request from line 5 */ +#define EXTI_SWIEV_SWIEV6 BIT(6) /*!< software interrupt/event request from line 6 */ +#define EXTI_SWIEV_SWIEV7 BIT(7) /*!< software interrupt/event request from line 7 */ +#define EXTI_SWIEV_SWIEV8 BIT(8) /*!< software interrupt/event request from line 8 */ +#define EXTI_SWIEV_SWIEV9 BIT(9) /*!< software interrupt/event request from line 9 */ +#define EXTI_SWIEV_SWIEV10 BIT(10) /*!< software interrupt/event request from line 10 */ +#define EXTI_SWIEV_SWIEV11 BIT(11) /*!< software interrupt/event request from line 11 */ +#define EXTI_SWIEV_SWIEV12 BIT(12) /*!< software interrupt/event request from line 12 */ +#define EXTI_SWIEV_SWIEV13 BIT(13) /*!< software interrupt/event request from line 13 */ +#define EXTI_SWIEV_SWIEV14 BIT(14) /*!< software interrupt/event request from line 14 */ +#define EXTI_SWIEV_SWIEV15 BIT(15) /*!< software interrupt/event request from line 15 */ +#define EXTI_SWIEV_SWIEV16 BIT(16) /*!< software interrupt/event request from line 16 */ +#define EXTI_SWIEV_SWIEV17 BIT(17) /*!< software interrupt/event request from line 17 */ +#define EXTI_SWIEV_SWIEV18 BIT(18) /*!< software interrupt/event request from line 18 */ +#define EXTI_SWIEV_SWIEV19 BIT(19) /*!< software interrupt/event request from line 19 */ +#define EXTI_SWIEV_SWIEV21 BIT(21) /*!< software interrupt/event request from line 21 */ +#define EXTI_SWIEV_SWIEV22 BIT(22) /*!< software interrupt/event request from line 22 */ + +/* EXTI_PD */ +#define EXTI_PD_PD0 BIT(0) /*!< interrupt/event pending status from line 0 */ +#define EXTI_PD_PD1 BIT(1) /*!< interrupt/event pending status from line 1 */ +#define EXTI_PD_PD2 BIT(2) /*!< interrupt/event pending status from line 2 */ +#define EXTI_PD_PD3 BIT(3) /*!< interrupt/event pending status from line 3 */ +#define EXTI_PD_PD4 BIT(4) /*!< interrupt/event pending status from line 4 */ +#define EXTI_PD_PD5 BIT(5) /*!< interrupt/event pending status from line 5 */ +#define EXTI_PD_PD6 BIT(6) /*!< interrupt/event pending status from line 6 */ +#define EXTI_PD_PD7 BIT(7) /*!< interrupt/event pending status from line 7 */ +#define EXTI_PD_PD8 BIT(8) /*!< interrupt/event pending status from line 8 */ +#define EXTI_PD_PD9 BIT(9) /*!< interrupt/event pending status from line 9 */ +#define EXTI_PD_PD10 BIT(10) /*!< interrupt/event pending status from line 10 */ +#define EXTI_PD_PD11 BIT(11) /*!< interrupt/event pending status from line 11 */ +#define EXTI_PD_PD12 BIT(12) /*!< interrupt/event pending status from line 12 */ +#define EXTI_PD_PD13 BIT(13) /*!< interrupt/event pending status from line 13 */ +#define EXTI_PD_PD14 BIT(14) /*!< interrupt/event pending status from line 14 */ +#define EXTI_PD_PD15 BIT(15) /*!< interrupt/event pending status from line 15 */ +#define EXTI_PD_PD16 BIT(16) /*!< interrupt/event pending status from line 16 */ +#define EXTI_PD_PD17 BIT(17) /*!< interrupt/event pending status from line 17 */ +#define EXTI_PD_PD18 BIT(18) /*!< interrupt/event pending status from line 18 */ +#define EXTI_PD_PD19 BIT(19) /*!< interrupt/event pending status from line 19 */ +#define EXTI_PD_PD21 BIT(21) /*!< interrupt/event pending status from line 21 */ +#define EXTI_PD_PD22 BIT(22) /*!< interrupt/event pending status from line 22 */ + +/* constants definitions */ +/* EXTI line number */ +typedef enum +{ + EXTI_0 = BIT(0), /*!< EXTI line 0 */ + EXTI_1 = BIT(1), /*!< EXTI line 1 */ + EXTI_2 = BIT(2), /*!< EXTI line 2 */ + EXTI_3 = BIT(3), /*!< EXTI line 3 */ + EXTI_4 = BIT(4), /*!< EXTI line 4 */ + EXTI_5 = BIT(5), /*!< EXTI line 5 */ + EXTI_6 = BIT(6), /*!< EXTI line 6 */ + EXTI_7 = BIT(7), /*!< EXTI line 7 */ + EXTI_8 = BIT(8), /*!< EXTI line 8 */ + EXTI_9 = BIT(9), /*!< EXTI line 9 */ + EXTI_10 = BIT(10), /*!< EXTI line 10 */ + EXTI_11 = BIT(11), /*!< EXTI line 11 */ + EXTI_12 = BIT(12), /*!< EXTI line 12 */ + EXTI_13 = BIT(13), /*!< EXTI line 13 */ + EXTI_14 = BIT(14), /*!< EXTI line 14 */ + EXTI_15 = BIT(15), /*!< EXTI line 15 */ + EXTI_16 = BIT(16), /*!< EXTI line 16 */ + EXTI_17 = BIT(17), /*!< EXTI line 17 */ +#ifdef GD32F130_150 + EXTI_18 = BIT(18), /*!< EXTI line 18 */ +#endif /* GD32F130_150 */ + EXTI_19 = BIT(19), /*!< EXTI line 19 */ + EXTI_21 = BIT(21), /*!< EXTI line 21 */ + EXTI_22 = BIT(22), /*!< EXTI line 22 */ + EXTI_25 = BIT(25), /*!< EXTI line 25 */ + EXTI_27 = BIT(27) /*!< EXTI line 27 */ +}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_type_enum; + +/* function declarations */ +/* deinitialize the EXTI */ +void exti_deinit(void); +/* enable the configuration of EXTI initialize */ +void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type); +/* enable the interrupts from EXTI line x */ +void exti_interrupt_enable(exti_line_enum linex); +/* enable the events from EXTI line x */ +void exti_event_enable(exti_line_enum linex); +/* disable the interrupts from EXTI line x */ +void exti_interrupt_disable(exti_line_enum linex); +/* disable the events from EXTI line x */ +void exti_event_disable(exti_line_enum linex); + +/* get EXTI lines pending flag */ +FlagStatus exti_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_flag_clear(exti_line_enum linex); +/* get EXTI lines flag when the interrupt flag is set */ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_interrupt_flag_clear(exti_line_enum linex); +/* EXTI software interrupt event enable */ +void exti_software_interrupt_enable(exti_line_enum linex); +/* EXTI software interrupt event disable */ +void exti_software_interrupt_disable(exti_line_enum linex); + +#endif /* GD32F1X0_EXTI_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_fmc.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_fmc.h new file mode 100644 index 0000000..bc94da1 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_fmc.h @@ -0,0 +1,239 @@ +/*! + \file gd32f1x0_fmc.h + \brief definitions for the FMC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_FMC_H +#define GD32F1X0_FMC_H + +#include "gd32f1x0.h" + +/* FMC and option byte definition */ +#define FMC FMC_BASE /*!< FMC register base address */ +#define OB OB_BASE /*!< option byte base address */ + +/* registers definitions */ +#define FMC_WS REG32((FMC) + 0x00U) /*!< FMC wait state register */ +#define FMC_KEY REG32((FMC) + 0x04U) /*!< FMC unlock key register */ +#define FMC_OBKEY REG32((FMC) + 0x08U) /*!< FMC option bytes unlock key register */ +#define FMC_STAT REG32((FMC) + 0x0CU) /*!< FMC status register */ +#define FMC_CTL REG32((FMC) + 0x10U) /*!< FMC control register */ +#define FMC_ADDR REG32((FMC) + 0x14U) /*!< FMC address register */ +#define FMC_OBSTAT REG32((FMC) + 0x1CU) /*!< FMC option bytes status register */ +#define FMC_WP REG32((FMC) + 0x20U) /*!< FMC write protection register */ +#define FMC_WSEN REG32((FMC) + 0xFCU) /*!< FMC wait state enable register */ +#define FMC_PID REG32((FMC) + 0x100U) /*!< FMC product ID register */ + +#define OB_SPC REG16((OB) + 0x00U) /*!< option byte security protection value */ +#define OB_USER REG16((OB) + 0x02U) /*!< option byte user value*/ +#define OB_WP0 REG16((OB) + 0x08U) /*!< option byte write protection 0 */ +#define OB_WP1 REG16((OB) + 0x0AU) /*!< option byte write protection 1 */ + +/* bits definitions */ +/* FMC_WS */ +#define FMC_WS_WSCNT BITS(0,2) /*!< wait state counter */ + +/* FMC_KEY */ +#define FMC_KEY_KEY BITS(0,31) /*!< FMC main flash unlock key bits */ + +/* FMC_OBKEY */ +#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option bytes unlock key bits */ + +/* FMC_STAT */ +#define FMC_STAT_BUSY BIT(0) /*!< flash busy flag bit */ +#define FMC_STAT_PGERR BIT(2) /*!< flash program error flag bit */ +#define FMC_STAT_WPERR BIT(4) /*!< flash write protection error flag bit */ +#define FMC_STAT_ENDF BIT(5) /*!< flash end of operation flag bit */ + +/* FMC_CTL */ +#define FMC_CTL_PG BIT(0) /*!< main flash program command bit */ +#define FMC_CTL_PER BIT(1) /*!< main flash page erase bit */ +#define FMC_CTL_MER BIT(2) /*!< main flash mass erase bit */ +#define FMC_CTL_OBPG BIT(4) /*!< option bytes program command bit */ +#define FMC_CTL_OBER BIT(5) /*!< option bytes erase command bit */ +#define FMC_CTL_START BIT(6) /*!< send erase command to FMC bit */ +#define FMC_CTL_LK BIT(7) /*!< flash lock bit */ +#define FMC_CTL_OBWEN BIT(9) /*!< option bytes erase/program enable bit */ +#define FMC_CTL_ERRIE BIT(10) /*!< error interrupt enable bit */ +#define FMC_CTL_ENDIE BIT(12) /*!< end of operation interrupt enable bit */ +#define FMC_CTL_OBRLD BIT(13) /*!< option bytes reload bit */ + +/* FMC_ADDR */ +#define FMC_ADDR_ADDR BITS(0,31) /*!< flash command address bits */ + +/* FMC_OBSTAT */ +#define FMC_OBSTAT_OBERR BIT(0) /*!< option bytes read error bit */ +#define FMC_OBSTAT_PLVL_BIT0 BIT(1) /*!< protection level bit 0 */ +#define FMC_OBSTAT_PLVL_BIT1 BIT(2) /*!< protection level bit 1 */ +#define FMC_OBSTAT_USER BITS(8,15) /*!< option bytes user bits */ +#define FMC_OBSTAT_DATA BITS(16,31) /*!< option byte data bits */ + +/* FMC_WSEN */ +#define FMC_WSEN_WSEN BIT(0) /*!< FMC wait state enable bit */ +#ifdef GD32F170_190 +#define FMC_WSEN_BPEN BIT(1) /*!< FMC bit program enable bit */ +#endif /* GD32F170_190 */ + +/* 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_PGERR, /*!< program error */ + FMC_WPERR, /*!< erase/program protection error */ + FMC_TOERR, /*!< timeout error */ + FMC_OB_HSPC /*!< option byte security protection code high */ +}fmc_state_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_0 ((uint8_t)0x00U) /*!< 0 wait state added */ +#define WS_WSCNT_1 ((uint8_t)0x01U) /*!< 1 wait state added */ +#define WS_WSCNT_2 ((uint8_t)0x02U) /*!< 2 wait state added */ + +/* read protect configure */ +#define FMC_NSPC ((uint8_t)0xA5U) /*!< no security protection */ +#define FMC_LSPC ((uint8_t)0xBBU) /*!< low security protection, any value except 0xA5 or 0xCC */ +#define FMC_HSPC ((uint8_t)0xCCU) /*!< high security protection */ + +/* option byte write protection */ +#define OB_LWP ((uint32_t)0x000000FFU) /*!< write protection low bits */ +#define OB_HWP ((uint32_t)0x0000FF00U) /*!< write protection high bits */ + +/* option byte software/hardware free watchdog timer */ +#define OBUSER_NWDG_HW(regval) (BIT(0) & ((uint32_t)(regval) << 0)) +#define OB_FWDGT_HW OBUSER_NWDG_HW(0) /*!< hardware free watchdog timer */ +#define OB_FWDGT_SW OBUSER_NWDG_HW(1) /*!< software free watchdog timer */ + +/* option byte reset or not entering deep sleep mode */ +#define OBUSER_NRST_DPSLP(regval) (BIT(1) & ((uint32_t)(regval) << 1)) +#define OB_DEEPSLEEP_RST OBUSER_NRST_DPSLP(0) /*!< generate a reset instead of entering deepsleep mode */ +#define OB_DEEPSLEEP_NRST OBUSER_NRST_DPSLP(1) /*!< no reset when entering deepsleep mode */ + +/* option byte reset or not entering standby mode */ +#define OBUSER_NRST_STDBY(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define OB_STDBY_RST OBUSER_NRST_STDBY(0) /*!< generate a reset instead of entering standby mode */ +#define OB_STDBY_NRST OBUSER_NRST_STDBY(1) /*!< no reset when entering deepsleep mode */ + +/* option byte OB_BOOT1_n set */ +#define OBUSER_BOOT1_N(regval) (BIT(4) & ((uint32_t)(regval) << 4)) +#define OB_BOOT1_SET_1 OBUSER_BOOT1_N(0) /*!< BOOT1 bit is 1 */ +#define OB_BOOT1_SET_0 OBUSER_BOOT1_N(1) /*!< BOOT1 bit is 0 */ + +/* option byte VDDA monitor enable/disable */ +#define OBUSER_VDDA_VISOR(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define OB_VDDA_DISABLE OBUSER_VDDA_VISOR(0) /*!< disable VDDA monitor */ +#define OB_VDDA_ENABLE OBUSER_VDDA_VISOR(1) /*!< enable VDDA monitor */ + +/* option byte SRAM parity enable/disable */ +#define OBUSER_SRAM_PARITY(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define OB_SRAM_PARITY_ENABLE OBUSER_SRAM_PARITY(0) /*!< enable SRAM parity check */ +#define OB_SRAM_PARITY_DISABLE OBUSER_SRAM_PARITY(1) /*!< disable SRAM parity check */ + +/* option byte security protection level in FMC_OBSTAT register */ +#define OB_OBSTAT_PLEVEL_NO ((uint32_t)0x00000000U) /*!< no security protection */ +#define OB_OBSTAT_PLEVEL_LOW ((uint32_t)0x00000002U) /*!< low security protection */ +#define OB_OBSTAT_PLEVEL_HIGH ((uint32_t)0x00000006U) /*!< high security protection */ + +/* option byte user mask */ +#define OB_USER_MASK ((uint8_t)0x88U) /*!< OB_USER reserved bit mask */ + +/* option byte data address */ +#define OB_DATA_ADDR0 ((uint32_t)0x1FFFF804U) /*!< option byte data address 0 */ +#define OB_DATA_ADDR1 ((uint32_t)0x1FFFF806U) /*!< option byte data address 1 */ + +/* FMC flags */ +#define FMC_FLAG_BUSY FMC_STAT_BUSY /*!< FMC busy flag */ +#define FMC_FLAG_PGERR FMC_STAT_PGERR /*!< FMC programming error flag */ +#define FMC_FLAG_WPERR FMC_STAT_WPERR /*!< FMC write protection error flag */ +#define FMC_FLAG_END FMC_STAT_ENDF /*!< FMC end of programming flag */ + +/* FMC interrupt enable */ +#define FMC_INTEN_END FMC_CTL_ENDIE /*!< enable FMC end of operation interrupt */ +#define FMC_INTEN_ERR FMC_CTL_ERRIE /*!< enable FMC error interrupt */ + +/* FMC time out */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0x000F0000U) /*!< count to judge of FMC timeout */ + +/* function declarations */ +/* FMC main memory programming functions */ +/* unlock the main FMC operation */ +void fmc_unlock(void); +/* lock the main FMC operation */ +void fmc_lock(void); +/* set the wait state counter value */ +void fmc_wscnt_set(uint8_t wscnt); +/* fmc wait state enable */ +void fmc_wait_state_enable(void); +/* fmc wait state disable */ +void fmc_wait_state_disable(void); +/* FMC erase page */ +fmc_state_enum fmc_page_erase(uint32_t page_address); +/* FMC erase whole chip */ +fmc_state_enum fmc_mass_erase(void); +/* FMC program a word at the corresponding address */ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data); +/* FMC program a half word at the corresponding address */ +fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data); +#ifdef GD32F170_190 +/* FMC program a word at the corresponding address without erasing */ +fmc_state_enum fmc_word_reprogram(uint32_t address, uint32_t data); +#endif /* GD32F170_190 */ + +/* FMC option bytes programming functions */ +/* unlock the option byte operation */ +void ob_unlock(void); +/* lock the option byte operation */ +void ob_lock(void); +/* reload the option byte and generate a system reset */ +void ob_reset(void); +/* erase option byte */ +fmc_state_enum ob_erase(void); +/* enable option byte write protection (OB_WP) */ +fmc_state_enum ob_write_protection_enable(uint32_t ob_wp); +/* configure read out protect */ +fmc_state_enum ob_security_protection_config(uint8_t ob_spc); +/* write the FMC option byte user */ +fmc_state_enum ob_user_write(uint8_t ob_user); +/* write the FMC option byte data */ +fmc_state_enum ob_data_program(uint32_t address, uint8_t data); +/* get the FMC option byte OB_USER */ +uint8_t ob_user_get(void); +/* get the FMC option byte OB_DATA */ +uint16_t ob_data_get(void); +/* get the FMC option byte write protection */ +uint16_t ob_write_protection_get(void); +/* get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register */ +uint32_t ob_obstat_plevel_get(void); + +/* FMC interrupts and flags management functions */ +/* enable FMC interrupt */ +void fmc_interrupt_enable(uint32_t interrupt); +/* disable FMC interrupt */ +void fmc_interrupt_disable(uint32_t interrupt); +/* get flag set or reset */ +FlagStatus fmc_flag_get(uint32_t flag); +/* clear the FMC pending flag */ +void fmc_flag_clear(uint32_t flag); +/* return the FMC state */ +fmc_state_enum fmc_state_get(void); +/* check FMC ready or not */ +fmc_state_enum fmc_ready_wait(uint32_t timeout); + +#endif /* GD32F1X0_FMC_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_fwdgt.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_fwdgt.h new file mode 100644 index 0000000..e95721d --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_fwdgt.h @@ -0,0 +1,100 @@ +/*! + \file gd32f1x0_fwdgt.h + \brief definitions for the FWDGT +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_FWDGT_H +#define GD32F1X0_FWDGT_H + +#include "gd32f1x0.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE + +/* registers definitions */ +#define FWDGT_CTL REG32((FWDGT) + 0x00U) /*!< FWDGT control register */ +#define FWDGT_PSC REG32((FWDGT) + 0x04U) /*!< FWDGT prescaler register */ +#define FWDGT_RLD REG32((FWDGT) + 0x08U) /*!< FWDGT reload register */ +#define FWDGT_STAT REG32((FWDGT) + 0x0CU) /*!< FWDGT status register */ +#define FWDGT_WND REG32((FWDGT) + 0x10U) /*!< 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 */ +/* ctl register value */ +#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_CTL_CMD bit field */ + +/* 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 */ + +/* rld register value */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_RLD_RLD bit field */ + +/* wnd register value */ +#define WND_WND(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_WND_WND bit field */ + +/* control value */ +#define FWDGT_WRITEACCESS_ENABLE ((uint16_t)0x5555U) /*!< FWDGT_CTL bits write access enable value */ +#define FWDGT_WRITEACCESS_DISABLE ((uint16_t)0x0000U) /*!< FWDGT_CTL bits write access disable value */ +#define FWDGT_KEY_RELOAD ((uint16_t)0xAAAAU) /*!< FWDGT_CTL bits fwdgt counter reload value */ +#define FWDGT_KEY_ENABLE ((uint16_t)0xCCCCU) /*!< FWDGT_CTL bits fwdgt counter enable value */ + +/* FWDGT timeout value */ +#define FWDGT_WND_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_WND register write operation state flag timeout */ +#define FWDGT_PSC_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_PSC register write operation state flag timeout */ +#define FWDGT_RLD_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_RLD register write operation state flag timeout */ + +/* FWDGT flag definitions */ +#define FWDGT_FLAG_PUD FWDGT_STAT_PUD /*!< a write operation to FWDGT_PSC register is on going */ +#define FWDGT_FLAG_RUD FWDGT_STAT_RUD /*!< a write operation to FWDGT_RLD register is on going */ +#define FWDGT_FLAG_WUD FWDGT_STAT_WUD /*!< a write operation to FWDGT_WND register is on going */ + +/* function declarations */ +/* disable write access to FWDGT_PSC,FWDGT_RLD and FWDGT_WND */ +void fwdgt_write_disable(void); +/* start the free watchdog timer counter */ +void fwdgt_enable(void); + +/* configure the free watchdog timer 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 /* GD32F1X0_FWDGT_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_gpio.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_gpio.h new file mode 100644 index 0000000..60067ad --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_gpio.h @@ -0,0 +1,378 @@ +/*! + \file gd32f1x0_gpio.h + \brief definitions for the GPIO +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform for GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform for GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_GPIO_H +#define GD32F1X0_GPIO_H + +#include "gd32f1x0.h" + +/* GPIOx(x=A,B,C,D,F) definitions */ +#define GPIOA (GPIO_BASE + 0x00000000U) +#define GPIOB (GPIO_BASE + 0x00000400U) +#define GPIOC (GPIO_BASE + 0x00000800U) +#define GPIOD (GPIO_BASE + 0x00000C00U) +#define GPIOF (GPIO_BASE + 0x00001400U) + +/* registers definitions */ +#define GPIO_CTL(gpiox) REG32((gpiox) + 0x00U) /*!< GPIO port control register */ +#define GPIO_OMODE(gpiox) REG32((gpiox) + 0x04U) /*!< GPIO port output mode register */ +#define GPIO_OSPD(gpiox) REG32((gpiox) + 0x08U) /*!< GPIO port output speed register */ +#define GPIO_PUD(gpiox) REG32((gpiox) + 0x0CU) /*!< GPIO port pull-up/down register */ +#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x10U) /*!< GPIO port input status register */ +#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x14U) /*!< GPIO port output control register */ +#define GPIO_BOP(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port bit operation register */ +#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x1CU) /*!< GPIO port configuration lock register */ +#define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x20U) /*!< GPIO alternate function selected register 0 */ +#define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x24U) /*!< GPIO alternate function selected register 1 */ +#define GPIO_BC(gpiox) REG32((gpiox) + 0x28U) /*!< GPIO bit clear register */ +#define GPIO_TG(gpiox) REG32((gpiox) + 0x2CU) /*!< GPIO port bit toggle register */ + +/* bits definitions */ +/* GPIO_CTL */ +#define GPIO_CTL_CTL0 BITS(0,1) /*!< pin 0 configuration bits */ +#define GPIO_CTL_CTL1 BITS(2,3) /*!< pin 1 configuration bits */ +#define GPIO_CTL_CTL2 BITS(4,5) /*!< pin 2 configuration bits */ +#define GPIO_CTL_CTL3 BITS(6,7) /*!< pin 3 configuration bits */ +#define GPIO_CTL_CTL4 BITS(8,9) /*!< pin 4 configuration bits */ +#define GPIO_CTL_CTL5 BITS(10,11) /*!< pin 5 configuration bits */ +#define GPIO_CTL_CTL6 BITS(12,13) /*!< pin 6 configuration bits */ +#define GPIO_CTL_CTL7 BITS(14,15) /*!< pin 7 configuration bits */ +#define GPIO_CTL_CTL8 BITS(16,17) /*!< pin 8 configuration bits */ +#define GPIO_CTL_CTL9 BITS(18,19) /*!< pin 9 configuration bits */ +#define GPIO_CTL_CTL10 BITS(20,21) /*!< pin 10 configuration bits */ +#define GPIO_CTL_CTL11 BITS(22,23) /*!< pin 11 configuration bits */ +#define GPIO_CTL_CTL12 BITS(24,25) /*!< pin 12 configuration bits */ +#define GPIO_CTL_CTL13 BITS(26,27) /*!< pin 13 configuration bits */ +#define GPIO_CTL_CTL14 BITS(28,29) /*!< pin 14 configuration bits */ +#define GPIO_CTL_CTL15 BITS(30,31) /*!< pin 15 configuration bits */ + +/* GPIO_OMODE */ +#define GPIO_OMODE_OM0 BIT(0) /*!< pin 0 output mode bit */ +#define GPIO_OMODE_OM1 BIT(1) /*!< pin 1 output mode bit */ +#define GPIO_OMODE_OM2 BIT(2) /*!< pin 2 output mode bit */ +#define GPIO_OMODE_OM3 BIT(3) /*!< pin 3 output mode bit */ +#define GPIO_OMODE_OM4 BIT(4) /*!< pin 4 output mode bit */ +#define GPIO_OMODE_OM5 BIT(5) /*!< pin 5 output mode bit */ +#define GPIO_OMODE_OM6 BIT(6) /*!< pin 6 output mode bit */ +#define GPIO_OMODE_OM7 BIT(7) /*!< pin 7 output mode bit */ +#define GPIO_OMODE_OM8 BIT(8) /*!< pin 8 output mode bit */ +#define GPIO_OMODE_OM9 BIT(9) /*!< pin 9 output mode bit */ +#define GPIO_OMODE_OM10 BIT(10) /*!< pin 10 output mode bit */ +#define GPIO_OMODE_OM11 BIT(11) /*!< pin 11 output mode bit */ +#define GPIO_OMODE_OM12 BIT(12) /*!< pin 12 output mode bit */ +#define GPIO_OMODE_OM13 BIT(13) /*!< pin 13 output mode bit */ +#define GPIO_OMODE_OM14 BIT(14) /*!< pin 14 output mode bit */ +#define GPIO_OMODE_OM15 BIT(15) /*!< pin 15 output mode bit */ + +/* GPIO_OSPD */ +#define GPIO_OSPD_OSPD0 BITS(0,1) /*!< pin 0 output max speed bits */ +#define GPIO_OSPD_OSPD1 BITS(2,3) /*!< pin 1 output max speed bits */ +#define GPIO_OSPD_OSPD2 BITS(4,5) /*!< pin 2 output max speed bits */ +#define GPIO_OSPD_OSPD3 BITS(6,7) /*!< pin 3 output max speed bits */ +#define GPIO_OSPD_OSPD4 BITS(8,9) /*!< pin 4 output max speed bits */ +#define GPIO_OSPD_OSPD5 BITS(10,11) /*!< pin 5 output max speed bits */ +#define GPIO_OSPD_OSPD6 BITS(12,13) /*!< pin 6 output max speed bits */ +#define GPIO_OSPD_OSPD7 BITS(14,15) /*!< pin 7 output max speed bits */ +#define GPIO_OSPD_OSPD8 BITS(16,17) /*!< pin 8 output max speed bits */ +#define GPIO_OSPD_OSPD9 BITS(18,19) /*!< pin 9 output max speed bits */ +#define GPIO_OSPD_OSPD10 BITS(20,21) /*!< pin 10 output max speed bits */ +#define GPIO_OSPD_OSPD11 BITS(22,23) /*!< pin 11 output max speed bits */ +#define GPIO_OSPD_OSPD12 BITS(24,25) /*!< pin 12 output max speed bits */ +#define GPIO_OSPD_OSPD13 BITS(26,27) /*!< pin 13 output max speed bits */ +#define GPIO_OSPD_OSPD14 BITS(28,29) /*!< pin 14 output max speed bits */ +#define GPIO_OSPD_OSPD15 BITS(30,31) /*!< pin 15 output max speed bits */ + +/* GPIO_PUD */ +#define GPIO_PUD_PUD0 BITS(0,1) /*!< pin 0 pull-up or pull-down bits */ +#define GPIO_PUD_PUD1 BITS(2,3) /*!< pin 1 pull-up or pull-down bits */ +#define GPIO_PUD_PUD2 BITS(4,5) /*!< pin 2 pull-up or pull-down bits */ +#define GPIO_PUD_PUD3 BITS(6,7) /*!< pin 3 pull-up or pull-down bits */ +#define GPIO_PUD_PUD4 BITS(8,9) /*!< pin 4 pull-up or pull-down bits */ +#define GPIO_PUD_PUD5 BITS(10,11) /*!< pin 5 pull-up or pull-down bits */ +#define GPIO_PUD_PUD6 BITS(12,13) /*!< pin 6 pull-up or pull-down bits */ +#define GPIO_PUD_PUD7 BITS(14,15) /*!< pin 7 pull-up or pull-down bits */ +#define GPIO_PUD_PUD8 BITS(16,17) /*!< pin 8 pull-up or pull-down bits */ +#define GPIO_PUD_PUD9 BITS(18,19) /*!< pin 9 pull-up or pull-down bits */ +#define GPIO_PUD_PUD10 BITS(20,21) /*!< pin 10 pull-up or pull-down bits */ +#define GPIO_PUD_PUD11 BITS(22,23) /*!< pin 11 pull-up or pull-down bits */ +#define GPIO_PUD_PUD12 BITS(24,25) /*!< pin 12 pull-up or pull-down bits */ +#define GPIO_PUD_PUD13 BITS(26,27) /*!< pin 13 pull-up or pull-down bits */ +#define GPIO_PUD_PUD14 BITS(28,29) /*!< pin 14 pull-up or pull-down bits */ +#define GPIO_PUD_PUD15 BITS(30,31) /*!< pin 15 pull-up or pull-down bits */ + +/* GPIO_ISTAT */ +#define GPIO_ISTAT_ISTAT0 BIT(0) /*!< pin 0 input status */ +#define GPIO_ISTAT_ISTAT1 BIT(1) /*!< pin 1 input status */ +#define GPIO_ISTAT_ISTAT2 BIT(2) /*!< pin 2 input status */ +#define GPIO_ISTAT_ISTAT3 BIT(3) /*!< pin 3 input status */ +#define GPIO_ISTAT_ISTAT4 BIT(4) /*!< pin 4 input status */ +#define GPIO_ISTAT_ISTAT5 BIT(5) /*!< pin 5 input status */ +#define GPIO_ISTAT_ISTAT6 BIT(6) /*!< pin 6 input status */ +#define GPIO_ISTAT_ISTAT7 BIT(7) /*!< pin 7 input status */ +#define GPIO_ISTAT_ISTAT8 BIT(8) /*!< pin 8 input status */ +#define GPIO_ISTAT_ISTAT9 BIT(9) /*!< pin 9 input status */ +#define GPIO_ISTAT_ISTAT10 BIT(10) /*!< pin 10 input status */ +#define GPIO_ISTAT_ISTAT11 BIT(11) /*!< pin 11 input status */ +#define GPIO_ISTAT_ISTAT12 BIT(12) /*!< pin 12 input status */ +#define GPIO_ISTAT_ISTAT13 BIT(13) /*!< pin 13 input status */ +#define GPIO_ISTAT_ISTAT14 BIT(14) /*!< pin 14 input status */ +#define GPIO_ISTAT_ISTAT15 BIT(15) /*!< pin 15 input status */ + +/* GPIO_OCTL */ +#define GPIO_OCTL_OCTL0 BIT(0) /*!< pin 0 output bit */ +#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output bit */ +#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output bit */ +#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output bit */ +#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output bit */ +#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output bit */ +#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output bit */ +#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output bit */ +#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output bit */ +#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output bit */ +#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output bit */ +#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output bit */ +#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output bit */ +#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output bit */ +#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output bit */ +#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output bit */ + +/* GPIO_BOP */ +#define GPIO_BOP_BOP0 BIT(0) /*!< pin 0 set bit */ +#define GPIO_BOP_BOP1 BIT(1) /*!< pin 1 set bit */ +#define GPIO_BOP_BOP2 BIT(2) /*!< pin 2 set bit */ +#define GPIO_BOP_BOP3 BIT(3) /*!< pin 3 set bit */ +#define GPIO_BOP_BOP4 BIT(4) /*!< pin 4 set bit */ +#define GPIO_BOP_BOP5 BIT(5) /*!< pin 5 set bit */ +#define GPIO_BOP_BOP6 BIT(6) /*!< pin 6 set bit */ +#define GPIO_BOP_BOP7 BIT(7) /*!< pin 7 set bit */ +#define GPIO_BOP_BOP8 BIT(8) /*!< pin 8 set bit */ +#define GPIO_BOP_BOP9 BIT(9) /*!< pin 9 set bit */ +#define GPIO_BOP_BOP10 BIT(10) /*!< pin 10 set bit */ +#define GPIO_BOP_BOP11 BIT(11) /*!< pin 11 set bit */ +#define GPIO_BOP_BOP12 BIT(12) /*!< pin 12 set bit */ +#define GPIO_BOP_BOP13 BIT(13) /*!< pin 13 set bit */ +#define GPIO_BOP_BOP14 BIT(14) /*!< pin 14 set bit */ +#define GPIO_BOP_BOP15 BIT(15) /*!< pin 15 set bit */ +#define GPIO_BOP_CR0 BIT(16) /*!< pin 0 clear bit */ +#define GPIO_BOP_CR1 BIT(17) /*!< pin 1 clear bit */ +#define GPIO_BOP_CR2 BIT(18) /*!< pin 2 clear bit */ +#define GPIO_BOP_CR3 BIT(19) /*!< pin 3 clear bit */ +#define GPIO_BOP_CR4 BIT(20) /*!< pin 4 clear bit */ +#define GPIO_BOP_CR5 BIT(21) /*!< pin 5 clear bit */ +#define GPIO_BOP_CR6 BIT(22) /*!< pin 6 clear bit */ +#define GPIO_BOP_CR7 BIT(23) /*!< pin 7 clear bit */ +#define GPIO_BOP_CR8 BIT(24) /*!< pin 8 clear bit */ +#define GPIO_BOP_CR9 BIT(25) /*!< pin 9 clear bit */ +#define GPIO_BOP_CR10 BIT(26) /*!< pin 10 clear bit */ +#define GPIO_BOP_CR11 BIT(27) /*!< pin 11 clear bit */ +#define GPIO_BOP_CR12 BIT(28) /*!< pin 12 clear bit */ +#define GPIO_BOP_CR13 BIT(29) /*!< pin 13 clear bit */ +#define GPIO_BOP_CR14 BIT(30) /*!< pin 14 clear bit */ +#define GPIO_BOP_CR15 BIT(31) /*!< pin 15 clear bit */ + +/* GPIO_LOCK */ +#define GPIO_LOCK_LK0 BIT(0) /*!< pin 0 lock bit */ +#define GPIO_LOCK_LK1 BIT(1) /*!< pin 1 lock bit */ +#define GPIO_LOCK_LK2 BIT(2) /*!< pin 2 lock bit */ +#define GPIO_LOCK_LK3 BIT(3) /*!< pin 3 lock bit */ +#define GPIO_LOCK_LK4 BIT(4) /*!< pin 4 lock bit */ +#define GPIO_LOCK_LK5 BIT(5) /*!< pin 5 lock bit */ +#define GPIO_LOCK_LK6 BIT(6) /*!< pin 6 lock bit */ +#define GPIO_LOCK_LK7 BIT(7) /*!< pin 7 lock bit */ +#define GPIO_LOCK_LK8 BIT(8) /*!< pin 8 lock bit */ +#define GPIO_LOCK_LK9 BIT(9) /*!< pin 9 lock bit */ +#define GPIO_LOCK_LK10 BIT(10) /*!< pin 10 lock bit */ +#define GPIO_LOCK_LK11 BIT(11) /*!< pin 11 lock bit */ +#define GPIO_LOCK_LK12 BIT(12) /*!< pin 12 lock bit */ +#define GPIO_LOCK_LK13 BIT(13) /*!< pin 13 lock bit */ +#define GPIO_LOCK_LK14 BIT(14) /*!< pin 14 lock bit */ +#define GPIO_LOCK_LK15 BIT(15) /*!< pin 15 lock bit */ +#define GPIO_LOCK_LKK BIT(16) /*!< pin sequence lock key */ + +/* GPIO_AFSEL0 */ +#define GPIO_AFSEL0_SEL0 BITS(0,3) /*!< pin 0 alternate function selected */ +#define GPIO_AFSEL0_SEL1 BITS(4,7) /*!< pin 1 alternate function selected */ +#define GPIO_AFSEL0_SEL2 BITS(8,11) /*!< pin 2 alternate function selected */ +#define GPIO_AFSEL0_SEL3 BITS(12,15) /*!< pin 3 alternate function selected */ +#define GPIO_AFSEL0_SEL4 BITS(16,19) /*!< pin 4 alternate function selected */ +#define GPIO_AFSEL0_SEL5 BITS(20,23) /*!< pin 5 alternate function selected */ +#define GPIO_AFSEL0_SEL6 BITS(24,27) /*!< pin 6 alternate function selected */ +#define GPIO_AFSEL0_SEL7 BITS(28,31) /*!< pin 7 alternate function selected */ + +/* GPIO_AFSEL1 */ +#define GPIO_AFSEL1_SEL8 BITS(0,3) /*!< pin 8 alternate function selected */ +#define GPIO_AFSEL1_SEL9 BITS(4,7) /*!< pin 9 alternate function selected */ +#define GPIO_AFSEL1_SEL10 BITS(8,11) /*!< pin 10 alternate function selected */ +#define GPIO_AFSEL1_SEL11 BITS(12,15) /*!< pin 11 alternate function selected */ +#define GPIO_AFSEL1_SEL12 BITS(16,19) /*!< pin 12 alternate function selected */ +#define GPIO_AFSEL1_SEL13 BITS(20,23) /*!< pin 13 alternate function selected */ +#define GPIO_AFSEL1_SEL14 BITS(24,27) /*!< pin 14 alternate function selected */ +#define GPIO_AFSEL1_SEL15 BITS(28,31) /*!< pin 15 alternate function selected */ + +/* GPIO_BC */ +#define GPIO_BC_CR0 BIT(0) /*!< pin 0 clear bit */ +#define GPIO_BC_CR1 BIT(1) /*!< pin 1 clear bit */ +#define GPIO_BC_CR2 BIT(2) /*!< pin 2 clear bit */ +#define GPIO_BC_CR3 BIT(3) /*!< pin 3 clear bit */ +#define GPIO_BC_CR4 BIT(4) /*!< pin 4 clear bit */ +#define GPIO_BC_CR5 BIT(5) /*!< pin 5 clear bit */ +#define GPIO_BC_CR6 BIT(6) /*!< pin 6 clear bit */ +#define GPIO_BC_CR7 BIT(7) /*!< pin 7 clear bit */ +#define GPIO_BC_CR8 BIT(8) /*!< pin 8 clear bit */ +#define GPIO_BC_CR9 BIT(9) /*!< pin 9 clear bit */ +#define GPIO_BC_CR10 BIT(10) /*!< pin 10 clear bit */ +#define GPIO_BC_CR11 BIT(11) /*!< pin 11 clear bit */ +#define GPIO_BC_CR12 BIT(12) /*!< pin 12 clear bit */ +#define GPIO_BC_CR13 BIT(13) /*!< pin 13 clear bit */ +#define GPIO_BC_CR14 BIT(14) /*!< pin 14 clear bit */ +#define GPIO_BC_CR15 BIT(15) /*!< pin 15 clear bit */ + +#ifdef GD32F170_190 +/* 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 */ + +#endif /* GD32F170_190 */ + +/* 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) /*!< without weak pull-up and pull-down resistors */ +#define GPIO_PUPD_PULLUP PUD_PUPD(1) /*!< with weak pull-up resistor */ +#define GPIO_PUPD_PULLDOWN PUD_PUPD(2) /*!< with weak pull-down resistor */ + +/* GPIO pin definitions */ +#define GPIO_PIN_0 BIT(0) /*!< GPIO pin 0 */ +#define GPIO_PIN_1 BIT(1) /*!< GPIO pin 1 */ +#define GPIO_PIN_2 BIT(2) /*!< GPIO pin 2 */ +#define GPIO_PIN_3 BIT(3) /*!< GPIO pin 3 */ +#define GPIO_PIN_4 BIT(4) /*!< GPIO pin 4 */ +#define GPIO_PIN_5 BIT(5) /*!< GPIO pin 5 */ +#define GPIO_PIN_6 BIT(6) /*!< GPIO pin 6 */ +#define GPIO_PIN_7 BIT(7) /*!< GPIO pin 7 */ +#define GPIO_PIN_8 BIT(8) /*!< GPIO pin 8 */ +#define GPIO_PIN_9 BIT(9) /*!< GPIO pin 9 */ +#define GPIO_PIN_10 BIT(10) /*!< GPIO pin 10 */ +#define GPIO_PIN_11 BIT(11) /*!< GPIO pin 11 */ +#define GPIO_PIN_12 BIT(12) /*!< GPIO pin 12 */ +#define GPIO_PIN_13 BIT(13) /*!< GPIO pin 13 */ +#define GPIO_PIN_14 BIT(14) /*!< GPIO pin 14 */ +#define GPIO_PIN_15 BIT(15) /*!< GPIO pin 15 */ +#define GPIO_PIN_ALL BITS(0,15) /*!< GPIO pin all */ + +/* GPIO mode configuration values */ +#define GPIO_MODE_SET(n, mode) ((uint32_t)((uint32_t)(mode) << (2U * (n)))) +#define GPIO_MODE_MASK(n) (0x3U << (2U * (n))) + +/* GPIO pull-up/pull-down values */ +#define GPIO_PUPD_SET(n, pupd) ((uint32_t)((uint32_t)(pupd) << (2U * (n)))) +#define GPIO_PUPD_MASK(n) (0x3U << (2U * (n))) + +/* GPIO output speed values */ +#define GPIO_OSPEED_SET(n, speed) ((uint32_t)((uint32_t)(speed) << (2U * (n)))) +#define GPIO_OSPEED_MASK(n) (0x3U << (2U * (n))) + +/* GPIO output type */ +#define GPIO_OTYPE_PP ((uint8_t)(0x00U)) /*!< push pull mode */ +#define GPIO_OTYPE_OD ((uint8_t)(0x01U)) /*!< open drain mode */ + +/* GPIO output max speed value */ +#define OSPD_OSPD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_OSPEED_2MHZ OSPD_OSPD(0) /*!< output max speed 2M */ +#define GPIO_OSPEED_10MHZ OSPD_OSPD(1) /*!< output max speed 10M */ +#define GPIO_OSPEED_50MHZ OSPD_OSPD(3) /*!< output max speed 50M */ + +/* GPIO alternate function values */ +#define GPIO_AFR_SET(n, af) ((uint32_t)((uint32_t)(af) << (4U * (n)))) +#define GPIO_AFR_MASK(n) (0xFU << (4U * (n))) + +/* GPIO alternate function */ +#define AF(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define GPIO_AF_0 AF(0) /*!< alternate function selected 0 */ +#define GPIO_AF_1 AF(1) /*!< alternate function selected 1 */ +#define GPIO_AF_2 AF(2) /*!< alternate function selected 2 */ +#define GPIO_AF_3 AF(3) /*!< alternate function selected 3 */ +#define GPIO_AF_4 AF(4) /*!< alternate function selected 4 */ +#define GPIO_AF_5 AF(5) /*!< alternate function selected 5 */ +#define GPIO_AF_6 AF(6) /*!< alternate function selected 6 */ +#define GPIO_AF_7 AF(7) /*!< alternate function selected 7 */ +#define GPIO_AF_8 AF(8) /*!< alternate function selected 8 */ +#define GPIO_AF_9 AF(9) /*!< alternate function selected 9 */ +#define GPIO_AF_10 AF(10) /*!< alternate function selected 10 */ +#define GPIO_AF_11 AF(11) /*!< alternate function selected 11 */ + +/* 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); + +#ifdef GD32F170_190 + +/* 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 /* GD32F170_190 */ + +#endif /* GD32F1X0_GPIO_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_i2c.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_i2c.h new file mode 100644 index 0000000..909f6ad --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_i2c.h @@ -0,0 +1,341 @@ +/*! + \file gd32f1x0_i2c.h + \brief definitions for the I2C +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_I2C_H +#define GD32F1X0_I2C_H + +#include "gd32f1x0.h" + +/* I2Cx(x=0,1) definitions */ +#define I2C0 I2C_BASE /*!< I2C0 base address */ +#define I2C1 (I2C_BASE+0x400U) /*!< I2C1 base address */ +#ifdef GD32F170_190 +#define I2C2 (I2C_BASE+0x6C00U) /*!< I2C2 base address */ +#endif /* GD32F170_190 */ + +/* registers definitions */ +#define I2C_CTL0(i2cx) REG32((i2cx) + 0x00U) /*!< I2C control register 0 */ +#define I2C_CTL1(i2cx) REG32((i2cx) + 0x04U) /*!< I2C control register 1 */ +#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x08U) /*!< I2C slave address register 0*/ +#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0CU) /*!< I2C slave address register */ +#define I2C_DATA(i2cx) REG32((i2cx) + 0x10U) /*!< I2C transfer buffer register */ +#define I2C_STAT0(i2cx) REG32((i2cx) + 0x14U) /*!< I2C transfer status register 0 */ +#define I2C_STAT1(i2cx) REG32((i2cx) + 0x18U) /*!< I2C transfer status register */ +#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x1CU) /*!< I2C clock configure register */ +#define I2C_RT(i2cx) REG32((i2cx) + 0x20U) /*!< I2C rise time register */ +#ifdef GD32F170_190 +#define I2C_SAMCS(i2cx) REG32((i2cx) + 0x80U) /*!< I2C SAM control and status register */ +#endif /* GD32F170_190 */ + +/* bits definitions */ +/* I2Cx_CTL0 */ +#define I2C_CTL0_I2CEN BIT(0) /*!< peripheral enable */ +#define I2C_CTL0_SMBEN BIT(1) /*!< SMBus mode */ +#define I2C_CTL0_SMBSEL BIT(3) /*!< SMBus type */ +#define I2C_CTL0_ARPEN BIT(4) /*!< ARP enable */ +#define I2C_CTL0_PECEN BIT(5) /*!< PEC enable */ +#define I2C_CTL0_GCEN BIT(6) /*!< general call enable */ +#define I2C_CTL0_DISSTRC BIT(7) /*!< clock stretching disable (slave mode) */ +#define I2C_CTL0_START BIT(8) /*!< start generation */ +#define I2C_CTL0_STOP BIT(9) /*!< stop generation */ +#define I2C_CTL0_ACKEN BIT(10) /*!< acknowledge enable */ +#define I2C_CTL0_POAP BIT(11) /*!< acknowledge/PEC position (for data reception) */ +#define I2C_CTL0_PECTRANS BIT(12) /*!< packet error checking */ +#define I2C_CTL0_SALT BIT(13) /*!< SMBus alert */ +#define I2C_CTL0_SRESET BIT(15) /*!< software reset */ + +/* I2Cx_CTL1 */ +#define I2C_CTL1_I2CCLK BITS(0,5) /*!< I2CCLK[5:0] bits (peripheral clock frequency) */ +#define I2C_CTL1_ERRIE BIT(8) /*!< error interrupt inable */ +#define I2C_CTL1_EVIE BIT(9) /*!< event interrupt enable */ +#define I2C_CTL1_BUFIE BIT(10) /*!< buffer interrupt enable */ +#define I2C_CTL1_DMAON BIT(11) /*!< DMA requests enable */ +#define I2C_CTL1_DMALST BIT(12) /*!< DMA last transfer */ + +/* I2Cx_SADDR0 */ +#define I2C_SADDR0_ADDRESS0 BIT(0) /*!< bit 0 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS BITS(1,7) /*!< 7-bit address or bits 7:1 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS_H BITS(8,9) /*!< highest two bits of a 10-bit address */ +#define I2C_SADDR0_ADDFORMAT BIT(15) /*!< address mode for the I2C slave */ + +/* I2Cx_SADDR1 */ +#define I2C_SADDR1_DUADEN BIT(0) /*!< aual-address mode switch */ +#define I2C_SADDR1_ADDRESS2 BITS(1,7) /*!< second I2C address for the slave in dual-address mode */ + +/* I2Cx_DATA */ +#define I2C_DATA_TRB BITS(0,7) /*!< 8-bit data register */ + +/* I2Cx_STAT0 */ +#define I2C_STAT0_SBSEND BIT(0) /*!< start bit (master mode) */ +#define I2C_STAT0_ADDSEND BIT(1) /*!< address sent (master mode)/matched (slave mode) */ +#define I2C_STAT0_BTC BIT(2) /*!< byte transfer finished */ +#define I2C_STAT0_ADD10SEND BIT(3) /*!< 10-bit header sent (master mode) */ +#define I2C_STAT0_STPDET BIT(4) /*!< stop detection (slave mode) */ +#define I2C_STAT0_RBNE BIT(6) /*!< data register not empty (receivers) */ +#define I2C_STAT0_TBE BIT(7) /*!< data register empty (transmitters) */ +#define I2C_STAT0_BERR BIT(8) /*!< bus error */ +#define I2C_STAT0_LOSTARB BIT(9) /*!< arbitration lost (master mode) */ +#define I2C_STAT0_AERR BIT(10) /*!< acknowledge failure */ +#define I2C_STAT0_OUERR BIT(11) /*!< overrun/underrun */ +#define I2C_STAT0_PECERR BIT(12) /*!< PEC error in reception */ +#define I2C_STAT0_SMBTO BIT(14) /*!< timeout signal in SMBus mode */ +#define I2C_STAT0_SMBALT BIT(15) /*!< SMBus alert status */ + +/* I2Cx_STAT1 */ +#define I2C_STAT1_MASTER BIT(0) /*!< master/slave */ +#define I2C_STAT1_I2CBSY BIT(1) /*!< bus busy */ +#define I2C_STAT1_TRS BIT(2) /*!< transmitter/receiver */ +#define I2C_STAT1_RXGC BIT(4) /*!< general call address (slave mode) */ +#define I2C_STAT1_DEFSMB BIT(5) /*!< SMBus device default address (slave mode) */ +#define I2C_STAT1_HSTSMB BIT(6) /*!< SMBus host header (slave mode) */ +#define I2C_STAT1_DUMODF BIT(7) /*!< dual flag (slave mode) */ +#define I2C_STAT1_ECV BITS(8,15) /*!< packet error checking value */ + +/* I2Cx_CKCFG */ +#define I2C_CKCFG_CLKC BITS(0,11) /*!< clock control register in fast/standard mode (master mode) */ +#define I2C_CKCFG_DTCY BIT(14) /*!< fast mode duty cycle */ +#define I2C_CKCFG_FAST BIT(15) /*!< I2C speed selection in master mode */ + +/* I2Cx_RT */ +#define I2C_RT_RISETIME BITS(0,5) /*!< maximum rise time in fast/standard mode (Master mode) */ + +#ifdef GD32F170_190 +/* I2Cx_SAMCS */ +#define I2C_SAMCS_SAMEN BIT(0) /*!< SAM_V interface enable */ +#define I2C_SAMCS_STOEN BIT(1) /*!< SAM_V interface timeout detect enable */ +#define I2C_SAMCS_TFFIE BIT(4) /*!< txframe fall interrupt enable */ +#define I2C_SAMCS_TFRIE BIT(5) /*!< txframe rise interrupt enable */ +#define I2C_SAMCS_RFFIE BIT(6) /*!< rxframe fall interrupt enable */ +#define I2C_SAMCS_RFRIE BIT(7) /*!< rxframe rise interrupt enable */ +#define I2C_SAMCS_TXF BIT(8) /*!< level of txframe signal */ +#define I2C_SAMCS_RXF BIT(9) /*!< level of rxframe signal */ +#define I2C_SAMCS_TFF BIT(12) /*!< txframe fall flag, cleared by software write 0 */ +#define I2C_SAMCS_TFR BIT(13) /*!< txframe rise flag, cleared by software write 0 */ +#define I2C_SAMCS_RFF BIT(14) /*!< rxframe fall flag, cleared by software write 0 */ +#define I2C_SAMCS_RFR BIT(15) /*!< rxframe rise flag, cleared by software write 0 */ +#endif /* GD32F170_190 */ + +/* constants definitions */ +/* SMBus/I2C mode switch and SMBus type selection */ +#define I2C_I2CMODE_ENABLE ((uint32_t)0x00000000U) /*!< I2C mode */ +#define I2C_SMBUSMODE_ENABLE I2C_CTL0_SMBEN /*!< SMBus mode */ + +/* SMBus/I2C mode switch and SMBus type selection */ +#define I2C_SMBUS_DEVICE ((uint32_t)0x00000000U) /*!< SMBus mode device type */ +#define I2C_SMBUS_HOST I2C_CTL0_SMBSEL /*!< SMBus mode host type */ + +/* I2C transfer direction */ +#define I2C_RECEIVER ((uint32_t)0x00000001U) /*!< receiver */ +#define I2C_TRANSMITTER ((uint32_t)0xFFFFFFFEU) /*!< transmitter */ + +/* whether or not to send an ACK */ +#define I2C_ACK_DISABLE ((uint32_t)0x00000000U) /*!< ACK will be not sent */ +#define I2C_ACK_ENABLE ((uint32_t)0x00000001U) /*!< ACK will be sent */ + +/* I2C POAP position*/ +#define I2C_ACKPOS_NEXT ((uint32_t)0x00000000U) /*!< ACKEN bit decides whether or not to send ACK for the next byte */ +#define I2C_ACKPOS_CURRENT ((uint32_t)0x00000001U) /*!< ACKEN bit decides whether or not to send ACK or not for the current byte */ + +/* I2C dual-address mode switch */ +#define I2C_DUADEN_DISABLE ((uint32_t)0x00000000U) /*!< dual-address mode disabled */ +#define I2C_DUADEN_ENABLE ((uint32_t)0x00000001U) /*!< dual-address mode enabled */ + +/* whether or not to stretch SCL low */ +#define I2C_SCLSTRETCH_ENABLE ((uint32_t)0x00000000U) /*!< SCL stretching is enabled */ +#define I2C_SCLSTRETCH_DISABLE I2C_CTL0_DISSTRC /*!< SCL stretching is disabled */ + +/* whether or not to response to a general call */ +#define I2C_GCEN_ENABLE I2C_CTL0_GCEN /*!< slave will response to a general call */ +#define I2C_GCEN_DISABLE ((uint32_t)0x00000000U) /*!< slave will not response to a general call */ + +/* software reset I2C */ +#define I2C_SRESET_SET I2C_CTL0_SRESET /*!< I2C is under reset */ +#define I2C_SRESET_RESET ((uint32_t)0x00000000U) /*!< I2C is not under reset */ + +/* I2C DMA mode configure */ +/* DMA mode switch */ +#define I2C_DMA_ON I2C_CTL1_DMAON /*!< DMA mode enabled */ +#define I2C_DMA_OFF ((uint32_t)0x00000000U) /*!< DMA mode disabled */ + +/* flag indicating DMA last transfer */ +#define I2C_DMALST_ON I2C_CTL1_DMALST /*!< next DMA EOT is the last transfer */ +#define I2C_DMALST_OFF ((uint32_t)0x00000000U) /*!< next DMA EOT is not the last transfer */ + +/* I2C PEC configure */ +/* PEC enable */ +#define I2C_PEC_ENABLE I2C_CTL0_PECEN /*!< PEC calculation on */ +#define I2C_PEC_DISABLE ((uint32_t)0x00000000U) /*!< PEC calculation off */ + +/* PEC transfer */ +#define I2C_PECTRANS_ENABLE I2C_CTL0_PECTRANS /*!< transfer PEC */ +#define I2C_PECTRANS_DISABLE ((uint32_t)0x00000000U) /*!< not transfer PEC value */ + +/* I2C SMBus configure */ +/* issue or not alert through SMBA pin */ +#define I2C_SALTSEND_ENABLE I2C_CTL0_SALT /*!< issue alert through SMBA pin */ +#define I2C_SALTSEND_DISABLE ((uint32_t)0x00000000U) /*!< not issue alert through SMBA */ + +/* ARP protocol in SMBus switch */ +#define I2C_ARP_ENABLE I2C_CTL0_ARPEN /*!< ARP enable */ +#define I2C_ARP_DISABLE ((uint32_t)0x00000000U) /*!< ARP disable */ + +/* fast mode plus enable */ +#define I2C_FAST_MODE_PLUS_ENABLE I2C_FMPCFG_FMPEN /*!< fast mode plus enable */ +#define I2C_FAST_MODE_PLUS_DISABLE ((uint32_t)0x00000000U) /*!< fast mode plus disable */ + +/* transmit I2C data */ +#define DATA_TRANS(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* receive I2C data */ +#define DATA_RECV(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* I2C flag definitions */ +#define I2C_FLAG_SBSEND BIT(0) /*!< start condition sent out in master mode */ +#define I2C_FLAG_ADDSEND BIT(1) /*!< address is sent in master mode or received and matches in slave mode */ +#define I2C_FLAG_BTC BIT(2) /*!< byte transmission finishes */ +#define I2C_FLAG_ADD10SEND BIT(3) /*!< header of 10-bit address is sent in master mode */ +#define I2C_FLAG_STPDET BIT(4) /*!< etop condition detected in slave mode */ +#define I2C_FLAG_RBNE BIT(6) /*!< I2C_DATA is not Empty during receiving */ +#define I2C_FLAG_TBE BIT(7) /*!< I2C_DATA is empty during transmitting */ +#define I2C_FLAG_BERR BIT(8) /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */ +#define I2C_FLAG_LOSTARB BIT(9) /*!< arbitration lost in master mode */ +#define I2C_FLAG_AERR BIT(10) /*!< acknowledge error */ +#define I2C_FLAG_OUERR BIT(11) /*!< over-run or under-run situation occurs in slave mode */ +#define I2C_FLAG_PECERR BIT(12) /*!< PEC error when receiving data */ +#define I2C_FLAG_SMBTO BIT(14) /*!< timeout signal in SMBus mode */ +#define I2C_FLAG_SMBALT BIT(15) /*!< SMBus alert status */ +#define I2C_FLAG_MASTER (BIT(0)|BIT(31)) /*!< a flag indicating whether I2C block is in master or slave mode */ +#define I2C_FLAG_I2CBSY (BIT(1)|BIT(31)) /*!< busy flag */ +#define I2C_FLAG_TRS (BIT(2)|BIT(31)) /*!< whether the I2C is a transmitter or a receiver */ +#define I2C_FLAG_RXGC (BIT(4)|BIT(31)) /*!< general call address (00h) received */ +#define I2C_FLAG_DEFSMB (BIT(5)|BIT(31)) /*!< default address of SMBus device */ +#define I2C_FLAG_HSTSMB (BIT(6)|BIT(31)) /*!< SMBus host header detected in slave mode */ +#define I2C_FLAG_DUMOD (BIT(7)|BIT(31)) /*!< dual flag in slave mode indicating which address is matched in dual-address mode */ + +/* I2C interrupt flags */ +#define I2C_INT_FLAG_SBSEND I2C_FLAG_SBSEND /*!< start condition sent out in master mode interrupt flag */ +#define I2C_INT_FLAG_ADDSEND I2C_FLAG_ADDSEND /*!< address is sent in master mode or received and matches in slave mode interrupt flag */ +#define I2C_INT_FLAG_BTC I2C_FLAG_BTC /*!< byte transmission finishes */ +#define I2C_INT_FLAG_ADD10SEND I2C_FLAG_ADD10SEND /*!< header of 10-bit address is sent in master mode interrupt flag */ +#define I2C_INT_FLAG_STPDET I2C_FLAG_STPDET /*!< stop condition detected in slave mode interrupt flag */ +#define I2C_INT_FLAG_RBNE I2C_FLAG_RBNE /*!< I2C_DATA is not Empty during receiving interrupt flag */ +#define I2C_INT_FLAG_TBE I2C_FLAG_TBE /*!< I2C_DATA is empty during transmitting interrupt flag */ +#define I2C_INT_FLAG_BERR I2C_FLAG_BERR /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag */ +#define I2C_INT_FLAG_LOSTARB I2C_FLAG_LOSTARB /*!< arbitration lost in master mode interrupt flag */ +#define I2C_INT_FLAG_AERR I2C_FLAG_AERR /*!< acknowledge error interrupt flag */ +#define I2C_INT_FLAG_OUERR I2C_FLAG_OUERR /*!< over-run or under-run situation occurs in slave mode interrupt flag */ +#define I2C_INT_FLAG_PECERR I2C_FLAG_PECERR /*!< PEC error when receiving data interrupt flag */ +#define I2C_INT_FLAG_SMBTO I2C_FLAG_SMBTO /*!< timeout signal in SMBus mode interrupt flag */ +#define I2C_INT_FLAG_SMBALT I2C_FLAG_SMBALT /*!< SMBus Alert status interrupt flag */ + +/* I2C interrupt enable bit */ +#define I2C_INT_ERR I2C_CTL1_ERRIE /*!< error interrupt enable */ +#define I2C_INT_EV I2C_CTL1_EVIE /*!< event interrupt enable */ +#define I2C_INT_BUF I2C_CTL1_BUFIE /*!< buffer interrupt enable */ + +/* I2C duty cycle in fast mode */ +#define CKCFG_DTCY(regval) (BIT(14) & ((uint32_t)(regval) << 14)) +#define I2C_DTCY_2 CKCFG_DTCY(0) /*!< I2C fast mode Tlow/Thigh = 2 */ +#define I2C_DTCY_16_9 CKCFG_DTCY(1) /*!< I2C fast mode Tlow/Thigh = 16/9 */ + +/* address mode for the I2C slave */ +#define SADDR0_ADDFORMAT(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define I2C_ADDFORMAT_7BITS SADDR0_ADDFORMAT(0) /*!< address:7 bits */ +#define I2C_ADDFORMAT_10BITS SADDR0_ADDFORMAT(1) /*!< address:10 bits */ + +/* function declarations */ +/* reset I2C */ +void i2c_deinit(uint32_t i2c_periph); +/* configure I2C clock */ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc); +/* configure I2C address */ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr); +/* SMBus type selection */ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type); +/* whether or not to send an ACK */ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack); +/* configure I2C POAP position */ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos); +/* master send slave address */ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection); +/* dual-address mode switch */ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t dualaddr); + +/* enable I2C */ +void i2c_enable(uint32_t i2c_periph); +/* disable I2C */ +void i2c_disable(uint32_t i2c_periph); +/* generate a START condition on I2C bus */ +void i2c_start_on_bus(uint32_t i2c_periph); +/* generate a STOP condition on I2C bus */ +void i2c_stop_on_bus(uint32_t i2c_periph); +/* I2C transmit data function */ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data); +/* I2C receive data function */ +uint8_t i2c_data_receive(uint32_t i2c_periph); +/* I2C DMA mode enable */ +void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate); +/* flag indicating DMA last transfer */ +void i2c_dma_last_transfer_enable(uint32_t i2c_periph, uint32_t dmalast); +/* whether to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara ); +/* whether or not to response to a general call */ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara); +/* software reset I2C */ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset); + +/* check I2C flag is set or not */ +FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag); +/* clear I2C flag */ +void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag); +/* enable I2C interrupt */ +void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t inttype); +/* disable I2C interrupt */ +void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t inttype); +/* check I2C interrupt flag */ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph,uint32_t intflag); +/* clear I2C interrupt flag */ +void i2c_interrupt_flag_clear(uint32_t i2c_periph,uint32_t intflag); + +/* I2C PEC calculation on or off */ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate); +/* I2C whether to transfer PEC value */ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara); +/* packet error checking value */ +uint8_t i2c_pec_value_get(uint32_t i2c_periph); +/* I2C issue alert through SMBA pin */ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara); +/* I2C ARP protocol in SMBus switch */ +void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate); + +#ifdef GD32F170_190 +/* enable SAM_V interface */ +void i2c_sam_enable(uint32_t i2c_periph); +/* disable SAM_V interface */ +void i2c_sam_disable(uint32_t i2c_periph); +/* enable SAM_V interface timeout detect */ +void i2c_sam_timeout_enable(uint32_t i2c_periph); +/* disable SAM_V interface timeout detect */ +void i2c_sam_timeout_disable(uint32_t i2c_periph); +/* enable the specified I2C SAM interrupt */ +void i2c_sam_interrupt_enable(uint32_t i2c_periph, uint32_t inttype); +/* disable the specified I2C SAM interrupt */ +void i2c_sam_interrupt_disable(uint32_t i2c_periph, uint32_t inttype); +/* check i2c SAM state */ +FlagStatus i2c_sam_flag_get(uint32_t i2c_periph, uint32_t samstate); +/* clear i2c SAM state */ +void i2c_sam_flag_clear(uint32_t i2c_periph, uint32_t samstate); +#endif /*GD32F170_190*/ + +#endif /* GD32F1X0_I2C_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_ivref.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_ivref.h new file mode 100644 index 0000000..df4f146 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_ivref.h @@ -0,0 +1,217 @@ +/*! + \file gd32f1x0_ivref.h + \brief definitions for the IVREF +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 + +#ifndef GD32F1X0_IVREF_H +#define GD32F1X0_IVREF_H + +#include "gd32f1x0.h" + +/* IVREF definitions */ +#define IVREF IVREF_BASE + +/* registers definitions */ +#define IVREF_CTL REG32(IVREF + 0x300U) /*!< IVREF control register */ + +/* bits definitions */ +/* IVREF_CTL */ +#define IVREF_CTL_CSDT BITS(0,5) /*!< current step data */ +#define IVREF_CTL_SCMOD BIT(7) /*!< sink current mode */ +#define IVREF_CTL_CPT BITS(8,12) /*!< current precision trim */ +#define IVREF_CTL_SSEL BIT(14) /*!< step selection */ +#define IVREF_CTL_CREN BIT(15) /*!< current reference enable */ +#define IVREF_CTL_VPT BITS(24,28) /*!< voltage precision trim */ +#define IVREF_CTL_DECAP BIT(30) /*!< connect/disconnect external capacitor */ +#define IVREF_CTL_VREN BIT(31) /*!< voltage reference enable */ + +/* constants definitions */ +/* vref mode selection */ +#define VREF_DISCONNECT_EXTERNAL_CAP BIT(30) /*!< VREF disconnect external capacitor */ +#define VREF_CONNECT_EXTERNAL_CAP ((uint32_t)0x00000000) /*!< VREF connect external capacitor */ + +/* vref voltage precision trim */ +#define CTL_VPT(regval) (BITS(24,28) & ((regval) << 24)) +#define VREF_VOLT_PRECISION_TRIM_0 CTL_VPT(0) /*!< VREF voltage precision trim 0 */ +#define VREF_VOLT_PRECISION_TRIM_1 CTL_VPT(1) /*!< VREF voltage precision trim 1 */ +#define VREF_VOLT_PRECISION_TRIM_2 CTL_VPT(2) /*!< VREF voltage precision trim 2 */ +#define VREF_VOLT_PRECISION_TRIM_3 CTL_VPT(3) /*!< VREF voltage precision trim 3 */ +#define VREF_VOLT_PRECISION_TRIM_4 CTL_VPT(4) /*!< VREF voltage precision trim 4 */ +#define VREF_VOLT_PRECISION_TRIM_5 CTL_VPT(5) /*!< VREF voltage precision trim 5 */ +#define VREF_VOLT_PRECISION_TRIM_6 CTL_VPT(6) /*!< VREF voltage precision trim 6 */ +#define VREF_VOLT_PRECISION_TRIM_7 CTL_VPT(7) /*!< VREF voltage precision trim 7 */ +#define VREF_VOLT_PRECISION_TRIM_8 CTL_VPT(8) /*!< VREF voltage precision trim 8 */ +#define VREF_VOLT_PRECISION_TRIM_9 CTL_VPT(9) /*!< VREF voltage precision trim 9 */ +#define VREF_VOLT_PRECISION_TRIM_10 CTL_VPT(10) /*!< VREF voltage precision trim 10 */ +#define VREF_VOLT_PRECISION_TRIM_11 CTL_VPT(11) /*!< VREF voltage precision trim 11 */ +#define VREF_VOLT_PRECISION_TRIM_12 CTL_VPT(12) /*!< VREF voltage precision trim 12 */ +#define VREF_VOLT_PRECISION_TRIM_13 CTL_VPT(13) /*!< VREF voltage precision trim 13 */ +#define VREF_VOLT_PRECISION_TRIM_14 CTL_VPT(14) /*!< VREF voltage precision trim 14 */ +#define VREF_VOLT_PRECISION_TRIM_15 CTL_VPT(15) /*!< VREF voltage precision trim 15 */ +#define VREF_VOLT_PRECISION_TRIM_16 CTL_VPT(16) /*!< VREF voltage precision trim 16 */ +#define VREF_VOLT_PRECISION_TRIM_17 CTL_VPT(17) /*!< VREF voltage precision trim 17 */ +#define VREF_VOLT_PRECISION_TRIM_18 CTL_VPT(18) /*!< VREF voltage precision trim 18 */ +#define VREF_VOLT_PRECISION_TRIM_19 CTL_VPT(19) /*!< VREF voltage precision trim 19 */ +#define VREF_VOLT_PRECISION_TRIM_20 CTL_VPT(20) /*!< VREF voltage precision trim 20 */ +#define VREF_VOLT_PRECISION_TRIM_21 CTL_VPT(21) /*!< VREF voltage precision trim 21 */ +#define VREF_VOLT_PRECISION_TRIM_22 CTL_VPT(22) /*!< VREF voltage precision trim 22 */ +#define VREF_VOLT_PRECISION_TRIM_23 CTL_VPT(23) /*!< VREF voltage precision trim 23 */ +#define VREF_VOLT_PRECISION_TRIM_24 CTL_VPT(24) /*!< VREF voltage precision trim 24 */ +#define VREF_VOLT_PRECISION_TRIM_25 CTL_VPT(25) /*!< VREF voltage precision trim 25 */ +#define VREF_VOLT_PRECISION_TRIM_26 CTL_VPT(26) /*!< VREF voltage precision trim 26 */ +#define VREF_VOLT_PRECISION_TRIM_27 CTL_VPT(27) /*!< VREF voltage precision trim 27 */ +#define VREF_VOLT_PRECISION_TRIM_28 CTL_VPT(28) /*!< VREF voltage precision trim 28 */ +#define VREF_VOLT_PRECISION_TRIM_29 CTL_VPT(29) /*!< VREF voltage precision trim 29 */ +#define VREF_VOLT_PRECISION_TRIM_30 CTL_VPT(30) /*!< VREF voltage precision trim 30 */ +#define VREF_VOLT_PRECISION_TRIM_31 CTL_VPT(31) /*!< VREF voltage precision trim 31 */ + +/* iref current precision trim */ +#define CTL_CPT(regval) (BITS(8,12) & ((regval) << 8)) +#define IREF_CUR_PRECISION_TRIM_0 CTL_CPT(0) /*!< IREF current precision trim 0 */ +#define IREF_CUR_PRECISION_TRIM_1 CTL_CPT(1) /*!< IREF current precision trim 1 */ +#define IREF_CUR_PRECISION_TRIM_2 CTL_CPT(2) /*!< IREF current precision trim 2 */ +#define IREF_CUR_PRECISION_TRIM_3 CTL_CPT(3) /*!< IREF current precision trim 3 */ +#define IREF_CUR_PRECISION_TRIM_4 CTL_CPT(4) /*!< IREF current precision trim 4 */ +#define IREF_CUR_PRECISION_TRIM_5 CTL_CPT(5) /*!< IREF current precision trim 5 */ +#define IREF_CUR_PRECISION_TRIM_6 CTL_CPT(6) /*!< IREF current precision trim 6 */ +#define IREF_CUR_PRECISION_TRIM_7 CTL_CPT(7) /*!< IREF current precision trim 7 */ +#define IREF_CUR_PRECISION_TRIM_8 CTL_CPT(8) /*!< IREF current precision trim 8 */ +#define IREF_CUR_PRECISION_TRIM_9 CTL_CPT(9) /*!< IREF current precision trim 9 */ +#define IREF_CUR_PRECISION_TRIM_10 CTL_CPT(10) /*!< IREF current precision trim 10 */ +#define IREF_CUR_PRECISION_TRIM_11 CTL_CPT(11) /*!< IREF current precision trim 11 */ +#define IREF_CUR_PRECISION_TRIM_12 CTL_CPT(12) /*!< IREF current precision trim 12 */ +#define IREF_CUR_PRECISION_TRIM_13 CTL_CPT(13) /*!< IREF current precision trim 13 */ +#define IREF_CUR_PRECISION_TRIM_14 CTL_CPT(14) /*!< IREF current precision trim 14 */ +#define IREF_CUR_PRECISION_TRIM_15 CTL_CPT(15) /*!< IREF current precision trim 15 */ +#define IREF_CUR_PRECISION_TRIM_16 CTL_CPT(16) /*!< IREF current precision trim 16 */ +#define IREF_CUR_PRECISION_TRIM_17 CTL_CPT(17) /*!< IREF current precision trim 17 */ +#define IREF_CUR_PRECISION_TRIM_18 CTL_CPT(18) /*!< IREF current precision trim 18 */ +#define IREF_CUR_PRECISION_TRIM_19 CTL_CPT(19) /*!< IREF current precision trim 19 */ +#define IREF_CUR_PRECISION_TRIM_20 CTL_CPT(20) /*!< IREF current precision trim 20 */ +#define IREF_CUR_PRECISION_TRIM_21 CTL_CPT(21) /*!< IREF current precision trim 21 */ +#define IREF_CUR_PRECISION_TRIM_22 CTL_CPT(22) /*!< IREF current precision trim 22 */ +#define IREF_CUR_PRECISION_TRIM_23 CTL_CPT(23) /*!< IREF current precision trim 23 */ +#define IREF_CUR_PRECISION_TRIM_24 CTL_CPT(24) /*!< IREF current precision trim 24 */ +#define IREF_CUR_PRECISION_TRIM_25 CTL_CPT(25) /*!< IREF current precision trim 25 */ +#define IREF_CUR_PRECISION_TRIM_26 CTL_CPT(26) /*!< IREF current precision trim 26 */ +#define IREF_CUR_PRECISION_TRIM_27 CTL_CPT(27) /*!< IREF current precision trim 27 */ +#define IREF_CUR_PRECISION_TRIM_28 CTL_CPT(28) /*!< IREF current precision trim 28 */ +#define IREF_CUR_PRECISION_TRIM_29 CTL_CPT(29) /*!< IREF current precision trim 29 */ +#define IREF_CUR_PRECISION_TRIM_30 CTL_CPT(30) /*!< IREF current precision trim 30 */ +#define IREF_CUR_PRECISION_TRIM_31 CTL_CPT(31) /*!< IREF current precision trim 31 */ + +/* iref mode selection */ +#define IREF_MODE_LOW_POWER ((uint32_t)0x00000000) +#define IREF_MODE_HIGH_CURRENT BIT(14) + +/* iref current step */ +#define CTL_CSDA(regval) (BITS(0,5) & ((regval) << 5)) +#define IREF_CUR_STEP_DATA_0 CTL_CSDA(0) /*!< IREF current step data 0 */ +#define IREF_CUR_STEP_DATA_1 CTL_CSDA(1) /*!< IREF current step data 1 */ +#define IREF_CUR_STEP_DATA_2 CTL_CSDA(2) /*!< IREF current step data 2 */ +#define IREF_CUR_STEP_DATA_3 CTL_CSDA(3) /*!< IREF current step data 3 */ +#define IREF_CUR_STEP_DATA_4 CTL_CSDA(4) /*!< IREF current step data 4 */ +#define IREF_CUR_STEP_DATA_5 CTL_CSDA(5) /*!< IREF current step data 5 */ +#define IREF_CUR_STEP_DATA_6 CTL_CSDA(6) /*!< IREF current step data 6 */ +#define IREF_CUR_STEP_DATA_7 CTL_CSDA(7) /*!< IREF current step data 7 */ +#define IREF_CUR_STEP_DATA_8 CTL_CSDA(8) /*!< IREF current step data 8 */ +#define IREF_CUR_STEP_DATA_9 CTL_CSDA(9) /*!< IREF current step data 9 */ +#define IREF_CUR_STEP_DATA_10 CTL_CSDA(10) /*!< IREF current step data 10 */ +#define IREF_CUR_STEP_DATA_11 CTL_CSDA(11) /*!< IREF current step data 11 */ +#define IREF_CUR_STEP_DATA_12 CTL_CSDA(12) /*!< IREF current step data 12 */ +#define IREF_CUR_STEP_DATA_13 CTL_CSDA(13) /*!< IREF current step data 13 */ +#define IREF_CUR_STEP_DATA_14 CTL_CSDA(14) /*!< IREF current step data 14 */ +#define IREF_CUR_STEP_DATA_15 CTL_CSDA(15) /*!< IREF current step data 15 */ +#define IREF_CUR_STEP_DATA_16 CTL_CSDA(16) /*!< IREF current step data 16 */ +#define IREF_CUR_STEP_DATA_17 CTL_CSDA(17) /*!< IREF current step data 17 */ +#define IREF_CUR_STEP_DATA_18 CTL_CSDA(18) /*!< IREF current step data 18 */ +#define IREF_CUR_STEP_DATA_19 CTL_CSDA(19) /*!< IREF current step data 19 */ +#define IREF_CUR_STEP_DATA_20 CTL_CSDA(20) /*!< IREF current step data 20 */ +#define IREF_CUR_STEP_DATA_21 CTL_CSDA(21) /*!< IREF current step data 21 */ +#define IREF_CUR_STEP_DATA_22 CTL_CSDA(22) /*!< IREF current step data 22 */ +#define IREF_CUR_STEP_DATA_23 CTL_CSDA(23) /*!< IREF current step data 23 */ +#define IREF_CUR_STEP_DATA_24 CTL_CSDA(24) /*!< IREF current step data 24 */ +#define IREF_CUR_STEP_DATA_25 CTL_CSDA(25) /*!< IREF current step data 25 */ +#define IREF_CUR_STEP_DATA_26 CTL_CSDA(26) /*!< IREF current step data 26 */ +#define IREF_CUR_STEP_DATA_27 CTL_CSDA(27) /*!< IREF current step data 27 */ +#define IREF_CUR_STEP_DATA_28 CTL_CSDA(28) /*!< IREF current step data 28 */ +#define IREF_CUR_STEP_DATA_29 CTL_CSDA(29) /*!< IREF current step data 29 */ +#define IREF_CUR_STEP_DATA_30 CTL_CSDA(30) /*!< IREF current step data 30 */ +#define IREF_CUR_STEP_DATA_31 CTL_CSDA(31) /*!< IREF current step data 31 */ +#define IREF_CUR_STEP_DATA_32 CTL_CSDA(32) /*!< IREF current step data 32 */ +#define IREF_CUR_STEP_DATA_33 CTL_CSDA(33) /*!< IREF current step data 33 */ +#define IREF_CUR_STEP_DATA_34 CTL_CSDA(34) /*!< IREF current step data 34 */ +#define IREF_CUR_STEP_DATA_35 CTL_CSDA(35) /*!< IREF current step data 35 */ +#define IREF_CUR_STEP_DATA_36 CTL_CSDA(36) /*!< IREF current step data 36 */ +#define IREF_CUR_STEP_DATA_37 CTL_CSDA(37) /*!< IREF current step data 37 */ +#define IREF_CUR_STEP_DATA_38 CTL_CSDA(38) /*!< IREF current step data 38 */ +#define IREF_CUR_STEP_DATA_39 CTL_CSDA(39) /*!< IREF current step data 39 */ +#define IREF_CUR_STEP_DATA_40 CTL_CSDA(40) /*!< IREF current step data 40 */ +#define IREF_CUR_STEP_DATA_41 CTL_CSDA(41) /*!< IREF current step data 41 */ +#define IREF_CUR_STEP_DATA_42 CTL_CSDA(42) /*!< IREF current step data 42 */ +#define IREF_CUR_STEP_DATA_43 CTL_CSDA(43) /*!< IREF current step data 43 */ +#define IREF_CUR_STEP_DATA_44 CTL_CSDA(44) /*!< IREF current step data 44 */ +#define IREF_CUR_STEP_DATA_45 CTL_CSDA(45) /*!< IREF current step data 45 */ +#define IREF_CUR_STEP_DATA_46 CTL_CSDA(46) /*!< IREF current step data 46 */ +#define IREF_CUR_STEP_DATA_47 CTL_CSDA(47) /*!< IREF current step data 47 */ +#define IREF_CUR_STEP_DATA_48 CTL_CSDA(48) /*!< IREF current step data 48 */ +#define IREF_CUR_STEP_DATA_49 CTL_CSDA(49) /*!< IREF current step data 49 */ +#define IREF_CUR_STEP_DATA_50 CTL_CSDA(50) /*!< IREF current step data 50 */ +#define IREF_CUR_STEP_DATA_51 CTL_CSDA(51) /*!< IREF current step data 51 */ +#define IREF_CUR_STEP_DATA_52 CTL_CSDA(52) /*!< IREF current step data 52 */ +#define IREF_CUR_STEP_DATA_53 CTL_CSDA(53) /*!< IREF current step data 53 */ +#define IREF_CUR_STEP_DATA_54 CTL_CSDA(54) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_55 CTL_CSDA(55) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_56 CTL_CSDA(56) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_57 CTL_CSDA(57) /*!< IREF current step data 57 */ +#define IREF_CUR_STEP_DATA_58 CTL_CSDA(58) /*!< IREF current step data 58 */ +#define IREF_CUR_STEP_DATA_59 CTL_CSDA(59) /*!< IREF current step data 59 */ +#define IREF_CUR_STEP_DATA_60 CTL_CSDA(60) /*!< IREF current step data 60 */ +#define IREF_CUR_STEP_DATA_61 CTL_CSDA(61) /*!< IREF current step data 61 */ +#define IREF_CUR_STEP_DATA_62 CTL_CSDA(62) /*!< IREF current step data 62 */ +#define IREF_CUR_STEP_DATA_63 CTL_CSDA(63) /*!< IREF current step data 63 */ + +/* iref sink current mode*/ +#define IREF_SOURCE_CURRENT ((uint32_t)0x00000000) /*!< IREF source current */ +#define IREF_SINK_CURRENT BIT(7) /*!< IREF sink current */ + +/* function declarations */ + +/* deinit vref */ +void ivref_deinit(void); +/* enable vref */ +void vref_enable(void); +/* disable vref */ +void vref_disable(void); +/* enable vref */ +void iref_enable(void); +/* disable iref */ +void iref_disable(void); + +/* set verf mode */ +void vref_mode_set(uint32_t vrefmode); +/* set vrer voltage precision trim value */ +void vref_precision_trim_value_set(uint32_t precisiontrim); +/* set iref mode*/ +void iref_mode_set(uint32_t irefmode); +/* set iref sink current mode*/ +void iref_sink_set(uint32_t irefsinkmode); +/* set iref current precision trim value */ +void iref_precision_trim_value_set(uint32_t precisiontrim); +/* set iref step data*/ +void iref_step_data_config(uint32_t irefstepdata); + +#endif /* GD32F1X0_IVREF_H */ + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_libopt.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_misc.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_misc.h new file mode 100644 index 0000000..9983c14 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_misc.h @@ -0,0 +1,71 @@ +/*! + \file gd32f1x0_misc.h + \brief definitions for the MISC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_MISC_H +#define GD32F1X0_MISC_H + +#include "gd32f1x0.h" + +/* constants definitions */ +/* set the RAM and FLASH base address */ +#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000U) /*!< RAM base address */ +#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000U) /*!< Flash base address */ + +/* set the NVIC vector table offset mask */ +#define NVIC_VECTTAB_OFFSET_MASK ((uint32_t)0x1FFFFF80U) + +/* the register key mask, if you want to do the write operation, you should write 0x5FA to VECTKEY bits */ +#define NVIC_AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000U) + +/* priority group - define the pre-emption priority and the subpriority */ +#define NVIC_PRIGROUP_PRE0_SUB4 ((uint32_t)0x700U) /*!< 0 bits for pre-emption priority 4 bits for subpriority */ +#define NVIC_PRIGROUP_PRE1_SUB3 ((uint32_t)0x600U) /*!< 1 bits for pre-emption priority 3 bits for subpriority */ +#define NVIC_PRIGROUP_PRE2_SUB2 ((uint32_t)0x500U) /*!< 2 bits for pre-emption priority 2 bits for subpriority */ +#define NVIC_PRIGROUP_PRE3_SUB1 ((uint32_t)0x400U) /*!< 3 bits for pre-emption priority 1 bits for subpriority */ +#define NVIC_PRIGROUP_PRE4_SUB0 ((uint32_t)0x300U) /*!< 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)0x02U) /*!< choose the the system whether enter low power mode by exiting from ISR */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04U) /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10U) /*!< choose the interrupt source that can wake up the lowpower mode */ + +#define SCB_LPM_SLEEP_EXIT_ISR SCB_SCR_SLEEPONEXIT +#define SCB_LPM_DEEPSLEEP SCB_SCR_SLEEPDEEP +#define SCB_LPM_WAKE_BY_ALL_INT SCB_SCR_SEVONPEND + +/* choose the systick clock source */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from HCLK/8 */ +#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U) /*!< systick clock source is from HCLK */ + +/* function declarations */ +/* set the priority group */ +void nvic_priority_group_set(uint32_t nvic_prigroup); + +/* enable NVIC request */ +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority); +/* disable NVIC request */ +void nvic_irq_disable(uint8_t nvic_irq); + +/* set the NVIC vector table base address */ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset); + +/* set the state of the low power mode */ +void system_lowpower_set(uint8_t lowpower_mode); +/* reset the state of the low power mode */ +void system_lowpower_reset(uint8_t lowpower_mode); + +/* set the systick clock source */ +void systick_clksource_set(uint32_t systick_clksource); + +#endif /* GD32F1X0_MISC_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_opa.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_opa.h new file mode 100644 index 0000000..7b2fc1e --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_opa.h @@ -0,0 +1,140 @@ +/*! + \file gd32f1x0_opa.h + \brief definitions for the OPA +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 + +#ifndef GD32F1X0_OPA_H +#define GD32F1X0_OPA_H + +#include "gd32f1x0.h" + +/* OPAx(x=0,1,2) definitions */ +#define OPA OPA_BASE +#define OPA0 ((uint32_t)0) +#define OPA1 ((uint32_t)1) +#define OPA2 ((uint32_t)2) + +/* registers definitions */ +#define OPA_CTL REG32(OPA + 0x00U) /*!< OPA control register */ +#define OPA_BT REG32(OPA + 0x04U) /*!< OPA bias trimming register for normal mode */ +#define OPA_LPBT REG32(OPA + 0x08U) /*!< OPA bias trimming register for low power mode */ + +/* bits definitions */ +/* OPA_CLT */ +#define OPA_CTL_OPA0PD BIT(0) /*!< OPA0 power down */ +#define OPA_CTL_T3OPA0 BIT(1) /*!< T3 switch enable for OPA0 */ +#define OPA_CTL_S1OPA0 BIT(2) /*!< S1 switch enable for OPA0 */ +#define OPA_CTL_S2OPA0 BIT(3) /*!< S2 switch enable for OPA0 */ +#define OPA_CTL_S3OPA0 BIT(4) /*!< S3 switch enable for OPA0 */ +#define OPA_CTL_OPA0CAL_L BIT(5) /*!< OPA1 offset calibration for P diff */ +#define OPA_CTL_OPA0CAL_H BIT(6) /*!< OPA1 offset calibration for N diff */ +#define OPA_CTL_OPA0LPM BIT(7) /*!< OPA0 low power mode */ +#define OPA_CTL_OPA1PD BIT(8) /*!< OPA1 power down */ +#define OPA_CTL_T3OPA1 BIT(9) /*!< T3 switch enable for OPA1 */ +#define OPA_CTL_S1OPA1 BIT(10) /*!< S1 switch enable for OPA1 */ +#define OPA_CTL_S2OPA1 BIT(11) /*!< S2 switch enable for OPA1 */ +#define OPA_CTL_S3OPA1 BIT(12) /*!< S3 switch enable for OPA1 */ +#define OPA_CTL_OPA1CAL_L BIT(13) /*!< OPA1 offset calibration for P diff */ +#define OPA_CTL_OPA1CAL_H BIT(14) /*!< OPA1 offset calibration for N diff */ +#define OPA_CTL_OPA1LPM BIT(15) /*!< OPA1 low power mode */ +#define OPA_CTL_OPA2PD BIT(16) /*!< OPA2 power down */ +#define OPA_CTL_T3OPA2 BIT(17) /*!< T3 switch enable for OPA2 */ +#define OPA_CTL_S1OPA2 BIT(18) /*!< S1 switch enable for OPA2 */ +#define OPA_CTL_S2OPA2 BIT(19) /*!< S2 switch enable for OPA2 */ +#define OPA_CTL_S3OPA2 BIT(20) /*!< S3 switch enable for OPA2 */ +#define OPA_CTL_OPA2CAL_L BIT(21) /*!< OPA2 offset calibration for P diff */ +#define OPA_CTL_OPA2CAL_H BIT(22) /*!< OPA2 offset calibration for N diff */ +#define OPA_CTL_OPA2LPM BIT(23) /*!< OPA2 low power mode */ +#define OPA_CTL_S4OPA1 BIT(27) /*!< S4 switch enable for OPA2 */ +#define OPA_CTL_OPA_RANGE BIT(28) /*!< Power supply range */ +#define OPA_CTL_OPA0CALOUT BIT(29) /*!< OPA0 calibration output */ +#define OPA_CTL_OPA1CALOUT BIT(30) /*!< OPA1 calibration output */ +#define OPA_CTL_OPA2CALOUT BIT(31) /*!< OPA2 calibration output */ + +/* OPA_BT */ +#define OPA_BT_OA0_TRIM_LOW BITS(0,4) /*!< OPA0, normal mode 5-bit bias trim value for PMOS pairs */ +#define OPA_BT_OA0_TRIM_HIGH BITS(5,9) /*!< OPA0, normal mode 5-bit bias trim value for NMOS pairs */ +#define OPA_BT_OA1_TRIM_LOW BITS(10,14) /*!< OPA1, normal mode 5-bit bias trim value for PMOS pairs */ +#define OPA_BT_OA1_TRIM_HIGH BITS(15,19) /*!< OPA1, normal mode 5-bit bias trim value for NMOS pairs */ +#define OPA_BT_OA2_TRIM_LOW BITS(20,24) /*!< OPA2, normal mode 5-bit bias trim value for PMOS pairs*/ +#define OPA_BT_OA2_TRIM_HIGH BITS(25,29) /*!< OPA2, normal mode 5-bit bias trim value for NMOS pairs */ +#define OPA_BT_OT_USER BIT(31) /*!< OPA trimming mode */ + +/* OPA_LPBT */ +#define OPA_LPBT_OA0_TRIM_LOW BITS(0,4) /*!< OPA0, low-power mode 5-bit bias trim value for PMOS pairs */ +#define OPA_LPBT_OA0_TRIM_HIGH BITS(5,9) /*!< OPA0, low-power mode 5-bit bias trim value for NMOS pairs */ +#define OPA_LPBT_OA1_TRIM_LOW BITS(10,14) /*!< OPA1, low-power mode 5-bit bias trim value for PMOS pairs */ +#define OPA_LPBT_OA1_TRIM_HIGH BITS(15,19) /*!< OPA1, low-power mode 5-bit bias trim value for NMOS pairs */ +#define OPA_LPBT_OA2_TRIM_LOW BITS(20,24) /*!< OPA2, low-power mode 5-bit bias trim value for PMOS pairs */ +#define OPA_LPBT_OA2_TRIM_HIGH BITS(25,29) /*!< OPA2, low-power mode 5-bit bias trim value for NMOS pairs */ + +/* constants definitions */ +/* opa switch definitions */ +#define OPA_T3OPA0 OPA_CTL_T3OPA0 /*!< T3 switch enable for OPA0 */ +#define OPA_S1OPA0 OPA_CTL_S1OPA0 /*!< S1 switch enable for OPA0 */ +#define OPA_S2OPA0 OPA_CTL_S2OPA0 /*!< S2 switch enable for OPA0 */ +#define OPA_S3OPA0 OPA_CTL_S3OPA0 /*!< S3 switch enable for OPA0 */ +#define OPA_T3OPA1 OPA_CTL_S3OPA1 /*!< T3 switch enable for OPA1 */ +#define OPA_S1OPA1 OPA_CTL_S1OPA1 /*!< S1 switch enable for OPA1 */ +#define OPA_S2OPA1 OPA_CTL_S2OPA1 /*!< S2 switch enable for OPA1 */ +#define OPA_S3OPA1 OPA_CTL_S3OPA1 /*!< S3 switch enable for OPA1 */ +#define OPA_S4OPA1 OPA_CTL_S4OPA1 /*!< S4 switch enable for OPA1 */ +#define OPA_T3OPA2 OPA_CTL_T3OPA2 /*!< T3 switch enable for OPA2 */ +#define OPA_S1OPA2 OPA_CTL_S1OPA2 /*!< S1 switch enable for OPA2 */ +#define OPA_S2OPA2 OPA_CTL_S2OPA2 /*!< S2 switch enable for OPA2 */ +#define OPA_S3OPA2 OPA_CTL_S3OPA2 /*!< S3 switch enable for OPA2 */ + +/* opa trimming mode */ +#define OPA_BT_TRIM_FACTORY ((uint32_t)0x00000000) /*!< factory trimming */ +#define OPA_BT_TRIM_USER OPA_BT_OT_USER /*!< user trimming */ + +/* opa input */ +#define OPA_INPUT_N ((uint32_t)0x00000040) /*!< NMOS input */ +#define OPA_INPUT_P ((uint32_t)0x00000020) /*!< PMOS input */ + +/* opa power range */ +#define OPA_POWRANGE_LOW ((uint32_t)0x00000000) /*!< low power range is selected (VDDA is lower than 3.3V) */ +#define OPA_POWRANGE_HIGH OPA_CTL_OPA_RANGE /*!< high power range is selected (VDDA is higher than 3.3V) */ + +/* function declarations */ + +/* deinit opa */ +void opa_deinit(void); +/* enable opa */ +void opa_enable(uint32_t opa_periph); +/* disable opa */ +void opa_disable(uint32_t opa_periph); +/* enable opa switch */ +void opa_switch_enable(uint32_t opax_swy); +/* disable opa switch */ +void opa_switch_disable(uint32_t opax_swy); +/* enable opa low_power mode */ +void opa_low_power_enable(uint32_t opa_periph); +/* dis opa low_power mode */ +void opa_low_power_disable(uint32_t opa_periph); +/* set opa power range */ +void opa_power_range_config(uint32_t powerrange); +/* set opa bias trimming mode */ +void opa_trim_mode_set(uint32_t opa_trimmode); + +/* set opa bias trimming value normal mode */ +void opa_trim_value_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue); +/* set opa bias trimming value low power mode */ +void opa_trim_value_lp_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue); +/* get opa calibration flag */ +FlagStatus opa_cal_out_get(uint32_t opa_periph); + +#endif /* GD32F1X0_OPA_H */ + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_pmu.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_pmu.h new file mode 100644 index 0000000..86fa4f0 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_pmu.h @@ -0,0 +1,108 @@ +/*! + \file gd32f1x0_pmu.h + \brief definitions for the PMU +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_PMU_H +#define GD32F1X0_PMU_H + +#include "gd32f1x0.h" + +/* PMU definitions */ +#define PMU PMU_BASE + +/* registers definitions */ +#define PMU_CTL REG32((PMU) + 0x00U) /*!< PMU control register */ +#define PMU_CS REG32((PMU) + 0x04U) /*!< PMU control and status register */ + +/* bits definitions */ +/* PMU_CTL */ +#define PMU_CTL_LDOLP BIT(0) /*!< ldo low power mode */ +#define PMU_CTL_STBMOD BIT(1) /*!< standby mode */ +#define PMU_CTL_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL_LVDEN BIT(4) /*!< low voltage detector enable */ +#define PMU_CTL_LVDT BITS(5,7) /*!< low voltage detector threshold */ +#define PMU_CTL_BKPWEN BIT(8) /*!< backup domain write enable */ + +/* PMU_CS */ +#define PMU_CS_WUF BIT(0) /*!< wakeup flag */ +#define PMU_CS_STBF BIT(1) /*!< standby flag */ +#define PMU_CS_LVDF BIT(2) /*!< low voltage detector status flag */ +#define PMU_CS_WUPEN0 BIT(8) /*!< wakeup pin 0 enable */ +#define PMU_CS_WUPEN1 BIT(9) /*!< wakeup pin 1 enable */ + +/* constants definitions */ +/* PMU low voltage detector threshold definitions */ +#define CTL_LVDT(regval) (BITS(5,7)&((uint32_t)(regval) << 5)) +#define PMU_LVDT_0 CTL_LVDT(0) /*!< voltage threshold is 2.2V */ +#define PMU_LVDT_1 CTL_LVDT(1) /*!< voltage threshold is 2.3V */ +#define PMU_LVDT_2 CTL_LVDT(2) /*!< voltage threshold is 2.4V */ +#define PMU_LVDT_3 CTL_LVDT(3) /*!< voltage threshold is 2.5V */ +#define PMU_LVDT_4 CTL_LVDT(4) /*!< voltage threshold is 2.6V */ +#define PMU_LVDT_5 CTL_LVDT(5) /*!< voltage threshold is 2.7V */ +#define PMU_LVDT_6 CTL_LVDT(6) /*!< voltage threshold is 2.8V */ +#define PMU_LVDT_7 CTL_LVDT(7) /*!< voltage threshold is 2.9V */ + +/* 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 */ + +/* PMU ldo definitions */ +#define PMU_LDO_NORMAL ((uint32_t)0x00000000) /*!< LDO normal work when pmu enter deepsleep mode */ +#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when pmu enter deepsleep mode */ + +/* PMU flag reset definitions */ +#define PMU_FLAG_RESET_WAKEUP ((uint8_t)0x00) /*!< wakeup flag reset */ +#define PMU_FLAG_RESET_STANDBY ((uint8_t)0x01) /*!< standby flag reset */ + +/* PMU command constants definitions */ +#define WFI_CMD ((uint8_t)0x00) /*!< use WFI command */ +#define WFE_CMD ((uint8_t)0x01) /*!< use WFE command */ + +/* PMU wakeup pin definitions */ +#define PMU_WAKEUP_PIN0 PMU_CS_WUPEN0 /*!< wakeup pin 0 */ +#define PMU_WAKEUP_PIN1 PMU_CS_WUPEN1 /*!< wakeup pin 1 */ + +/* function declarations */ + +/* PMU reset */ +void pmu_deinit(void); +/* select low voltage detector threshold */ +void pmu_lvd_select(uint32_t lvdt_n); +/* PMU lvd disable */ +void pmu_lvd_disable(void); + +/* PMU work at sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* PMU work at deepsleep mode */ +void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd); +/* PMU work at standby mode */ +void pmu_to_standbymode(uint8_t standbymodecmd); + +/* reset flag bit */ +void pmu_flag_clear(uint32_t flag_reset); +/* get flag state */ +FlagStatus pmu_flag_get(uint32_t flag); + +/* PMU backup domain write enable */ +void pmu_backup_write_enable(void); +/* PMU backup domain write disable */ +void pmu_backup_write_disable(void); + +/* wakeup pin enable */ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin); +/* wakeup pin disable */ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin); + +#endif /* GD32F1X0_PMU_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_rcu.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_rcu.h new file mode 100644 index 0000000..9396151 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_rcu.h @@ -0,0 +1,972 @@ +/*! + \file gd32f1x0_rcu.h + \brief definitions for the RCU +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_RCU_H +#define GD32F1X0_RCU_H + +#include "gd32f1x0.h" + +/* RCU definitions */ +#define RCU RCU_BASE + +/* registers definitions */ +#define RCU_CTL0 REG32(RCU + 0x00U) /*!< control register 0 */ +#define RCU_CFG0 REG32(RCU + 0x04U) /*!< configuration register 0 */ +#define RCU_INT REG32(RCU + 0x08U) /*!< interrupt register */ +#define RCU_APB2RST REG32(RCU + 0x0CU) /*!< APB2 reset register */ +#define RCU_APB1RST REG32(RCU + 0x10U) /*!< APB1 reset register */ +#define RCU_AHBEN REG32(RCU + 0x14U) /*!< AHB enable register */ +#define RCU_APB2EN REG32(RCU + 0x18U) /*!< APB2 enable register */ +#define RCU_APB1EN REG32(RCU + 0x1CU) /*!< APB1 enable register */ +#define RCU_BDCTL REG32(RCU + 0x20U) /*!< backup domain control register */ +#define RCU_RSTSCK REG32(RCU + 0x24U) /*!< reset source /clock register */ +#define RCU_AHBRST REG32(RCU + 0x28U) /*!< AHB reset register */ +#define RCU_CFG1 REG32(RCU + 0x2CU) /*!< configuration register 1 */ +#define RCU_CFG2 REG32(RCU + 0x30U) /*!< configuration register 2 */ +#define RCU_CTL1 REG32(RCU + 0x34U) /*!< control register 1 */ +#ifdef GD32F170_190 +#define RCU_CFG3 REG32(RCU + 0x80U) /*!< configuration register 3 */ +#endif /* GD32F170_190 */ +#define RCU_ADDAPB1EN REG32(RCU + 0xF8U) /*!< APB1 additional enable register */ +#define RCU_ADDAPB1RST REG32(RCU + 0xFCU) /*!< APB1 additional reset register */ +#define RCU_VKEY REG32(RCU + 0x100U) /*!< voltage key register */ +#define RCU_DSV REG32(RCU + 0x134U) /*!< deep-sleep mode voltage register */ +#ifdef GD32F130_150 +#define RCU_PDVSEL REG32(RCU + 0x138U) /*!< power down voltage select register */ +#endif /* GD32F130_150 */ + +/* bits definitions */ +/* RCU_CTL0 */ +#define RCU_CTL0_IRC8MEN BIT(0) /*!< internal high speed oscillator enable */ +#define RCU_CTL0_IRC8MSTB BIT(1) /*!< IRC8M high speed internal oscillator stabilization flag */ +#define RCU_CTL0_IRC8MADJ BITS(3,7) /*!< high speed internal oscillator clock trim adjust value */ +#define RCU_CTL0_IRC8MCALIB BITS(8,15) /*!< high speed internal oscillator calibration value register */ +#define RCU_CTL0_HXTALEN BIT(16) /*!< external high speed oscillator enable */ +#define RCU_CTL0_HXTALSTB BIT(17) /*!< external crystal oscillator clock stabilization flag */ +#define RCU_CTL0_HXTALBPS BIT(18) /*!< external crystal oscillator clock bypass mode enable */ +#define RCU_CTL0_CKMEN BIT(19) /*!< HXTAL clock monitor enable */ +#define RCU_CTL0_PLLEN BIT(24) /*!< PLL enable */ +#define RCU_CTL0_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_ADCPSC BITS(14,15) /*!< ADC clock prescaler selection */ +#define RCU_CFG0_PLLSEL BIT(16) /*!< PLL clock source selection */ +#define RCU_CFG0_PLLPREDV BIT(17) /*!< HXTAL divider for PLL source clock selection */ +#define RCU_CFG0_PLLMF (BIT(27) | BITS(18,21)) /*!< PLL multiply factor */ +#ifdef GD32F130_150 +#define RCU_CFG0_USBDPSC BITS(22,23) /*!< USBD clock prescaler selection */ +#define RCU_CFG0_CKOUTSEL BITS(24,26) /*!< CK_OUT clock source selection */ +#elif defined (GD32F170_190) +#define RCU_CFG0_CKOUT0SEL BITS(24,26) /*!< CK_OUT0 clock source selection */ +#endif /* GD32F130_150 */ +#define RCU_CFG0_PLLMF4 BIT(27) /*!< bit 4 of PLLMF */ +#ifdef GD32F130_150 +#define RCU_CFG0_CKOUTDIV BITS(28,30) /*!< CK_OUT divider which the CK_OUT frequency can be reduced */ +#elif defined (GD32F170_190) +#define RCU_CFG0_CKOUT0DIV BITS(28,30) /*!< CK_OUT0 divider which the CK_OUT0 frequency can be reduced */ +#endif /* GD32F130_150 */ +#define RCU_CFG0_PLLDV BIT(31) /*!< CK_PLL divide by 1 or 2 for CK_OUT(GD32F130_150) or CK_OUT0(GD32F170_190) */ + +/* 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 */ +#ifdef GD32F130_150 +#define RCU_INT_IRC14MSTBIF BIT(5) /*!< IRC14M stabilization interrupt flag */ +#elif defined (GD32F170_190) +#define RCU_INT_IRC28MSTBIF BIT(5) /*!< IRC28M stabilization interrupt flag */ +#endif /* GD32F130_150 */ +#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 */ +#ifdef GD32F130_150 +#define RCU_INT_IRC14MSTBIE BIT(13) /*!< IRC14M stabilization interrupt enable */ +#elif defined (GD32F170_190) +#define RCU_INT_IRC28MSTBIE BIT(13) /*!< IRC28M stabilization interrupt enable */ +#endif /* GD32F130_150 */ +#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 */ +#ifdef GD32F130_150 +#define RCU_INT_IRC14MSTBIC BIT(21) /*!< IRC14M stabilization interrupt clear */ +#elif defined (GD32F170_190) +#define RCU_INT_IRC28MSTBIC BIT(21) /*!< IRC28M stabilization interrupt clear */ +#endif /* GD32F130_150 */ +#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_ADCRST BIT(9) /*!< ADC reset */ +#define RCU_APB2RST_TIMER0RST BIT(11) /*!< TIMER0 reset */ +#define RCU_APB2RST_SPI0RST BIT(12) /*!< SPI0 reset */ +#define RCU_APB2RST_USART0RST BIT(14) /*!< USART0 reset */ +#define RCU_APB2RST_TIMER14RST BIT(16) /*!< TIMER14 reset */ +#define RCU_APB2RST_TIMER15RST BIT(17) /*!< TIMER15 reset */ +#define RCU_APB2RST_TIMER16RST BIT(18) /*!< TIMER16 reset */ + +/* RCU_APB1RST */ +#define RCU_APB1RST_TIMER1RST BIT(0) /*!< TIMER1 timer reset */ +#define RCU_APB1RST_TIMER2RST BIT(1) /*!< TIMER2 timer reset */ +#define RCU_APB1RST_TIMER5RST BIT(4) /*!< TIMER5 timer reset */ +#define RCU_APB1RST_TIMER13RST BIT(8) /*!< TIMER13 timer reset */ +#ifdef GD32F170_190 +#define RCU_APB1RST_SLCDRST BIT(9) /*!< SLCD reset */ +#endif /* GD32F170_190 */ +#define RCU_APB1RST_WWDGTRST BIT(11) /*!< window watchdog timer reset */ +#define RCU_APB1RST_SPI1RST BIT(14) /*!< SPI1 reset */ +#define RCU_APB1RST_SPI2RST BIT(15) /*!< SPI2 reset */ +#define RCU_APB1RST_USART1RST BIT(17) /*!< USART1 reset */ +#define RCU_APB1RST_I2C0RST BIT(21) /*!< I2C0 reset */ +#define RCU_APB1RST_I2C1RST BIT(22) /*!< I2C1 reset */ +#ifdef GD32F130_150 +#define RCU_APB1RST_USBDRST BIT(23) /*!< USBD reset */ +#endif /* GD32F130_150 */ +#ifdef GD32F170_190 +#define RCU_APB1RST_CAN0RST BIT(25) /*!< CAN0 reset */ +#define RCU_APB1RST_CAN1RST BIT(26) /*!< CAN1 reset */ +#endif /* GD32F170_190 */ +#define RCU_APB1RST_PMURST BIT(28) /*!< power control reset */ +#define RCU_APB1RST_DACRST BIT(29) /*!< DAC reset */ +#define RCU_APB1RST_CECRST BIT(30) /*!< HDMI CEC reset */ +#ifdef GD32F170_190 +#define RCU_APB1RST_OPAIVREFRST BIT(31) /*!< OPA and IVREF reset */ +#endif /* GD32F170_190 */ + +/* RCU_AHBEN */ +#define RCU_AHBEN_DMAEN BIT(0) /*!< DMA clock enable */ +#define RCU_AHBEN_SRAMSPEN BIT(2) /*!< SRAM interface clock enable */ +#define RCU_AHBEN_FMCSPEN BIT(4) /*!< FMC clock enable */ +#define RCU_AHBEN_CRCEN BIT(6) /*!< CRC clock enable */ +#define RCU_AHBEN_PAEN BIT(17) /*!< GPIO port A clock enable */ +#define RCU_AHBEN_PBEN BIT(18) /*!< GPIO port B clock enable */ +#define RCU_AHBEN_PCEN BIT(19) /*!< GPIO port C clock enable */ +#define RCU_AHBEN_PDEN BIT(20) /*!< GPIO port D clock enable */ +#define RCU_AHBEN_PFEN BIT(22) /*!< GPIO port F clock enable */ +#define RCU_AHBEN_TSIEN BIT(24) /*!< TSI clock enable */ + +/* RCU_APB2EN */ +#define RCU_APB2EN_CFGCMPEN BIT(0) /*!< system configuration and comparator clock enable */ +#define RCU_APB2EN_ADCEN BIT(9) /*!< ADC interface clock enable */ +#define RCU_APB2EN_TIMER0EN BIT(11) /*!< TIMER0 timer clock enable */ +#define RCU_APB2EN_SPI0EN BIT(12) /*!< SPI0 clock enable */ +#define RCU_APB2EN_USART0EN BIT(14) /*!< USART0 clock enable */ +#define RCU_APB2EN_TIMER14EN BIT(16) /*!< TIMER14 timer clock enable */ +#define RCU_APB2EN_TIMER15EN BIT(17) /*!< TIMER15 timer clock enable */ +#define RCU_APB2EN_TIMER16EN BIT(18) /*!< TIMER16 timer clock enable */ + +/* RCU_APB1EN */ +#define RCU_APB1EN_TIMER1EN BIT(0) /*!< TIMER1 timer clock enable */ +#define RCU_APB1EN_TIMER2EN BIT(1) /*!< TIMER2 timer clock enable */ +#define RCU_APB1EN_TIMER5EN BIT(4) /*!< TIMER5 timer clock enable */ +#define RCU_APB1EN_TIMER13EN BIT(8) /*!< TIMER13 timer clock enable */ +#ifdef GD32F170_190 +#define RCU_APB1EN_SLCDEN BIT(9) /*!< SLCD clock enable */ +#endif /* GD32F170_190 */ +#define RCU_APB1EN_WWDGTEN BIT(11) /*!< window watchdog timer clock enable */ +#define RCU_APB1EN_SPI1EN BIT(14) /*!< SPI1 clock enable */ +#define RCU_APB1EN_SPI2EN BIT(15) /*!< SPI2 clock enable */ +#define RCU_APB1EN_USART1EN BIT(17) /*!< USART1 clock enable */ +#define RCU_APB1EN_I2C0EN BIT(21) /*!< I2C0 clock enable */ +#define RCU_APB1EN_I2C1EN BIT(22) /*!< I2C1 clock enable */ +#ifdef GD32F130_150 +#define RCU_APB1EN_USBDEN BIT(23) /*!< USBD clock enable */ +#endif /* GD32F130_150 */ +#ifdef GD32F170_190 +#define RCU_APB1EN_CAN0EN BIT(25) /*!< CAN0 clock enable */ +#define RCU_APB1EN_CAN1EN BIT(26) /*!< CAN1 clock enable */ +#endif /* GD32F170_190 */ +#define RCU_APB1EN_PMUEN BIT(28) /*!< power interface clock enable */ +#define RCU_APB1EN_DACEN BIT(29) /*!< DAC interface clock enable */ +#define RCU_APB1EN_CECEN BIT(30) /*!< HDMI CEC interface clock enable */ +#ifdef GD32F170_190 +#define RCU_APB1EN_OPAIVREFEN BIT(31) /*!< OPA and IVREF clock enable */ +#endif /* GD32F170_190 */ + +/* RCU_BDCTL */ +#define RCU_BDCTL_LXTALEN BIT(0) /*!< LXTAL enable */ +#define RCU_BDCTL_LXTALSTB BIT(1) /*!< external low-speed oscillator stabilization */ +#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 */ +#define RCU_RSTSCK_V12RSTF BIT(23) /*!< V12 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_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_PFRST BIT(22) /*!< GPIO port F reset */ +#define RCU_AHBRST_TSIRST BIT(24) /*!< TSI unit reset */ + +/* RCU_CFG1 */ +#define RCU_CFG1_HXTALPREDV BITS(0,3) /*!< CK_HXTAL divider previous PLL */ + +/* RCU_CFG2 */ +#define RCU_CFG2_USART0SEL BITS(0,1) /*!< CK_USART0 clock source selection */ +#define RCU_CFG2_CECSEL BIT(6) /*!< CK_CEC clock source selection */ +#define RCU_CFG2_ADCSEL BIT(8) /*!< CK_ADC clock source selection */ +#ifdef GD32F170_190 +#define RCU_CFG2_IRC28MDIV BIT(16) /*!< CK_IRC28M divider 2 or not */ +#endif /* GD32F170_190 */ + +/* RCU_CTL1 */ +#ifdef GD32F130_150 +#define RCU_CTL1_IRC14MEN BIT(0) /*!< IRC14M internal 14M RC oscillator enable */ +#define RCU_CTL1_IRC14MSTB BIT(1) /*!< IRC14M internal 14M RC oscillator stabilization flag */ +#define RCU_CTL1_IRC14MADJ BITS(3,7) /*!< internal 14M RC oscillator clock trim adjust value */ +#define RCU_CTL1_IRC14MCALIB BITS(8,15) /*!< internal 14M RC oscillator calibration value register */ +#elif defined (GD32F170_190) +#define RCU_CTL1_IRC28MEN BIT(0) /*!< IRC28M internal 28M RC oscillator enable */ +#define RCU_CTL1_IRC28MSTB BIT(1) /*!< IRC28M internal 28M RC oscillator stabilization flag */ +#define RCU_CTL1_IRC28MADJ BITS(3,7) /*!< internal 28M RC oscillator clock trim adjust value */ +#define RCU_CTL1_IRC28MCALIB BITS(8,15) /*!< internal 28M RC oscillator calibration value register */ +#endif /* GD32F130_150 */ + +#ifdef GD32F170_190 +/* RCU_CFG3 */ +#define RCU_CFG3_CKOUT1SRC BITS(0,2) /*!< CKOUT1 clock source selection */ +#define RCU_CFG3_CKOUT1DIV BITS(8,13) /*!< CK_OUT1 divider which the CK_OUT1 frequency can be reduced */ +#endif /* GD32F170_190 */ + +/* RCU_ADDAPB1EN */ +#define RCU_ADDAPB1EN_I2C2EN BIT(0) /*!< I2C2 unit clock enable */ + +/* RCU_ADDAPB1RST */ +#define RCU_ADDAPB1RST_I2C2RST BIT(0) /*!< I2C2 unit reset */ + +/* RCU_VKEY */ +#define RCU_VKEY_KEY BITS(0,31) /*!< key of RCU_PDVSEL and RCU_DSV register */ + +/* RCU_DSV */ +#define RCU_DSV_DSLPVS BITS(0,2) /*!< deep-sleep mode voltage select */ + +#ifdef GD32F130_150 +/* RCU_PDVSEL */ +#define RCU_PDVSEL_PDRVS BIT(0) /*!< power down voltage select */ +#endif /* GD32F130_150 */ + +/* constants definitions */ +/* define the peripheral clock enable bit position and its register index offset */ +#define RCU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (bitpos)) +#define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph) >> 6))) +#define RCU_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +/* define the voltage key unlock value */ +#define RCU_VKEY_UNLOCK ((uint32_t)0x1A2B3C4DU) + +/* register index */ +enum reg_idx +{ + /* peripherals enable */ + IDX_AHBEN = 0x14U, + IDX_APB2EN = 0x18U, + IDX_APB1EN = 0x1CU, + IDX_ADDAPB1EN = 0xF8U, + /* peripherals reset */ + IDX_AHBRST = 0x28U, + IDX_APB2RST = 0x0CU, + IDX_APB1RST = 0x10U, + IDX_ADDAPB1RST = 0xFCU, + /* clock stabilization */ + IDX_CTL0 = 0x00U, + IDX_BDCTL = 0x20U, + IDX_STB = 0x24U, + IDX_CTL1 = 0x34U, + /* peripheral reset */ + IDX_RSTSCK = 0x24U, + /* clock stabilization and stuck interrupt */ + IDX_INT = 0x08U, + /* configuration register */ + IDX_CFG0 = 0x04U, + IDX_CFG2 = 0x30U +}; + +/* peripheral clock enable */ +typedef enum +{ + /* AHB peripherals */ + RCU_DMA = RCU_REGIDX_BIT(IDX_AHBEN, 0U), /*!< DMA clock */ + RCU_CRC = RCU_REGIDX_BIT(IDX_AHBEN, 6U), /*!< CRC clock */ + RCU_GPIOA = RCU_REGIDX_BIT(IDX_AHBEN, 17U), /*!< GPIOA clock */ + RCU_GPIOB = RCU_REGIDX_BIT(IDX_AHBEN, 18U), /*!< GPIOB clock */ + RCU_GPIOC = RCU_REGIDX_BIT(IDX_AHBEN, 19U), /*!< GPIOC clock */ + RCU_GPIOD = RCU_REGIDX_BIT(IDX_AHBEN, 20U), /*!< GPIOD clock */ + RCU_GPIOF = RCU_REGIDX_BIT(IDX_AHBEN, 22U), /*!< GPIOF clock */ + RCU_TSI = RCU_REGIDX_BIT(IDX_AHBEN, 24U), /*!< TSI clock */ + + /* APB2 peripherals */ + RCU_CFGCMP = RCU_REGIDX_BIT(IDX_APB2EN, 0U), /*!< CFGCMP clock */ + RCU_ADC = RCU_REGIDX_BIT(IDX_APB2EN, 9U), /*!< ADC clock */ + RCU_TIMER0 = RCU_REGIDX_BIT(IDX_APB2EN, 11U), /*!< TIMER0 clock */ + RCU_SPI0 = RCU_REGIDX_BIT(IDX_APB2EN, 12U), /*!< SPI0 clock */ + RCU_USART0 = RCU_REGIDX_BIT(IDX_APB2EN, 14U), /*!< USART0 clock */ + RCU_TIMER14 = RCU_REGIDX_BIT(IDX_APB2EN, 16U), /*!< TIMER14 clock */ + RCU_TIMER15 = RCU_REGIDX_BIT(IDX_APB2EN, 17U), /*!< TIMER15 clock */ + RCU_TIMER16 = RCU_REGIDX_BIT(IDX_APB2EN, 18U), /*!< TIMER16 clock */ + + /* APB1 peripherals */ + RCU_TIMER1 = RCU_REGIDX_BIT(IDX_APB1EN, 0U), /*!< TIMER1 clock */ + RCU_TIMER2 = RCU_REGIDX_BIT(IDX_APB1EN, 1U), /*!< TIMER2 clock */ + RCU_TIMER5 = RCU_REGIDX_BIT(IDX_APB1EN, 4U), /*!< TIMER5 clock */ + RCU_TIMER13 = RCU_REGIDX_BIT(IDX_APB1EN, 8U), /*!< TIMER13 clock */ +#ifdef GD32F170_190 + RCU_SLCD = RCU_REGIDX_BIT(IDX_APB1EN, 9U), /*!< SLCD clock */ +#endif /* GD32F170_190 */ + RCU_WWDGT = RCU_REGIDX_BIT(IDX_APB1EN, 11U), /*!< WWDGT clock */ + RCU_SPI1 = RCU_REGIDX_BIT(IDX_APB1EN, 14U), /*!< SPI1 clock */ + RCU_SPI2 = RCU_REGIDX_BIT(IDX_APB1EN, 15U), /*!< SPI2 clock */ + RCU_USART1 = RCU_REGIDX_BIT(IDX_APB1EN, 17U), /*!< USART1 clock */ + RCU_I2C0 = RCU_REGIDX_BIT(IDX_APB1EN, 21U), /*!< I2C0 clock */ + RCU_I2C1 = RCU_REGIDX_BIT(IDX_APB1EN, 22U), /*!< I2C1 clock */ +#ifdef GD32F130_150 + RCU_USBD = RCU_REGIDX_BIT(IDX_APB1EN, 23U), /*!< USBD clock */ +#endif /* GD32F130_150 */ +#ifdef GD32F170_190 + RCU_CAN0 = RCU_REGIDX_BIT(IDX_APB1EN, 25U), /*!< CAN0 clock */ + RCU_CAN1 = RCU_REGIDX_BIT(IDX_APB1EN, 26U), /*!< CAN1 clock */ +#endif /* GD32F170_190 */ + RCU_PMU = RCU_REGIDX_BIT(IDX_APB1EN, 28U), /*!< PMU clock */ + RCU_DAC = RCU_REGIDX_BIT(IDX_APB1EN, 29U), /*!< DAC clock */ + RCU_CEC = RCU_REGIDX_BIT(IDX_APB1EN, 30U), /*!< CEC clock */ +#ifdef GD32F170_190 + RCU_OPAIVREF = RCU_REGIDX_BIT(IDX_APB1EN, 31U), /*!< OPAIVREF clock */ +#endif /* GD32F170_190 */ + RCU_RTC = RCU_REGIDX_BIT(IDX_BDCTL, 15U), /*!< RTC clock */ + + /* RCU_ADDAPB1EN */ + RCU_I2C2 = RCU_REGIDX_BIT(IDX_ADDAPB1EN, 0U) /*!< I2C2 clock */ +}rcu_periph_enum; + +/* peripheral clock enable when sleep mode*/ +typedef enum +{ + /* AHB peripherals */ + RCU_SRAM_SLP = RCU_REGIDX_BIT(IDX_AHBEN, 2U), /*!< SRAM clock when sleep mode */ + RCU_FMC_SLP = RCU_REGIDX_BIT(IDX_AHBEN, 4U) /*!< FMC clock when sleep mode */ +}rcu_periph_sleep_enum; + +/* peripherals reset */ +typedef enum +{ + /* AHB peripherals reset */ + RCU_GPIOARST = RCU_REGIDX_BIT(IDX_AHBRST, 17U), /*!< GPIOA reset */ + RCU_GPIOBRST = RCU_REGIDX_BIT(IDX_AHBRST, 18U), /*!< GPIOB reset */ + RCU_GPIOCRST = RCU_REGIDX_BIT(IDX_AHBRST, 19U), /*!< GPIOC reset */ + RCU_GPIODRST = RCU_REGIDX_BIT(IDX_AHBRST, 20U), /*!< GPIOD reset */ + RCU_GPIOFRST = RCU_REGIDX_BIT(IDX_AHBRST, 22U), /*!< GPIOF reset */ + RCU_TSIRST = RCU_REGIDX_BIT(IDX_AHBRST, 24U), /*!< TSI reset */ + + /* APB2 peripherals reset */ + RCU_CFGCMPRST = RCU_REGIDX_BIT(IDX_APB2RST, 0U), /*!< CFGCMP reset */ + RCU_ADCRST = RCU_REGIDX_BIT(IDX_APB2RST, 9U), /*!< ADC reset */ + RCU_TIMER0RST = RCU_REGIDX_BIT(IDX_APB2RST, 11U), /*!< TIMER0 reset */ + RCU_SPI0RST = RCU_REGIDX_BIT(IDX_APB2RST, 12U), /*!< SPI0 reset */ + RCU_USART0RST = RCU_REGIDX_BIT(IDX_APB2RST, 14U), /*!< USART0 reset */ + RCU_TIMER14RST = RCU_REGIDX_BIT(IDX_APB2RST, 16U), /*!< TIMER14 reset */ + RCU_TIMER15RST = RCU_REGIDX_BIT(IDX_APB2RST, 17U), /*!< TIMER15 reset */ + RCU_TIMER16RST = RCU_REGIDX_BIT(IDX_APB2RST, 18U), /*!< TIMER16 reset */ + + /* APB1 peripherals reset */ + RCU_TIMER1RST = RCU_REGIDX_BIT(IDX_APB1RST, 0U), /*!< TIMER1 reset */ + RCU_TIMER2RST = RCU_REGIDX_BIT(IDX_APB1RST, 1U), /*!< TIMER2 reset */ + RCU_TIMER5RST = RCU_REGIDX_BIT(IDX_APB1RST, 4U), /*!< TIMER5 reset */ + RCU_TIMER13RST = RCU_REGIDX_BIT(IDX_APB1RST, 8U), /*!< TIMER13 reset */ +#ifdef GD32F170_190 + RCU_SLCDRST = RCU_REGIDX_BIT(IDX_APB1RST, 9U), /*!< SLCD reset */ +#endif /* GD32F170_190 */ + RCU_WWDGTRST = RCU_REGIDX_BIT(IDX_APB1RST, 11U), /*!< WWDGT reset */ + RCU_SPI1RST = RCU_REGIDX_BIT(IDX_APB1RST, 14U), /*!< SPI1 reset */ + RCU_SPI2RST = RCU_REGIDX_BIT(IDX_APB1RST, 15U), /*!< SPI2 reset */ + RCU_USART1RST = RCU_REGIDX_BIT(IDX_APB1RST, 17U), /*!< USART1 reset */ + RCU_I2C0RST = RCU_REGIDX_BIT(IDX_APB1RST, 21U), /*!< I2C0 reset */ + RCU_I2C1RST = RCU_REGIDX_BIT(IDX_APB1RST, 22U), /*!< I2C1 reset */ +#ifdef GD32F130_150 + RCU_USBDRST = RCU_REGIDX_BIT(IDX_APB1RST, 23U), /*!< USBD reset */ +#endif /* GD32F130_150 */ +#ifdef GD32F170_190 + RCU_CAN0RST = RCU_REGIDX_BIT(IDX_APB1RST, 25U), /*!< CAN0 reset */ + RCU_CAN1RST = RCU_REGIDX_BIT(IDX_APB1RST, 26U), /*!< CAN1 reset */ +#endif /* GD32F170_190 */ + RCU_PMURST = RCU_REGIDX_BIT(IDX_APB1RST, 28U), /*!< PMU reset */ + RCU_DACRST = RCU_REGIDX_BIT(IDX_APB1RST, 29U), /*!< DAC reset */ + RCU_CECRST = RCU_REGIDX_BIT(IDX_APB1RST, 30U), /*!< CEC reset */ +#ifdef GD32F170_190 + RCU_OPAIVREFRST = RCU_REGIDX_BIT(IDX_APB1RST, 31U), /*!< OPAIVREF reset */ +#endif /* GD32F170_190 */ + + /* RCU_ADDAPB1RST */ + RCU_I2C2RST = RCU_REGIDX_BIT(IDX_ADDAPB1RST, 0U), /*!< I2C2 reset */ +}rcu_periph_reset_enum; + +/* clock stabilization and peripheral reset flags */ +typedef enum +{ + RCU_FLAG_IRC40KSTB = RCU_REGIDX_BIT(IDX_STB, 1U), /*!< IRC40K stabilization flags */ + RCU_FLAG_LXTALSTB = RCU_REGIDX_BIT(IDX_BDCTL, 1U), /*!< LXTAL stabilization flags */ + RCU_FLAG_IRC8MSTB = RCU_REGIDX_BIT(IDX_CTL0, 1U), /*!< IRC8M stabilization flags */ + RCU_FLAG_HXTALSTB = RCU_REGIDX_BIT(IDX_CTL0, 17U), /*!< HXTAL stabilization flags */ + RCU_FLAG_PLLSTB = RCU_REGIDX_BIT(IDX_CTL0, 25U), /*!< PLL stabilization flags */ +#ifdef GD32F130_150 + RCU_FLAG_IRC14MSTB = RCU_REGIDX_BIT(IDX_CTL1, 1U), /*!< IRC14M stabilization flags */ +#elif defined (GD32F170_190) + RCU_FLAG_IRC28MSTB = RCU_REGIDX_BIT(IDX_CTL1, 1U), /*!< IRC28M stabilization flags */ +#endif /* GD32F130_150 */ + RCU_FLAG_V12RST = RCU_REGIDX_BIT(IDX_RSTSCK, 23U), /*!< V12 reset flags */ + RCU_FLAG_OBLRST = RCU_REGIDX_BIT(IDX_RSTSCK, 25U), /*!< OBL reset flags */ + RCU_FLAG_EPRST = RCU_REGIDX_BIT(IDX_RSTSCK, 26U), /*!< EPR reset flags */ + RCU_FLAG_PORRST = RCU_REGIDX_BIT(IDX_RSTSCK, 27U), /*!< Power reset flags */ + RCU_FLAG_SWRST = RCU_REGIDX_BIT(IDX_RSTSCK, 28U), /*!< SW reset flags */ + RCU_FLAG_FWDGTRST = RCU_REGIDX_BIT(IDX_RSTSCK, 29U), /*!< FWDGT reset flags */ + RCU_FLAG_WWDGTRST = RCU_REGIDX_BIT(IDX_RSTSCK, 30U), /*!< WWDGT reset flags */ + RCU_FLAG_LPRST = RCU_REGIDX_BIT(IDX_RSTSCK, 31U) /*!< LP reset flags */ +}rcu_flag_enum; + +/* clock stabilization and ckm interrupt flags */ +typedef enum +{ + RCU_INT_FLAG_IRC40KSTB = RCU_INT_IRC40KSTBIF, /*!< IRC40K stabilization interrupt flag */ + RCU_INT_FLAG_LXTALSTB = RCU_INT_LXTALSTBIF, /*!< LXTAL stabilization interrupt flag */ + RCU_INT_FLAG_IRC8MSTB = RCU_INT_IRC8MSTBIF, /*!< IRC8M stabilization interrupt flag */ + RCU_INT_FLAG_HXTALSTB = RCU_INT_HXTALSTBIF, /*!< HXTAL stabilization interrupt flag */ + RCU_INT_FLAG_PLLSTB = RCU_INT_PLLSTBIF, /*!< PLL stabilization interrupt flag */ +#ifdef GD32F130_150 + RCU_INT_FLAG_IRC14MSTB = RCU_INT_IRC14MSTBIF, /*!< IRC14M stabilization interrupt flag */ +#elif defined (GD32F170_190) + RCU_INT_FLAG_IRC28MSTB = RCU_INT_IRC28MSTBIF, /*!< IRC28M stabilization interrupt flag */ +#endif /* GD32F130_150 */ + RCU_INT_FLAG_CKM = RCU_INT_CKMIF /*!< CKM interrupt flag */ +}rcu_int_flag_enum; + +/* clock stabilization and stuck interrupt flags clear */ +typedef enum +{ + RCU_INT_FLAG_IRC40KSTB_CLR = RCU_INT_IRC40KSTBIC, /*!< IRC40K stabilization interrupt flags clear */ + RCU_INT_FLAG_LXTALSTB_CLR = RCU_INT_LXTALSTBIC, /*!< LXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_IRC8MSTB_CLR = RCU_INT_IRC8MSTBIC, /*!< IRC8M stabilization interrupt flags clear */ + RCU_INT_FLAG_HXTALSTB_CLR = RCU_INT_HXTALSTBIC, /*!< HXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLSTB_CLR = RCU_INT_PLLSTBIC, /*!< PLL stabilization interrupt flags clear */ +#ifdef GD32F130_150 + RCU_INT_FLAG_IRC14MSTB_CLR = RCU_INT_IRC14MSTBIC, /*!< IRC14M stabilization interrupt flags clear */ +#elif defined (GD32F170_190) + RCU_INT_FLAG_IRC28MSTB_CLR = RCU_INT_IRC28MSTBIC, /*!< IRC28M stabilization interrupt flags clear */ +#endif /* GD32F130_150 */ + RCU_INT_FLAG_CKM_CLR = RCU_INT_CKMIC /*!< CKM interrupt flags clear */ +}rcu_int_flag_clear_enum; + +/* clock stabilization interrupt enable or disable */ +typedef enum +{ + RCU_INT_IRC40KSTB = RCU_INT_IRC40KSTBIE, /*!< IRC40K stabilization interrupt */ + RCU_INT_LXTALSTB = RCU_INT_LXTALSTBIE, /*!< LXTAL stabilization interrupt */ + RCU_INT_IRC8MSTB = RCU_INT_IRC8MSTBIE, /*!< IRC8M stabilization interrupt */ + RCU_INT_HXTALSTB = RCU_INT_HXTALSTBIE, /*!< HXTAL stabilization interrupt */ + RCU_INT_PLLSTB = RCU_INT_PLLSTBIE, /*!< PLL stabilization interrupt */ +#ifdef GD32F130_150 + RCU_INT_IRC14MSTB = RCU_INT_IRC14MSTBIE /*!< IRC14M stabilization interrupt */ +#elif defined (GD32F170_190) + RCU_INT_IRC28MSTB = RCU_INT_IRC28MSTBIE /*!< IRC28M stabilization interrupt */ +#endif /* GD32F130_150 */ +}rcu_int_enum; + +/* ADC clock source */ +typedef enum +{ +#ifdef GD32F130_150 + RCU_ADCCK_IRC14M = 0, /*!< ADC clock source select IRC14M */ +#elif defined (GD32F170_190) + RCU_ADCCK_IRC28M_DIV2 = 0, /*!< ADC clock source select IRC28M/2 */ + RCU_ADCCK_IRC28M, /*!< ADC clock source select IRC28M */ +#endif /* GD32F130_150 */ + RCU_ADCCK_APB2_DIV2, /*!< ADC clock source select APB2/2 */ + RCU_ADCCK_APB2_DIV4, /*!< ADC clock source select APB2/4 */ + RCU_ADCCK_APB2_DIV6, /*!< ADC clock source select APB2/6 */ + RCU_ADCCK_APB2_DIV8 /*!< ADC clock source select APB2/8 */ +}rcu_adc_clock_enum; + +/* oscillator types */ +typedef enum +{ + RCU_HXTAL = RCU_REGIDX_BIT(IDX_CTL0, 16U), /*!< HXTAL */ + RCU_LXTAL = RCU_REGIDX_BIT(IDX_BDCTL, 0U), /*!< LXTAL */ + RCU_IRC8M = RCU_REGIDX_BIT(IDX_CTL0, 0U), /*!< IRC8M */ +#ifdef GD32F130_150 + RCU_IRC14M = RCU_REGIDX_BIT(IDX_CTL1, 0U), /*!< IRC14M */ +#elif defined (GD32F170_190) + RCU_IRC28M = RCU_REGIDX_BIT(IDX_CTL1, 0U), /*!< IRC28M */ +#endif /* GD32F130_150 */ + RCU_IRC40K = RCU_REGIDX_BIT(IDX_RSTSCK, 0U), /*!< IRC40K */ + RCU_PLL_CK = RCU_REGIDX_BIT(IDX_CTL0, 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_ADC, /*!< ADC clock */ + CK_CEC, /*!< CEC clock */ + CK_USART /*!< USART clock */ +}rcu_clock_freq_enum; + +/* 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 */ + +/* ADC clock prescaler selection */ +#define CFG0_ADCPSC(regval) (BITS(14,15) & ((uint32_t)(regval) << 14)) +#define RCU_ADC_CKAPB2_DIV2 CFG0_ADCPSC(0) /*!< ADC clock prescaler select CK_APB2/2 */ +#define RCU_ADC_CKAPB2_DIV4 CFG0_ADCPSC(1) /*!< ADC clock prescaler select CK_APB2/4 */ +#define RCU_ADC_CKAPB2_DIV6 CFG0_ADCPSC(2) /*!< ADC clock prescaler select CK_APB2/6 */ +#define RCU_ADC_CKAPB2_DIV8 CFG0_ADCPSC(3) /*!< ADC clock prescaler select CK_APB2/8 */ + +/* PLL clock source selection */ +#define RCU_PLLSRC_IRC8M_DIV2 (uint32_t)0x00000000 /*!< PLL clock source select IRC8M/2 */ +#define RCU_PLLSRC_HXTAL RCU_CFG0_PLLSEL /*!< PLL clock source select HXTAL */ + +/* HXTAL divider for PLL source clock selection */ +#define RCU_PLLPREDV_HXTAL (uint32_t)0x00000000 /*!< HXTAL clock selected */ +#define RCU_PLLPREDV_HXTAL_DIV2 RCU_CFG0_PLLPREDV /*!< HXTAL/2 clock selected */ + +/* PLL multiply factor */ +#define CFG0_PLLMF(regval) (BITS(18,21) & ((uint32_t)(regval) << 18)) +#define RCU_PLL_MUL2 CFG0_PLLMF(0) /*!< PLL source clock multiply by 2 */ +#define RCU_PLL_MUL3 CFG0_PLLMF(1) /*!< PLL source clock multiply by 3 */ +#define RCU_PLL_MUL4 CFG0_PLLMF(2) /*!< PLL source clock multiply by 4 */ +#define RCU_PLL_MUL5 CFG0_PLLMF(3) /*!< PLL source clock multiply by 5 */ +#define RCU_PLL_MUL6 CFG0_PLLMF(4) /*!< PLL source clock multiply by 6 */ +#define RCU_PLL_MUL7 CFG0_PLLMF(5) /*!< PLL source clock multiply by 7 */ +#define RCU_PLL_MUL8 CFG0_PLLMF(6) /*!< PLL source clock multiply by 8 */ +#define RCU_PLL_MUL9 CFG0_PLLMF(7) /*!< PLL source clock multiply by 9 */ +#define RCU_PLL_MUL10 CFG0_PLLMF(8) /*!< PLL source clock multiply by 10 */ +#define RCU_PLL_MUL11 CFG0_PLLMF(9) /*!< PLL source clock multiply by 11 */ +#define RCU_PLL_MUL12 CFG0_PLLMF(10) /*!< PLL source clock multiply by 12 */ +#define RCU_PLL_MUL13 CFG0_PLLMF(11) /*!< PLL source clock multiply by 13 */ +#define RCU_PLL_MUL14 CFG0_PLLMF(12) /*!< PLL source clock multiply by 14 */ +#define RCU_PLL_MUL15 CFG0_PLLMF(13) /*!< PLL source clock multiply by 15 */ +#define RCU_PLL_MUL16 CFG0_PLLMF(14) /*!< PLL source clock multiply by 16 */ +#define RCU_PLL_MUL17 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(0)) /*!< PLL source clock multiply by 17 */ +#define RCU_PLL_MUL18 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(1)) /*!< PLL source clock multiply by 18 */ +#define RCU_PLL_MUL19 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(2)) /*!< PLL source clock multiply by 19 */ +#define RCU_PLL_MUL20 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(3)) /*!< PLL source clock multiply by 20 */ +#define RCU_PLL_MUL21 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(4)) /*!< PLL source clock multiply by 21 */ +#define RCU_PLL_MUL22 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(5)) /*!< PLL source clock multiply by 22 */ +#define RCU_PLL_MUL23 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(6)) /*!< PLL source clock multiply by 23 */ +#define RCU_PLL_MUL24 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(7)) /*!< PLL source clock multiply by 24 */ +#define RCU_PLL_MUL25 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(8)) /*!< PLL source clock multiply by 25 */ +#define RCU_PLL_MUL26 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(9)) /*!< PLL source clock multiply by 26 */ +#define RCU_PLL_MUL27 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(10)) /*!< PLL source clock multiply by 27 */ +#define RCU_PLL_MUL28 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(11)) /*!< PLL source clock multiply by 28 */ +#define RCU_PLL_MUL29 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(12)) /*!< PLL source clock multiply by 29 */ +#define RCU_PLL_MUL30 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(13)) /*!< PLL source clock multiply by 30 */ +#define RCU_PLL_MUL31 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(14)) /*!< PLL source clock multiply by 31 */ +#define RCU_PLL_MUL32 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(15)) /*!< PLL source clock multiply by 32 */ + +#ifdef GD32F130_150 +/* USBD clock prescaler selection */ +#define CFG0_USBDPSC(regval) (BITS(22,23) & ((uint32_t)(regval) << 22)) +#define RCU_USBD_CKPLL_DIV1_5 CFG0_USBDPSC(0) /*!< USBD clock prescaler select CK_PLL/1.5 */ +#define RCU_USBD_CKPLL_DIV1 CFG0_USBDPSC(1) /*!< USBD clock prescaler select CK_PLL */ +#define RCU_USBD_CKPLL_DIV2_5 CFG0_USBDPSC(2) /*!< USBD clock prescaler select CK_PLL/2.5 */ +#define RCU_USBD_CKPLL_DIV2 CFG0_USBDPSC(3) /*!< USBD clock prescaler select CK_PLL/2 */ + +/* CK_OUT clock source selection */ +#define CFG0_CKOUTSEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define RCU_CKOUTSRC_NONE CFG0_CKOUTSEL(0) /*!< no clock selected */ +#define RCU_CKOUTSRC_IRC14M CFG0_CKOUTSEL(1) /*!< CK_OUT clock source select IRC14M */ +#define RCU_CKOUTSRC_IRC40K CFG0_CKOUTSEL(2) /*!< CK_OUT clock source select IRC40K */ +#define RCU_CKOUTSRC_LXTAL CFG0_CKOUTSEL(3) /*!< CK_OUT clock source select LXTAL */ +#define RCU_CKOUTSRC_CKSYS CFG0_CKOUTSEL(4) /*!< CK_OUT clock source select CKSYS */ +#define RCU_CKOUTSRC_IRC8M CFG0_CKOUTSEL(5) /*!< CK_OUT clock source select IRC8M */ +#define RCU_CKOUTSRC_HXTAL CFG0_CKOUTSEL(6) /*!< CK_OUT clock source select HXTAL */ +#define RCU_CKOUTSRC_CKPLL_DIV1 (RCU_CFG0_PLLDV | CFG0_CKOUTSEL(7)) /*!< CK_OUT clock source select CK_PLL */ +#define RCU_CKOUTSRC_CKPLL_DIV2 CFG0_CKOUTSEL(7) /*!< CK_OUT clock source select CK_PLL/2 */ + +/* 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 */ +#elif defined (GD32F170_190) +/* CK_OUT0 clock source selection */ +#define CFG0_CKOUT0SEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define RCU_CKOUT0SRC_NONE CFG0_CKOUT0SEL(0) /*!< no clock selected */ +#define RCU_CKOUT0SRC_IRC28M CFG0_CKOUT0SEL(1) /*!< CK_OUT0 clock source select IRC28M */ +#define RCU_CKOUT0SRC_IRC40K CFG0_CKOUT0SEL(2) /*!< CK_OUT0 clock source select IRC40K */ +#define RCU_CKOUT0SRC_LXTAL CFG0_CKOUT0SEL(3) /*!< CK_OUT0 clock source select LXTAL */ +#define RCU_CKOUT0SRC_CKSYS CFG0_CKOUT0SEL(4) /*!< CK_OUT0 clock source select CKSYS */ +#define RCU_CKOUT0SRC_IRC8M CFG0_CKOUT0SEL(5) /*!< CK_OUT0 clock source select IRC8M */ +#define RCU_CKOUT0SRC_HXTAL CFG0_CKOUT0SEL(6) /*!< CK_OUT0 clock source select HXTAL */ +#define RCU_CKOUT0SRC_CKPLL_DIV1 (RCU_CFG0_PLLDV | CFG0_CKOUT0SEL(7)) /*!< CK_OUT0 clock source select CK_PLL */ +#define RCU_CKOUT0SRC_CKPLL_DIV2 CFG0_CKOUT0SEL(7) /*!< CK_OUT0 clock source select CK_PLL/2 */ + +/* CK_OUT0 divider */ +#define CFG0_CKOUT0DIV(regval) (BITS(28,30) & ((uint32_t)(regval) << 28)) +#define RCU_CKOUT0_DIV1 CFG0_CKOUT0DIV(0) /*!< CK_OUT0 is divided by 1 */ +#define RCU_CKOUT0_DIV2 CFG0_CKOUT0DIV(1) /*!< CK_OUT0 is divided by 2 */ +#define RCU_CKOUT0_DIV4 CFG0_CKOUT0DIV(2) /*!< CK_OUT0 is divided by 4 */ +#define RCU_CKOUT0_DIV8 CFG0_CKOUT0DIV(3) /*!< CK_OUT0 is divided by 8 */ +#define RCU_CKOUT0_DIV16 CFG0_CKOUT0DIV(4) /*!< CK_OUT0 is divided by 16 */ +#define RCU_CKOUT0_DIV32 CFG0_CKOUT0DIV(5) /*!< CK_OUT0 is divided by 32 */ +#define RCU_CKOUT0_DIV64 CFG0_CKOUT0DIV(6) /*!< CK_OUT0 is divided by 64 */ +#define RCU_CKOUT0_DIV128 CFG0_CKOUT0DIV(7) /*!< CK_OUT0 is divided by 128 */ +#endif /* GD32F130_150 */ + +/* CK_PLL divide by 1 or 2 for CK_OUT */ +#define RCU_PLLDV_CKPLL_DIV2 (uint32_t)0x00000000U /*!< CK_PLL divide by 2 for CK_OUT */ +#define RCU_PLLDV_CKPLL RCU_CFG0_PLLDV /*!< CK_PLL divide by 1 for CK_OUT */ + +/* 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 selected */ +#define RCU_RTCSRC_LXTAL BDCTL_RTCSRC(1) /*!< LXTAL selected as RTC source clock */ +#define RCU_RTCSRC_IRC40K BDCTL_RTCSRC(2) /*!< IRC40K selected as RTC source clock */ +#define RCU_RTCSRC_HXTAL_DIV32 BDCTL_RTCSRC(3) /*!< HXTAL/32 selected as RTC source clock */ + +#ifdef GD32F170_190 +/* SLCD clock entry selection */ +#define BDCTL_RTCSRC(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define RCU_SLCDSRC_NONE BDCTL_RTCSRC(0) /*!< no clock selected */ +#define RCU_SLCDSRC_LXTAL BDCTL_RTCSRC(1) /*!< LXTAL selected as SLCD source clock */ +#define RCU_SLCDSRC_IRC40K BDCTL_RTCSRC(2) /*!< IRC40K selected as SLCD source clock */ +#define RCU_SLCDSRC_HXTAL_DIV32 BDCTL_RTCSRC(3) /*!< HXTAL/32 selected as SLCD source clock */ +#endif /* GD32F170_190 */ + +/* CK_HXTAL divider previous PLL */ +#define CFG1_HXTALPREDV(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define RCU_PLL_HXTAL_DIV1 CFG1_HXTALPREDV(0) /*!< HXTAL input to PLL not divided */ +#define RCU_PLL_HXTAL_DIV2 CFG1_HXTALPREDV(1) /*!< HXTAL input to PLL divided by 2 */ +#define RCU_PLL_HXTAL_DIV3 CFG1_HXTALPREDV(2) /*!< HXTAL input to PLL divided by 3 */ +#define RCU_PLL_HXTAL_DIV4 CFG1_HXTALPREDV(3) /*!< HXTAL input to PLL divided by 4 */ +#define RCU_PLL_HXTAL_DIV5 CFG1_HXTALPREDV(4) /*!< HXTAL input to PLL divided by 5 */ +#define RCU_PLL_HXTAL_DIV6 CFG1_HXTALPREDV(5) /*!< HXTAL input to PLL divided by 6 */ +#define RCU_PLL_HXTAL_DIV7 CFG1_HXTALPREDV(6) /*!< HXTAL input to PLL divided by 7 */ +#define RCU_PLL_HXTAL_DIV8 CFG1_HXTALPREDV(7) /*!< HXTAL input to PLL divided by 8 */ +#define RCU_PLL_HXTAL_DIV9 CFG1_HXTALPREDV(8) /*!< HXTAL input to PLL divided by 9 */ +#define RCU_PLL_HXTAL_DIV10 CFG1_HXTALPREDV(9) /*!< HXTAL input to PLL divided by 10 */ +#define RCU_PLL_HXTAL_DIV11 CFG1_HXTALPREDV(10) /*!< HXTAL input to PLL divided by 11 */ +#define RCU_PLL_HXTAL_DIV12 CFG1_HXTALPREDV(11) /*!< HXTAL input to PLL divided by 12 */ +#define RCU_PLL_HXTAL_DIV13 CFG1_HXTALPREDV(12) /*!< HXTAL input to PLL divided by 13 */ +#define RCU_PLL_HXTAL_DIV14 CFG1_HXTALPREDV(13) /*!< HXTAL input to PLL divided by 14 */ +#define RCU_PLL_HXTAL_DIV15 CFG1_HXTALPREDV(14) /*!< HXTAL input to PLL divided by 15 */ +#define RCU_PLL_HXTAL_DIV16 CFG1_HXTALPREDV(15) /*!< HXTAL input to PLL divided by 16 */ + +/* USART0 clock source selection */ +#define CFG2_USART0SEL(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_USART0SRC_CKAPB2 CFG2_USART0SEL(0) /*!< CK_USART0 select CK_APB2 */ +#define RCU_USART0SRC_CKSYS CFG2_USART0SEL(1) /*!< CK_USART0 select CK_SYS */ +#define RCU_USART0SRC_LXTAL CFG2_USART0SEL(2) /*!< CK_USART0 select LXTAL */ +#define RCU_USART0SRC_IRC8M CFG2_USART0SEL(3) /*!< CK_USART0 select IRC8M */ + +/* CEC clock source selection */ +#define RCU_CECSRC_IRC8M_DIV244 (uint32_t)0x00000000U /*!< CK_CEC clock source select IRC8M/244 */ +#define RCU_CECSRC_LXTAL RCU_CFG2_CECSEL /*!< CK_CEC clock source select LXTAL */ + +#ifdef GD32F130_150 +/* ADC clock source selection */ +#define RCU_ADCSRC_IRC14M (uint32_t)0x00000000U /*!< ADC clock source select */ +#define RCU_ADCSRC_APB2DIV RCU_CFG2_ADCSEL /*!< ADC clock source select */ +#elif defined (GD32F170_190) +/* ADC clock source selection */ +#define RCU_ADCSRC_IRC28M (uint32_t)0x00000000U /*!< ADC clock source select */ +#define RCU_ADCSRC_APB2DIV RCU_CFG2_ADCSEL /*!< ADC clock source select */ + +/* IRC28M clock divider for ADC */ +#define RCU_ADC_IRC28M_DIV2 (uint32_t)0x00000000U /*!< IRC28M/2 select to ADC clock */ +#define RCU_ADC_IRC28M_DIV1 RCU_CFG2_IRC28MDIV /*!< IRC28M select to ADC clock */ + +/* CK_OUT1 clock source selection */ +#define CFG3_CKOUT1SRC(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define RCU_CKOUT1SRC_NONE CFG3_CKOUT1SRC(0) /*!< no clock selected */ +#define RCU_CKOUT1SRC_IRC28M CFG3_CKOUT1SRC(1) /*!< CK_OUT1 clock source select IRC28M */ +#define RCU_CKOUT1SRC_IRC40K CFG3_CKOUT1SRC(2) /*!< CK_OUT1 clock source select IRC40K */ +#define RCU_CKOUT1SRC_LXTAL CFG3_CKOUT1SRC(3) /*!< CK_OUT1 clock source select LXTAL */ +#define RCU_CKOUT1SRC_CKSYS CFG3_CKOUT1SRC(4) /*!< CK_OUT1 clock source select CKSYS */ +#define RCU_CKOUT1SRC_IRC8M CFG3_CKOUT1SRC(5) /*!< CK_OUT1 clock source select IRC8M */ +#define RCU_CKOUT1SRC_HXTAL CFG3_CKOUT1SRC(6) /*!< CK_OUT1 clock source select HXTAL */ +#define RCU_CKOUT1SRC_CKPLL_DIV1 0x00000007U /*!< CK_OUT1 clock source select CK_PLL */ +#define RCU_CKOUT1SRC_CKPLL_DIV2 0x00000008U /*!< CK_OUT1 clock source select CK_PLL/2 */ + +/* CK_OUT1 divider */ +#define CFG3_CKOUT1DIV(regval) (BITS(8,13) & ((uint32_t)(regval) << 8)) +#define RCU_CKOUT1_DIV1 CFG3_CKOUT1DIV(0) /*!< CK_OUT1 is divided by 1 */ +#define RCU_CKOUT1_DIV2 CFG3_CKOUT1DIV(1) /*!< CK_OUT1 is divided by 2 */ +#define RCU_CKOUT1_DIV3 CFG3_CKOUT1DIV(2) /*!< CK_OUT1 is divided by 3 */ +#define RCU_CKOUT1_DIV4 CFG3_CKOUT1DIV(3) /*!< CK_OUT1 is divided by 4 */ +#define RCU_CKOUT1_DIV5 CFG3_CKOUT1DIV(4) /*!< CK_OUT1 is divided by 5 */ +#define RCU_CKOUT1_DIV6 CFG3_CKOUT1DIV(5) /*!< CK_OUT1 is divided by 6 */ +#define RCU_CKOUT1_DIV7 CFG3_CKOUT1DIV(6) /*!< CK_OUT1 is divided by 7 */ +#define RCU_CKOUT1_DIV8 CFG3_CKOUT1DIV(7) /*!< CK_OUT1 is divided by 8 */ +#define RCU_CKOUT1_DIV9 CFG3_CKOUT1DIV(8) /*!< CK_OUT1 is divided by 9 */ +#define RCU_CKOUT1_DIV10 CFG3_CKOUT1DIV(9) /*!< CK_OUT1 is divided by 10 */ +#define RCU_CKOUT1_DIV11 CFG3_CKOUT1DIV(10) /*!< CK_OUT1 is divided by 11 */ +#define RCU_CKOUT1_DIV12 CFG3_CKOUT1DIV(11) /*!< CK_OUT1 is divided by 12 */ +#define RCU_CKOUT1_DIV13 CFG3_CKOUT1DIV(12) /*!< CK_OUT1 is divided by 13 */ +#define RCU_CKOUT1_DIV14 CFG3_CKOUT1DIV(13) /*!< CK_OUT1 is divided by 14 */ +#define RCU_CKOUT1_DIV15 CFG3_CKOUT1DIV(14) /*!< CK_OUT1 is divided by 15 */ +#define RCU_CKOUT1_DIV16 CFG3_CKOUT1DIV(15) /*!< CK_OUT1 is divided by 16 */ +#define RCU_CKOUT1_DIV17 CFG3_CKOUT1DIV(16) /*!< CK_OUT1 is divided by 17 */ +#define RCU_CKOUT1_DIV18 CFG3_CKOUT1DIV(17) /*!< CK_OUT1 is divided by 18 */ +#define RCU_CKOUT1_DIV19 CFG3_CKOUT1DIV(18) /*!< CK_OUT1 is divided by 19 */ +#define RCU_CKOUT1_DIV20 CFG3_CKOUT1DIV(19) /*!< CK_OUT1 is divided by 20 */ +#define RCU_CKOUT1_DIV21 CFG3_CKOUT1DIV(20) /*!< CK_OUT1 is divided by 21 */ +#define RCU_CKOUT1_DIV22 CFG3_CKOUT1DIV(21) /*!< CK_OUT1 is divided by 22 */ +#define RCU_CKOUT1_DIV23 CFG3_CKOUT1DIV(22) /*!< CK_OUT1 is divided by 23 */ +#define RCU_CKOUT1_DIV24 CFG3_CKOUT1DIV(23) /*!< CK_OUT1 is divided by 24 */ +#define RCU_CKOUT1_DIV25 CFG3_CKOUT1DIV(24) /*!< CK_OUT1 is divided by 25 */ +#define RCU_CKOUT1_DIV26 CFG3_CKOUT1DIV(25) /*!< CK_OUT1 is divided by 26 */ +#define RCU_CKOUT1_DIV27 CFG3_CKOUT1DIV(26) /*!< CK_OUT1 is divided by 27 */ +#define RCU_CKOUT1_DIV28 CFG3_CKOUT1DIV(27) /*!< CK_OUT1 is divided by 28 */ +#define RCU_CKOUT1_DIV29 CFG3_CKOUT1DIV(28) /*!< CK_OUT1 is divided by 29 */ +#define RCU_CKOUT1_DIV30 CFG3_CKOUT1DIV(29) /*!< CK_OUT1 is divided by 30 */ +#define RCU_CKOUT1_DIV31 CFG3_CKOUT1DIV(30) /*!< CK_OUT1 is divided by 31 */ +#define RCU_CKOUT1_DIV32 CFG3_CKOUT1DIV(31) /*!< CK_OUT1 is divided by 32 */ +#define RCU_CKOUT1_DIV33 CFG3_CKOUT1DIV(32) /*!< CK_OUT1 is divided by 33 */ +#define RCU_CKOUT1_DIV34 CFG3_CKOUT1DIV(33) /*!< CK_OUT1 is divided by 34 */ +#define RCU_CKOUT1_DIV35 CFG3_CKOUT1DIV(34) /*!< CK_OUT1 is divided by 35 */ +#define RCU_CKOUT1_DIV36 CFG3_CKOUT1DIV(35) /*!< CK_OUT1 is divided by 36 */ +#define RCU_CKOUT1_DIV37 CFG3_CKOUT1DIV(36) /*!< CK_OUT1 is divided by 37 */ +#define RCU_CKOUT1_DIV38 CFG3_CKOUT1DIV(37) /*!< CK_OUT1 is divided by 38 */ +#define RCU_CKOUT1_DIV39 CFG3_CKOUT1DIV(38) /*!< CK_OUT1 is divided by 39 */ +#define RCU_CKOUT1_DIV40 CFG3_CKOUT1DIV(39) /*!< CK_OUT1 is divided by 40 */ +#define RCU_CKOUT1_DIV41 CFG3_CKOUT1DIV(40) /*!< CK_OUT1 is divided by 41 */ +#define RCU_CKOUT1_DIV42 CFG3_CKOUT1DIV(41) /*!< CK_OUT1 is divided by 42 */ +#define RCU_CKOUT1_DIV43 CFG3_CKOUT1DIV(42) /*!< CK_OUT1 is divided by 43 */ +#define RCU_CKOUT1_DIV44 CFG3_CKOUT1DIV(43) /*!< CK_OUT1 is divided by 44 */ +#define RCU_CKOUT1_DIV45 CFG3_CKOUT1DIV(44) /*!< CK_OUT1 is divided by 45 */ +#define RCU_CKOUT1_DIV46 CFG3_CKOUT1DIV(45) /*!< CK_OUT1 is divided by 46 */ +#define RCU_CKOUT1_DIV47 CFG3_CKOUT1DIV(46) /*!< CK_OUT1 is divided by 47 */ +#define RCU_CKOUT1_DIV48 CFG3_CKOUT1DIV(47) /*!< CK_OUT1 is divided by 48 */ +#define RCU_CKOUT1_DIV49 CFG3_CKOUT1DIV(48) /*!< CK_OUT1 is divided by 49 */ +#define RCU_CKOUT1_DIV50 CFG3_CKOUT1DIV(49) /*!< CK_OUT1 is divided by 50 */ +#define RCU_CKOUT1_DIV51 CFG3_CKOUT1DIV(50) /*!< CK_OUT1 is divided by 51 */ +#define RCU_CKOUT1_DIV52 CFG3_CKOUT1DIV(51) /*!< CK_OUT1 is divided by 52 */ +#define RCU_CKOUT1_DIV53 CFG3_CKOUT1DIV(52) /*!< CK_OUT1 is divided by 53 */ +#define RCU_CKOUT1_DIV54 CFG3_CKOUT1DIV(53) /*!< CK_OUT1 is divided by 54 */ +#define RCU_CKOUT1_DIV55 CFG3_CKOUT1DIV(54) /*!< CK_OUT1 is divided by 55 */ +#define RCU_CKOUT1_DIV56 CFG3_CKOUT1DIV(55) /*!< CK_OUT1 is divided by 56 */ +#define RCU_CKOUT1_DIV57 CFG3_CKOUT1DIV(56) /*!< CK_OUT1 is divided by 57 */ +#define RCU_CKOUT1_DIV58 CFG3_CKOUT1DIV(57) /*!< CK_OUT1 is divided by 58 */ +#define RCU_CKOUT1_DIV59 CFG3_CKOUT1DIV(58) /*!< CK_OUT1 is divided by 59 */ +#define RCU_CKOUT1_DIV60 CFG3_CKOUT1DIV(59) /*!< CK_OUT1 is divided by 60 */ +#define RCU_CKOUT1_DIV61 CFG3_CKOUT1DIV(60) /*!< CK_OUT1 is divided by 61 */ +#define RCU_CKOUT1_DIV62 CFG3_CKOUT1DIV(61) /*!< CK_OUT1 is divided by 62 */ +#define RCU_CKOUT1_DIV63 CFG3_CKOUT1DIV(62) /*!< CK_OUT1 is divided by 63 */ +#define RCU_CKOUT1_DIV64 CFG3_CKOUT1DIV(63) /*!< CK_OUT1 is divided by 64 */ +#endif /* GD32F130_150 */ + +#ifdef GD32F130_150 +/* Deep-sleep mode voltage */ +#define DSV_DSLPVS(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define RCU_DEEPSLEEP_V_1_2 DSV_DSLPVS(0) /*!< core voltage is 1.2V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_1 DSV_DSLPVS(1) /*!< core voltage is 1.1V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_0 DSV_DSLPVS(2) /*!< core voltage is 1.0V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0_9 DSV_DSLPVS(3) /*!< core voltage is 0.9V in deep-sleep mode */ + +/*Power down voltage select*/ +#define RCU_PDR_V_2_6 (uint32_t)0x00000000U /*!< power down voltage is 2.6V */ +#define RCU_PDR_V_1_8 RCU_PDVSEL_PDRVS /*!< power down voltage is 1.8V */ + +#elif defined (GD32F170_190) +/* Deep-sleep mode voltage */ +#define DSV_DSLPVS(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define RCU_DEEPSLEEP_V_1_8 DSV_DSLPVS(0) /*!< core voltage is 1.8V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_6 DSV_DSLPVS(1) /*!< core voltage is 1.6V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_4 DSV_DSLPVS(2) /*!< core voltage is 1.4V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_2 DSV_DSLPVS(3) /*!< core voltage is 1.2V in deep-sleep mode */ +#endif /* GD32F130_150 */ + +/* function declarations */ +/* deinitialize the RCU */ +void rcu_deinit(void); +/* enable the peripherals clock */ +void rcu_periph_clock_enable(rcu_periph_enum periph); +/* disable the peripherals clock */ +void rcu_periph_clock_disable(rcu_periph_enum periph); +/* enable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph); +/* disable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph); +/* reset the peripherals */ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset); +/* disable reset the peripheral */ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset); +/* reset the BKP domain */ +void rcu_bkp_reset_enable(void); +/* disable the BKP domain reset */ +void rcu_bkp_reset_disable(void); + +/* configure the system clock source */ +void rcu_system_clock_source_config(uint32_t ck_sys); +/* get the system clock source */ +uint32_t rcu_system_clock_source_get(void); +/* configure the AHB prescaler selection */ +void rcu_ahb_clock_config(uint32_t ck_ahb); +/* configure the APB1 prescaler selection */ +void rcu_apb1_clock_config(uint32_t ck_apb1); +/* configure the APB2 prescaler selection */ +void rcu_apb2_clock_config(uint32_t ck_apb2); +/* configure the ADC clock source and prescaler selection */ +void rcu_adc_clock_config(rcu_adc_clock_enum ck_adc); +#ifdef GD32F130_150 +/* configure the USBD prescaler selection */ +void rcu_usbd_clock_config(uint32_t ck_usbd); +/* configure the CK_OUT clock source and divider */ +void rcu_ckout_config(uint32_t ckout_src, uint32_t ckout_div); +#elif defined (GD32F170_190) +/* configure the CK_OUT0 clock source and divider */ +void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div); +/* configure the CK_OUT1 clock source and divider */ +void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div); +#endif /* GD32F130_150 */ +/* configure the PLL clock source selection and PLL multiply factor */ +void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul); +/* configure the USART clock source selection */ +void rcu_usart_clock_config(uint32_t ck_usart); +/* configure the CEC clock source selection */ +void rcu_cec_clock_config(uint32_t ck_cec); +/* configure the RTC clock source selection */ +void rcu_rtc_clock_config(uint32_t rtc_clock_source); +#ifdef GD32F170_190 +void rcu_slcd_clock_config(uint32_t slcd_clock_source); +#endif /* GD32F170_190 */ +/* configure the HXTAL divider used as input of PLL */ +void rcu_hxtal_prediv_config(uint32_t hxtal_prediv); +/* configure the LXTAL drive capability */ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap); + +/* get the clock stabilization and periphral reset flags */ +FlagStatus rcu_flag_get(rcu_flag_enum flag); +/* clear the reset flag */ +void rcu_all_reset_flag_clear(void); +/* get the clock stabilization interrupt and ckm flags */ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag); +/* clear the interrupt flags */ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear); +/* enable the stabilization interrupt */ +void rcu_interrupt_enable(rcu_int_enum stab_int); +/* disable the stabilization interrupt */ +void rcu_interrupt_disable(rcu_int_enum stab_int); + +/* wait until oscillator stabilization flags is SET or oscillator startup is timeout */ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci); +/* turn on the oscillator */ +void rcu_osci_on(rcu_osci_type_enum osci); +/* turn off the oscillator */ +void rcu_osci_off(rcu_osci_type_enum osci); +/* enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci); +/* disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci); +/* enable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_enable(void); +/* disable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_disable(void); + +/* set the IRC8M adjust value */ +void rcu_irc8m_adjust_value_set(uint8_t irc8m_adjval); +#ifdef GD32F130_150 +/* set the IRC14M adjust value */ +void rcu_irc14m_adjust_value_set(uint8_t irc14m_adjval); +#elif defined (GD32F170_190) +/* set the IRC28M adjust value */ +void rcu_irc28m_adjust_value_set(uint8_t irc28m_adjval); +#endif /* GD32F130_150 */ +/* unlock the voltage key */ +void rcu_voltage_key_unlock(void); +/* set the deep sleep mode voltage */ +void rcu_deepsleep_voltage_set(uint32_t dsvol); +#ifdef GD32F130_150 +/* set the power down voltage */ +void rcu_power_down_voltage_set(uint32_t pdvol); +#endif /* GD32F130_150 */ + +/* get the system clock, bus and peripheral clock frequency */ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock); + +#endif /* GD32F1X0_RCU_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_rtc.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_rtc.h new file mode 100644 index 0000000..259716b --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_rtc.h @@ -0,0 +1,540 @@ +/*! + \file gd32f1x0_rtc.h + \brief definitions for the RTC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_RTC_H +#define GD32F1X0_RTC_H + +#include "gd32f1x0.h" + +/* RTC definitions */ +#define RTC RTC_BASE + +/* registers definitions */ +#define RTC_TIME REG32((RTC) + 0x00U) /*!< RTC time of day register */ +#define RTC_DATE REG32((RTC) + 0x04U) /*!< RTC date register */ +#define RTC_CTL REG32((RTC) + 0x08U) /*!< RTC control register */ +#define RTC_STAT REG32((RTC) + 0x0CU) /*!< RTC status register */ +#define RTC_PSC REG32((RTC) + 0x10U) /*!< RTC time prescaler register */ +#define RTC_ALRM0TD REG32((RTC) + 0x1CU) /*!< RTC alarm 0 time and date register */ +#define RTC_WPK REG32((RTC) + 0x24U) /*!< RTC write protection key register */ +#define RTC_SS REG32((RTC) + 0x28U) /*!< RTC sub second register */ +#define RTC_SHIFTCTL REG32((RTC) + 0x2CU) /*!< RTC shift function control register */ +#define RTC_TTS REG32((RTC) + 0x30U) /*!< RTC time of timestamp register */ +#define RTC_DTS REG32((RTC) + 0x34U) /*!< RTC date of timestamp register */ +#define RTC_SSTS REG32((RTC) + 0x38U) /*!< RTC sub second of timestamp register */ +#define RTC_HRFC REG32((RTC) + 0x3CU) /*!< RTC high resolution frequency compensation registor */ +#define RTC_TAMP REG32((RTC) + 0x40U) /*!< RTC tamper register */ +#define RTC_ALRM0SS REG32((RTC) + 0x44U) /*!< RTC alarm 0 sub second register */ +#define RTC_BKP0 REG32((RTC) + 0x50U) /*!< RTC backup register */ +#define RTC_BKP1 REG32((RTC) + 0x54U) /*!< RTC backup register */ +#define RTC_BKP2 REG32((RTC) + 0x58U) /*!< RTC backup register */ +#define RTC_BKP3 REG32((RTC) + 0x5CU) /*!< RTC backup register */ +#define RTC_BKP4 REG32((RTC) + 0x60U) /*!< RTC backup register */ + +/* bits definitions */ +/* RTC_TIME */ +#define RTC_TIME_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TIME_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_TIME_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TIME_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TIME_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TIME_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TIME_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DATE */ +#define RTC_DATE_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DATE_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DATE_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DATE_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DATE_DOW BITS(13,15) /*!< day of week units */ +#define RTC_DATE_YRU BITS(16,19) /*!< year units in BCD code */ +#define RTC_DATE_YRT BITS(20,23) /*!< year tens in BCD code */ + +/* RTC_CTL */ +#define RTC_CTL_TSEG BIT(3) /*!< valid event edge of time-stamp */ +#define RTC_CTL_REFEN BIT(4) /*!< reference clock detection function enable */ +#define RTC_CTL_BPSHAD BIT(5) /*!< shadow registers bypass control */ +#define RTC_CTL_CS BIT(6) /*!< display format of clock system */ +#define RTC_CTL_ALRM0EN BIT(8) /*!< alarm function enable */ +#define RTC_CTL_TSEN BIT(11) /*!< time-stamp function enable */ +#define RTC_CTL_ALRM0IE BIT(12) /*!< RTC alarm interrupt enable */ +#define RTC_CTL_TSIE BIT(15) /*!< time-stamp interrupt enable */ +#define RTC_CTL_A1H BIT(16) /*!< add 1 hour(summer time change) */ +#define RTC_CTL_S1H BIT(17) /*!< subtract 1 hour(winter time change) */ +#define RTC_CTL_DSM BIT(18) /*!< daylight saving mark */ +#define RTC_CTL_COS BIT(19) /*!< calibration output selection */ +#define RTC_CTL_OPOL BIT(20) /*!< output polarity */ +#define RTC_CTL_OS BITS(21,22) /*!< output selection */ +#define RTC_CTL_COEN BIT(23) /*!< calibration output enable */ + +/* RTC_STAT */ +#define RTC_STAT_ALRM0WF BIT(0) /*!< alarm configuration can be write flag */ +#define RTC_STAT_SOPF BIT(3) /*!< shift function operation pending flag */ +#define RTC_STAT_YCM BIT(4) /*!< year configuration mark status flag */ +#define RTC_STAT_RSYNF BIT(5) /*!< register synchronization flag */ +#define RTC_STAT_INITF BIT(6) /*!< initialization state flag */ +#define RTC_STAT_INITM BIT(7) /*!< enter initialization mode */ +#define RTC_STAT_ALRM0F BIT(8) /*!< alarm occurs flag */ +#define RTC_STAT_TSF BIT(11) /*!< time-stamp flag */ +#define RTC_STAT_TSOVRF BIT(12) /*!< time-stamp overflow flag */ +#define RTC_STAT_TP0F BIT(13) /*!< RTC tamp 0 detected flag */ +#define RTC_STAT_TP1F BIT(14) /*!< RTC tamp 1 detected flag */ +#define RTC_STAT_SCPF BIT(16) /*!< recalibration pending flag */ + +/* RTC_PSC */ +#define RTC_PSC_FACTOR_S BITS(0,14) /*!< synchronous prescaler factor */ +#define RTC_PSC_FACTOR_A BITS(16,22) /*!< asynchronous prescaler factor */ + +/* RTC_ALRM0TD */ +#define RTC_ALRM0TD_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_ALRM0TD_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_ALRM0TD_MSKS BIT(7) /*!< alarm second mask bit */ +#define RTC_ALRM0TD_MNU BITS(8,11) /*!< minutes units in BCD code */ +#define RTC_ALRM0TD_MNT BITS(12,14) /*!< minutes tens in BCD code */ +#define RTC_ALRM0TD_MSKM BIT(15) /*!< alarm minutes mask bit */ +#define RTC_ALRM0TD_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_ALRM0TD_HRT BITS(20,21) /*!< hour units in BCD code */ +#define RTC_ALRM0TD_PM BIT(22) /*!< AM/PM flag */ +#define RTC_ALRM0TD_MSKH BIT(23) /*!< alarm hour mask bit */ +#define RTC_ALRM0TD_DAYU BITS(24,27) /*!< date units or week day in BCD code */ +#define RTC_ALRM0TD_DAYT BITS(28,29) /*!< date tens in BCD code */ +#define RTC_ALRM0TD_DOWS BIT(30) /*!< day of week selection */ +#define RTC_ALRM0TD_MSKD BIT(31) /*!< alarm date mask bit */ + +/* RTC_WPK */ +#define RTC_WPK_WPK BITS(0,7) /*!< key for write protection */ + +/* RTC_SS */ +#define RTC_SS_SSC BITS(0,15) /*!< sub second value */ + +/* RTC_SHIFTCTL */ +#define RTC_SHIFTCTL_SFS BITS(0,14) /*!< subtract a fraction of a second */ +#define RTC_SHIFTCTL_A1S BIT(31) /*!< one second add */ + +/* RTC_TTS */ +#define RTC_TTS_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TTS_SCT BITS(4,6) /*!< second units in BCD code */ +#define RTC_TTS_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TTS_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TTS_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TTS_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TTS_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DTS */ +#define RTC_DTS_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DTS_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DTS_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DTS_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DTS_DOW BITS(13,15) /*!< day of week units */ + +/* RTC_SSTS */ +#define RTC_SSTS_SSC BITS(0,15) /*!< timestamp sub second units */ + +/* RTC_HRFC */ +#define RTC_HRFC_CMSK BITS(0,8) /*!< calibration mask number */ +#define RTC_HRFC_CWND16 BIT(13) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_CWND8 BIT(14) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_FREQI BIT(15) /*!< increase RTC frequency by 488.5ppm */ + +/* RTC_TAMP */ +#define RTC_TAMP_TP0EN BIT(0) /*!< tamper 0 detection enable */ +#define RTC_TAMP_TP0EG BIT(1) /*!< tamper 0 event trigger edge for RTC tamp 0 input */ +#define RTC_TAMP_TPIE BIT(2) /*!< tamper detection interrupt enable */ +#define RTC_TAMP_TP1EN BIT(3) /*!< tamper 1 detection enable */ +#define RTC_TAMP_TP1EG BIT(4) /*!< tamper 1 event trigger edge for RTC tamp 1 input */ +#define RTC_TAMP_TPTS BIT(7) /*!< make tamper function used for timestamp function */ +#define RTC_TAMP_FREQ BITS(8,10) /*!< sample frequency of tamper event detection */ +#define RTC_TAMP_FLT BITS(11,12) /*!< RTC tamp x filter count setting */ +#define RTC_TAMP_PRCH BITS(13,14) /*!< precharge duration time of RTC tamp x */ +#define RTC_TAMP_DISPU BIT(15) /*!< RTC tamp x pull up disable bit */ +#define RTC_TAMP_PC13VAL BIT(18) /*!< alarm output type control/PC13 output value */ +#define RTC_TAMP_PC13MDE BIT(19) /*!< PC13 mode */ +#define RTC_TAMP_PC14VAL BIT(20) /*!< PC14 output value */ +#define RTC_TAMP_PC14MDE BIT(21) /*!< PC14 mode */ +#define RTC_TAMP_PC15VAL BIT(22) /*!< PC15 output value */ +#define RTC_TAMP_PC15MDE BIT(23) /*!< PC15 mode */ + +/* RTC_ALRM0SS */ +#define RTC_ALRM0SS_SSC BITS(0,14) /*!< alarm sub second value */ +#define RTC_ALRM0SS_MASKSSC BITS(24,27) /*!< mask control bit of SS */ + +/* RTC_BKP0 */ +#define RTC_BKP0_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP1 */ +#define RTC_BKP1_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP2 */ +#define RTC_BKP2_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP3 */ +#define RTC_BKP3_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP4 */ +#define RTC_BKP4_DATA BITS(0,31) /*!< backup domain registers */ + + +/* constants definitions */ +/* structure for initialization of the RTC */ +typedef struct +{ + uint8_t rtc_year; /*!< RTC year value: 0x0 - 0x99(BCD format) */ + uint8_t rtc_month; /*!< RTC month value */ + uint8_t rtc_date; /*!< RTC date value: 0x1 - 0x31(BCD format) */ + uint8_t rtc_day_of_week; /*!< RTC weekday value */ + uint8_t rtc_hour; /*!< RTC hour value */ + uint8_t rtc_minute; /*!< RTC minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_second; /*!< RTC second value: 0x0 - 0x59(BCD format) */ + uint16_t rtc_factor_asyn; /*!< RTC asynchronous prescaler value: 0x0 - 0x7F */ + uint16_t rtc_factor_syn; /*!< RTC synchronous prescaler value: 0x0 - 0x7FFF */ + uint32_t rtc_am_pm; /*!< RTC AM/PM value */ + uint32_t rtc_display_format; /*!< RTC time notation */ +}rtc_parameter_struct; + +/* structure for RTC alarm configuration */ +typedef struct +{ + uint32_t rtc_alarm_mask; /*!< RTC alarm mask */ + uint32_t rtc_weekday_or_date; /*!< specify RTC alarm is on date or weekday */ + uint8_t rtc_alarm_day; /*!< RTC alarm date or weekday value*/ + uint8_t rtc_alarm_hour; /*!< RTC alarm hour value */ + uint8_t rtc_alarm_minute; /*!< RTC alarm minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_alarm_second; /*!< RTC alarm second value: 0x0 - 0x59(BCD format) */ + uint32_t rtc_am_pm; /*!< RTC alarm AM/PM value */ +}rtc_alarm_struct; + +/* structure for RTC time-stamp configuration */ +typedef struct +{ + uint8_t rtc_timestamp_month; /*!< RTC time-stamp month value */ + uint8_t rtc_timestamp_date; /*!< RTC time-stamp date value: 0x1 - 0x31(BCD format) */ + uint8_t rtc_timestamp_day; /*!< RTC time-stamp weekday value */ + uint8_t rtc_timestamp_hour; /*!< RTC time-stamp hour value */ + uint8_t rtc_timestamp_minute; /*!< RTC time-stamp minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_timestamp_second; /*!< RTC time-stamp second value: 0x0 - 0x59(BCD format) */ + uint32_t rtc_am_pm; /*!< RTC time-stamp AM/PM value */ +}rtc_timestamp_struct; + +/* structure for RTC tamper configuration */ +typedef struct +{ + uint32_t rtc_tamper_source; /*!< RTC tamper source */ + uint32_t rtc_tamper_trigger; /*!< RTC tamper trigger */ + uint32_t rtc_tamper_filter; /*!< RTC tamper consecutive samples needed during a voltage level detection */ + uint32_t rtc_tamper_sample_frequency; /*!< RTC tamper sampling frequency during a voltage level detection */ + ControlStatus rtc_tamper_precharge_enable; /*!< RTC tamper precharge feature during a voltage level detection */ + uint32_t rtc_tamper_precharge_time; /*!< RTC tamper precharge duration if precharge feature is enabled */ + ControlStatus rtc_tamper_with_timestamp; /*!< RTC tamper time-stamp feature */ +}rtc_tamper_struct; + +/* time register value */ +#define TIME_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_TIME_SC bit field */ +#define GET_TIME_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TIME_SC bit field */ + +#define TIME_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TIME_MN bit field */ +#define GET_TIME_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TIME_MN bit field */ + +#define TIME_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U))/*!< write value to RTC_TIME_HR bit field */ +#define GET_TIME_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TIME_HR bit field */ + +#define RTC_AM ((uint32_t)0x00000000U) /*!< AM format */ +#define RTC_PM RTC_TIME_PM /*!< PM format */ + +/* date register value */ +#define DATE_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_DATE_DAY bit field */ +#define GET_DATE_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DATE_DAY bit field */ + +#define DATE_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_DATE_MON bit field */ +#define GET_DATE_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DATE_MON bit field */ +#define RTC_JAN ((uint8_t)0x01U) /*!< Janurary */ +#define RTC_FEB ((uint8_t)0x02U) /*!< February */ +#define RTC_MAR ((uint8_t)0x03U) /*!< March */ +#define RTC_APR ((uint8_t)0x04U) /*!< April */ +#define RTC_MAY ((uint8_t)0x05U) /*!< May */ +#define RTC_JUN ((uint8_t)0x06U) /*!< June */ +#define RTC_JUL ((uint8_t)0x07U) /*!< July */ +#define RTC_AUG ((uint8_t)0x08U) /*!< August */ +#define RTC_SEP ((uint8_t)0x09U) /*!< September */ +#define RTC_OCT ((uint8_t)0x10U) /*!< October */ +#define RTC_NOV ((uint8_t)0x11U) /*!< November */ +#define RTC_DEC ((uint8_t)0x12U) /*!< December */ + +#define DATE_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U))/*!< write value to RTC_DATE_DOW bit field */ +#define GET_DATE_DOW(regval) GET_BITS((regval),13,15) /*!< get value of RTC_DATE_DOW bit field */ +#define RTC_MONDAY ((uint8_t)0x01) /*!< Monday */ +#define RTC_TUESDAY ((uint8_t)0x02) /*!< Tuesday */ +#define RTC_WEDSDAY ((uint8_t)0x03) /*!< Wednesday */ +#define RTC_THURSDAY ((uint8_t)0x04) /*!< Thursday */ +#define RTC_FRIDAY ((uint8_t)0x05) /*!< Friday */ +#define RTC_SATURDAY ((uint8_t)0x06) /*!< Saturday */ +#define RTC_SUNDAY ((uint8_t)0x07) /*!< Sunday */ + +#define DATE_YR(regval) (BITS(16,23) & ((uint32_t)(regval) << 16U))/*!< write value to RTC_DATE_YR bit field */ +#define GET_DATE_YR(regval) GET_BITS((regval),16,23) /*!< get value of RTC_DATE_YR bit field */ + +/* ctl register value */ +#define CTL_OS(regval) (BITS(21,22) & ((uint32_t)(regval) << 21U))/*!< write value to RTC_CTL_OS bit field */ +#define RTC_OS_DISABLE CTL_OS(0) /*!< disable output RTC_ALARM */ +#define RTC_OS_ENABLE CTL_OS(1) /*!< enable alarm flag output */ + +#define RTC_CALIBRATION_512HZ RTC_CTL_COEN /*!< calibration output of 512Hz is enable */ +#define RTC_CALIBRATION_1HZ RTC_CTL_COEN | RTC_CTL_COS /*!< calibration output of 1Hz is enable */ +#define RTC_ALARM_HIGH RTC_CTL_OS_ENABLE /*!< enable alarm flag output with high level */ +#define RTC_ALARM_LOW RTC_CTL_OS_ENABLE | RTC_CTL_OPOL /*!< enable alarm flag output with low level*/ + +#define RTC_24HOUR ((uint32_t)0x00000000U) /*!< 24-hour format */ +#define RTC_12HOUR RTC_CTL_CS /*!< 12-hour format */ + +#define RTC_TIMESTAMP_RISING_EDGE ((uint32_t)0x00000000U) /*!< rising edge is valid event edge for time-stamp event */ +#define RTC_TIMESTAMP_FALLING_EDGE RTC_CTL_TSEG /*!< falling edge is valid event edge for time-stamp event */ + +/* psc register value */ +#define PSC_FACTOR_S(regval) (BITS(0,14) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_PSC_FACTOR_S bit field */ +#define GET_PSC_FACTOR_S(regval) GET_BITS((regval),0,14) /*!< get value of RTC_PSC_FACTOR_S bit field */ + +#define PSC_FACTOR_A(regval) (BITS(16,22) & ((uint32_t)(regval) << 16U))/*!< write value to RTC_PSC_FACTOR_A bit field */ +#define GET_PSC_FACTOR_A(regval) GET_BITS((regval),16,22) /*!< get value of RTC_PSC_FACTOR_A bit field */ + +/* alrm0td register value */ +#define ALRM0TD_SC(regval) (BITS(0,6) & ((uint32_t)(regval)<< 0U)) /*!< write value to RTC_ALRM0TD_SC bit field */ +#define GET_ALRM0TD_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_ALRM0TD_SC bit field */ + +#define ALRM0TD_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_ALRM0TD_MN bit field */ +#define GET_ALRM0TD_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_ALRM0TD_MN bit field */ + +#define ALRM0TD_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U))/*!< write value to RTC_ALRM0TD_HR bit field */ +#define GET_ALRM0TD_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_ALRM0TD_HR bit field */ + +#define ALRM0TD_DAY(regval) (BITS(24,29) & ((uint32_t)(regval) << 24U))/*!< write value to RTC_ALRM0TD_DAY bit field */ +#define GET_ALRM0TD_DAY(regval) GET_BITS((regval),24,29) /*!< get value of RTC_ALRM0TD_DAY bit field */ + +#define RTC_ALARM_NONE_MASK ((uint32_t)0x00000000U) /*!< alarm none mask */ +#define RTC_ALARM_DATE_MASK RTC_ALRM0TD_MSKD /*!< alarm date mask */ +#define RTC_ALARM_HOUR_MASK RTC_ALRM0TD_MSKH /*!< alarm hour mask */ +#define RTC_ALARM_MINUTE_MASK RTC_ALRM0TD_MSKM /*!< alarm minute mask */ +#define RTC_ALARM_SECOND_MASK RTC_ALRM0TD_MSKS /*!< alarm second mask */ +#define RTC_ALARM_ALL_MASK (RTC_ALRM0TD_MSKD|RTC_ALRM0TD_MSKH|RTC_ALRM0TD_MSKM|RTC_ALRM0TD_MSKS) /*!< alarm all mask */ + +#define RTC_ALARM_DATE_SELECTED ((uint32_t)0x00000000U) /*!< alarm date format selected */ +#define RTC_ALARM_WEEKDAY_SELECTED RTC_ALRM0TD_DOWS /*!< alarm weekday format selected */ + +/* wpk register value */ +#define WPK_WPK(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_WPK_WPK bit field */ + +/* ss register value */ +#define SS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SS_SSC bit field */ + +/* shiftctl register value */ +#define SHIFTCTL_SFS(regval) (BITS(0,14) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SHIFTCTL_SFS bit field */ + +#define RTC_SHIFT_ADD1S_RESET ((uint32_t)0x00000000U) /*!< not add 1 second */ +#define RTC_SHIFT_ADD1S_SET RTC_SHIFTCTL_A1S /*!< add one second to the clock */ + +/* tts register value */ +#define TTS_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_TTS_SC bit field */ +#define GET_TTS_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TTS_SC bit field */ + +#define TTS_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TTS_MN bit field */ +#define GET_TTS_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TTS_MN bit field */ + +#define TTS_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U))/*!< write value to RTC_TTS_HR bit field */ +#define GET_TTS_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TTS_HR bit field */ + +/* dts register value */ +#define DTS_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_DTS_DAY bit field */ +#define GET_DTS_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DTS_DAY bit field */ + +#define DTS_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_DTS_MON bit field */ +#define GET_DTS_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DTS_MON bit field */ + +#define DTS_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U))/*!< write value to RTC_DTS_DOW bit field */ +#define GET_DTS_DOW(regval) GET_BITS((regval),13,15) /*!< get value of RTC_DTS_DOW bit field */ + +/* ssts register value */ +#define SSTS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SSTS_SSC bit field */ + +/* hrfc register value */ +#define HRFC_CMSK(regval) (BITS(0,8) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_HRFC_CMSK bit field */ + +#define RTC_CALIBRATION_WINDOW_32S ((uint32_t)0x00000000U) /*!< 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_16S RTC_HRFC_CWND16 /*!< 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_8S RTC_HRFC_CWND8 /*!< 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz */ + +#define RTC_CALIBRATION_PLUS_SET RTC_HRFC_FREQI /*!< increase RTC frequency by 488.5ppm */ +#define RTC_CALIBRATION_PLUS_RESET ((uint32_t)0x00000000U) /*!< no effect */ + +/* tamp register value */ +#define TAMP_FREQ(regval) (BITS(8,10) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TAMP_FREQ bit field */ +#define RTC_FREQ_DIV32768 TAMP_FREQ(0) /*!< sample once every 32768 RTCCLK(1Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV16384 TAMP_FREQ(1) /*!< sample once every 16384 RTCCLK(2Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV8192 TAMP_FREQ(2) /*!< sample once every 8192 RTCCLK(4Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV4096 TAMP_FREQ(3) /*!< sample once every 4096 RTCCLK(8Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV2048 TAMP_FREQ(4) /*!< sample once every 2048 RTCCLK(16Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV1024 TAMP_FREQ(5) /*!< sample once every 1024 RTCCLK(32Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV512 TAMP_FREQ(6) /*!< sample once every 512 RTCCLK(64Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV256 TAMP_FREQ(7) /*!< sample once every 256 RTCCLK(128Hz if RTCCLK=32.768KHz) */ + +#define TAMP_FLT(regval) (BITS(11,12) & ((uint32_t)(regval) << 11U))/*!< write value to RTC_TAMP_FLT bit field */ +#define RTC_FLT_EDGE TAMP_FLT(0) /*!< detecting tamper event using edge mode. precharge duration is disabled automatically */ +#define RTC_FLT_2S TAMP_FLT(1) /*!< detecting tamper event using level mode.2 consecutive valid level samples will make a effective tamper event */ +#define RTC_FLT_4S TAMP_FLT(2) /*!< detecting tamper event using level mode.4 consecutive valid level samples will make an effective tamper event */ +#define RTC_FLT_8S TAMP_FLT(3) /*!< detecting tamper event using level mode.8 consecutive valid level samples will make a effective tamper event */ + +#define TAMP_PRCH(regval) (BITS(13,14 ) & ((uint32_t)(regval) << 13U))/*!< write value to RTC_TAMP_PRCH bit field */ +#define RTC_PRCH_1C TAMP_PRCH(0) /*!< 1 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_2C TAMP_PRCH(1) /*!< 2 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_4C TAMP_PRCH(2) /*!< 4 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_8C TAMP_PRCH(3) /*!< 8 RTC clock prechagre time before each sampling */ + +#define RTC_TAMPER0 RTC_TAMP_TP0EN /*!< tamper 0 detection enable */ +#define RTC_TAMPER1 RTC_TAMP_TP1EN /*!< tamper 1 detection enable */ + +#define RTC_TAMPER_TRIGGER_EDGE_RISING ((uint32_t)0x00000000U) /*!< tamper detection is in rising edge mode */ +#define RTC_TAMPER_TRIGGER_EDGE_FALLING RTC_TAMP_TP0EG /*!< tamper detection is in falling edge mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_LOW ((uint32_t)0x00000000U) /*!< tamper detection is in low level mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_HIGH RTC_TAMP_TP0EG /*!< tamper detection is in high level mode */ + +#define RTC_TAMPER_TRIGGER_POS ((uint32_t)0x00000001U) /* shift position of trigger relative to source */ + +#define RTC_ALARM_OUTPUT_OD ((uint32_t)0x00000000U) /*!< RTC alarm output open-drain mode */ +#define RTC_ALARM_OUTPUT_PP RTC_TAMP_PC13VAL /*!< RTC alarm output push-pull mode */ + +/* alrm0ss register value */ +#define ALRM0SS_SSC(regval) (BITS(0,14) & ((uint32_t)(regval)<< 0U)) /*!< write value to RTC_ALRM0SS_SSC bit field */ + +#define ALRM0SS_MASKSSC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24U))/*!< write value to RTC_ALRM0SS_MASKSSC bit field */ +#define RTC_MASKSSC_0_14 ALRM0SS_MASKSSC(0) /*!< mask alarm subsecond configuration */ +#define RTC_MASKSSC_1_14 ALRM0SS_MASKSSC(1) /*!< mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared */ +#define RTC_MASKSSC_2_14 ALRM0SS_MASKSSC(2) /*!< mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared */ +#define RTC_MASKSSC_3_14 ALRM0SS_MASKSSC(3) /*!< mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared */ +#define RTC_MASKSSC_4_14 ALRM0SS_MASKSSC(4) /*!< mask RTC_ALRM0SS_SSC[14:4], and RTC_ALRM0SS_SSC[3:0] is to be compared */ +#define RTC_MASKSSC_5_14 ALRM0SS_MASKSSC(5) /*!< mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared */ +#define RTC_MASKSSC_6_14 ALRM0SS_MASKSSC(6) /*!< mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared */ +#define RTC_MASKSSC_7_14 ALRM0SS_MASKSSC(7) /*!< mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared */ +#define RTC_MASKSSC_8_14 ALRM0SS_MASKSSC(8) /*!< mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared */ +#define RTC_MASKSSC_9_14 ALRM0SS_MASKSSC(9) /*!< mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared */ +#define RTC_MASKSSC_10_14 ALRM0SS_MASKSSC(10) /*!< mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared */ +#define RTC_MASKSSC_11_14 ALRM0SS_MASKSSC(11) /*!< mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared */ +#define RTC_MASKSSC_12_14 ALRM0SS_MASKSSC(12) /*!< mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared */ +#define RTC_MASKSSC_13_14 ALRM0SS_MASKSSC(13) /*!< mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared */ +#define RTC_MASKSSC_14 ALRM0SS_MASKSSC(14) /*!< mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared */ +#define RTC_MASKSSC_NONE ALRM0SS_MASKSSC(15) /*!< mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared */ + +/* RTC interrupt source */ +#define RTC_INT_TIMESTAMP RTC_CTL_TSIE /*!< time-stamp interrupt enable */ +#define RTC_INT_ALARM RTC_CTL_ALRM0IE /*!< RTC alarm interrupt enable */ +#define RTC_INT_TAMP RTC_TAMP_TPIE /*!< tamper detection interrupt enable */ + +/* write protect key */ +#define RTC_UNLOCK_KEY1 ((uint8_t)0xCAU) /*!< RTC unlock key1 */ +#define RTC_UNLOCK_KEY2 ((uint8_t)0x53U) /*!< RTC unlock key2 */ +#define RTC_LOCK_KEY ((uint8_t)0xFFU) /*!< RTC lock key */ + +/* registers reset value */ +#define RTC_REGISTER_RESET ((uint32_t)0x00000000U) /*!< RTC common register reset value */ +#define RTC_DATE_RESET ((uint32_t)0x00002101U) /*!< RTC_DATE register reset value */ +#define RTC_STAT_RESET ((uint32_t)0x00000007U) /*!< RTC_STAT register reset value */ +#define RTC_PSC_RESET ((uint32_t)0x007F00FFU) /*!< RTC_PSC register reset value */ + +/* RTC timeout value */ +#define RTC_INITM_TIMEOUT ((uint32_t)0x00004000U) /*!< initialization state flag timeout */ +#define RTC_RSYNF_TIMEOUT ((uint32_t)0x00008000U) /*!< register synchronization flag timeout */ +#define RTC_HRFC_TIMEOUT ((uint32_t)0x00001000U) /*!< recalibration pending flag timeout */ +#define RTC_SHIFTCTL_TIMEOUT ((uint32_t)0x00001000U) /*!< shift function operation pending flag timeout */ +#define RTC_ALRM0WF_TIMEOUT ((uint32_t)0x00008000U) /*!< alarm configuration can be write flag timeout */ + +/* RTC flag */ +#define RTC_FLAG_RECALIBRATION RTC_STAT_SCPF /*!< recalibration pending flag */ +#define RTC_FLAG_TAMP1 RTC_STAT_TP1F /*!< tamper 1 event flag */ +#define RTC_FLAG_TAMP0 RTC_STAT_TP0F /*!< tamper 0 event flag */ +#define RTC_FLAG_TIMESTAMP_OVERFLOW RTC_STAT_TSOVRF /*!< time-stamp overflow event flag */ +#define RTC_FLAG_TIMESTAMP RTC_STAT_TSF /*!< time-stamp event flag */ +#define RTC_FLAG_ALARM0 RTC_STAT_ALRM0F /*!< alarm event flag */ +#define RTC_FLAG_INIT RTC_STAT_INITF /*!< init mode event flag */ +#define RTC_FLAG_RSYN RTC_STAT_RSYNF /*!< registers synchronized flag */ +#define RTC_FLAG_YCM RTC_STAT_YCM /*!< year parameter configured event flag */ +#define RTC_FLAG_SHIFT RTC_STAT_SOPF /*!< shift operation pending flag */ +#define RTC_FLAG_ALARM0_WRITTEN RTC_STAT_ALRM0WF /*!< alarm written available flag */ + +/* function declarations */ +/* reset most of the RTC registers */ +ErrStatus rtc_deinit(void); +/* initialize RTC registers */ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct); +/* enter RTC init mode */ +ErrStatus rtc_init_mode_enter(void); +/* exit RTC init mode */ +void rtc_init_mode_exit(void); +/* wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow registers are updated */ +ErrStatus rtc_register_sync_wait(void); + +/* get current time and date */ +void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct); +/* get current subsecond value */ +uint32_t rtc_subsecond_get(void); + +/* configure RTC alarm */ +void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time); +/* configure subsecond of RTC alarm */ +void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond); +/* get RTC alarm */ +void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time); +/* get RTC alarm subsecond */ +uint32_t rtc_alarm_subsecond_get(void); +/* enable RTC alarm */ +void rtc_alarm_enable(void); +/* disable RTC alarm */ +ErrStatus rtc_alarm_disable(void); + +/* enable RTC time-stamp */ +void rtc_timestamp_enable(uint32_t edge); +/* disable RTC time-stamp */ +void rtc_timestamp_disable(void); +/* get RTC timestamp time and date */ +void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp); +/* get RTC time-stamp subsecond */ +uint32_t rtc_timestamp_subsecond_get(void); + +/* enable RTC tamper */ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper); +/* disable RTC tamper */ +void rtc_tamper_disable(uint32_t source); + +/* enable specified RTC interrupt */ +void rtc_interrupt_enable(uint32_t interrupt); +/* disble specified RTC interrupt */ +void rtc_interrupt_disable(uint32_t interrupt); +/* check specified flag */ +FlagStatus rtc_flag_get(uint32_t flag); +/* clear specified flag */ +void rtc_flag_clear(uint32_t flag); + +/* configure RTC alternate output source */ +void rtc_alter_output_config(uint32_t source, uint32_t mode); +/* configure RTC calibration register */ +ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus); +/* ajust the daylight saving time by adding or substracting one hour from the current time */ +void rtc_hour_adjust(uint32_t operation); +/* ajust RTC second or subsecond value of current time */ +ErrStatus rtc_second_ajust(uint32_t add, uint32_t minus); +/* enable RTC bypass shadow registers function */ +void rtc_bypass_shadow_enable(void); +/* disable RTC bypass shadow registers function */ +void rtc_bypass_shadow_disable(void); +/* enable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_enable(void); +/* disable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_disable(void); + +#endif /* GD32F1X0_RTC_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_slcd.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_slcd.h new file mode 100644 index 0000000..76e1002 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_slcd.h @@ -0,0 +1,255 @@ +/*! + \file gd32f1x0_slcd.h + \brief definitions for the SLCD +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 +#ifndef GD32F1X0_SLCD_H +#define GD32F1X0_SLCD_H + +#include "gd32f1x0.h" + +/* SLCD definitions */ +#define SLCD SLCD_BASE + +/* registers definitions */ +#define SLCD_CTL REG32(SLCD + 0x00U) /*!< SLCD controller register */ +#define SLCD_CFG REG32(SLCD + 0x04U) /*!< SLCD configuration register */ +#define SLCD_STAT REG32(SLCD + 0x08U) /*!< SLCD status flag register */ +#define SLCD_STATC REG32(SLCD + 0x0CU) /*!< SLCD status flag clear register */ +#define SLCD_DATA0 REG32(SLCD + 0x14U) /*!< SLCD display data register 0 */ +#define SLCD_DATA1 REG32(SLCD + 0x1CU) /*!< SLCD display data register 1 */ +#define SLCD_DATA2 REG32(SLCD + 0x24U) /*!< SLCD display data register 2 */ +#define SLCD_DATA3 REG32(SLCD + 0x2CU) /*!< SLCD display data register 3 */ +#define SLCD_DATA4 REG32(SLCD + 0x34U) /*!< SLCD display data register 4 */ +#define SLCD_DATA5 REG32(SLCD + 0x3CU) /*!< SLCD display data register 5 */ +#define SLCD_DATA6 REG32(SLCD + 0x44U) /*!< SLCD display data register 6 */ +#define SLCD_DATA7 REG32(SLCD + 0x4CU) /*!< SLCD display data register 7 */ + +/* bits definitions */ +/* SLCD_CTL */ +#define SLCD_CTL_LCDON BIT(0) /*!< SLCD controller start */ +#define SLCD_CTL_VSRC BIT(1) /*!< SLCD Voltage source */ +#define SLCD_CTL_DUTY BITS(2,4) /*!< duty select */ +#define SLCD_CTL_BIAS BITS(5,6) /*!< SLCD bias voltage select */ +#define SLCD_CTL_COMS BIT(7) /*!< regular channel start flag */ + +/* SLCD_CFG */ +#define SLCD_CFG_HDEN BIT(0) /*!< high drive enable */ +#define SLCD_CFG_SOFIE BIT(1) /*!< start of frame interrupt enable */ +#define SLCD_CFG_UPDIE BIT(3) /*!< SLCD update done interrupt enable */ +#define SLCD_CFG_PULSE BITS(4,6) /*!< pulse on duration */ +#define SLCD_CFG_DTD BITS(7,9) /*!< dead time duration */ +#define SLCD_CFG_CONR BITS(10,12) /*!< contrast ratio */ +#define SLCD_CFG_BLKDIV BITS(13,15) /*!< blink frequency divider */ +#define SLCD_CFG_BLKMOD BITS(16,17) /*!< blink mode */ +#define SLCD_CFG_DIV BITS(18,21) /*!< SLCD clock divider */ +#define SLCD_CFG_PSC BITS(22,25) /*!< SLCD clock prescaler */ + +/* SLCD_STAT */ +#define SLCD_STAT_ONF BIT(0) /*!< SLCD controller on flag */ +#define SLCD_STAT_SOF BIT(1) /*!< start of frame flag */ +#define SLCD_STAT_UPRF BIT(2) /*!< SLCD data update request flag */ +#define SLCD_STAT_UPDF BIT(3) /*!< update data done flag */ +#define SLCD_STAT_VRDYF BIT(4) /*!< SLCD voltage ready flag */ +#define SLCD_STAT_SYNF BIT(5) /*!< SLCD register synchronization flag */ + +/* SLCD_STATC */ +#define SLCD_STATC_SOFC BIT(1) /*!< start of frame flag clear */ +#define SLCD_STATC_UPDC BIT(3) /*!< SLCD data update done clear bit */ + +/* SLCD_DATAx */ +#define SLCD_DATAx_DATA BITS(0,31) /*!< each bit corresponds to one segment to display */ + +/* constants definitions */ +/* status flag */ +#define SLCD_FLAG_ON SLCD_STAT_ONF /*!< SLCD controller on flag */ +#define SLCD_FLAG_SOF SLCD_STAT_SOF /*!< start of frame flag */ +#define SLCD_FLAG_UPR SLCD_STAT_UPRF /*!< SLCD data update request flag */ +#define SLCD_FLAG_UPD SLCD_STAT_UPDF /*!< update data done flag */ +#define SLCD_FLAG_VRDY SLCD_STAT_VRDYF /*!< SLCD voltage ready flag */ +#define SLCD_FLAG_SYN SLCD_STAT_SYNF /*!< SLCD register synchronization flag */ + +/* interrupt flag */ +#define SLCD_INT_FLAG_SOF ((uint8_t)0x00U) /*!< start of frame interrupt */ +#define SLCD_INT_FLAG_UPD ((uint8_t)0x01U) /*!< update data done interrupt */ + +/* interrupt source */ +#define SLCD_INT_SOF ((uint8_t)0x00U) /*!< start of frame interrupt */ +#define SLCD_INT_UPD ((uint8_t)0x01U) /*!< update data done interrupt */ + +/* voltage source definitions */ +#define SLCD_VOLTAGE_INTERNAL ((uint8_t)0x00U) /*!< SLCD internal voltage source */ +#define SLCD_VOLTAGE_EXTERNAL ((uint8_t)0x01U) /*!< SLCD external voltage source */ + +/* data register definitions */ +#define SLCD_DATA_REG0 ((uint32_t)0x00000000U) /*!< SLCD display data register 0 */ +#define SLCD_DATA_REG1 ((uint32_t)0x00000002U) /*!< SLCD display data register 1 */ +#define SLCD_DATA_REG2 ((uint32_t)0x00000004U) /*!< SLCD display data register 2 */ +#define SLCD_DATA_REG3 ((uint32_t)0x00000006U) /*!< SLCD display data register 3 */ +#define SLCD_DATA_REG4 ((uint32_t)0x00000008U) /*!< SLCD display data register 4 */ +#define SLCD_DATA_REG5 ((uint32_t)0x0000000AU) /*!< SLCD display data register 5 */ +#define SLCD_DATA_REG6 ((uint32_t)0x0000000CU) /*!< SLCD display data register 6 */ +#define SLCD_DATA_REG7 ((uint32_t)0x0000000EU) /*!< SLCD display data register 7 */ + +/* bias voltage definitions */ +#define CTL_BIAS(regval) (BITS(5,6) & ((uint32_t)(regval) << 5U)) +#define SLCD_BIAS_1_4 CTL_BIAS(0) /*!< 1/4 voltage bias */ +#define SLCD_BIAS_1_2 CTL_BIAS(1) /*!< 1/2 voltage bias */ +#define SLCD_BIAS_1_3 CTL_BIAS(2) /*!< 1/3 voltage bias */ + +/* duty select definitions */ +#define CTL_DUTY(regval) (BITS(2,4) & ((uint32_t)(regval) << 2U)) +#define SLCD_DUTY_STATIC CTL_DUTY(0) /*!< static dutycycle */ +#define SLCD_DUTY_1_2 CTL_DUTY(1) /*!< 1/2 dutycycle */ +#define SLCD_DUTY_1_3 CTL_DUTY(2) /*!< 1/3 dutycycle */ +#define SLCD_DUTY_1_4 CTL_DUTY(3) /*!< 1/4 dutycycle */ +#define SLCD_DUTY_1_6 CTL_DUTY(5) /*!< 1/6 dutycycle */ +#define SLCD_DUTY_1_8 CTL_DUTY(4) /*!< 1/8 dutycycle */ + +/* SLCD clock prescaler */ +#define CFG_PRE(regval) (BITS(22,25) & ((uint32_t)(regval) << 22U)) +#define SLCD_PRESCALER_1 CFG_PRE(0) /*!< PRE = 0 */ +#define SLCD_PRESCALER_2 CFG_PRE(1) /*!< PRE = 1 */ +#define SLCD_PRESCALER_4 CFG_PRE(2) /*!< PRE = 2 */ +#define SLCD_PRESCALER_8 CFG_PRE(3) /*!< PRE = 3 */ +#define SLCD_PRESCALER_16 CFG_PRE(4) /*!< PRE = 4 */ +#define SLCD_PRESCALER_32 CFG_PRE(5) /*!< PRE = 5 */ +#define SLCD_PRESCALER_64 CFG_PRE(6) /*!< PRE = 6 */ +#define SLCD_PRESCALER_128 CFG_PRE(7) /*!< PRE = 7 */ +#define SLCD_PRESCALER_256 CFG_PRE(8) /*!< PRE = 8 */ +#define SLCD_PRESCALER_512 CFG_PRE(9) /*!< PRE = 9 */ +#define SLCD_PRESCALER_1024 CFG_PRE(10) /*!< PRE = 10 */ +#define SLCD_PRESCALER_2048 CFG_PRE(11) /*!< PRE = 11 */ +#define SLCD_PRESCALER_4096 CFG_PRE(12) /*!< PRE = 12 */ +#define SLCD_PRESCALER_8192 CFG_PRE(13) /*!< PRE = 13 */ +#define SLCD_PRESCALER_16384 CFG_PRE(14) /*!< PRE = 14 */ +#define SLCD_PRESCALER_32768 CFG_PRE(15) /*!< PRE = 15 */ + +/* SLCD clock divider */ +#define CFG_DIV(regval) (BITS(18,21) & ((uint32_t)(regval) << 18U)) +#define SLCD_DIVIDER_16 CFG_DIV(0) /*!< DIV = 16 */ +#define SLCD_DIVIDER_17 CFG_DIV(1) /*!< DIV = 17 */ +#define SLCD_DIVIDER_18 CFG_DIV(2) /*!< DIV = 18 */ +#define SLCD_DIVIDER_19 CFG_DIV(3) /*!< DIV = 19 */ +#define SLCD_DIVIDER_20 CFG_DIV(4) /*!< DIV = 20 */ +#define SLCD_DIVIDER_21 CFG_DIV(5) /*!< DIV = 21 */ +#define SLCD_DIVIDER_22 CFG_DIV(6) /*!< DIV = 22 */ +#define SLCD_DIVIDER_23 CFG_DIV(7) /*!< DIV = 23 */ +#define SLCD_DIVIDER_24 CFG_DIV(8) /*!< DIV = 24 */ +#define SLCD_DIVIDER_25 CFG_DIV(9) /*!< DIV = 25 */ +#define SLCD_DIVIDER_26 CFG_DIV(10) /*!< DIV = 26 */ +#define SLCD_DIVIDER_27 CFG_DIV(11) /*!< DIV = 27 */ +#define SLCD_DIVIDER_28 CFG_DIV(12) /*!< DIV = 28 */ +#define SLCD_DIVIDER_29 CFG_DIV(13) /*!< DIV = 29 */ +#define SLCD_DIVIDER_30 CFG_DIV(14) /*!< DIV = 30 */ +#define SLCD_DIVIDER_31 CFG_DIV(15) /*!< DIV = 31 */ + +/* SLCD blink mode */ +#define CFG_BLKM(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define SLCD_BLINKMODE_OFF CFG_BLKM(0) /*!< blink disabled */ +#define SLCD_BLINKMODE_SEG0_COM0 CFG_BLKM(1) /*!< blink enabled on SEG[0], COM[0] */ +#define SLCD_BLINKMODE_SEG0_ALLCOM CFG_BLKM(2) /*!< blink enabled on SEG[0], all COM */ +#define SLCD_BLINKMODE_ALLSEG_ALLCOM CFG_BLKM(3) /*!< blink enabled on all SEG and all COM */ + +/* SLCD blink frequency divider */ +#define CFG_BLKDIV(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U)) +#define SLCD_BLINK_FREQUENCY_DIV8 CFG_BLKDIV(0) /*!< blink frequency = fSLCD/8 */ +#define SLCD_BLINK_FREQUENCY_DIV16 CFG_BLKDIV(1) /*!< blink frequency = fSLCD/16 */ +#define SLCD_BLINK_FREQUENCY_DIV32 CFG_BLKDIV(2) /*!< blink frequency = fSLCD/32 */ +#define SLCD_BLINK_FREQUENCY_DIV64 CFG_BLKDIV(3) /*!< blink frequency = fSLCD/64 */ +#define SLCD_BLINK_FREQUENCY_DIV128 CFG_BLKDIV(4) /*!< blink frequency = fSLCD/128 */ +#define SLCD_BLINK_FREQUENCY_DIV256 CFG_BLKDIV(5) /*!< blink frequency = fSLCD/256 */ +#define SLCD_BLINK_FREQUENCY_DIV512 CFG_BLKDIV(6) /*!< blink frequency = fSLCD/512 */ +#define SLCD_BLINK_FREQUENCY_DIV1024 CFG_BLKDIV(7) /*!< blink frequency = fSLCD/1024 */ + +/* SLCD Contrast ratio */ +#define CFG_CONR(regval) (BITS(10,12) & ((uint32_t)(regval) << 10U)) +#define SLCD_CONTRAST_LEVEL_0 CFG_CONR(0) /*!< maximum SLCD Voltage = 2.60V */ +#define SLCD_CONTRAST_LEVEL_1 CFG_CONR(1) /*!< maximum SLCD Voltage = 2.73V */ +#define SLCD_CONTRAST_LEVEL_2 CFG_CONR(2) /*!< maximum SLCD Voltage = 2.86V */ +#define SLCD_CONTRAST_LEVEL_3 CFG_CONR(3) /*!< maximum SLCD Voltage = 2.99V */ +#define SLCD_CONTRAST_LEVEL_4 CFG_CONR(4) /*!< maximum SLCD Voltage = 3.12V */ +#define SLCD_CONTRAST_LEVEL_5 CFG_CONR(5) /*!< maximum SLCD Voltage = 3.25V */ +#define SLCD_CONTRAST_LEVEL_6 CFG_CONR(6) /*!< maximum SLCD Voltage = 3.38V */ +#define SLCD_CONTRAST_LEVEL_7 CFG_CONR(7) /*!< maximum SLCD Voltage = 3.51V */ + +/* dead time duration */ +#define CFG_DD(regval) (BITS(7,9) & ((uint32_t)(regval) << 7U)) +#define SLCD_DEADTIME_PERIOD_0 CFG_DD(0) /*!< no dead time */ +#define SLCD_DEADTIME_PERIOD_1 CFG_DD(1) /*!< 1 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_2 CFG_DD(2) /*!< 2 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_3 CFG_DD(3) /*!< 3 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_4 CFG_DD(4) /*!< 4 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_5 CFG_DD(5) /*!< 5 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_6 CFG_DD(6) /*!< 6 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_7 CFG_DD(7) /*!< 7 phase inserted between couple of frame */ + +/* pulse on duration */ +#define CFG_PULSE(regval) (BITS(4,6) & ((uint32_t)(regval) << 4U)) +#define SLCD_PULSEON_DURATION_0 CFG_PULSE(0) /*!< pulse on duration = 0 */ +#define SLCD_PULSEON_DURATION_1 CFG_PULSE(1) /*!< pulse on duration = 1*1/fPRE */ +#define SLCD_PULSEON_DURATION_2 CFG_PULSE(2) /*!< pulse on duration = 2*1/fPRE */ +#define SLCD_PULSEON_DURATION_3 CFG_PULSE(3) /*!< pulse on duration = 3*1/fPRE */ +#define SLCD_PULSEON_DURATION_4 CFG_PULSE(4) /*!< pulse on duration = 4*1/fPRE */ +#define SLCD_PULSEON_DURATION_5 CFG_PULSE(5) /*!< pulse on duration = 5*1/fPRE */ +#define SLCD_PULSEON_DURATION_6 CFG_PULSE(6) /*!< pulse on duration = 6*1/fPRE */ +#define SLCD_PULSEON_DURATION_7 CFG_PULSE(7) /*!< pulse on duration = 7*1/fPRE */ + +/* function declarations */ +/* check the SLCD status flag */ +FlagStatus slcd_flag_get(uint8_t slcd_flag); +/* check the SLCD interrupt flag */ +FlagStatus slcd_interrupt_flag_get(uint8_t slcd_interrupt); +/* clear the SLCD flag */ +void slcd_flag_clear(uint8_t slcd_flag); +/* clear the SLCD interrupt flag */ +void slcd_interrupt_flag_clear(uint8_t slcd_interrupt); +/* the SLCD interrupt config */ +void slcd_interrupt_config(uint8_t slcd_interrupt,ControlStatus newvalue); + +/* SLCD bias voltage select */ +void slcd_bias_voltage_select(uint32_t bias_voltage); +/* SLCD duty select */ +void slcd_duty_select(uint32_t duty); +/* SLCD input clock config */ +void slcd_clock_config(uint32_t prescaler,uint32_t divider); +/* SLCD blink mode config */ +void slcd_blink_mode_config(uint32_t mode,uint32_t blink_divider); +/* SLCD contrast ratio config */ +void slcd_contrast_ratio_config(uint32_t contrast_ratio); +/* SLCD dead time duration config */ +void slcd_dead_time_config(uint32_t dead_time); +/* SLCD pulse on duration config */ +void slcd_pulse_on_duration_config(uint32_t duration); +/* SLCD common/segment pad select */ +void slcd_com_seg_remap(ControlStatus newvalue); +/* SLCD voltage source select */ +void slcd_voltage_source_select(uint8_t voltage_source); +/* SLCD high drive enable */ +void slcd_high_drive_config(ControlStatus newvalue); + +/* SLCD data register write */ +void slcd_data_register_write(uint32_t data_reg,uint32_t data); +/* SLCD data update request */ +void slcd_data_update_request(void); + +/* SLCD reset */ +void slcd_deinit(void); +/* enable SLCD interface */ +void slcd_enable(void); +/* disable SLCD interface */ +void slcd_disable(void); + +#endif /* GD32F1X0_SLCD_H */ + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_spi.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_spi.h new file mode 100644 index 0000000..82ad8a1 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_spi.h @@ -0,0 +1,321 @@ +/*! + \file gd32f1x0_spi.h + \brief definitions for the SPI +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_SPI_H +#define GD32F1X0_SPI_H + +#include "gd32f1x0.h" + +/* SPIx(x=0,1,2) definitions */ +#define SPI0 (SPI_BASE + 0x0000F800U) +#define SPI1 SPI_BASE +#define SPI2 (SPI_BASE + 0x00000400U) + +/* registers definitions */ +#define SPI_CTL0(spix) REG32((spix) + 0x00U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x04U) /*!< SPI control register 1*/ +#define SPI_STAT(spix) REG32((spix) + 0x08U) /*!< SPI status register */ +#define SPI_DATA(spix) REG32((spix) + 0x0CU) /*!< SPI data register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x10U) /*!< SPI CRC polynomial register */ +#define SPI_RCRC(spix) REG32((spix) + 0x14U) /*!< SPI receive CRC register */ +#define SPI_TCRC(spix) REG32((spix) + 0x18U) /*!< SPI transmit CRC register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x1CU) /*!< SPI I2S control register */ +#define SPI_I2SPSC(spix) REG32((spix) + 0x20U) /*!< SPI I2S clock prescaler register */ +#ifdef GD32F170_190 +#define SPI_QCTL(spix) REG32((spix) + 0x80U) /*!< SPI quad wire control register */ +#endif /* GD32F170_190 */ + +/* 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 selection */ +#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 transfer next */ +#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_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 config error */ +#define SPI_STAT_RXORERR BIT(6) /*!< SPI reception overrun error Bit */ +#define SPI_STAT_TRANS BIT(7) /*!< transmitting on-going 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_I2S_PSC */ +#define SPI_I2SPSC_DIV BITS(0,7) /*!< dividing factor for the prescaler */ +#define SPI_I2SPSC_OF BIT(8) /*!< odd factor for the prescaler */ +#define SPI_I2SPSC_MCKOEN BIT(9) /*!< I2S MCK output enable */ + +#ifdef GD32F170_190 +/* SPI_QCTL */ +#define SPI_QCTL_QMOD BIT(0) /*!< quad wire mode enable. */ +#define SPI_QCTL_QRD BIT(1) /*!< quad wire read select. */ +#define SPI_QCTL_IO23_DRV BIT(2) /*!< drive SPI_IO2 and SPI_IO3 */ +#endif /* GD32F170_190 */ + +/* 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 prescale factor */ +#define CTL0_PSC(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) +#define SPI_PSC_2 CTL0_PSC(0) /*!< SPI clock prescale factor is 2 */ +#define SPI_PSC_4 CTL0_PSC(1) /*!< SPI clock prescale factor is 4 */ +#define SPI_PSC_8 CTL0_PSC(2) /*!< SPI clock prescale factor is 8 */ +#define SPI_PSC_16 CTL0_PSC(3) /*!< SPI clock prescale factor is 16 */ +#define SPI_PSC_32 CTL0_PSC(4) /*!< SPI clock prescale factor is 32 */ +#define SPI_PSC_64 CTL0_PSC(5) /*!< SPI clock prescale factor is 64 */ +#define SPI_PSC_128 CTL0_PSC(6) /*!< SPI clock prescale factor is 128 */ +#define SPI_PSC_256 CTL0_PSC(7) /*!< SPI clock prescale factor is 256 */ + +/* I2S audio sample rate */ +#define I2S_AUDIOSAMPLE_8K ((uint32_t)8000U) /*!< I2S audio sample rate is 8KHz */ +#define I2S_AUDIOSAMPLE_11K ((uint32_t)11025U) /*!< I2S audio sample rate is 11KHz */ +#define I2S_AUDIOSAMPLE_16K ((uint32_t)16000U) /*!< I2S audio sample rate is 16KHz */ +#define I2S_AUDIOSAMPLE_22K ((uint32_t)22050U) /*!< I2S audio sample rate is 22KHz */ +#define I2S_AUDIOSAMPLE_32K ((uint32_t)32000U) /*!< I2S audio sample rate is 32KHz */ +#define I2S_AUDIOSAMPLE_44K ((uint32_t)44100U) /*!< I2S audio sample rate is 44KHz */ +#define I2S_AUDIOSAMPLE_48K ((uint32_t)48000U) /*!< I2S audio sample rate is 48KHz */ +#define I2S_AUDIOSAMPLE_96K ((uint32_t)96000U) /*!< I2S audio sample rate is 96KHz */ +#define I2S_AUDIOSAMPLE_192K ((uint32_t)192000U) /*!< I2S audio sample rate is 192KHz */ + +/* I2S frame format */ +#define I2SCTL_DTLEN(regval) (BITS(1,2) & ((uint32_t)(regval) << 1)) +#define I2S_FRAMEFORMAT_DT16B_CH16B I2SCTL_DTLEN(0) /*!< I2S data length is 16 bit and channel length is 16 bit */ +#define I2S_FRAMEFORMAT_DT16B_CH32B (I2SCTL_DTLEN(0) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 16 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT24B_CH32B (I2SCTL_DTLEN(1) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 24 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT32B_CH32B (I2SCTL_DTLEN(2) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 32 bit and channel length is 32 bit */ + +/* I2S master clock output */ +#define I2S_MCKOUT_DISABLE ((uint32_t)0x00000000U) /*!< I2S master clock output disable */ +#define I2S_MCKOUT_ENABLE SPI_I2SPSC_MCKOEN /*!< I2S master clock output enable */ + +/* I2S operation mode */ +#define I2SCTL_I2SOPMOD(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define I2S_MODE_SLAVETX I2SCTL_I2SOPMOD(0) /*!< I2S slave transmit mode */ +#define I2S_MODE_SLAVERX I2SCTL_I2SOPMOD(1) /*!< I2S slave receive mode */ +#define I2S_MODE_MASTERTX I2SCTL_I2SOPMOD(2) /*!< I2S master transmit mode */ +#define I2S_MODE_MASTERRX I2SCTL_I2SOPMOD(3) /*!< I2S master receive mode */ + +/* I2S standard */ +#define I2SCTL_I2SSTD(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define I2S_STD_PHILLIPS I2SCTL_I2SSTD(0) /*!< I2S phillips standard */ +#define I2S_STD_MSB I2SCTL_I2SSTD(1) /*!< I2S MSB standard */ +#define I2S_STD_LSB I2SCTL_I2SSTD(2) /*!< I2S LSB standard */ +#define I2S_STD_PCMSHORT I2SCTL_I2SSTD(3) /*!< I2S PCM short standard */ +#define I2S_STD_PCMLONG (I2SCTL_I2SSTD(3) | SPI_I2SCTL_PCMSMOD) /*!< I2S PCM long standard */ + +/* I2S clock polarity */ +#define I2S_CKPL_LOW ((uint32_t)0x00000000U) /*!< I2S clock polarity low level */ +#define I2S_CKPL_HIGH SPI_I2SCTL_CKPL /*!< I2S clock polarity high level */ + +/* SPI DMA constants definitions */ +#define SPI_DMA_TRANSMIT ((uint8_t)0x00U) /*!< SPI transmit data use DMA */ +#define SPI_DMA_RECEIVE ((uint8_t)0x01U) /*!< SPI receive data use DMA */ + +/* SPI CRC constants definitions */ +#define SPI_CRC_TX ((uint8_t)0x00U) /*!< SPI transmit CRC value */ +#define SPI_CRC_RX ((uint8_t)0x01U) /*!< SPI receive CRC value */ + +/* SPI/I2S interrupt enable/disable constants definitions */ +#define SPI_I2S_INT_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt */ +#define SPI_I2S_INT_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt */ +#define SPI_I2S_INT_ERR ((uint8_t)0x02U) /*!< error interrupt */ + +/* SPI/I2S interrupt flag constants definitions */ +#define SPI_I2S_INT_FLAG_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt */ +#define SPI_I2S_INT_FLAG_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt */ +#define SPI_I2S_INT_FLAG_RXORERR ((uint8_t)0x02U) /*!< overrun interrupt */ +#define SPI_INT_FLAG_CONFERR ((uint8_t)0x03U) /*!< config error interrupt */ +#define SPI_INT_FLAG_CRCERR ((uint8_t)0x04U) /*!< CRC error interrupt */ +#define I2S_INT_FLAG_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt */ + +/* 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 flag */ +#define SPI_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define I2S_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define I2S_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define I2S_FLAG_CH SPI_STAT_I2SCH /*!< transmit buffer empty interrupt */ +#define I2S_FLAG_TXURERR SPI_STAT_TXURERR /*!< underrun error flag */ +#define I2S_FLAG_RXORERR SPI_STAT_RXORERR /*!< overrun flag */ +#define I2S_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ + +/* function declarations */ +/* reset SPI and I2S */ +void spi_i2s_deinit(uint32_t spi_periph); +/* initialize SPI parameter */ +void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct); +/* enable SPI */ +void spi_enable(uint32_t spi_periph); +/* disable SPI */ +void spi_disable(uint32_t spi_periph); + +/* configure I2S prescaler */ +void i2s_psc_config(uint32_t spi_periph,uint32_t audiosample,uint32_t frameformat,uint32_t mckout); +/* initialize I2S parameter */ +void i2s_init(uint32_t spi_periph,uint32_t mode,uint32_t standard,uint32_t ckpl); +/* enable I2S */ +void i2s_enable(uint32_t spi_periph); +/* disable I2S */ +void i2s_disable(uint32_t spi_periph); + +/* 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); + +/* enable SPI DMA */ +void spi_dma_enable(uint32_t spi_periph, uint8_t dma); +/* disable SPI DMA */ +void spi_dma_disable(uint32_t spi_periph, uint8_t dma); + +/* configure SPI/I2S data frame format */ +void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format); +/* SPI transmit data */ +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data); +/* SPI receive data */ +uint16_t spi_i2s_data_receive(uint32_t spi_periph); +/* configure SPI bidirectional transfer direction */ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction); + +/* 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); +/* get SPI and I2S flag status */ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph,uint32_t flag); +/* clear SPI CRC error flag status */ +void spi_crc_error_clear(uint32_t spi_periph); + +/* 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); + +#ifdef GD32F170_190 +/* enable quad wire SPI */ +void qspi_enable(uint32_t spi_periph); +/* disable quad wire SPI */ +void qspi_disable(uint32_t spi_periph); +/* enable quad wire SPI write */ +void qspi_write_enable(uint32_t spi_periph); +/* enable quad wire SPI read */ +void qspi_read_enable(uint32_t spi_periph); +/* enable quad wire SPI_IO2 and SPI_IO3 pin output */ +void qspi_io23_output_enable(uint32_t spi_periph); +/* disable quad wire SPI_IO2 and SPI_IO3 pin output */ +void qspi_io23_output_disable(uint32_t spi_periph); +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_SPI_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_syscfg.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_syscfg.h new file mode 100644 index 0000000..592966e --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_syscfg.h @@ -0,0 +1,182 @@ +/*! + \file gd32f1x0_syscfg.h + \brief definitions for the SYSCFG +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_SYSCFG_H +#define GD32F1X0_SYSCFG_H + +#include "gd32f1x0.h" + +/* SYSCFG definitions */ +#define SYSCFG SYSCFG_BASE + +/* registers definitions */ +#define SYSCFG_CFG0 REG32(SYSCFG + 0x00U) /*!< system configuration register 0 */ +#ifdef GD32F170_190 +#define SYSCFG_CFG1 REG32(SYSCFG + 0x04U) /*!< system configuration register 1 */ +#endif /* GD32F170_190 */ +#define SYSCFG_EXTISS0 REG32(SYSCFG + 0x08U) /*!< EXTI sources selection register 0 */ +#define SYSCFG_EXTISS1 REG32(SYSCFG + 0x0CU) /*!< EXTI sources selection register 1 */ +#define SYSCFG_EXTISS2 REG32(SYSCFG + 0x10U) /*!< EXTI sources selection register 2 */ +#define SYSCFG_EXTISS3 REG32(SYSCFG + 0x14U) /*!< EXTI sources selection register 3 */ +#define SYSCFG_CFG2 REG32(SYSCFG + 0x18U) /*!< system configuration register 2 */ + +/* SYSCFG_CFG0 bits definitions */ +#define SYSCFG_CFG0_BOOT_MODE BITS(0,1) /*!< SYSCFG memory remap config */ +#define SYSCFG_CFG0_ADC_DMA_RMP BIT(8) /*!< ADC DMA remap config */ +#define SYSCFG_CFG0_USART0_TX_DMA_RMP BIT(9) /*!< USART0 Tx DMA remap config */ +#define SYSCFG_CFG0_USART0_RX_DMA_RMP BIT(10) /*!< USART0 Rx DMA remap config */ +#define SYSCFG_CFG0_TIMER15_DMA_RMP BIT(11) /*!< TIMER 15 DMA remap config */ +#define SYSCFG_CFG0_TIMER16_DMA_RMP BIT(12) /*!< TIMER 16 DMA remap config */ +#define SYSCFG_CFG0_PB9_HCCE BIT(19) /*!< PB9 pin high current capability enable */ + +#ifdef GD32F170_190 +/* SYSCFG_CFG1 bits definitions */ +#define SYSCFG_CFG1_SLCD_DECA BITS(1,3) /*!< decouping capacitance connection for LCD */ +#endif /* GD32F170_190 */ + +/* SYSCFG_EXTISS0 bits definitions */ +#define SYSCFG_EXTISS0_EXTI0_SS BITS(0,3) /*!< EXTI 0 configuration */ +#define SYSCFG_EXTISS0_EXTI1_SS BITS(4,7) /*!< EXTI 1 configuration */ +#define SYSCFG_EXTISS0_EXTI2_SS BITS(8,11) /*!< EXTI 2 configuration */ +#define SYSCFG_EXTISS0_EXTI3_SS BITS(12,15) /*!< EXTI 3 configuration */ + +/* SYSCFG_EXTISS1 bits definitions */ +#define SYSCFG_EXTISS1_EXTI4_SS BITS(0,3) /*!< EXTI 4 configuration */ +#define SYSCFG_EXTISS1_EXTI5_SS BITS(4,7) /*!< EXTI 5 configuration */ +#define SYSCFG_EXTISS1_EXTI6_SS BITS(8,11) /*!< EXTI 6 configuration */ +#define SYSCFG_EXTISS1_EXTI7_SS BITS(12,15) /*!< EXTI 7 configuration */ + +/* SYSCFG_EXTISS2 bits definitions */ +#define SYSCFG_EXTISS2_EXTI8_SS BITS(0,3) /*!< EXTI 8 configuration */ +#define SYSCFG_EXTISS2_EXTI9_SS BITS(4,7) /*!< EXTI 9 configuration */ +#define SYSCFG_EXTISS2_EXTI10_SS BITS(8,11) /*!< EXTI 10 configuration */ +#define SYSCFG_EXTISS2_EXTI11_SS BITS(12,15) /*!< EXTI 11 configuration */ + +/* SYSCFG_EXTISS3 bits definitions */ +#define SYSCFG_EXTISS3_EXTI12_SS BITS(0,3) /*!< EXTI 12 configuration */ +#define SYSCFG_EXTISS3_EXTI13_SS BITS(4,7) /*!< EXTI 13 configuration */ +#define SYSCFG_EXTISS3_EXTI14_SS BITS(8,11) /*!< EXTI 14 configuration */ +#define SYSCFG_EXTISS3_EXTI15_SS BITS(12,15) /*!< EXTI 15 configuration */ + +/* SYSCFG_CFG2 bits definitions */ +#define SYSCFG_CFG2_LOCKUP_LOCK BIT(0) /*!< enable and lock the LOCKUP (Hardfault) output of Cortex-M4 with break input of TIMER0/14/15/16 */ +#define SYSCFG_CFG2_SRAM_PARITY_ERROR_LOCK BIT(1) /*!< enable and lock the SRAM_PARITY error signal with break input of TIMER0/14/15/16 */ +#define SYSCFG_CFG2_LVD_LOCK BIT(2) /*!< enable and lock the LVD connection with TIMER0 break input and also the LVD_EN and LVDSEL[2:0] bits of the power control interface */ +#define SYSCFG_CFG2_SRAM_PCEF BIT(8) /*!< SRAM parity check error flag */ + +/* constants definitions */ +/* DMA remap definitions */ +#define SYSCFG_DMA_REMAP_ADC SYSCFG_CFG0_ADC_DMA_RMP /*!< ADC DMA remap */ +#define SYSCFG_DMA_REMAP_USART0TX SYSCFG_CFG0_USART0_TX_DMA_RMP /*!< USART0_TX DMA remap */ +#define SYSCFG_DMA_REMAP_USART0RX SYSCFG_CFG0_USART0_RX_DMA_RMP /*!< USART0_RX DMA remap */ +#define SYSCFG_DMA_REMAP_TIMER15 SYSCFG_CFG0_TIMER15_DMA_RMP /*!< TIMER15 DMA remap */ +#define SYSCFG_DMA_REMAP_TIMER16 SYSCFG_CFG0_TIMER16_DMA_RMP /*!< TIMER16 DMA remap */ + +/* high current definitions */ +#define SYSCFG_HIGH_CURRENT_ENABLE SYSCFG_CFG0_PB9_HCCE /*!< high current enable */ +#define SYSCFG_HIGH_CURRENT_DISABLE (~SYSCFG_CFG0_PB9_HCCE) /*!< high current disable */ + +/* EXTI source select definition */ +#define EXTISS0 ((uint8_t)0x00U) /*!< EXTI source select register 0 */ +#define EXTISS1 ((uint8_t)0x01U) /*!< EXTI source select register 1 */ +#define EXTISS2 ((uint8_t)0x02U) /*!< EXTI source select register 2 */ +#define EXTISS3 ((uint8_t)0x03U) /*!< EXTI source select register 3 */ + +/* EXTI source select mask bits definition */ +#define EXTI_SS_MASK BITS(0,3) /*!< EXTI source select mask */ + +/* EXTI source select jumping step definition */ +#define EXTI_SS_JSTEP ((uint8_t)(0x04U)) /*!< EXTI source select jumping step */ + +/* EXTI source select moving step definition */ +#define EXTI_SS_MSTEP(pin) (EXTI_SS_JSTEP * ((pin) % EXTI_SS_JSTEP)) /*!< EXTI source select moving step */ + +/* EXTI source port definitions */ +#define EXTI_SOURCE_GPIOA ((uint8_t)0x00U) /*!< EXTI GPIOA configuration */ +#define EXTI_SOURCE_GPIOB ((uint8_t)0x01U) /*!< EXTI GPIOB configuration */ +#define EXTI_SOURCE_GPIOC ((uint8_t)0x02U) /*!< EXTI GPIOC configuration */ +#define EXTI_SOURCE_GPIOD ((uint8_t)0x03U) /*!< EXTI GPIOD configuration */ +#define EXTI_SOURCE_GPIOF ((uint8_t)0x05U) /*!< EXTI GPIOF configuration */ + +/* EXTI 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_PARITY_ERROR SYSCFG_CFG2_SRAM_PARITY_ERROR_LOCK /*!< SRAM parity error lock */ +#define SYSCFG_LOCK_LVD SYSCFG_CFG2_LVD_LOCK /*!< LVD lock */ + +/* SRAM parity check error flag definitions */ +#define SYSCFG_SRAM_PCEF SYSCFG_CFG2_SRAM_PCEF /*!< SRAM parity check error flag */ + +#ifdef GD32F170_190 +#define SYSCFG_LCD_DECA(regval) (BITS(1,3) & ((uint32_t)(regval) << 1)) +#define SYSCFG_VLCD_RAIL1 SYSCFG_LCD_DECA(2) /*!< VLCD rail1 */ +#define SYSCFG_VLCD_RAIL2 SYSCFG_LCD_DECA(1) /*!< VLCD rail2 */ +#define SYSCFG_VLCD_RAIL3 SYSCFG_LCD_DECA(4) /*!< VLCD rail3 */ + +/* VLCD bias definition */ +#define VLCD_BIAS1_2_RAIL1 ((uint8_t)0) /*!< VLCD bias is 1/2, using VLCDrail1 */ +#define VLCD_BIAS1_2_RAIL2 ((uint8_t)1) /*!< VLCD bias is 1/2, using VLCDrail2 */ +#define VLCD_BIAS1_2_RAIL3 ((uint8_t)2) /*!< VLCD bias is 1/2, using VLCDrail3 */ +#define VLCD_BIAS1_3_RAIL1_2 ((uint8_t)3) /*!< VLCD bias is 1/3, using VLCDrail1 and VLCDrail2 */ +#define VLCD_BIAS1_3_RAIL1_3 ((uint8_t)4) /*!< VLCD bias is 1/3, using VLCDrail1 and VLCDrail3 */ +#define VLCD_BIAS1_4_RAILALL ((uint8_t)5) /*!< VLCD bias is 1/4, using all VLCDrails */ +#endif /* GD32F170_190 */ + +/* function declarations */ +/* deinit syscfg module */ +void syscfg_deinit(void); + +/* enable the DMA channels remapping */ +void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap); +/* disable the DMA channels remapping */ +void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap); + +/* enable PB9 high current capability */ +void syscfg_high_current_enable(void); +/* disable PB9 high current capability */ +void syscfg_high_current_disable(void); + +/* configure the GPIO pin as EXTI Line */ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin); +/* connect TIMER0/14/15/16 break input to the selected parameter */ +void syscfg_lock_config(uint32_t syscfg_lock); + +/* check if the specified flag in SYSCFG_CFG2 is set or not */ +FlagStatus syscfg_flag_get(uint32_t syscfg_flag); +/* clear the flag in SYSCFG_CFG2 by writing 1 */ +void syscfg_flag_clear(uint32_t syscfg_flag); + +#ifdef GD32F170_190 +/* configure the VLCD intermediate voltage rail */ +void syscfg_vlcd_rail_config(uint8_t vlcd_bias); +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_SYSCFG_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_timer.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_timer.h new file mode 100644 index 0000000..f1e377a --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_timer.h @@ -0,0 +1,760 @@ +/*! + \file gd32f1x0_timer.h + \brief definitions for the TIMER +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_TIMER_H +#define GD32F1X0_TIMER_H + +#include "gd32f1x0.h" + +/* TIMERx(x=0,1,2,5,13,14,15,16) definitions */ +#define TIMER0 (TIMER_BASE + 0x00012C00U) +#define TIMER1 (TIMER_BASE + 0x00000000U) +#define TIMER2 (TIMER_BASE + 0x00000400U) +#define TIMER5 (TIMER_BASE + 0x00001000U) +#define TIMER13 (TIMER_BASE + 0x00002000U) +#define TIMER14 (TIMER_BASE + 0x00014000U) +#define TIMER15 (TIMER_BASE + 0x00014400U) +#define TIMER16 (TIMER_BASE + 0x00014800U) + +/* registers definitions */ +#define TIMER_CTL0(timerx) REG32((timerx) + 0x00U) /*!< TIMER control register 0 */ +#define TIMER_CTL1(timerx) REG32((timerx) + 0x04U) /*!< TIMER control register 1 */ +#define TIMER_SMCFG(timerx) REG32((timerx) + 0x08U) /*!< TIMER slave mode configuration register */ +#define TIMER_DMAINTEN(timerx) REG32((timerx) + 0x0CU) /*!< TIMER DMA and interrupt enable register */ +#define TIMER_INTF(timerx) REG32((timerx) + 0x10U) /*!< TIMER interrupt flag register */ +#define TIMER_SWEVG(timerx) REG32((timerx) + 0x14U) /*!< TIMER software event generation register */ +#define TIMER_CHCTL0(timerx) REG32((timerx) + 0x18U) /*!< TIMER channel control register 0 */ +#define TIMER_CHCTL1(timerx) REG32((timerx) + 0x1CU) /*!< TIMER channel control register 1 */ +#define TIMER_CHCTL2(timerx) REG32((timerx) + 0x20U) /*!< TIMER channel control register 2 */ +#define TIMER_CNT(timerx) REG32((timerx) + 0x24U) /*!< TIMER counter register */ +#define TIMER_PSC(timerx) REG32((timerx) + 0x28U) /*!< TIMER prescaler register */ +#define TIMER_CAR(timerx) REG32((timerx) + 0x2CU) /*!< TIMER counter auto reload register */ +#define TIMER_CREP(timerx) REG32((timerx) + 0x30U) /*!< TIMER counter repetition register */ +#define TIMER_CH0CV(timerx) REG32((timerx) + 0x34U) /*!< TIMER channel 0 capture/compare value register */ +#define TIMER_CH1CV(timerx) REG32((timerx) + 0x38U) /*!< TIMER channel 1 capture/compare value register */ +#define TIMER_CH2CV(timerx) REG32((timerx) + 0x3CU) /*!< TIMER channel 2 capture/compare value register */ +#define TIMER_CH3CV(timerx) REG32((timerx) + 0x40U) /*!< TIMER channel 3 capture/compare value register */ +#define TIMER_CCHP(timerx) REG32((timerx) + 0x44U) /*!< TIMER complementary channel protection register */ +#define TIMER_DMACFG(timerx) REG32((timerx) + 0x48U) /*!< TIMER DMA configuration register */ +#define TIMER_DMATB(timerx) REG32((timerx) + 0x4CU) /*!< TIMER DMA transfer buffer register */ +#define TIMER_IRMP(timerx) REG32((timerx) + 0x50U) /*!< TIMER channel input remap register(only for TIMER13) */ +#define TIMER_CFG(timerx) REG32((timerx) + 0xFCU) /*!< TIMER configuration register */ + +/* bits definitions */ +/* TIMER_CTL0 */ +#define TIMER_CTL0_CEN BIT(0) /*!< TIMER counter enable */ +#define TIMER_CTL0_UPDIS BIT(1) /*!< update disable */ +#define TIMER_CTL0_UPS BIT(2) /*!< update source */ +#define TIMER_CTL0_SPM BIT(3) /*!< single pulse mode */ +#define TIMER_CTL0_DIR BIT(4) /*!< timer counter direction */ +#define TIMER_CTL0_CAM BITS(5,6) /*!< center-aligned mode selection */ +#define TIMER_CTL0_ARSE BIT(7) /*!< auto-reload shadow enable */ +#define TIMER_CTL0_CKDIV BITS(8,9) /*!< clock division */ + +/* TIMER_CTL1 */ +#define TIMER_CTL1_CCSE BIT(0) /*!< commutation control shadow register enable */ +#define TIMER_CTL1_CCUC BIT(2) /*!< commutation control shadow register update control */ +#define TIMER_CTL1_DMAS BIT(3) /*!< DMA request source selection */ +#define TIMER_CTL1_MMC BITS(4,6) /*!< master mode control */ +#define TIMER_CTL1_TI0S BIT(7) /*!< channel 0 trigger input selection(hall mode selection) */ +#define TIMER_CTL1_ISO0 BIT(8) /*!< idle state of channel 0 output */ +#define TIMER_CTL1_ISO0N BIT(9) /*!< idle state of channel 0 complementary output */ +#define TIMER_CTL1_ISO1 BIT(10) /*!< idle state of channel 1 output */ +#define TIMER_CTL1_ISO1N BIT(11) /*!< idle state of channel 1 complementary output */ +#define TIMER_CTL1_ISO2 BIT(12) /*!< idle state of channel 2 output */ +#define TIMER_CTL1_ISO2N BIT(13) /*!< idle state of channel 2 complementary output */ +#define TIMER_CTL1_ISO3 BIT(14) /*!< idle state of channel 3 output */ + +/* TIMER_SMCFG */ +#define TIMER_SMCFG_SMC BITS(0,2) /*!< slave mode control */ +#define TIMER_SMCFG_OCRC BIT(3) /*!< OCPRE clear source selection */ +#define TIMER_SMCFG_TRGS BITS(4,6) /*!< trigger selection */ +#define TIMER_SMCFG_MSM BIT(7) /*!< master-slave mode */ +#define TIMER_SMCFG_ETFC BITS(8,11) /*!< external trigger filter control */ +#define TIMER_SMCFG_ETPSC BITS(12,13) /*!< external trigger prescaler */ +#define TIMER_SMCFG_SMC1 BIT(14) /*!< part of SMC for enable external clock mode 1 */ +#define TIMER_SMCFG_ETP BIT(15) /*!< external trigger polarity */ + +/* TIMER_DMAINTEN */ +#define TIMER_DMAINTEN_UPIE BIT(0) /*!< update interrupt enable */ +#define TIMER_DMAINTEN_CH0IE BIT(1) /*!< channel 0 interrupt enable */ +#define TIMER_DMAINTEN_CH1IE BIT(2) /*!< channel 1 interrupt enable */ +#define TIMER_DMAINTEN_CH2IE BIT(3) /*!< channel 2 interrupt enable */ +#define TIMER_DMAINTEN_CH3IE BIT(4) /*!< channel 3 interrupt enable */ +#define TIMER_DMAINTEN_CMTIE BIT(5) /*!< commutation DMA request enable */ +#define TIMER_DMAINTEN_TRGIE BIT(6) /*!< trigger interrupt enable */ +#define TIMER_DMAINTEN_BRKIE BIT(7) /*!< break interrupt enable */ +#define TIMER_DMAINTEN_UPDEN BIT(8) /*!< update DMA request enable */ +#define TIMER_DMAINTEN_CH0DEN BIT(9) /*!< channel 0 DMA request enable */ +#define TIMER_DMAINTEN_CH1DEN BIT(10) /*!< channel 1 DMA request enable */ +#define TIMER_DMAINTEN_CH2DEN BIT(11) /*!< channel 2 DMA request enable */ +#define TIMER_DMAINTEN_CH3DEN BIT(12) /*!< channel 3 DMA request enable */ +#define TIMER_DMAINTEN_CMTDEN BIT(13) /*!< channel control update DMA request enable */ +#define TIMER_DMAINTEN_TRGDEN BIT(14) /*!< trigger DMA request enable */ + +/* TIMER_INTF */ +#define TIMER_INTF_UPIF BIT(0) /*!< update interrupt flag */ +#define TIMER_INTF_CH0IF BIT(1) /*!< channel 0 interrupt flag */ +#define TIMER_INTF_CH1IF BIT(2) /*!< channel 1 interrupt flag */ +#define TIMER_INTF_CH2IF BIT(3) /*!< channel 2 interrupt flag */ +#define TIMER_INTF_CH3IF BIT(4) /*!< channel 3 interrupt flag */ +#define TIMER_INTF_CMTIF BIT(5) /*!< channel commutation interrupt flag */ +#define TIMER_INTF_TRGIF BIT(6) /*!< trigger interrupt flag */ +#define TIMER_INTF_BRKIF BIT(7) /*!< break interrupt flag */ +#define TIMER_INTF_CH0OF BIT(9) /*!< channel 0 overcapture flag */ +#define TIMER_INTF_CH1OF BIT(10) /*!< channel 1 overcapture flag */ +#define TIMER_INTF_CH2OF BIT(11) /*!< channel 2 overcapture flag */ +#define TIMER_INTF_CH3OF BIT(12) /*!< channel 3 overcapture flag */ + +/* TIMER_SWEVG */ +#define TIMER_SWEVG_UPG BIT(0) /*!< update event generate */ +#define TIMER_SWEVG_CH0G BIT(1) /*!< channel 0 capture or compare event generation */ +#define TIMER_SWEVG_CH1G BIT(2) /*!< channel 1 capture or compare event generation */ +#define TIMER_SWEVG_CH2G BIT(3) /*!< channel 2 capture or compare event generation */ +#define TIMER_SWEVG_CH3G BIT(4) /*!< channel 3 capture or compare event generation */ +#define TIMER_SWEVG_CMTG BIT(5) /*!< channel commutation event generation */ +#define TIMER_SWEVG_TRGG BIT(6) /*!< trigger event generation */ +#define TIMER_SWEVG_BRKG BIT(7) /*!< break event generation */ + +/* TIMER_CHCTL0 */ +/* output compare mode */ +#define TIMER_CHCTL0_CH0MS BITS(0,1) /*!< channel 0 mode selection */ +#define TIMER_CHCTL0_CH0COMFEN BIT(2) /*!< channel 0 output compare fast enable */ +#define TIMER_CHCTL0_CH0COMSEN BIT(3) /*!< channel 0 output compare shadow enable */ +#define TIMER_CHCTL0_CH0COMCTL BITS(4,6) /*!< channel 0 output compare mode */ +#define TIMER_CHCTL0_CH0COMCEN BIT(7) /*!< channel 0 output compare clear enable */ +#define TIMER_CHCTL0_CH1MS BITS(8,9) /*!< channel 1 mode selection */ +#define TIMER_CHCTL0_CH1COMFEN BIT(10) /*!< channel 1 output compare fast enable */ +#define TIMER_CHCTL0_CH1COMSEN BIT(11) /*!< channel 1 output compare shadow enable */ +#define TIMER_CHCTL0_CH1COMCTL BITS(12,14) /*!< channel 1 output compare mode */ +#define TIMER_CHCTL0_CH1COMCEN BIT(15) /*!< channel 1 output compare clear enable */ +/* input capture mode */ +#define TIMER_CHCTL0_CH0CAPPSC BITS(2,3) /*!< channel 0 input capture prescaler */ +#define TIMER_CHCTL0_CH0CAPFLT BITS(4,7) /*!< channel 0 input capture filter control */ +#define TIMER_CHCTL0_CH1CAPPSC BITS(10,11) /*!< channel 1 input capture prescaler */ +#define TIMER_CHCTL0_CH1CAPFLT BITS(12,15) /*!< channel 1 input capture filter control */ + +/* TIMER_CHCTL1 */ +/* output compare mode */ +#define TIMER_CHCTL1_CH2MS BITS(0,1) /*!< channel 2 mode selection */ +#define TIMER_CHCTL1_CH2COMFEN BIT(2) /*!< channel 2 output compare fast enable */ +#define TIMER_CHCTL1_CH2COMSEN BIT(3) /*!< channel 2 output compare shadow enable */ +#define TIMER_CHCTL1_CH2COMCTL BITS(4,6) /*!< channel 2 output compare mode */ +#define TIMER_CHCTL1_CH2COMCEN BIT(7) /*!< channel 2 output compare clear enable */ +#define TIMER_CHCTL1_CH3MS BITS(8,9) /*!< channel 3 mode selection */ +#define TIMER_CHCTL1_CH3COMFEN BIT(10) /*!< channel 3 output compare fast enable */ +#define TIMER_CHCTL1_CH3COMSEN BIT(11) /*!< channel 3 output compare shadow enable */ +#define TIMER_CHCTL1_CH3COMCTL BITS(12,14) /*!< channel 3 output compare mode */ +#define TIMER_CHCTL1_CH3COMCEN BIT(15) /*!< channel 3 output compare clear enable */ +/* input capture mode */ +#define TIMER_CHCTL1_CH2CAPPSC BITS(2,3) /*!< channel 2 input capture prescaler */ +#define TIMER_CHCTL1_CH2CAPFLT BITS(4,7) /*!< channel 2 input capture filter control */ +#define TIMER_CHCTL1_CH3CAPPSC BITS(10,11) /*!< channel 3 input capture prescaler */ +#define TIMER_CHCTL1_CH3CAPFLT BITS(12,15) /*!< channel 3 input capture filter control */ + +/* TIMER_CHCTL2 */ +#define TIMER_CHCTL2_CH0EN BIT(0) /*!< channel 0 enable */ +#define TIMER_CHCTL2_CH0P BIT(1) /*!< channel 0 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 enable */ +#define TIMER_CHCTL2_CH1P BIT(5) /*!< channel 1 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 enable */ +#define TIMER_CHCTL2_CH2P BIT(9) /*!< channel 2 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 enable */ +#define TIMER_CHCTL2_CH3P BIT(13) /*!< channel 3 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) /*!< capture/compare value of channel 0 */ + +/* TIMER_CH1CV */ +#define TIMER_CH1CV_CH1VAL BITS(0,15) /*!< capture/compare value of channel 1 */ + +/* TIMER_CH2CV */ +#define TIMER_CH2CV_CH2VAL BITS(0,15) /*!< capture/compare value of channel 2 */ + +/* TIMER_CH3CV */ +#define TIMER_CH3CV_CH3VAL BITS(0,15) /*!< capture/compare value of channel 3 */ + +/* TIMER_CCHP */ +#define TIMER_CCHP_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_CCHP_PROT BITS(8,9) /*!< complementary register protect control */ +#define TIMER_CCHP_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_CCHP_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_CCHP_BRKEN BIT(12) /*!< break enable */ +#define TIMER_CCHP_BRKP BIT(13) /*!< break polarity */ +#define TIMER_CCHP_OAEN BIT(14) /*!< output automatic enable */ +#define TIMER_CCHP_POEN BIT(15) /*!< primary output enable */ + +/* TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA BITS(0,4) /*!< DMA transfer access start address */ +#define TIMER_DMACFG_DMATC BITS(8,12) /*!< DMA transfer count */ + +/* TIMER_DMATB */ +#define TIMER_DMATB_DMATB BITS(0,15) /*!< DMA transfer buffer address */ + +/* TIMER_IRMP */ +#define TIMER13_IRMP_CI0_RMP BITS(0,1) /*!< TIMER13 channel 0 input remap */ + +#ifdef GD32F170_190 +/* TIMER_CFG */ +#define TIMER_CFG_OUTSEL BIT(0) /*!< the output value selection */ +#define TIMER_CFG_CHVSEL BIT(1) /*!< write CHxVAL register selection */ +#endif /* GD32F170_190 */ + +/* 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; + +/* channel input parameter struct definitions */ +typedef struct +{ + uint16_t icpolarity; /*!< channel input polarity */ + uint16_t icselection; /*!< channel input mode selection */ + uint16_t icprescaler; /*!< channel input capture prescaler */ + uint16_t icfilter; /*!< channel input capture filter control */ +}timer_ic_parameter_struct; + +/* TIMER interrupt enable or disable */ +#define TIMER_INT_UP TIMER_DMAINTEN_UPIE /*!< update interrupt */ +#define TIMER_INT_CH0 TIMER_DMAINTEN_CH0IE /*!< channel 0 interrupt */ +#define TIMER_INT_CH1 TIMER_DMAINTEN_CH1IE /*!< channel 1 interrupt */ +#define TIMER_INT_CH2 TIMER_DMAINTEN_CH2IE /*!< channel 2 interrupt */ +#define TIMER_INT_CH3 TIMER_DMAINTEN_CH3IE /*!< channel 3 interrupt */ +#define TIMER_INT_CMT TIMER_DMAINTEN_CMTIE /*!< channel commutation interrupt flag */ +#define TIMER_INT_TRG TIMER_DMAINTEN_TRGIE /*!< trigger interrupt */ +#define TIMER_INT_BRK TIMER_DMAINTEN_BRKIE /*!< break interrupt */ + +/* TIMER flag */ +#define TIMER_FLAG_UP TIMER_INTF_UPIF /*!< update flag */ +#define TIMER_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 flag */ +#define TIMER_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 flag */ +#define TIMER_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 flag */ +#define TIMER_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 flag */ +#define TIMER_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation flag */ +#define TIMER_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger flag */ +#define TIMER_FLAG_BRK TIMER_INTF_BRKIF /*!< break flag */ +#define TIMER_FLAG_CH0O TIMER_INTF_CH0OF /*!< channel 0 overcapture flag */ +#define TIMER_FLAG_CH1O TIMER_INTF_CH1OF /*!< channel 1 overcapture flag */ +#define TIMER_FLAG_CH2O TIMER_INTF_CH2OF /*!< channel 2 overcapture flag */ +#define TIMER_FLAG_CH3O TIMER_INTF_CH3OF /*!< channel 3 overcapture flag */ + +/* TIMER interrupt flag */ +#define TIMER_INT_FLAG_UP TIMER_INTF_UPIF /*!< update interrupt flag */ +#define TIMER_INT_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 interrupt flag */ +#define TIMER_INT_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 interrupt flag */ +#define TIMER_INT_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 interrupt flag */ +#define TIMER_INT_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 interrupt flag */ +#define TIMER_INT_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation interrupt flag */ +#define TIMER_INT_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger interrupt flag */ +#define TIMER_INT_FLAG_BRK TIMER_INTF_BRKIF /*!< break interrupt flag */ + +/* TIMER DMA source enable */ +#define TIMER_DMA_UPD ((uint16_t)0x0100U) /*!< update DMA enable */ +#define TIMER_DMA_CH0D ((uint16_t)0x0200U) /*!< channel 0 DMA enable */ +#define TIMER_DMA_CH1D ((uint16_t)0x0400U) /*!< channel 1 DMA enable */ +#define TIMER_DMA_CH2D ((uint16_t)0x0800U) /*!< channel 2 DMA enable */ +#define TIMER_DMA_CH3D ((uint16_t)0x1000U) /*!< channel 3 DMA enable */ +#define TIMER_DMA_CMTD ((uint16_t)0x2000U) /*!< commutation DMA request enable */ +#define TIMER_DMA_TRGD ((uint16_t)0x4000U) /*!< trigger DMA enable */ + +/* update disable */ +#define TIMER_UPDIS_ENABLE TIMER_CTL0_UPDIS /*!< update enable */ +#define TIMER_UPDIS_DISABLE ~TIMER_CTL0_UPDIS /*!< update disable */ + +/* TIMER count enable */ +#define TIMER_COUNTER_ENABLE TIMER_CTL0_CEN /*!< count enable */ +#define TIMER_COUNTER_DISABLE ~TIMER_CTL0_CEN /*!< count disable */ + +/* channel DMA request source selection */ +#define TIMER_DMAREQUEST_UPDATEEVENT ((uint8_t)0x00U) /*!< DMA request of channel y is sent when update event occurs */ +#define TIMER_DMAREQUEST_CHANNELEVENT ((uint8_t)0x01U) /*!< DMA request of channel y is sent when channel y event occurs */ + +/* OCPRE clear source selection */ +#define TIMER_OCPRE_CLEAR_SOURCE_ETIF ((uint8_t)0x01U) /*!< OCPRE_CLR_INT is connected to ETIF */ +#define TIMER_OCPRE_CLEAR_SOURCE_CLR ((uint8_t)0x00U) /*!< OCPRE_CLR_INT is connected to the OCPRE_CLR input */ + +/* DMA access base address */ +#define DMACFG_DMATA(regval) (BITS(0, 4) & ((uint32_t)(regval) << 0U)) +#define TIMER_DMACFG_DMATA_CTL0 DMACFG_DMATA(0) /*!< DMA transfer address is TIMER_CTL0 */ +#define TIMER_DMACFG_DMATA_CTL1 DMACFG_DMATA(1) /*!< DMA transfer address is TIMER_CTL1 */ +#define TIMER_DMACFG_DMATA_SMCFG DMACFG_DMATA(2) /*!< DMA transfer address is TIMER_SMCFG */ +#define TIMER_DMACFG_DMATA_DMAINTEN DMACFG_DMATA(3) /*!< DMA transfer address is TIMER_DMAINTEN */ +#define TIMER_DMACFG_DMATA_INTF DMACFG_DMATA(4) /*!< DMA transfer address is TIMER_INTF */ +#define TIMER_DMACFG_DMATA_SWEVG DMACFG_DMATA(5) /*!< DMA transfer address is TIMER_SWEVG */ +#define TIMER_DMACFG_DMATA_CHCTL0 DMACFG_DMATA(6) /*!< DMA transfer address is TIMER_CHCTL0 */ +#define TIMER_DMACFG_DMATA_CHCTL1 DMACFG_DMATA(7) /*!< DMA transfer address is TIMER_CHCTL1 */ +#define TIMER_DMACFG_DMATA_CHCTL2 DMACFG_DMATA(8) /*!< DMA transfer address is TIMER_CHCTL2 */ +#define TIMER_DMACFG_DMATA_CNT DMACFG_DMATA(9) /*!< DMA transfer address is TIMER_CNT */ +#define TIMER_DMACFG_DMATA_PSC DMACFG_DMATA(10) /*!< DMA transfer address is TIMER_PSC */ +#define TIMER_DMACFG_DMATA_CAR DMACFG_DMATA(11) /*!< DMA transfer address is TIMER_CAR */ +#define TIMER_DMACFG_DMATA_CREP DMACFG_DMATA(12) /*!< DMA transfer address is TIMER_CREP */ +#define TIMER_DMACFG_DMATA_CH0CV DMACFG_DMATA(13) /*!< DMA transfer address is TIMER_CH0CV */ +#define TIMER_DMACFG_DMATA_CH1CV DMACFG_DMATA(14) /*!< DMA transfer address is TIMER_CH1CV */ +#define TIMER_DMACFG_DMATA_CH2CV DMACFG_DMATA(15) /*!< DMA transfer address is TIMER_CH2CV */ +#define TIMER_DMACFG_DMATA_CH3CV DMACFG_DMATA(16) /*!< DMA transfer address is TIMER_CH3CV */ +#define TIMER_DMACFG_DMATA_CCHP DMACFG_DMATA(17) /*!< DMA transfer address is TIMER_CCHP */ +#define TIMER_DMACFG_DMATA_DMACFG DMACFG_DMATA(18) /*!< DMA transfer address is TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA_DMATB DMACFG_DMATA(19) /*!< DMA transfer address is TIMER_DMATB */ + +/* DMA access burst length */ +#define DMACFG_DMATC(regval) (BITS(8, 12) & ((uint32_t)(regval) << 8U)) +#define TIMER_DMACFG_DMATC_1TRANSFER DMACFG_DMATC(0) /*!< DMA transfer 1 time */ +#define TIMER_DMACFG_DMATC_2TRANSFER DMACFG_DMATC(1) /*!< DMA transfer 2 times */ +#define TIMER_DMACFG_DMATC_3TRANSFER DMACFG_DMATC(2) /*!< DMA transfer 3 times */ +#define TIMER_DMACFG_DMATC_4TRANSFER DMACFG_DMATC(3) /*!< DMA transfer 4 times */ +#define TIMER_DMACFG_DMATC_5TRANSFER DMACFG_DMATC(4) /*!< DMA transfer 5 times */ +#define TIMER_DMACFG_DMATC_6TRANSFER DMACFG_DMATC(5) /*!< DMA transfer 6 times */ +#define TIMER_DMACFG_DMATC_7TRANSFER DMACFG_DMATC(6) /*!< DMA transfer 7 times */ +#define TIMER_DMACFG_DMATC_8TRANSFER DMACFG_DMATC(7) /*!< DMA transfer 8 times */ +#define TIMER_DMACFG_DMATC_9TRANSFER DMACFG_DMATC(8) /*!< DMA transfer 9 times */ +#define TIMER_DMACFG_DMATC_10TRANSFER DMACFG_DMATC(9) /*!< DMA transfer 10 times */ +#define TIMER_DMACFG_DMATC_11TRANSFER DMACFG_DMATC(10) /*!< DMA transfer 11 times */ +#define TIMER_DMACFG_DMATC_12TRANSFER DMACFG_DMATC(11) /*!< DMA transfer 12 times */ +#define TIMER_DMACFG_DMATC_13TRANSFER DMACFG_DMATC(12) /*!< DMA transfer 13 times */ +#define TIMER_DMACFG_DMATC_14TRANSFER DMACFG_DMATC(13) /*!< DMA transfer 14 times */ +#define TIMER_DMACFG_DMATC_15TRANSFER DMACFG_DMATC(14) /*!< DMA transfer 15 times */ +#define TIMER_DMACFG_DMATC_16TRANSFER DMACFG_DMATC(15) /*!< DMA transfer 16 times */ +#define TIMER_DMACFG_DMATC_17TRANSFER DMACFG_DMATC(16) /*!< DMA transfer 17 times */ +#define TIMER_DMACFG_DMATC_18TRANSFER DMACFG_DMATC(17) /*!< DMA transfer 18 times */ + +/* TIMER software event generation source */ +#define TIMER_EVENT_SRC_UPG ((uint16_t)0x0001U) /*!< update event generation */ +#define TIMER_EVENT_SRC_CH0G ((uint16_t)0x0002U) /*!< channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH1G ((uint16_t)0x0004U) /*!< channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH2G ((uint16_t)0x0008U) /*!< channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH3G ((uint16_t)0x0010U) /*!< channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CMTG ((uint16_t)0x0020U) /*!< channel commutation event generation */ +#define TIMER_EVENT_SRC_TRGG ((uint16_t)0x0040U) /*!< trigger event generation */ +#define TIMER_EVENT_SRC_BRKG ((uint16_t)0x0080U) /*!< break event generation */ + +/* center-aligned mode selection */ +#define CTL0_CAM(regval) ((uint16_t)(BITS(5, 6) & ((uint32_t)(regval) << 5U))) +#define TIMER_COUNTER_EDGE CTL0_CAM(0) /*!< edge-aligned mode */ +#define TIMER_COUNTER_CENTER_DOWN CTL0_CAM(1) /*!< center-aligned and counting down assert mode */ +#define TIMER_COUNTER_CENTER_UP CTL0_CAM(2) /*!< center-aligned and counting up assert mode */ +#define TIMER_COUNTER_CENTER_BOTH CTL0_CAM(3) /*!< center-aligned and counting up/down assert mode */ + +/* TIMER prescaler reload mode */ +#define TIMER_PSC_RELOAD_NOW ((uint8_t)0x00U) /*!< the prescaler is loaded right now */ +#define TIMER_PSC_RELOAD_UPDATE ((uint8_t)0x01U) /*!< 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)0x0010U) /*!< 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 ((uint8_t)0x00U) /*!< single pulse mode */ +#define TIMER_SP_MODE_REPETITIVE ((uint8_t)0x01U) /*!< repetitive pulse mode */ + +/* auto-reload shadow enable */ +#define TIMER_ARSE_ENABLE TIMER_CTL0_ARSE /*!< auto-reload shadow enable */ +#define TIMER_ARSE_DISABLE ~TIMER_CTL0_ARSE /*!< auto-reload shadow disable */ + +/* update source */ +#define TIMER_UPDATE_SRC_REGULAR ((uint8_t)0x00U) /*!< update generate only by counter overflow/underflow */ +#define TIMER_UPDATE_SRC_GLOBAL ((uint8_t)0x01U) /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */ + +/* run mode off-state configure */ +#define TIMER_ROS_STATE_ENABLE ((uint16_t)0x0800U) /*!< channel OC outputs enable in run mode */ +#define TIMER_ROS_STATE_DISABLE ((uint16_t)0x0000U) /*!< channel OC outputs disable in run mode */ + +/* idle mode off-state configure */ +#define TIMER_IOS_STATE_ENABLE ((uint16_t)0x0400U) /*!< channel OC outputs enable in idle mode */ +#define TIMER_IOS_STATE_DISABLE ((uint16_t)0x0000U) /*!< channel OC outputs disable in idle mode */ + +/* break input polarity */ +#define TIMER_BREAK_POLARITY_LOW ((uint16_t)0x0000U) /*!< break input polarity is low */ +#define TIMER_BREAK_POLARITY_HIGH ((uint16_t)0x2000U) /*!< break input polarity is high */ + +/* output automatic enable */ +#define TIMER_OUTAUTO_ENABLE ((uint16_t)0x4000U) /*!< output automatic enable */ +#define TIMER_OUTAUTO_DISABLE ((uint16_t)0x0000U) /*!< output automatic disable */ + +/* complementary register protect control */ +#define CCHP_PROT(regval) ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CCHP_PROT_OFF CCHP_PROT(0) /*!< protect disable */ +#define TIMER_CCHP_PROT_0 CCHP_PROT(1) /*!< PROT mode 0 */ +#define TIMER_CCHP_PROT_1 CCHP_PROT(2) /*!< PROT mode 1 */ +#define TIMER_CCHP_PROT_2 CCHP_PROT(3) /*!< PROT mode 2 */ + +/* break input enable */ +#define TIMER_BREAK_ENABLE ((uint16_t)0x1000U) /*!< break input enable */ +#define TIMER_BREAK_DISABLE ((uint16_t)0x0000U) /*!< break input disable */ + +/* TIMER channel y(y=0,1,2,3) */ +#define TIMER_CH_0 ((uint16_t)0x0000U) /*!< TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) */ +#define TIMER_CH_1 ((uint16_t)0x0001U) /*!< TIMER channel1(TIMERx(x=0,1,2,14)) */ +#define TIMER_CH_2 ((uint16_t)0x0002U) /*!< TIMER channel2(TIMERx(x=0,1,2)) */ +#define TIMER_CH_3 ((uint16_t)0x0003U) /*!< TIMER channel3(TIMERx(x=0,1,2)) */ + +/* channel enable state*/ +#define TIMER_CCX_ENABLE ((uint16_t)0x0001U) /*!< channel enable */ +#define TIMER_CCX_DISABLE ((uint16_t)0x0000U) /*!< channel disable */ + +/* channel complementary output enable state*/ +#define TIMER_CCXN_ENABLE ((uint16_t)0x0004U) /*!< channel complementary enable */ +#define TIMER_CCXN_DISABLE ((uint16_t)0x0000U) /*!< channel complementary disable */ + +/* channel output polarity */ +#define TIMER_OC_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel output polarity is high */ +#define TIMER_OC_POLARITY_LOW ((uint16_t)0x0002U) /*!< channel output polarity is low */ + +/* channel complementary output polarity */ +#define TIMER_OCN_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel complementary output polarity is high */ +#define TIMER_OCN_POLARITY_LOW ((uint16_t)0x0008U) /*!< channel complementary output polarity is low */ + +/* idle state of channel output */ +#define TIMER_OC_IDLE_STATE_HIGH ((uint16_t)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 */ + +/* channel output compare mode */ +#define TIMER_OC_MODE_TIMING ((uint16_t)0x0000U) /*!< timing mode */ +#define TIMER_OC_MODE_ACTIVE ((uint16_t)0x0010U) /*!< active mode */ +#define TIMER_OC_MODE_INACTIVE ((uint16_t)0x0020U) /*!< inactive mode */ +#define TIMER_OC_MODE_TOGGLE ((uint16_t)0x0030U) /*!< toggle mode */ +#define TIMER_OC_MODE_LOW ((uint16_t)0x0040U) /*!< force low mode */ +#define TIMER_OC_MODE_HIGH ((uint16_t)0x0050U) /*!< force high mode */ +#define TIMER_OC_MODE_PWM0 ((uint16_t)0x0060U) /*!< PWM0 mode */ +#define TIMER_OC_MODE_PWM1 ((uint16_t)0x0070U) /*!< PWM1 mode*/ + +/* channel output compare shadow enable */ +#define TIMER_OC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< channel output shadow state enable */ +#define TIMER_OC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel output shadow state disable */ + +/* channel output compare fast enable */ +#define TIMER_OC_FAST_ENABLE ((uint16_t)0x0004U) /*!< channel output fast function enable */ +#define TIMER_OC_FAST_DISABLE ((uint16_t)0x0000U) /*!< channel output fast function disable */ + +/* channel output compare clear enable. */ +#define TIMER_OC_CLEAR_ENABLE ((uint16_t)0x0080U) /*!< channel output clear function enable */ +#define TIMER_OC_CLEAR_DISABLE ((uint16_t)0x0000U) /*!< channel output clear function disable */ + +/* channel control shadow register update control */ +#define TIMER_UPDATECTL_CCU ((uint8_t)0x00U) /*!< the shadow registers update by when CMTG bit is set */ +#define TIMER_UPDATECTL_CCUTRI ((uint8_t)0x01U) /*!< the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs */ + +/* channel input capture polarity */ +#define TIMER_IC_POLARITY_RISING ((uint16_t)0x0000U) /*!< input capture rising edge */ +#define TIMER_IC_POLARITY_FALLING ((uint16_t)0x0002U) /*!< input capture falling edge */ +#define TIMER_IC_POLARITY_BOTH_EDGE ((uint16_t)0x000AU) /*!< input capture both edge */ + +/* TIMER input capture selection */ +#define TIMER_IC_SELECTION_DIRECTTI ((uint16_t)0x0001U) /*!< channel y is configured as input and icy is mapped on CIy */ +#define TIMER_IC_SELECTION_INDIRECTTI ((uint16_t)0x0002U) /*!< channel y is configured as input and icy is mapped on opposite input */ +#define TIMER_IC_SELECTION_ITS ((uint16_t)0x0003U) /*!< channel y is configured as input and icy is mapped on ITS */ + +/* channel input capture prescaler */ +#define TIMER_IC_PSC_DIV1 ((uint16_t)0x0000U) /*!< no prescaler */ +#define TIMER_IC_PSC_DIV2 ((uint16_t)0x0004U) /*!< divided by 2 */ +#define TIMER_IC_PSC_DIV4 ((uint16_t)0x0008U) /*!< divided by 4*/ +#define TIMER_IC_PSC_DIV8 ((uint16_t)0x000CU) /*!< divided by 8 */ + +/* trigger selection */ +#define SMCFG_TRGSEL(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define TIMER_SMCFG_TRGSEL_ITI0 SMCFG_TRGSEL(0) /*!< internal trigger 0 */ +#define TIMER_SMCFG_TRGSEL_ITI1 SMCFG_TRGSEL(1) /*!< internal trigger 1 */ +#define TIMER_SMCFG_TRGSEL_ITI2 SMCFG_TRGSEL(2) /*!< internal trigger 2 */ +#define TIMER_SMCFG_TRGSEL_ITI3 SMCFG_TRGSEL(3) /*!< internal trigger 3 */ +#define TIMER_SMCFG_TRGSEL_CI0F_ED SMCFG_TRGSEL(4) /*!< TI0 edge detector */ +#define TIMER_SMCFG_TRGSEL_CI0FE0 SMCFG_TRGSEL(5) /*!< filtered TIMER input 0 */ +#define TIMER_SMCFG_TRGSEL_CI1FE1 SMCFG_TRGSEL(6) /*!< filtered TIMER input 1 */ +#define TIMER_SMCFG_TRGSEL_ETIFP SMCFG_TRGSEL(7) /*!< external trigger */ + +/* master mode control */ +#define CTL1_MMC(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define TIMER_TRI_OUT_SRC_RESET CTL1_MMC(0) /*!< the UPG bit as trigger output */ +#define TIMER_TRI_OUT_SRC_ENABLE CTL1_MMC(1) /*!< the counter enable signal TIMER_CTL0_CEN as trigger output */ +#define TIMER_TRI_OUT_SRC_UPDATE CTL1_MMC(2) /*!< update event as trigger output */ +#define TIMER_TRI_OUT_SRC_CH0 CTL1_MMC(3) /*!< a capture or a compare match occurred in channal 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 ((uint8_t)0x00U) /*!< master slave mode enable */ +#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint8_t)0x01U) /*!< 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 ~TIMER_SMCFG_ETP /*!< active high or rising edge active */ + +/* channel 0 trigger input selection */ +#define TIMER_HALLINTERFACE_ENABLE ((uint8_t)0x00U) /*!< TIMER hall sensor mode enable */ +#define TIMER_HALLINTERFACE_DISABLE ((uint8_t)0x01U) /*!< TIMER hall sensor mode disable */ + +/* channel 0 input remap */ +#define IRMP_CI0_RMP(regval) (BITS(0, 1) & ((uint32_t)(regval) << 0U)) +#define TIMER_IRMP_CI0_RMP_GPIO IRMP_CI0_RMP(0) /*!< channel 0 input is connected to GPIO */ +#define TIMER_IRMP_CI0_RTCCLK IRMP_CI0_RMP(1) /*!< channel 0 input is connected to the RTCCLK */ +#define TIMER_IRMP_CI0_HXTALDIV32 IRMP_CI0_RMP(2) /*!< channel 0 input is connected to HXTAL/32 clock */ +#define TIMER_IRMP_CI0_CKOUTSEL IRMP_CI0_RMP(3) /*!< channel 0 input is connected to CKOUTSEL */ + +#ifdef GD32F170_190 +/* write CHxVAL register selection */ +#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CHxVAL register selection disable */ +#define TIMER_CHVSEL_ENABLE ((uint16_t)0x0002U) /*!< write CHxVAL register selection enable */ + +/* the output value selection */ +#define TIMER_OUTSEL_DISABLE ((uint16_t)0x0000U) /*!< output value selection disable */ +#define TIMER_OUTSEL_ENABLE ((uint16_t)0x0001U) /*!< output value selection enable */ +#endif /* GD32F170_190 */ + +/* function declarations */ +/* TIMER timebase*/ +/* deinit a timer */ +void timer_deinit(uint32_t timer_periph); +/* initialize TIMER counter */ +void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara); +/* enable a timer */ +void timer_enable(uint32_t timer_periph); +/* disable a timer */ +void timer_disable(uint32_t timer_periph); + +/* enable the auto reload shadow function */ +void timer_auto_reload_shadow_enable(uint32_t timer_periph); +/* disable the auto reload shadow function */ +void timer_auto_reload_shadow_disable(uint32_t timer_periph); + +/* enable the update event */ +void timer_update_event_enable(uint32_t timer_periph); +/* disable the update event */ +void timer_update_event_disable(uint32_t timer_periph); + +/* set TIMER counter alignment mode */ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned); +/* set TIMER counter up direction */ +void timer_counter_up_direction(uint32_t timer_periph); +/* set TIMER counter down direction */ +void timer_counter_down_direction(uint32_t timer_periph); + +/* configure TIMER prescaler */ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload); +/* configure TIMER repetition counter 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, uint8_t spmode); +/* configure TIMER update source */ +void timer_update_source_config(uint32_t timer_periph, uint8_t update); + +/* TIMER interrupt and flag*/ +/* enable the TIMER interrupt */ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt); +/* disable the TIMER interrupt */ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt); +/* get TIMER interrupt flag */ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt); +/* clear TIMER interrupt flag */ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt); +/* get TIMER flag */ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag); +/* clear TIMER flag */ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag); + +/* TIMER DMA and event*/ +/* enable the TIMER DMA */ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma); +/* disable the TIMER DMA */ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma); +/* channel DMA request source selection */ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request); +/* configure the TIMER DMA transfer */ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth); + +/* software generate events */ +void timer_event_software_generate(uint32_t timer_periph, uint16_t event); + +/* TIMER channel complementary protection */ +/* 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); + +/* channel capture/compare control shadow register enable */ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue); +/* configure TIMER channel control shadow register update control */ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl); +/* select TIMER OCPRE clear source */ +void timer_ocpre_clear_source_config(uint32_t timer_periph, uint8_t ocpreclear); + +/* TIMER channel output */ +/* configure TIMER channel output function */ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct* ocpara); +/* configure TIMER channel output compare mode */ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode); +/* configure TIMER channel output pulse value */ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse); + +/* configure TIMER channel output shadow function */ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow); +/* configure TIMER channel output fast function */ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast); +/* configure TIMER channel output clear function */ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear); + +/* configure TIMER channel output polarity */ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity); +/* configure TIMER channel complementary output polarity */ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity); +/* configure TIMER channel enable state */ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_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 */ +/* 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, uint32_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, uint8_t hallmode); + +/* TIMER master and slave mode */ +/* select TIMER input trigger source */ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger); +/* select TIMER master mode output trigger source */ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t 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, uint8_t masterslave); +/* configure TIMER external trigger input */ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t expolarity, 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 expolarity, 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 expolarity, 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 expolarity, uint32_t extfilter); +/* disable TIMER the external clock mode 1 */ +void timer_external_clock_mode1_disable(uint32_t timer_periph); + +/* configure TIMER13 channel0 remap function */ +void timer_channel_remap_config(uint32_t timer_periph, uint16_t channel, uint32_t remap); + +#ifdef GD32F170_190 +/* configure TIMER cc register selection */ +void timer_write_cc_register_config(uint32_t timer_periph, uint32_t ccsel); +/* configure TIMER output value selection */ +void timer_output_value_selection_config(uint32_t timer_periph, uint32_t outsel); +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_TIMER_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_tsi.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_tsi.h new file mode 100644 index 0000000..30a4374 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_tsi.h @@ -0,0 +1,340 @@ +/*! + \file gd32f1x0_tsi.h + \brief definitions for the TSI +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_TSI_H +#define GD32F1X0_TSI_H + +#include "gd32f1x0.h" + +/* TSI definitions */ +#define TSI TSI_BASE /*!< TSI base address */ + +/* registers definitions */ +#define TSI_CTL REG32(TSI + 0x00U) /*!< TSI control register */ +#define TSI_INTEN REG32(TSI + 0x04U) /*!< TSI interrupt enable register */ +#define TSI_INTC REG32(TSI + 0x08U) /*!< TSI interrupt flag clear register */ +#define TSI_INTF REG32(TSI + 0x0CU) /*!< TSI interrupt flag register */ +#define TSI_PHM REG32(TSI + 0x10U) /*!< TSI pin hysteresis mode register */ +#define TSI_ASW REG32(TSI + 0x18U) /*!< TSI analog switch register */ +#define TSI_SAMPCFG REG32(TSI + 0x20U) /*!< TSI sample configuration register */ +#define TSI_CHCFG REG32(TSI + 0x28U) /*!< TSI channel configuration register */ +#define TSI_GCTL REG32(TSI + 0x30U) /*!< TSI group control register */ +#define TSI_G0CYCN REG32(TSI + 0x34U) /*!< TSI group 0 cycle number register */ +#define TSI_G1CYCN REG32(TSI + 0x38U) /*!< TSI group 1 cycle number register */ +#define TSI_G2CYCN REG32(TSI + 0x3CU) /*!< TSI group 2 cycle number register */ +#define TSI_G3CYCN REG32(TSI + 0x40U) /*!< TSI group 3 cycle number register */ +#define TSI_G4CYCN REG32(TSI + 0x44U) /*!< TSI group 4 cycle number register */ +#define TSI_G5CYCN REG32(TSI + 0x48U) /*!< TSI group 5 cycle number register */ + +/* bits definitions */ +/* TSI_CTL */ +#define TSI_CTL_TSIEN BIT(0) /*!< TSI enable */ +#define TSI_CTL_TSIS BIT(1) /*!< TSI start */ +#define TSI_CTL_TRGMOD BIT(2) /*!< trigger mode selection */ +#define TSI_CTL_EGSEL BIT(3) /*!< edge selection */ +#define TSI_CTL_PINMOD BIT(4) /*!< pin mode */ +#define TSI_CTL_MCN BITS(5,7) /*!< max cycle number of a sequence */ +#define TSI_CTL_CTCDIV BITS(12,14) /*!< CTCLK clock division factor */ +#define TSI_CTL_ECDIV BIT(15) /*!< ECCLK clock division factor */ +#define TSI_CTL_ECEN BIT(16) /*!< extend charge state enable */ +#define TSI_CTL_ECDT BITS(17,23) /*!< extend charge State maximum duration time */ +#define TSI_CTL_CTDT BITS(24,27) /*!< charge transfer state duration time */ +#define TSI_CTL_CDT BITS(28,31) /*!< charge state duration time */ + +/* TSI_INTEN */ +#define TSI_INTEN_CTCFIE BIT(0) /*!< charge transfer complete flag interrupt enable */ +#define TSI_INTEN_MNERRIE BIT(1) /*!< max cycle number error interrupt enable */ + +/* TSI_INTC */ +#define TSI_INTC_CCTCF BIT(0) /*!< clear charge transfer complete flag */ +#define TSI_INTC_CMNERR BIT(1) /*!< clear max cycle number error */ + +/* TSI_INTF */ +#define TSI_INTF_CTCF BIT(0) /*!< charge transfer complete flag */ +#define TSI_INTF_MNERR BIT(1) /*!< max cycle number error */ + +/* TSI_PHM */ +#define TSI_PHM_G0P0 BIT(0) /*!< pin G0P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G0P1 BIT(1) /*!< pin G0P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G0P2 BIT(2) /*!< pin G0P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G0P3 BIT(3) /*!< pin G0P3 Schmitt trigger hysteresis state */ +#define TSI_PHM_G1P0 BIT(4) /*!< pin G1P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G1P1 BIT(5) /*!< pin G1P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G1P2 BIT(6) /*!< pin G1P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G1P3 BIT(7) /*!< pin G1P3 Schmitt trigger hysteresis state */ +#define TSI_PHM_G2P0 BIT(8) /*!< pin G2P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G2P1 BIT(9) /*!< pin G2P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G2P2 BIT(10) /*!< pin G2P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G2P3 BIT(11) /*!< pin G2P3 Schmitt trigger hysteresis state */ +#define TSI_PHM_G3P0 BIT(12) /*!< pin G3P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G3P1 BIT(13) /*!< pin G3P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G3P2 BIT(14) /*!< pin G3P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G3P3 BIT(15) /*!< pin G3P3 Schmitt trigger hysteresis state */ +#define TSI_PHM_G4P0 BIT(16) /*!< pin G4P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G4P1 BIT(17) /*!< pin G4P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G4P2 BIT(18) /*!< pin G4P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G4P3 BIT(19) /*!< pin G4P3 Schmitt trigger hysteresis state */ +#define TSI_PHM_G5P0 BIT(20) /*!< pin G5P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G5P1 BIT(21) /*!< pin G5P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G5P2 BIT(22) /*!< pin G5P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G5P3 BIT(23) /*!< pin G5P3 Schmitt trigger hysteresis state */ + +/* TSI_ASW */ +#define TSI_ASW_G0P0 BIT(0) /*!< pin G0P0 analog switch state */ +#define TSI_ASW_G0P1 BIT(1) /*!< pin G0P2 analog switch state */ +#define TSI_ASW_G0P2 BIT(2) /*!< pin G0P3 analog switch state */ +#define TSI_ASW_G0P3 BIT(3) /*!< pin G0P4 analog switch state */ +#define TSI_ASW_G1P0 BIT(4) /*!< pin G1P0 analog switch state */ +#define TSI_ASW_G1P1 BIT(5) /*!< pin G1P1 analog switch state */ +#define TSI_ASW_G1P2 BIT(6) /*!< pin G1P2 analog switch state */ +#define TSI_ASW_G1P3 BIT(7) /*!< pin G1P3 analog switch state */ +#define TSI_ASW_G2P0 BIT(8) /*!< pin G2P0 analog switch state */ +#define TSI_ASW_G2P1 BIT(9) /*!< pin G2P1 analog switch state */ +#define TSI_ASW_G2P2 BIT(10) /*!< pin G2P2 analog switch state */ +#define TSI_ASW_G2P3 BIT(11) /*!< pin G2P3 analog switch state */ +#define TSI_ASW_G3P0 BIT(12) /*!< pin G3P0 analog switch state */ +#define TSI_ASW_G3P1 BIT(13) /*!< pin G3P1 analog switch state */ +#define TSI_ASW_G3P2 BIT(14) /*!< pin G3P2 analog switch state */ +#define TSI_ASW_G3P3 BIT(15) /*!< pin G3P3 analog switch state */ +#define TSI_ASW_G4P0 BIT(16) /*!< pin G4P0 analog switch state */ +#define TSI_ASW_G4P1 BIT(17) /*!< pin G4P1 analog switch state */ +#define TSI_ASW_G4P2 BIT(18) /*!< pin G4P2 analog switch state */ +#define TSI_ASW_G4P3 BIT(19) /*!< pin G4P3 analog switch state */ +#define TSI_ASW_G5P0 BIT(20) /*!< pin G5P0 analog switch state */ +#define TSI_ASW_G5P1 BIT(21) /*!< pin G5P1 analog switch state */ +#define TSI_ASW_G5P2 BIT(22) /*!< pin G5P2 analog switch state */ +#define TSI_ASW_G5P3 BIT(23) /*!< pin G5P3 analog switch state */ + +/* TSI_SAMPCFG */ +#define TSI_SAMPCFG_G0P0 BIT(0) /*!< pin G0P0 sample pin mode */ +#define TSI_SAMPCFG_G0P1 BIT(1) /*!< pin G0P1 sample pin mode */ +#define TSI_SAMPCFG_G0P2 BIT(2) /*!< pin G0P2 sample pin mode */ +#define TSI_SAMPCFG_G0P3 BIT(3) /*!< pin G0P3 sample pin mode */ +#define TSI_SAMPCFG_G1P0 BIT(4) /*!< pin G1P0 sample pin mode */ +#define TSI_SAMPCFG_G1P1 BIT(5) /*!< pin G1P1 sample pin mode */ +#define TSI_SAMPCFG_G1P2 BIT(6) /*!< pin G1P2 sample pin mode */ +#define TSI_SAMPCFG_G1P3 BIT(7) /*!< pin G1P3 sample pin mode */ +#define TSI_SAMPCFG_G2P0 BIT(8) /*!< pin G2P0 sample pin mode */ +#define TSI_SAMPCFG_G2P1 BIT(9) /*!< pin G2P1 sample pin mode */ +#define TSI_SAMPCFG_G2P2 BIT(10) /*!< pin G2P2 sample pin mode */ +#define TSI_SAMPCFG_G2P3 BIT(11) /*!< pin G2P3 sample pin mode */ +#define TSI_SAMPCFG_G3P0 BIT(12) /*!< pin G3P0 sample pin mode */ +#define TSI_SAMPCFG_G3P1 BIT(13) /*!< pin G3P1 sample pin mode */ +#define TSI_SAMPCFG_G3P2 BIT(14) /*!< pin G3P2 sample pin mode */ +#define TSI_SAMPCFG_G3P3 BIT(15) /*!< pin G3P3 sample pin mode */ +#define TSI_SAMPCFG_G4P0 BIT(16) /*!< pin G4P0 sample pin mode */ +#define TSI_SAMPCFG_G4P1 BIT(17) /*!< pin G4P1 sample pin mode */ +#define TSI_SAMPCFG_G4P2 BIT(18) /*!< pin G4P2 sample pin mode */ +#define TSI_SAMPCFG_G4P3 BIT(19) /*!< pin G4P3 sample pin mode */ +#define TSI_SAMPCFG_G5P0 BIT(20) /*!< pin G5P0 sample pin mode */ +#define TSI_SAMPCFG_G5P1 BIT(21) /*!< pin G5P1 sample pin mode */ +#define TSI_SAMPCFG_G5P2 BIT(22) /*!< pin G5P2 sample pin mode */ +#define TSI_SAMPCFG_G5P3 BIT(23) /*!< pin G5P3 sample pin mode */ + +/* TSI_CHCFG */ +#define TSI_CHCFG_G0P0 BIT(0) /*!< pin G0P0 channel pin mode */ +#define TSI_CHCFG_G0P1 BIT(1) /*!< pin G0P1 channel pin mode */ +#define TSI_CHCFG_G0P2 BIT(2) /*!< pin G0P2 channel pin mode */ +#define TSI_CHCFG_G0P3 BIT(3) /*!< pin G0P3 channel pin mode */ +#define TSI_CHCFG_G1P0 BIT(4) /*!< pin G1P0 channel pin mode */ +#define TSI_CHCFG_G1P1 BIT(5) /*!< pin G1P1 channel pin mode */ +#define TSI_CHCFG_G1P2 BIT(6) /*!< pin G1P2 channel pin mode */ +#define TSI_CHCFG_G1P3 BIT(7) /*!< pin G1P3 channel pin mode */ +#define TSI_CHCFG_G2P0 BIT(8) /*!< pin G2P0 channel pin mode */ +#define TSI_CHCFG_G2P1 BIT(9) /*!< pin G2P1 channel pin mode */ +#define TSI_CHCFG_G2P2 BIT(10) /*!< pin G2P2 channel pin mode */ +#define TSI_CHCFG_G2P3 BIT(11) /*!< pin G2P3 channel pin mode */ +#define TSI_CHCFG_G3P0 BIT(12) /*!< pin G3P0 channel pin mode */ +#define TSI_CHCFG_G3P1 BIT(13) /*!< pin G3P1 channel pin mode */ +#define TSI_CHCFG_G3P2 BIT(14) /*!< pin G3P2 channel pin mode */ +#define TSI_CHCFG_G3P3 BIT(15) /*!< pin G3P3 channel pin mode */ +#define TSI_CHCFG_G4P0 BIT(16) /*!< pin G4P0 channel pin mode */ +#define TSI_CHCFG_G4P1 BIT(17) /*!< pin G4P1 channel pin mode */ +#define TSI_CHCFG_G4P2 BIT(18) /*!< pin G4P2 channel pin mode */ +#define TSI_CHCFG_G4P3 BIT(19) /*!< pin G4P3 channel pin mode */ +#define TSI_CHCFG_G5P0 BIT(20) /*!< pin G5P0 channel pin mode */ +#define TSI_CHCFG_G5P1 BIT(21) /*!< pin G5P1 channel pin mode */ +#define TSI_CHCFG_G5P2 BIT(22) /*!< pin G5P2 channel pin mode */ +#define TSI_CHCFG_G5P3 BIT(23) /*!< pin G5P3 channel pin mode */ + +/* TSI_GCTL */ +#define TSI_GCTL_GE0 BIT(0) /*!< group0 enable */ +#define TSI_GCTL_GE1 BIT(1) /*!< group1 enable */ +#define TSI_GCTL_GE2 BIT(2) /*!< group2 enable */ +#define TSI_GCTL_GE3 BIT(3) /*!< group3 enable */ +#define TSI_GCTL_GE4 BIT(4) /*!< group4 enable */ +#define TSI_GCTL_GE5 BIT(5) /*!< group5 enable */ +#define TSI_GCTL_GC0 BIT(16) /*!< group0 complete */ +#define TSI_GCTL_GC1 BIT(17) /*!< group1 complete */ +#define TSI_GCTL_GC2 BIT(18) /*!< group2 complete */ +#define TSI_GCTL_GC3 BIT(19) /*!< group3 complete */ +#define TSI_GCTL_GC4 BIT(20) /*!< group4 complete */ +#define TSI_GCTL_GC5 BIT(21) /*!< group5 complete */ + +/* constants definitions */ +/* CTCLK clock division factor */ +#define CTL_CTCDIV(regval) (BITS(12,14) & ((regval) << 12U)) /*!< CTCLK clock division factor */ +#define TSI_CTCDIV_DIV1 CTL_CTCDIV(0) /*!< fCTCLK = fHCLK */ +#define TSI_CTCDIV_DIV2 CTL_CTCDIV(1) /*!< fCTCLK = fHCLK/2 */ +#define TSI_CTCDIV_DIV4 CTL_CTCDIV(2) /*!< fCTCLK = fHCLK/4 */ +#define TSI_CTCDIV_DIV8 CTL_CTCDIV(3) /*!< fCTCLK = fHCLK/8 */ +#define TSI_CTCDIV_DIV16 CTL_CTCDIV(4) /*!< fCTCLK = fHCLK/16 */ +#define TSI_CTCDIV_DIV32 CTL_CTCDIV(5) /*!< fCTCLK = fHCLK/32 */ +#define TSI_CTCDIV_DIV64 CTL_CTCDIV(6) /*!< fCTCLK = fHCLK/64 */ +#define TSI_CTCDIV_DIV128 CTL_CTCDIV(7) /*!< fCTCLK = fHCLK/128 */ + +/* charge transfer state duration Time */ +#define CTL_CTDT(regval) (BITS(24,27) & ((regval) << 24U)) /*!< charge transfer state duration time */ +#define TSI_TRANSFER_1CTCLK CTL_CTDT(0) /*!< the duration time of transfer state is 1 CTCLK */ +#define TSI_TRANSFER_2CTCLK CTL_CTDT(1) /*!< the duration time of transfer state is 2 CTCLK */ +#define TSI_TRANSFER_3CTCLK CTL_CTDT(2) /*!< the duration time of transfer state is 3 CTCLK */ +#define TSI_TRANSFER_4CTCLK CTL_CTDT(3) /*!< the duration time of transfer state is 4 CTCLK */ +#define TSI_TRANSFER_5CTCLK CTL_CTDT(4) /*!< the duration time of transfer state is 5 CTCLK */ +#define TSI_TRANSFER_6CTCLK CTL_CTDT(5) /*!< the duration time of transfer state is 6 CTCLK */ +#define TSI_TRANSFER_7CTCLK CTL_CTDT(6) /*!< the duration time of transfer state is 7 CTCLK */ +#define TSI_TRANSFER_8CTCLK CTL_CTDT(7) /*!< the duration time of transfer state is 8 CTCLK */ +#define TSI_TRANSFER_9CTCLK CTL_CTDT(8) /*!< the duration time of transfer state is 9 CTCLK */ +#define TSI_TRANSFER_10CTCLK CTL_CTDT(9) /*!< the duration time of transfer state is 10 CTCLK */ +#define TSI_TRANSFER_11CTCLK CTL_CTDT(10) /*!< the duration time of transfer state is 11 CTCLK */ +#define TSI_TRANSFER_12CTCLK CTL_CTDT(11) /*!< the duration time of transfer state is 12 CTCLK */ +#define TSI_TRANSFER_13CTCLK CTL_CTDT(12) /*!< the duration time of transfer state is 13 CTCLK */ +#define TSI_TRANSFER_14CTCLK CTL_CTDT(13) /*!< the duration time of transfer state is 14 CTCLK */ +#define TSI_TRANSFER_15CTCLK CTL_CTDT(14) /*!< the duration time of transfer state is 15 CTCLK */ +#define TSI_TRANSFER_16CTCLK CTL_CTDT(15) /*!< the duration time of transfer state is 16 CTCLK */ + +/* charge state duration time */ +#define CTL_CDT(regval) (BITS(28,31) & ((regval) << 28U)) /*!< charge state duration time */ +#define TSI_CHARGE_1CTCLK CTL_CDT(0) /*!< the duration time of charge state is 1 CTCLK */ +#define TSI_CHARGE_2CTCLK CTL_CDT(1) /*!< the duration time of charge state is 2 CTCLK */ +#define TSI_CHARGE_3CTCLK CTL_CDT(2) /*!< the duration time of charge state is 3 CTCLK */ +#define TSI_CHARGE_4CTCLK CTL_CDT(3) /*!< the duration time of charge state is 4 CTCLK */ +#define TSI_CHARGE_5CTCLK CTL_CDT(4) /*!< the duration time of charge state is 5 CTCLK */ +#define TSI_CHARGE_6CTCLK CTL_CDT(5) /*!< the duration time of charge state is 6 CTCLK */ +#define TSI_CHARGE_7CTCLK CTL_CDT(6) /*!< the duration time of charge state is 7 CTCLK */ +#define TSI_CHARGE_8CTCLK CTL_CDT(7) /*!< the duration time of charge state is 8 CTCLK */ +#define TSI_CHARGE_9CTCLK CTL_CDT(8) /*!< the duration time of charge state is 9 CTCLK */ +#define TSI_CHARGE_10CTCLK CTL_CDT(9) /*!< the duration time of charge state is 10 CTCLK */ +#define TSI_CHARGE_11CTCLK CTL_CDT(10) /*!< the duration time of charge state is 11 CTCLK */ +#define TSI_CHARGE_12CTCLK CTL_CDT(11) /*!< the duration time of charge state is 12 CTCLK */ +#define TSI_CHARGE_13CTCLK CTL_CDT(12) /*!< the duration time of charge state is 13 CTCLK */ +#define TSI_CHARGE_14CTCLK CTL_CDT(13) /*!< the duration time of charge state is 14 CTCLK */ +#define TSI_CHARGE_15CTCLK CTL_CDT(14) /*!< the duration time of charge state is 15 CTCLK */ +#define TSI_CHARGE_16CTCLK CTL_CDT(15) /*!< the duration time of charge state is 16 CTCLK */ + +/* max cycle number of a sequence */ +#define CTL_MCN(regval) (BITS(5,7) & ((regval) << 5U)) /*!< max cycle number of a sequence */ +#define TSI_MAXNUM255 CTL_MCN(0) /*!< the max cycle number of a sequence is 255 */ +#define TSI_MAXNUM511 CTL_MCN(1) /*!< the max cycle number of a sequence is 511 */ +#define TSI_MAXNUM1023 CTL_MCN(2) /*!< the max cycle number of a sequence is 1023 */ +#define TSI_MAXNUM2047 CTL_MCN(3) /*!< the max cycle number of a sequence is 2047 */ +#define TSI_MAXNUM4095 CTL_MCN(4) /*!< the max cycle number of a sequence is 4095 */ +#define TSI_MAXNUM8191 CTL_MCN(5) /*!< the max cycle number of a sequence is 8191 */ +#define TSI_MAXNUM16383 CTL_MCN(6) /*!< the max cycle number of a sequence is 16383 */ + +/* ECCLK clock division factor */ +#define TSI_EXTEND_DIV1 ((uint32_t)0x00000000U) /*!< fECCLK = fHCLK */ +#define TSI_EXTEND_DIV2 ((uint32_t)0x00000001U) /*!< fECCLK = fHCLK/2 */ + +/* Extend Charge State Maximum Duration Time */ +#define TSI_EXTENDMAX(regval) (BITS(17,23) & ((regval) << 17U)) /* value range 1...128,extend charge state maximum duration time */ + +/* hardware trigger mode */ +#define TSI_FALLING_TRIGGER ((uint32_t)0x00000000U) /*!< falling edge trigger TSI charge transfer sequence */ +#define TSI_RISING_TRIGGER ((uint32_t)0x00000001U) /*!< rising edge trigger TSI charge transfer sequence */ + +/* pin mode */ +#define TSI_OUTPUT_LOW ((uint32_t)0x00000000U) /*!< TSI pin will output low when IDLE */ +#define TSI_INPUT_FLOATING ((uint32_t)0x00000001U) /*!< TSI pin will keep input_floating when IDLE */ + +/* interrupt enable bits */ +#define TSI_INT_CTCF TSI_INTEN_CTCFIE /*!< charge transfer complete flag interrupt enable */ +#define TSI_INTEN_MNERR TSI_INTEN_MNERRIE /*!< max cycle number error interrupt enable */ + +/* interrupt flag bits */ +#define TSI_INT_FLAG_CTC TSI_INTF_CTCF /*!< charge transfer complete flag */ +#define TSI_INT_FLAG_MNERR TSI_INTF_MNERR /*!< max cycle number error */ + +/* function declarations */ +/* reset TSI peripheral */ +void tsi_deinit(void); +/* initialize TSI plus prescaler,charge plus,transfer plus,max cycle number */ +void tsi_init(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration,uint32_t max_number); +/* enable TSI module */ +void tsi_enable(void); +/* disable TSI module */ +void tsi_disable(void); +/* enable sample pin */ +void tsi_sample_pin_enable(uint32_t sample); +/* disable sample pin */ +void tsi_sample_pin_disable(uint32_t sample); +/* enable channel pin */ +void tsi_channel_pin_enable(uint32_t channel); +/* disable channel pin */ +void tsi_channel_pin_disable(uint32_t channel); + +/* configure TSI triggering by software */ +void tsi_sofeware_mode_config(void); +/* start a charge-transfer sequence when TSI is in software trigger mode */ +void tsi_software_start(void); +/* stop a charge-transfer sequence when TSI is in software trigger mode */ +void tsi_software_stop(void); +/* configure TSI triggering by hardware */ +void tsi_hardware_mode_config(uint8_t trigger_edge); +/* configure TSI pin mode when charge-transfer sequence is IDLE */ +void tsi_pin_mode_config(uint8_t pin_mode); +/* configure extend charge state */ +void tsi_extend_charge_config(ControlStatus extend,uint8_t prescaler,uint32_t max_duration); + +/* configure charge plus and transfer plus */ +void tsi_plus_config(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration); +/* configure the max cycle number of a charge-transfer sequence */ +void tsi_max_number_config(uint32_t max_number); +/* switch on hysteresis pin */ +void tsi_hysteresis_on(uint32_t group_pin); +/* switch off hysteresis pin */ +void tsi_hysteresis_off(uint32_t group_pin); +/* switch on analog pin */ +void tsi_analog_on(uint32_t group_pin); +/* switch off analog pin */ +void tsi_analog_off(uint32_t group_pin); + +/* enable TSI interrupt */ +void tsi_interrupt_enable(uint32_t source); +/* disable TSI interrupt */ +void tsi_interrupt_disable(uint32_t source); +/* clear interrupt flag */ +void tsi_interrupt_flag_clear(uint32_t flag); +/* get TSI module current status */ +FlagStatus tsi_interrupt_flag_get(uint32_t status); + +/* enbale group */ +void tsi_group_enable(uint32_t group); +/* disbale group */ +void tsi_group_disable(uint32_t group); +/* get group complete status */ +FlagStatus tsi_group_status_get(uint32_t group); +/* get the cycle number for group0 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group0_cycle_get(void); +/* get the cycle number for group1 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group1_cycle_get(void); +/* get the cycle number for group2 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group2_cycle_get(void); +/* get the cycle number for group3 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group3_cycle_get(void); +/* get the cycle number for group4 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group4_cycle_get(void); +/* get the cycle number for group5 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group5_cycle_get(void); + +#endif /* GD32F1X0_TSI_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_usart.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_usart.h new file mode 100644 index 0000000..d0ed92d --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_usart.h @@ -0,0 +1,542 @@ +/*! + \file gd32f1x0_usart.h + \brief definitions for the USART +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_USART_H +#define GD32F1X0_USART_H + +#include "gd32f1x0.h" + +/* USARTx(x=0,1) definitions */ +#define USART0 (USART_BASE + 0x0000F400U) +#define USART1 USART_BASE + +/* registers definitions */ +#define USART_CTL0(usartx) REG32((usartx) + 0x00U) /*!< USART control register 0 */ +#define USART_CTL1(usartx) REG32((usartx) + 0x04U) /*!< USART control register 1 */ +#define USART_CTL2(usartx) REG32((usartx) + 0x08U) /*!< USART control register 2 */ +#define USART_BAUD(usartx) REG32((usartx) + 0x0CU) /*!< USART baud rate register */ +#define USART_GP(usartx) REG32((usartx) + 0x10U) /*!< USART guard time and prescaler register */ +#define USART_RT(usartx) REG32((usartx) + 0x14U) /*!< USART receiver timeout register */ +#define USART_CMD(usartx) REG32((usartx) + 0x18U) /*!< USART command register */ +#define USART_STAT(usartx) REG32((usartx) + 0x1CU) /*!< USART status register */ +#define USART_INTC(usartx) REG32((usartx) + 0x20U) /*!< USART status clear register */ +#define USART_RDATA(usartx) REG32((usartx) + 0x24U) /*!< USART receive data register */ +#define USART_TDATA(usartx) REG32((usartx) + 0x28U) /*!< USART transmit data register */ + +/* bits definitions */ +/* USARTx_CTL0 */ +#define USART_CTL0_UEN BIT(0) /*!< USART enable */ +#define USART_CTL0_UESM BIT(1) /*!< USART enable in deep-sleep mode */ +#define USART_CTL0_REN BIT(2) /*!< receiver enable */ +#define USART_CTL0_TEN BIT(3) /*!< transmitter enable */ +#define USART_CTL0_IDLEIE BIT(4) /*!< idle line detected interrupt enable */ +#define USART_CTL0_RBNEIE BIT(5) /*!< read data buffer not empty interrupt and overrun error interrupt enable */ +#define USART_CTL0_TCIE BIT(6) /*!< transmission complete interrupt enable */ +#define USART_CTL0_TBEIE BIT(7) /*!< transmitter register empty interrupt enable */ +#define USART_CTL0_PERRIE BIT(8) /*!< parity error interrupt enable */ +#define USART_CTL0_PM BIT(9) /*!< parity mode */ +#define USART_CTL0_PCEN BIT(10) /*!< parity control enable */ +#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL BIT(12) /*!< word length */ +#define USART_CTL0_MEN BIT(13) /*!< mute mode enable */ +#define USART_CTL0_AMIE BIT(14) /*!< address match interrupt enable */ +#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ +#define USART_CTL0_DED BITS(16,20) /*!< driver enable deassertion time */ +#define USART_CTL0_DEA BITS(21,25) /*!< driver enable assertion time */ +#define USART_CTL0_RTIE BIT(26) /*!< receiver timeout interrupt enable */ +#define USART_CTL0_EBIE BIT(27) /*!< end of block interrupt enable */ + +/* USARTx_CTL1 */ +#define USART_CTL1_ADDM BIT(4) /*!< address detection mode */ +#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ +#define USART_CTL1_LBDIE BIT(6) /*!< LIN break detection interrupt enable */ +#define USART_CTL1_CLEN BIT(8) /*!< last bit clock pulse */ +#define USART_CTL1_CPH BIT(9) /*!< clock phase */ +#define USART_CTL1_CPL BIT(10) /*!< clock polarity */ +#define USART_CTL1_CKEN BIT(11) /*!< ck pin enable */ +#define USART_CTL1_STB BITS(12,13) /*!< stop bits length */ +#define USART_CTL1_LMEN BIT(14) /*!< LIN mode enable */ +#define USART_CTL1_STRP BIT(15) /*!< swap TX/RX pins */ +#define USART_CTL1_RINV BIT(16) /*!< RX pin level inversion */ +#define USART_CTL1_TINV BIT(17) /*!< TX pin level inversion */ +#define USART_CTL1_DINV BIT(18) /*!< data bit level inversion */ +#define USART_CTL1_MSBF BIT(19) /*!< most significant bit first */ +#define USART_CTL1_ABDEN BIT(20) /*!< auto baud rate enable */ +#define USART_CTL1_ABDM BITS(21,22) /*!< auto baud rate mode */ +#define USART_CTL1_RTEN BIT(23) /*!< receiver timeout enable */ +#define USART_CTL1_ADDR BITS(24,31) /*!< address of the USART terminal */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< error interrupt enable in multibuffer communication */ +#define USART_CTL2_IREN BIT(1) /*!< IrDA mode enable */ +#define USART_CTL2_IRLP BIT(2) /*!< IrDA low-power */ +#define USART_CTL2_HDEN BIT(3) /*!< half-duplex enable */ +#define USART_CTL2_NKEN BIT(4) /*!< NACK enable in smartcard mode */ +#define USART_CTL2_SCEN BIT(5) /*!< smartcard mode enable */ +#define USART_CTL2_DENR BIT(6) /*!< DMA enable for reception */ +#define USART_CTL2_DENT BIT(7) /*!< DMA enable for transmission */ +#define USART_CTL2_RTSEN BIT(8) /*!< RTS enable */ +#define USART_CTL2_CTSEN BIT(9) /*!< CTS enable */ +#define USART_CTL2_CTSIE BIT(10) /*!< CTS interrupt enable */ +#define USART_CTL2_OSB BIT(11) /*!< one sample bit mode */ +#define USART_CTL2_OVRD BIT(12) /*!< overrun disable */ +#define USART_CTL2_DDRE BIT(13) /*!< disable DMA on reception error */ +#define USART_CTL2_DEM BIT(14) /*!< driver enable mode */ +#define USART_CTL2_DEP BIT(15) /*!< driver enable polarity mode */ +#define USART_CTL2_SCRTNUM BITS(17,19) /*!< smartcard auto-retry number */ +#define USART_CTL2_WUM BITS(20,21) /*!< wakeup mode from deep-sleep mode */ +#define USART_CTL2_WUIE BIT(22) /*!< wakeup from deep-sleep mode interrupt enable */ + +/* USARTx_BAUD */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer of baud-rate divider */ + +/* USARTx_GP */ +#define USART_GP_PSC BITS(0,7) /*!< prescaler value for dividing the system clock */ +#define USART_GP_GUAT BITS(8,15) /*!< guard time value in smartcard mode */ + +/* USARTx_RT */ +#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ +#define USART_RT_BL BITS(24,31) /*!< block length */ + +/* USARTx_CMD */ +#define USART_CMD_ABDCMD BIT(0) /*!< auto baudrate detection command */ +#define USART_CMD_SBKCMD BIT(1) /*!< send break command */ +#define USART_CMD_MMCMD BIT(2) /*!< mute mode command */ +#define USART_CMD_RXFCMD BIT(3) /*!< receive data flush command */ +#define USART_CMD_TXFCMD BIT(4) /*!< transmit data flush request */ + +/* USARTx_STAT */ +#define USART_STAT_PERR BIT(0) /*!< parity error flag */ +#define USART_STAT_FERR BIT(1) /*!< frame error flag */ +#define USART_STAT_NERR BIT(2) /*!< noise error flag */ +#define USART_STAT_ORERR BIT(3) /*!< overrun error */ +#define USART_STAT_IDLEF BIT(4) /*!< idle line detected flag */ +#define USART_STAT_RBNE BIT(5) /*!< read data buffer not empty */ +#define USART_STAT_TC BIT(6) /*!< transmission completed */ +#define USART_STAT_TBE BIT(7) /*!< transmit data register empty */ +#define USART_STAT_LBDF BIT(8) /*!< LIN break detected flag */ +#define USART_STAT_CTSF BIT(9) /*!< CTS change flag */ +#define USART_STAT_CTS BIT(10) /*!< CTS level */ +#define USART_STAT_RTF BIT(11) /*!< receiver timeout flag */ +#define USART_STAT_EBF BIT(12) /*!< end of block flag */ +#define USART_STAT_ABDE BIT(14) /*!< auto baudrate detection error */ +#define USART_STAT_ABDF BIT(15) /*!< auto baudrate detection flag */ +#define USART_STAT_BSY BIT(16) /*!< busy flag */ +#define USART_STAT_AMF BIT(17) /*!< address match flag */ +#define USART_STAT_SBF BIT(18) /*!< send break flag */ +#define USART_STAT_RWU BIT(19) /*!< receiver wakeup from mute mode */ +#define USART_STAT_WUF BIT(20) /*!< wakeup from deep-sleep mode flag */ +#define USART_STAT_TEA BIT(21) /*!< transmit enable acknowledge flag */ +#define USART_STAT_REA BIT(22) /*!< receive enable acknowledge flag */ + +/* USARTx_INTC */ +#define USART_INTC_PEC BIT(0) /*!< parity error clear */ +#define USART_INTC_FEC BIT(1) /*!< frame error flag clear */ +#define USART_INTC_NEC BIT(2) /*!< noise detected clear */ +#define USART_INTC_OREC BIT(3) /*!< overrun error clear */ +#define USART_INTC_IDLEC BIT(4) /*!< idle line detected clear */ +#define USART_INTC_TCC BIT(6) /*!< transmission complete clear */ +#define USART_INTC_LBDC BIT(8) /*!< LIN break detected clear */ +#define USART_INTC_CTSC BIT(9) /*!< CTS change clear */ +#define USART_INTC_RTC BIT(11) /*!< receiver timeout clear */ +#define USART_INTC_EBC BIT(12) /*!< end of timeout clear */ +#define USART_INTC_AMC BIT(17) /*!< address match clear */ +#define USART_INTC_WUC BIT(20) /*!< wakeup from deep-sleep mode clear */ + +/* USARTx_RDATA */ +#define USART_RDATA_RDATA BITS(0,8) /*!< receive data value */ + +/* USARTx_TDATA */ +#define USART_TDATA_TDATA BITS(0,8) /*!< transmit data value */ + +/* constants definitions */ +/* define the USART bit position and its register index offset */ +#define USART_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define USART_REG_VAL(usartx, offset) (REG32((usartx) + (((uint32_t)(offset) & 0xFFFFU) >> 6))) +#define USART_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#define USART_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define USART_REG_VAL2(usartx, offset) (REG32((usartx) + ((uint32_t)(offset) >> 22))) +#define USART_BIT_POS2(val) (((uint32_t)(val) & 0x1F0000U) >> 16) + +/* register offset */ +#define USART_CTL0_REG_OFFSET 0x00U /*!< CTL0 register offset */ +#define USART_CTL1_REG_OFFSET 0x04U /*!< CTL1 register offset */ +#define USART_CTL2_REG_OFFSET 0x08U /*!< CTL2 register offset */ +#define USART_STAT_REG_OFFSET 0x1CU /*!< STAT 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_ABD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 15U), /*!< auto baudrate detection flag */ + USART_FLAG_ABDE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 14U), /*!< auto baudrate detection error */ + USART_FLAG_EB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 12U), /*!< end of block flag */ + USART_FLAG_RT = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout flag */ + USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 10U), /*!< CTS level */ + USART_FLAG_CTSF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 9U), /*!< CTS change flag */ + USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected flag */ + USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 7U), /*!< transmit data buffer empty */ + USART_FLAG_TC = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 6U), /*!< transmission complete */ + USART_FLAG_RBNE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty */ + USART_FLAG_IDLE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected flag */ + USART_FLAG_ORERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 3U), /*!< overrun error */ + USART_FLAG_NERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 2U), /*!< noise error flag */ + USART_FLAG_FERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 1U), /*!< frame error flag */ + USART_FLAG_PERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 0U), /*!< parity error flag */ +}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 */ +}usart_interrupt_flag_enum; + +/* USART interrupt enable or disable */ +typedef enum +{ + /* interrupt in CTL0 register */ + USART_INT_EB = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 27U), /*!< end of block interrupt */ + USART_INT_RT = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 26U), /*!< receiver timeout interrupt */ + USART_INT_AM = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 14U), /*!< address match interrupt */ + USART_INT_PERR = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 8U), /*!< parity error interrupt */ + USART_INT_TBE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt */ + USART_INT_TC = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 6U), /*!< transmission complete interrupt */ + USART_INT_RBNE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and overrun error interrupt */ + USART_INT_IDLE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 4U), /*!< IDLE line detected interrupt */ + /* interrupt in CTL1 register */ + USART_INT_LBD = USART_REGIDX_BIT(USART_CTL1_REG_OFFSET, 6U), /*!< LIN break detected interrupt */ + /* interrupt in CTL2 register */ + USART_INT_WU = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 22U), /*!< wakeup from deep-sleep mode interrupt */ + USART_INT_CTS = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 10U), /*!< CTS interrupt */ + USART_INT_ERR = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 0U), /*!< error interrupt */ +}usart_interrupt_enum; + +/* USART invert configure */ +typedef enum { + /* data bit level inversion */ + USART_DINV_ENABLE, /*!< data bit level inversion */ + USART_DINV_DISABLE, /*!< data bit level not inversion */ + /* TX pin level inversion */ + USART_TXPIN_ENABLE, /*!< TX pin level inversion */ + USART_TXPIN_DISABLE, /*!< TX pin level not inversion */ + /* RX pin level inversion */ + USART_RXPIN_ENABLE, /*!< RX pin level inversion */ + USART_RXPIN_DISABLE, /*!< RX pin level not inversion */ + /* swap TX/RX pins */ + USART_SWAP_ENABLE, /*!< swap TX/RX pins */ + USART_SWAP_DISABLE, /*!< not swap TX/RX pins */ +}usart_invert_enum; + +/* USART receiver configure */ +#define CTL0_REN(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_RECEIVE_ENABLE CTL0_REN(1) /*!< enable receiver */ +#define USART_RECEIVE_DISABLE CTL0_REN(0) /*!< disable receiver */ + +/* USART transmitter configure */ +#define CTL0_TEN(regval) (BIT(3) & ((uint32_t)(regval) << 3)) +#define USART_TRANSMIT_ENABLE CTL0_TEN(1) /*!< enable transmitter */ +#define USART_TRANSMIT_DISABLE CTL0_TEN(0) /*!< disable transmitter */ + +/* USART parity bits definitions */ +#define CTL0_PM(regval) (BITS(9,10) & ((uint32_t)(regval) << 9)) +#define USART_PM_NONE CTL0_PM(0) /*!< no parity */ +#define USART_PM_EVEN CTL0_PM(2) /*!< even parity */ +#define USART_PM_ODD CTL0_PM(3) /*!< odd parity */ + +/* USART wakeup method in mute mode */ +#define CTL0_WM(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_WM_IDLE CTL0_WM(0) /*!< idle line */ +#define USART_WM_ADDR CTL0_WM(1) /*!< address match */ + +/* USART word length definitions */ +#define CTL0_WL(regval) (BIT(12) & ((uint32_t)(regval) << 12)) +#define USART_WL_8BIT CTL0_WL(0) /*!< 8 bits */ +#define USART_WL_9BIT CTL0_WL(1) /*!< 9 bits */ + +/* USART oversample mode */ +#define CTL0_OVSMOD(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_OVSMOD_8 CTL0_OVSMOD(1) /*!< oversampling by 8 */ +#define USART_OVSMOD_16 CTL0_OVSMOD(0) /*!< oversampling by 16 */ + +/* USART address detection mode */ +#define CTL1_ADDM(regval) (BIT(4) & ((uint32_t)(regval) << 4)) +#define USART_ADDM_4BIT CTL1_ADDM(0) /*!< 4-bit address detection */ +#define USART_ADDM_FULLBIT CTL1_ADDM(1) /*!< full-bit address detection */ + +/* USART LIN break frame length */ +#define CTL1_LBLEN(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define USART_LBLEN_10B CTL1_LBLEN(0) /*!< 10 bits break detection */ +#define USART_LBLEN_11B CTL1_LBLEN(1) /*!< 11 bits break detection */ + +/* USART last bit clock pulse */ +#define CTL1_CLEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_CLEN_NONE CTL1_CLEN(0) /*!< clock pulse of the last data bit (MSB) is not output to the CK pin */ +#define USART_CLEN_EN CTL1_CLEN(1) /*!< clock pulse of the last data bit (MSB) is output to the CK pin */ + +/* USART clock phase */ +#define CTL1_CPH(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CPH_1CK CTL1_CPH(0) /*!< first clock transition is the first data capture edge */ +#define USART_CPH_2CK CTL1_CPH(1) /*!< second clock transition is the first data capture edge */ + +/* USART clock polarity */ +#define CTL1_CPL(regval) (BIT(10) & ((uint32_t)(regval) << 10)) +#define USART_CPL_LOW CTL1_CPL(0) /*!< steady low value on CK pin */ +#define USART_CPL_HIGH CTL1_CPL(1) /*!< steady high value on CK pin */ + +/* USART stop bits definitions */ +#define CTL1_STB(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define USART_STB_1BIT CTL1_STB(0) /*!< 1 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 */ + +/* USART auto baud rate detection mode bits definitions */ +#define CTL1_ABDM(regval) (BITS(21,22) & ((uint32_t)(regval) << 21)) +#define USART_ABDM_FTOR CTL1_ABDM(0) /*!< falling edge to rising edge measurement */ +#define USART_ABDM_FTOF CTL1_ABDM(1) /*!< falling edge to falling edge measurement */ + +/* USART IrDA low-power enable */ +#define CTL2_IRLP(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_IRLP_LOW CTL2_IRLP(1) /*!< low-power */ +#define USART_IRLP_NORMAL CTL2_IRLP(0) /*!< normal */ + +/* DMA enable for reception */ +#define CTL2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define USART_DENR_ENABLE CTL2_DENR(1) /*!< enable for reception */ +#define USART_DENR_DISABLE CTL2_DENR(0) /*!< disable for reception */ + +/* DMA enable for transmission */ +#define CTL2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_DENT_ENABLE CTL2_DENT(1) /*!< enable for transmission */ +#define USART_DENT_DISABLE CTL2_DENT(0) /*!< disable for transmission */ + +/* USART RTS hardware flow control configure */ +#define CTL2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CTL2_RTSEN(1) /*!< RTS hardware flow control enabled */ +#define USART_RTS_DISABLE CTL2_RTSEN(0) /*!< RTS hardware flow control disabled */ + +/* USART CTS hardware flow control configure */ +#define CTL2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CTL2_CTSEN(1) /*!< CTS hardware flow control enabled */ +#define USART_CTS_DISABLE CTL2_CTSEN(0) /*!< CTS hardware flow control disabled */ + +/* USART one sample bit method configure */ +#define CTL2_OSB(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_OSB_1BIT CTL2_OSB(1) /*!< 1 sample bit */ +#define USART_OSB_3BIT CTL2_OSB(0) /*!< 3 sample bits */ + +/* USART driver enable polarity mode */ +#define CTL2_DEP(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_DEP_HIGH CTL2_DEP(0) /*!< DE signal is active high */ +#define USART_DEP_LOW CTL2_DEP(1) /*!< DE signal is active low */ + +/* USART wakeup mode from deep-sleep mode */ +#define CTL2_WUM(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define USART_WUM_ADDR CTL2_WUM(0) /*!< WUF active on address match */ +#define USART_WUM_STARTB CTL2_WUM(2) /*!< WUF active on start bit */ +#define USART_WUM_RBNE CTL2_WUM(3) /*!< WUF active on RBNE */ + +/* 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); + +/* USART normal mode communication */ +/* 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 transmit data function */ +void usart_data_transmit(uint32_t usart_periph, uint32_t data); +/* USART receive data function */ +uint16_t usart_data_receive(uint32_t usart_periph); +/* 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); +/* overrun function is enabled */ +void usart_overrun_enable(uint32_t usart_periph); +/* overrun function is disabled */ +void usart_overrun_disable(uint32_t usart_periph); +/* configure the USART oversample mode */ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp); +/* sample bit method configure */ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb); + +/* auto baud rate detection */ +/* auto baud rate detection enable */ +void usart_autobaud_detection_enable(uint32_t usart_periph); +/* auto baud rate detection disable */ +void usart_autobaud_detection_disable(uint32_t usart_periph); +/* auto baud rate detection mode configure */ +void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod); + +/* multi-processor communication */ +/* 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); +/* address detection mode configure */ +void usart_address_detection_mode_config(uint32_t usart_periph, uint32_t addmod); +/* configure address of the USART */ +void usart_address_config(uint32_t usart_periph, uint8_t addr); +/* 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_config(uint32_t usart_periph, uint32_t rtimeout); + +/* LIN mode communication */ +/* LIN mode enable */ +void usart_lin_mode_enable(uint32_t usart_periph); +/* LIN mode disable */ +void usart_lin_mode_disable(uint32_t usart_periph); +/* LIN break detection length */ +void usart_lin_break_dection_length_config(uint32_t usart_periph, uint32_t lblen); + +/* half-duplex communication */ +/* half-duplex enable */ +void usart_halfduplex_enable(uint32_t usart_periph); +/* half-duplex disable */ +void usart_halfduplex_disable(uint32_t usart_periph); + +/* synchronous communication */ +/* clock enable */ +void usart_clock_enable(uint32_t usart_periph); +/* clock disable*/ +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 */ +/* smartcard mode enable */ +void usart_smartcard_mode_enable(uint32_t usart_periph); +/* smartcard mode disable */ +void usart_smartcard_mode_disable(uint32_t usart_periph); +/* NACK enable in smartcard mode */ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph); +/* NACK disable in smartcard mode */ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph); +/* guard time value configure in smartcard mode */ +void usart_guard_time_config(uint32_t usart_periph, uint32_t guat); +/* block length configure */ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl); +/* smartcard auto-retry number configure */ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum); + +/* 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 IrDA low-power */ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp); +/* configure the peripheral clock prescaler */ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc); + +/* 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); + +/* RS485 driver enable */ +void usart_rs485_driver_enable(uint32_t usart_periph); +/* RS485 driver disable */ +void usart_rs485_driver_disable(uint32_t usart_periph); +/* driver enable assertion time configure */ +void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime); +/* driver enable de-assertion time configure */ +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 for reception */ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd); +/* configure USART DMA for transmission */ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd); +/* disable DMA on reception error */ +void usart_reception_error_dma_disable(uint32_t usart_periph); +/* enable DMA on reception error */ +void usart_reception_error_dma_enable(uint32_t usart_periph); + +/* USART be able to wake up the mcu from deep-sleep mode */ +void usart_wakeup_enable(uint32_t usart_periph); +/* USART be not able to wake up the mcu from deep-sleep mode */ +void usart_wakeup_disable(uint32_t usart_periph); +/* wakeup mode from deep-sleep mode */ +void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum); + +/* flag functions */ +/* get flag in STAT register */ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag); +/* clear flag in STAT register */ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag); + +/* enable USART interrupt */ +void usart_interrupt_enable(uint32_t usart_periph, uint32_t inttype); +/* disable USART interrupt */ +void usart_interrupt_disable(uint32_t usart_periph, uint32_t inttype); +/* enable USART command */ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype); +/* get USART interrupt and flag status */ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag); +/* clear interrupt flag in STAT register */ +void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t flag); +#endif /* GD32F1X0_USART_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_wwdgt.h b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_wwdgt.h new file mode 100644 index 0000000..1eaf811 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Include/gd32f1x0_wwdgt.h @@ -0,0 +1,72 @@ +/*! + \file gd32f1x0_wwdgt.h + \brief definitions for the WWDGT +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_WWDGT_H +#define GD32F1X0_WWDGT_H + +#include "gd32f1x0.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE + +/* registers definitions */ +#define WWDGT_CTL REG32((WWDGT) + 0x00U) /*!< WWDGT control register */ +#define WWDGT_CFG REG32((WWDGT) + 0x04U) /*!< WWDGT configuration register */ +#define WWDGT_STAT REG32((WWDGT) + 0x08U) /*!< WWDGT status register */ + +/* bits definitions */ +/* WWDGT_CTL */ +#define WWDGT_CTL_CNT BITS(0,6) /*!< WWDGT counter value */ +#define WWDGT_CTL_WDGTEN BIT(7) /*!< WWDGT counter enable */ + +/* WWDGT_CFG */ +#define WWDGT_CFG_WIN BITS(0,6) /*!< WWDGT counter window value */ +#define WWDGT_CFG_PSC BITS(7,8) /*!< WWDGT prescaler divider value */ +#define WWDGT_CFG_EWIE BIT(9) /*!< early wakeup interrupt enable */ + +/* WWDGT_STAT */ +#define WWDGT_STAT_EWIF BIT(0) /*!< early wakeup interrupt flag */ + +/* constants definitions */ +/* ctl register value */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to WWDGT_CTL_CNT bit field */ + +/* cfg register value */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to WWDGT_CFG_WIN bit field */ + +#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 */ + +/* function declarations */ +/* reset the window watchdog timer configuration */ +void wwdgt_deinit(void); +/* start the window watchdog timer counter */ +void wwdgt_enable(void); + +/* configure the window watchdog timer counter value */ +void wwdgt_counter_update(uint16_t counter_value); +/* configure counter value, window value, and prescaler divider value */ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler); + +/* enable early wakeup interrupt of WWDGT */ +void wwdgt_interrupt_enable(void); +/* check early wakeup interrupt state of WWDGT */ +FlagStatus wwdgt_flag_get(void); +/* clear early wakeup interrupt state of WWDGT */ +void wwdgt_flag_clear(void); + +#endif /* GD32F1X0_WWDGT_H */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_adc.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_adc.c new file mode 100644 index 0000000..c56ab8a --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_adc.c @@ -0,0 +1,817 @@ +/*! + \file gd32f1x0_adc.c + \brief ADC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_adc.h" + +/*! + \brief ADC reset + \param[in] none + \param[out] none + \retval none +*/ +void adc_deinit(void) +{ + rcu_periph_reset_enable(RCU_ADCRST); + rcu_periph_reset_disable(RCU_ADCRST); +} + +/*! + \brief enable ADC interface + \param[in] none + \param[out] none + \retval none +*/ +void adc_enable(void) +{ + if(RESET == (ADC_CTL1 & ADC_CTL1_ADCON)){ + ADC_CTL1 |= (uint32_t)ADC_CTL1_ADCON; + } +} + +/*! + \brief disable ADC interface + \param[in] none + \param[out] none + \retval none +*/ +void adc_disable(void) +{ + ADC_CTL1 &= (uint32_t)~(ADC_CTL1_ADCON); +} + +/*! + \brief ADC calibration and reset calibration + \param[in] none + \param[out] none + \retval none +*/ +void adc_calibration_enable(void) +{ + /* reset the selected ADC1 calibration registers */ + ADC_CTL1 |= (uint32_t) ADC_CTL1_RSTCLB; + /* check the RSTCLB bit state */ + while((ADC_CTL1 & ADC_CTL1_RSTCLB)){ + } + /* enable ADC calibration process */ + ADC_CTL1 |= ADC_CTL1_CLB; + /* check the CLB bit state */ + while((ADC_CTL1 & ADC_CTL1_CLB)){ + } +} + +/*! + \brief enable DMA request + \param[in] none + \param[out] none + \retval none +*/ +void adc_dma_mode_enable(void) +{ + ADC_CTL1 |= (uint32_t)(ADC_CTL1_DMA); +} + +/*! + \brief disable DMA request + \param[in] none + \param[out] none + \retval none +*/ +void adc_dma_mode_disable(void) +{ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DMA); +} + +/*! + \brief enable ADC0 temperature sensor and Vrefint channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_tempsensor_vrefint_enable(void) +{ + /* enable the temperature sensor and Vrefint channel */ + ADC_CTL1 |= ADC_CTL1_TSVREN; +} + +/*! + \brief disable ADC0 temperature sensor and Vrefint channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_tempsensor_vrefint_disable(void) +{ + /* disable the temperature sensor and Vrefint channel */ + ADC_CTL1 &= ~ADC_CTL1_TSVREN; +} + +/*! + \brief enable the vbat channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_vbat_enable(void) +{ + /* enable the vbat channel */ + ADC_CTL1 |= ADC_CTL1_VBETEN; +} + +/*! + \brief disable the vbat channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_vbat_disable(void) +{ + /* disable the vbat channel */ + ADC_CTL1 &= ~ADC_CTL1_VBETEN; +} + +/*! + \brief adc discontinuous mode config + \param[in] channel_group: select the channel group + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] length: number of conversions in discontinuous mode,the number can be 1..8 + for regular channel ,the number is insignificant for inserted channel + \param[out] none + \retval none +*/ +void adc_discontinuous_mode_config(uint8_t channel_group,uint8_t length) +{ + ADC_CTL0 &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC)); + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + /* config the number of conversions in discontinuous mode */ + ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DISNUM); + ADC_CTL0 |= (uint32_t)(((uint32_t)length - 1U) << 13U); + + ADC_CTL0 |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t)ADC_CTL0_DISIC; + break; + default: + break; + } +} + +/*! + \brief enable or disable ADC special function + \param[in] function: the function to config + one or more parameters can be selected 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 function, ControlStatus newvalue) +{ + if(newvalue){ + if(RESET != (function & ADC_SCAN_MODE)){ + ADC_CTL0 |= ADC_SCAN_MODE; + } + if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){ + ADC_CTL0 |= ADC_INSERTED_CHANNEL_AUTO; + } + if(RESET != (function & ADC_CONTINUOUS_MODE)){ + ADC_CTL1 |= ADC_CONTINUOUS_MODE; + } + }else{ + if(RESET != (function & ADC_SCAN_MODE)){ + ADC_CTL0 &= ~ADC_SCAN_MODE; + } + if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){ + ADC_CTL0 &= ~ADC_INSERTED_CHANNEL_AUTO; + } + if(RESET != (function & ADC_CONTINUOUS_MODE)){ + ADC_CTL1 &= ~ADC_CONTINUOUS_MODE; + } + } +} + +/*! + \brief adc data alignment config + \param[in] data_alignment: data alignment select + only one parameter can be selected + \arg ADC_DATAALIGN_RIGHT: LSB alignment + \arg ADC_DATAALIGN_LEFT: MSB alignment + \param[out] none + \retval none +*/ +void adc_data_alignment_config(uint32_t data_alignment) +{ + if(data_alignment){ + ADC_CTL1 |= ADC_CTL1_DAL; + }else{ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DAL); + } +} + +/*! + \brief config the length of regular channel group or inserted channel group + \param[in] channel_group: select the channel group + only one parameter can be selected + \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-17 + inserted channel 1-4 + \param[out] none + \retval none +*/ +void adc_channel_length_config(uint8_t channel_group,uint32_t length) +{ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_RSQ0 &= ~(((uint32_t)length - 1U) << 20U); + ADC_RSQ0 |= (((uint32_t)length - 1U) << 20U); + break; + case ADC_INSERTED_CHANNEL: + ADC_ISQ &= ~(((uint32_t)length - 1U) << 20U); + ADC_ISQ |= (((uint32_t)length - 1U) << 20U); + break; + default: + break; + } +} + +/*! + \brief ADC regular channel config + \param[in] rank: the regular group sequencer rank,this parameter must be between 0 to 15 + \param[in] channel: the selected ADC channel + \arg ADC_CHANNEL_x(x=0..18): ADC Channelx + \param[in] sample_time: the sample time value + \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles + \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles + \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles + \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles + \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles + \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles + \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles + \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles + \param[out] none + \retval none +*/ +void adc_regular_channel_config(uint8_t rank, uint8_t channel,uint32_t sample_time) +{ + uint32_t rsq,sampt; + +#ifdef GD32F130_150 + if(ADC_CHANNEL_18 == channel){ + channel = ADC_CHANNEL_0; + } +#endif + + /* configure ADC regular sequence */ + if(rank < 6U){ + rsq = ADC_RSQ2; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank))); + rsq |= ((uint32_t)channel << (5U*rank)); + ADC_RSQ2 = rsq; + }else if(rank < 12U){ + rsq = ADC_RSQ1; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U)))); + rsq |= ((uint32_t)channel << (5U*(rank-6U))); + ADC_RSQ1 = rsq; + }else if(rank < 16U){ + rsq = ADC_RSQ0; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U)))); + rsq |= ((uint32_t)channel << (5U*(rank-12U))); + ADC_RSQ0 = rsq; + }else{ + /* illegal parameters */ + } + + /* configure ADC sampling time */ + if(channel < 10U){ + sampt = ADC_SAMPT1; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel))); + sampt |= (uint32_t)(sample_time << (3U*channel)); + ADC_SAMPT1 = sampt; + }else if(channel < 18U){ + sampt = ADC_SAMPT0; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel-10U)))); + sampt |= (uint32_t)(sample_time << (3U*(channel-10U))); + ADC_SAMPT0 = sampt; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief ADC inserted channel config + \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3 + \param[in] channel: the selected ADC channel + \arg ADC_CHANNEL_x(x=0..18): ADC Channelx + \param[in] sample_time: The sample time value + \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles + \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles + \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles + \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles + \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles + \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles + \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles + \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles + \param[out] none + \retval none +*/ +void adc_inserted_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time) +{ + uint8_t inserted_length; + uint32_t isq,sampt; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20, 21); + if(rank < 5U){ + isq = ADC_ISQ; + isq &= ~((uint32_t)(ADC_ISQ_ISQN << (15U - (inserted_length - rank)*5U))); + isq |= ((uint32_t)channel << (15U - (inserted_length - rank)*5U)); + ADC_ISQ = isq; + } + + if(channel < 10U){ + sampt = ADC_SAMPT1; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel))); + sampt |= (uint32_t) sample_time << (3U*channel); + ADC_SAMPT1 = sampt; + }else if(channel < 19U){ + sampt = ADC_SAMPT0; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel-10U)))); + sampt |= ((uint32_t)sample_time << (3U*(channel-10U))); + ADC_SAMPT0 = sampt; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief adc inserted channel offset config + \param[in] inserted_channel : insert channel select + \arg ADC_INSERTED_CHANNEL_0: inserted channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted channel3 + \param[in] offset : the offset data + \param[out] none + \retval the conversion value +*/ +void adc_inserted_channel_offset_config(uint8_t inserted_channel,uint16_t offset) +{ + uint8_t inserted_length; + uint32_t num = 0U; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20U, 21U); + num = 3U - (inserted_length - inserted_channel); + + if(num <= 3U){ + /* calculate the offset of the register */ + num = num * 4U; + /* config the offset of the selected channels */ + REG32((ADC_BASE) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset); + } +} + +/*! + \brief adc external trigger enable + \param[in] adc_channel_group: select the channel group + \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(uint8_t channel_group,ControlStatus newvalue) +{ + if(newvalue){ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_ETERC; + } + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_ETEIC; + } + }else{ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 &= ~ADC_CTL1_ETERC; + } + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 &= ~ADC_CTL1_ETEIC; + } + } +} + +/*! + \brief adc external trigger source config + \param[in] adc_channel_group: select the channel group + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] external_trigger_source: regular or inserted group trigger source + for regular channel: + \arg ADC_EXTTRIG_REGULAR_T0_CH0: external trigger timer 0 CH0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T0_CH1: external trigger timer 0 CH1 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T0_CH2: external trigger timer 0 CH2 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T1_CH1: external trigger timer 1 CH1 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T2_TRGO: external trigger timer 2 TRGO event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T14_CH0: external trigger timer 14 CH0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_EXT_IT11: external trigger extiline 11 select for regular channel + \arg ADC_EXTTRIG_REGULAR_SWRCST: software trigger select for regular channel + for inserted channel: + \arg ADC_EXTTRIG_INSERTED_T0_TRGO: external trigger timer0 TRGO event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T0_CH3: external trigger timer0 CH3 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T1_TRGO: external trigger timer1 TRGO event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T1_CH0: external trigger timer1 CH0 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T2_CH3: external trigger timer2 CH3 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T14_TRGO: external trigger timer14 TRGO event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_EXT_IT15: external interrupt line 15 select for inserted channel + \arg ADC_EXTTRIG_INSERTED_SWRCST: software trigger select for inserted channel + \param[out] none + \retval none +*/ +void adc_external_trigger_source_config(uint8_t channel_group,uint32_t external_trigger_source) +{ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSRC); + ADC_CTL1 |= (uint32_t)external_trigger_source; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSIC); + ADC_CTL1 |= (uint32_t)external_trigger_source; + break; + default: + break; + } +} + +/*! + \brief adc software trigger enable + \param[in] adc_channel_group: select the channel group + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[out] none + \retval none +*/ +void adc_software_trigger_enable(uint8_t channel_group) +{ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_SWRCST; + } + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_SWICST; + } +} + +/*! + \brief adc regular group data register read + \param[in] none + \param[out] none + \retval the conversion value +*/ +uint16_t adc_regular_data_read(void) +{ + return (uint16_t)(ADC_RDATA); +} + +/*! + \brief adc inserted group data register read + \param[in] inserted_channel : insert channel select + \arg ADC_INSERTED_CHANNEL_0: inserted channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted channel3 + \param[out] none + \retval the conversion value +*/ +uint16_t adc_inserted_data_read(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; + break; + case ADC_INSERTED_CHANNEL_1: + idata = ADC_IDATA1; + break; + case ADC_INSERTED_CHANNEL_2: + idata = ADC_IDATA2; + break; + case ADC_INSERTED_CHANNEL_3: + idata = ADC_IDATA3; + break; + default: + idata = 0U; + break; + } + return (uint16_t)idata; +} + +/*! + \brief get the ADC flag bits + \param[in] flag: the adc flag bits + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_flag_get(uint32_t flag) +{ + FlagStatus reval = RESET; + + if(ADC_STAT & flag){ + reval = SET; + } + return reval; + +} + +/*! + \brief clear the ADC status flag + \param[in] flag: the adc flag bits + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \param[out] none + \retval none +*/ +void adc_flag_clear(uint32_t flag) +{ + ADC_STAT &= ~((uint32_t)flag); +} + +/*! + \brief get the ADC interrupt bits + \param[in] flag: the adc interrupt flag + \arg ADC_INT_FLAG_WDE: analog watchdog 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 + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_interrupt_flag_get(uint32_t flag) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + /* check the interrupt bits */ + switch(flag){ + case ADC_INT_FLAG_WDE: + state = ADC_STAT & ADC_STAT_WDE; + if((ADC_CTL0 & ADC_CTL0_WDEIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOC: + state = ADC_STAT & ADC_STAT_EOC; + if((ADC_CTL0 & ADC_CTL0_EOCIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOIC: + state = ADC_STAT & ADC_STAT_EOIC; + if((ADC_CTL0 & ADC_CTL0_EOICIE) && state){ + interrupt_flag = SET; + } + break; + default: + break; + } + + return interrupt_flag; +} + +/*! + \brief clear the ADC interrupt bits + \param[in] adc_interrupt: the adc interrupt bits + \arg ADC_INT_FLAG_WDE: analog watchdog 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 + \param[out] none + \retval none +*/ +void adc_interrupt_flag_clear(uint32_t flag) +{ + ADC_STAT &= ~((uint32_t)flag); +} + +/*! + \brief enable ADC interrupt + \param[in] adc_periph: ADCx, x=0,1,2 + only one among these parameters can be selected + \param[in] interrupt: the adc interrupt + one or more parameters can be selected + \arg ADC_INT_WDE: analog watchdog interrupt + \arg ADC_INT_EOC: end of group conversion interrupt + \arg ADC_INT_EOIC: end of inserted group conversion interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_enable(uint32_t interrupt) +{ + if(RESET != (interrupt & ADC_INT_WDE)){ + ADC_CTL0 |= (uint32_t) ADC_CTL0_WDEIE; + } + + if(RESET != (interrupt & ADC_INT_EOC)){ + ADC_CTL0 |= (uint32_t) ADC_CTL0_EOCIE; + } + + if(RESET != (interrupt & ADC_INT_EOIC)){ + ADC_CTL0 |= (uint32_t) ADC_CTL0_EOICIE; + } +} + +/*! + \brief disable ADC interrupt + \param[in] adc_periph: ADCx,x=0,1,2 + only one among these parameters can be selected + \param[in] interrupt: the adc interrupt flag + one or more parameters can be selected + \arg ADC_INT_WDE: analog watchdog interrupt flag + \arg ADC_INT_EOC: end of group conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_disable(uint32_t interrupt) +{ + if(RESET != (interrupt & ADC_INT_WDE)){ + ADC_CTL0 &= ~(uint32_t) ADC_CTL0_WDEIE; + } + + if(RESET != (interrupt & ADC_INT_EOC)){ + ADC_CTL0 &= ~(uint32_t) ADC_CTL0_EOCIE; + } + + if(RESET != (interrupt & ADC_INT_EOIC)){ + ADC_CTL0 &= ~(uint32_t) ADC_CTL0_EOICIE; + } +} + +/*! + \brief ADC analog watchdog single channel config + \param[in] channel: the selected ADC channel + \arg ADC_CHANNEL_x: ADC Channelx(x=0..18) + \param[out] none + \retval none +*/ +void adc_watchdog_single_channel_enable(uint8_t channel) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); + + ADC_CTL0 |= (uint32_t)channel; + ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); +} + +/*! + \brief adc analog watchdog group channel config + \param[in] adc_channel_group: the channel group use analog watchdog + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group + \param[out] none + \retval none +*/ +void adc_watchdog_group_channel_enable(uint8_t channel_group) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); + /* select the group */ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL0 |= (uint32_t) ADC_CTL0_RWDEN; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t) ADC_CTL0_IWDEN; + break; + case ADC_REGULAR_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN); + break; + default: + break; + } +} + + + +/*! + \brief ADC analog watchdog disable + \param[in] none + \param[out] none + \retval none +*/ +void adc_watchdog_disable(void) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); +} + +/*! + \brief ADC analog watchdog threshold config + \param[in] low_threshold: analog watchdog low threshold + \param[in] high_threshold: analog watchdog high threshold + \param[out] none + \retval none +*/ +void adc_watchdog_threshold_config(uint16_t low_threshold,uint16_t high_threshold) +{ + ADC_WDLT = (uint32_t)low_threshold; + ADC_WDHT = (uint32_t)high_threshold; +} + +#ifdef GD32F170_190 +/*! + \brief adc resolution config + \param[in] resolution: ADC resolution + \arg ADC_RESOLUTION_12B: 12-bit ADC resolution + \arg ADC_RESOLUTION_10B: 10-bit ADC resolution + \arg ADC_RESOLUTION_8B: 8-bit ADC resolution + \arg ADC_RESOLUTION_6B: 6-bit ADC resolution + \param[out] none + \retval none +*/ +void adc_resolution_config(uint32_t resolution) +{ + ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DRES); + ADC_CTL0 |= (uint32_t)resolution; +} + +/*! + \brief adc oversample mode config + \param[in] mode: ADC oversampling mode + \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 + \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 + \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio X2 + \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio X4 + \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio X8 + \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio X16 + \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio X32 + \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio X64 + \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio X128 + \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio X256 + \param[out] none + \retval none +*/ +void adc_oversample_mode_config(uint8_t mode, uint16_t shift,uint8_t ratio) +{ + if(mode){ + ADC_OVSAMPCTL |= (uint32_t)ADC_OVSAMPCTL_TOVS; + }else{ + ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_TOVS); + } + /* config the shift and ratio */ + ADC_OVSAMPCTL &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS)); + ADC_OVSAMPCTL |= ((uint32_t)shift | (uint32_t)ratio); +} + +/*! + \brief enable ADC oversample mode + \param[in] none + \param[out] none + \retval none +*/ +void adc_oversample_mode_enable(void) +{ + ADC_OVSAMPCTL |= ADC_OVSAMPCTL_OVSEN; +} + +/*! + \brief disable ADC oversample mode + \param[in] none + \param[out] none + \retval none +*/ +void adc_oversample_mode_disable(void) +{ + ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN); +} +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_can.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_can.c new file mode 100644 index 0000000..00cc46e --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_can.c @@ -0,0 +1,893 @@ +/*! + \file gd32f1x0_can.c + \brief CAN driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 + +#include "gd32f1x0_can.h" +#include "gd32f1x0.h" + +/*! + \brief deinitialize CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_deinit(uint32_t can_periph) +{ + if(CAN0 == can_periph){ + rcu_periph_reset_enable(RCU_CAN0RST); + rcu_periph_reset_disable(RCU_CAN0RST); + }else{ + rcu_periph_reset_enable(RCU_CAN1RST); + rcu_periph_reset_disable(RCU_CAN1RST); + } +} + +/*! + \brief initialize CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_parameter_init: parameters for CAN initializtion + \arg working_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE + \arg resync_jump_width: CAN_BT_SJW_xTQ(x=1, 2, 3, 4) + \arg time_segment_1: CAN_BT_BS1_xTQ(1..16) + \arg time_segment_2: CAN_BT_BS2_xTQ(1..8) + \arg time_triggered: ENABLE or DISABLE + \arg auto_bus_off_recovery: ENABLE or DISABLE + \arg auto_wake_up: ENABLE or DISABLE + \arg auto_retrans: ENABLE or DISABLE + \arg rec_fifo_overwrite: ENABLE or DISABLE + \arg trans_fifo_order: ENABLE or DISABLE + \arg prescaler: 0x0001 - 0x03FF + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init) +{ + uint32_t timeout = CAN_TIMEOUT; + ErrStatus flag = ERROR; + + /* disable sleep mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; + /* enable initialize mode */ + CAN_CTL(can_periph) |= CAN_CTL_IWMOD; + /* wait ACK */ + while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){ + timeout--; + } + /* check initialize working success */ + if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + flag = ERROR; + }else{ + /* set the bit timing register */ + CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \ + BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \ + BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \ + BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \ + BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U))); + /* time trigger communication mode */ + if(ENABLE == can_parameter_init->time_triggered){ + CAN_CTL(can_periph) |= CAN_CTL_TTC; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_TTC; + } + /* automatic bus-off managment */ + if(ENABLE == can_parameter_init->auto_bus_off_recovery){ + CAN_CTL(can_periph) |= CAN_CTL_ABOR; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_ABOR; + } + /* automatic wakeup mode */ + if(ENABLE == can_parameter_init->auto_wake_up){ + CAN_CTL(can_periph) |= CAN_CTL_AWU; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_AWU; + } + /* automatic retransmission mode */ + if(ENABLE == can_parameter_init->auto_retrans){ + CAN_CTL(can_periph) |= CAN_CTL_ARD; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_ARD; + } + /* receive fifo overwrite mode */ + if(ENABLE == can_parameter_init->rec_fifo_overwrite){ + CAN_CTL(can_periph) |= CAN_CTL_RFOD; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_RFOD; + } + /* transmit fifo order */ + if(ENABLE == can_parameter_init->trans_fifo_order){ + CAN_CTL(can_periph) |= CAN_CTL_TFO; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_TFO; + } + /* disable initialize mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD; + timeout = CAN_TIMEOUT; + /* wait the ACK */ + while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){ + timeout--; + } + /* check exit initialize mode */ + if(CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + flag = SUCCESS; + } + } + return flag; +} + +/*! + \brief initialize CAN filter + \param[in] can_filter_parameter_init: struct for CAN filter initialization + \arg filter_list_high: 0x0000 - 0xFFFF + \arg filter_list_low: 0x0000 - 0xFFFF + \arg filter_mask_high: 0x0000 - 0xFFFF + \arg filter_mask_low: 0x0000 - 0xFFFF + \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1 + \arg filter_number: 0 - 27 + \arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST + \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT + \arg filter_enable: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init) +{ + uint32_t val = 0U; + + val = ((uint32_t)1) << (can_filter_parameter_init->filter_number); + /* filter lock disable */ + CAN_FCTL(CAN0) |= CAN_FCTL_FLD; + /* disable filter */ + CAN_FW(CAN0) &= ~(uint32_t)val; + /* filter 16 bits */ + if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){ + /* set filter 16 bits */ + CAN_FSCFG(CAN0) &= ~(uint32_t)val; + /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */ + CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */ + CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS); + } + /* filter 32 bits */ + if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){ + /* set filter 32 bits */ + CAN_FSCFG(CAN0) |= (uint32_t)val; + /* 32 bits list or first 32 bits list */ + CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + /* 32 bits mask or second 32 bits list */ + CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS); + } + /* filter mode */ + if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){ + /* mask mode */ + CAN_FMCFG(CAN0) &= ~(uint32_t)val; + }else{ + /* list mode */ + CAN_FMCFG(CAN0) |= (uint32_t)val; + } + /* filter FIFO */ + if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){ + /* FIFO0 */ + CAN_FAFIFO(CAN0) &= ~(uint32_t)val; + }else{ + /* FIFO1 */ + CAN_FAFIFO(CAN0) |= (uint32_t)val; + } + /* filter working */ + if(ENABLE == can_filter_parameter_init->filter_enable){ + + CAN_FW(CAN0) |= (uint32_t)val; + } + /* filter lock enable */ + CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; +} + +/*! + \brief set CAN1 fliter start bank number + \param[in] start_bank: CAN1 start bank number + \arg (1..27) + \param[out] none + \retval none +*/ +void can1_filter_start_bank(uint8_t start_bank) +{ + /* filter lock disable */ + CAN_FCTL(CAN0) |= CAN_FCTL_FLD; + /* set CAN1 filter start number */ + CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F; + CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank); + /* filter lock enaable */ + CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; +} + +/*! + \brief enable CAN debug freeze + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_debug_freeze_enable(uint32_t can_periph) +{ + CAN_CTL(can_periph) |= CAN_CTL_DFZ; + + if(CAN0 == can_periph){ + dbg_periph_enable(DBG_CAN0_HOLD); + }else{ + dbg_periph_enable(DBG_CAN1_HOLD); + } +} + +/*! + \brief disable CAN debug freeze + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_debug_freeze_disable(uint32_t can_periph) +{ + CAN_CTL(can_periph) |= CAN_CTL_DFZ; + + if(CAN0 == can_periph){ + dbg_periph_disable(DBG_CAN0_HOLD); + }else{ + dbg_periph_disable(DBG_CAN1_HOLD); + } +} + +/*! + \brief enable CAN time trigger mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_trigger_mode_enable(uint32_t can_periph) +{ + uint8_t mailbox_number; + + /* enable the tcc mode */ + CAN_CTL(can_periph) |= CAN_CTL_TTC; + /* enable time stamp */ + for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){ + CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN; + } +} + +/*! + \brief disable CAN time trigger mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_trigger_mode_disable(uint32_t can_periph) +{ + uint8_t mailbox_number; + + /* disable the TCC mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_TTC; + /* reset TSEN bits */ + for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){ + CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN; + } +} + +/*! + \brief transmit CAN message + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] transmit_message: struct for CAN transmit message + \arg tx_sfid: 0x00000000 - 0x000007FF + \arg tx_efid: 0x00000000 - 0x1FFFFFFF + \arg tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED + \arg tx_ft: CAN_FT_DATA, CAN_FT_REMOTE + \arg tx_dlenc: 1 - 7 + \arg tx_data[]: 0x00 - 0xFF + \param[out] none + \retval mailbox_number +*/ +uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message) +{ + uint8_t mailbox_number = CAN_MAILBOX0; + + /* select one empty mailbox */ + if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){ + mailbox_number = CAN_MAILBOX0; + }else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){ + mailbox_number = CAN_MAILBOX1; + }else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){ + mailbox_number = CAN_MAILBOX2; + }else{ + mailbox_number = CAN_NOMAILBOX; + } + if(CAN_NOMAILBOX == mailbox_number){ + return CAN_NOMAILBOX; + } + + CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN; + if(CAN_FF_STANDARD == transmit_message->tx_ff){ + /* set transmit mailbox standard identifier */ + CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \ + transmit_message->tx_ft); + }else{ + /* set transmit mailbox extended identifier */ + CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \ + transmit_message->tx_ff | \ + transmit_message->tx_ft); + } + /* set the data length */ + CAN_TMP(can_periph, mailbox_number) &= ((uint32_t)~CAN_TMP_DLENC); + CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen; + /* set the data */ + CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \ + TMDATA0_DB2(transmit_message->tx_data[2]) | \ + TMDATA0_DB1(transmit_message->tx_data[1]) | \ + TMDATA0_DB0(transmit_message->tx_data[0]); + CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \ + TMDATA1_DB6(transmit_message->tx_data[6]) | \ + TMDATA1_DB5(transmit_message->tx_data[5]) | \ + TMDATA1_DB4(transmit_message->tx_data[4]); + /* enable transmission */ + CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN; + + return mailbox_number; +} + +/*! + \brief get CAN transmit state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] mailbox_number + \arg CAN_MAILBOX(x=0,1,2) + \param[out] none + \retval can_transmit_state_enum +*/ +can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number) +{ + can_transmit_state_enum state = CAN_TRANSMIT_FAILED; + uint32_t val = 0U; + + switch(mailbox_number){ + case CAN_MAILBOX0: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0); + break; + case CAN_MAILBOX1: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1); + break; + case CAN_MAILBOX2: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2); + break; + default: + val = CAN_TRANSMIT_FAILED; + break; + } + switch(val){ + /* transmit pending */ + case (CAN_STATE_PENDING): + state = CAN_TRANSMIT_PENDING; + break; + /* transmit succeeded */ + case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0): + state = CAN_TRANSMIT_OK; + break; + case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1): + state = CAN_TRANSMIT_OK; + break; + case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2): + state = CAN_TRANSMIT_OK; + break; + default: + state = CAN_TRANSMIT_FAILED; + break; + } + return state; +} + +/*! + \brief stop CAN transmission + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] mailbox_number + only one parameter can be selected which is shown as below: + \arg CAN_MAILBOXx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number) +{ + if(CAN_MAILBOX0 == mailbox_number){ + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0; + }else if(CAN_MAILBOX1 == mailbox_number){ + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1; + }else if(CAN_MAILBOX2 == mailbox_number){ + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief CAN receive message + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + \arg CAN_FIFOx(x=0,1) + \param[out] receive_message: struct for CAN receive message + \arg rx_sfid: 0x00000000 - 0x000007FF + \arg rx_efid: 0x00000000 - 0x1FFFFFFF + \arg rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED + \arg rx_ft: CAN_FT_DATA, CAN_FT_REMOTE + \arg rx_dlenc: 1 - 7 + \arg rx_data[]: 0x00 - 0xFF + \arg rx_fi: 0 - 27 + \retval none +*/ +void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message) +{ + /* get the frame format */ + receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number)); + if(CAN_FF_STANDARD == receive_message->rx_ff){ + /* get standard identifier */ + receive_message -> rx_sfid = (uint32_t)(RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number))); + }else{ + /* get extended identifier */ + receive_message -> rx_efid = (uint32_t)(RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number))); + } + + /* get frame type */ + receive_message -> rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number)); + /* get recevie data length */ + receive_message -> rx_dlen = (uint8_t)(RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number))); + /* filtering index */ + receive_message -> rx_fi = (uint8_t)(RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number))); + + /* receive data */ + receive_message -> rx_data[0] = (uint8_t)(RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[1] = (uint8_t)(RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[2] = (uint8_t)(RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[3] = (uint8_t)(RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[4] = (uint8_t)(RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[5] = (uint8_t)(RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[6] = (uint8_t)(RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[7] = (uint8_t)(RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number))); + + /* release FIFO */ + if(CAN_FIFO0 == fifo_number){ + CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0; + }else{ + CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1; + } +} + +/*! + \brief release FIFO0 + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + \arg CAN_FIFOx(x=0,1) + \param[out] none + \retval none +*/ +void can_fifo_release(uint32_t can_periph, uint8_t fifo_number) +{ + if(CAN_FIFO0 == fifo_number){ + CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0; + }else if(CAN_FIFO1 == fifo_number){ + CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief CAN receive message length + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + \arg CAN_FIFOx(x=0,1) + \param[out] none + \retval message length +*/ +uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number) +{ + uint8_t val = 0U; + + if(CAN_FIFO0 == fifo_number){ + val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK); + }else if(CAN_FIFO1 == fifo_number){ + val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK); + }else{ + /* illegal parameters */ + } + return val; +} + +/*! + \brief set CAN working mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_working_mode + \arg CAN_MODE_INITIALIZE + \arg CAN_MODE_NORMAL + \arg CAN_MODE_SLEEP + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode) +{ + ErrStatus flag = ERROR; + /* timeout for IWS or also for SLPWS bits */ + uint32_t timeout = CAN_TIMEOUT; + + if(CAN_MODE_INITIALIZE == working_mode){ + /* disable sleep mode */ + CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD); + /* set initialize mode */ + CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD; + /* wait the acknowledge */ + while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){ + timeout--; + } + if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + }else if(CAN_MODE_NORMAL == working_mode){ + /* enter normal mode */ + CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD); + /* wait the acknowledge */ + while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)){ + timeout--; + } + if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + }else if(CAN_MODE_SLEEP == working_mode){ + /* disable initialize mode */ + CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD); + /* set sleep mode */ + CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD; + /* wait the acknowledge */ + while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)){ + timeout--; + } + if(CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + }else{ + flag = ERROR; + } + return flag; +} + +/*! + \brief wake up CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus can_wakeup(uint32_t can_periph) +{ + ErrStatus flag = ERROR; + uint32_t timeout = CAN_TIMEOUT; + + /* wakeup */ + CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; + + while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)){ + timeout--; + } + if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + return flag; +} + +/*! + \brief get CAN error type + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval can_error_enum +*/ +can_error_enum can_error_get(uint32_t can_periph) +{ + can_error_enum error; + error = CAN_ERROR_NONE; + + /* get error type */ + error = (can_error_enum)((CAN_ERR(can_periph) & CAN_ERR_ERRN) >> 4U); + return error; +} + +/*! + \brief get CAN receive error number + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval error number +*/ +uint8_t can_receive_error_number_get(uint32_t can_periph) +{ + uint8_t val; + + val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_RECNT) >> 24U); + return val; +} + +/*! + \brief get CAN transmit error number + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval error number +*/ +uint8_t can_transmit_error_number_get(uint32_t can_periph) +{ + uint8_t val; + + val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_TECNT) >> 16U); + return val; +} + +/*! + \brief enable CAN interrupt + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] interrupt + \arg CAN_INT_TME: transmit mailbox empty interrupt enable + \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable + \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable + \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable + \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable + \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable + \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable + \arg CAN_INT_WERR: warning error interrupt enable + \arg CAN_INT_PERR: passive error interrupt enable + \arg CAN_INT_BO: bus-off interrupt enable + \arg CAN_INT_ERRN: error number interrupt enable + \arg CAN_INT_ERR: error interrupt enable + \arg CAN_INT_WU: wakeup interrupt enable + \arg CAN_INT_SLPW: sleep working interrupt enable + \param[out] none + \retval none +*/ +void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt) +{ + CAN_INTEN(can_periph) |= interrupt; +} + +/*! + \brief disable CAN interrupt + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] interrupt + \arg CAN_INT_TME: transmit mailbox empty interrupt enable + \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable + \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable + \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable + \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable + \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable + \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable + \arg CAN_INT_WERR: warning error interrupt enable + \arg CAN_INT_PERR: passive error interrupt enable + \arg CAN_INT_BO: bus-off interrupt enable + \arg CAN_INT_ERRN: error number interrupt enable + \arg CAN_INT_ERR: error interrupt enable + \arg CAN_INT_WU: wakeup interrupt enable + \arg CAN_INT_SLPW: sleep working interrupt enable + \param[out] none + \retval none +*/ +void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt) +{ + CAN_INTEN(can_periph) &= ~interrupt; +} + +/*! + \brief get CAN flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_MTE2: mailbox 2 transmit error + \arg CAN_FLAG_MTE1: mailbox 1 transmit error + \arg CAN_FLAG_MTE0: mailbox 0 transmit error + \arg CAN_FLAG_MTF2: mailbox 2 transmit finished + \arg CAN_FLAG_MTF1: mailbox 1 transmit finished + \arg CAN_FLAG_MTF0: mailbox 0 transmit finished + \arg CAN_FLAG_RFO0: receive FIFO0 overfull + \arg CAN_FLAG_RFF0: receive FIFO0 full + \arg CAN_FLAG_RFO1: receive FIFO1 overfull + \arg CAN_FLAG_RFF1: receive FIFO1 full + \arg CAN_FLAG_BOERR: bus-off error + \arg CAN_FLAG_PERR: passive error + \arg CAN_FLAG_WERR: warning error + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag) +{ + if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CAN flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_MTE2: mailbox 2 transmit error + \arg CAN_FLAG_MTE1: mailbox 1 transmit error + \arg CAN_FLAG_MTE0: mailbox 0 transmit error + \arg CAN_FLAG_MTF2: mailbox 2 transmit finished + \arg CAN_FLAG_MTF1: mailbox 1 transmit finished + \arg CAN_FLAG_MTF0: mailbox 0 transmit finished + \arg CAN_FLAG_RFO0: receive FIFO0 overfull + \arg CAN_FLAG_RFF0: receive FIFO0 full + \arg CAN_FLAG_RFO1: receive FIFO1 overfull + \arg CAN_FLAG_RFF1: receive FIFO1 full + \param[out] none + \retval none +*/ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag) +{ + CAN_REG_VAL(can_periph, flag) |= BIT(CAN_BIT_POS(flag)); +} + +/*! + \brief get CAN interrupt flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering + \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode + \arg CAN_INT_FLAG_ERRIF: error interrupt flag + \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag + \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag + \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag + \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag + \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag) +{ + FlagStatus ret1 = RESET; + FlagStatus ret2 = RESET; + + /* get the staus of interrupt flag */ + ret1 = (FlagStatus)(CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag))); + /* get the staus of interrupt enale bit */ + ret2 = (FlagStatus)(CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag))); + if(ret1 && ret2){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CAN interrupt flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering + \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode + \arg CAN_INT_FLAG_ERRIF: error interrupt flag + \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag + \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag + \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag + \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag + \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag + \param[out] none + \retval none +*/ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag) +{ + CAN_REG_VALS(can_periph, flag) |= BIT(CAN_BIT_POS0(flag)); +} + +/*! + \brief enable CAN phy + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_phy_enable(uint32_t can_periph) +{ + CAN_PHYCTL(can_periph) |= CAN_PHYCTL_PHYEN; +} + +/*! + \brief disable CAN phy + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_phy_disable(uint32_t can_periph) +{ + CAN_PHYCTL(can_periph) &= ~CAN_PHYCTL_PHYEN; +} + +/*! + \brief set CAN phy mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_phy_mode + \arg CAN_PHYMODE_LOW_SLOPE + \arg CAN_PHYMODE_MIDDLE_SLOPE + \arg CAN_PHYMODE_HIGH_SLOPE + \arg CAN_PHYMODE_HIGH_SPEED + \param[out] none + \retval none +*/ +void can_phy_mode(uint32_t can_periph, uint32_t phy_mode) +{ + CAN_PHYCTL(can_periph) &= (~CAN_PHYCTL_POMODE_MASK); + switch(phy_mode){ + case CAN_PHYCTL_POMODE_0: + /*!< CAN PHY low slope mode */ + CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_0; + break; + case CAN_PHYCTL_POMODE_1: + /*!< CAN PHY middle slope mode */ + CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_1; + break; + case CAN_PHYCTL_POMODE_2: + /*!< CAN PHY high slope mode */ + CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_2; + break; + case CAN_PHYCTL_POMODE_3: + /*!< CAN PHY high speed mode */ + CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_3; + break; + default: + break; + } +} + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cec.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cec.c new file mode 100644 index 0000000..bf3d296 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cec.c @@ -0,0 +1,452 @@ +/*! + \file gd32f1x0_cec.c + \brief CEC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_cec.h" +#include "gd32f1x0_rcu.h" + +/*! + \brief reset HDMI-CEC controller + \param[in] none + \param[out] none + \retval none +*/ +void cec_deinit(void) +{ + rcu_periph_reset_enable(RCU_CECRST); + rcu_periph_reset_disable(RCU_CECRST); +} + +/*! + \brief configure signal free time,the signal free time counter start option,own address + \param[in] sftmopt: signal free time counter start option + \arg CEC_SFT_START_STAOM: signal free time counter starts counting when STAOM is asserted + \arg CEC_SFT_START_LAST: signal free time counter starts automatically after transmission/reception end + \param[in] sft: signal free time + \arg CEC_SFT_PROTOCOL_PERIOD: the signal free time will perform as HDMI-CEC protocol description + \arg CEC_SFT_1POINT5_PERIOD: 1.5 nominal data bit periods + \arg CEC_SFT_2POINT5_PERIOD: 2.5 nominal data bit periods + \arg CEC_SFT_3POINT5_PERIOD: 3.5 nominal data bit periods + \arg CEC_SFT_4POINT5_PERIOD: 4.5 nominal data bit periods + \arg CEC_SFT_5POINT5_PERIOD: 5.5 nominal data bit periods + \arg CEC_SFT_6POINT5_PERIOD: 6.5 nominal data bit periods + \arg CEC_SFT_7POINT5_PERIOD: 7.5 nominal data bit periods + \param[in] address: own address + \arg CEC_OWN_ADDRESS_CLEAR: own address is cleared + \arg CEC_OWN_ADDRESSx(x=0..14): own address is x + \param[out] none + \retval none +*/ +void cec_init(uint32_t sftopt, uint32_t sft, uint32_t address) +{ + uint32_t cfg; + cfg = CEC_CFG; + /* clear SFTOPT bit,SFT[2:0] */ + cfg &= ~(CEC_CFG_SFTOPT | CEC_CFG_SFT); + /* assign SFTOPT bit,SFT[2:0] */ + cfg |= (sftopt | sft); + CEC_CFG = cfg; + if(CEC_OWN_ADDRESS_CLEAR == address){ + CEC_CFG &= ~CEC_CFG_OAD; + }else{ + CEC_CFG |= address; + } +} + +/*! + \brief configure generate Error-bit when detected some abnormal situation or not, + whether stop receive message when detected bit rising error + \param[in] broadcast: + \arg CEC_BROADCAST_ERROR_BIT_ON:generate Error-bit in broadcast + \arg CEC_BROADCAST_ERROR_BIT_OFF:do not generate Error-bit in broadcast + \param[in] singlecast_lbpe: + \arg CEC_LONG_PERIOD_ERROR_BIT_ON:generate Error-bit on long bit period error + \arg CEC_LONG_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on long bit period error + \param[in] singlecast_bre: + \arg CEC_RISING_PERIOD_ERROR_BIT_ON:generate Error-bit on bit rising error + \arg CEC_RISING_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on bit rising error + \param[in] rxbrestp: + \arg CEC_STOP_RISING_ERROR_BIT_ON: stop reception when detected bit rising error + \arg CEC_STOP_RISING_ERROR_BIT_OFF: do not stop reception when detected bit rising error + \param[out] none + \retval none +*/ +void cec_error_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre, uint32_t rxbrestp) +{ + uint32_t cfg; + cfg = CEC_CFG; + /* clear BCNG bit, BPLEG bit, BREG bit */ + cfg &= ~(CEC_CFG_BCNG | CEC_CFG_BPLEG | CEC_CFG_BREG); + /* assign BCNG bit, BPLEG bit, BREG bit */ + cfg |= (broadcast | singlecast_lbpe | singlecast_bre); + CEC_CFG = cfg; + if(CEC_STOP_RISING_ERROR_BIT_ON == rxbrestp){ + CEC_CFG |= CEC_CFG_BRES; + }else{ + CEC_CFG &= ~CEC_CFG_BRES; + } +} + +/*! + \brief enable HDMI-CEC controller + \param[in] none + \param[out] none + \retval none +*/ +void cec_enable(void) +{ + CEC_CTL |= CEC_CTL_CECEN; +} + +/*! + \brief disable HDMI-CEC controller + \param[in] none + \param[out] none + \retval none +*/ +void cec_disable(void) +{ + CEC_CTL &= ~CEC_CTL_CECEN; +} + +/*! + \brief start CEC message transmission + \param[in] none + \param[out] none + \retval none +*/ +void cec_transmission_start(void) +{ + CEC_CTL |= CEC_CTL_STAOM; +} + +/*! + \brief end CEC message transmission + \param[in] none + \param[out] none + \retval none +*/ +void cec_transmission_end(void) +{ + CEC_CTL |= CEC_CTL_ENDOM; +} + +/*! + \brief enable CEC listen mode. + \param[in] none + \param[out] none + \retval none +*/ +void cec_listen_mode_enable(void) +{ + CEC_CFG |= CEC_CFG_LMEN; +} + +/*! + \brief disable CEC listen mode. + \param[in] none + \param[out] none + \retval none +*/ +void cec_listen_mode_disable(void) +{ + CEC_CFG &= ~CEC_CFG_LMEN; +} + +/*! + \brief configure and clear own address.the controller can be configured to multiple own address + \param[in] address: own address + \arg CEC_OWN_ADDRESS_CLEAR: own address is cleared + \arg CEC_OWN_ADDRESSx(x=0..14): own address is x + \param[out] none + \retval none +*/ +void cec_own_address_config(uint32_t address) +{ + if(CEC_OWN_ADDRESS_CLEAR == address){ + CEC_CFG &= ~CEC_CFG_OAD; + } else { + CEC_CFG |= address; + } +} + +/*! + \brief configure signal free time and the signal free time counter start option + \param[in] sftopt: signal free time counter start option + \arg CEC_SFT_START_STAOM: signal free time counter starts counting when STAOM is asserted + \arg CEC_SFT_START_LAST: signal free time counter starts automatically after transmission/reception end + \param[in] sft: signal free time + \arg CEC_SFT_PROTOCOL_PERIOD: the signal free time will perform as HDMI-CEC protocol description + \arg CEC_SFT_1POINT5_PERIOD: 1.5 nominal data bit periods + \arg CEC_SFT_2POINT5_PERIOD: 2.5 nominal data bit periods + \arg CEC_SFT_3POINT5_PERIOD: 3.5 nominal data bit periods + \arg CEC_SFT_4POINT5_PERIOD: 4.5 nominal data bit periods + \arg CEC_SFT_5POINT5_PERIOD: 5.5 nominal data bit periods + \arg CEC_SFT_6POINT5_PERIOD: 6.5 nominal data bit periods + \arg CEC_SFT_7POINT5_PERIOD: 7.5 nominal data bit periods + \param[out] none + \retval none +*/ +void cec_sft_config(uint32_t sftopt, uint32_t sft) +{ + uint32_t cfg; + cfg = CEC_CFG; + /* clear SFTOPT bit,SFT[2:0] */ + cfg &= ~(CEC_CFG_SFTOPT | CEC_CFG_SFT); + /* assign SFTOPT bit,SFT[2:0] */ + cfg |= (sftopt | sft); + CEC_CFG = cfg; +} + +/*! + \brief configure generate Error-bit when detected some abnormal situation or not + \param[in] broadcast: + \arg CEC_BROADCAST_ERROR_BIT_ON:generate Error-bit in broadcast + \arg CEC_BROADCAST_ERROR_BIT_OFF:do not generate Error-bit in broadcast + \param[in] singlecast_lbpe: + \arg CEC_LONG_PERIOD_ERROR_BIT_ON:generate Error-bit on long bit period error + \arg CEC_LONG_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on long bit period error + \param[in] singlecast_bre: + \arg CEC_RISING_PERIOD_ERROR_BIT_ON:generate Error-bit on bit rising error + \arg CEC_RISING_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on bit rising error + \param[out] none + \retval none +*/ +void cec_generate_errorbit_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre) +{ + uint32_t cfg; + cfg = CEC_CFG; + /* clear BCNG bit, BPLEG bit, BREG bit */ + cfg &= ~(CEC_CFG_BCNG | CEC_CFG_BPLEG | CEC_CFG_BREG); + /* assign BCNG bit, BPLEG bit, BREG bit */ + cfg |= (broadcast | singlecast_lbpe | singlecast_bre); + CEC_CFG = cfg; +} + +/*! + \brief whether stop receive message when detected bit rising error + \param[in] rxbrestp: + \arg CEC_STOP_RISING_ERROR_BIT_ON: stop reception when detected bit rising error + \arg CEC_STOP_RISING_ERROR_BIT_OFF: do not stop reception when detected bit rising error + \param[out] none + \retval none +*/ +void cec_stop_receive_bre_config(uint32_t rxbrestp) +{ + if(CEC_STOP_RISING_ERROR_BIT_ON == rxbrestp){ + CEC_CFG |= CEC_CFG_BRES; + } else { + CEC_CFG &= ~CEC_CFG_BRES; + } +} + +/*! + \brief enable reception bit timing tolerance + \param[in] none + \param[out] none + \retval none +*/ +void cec_reception_tolerance_enable(void) +{ + CEC_CFG |= CEC_CFG_RTOL; +} + +/*! + \brief disable reception bit timing tolerance + \param[in] none + \param[out] none + \retval none +*/ +void cec_reception_tolerance_disable(void) +{ + CEC_CFG &= ~CEC_CFG_RTOL; +} + +/*! + \brief send a data by the CEC peripheral + \param[in] data: the data to transmit + \param[out] none + \retval none +*/ +void cec_data_send(uint8_t data) +{ + CEC_TDATA = (uint32_t)data; +} + +/*! + \brief receive a data by the CEC peripheral + \param[in] data: the data to receive + \param[out] none + \retval none +*/ +uint8_t cec_data_receive(void) +{ + return (uint8_t)CEC_RDATA; +} + +/*! + \brief get CEC int flag + \param[in] flag: specify which flag + \arg CEC_INT_FLAG_BR: Rx-byte data received + \arg CEC_INT_FLAG_REND: end of reception + \arg CEC_INT_FLAG_RO: RX overrun + \arg CEC_INT_FLAG_BRE: bit rising error + \arg CEC_INT_FLAG_BPSE: short bit period error + \arg CEC_INT_FLAG_BPLE: long bit period error + \arg CEC_INT_FLAG_RAE: Rx ACK error + \arg CEC_INT_FLAG_ARBF: arbitration lost + \arg CEC_INT_FLAG_TBR: Tx-byte data request + \arg CEC_INT_FLAG_TEND: transmission successfully end + \arg CEC_INT_FLAG_TU: Tx data buffer underrun + \arg CEC_INT_FLAG_TERR: Tx-error + \arg CEC_INT_FLAG_TAERR: Tx ACK error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus cec_interrupt_flag_get(uint32_t flag) +{ + uint32_t interrupt_enable = 0U,interrupt_flag = 0U; + interrupt_flag = (CEC_INTF & flag); + interrupt_enable = (CEC_INTEN & flag); + if(interrupt_flag && interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CEC int flag and status + \param[in] flag: specify which flag + \arg CEC_INT_FLAG_BR: Rx-byte data received + \arg CEC_INT_FLAG_REND: end of reception + \arg CEC_INT_FLAG_RO: RX overrun + \arg CEC_INT_FLAG_BRE: bit rising error + \arg CEC_INT_FLAG_BPSE: short bit period error + \arg CEC_INT_FLAG_BPLE: long bit period error + \arg CEC_INT_FLAG_RAE: Rx ACK error + \arg CEC_INT_FLAG_ARBF: arbitration lost + \arg CEC_INT_FLAG_TBR: Tx-byte data request + \arg CEC_INT_FLAG_TEND: transmission successfully end + \arg CEC_INT_FLAG_TU: Tx data buffer underrun + \arg CEC_INT_FLAG_TERR: Tx-error + \arg CEC_INT_FLAG_TAERR: Tx ACK error flag + \param[out] none + \retval none +*/ +void cec_interrupt_flag_clear(uint32_t flag) +{ + CEC_INTF = flag; +} + +/*! + \brief enable interrupt + \param[in] flag: specify which flag + \arg CEC_INT_BR: enable Rx-byte data received interrupt + \arg CEC_INT_REND: enable end of reception interrupt + \arg CEC_INT_RO: enable RX overrun interrupt + \arg CEC_INT_BRE: enable bit rising error interrupt + \arg CEC_INT_BPSE: enable short bit period error interrupt + \arg CEC_INT_BPLE: enable long bit period error interrupt + \arg CEC_INT_RAE: enable Rx ACK error interrupt + \arg CEC_INT_ARBF: enable arbitration lost interrupt + \arg CEC_INT_TBR: enable Tx-byte data request interrupt + \arg CEC_INT_TEND: enable transmission successfully end interrupt + \arg CEC_INT_TU: enable Tx data buffer underrun interrupt + \arg CEC_INT_TERR: enable Tx-error interrupt + \arg CEC_INT_TAERR: enable Tx ACK error interrupt + \param[out] none + \retval none +*/ +void cec_interrupt_enable(uint32_t flag) +{ + CEC_INTEN |= flag; +} + +/*! + \brief disable interrupt + \param[in] flag: specify which flag + \arg CEC_INT_BR: disable Rx-byte data received interrupt + \arg CEC_INT_REND: disable end of reception interrupt + \arg CEC_INT_RO: disable RX overrun interrupt + \arg CEC_INT_BRE: disable bit rising error interrupt + \arg CEC_INT_BPSE: disable short bit period error interrupt + \arg CEC_INT_BPLE: disable long bit period error interrupt + \arg CEC_INT_RAE: disable Rx ACK error interrupt + \arg CEC_INT_ARBF: disable arbitration lost interrupt + \arg CEC_INT_TBR: disable Tx-byte data request interrupt + \arg CEC_INT_TEND: disable transmission successfully end interrupt + \arg CEC_INT_TU: disable Tx data buffer underrun interrupt + \arg CEC_INT_TERR: disable Tx-error interrupt + \arg CEC_INT_TAERR: disable Tx ACK error interrupt + + \param[out] none + \retval none +*/ +void cec_interrupt_disable(uint32_t flag) +{ + CEC_INTEN &= ~flag; +} + +/*! + \brief get CEC status + \param[in] flag: specify which flag + \arg CEC_FLAG_BR: Rx-byte data received + \arg CEC_FLAG_REND: end of reception + \arg CEC_FLAG_RO: RX overrun + \arg CEC_FLAG_BRE: bit rising error + \arg CEC_FLAG_BPSE: short bit period error + \arg CEC_FLAG_BPLE: long bit period error + \arg CEC_FLAG_RAE: Rx ACK error + \arg CEC_FLAG_ARBF: arbitration lost + \arg CEC_FLAG_TBR: Tx-byte data request + \arg CEC_FLAG_TEND: transmission successfully end + \arg CEC_FLAG_TU: Tx data buffer underrun + \arg CEC_FLAG_TERR: Tx-error + \arg CEC_FLAG_TAERR Tx ACK error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus cec_flag_get(uint32_t flag) +{ + if(CEC_INTF & flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CEC status + \param[in] flag: specify which flag + \arg CEC_FLAG_BR: Rx-byte data received + \arg CEC_FLAG_REND: end of reception + \arg CEC_FLAG_RO: RX overrun + \arg CEC_FLAG_BRE: bit rising error + \arg CEC_FLAG_BPSE: short bit period error + \arg CEC_FLAG_BPLE: long bit period error + \arg CEC_FLAG_RAE: Rx ACK error + \arg CEC_FLAG_ARBF: arbitration lost + \arg CEC_FLAG_TBR: Tx-byte data request + \arg CEC_FLAG_TEND: transmission successfully end + \arg CEC_FLAG_TU: Tx data buffer underrun + \arg CEC_FLAG_TERR: Tx-error + \arg CEC_FLAG_TAERR Tx ACK error flag + + \param[out] none + \retval FlagStatus: SET or RESET +*/ +void cec_flag_clear(uint32_t flag) +{ + CEC_INTF |= flag; +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cmp.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cmp.c new file mode 100644 index 0000000..5a866da --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cmp.c @@ -0,0 +1,244 @@ +/*! + \file gd32f1x0_cmp.c + \brief CMP driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5,9) +*/ + +#include "gd32f1x0_cmp.h" + +/*! + \brief deinitialize comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_deinit(void) +{ + CMP_CS = ((uint32_t)0x00000000); +} + +/*! + \brief initialize comparator mode + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] cmp_operating_mode + \arg CMP_HIGHSPEED: high speed mode + \arg CMP_MIDDLESPEED: medium speed mode + \arg CMP_LOWSPEED: low speed mode + \arg CMP_VERYLOWSPEED: very-low speed mode + \param[in] cmp_inverting_input + \arg CMP_1_4VREFINT: VREFINT *1/4 input + \arg CMP_1_2VREFINT: VREFINT *1/2 input + \arg CMP_3_4VREFINT: VREFINT *3/4 input + \arg CMP_VREFINT: VREFINT input + \arg CMP_DAC: PA4 (DAC) input + \arg CMP_PA5: PA5 input + \arg CMP_PA_0_2: PA0 or PA2 input + \param[in] cmp_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(uint32_t cmp_periph, operating_mode_enum cmp_operating_mode, inverting_input_enum cmp_inverting_input, cmp_hysteresis_enum output_hysteresis) +{ + if(CMP0 == cmp_periph){ + /* initialize comparator 0 mode */ + CMP_CS |= CS_CMP0M(cmp_operating_mode) | CS_CMP0MSEL(cmp_inverting_input) | CS_CMP0HST(output_hysteresis); + }else{ + /* initialize comparator 1 mode */ + CMP_CS |= CS_CMP1M(cmp_operating_mode) | CS_CMP1MSEL(cmp_inverting_input) | CS_CMP1HST(output_hysteresis); + } +} + +/*! + \brief initialize comparator output + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] cmp_output + \arg CMP_OUTPUT_NONE: output no selection + \arg CMP_OUTPUT_TIMER0BKIN: TIMER 0 break input + \arg CMP_OUTPUT_TIMER0IC0: TIMER 0 channel0 input capture + \arg CMP_OUTPUT_TIMER0OCPRECLR: TIMER 0 OCPRE_CLR input + \arg CMP_OUTPUT_TIMER1IC3: TIMER 1 channel3 input capture + \arg CMP_OUTPUT_TIMER1OCPRECLR: TIMER 1 OCPRE_CLR input + \arg CMP_OUTPUT_TIMER2IC0: TIMER 2 channel0 input capture + \arg CMP_OUTPUT_TIMER2OCPRECLR: TIMER 2 OCPRE_CLR input + \param[in] cmp_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(uint32_t cmp_periph, cmp_output_enum cmp_output_slection, uint32_t cmp_output_polarity) +{ + /* initialize comparator 0 output */ + if(CMP0 == cmp_periph){ + CMP_CS |= CS_CMP0OSEL(cmp_output_slection); + /* output polarity */ + if(CMP_OUTPUT_POLARITY_INVERTED == cmp_output_polarity){ + CMP_CS |= CMP_CS_CMP0PL; + }else{ + CMP_CS &= ~CMP_CS_CMP0PL; + } + }else{ + CMP_CS |= CS_CMP1OSEL(cmp_output_slection); + + if(CMP_OUTPUT_POLARITY_INVERTED == cmp_output_polarity){ + CMP_CS |= CMP_CS_CMP1PL; + }else{ + CMP_CS &= ~CMP_CS_CMP1PL; + } + } +} + +/*! + \brief enable comparator + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_enable(uint32_t cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP_CS |= CMP_CS_CMP0EN; + }else{ + CMP_CS |= CMP_CS_CMP1EN; + } +} + +/*! + \brief disable comparator + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_disable(uint32_t cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP_CS &= ~CMP_CS_CMP0EN; + }else{ + CMP_CS &= ~CMP_CS_CMP1EN; + } +} + +/*! + \brief enable comparator switch + \param[in] none + \param[out] none + \retval none +*/ +void cmp_switch_enable(void) +{ + CMP_CS |= CMP_CS_CMP0SW; +} + +/*! + \brief disable comparator switch + \param[in] none + \param[out] none + \retval none +*/ +void cmp_switch_disable(void) +{ + CMP_CS &= ~CMP_CS_CMP0SW; +} + + + +/*! + \brief enable the window mode + \param[in] none + \param[out] none + \retval none +*/ +void cmp_window_enable(void) +{ + CMP_CS |= CMP_CS_WNDEN; +} + +/*! + \brief disable the window mode + \param[in] none + \param[out] none + \retval none +*/ +void cmp_window_disable(void) +{ + CMP_CS &= ~CMP_CS_WNDEN; +} + +/*! + \brief lock the comparator + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_lock_enable(uint32_t cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP_CS |= CMP_CS_CMP0LK; + }else{ + CMP_CS |= CMP_CS_CMP1LK; + } +} + +/*! + \brief unlock the comparator + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_lock_disable(uint32_t cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP_CS &= ~CMP_CS_CMP0LK; + }else{ + CMP_CS &= ~CMP_CS_CMP1LK; + } +} + +/*! + \brief get output level + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval the output level +*/ +uint32_t cmp_output_level_get(uint32_t cmp_periph) +{ + if(CMP0 == cmp_periph){ + if(CMP_CS & CMP_CS_CMP0O){ + return CMP_OUTPUTLEVEL_HIGH; + }else{ + return CMP_OUTPUTLEVEL_LOW; + } + }else{ + if(CMP_CS & CMP_CS_CMP1O){ + return CMP_OUTPUTLEVEL_HIGH; + }else{ + return CMP_OUTPUTLEVEL_LOW; + } + } +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_crc.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_crc.c new file mode 100644 index 0000000..9528362 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_crc.c @@ -0,0 +1,155 @@ +/*! + \file gd32f1x0_crc.c + \brief CRC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_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_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 initializaiton 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 initializaiton 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 + \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 CRC calculate a 32-bit data + \param[in] sdata: specify 32-bit data + \param[out] none + \retval 32-bit CRC calculate value +*/ +uint32_t crc_single_data_calculate(uint32_t sdata) +{ + CRC_DATA = sdata; + return (CRC_DATA); +} + +/*! + \brief CRC calculate a 32-bit data array + \param[in] array: pointer to an array of 32 bit data words + \param[in] size: size of the array + \param[out] none + \retval 32-bit CRC calculate value +*/ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size) +{ + uint32_t index; + for(index = 0U; index < size; index++){ + CRC_DATA = array[index]; + } + return (CRC_DATA); +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dac.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dac.c new file mode 100644 index 0000000..a82e9e3 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dac.c @@ -0,0 +1,792 @@ +/*! + \file gd32f1x0_dac.c + \brief DAC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + +#include "gd32f1x0_dac.h" + +/*! + \brief deinit 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 DAC0 + \param[in] none + \param[out] none + \retval none +*/ +void dac0_enable(void) +{ + DAC_CTL |= DAC_CTL_DEN0; +} + +/*! + \brief disable DAC0 + \param[in] none + \param[out] none + \retval none +*/ +void dac0_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DEN0; +} + +/*! + \brief enable DAC0 DMA + \param[in] none + \param[out] none + \retval none +*/ +void dac0_dma_enable(void) +{ + DAC_CTL |= DAC_CTL_DDMAEN0; +} + +/*! + \brief disable DAC0 DMA + \param[in] none + \param[out] none + \retval none +*/ +void dac0_dma_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DDMAEN0; +} + +/*! + \brief enable DAC0 output buffer + \param[in] none + \param[out] none + \retval none +*/ +void dac0_output_buffer_enable(void) +{ + DAC_CTL &= ~DAC_CTL_DBOFF0; +} + +/*! + \brief disable DAC0 output buffer + \param[in] none + \param[out] none + \retval none +*/ +void dac0_output_buffer_disable(void) +{ + DAC_CTL |= DAC_CTL_DBOFF0; +} + +/*! + \brief enable DAC0 trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac0_trigger_enable(void) +{ + DAC_CTL |= DAC_CTL_DTEN0; +} + +/*! + \brief disable DAC0 trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac0_trigger_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DTEN0; +} + +/*! + \brief enable DAC0 software trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac0_software_trigger_enable(void) +{ + DAC_SWT |= DAC_SWT_SWTR0; +} + +/*! + \brief disable DAC0 software trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac0_software_trigger_disable(void) +{ + DAC_SWT &= ~DAC_SWT_SWTR0; +} + +/*! + \brief enable DAC0 interrupt(DAC0 DMA underrun interrupt) + \param[in] none + \param[out] none + \retval none +*/ +void dac0_interrupt_enable(void) +{ + DAC_CTL |= DAC_CTL_DDUDRIE0; +} + +/*! + \brief disable DAC0 interrupt(DAC0 DMA underrun interrupt) + \param[in] none + \param[out] none + \retval none +*/ +void dac0_interrupt_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DDUDRIE0; +} + +/*! + \brief set DAC0 tgigger source + \param[in] triggersource: external triggers of DAC + \arg DAC_TRIGGER_T1_TRGO: trigger source is timer1 trgo + \arg DAC_TRIGGER_T2_TRGO: trigger source is timer2 trgo + \arg DAC_TRIGGER_T5_TRGO: trigger source is timer5 trgo + \arg DAC_TRIGGER_T14_TRGO: trigger source is timer14 trgo + \arg DAC_TRIGGER_EXTI_IT9: trigger source is exti interrupt line 9 + \arg DAC_TRIGGER_SOFTWARE: trigger source is software + \param[out] none + \retval none +*/ +void dac0_trigger_source_config(uint32_t triggersource) +{ + DAC_CTL &= ~DAC_CTL_DTSEL0; + DAC_CTL |= triggersource; +} + +/*! + \brief get the last data output value of DAC0 + \param[in] none + \param[out] none + \retval DAC output data +*/ +uint16_t dac0_output_value_get(void) +{ + uint16_t data = 0U; + data = (uint16_t)DAC0_DO; + return data; +} + +/*! + \brief get the specified DAC0 flag(DAC0 DMA underrun flag) + \param[in] none + \param[out] none + \retval the state of dac bit(SET or RESET) +*/ +FlagStatus dac0_flag_get(void) +{ + /* check the DMA underrun flag */ + if((uint8_t)RESET != (DAC_STAT & DAC_STAT_DDUDR0)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the specified DAC0 flag(DAC0 DMA underrun flag) + \param[in] none + \param[out] none + \retval none +*/ +void dac0_flag_clear(void) +{ + DAC_STAT &= ~DAC_STAT_DDUDR0; +} + +/*! + \brief get the specified DAC0 interrupt flag(DAC0 DMA underrun interrupt flag) + \param[in] none + \param[out] none + \retval the state of DAC interrupt flag(SET or RESET) +*/ +FlagStatus dac0_interrupt_flag_get(void) +{ + uint32_t ddudr_flag = 0U, ddudrie_flag = 0U; + ddudr_flag = (DAC_STAT & DAC_STAT_DDUDR0); + ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE0; + /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the specified DAC0 interrupt flag(DAC0 DMA underrun interrupt flag) + \param[in] none + \param[out] none + \retval none +*/ +void dac0_interrupt_flag_clear(void) +{ + DAC_CTL &= ~DAC_CTL_DDUDRIE0; +} + +/*! + \brief set DAC0 data holding register value + \param[in] dac_align + \arg DAC_ALIGN_8B_R: data right 8b alignment + \arg DAC_ALIGN_12B_R: data right 12b alignment + \arg DAC_ALIGN_12B_L: data left 12b alignment + \param[in] data: data to be loaded + \param[out] none + \retval none +*/ +void dac0_data_set(uint32_t dac_align, uint16_t data) +{ + switch(dac_align){ + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + DAC0_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + DAC0_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + DAC0_R8DH = data; + break; + default: + break; + } +} + +#ifdef GD32F170_190 +/*! + \brief enable DAC + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DEN0; + }else{ + DAC_CTL |= DAC_CTL_DEN1; + } +} + +/*! + \brief disable DAC + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DEN0; + }else{ + DAC_CTL &= ~DAC_CTL_DEN1; + } +} + +/*! + \brief enable DAC DMA function + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_dma_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DDMAEN0; + }else{ + DAC_CTL |= DAC_CTL_DDMAEN1; + } +} + +/*! + \brief disable DAC DMA function + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_dma_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DDMAEN0; + }else{ + DAC_CTL &= ~DAC_CTL_DDMAEN1; + } +} + +/*! + \brief enable DAC output buffer + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_output_buffer_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DBOFF0; + }else{ + DAC_CTL &= ~DAC_CTL_DBOFF1; + } +} + +/*! + \brief disable DAC output buffer + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_output_buffer_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DBOFF0; + }else{ + DAC_CTL |= DAC_CTL_DBOFF1; + } +} + +/*! + \brief enable DAC trigger + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_trigger_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DTEN0; + }else{ + DAC_CTL |= DAC_CTL_DTEN1; + } +} + +/*! + \brief disable DAC trigger + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_trigger_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DTEN0; + }else{ + DAC_CTL &= ~DAC_CTL_DTEN1; + } +} + +/*! + \brief enable DAC software trigger + \param[in] dac_periph + \arg DACx(x =0,1) + \retval none +*/ +void dac_software_trigger_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_SWT |= DAC_SWT_SWTR0; + }else{ + DAC_SWT |= DAC_SWT_SWTR1; + } +} + +/*! + \brief disable DAC software trigger + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_software_trigger_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_SWT &= ~DAC_SWT_SWTR0; + }else{ + DAC_SWT &= ~DAC_SWT_SWTR1; + } +} + +/*! + \brief get DAC output value + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval DAC output data +*/ +uint16_t dac_output_value_get(uint32_t dac_periph) +{ + uint16_t data = 0U; + if(DAC0 == dac_periph){ + data = (uint16_t)DAC0_DO; + }else{ + data = (uint16_t)DAC1_DO; + } + return data; +} + +/*! + \brief enable DAC interrupt(DAC0 DMA underrun interrupt) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_interrupt_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DDUDRIE0; + }else{ + DAC_CTL |= DAC_CTL_DDUDRIE1; + } +} + +/*! + \brief disable DAC interrupt(DAC0 DMA underrun interrupt) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_interrupt_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DDUDRIE0; + }else{ + DAC_CTL &= ~DAC_CTL_DDUDRIE1; + } +} + +/*! + \brief set DAC trigger source + \param[in] dac_periph + \arg DACx(x =0,1) + \param[in] triggersource: external triggers of DAC + \arg DAC_TRIGGER_T1_TRGO: trigger source is timer1 trgo + \arg DAC_TRIGGER_T2_TRGO: trigger source is timer2 trgo + \arg DAC_TRIGGER_T5_TRGO: trigger source is timer5 trgo + \arg DAC_TRIGGER_T14_TRGO: trigger source is timer14 trgo + \arg DAC_TRIGGER_EXTI_IT9: trigger source is exti interrupt line 9 + \arg DAC_TRIGGER_SOFTWARE: trigger source is software + \param[out] none + \retval none +*/ +void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DTSEL0; + DAC_CTL |= triggersource; + }else{ + DAC_CTL &= ~DAC_CTL_DTSEL1; + DAC_CTL |= (triggersource <<16); + } +} + +/*! + \brief get the specified DAC flag(DAC DMA underrun flag) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval the state of dac bit(SET or RESET) +*/ +FlagStatus dac_flag_get(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + /* check the DMA underrun flag */ + if(RESET != (DAC_STAT & DAC_STAT_DDUDR0)){ + return SET; + }else{ + return RESET; + } + }else{ + /* check the DMA underrun flag */ + if(RESET != (DAC_STAT & DAC_STAT_DDUDR1)){ + return SET; + }else{ + return RESET; + } + } +} + +/*! + \brief clear the specified DAC flag(DAC DMA underrun flag) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_flag_clear(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_STAT |= DAC_STAT_DDUDR0; + }else{ + DAC_STAT |= DAC_STAT_DDUDR1; + } +} + +/*! + \brief get the specified DAC interrupt flag(DAC DMA underrun interrupt flag) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval the state of DAC interrupt flag(SET or RESET) +*/ +FlagStatus dac_interrupt_flag_get(uint32_t dac_periph) +{ + uint32_t ddudr_flag = 0U, ddudrie_flag = 0U; + if(DAC0 == dac_periph){ + ddudr_flag = DAC_STAT & DAC_STAT_DDUDR0; + ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE0; + /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){ + return SET; + }else{ + return RESET; + } + }else{ + ddudr_flag = DAC_STAT & DAC_STAT_DDUDR1; + ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE1; + /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){ + return SET; + }else{ + return RESET; + } + } +} + +/*! + \brief clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_interrupt_flag_clear(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_STAT |= DAC_STAT_DDUDR0; + }else{ + DAC_STAT |= DAC_STAT_DDUDR1; + } +} + +/*! + \brief enable DAC concurrent mode + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1; + DAC_CTL |= (ctl); +} + +/*! + \brief disable DAC concurrent mode + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1; + DAC_CTL &= (~ctl); +} + +/*! + \brief enable DAC concurrent software trigger function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_enable(void) +{ + uint32_t swt = 0U; + swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; + DAC_SWT |= (swt); +} + +/*! + \brief disable DAC concurrent software trigger function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_disable(void) +{ + uint32_t swt = 0U; + swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; + DAC_SWT &= (~swt); +} + +/*! + \brief enable DAC concurrent buffer funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_output_buffer_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1; + DAC_CTL &= (~ctl); +} + +/*! + \brief disable DAC concurrent buffer funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_output_buffer_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1; + DAC_CTL |= (ctl); +} + +/*! + \brief enable DAC concurrent interrupt funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_interrupt_enable(void) +{ + DAC_CTL |= DAC_CTL_DDUDRIE0; + DAC_CTL |= DAC_CTL_DDUDRIE1; +} + +/*! + \brief disable DAC concurrent interrupt funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_interrupt_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DDUDRIE0; + DAC_CTL &= ~DAC_CTL_DDUDRIE1; +} + +/*! + \brief set the DAC specified data holding register value + \param[in] dac_periph + \arg DACx(x=0,1) + \param[in] dac_align + \arg DAC_ALIGN_8B_R: data right 8b alignment + \arg DAC_ALIGN_12B_R: data right 12b alignment + \arg DAC_ALIGN_12B_L: data left 12b alignment + \param[in] data: data to be loaded + \param[out] none + \retval none +*/ +void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data) +{ + if(DAC0 == dac_periph){ + switch(dac_align){ + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + DAC0_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + DAC0_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + DAC0_R8DH = data; + break; + default: + break; + } + }else{ + switch(dac_align){ + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + DAC1_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + DAC1_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + DAC1_R8DH = data; + break; + default: + break; + } + } +} + +/*! + \brief set DAC concurrent mode data holding register value + \param[in] dac_align + \arg DAC_ALIGN_8B_R: data right 8b alignment + \arg DAC_ALIGN_12B_R: data right 12b alignment + \arg DAC_ALIGN_12B_L: data left 12b alignment + \param[in] data1: data to be loaded + \param[in] data2: data to be loaded + \param[out] none + \retval none +*/ +void dac_concurrent_data_set(uint32_t dac_align, uint16_t data1, uint16_t data2) +{ + uint32_t data = 0U; + switch(dac_align){ + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + data = ((uint32_t)data2 << 16U) | data1; + DACC_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + data = ((uint32_t)data2 << 16U) | data1; + DACC_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + data = ((uint32_t)data2 << 8U) | data1; + DACC_R8DH = data; + break; + default: + break; + } +} + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dbg.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dbg.c new file mode 100644 index 0000000..05e649b --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dbg.c @@ -0,0 +1,106 @@ +/*! + \file gd32f1x0_dbg.c + \brief DBG driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_dbg.h" + +#define DBG_RESET_VAL 0x00000000U + +/*! + \brief deinitialize the DBG + \param[in] none + \param[out] none + \retval none +*/ +void dbg_deinit(void) +{ + DBG_CTL0 = DBG_RESET_VAL; + DBG_CTL1 = DBG_RESET_VAL; +} + +/*! + \brief read DBG_ID code register + \param[in] none + \param[out] none + \retval DBG_ID code +*/ +uint32_t dbg_id_get(void) +{ + return DBG_ID; +} + +/*! + \brief enable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + this parameter can be any combination of the following values: + \arg DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_enable(uint32_t dbg_low_power) +{ + DBG_CTL0 |= dbg_low_power; +} + +/*! + \brief disable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + this parameter can be any combination of the following values: + \arg DBG_LOW_POWER_SLEEP: donot keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: donot keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: donot keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_disable(uint32_t dbg_low_power) +{ + DBG_CTL0 &= ~dbg_low_power; +} + +/*! + \brief enable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: refer to dbg_periph_enum + only one parameter can be selected which is shown as below: + \arg DBG_FWDGT_HOLD : debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted + \arg DBG_CANx_HOLD (x=0,1): hold CANx counter when core is halted(170_190 series only) + \arg DBG_I2Cx_HOLD (x=0,1,2): hold I2Cx smbus when core is halted + \arg DBG_TIMERx_HOLD (x=0,1,2,5,13,14,15,16): hold TIMERx counter when core is halted + \arg DBG_RTC_HOLD : hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_enable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph)); +} + +/*! + \brief disable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: refer to dbg_periph_enum + only one parameter can be selected which is shown as below: + \arg DBG_FWDGT_HOLD : debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted + \arg DBG_CANx_HOLD (x=0,1): hold CANx counter when core is halted(170_190 series only) + \arg DBG_I2Cx_HOLD (x=0,1,2): hold I2Cx smbus when core is halted + \arg DBG_TIMERx_HOLD (x=0,1,2,5,13,14,15,16): hold TIMERx counter when core is halted + \arg DBG_RTC_HOLD : hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_disable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) &= ~BIT(DBG_BIT_POS(dbg_periph)); +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dma.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dma.c new file mode 100644 index 0000000..4cec0fc --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dma.c @@ -0,0 +1,492 @@ +/*! + \file gd32f1x0_dma.c + \brief DMA driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_dma.h" + +/*! + \brief deinitialize DMA a channel registers + \param[in] channelx: specify which DMA channel is deinitialized + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_deinit(dma_channel_enum channelx) +{ + /* disable DMA a channel */ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN; + /* reset DMA channel registers */ + DMA_CHCTL(channelx) = DMA_CHCTL_RESET_VALUE; + DMA_CHCNT(channelx) = DMA_CHCNT_RESET_VALUE; + DMA_CHPADDR(channelx) = DMA_CHPADDR_RESET_VALUE; + DMA_CHMADDR(channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_INTC |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE,channelx); +} + +/*! + \brief initialize DMA channel + \param[in] channelx: specify which DMA channel is initialized + \arg DMA_CHx(x=0..6) + \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 + \param[out] none + \retval none +*/ +void dma_init(dma_channel_enum channelx, dma_parameter_struct init_struct) +{ + uint32_t ctl; + /* configure peripheral base address */ + DMA_CHPADDR(channelx) = init_struct.periph_addr; + + /* configure memory base address */ + DMA_CHMADDR(channelx) = init_struct.memory_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(channelx) = init_struct.number; + + /* configure peripheral transfer width,memory transfer width, */ + ctl = DMA_CHCTL(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(channelx)=ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct.periph_inc){ + DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA; + }else{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct.memory_inc){ + DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA; + }else{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure the direction of data transfer */ + if(DMA_PERIPHERAL_TO_MEMORY == init_struct.direction){ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR; + }else{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief enable DMA circulation mode + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_circulation_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_CMEN; +} + +/*! + \brief disable DMA circulation mode + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_circulation_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CMEN; +} + +/*! + \brief enable memory to memory mode + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_M2M; +} + +/*! + \brief disable memory to memory mode + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_M2M; +} + +/*! + \brief enable DMA channel + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_channel_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_CHEN; +} + +/*! + \brief disable DMA channel + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_channel_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN; +} + +/*! + \brief set DMA peripheral base address + \param[in] channelx: specify which DMA channel to set peripheral base address + \arg DMA_CHx(x=0..6) + \param[in] address: peripheral base address + \param[out] none + \retval none +*/ +void dma_periph_address_config(dma_channel_enum channelx, uint32_t address) +{ + DMA_CHPADDR(channelx) = address; +} + +/*! + \brief set DMA Memory base address + \param[in] channelx: specify which DMA channel to set Memory base address + \arg DMA_CHx(x=0..6) + \param[in] address: Memory base address + \param[out] none + \retval none +*/ +void dma_memory_address_config(dma_channel_enum channelx, uint32_t address) +{ + DMA_CHMADDR(channelx) = address; +} + +/*! + \brief set the number of remaining data to be transferred by the DMA + \param[in] channelx: specify which DMA channel to set number + \arg DMA_CHx(x=0..6) + \param[in] number: the number of remaining data to be transferred by the DMA + \param[out] none + \retval none +*/ +void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number) +{ + DMA_CHCNT(channelx) = number; +} + +/*! + \brief get the number of remaining data to be transferred by the DMA + \param[in] channelx: specify which DMA channel to set number + \arg DMA_CHx(x=0..6) + \param[out] none + \retval uint32_t: the number of remaining data to be transferred by the DMA +*/ +uint32_t dma_transfer_number_get(dma_channel_enum channelx) +{ + return (uint32_t)DMA_CHCNT(channelx); +} + +/*! + \brief configure priority level of DMA channel + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] priority: priority Level of this channel + \arg DMA_PRIORITY_LOW: low priority + \arg DMA_PRIORITY_MEDIUM: medium priority + \arg DMA_PRIORITY_HIGH: high priority + \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority + \param[out] none + \retval none +*/ +void dma_priority_config(dma_channel_enum channelx, uint32_t priority) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PRIO; + ctl |= priority; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief configure transfer data size of memory + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] msize: transfer data size of memory + \arg DMA_MEMORY_WIDTH_8BIT: transfer data size of memory is 8-bit + \arg DMA_MEMORY_WIDTH_16BIT: transfer data size of memory is 16-bit + \arg DMA_MEMORY_WIDTH_32BIT: transfer data size of memory is 32-bit + \param[out] none + \retval none +*/ +void dma_memory_width_config (dma_channel_enum channelx, uint32_t msize) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MWIDTH; + ctl |= msize; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief configure transfer data size of peripheral + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] msize: transfer data size of peripheral + \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data size of peripheral is 8-bit + \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data size of peripheral is 16-bit + \arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data size of peripheral is 32-bit + \param[out] none + \retval none +*/ +void dma_periph_width_config (dma_channel_enum channelx, uint32_t psize) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PWIDTH; + ctl |= psize; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief enable next address increasement algorithm of memory + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_memory_increase_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA; +} + +/*! + \brief disable next address increasement algorithm of memory + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_memory_increase_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA; +} + +/*! + \brief enable next address increasement algorithm of peripheral + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_periph_increase_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA; +} + +/*! + \brief disable next address increasement algorithm of peripheral + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_periph_increase_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA; +} + +/*! + \brief configure the direction of data transfer on the channel + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] direction: specify the direction of data transfer + \arg DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory + \arg DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral + \param[out] none + \retval none +*/ +void dma_transfer_direction_config(dma_channel_enum channelx, uint8_t direction) +{ + if(DMA_PERIPHERAL_TO_MEMORY == direction){ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR; + } else { + DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief check DMA flag and interrupt enable bit is set or not + \param[in] channelx: specify which DMA channel to get flag + \arg DMA_CHx(x=0..6) + \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: full transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_ERR: error interrupt flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag) +{ + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + uint32_t gif_check = 0x0FU, gif_enable = 0x0EU; + + switch(flag){ + case DMA_INT_FLAG_FTF: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_FTFIE; + break; + case DMA_INT_FLAG_HTF: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INT_FLAG_ERR: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL( channelx) & DMA_CHXCTL_ERRIE; + break; + case DMA_INT_FLAG_G: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(gif_check, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL(channelx) & gif_enable; + break; + default: + break; + } + + if(interrupt_flag & interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear DMA a channel flag + \param[in] channelx: specify which DMA channel to clear flag + \arg DMA_CHx(x=0..6) + \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: full transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_ERR: error interrupt flag of channel + \param[out] none + \retval none +*/ +void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC |= DMA_FLAG_ADD(flag, channelx); +} + +/*! + \brief enable DMA interrupt + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] source: specify which interrupt to enbale + \arg DMA_INT_ERR: channel error interrupt + \arg DMA_INT_HTF: channel transfer half complete interrupt + \arg DMA_INT_FTF: channel transfer complete interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(channelx) |= source; +} + +/*! + \brief disable DMA interrupt + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] source: specify which interrupt to disbale + \arg DMA_INT_ERR: channel error interrupt + \arg DMA_INT_HTF: channel transfer half complete interrupt + \arg DMA_INT_FTF: for channel transfer complete interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(channelx) &= ~source; +} + +/*! + \brief check DMA flag is set or not + \param[in] channelx: specify which DMA channel to get flag + \arg DMA_CHx(x=0..6) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag) +{ + FlagStatus reval; + + if(RESET != (DMA_INTF & DMA_FLAG_ADD(flag, channelx))){ + reval = SET; + }else{ + reval = RESET; + } + + return reval; +} + +/*! + \brief clear DMA a channel flag + \param[in] channelx: specify which DMA channel to clear flag + \arg DMA_CHx(x=0..6) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval none +*/ +void dma_flag_clear(dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC |= DMA_FLAG_ADD(flag, channelx); +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_exti.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_exti.c new file mode 100644 index 0000000..559171a --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_exti.c @@ -0,0 +1,247 @@ +/*! + \file gd32f1x0_exti.c + \brief EXTI driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_exti.h" + +#define EXTI_INTEN_RESET_VAL 0x0F900000U +#define EXTI_EVEN_RESET_VAL 0x00000000U +#define EXTI_RTEN_RESET_VAL 0x00000000U +#define EXTI_FTEN_RESET_VAL 0x00000000U +#define EXTI_SWIEV_RESET_VAL 0x00000000U + +/*! + \brief deinitialize the EXTI + \param[in] none + \param[out] none + \retval none +*/ +void exti_deinit(void) +{ + /* reset the value of the EXTI registers */ + EXTI_INTEN = EXTI_INTEN_RESET_VAL; + EXTI_EVEN = EXTI_EVEN_RESET_VAL; + EXTI_RTEN = EXTI_RTEN_RESET_VAL; + EXTI_FTEN = EXTI_FTEN_RESET_VAL; + EXTI_SWIEV = EXTI_SWIEV_RESET_VAL; +} + +/*! + \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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \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 + \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; + 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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_interrupt_enable(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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_event_enable(exti_line_enum linex) +{ + EXTI_EVEN |= (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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_interrupt_disable(exti_line_enum linex) +{ + EXTI_INTEN &= ~(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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_event_disable(exti_line_enum linex) +{ + EXTI_EVEN &= ~(uint32_t)linex; +} + +/*! + \brief get EXTI lines flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_flag_get(exti_line_enum linex) +{ + if(RESET != (EXTI_PD & (uint32_t)linex)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)linex; +} + +/*! + \brief get EXTI lines flag when the interrupt flag is set + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex) +{ + uint32_t flag_left, flag_right; + flag_left = EXTI_PD & (uint32_t)linex; + flag_right = EXTI_INTEN & (uint32_t)linex; + if((RESET != flag_left) && (RESET != flag_right)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_interrupt_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_software_interrupt_disable(exti_line_enum linex) +{ + EXTI_SWIEV &= ~(uint32_t)linex; +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fmc.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fmc.c new file mode 100644 index 0000000..70e9377 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fmc.c @@ -0,0 +1,664 @@ +/*! + \file gd32f1x0_fmc.c + \brief FMC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_fmc.h" + +/* FMC main memory programming functions */ + +/*! + \brief unlock the main FMC operation + it is better to used in pairs with fmc_lock + \param[in] none + \param[out] none + \retval none +*/ +void fmc_unlock(void) +{ + if((RESET != (FMC_CTL & FMC_CTL_LK))){ + /* write the FMC key */ + FMC_KEY = UNLOCK_KEY0; + FMC_KEY = UNLOCK_KEY1; + } +} + +/*! + \brief lock the main FMC operation + it is better to used in pairs with fmc_unlock after an operation + \param[in] none + \param[out] none + \retval none +*/ +void fmc_lock(void) +{ + /* set the LK bit*/ + FMC_CTL |= FMC_CTL_LK; +} + +/*! + \brief set the wait state counter value + \param[in] wscnt: wait state counter value + \arg WS_WSCNT_0: 0 wait state added + \arg WS_WSCNT_1: 1 wait state added + \arg WS_WSCNT_2: 2 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 fmc wait state enable + \param[in] none + \param[out] none + \retval none +*/ +void fmc_wait_state_enable(void) +{ + /* unlock the main flash */ + fmc_unlock(); + + /* set the WSEN bit in register FMC_WSEN */ + FMC_WSEN |= FMC_WSEN_WSEN; + + /* lock the main flash after operation */ + fmc_lock(); +} + +/*! + \brief fmc wait state disable + \param[in] none + \param[out] none + \retval none +*/ +void fmc_wait_state_disable(void) +{ + /* unlock the main flash */ + fmc_unlock(); + + /* reset the WSEN bit in register FMC_WSEN */ + FMC_WSEN &= ~FMC_WSEN_WSEN; + + /* lock the main flash after operation */ + fmc_lock(); +} + +/*! + \brief erase page + \param[in] page_address: target page start address + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_page_erase(uint32_t page_address) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start page erase */ + FMC_CTL |= FMC_CTL_PER; + FMC_ADDR = page_address; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PER bit */ + FMC_CTL &= ~FMC_CTL_PER; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief erase whole chip + \param[in] none + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_mass_erase(void) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start chip erase */ + FMC_CTL |= FMC_CTL_MER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER bit */ + FMC_CTL &= ~FMC_CTL_MER; + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief program a word at the corresponding address + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + + REG32(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program a half word at the corresponding address + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + + REG16(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +#ifdef GD32F170_190 +/*! + \brief program a word at the corresponding address without erasing + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_word_reprogram(uint32_t address, uint32_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + FMC_WSEN |= FMC_WSEN_BPEN; + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + + REG32(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} +#endif /* GD32F170_190 */ + +/* FMC option bytes programming functions */ + +/*! + \brief unlock the option byte operation + it is better to used in pairs with ob_lock + \param[in] none + \param[out] none + \retval none +*/ +void ob_unlock(void) +{ + if(RESET == (FMC_CTL & FMC_CTL_OBWEN)){ + /* write the FMC key */ + FMC_OBKEY = UNLOCK_KEY0; + FMC_OBKEY = UNLOCK_KEY1; + } +} + +/*! + \brief lock the option byte 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 OBWE bit */ + FMC_CTL &= ~FMC_CTL_OBWEN; +} + +/*! + \brief reload the option byte and generate a system reset + \param[in] none + \param[out] none + \retval none +*/ +void ob_reset(void) +{ + /* set the OBRLD bit */ + FMC_CTL |= FMC_CTL_OBRLD; +} + +/*! + \brief erase the option byte + programmer must ensure FMC & option byte are both unlocked before calling this function + \param[in] none + \param[out] none + \retval fmc_state +*/ +fmc_state_enum ob_erase(void) +{ + uint16_t fmc_spc; + uint32_t fmc_plevel = ob_obstat_plevel_get(); + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* get the original option byte security protection code */ + if(OB_OBSTAT_PLEVEL_NO == fmc_plevel){ + fmc_spc = FMC_NSPC; + }else if(OB_OBSTAT_PLEVEL_LOW == fmc_plevel){ + fmc_spc = FMC_LSPC; + }else{ + fmc_spc = FMC_HSPC; + fmc_state = FMC_OB_HSPC; + } + + if(FMC_READY == fmc_state){ + /* start erase the option byte */ + FMC_CTL |= FMC_CTL_OBER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + + /* set the OBPG bit */ + FMC_CTL |= FMC_CTL_OBPG; + + /* restore the last get option byte security protection code */ + OB_SPC = fmc_spc; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief enable option byte write protection (OB_WP) + \param[in] ob_wp: write protection configuration data + \param[out] none + \retval fmc_state +*/ +fmc_state_enum ob_write_protection_enable(uint32_t ob_wp) +{ + uint16_t ob_wrp0, ob_wrp1; + + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + ob_wp = (uint32_t)(~ob_wp); + ob_wrp0 = (uint16_t)(ob_wp & OB_LWP); + ob_wrp1 = (uint16_t)((ob_wp & OB_HWP) >> 8); + + if(FMC_READY == fmc_state){ + /* set the OBPG bit*/ + FMC_CTL |= FMC_CTL_OBPG; + + if(0xFFU != ob_wrp0){ + OB_WP0 = ob_wrp0; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + if((FMC_READY == fmc_state) && (0xFFU != ob_wrp1)){ + OB_WP1 = ob_wrp1; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure security protection + \param[in] ob_spc: specify security protection code + \arg FMC_NSPC: no security protection + \arg FMC_LSPC: low security protection + \arg FMC_HSPC: high security protection + \param[out] none + \retval fmc_state +*/ +fmc_state_enum ob_security_protection_config(uint8_t ob_spc) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* the OB_SPC byte cannot be reprogrammed if protection level is high */ + if(OB_OBSTAT_PLEVEL_HIGH == ob_obstat_plevel_get()){ + fmc_state = FMC_OB_HSPC; + } + + if(FMC_READY == fmc_state){ + /* start erase the option byte */ + FMC_CTL |= FMC_CTL_OBER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + + /* enable the option bytes programming */ + FMC_CTL |= FMC_CTL_OBPG; + + OB_SPC = ob_spc; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC user option byte + \param[in] ob_user: user option byte + \arg OB_FWDGT_SW: software free watchdog timer + \arg OB_FWDGT_HW: hardware free watchdog timer + \arg OB_DEEPSLEEP_NRST: generate a reset instead of entering deepsleep mode + \arg OB_DEEPSLEEP_RST: no reset when entering deepsleep mode + \arg OB_STDBY_NRST: generate a reset instead of entering standby mode + \arg OB_STDBY_RST: no reset when entering deepsleep mode + \arg OB_BOOT1_SET_1: BOOT1 bit is 1 + \arg OB_BOOT1_SET_0: BOOT1 bit is 0 + \arg OB_VDDA_DISABLE: disable VDDA monitor + \arg OB_VDDA_ENABLE: enable VDDA monitor + \arg OB_SRAM_PARITY_DISABLE: disable sram parity check + \arg OB_SRAM_PARITY_ENABLE: enable sram parity check + \param[out] none + \retval fmc_state +*/ +fmc_state_enum ob_user_write(uint8_t ob_user) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the OBPG bit */ + FMC_CTL |= FMC_CTL_OBPG; + + OB_USER = (uint8_t)(ob_user | OB_USER_MASK); + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC data option byte + \param[in] address: OB_DATA_ADDR0 or OB_DATA_ADDR1 + \arg OB_DATA_ADDR0: option byte data address 0 + \arg OB_DATA_ADDR1: option byte data address 1 + \param[in] data: the byte to be programmed + \param[out] none + \retval fmc_state +*/ +fmc_state_enum ob_data_program(uint32_t address, uint8_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the OBPG bit */ + FMC_CTL |= FMC_CTL_OBPG; + REG16(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief get OB_USER in register FMC_OBSTAT + \param[in] none + \param[out] none + \retval ob_user +*/ +uint8_t ob_user_get(void) +{ + return (uint8_t)(FMC_OBSTAT >> 8); +} + +/*! + \brief get OB_DATA in register FMC_OBSTAT + \param[in] none + \param[out] none + \retval ob_data +*/ +uint16_t ob_data_get(void) +{ + return (uint16_t)(FMC_OBSTAT >> 16); +} + +/*! + \brief get the FMC option byte write protection (OB_WP) in register FMC_WP + \param[in] none + \param[out] none + \retval OB_WP +*/ +uint16_t ob_write_protection_get(void) +{ + return (uint16_t)(FMC_WP); +} + +/*! + \brief get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register + \param[in] none + \param[out] none + \retval the value of PLEVEL +*/ +uint32_t ob_obstat_plevel_get(void) +{ + return (FMC_OBSTAT & (FMC_OBSTAT_PLVL_BIT0 | FMC_OBSTAT_PLVL_BIT1)); +} + +/* FMC interrupts and flags management functions */ +/*! + \brief enable FMC interrupt + \param[in] interrupt: the FMC interrupt source + \arg FMC_INTEN_END: FMC end of operation interrupt + \arg FMC_INTEN_ERR: FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_enable(uint32_t interrupt) +{ + FMC_CTL |= interrupt; +} + +/*! + \brief disable FMC interrupt + \param[in] interrupt: the FMC interrupt source + \arg FMC_INTEN_END: FMC end of operation interrupt + \arg FMC_INTEN_ERR: FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_disable(uint32_t interrupt) +{ + FMC_CTL &= ~(uint32_t)interrupt; +} + +/*! + \brief get flag set or reset + \param[in] flag: check FMC flag + \arg FMC_FLAG_BUSY: FMC busy flag + \arg FMC_FLAG_PGERR: FMC programming error flag + \arg FMC_FLAG_WPERR: FMC write protection error flag + \arg FMC_FLAG_END: FMC end of programming flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flag_get(uint32_t flag) +{ + FlagStatus status = RESET; + + if(FMC_STAT & flag){ + status = SET; + } + /* return the state of corresponding FMC flag */ + return status; +} + +/*! + \brief clear the FMC pending flag by writing 1 + \param[in] flag: clear FMC flag + \arg FMC_FLAG_PGERR: FMC programming error flag + \arg FMC_FLAG_WPERR: FMC write protection error flag + \arg FMC_FLAG_END: fmc end of programming flag + \param[out] none + \retval none +*/ +void fmc_flag_clear(uint32_t flag) +{ + /* clear the flags */ + FMC_STAT = flag; +} + +/*! + \brief get the FMC state + \param[in] none + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_BUSY)){ + fmc_state = FMC_BUSY; + }else{ + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_WPERR)){ + fmc_state = FMC_WPERR; + }else{ + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGERR)){ + fmc_state = FMC_PGERR; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC is ready or not + \param[in] timeout: timeout count + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_ready_wait(uint32_t timeout) +{ + fmc_state_enum fmc_state = FMC_BUSY; + + /* wait for FMC ready */ + do{ + /* get FMC state */ + fmc_state = fmc_state_get(); + timeout--; + }while((FMC_BUSY == fmc_state) && (0U != timeout)); + + if(FMC_BUSY == fmc_state){ + fmc_state = FMC_TOERR; + } + /* return the FMC state */ + return fmc_state; +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fwdgt.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fwdgt.c new file mode 100644 index 0000000..0c403fa --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fwdgt.c @@ -0,0 +1,146 @@ +/*! + \file gd32f1x0_fwdgt.c + \brief FWDGT driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_fwdgt.h" + +/*! + \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 reload the counter of FWDGT + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_counter_reload(void) +{ + FWDGT_CTL = FWDGT_KEY_RELOAD; +} + +/*! + \brief start the free watchdog timer counter + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_enable(void) +{ + FWDGT_CTL = FWDGT_KEY_ENABLE; +} + +/*! + \brief configure the free watchdog timer counter window value + \param[in] window_value: specify window value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_window_value_config(uint16_t window_value) +{ + uint32_t time_index = FWDGT_WND_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_WND */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the WUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_WUD; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_WND = WND_WND(window_value); + + return SUCCESS; +} + +/*! + \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 + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC,and FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_div; + + timeout = FWDGT_RLD_TIMEOUT; + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + /* reload the counter */ + FWDGT_CTL = FWDGT_KEY_RELOAD; + + return SUCCESS; +} + +/*! + \brief get flag state of FWDGT + \param[in] flag: flag to get + \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(FWDGT_STAT & flag){ + return SET; + } + + return RESET; +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_gpio.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_gpio.c new file mode 100644 index 0000000..0cb8683 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_gpio.c @@ -0,0 +1,337 @@ +/*! + \file gd32f1x0_gpio.c + \brief GPIO driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform for GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform for GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_gpio.h" + +/*! + \brief reset GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[out] none + \retval none +*/ +void gpio_deinit(uint32_t gpio_periph) +{ + switch(gpio_periph){ + case GPIOA: + /* reset GPIOA */ + rcu_periph_reset_enable(RCU_GPIOARST); + rcu_periph_reset_disable(RCU_GPIOARST); + break; + case GPIOB: + /* reset GPIOB */ + rcu_periph_reset_enable(RCU_GPIOBRST); + rcu_periph_reset_disable(RCU_GPIOBRST); + break; + case GPIOC: + /* reset GPIOC */ + rcu_periph_reset_enable(RCU_GPIOCRST); + rcu_periph_reset_disable(RCU_GPIOCRST); + break; + case GPIOD: + /* reset GPIOD */ + rcu_periph_reset_enable(RCU_GPIODRST); + rcu_periph_reset_disable(RCU_GPIODRST); + break; + case GPIOF: + /* reset GPIOF */ + rcu_periph_reset_enable(RCU_GPIOFRST); + rcu_periph_reset_disable(RCU_GPIOFRST); + break; + default: + break; + } +} + +/*! + \brief set GPIO output mode + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] mode: gpio pin mode + \arg GPIO_MODE_INPUT: input mode + \arg GPIO_MODE_OUTPUT: output mode + \arg GPIO_MODE_AF: alternate function mode + \arg GPIO_MODE_ANALOG: analog mode + \param[in] pull_up_down: gpio pin with pull-up or pull-down resistor + \arg GPIO_PUPD_NONE: without weak pull-up and pull-down resistors + \arg GPIO_PUPD_PULLUP: with weak pull-up resistor + \arg GPIO_PUPD_PULLDOWN:with weak pull-down resistor + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_mode_set(uint32_t gpio_periph,uint32_t mode,uint32_t pull_up_down,uint32_t pin) +{ + uint16_t i; + uint32_t ctl, pupd; + + ctl = GPIO_CTL(gpio_periph); + pupd = GPIO_PUD(gpio_periph); + + for (i = 0U; i < 16U; i++){ + if((1U << i) & pin){ + /* clear the specified pin mode bits */ + ctl &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + ctl |= GPIO_MODE_SET(i, mode); + + /* clear the specified pin pupd bits */ + pupd &= ~GPIO_PUPD_MASK(i); + /* set the specified pin pupd bits */ + pupd |= GPIO_PUPD_SET(i, pull_up_down); + } + } + + GPIO_CTL(gpio_periph) = ctl; + GPIO_PUD(gpio_periph) = pupd; +} + +/*! + \brief set GPIO output type and speed + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] otype: gpio pin output mode + \arg GPIO_OTYPE_PP: push pull mode + \arg GPIO_OTYPE_OD: open drain mode + \param[in] speed + \arg GPIO_OSPEED_2MHZ: output max speed 2M + \arg GPIO_OSPEED_10MHZ: output max speed 10M + \arg GPIO_OSPEED_50MHZ: output max speed 50M + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_output_options_set(uint32_t gpio_periph,uint8_t otype,uint32_t speed,uint32_t pin) +{ + uint16_t i; + uint32_t ospeedr; + + if(0x1U == otype){ + GPIO_OMODE(gpio_periph) |= (uint32_t)pin; + }else{ + GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin); + } + + /* get the specified pin output speed bits value */ + ospeedr = GPIO_OSPD(gpio_periph); + + for(i = 0U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin output speed bits */ + ospeedr &= ~GPIO_OSPEED_MASK(i); + /* set the specified pin output speed bits */ + ospeedr |= GPIO_OSPEED_SET(i,speed); + } + } + GPIO_OSPD(gpio_periph) = ospeedr; +} + +/*! + \brief set GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] pin: 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 + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] pin: 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,F) + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[in] bit_value: SET or RESET + \arg RESET: clear the port pin + \arg SET: set the port pin + \param[out] none + \retval none +*/ +void gpio_bit_write(uint32_t gpio_periph,uint32_t pin,bit_status bit_value) +{ + if(RESET != bit_value){ + GPIO_BOP(gpio_periph) = (uint32_t)pin; + }else{ + GPIO_BC(gpio_periph) = (uint32_t)pin; + } +} + +/*! + \brief write data to the specified GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] data: specify the value to be written to the port output control register + \param[out] none + \retval none +*/ +void gpio_port_write(uint32_t gpio_periph,uint16_t data) +{ + GPIO_OCTL(gpio_periph) = (uint32_t)data; +} + +/*! + \brief get GPIO pin input status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval input state of gpio pin: SET or RESET +*/ +FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin) +{ + if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO all pins input status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[out] none + \retval input 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,F) + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval output state of gpio pin: SET or RESET +*/ +FlagStatus gpio_output_bit_get(uint32_t gpio_periph,uint32_t pin) +{ + if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO all pins output status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[out] none + \retval output 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,F) + \param[in] alt_func_num: gpio pin af function, please refer to specific device datasheet + \arg GPIO_AF_0: TIMER2, TIMER13, TIMER14, TIMER16, SPI0, I2S0, SPI1, SPI2, I2S2, CK_OUT, + SWDIO, SWCLK, USART0, CEC, IFRP, I2C0, I2C1, TSI, EVENTOUT + \arg GPIO_AF_1: USART0, USART1, IFRP, CEC, TIMER2, TIMER14, I2C0, I2C1, I2C2, EVENTOUT + \arg GPIO_AF_2: TIMER0, TIMER1, TIMER15, TIMER16, EVENTOUT + \arg GPIO_AF_3: TSI, I2C0, TIMER14, EVENTOUT + \arg GPIO_AF_4(port A,B only): TIMER13, I2C0, I2C1, I2C2, USART1 + \arg GPIO_AF_5(port A,B only): TIMER15, TIMER16, SPI2, I2S2, I2C0, I2C1 + \arg GPIO_AF_6(port A,B only): SPI1, EVENTOUT + \arg GPIO_AF_7(port A,B only): CMP0, CMP1 + \arg GPIO_AF_9(port A,B only): CAN0, CAN1 (for GD32F170xx and GD32F190xx devices) + \arg GPIO_AF_11: SLCD (for GD32F170xx and GD32F190xx devices) + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_af_set(uint32_t gpio_periph,uint32_t alt_func_num,uint32_t pin) +{ + uint16_t i; + uint32_t afrl, afrh; + + afrl = GPIO_AFSEL0(gpio_periph); + afrh = GPIO_AFSEL1(gpio_periph); + + for (i = 0U; i < 8U; i++){ + if((1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrl &= ~GPIO_AFR_MASK(i); + afrl |= GPIO_AFR_SET(i,alt_func_num); + } + } + + for (i = 8U; i < 16U; i++){ + if((1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrh &= ~GPIO_AFR_MASK(i - 8U); + afrh |= GPIO_AFR_SET(i - 8U,alt_func_num); + } + } + + GPIO_AFSEL0(gpio_periph) = afrl; + GPIO_AFSEL1(gpio_periph) = afrh; +} + +/*! + \brief lock GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B) + \param[in] pin: 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); +} + +#ifdef GD32F170_190 +/*! + \brief toggle GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] pin: 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 + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[out] none + \retval none +*/ +void gpio_port_toggle(uint32_t gpio_periph) +{ + GPIO_TG(gpio_periph) = 0x0000FFFFU; +} + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_i2c.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_i2c.c new file mode 100644 index 0000000..8b6c994 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_i2c.c @@ -0,0 +1,795 @@ +/*! + \file gd32f1x0_i2c.c + \brief I2C driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_i2c.h" + +#define I2CCLK_MAX 0x3fU /*!< i2cclk max value */ +#define I2C_FLAG_MASK 0x0000FFFFU /*!< i2c flag mask */ + +/*! + \brief reset I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_deinit(uint32_t i2c_periph) +{ + switch(i2c_periph){ + case I2C0: + /* reset I2C0 */ + rcu_periph_reset_enable(RCU_I2C0RST); + rcu_periph_reset_disable(RCU_I2C0RST); + break; + case I2C1: + /* reset I2C1 */ + rcu_periph_reset_enable(RCU_I2C1RST); + rcu_periph_reset_disable(RCU_I2C1RST); + break; +#ifdef GD32F170_190 + case I2C2: + /* reset I2C2 */ + rcu_periph_reset_enable(RCU_I2C2RST); + rcu_periph_reset_disable(RCU_I2C2RST); + break; +#endif /* GD32F170_190 */ + default: + break; + } +} + +/*! + \brief configure I2C clock + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz) + and fast mode plus (up to 1MHz) + \param[in] dutycyc: duty cycle in fast mode or fast mode plus + \arg I2C_DTCY_2: T_low/T_high=2 + \arg I2C_DTCY_16_9: T_low/T_high=16/9 + \param[out] none + \retval none +*/ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc) +{ + uint32_t pclk1,clkc,freq,risetime; + uint32_t temp; + + pclk1 = rcu_clock_freq_get(CK_APB1); + /* I2C peripheral clock frequency */ + freq = (uint32_t)(pclk1/1000000U); + if(freq >= I2CCLK_MAX){ + freq = I2CCLK_MAX; + } + temp = I2C_CTL1(i2c_periph); + temp &= ~I2C_CTL1_I2CCLK; + temp |= freq; + + I2C_CTL1(i2c_periph) = temp; + + if(100000U >= clkspeed){ + /* the maximum SCL rise time is 1000ns in standard mode */ + risetime = (uint32_t)((pclk1/1000000U)+1U); + if(risetime >= I2CCLK_MAX){ + I2C_RT(i2c_periph) = I2CCLK_MAX; + }else{ + I2C_RT(i2c_periph) = risetime; + } + clkc = (uint32_t)(pclk1/(clkspeed*2U)); + if(clkc < 0x04U){ + /* the CLKC in standard mode minmum value is 4 */ + clkc = 0x04U; + } + I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc); + + }else if(400000U >= clkspeed){ + /* the maximum SCL rise time is 300ns in fast mode */ + I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)300U)/(uint32_t)1000U)+(uint32_t)1U); + if(I2C_DTCY_2 == dutycyc){ + /* I2C duty cycle is 2 */ + clkc = (uint32_t)(pclk1/(clkspeed*3U)); + I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY; + }else{ + /* I2C duty cycle is 16/9 */ + clkc = (uint32_t)(pclk1/(clkspeed*25U)); + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY; + } + if(0U == (clkc & I2C_CKCFG_CLKC)){ + /* the CLKC in fast mode minmum value is 1 */ + clkc |= 0x0001U; + } + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST; + I2C_CKCFG(i2c_periph) |= clkc; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure I2C address + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] mode: + \arg I2C_I2CMODE_ENABLE: I2C mode + \arg I2C_SMBUSMODE_ENABLE: SMBus mode + \param[in] addformat: 7bits or 10bits + \arg I2C_ADDFORMAT_7BITS: 7bits + \arg I2C_ADDFORMAT_10BITS: 10bits + \param[in] addr: I2C address + \param[out] none + \retval none +*/ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr) +{ + /* SMBus/I2C mode selected */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SMBEN); + ctl |= mode; + I2C_CTL0(i2c_periph) = ctl; + /* configure address */ + I2C_SADDR0(i2c_periph) = (addformat | addr); +} + +/*! + \brief SMBus type selection + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] ack: + \arg I2C_SMBUS_DEVICE: device + \arg I2C_SMBUS_HOST: host + \param[out] none + \retval none +*/ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type) +{ + if(I2C_SMBUS_HOST == type){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL); + } +} + +/*! + \brief whether or not to send an ACK + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] ack: + \arg I2C_ACK_ENABLE: ACK will be sent + \arg I2C_ACK_DISABLE: ACK will not be sent + \param[out] none + \retval none +*/ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack) +{ + if(I2C_ACK_ENABLE == ack){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN); + } +} + +/*! + \brief I2C POAP position configure + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] pos: + \arg I2C_ACKPOS_CURRENT: whether to send ACK or not for the current + \arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte + \param[out] none + \retval none +*/ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos) +{ + /* configure I2C POAP position */ + if(I2C_ACKPOS_NEXT == pos){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP); + } +} + +/*! + \brief master send slave address + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] addr: slave address + \param[in] trandirection: transmitter or receiver + \arg I2C_TRANSMITTER: transmitter + \arg I2C_RECEIVER: receiver + \param[out] none + \retval none +*/ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection) +{ + if(I2C_TRANSMITTER == trandirection){ + addr = addr & I2C_TRANSMITTER; + }else{ + addr = addr | I2C_RECEIVER; + } + I2C_DATA(i2c_periph) = addr; +} + +/*! + \brief dual-address mode switch + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dualaddr: + \arg I2C_DUADEN_DISABLE: disable dual-address mode + \arg I2C_DUADEN_ENABLE: enable dual-address mode + \param[out] none + \retval none +*/ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t dualaddr) +{ + if(I2C_DUADEN_ENABLE == dualaddr){ + I2C_SADDR1(i2c_periph) |= I2C_SADDR1_DUADEN; + }else{ + I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN); + } +} + +/*! + \brief enable I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN; +} + +/*! + \brief disable I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_I2CEN); +} + +/*! + \brief generate a START condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_start_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_START; +} + +/*! + \brief generate a STOP condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_stop_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP; +} + +/*! + \brief I2C transmit data function + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data) +{ + I2C_DATA(i2c_periph) = DATA_TRANS(data); +} + +/*! + \brief I2C receive data function + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval data of received +*/ +uint8_t i2c_data_receive(uint32_t i2c_periph) +{ + return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph)); +} + +/*! + \brief enable I2C DMA mode + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dmastate: + \arg I2C_DMA_ON: DMA mode enable + \arg I2C_DMA_OFF: DMA mode disable + \param[out] none + \retval none +*/ +void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate) +{ + /* configure I2C DMA function */ + uint32_t ctl = 0U; + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMAON); + ctl |= dmastate; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief flag indicating DMA last transfer + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dmalast: + \arg I2C_DMALST_ON: next DMA EOT is the last transfer + \arg I2C_DMALST_OFF: next DMA EOT is not the last transfer + \param[out] none + \retval none +*/ +void i2c_dma_last_transfer_enable(uint32_t i2c_periph, uint32_t dmalast) +{ + /* configure DMA last transfer */ + uint32_t ctl = 0U; + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMALST); + ctl |= dmalast; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief whether to stretch SCL low when data is not ready in slave mode + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] stretchpara: + \arg I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled + \arg I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara) +{ + /* configure I2C SCL strerching enable or disable */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_DISSTRC); + ctl |= stretchpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief whether or not to response to a general call + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] gcallpara: + \arg I2C_GCEN_ENABLE: slave will response to a general call + \arg I2C_GCEN_DISABLE: slave will not response to a general call + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara) +{ + /* configure slave response to a general call enable or disable */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_GCEN); + ctl |= gcallpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief software reset I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] sreset: + \arg I2C_SRESET_SET: I2C is under reset + \arg I2C_SRESET_RESET: I2C is not under reset + \param[out] none + \retval none +*/ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset) +{ + /* modify CTL0 and configure software reset I2C state */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SRESET); + ctl |= sreset; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief check I2C flag is set or not + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] flag: + \arg I2C_FLAG_SBSEND: start condition send out + \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode + \arg I2C_FLAG_BTC: byte transmission finishes + \arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode + \arg I2C_FLAG_STPDET: stop condition detected in slave mode + \arg I2C_FLAG_RBNE: I2C_DATA is not Empty during receiving + \arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting + \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_AERR: acknowledge error + \arg I2C_FLAG_OUERR: overrun or underrun situation occurs in slave mode + \arg I2C_FLAG_PECERR: PEC error when receiving data + \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode + \arg I2C_FLAG_SMBALT: SMBus alert status + \arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode + \arg I2C_FLAG_I2CBSY: busy flag + \arg I2C_FLAG_TRS: whether the I2C is a transmitter or a receiver + \arg I2C_FLAG_RXGC: general call address (00h) received + \arg I2C_FLAG_DEFSMB: default address of SMBus device + \arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode + \arg I2C_FLAG_DUMODF: dual flag in slave mode indicating which address is matched in dual-address mode + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag) +{ + uint32_t reg = 0U; + FlagStatus reval = RESET; + /* get the flag in which register */ + reg = (BIT(31) & flag); + if((BIT(31) == reg)){ + if((I2C_STAT1(i2c_periph)&(flag & I2C_FLAG_MASK))){ + reval = SET; + }else{ + reval = RESET; + } + }else{ + if((I2C_STAT0(i2c_periph)&(flag & I2C_FLAG_MASK))){ + reval = SET; + }else{ + reval = RESET; + } + } + /* return the flag status */ + return reval; +} + +/*! + \brief clear I2C flag + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] flag: flag type + \arg I2C_FLAG_SMBALT: SMBus Alert status + \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode + \arg I2C_FLAG_PECERR: PEC error when receiving data + \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode + \arg I2C_FLAG_AERR: acknowledge error + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_BERR: a bus error + \arg I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1 + \param[out] none + \retval none +*/ +void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag) +{ + if(I2C_FLAG_ADDSEND == flag){ + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + }else{ + I2C_STAT0(i2c_periph) &= ~(flag); + } +} + +/*! + \brief enable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] inttype: interrupt type + \arg I2C_INT_ERR: error interrupt enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \param[out] none + \retval none +*/ +void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t inttype) +{ + I2C_CTL1(i2c_periph) |= (inttype); +} + +/*! + \brief disable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] inttype: interrupt type + \arg I2C_INT_ERR: error interrupt enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \param[out] none + \retval none +*/ +void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t inttype) +{ + I2C_CTL1(i2c_periph) &= ~(inttype); +} + +/*! + \brief check I2C interrupt flag + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] int_flag: interrupt flag + \arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag + \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag + \arg I2C_INT_FLAG_BTC: byte transmission finishes + \arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag + \arg I2C_INT_FLAG_STPDET: etop condition detected in slave mode interrupt flag + \arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag + \arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag + \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag + \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag + \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag + \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag + \param[out] none + \retval none +*/ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, uint32_t intflag) +{ + uint32_t evie, errie, bufie; + + evie = I2C_CTL1(i2c_periph)&I2C_CTL1_EVIE; + errie = I2C_CTL1(i2c_periph)&I2C_CTL1_ERRIE; + /* check I2C event interrupt enable bit */ + if((intflag&0x00ffU) && evie){ + if(intflag&0x001fU){ + /* check I2C event flags except TBE and RBNE */ + if(intflag & I2C_STAT0(i2c_periph)){ + return SET; + }else{ + return RESET; + } + }else{ + /* check I2C event flags TBE and RBNE */ + bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE; + if(bufie){ + if(intflag & I2C_STAT0(i2c_periph)){ + return SET; + }else{ + return RESET; + } + }else{ + return RESET; + } + } + /* check I2C error interrupt enable bit */ + }else if((intflag&0xff00U) && errie){ + /* check I2C error flags */ + if(intflag & I2C_STAT0(i2c_periph)){ + return SET; + }else{ + return RESET; + } + }else{ + return RESET; + } +} + +/*! + \brief clear I2C interrupt flag + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] intflag: interrupt flag + \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag + \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag + \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag + \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag + \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag + \param[out] none + \retval none +*/ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, uint32_t intflag) +{ + if(I2C_INT_FLAG_ADDSEND == intflag){ + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + }else{ + I2C_STAT0(i2c_periph) &= ~(intflag); + } +} + +/*! + \brief I2C PEC calculation on or off + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] pecpara: + \arg I2C_PEC_ENABLE: PEC calculation on + \arg I2C_PEC_DISABLE: PEC calculation off + \param[out] none + \retval none +*/ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate) +{ + /* on/off PEC calculation */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECEN); + ctl |= pecstate; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief I2C whether to transfer PEC value + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] pecpara: + \arg I2C_PECTRANS_ENABLE: transfer PEC + \arg I2C_PECTRANS_DISABLE: not transfer PEC + \param[out] none + \retval none +*/ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara) +{ + /* whether to transfer PEC */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECTRANS); + ctl |= pecpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief get packet error checking value + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval PEC value +*/ +uint8_t i2c_pec_value_get(uint32_t i2c_periph) +{ + return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_ECV)>>8); +} + +/*! + \brief I2C issue alert through SMBA pin + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] smbuspara: + \arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin + \arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin + \param[out] none + \retval none +*/ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara) +{ + /* issue alert through SMBA pin configure*/ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SALT); + ctl |= smbuspara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief enable or disable I2C ARP protocol in SMBus switch + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] smbuspara: + \arg I2C_ARP_ENABLE: enable ARP + \arg I2C_ARP_DISABLE: disable ARP + \param[out] none + \retval none +*/ +void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate) +{ + /* enable or disable I2C ARP protocol*/ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_ARPEN); + ctl |= arpstate; + I2C_CTL0(i2c_periph) = ctl; +} + +#ifdef GD32F170_190 + +/*! + \brief enable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN; +} + +/*! + \brief disable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN); +} + +/*! + \brief enable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN; +} + +/*! + \brief disable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN); +} + +/*! + \brief enable the specified I2C SAM interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] inttype: interrupt type + \@arg I2C_SAMCS_TFFIE: txframe fall interrupt + \@arg I2C_SAMCS_TFRIE: txframe rise interrupt + \@arg I2C_SAMCS_RFFIE: rxframe fall interrupt + \@arg I2C_SAMCS_RFRIE: rxframe rise interrupt + \param[out] none + \retval none +*/ +void i2c_sam_interrupt_enable(uint32_t i2c_periph, uint32_t inttype) +{ + I2C_SAMCS(i2c_periph) |= (inttype); +} + +/*! + \brief disable i2c interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] inttype: interrupt type + \@arg I2C_SAMCS_TFFIE: txframe fall interrupt + \@arg I2C_SAMCS_TFRIE: txframe rise interrupt + \@arg I2C_SAMCS_RFFIE: rxframe fall interrupt + \@arg I2C_SAMCS_RFRIE: rxframe rise interrupt + \param[out] none + \retval none +*/ +void i2c_sam_interrupt_disable(uint32_t i2c_periph, uint32_t inttype) +{ + I2C_SAMCS(i2c_periph) &= ~(inttype); +} + +/*! + \brief check i2c SAM state + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] samstate: state type + \@arg I2C_SAMCS_TXF: level of txframe signal + \@arg I2C_SAMCS_RXF: level of rxframe signal + \@arg I2C_SAMCS_TFF: txframe fall flag + \@arg I2C_SAMCS_TFR: txframe rise flag + \@arg I2C_SAMCS_RFF: rxframe fall flag + \@arg I2C_SAMCS_RFR: rxframe rise flag + \param[out] none + \retval state of i2c SAM +*/ +FlagStatus i2c_sam_flag_get(uint32_t i2c_periph, uint32_t samstate) +{ + if(I2C_SAMCS(i2c_periph) & samstate){ + return SET; + } + + return RESET; +} +/*! + \brief clear i2c SAM state + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] samstate: state type + \@arg I2C_SAMCS_TFF: txframe fall flag + \@arg I2C_SAMCS_TFR: txframe rise flag + \@arg I2C_SAMCS_RFF: rxframe fall flag + \@arg I2C_SAMCS_RFR: rxframe rise flag + \param[out] none + \retval none +*/ +void i2c_sam_flag_clear(uint32_t i2c_periph, uint32_t samstate) +{ + I2C_SAMCS(i2c_periph) &= ~(samstate); + +} + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_ivref.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_ivref.c new file mode 100644 index 0000000..4737114 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_ivref.c @@ -0,0 +1,180 @@ +/*! + \file gd32f1x0_ivref.c + \brief IVREF driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 + +#include "gd32f1x0_ivref.h" + +/*! + \brief deinit IVREF + \param[in] none + \param[out] none + \retval none +*/ +void ivref_deinit(void) +{ + rcu_periph_reset_enable(RCU_OPAIVREFRST); + rcu_periph_reset_disable(RCU_OPAIVREFRST); +} + +/*! + \brief enable VREF + \param[in] none + \param[out] none + \retval none +*/ +void vref_enable(void) +{ + IVREF_CTL |= IVREF_CTL_VREN; +} + +/*! + \brief disable VREF + \param[in] none + \param[out] none + \retval none +*/ +void vref_disable(void) +{ + IVREF_CTL &= ~IVREF_CTL_VREN; +} + +/*! + \brief set VREF mode + \param[in] vrefmode + \arg VREF_CONNECT_EXTERNAL_CAP: vref connect external capacitor + \arg VREF_DISCONNECT_EXTERNAL_CAP: vref disconnect external capacitor + \param[out] none + \retval none +*/ +void vref_mode_set(uint32_t vrefmode) +{ + uint32_t ctl = 0U; + ctl = IVREF_CTL; + /* clear voltage reference enable bits */ + ctl &= ~IVREF_CTL_DECAP; + ctl |= vrefmode; + IVREF_CTL = ctl; +} + +/*! + \brief set VREF voltage precision trim. + \param[in] precisiontrim + \arg VREF_VOLT_PRECISION_TRIM_X(x=0..31): (-6.4+ 0.4*x)% + \param[out] none + \retval none +*/ +void vref_precision_trim_value_set(uint32_t precisiontrim) +{ + uint32_t ctl = 0U; + ctl = IVREF_CTL; + ctl &= ~IVREF_CTL_VPT; + ctl |= precisiontrim; + IVREF_CTL = ctl; +} + +/*! + \brief enable IREF + \param[in] none + \param[out] none + \retval none +*/ +void iref_enable(void) +{ + IVREF_CTL |= IVREF_CTL_CREN; +} + +/*! + \brief disable IREF + \param[in] none + \param[out] none + \retval none +*/ +void iref_disable(void) +{ + IVREF_CTL &= ~IVREF_CTL_CREN; +} + +/*! + \brief set IREF mode + \param[in] irefmode + \arg IREF_MODE_LOW_POWER: 1uA step + \arg IREF_MODE_HIGH_CURRENT: 8uA step + \param[out] none + \retval none +*/ +void iref_mode_set(uint32_t irefmode) +{ + uint32_t ctl = 0U; + ctl = IVREF_CTL; + ctl &= ~IVREF_CTL_SSEL; + ctl |= irefmode; + IVREF_CTL = ctl; +} + +/*! + \brief set IREF precision_trim_value + \param[in] precisiontrim + \arg IREF_CUR_PRECISION_TRIM_X(x=0..31): (-15+ x)% + \param[out] none + \retval none +*/ +void iref_precision_trim_value_set(uint32_t precisiontrim) +{ + uint32_t ctl = 0U; + ctl = IVREF_CTL; + ctl &= ~IVREF_CTL_CPT; + ctl |= precisiontrim; + IVREF_CTL = ctl; +} + +/*! + \brief set IREF sink mode + \param[in] irefsinkmode + \arg IREF_SOURCE_CURRENT : source current. + \arg IREF_SINK_CURRENT: sink current + \param[out] none + \retval none +*/ +void iref_sink_set(uint32_t irefsinkmode) +{ + uint32_t ctl = 0U; + ctl = IVREF_CTL; + /* clear sink current mode bits */ + ctl &= ~IVREF_CTL_SCMOD; + /* set sink current mode bits */ + ctl |= irefsinkmode; + IVREF_CTL = ctl; +} + +/*! + \brief set IREF step data + \param[in] irefstepdata + \arg IREF_CUR_STEP_DATA_X:(x=0..63): step*x + \param[out] none + \retval none +*/ +void iref_step_data_config(uint32_t irefstepdata) +{ + uint32_t ctl = 0U; + /* get ctl value */ + ctl = IVREF_CTL; + /* clear current step data bits */ + ctl &= ~IVREF_CTL_CSDT; + /* set current step data bits */ + ctl |= irefstepdata; + IVREF_CTL = ctl; +} + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_misc.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_misc.c new file mode 100644 index 0000000..31af322 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_misc.c @@ -0,0 +1,149 @@ +/*! + \file gd32f1x0_misc.c + \brief MISC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_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)0x700)==NVIC_PRIGROUP_PRE0_SUB4){ + temp_pre = 0U; + temp_sub = 0x4U; + }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE1_SUB3){ + temp_pre = 1U; + temp_sub = 0x3U; + }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE2_SUB2){ + temp_pre = 2U; + temp_sub = 0x2U; + }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE3_SUB1){ + temp_pre = 3U; + temp_sub = 0x1U; + }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE4_SUB0){ + temp_pre = 4U; + temp_sub = 0x0U; + }else{ + } + /* get the temp_priority to fill the NVIC->IP register */ + temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre); + temp_priority |= nvic_irq_sub_priority &(0x0FU >> (0x4U - temp_sub)); + temp_priority = temp_priority << 0x04U; + NVIC->IP[nvic_irq] = (uint8_t)temp_priority; + /* enable the selected IRQ */ + NVIC->ISER[nvic_irq >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F); +} + +/*! + \brief disable NVIC request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[out] none + \retval none +*/ +void nvic_irq_disable(uint8_t nvic_irq) +{ + /* disable the selected IRQ.*/ + NVIC->ICER[nvic_irq >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F); +} + +/*! + \brief set the NVIC vector table base address + \param[in] nvic_vict_tab: the RAM or FLASH base address + \arg NVIC_VECTTAB_RAM: RAM base address + \are NVIC_VECTTAB_FLASH: Flash base address + \param[in] offset: Vector Table offset + \param[out] none + \retval none +*/ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset) +{ + SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK); +} + +/*! + \brief set the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up + by all the enable and disable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_set(uint8_t lowpower_mode) +{ + SCB->SCR |= (uint32_t)lowpower_mode; +} + +/*! + \brief reset the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be + woke up by the enable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_reset(uint8_t lowpower_mode) +{ + SCB->SCR &= (~(uint32_t)lowpower_mode); +} + +/*! + \brief set the systick clock source + \param[in] systick_clksource: the systick clock source needed to choose + \arg SYSTICK_CLKSOURCE_HCLK: systick clock source is from HCLK + \arg SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8 + \param[out] none + \retval none +*/ + +void systick_clksource_set(uint32_t systick_clksource) +{ + if(SYSTICK_CLKSOURCE_HCLK == systick_clksource ){ + /* set the systick clock source from HCLK */ + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + }else{ + /* set the systick clock source from HCLK/8 */ + SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8; + } +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_opa.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_opa.c new file mode 100644 index 0000000..9800c26 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_opa.c @@ -0,0 +1,341 @@ +/*! + \file gd32f1x0_opa.c + \brief OPA driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 + +#include "gd32f1x0_opa.h" + +/*! + \brief deinit the OPA register to its default reset value + \param[in] none + \param[out] none + \retval none +*/ +void opa_deinit(void) +{ + rcu_periph_reset_enable(RCU_OPAIVREFRST); + rcu_periph_reset_disable(RCU_OPAIVREFRST); +} + +/*! + \brief enable OPA switch + \param[in] opax_swy + \arg OPA_T3OPA0: T3 switch enable for OPA0 + \arg OPA_S1OPA0: S1 switch enable for OPA0 + \arg OPA_S2OPA0: S2 switch enable for OPA0 + \arg OPA_S3OPA0: S3 switch enable for OPA0 + \arg OPA_T3OPA1: T3 switch enable for OPA1 + \arg OPA_S1OPA1: S1 switch enable for OPA1 + \arg OPA_S2OPA1: S2 switch enable for OPA1 + \arg OPA_S3OPA1: S3 switch enable for OPA1 + \arg OPA_S4OPA1: S4 switch enable for OPA1 + \arg OPA_T3OPA2: T3 switch enable for OPA2 + \arg OPA_S1OPA2: S3 switch enable for OPA2 + \arg OPA_S2OPA2: S3 switch enable for OPA2 + \arg OPA_S3OPA2: S3 switch enable for OPA2 + \param[out] none + \retval none +*/ +void opa_switch_enable(uint32_t opax_swy) +{ + OPA_CTL |= (uint32_t)(opax_swy); +} + +/*! + \brief enable OPA + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[out] none + \retval none +*/ +void opa_enable(uint32_t opa_periph) +{ + if(OPA0 == opa_periph){ + OPA_CTL &= ~OPA_CTL_OPA0PD; + }else if(OPA1 == opa_periph){ + OPA_CTL &= ~OPA_CTL_OPA1PD; + }else{ + OPA_CTL &= ~OPA_CTL_OPA2PD; + } +} + +/*! + \brief disable OPA + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[out] none + \retval none +*/ +void opa_disable(uint32_t opa_periph) +{ + if(OPA0 == opa_periph){ + OPA_CTL |= OPA_CTL_OPA0PD; + }else if(OPA1 == opa_periph){ + OPA_CTL |= OPA_CTL_OPA1PD; + }else{ + OPA_CTL |= OPA_CTL_OPA2PD; + } +} + +/*! + \brief disable OPA switch + \param[in] opax_swy + \arg OPA_T3OPA0: T3 switch enable for OPA0 + \arg OPA_S1OPA0: S1 switch enable for OPA0 + \arg OPA_S2OPA0: S2 switch enable for OPA0 + \arg OPA_S3OPA0: S3 switch enable for OPA0 + \arg OPA_T3OPA1: T3 switch enable for OPA1 + \arg OPA_S1OPA1: S1 switch enable for OPA1 + \arg OPA_S2OPA1: S2 switch enable for OPA1 + \arg OPA_S3OPA1: S3 switch enable for OPA1 + \arg OPA_S4OPA1: S4 switch enable for OPA1 + \arg OPA_T3OPA2: T3 switch enable for OPA2 + \arg OPA_S1OPA2: S3 switch enable for OPA2 + \arg OPA_S2OPA2: S3 switch enable for OPA2 + \arg OPA_S3OPA2: S3 switch enable for OPA2 + \param[out] none + \retval none +*/ +void opa_switch_disable(uint32_t opax_swy) +{ + OPA_CTL &= ~opax_swy; +} + +/*! + \brief enable OPA in low power mode + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[out] none + \retval none +*/ +void opa_low_power_enable(uint32_t opa_periph) +{ + if(OPA0 == opa_periph){ + OPA_CTL &= ~OPA_CTL_OPA0LPM; + }else if(OPA1 == opa_periph){ + OPA_CTL &= ~OPA_CTL_OPA1LPM; + }else{ + OPA_CTL &= ~OPA_CTL_OPA2LPM; + } +} + +/*! + \brief disable OPA in low power mode + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[out] none + \retval none +*/ +void opa_low_power_disable(uint32_t opa_periph) +{ + if(OPA0 == opa_periph){ + OPA_CTL |= OPA_CTL_OPA0LPM; + }else if(OPA1 == opa_periph){ + OPA_CTL |= OPA_CTL_OPA1LPM; + }else{ + OPA_CTL |= OPA_CTL_OPA2LPM; + } +} + +/*! + \brief set OPA power range + \param[in] powerrange + \arg OPA_POWRANGE_LOW: Low power range is selected (VDDA is lower than 3.3V) + \arg OPA_POWRANGE_HIGH: High power range is selected (VDDA is higher than 3.3V) + \param[out] none + \retval none +*/ +void opa_power_range_config(uint32_t powerrange) +{ + OPA_CTL &= ~OPA_CTL_OPA_RANGE; + OPA_CTL |= powerrange; +} + +/*! + \brief set OPA bias trimming mode + \param[in] opa_trimmode + \arg OPA_BT_TRIM_FACTORY: factory trimming values are used for offset calibration + \arg OPA_BT_TRIM_USER: user trimming values are used for offset calibration + \param[out] none + \retval none +*/ +void opa_trim_mode_set(uint32_t opa_trimmode) +{ + OPA_BT &= ~OPA_BT_OT_USER; + OPA_BT |= opa_trimmode; +} + +/*! + \brief set OPA bias trimming value + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[in] opa_input + \arg OPA_INPUT_P: PMOS input is selected to configure the trimming value + \arg OPA_INPUT_N: NMOS input is selected to configure the trimming value + \param[in] opa_trimmode + \arg this parameter can be any value lower or equal to 0x0000001F. + \param[out] none + \retval none +*/ +void opa_trim_value_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue) +{ + uint32_t bt = 0U, ctl = 0U; + ctl = OPA_CTL; + bt = OPA_BT; + + if(OPA0 == opa_periph){ + /* clear the specified opa calibration for N diff and P diff */ + ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H); + /* set the specified opa calibration for N diff or P diff */ + ctl |= opa_input; + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA0_TRIM_LOW); + bt |= (opa_trimvalue); + }else{ + /* clear the specified NMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA0_TRIM_HIGH); + bt |= (opa_trimvalue << 5U); + } + + }else if(OPA1 == opa_periph){ + ctl &= (uint32_t)~(OPA_CTL_OPA1CAL_L | OPA_CTL_OPA1CAL_H); + ctl |= (uint32_t)(opa_input << 8U); + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA1_TRIM_LOW); + bt |= (opa_trimvalue << 10U); + }else{ + /* clear the specified NMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA1_TRIM_HIGH); + bt |= (opa_trimvalue << 15U); + } + }else{ + ctl &= (uint32_t)~(OPA_CTL_OPA2CAL_L | OPA_CTL_OPA2CAL_H); + ctl |= (uint32_t)(opa_input << 16U); + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA2_TRIM_LOW); + bt |= (opa_trimvalue << 20U); + }else{ + /* clear the specified NMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA2_TRIM_HIGH); + bt |= (opa_trimvalue << 25U); + } + } + + OPA_CTL = ctl; + OPA_BT = bt; +} + +/*! + \brief set OPA bias trimming value low power + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[in] opa_input + \arg OPA_INPUT_P: PMOS input is selected to configure the trimming value + \arg OPA_INPUT_N: NMOS input is selected to configure the trimming value + \param[in] opa_trimmode + \arg this parameter can be any value lower or equal to 0x0000001F. + \param[out] none + \retval none +*/ +void opa_trim_value_lp_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue) +{ + uint32_t lpbt = 0U, ctl = 0U; + ctl = OPA_CTL; + lpbt = OPA_LPBT; + + if(OPA0 == opa_periph){ + ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H); + ctl |= opa_input; + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA0_TRIM_LOW); + lpbt |= (opa_trimvalue); + }else{ + /* clear the specified NMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA0_TRIM_HIGH); + lpbt |= (opa_trimvalue << 5U); + } + }else if (OPA1 == opa_periph){ + ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H); + ctl |= (uint32_t)(opa_input << 8U); + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA1_TRIM_LOW); + lpbt |= (opa_trimvalue << 10U); + }else{ + /* clear the specified NMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA1_TRIM_HIGH); + lpbt |= (opa_trimvalue << 15U); + } + + }else{ + ctl &= (uint32_t)~(OPA_CTL_OPA2CAL_L | OPA_CTL_OPA2CAL_H); + ctl |= (uint32_t)(opa_input << 16U); + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA2_TRIM_LOW); + lpbt |= (opa_trimvalue << 20U); + }else{ + /* clear the specified NMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA2_TRIM_HIGH); + lpbt |= (opa_trimvalue << 25U); + } + } + + OPA_CTL = ctl; + OPA_LPBT = lpbt; +} + +/*! + \brief get OPA calibration flag + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[out] none + \retval The state of the OPA calibration flag (SET or RESET) +*/ +FlagStatus opa_cal_out_get(uint32_t opa_periph) +{ + uint32_t data = 0U; + FlagStatus bitstatus = RESET; + data = OPA_CTL; + + if(OPA0 == opa_periph){ + /* get opa0 calibration output bit status */ + if ((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){ + bitstatus = SET; + }else{ + bitstatus = RESET; + } + }else if(OPA1 == opa_periph){ + /* get opa1 calibration output bit status */ + if ((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){ + bitstatus = SET; + }else{ + bitstatus = RESET; + } + }else{ + /* get opa2 calibration output bit status */ + if((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){ + bitstatus = SET; + }else{ + bitstatus = RESET; + } + } + return bitstatus; +} + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_pmu.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_pmu.c new file mode 100644 index 0000000..ee594e6 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_pmu.c @@ -0,0 +1,257 @@ +/*! + \file gd32f1x0_pmu.c + \brief PMU driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_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: + \arg PMU_LVDT_0: voltage threshold is 2.2V (GD32F130_150) or 2.4V (GD32F170_190) + \arg PMU_LVDT_1: voltage threshold is 2.3V (GD32F130_150) or 2.7V (GD32F170_190) + \arg PMU_LVDT_2: voltage threshold is 2.4V (GD32F130_150) or 3.0V (GD32F170_190) + \arg PMU_LVDT_3: voltage threshold is 2.5V (GD32F130_150) or 3.3V (GD32F170_190) + \arg PMU_LVDT_4: voltage threshold is 2.6V (GD32F130_150) or 3.6V (GD32F170_190) + \arg PMU_LVDT_5: voltage threshold is 2.7V (GD32F130_150) or 3.9V (GD32F170_190) + \arg PMU_LVDT_6: voltage threshold is 2.8V (GD32F130_150) or 4.2V (GD32F170_190) + \arg PMU_LVDT_7: voltage threshold is 2.9V (GD32F130_150) or 4.5V (GD32F170_190) + \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 PMU lvd disable + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; +} + +/*! + \brief PMU work at sleep mode + \param[in] sleepmodecmd: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_sleepmode(uint8_t sleepmodecmd) +{ + /* clear sleepdeep bit of Cortex-M3 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + + /* select WFI or WFE command to enter sleep mode */ + if(WFI_CMD == sleepmodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \brief PMU work at deepsleep mode + \param[in] ldo + \arg PMU_LDO_NORMAL: LDO normal work when pmu enter deepsleep mode + \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode + \param[in] deepsleepmodecmd: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd) +{ + static uint32_t reg_snap[ 4 ]; + /* clear stbmod and ldolp bits */ + PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP)); + + /* set ldolp bit according to pmu_ldo */ + PMU_CTL |= ldo; + + /* set sleepdeep bit of Cortex-M3 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + reg_snap[ 0 ] = REG32( 0xE000E010 ); + reg_snap[ 1 ] = REG32( 0xE000E100 ); + reg_snap[ 2 ] = REG32( 0xE000E104 ); + reg_snap[ 3 ] = REG32( 0xE000E108 ); + + REG32( 0xE000E010 ) &= 0x00010004; + REG32( 0xE000E180 ) = 0XB7FFEF19; + REG32( 0xE000E184 ) = 0XFFFFFBFF; + REG32( 0xE000E188 ) = 0xFFFFFFFF; + + /* select WFI or WFE command to enter deepsleep mode */ + if(WFI_CMD == deepsleepmodecmd){ + __WFI(); + }else{ + __SEV(); + __WFE(); + __WFE(); + } + + REG32( 0xE000E010 ) = reg_snap[ 0 ] ; + REG32( 0xE000E100 ) = reg_snap[ 1 ] ; + REG32( 0xE000E104 ) = reg_snap[ 2 ] ; + REG32( 0xE000E108 ) = reg_snap[ 3 ] ; + + /* reset sleepdeep bit of Cortex-M3 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); +} + +/*! + \brief pmu work at standby mode + \param[in] standbymodecmd: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_standbymode(uint8_t standbymodecmd) +{ + /* set sleepdeep bit of Cortex-M3 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* set stbmod bit */ + PMU_CTL |= PMU_CTL_STBMOD; + + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + + /* select WFI or WFE command to enter standby mode */ + if(WFI_CMD == standbymodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \brief clear flag bit + \param[in] flag_reset: + \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag + \arg PMU_FLAG_RESET_STANDBY: reset standby flag + \param[out] none + \retval none +*/ +void pmu_flag_clear(uint32_t flag_reset) +{ + switch(flag_reset){ + case PMU_FLAG_RESET_WAKEUP: + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + break; + case PMU_FLAG_RESET_STANDBY: + /* reset standby flag */ + PMU_CTL |= PMU_CTL_STBRST; + break; + default : + break; + } +} + +/*! + \brief get flag state + \param[in] flag: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \arg PMU_FLAG_LVD: lvd flag + \param[out] none + \retval FlagStatus SET or RESET +*/ +FlagStatus pmu_flag_get(uint32_t flag ) +{ + if(PMU_CS & flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief backup domain write enable + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL |= PMU_CTL_BKPWEN; +} + +/*! + \brief backup domain write disable + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL &= ~PMU_CTL_BKPWEN; +} + +/*! + \brief wakeup pin enable + \param[in] wakeup_pin: + \arg PMU_WAKEUP_PIN0: wakeup pin 0 + \arg PMU_WAKEUP_PIN1: wakeup pin 1 + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin ) +{ + PMU_CS |= wakeup_pin; +} + +/*! + \brief wakeup pin disable + \param[in] wakeup_pin: + \arg PMU_WAKEUP_PIN0: wakeup pin 0 + \arg PMU_WAKEUP_PIN1: wakeup pin 1 + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin ) +{ + PMU_CS &= ~wakeup_pin; + +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rcu.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rcu.c new file mode 100644 index 0000000..02f13de --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rcu.c @@ -0,0 +1,1214 @@ +/*! + \file gd32f1x0_rcu.c + \brief RCU driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_rcu.h" + +#define SEL_IRC8M 0x00U +#define SEL_HXTAL 0x01U +#define SEL_PLL 0x02U + +/* define startup timeout count */ +#define OSC_STARTUP_TIMEOUT ((uint32_t)0xFFFFFU) +#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x3FFFFFFU) + +/*! + \brief deinitialize the RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_deinit(void) +{ + /* enable IRC8M */ + RCU_CTL0 |= RCU_CTL0_IRC8MEN; + while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){ + } + /* reset RCU */ +#ifdef GD32F130_150 + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); +#elif defined (GD32F170_190) + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV | RCU_CFG0_PLLDV); +#endif /* GD32F130_150 */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV); +#ifdef GD32F130_150 + RCU_CFG0 &= ~(RCU_CFG0_USBDPSC); +#endif /* GD32F130_150 */ + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS); + RCU_CFG1 &= ~RCU_CFG1_HXTALPREDV; + RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_CECSEL | RCU_CFG2_ADCSEL); +#ifdef GD32F130_150 + RCU_CTL1 &= ~RCU_CTL1_IRC14MEN; +#elif defined (GD32F170_190) + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CTL1 &= ~RCU_CTL1_IRC28MEN; + RCU_CFG3 &= ~RCU_CFG3_CKOUT1SRC; + RCU_CFG3 &= ~RCU_CFG3_CKOUT1DIV; +#endif /* GD32F130_150 */ + RCU_INT = 0x00000000U; +} + +/*! + \brief enable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + \arg RCU_GPIOx (x=A,B,C,D,F): GPIO ports clock + \arg RCU_DMA: DMA clock + \arg RCU_CRC: CRC clock + \arg RCU_TSI: TSI clock + \arg RCU_CFGCMP: CFGCMP clock + \arg RCU_ADC: ADC clock + \arg RCU_TIMERx (x=0,1,2,5,13,14,15,16): TIMER clock + \arg RCU_SPIx (x=0,1,2): SPI clock + \arg RCU_USARTx (x=0,1): USART clock + \arg RCU_SLCD: SLCD clock, only in GD32F170_190 + \arg RCU_WWDGT: WWDGT clock + \arg RCU_I2Cx (x=0,1,2): I2C clock + \arg RCU_USBD: USBD clock, only in GD32F130_150 + \arg RCU_CANx (x=0,1): CAN clock, only in GD32F170_190 + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC clock + \arg RCU_CEC: CEC clock + \arg RCU_OPAIVREF: OPAIVREF clock, only in GD32F170_190 + \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 + \arg RCU_GPIOx (x=A,B,C,D,F): GPIO ports clock + \arg RCU_DMA: DMA clock + \arg RCU_CRC: CRC clock + \arg RCU_TSI: TSI clock + \arg RCU_CFGCMP: CFGCMP clock + \arg RCU_ADC: ADC clock + \arg RCU_TIMERx (x=0,1,2,5,13,14,15,16): TIMER clock + \arg RCU_SPIx (x=0,1,2): SPI clock + \arg RCU_USARTx (x=0,1): USART clock + \arg RCU_SLCD: SLCD clock, only in GD32F170_190 + \arg RCU_WWDGT: WWDGT clock + \arg RCU_I2Cx (x=0,1,2): I2C clock + \arg RCU_USBD: USBD clock only in GD32F130_150 + \arg RCU_CANx (x=0,1): CAN clock, only in GD32F170_190 + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC clock + \arg RCU_CEC: CEC clock + \arg RCU_OPAIVREF: OPAIVREF clock, only in GD32F170_190 + \arg RCU_RTC: RTC clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_disable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief enable the peripherals clock when sleep mode + \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 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 peripherals + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + \arg RCU_GPIOxRST (x=A,B,C,D,F): reset GPIO ports + \arg RCU_TSIRST: reset TSI + \arg RCU_CFGCMPRST: reset CFGCMP + \arg RCU_ADCRST: reset ADC + \arg RCU_TIMERxRST (x=0,1,2,5,13,14,15,16): reset TIMER + \arg RCU_SPIxRST (x=0,1,2): reset SPI + \arg RCU_USARTxRST (x=0,1): reset USART + \arg RCU_SLCDRST: reset SLCD, only in GD32F170_190 + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_I2CxRST (x=0,1,2): reset I2C + \arg RCU_USBDRST: reset USBD, only in GD32F130_150 + \arg RCU_CANxRST (x=0,1): reset CAN, only in GD32F170_190 + \arg RCU_PMURST: reset PMU + \arg RCU_DACRST: reset DAC + \arg RCU_CECRST: reset CEC + \arg RCU_OPAIVREFRST: reset OPAIVREF, only in GD32F170_190 + \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 + \arg RCU_GPIOxRST (x=A,B,C,D,F): reset GPIO ports + \arg RCU_TSIRST: reset TSI + \arg RCU_CFGCMPRST: reset CFGCMP + \arg RCU_ADCRST: reset ADC + \arg RCU_TIMERxRST (x=0,1,2,5,13,14,15,16): reset TIMER + \arg RCU_SPIxRST (x=0,1,2): reset SPI + \arg RCU_USARTxRST (x=0,1): reset USART + \arg RCU_SLCDRST: reset SLCD, only in GD32F170_190 + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_I2CxRST (x=0,1,2): reset I2C + \arg RCU_USBDRST: reset USBD, only in GD32F130_150 + \arg RCU_CANxRST (x=0,1): reset CAN, only in GD32F170_190 + \arg RCU_PMURST: reset PMU + \arg RCU_DACRST: reset DAC + \arg RCU_CECRST: reset CEC + \arg RCU_OPAIVREFRST: reset OPAIVREF, only in GD32F170_190 + \param[out] none + \retval none +*/ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) &= ~BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief reset the BKP domain + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_enable(void) +{ + RCU_BDCTL |= RCU_BDCTL_BKPRST; +} + +/*! + \brief disable the BKP domain 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 + \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 cksys_source = 0U; + cksys_source = RCU_CFG0; + /* reset the SCS bits and set according to ck_sys */ + cksys_source &= ~RCU_CFG0_SCS; + RCU_CFG0 = (ck_sys | cksys_source); +} + +/*! + \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: select CK_IRC8M as the CK_SYS source + \arg RCU_SCSS_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_SCSS_PLL: select CK_PLL as the CK_SYS source +*/ +uint32_t rcu_system_clock_source_get(void) +{ + return (RCU_CFG0 & 0x0000000CU); +} + +/*! + \brief configure the AHB clock prescaler selection + \param[in] ck_ahb: AHB clock prescaler selection + \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 ahbpsc = 0U; + ahbpsc = RCU_CFG0; + /* reset the AHBPSC bits and set according to ck_ahb */ + ahbpsc &= ~RCU_CFG0_AHBPSC; + RCU_CFG0 = (ck_ahb | ahbpsc); +} + +/*! + \brief configure the APB1 clock prescaler selection + \param[in] ck_apb1: APB1 clock prescaler selection + \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 apb1psc = 0U; + apb1psc = RCU_CFG0; + /* reset the APB1PSC and set according to ck_apb1 */ + apb1psc &= ~RCU_CFG0_APB1PSC; + RCU_CFG0 = (ck_apb1 | apb1psc); +} + +/*! + \brief configure the APB2 clock prescaler selection + \param[in] ck_apb2: APB2 clock prescaler selection + \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 apb2psc = 0U; + apb2psc = RCU_CFG0; + /* reset the APB2PSC and set according to ck_apb2 */ + apb2psc &= ~RCU_CFG0_APB2PSC; + RCU_CFG0 = (ck_apb2 | apb2psc); +} + +/*! + \brief configure the ADC clock prescaler selection + \param[in] ck_adc: ADC clock prescaler selection, refer to rcu_adc_clock_enum + \arg RCU_ADCCK_IRC14M: select CK_IRC14M as CK_ADC, only in GD32F130_150 + \arg RCU_ADCCK_IRC28M_DIV2: select CK_IRC28M/2 as CK_ADC, only in GD32F170_190 + \arg RCU_ADCCK_IRC28M: select CK_IRC28M as CK_ADC, only in GD32F170_190 + \arg RCU_ADCCK_APB2_DIV2: select CK_APB2/2 as CK_ADC + \arg RCU_ADCCK_APB2_DIV4: select CK_APB2/4 as CK_ADC + \arg RCU_ADCCK_APB2_DIV6: select CK_APB2/6 as CK_ADC + \arg RCU_ADCCK_APB2_DIV8: select CK_APB2/8 as CK_ADC + \param[out] none + \retval none +*/ +void rcu_adc_clock_config(rcu_adc_clock_enum ck_adc) +{ + /* reset the ADCPSC, ADCSEL, IRC28MDIV bits */ + RCU_CFG0 &= ~RCU_CFG0_ADCPSC; +#ifdef GD32F130_150 + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; +#elif defined (GD32F170_190) + RCU_CFG2 &= ~(RCU_CFG2_ADCSEL | RCU_CFG2_IRC28MDIV); +#endif /* GD32F130_150 */ + /* set the ADC clock according to ck_adc */ + switch(ck_adc){ +#ifdef GD32F130_150 + case RCU_ADCCK_IRC14M: + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; + break; +#elif defined (GD32F170_190) + case RCU_ADCCK_IRC28M_DIV2: + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_IRC28M: + RCU_CFG2 |= RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; + break; +#endif /* GD32F130_150 */ + case RCU_ADCCK_APB2_DIV2: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV4: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV4; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV6: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV6; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV8: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV8; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + default: + break; + } +} + +#ifdef GD32F130_150 +/*! + \brief configure the USBD clock prescaler selection + \param[in] ck_usbd: USBD clock prescaler selection + \arg RCU_USBD_CKPLL_DIV1_5: select CK_PLL/1.5 as CK_USBD + \arg RCU_USBD_CKPLL_DIV1: select CK_PLL as CK_USBD + \arg RCU_USBD_CKPLL_DIV2_5: select CK_PLL/2.5 as CK_USBD + \arg RCU_USBD_CKPLL_DIV2: select CK_PLL/2 as CK_USBD + \param[out] none + \retval none +*/ +void rcu_usbd_clock_config(uint32_t ck_usbd) +{ + /* reset the USBDPSC bits and set according to ck_usbd */ + RCU_CFG0 &= ~RCU_CFG0_USBDPSC; + RCU_CFG0 |= ck_usbd; +} + +/*! + \brief configure the CK_OUT clock source and divider + \param[in] ckout_src: CK_OUT clock source selection + \arg RCU_CKOUTSRC_NONE: no clock selected + \arg RCU_CKOUTSRC_IRC14M: IRC14M selected + \arg RCU_CKOUTSRC_IRC40K: IRC40K selected + \arg RCU_CKOUTSRC_LXTAL: LXTAL selected + \arg RCU_CKOUTSRC_CKSYS: CKSYS selected + \arg RCU_CKOUTSRC_IRC8M: IRC8M 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); +} +#elif defined (GD32F170_190) +/*! + \brief configure the CK_OUT0 clock source and divider + \param[in] ckout0_src: CK_OUT0 clock source selection + \arg RCU_CKOUT0SRC_NONE: no clock selected + \arg RCU_CKOUT0SRC_IRC28M: IRC28M selected + \arg RCU_CKOUT0SRC_IRC40K: IRC40K selected + \arg RCU_CKOUT0SRC_LXTAL: LXTAL selected + \arg RCU_CKOUT0SRC_CKSYS: CKSYS selected + \arg RCU_CKOUT0SRC_IRC8M: IRC8M selected + \arg RCU_CKOUT0SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT0SRC_CKPLL_DIV1: CK_PLL selected + \arg RCU_CKOUT0SRC_CKPLL_DIV2: CK_PLL/2 selected + \param[in] ckout0_div: CK_OUT0 divider + \arg RCU_CKOUT0_DIVx(x=1,2,4,8,16,32,64,128): CK_OUT0 is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div) +{ + uint32_t ckout0 = 0U; + ckout0 = RCU_CFG0; + /* reset the CKOUT0SEL, CKOUT0DIV and PLLDV bits and set according to ckout0_src and ckout0_div */ + ckout0 &= ~(RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV | RCU_CFG0_PLLDV); + RCU_CFG0 = (ckout0 | ckout0_src | ckout0_div); +} + +/*! + \brief configure the CK_OUT1 clock source and divider + \param[in] ckout1_src: CK_OUT1 clock source selection + \arg RCU_CKOUT1SRC_NONE: no clock selected + \arg RCU_CKOUT1SRC_IRC28M: IRC28M selected + \arg RCU_CKOUT1SRC_IRC40K: IRC40K selected + \arg RCU_CKOUT1SRC_LXTAL: LXTAL selected + \arg RCU_CKOUT1SRC_CKSYS: CKSYS selected + \arg RCU_CKOUT1SRC_IRC8M: IRC8M selected + \arg RCU_CKOUT1SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT1SRC_CKPLL_DIV1: CK_PLL selected + \arg RCU_CKOUT1SRC_CKPLL_DIV2: CK_PLL/2 selected + \param[in] ckout1_div: CK_OUT1 divider + \arg RCU_CKOUT1_DIVx(x=1..64): CK_OUT1 is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div) +{ + uint32_t ckout1 = 0U; + ckout1 = RCU_CFG3; + /* reset the CKOUT1SRC, CKOUT1DIV bits and set according to ckout1_src and ckout1_div */ + ckout1 &= ~(RCU_CFG3_CKOUT1SRC | RCU_CFG3_CKOUT1DIV); + if(RCU_CKOUT1SRC_CKPLL_DIV1 == ckout1_src){ + RCU_CFG0 |= RCU_CFG0_PLLDV; + ckout1_src = CFG3_CKOUT1SRC(7); + }else if(RCU_CKOUT1SRC_CKPLL_DIV2 == ckout1_src){ + RCU_CFG0 &= ~RCU_CFG0_PLLDV; + ckout1_src = CFG3_CKOUT1SRC(7); + }else{ + } + RCU_CFG3 = (ckout1 | ckout1_src | ckout1_div); +} +#endif /* GD32F130_150 */ + +/*! + \brief configure the PLL clock source selection and PLL multiply factor + \param[in] pll_src: PLL clock source selection + \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 + \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 |= (pll_src | pll_mul); +} + +/*! + \brief configure the USART clock source selection + \param[in] ck_usart: USART clock source selection + \arg RCU_USART0SRC_CKAPB2: CK_USART0 select CK_APB2 + \arg RCU_USART0SRC_CKSYS: CK_USART0 select CK_SYS + \arg RCU_USART0SRC_LXTAL: CK_USART0 select CK_LXTAL + \arg RCU_USART0SRC_IRC8M: CK_USART0 select CK_IRC8M + \param[out] none + \retval none +*/ +void rcu_usart_clock_config(uint32_t ck_usart) +{ + /* reset the USART0SEL bits and set according to ck_usart */ + RCU_CFG2 &= ~RCU_CFG2_USART0SEL; + RCU_CFG2 |= ck_usart; +} + +/*! + \brief configure the CEC clock source selection + \param[in] ck_cec: CEC clock source selection + \arg RCU_CECSRC_IRC8M_DIV244: CK_CEC select CK_IRC8M/244 + \arg RCU_CECSRC_LXTAL: CK_CEC select CK_LXTAL + \param[out] none + \retval none +*/ +void rcu_cec_clock_config(uint32_t ck_cec) +{ + /* reset the CECSEL bit and set according to ck_cec */ + RCU_CFG2 &= ~RCU_CFG2_CECSEL; + RCU_CFG2 |= ck_cec; +} + +/*! + \brief configure the RTC clock source selection + \param[in] rtc_clock_source: RTC clock source selection + \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_DIV32: CK_HXTAL/32 selected as RTC source clock + \param[out] none + \retval none +*/ +void rcu_rtc_clock_config(uint32_t rtc_clock_source) +{ + /* reset the RTCSRC bits and set according to rtc_clock_source */ + RCU_BDCTL &= ~RCU_BDCTL_RTCSRC; + RCU_BDCTL |= rtc_clock_source; +} + +#ifdef GD32F170_190 +/*! + \brief configure the SLCD clock source selection + \param[in] slcd_clock_source: SLCD clock source selection + \arg RCU_SLCDSRC_NONE: no clock selected + \arg RCU_SLCDSRC_LXTAL: CK_LXTAL selected as SLCD source clock + \arg RCU_SLCDSRC_IRC40K: CK_IRC40K selected as SLCD source clock + \arg RCU_SLCDSRC_HXTAL_DIV32: CK_HXTAL/32 selected as SLCD source clock + \param[out] none + \retval none +*/ +void rcu_slcd_clock_config(uint32_t slcd_clock_source) +{ + /* reset the bits and set according to rtc_clock_source */ + RCU_BDCTL &= ~RCU_BDCTL_RTCSRC; + RCU_BDCTL |= slcd_clock_source; +} +#endif /* GD32F170_190 */ + +/*! + \brief configure the HXTAL divider used as input of PLL + \param[in] hxtal_prediv: HXTAL divider used as input of PLL + \arg RCU_PLL_HXTAL_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 HXTALPREDV bits and set according to hxtal_prediv */ + prediv &= ~RCU_CFG1_HXTALPREDV; + RCU_CFG1 = (prediv | hxtal_prediv); +} + +/*! + \brief configure the LXTAL drive capability + \param[in] lxtal_dricap: drive capability of LXTAL + \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) +{ + /* reset the LXTALDRI bits and set according to lxtal_dricap */ + RCU_BDCTL &= ~RCU_BDCTL_LXTALDRI; + RCU_BDCTL |= lxtal_dricap; +} + +/*! + \brief get the clock stabilization and periphral reset flags + \param[in] flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum + \arg RCU_FLAG_IRC40KSTB: IRC40K stabilization flag + \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag + \arg RCU_FLAG_IRC8MSTB: IRC8M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_PLLSTB: PLL stabilization flag + \arg RCU_FLAG_IRC14MSTB: IRC14M stabilization flag, only in GD32F130_150 + \arg RCU_FLAG_IRC28MSTB: IRC28M stabilization flag, only in GD32F170_190 + \arg RCU_FLAG_V12RST: V12 domain Power reset flag + \arg RCU_FLAG_OBLRST: Option byte loader reset flag + \arg RCU_FLAG_EPRST: External PIN reset flag + \arg RCU_FLAG_PORRST: Power reset flag + \arg RCU_FLAG_SWRST: Software reset flag + \arg RCU_FLAG_FWDGTRST: Free watchdog timer reset flag + \arg RCU_FLAG_WWDGTRST: Window watchdog timer reset flag + \arg RCU_FLAG_LPRST: Low-power reset flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_flag_get(rcu_flag_enum flag) +{ + if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear 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 + \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_IRC14MSTB: IRC14M stabilization interrupt flag, only in GD32F130_150 + \arg RCU_INT_FLAG_IRC28MSTB: IRC28M stabilization interrupt flag, only in GD32F170_190 + \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) +{ + if(RESET != (RCU_INT & int_flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the interrupt flags + \param[in] int_flag_clear: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum + \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_IRC14MSTB_CLR: IRC14M stabilization interrupt flag clear, only in GD32F130_150 + \arg RCU_INT_FLAG_IRC28MSTB_CLR: IRC28M stabilization interrupt flag clear, only in GD32F170_190 + \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear + \param[out] none + \retval none +*/ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear) +{ + RCU_INT |= (uint32_t)int_flag_clear; +} + +/*! + \brief enable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt enable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable + \arg RCU_INT_IRC14MSTB: IRC14M stabilization interrupt enable, only in GD32F130_150 + \arg RCU_INT_IRC28MSTB: IRC28M stabilization interrupt enable, only in GD32F170_190 + \param[out] none + \retval none +*/ +void rcu_interrupt_enable(rcu_int_enum stab_int) +{ + RCU_INT |= (uint32_t)stab_int; +} + + +/*! + \brief disable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt disable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt disable + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt disable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt disable + \arg RCU_INT_IRC14MSTB: IRC14M stabilization interrupt disable, only in GD32F130_150 + \arg RCU_INT_IRC28MSTB: IRC28M stabilization interrupt disable, only in GD32F170_190 + \param[out] none + \retval none +*/ +void rcu_interrupt_disable(rcu_int_enum stab_int) +{ + RCU_INT &= ~(uint32_t)stab_int; +} + +/*! + \brief wait until oscillator stabilization flags is SET or oscillator startup is timeout + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC14M: IRC14M, only in GD32F130_150 + \arg RCU_IRC28M: IRC28M, only in GD32F170_190 + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: 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; +#ifdef GD32F130_150 + /* wait IRC14M stable */ + case RCU_IRC14M: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC14MSTB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC14MSTB)){ + reval = SUCCESS; + } + break; +#elif defined (GD32F170_190) + /* wait IRC28M stable */ + case RCU_IRC28M: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC28MSTB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC28MSTB)){ + reval = SUCCESS; + } + break; +#endif /* GD32F130_150 */ + /* 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 + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC14M: IRC14M, only in GD32F130_150 + \arg RCU_IRC28M: IRC28M, only in GD32F170_190 + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: 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 + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC14M: IRC14M, only in GD32F130_150 + \arg RCU_IRC28M: IRC28M, only in GD32F170_190 + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: 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 + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) +{ + uint32_t reg; + switch(osci){ + case RCU_HXTAL: + /* HXTALEN must be reset before enable the oscillator bypass mode */ + reg = RCU_CTL0; + RCU_CTL0 &= ~RCU_CTL0_HXTALEN; + RCU_CTL0 = (reg | RCU_CTL0_HXTALBPS); + break; + case RCU_LXTAL: + /* LXTALEN must be reset before enable the oscillator bypass mode */ + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg | RCU_BDCTL_LXTALBPS); + break; + case RCU_IRC8M: +#ifdef GD32F130_150 + case RCU_IRC14M: +#elif defined (GD32F170_190) + case RCU_IRC28M: +#endif /* GD32F130_150 */ + case RCU_IRC40K: + case RCU_PLL_CK: + break; + default: + break; + } +} + +/*! + \brief disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci) +{ + uint32_t reg; + switch(osci){ + case RCU_HXTAL: + /* HXTALEN must be reset before disable the oscillator bypass mode */ + reg = RCU_CTL0; + RCU_CTL0 &= ~RCU_CTL0_HXTALEN; + RCU_CTL0 = (reg & (~RCU_CTL0_HXTALBPS)); + break; + case RCU_LXTAL: + /* LXTALEN must be reset before disable the oscillator bypass mode */ + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL =(reg & (~RCU_BDCTL_LXTALBPS)); + break; + case RCU_IRC8M: +#ifdef GD32F130_150 + case RCU_IRC14M: +#elif defined (GD32F170_190) + case RCU_IRC28M: +#endif /* GD32F130_150 */ + case RCU_IRC40K: + case RCU_PLL_CK: + break; + default: + break; + } +} + +/*! + \brief enable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ + +void rcu_hxtal_clock_monitor_enable(void) +{ + RCU_CTL0 |= RCU_CTL0_CKMEN; +} + +/*! + \brief disable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_disable(void) +{ + RCU_CTL0 &= ~RCU_CTL0_CKMEN; +} + +/*! + \brief set the IRC8M adjust value + \param[in] irc8m_adjval: IRC8M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc8m_adjust_value_set(uint8_t irc8m_adjval) +{ + uint32_t adjust = 0U; + adjust = RCU_CTL0; + /* reset the IRC8MADJ bits and set according to irc8m_adjval */ + adjust &= ~RCU_CTL0_IRC8MADJ; + RCU_CTL0 = (adjust | ((uint32_t)(irc8m_adjval)<<3)); +} + +#ifdef GD32F130_150 +/*! + \brief set the IRC14M adjust value + \param[in] irc14m_adjval: IRC14M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc14m_adjust_value_set(uint8_t irc14m_adjval) +{ + uint32_t adjust = 0U; + adjust = RCU_CTL1; + /* reset the IRC14MADJ bits and set according to irc14m_adjval */ + adjust &= ~RCU_CTL1_IRC14MADJ; + RCU_CTL1 = (adjust | ((uint32_t)(irc14m_adjval)<<3)); +} +#elif defined (GD32F170_190) +/*! + \brief set the IRC28M adjust value + \param[in] irc28m_adjval: IRC28M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc28m_adjust_value_set(uint8_t irc28m_adjval) +{ + uint32_t adjust = 0U; + adjust = RCU_CTL1; + /* reset the IRC28MADJ bits and set according to irc28m_adjval */ + adjust &= ~RCU_CTL1_IRC28MADJ; + RCU_CTL1 = (adjust | ((uint32_t)(irc28m_adjval)<<3)); +} +#endif /* GD32F130_150 */ + +/*! + \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 set voltage in deep sleep mode + \param[in] dsvol: deep sleep mode voltage + \arg RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V, only in GD32F130_150 + \arg RCU_DEEPSLEEP_V_1_1: the core voltage is 1.1V, only in GD32F130_150 + \arg RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V, only in GD32F130_150 + \arg RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V, only in GD32F130_150 + + \arg RCU_DEEPSLEEP_V_1_8: the core voltage is 1.8V, only in GD32F170_190 + \arg RCU_DEEPSLEEP_V_1_6: the core voltage is 1.6V, only in GD32F170_190 + \arg RCU_DEEPSLEEP_V_1_4: the core voltage is 1.4V, only in GD32F170_190 + \arg RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V, only in GD32F170_190 + \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; +} + +#ifdef GD32F130_150 +/*! + \brief set the power down voltage + \param[in] pdvol: power down voltage select + \arg RCU_PDR_V_2_6: power down voltage is 2.6V + \arg RCU_PDR_V_1_8: power down voltage is 1.8V + \param[out] none + \retval none +*/ +void rcu_power_down_voltage_set(uint32_t pdvol) +{ + /* reset the PDRVS bits and set according to pdvol */ + RCU_PDVSEL &= ~RCU_PDVSEL_PDRVS; + RCU_PDVSEL |= pdvol; +} +#endif /* GD32F130_150 */ + +/*! + \brief get the system clock, bus and peripheral clock frequency + \param[in] clock: the clock frequency which to get + \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_ADC: ADC clock frequency + \arg CK_CEC: CEC clock frequency + \arg CK_USART: USART clock frequency + \param[out] none + \retval clock frequency of system, AHB, APB1, APB2, ADC, CEC or USRAT +*/ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) +{ + uint32_t sws = 0U, adcps = 0U, ck_freq = 0U; + uint32_t cksys_freq = 0U, ahb_freq = 0U, apb1_freq = 0U, apb2_freq = 0U; + uint32_t adc_freq = 0U, cec_freq = 0U, usart_freq = 0U; + uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U; + /* exponent of AHB, APB1 and APB2 clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + const uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + const uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC8M is selected as CK_SYS */ + case SEL_IRC8M: + cksys_freq = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + cksys_freq = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case SEL_PLL: + /* get the value of PLLMF[3:0] */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf4 = GET_BITS(RCU_CFG0, 27, 27); + /* high 16 bits */ + if(1U == pllmf4){ + pllmf += 17U; + }else{ + pllmf += 2U; + } + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = GET_BITS(RCU_CFG0, 16, 16); + if(0U != pllsel){ + prediv = (GET_BITS(RCU_CFG1,0, 3) + 1U); + cksys_freq = (HXTAL_VALUE / prediv) * pllmf; + }else{ + cksys_freq = (IRC8M_VALUE >> 1) * 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_ADC: + /* calculate ADC clock frequency */ + if(RCU_ADCSRC_APB2DIV != (RCU_CFG2 & RCU_CFG2_ADCSEL)){ +#ifdef GD32F130_150 + adc_freq = IRC14M_VALUE; +#elif defined (GD32F170_190) + if(RCU_ADC_IRC28M_DIV1 != (RCU_CFG2 & RCU_CFG2_IRC28MDIV)){ + adc_freq = IRC28M_VALUE >> 1; + }else{ + adc_freq = IRC28M_VALUE; + } +#endif /* GD32F130_150 */ + }else{ + /* ADC clock select CK_APB2 divided by 2/4/6/8 */ + adcps = GET_BITS(RCU_CFG0, 14, 15); + switch(adcps){ + case 0: + adc_freq = apb2_freq / 2U; + break; + case 1: + adc_freq = apb2_freq / 4U; + break; + case 2: + adc_freq = apb2_freq / 6U; + break; + case 3: + adc_freq = apb2_freq / 8U; + break; + default: + break; + } + } + ck_freq = adc_freq; + break; + case CK_CEC: + /* calculate CEC clock frequency */ + if(RCU_CECSRC_LXTAL != (RCU_CFG2 & RCU_CFG2_CECSEL)){ + cec_freq = IRC8M_VALUE / 244U; + }else{ + cec_freq = LXTAL_VALUE; + } + ck_freq = cec_freq; + break; + case CK_USART: + /* calculate USART clock frequency */ + if(RCU_USART0SRC_CKAPB2 == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = apb2_freq; + }else if(RCU_USART0SRC_CKSYS == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = cksys_freq; + }else if(RCU_USART0SRC_LXTAL == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = LXTAL_VALUE; + }else if(RCU_USART0SRC_IRC8M == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = IRC8M_VALUE; + }else{ + } + ck_freq = usart_freq; + break; + default: + break; + } + return ck_freq; +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rtc.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rtc.c new file mode 100644 index 0000000..63ac1f5 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rtc.c @@ -0,0 +1,930 @@ +/*! + \file gd32f1x0_rtc.c + \brief RTC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_rtc.h" + +/*! + \brief reset most of the RTC registers + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_deinit(void) +{ + ErrStatus error_status = ERROR; + + /* RTC_TAMP register is not under write protection */ + RTC_TAMP = RTC_REGISTER_RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* reset RTC_CTL register, this can be done without the init mode */ + RTC_CTL &= RTC_REGISTER_RESET; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition. + in order to read calendar from shadow register, not the real registers being reset */ + RTC_TIME = RTC_REGISTER_RESET; + RTC_DATE = RTC_DATE_RESET; + + RTC_PSC = RTC_PSC_RESET; + + /* reset RTC_STAT register, also exit init mode. + at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */ + RTC_STAT = RTC_STAT_RESET; + + /* to write RTC_ALRM0SS register, ALRM0EN bit in RTC_CTL register should be reset as the condition */ + RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM0SS = RTC_REGISTER_RESET; + + /* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */ + RTC_SHIFTCTL = RTC_REGISTER_RESET; + RTC_HRFC = RTC_REGISTER_RESET; + + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief initialize RTC registers + \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + rtc_year: 0x0 - 0x99(BCD format) + rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_date: 0x1 - 0x31(BCD format) + rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose + rtc_minute: 0x0 - 0x59(BCD format) + rtc_second: 0x0 - 0x59(BCD format) + rtc_factor_asyn: 0x0 - 0x7F + rtc_factor_syn: 0x0 - 0x7FFF + rtc_am_pm: RTC_AM, RTC_PM + rtc_display_format: RTC_24HOUR, RTC_12HOUR + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct) +{ + ErrStatus error_status = ERROR; + uint32_t reg_time = 0U, reg_date = 0U; + + reg_date = (DATE_YR(rtc_initpara_struct->rtc_year) | \ + DATE_DOW(rtc_initpara_struct->rtc_day_of_week) | \ + DATE_MON(rtc_initpara_struct->rtc_month) | \ + DATE_DAY(rtc_initpara_struct->rtc_date)); + + reg_time = (rtc_initpara_struct->rtc_am_pm| \ + TIME_HR(rtc_initpara_struct->rtc_hour) | \ + TIME_MN(rtc_initpara_struct->rtc_minute) | \ + TIME_SC(rtc_initpara_struct->rtc_second)); + + /* 1st: disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* 2nd: enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->rtc_factor_asyn)| \ + PSC_FACTOR_S(rtc_initpara_struct->rtc_factor_syn)); + + RTC_TIME = (uint32_t)reg_time; + RTC_DATE = (uint32_t)reg_date; + + RTC_CTL &= (uint32_t)(~RTC_CTL_CS); + RTC_CTL |= rtc_initpara_struct->rtc_display_format; + + /* 3rd: exit init mode */ + rtc_init_mode_exit(); + + /* 4th: wait the RSYNF flag to set */ + error_status = rtc_register_sync_wait(); + } + + /* 5th: enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enter RTC init mode + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init_mode_enter(void) +{ + uint32_t time_index = RTC_INITM_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + /* check whether it has been in init mode */ + if ((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){ + RTC_STAT |= RTC_STAT_INITM; + + /* wait until the INITF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_INITF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + }else{ + error_status = SUCCESS; + } + return error_status; +} + +/*! + \brief exit RTC init mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_init_mode_exit(void) +{ + RTC_STAT &= (uint32_t)(~RTC_STAT_INITM); +} + +/*! + \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow + registers are updated + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_register_sync_wait(void) +{ + volatile uint32_t time_index = RTC_RSYNF_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + if ((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* firstly clear RSYNF flag */ + RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF); + + /* wait until RSYNF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_RSYNF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + }else{ + error_status = SUCCESS; + } + + return error_status; +} + +/*! + \brief get current time and date + \param[in] none + \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + rtc_year: 0x0 - 0x99(BCD format) + rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_date: 0x1 - 0x31(BCD format) + rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose + rtc_minute: 0x0 - 0x59(BCD format) + rtc_second: 0x0 - 0x59(BCD format) + rtc_factor_asyn: 0x0 - 0x7F + rtc_factor_syn: 0x0 - 0x7FFF + rtc_am_pm: RTC_AM, RTC_PM + rtc_display_format: RTC_24HOUR, RTC_12HOUR + \retval none +*/ +void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct) +{ + uint32_t temp_tr = 0U, temp_dr = 0U, temp_pscr = 0U, temp_ctlr = 0U; + + temp_tr = (uint32_t)RTC_TIME; + temp_dr = (uint32_t)RTC_DATE; + temp_pscr = (uint32_t)RTC_PSC; + temp_ctlr = (uint32_t)RTC_CTL; + + /* get current time and construct rtc_parameter_struct structure */ + rtc_initpara_struct->rtc_year = (uint8_t)GET_DATE_YR(temp_dr); + rtc_initpara_struct->rtc_month = (uint8_t)GET_DATE_MON(temp_dr); + rtc_initpara_struct->rtc_date = (uint8_t)GET_DATE_DAY(temp_dr); + rtc_initpara_struct->rtc_day_of_week = (uint8_t)GET_DATE_DOW(temp_dr); + rtc_initpara_struct->rtc_hour = (uint8_t)GET_TIME_HR(temp_tr); + rtc_initpara_struct->rtc_minute = (uint8_t)GET_TIME_MN(temp_tr); + rtc_initpara_struct->rtc_second = (uint8_t)GET_TIME_SC(temp_tr); + rtc_initpara_struct->rtc_factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr); + rtc_initpara_struct->rtc_factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr); + rtc_initpara_struct->rtc_am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM); + rtc_initpara_struct->rtc_display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS); +} + +/*! + \brief get current subsecond value + \param[in] none + \param[out] none + \retval current subsecond value +*/ +uint32_t rtc_subsecond_get(void) +{ + uint32_t reg = 0U; + /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */ + reg = (uint32_t)RTC_SS; + /* read RTC_DATE to unlock the 3 shadow registers */ + (void) (RTC_DATE); + + return reg; +} + +/*! + \brief configure RTC alarm + \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_alarm_minute: 0x0 - 0x59(BCD format) + rtc_alarm_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \param[out] none + \retval none +*/ +void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time) +{ + uint32_t reg_alrm0td = 0U; + + reg_alrm0td = (rtc_alarm_time->rtc_alarm_mask | \ + rtc_alarm_time->rtc_weekday_or_date | \ + rtc_alarm_time->rtc_am_pm | \ + ALRM0TD_DAY(rtc_alarm_time->rtc_alarm_day) | \ + ALRM0TD_HR(rtc_alarm_time->rtc_alarm_hour) | \ + ALRM0TD_MN(rtc_alarm_time->rtc_alarm_minute) | \ + ALRM0TD_SC(rtc_alarm_time->rtc_alarm_second)); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_ALRM0TD = (uint32_t)reg_alrm0td; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure subsecond of RTC alarm + \param[in] mask_subsecond: alarm subsecond mask + \arg RTC_MASKSSC_0_14: mask alarm subsecond configuration + \arg RTC_MASKSSC_1_14: mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared + \arg RTC_MASKSSC_2_14: mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared + \arg RTC_MASKSSC_3_14: mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared + \arg RTC_MASKSSC_4_14: mask RTC_ALRM0SS_SSC[14:4]], and RTC_ALRM0SS_SSC[3:0] is to be compared + \arg RTC_MASKSSC_5_14: mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared + \arg RTC_MASKSSC_6_14: mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared + \arg RTC_MASKSSC_7_14: mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared + \arg RTC_MASKSSC_8_14: mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared + \arg RTC_MASKSSC_9_14: mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared + \arg RTC_MASKSSC_10_14: mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared + \arg RTC_MASKSSC_11_14: mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared + \arg RTC_MASKSSC_12_14: mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared + \arg RTC_MASKSSC_13_14: mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared + \arg RTC_MASKSSC_14: mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared + \arg RTC_MASKSSC_NONE: mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared + \param[in] subsecond: alarm subsecond value(0x000 - 0x7FFF) + \param[out] none + \retval none +*/ +void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_ALRM0SS = mask_subsecond | subsecond; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC alarm + \param[in] none + \param[out] none + \retval none +*/ +void rtc_alarm_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= RTC_CTL_ALRM0EN; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC alarm + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_alarm_disable(void) +{ + volatile uint32_t time_index = RTC_ALRM0WF_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the state of alarm */ + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN); + + /* wait until ALRM0WF flag to be set after the alarm is disabled */ + do{ + flag_status = RTC_STAT & RTC_STAT_ALRM0WF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief get RTC alarm + \param[in] none + \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_alarm_minute: 0x0 - 0x59(BCD format) + rtc_alarm_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time) +{ + uint32_t reg_alrm0td = 0U; + + /* get the value of RTC_ALRM0TD register */ + reg_alrm0td = RTC_ALRM0TD; + + /* get alarm parameters and construct the rtc_alarm_struct structure */ + rtc_alarm_time->rtc_alarm_mask = reg_alrm0td & RTC_ALARM_ALL_MASK; + rtc_alarm_time->rtc_am_pm = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_PM); + rtc_alarm_time->rtc_weekday_or_date = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_DOWS); + rtc_alarm_time->rtc_alarm_day = (uint8_t)GET_ALRM0TD_DAY(reg_alrm0td); + rtc_alarm_time->rtc_alarm_hour = (uint8_t)GET_ALRM0TD_HR(reg_alrm0td); + rtc_alarm_time->rtc_alarm_minute = (uint8_t)GET_ALRM0TD_MN(reg_alrm0td); + rtc_alarm_time->rtc_alarm_second = (uint8_t)GET_ALRM0TD_SC(reg_alrm0td); +} + +/*! + \brief get RTC alarm subsecond + \param[in] none + \param[out] none + \retval RTC alarm subsecond value +*/ +uint32_t rtc_alarm_subsecond_get(void) +{ + return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC)); +} + +/*! + \brief enable RTC time-stamp + \param[in] edge: specify which edge to detect of time-stamp + \arg RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event + \arg RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event + \param[out] none + \retval none +*/ +void rtc_timestamp_enable(uint32_t edge) +{ + uint32_t reg_ctl = 0U; + + /* clear the bits to be configured in RTC_CTL */ + reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN))); + + /* new configuration */ + reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL = (uint32_t)reg_ctl; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC time-stamp + \param[in] none + \param[out] none + \retval none +*/ +void rtc_timestamp_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the TSEN bit */ + RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief get RTC timestamp time and date + \param[in] none + \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains + parameters for RTC time-stamp configuration + members of the structure and the member values are shown as below: + rtc_timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_timestamp_date: 0x1 - 0x31(BCD format) + rtc_timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_timestamp_minute: 0x0 - 0x59(BCD format) + rtc_timestamp_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp) +{ + uint32_t temp_tts = 0U, temp_dts = 0U; + + /* get the value of time_stamp registers */ + temp_tts = (uint32_t)RTC_TTS; + temp_dts = (uint32_t)RTC_DTS; + + /* get timestamp time and construct the rtc_timestamp_struct structure */ + rtc_timestamp->rtc_am_pm = (uint32_t)(temp_tts & RTC_TTS_PM); + rtc_timestamp->rtc_timestamp_month = (uint8_t)GET_DTS_MON(temp_dts); + rtc_timestamp->rtc_timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts); + rtc_timestamp->rtc_timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts); + rtc_timestamp->rtc_timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts); + rtc_timestamp->rtc_timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts); + rtc_timestamp->rtc_timestamp_second = (uint8_t)GET_TTS_SC(temp_tts); +} + +/*! + \brief get RTC time-stamp subsecond + \param[in] none + \param[out] none + \retval RTC time-stamp subsecond value +*/ +uint32_t rtc_timestamp_subsecond_get(void) +{ + return ((uint32_t)RTC_SSTS); +} + +/*! + \brief enable RTC tamper + \param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains + parameters for RTC tamper configuration + members of the structure and the member values are shown as below: + rtc_tamper_source: RTC_TAMPER0, RTC_TAMPER1 + rtc_tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING + RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH + rtc_tamper_filter: RTC_FLT_EDGE, RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S + rtc_tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192, + RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024, + RTC_FREQ_DIV512, RTC_FREQ_DIV256 + rtc_tamper_precharge_enable: DISABLE, ENABLE + rtc_tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C + rtc_tamper_with_timestamp: DISABLE, ENABLE + \param[out] none + \retval none +*/ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~(rtc_tamper->rtc_tamper_source); + + /* tamper filter must be used when the tamper source is voltage level detection */ + RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT; + + /* the tamper source is voltage level detection */ + if(rtc_tamper->rtc_tamper_filter != RTC_FLT_EDGE ){ + RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT); + + /* check if the tamper pin need precharge, if need, then configure the precharge time */ + if(DISABLE == rtc_tamper->rtc_tamper_precharge_enable){ + RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU; + }else{ + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_precharge_time); + } + + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_sample_frequency); + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_filter); + } + + RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS; + + if(DISABLE != rtc_tamper->rtc_tamper_with_timestamp){ + /* the tamper event also cause a time-stamp event */ + RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS; + } + + /* configure the tamper trigger */ + RTC_TAMP &= ((uint32_t)~((rtc_tamper->rtc_tamper_source) << RTC_TAMPER_TRIGGER_POS)); + if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->rtc_tamper_trigger){ + RTC_TAMP |= (uint32_t)((rtc_tamper->rtc_tamper_source)<< RTC_TAMPER_TRIGGER_POS); + } + /* enable tamper */ + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_source); +} + +/*! + \brief disable RTC tamper + \param[in] source: specify which tamper source to be disabled + \arg RTC_TAMPER0 + \arg RTC_TAMPER1 + \param[out] none + \retval none +*/ +void rtc_tamper_disable(uint32_t source) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~source; + +} + +/*! + \brief enable specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be enabled + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_TAMP: tamp interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_enable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enable the interrupts in RTC_CTL register */ + RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE); + /* enable the interrupts in RTC_TAMP register */ + RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disble specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be disabled + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_TAMP: tamp interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_disable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* disable the interrupts in RTC_CTL register */ + RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE); + /* disable the interrupts in RTC_TAMP register */ + RTC_TAMP &= (uint32_t)~(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief check specified flag + \param[in] flag: specify which flag to check + \arg RTC_FLAG_RECALIBRATION: recalibration pending flag + \arg RTC_FLAG_TAMP1: tamper 1 event flag + \arg RTC_FLAG_TAMP0: tamper 0 event flag + \arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag + \arg RTC_FLAG_TIMESTAMP: time-stamp event flag + \arg RTC_FLAG_ALARM0: alarm event flag + \arg RTC_FLAG_INIT: init mode event flag + \arg RTC_FLAG_RSYN: time and date registers synchronized event flag + \arg RTC_FLAG_YCM: year parameter configured event flag + \arg RTC_FLAG_SHIFT: shift operation pending flag + \arg RTC_FLAG_ALARM0_WRITTEN: alarm writen available flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rtc_flag_get(uint32_t flag) +{ + FlagStatus flag_state = RESET; + + if ((uint32_t)RESET != (RTC_STAT & flag)){ + flag_state = SET; + } + return flag_state; +} + +/*! + \brief clear specified flag + \param[in] flag: specify which flag to clear + \arg RTC_FLAG_TAMP1: tamper 1 event flag + \arg RTC_FLAG_TAMP0: tamper 0 event flag + \arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag + \arg RTC_FLAG_TIMESTAMP: time-stamp event flag + \arg RTC_FLAG_ALARM0: alarm event flag + \arg RTC_FLAG_RSYN: time and date registers synchronized event flag + \param[out] none + \retval none +*/ +void rtc_flag_clear(uint32_t flag) +{ + RTC_STAT &= (uint32_t)(~flag); +} + +/*! + \brief configure rtc alternate output source + \param[in] source: specify signal to output + \arg RTC_CALIBRATION_512HZ: when the LXTAL freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \arg RTC_CALIBRATION_1HZ: when the LXTAL freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \arg RTC_ALARM_HIGH: when the alarm flag is set, the output pin is high + \arg RTC_ALARM_LOW: when the Alarm flag is set, the output pin is low + \param[in] mode: specify the output pin (PC13) mode when output alarm signal + \arg RTC_ALARM_OUTPUT_OD: open drain mode + \arg RTC_ALARM_OUTPUT_PP: push pull mode + \param[out] none + \retval none +*/ +void rtc_alter_output_config(uint32_t source, uint32_t mode) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_OS | RTC_CTL_OPOL | RTC_CTL_COS); + + RTC_CTL |= (uint32_t)(source); + + /* alarm output */ + if((uint32_t)RESET != (source & RTC_OS_ENABLE)){ + RTC_TAMP &= (uint32_t)~(RTC_TAMP_PC13VAL); + RTC_TAMP |= (uint32_t)(mode); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief ajust the daylight saving time by adding or substracting one hour from the current time + \param[in] operation: hour ajustment operation + \arg RTC_CTL_A1H: add one hour + \arg RTC_CTL_S1H: substract one hour + \param[out] none + \retval none +*/ +void rtc_hour_adjust(uint32_t operation) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint32_t)(operation); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint8_t)RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint8_t)~RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_enable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL |= (uint32_t)RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief disable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_disable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL &= (uint32_t)~RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief ajust RTC second or subsecond value of current time + \param[in] add: add 1s to current time or not + \arg RTC_SHIFT_ADD1S_RESET: no effect + \arg RTC_SHIFT_ADD1S_SET: add 1s to current time + \param[in] minus: number of subsecond to minus from current time(0x0 - 0x7FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_second_ajust(uint32_t add, uint32_t minus) +{ + uint32_t time_index = RTC_SHIFTCTL_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + uint32_t temp=0U; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a shift operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SOPF; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + temp = RTC_CTL & RTC_CTL_REFEN; + /* check if the function of reference clock detection is disabled */ + if(((uint32_t)RESET == flag_status) && (RESET == temp)){ + RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus)); + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief configure RTC calibration register + \param[in] window: select calibration window + \arg RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz + \param[in] plus: add RTC clock or not + \arg RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock + \arg RTC_CALIBRATION_PLUS_RESET: no effect + \param[in] minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus) +{ + uint32_t time_index = RTC_HRFC_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a calibration operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SCPF; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + if((uint32_t)RESET == flag_status){ + RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus)); + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_slcd.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_slcd.c new file mode 100644 index 0000000..232683c --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_slcd.c @@ -0,0 +1,445 @@ +/*! + \file gd32f1x0_slcd.c + \brief SLCD driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_rcu.h" + +/*! + \brief SLCD reset + \param[in] none + \param[out] none + \retval none +*/ +void slcd_deinit(void) +{ + rcu_periph_reset_enable(RCU_SLCDRST); + rcu_periph_reset_disable(RCU_SLCDRST); +} + +/*! + \brief get the SLCD status flag + \param[in] slcd_flag: the adc status flag bits + \arg SLCD_FLAG_ON: SLCD controller on flag + \arg SLCD_FLAG_SOF: start of frame flag + \arg SLCD_FLAG_UPR: SLCD data update request flag + \arg SLCD_FLAG_UPD: update LCDS data done flag + \arg SLCD_FLAG_VRDY: SLCD voltage ready flag + \arg SLCD_FLAG_SYN: SLCD CFG register synchronization flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus slcd_flag_get(uint8_t slcd_flag) +{ + if(SLCD_STAT & slcd_flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get the SLCD interrupt flag + \param[in] slcd_interrupt: the adc interrupt flag bits + \arg SLCD_INT_FLAG_SOF: start of frame interrupt + \arg SLCD_INT_FLAG_UPD: SLCD update done interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus slcd_interrupt_flag_get(uint8_t slcd_interrupt) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + /* check the interrupt bits */ + switch(slcd_interrupt){ + case SLCD_INT_FLAG_SOF: + state = SLCD_STAT & SLCD_FLAG_SOF; + if((SLCD_CFG & SLCD_CFG_SOFIE) && state){ + interrupt_flag = SET; + } + break; + case SLCD_INT_FLAG_UPD: + state = SLCD_STAT & SLCD_FLAG_UPD; + if((SLCD_CFG & SLCD_CFG_UPDIE) && state){ + interrupt_flag = SET; + } + break; + default: + break; + } + return interrupt_flag; +} + +/*! + \brief clear the SLCD flag + \param[in] slcd_flag: the adc status flag bits + \arg SLCD_FLAG_SOF: start of frame flag + \arg SLCD_FLAG_UPD: update LCDS data done flag + \param[out] none + \retval none +*/ +void slcd_flag_clear(uint8_t slcd_flag) +{ + /* check the interrupt bits */ + switch(slcd_flag){ + case SLCD_FLAG_SOF: + SLCD_STATC |= SLCD_STATC_SOFC; + break; + case SLCD_FLAG_UPD: + SLCD_STATC |= SLCD_STATC_UPDC; + break; + default: + break; + } +} + +/*! + \brief clear the SLCD interrupt flag + \param[in] slcd_interrupt: the adc interrupt bits + \arg SLCD_INT_FLAG_SOF: start of frame interrupt + \arg SLCD_INT_FLAG_UPD: SLCD update done interrupt + \param[out] none + \retval none +*/ +void slcd_interrupt_flag_clear(uint8_t slcd_interrupt) +{ + /* check the interrupt bits */ + switch(slcd_interrupt){ + case SLCD_INT_FLAG_SOF: + SLCD_STATC |= SLCD_STATC_SOFC; + break; + case SLCD_INT_FLAG_UPD: + SLCD_STATC |= SLCD_STATC_UPDC; + break; + default: + break; + } +} + +/*! + \brief the SLCD interrupt config + \param[in] slcd_interrupt: the adc interrupt bits + \arg SLCD_INT_SOF: start of frame interrupt + \arg SLCD_INT_UPD: SLCD update done interrupt + \param[out] none + \retval none +*/ +void slcd_interrupt_config(uint8_t slcd_interrupt,ControlStatus newvalue) +{ + /* ENABLE or DISABLE the interrupt */ + if(newvalue){ + /* select the interrupt source */ + switch(slcd_interrupt){ + case SLCD_INT_SOF: + SLCD_CFG |= (uint32_t) SLCD_CFG_SOFIE; + break; + case SLCD_INT_UPD: + SLCD_CFG |= (uint32_t) SLCD_CFG_UPDIE; + break; + default: + break; + } + }else{ + switch(slcd_interrupt){ + /* select the interrupt source */ + case SLCD_INT_SOF: + SLCD_CFG &= (uint32_t)~(SLCD_CFG_SOFIE); + break; + case SLCD_INT_UPD: + SLCD_CFG &= (uint32_t)~(SLCD_CFG_UPDIE); + break; + default: + break; + } + } +} + +/*! + \brief SLCD bias voltage select + \param[in] bias_voltage: the SLCD voltage bias + \arg SLCD_BIAS_1_4: 1/4 voltage bias + \arg SLCD_BIAS_1_2: 1/2 voltage bias + \arg SLCD_BIAS_1_3: 1/3 voltage bias + \param[out] none + \retval none +*/ +void slcd_bias_voltage_select(uint32_t bias_voltage) +{ + SLCD_CTL &= (uint32_t)~(SLCD_CTL_BIAS); + SLCD_CTL |= (uint32_t)bias_voltage; +} + +/*! + \brief SLCD duty cycle select + \param[in] duty: the adc flag bits + \arg SLCD_DUTY_STATIC: static dutycycle + \arg SLCD_DUTY_1_2: 1/2 dutycycle + \arg SLCD_DUTY_1_3: 1/3 dutycycle + \arg SLCD_DUTY_1_4: 1/4 dutycycle + \arg SLCD_DUTY_1_6: 1/6 dutycycle + \arg SLCD_DUTY_1_8: 1/8 dutycycle + \param[out] none + \retval none +*/ +void slcd_duty_select(uint32_t duty) +{ + SLCD_CTL &= (uint32_t)~(SLCD_CTL_DUTY); + SLCD_CTL |= (uint32_t)duty; +} + +/*! + \brief config the prescaler and the divider of SLCD clock + fSLCD = finclk/( pow( 2 , PRE )* DIV ) + \param[in] prescaler: the prescaler factor + \arg SLCD_PRESCALER_1: PRE = 0 + \arg SLCD_PRESCALER_2: PRE = 1 + \arg SLCD_PRESCALER_4: PRE = 2 + \arg SLCD_PRESCALER_8: PRE = 3 + \arg SLCD_PRESCALER_16: PRE = 4 + \arg SLCD_PRESCALER_32: PRE = 5 + \arg SLCD_PRESCALER_64: PRE = 6 + \arg SLCD_PRESCALER_128: PRE = 7 + \arg SLCD_PRESCALER_256: PRE = 8 + \arg SLCD_PRESCALER_512: PRE = 9 + \arg SLCD_PRESCALER_1024: PRE = 10 + \arg SLCD_PRESCALER_2048: PRE = 11 + \arg SLCD_PRESCALER_4096: PRE = 12 + \arg SLCD_PRESCALER_8192: PRE = 13 + \arg SLCD_PRESCALER_16384: PRE = 14 + \arg SLCD_PRESCALER_32768: PRE = 15 + \param[in] divider: the divider factor + \arg SLCD_DIVIDER_x: x= 16..31 ,DIV = 16..31 + \param[out] none + \retval none +*/ +void slcd_clock_config(uint32_t prescaler,uint32_t divider) +{ + uint32_t cfg; + + /* config the prescaler and the divider */ + cfg = SLCD_CFG; + cfg &= (uint32_t)~(SLCD_CFG_PSC | SLCD_CFG_DIV); + cfg |= (uint32_t)(prescaler | divider); + SLCD_CFG = cfg; +} + +/*! + \brief SLCD blink mode config + \param[in] mode: the prescaler factor + \arg SLCD_BLINKMODE_OFF: blink disabled + \arg SLCD_BLINKMODE_SEG0_COM0: blink enabled on SEG[0], COM[0] + \arg SLCD_BLINKMODE_SEG0_ALLCOM: blink enabled on SEG[0], all COM + \arg SLCD_BLINKMODE_ALLSEG_ALLCOM: blink enabled on all SEG and all COM + \param[in] blink_divider: the divider factor + \arg SLCD_BLINK_FREQUENCY_DIV8: blink frequency = fSLCD/8 + \arg SLCD_BLINK_FREQUENCY_DIV16: blink frequency = fSLCD/16 + \arg SLCD_BLINK_FREQUENCY_DIV32: blink frequency = fSLCD/32 + \arg SLCD_BLINK_FREQUENCY_DIV64: blink frequency = fSLCD/64 + \arg SLCD_BLINK_FREQUENCY_DIV128: blink frequency = fSLCD/128 + \arg SLCD_BLINK_FREQUENCY_DIV256: blink frequency = fSLCD/256 + \arg SLCD_BLINK_FREQUENCY_DIV512: blink frequency = fSLCD/512 + \arg SLCD_BLINK_FREQUENCY_DIV1024: blink frequency = fSLCD/1024 + \param[out] none + \retval none +*/ +void slcd_blink_mode_config(uint32_t mode,uint32_t blink_divider) +{ + SLCD_CFG &= (uint32_t)~(SLCD_CFG_BLKMOD | SLCD_CFG_BLKDIV); + SLCD_CFG |= (uint32_t)(mode | blink_divider); +} + +/*! + \brief SLCD contrast ratio config + \param[in] contrast_ratio: specify the VSLCD voltage ,when chosing the internal voltage source + \arg SLCD_CONTRAST_LEVEL_0: maximum SLCD Voltage = 2.60V + \arg SLCD_CONTRAST_LEVEL_1: maximum SLCD Voltage = 2.73V + \arg SLCD_CONTRAST_LEVEL_2: maximum SLCD Voltage = 2.86V + \arg SLCD_CONTRAST_LEVEL_3: maximum SLCD Voltage = 2.99V + \arg SLCD_CONTRAST_LEVEL_4: maximum SLCD Voltage = 3.12V + \arg SLCD_CONTRAST_LEVEL_5: maximum SLCD Voltage = 3.25V + \arg SLCD_CONTRAST_LEVEL_6: maximum SLCD Voltage = 3.38V + \arg SLCD_CONTRAST_LEVEL_7: maximum SLCD Voltage = 3.51V + \param[out] none + \retval none +*/ +void slcd_contrast_ratio_config(uint32_t contrast_ratio) +{ + uint32_t cfg; + + /* config the contrast ratio */ + cfg = SLCD_CFG; + cfg &= (uint32_t)~(SLCD_CFG_CONR); + cfg |= (uint32_t)contrast_ratio; + SLCD_CFG = cfg; +} + +/*! + \brief SLCD dead time duration config + \param[in] dead_time: configure the length of the dead time between frames + \arg SLCD_DEADTIME_PERIOD_0: no dead time + \arg SLCD_DEADTIME_PERIOD_1: 1 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_2: 2 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_3: 3 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_4: 4 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_5: 5 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_6: 6 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_7: 7 phase inserted between couple of frame + \param[out] none + \retval none +*/ +void slcd_dead_time_config(uint32_t dead_time) +{ + uint32_t cfg; + + /* config dead time duration */ + cfg = SLCD_CFG; + cfg &= (uint32_t)~(SLCD_CFG_DTD); + cfg |= (uint32_t)dead_time; + SLCD_CFG = cfg; +} + +/*! + \brief SLCD pulse on duration config + \param[in] duration: configure the length of the dead time between frames + \arg SLCD_PULSEON_DURATION_0: pulse on duration = 0 + \arg SLCD_PULSEON_DURATION_1: pulse on duration = 1*1/fPRE + \arg SLCD_PULSEON_DURATION_2: pulse on duration = 2*1/fPRE + \arg SLCD_PULSEON_DURATION_3: pulse on duration = 3*1/fPRE + \arg SLCD_PULSEON_DURATION_4: pulse on duration = 4*1/fPRE + \arg SLCD_PULSEON_DURATION_5: pulse on duration = 5*1/fPRE + \arg SLCD_PULSEON_DURATION_6: pulse on duration = 6*1/fPRE + \arg SLCD_PULSEON_DURATION_7: pulse on duration = 7*1/fPRE + \param[out] none + \retval none +*/ +void slcd_pulse_on_duration_config(uint32_t duration) +{ + uint32_t cfg; + + /* config pulse on duration */ + cfg = SLCD_CFG; + cfg &= (uint32_t)~(SLCD_CFG_PULSE); + cfg |= (uint32_t)duration; + SLCD_CFG = cfg; +} + +/*! + \brief SLCD common/segment pad select + \param[in] NewValue: ENABLE or DISABLE + \arg ENABLE: LCD_COM[7:4] pad select LCD_SEG[31:28] + \arg DISABLE: LCD_COM[7:4] pad select LCD_COM[7:4] + \param[out] none + \retval none +*/ +void slcd_com_seg_remap(ControlStatus newvalue) +{ + if( ENABLE == newvalue ){ + SLCD_CTL |= SLCD_CTL_COMS; + }else{ + SLCD_CTL &= ~(SLCD_CTL_COMS); + } +} + +/*! + \brief SLCD voltage source select + \param[in] voltage_source: the SLCD voltage source + \arg SLCD_VOLTAGE_INTERNAL: internal source + \arg SLCD_VOLTAGE_EXTERNAL: external source (VSLCD pin) + \param[out] none + \retval none +*/ +void slcd_voltage_source_select(uint8_t voltage_source) +{ + if( SLCD_VOLTAGE_EXTERNAL == voltage_source ){ + SLCD_CTL |= SLCD_CTL_VSRC; + }else{ + SLCD_CTL &= ~(SLCD_CTL_VSRC); + } +} + +/*! + \brief enable or disable permanent high drive + \param[in] NewValue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void slcd_high_drive_config(ControlStatus newvalue) +{ + if( ENABLE == newvalue ){ + SLCD_CFG |= SLCD_CFG_HDEN; + }else{ + SLCD_CFG &= ~(SLCD_CFG_HDEN); + } +} + +/*! + \brief SLCD voltage source select + \param[in] data_reg: the SLCD data register + \arg SLCD_DATA_REG0: SLCD_DATA register 0 + \arg SLCD_DATA_REG1: SLCD_DATA Register 1 + \arg SLCD_DATA_REG2: SLCD_DATA register 2 + \arg SLCD_DATA_REG3: SLCD_DATA Register 3 + \arg SLCD_DATA_REG4: SLCD_DATA register 4 + \arg SLCD_DATA_REG5: SLCD_DATA Register 5 + \arg SLCD_DATA_REG6: SLCD_DATA register 6 + \arg SLCD_DATA_REG7: SLCD_DATA Register 7 + \param[in] data: the data write to the register + \param[out] none + \retval none +*/ +void slcd_data_register_write(uint32_t data_reg,uint32_t data) +{ + volatile uint32_t *pdata; + + /* point to DATA register */ + pdata = &SLCD_DATA0; + + /* wtite data word to DATA register */ + *(pdata + data_reg) = (uint32_t)data; +} + +/*! + \brief SLCD data update request + \param[in] none + \param[out] none + \retval none +*/ +void slcd_data_update_request(void) +{ + SLCD_STAT |= SLCD_STAT_UPRF; +} + +/*! + \brief enable SLCD interface + \param[in] none + \param[out] none + \retval none +*/ +void slcd_enable(void) +{ + SLCD_CTL |= SLCD_CTL_LCDON; +} + +/*! + \brief disable SLCD interface + \param[in] none + \param[out] none + \retval none +*/ +void slcd_disable(void) +{ + SLCD_CTL &= ~(SLCD_CTL_LCDON); +} + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_spi.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_spi.c new file mode 100644 index 0000000..356e342 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_spi.c @@ -0,0 +1,679 @@ +/*! + \file gd32f1x0_spi.c + \brief SPI driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_spi.h" + +#define SPI_INIT_MASK ((uint32_t)0x00003040U) +#define I2S_INIT_MASK ((uint32_t)0x0000F047U) +#define SPI_I2SPSC_RESET ((uint32_t)0x00000002U) /*!< I2S clock prescaler register reset value */ + +/*! + \brief reset SPI and I2S + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_i2s_deinit(uint32_t spi_periph) +{ + switch(spi_periph){ + case SPI0: + /* reset SPI0 and I2S0 */ + rcu_periph_reset_enable(RCU_SPI0RST); + rcu_periph_reset_disable(RCU_SPI0RST); + break; + case SPI1: + /* reset SPI1 */ + rcu_periph_reset_enable(RCU_SPI1RST); + rcu_periph_reset_disable(RCU_SPI1RST); + break; + case SPI2: + /* reset SPI2 and I2S2 */ + rcu_periph_reset_enable(RCU_SPI2RST); + rcu_periph_reset_disable(RCU_SPI2RST); + break; + default : + break; + } +} + +/*! + \brief initialize SPI parameter + \param[in] spi_periph: SPIx(x=0,1,2) + \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; + + /* select SPI mode */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL); +} + +/*! + \brief enable SPI + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_enable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN; +} + +/*! + \brief disable SPI + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_disable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN); +} + +/*! + \brief configure I2S prescaler + \param[in] spi_periph: SPIx(only x=0,2) + \param[in] audiosample: I2S audio sample rate + \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] frameformat: I2S data length and channel length + \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] mckout: I2S master clock output + \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 audiosample,uint32_t frameformat,uint32_t mckout) +{ + uint32_t i2sdiv = 2U, i2sof = 0U; + uint32_t clks = 0U; + uint32_t i2sclock = 0U; + + /* deinit SPI_I2SPSC register */ + SPI_I2SPSC(spi_periph) = SPI_I2SPSC_RESET; + + /* get system clock */ + i2sclock =rcu_clock_freq_get(CK_SYS); + /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */ + if(I2S_MCKOUT_ENABLE == mckout){ + clks = (uint32_t)(((i2sclock / 256U) * 10U) / audiosample); + }else{ + if(I2S_FRAMEFORMAT_DT16B_CH16B == frameformat){ + clks = (uint32_t)(((i2sclock / 32U) *10U ) / audiosample); + }else{ + clks = (uint32_t)(((i2sclock / 64U) *10U ) / audiosample); + } + } + /* remove the flaoting 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 | 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)frameformat; +} + +/*! + \brief initialize I2S parameter + \param[in] spi_periph: SPIx(only x=0,2) + \param[in] mode: I2S operation mode + \arg I2S_MODE_SLAVETX : I2S slave transmit mode + \arg I2S_MODE_SLAVERX : I2S slave receive mode + \arg I2S_MODE_MASTERTX : I2S master transmit mode + \arg I2S_MODE_MASTERRX : I2S master receive mode + \param[in] standard: I2S standard + \arg I2S_STD_PHILLIPS : I2S phillips standard + \arg I2S_STD_MSB : I2S MSB standard + \arg I2S_STD_LSB : I2S LSB standard + \arg I2S_STD_PCMSHORT : I2S PCM short standard + \arg I2S_STD_PCMLONG : I2S PCM long standard + \param[in] ckpl: I2S idle state clock polarity + \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 mode,uint32_t standard,uint32_t ckpl) +{ + uint32_t reg= 0U; + reg= SPI_I2SCTL(spi_periph); + reg &= I2S_INIT_MASK; + + /* enable I2S */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)mode; + /* select I2S standard */ + reg |= (uint32_t)standard; + /* select I2S polarity */ + reg |= (uint32_t)ckpl; + /* write to SPI_I2SCTL register */ + SPI_I2SCTL(spi_periph) = (uint32_t)reg; +} + +/*! + \brief I2S enable + \param[in] spi_periph: SPIx(x=0,2) + \param[out] none + \retval none +*/ +void i2s_enable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN; +} + +/*! + \brief I2S disable + \param[in] spi_periph: SPIx(x=0,2) + \param[out] none + \retval none +*/ +void i2s_disable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN); +} + +/*! + \brief SPI NSS output enable + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_nss_output_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV; +} + +/*! + \brief SPI NSS output disable + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_nss_output_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV); +} + +/*! + \brief SPI NSS pin high level in software mode + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_nss_internal_high(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS; +} + +/*! + \brief SPI NSS pin low level in software mode + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_nss_internal_low(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS); +} + +/*! + \brief enable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] dma: SPI DMA mode + \arg SPI_DMA_TRANSMIT: SPI transmit data use DMA + \arg SPI_DMA_RECEIVE: SPI receive data use DMA + \param[out] none + \retval none +*/ +void spi_dma_enable(uint32_t spi_periph,uint8_t dma) +{ + if(SPI_DMA_TRANSMIT == dma){ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN; + }else{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN; + } +} + +/*! + \brief disable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] dma: SPI DMA mode + \arg SPI_DMA_TRANSMIT: SPI transmit data use DMA + \arg SPI_DMA_RECEIVE: SPI receive data use DMA + \param[out] none + \retval none +*/ +void spi_dma_disable(uint32_t spi_periph,uint8_t dma) +{ + if(SPI_DMA_TRANSMIT == dma){ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN); + }else{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN); + } +} + +/*! + \brief configure SPI/I2S data frame format + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] frame_format: SPI frame size + \arg SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits + \arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits + \param[out] none + \retval none +*/ +void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format) +{ + /* clear SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16); + /* configure SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) |= (uint32_t)frame_format; +} + +/*! + \brief SPI transmit data + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] data: 16-bit data + \param[out] none + \retval none +*/ +void spi_i2s_data_transmit(uint32_t spi_periph,uint16_t data) +{ + SPI_DATA(spi_periph) = (uint32_t)data; +} + +/*! + \brief SPI receive data + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval 16-bit data +*/ +uint16_t spi_i2s_data_receive(uint32_t spi_periph) +{ + return ((uint16_t)SPI_DATA(spi_periph)); +} + +/*! + \brief configure SPI bidirectional transfer direction + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] transfer_direction: SPI transfer direction + \arg SPI_BIDIRECTIONAL_TRANSMIT: SPI work in transmit-only mode + \arg SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode + \retval none +*/ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction) +{ + if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction){ + /* set the transmit only mode */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT; + }else{ + /* set the receive only mode */ + SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE; + } +} + +/*! + \brief enable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] interrupt: + \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 + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_enable(uint32_t spi_periph,uint8_t interrupt) +{ + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_TBE : + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE; + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_RBNE : + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE; + break; + /* SPI/I2S error */ + case SPI_I2S_INT_ERR : + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE; + break; + default : + break; + } +} + +/*! + \brief disable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] interrupt: + \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 + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_disable(uint32_t spi_periph,uint8_t interrupt) +{ + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_TBE : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE); + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_RBNE : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE); + break; + /* SPI/I2S error */ + case SPI_I2S_INT_ERR : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE); + break; + default : + break; + } +} +/*! + \brief get SPI and I2S interrupt flag status + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] interrupt: SPI/I2S interrupt flag status + \arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt. + \arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt. + \arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt. + \arg SPI_INT_FLAG_CONFERR: config error interrupt. + \arg SPI_INT_FLAG_CRCERR: CRC error interrupt. + \arg I2S_INT_FLAG_TXURERR: underrun error interrupt. + \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; + default : + break; + } + /*get SPI/I2S interrupt flag status */ + if(reg1 && reg2){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get SPI and I2S flag status + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] flag: SPI/I2S flag status + \arg SPI_FLAG_TBE: transmit buffer empty flag. + \arg SPI_FLAG_RBNE: receive buffer not empty flag. + \arg SPI_FLAG_TRANS: transmit on-going flag. + \arg SPI_FLAG_RXORERR: receive overrun error flag. + \arg SPI_FLAG_CONFERR: mode config error flag. + \arg SPI_FLAG_CRCERR: CRC error flag. + \arg 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. + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph,uint32_t flag) +{ + if(SPI_STAT(spi_periph) & flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear SPI CRC error flag status + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_crc_error_clear(uint32_t spi_periph) +{ + SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR); +} + +/*! + \brief turn on CRC function + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_crc_on(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; +} + +/*! + \brief turn off CRC function + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_crc_off(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN); +} + +/*! + \brief set CRC polynomial + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] crc_poly: CRC polynomial value + \param[out] none + \retval none +*/ +void spi_crc_polynomial_set(uint32_t spi_periph,uint16_t crc_poly) +{ + /* set SPI CRC polynomial */ + SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly; +} + +/*! + \brief get SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1,2) + \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 SPI next data is CRC value + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_crc_next(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT; +} + +/*! + \brief get SPI CRC send value or receive value + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] crc: SPI CRC value + \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))); + } +} + +#ifdef GD32F170_190 +/*! + \brief enable quad wire SPI + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ +void qspi_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD; +} + +/*! + \brief disable quad wire SPI + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ +void qspi_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= ~SPI_QCTL_QMOD ; +} + +/*! + \brief enable quad wire SPI write + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ +void qspi_write_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD); +} + +/*! + \brief enable quad wire SPI read + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ +void qspi_read_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD; +} + +/*! + \brief enable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ +void qspi_io23_output_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV; +} + + /*! + \brief disable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ + void qspi_io23_output_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV); +} +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_syscfg.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_syscfg.c new file mode 100644 index 0000000..70be0e7 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_syscfg.c @@ -0,0 +1,214 @@ +/*! + \file gd32f1x0_syscfg.c + \brief SYSCFG driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_syscfg.h" + +/*! + \brief reset the SYSCFG registers + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_deinit(void) +{ + rcu_periph_reset_enable(RCU_CFGCMPRST); + rcu_periph_reset_disable(RCU_CFGCMPRST); +} + +/*! + \brief enable the DMA channels remapping + \param[in] syscfg_dma_remap: specify the DMA channels to remap + \arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0) + \arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2) + \arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2) + \arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1) + \arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1 + \param[out] none + \retval none +*/ +void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap) +{ + SYSCFG_CFG0 |= syscfg_dma_remap; +} + +/*! + \brief disable the DMA channels remapping + \param[in] syscfg_dma_remap: specify the DMA channels to remap + \arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0) + \arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2) + \arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2) + \arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1) + \arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1 + \param[out] none + \retval none +*/ +void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap) +{ + SYSCFG_CFG0 &= ~syscfg_dma_remap; +} + +/*! + \brief enable PB9 high current capability + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_high_current_enable(void) +{ + SYSCFG_CFG0 |= SYSCFG_HIGH_CURRENT_ENABLE; +} + +/*! + \brief disable PB9 high current capability + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_high_current_disable(void) +{ + SYSCFG_CFG0 &= SYSCFG_HIGH_CURRENT_DISABLE; +} + +#ifdef GD32F170_190 +/*! + \brief configure the VLCD intermediate voltage rail + \param[in] vlcd_bias: specify VLCD bias + \arg VLCD_BIAS1_2_RAIL1: VLCD bias is 1/2, using rail1 + \arg VLCD_BIAS1_2_RAIL2: VLCD bias is 1/2, using rail2 + \arg VLCD_BIAS1_2_RAIL3: VLCD bias is 1/2, using rail3 + \arg VLCD_BIAS1_3_RAIL1_2: VLCD bias is 1/3, using rail1 and rail2 + \arg VLCD_BIAS1_3_RAIL1_3: VLCD bias is 1/3, using rail1 and rail3 + \arg VLCD_BIAS1_4_RAILALL: VLCD bias is 1/4, using all rails + \param[out] none + \retval none +*/ +void syscfg_vlcd_rail_config(uint8_t vlcd_bias) +{ + uint32_t cfg1 = SYSCFG_CFG1; + + /* Clear system configuration register 1 */ + SYSCFG_CFG1 = 0U; + + switch(vlcd_bias){ + /* according to VLCD bias, configure rails combination */ + case VLCD_BIAS1_2_RAIL1: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL1; + break; + case VLCD_BIAS1_2_RAIL2: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL2; + break; + case VLCD_BIAS1_2_RAIL3: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3; + break; + case VLCD_BIAS1_3_RAIL1_2: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL2 | SYSCFG_VLCD_RAIL1; + break; + case VLCD_BIAS1_3_RAIL1_3: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3 | SYSCFG_VLCD_RAIL1; + break; + case VLCD_BIAS1_4_RAILALL: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3 | SYSCFG_VLCD_RAIL2 | SYSCFG_VLCD_RAIL1; + break; + default: + SYSCFG_CFG1 = cfg1; + break; + } +} +#endif /* GD32F170_190 */ + +/*! + \brief configure the GPIO pin as EXTI Line + \param[in] exti_port: specify the GPIO port used in EXTI + \arg EXTI_SOURCE_GPIOx(x = A,B,C,D,F): EXTI GPIO port + \param[in] exti_pin: specify the EXTI line + \arg EXTI_SOURCE_PINx(x = 0..15): EXTI GPIO pin + \param[out] none + \retval none +*/ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin) +{ + uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin))); + uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin)); + + switch(exti_pin / EXTI_SS_JSTEP){ + case EXTISS0: + /* clear EXTI source line(0..3) */ + SYSCFG_EXTISS0 &= clear_exti_mask; + /* configure EXTI soure line(0..3) */ + SYSCFG_EXTISS0 |= config_exti_mask; + break; + case EXTISS1: + /* clear EXTI soure line(4..7) */ + SYSCFG_EXTISS1 &= clear_exti_mask; + /* configure EXTI soure line(4..7) */ + SYSCFG_EXTISS1 |= config_exti_mask; + break; + case EXTISS2: + /* clear EXTI soure line(8..11) */ + SYSCFG_EXTISS2 &= clear_exti_mask; + /* configure EXTI soure line(8..11) */ + SYSCFG_EXTISS2 |= config_exti_mask; + break; + case EXTISS3: + /* clear EXTI soure line(12..15) */ + SYSCFG_EXTISS3 &= clear_exti_mask; + /* configure EXTI soure line(12..15) */ + SYSCFG_EXTISS3 |= config_exti_mask; + break; + default: + break; + } +} + +/*! + \brief connect TIMER0/14/15/16 break input to the selected parameter + \param[in] syscfg_lock: Specify the parameter to be connected + \arg SYSCFG_LOCK_LOCKUP: Cortex-M3 lockup output connected to the break input + \arg SYSCFG_LOCK_SRAM_PARITY_ERROR: SRAM_PARITY 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 check if the specified flag in SYSCFG_CFG2 is set or not. + \param[in] syscfg_flag: specify the flag in SYSCFG_CFG2 to check. + \arg SYSCFG_SRAM_PCEF: SRAM parity check error flag. + \param[out] none + \retval the syscfg_flag state returned (SET or RESET). + */ +FlagStatus syscfg_flag_get(uint32_t syscfg_flag) +{ + if((SYSCFG_CFG2 & syscfg_flag) != (uint32_t)RESET){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the flag in SYSCFG_CFG2 by writing 1. + \param[in] syscfg_flag: Specify the flag in SYSCFG_CFG2 to clear. + \arg SYSCFG_SRAM_PCEF: SRAM parity check error flag. + \param[out] none + \retval none +*/ +void syscfg_flag_clear(uint32_t syscfg_flag) +{ + SYSCFG_CFG2 |= (uint32_t) syscfg_flag; +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_timer.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_timer.c new file mode 100644 index 0000000..4dad636 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_timer.c @@ -0,0 +1,1887 @@ +/*! + \file gd32f1x0_timer.c + \brief TIMER driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_timer.h" + +/*! + \brief deinit a timer + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_deinit(uint32_t timer_periph) +{ + switch(timer_periph){ + case TIMER0: + /* reset TIMER0 */ + rcu_periph_reset_enable(RCU_TIMER0RST); + rcu_periph_reset_disable(RCU_TIMER0RST); + break; + case TIMER1: + /* reset TIMER1 */ + rcu_periph_reset_enable(RCU_TIMER1RST); + rcu_periph_reset_disable(RCU_TIMER1RST); + break; + case TIMER2: + /* reset TIMER2 */ + rcu_periph_reset_enable(RCU_TIMER2RST); + rcu_periph_reset_disable(RCU_TIMER2RST); + break; + case TIMER5: + /* reset TIMER5 */ + rcu_periph_reset_enable(RCU_TIMER5RST); + rcu_periph_reset_disable(RCU_TIMER5RST); + break; + case TIMER13: + /* reset TIMER13 */ + rcu_periph_reset_enable(RCU_TIMER13RST); + rcu_periph_reset_disable(RCU_TIMER13RST); + break; + case TIMER14: + /* reset TIMER14 */ + rcu_periph_reset_enable(RCU_TIMER14RST); + rcu_periph_reset_disable(RCU_TIMER14RST); + break; + case TIMER15: + /* reset TIMER15 */ + rcu_periph_reset_enable(RCU_TIMER15RST); + rcu_periph_reset_disable(RCU_TIMER15RST); + break; + case TIMER16: + /* reset TIMER16 */ + rcu_periph_reset_enable(RCU_TIMER16RST); + rcu_periph_reset_disable(RCU_TIMER16RST); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER counter + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] initpara: init parameter struct + prescaler: prescaler value of the counter clock,0~65535 + alignedmode: TIMER_COUNTER_EDGE,TIMER_COUNTER_CENTER_DOWN,TIMER_COUNTER_CENTER_UP,TIMER_COUNTER_CENTER_BOTH + counterdirection: TIMER_COUNTER_UP,TIMER_COUNTER_DOWN + period: counter auto reload value + clockdivision: TIMER_CKDIV_DIV1,TIMER_CKDIV_DIV2,TIMER_CKDIV_DIV4 + repetitioncounter: counter repetition value,0~255 + \param[out] none + \retval none +*/ +void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara) +{ + /* configure the counter prescaler value */ + TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler; + + /* configure the counter direction and aligned mode */ + if((TIMER0 == timer_periph) || (TIMER1 == timer_periph) || (TIMER2 == timer_periph)){ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_DIR|TIMER_CTL0_CAM); + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->alignedmode; + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->counterdirection; + }else{ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_DIR); + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->counterdirection; + } + + /* configure the autoreload value */ + TIMER_CAR(timer_periph) = (uint32_t)initpara->period; + + if((TIMER5 != timer_periph)){ + /* reset the CKDIV bit */ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_CKDIV); + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->clockdivision; + } + + if((TIMER0 == timer_periph) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph)|| (TIMER16 == timer_periph)){ + /* configure the repetition counter value */ + TIMER_CREP(timer_periph) = (uint32_t)initpara->repetitioncounter; + } + + /* generate an update event */ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_PSC_RELOAD_NOW; +} + +/*! + \brief enable a timer + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_COUNTER_ENABLE; +} + +/*! + \brief disable a timer + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (uint32_t)TIMER_COUNTER_DISABLE; +} + +/*! + \brief enable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_ARSE_ENABLE; +} + +/*! + \brief disable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (uint32_t) TIMER_ARSE_DISABLE; +} + +/*! + \brief enable the update event + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_update_event_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_UPDIS_ENABLE; +} + +/*! + \brief disable the update event + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_update_event_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (uint32_t) TIMER_UPDIS_DISABLE; +} + +/*! + \brief set TIMER counter alignment mode + \param[in] timer_periph: TIMERx(x=0,1,2) + \param[in] aligned: + \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,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_counter_up_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_DIR); + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_COUNTER_UP; +} + +/*! + \brief set TIMER counter down direction + \param[in] timer_periph: TIMERx(x=0,1,2) + \param[out] none + \retval none +*/ +void timer_counter_down_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_DIR); + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_COUNTER_DOWN; +} + +/*! + \brief configure TIMER prescaler + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] prescaler: prescaler value + \param[in] pscreload: prescaler reload mode + \arg TIMER_PSC_RELOAD_NOW: the prescaler is loaded right now + \arg TIMER_PSC_RELOAD_UPDATE: the prescaler is loaded at the next update event + \param[out] none + \retval none +*/ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload) +{ + TIMER_PSC(timer_periph) = (uint32_t)prescaler; + + if(TIMER_PSC_RELOAD_NOW == pscreload){ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; + } +} + +/*! + \brief configure TIMER repetition register value + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[in] repetition: the counter repetition value + \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,2,5,13,14,15,16) + \param[in] autoreload: the counter auto-reload value + \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,2,5,13,14,15,16) + \param[in] counter: the counter value + \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,2,5,13,14,15,16) + \param[out] none + \retval counter value +*/ +uint32_t timer_counter_read(uint32_t timer_periph) +{ + uint32_t count_value = 0U; + count_value = TIMER_CNT(timer_periph); + return (count_value); +} + +/*! + \brief read TIMER prescaler value + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval prescaler register value +*/ +uint16_t timer_prescaler_read(uint32_t timer_periph) +{ + uint16_t prescaler_value = 0U; + prescaler_value = (uint16_t)(TIMER_PSC(timer_periph)); + return (prescaler_value); +} + +/*! + \brief configure TIMER single pulse mode + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] spmode: + \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, uint8_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{ + } +} + +/*! + \brief configure TIMER update source + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] update: + \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, uint8_t update) +{ + if(TIMER_UPDATE_SRC_REGULAR == update){ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS; + }else if(update == TIMER_UPDATE_SRC_GLOBAL){ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS; + }else{ + } +} + +/*! + \brief enable the TIMER interrupt + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] interrupt: timer interrupt enable source + \arg TIMER_INT_UP: update interrupt enable + \arg TIMER_INT_CH0: channel 0 interrupt enable + \arg TIMER_INT_CH1: channel 1 interrupt enable + \arg TIMER_INT_CH2: channel 2 interrupt enable + \arg TIMER_INT_CH3: channel 3 interrupt enable + \arg TIMER_INT_CMT: commutation interrupt enable + \arg TIMER_INT_TRG: trigger interrupt enable + \arg TIMER_INT_BRK: break interrupt enable + \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,2,5,13,14,15,16) + \param[in] interrupt: timer interrupt source enable + \arg TIMER_INT_UP: update interrupt enable + \arg TIMER_INT_CH0: channel 0 interrupt enable + \arg TIMER_INT_CH1: channel 1 interrupt enable + \arg TIMER_INT_CH2: channel 2 interrupt enable + \arg TIMER_INT_CH3: channel 3 interrupt enable + \arg TIMER_INT_CMT: commutation interrupt enable + \arg TIMER_INT_TRG: trigger interrupt enable + \arg TIMER_INT_BRK: break interrupt enable + \param[out] none + \retval none +*/ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) &= (uint32_t)(~ interrupt); +} + +/*! + \brief get timer interrupt flag + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] interrupt: the timer interrupt bits + \arg TIMER_INT_FLAG_UP: update interrupt flag + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag + \arg TIMER_INT_FLAG_BRK: break interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt) +{ + uint16_t intval = 0U, intenable = 0U; + + intval = (uint16_t)(TIMER_INTF(timer_periph) & interrupt); + intenable = (uint16_t)(TIMER_DMAINTEN(timer_periph) & interrupt); + + if(((uint16_t)RESET != intval ) && (((uint16_t)RESET) != intenable)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER interrupt flag + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] interrupt: the timer interrupt bits + \arg TIMER_INT_FLAG_UP: update interrupt flag + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag + \arg TIMER_INT_FLAG_BRK: break interrupt flag + \param[out] none + \retval none +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_INTF(timer_periph) &= (uint32_t)(~(uint32_t)interrupt); +} + +/*! + \brief get TIMER flags + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] flag: the timer interrupt flags + \arg TIMER_FLAG_UP: update flag + \arg TIMER_FLAG_CH0: channel 0 flag + \arg TIMER_FLAG_CH1: channel 1 flag + \arg TIMER_FLAG_CH2: channel 2 flag + \arg TIMER_FLAG_CH3: channel 3 flag + \arg TIMER_FLAG_CMT: channel commutation flag + \arg TIMER_FLAG_TRG: trigger flag + \arg TIMER_FLAG_BRK: break flag + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) +{ + if(((uint16_t)RESET) != ((uint16_t)(TIMER_INTF(timer_periph) & flag))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER flags + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] flag: the timer interrupt flags + \arg TIMER_FLAG_UP: update flag + \arg TIMER_FLAG_CH0: channel 0 flag + \arg TIMER_FLAG_CH1: channel 1 flag + \arg TIMER_FLAG_CH2: channel 2 flag + \arg TIMER_FLAG_CH3: channel 3 flag + \arg TIMER_FLAG_CMT: channel commutation flag + \arg TIMER_FLAG_TRG: trigger flag + \arg TIMER_FLAG_BRK: break flag + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag + \param[out] none + \retval none +*/ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag) +{ + TIMER_INTF(timer_periph) &= (uint32_t)(~(uint32_t)flag); +} + +/*! + \brief enable the TIMER DMA + \param[in] timer_periph: TIMERx(x=0,1,2,5,14,15,16) + \param[in] dma: timer DMA source enable + \arg TIMER_DMA_UPD: update DMA enable + \arg TIMER_DMA_CH0D: channel 0 DMA enable + \arg TIMER_DMA_CH1D: channel 1 DMA enable + \arg TIMER_DMA_CH2D: channel 2 DMA enable + \arg TIMER_DMA_CH3D: channel 3 DMA enable + \arg TIMER_DMA_CMTD: channel commutation DMA request enable + \arg TIMER_DMA_TRGD: trigger DMA enable + \param[out] none + \retval none +*/ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; +} + +/*! + \brief disable the TIMER DMA + \param[in] timer_periph: TIMERx(x=0,1,2,5,14,15,16) + \param[in] dma: timer DMA source enable + \arg TIMER_DMA_UPD: update DMA enable + \arg TIMER_DMA_CH0D: channel 0 DMA enable + \arg TIMER_DMA_CH1D: channel 1 DMA enable + \arg TIMER_DMA_CH2D: channel 2 DMA enable + \arg TIMER_DMA_CH3D: channel 3 DMA enable + \arg TIMER_DMA_CMTD: channel commutation DMA request enable + \arg TIMER_DMA_TRGD: trigger DMA enable + \param[out] none + \retval none +*/ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) &= ~(uint32_t)dma; +} + +/*! + \brief channel DMA request source selection + \param[in] timer_periph: TIMERx(x=0,1,2,5,14,15,16) + \param[in] dma_request: channel DMA request source selection + \arg TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel y is sent when channel y event occurs + \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel y is sent when update event occurs + \param[out] none + \retval none +*/ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request) +{ + if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS; + }else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request){ + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_DMAS; + }else{ + } +} + +/*! + \brief configure the TIMER DMA transfer + \param[in] timer_periph: TIMERx(x=0,1,2,5,14,15,16) + \param[in] dma_baseaddr: + \arg TIMER_DMACFG_DMATA_CTL0: DMA transfer address is TIMER_CTL0 + \arg TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1 + \arg TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG + \arg TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN + \arg TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF + \arg TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG + \arg TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0 + \arg TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1 + \arg TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2 + \arg TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT + \arg TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC + \arg TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR + \arg TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP + \arg TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV + \arg TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV + \arg TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV + \arg TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV + \arg TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP + \arg TIMER_DMACFG_DMATA_DMACFG: DMA transfer address is TIMER_DMACFG + \arg TIMER_DMACFG_DMATA_DMATB: DMA transfer address is TIMER_DMATB + \param[in] dma_lenth: + \arg TIMER_DMACFG_DMATC_xTRANSFER(x=1..18): DMA transfer x time + \param[out] none + \retval none +*/ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth) +{ + TIMER_DMACFG(timer_periph) &= (uint32_t)(~(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC)); + TIMER_DMACFG(timer_periph) |= (uint32_t)(dma_baseaddr | dma_lenth); +} + +/*! + \brief software generate events + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] event: the timer software event generation sources + \arg TIMER_EVENT_SRC_UPG: update event generation + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation + \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation + \arg TIMER_EVENT_SRC_TRGG: trigger event generation + \arg TIMER_EVENT_SRC_BRKG: break event generation + \param[out] none + \retval none +*/ +void timer_event_software_generate(uint32_t timer_periph, uint16_t event) +{ + TIMER_SWEVG(timer_periph) |= (uint32_t)event; +} + +/*! + \brief configure TIMER break function + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[in] breakpara: TIMER break parameter struct + runoffstate: TIMER_ROS_STATE_ENABLE,TIMER_ROS_STATE_DISABLE + ideloffstate: TIMER_IOS_STATE_ENABLE,TIMER_IOS_STATE_DISABLE + deadtime: 0~255 + 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,14,15,16) + \param[out] none + \retval none +*/ +void timer_break_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_BREAK_ENABLE; +} + +/*! + \brief disable TIMER break function + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[out] none + \retval none +*/ +void timer_break_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= (uint32_t)TIMER_BREAK_DISABLE; +} + +/*! + \brief enable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[out] none + \retval none +*/ +void timer_automatic_output_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_OUTAUTO_ENABLE; +} + +/*! + \brief disable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[out] none + \retval none +*/ +void timer_automatic_output_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= (uint32_t)TIMER_OUTAUTO_DISABLE; +} + +/*! + \brief configure TIMER primary output function + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_primary_output_config(uint32_t timer_periph,ControlStatus newvalue) +{ + if(newvalue){ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_POEN; + }else{ + TIMER_CCHP(timer_periph) &= (uint32_t)(~ TIMER_CCHP_POEN); + } +} + +/*! + \brief channel capture/compare control shadow register enable + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(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,1,2) + \param[in] ccuctl: channel control shadow register update control + \arg TIMER_UPDATECTL_CCU: the shadow registers update by when CMTG bit is set + \arg TIMER_UPDATECTL_CCUTRI: the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl) +{ + if(TIMER_UPDATECTL_CCU == ccuctl){ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC); + }else if(TIMER_UPDATECTL_CCUTRI == ccuctl){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC; + }else{ + } +} + +/*! + \brief configure TIMER channel output function + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] ocpara: TIMER channeln output parameter struct + outputstate: TIMER_CCX_ENABLE,TIMER_CCX_DISABLE + outputnstate: TIMER_CCXN_ENABLE,TIMER_CCXN_DISABLE + ocpolarity: TIMER_OC_POLARITY_HIGH,TIMER_OC_POLARITY_LOW + ocnpolarity: TIMER_OCN_POLARITY_HIGH,TIMER_OCN_POLARITY_LOW + ocidlestate: TIMER_OC_IDLE_STATE_LOW,TIMER_OC_IDLE_STATE_HIGH + ocnidlestate: TIMER_OCN_IDLE_STATE_LOW,TIMER_OCN_IDLE_STATE_HIGH + \param[out] none + \retval none +*/ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct* ocpara) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0EN); + /* 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) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){ + /* reset the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0NEN); + /* set the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputnstate; + /* reset the CH0NP bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0NP); + /* set the CH0NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocnpolarity; + /* reset the ISO0 bit */ + TIMER_CTL1(timer_periph) &=(uint32_t)(~TIMER_CTL1_ISO0); + /* set the ISO0 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocidlestate; + /* reset the ISO0N bit */ + TIMER_CTL1(timer_periph) &=(uint32_t)(~TIMER_CTL1_ISO0N); + /* set the ISO0N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocnidlestate; + } + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1EN); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 4); + /* 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 << 4); + + if((TIMER0 == timer_periph)){ + /* reset the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1NEN); + /* set the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputnstate << 4); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1NP); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->ocnpolarity << 4); + /* 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 << 2); + /* 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 << 2); + } + 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 << 8); + /* 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 << 8); + + if((TIMER0 == timer_periph)){ + /* reset the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH2NEN); + /* set the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputnstate << 8); + /* reset the CH2NP bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH2NP); + /* set the CH2NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->ocnpolarity << 8); + /* 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 << 4); + /* 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 << 4); + } + 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 << 12); + /* 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 << 12); + + if((TIMER0 == timer_periph)){ + /* reset the ISO3 bit */ + TIMER_CTL1(timer_periph) &=(uint32_t)(~TIMER_CTL1_ISO3); + /* set the ISO3 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)ocpara->ocidlestate << 6); + } + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output compare mode + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] ocmode: channel output compare mode + \arg TIMER_OC_MODE_TIMING: timing mode + \arg TIMER_OC_MODE_ACTIVE: active mode + \arg TIMER_OC_MODE_INACTIVE: inactive mode + \arg TIMER_OC_MODE_TOGGLE: toggle mode + \arg TIMER_OC_MODE_LOW: force low mode + \arg TIMER_OC_MODE_HIGH: force high mode + \arg TIMER_OC_MODE_PWM0: PWM0 mode + \arg TIMER_OC_MODE_PWM1: PWM1 mode + \param[out] none + \retval none +*/ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocmode << 8); + 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 << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output pulse value + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \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; + default: + break; + } +} + +/*! + \brief configure TIMER channel output shadow function + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] ocshadow: channel output shadow state + \arg TIMER_OC_SHADOW_ENABLE: channel output shadow state enable + \arg TIMER_OC_SHADOW_DISABLE: channel output shadow state disable + \param[out] none + \retval none +*/ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocshadow << 8); + 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 << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output fast function + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] ocfast: channel output fast function + \arg TIMER_OC_FAST_ENABLE: channel output fast function enable + \arg TIMER_OC_FAST_DISABLE: channel output fast function disable + \param[out] none + \retval none +*/ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &=(uint32_t)(~TIMER_CHCTL1_CH2COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &=(uint32_t)(~TIMER_CHCTL1_CH3COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output clear function + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] occlear: channel output clear function + \arg TIMER_OC_CLEAR_ENABLE: channel output clear function enable + \arg TIMER_OC_CLEAR_DISABLE: channel output clear function disable + \param[out] none + \retval none +*/ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)occlear << 8); + 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 << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output polarity + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] ocpolarity: channel output polarity + \arg TIMER_OC_POLARITY_HIGH: channel output polarity is high + \arg TIMER_OC_POLARITY_LOW: channel output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 4); + 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 << 8); + 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 << 12); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output polarity + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \param[in] ocnpolarity: channel complementary output polarity + \arg TIMER_OCN_POLARITY_HIGH: channel complementary output polarity is high + \arg TIMER_OCN_POLARITY_LOW: channel complementary output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 4); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH2NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER OCPRE clear source selection + \param[in] timer_periph: TIMERx(x=0,1,2) + \param[in] clear: OCPRE clear source + \arg TIMER_OCPRE_CLEAR_SOURCE_ETIF: OCPRE_CLR_INT is connected to ETIF + \arg TIMER_OCPRE_CLEAR_SOURCE_CLR: OCPRE_CLR_INT is connected to the OCPRE_CLR input + \param[out] none + \retval none +*/ +void timer_ocpre_clear_source_config(uint32_t timer_periph, uint8_t ocpreclear) +{ + if(TIMER_OCPRE_CLEAR_SOURCE_ETIF == ocpreclear){ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_OCRC; + }else if(TIMER_OCPRE_CLEAR_SOURCE_CLR == ocpreclear){ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_OCRC; + }else{ + } +} + +/*! + \brief configure TIMER channel enable state + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] state: TIMER channel enable state + \arg TIMER_CCX_ENABLE: channel enable + \arg TIMER_CCX_DISABLE: channel disable + \param[out] none + \retval none +*/ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_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 << 4); + 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 << 8); + 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 << 12); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output enable state + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \param[in] ocnstate: TIMER channel complementary output enable state + \arg TIMER_CCXN_ENABLE: channel complementary enable + \arg TIMER_CCXN_DISABLE: channel complementary disable + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnstate; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 4); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH2NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER input capture parameter + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] icpara: TIMER channel intput parameter struct + icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING,TIMER_IC_POLARITY_BOTH_EDGE + icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI,TIMER_IC_SELECTION_ITS + icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_capture_config(uint32_t timer_periph,uint16_t channel,timer_ic_parameter_struct* icpara) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0EN); + + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpara->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpara->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(((uint32_t)icpara->icfilter << 4)); + + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1EN); + + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpara->icpolarity << 4); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icpara->icselection << 8); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icpara->icfilter << 12); + + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH2EN); + + /* reset the CH2P and CH2NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH2P|TIMER_CHCTL2_CH2NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpara->icpolarity << 8); + /* reset the CH2MS bit */ + TIMER_CHCTL1(timer_periph) &=(uint32_t)(~TIMER_CHCTL1_CH2MS); + 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<< 4); + + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH3EN); + + /* reset the CH3P bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH3P)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpara->icpolarity << 12); + /* reset the CH3MS bit */ + TIMER_CHCTL1(timer_periph) &=(uint32_t)(~TIMER_CHCTL1_CH3MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)icpara->icselection << 8); + /* reset the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &=(uint32_t)(~TIMER_CHCTL1_CH3CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)icpara->icfilter << 12); + + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN; + break; + default: + break; + } + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, channel,(uint32_t)icpara->icprescaler); +} + +/*! + \brief configure TIMER channel input capture prescaler value + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] prescaler: channel input capture prescaler value + \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, uint32_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 << 8); + 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 << 8); + break; + default: + break; + } +} + +/*! + \brief read TIMER channel capture compare register value + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[out] none + \retval channel capture compare register value +*/ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel) +{ + uint32_t count_value=0U; + + switch(channel){ + case TIMER_CH_0: + count_value = TIMER_CH0CV(timer_periph); + break; + case TIMER_CH_1: + count_value = TIMER_CH1CV(timer_periph); + break; + case TIMER_CH_2: + count_value = TIMER_CH2CV(timer_periph); + break; + case TIMER_CH_3: + count_value = TIMER_CH3CV(timer_periph); + break; + default: + break; + } + return (count_value); +} + +/*! + \brief configure TIMER input pwm capture function + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \param[in] icpwm:TIMER channel intput pwm parameter struct + icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING + icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI + icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm) +{ + uint16_t icpolarity = 0x0U; + uint16_t icselection = 0x0U; + + if(TIMER_IC_POLARITY_RISING == icpwm->icpolarity){ + icpolarity = TIMER_IC_POLARITY_FALLING; + }else{ + icpolarity = TIMER_IC_POLARITY_RISING; + } + + if(TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection){ + icselection = TIMER_IC_SELECTION_INDIRECTTI; + }else{ + icselection = TIMER_IC_SELECTION_DIRECTTI; + } + + if(TIMER_CH_0 == channel){ + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpwm->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpwm->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpwm->icfilter); + /* 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,(uint32_t)icpwm->icprescaler); + + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpolarity << 4); + /* 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 << 8); + /* 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 << 8); + /* 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,(uint32_t)icpwm->icprescaler); + }else{ + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpwm->icpolarity << 4); + /* 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 << 8); + /* 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 << 8); + /* 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,(uint32_t)icpwm->icprescaler); + + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)icpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)icselection; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)icpwm->icfilter; + /* 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,(uint32_t)icpwm->icprescaler); + } +} + +/*! + \brief configure TIMER hall sensor mode + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] hallmode: + \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, uint8_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{ + } +} + +/*! + \brief select TIMER input trigger source + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] intrigger: + \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 + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0 + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1 + \arg TIMER_SMCFG_TRGSEL_ETIFP: external trigger + \param[out] none + \retval none +*/ +void timer_input_trigger_source_select(uint32_t timer_periph,uint32_t intrigger) +{ + TIMER_SMCFG(timer_periph) &=(uint32_t)(~TIMER_SMCFG_TRGS); + TIMER_SMCFG(timer_periph) |= (uint32_t)intrigger; +} + +/*! + \brief select TIMER master mode output trigger source + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] outrigger: + \arg TIMER_TRI_OUT_SRC_RESET: the UPG bit as trigger output + \arg TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output + \arg TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output + \arg TIMER_TRI_OUT_SRC_CH0: a capture or a compare match occurred in channal0 as trigger output TRGO + \arg TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output + \arg TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output + \arg TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output + \arg TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output + \param[out] none + \retval none +*/ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger) +{ + TIMER_CTL1(timer_periph) &=(uint32_t)(~TIMER_CTL1_MMC); + TIMER_CTL1(timer_periph) |= (uint32_t)outrigger; +} + +/*! + \brief select TIMER slave mode + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] slavemode: + \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) +{ + TIMER_SMCFG(timer_periph) &=(uint32_t)(~TIMER_SMCFG_SMC); + + TIMER_SMCFG(timer_periph) |= (uint32_t)slavemode; +} + +/*! + \brief configure TIMER master slave mode + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] masterslave: + \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, uint8_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{ + } +} + +/*! + \brief configure TIMER external trigger input + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] extprescaler: + \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] expolarity: + \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 0x00 and 0x0F + \param[out] none + \retval none +*/ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t expolarity, 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|expolarity); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extfilter << (uint16_t)8); +} + +/*! + \brief configure TIMER quadrature decoder mode + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] decomode: + \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: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[in] ic1polarity: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[out] none + \retval none +*/ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity) +{ + TIMER_SMCFG(timer_periph) &=(uint32_t)(~TIMER_SMCFG_SMC); + TIMER_SMCFG(timer_periph) |= (uint32_t)decomode; + + TIMER_CHCTL0(timer_periph) &= (uint32_t)(((uint32_t)(~TIMER_CHCTL0_CH0MS))&((uint32_t)(~TIMER_CHCTL0_CH1MS))); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI|((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8)); + + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)(ic0polarity|((uint32_t)ic1polarity << 4U)); +} + +/*! + \brief configure TIMER internal clock mode + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[out] none + \retval none +*/ +void timer_internal_clock_config(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= (uint32_t)TIMER_SLAVE_MODE_DISABLE; +} + +/*! + \brief configure TIMER the internal trigger as external clock input + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] intrigger: + \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,2,14) + \param[in] extrigger: + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0 + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1 + \param[in] expolarity: + \arg TIMER_IC_POLARITY_RISING: active low or falling edge active + \arg TIMER_IC_POLARITY_FALLING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t expolarity, uint32_t extfilter) +{ + if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger){ + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1EN); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)expolarity << 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 << 8U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + }else{ + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)expolarity; + /* 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; + /* 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,2) + \param[in] extprescaler: + \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] expolarity: + \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 expolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, expolarity, extfilter); + + /* 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; + + /* reset the TRGS bit */ + TIMER_SMCFG(timer_periph) &=(uint32_t)(~TIMER_SMCFG_TRGS); + /* set the TRGS bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_TRGSEL_ETIFP; +} + +/*! + \brief configure TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0,1,2) + \param[in] extprescaler: + \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] expolarity: + \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 expolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, expolarity, extfilter); + + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief disable TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_disable(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief configure TIMER13 channel0 remap function + \param[in] timer_periph: TIMERx(x=13) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=13)) + \param[in] remap: + \arg TIMER_IRMP_CI0_RMP_GPIO: channel 0 input is connected to GPIO + \arg TIMER_IRMP_CI0_RTCCLK: channel 0 input is connected to the RTCCLK + \arg TIMER_IRMP_CI0_HXTALDIV32: channel 0 input is connected to HXTAL/32 clock + \arg TIMER_IRMP_CI0_CKOUTSEL: channel 0 input is connected to CKOUTSEL + \param[out] none + \retval none +*/ +void timer_channel_remap_config(uint32_t timer_periph, uint16_t channel, uint32_t remap) +{ + if(TIMER_CH_0 == channel){ + TIMER_IRMP(timer_periph) = (uint32_t)remap; + } +} + +#ifdef GD32F170_190 + +/*! + \brief configure TIMER cc register selection + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] ccsel: + \arg TIMER_CHVSEL_DISABLE: write CHxVAL register selection disable + \arg TIMER_CHVSEL_ENABLE: write CHxVAL register selection enable + \param[out] none + \retval none +*/ +void timer_write_cc_register_config(uint32_t timer_periph, uint32_t ccsel) +{ + if(ccsel){ + TIMER_CFG(timer_periph) |= (uint32_t)ccsel; + }else{ + TIMER_CFG(timer_periph) &= (uint32_t)ccsel; + } +} + +/*! + \brief configure TIMER output value selection + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] outsel: + \arg TIMER_OUTSEL_DISABLE: output value selection disable + \arg TIMER_OUTSEL_ENABLE: output value selection enable + \param[out] none + \retval none +*/ +void timer_output_value_selection_config(uint32_t timer_periph, uint32_t outsel) +{ + if(outsel){ + TIMER_CFG(timer_periph) |= (uint32_t)outsel; + }else{ + TIMER_CFG(timer_periph) &= (uint32_t)outsel; + } +} + +#endif /* GD32F170_190 */ diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_tsi.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_tsi.c new file mode 100644 index 0000000..a9b6899 --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_tsi.c @@ -0,0 +1,518 @@ +/*! + \file gd32f1x0_tsi.c + \brief TSI driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_tsi.h" +#include "gd32f1x0_rcu.h" + +/*! + \brief reset TSI peripheral + \param[in] none + \param[out] none + \retval none +*/ +void tsi_deinit(void) +{ + rcu_periph_reset_enable(RCU_TSIRST); + rcu_periph_reset_disable(RCU_TSIRST); +} + +/*! + \brief initialize TSI plus prescaler,charge plus,transfer plus,max cycle number + \param[in] prescaler: CTCLK clock division factor + \arg TSI_CTCDIV_DIV1: fCTCLK = fHCLK + \arg TSI_CTCDIV_DIV2: fCTCLK = fHCLK/2 + \arg TSI_CTCDIV_DIV4: fCTCLK = fHCLK/4 + \arg TSI_CTCDIV_DIV8: fCTCLK = fHCLK/8 + \arg TSI_CTCDIV_DIV16: fCTCLK = fHCLK/16 + \arg TSI_CTCDIV_DIV32: fCTCLK = fHCLK/32 + \arg TSI_CTCDIV_DIV64: fCTCLK = fHCLK/64 + \arg TSI_CTCDIV_DIV128: fCTCLK = fHCLK/128 + \param[in] charge_duration: charge state duration time + \arg TSI_CHARGE_1CTCLK(x=1..16): the duration time of charge state is x CTCLK + \param[in] transfer_duration: charge transfer state duration time + \arg TSI_TRANSFER_xCTCLK(x=1..16): the duration time of transfer state is x CTCLK + \param[in] max_number: max cycle number + \arg TSI_MAXNUM255: the max cycle number of a sequence is 255 + \arg TSI_MAXNUM511: the max cycle number of a sequence is 511 + \arg TSI_MAXNUM1023: the max cycle number of a sequence is 1023 + \arg TSI_MAXNUM2047: the max cycle number of a sequence is 2047 + \arg TSI_MAXNUM4095: the max cycle number of a sequence is 4095 + \arg TSI_MAXNUM8191: the max cycle number of a sequence is 8191 + \arg TSI_MAXNUM16383: the max cycle number of a sequence is 16383 + \param[out] none + \retval none +*/ +void tsi_init(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration,uint32_t max_number) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + uint32_t ctl; + ctl = TSI_CTL; + /*configure TSI clock division factor,charge state duration time,charge transfer state duration time */ + ctl &= ~(TSI_CTL_CTCDIV|TSI_CTL_CTDT|TSI_CTL_CDT|TSI_CTL_MCN); + ctl |= (prescaler|charge_duration|transfer_duration|max_number); + TSI_CTL = ctl; + } +} + +/*! + \brief enable sample pin + \param[in] sample: sample pin + \arg TSI_SAMPCFG_GxPy( x=0..5,y=0..3):pin y of group x is sample pin + \param[out] none + \retval none +*/ +void tsi_sample_pin_enable(uint32_t sample) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + TSI_SAMPCFG |= sample; + } +} + +/*! + \brief disable sample pin + \param[in] sample: sample pin + \arg TSI_SAMPCFG_GxPy( x=0..5,y=0..3): pin y of group x is sample pin + \param[out] none + \retval none +*/ +void tsi_sample_pin_disable(uint32_t sample) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + TSI_SAMPCFG &= ~sample; + } +} + +/*! + \brief enable channel pin + \param[in] channel: channel pin + \arg TSI_CHCFG_GxPy( x=0..5,y=0..3): pin y of group x + \param[out] none + \retval none +*/ +void tsi_channel_pin_enable(uint32_t channel) +{ + TSI_CHCFG |= channel; +} + +/*! + \brief disable channel pin + \param[in] channel: channel pin + \arg TSI_CHCFG_GxPy( x=0..5,y=0..3): pin y of group x + \param[out] none + \retval none +*/ +void tsi_channel_pin_disable(uint32_t channel) +{ + TSI_CHCFG &= ~channel; +} + +/*! + \brief configure charge plus and transfer plus + \param[in] prescaler: CTCLK clock division factor + \arg TSI_CTCDIV_DIV1: fCTCLK = fHCLK + \arg TSI_CTCDIV_DIV2: fCTCLK = fHCLK/2 + \arg TSI_CTCDIV_DIV4: fCTCLK = fHCLK/4 + \arg TSI_CTCDIV_DIV8: fCTCLK = fHCLK/6 + \arg TSI_CTCDIV_DIV16: fCTCLK = fHCLK/8 + \arg TSI_CTCDIV_DIV32: fCTCLK = fHCLK/32 + \arg TSI_CTCDIV_DIV64: fCTCLK = fHCLK/64 + \arg TSI_CTCDIV_DIV128: fCTCLK = fHCLK/128 + \param[in] charge_duration: charge state duration time + \arg TSI_CHARGE_xCTCLK(x=1..16): the duration time of charge state is x CTCLK + \param[in] transfer_duration: charge transfer state duration time + \arg TSI_TRANSFER_xCTCLK(x=1..16): the duration time of transfer state is x CTCLK + \param[out] none + \retval none +*/ +void tsi_plus_config(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + uint32_t ctl; + ctl = TSI_CTL; + /*configure TSI clock division factor,charge state duration time,charge transfer state duration time */ + ctl &= ~(TSI_CTL_CTCDIV|TSI_CTL_CTDT|TSI_CTL_CDT); + ctl |= (prescaler|charge_duration|transfer_duration); + TSI_CTL = ctl; + } +} + +/*! + \brief configure TSI triggering by software + \param[in] none + \param[out] none + \retval none +*/ +void tsi_sofeware_mode_config(void) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + TSI_CTL &= ~TSI_CTL_TRGMOD; + } +} + +/*! + \brief configure TSI triggering by hardware + \param[in] trigger_edge: the edge type in hardware trigger mode + \arg TSI_FALLING_TRIGGER: falling edge trigger TSI charge transfer sequence + \arg TSI_RISING_TRIGGER: rising edge trigger TSI charge transfer sequence + \param[out] none + \retval none +*/ +void tsi_hardware_mode_config(uint8_t trigger_edge) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + /*enable hardware mode*/ + TSI_CTL |= TSI_CTL_TRGMOD; + /*configure the edge type in hardware trigger mode*/ + if(TSI_FALLING_TRIGGER == (uint32_t)trigger_edge){ + TSI_CTL &= ~TSI_CTL_EGSEL; + }else{ + TSI_CTL |= TSI_CTL_EGSEL; + } + } +} + +/*! + \brief configure TSI pin mode when charge-transfer sequence is IDLE + \param[in] pin_mode: pin mode when charge-transfer sequence is IDLE + \arg TSI_OUTPUT_LOW: TSI pin will output low when IDLE + \arg TSI_INPUT_FLOATING: TSI pin will keep input_floating when IDLE + \param[out] none + \retval none +*/ +void tsi_pin_mode_config(uint8_t pin_mode) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + if(TSI_OUTPUT_LOW == pin_mode){ + TSI_CTL &= ~TSI_CTL_PINMOD; + }else{ + TSI_CTL |= TSI_CTL_PINMOD; + } + } +} + +/*! + \brief configure the max cycle number of a charge-transfer sequence + \param[in] max_number: max cycle number + \arg TSI_MAXNUM255: the max cycle number of a sequence is 255 + \arg TSI_MAXNUM511: the max cycle number of a sequence is 511 + \arg TSI_MAXNUM1023: the max cycle number of a sequence is 1023 + \arg TSI_MAXNUM2047: the max cycle number of a sequence is 2047 + \arg TSI_MAXNUM4095: the max cycle number of a sequence is 4095 + \arg TSI_MAXNUM8191: the max cycle number of a sequence is 8191 + \arg TSI_MAXNUM16383: the max cycle number of a sequence is 16383 + \param[out] none + \retval none +*/ +void tsi_max_number_config(uint32_t max_number) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + uint32_t maxnum; + maxnum = TSI_CTL; + /*configure the max cycle number of a charge-transfer sequence*/ + maxnum &= ~TSI_CTL_MCN; + maxnum |= max_number; + TSI_CTL = maxnum; + } +} + +/*! + \brief start a charge-transfer sequence when TSI is in software trigger mode + \param[in] none + \param[out] none + \retval none +*/ +void tsi_software_start(void) +{ + TSI_CTL |= TSI_CTL_TSIS; +} + +/*! + \brief stop a charge-transfer sequence when TSI is in software trigger mode + \param[in] none + \param[out] none + \retval none +*/ +void tsi_software_stop(void) +{ + TSI_CTL &= ~TSI_CTL_TSIS; +} + +/*! + \brief enable TSI module + \param[in] none + \param[out] none + \retval none +*/ +void tsi_enable(void) +{ + TSI_CTL |= TSI_CTL_TSIEN; +} + +/*! + \brief disable TSI module + \param[in] none + \param[out] none + \retval none +*/ +void tsi_disable(void) +{ + TSI_CTL &= ~TSI_CTL_TSIEN; +} + +/*! + \brief configure extend charge state + \param[in] extend: enable or disable extend charge state + \arg ENABLE: enable extend charge state + \arg DISABLE: disable extend charge state + \param[in] prescaler: ECCLK clock division factor + \arg TSI_EXTEND_DIV1: fECCLK = fHCLK + \arg TSI_EXTEND_DIV2: fECCLK = fHCLK/2 + \param[in] max_duration: value range 1...128,extend charge state maximum duration time is 1*tECCLK~128*tECCLK + \param[out] none + \retval none +*/ +void tsi_extend_charge_config(ControlStatus extend,uint8_t prescaler,uint32_t max_duration) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + uint32_t ctl; + if(DISABLE == extend){ + /*disable extend charge state*/ + TSI_CTL &= ~TSI_CTL_ECEN; + }else{ + /*configure extend charge state maximum duration time*/ + ctl = TSI_CTL; + ctl &= ~TSI_CTL_ECDT; + ctl |= TSI_EXTENDMAX((uint32_t)(max_duration-1U)); + TSI_CTL = ctl; + /*configure ECCLK clock division factor*/ + if(TSI_EXTEND_DIV1 == prescaler){ + TSI_CTL &= ~TSI_CTL_ECDIV; + }else{ + TSI_CTL |= TSI_CTL_ECDIV; + } + /*enable extend charge state*/ + TSI_CTL |= TSI_CTL_ECEN; + } + } +} + +/*! + \brief enable TSI interrupt + \param[in] source: select interrupt which will be enabled + \arg TSI_INT_CTCF: charge-transfer complete flag interrupt enable + \arg TSI_INTEN_MNERR: max cycle number error interrupt enable + \param[out] none + \retval none +*/ +void tsi_interrupt_enable(uint32_t source) +{ + TSI_INTEN |= source; +} + +/*! + \brief disable TSI interrupt + \param[in] source: select interrupt which will be disabled + \arg TSI_INT_CTCF: charge-transfer complete flag interrupt disable + \arg TSI_INTEN_MNERR: max cycle number error interrupt disable + \param[out] none + \retval none +*/ +void tsi_interrupt_disable(uint32_t source) +{ + TSI_INTEN &= ~source; +} + +/*! + \brief clear flag + \param[in] source: select flag which will be cleared + \arg TSI_INT_FLAG_CTC: clear charge-transfer complete flag + \arg TSI_INT_FLAG_MNERR: clear max cycle number error + \param[out] none + \retval none +*/ +void tsi_interrupt_flag_clear(uint32_t flag) +{ + TSI_INTC |= flag; +} + +/*! + \brief get TSI module current status + \param[in] status: + \arg TSI_INT_FLAG_CTC: charge-transfer complete flag + \arg TSI_INT_FLAG_MNERR: max Cycle Number Error + \param[out] none + \retval FlagStatus:SET or RESET +*/ +FlagStatus tsi_interrupt_flag_get(uint32_t status) +{ + if(TSI_INTF & status){ + return SET; + } else { + return RESET; + } +} + +/*! + \brief switch on hysteresis pin + \param[in] group_pin: select pin which will be switched on hysteresis + \arg TSI_PHM_GxPy(x=0..5,y=0..3): pin y of group x switch on hysteresis + \param[out] none + \retval none +*/ +void tsi_hysteresis_on(uint32_t group_pin) +{ + TSI_PHM |= group_pin; +} + +/*! + \brief switch off hysteresis pin + \param[in] group_pin: select pin which will be switched off hysteresis + \arg TSI_PHM_GxPy(x=0..5,y=0..3): pin y of group x switch off hysteresis + \param[out] none + \retval none +*/ +void tsi_hysteresis_off(uint32_t group_pin) +{ + TSI_PHM &= ~group_pin; +} + +/*! + \brief switch on analog pin + \param[in] group_pin: select pin which will be switched on analog + \arg TSI_ASW_GxPy(x=0..5,y=0..3):pin y of group x switch on analog + \param[out] none + \retval none +*/ +void tsi_analog_on(uint32_t group_pin) +{ + TSI_ASW |= group_pin; +} + +/*! + \brief switch off analog pin + \param[in] group_pin: select pin which will be switched off analog + \arg TSI_ASW_GxPy(x=0..5,y=0..3):pin y of group x switch off analog + \param[out] none + \retval none +*/ +void tsi_analog_off(uint32_t group_pin) +{ + TSI_ASW &= ~group_pin; +} + +/*! + \brief enbale group + \param[in] group: select group to be enabled + \arg TSI_GCTL_GEx(x=0..5): the x group will be enabled + \param[out] none + \retval none +*/ +void tsi_group_enable(uint32_t group) +{ + TSI_GCTL |= group; +} + +/*! + \brief disbale group + \param[in] group: select group to be disabled + \arg TSI_GCTL_GEx(x=0..5):the x group will be disabled + \param[out] none + \retval none +*/ +void tsi_group_disable(uint32_t group) +{ + TSI_GCTL &= ~group; +} + +/*! + \brief get group complete status + \param[in] group: select group + \arg TSI_GCTL_GCx(x=0..5): get the complete status of group x + \param[out] none + \retval FlagStatus: group complete status,SET or RESET +*/ +FlagStatus tsi_group_status_get(uint32_t group) +{ + if(TSI_GCTL & group){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get the cycle number for group0 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group0 cycle number +*/ +uint16_t tsi_group0_cycle_get(void) +{ + return (uint16_t)TSI_G0CYCN; +} + +/*! + \brief get the cycle number for group1 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group1 cycle number +*/ +uint16_t tsi_group1_cycle_get(void) +{ + return (uint16_t)TSI_G1CYCN; +} + +/*! + \brief get the cycle number for group2 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group2 cycle number +*/ +uint16_t tsi_group2_cycle_get(void) +{ + return (uint16_t)TSI_G2CYCN; +} + +/*! + \brief get the cycle number for group3 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group3 cycle number +*/ +uint16_t tsi_group3_cycle_get(void) +{ + return (uint16_t)TSI_G3CYCN; +} + +/*! + \brief get the cycle number for group4 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group4 cycle number +*/ +uint16_t tsi_group4_cycle_get(void) +{ + return (uint16_t)TSI_G4CYCN; +} + +/*! + \brief get the cycle number for group5 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group5 cycle number +*/ +uint16_t tsi_group5_cycle_get(void) +{ + return (uint16_t)TSI_G5CYCN; +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_usart.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_usart.c new file mode 100644 index 0000000..08410fd --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_usart.c @@ -0,0 +1,1162 @@ +/*! + \file gd32f1x0_usart.c + \brief USART driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.1, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_usart.h" +#include "gd32f1x0_rcu.h" + +/*! + \brief reset USART + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_deinit(uint32_t usart_periph) +{ + switch(usart_periph){ + case USART0: + rcu_periph_reset_enable(RCU_USART0RST); + rcu_periph_reset_disable(RCU_USART0RST); + break; + case USART1: + rcu_periph_reset_enable(RCU_USART1RST); + rcu_periph_reset_disable(RCU_USART1RST); + break; + default: + break; + } +} + +/*! + \brief configure USART baud rate value + \param[in] usart_periph: USARTx(x=0,1) + \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){ + case USART0: + uclk = rcu_clock_freq_get(CK_USART); + break; + case USART1: + uclk = rcu_clock_freq_get(CK_APB1); + break; + default: + break; + } + if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD){ + /* when oversampling by 8,configure the value of USART_BAUD */ + udiv = ((2U*uclk)+baudval/2U)/baudval; + intdiv = udiv & 0xfff0U; + fradiv = (udiv>>1U) & 0x7U; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + }else{ + /* when oversampling by 16,configure the value of USART_BAUD */ + udiv = (uclk+baudval/2U)/baudval; + intdiv = udiv & 0xfff0U; + fradiv = udiv & 0xfU; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } +} + +/*! + \brief configure USART parity + \param[in] usart_periph: USARTx(x=0,1) + \param[in] paritycfg: USART parity configure + \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) + \param[in] wlen: USART word length configure + \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) + \param[in] stblen: USART stop bit configure + \arg USART_STB_1BIT: 1 bit + \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) + \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) + \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) + \param[in] txconfig: enable or disable USART transmitter + \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) + \param[in] rxconfig: enable or disable USART receiver + \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 USART transmit data function + \param[in] usart_periph: USARTx(x=0,1) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void usart_data_transmit(uint32_t usart_periph, uint32_t data) +{ + USART_TDATA(usart_periph) = (USART_TDATA_TDATA & data); +} + +/*! + \brief USART receive data function + \param[in] usart_periph: USARTx(x=0,1) + \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 data is transmitted/received with the LSB/MSB first + \param[in] usart_periph: USARTx(x=0,1) + \param[in] msbf: LSB/MSB + \arg USART_MSBF_LSB: LSB first + \arg USART_MSBF_MSB: MSB first + \param[out] none + \retval none +*/ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* configure LSB or MSB first */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_MSBF); + USART_CTL1(usart_periph) |= (USART_CTL1_MSBF & msbf) ; +} + +/*! + \brief USART inverted configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] invertpara: refer to usart_invert_enum + \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_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_TINV); + break; + case USART_RXPIN_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_RINV); + break; + case USART_SWAP_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_STRP); + break; + case USART_TXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_TINV; + break; + case USART_RXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_RINV; + break; + case USART_SWAP_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_STRP; + break; + default: + break; + } +} + +/*! + \brief overrun function is enabled + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_overrun_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_OVRD); +} + +/*! + \brief overrun function is disabled + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_overrun_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) |= USART_CTL2_OVRD; +} + +/*! + \brief configure the USART oversample mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] oversamp: oversample value + \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 sample bit method configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] osb: sample bit + \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 auto baud rate detection enable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_autobaud_detection_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_ABDEN; +} + +/*! + \brief auto baud rate detection disable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_autobaud_detection_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDEN); +} + +/*! + \brief auto baud rate detection mode configure + \param[in] usart_periph: USARTx(x=0) + \param[in] abdmod: auto baud rate detection mode + \arg USART_ABDM_FTOR: falling edge to rising edge measurement + \arg USART_ABDM_FTOF: falling edge to falling edge measurement + \param[out] none + \retval none +*/ +void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod) +{ + /* reset ABDM bits */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDM); + USART_CTL1(usart_periph) |= (abdmod); +} + +/*! + \brief mute mode enable + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_mute_mode_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_MEN; +} + +/*! + \brief mute mode disable + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_mute_mode_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_MEN); +} + +/*! + \brief wakeup method in mute mode configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] wmethod: two methods be used to enter or exit the mute mode + \arg USART_WM_IDLE: idle line + \arg USART_WM_ADDR: address mark + \param[out] none + \retval none +*/ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL0(usart_periph) &= ~(USART_CTL0_WM); + USART_CTL0(usart_periph) |= wmethod; +} + +/*! + \brief address detection mode configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] addmod: address detection mode + \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 address of the USART terminal + \param[in] usart_periph: USARTx(x=0,1) + \param[in] addr: 0x00-0xFF, address of USART terminal + \param[out] none + \retval none +*/ +void usart_address_config(uint32_t usart_periph, uint8_t addr) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & (((uint32_t)addr) << 24)); +} + +/*! + \brief receiver timeout enable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_RTEN; +} + +/*! + \brief receiver timeout disable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_RTEN); +} + +/*! + \brief receiver timeout threshold configure + \param[in] usart_periph: USARTx(x=0) + \param[in] rtimeout: 0x000000-0xFFFFFF, receiver timeout value in terms of number of baud clocks + \param[out] none + \retval none +*/ +void usart_receiver_timeout_config(uint32_t usart_periph, uint32_t rtimeout) +{ + USART_RT(usart_periph) &= ~(USART_RT_RT); + USART_RT(usart_periph) |= (rtimeout); +} + +/*! + \brief LIN mode enable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_lin_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_LMEN; +} + +/*! + \brief LIN mode disable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_lin_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); +} + +/*! + \brief LIN break detection length + \param[in] usart_periph: USARTx(x=0) + \param[in] lblen: LIN break detection length + \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_dection_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 & (lblen)); +} + +/*! + \brief half-duplex enable + \param[in] usart_periph: USARTx(x=0,1) + \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 half-duplex disable + \param[in] usart_periph: USARTx(x=0,1) + \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 clock enable + \param[in] usart_periph: USARTx(x=0) + \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 clock disable + \param[in] usart_periph: USARTx(x=0) + \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) + \param[in] clen: last bit clock pulse + \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 + \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 + \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 smartcard mode enable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_SCEN; +} + +/*! + \brief smartcard mode disable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN); +} + +/*! + \brief NACK enable in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_NKEN; +} + +/*! + \brief NACK disable in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN); +} + +/*! + \brief guard time value configure in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[in] guat: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_guard_time_config(uint32_t usart_periph, 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 block length configure + \param[in] usart_periph: USARTx(x=0) + \param[in] bl: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl) +{ + USART_RT(usart_periph) &= ~(USART_RT_BL); + USART_RT(usart_periph) |= (USART_RT_BL & ((bl) << 24)); +} + +/*! + \brief smartcard auto-retry number configure + \param[in] usart_periph: USARTx(x=0) + \param[in] scrtnum: 0x0-0x7, 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 IrDA mode enable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_irda_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_IREN; +} + +/*! + \brief IrDA mode disable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_irda_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN); +} + +/*! + \brief IrDA low-power configure + \param[in] usart_periph: USARTx(x=0) + \param[in] irlp: IrDA low-power or normal + \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 & irlp); +} + +/*! + \brief configure the peripheral clock prescaler in USART IrDA low-power mode or in USART SmartCard mode + \param[in] usart_periph: USARTx(x=0) + \param[in] psc: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_prescaler_config(uint32_t usart_periph, 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 hardware flow control RTS + \param[in] usart_periph: USARTx(x=0,1) + \param[in] rtsconfig: enable or disable RTS + \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) + \param[in] ctsconfig: enable or disable CTS + \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 RS485 driver enable + \param[in] usart_periph: USARTx(x=0,1) + \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 RS485 driver disable + \param[in] usart_periph: USARTx(x=0,1) + \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 driver enable assertion time configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] deatime: 0x00-0x1F + \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 driver enable de-assertion time configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dedtime: 0x00-0x1F + \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) + \param[in] dep: DE signal + \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) + \param[in] dmacmd: enable or disable DMA for reception + \arg USART_DENR_ENABLE: DMA enable for reception + \arg USART_DENR_DISABLE: DMA disable for reception + \param[out] none + \retval none +*/ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~USART_CTL2_DENR; + /* configure DMA reception */ + USART_CTL2(usart_periph) |= dmacmd; +} + +/*! + \brief configure USART DMA transmission + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dmacmd: enable or disable DMA for transmission + \arg USART_DENT_ENABLE: DMA enable for transmission + \arg USART_DENT_DISABLE: DMA disable for transmission + \param[out] none + \retval none +*/ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~USART_CTL2_DENT; + /* configure DMA transmission */ + USART_CTL2(usart_periph) |= dmacmd; +} + +/*! + \brief disable DMA on reception error + \param[in] usart_periph: USARTx(x=0,1) + \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) + \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 USART be able to wake up the MCU from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_wakeup_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UESM; +} + +/*! + \brief USART be not able to wake up the MCU from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_wakeup_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UESM); +} + +/*! + \brief wakeup mode from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[in] wum: wakeup mode + \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 get flag in STAT register + \param[in] usart_periph: USARTx(x=0,1) + \param[in] flag: flag type + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise error flag + \arg USART_FLAG_ORERR: overrun error + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_TC: transmission completed + \arg USART_FLAG_TBE: transmit data register empty + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_CTS: CTS level + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_ABDE: auto baudrate detection error + \arg USART_FLAG_ABD: auto baudrate detection flag + \arg USART_FLAG_BSY: busy flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_SB: send break flag + \arg USART_FLAG_RWU: receiver wakeup from mute mode. + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_FLAG_TEA: transmit enable acknowledge flag + \arg USART_FLAG_REA: receive enable acknowledge 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) + \param[in] flag: flag type + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise detected flag + \arg USART_FLAG_ORERR:overrun error flag + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_TC: transmission complete flag + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \param[out] none + \retval none +*/ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) +{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS(flag)); +} + +/*! + \brief enable USART interrupt + \param[in] usart_periph: USARTx(x=0,1) + \param[in] inttype: interrupt type + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and + overrun error interrupt enable interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \param[out] none + \retval none +*/ +void usart_interrupt_enable(uint32_t usart_periph, uint32_t inttype) +{ + USART_REG_VAL(usart_periph, inttype) |= BIT(USART_BIT_POS(inttype)); +} + +/*! + \brief disable USART interrupt + \param[in] usart_periph: USARTx(x=0,1) + \param[in] inttype: interrupt type + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and + overrun error interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \param[out] none + \retval none +*/ +void usart_interrupt_disable(uint32_t usart_periph, uint32_t inttype) +{ + USART_REG_VAL(usart_periph, inttype) &= ~BIT(USART_BIT_POS(inttype)); +} + +/*! + \brief enable USART command + \param[in] usart_periph: USARTx(x=0,1) + \param[in] cmdtype: command type + \arg USART_CMD_ABDCMD: auto baudrate detection command + \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 get USART interrupt and flag status + \param[in] usart_periph: USARTx(x=0,1) + \param[in] int_flag: interrupt and flag type, refer to usart_interrupt_flag_enum + \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 + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t 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 in STAT register + \param[in] usart_periph: USARTx(x=0,1) + \param[in] flag: USART interrupt flag + \arg USART_INT_FLAG_PERR: parity error flag + \arg USART_INT_FLAG_FERR: frame error flag + \arg USART_INT_FLAG_NERR: noise detected flag + \arg USART_INT_FLAG_ORERR:overrun error flag + \arg USART_INT_FLAG_IDLE: idle line detected flag + \arg USART_INT_FLAG_TC: transmission complete flag + \arg USART_INT_FLAG_LBD: LIN break detected flag + \arg USART_INT_FLAG_CTS: CTS change flag + \arg USART_INT_FLAG_RT: receiver timeout flag + \arg USART_INT_FLAG_EB: end of block flag + \arg USART_INT_FLAG_AM: address match flag + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode flag + \param[out] none + \retval none +*/ +void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t flag) +{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS2(flag)); +} diff --git a/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_wwdgt.c b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_wwdgt.c new file mode 100644 index 0000000..7a762cc --- /dev/null +++ b/Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_wwdgt.c @@ -0,0 +1,121 @@ +/*! + \file gd32f1x0_wwdgt.c + \brief WWDGT driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_rcu.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 configure the window watchdog timer counter value + \param[in] counter_value: 0x00 - 0x7F + \param[out] none + \retval none +*/ +void wwdgt_counter_update(uint16_t counter_value) +{ + uint32_t reg = 0U; + + reg = WWDGT_CTL & (~WWDGT_CTL_CNT); + reg |= (uint32_t)(CTL_CNT((uint32_t)counter_value)); + + WWDGT_CTL = (uint32_t)reg; +} + +/*! + \brief start the window watchdog timer counter + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_enable(void) +{ + WWDGT_CTL |= WWDGT_CTL_WDGTEN; +} + +/*! + \brief configure counter value, window value, and prescaler divider value + \param[in] counter: 0x00 - 0x7F + \param[in] window: 0x00 - 0x7F + \param[in] prescaler: wwdgt prescaler value + \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) +{ + uint32_t reg_cfg = 0U, reg_ctl = 0U; + + /* clear WIN and PSC bits, clear CNT bit */ + reg_cfg = WWDGT_CFG &(~(WWDGT_CFG_WIN | WWDGT_CFG_PSC)); + reg_ctl = WWDGT_CTL &(~(uint32_t)WWDGT_CTL_CNT); + + /* configure WIN and PSC bits, configure CNT bit */ + reg_cfg |= (uint32_t)(CFG_WIN(window)); + reg_cfg |= (uint32_t)(prescaler); + reg_ctl |= (uint32_t)(CTL_CNT(counter)); + + WWDGT_CFG = (uint32_t)reg_cfg; + WWDGT_CTL = (uint32_t)reg_ctl; +} + +/*! + \brief enable early wakeup interrupt of WWDGT + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_interrupt_enable(void) +{ + WWDGT_CFG |= WWDGT_CFG_EWIE; +} + +/*! + \brief check early wakeup interrupt state of WWDGT + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus wwdgt_flag_get(void) +{ + if(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)(~(uint32_t)WWDGT_STAT_EWIF); +} diff --git a/GD32F130C6_FLASH.ld b/GD32F130C6_FLASH.ld new file mode 100644 index 0000000..b72fec0 --- /dev/null +++ b/GD32F130C6_FLASH.ld @@ -0,0 +1,139 @@ +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20000400; + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x400; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K + MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .ARM.attributes 0 : { *(.ARM.attributes) } + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = .; + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : AT ( _sidata ) + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + PROVIDE ( end = _ebss ); + PROVIDE ( _end = _ebss ); + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(4); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(4); + } >RAM + + /* MEMORY_bank1 section, code must be located here explicitly */ + /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */ + .memory_b1_text : + { + *(.mb1text) /* .mb1text sections (code) */ + *(.mb1text*) /* .mb1text* sections (code) */ + *(.mb1rodata) /* read-only data (constants) */ + *(.mb1rodata*) + } >MEMORY_B1 + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } +} diff --git a/Inc/config.h b/Inc/config.h new file mode 100644 index 0000000..e96db1a --- /dev/null +++ b/Inc/config.h @@ -0,0 +1,90 @@ +/** + * This file is part of the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +// Define to prevent recursive inclusion +#ifndef CONFIG_H +#define CONFIG_H + +/* ==================================== VARIANT SELECTION ==================================== */ +#if !defined(PLATFORMIO) + #define VARIANT_DEBUG // Variant for debugging and checking the capabilities of the side-board + //#define VARIANT_HOVERBOARD // Variant for using the side-boards connected to the Hoverboard mainboard +#endif + +/* ==================================== DO NOT TOUCH SETTINGS ==================================== */ +#define MPU6050 // [-] Define IMU sensor type +#define MPU_GYRO_FSR 2000 // [deg/s] Set Gyroscope Full Scale Range: 250 deg/s, 500 deg/s, 1000 deg/s, 2000 deg/s. !! DMP sensor fusion works only with 2000 deg/s !! +#define MPU_ACCEL_FSR 2 // [g] Set Acceleromenter Full Scale Range: 2g, 4g, 8g, 16g. !! DMP sensor fusion works only with 2g !! +#define MPU_I2C_SPEED 400000 // [bit/s] Define I2C speed for communicating with the MPU6050 +#define DELAY_IN_MAIN_LOOP 1 // [ms] Delay in the main loop +/* =============================================================================================== */ + + +/* ==================================== SETTINGS MPU-6050 ==================================== */ +#define MPU_DMP_ENABLE // [-] Enable flag for MPU-6050 DMP (Digital Motion Processing) functionality. +#define MPU_DEFAULT_HZ 20 // [Hz] Default MPU frequecy: must be between 1Hz and 200Hz. +#define TEMP_READ_MS 500 // [ms] Temperature read time interval +#define PEDO_READ_MS 1000 // [ms] Pedometer read time interval +// #define USE_CAL_HW_REGISTERS // [-] Uncommnent this to SAVE the sensor calibration to the MPU-6050 registers after the Self-test was run + +// DMP Tap Detection Settings +#define DMP_TAP_AXES TAP_XYZ // [-] Set which axes will register a tap: TAP_XYZ, TAP_X, TAP_Y, TAP_Z +#define DMP_TAP_THRESH 250 // [mg/ms] Set tap threshold for the selected axis. +#define DMP_TAP_COUNT 1 // [-] Set minimum number of taps needed for an interrupt. Minimum consecutive taps: 1 to 4 +#define DMP_TAP_TIME 100 // [ms] Set time length between valid taps. +#define DMP_TAP_TIME_MULTI 500 // [ms] Set max time between taps to register as a multi-tap. +#define DMP_SHAKE_REJECT_THRESH 200 // [deg/s] Set shake rejection threshold in degree per second (dps). If the DMP detects a gyro sample larger than the thresh, taps are rejected. +#define DMP_SHAKE_REJECT_TIME 40 // [ms] Set shake rejection time. Sets the length of time that the gyro must be outside of the DMP_SHAKE_REJECT_THRESH before taps are rejected. A mandatory 60 ms is added to this parameter. +#define DMP_SHAKE_REJECT_TIMEOUT 10 // [ms] Set shake rejection timeout. Sets the length of time after a shake rejection that the gyro must stay inside of the threshold before taps can be detected again. A mandatory 60 ms is added to this parameter. + + +/* ==================================== SETTINGS USART ==================================== */ +#if defined(VARIANT_DEBUG) + #define SERIAL_DEBUG // [-] Define for Serial Debug via the serial port +#elif defined(VARIANT_HOVERBOARD) + #define SERIAL_CONTROL // [-] Define for Serial Control via the serial port + #define SERIAL_FEEDBACK // [-] Define for Serial Feedback via the serial port +#endif +#define USART_MAIN_BAUD 38400 // [bit/s] MAIN Serial Tx/Rx baud rate +#define SERIAL_START_FRAME 0xAAAA // [-] Start frame definition for reliable serial communication +#define SERIAL_TIMEOUT 300 // [-] Numer of wrong received data for Serial timeout detection + + +/* ==================================== SETTINGS AUX ==================================== */ +// #define AUX45_USE_GPIO // [-] Use AUX4, AUX5 as GPIO ports +// #define AUX45_USE_I2C // [-] Use AUX4, AUX5 as I2C port +#define AUX45_USE_USART // [-] Use AUX4, AUX5 as USART port +#ifdef AUX45_USE_USART + #define USART_AUX_BAUD 38400 // [bit/s] AUX Serial Tx/Rx baud rate +#endif +#ifdef AUX45_USE_I2C + #define AUX_I2C_SPEED 100000 // [bit/s] Define I2C speed for communicating via AUX45 wires +#endif + + +/* ==================================== VALIDATE SETTINGS ==================================== */ +#if defined(SERIAL_DEBUG) && defined(SERIAL_CONTROL) + #error SERIAL_DEBUG and SERIAL_CONTROL not allowed. It is on the same cable. +#endif + +#if defined(AUX45_USE_GPIO) && (defined(AUX45_USE_USART) || defined(AUX45_USE_I2C)) || (defined(AUX45_USE_USART) && defined(AUX45_USE_I2C)) + #error AUX45_USE_(GPIO,USART,I2C) not allowed in the same time. It is on the same cable. +#endif + +#endif diff --git a/Inc/defines.h b/Inc/defines.h new file mode 100644 index 0000000..7b56610 --- /dev/null +++ b/Inc/defines.h @@ -0,0 +1,171 @@ +/** + * This file is part of the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +// Define to prevent recursive inclusion +#ifndef DEFINES_H +#define DEFINES_H + + +// Includes +#include "gd32f1x0.h" +#include "config.h" + +/* =========================== Defines General =========================== */ +// #define _BV(bit) (1 << (bit)) +// #define ARRAYNUM(arr_nanme) (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme))) +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#define i2c_write i2c_writeBytes +#define i2c_read i2c_readBytes +#define delay_ms delay_1ms +#define get_ms get_tick_count_ms + + +/* =========================== Defines LEDs =========================== */ +#define LED1_GPIO_Port GPIOA +#define LED1_Pin GPIO_PIN_0 // RED +#define LED2_GPIO_Port GPIOB +#define LED2_Pin GPIO_PIN_9 // GREEN +#define LED3_GPIO_Port GPIOB +#define LED3_Pin GPIO_PIN_8 // YELLOW +#define LED4_GPIO_Port GPIOB +#define LED4_Pin GPIO_PIN_5 // BLUE1 +#define LED5_GPIO_Port GPIOB +#define LED5_Pin GPIO_PIN_4 // BLUE2 + + +/* =========================== Defines SENSORS =========================== */ +#define SENSOR1_GPIO_Port GPIOA +#define SENSOR1_Pin GPIO_PIN_4 +#define SENSOR2_GPIO_Port GPIOC +#define SENSOR2_Pin GPIO_PIN_14 + + +/* =========================== Defines USART =========================== */ +#define USART_GPIO_PORT GPIOA +#define USART_GPIO_CLK RCU_GPIOA +#define USART_AF GPIO_AF_1 + +// USART ports number +#define USARTn 2 + + +// USART to Auxiliary, connected to USART0 +#define USART_AUX USART0 +#define USART_AUX_CLK RCU_USART0 +#define USART_AUX_TX_PIN GPIO_PIN_9 +#define USART_AUX_RX_PIN GPIO_PIN_10 + + +// USART to Mainboard, connected to USART1 +#define USART_MAIN USART1 +#define USART_MAIN_CLK RCU_USART1 +#define USART_MAIN_TX_PIN GPIO_PIN_2 +#define USART_MAIN_RX_PIN GPIO_PIN_3 + +// USART address for DMA defines +#define USART0_TDATA_ADDRESS ((uint32_t)0x40013828) // USART0: 0x4001 3800 - 0x4001 3BFF +#define USART0_RDATA_ADDRESS ((uint32_t)0x40013824) +#define USART1_TDATA_ADDRESS ((uint32_t)0x40004428) // USART1: 0x4000 4400 - 0x4000 47FF +#define USART1_RDATA_ADDRESS ((uint32_t)0x40004424) + + +/* =========================== Defines AUX =========================== */ +#define AUX1_PU_GPIO_Port GPIOC +#define AUX1_PU_Pin GPIO_PIN_15 +#define AUX2_GPIO_Port GPIOA +#define AUX2_Pin GPIO_PIN_1 +#define AUX3_GPIO_Port GPIOB +#define AUX3_Pin GPIO_PIN_10 +#ifdef AUX45_USE_GPIO + #define AUX4_GPIO_Port GPIOA + #define AUX4_Pin GPIO_PIN_10 + #define AUX5_GPIO_Port GPIOA + #define AUX5_Pin GPIO_PIN_9 +#endif + + +/* =========================== Defines I2C =========================== */ +typedef enum {READ = 0, WRITE = !READ} i2c_cmd; +#define MPU_I2C I2C0 +#define MPU_RCU_I2C RCU_I2C0 +#define MPU_SCL_GPIO_Port GPIOB +#define MPU_SCL_Pin GPIO_PIN_6 +#define MPU_SDA_GPIO_Port GPIOB +#define MPU_SDA_Pin GPIO_PIN_7 +#define I2C_OWN_ADDRESS7 0x24 + +#ifdef AUX45_USE_I2C + #define AUX_I2C I2C1 + #define AUX_RCU_I2C RCU_I2C1 + #define AUX_SCL_GPIO_Port GPIOA + #define AUX_SCL_Pin GPIO_PIN_9 + #define AUX_SDA_GPIO_Port GPIOA + #define AUX_SDA_Pin GPIO_PIN_10 + #define AUX_I2C_OWN_ADDRESS7 0x34 +#endif + +/* =========================== Defines MPU-6050 =========================== */ +#define log_i printf // redirect the log_i debug function to printf +#define RAD2DEG 57.295779513082323 // RAD2DEG = 180/pi. Example: angle[deg] = angle[rad] * RAD2DEG +#define ACCEL_ON (0x01) +#define GYRO_ON (0x02) +#define COMPASS_ON (0x04) + +#define PRINT_ACCEL (0x01) +#define PRINT_GYRO (0x02) +#define PRINT_QUAT (0x04) +#define PRINT_EULER (0x08) +#define PRINT_TEMP (0x10) +#define PRINT_PEDO (0x20) + +typedef struct{ + int16_t x; + int16_t y; + int16_t z; +} Gyro; + +typedef struct{ + int16_t x; + int16_t y; + int16_t z; +} Accel; + +typedef struct{ + int32_t w; + int32_t x; + int32_t y; + int32_t z; +} Quaternion; + +typedef struct{ + int16_t roll; + int16_t pitch; + int16_t yaw; +} Euler; + +typedef struct { + Gyro gyro; + Accel accel; + Quaternion quat; + Euler euler; + int16_t temp; +} MPU_Data; + +#endif diff --git a/Inc/gd32f1x0_it.h b/Inc/gd32f1x0_it.h new file mode 100644 index 0000000..7d4f944 --- /dev/null +++ b/Inc/gd32f1x0_it.h @@ -0,0 +1,52 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" +#include "config.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* I2C0 event handle function */ +void I2C0_EV_IRQHandler(void); +/* I2C0 error handle function */ +void I2C0_ER_IRQHandler(void); +#ifdef AUX45_USE_I2C +/* I2C1 event handle function */ +void I2C1_EV_IRQHandler(void); +/* I2C1 error handle function */ +void I2C1_ER_IRQHandler(void); +#endif + + +#endif /* GD32F1X0_IT_H */ diff --git a/Inc/i2c_it.h b/Inc/i2c_it.h new file mode 100644 index 0000000..d484752 --- /dev/null +++ b/Inc/i2c_it.h @@ -0,0 +1,37 @@ +/** + * This file is part of the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +#ifndef I2C_IT_H +#define I2C_IT_H + +#include "gd32f1x0.h" +#include "config.h" + +/* Interrupt function declarations */ +void I2C0_EventIRQ_Handler(void); // handle I2C0 event interrupt request +void I2C0_ErrorIRQ_Handler(void); // handle I2C0 error interrupt request + +#ifdef AUX45_USE_I2C +void I2C1_EventIRQ_Handler(void); // handle I2C1 event interrupt request +void I2C1_ErrorIRQ_Handler(void); // handle I2C1 error interrupt request +#endif + + +#endif /* I2C_IT_H */ + diff --git a/Inc/mpu6050.h b/Inc/mpu6050.h new file mode 100644 index 0000000..4cf0602 --- /dev/null +++ b/Inc/mpu6050.h @@ -0,0 +1,144 @@ +/** + * This file was taken from InvenSense MotionApps v6.12 library and + * refactored for the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + + +// Define to prevent recursive inclusion +#ifndef MPU6050_H +#define MPU6050_H + +#include +#include "defines.h" + +//-------------------------------------------- +#define INV_X_GYRO (0x40) +#define INV_Y_GYRO (0x20) +#define INV_Z_GYRO (0x10) +#define INV_XYZ_GYRO (INV_X_GYRO | INV_Y_GYRO | INV_Z_GYRO) +#define INV_XYZ_ACCEL (0x08) +#define INV_XYZ_COMPASS (0x01) + + +#define MPU_INT_STATUS_DATA_READY (0x0001) +#define MPU_INT_STATUS_DMP (0x0002) +#define MPU_INT_STATUS_PLL_READY (0x0004) +#define MPU_INT_STATUS_I2C_MST (0x0008) +#define MPU_INT_STATUS_FIFO_OVERFLOW (0x0010) +#define MPU_INT_STATUS_ZMOT (0x0020) +#define MPU_INT_STATUS_MOT (0x0040) +#define MPU_INT_STATUS_FREE_FALL (0x0080) +#define MPU_INT_STATUS_DMP_0 (0x0100) +#define MPU_INT_STATUS_DMP_1 (0x0200) +#define MPU_INT_STATUS_DMP_2 (0x0400) +#define MPU_INT_STATUS_DMP_3 (0x0800) +#define MPU_INT_STATUS_DMP_4 (0x1000) +#define MPU_INT_STATUS_DMP_5 (0x2000) + +/* Set up APIs */ +int mpu_init(void); +int mpu_init_slave(void); +int mpu_set_bypass(unsigned char bypass_on); + +/* Configuration APIs */ +int mpu_lp_accel_mode(unsigned short rate); +int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time, unsigned short lpa_freq); +int mpu_set_int_level(unsigned char active_low); +int mpu_set_int_latched(unsigned char enable); + +int mpu_set_dmp_state(unsigned char enable); +int mpu_get_dmp_state(unsigned char *enabled); + +int mpu_get_lpf(unsigned short *lpf); +int mpu_set_lpf(unsigned short lpf); + +int mpu_get_gyro_fsr(unsigned short *fsr); +int mpu_set_gyro_fsr(unsigned short fsr); + +int mpu_get_accel_fsr(unsigned char *fsr); +int mpu_set_accel_fsr(unsigned char fsr); + +int mpu_get_compass_fsr(unsigned short *fsr); + +int mpu_get_gyro_sens(float *sens); +int mpu_get_accel_sens(unsigned short *sens); + +int mpu_get_sample_rate(unsigned short *rate); +int mpu_set_sample_rate(unsigned short rate); +int mpu_get_compass_sample_rate(unsigned short *rate); +int mpu_set_compass_sample_rate(unsigned short rate); + +int mpu_get_fifo_config(unsigned char *sensors); +int mpu_configure_fifo(unsigned char sensors); + +int mpu_get_power_state(unsigned char *power_on); +int mpu_set_sensors(unsigned char sensors); + +int mpu_read_6500_accel_bias(long *accel_bias); +int mpu_set_gyro_bias_reg(long * gyro_bias); +int mpu_set_accel_bias_6500_reg(const long *accel_bias); +int mpu_read_6050_accel_bias(long *accel_bias); +int mpu_set_accel_bias_6050_reg(const long *accel_bias); + +/* Data getter/setter APIs */ +int mpu_get_gyro_reg(short *data, unsigned long *timestamp); +int mpu_get_accel_reg(short *data, unsigned long *timestamp); +int mpu_get_compass_reg(short *data, unsigned long *timestamp); +int mpu_get_temperature(long *data, unsigned long *timestamp); + +int mpu_get_int_status(short *status); +int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, + unsigned char *sensors, unsigned char *more); +int mpu_read_fifo_stream(unsigned short length, unsigned char *data, + unsigned char *more); +int mpu_reset_fifo(void); + +int mpu_write_mem(unsigned short mem_addr, unsigned short length, + unsigned char *data); +int mpu_read_mem(unsigned short mem_addr, unsigned short length, + unsigned char *data); +int mpu_load_firmware(unsigned short length, const unsigned char *firmware, + unsigned short start_addr, unsigned short sample_rate); + +int mpu_reg_dump(void); +int mpu_read_reg(unsigned char reg, unsigned char *data); +int mpu_run_self_test(long *gyro, long *accel); +int mpu_run_6500_self_test(long *gyro, long *accel, unsigned char debug); +void mpu_start_self_test(void); +void mpu_setup_gyro(void); + +/* MPU configuration */ +int mpu_config(void); + +/* MPU get packet data */ +void mpu_get_data(void); + +/* Data post-processing */ +void mpu_read_gyro_raw(void); +void mpu_read_accel_raw(void); +void mpu_calc_euler_angles(void); +void mpu_tap_func(unsigned char direction, unsigned char count); +void mpu_android_orient_func(unsigned char orientation); + +/* Handle user input commands */ +void mpu_handle_input(char c); +void mpu_print_to_console(void); + + +#endif diff --git a/Inc/mpu6050_dmp.h b/Inc/mpu6050_dmp.h new file mode 100644 index 0000000..cdfdd55 --- /dev/null +++ b/Inc/mpu6050_dmp.h @@ -0,0 +1,107 @@ +/** + * This file was taken from InvenSense MotionApps v6.12 library and + * refactored for the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + + +// Define to prevent recursive inclusion +#ifndef MPU6050_DMP_H +#define MPU6050_DMP_H + +#include + +#define TAP_X (0x01) +#define TAP_Y (0x02) +#define TAP_Z (0x04) +#define TAP_XYZ (0x07) + +#define TAP_X_UP (0x01) +#define TAP_X_DOWN (0x02) +#define TAP_Y_UP (0x03) +#define TAP_Y_DOWN (0x04) +#define TAP_Z_UP (0x05) +#define TAP_Z_DOWN (0x06) + +#define ANDROID_ORIENT_PORTRAIT (0x00) +#define ANDROID_ORIENT_LANDSCAPE (0x01) +#define ANDROID_ORIENT_REVERSE_PORTRAIT (0x02) +#define ANDROID_ORIENT_REVERSE_LANDSCAPE (0x03) + +#define DMP_INT_GESTURE (0x01) +#define DMP_INT_CONTINUOUS (0x02) + +#define DMP_FEATURE_TAP (0x001) +#define DMP_FEATURE_ANDROID_ORIENT (0x002) +#define DMP_FEATURE_LP_QUAT (0x004) +#define DMP_FEATURE_PEDOMETER (0x008) +#define DMP_FEATURE_6X_LP_QUAT (0x010) +#define DMP_FEATURE_GYRO_CAL (0x020) +#define DMP_FEATURE_SEND_RAW_ACCEL (0x040) +#define DMP_FEATURE_SEND_RAW_GYRO (0x080) +#define DMP_FEATURE_SEND_CAL_GYRO (0x100) + +#define INV_WXYZ_QUAT (0x100) + +/* Set up functions. */ +int dmp_load_motion_driver_firmware(void); +int dmp_set_fifo_rate(unsigned short rate); +int dmp_get_fifo_rate(unsigned short *rate); +int dmp_enable_feature(unsigned short mask); +int dmp_get_enabled_features(unsigned short *mask); +int dmp_set_interrupt_mode(unsigned char mode); +int dmp_set_orientation(unsigned short orient); +int dmp_set_gyro_bias(long *bias); +int dmp_set_accel_bias(long *bias); + +/* Tap functions. */ +int dmp_register_tap_cb(void (*func)(unsigned char, unsigned char)); +int dmp_set_tap_thresh(unsigned char axis, unsigned short thresh); +int dmp_set_tap_axes(unsigned char axis); +int dmp_set_tap_count(unsigned char min_taps); +int dmp_set_tap_time(unsigned short time); +int dmp_set_tap_time_multi(unsigned short time); +int dmp_set_shake_reject_thresh(long sf, unsigned short thresh); +int dmp_set_shake_reject_time(unsigned short time); +int dmp_set_shake_reject_timeout(unsigned short time); + +/* Android orientation functions. */ +int dmp_register_android_orient_cb(void (*func)(unsigned char)); + +/* LP quaternion functions. */ +int dmp_enable_lp_quat(unsigned char enable); +int dmp_enable_6x_lp_quat(unsigned char enable); + +/* Pedometer functions. */ +int dmp_get_pedometer_step_count(unsigned long *count); +int dmp_set_pedometer_step_count(unsigned long count); +int dmp_get_pedometer_walk_time(unsigned long *time); +int dmp_set_pedometer_walk_time(unsigned long time); + +/* DMP gyro calibration functions. */ +int dmp_enable_gyro_cal(unsigned char enable); + +/* Read function. This function should be called whenever the MPU interrupt is + * detected. + */ +int dmp_read_fifo(short *gyro, short *accel, long *quat, + unsigned long *timestamp, short *sensors, unsigned char *more); + + +#endif + diff --git a/Inc/mpu6050_dmpKey.h b/Inc/mpu6050_dmpKey.h new file mode 100644 index 0000000..a67896c --- /dev/null +++ b/Inc/mpu6050_dmpKey.h @@ -0,0 +1,495 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ +#ifndef DMPKEY_H__ +#define DMPKEY_H__ + + +#define KEY_CFG_25 (0) +#define KEY_CFG_24 (KEY_CFG_25 + 1) +#define KEY_CFG_26 (KEY_CFG_24 + 1) +#define KEY_CFG_27 (KEY_CFG_26 + 1) +#define KEY_CFG_21 (KEY_CFG_27 + 1) +#define KEY_CFG_20 (KEY_CFG_21 + 1) +#define KEY_CFG_TAP4 (KEY_CFG_20 + 1) +#define KEY_CFG_TAP5 (KEY_CFG_TAP4 + 1) +#define KEY_CFG_TAP6 (KEY_CFG_TAP5 + 1) +#define KEY_CFG_TAP7 (KEY_CFG_TAP6 + 1) +#define KEY_CFG_TAP0 (KEY_CFG_TAP7 + 1) +#define KEY_CFG_TAP1 (KEY_CFG_TAP0 + 1) +#define KEY_CFG_TAP2 (KEY_CFG_TAP1 + 1) +#define KEY_CFG_TAP3 (KEY_CFG_TAP2 + 1) +#define KEY_CFG_TAP_QUANTIZE (KEY_CFG_TAP3 + 1) +#define KEY_CFG_TAP_JERK (KEY_CFG_TAP_QUANTIZE + 1) +#define KEY_CFG_DR_INT (KEY_CFG_TAP_JERK + 1) +#define KEY_CFG_AUTH (KEY_CFG_DR_INT + 1) +#define KEY_CFG_TAP_SAVE_ACCB (KEY_CFG_AUTH + 1) +#define KEY_CFG_TAP_CLEAR_STICKY (KEY_CFG_TAP_SAVE_ACCB + 1) +#define KEY_CFG_FIFO_ON_EVENT (KEY_CFG_TAP_CLEAR_STICKY + 1) +#define KEY_FCFG_ACCEL_INPUT (KEY_CFG_FIFO_ON_EVENT + 1) +#define KEY_FCFG_ACCEL_INIT (KEY_FCFG_ACCEL_INPUT + 1) +#define KEY_CFG_23 (KEY_FCFG_ACCEL_INIT + 1) +#define KEY_FCFG_1 (KEY_CFG_23 + 1) +#define KEY_FCFG_3 (KEY_FCFG_1 + 1) +#define KEY_FCFG_2 (KEY_FCFG_3 + 1) +#define KEY_CFG_3D (KEY_FCFG_2 + 1) +#define KEY_CFG_3B (KEY_CFG_3D + 1) +#define KEY_CFG_3C (KEY_CFG_3B + 1) +#define KEY_FCFG_5 (KEY_CFG_3C + 1) +#define KEY_FCFG_4 (KEY_FCFG_5 + 1) +#define KEY_FCFG_7 (KEY_FCFG_4 + 1) +#define KEY_FCFG_FSCALE (KEY_FCFG_7 + 1) +#define KEY_FCFG_AZ (KEY_FCFG_FSCALE + 1) +#define KEY_FCFG_6 (KEY_FCFG_AZ + 1) +#define KEY_FCFG_LSB4 (KEY_FCFG_6 + 1) +#define KEY_CFG_12 (KEY_FCFG_LSB4 + 1) +#define KEY_CFG_14 (KEY_CFG_12 + 1) +#define KEY_CFG_15 (KEY_CFG_14 + 1) +#define KEY_CFG_16 (KEY_CFG_15 + 1) +#define KEY_CFG_18 (KEY_CFG_16 + 1) +#define KEY_CFG_6 (KEY_CFG_18 + 1) +#define KEY_CFG_7 (KEY_CFG_6 + 1) +#define KEY_CFG_4 (KEY_CFG_7 + 1) +#define KEY_CFG_5 (KEY_CFG_4 + 1) +#define KEY_CFG_2 (KEY_CFG_5 + 1) +#define KEY_CFG_3 (KEY_CFG_2 + 1) +#define KEY_CFG_1 (KEY_CFG_3 + 1) +#define KEY_CFG_EXTERNAL (KEY_CFG_1 + 1) +#define KEY_CFG_8 (KEY_CFG_EXTERNAL + 1) +#define KEY_CFG_9 (KEY_CFG_8 + 1) +#define KEY_CFG_ORIENT_3 (KEY_CFG_9 + 1) +#define KEY_CFG_ORIENT_2 (KEY_CFG_ORIENT_3 + 1) +#define KEY_CFG_ORIENT_1 (KEY_CFG_ORIENT_2 + 1) +#define KEY_CFG_GYRO_SOURCE (KEY_CFG_ORIENT_1 + 1) +#define KEY_CFG_ORIENT_IRQ_1 (KEY_CFG_GYRO_SOURCE + 1) +#define KEY_CFG_ORIENT_IRQ_2 (KEY_CFG_ORIENT_IRQ_1 + 1) +#define KEY_CFG_ORIENT_IRQ_3 (KEY_CFG_ORIENT_IRQ_2 + 1) +#define KEY_FCFG_MAG_VAL (KEY_CFG_ORIENT_IRQ_3 + 1) +#define KEY_FCFG_MAG_MOV (KEY_FCFG_MAG_VAL + 1) +#define KEY_CFG_LP_QUAT (KEY_FCFG_MAG_MOV + 1) + +/* MPU6050 keys */ +#define KEY_CFG_ACCEL_FILTER (KEY_CFG_LP_QUAT + 1) +#define KEY_CFG_MOTION_BIAS (KEY_CFG_ACCEL_FILTER + 1) +#define KEY_TEMPLABEL (KEY_CFG_MOTION_BIAS + 1) + +#define KEY_D_0_22 (KEY_TEMPLABEL + 1) +#define KEY_D_0_24 (KEY_D_0_22 + 1) +#define KEY_D_0_36 (KEY_D_0_24 + 1) +#define KEY_D_0_52 (KEY_D_0_36 + 1) +#define KEY_D_0_96 (KEY_D_0_52 + 1) +#define KEY_D_0_104 (KEY_D_0_96 + 1) +#define KEY_D_0_108 (KEY_D_0_104 + 1) +#define KEY_D_0_163 (KEY_D_0_108 + 1) +#define KEY_D_0_188 (KEY_D_0_163 + 1) +#define KEY_D_0_192 (KEY_D_0_188 + 1) +#define KEY_D_0_224 (KEY_D_0_192 + 1) +#define KEY_D_0_228 (KEY_D_0_224 + 1) +#define KEY_D_0_232 (KEY_D_0_228 + 1) +#define KEY_D_0_236 (KEY_D_0_232 + 1) + +#define KEY_DMP_PREVPTAT (KEY_D_0_236 + 1) +#define KEY_D_1_2 (KEY_DMP_PREVPTAT + 1) +#define KEY_D_1_4 (KEY_D_1_2 + 1) +#define KEY_D_1_8 (KEY_D_1_4 + 1) +#define KEY_D_1_10 (KEY_D_1_8 + 1) +#define KEY_D_1_24 (KEY_D_1_10 + 1) +#define KEY_D_1_28 (KEY_D_1_24 + 1) +#define KEY_D_1_36 (KEY_D_1_28 + 1) +#define KEY_D_1_40 (KEY_D_1_36 + 1) +#define KEY_D_1_44 (KEY_D_1_40 + 1) +#define KEY_D_1_72 (KEY_D_1_44 + 1) +#define KEY_D_1_74 (KEY_D_1_72 + 1) +#define KEY_D_1_79 (KEY_D_1_74 + 1) +#define KEY_D_1_88 (KEY_D_1_79 + 1) +#define KEY_D_1_90 (KEY_D_1_88 + 1) +#define KEY_D_1_92 (KEY_D_1_90 + 1) +#define KEY_D_1_96 (KEY_D_1_92 + 1) +#define KEY_D_1_98 (KEY_D_1_96 + 1) +#define KEY_D_1_100 (KEY_D_1_98 + 1) +#define KEY_D_1_106 (KEY_D_1_100 + 1) +#define KEY_D_1_108 (KEY_D_1_106 + 1) +#define KEY_D_1_112 (KEY_D_1_108 + 1) +#define KEY_D_1_128 (KEY_D_1_112 + 1) +#define KEY_D_1_152 (KEY_D_1_128 + 1) +#define KEY_D_1_160 (KEY_D_1_152 + 1) +#define KEY_D_1_168 (KEY_D_1_160 + 1) +#define KEY_D_1_175 (KEY_D_1_168 + 1) +#define KEY_D_1_176 (KEY_D_1_175 + 1) +#define KEY_D_1_178 (KEY_D_1_176 + 1) +#define KEY_D_1_179 (KEY_D_1_178 + 1) +#define KEY_D_1_218 (KEY_D_1_179 + 1) +#define KEY_D_1_232 (KEY_D_1_218 + 1) +#define KEY_D_1_236 (KEY_D_1_232 + 1) +#define KEY_D_1_240 (KEY_D_1_236 + 1) +#define KEY_D_1_244 (KEY_D_1_240 + 1) +#define KEY_D_1_250 (KEY_D_1_244 + 1) +#define KEY_D_1_252 (KEY_D_1_250 + 1) +#define KEY_D_2_12 (KEY_D_1_252 + 1) +#define KEY_D_2_96 (KEY_D_2_12 + 1) +#define KEY_D_2_108 (KEY_D_2_96 + 1) +#define KEY_D_2_208 (KEY_D_2_108 + 1) +#define KEY_FLICK_MSG (KEY_D_2_208 + 1) +#define KEY_FLICK_COUNTER (KEY_FLICK_MSG + 1) +#define KEY_FLICK_LOWER (KEY_FLICK_COUNTER + 1) +#define KEY_CFG_FLICK_IN (KEY_FLICK_LOWER + 1) +#define KEY_FLICK_UPPER (KEY_CFG_FLICK_IN + 1) +#define KEY_CGNOTICE_INTR (KEY_FLICK_UPPER + 1) +#define KEY_D_2_224 (KEY_CGNOTICE_INTR + 1) +#define KEY_D_2_244 (KEY_D_2_224 + 1) +#define KEY_D_2_248 (KEY_D_2_244 + 1) +#define KEY_D_2_252 (KEY_D_2_248 + 1) + +#define KEY_D_GYRO_BIAS_X (KEY_D_2_252 + 1) +#define KEY_D_GYRO_BIAS_Y (KEY_D_GYRO_BIAS_X + 1) +#define KEY_D_GYRO_BIAS_Z (KEY_D_GYRO_BIAS_Y + 1) +#define KEY_D_ACC_BIAS_X (KEY_D_GYRO_BIAS_Z + 1) +#define KEY_D_ACC_BIAS_Y (KEY_D_ACC_BIAS_X + 1) +#define KEY_D_ACC_BIAS_Z (KEY_D_ACC_BIAS_Y + 1) +#define KEY_D_GYRO_ENABLE (KEY_D_ACC_BIAS_Z + 1) +#define KEY_D_ACCEL_ENABLE (KEY_D_GYRO_ENABLE + 1) +#define KEY_D_QUAT_ENABLE (KEY_D_ACCEL_ENABLE +1) +#define KEY_D_OUTPUT_ENABLE (KEY_D_QUAT_ENABLE + 1) +#define KEY_D_CR_TIME_G (KEY_D_OUTPUT_ENABLE + 1) +#define KEY_D_CR_TIME_A (KEY_D_CR_TIME_G + 1) +#define KEY_D_CR_TIME_Q (KEY_D_CR_TIME_A + 1) +#define KEY_D_CS_TAX (KEY_D_CR_TIME_Q + 1) +#define KEY_D_CS_TAY (KEY_D_CS_TAX + 1) +#define KEY_D_CS_TAZ (KEY_D_CS_TAY + 1) +#define KEY_D_CS_TGX (KEY_D_CS_TAZ + 1) +#define KEY_D_CS_TGY (KEY_D_CS_TGX + 1) +#define KEY_D_CS_TGZ (KEY_D_CS_TGY + 1) +#define KEY_D_CS_TQ0 (KEY_D_CS_TGZ + 1) +#define KEY_D_CS_TQ1 (KEY_D_CS_TQ0 + 1) +#define KEY_D_CS_TQ2 (KEY_D_CS_TQ1 + 1) +#define KEY_D_CS_TQ3 (KEY_D_CS_TQ2 + 1) + +/* Compass keys */ +#define KEY_CPASS_BIAS_X (KEY_D_CS_TQ3 + 1) +#define KEY_CPASS_BIAS_Y (KEY_CPASS_BIAS_X + 1) +#define KEY_CPASS_BIAS_Z (KEY_CPASS_BIAS_Y + 1) +#define KEY_CPASS_MTX_00 (KEY_CPASS_BIAS_Z + 1) +#define KEY_CPASS_MTX_01 (KEY_CPASS_MTX_00 + 1) +#define KEY_CPASS_MTX_02 (KEY_CPASS_MTX_01 + 1) +#define KEY_CPASS_MTX_10 (KEY_CPASS_MTX_02 + 1) +#define KEY_CPASS_MTX_11 (KEY_CPASS_MTX_10 + 1) +#define KEY_CPASS_MTX_12 (KEY_CPASS_MTX_11 + 1) +#define KEY_CPASS_MTX_20 (KEY_CPASS_MTX_12 + 1) +#define KEY_CPASS_MTX_21 (KEY_CPASS_MTX_20 + 1) +#define KEY_CPASS_MTX_22 (KEY_CPASS_MTX_21 + 1) + +/* Gesture Keys */ +#define KEY_DMP_TAPW_MIN (KEY_CPASS_MTX_22 + 1) +#define KEY_DMP_TAP_THR_X (KEY_DMP_TAPW_MIN + 1) +#define KEY_DMP_TAP_THR_Y (KEY_DMP_TAP_THR_X + 1) +#define KEY_DMP_TAP_THR_Z (KEY_DMP_TAP_THR_Y + 1) +#define KEY_DMP_SH_TH_Y (KEY_DMP_TAP_THR_Z + 1) +#define KEY_DMP_SH_TH_X (KEY_DMP_SH_TH_Y + 1) +#define KEY_DMP_SH_TH_Z (KEY_DMP_SH_TH_X + 1) +#define KEY_DMP_ORIENT (KEY_DMP_SH_TH_Z + 1) +#define KEY_D_ACT0 (KEY_DMP_ORIENT + 1) +#define KEY_D_ACSX (KEY_D_ACT0 + 1) +#define KEY_D_ACSY (KEY_D_ACSX + 1) +#define KEY_D_ACSZ (KEY_D_ACSY + 1) + +#define KEY_X_GRT_Y_TMP (KEY_D_ACSZ + 1) +#define KEY_SKIP_X_GRT_Y_TMP (KEY_X_GRT_Y_TMP + 1) +#define KEY_SKIP_END_COMPARE (KEY_SKIP_X_GRT_Y_TMP + 1) +#define KEY_END_COMPARE_Y_X_TMP2 (KEY_SKIP_END_COMPARE + 1) +#define KEY_CFG_ANDROID_ORIENT_INT (KEY_END_COMPARE_Y_X_TMP2 + 1) +#define KEY_NO_ORIENT_INTERRUPT (KEY_CFG_ANDROID_ORIENT_INT + 1) +#define KEY_END_COMPARE_Y_X_TMP (KEY_NO_ORIENT_INTERRUPT + 1) +#define KEY_END_ORIENT_1 (KEY_END_COMPARE_Y_X_TMP + 1) +#define KEY_END_COMPARE_Y_X (KEY_END_ORIENT_1 + 1) +#define KEY_END_ORIENT (KEY_END_COMPARE_Y_X + 1) +#define KEY_X_GRT_Y (KEY_END_ORIENT + 1) +#define KEY_NOT_TIME_MINUS_1 (KEY_X_GRT_Y + 1) +#define KEY_END_COMPARE_Y_X_TMP3 (KEY_NOT_TIME_MINUS_1 + 1) +#define KEY_X_GRT_Y_TMP2 (KEY_END_COMPARE_Y_X_TMP3 + 1) + +/* Authenticate Keys */ +#define KEY_D_AUTH_OUT (KEY_X_GRT_Y_TMP2 + 1) +#define KEY_D_AUTH_IN (KEY_D_AUTH_OUT + 1) +#define KEY_D_AUTH_A (KEY_D_AUTH_IN + 1) +#define KEY_D_AUTH_B (KEY_D_AUTH_A + 1) + +/* Pedometer standalone only keys */ +#define KEY_D_PEDSTD_BP_B (KEY_D_AUTH_B + 1) +#define KEY_D_PEDSTD_HP_A (KEY_D_PEDSTD_BP_B + 1) +#define KEY_D_PEDSTD_HP_B (KEY_D_PEDSTD_HP_A + 1) +#define KEY_D_PEDSTD_BP_A4 (KEY_D_PEDSTD_HP_B + 1) +#define KEY_D_PEDSTD_BP_A3 (KEY_D_PEDSTD_BP_A4 + 1) +#define KEY_D_PEDSTD_BP_A2 (KEY_D_PEDSTD_BP_A3 + 1) +#define KEY_D_PEDSTD_BP_A1 (KEY_D_PEDSTD_BP_A2 + 1) +#define KEY_D_PEDSTD_INT_THRSH (KEY_D_PEDSTD_BP_A1 + 1) +#define KEY_D_PEDSTD_CLIP (KEY_D_PEDSTD_INT_THRSH + 1) +#define KEY_D_PEDSTD_SB (KEY_D_PEDSTD_CLIP + 1) +#define KEY_D_PEDSTD_SB_TIME (KEY_D_PEDSTD_SB + 1) +#define KEY_D_PEDSTD_PEAKTHRSH (KEY_D_PEDSTD_SB_TIME + 1) +#define KEY_D_PEDSTD_TIML (KEY_D_PEDSTD_PEAKTHRSH + 1) +#define KEY_D_PEDSTD_TIMH (KEY_D_PEDSTD_TIML + 1) +#define KEY_D_PEDSTD_PEAK (KEY_D_PEDSTD_TIMH + 1) +#define KEY_D_PEDSTD_TIMECTR (KEY_D_PEDSTD_PEAK + 1) +#define KEY_D_PEDSTD_STEPCTR (KEY_D_PEDSTD_TIMECTR + 1) +#define KEY_D_PEDSTD_WALKTIME (KEY_D_PEDSTD_STEPCTR + 1) +#define KEY_D_PEDSTD_DECI (KEY_D_PEDSTD_WALKTIME + 1) + +/*Host Based No Motion*/ +#define KEY_D_HOST_NO_MOT (KEY_D_PEDSTD_DECI + 1) + +/* EIS keys */ +#define KEY_P_EIS_FIFO_FOOTER (KEY_D_HOST_NO_MOT + 1) +#define KEY_P_EIS_FIFO_YSHIFT (KEY_P_EIS_FIFO_FOOTER + 1) +#define KEY_P_EIS_DATA_RATE (KEY_P_EIS_FIFO_YSHIFT + 1) +#define KEY_P_EIS_FIFO_XSHIFT (KEY_P_EIS_DATA_RATE + 1) +#define KEY_P_EIS_FIFO_SYNC (KEY_P_EIS_FIFO_XSHIFT + 1) +#define KEY_P_EIS_FIFO_ZSHIFT (KEY_P_EIS_FIFO_SYNC + 1) +#define KEY_P_EIS_FIFO_READY (KEY_P_EIS_FIFO_ZSHIFT + 1) +#define KEY_DMP_FOOTER (KEY_P_EIS_FIFO_READY + 1) +#define KEY_DMP_INTX_HC (KEY_DMP_FOOTER + 1) +#define KEY_DMP_INTX_PH (KEY_DMP_INTX_HC + 1) +#define KEY_DMP_INTX_SH (KEY_DMP_INTX_PH + 1) +#define KEY_DMP_AINV_SH (KEY_DMP_INTX_SH + 1) +#define KEY_DMP_A_INV_XH (KEY_DMP_AINV_SH + 1) +#define KEY_DMP_AINV_PH (KEY_DMP_A_INV_XH + 1) +#define KEY_DMP_CTHX_H (KEY_DMP_AINV_PH + 1) +#define KEY_DMP_CTHY_H (KEY_DMP_CTHX_H + 1) +#define KEY_DMP_CTHZ_H (KEY_DMP_CTHY_H + 1) +#define KEY_DMP_NCTHX_H (KEY_DMP_CTHZ_H + 1) +#define KEY_DMP_NCTHY_H (KEY_DMP_NCTHX_H + 1) +#define KEY_DMP_NCTHZ_H (KEY_DMP_NCTHY_H + 1) +#define KEY_DMP_CTSQ_XH (KEY_DMP_NCTHZ_H + 1) +#define KEY_DMP_CTSQ_YH (KEY_DMP_CTSQ_XH + 1) +#define KEY_DMP_CTSQ_ZH (KEY_DMP_CTSQ_YH + 1) +#define KEY_DMP_INTX_H (KEY_DMP_CTSQ_ZH + 1) +#define KEY_DMP_INTY_H (KEY_DMP_INTX_H + 1) +#define KEY_DMP_INTZ_H (KEY_DMP_INTY_H + 1) +//#define KEY_DMP_HPX_H (KEY_DMP_INTZ_H + 1) +//#define KEY_DMP_HPY_H (KEY_DMP_HPX_H + 1) +//#define KEY_DMP_HPZ_H (KEY_DMP_HPY_H + 1) + +/* Stream keys */ +#define KEY_STREAM_P_GYRO_Z (KEY_DMP_INTZ_H + 1) +#define KEY_STREAM_P_GYRO_Y (KEY_STREAM_P_GYRO_Z + 1) +#define KEY_STREAM_P_GYRO_X (KEY_STREAM_P_GYRO_Y + 1) +#define KEY_STREAM_P_TEMP (KEY_STREAM_P_GYRO_X + 1) +#define KEY_STREAM_P_AUX_Y (KEY_STREAM_P_TEMP + 1) +#define KEY_STREAM_P_AUX_X (KEY_STREAM_P_AUX_Y + 1) +#define KEY_STREAM_P_AUX_Z (KEY_STREAM_P_AUX_X + 1) +#define KEY_STREAM_P_ACCEL_Y (KEY_STREAM_P_AUX_Z + 1) +#define KEY_STREAM_P_ACCEL_X (KEY_STREAM_P_ACCEL_Y + 1) +#define KEY_STREAM_P_FOOTER (KEY_STREAM_P_ACCEL_X + 1) +#define KEY_STREAM_P_ACCEL_Z (KEY_STREAM_P_FOOTER + 1) + +#define NUM_KEYS (KEY_STREAM_P_ACCEL_Z + 1) + +typedef struct { + unsigned short key; + unsigned short addr; +} tKeyLabel; + +#define DINA0A 0x0a +#define DINA22 0x22 +#define DINA42 0x42 +#define DINA5A 0x5a + +#define DINA06 0x06 +#define DINA0E 0x0e +#define DINA16 0x16 +#define DINA1E 0x1e +#define DINA26 0x26 +#define DINA2E 0x2e +#define DINA36 0x36 +#define DINA3E 0x3e +#define DINA46 0x46 +#define DINA4E 0x4e +#define DINA56 0x56 +#define DINA5E 0x5e +#define DINA66 0x66 +#define DINA6E 0x6e +#define DINA76 0x76 +#define DINA7E 0x7e + +#define DINA00 0x00 +#define DINA08 0x08 +#define DINA10 0x10 +#define DINA18 0x18 +#define DINA20 0x20 +#define DINA28 0x28 +#define DINA30 0x30 +#define DINA38 0x38 +#define DINA40 0x40 +#define DINA48 0x48 +#define DINA50 0x50 +#define DINA58 0x58 +#define DINA60 0x60 +#define DINA68 0x68 +#define DINA70 0x70 +#define DINA78 0x78 + +#define DINA04 0x04 +#define DINA0C 0x0c +#define DINA14 0x14 +#define DINA1C 0x1C +#define DINA24 0x24 +#define DINA2C 0x2c +#define DINA34 0x34 +#define DINA3C 0x3c +#define DINA44 0x44 +#define DINA4C 0x4c +#define DINA54 0x54 +#define DINA5C 0x5c +#define DINA64 0x64 +#define DINA6C 0x6c +#define DINA74 0x74 +#define DINA7C 0x7c + +#define DINA01 0x01 +#define DINA09 0x09 +#define DINA11 0x11 +#define DINA19 0x19 +#define DINA21 0x21 +#define DINA29 0x29 +#define DINA31 0x31 +#define DINA39 0x39 +#define DINA41 0x41 +#define DINA49 0x49 +#define DINA51 0x51 +#define DINA59 0x59 +#define DINA61 0x61 +#define DINA69 0x69 +#define DINA71 0x71 +#define DINA79 0x79 + +#define DINA25 0x25 +#define DINA2D 0x2d +#define DINA35 0x35 +#define DINA3D 0x3d +#define DINA4D 0x4d +#define DINA55 0x55 +#define DINA5D 0x5D +#define DINA6D 0x6d +#define DINA75 0x75 +#define DINA7D 0x7d + +#define DINADC 0xdc +#define DINAF2 0xf2 +#define DINAAB 0xab +#define DINAAA 0xaa +#define DINAF1 0xf1 +#define DINADF 0xdf +#define DINADA 0xda +#define DINAB1 0xb1 +#define DINAB9 0xb9 +#define DINAF3 0xf3 +#define DINA8B 0x8b +#define DINAA3 0xa3 +#define DINA91 0x91 +#define DINAB6 0xb6 +#define DINAB4 0xb4 + + +#define DINC00 0x00 +#define DINC01 0x01 +#define DINC02 0x02 +#define DINC03 0x03 +#define DINC08 0x08 +#define DINC09 0x09 +#define DINC0A 0x0a +#define DINC0B 0x0b +#define DINC10 0x10 +#define DINC11 0x11 +#define DINC12 0x12 +#define DINC13 0x13 +#define DINC18 0x18 +#define DINC19 0x19 +#define DINC1A 0x1a +#define DINC1B 0x1b + +#define DINC20 0x20 +#define DINC21 0x21 +#define DINC22 0x22 +#define DINC23 0x23 +#define DINC28 0x28 +#define DINC29 0x29 +#define DINC2A 0x2a +#define DINC2B 0x2b +#define DINC30 0x30 +#define DINC31 0x31 +#define DINC32 0x32 +#define DINC33 0x33 +#define DINC38 0x38 +#define DINC39 0x39 +#define DINC3A 0x3a +#define DINC3B 0x3b + +#define DINC40 0x40 +#define DINC41 0x41 +#define DINC42 0x42 +#define DINC43 0x43 +#define DINC48 0x48 +#define DINC49 0x49 +#define DINC4A 0x4a +#define DINC4B 0x4b +#define DINC50 0x50 +#define DINC51 0x51 +#define DINC52 0x52 +#define DINC53 0x53 +#define DINC58 0x58 +#define DINC59 0x59 +#define DINC5A 0x5a +#define DINC5B 0x5b + +#define DINC60 0x60 +#define DINC61 0x61 +#define DINC62 0x62 +#define DINC63 0x63 +#define DINC68 0x68 +#define DINC69 0x69 +#define DINC6A 0x6a +#define DINC6B 0x6b +#define DINC70 0x70 +#define DINC71 0x71 +#define DINC72 0x72 +#define DINC73 0x73 +#define DINC78 0x78 +#define DINC79 0x79 +#define DINC7A 0x7a +#define DINC7B 0x7b + +#define DIND40 0x40 + + +#define DINA80 0x80 +#define DINA90 0x90 +#define DINAA0 0xa0 +#define DINAC9 0xc9 +#define DINACB 0xcb +#define DINACD 0xcd +#define DINACF 0xcf +#define DINAC8 0xc8 +#define DINACA 0xca +#define DINACC 0xcc +#define DINACE 0xce +#define DINAD8 0xd8 +#define DINADD 0xdd +#define DINAF8 0xf0 +#define DINAFE 0xfe + +#define DINBF8 0xf8 +#define DINAC0 0xb0 +#define DINAC1 0xb1 +#define DINAC2 0xb4 +#define DINAC3 0xb5 +#define DINAC4 0xb8 +#define DINAC5 0xb9 +#define DINBC0 0xc0 +#define DINBC2 0xc2 +#define DINBC4 0xc4 +#define DINBC6 0xc6 + + + +#endif // DMPKEY_H__ diff --git a/Inc/mpu6050_dmpmap.h b/Inc/mpu6050_dmpmap.h new file mode 100644 index 0000000..391ba14 --- /dev/null +++ b/Inc/mpu6050_dmpmap.h @@ -0,0 +1,264 @@ +/* + $License: + Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. + $ + */ +#ifndef DMPMAP_H +#define DMPMAP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define DMP_PTAT 0 +#define DMP_XGYR 2 +#define DMP_YGYR 4 +#define DMP_ZGYR 6 +#define DMP_XACC 8 +#define DMP_YACC 10 +#define DMP_ZACC 12 +#define DMP_ADC1 14 +#define DMP_ADC2 16 +#define DMP_ADC3 18 +#define DMP_BIASUNC 20 +#define DMP_FIFORT 22 +#define DMP_INVGSFH 24 +#define DMP_INVGSFL 26 +#define DMP_1H 28 +#define DMP_1L 30 +#define DMP_BLPFSTCH 32 +#define DMP_BLPFSTCL 34 +#define DMP_BLPFSXH 36 +#define DMP_BLPFSXL 38 +#define DMP_BLPFSYH 40 +#define DMP_BLPFSYL 42 +#define DMP_BLPFSZH 44 +#define DMP_BLPFSZL 46 +#define DMP_BLPFMTC 48 +#define DMP_SMC 50 +#define DMP_BLPFMXH 52 +#define DMP_BLPFMXL 54 +#define DMP_BLPFMYH 56 +#define DMP_BLPFMYL 58 +#define DMP_BLPFMZH 60 +#define DMP_BLPFMZL 62 +#define DMP_BLPFC 64 +#define DMP_SMCTH 66 +#define DMP_0H2 68 +#define DMP_0L2 70 +#define DMP_BERR2H 72 +#define DMP_BERR2L 74 +#define DMP_BERR2NH 76 +#define DMP_SMCINC 78 +#define DMP_ANGVBXH 80 +#define DMP_ANGVBXL 82 +#define DMP_ANGVBYH 84 +#define DMP_ANGVBYL 86 +#define DMP_ANGVBZH 88 +#define DMP_ANGVBZL 90 +#define DMP_BERR1H 92 +#define DMP_BERR1L 94 +#define DMP_ATCH 96 +#define DMP_BIASUNCSF 98 +#define DMP_ACT2H 100 +#define DMP_ACT2L 102 +#define DMP_GSFH 104 +#define DMP_GSFL 106 +#define DMP_GH 108 +#define DMP_GL 110 +#define DMP_0_5H 112 +#define DMP_0_5L 114 +#define DMP_0_0H 116 +#define DMP_0_0L 118 +#define DMP_1_0H 120 +#define DMP_1_0L 122 +#define DMP_1_5H 124 +#define DMP_1_5L 126 +#define DMP_TMP1AH 128 +#define DMP_TMP1AL 130 +#define DMP_TMP2AH 132 +#define DMP_TMP2AL 134 +#define DMP_TMP3AH 136 +#define DMP_TMP3AL 138 +#define DMP_TMP4AH 140 +#define DMP_TMP4AL 142 +#define DMP_XACCW 144 +#define DMP_TMP5 146 +#define DMP_XACCB 148 +#define DMP_TMP8 150 +#define DMP_YACCB 152 +#define DMP_TMP9 154 +#define DMP_ZACCB 156 +#define DMP_TMP10 158 +#define DMP_DZH 160 +#define DMP_DZL 162 +#define DMP_XGCH 164 +#define DMP_XGCL 166 +#define DMP_YGCH 168 +#define DMP_YGCL 170 +#define DMP_ZGCH 172 +#define DMP_ZGCL 174 +#define DMP_YACCW 176 +#define DMP_TMP7 178 +#define DMP_AFB1H 180 +#define DMP_AFB1L 182 +#define DMP_AFB2H 184 +#define DMP_AFB2L 186 +#define DMP_MAGFBH 188 +#define DMP_MAGFBL 190 +#define DMP_QT1H 192 +#define DMP_QT1L 194 +#define DMP_QT2H 196 +#define DMP_QT2L 198 +#define DMP_QT3H 200 +#define DMP_QT3L 202 +#define DMP_QT4H 204 +#define DMP_QT4L 206 +#define DMP_CTRL1H 208 +#define DMP_CTRL1L 210 +#define DMP_CTRL2H 212 +#define DMP_CTRL2L 214 +#define DMP_CTRL3H 216 +#define DMP_CTRL3L 218 +#define DMP_CTRL4H 220 +#define DMP_CTRL4L 222 +#define DMP_CTRLS1 224 +#define DMP_CTRLSF1 226 +#define DMP_CTRLS2 228 +#define DMP_CTRLSF2 230 +#define DMP_CTRLS3 232 +#define DMP_CTRLSFNLL 234 +#define DMP_CTRLS4 236 +#define DMP_CTRLSFNL2 238 +#define DMP_CTRLSFNL 240 +#define DMP_TMP30 242 +#define DMP_CTRLSFJT 244 +#define DMP_TMP31 246 +#define DMP_TMP11 248 +#define DMP_CTRLSF2_2 250 +#define DMP_TMP12 252 +#define DMP_CTRLSF1_2 254 +#define DMP_PREVPTAT 256 +#define DMP_ACCZB 258 +#define DMP_ACCXB 264 +#define DMP_ACCYB 266 +#define DMP_1HB 272 +#define DMP_1LB 274 +#define DMP_0H 276 +#define DMP_0L 278 +#define DMP_ASR22H 280 +#define DMP_ASR22L 282 +#define DMP_ASR6H 284 +#define DMP_ASR6L 286 +#define DMP_TMP13 288 +#define DMP_TMP14 290 +#define DMP_FINTXH 292 +#define DMP_FINTXL 294 +#define DMP_FINTYH 296 +#define DMP_FINTYL 298 +#define DMP_FINTZH 300 +#define DMP_FINTZL 302 +#define DMP_TMP1BH 304 +#define DMP_TMP1BL 306 +#define DMP_TMP2BH 308 +#define DMP_TMP2BL 310 +#define DMP_TMP3BH 312 +#define DMP_TMP3BL 314 +#define DMP_TMP4BH 316 +#define DMP_TMP4BL 318 +#define DMP_STXG 320 +#define DMP_ZCTXG 322 +#define DMP_STYG 324 +#define DMP_ZCTYG 326 +#define DMP_STZG 328 +#define DMP_ZCTZG 330 +#define DMP_CTRLSFJT2 332 +#define DMP_CTRLSFJTCNT 334 +#define DMP_PVXG 336 +#define DMP_TMP15 338 +#define DMP_PVYG 340 +#define DMP_TMP16 342 +#define DMP_PVZG 344 +#define DMP_TMP17 346 +#define DMP_MNMFLAGH 352 +#define DMP_MNMFLAGL 354 +#define DMP_MNMTMH 356 +#define DMP_MNMTML 358 +#define DMP_MNMTMTHRH 360 +#define DMP_MNMTMTHRL 362 +#define DMP_MNMTHRH 364 +#define DMP_MNMTHRL 366 +#define DMP_ACCQD4H 368 +#define DMP_ACCQD4L 370 +#define DMP_ACCQD5H 372 +#define DMP_ACCQD5L 374 +#define DMP_ACCQD6H 376 +#define DMP_ACCQD6L 378 +#define DMP_ACCQD7H 380 +#define DMP_ACCQD7L 382 +#define DMP_ACCQD0H 384 +#define DMP_ACCQD0L 386 +#define DMP_ACCQD1H 388 +#define DMP_ACCQD1L 390 +#define DMP_ACCQD2H 392 +#define DMP_ACCQD2L 394 +#define DMP_ACCQD3H 396 +#define DMP_ACCQD3L 398 +#define DMP_XN2H 400 +#define DMP_XN2L 402 +#define DMP_XN1H 404 +#define DMP_XN1L 406 +#define DMP_YN2H 408 +#define DMP_YN2L 410 +#define DMP_YN1H 412 +#define DMP_YN1L 414 +#define DMP_YH 416 +#define DMP_YL 418 +#define DMP_B0H 420 +#define DMP_B0L 422 +#define DMP_A1H 424 +#define DMP_A1L 426 +#define DMP_A2H 428 +#define DMP_A2L 430 +#define DMP_SEM1 432 +#define DMP_FIFOCNT 434 +#define DMP_SH_TH_X 436 +#define DMP_PACKET 438 +#define DMP_SH_TH_Y 440 +#define DMP_FOOTER 442 +#define DMP_SH_TH_Z 444 +#define DMP_TEMP29 448 +#define DMP_TEMP30 450 +#define DMP_XACCB_PRE 452 +#define DMP_XACCB_PREL 454 +#define DMP_YACCB_PRE 456 +#define DMP_YACCB_PREL 458 +#define DMP_ZACCB_PRE 460 +#define DMP_ZACCB_PREL 462 +#define DMP_TMP22 464 +#define DMP_TAP_TIMER 466 +#define DMP_TAP_THX 468 +#define DMP_TAP_THY 472 +#define DMP_TAP_THZ 476 +#define DMP_TAPW_MIN 478 +#define DMP_TMP25 480 +#define DMP_TMP26 482 +#define DMP_TMP27 484 +#define DMP_TMP28 486 +#define DMP_ORIENT 488 +#define DMP_THRSH 490 +#define DMP_ENDIANH 492 +#define DMP_ENDIANL 494 +#define DMP_BLPFNMTCH 496 +#define DMP_BLPFNMTCL 498 +#define DMP_BLPFNMXH 500 +#define DMP_BLPFNMXL 502 +#define DMP_BLPFNMYH 504 +#define DMP_BLPFNMYL 506 +#define DMP_BLPFNMZH 508 +#define DMP_BLPFNMZL 510 +#ifdef __cplusplus +} +#endif +#endif // DMPMAP_H diff --git a/Inc/setup.h b/Inc/setup.h new file mode 100644 index 0000000..c9f5d33 --- /dev/null +++ b/Inc/setup.h @@ -0,0 +1,37 @@ +/** + * This file is part of the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +// Define to prevent recursive inclusion +#ifndef SETUP_H +#define SETUP_H + +// Includes +#include "gd32f1x0.h" + +// Function declarations +void gpio_config(void); +void usart_config(uint32_t selUSART, uint32_t selBaudRate); +void usart_Tx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t Size); +void usart_Rx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t Size); + +void i2c_config(void); +void i2c_nvic_config(void); + +#endif + diff --git a/Inc/systick.h b/Inc/systick.h new file mode 100644 index 0000000..a372db3 --- /dev/null +++ b/Inc/systick.h @@ -0,0 +1,53 @@ +/*! + \file systick.h + \brief the header file of systick + + \version 2016-01-15, V1.0.0, demo for GD32F1x0 + \version 2016-05-13, V2.0.0, demo for GD32F1x0 + \version 2019-11-20, V3.0.0, demo for GD32F1x0 +*/ + +/* + Copyright (c) 2019, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); +/* tick count increment */ +void tick_count_increment(void); +/* get tick count ms */ +void get_tick_count_ms(unsigned long *count); + +#endif /* SYS_TICK_H */ diff --git a/Inc/util.h b/Inc/util.h new file mode 100644 index 0000000..a8c02e7 --- /dev/null +++ b/Inc/util.h @@ -0,0 +1,67 @@ +/** + * This file is part of the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +// Define to prevent recursive inclusion +#ifndef UTIL_H +#define UTIL_H + +#include +#include "gd32f1x0.h" +#include "defines.h" + + +extern volatile int8_t i2c_status; +extern volatile i2c_cmd i2c_ReadWriteCmd; +extern volatile uint8_t i2c_slaveAddress; +extern volatile uint8_t i2c_regAddress; +extern volatile uint8_t* i2c_txbuffer; +extern volatile uint8_t* i2c_rxbuffer; +extern volatile uint8_t i2c_nDABytes; +extern volatile int8_t i2c_nRABytes; + +#ifdef AUX45_USE_I2C +extern volatile int8_t i2c_aux_status; +extern volatile i2c_cmd i2c_aux_ReadWriteCmd; +extern volatile uint8_t i2c_aux_slaveAddress; +extern volatile uint8_t i2c_aux_regAddress; +extern volatile uint8_t* i2c_aux_txbuffer; +extern volatile uint8_t* i2c_aux_rxbuffer; +extern volatile uint8_t i2c_aux_nDABytes; +extern volatile int8_t i2c_aux_nRABytes; +#endif + +/* general functions */ +void consoleLog(char *message); +void introDemoLED(uint32_t tDelay); + +/* i2c write/read functions */ +int8_t i2c_writeBytes(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data); +int8_t i2c_writeByte (uint8_t slaveAddr, uint8_t regAddr, uint8_t data); +int8_t i2c_writeBit (uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data); +int8_t i2c_readBytes (uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data); +int8_t i2c_readByte (uint8_t slaveAddr, uint8_t regAddr, uint8_t *data); +int8_t i2c_readBit (uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data); + +#ifdef AUX45_USE_I2C +int8_t i2c_aux_writeBytes(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data); +int8_t i2c_aux_readBytes (uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data); +#endif + +#endif + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e62ec04 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/MDK-ARM/sideboard-hack.uvopt b/MDK-ARM/sideboard-hack.uvopt new file mode 100644 index 0000000..1302f11 --- /dev/null +++ b/MDK-ARM/sideboard-hack.uvopt @@ -0,0 +1,642 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + sideboard-hack + 0x4 + ARM-ADS + + 8000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 0 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 5 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0GD32F1x0_32 -FS08000000 -FL08000) + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + Startup + 0 + 0 + 0 + 0 + + 1 + 1 + 2 + 0 + 0 + 0 + .\startup_gd32f1x0.s + startup_gd32f1x0.s + 0 + 0 + + + + + CMSIS + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ..\Drivers\CMSIS\Source\system_gd32f1x0.c + system_gd32f1x0.c + 0 + 0 + + + + + Peripheral + 0 + 0 + 0 + 0 + + 3 + 3 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_adc.c + gd32f1x0_adc.c + 0 + 0 + + + 3 + 4 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_can.c + gd32f1x0_can.c + 0 + 0 + + + 3 + 5 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_cec.c + gd32f1x0_cec.c + 0 + 0 + + + 3 + 6 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_cmp.c + gd32f1x0_cmp.c + 0 + 0 + + + 3 + 7 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_crc.c + gd32f1x0_crc.c + 0 + 0 + + + 3 + 8 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_dac.c + gd32f1x0_dac.c + 0 + 0 + + + 3 + 9 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_dbg.c + gd32f1x0_dbg.c + 0 + 0 + + + 3 + 10 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_dma.c + gd32f1x0_dma.c + 0 + 0 + + + 3 + 11 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_exti.c + gd32f1x0_exti.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_fmc.c + gd32f1x0_fmc.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_fwdgt.c + gd32f1x0_fwdgt.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_gpio.c + gd32f1x0_gpio.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_i2c.c + gd32f1x0_i2c.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_ivref.c + gd32f1x0_ivref.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_misc.c + gd32f1x0_misc.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_opa.c + gd32f1x0_opa.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_pmu.c + gd32f1x0_pmu.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_rcu.c + gd32f1x0_rcu.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_rtc.c + gd32f1x0_rtc.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_slcd.c + gd32f1x0_slcd.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_spi.c + gd32f1x0_spi.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_syscfg.c + gd32f1x0_syscfg.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_timer.c + gd32f1x0_timer.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_tsi.c + gd32f1x0_tsi.c + 0 + 0 + + + 3 + 27 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_usart.c + gd32f1x0_usart.c + 0 + 0 + + + 3 + 28 + 1 + 0 + 0 + 0 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_wwdgt.c + gd32f1x0_wwdgt.c + 0 + 0 + + + + + Src + 1 + 0 + 0 + 0 + + 4 + 29 + 1 + 0 + 0 + 0 + ..\Src\gd32f1x0_it.c + gd32f1x0_it.c + 0 + 0 + + + 4 + 30 + 1 + 0 + 0 + 0 + ..\Src\main.c + main.c + 0 + 0 + + + 4 + 31 + 1 + 0 + 0 + 0 + ..\Src\setup.c + setup.c + 0 + 0 + + + 4 + 32 + 1 + 0 + 0 + 0 + ..\Src\systick.c + systick.c + 0 + 0 + + + 4 + 33 + 1 + 0 + 0 + 0 + ..\Src\util.c + util.c + 0 + 0 + + + 4 + 34 + 1 + 0 + 0 + 0 + ..\Src\i2c_it.c + i2c_it.c + 0 + 0 + + + 4 + 35 + 1 + 0 + 0 + 0 + ..\Src\mpu6050.c + mpu6050.c + 0 + 0 + + + 4 + 36 + 1 + 0 + 0 + 0 + ..\Src\mpu6050_dmp.c + mpu6050_dmp.c + 0 + 0 + + + 4 + 37 + 5 + 0 + 0 + 0 + ..\Inc\config.h + config.h + 0 + 0 + + + +
diff --git a/MDK-ARM/sideboard-hack.uvproj b/MDK-ARM/sideboard-hack.uvproj new file mode 100644 index 0000000..2446925 --- /dev/null +++ b/MDK-ARM/sideboard-hack.uvproj @@ -0,0 +1,627 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + sideboard-hack + 0x4 + ARM-ADS + 5060422::V5.06 update 4 (build 422)::ARMCC + + + GD32F130C6 + GigaDevice + IRAM(0x20000000-0x20000FFF) IROM(0x08000000-0x08007FFF) CLOCK(8000000) CPUTYPE("Cortex-M3") + + "Startup\GD\GD32F1x0\startup_gd32f1x0.s" ("GD32F1x0 Startup Code") + UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0GD32F1x0_32 -FS08000000 -FL08000) + 7715 + gd32f1x0.h + + + + + + + + + + SFD\GD\GD32F1x0\GD32F1x0.SFR + 0 + 0 + + + + GD\GD32F1x0\ + GD\GD32F1x0\ + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + firmware + 1 + 0 + 1 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP + DCM.DLL + -pCM3 + SARMCM3.DLL + + TCM.DLL + -pCM3 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + + 0 + 5 + + + + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M3" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x1000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x1000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 4 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + USE_STDPERIPH_DRIVER, GD32F130_150 + + ..\Inc;..\Drivers\CMSIS\Include;..\Drivers\CMSIS;..\Drivers\GD32F1x0_standard_peripheral\Include + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + .\Objects\sideboard-hack.sct + + + + + + + + + + + Startup + + + startup_gd32f1x0.s + 2 + .\startup_gd32f1x0.s + + + + + CMSIS + + + system_gd32f1x0.c + 1 + ..\Drivers\CMSIS\Source\system_gd32f1x0.c + + + + + Peripheral + + + gd32f1x0_adc.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_adc.c + + + gd32f1x0_can.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_can.c + + + gd32f1x0_cec.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_cec.c + + + gd32f1x0_cmp.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_cmp.c + + + gd32f1x0_crc.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_crc.c + + + gd32f1x0_dac.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_dac.c + + + gd32f1x0_dbg.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_dbg.c + + + gd32f1x0_dma.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_dma.c + + + gd32f1x0_exti.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_exti.c + + + gd32f1x0_fmc.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_fmc.c + + + gd32f1x0_fwdgt.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_fwdgt.c + + + gd32f1x0_gpio.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_gpio.c + + + gd32f1x0_i2c.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_i2c.c + + + gd32f1x0_ivref.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_ivref.c + + + gd32f1x0_misc.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_misc.c + + + gd32f1x0_opa.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_opa.c + + + gd32f1x0_pmu.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_pmu.c + + + gd32f1x0_rcu.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_rcu.c + + + gd32f1x0_rtc.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_rtc.c + + + gd32f1x0_slcd.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_slcd.c + + + gd32f1x0_spi.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_spi.c + + + gd32f1x0_syscfg.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_syscfg.c + + + gd32f1x0_timer.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_timer.c + + + gd32f1x0_tsi.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_tsi.c + + + gd32f1x0_usart.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_usart.c + + + gd32f1x0_wwdgt.c + 1 + ..\Drivers\GD32F1x0_standard_peripheral\Source\gd32f1x0_wwdgt.c + + + + + Src + + + gd32f1x0_it.c + 1 + ..\Src\gd32f1x0_it.c + + + main.c + 1 + ..\Src\main.c + + + setup.c + 1 + ..\Src\setup.c + + + systick.c + 1 + ..\Src\systick.c + + + util.c + 1 + ..\Src\util.c + + + i2c_it.c + 1 + ..\Src\i2c_it.c + + + mpu6050.c + 1 + ..\Src\mpu6050.c + + + mpu6050_dmp.c + 1 + ..\Src\mpu6050_dmp.c + + + config.h + 5 + ..\Inc\config.h + + + + + + + +
diff --git a/MDK-ARM/startup_gd32f1x0.s b/MDK-ARM/startup_gd32f1x0.s new file mode 100644 index 0000000..21422d0 --- /dev/null +++ b/MDK-ARM/startup_gd32f1x0.s @@ -0,0 +1,328 @@ +;/*! +; \file startup_gd32f1x0.s +; \brief start up file +;*/ + +;/* +; Copyright (C) 2017 GigaDevice + +; 2014-12-26, V1.0.0, firmware for GD32F1x0(x=3,5) +; 2016-01-15, V2.0.0, firmware for GD32F1x0(x=3,5,7,9) +; 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) +; 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +;*/ + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000400 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; /* reset Vector Mapped to at Address 0 */ + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + +; /* external interrupts handler */ + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect + DCD RTC_IRQHandler ; 18:RTC through EXTI Line + DCD FMC_IRQHandler ; 19:FMC + DCD RCU_IRQHandler ; 20:RCU + DCD EXTI0_1_IRQHandler ; 21:EXTI Line 0 and EXTI Line 1 + DCD EXTI2_3_IRQHandler ; 22:EXTI Line 2 and EXTI Line 3 + DCD EXTI4_15_IRQHandler ; 23:EXTI Line 4 to EXTI Line 15 + DCD TSI_IRQHandler ; 24:TSI + DCD DMA_Channel0_IRQHandler ; 25:DMA Channel 0 + DCD DMA_Channel1_2_IRQHandler ; 26:DMA Channel 1 and DMA Channel 2 + DCD DMA_Channel3_4_IRQHandler ; 27:DMA Channel 3 and DMA Channel 4 + DCD ADC_CMP_IRQHandler ; 28:ADC and Comparator 0-1 + DCD TIMER0_BRK_UP_TRG_COM_IRQHandler ; 29:TIMER0 Break,Update,Trigger and Commutation + DCD TIMER0_Channel_IRQHandler ; 30:TIMER0 Channel + DCD TIMER1_IRQHandler ; 31:TIMER1 + DCD TIMER2_IRQHandler ; 32:TIMER2 + DCD TIMER5_DAC_IRQHandler ; 33:TIMER5 and DAC + DCD 0 ; Reserved + DCD TIMER13_IRQHandler ; 35:TIMER13 + DCD TIMER14_IRQHandler ; 36:TIMER14 + DCD TIMER15_IRQHandler ; 37:TIMER15 + DCD TIMER16_IRQHandler ; 38:TIMER16 + DCD I2C0_EV_IRQHandler ; 39:I2C0 Event + DCD I2C1_EV_IRQHandler ; 40:I2C1 Event + DCD SPI0_IRQHandler ; 41:SPI0 + DCD SPI1_IRQHandler ; 42:SPI1 + DCD USART0_IRQHandler ; 43:USART0 + DCD USART1_IRQHandler ; 44:USART1 + DCD 0 ; Reserved + DCD CEC_IRQHandler ; 46:CEC + DCD 0 ; Reserved + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD 0 ; Reserved + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error + DCD I2C2_EV_IRQHandler ; 51:I2C2 Event + DCD I2C2_ER_IRQHandler ; 52:I2C2 Error + DCD USBD_LP_IRQHandler ; 53:USBD LP + DCD USBD_HP_IRQHandler ; 54:USBD HP + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD USBDWakeUp_IRQHandler ; 58:USBD Wakeup + DCD CAN0_TX_IRQHandler ; 59:CAN0 TX + DCD CAN0_RX0_IRQHandler ; 60:CAN0 RX0 + DCD CAN0_RX1_IRQHandler ; 61:CAN0 RX1 + DCD CAN0_SCE_IRQHandler ; 62:CAN0 SCE + DCD SLCD_IRQHandler ; 63:SLCD + DCD DMA_Channel5_6_IRQHandler ; 64:DMA Channel5 and Channel6 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SPI2_IRQHandler ; 67:SPI2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD CAN1_TX_IRQHandler ; 86:CAN1 TX + DCD CAN1_RX0_IRQHandler ; 87:CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; 88:CAN1 RX1 + DCD CAN1_SCE_IRQHandler ; 89:CAN1 SCE +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +;/* reset Handler */ +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +;/* dummy Exception Handlers */ +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler\ + PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler\ + PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC +; /* external interrupts handler */ + EXPORT WWDGT_IRQHandler [WEAK] + EXPORT LVD_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT RCU_IRQHandler [WEAK] + EXPORT EXTI0_1_IRQHandler [WEAK] + EXPORT EXTI2_3_IRQHandler [WEAK] + EXPORT EXTI4_15_IRQHandler [WEAK] + EXPORT TSI_IRQHandler [WEAK] + EXPORT DMA_Channel0_IRQHandler [WEAK] + EXPORT DMA_Channel1_2_IRQHandler [WEAK] + EXPORT DMA_Channel3_4_IRQHandler [WEAK] + EXPORT ADC_CMP_IRQHandler [WEAK] + EXPORT TIMER0_BRK_UP_TRG_COM_IRQHandler [WEAK] + EXPORT TIMER0_Channel_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT TIMER5_DAC_IRQHandler [WEAK] + EXPORT TIMER13_IRQHandler [WEAK] + EXPORT TIMER14_IRQHandler [WEAK] + EXPORT TIMER15_IRQHandler [WEAK] + EXPORT TIMER16_IRQHandler [WEAK] + EXPORT I2C0_EV_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT SPI0_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT USART0_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT CEC_IRQHandler [WEAK] + EXPORT I2C0_ER_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT USBD_LP_IRQHandler [WEAK] + EXPORT USBD_HP_IRQHandler [WEAK] + EXPORT USBDWakeUp_IRQHandler [WEAK] + EXPORT CAN0_TX_IRQHandler [WEAK] + EXPORT CAN0_RX0_IRQHandler [WEAK] + EXPORT CAN0_RX1_IRQHandler [WEAK] + EXPORT CAN0_SCE_IRQHandler [WEAK] + EXPORT SLCD_IRQHandler [WEAK] + EXPORT DMA_Channel5_6_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT CAN1_TX_IRQHandler [WEAK] + EXPORT CAN1_RX0_IRQHandler [WEAK] + EXPORT CAN1_RX1_IRQHandler [WEAK] + EXPORT CAN1_SCE_IRQHandler [WEAK] + +;/* external interrupts handler */ +WWDGT_IRQHandler +LVD_IRQHandler +RTC_IRQHandler +FMC_IRQHandler +RCU_IRQHandler +EXTI0_1_IRQHandler +EXTI2_3_IRQHandler +EXTI4_15_IRQHandler +TSI_IRQHandler +DMA_Channel0_IRQHandler +DMA_Channel1_2_IRQHandler +DMA_Channel3_4_IRQHandler +ADC_CMP_IRQHandler +TIMER0_BRK_UP_TRG_COM_IRQHandler +TIMER0_Channel_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +TIMER5_DAC_IRQHandler +TIMER13_IRQHandler +TIMER14_IRQHandler +TIMER15_IRQHandler +TIMER16_IRQHandler +I2C0_EV_IRQHandler +I2C1_EV_IRQHandler +SPI0_IRQHandler +SPI1_IRQHandler +USART0_IRQHandler +USART1_IRQHandler +CEC_IRQHandler +I2C0_ER_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +USBD_LP_IRQHandler +USBD_HP_IRQHandler +USBDWakeUp_IRQHandler +CAN0_TX_IRQHandler +CAN0_RX0_IRQHandler +CAN0_RX1_IRQHandler +CAN0_SCE_IRQHandler +SLCD_IRQHandler +DMA_Channel5_6_IRQHandler +SPI2_IRQHandler +CAN1_TX_IRQHandler +CAN1_RX0_IRQHandler +CAN1_RX1_IRQHandler +CAN1_SCE_IRQHandler + B . + ENDP + + ALIGN + +; user Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4c3a18a --- /dev/null +++ b/Makefile @@ -0,0 +1,210 @@ +########################################################################################################################## +# File automatically-generated by tool: [projectgenerator] version: [3.1.0] date: [Mon Feb 03 19:54:27 CET 2020] +########################################################################################################################## + +# ------------------------------------------------ +# Generic Makefile (based on gcc) +# +# ChangeLog : +# 2017-02-10 - Several enhancements + project update mode +# 2015-07-22 - first version +# ------------------------------------------------ + +###################################### +# target +###################################### +TARGET = firmware + + +###################################### +# building variables +###################################### +# debug build? +DEBUG = 1 +# optimization for size +OPT = -Os + + +####################################### +# paths +####################################### +# Build path +BUILD_DIR = build + +###################################### +# source +###################################### +# C sources +C_SOURCES = \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_adc.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_can.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cec.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cmp.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_crc.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dac.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dbg.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dma.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_exti.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fmc.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fwdgt.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_gpio.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_i2c.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_ivref.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_misc.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_opa.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_pmu.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rcu.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rtc.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_slcd.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_spi.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_syscfg.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_timer.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_tsi.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_usart.c \ +Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_wwdgt.c \ +Drivers/CMSIS/Source/system_gd32f1x0.c \ +Src/main.c \ +Src/util.c \ +Src/systick.c \ +Src/mpu6050.c \ +Src/mpu6050_dmp.c \ +Src/setup.c \ +Src/i2c_it.c \ +Src/gd32f1x0_it.c + +# ASM sources +ASM_SOURCES = \ +startup_gd32f1x0.s + + +####################################### +# binaries +####################################### +PREFIX = arm-none-eabi- +# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) +# either it can be added to the PATH environment variable. +ifdef GCC_PATH +CC = $(GCC_PATH)/$(PREFIX)gcc +AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp +CP = $(GCC_PATH)/$(PREFIX)objcopy +SZ = $(GCC_PATH)/$(PREFIX)size +else +CC = $(PREFIX)gcc +AS = $(PREFIX)gcc -x assembler-with-cpp +CP = $(PREFIX)objcopy +SZ = $(PREFIX)size +endif +HEX = $(CP) -O ihex +BIN = $(CP) -O binary -S + +####################################### +# CFLAGS +####################################### +# cpu +CPU = -mcpu=cortex-m3 + +# fpu +# NONE for Cortex-M0/M0+/M3 + +# float-abi + + +# mcu +MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) + +# macros for gcc +# AS defines +AS_DEFS = + +# C defines +C_DEFS = \ +-DUSE_STDPERIPH_DRIVER \ +-DGD32F130_150 + + +# AS includes +AS_INCLUDES = + +# C includes +C_INCLUDES = \ +-IInc \ +-IDrivers/GD32F1x0_standard_peripheral/Include \ +-IDrivers/CMSIS/Include \ +-IDrivers/CMSIS + +# compile gcc flags +ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +ifeq ($(DEBUG), 1) +CFLAGS += -g -gdwarf-2 +endif + + +# Generate dependency information +CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" + + +####################################### +# LDFLAGS +####################################### +# link script +LDSCRIPT = GD32F130C6_FLASH.ld + +# libraries +LIBS = -lc -lm -lnosys +LIBDIR = +LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections + +# default action: build all +all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin + + +####################################### +# build the application +####################################### +# list of objects +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) +# list of ASM program objects +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) +vpath %.s $(sort $(dir $(ASM_SOURCES))) + +$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) + $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ + +$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) + $(AS) -c $(CFLAGS) $< -o $@ + +$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile + $(CC) $(OBJECTS) $(LDFLAGS) -o $@ + $(SZ) $@ + +$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + $(HEX) $< $@ + +$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + $(BIN) $< $@ + +$(BUILD_DIR): + mkdir $@ + +####################################### +# clean up +####################################### +clean: + -rm -fR $(BUILD_DIR) + +flash: + st-flash --reset write $(BUILD_DIR)/$(TARGET).bin 0x8000000 + +unlock: + openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c init -c "reset halt" -c "stm32f1x unlock 0" + +####################################### +# dependencies +####################################### +-include $(wildcard $(BUILD_DIR)/*.d) + +# *** EOF *** diff --git a/README.md b/README.md new file mode 100644 index 0000000..d83a6fa --- /dev/null +++ b/README.md @@ -0,0 +1,89 @@ +# hoverboard-sideboard-hack-GD + +[![Build Status](link to travis) +[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) +[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=CU2SWN2XV9SCY¤cy_code=EUR&source=url) + +This repository implements the firmware for the hoveboard sideboards. The hoveboard comes with two identical sideboards that can be flashed with this firmware. + +The sideboards comes in two MCU flavours: +- [GD32F130C6T6](/docs/GD32F130xx-Datasheet_Rev3.3.pdf) -> use this repository if you have a GD32 MCU +- [STM32F103C8T6](/docs/stm32f103c8-Datasheet.pdf) -> use my [other repository](link) if you have an STM32 MCU + +--- +## Hardware + +![sideboard](/docs/pictures/sideboard_pinout.png) + +The original sideboard hardware supports one 4-pin cable that originally were connected to the hoveboard mainboard. They break out GND, 12/15V and USART. Additionally, two ports are used to connect to the LED boards. On the back of the board, two Photo Interrupter Optical Switches can be found, originally used to detect if a human is standing on the hoverboard. + +The [GD32F130C6T6](/docs/GD32F130xx-Datasheet_Rev3.3.pdf) pinout is shown in the follwing figure: +![MCU_pinout](/docs/pictures/MCU_pinout.png) + +The sideboards, also called sensor boards, feature an [MPU-6050](https://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/) from Invensense. The MPU-6050 determines the board orientation by combining a 3-axis gyroscope and a 3-axis accelerometer on the same silicon die, together with an onboard Digital Motion Processorâ„¢ (DMPâ„¢), which processes complex 6-axis MotionFusion algorithms. The DMPâ„¢ offers many features, such as: +* Accelerometer and Gyroscop raw data output +* Quaternion output +* Temperature output +* Pedometer +* Interrupts on gesture events such as Tap on all axes or Orientation change +* Low-power modes +* Self-test and calibration + +The MPU-6050 pinout and orientation of axes is shown in the follwing figure: +![MPU6050_pinout](/docs/pictures/MPU6050_pinout.png) + +For more details check-out the [MPU-6050 datasheet](/docs/1_MPU-6000-Datasheet.pdf) and [MPU-6050 registers](/docs/2_MPU-6000-Register-Map.pdf). + +--- +## Flashing + +On the sideboard, there is a debugging header with GND, 3V3, SWDIO and SWCLK. Connect GND, SWDIO and SWCLK to your ST-Link V2 programmer. The 3V3 can be either obtained by connecting the pin to the ST-Link programmer or powering the sideboard with 12/15V. + +If you never flashed your sideboard before, the MCU is probably locked. To unlock the flash, check-out the [wiki page](link). + +Then, choose one of the following ways for building and flashing the firmware: + +### 1. Using Keil uVision (recommended) + +In (Keil uVision)[https://www.keil.com/download/product/], open the [sideboard-hack.uvproj](/MDK-ARM/), click Build Target (or press F7), then click Load Code (or press F8). + +### 2. Using Ubuntu + +Prerequisites: install [ST-Flash utility](https://github.com/texane/stlink). + +To build the firmware, type: +``` +make +``` +then you can simply flash the firmware by typing: +``` +make flash +``` + +*Note: If someone finds a way to build and flash the GD32 MCU via (Platformio)[https://platformio.org/] please let me know.* + + +--- +## Example Variants + +This firmware offers currently these variants (selectable in (config.h)[/Inc/config.h]): +- **VARIANT_DEBUG**: In this variant the user can interact with sideboard via a Serial Monitor to observe and check the capabilities of the sideboard. +- **VARIANT_HOVERBOARD**: In this variant the sideboard is communicating with the mainboard of a hoverboard using the (FOC firmware repository)[link]. !This Variant is not yet fully tested! + +Of course the firmware can be further customized for other needs or projects. + +-- +## 3D Visualization Demo + +By calculating the Euler orientation angles from Quaternions, we can make a simple 3D visualization example (see [sketch](/docs/sketch_processing/sketch_processing.pde)) in [Processing](https://processing.org/) as shown below: + +![sketch_pic](/docs/pictures/sketch_processing_pic.png) + + +-- +##Contributions + +Every contribution to this repository is highly appriciated! Feel free to create pull requests to improve this firmware as ultimately you are going to help everyone. + +If you want to donate to keep this firmware updated, check-out the link below: +[![paypal](https://www.paypalobjects.com/en_US/NL/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=CU2SWN2XV9SCY¤cy_code=EUR&source=url) diff --git a/Src/gd32f1x0_it.c b/Src/gd32f1x0_it.c new file mode 100644 index 0000000..e1cdf79 --- /dev/null +++ b/Src/gd32f1x0_it.c @@ -0,0 +1,168 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" +#include "i2c_it.h" +#include "config.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1){ + } +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1){ + } +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1){ + } +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1){ + } +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + tick_count_increment(); + delay_decrement(); +} + +/*! + \brief this function handles I2C0 event interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C0_EV_IRQHandler(void) +{ + I2C0_EventIRQ_Handler(); +} + +/*! + \brief this function handles I2C0 error interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C0_ER_IRQHandler(void) +{ + I2C0_ErrorIRQ_Handler(); +} + +#ifdef AUX45_USE_I2C +/*! + \brief this function handles I2C1 event interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_EV_IRQHandler(void) +{ + I2C1_EventIRQ_Handler(); +} + +/*! + \brief this function handles I2C1 error interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_ER_IRQHandler(void) +{ + I2C1_ErrorIRQ_Handler(); +} +#endif diff --git a/Src/i2c_it.c b/Src/i2c_it.c new file mode 100644 index 0000000..c559018 --- /dev/null +++ b/Src/i2c_it.c @@ -0,0 +1,336 @@ +/** + * This file is part of the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + + +#include "gd32f1x0_i2c.h" +#include "i2c_it.h" +#include "util.h" +#include "systick.h" +#include "config.h" + +void I2C0_EventIRQ_Handler(void) +{ + uint16_t k; + if (i2c_ReadWriteCmd == WRITE) { // check for WRITE command + + // ======================================== WRITE ======================================== + // -------------------------------------------------------------------- + // | Master | S | AD+W | | RA | | DATA | | DATA | | P | + // | Slave | | | ACK | | ACK | | ACK | | ACK | | + // -------------------------------------------------------------------- + + if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SBSEND)) { // check if start condition is sent out in master mode + + i2c_master_addressing(I2C0, i2c_slaveAddress, I2C_TRANSMITTER); // send slave address with Transmit request + + } else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND)) { // check if address is sent in master mode + + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND); // clear ADDSEND bit + + } else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)) { // check if I2C_DATA is empty (Transmitted Byte Empty) + + if (i2c_nRABytes > 0) { // check if the Register Address has been sent + i2c_data_transmit(I2C0, i2c_regAddress); // the master sends the Register Address byte + i2c_nRABytes--; + } else { + if (i2c_nDABytes > 0) { + i2c_data_transmit(I2C0, *i2c_txbuffer++); // the master sends a data byte + i2c_nDABytes--; + for(k=0; k<500; k++); // make some clock cycles delay (otherwise DMP writing will fail!! Reason unknown yet.. could be that writing to MPU6050 memory takes a bit more time) + } else { + i2c_stop_on_bus(I2C0); // the master sends a stop condition to I2C bus + i2c_status = 0; // 0 = Success + i2c_interrupt_disable(I2C0, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); // disable the I2C0 interrupt + } + } + + } + + } else if (i2c_ReadWriteCmd == READ) { // check for READ command + + // ======================================== READ ======================================== + // -------------------------------------------------------------------------------------- + // | Master | S | AD+W | | RA | | S | AD+R | | ACK | | NACK | P | + // | Slave | | | ACK | | ACK | | | ACK | DATA | | DATA | | | + // -------------------------------------------------------------------------------------- + // <---------- Phase 1 ----------> <---------------- Phase 2 ----------------> + + // Phase 1 - send the Register Address + if (i2c_nRABytes >= 0) { + + if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SBSEND)) { // check if start condition is sent out in master mode + + i2c_master_addressing(I2C0, i2c_slaveAddress, I2C_TRANSMITTER); // send slave address with Transmit request + + } else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND)) { // check if address is sent in master mode + + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND); // clear ADDSEND bit + + } else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)) { // check if I2C_DATA is empty (Transmitted Byte Empty) + if (i2c_nRABytes > 0) { // check RABytes + i2c_data_transmit(I2C0, i2c_regAddress); // the master sends the Register Address byte + } else { + i2c_start_on_bus(I2C0); // send start condition + } + i2c_nRABytes--; + } + + // Phase 2 - read Data + } else { + + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SBSEND)){ // check if start condition is sent out in master mode + + i2c_master_addressing(I2C0, i2c_slaveAddress, I2C_RECEIVER); // sends slave address with Receive Request + + }else if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND)){ // check if address is sent in master mode + + if((1 == i2c_nDABytes) || (2 == i2c_nDABytes)){ + i2c_ack_config(I2C0, I2C_ACK_DISABLE); // clear the ACKEN before the ADDSEND is cleared + i2c_interrupt_flag_clear(I2C0,I2C_INT_FLAG_ADDSEND); // clear the ADDSEND bit + }else{ + i2c_interrupt_flag_clear(I2C0,I2C_INT_FLAG_ADDSEND); // clear the ADDSEND bit + } + + }else if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_RBNE)){ // check if I2C_DATA is not Empty (Received Byte Not Empty) + if(i2c_nDABytes > 0){ + if(3 == i2c_nDABytes){ + while(!i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_BTC)); // wait until the second last data byte is received into the shift register + i2c_ack_config(I2C0, I2C_ACK_DISABLE); // send a NACK for the last data byte + } + *i2c_rxbuffer++ = i2c_data_receive(I2C0); // read a data byte from I2C_DATA + i2c_nDABytes--; + if(0 == i2c_nDABytes){ + i2c_stop_on_bus(I2C0); // send a stop condition + i2c_status = 0; // 0 = Success + i2c_ack_config(I2C0, I2C_ACK_ENABLE); + i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT); + i2c_interrupt_disable(I2C0, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + } + } + + } + + } + } + +} + + + +void I2C0_ErrorIRQ_Handler(void) +{ + /* no acknowledge received */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR); + } + + /* SMBus alert */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBALT)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBALT); + } + + /* bus timeout in SMBus mode */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBTO)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBTO); + } + + /* over-run or under-run when SCL stretch is disabled */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_OUERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR); + } + + /* arbitration lost */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_LOSTARB)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_LOSTARB); + } + + /* bus error */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_BERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_BERR); + } + + /* CRC value doesn't match */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_PECERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_PECERR); + } + /* disable the error interrupt */ + i2c_interrupt_disable(I2C0,I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); +} + + +#ifdef AUX45_USE_I2C +/*! + \brief handle I2C1 event interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_EventIRQ_Handler(void) +{ + uint16_t k; + if (i2c_aux_ReadWriteCmd == WRITE) { // check for WRITE command + + // ======================================== WRITE ======================================== + // -------------------------------------------------------------------- + // | Master | S | AD+W | | RA | | DATA | | DATA | | P | + // | Slave | | | ACK | | ACK | | ACK | | ACK | | + // -------------------------------------------------------------------- + + if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SBSEND)) { // check if start condition is sent out in master mode + + i2c_master_addressing(I2C1, i2c_aux_slaveAddress, I2C_TRANSMITTER); // send slave address with Transmit request + + } else if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_ADDSEND)) { // check if address is sent in master mode + + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_ADDSEND); // clear ADDSEND bit + + } else if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_TBE)) { // check if I2C_DATA is empty (Transmitted Byte Empty) + + if (i2c_aux_nRABytes > 0) { // check if the Register Address has been sent + i2c_data_transmit(I2C1, i2c_aux_regAddress); // the master sends the Register Address byte + i2c_aux_nRABytes--; + } else { + if (i2c_aux_nDABytes > 0) { + i2c_data_transmit(I2C1, *i2c_aux_txbuffer++); // the master sends a data byte + i2c_aux_nDABytes--; + for(k=0; k<500; k++); // make some clock cycles delay (otherwise DMP writing will fail!! Reason unknown yet.. could be that writing to MPU6050 memory takes a bit more time) + } else { + i2c_stop_on_bus(I2C1); // the master sends a stop condition to I2C bus + i2c_aux_status = 0; // 0 = Success + i2c_interrupt_disable(I2C1, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); // disable the I2C0 interrupt + } + } + + } + + } else if (i2c_aux_ReadWriteCmd == READ) { // check for READ command + + // ======================================== READ ======================================== + // -------------------------------------------------------------------------------------- + // | Master | S | AD+W | | RA | | S | AD+R | | ACK | | NACK | P | + // | Slave | | | ACK | | ACK | | | ACK | DATA | | DATA | | | + // -------------------------------------------------------------------------------------- + // <---------- Phase 1 ----------> <---------------- Phase 2 ----------------> + + // Phase 1 - send the Register Address + if (i2c_aux_nRABytes >= 0) { + + if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SBSEND)) { // check if start condition is sent out in master mode + + i2c_master_addressing(I2C1, i2c_aux_slaveAddress, I2C_TRANSMITTER); // send slave address with Transmit request + + } else if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_ADDSEND)) { // check if address is sent in master mode + + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_ADDSEND); // clear ADDSEND bit + + } else if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_TBE)) { // check if I2C_DATA is empty (Transmitted Byte Empty) + if (i2c_aux_nRABytes > 0) { // check RABytes + i2c_data_transmit(I2C1, i2c_aux_regAddress); // the master sends the Register Address byte + } else { + i2c_start_on_bus(I2C1); // send start condition + } + i2c_aux_nRABytes--; + } + + // Phase 2 - read Data + } else { + + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SBSEND)){ // check if start condition is sent out in master mode + + i2c_master_addressing(I2C1, i2c_aux_slaveAddress, I2C_RECEIVER); // sends slave address with Receive Request + + }else if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_ADDSEND)){ // check if address is sent in master mode + + if((1 == i2c_aux_nDABytes) || (2 == i2c_aux_nDABytes)){ + i2c_ack_config(I2C1, I2C_ACK_DISABLE); // clear the ACKEN before the ADDSEND is cleared + i2c_interrupt_flag_clear(I2C1,I2C_INT_FLAG_ADDSEND); // clear the ADDSEND bit + }else{ + i2c_interrupt_flag_clear(I2C1,I2C_INT_FLAG_ADDSEND); // clear the ADDSEND bit + } + + }else if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_RBNE)){ // check if I2C_DATA is not Empty (Received Byte Not Empty) + if(i2c_aux_nDABytes > 0){ + if(3 == i2c_aux_nDABytes){ + while(!i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_BTC)); // wait until the second last data byte is received into the shift register + i2c_ack_config(I2C1, I2C_ACK_DISABLE); // send a NACK for the last data byte + } + *i2c_aux_rxbuffer++ = i2c_data_receive(I2C1); // read a data byte from I2C_DATA + i2c_aux_nDABytes--; + if(0 == i2c_aux_nDABytes){ + i2c_stop_on_bus(I2C1); // send a stop condition + i2c_aux_status = 0; // 0 = Success + i2c_ack_config(I2C1, I2C_ACK_ENABLE); + i2c_ackpos_config(I2C1, I2C_ACKPOS_CURRENT); + i2c_interrupt_disable(I2C1, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + } + } + + } + + } + } +} + +/*! + \brief handle I2C1 error interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_ErrorIRQ_Handler(void) +{ + /* no acknowledge received */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_AERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_AERR); + } + + /* SMBus alert */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBALT)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBALT); + } + + /* bus timeout in SMBus mode */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBTO)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBTO); + } + + /* over-run or under-run when SCL stretch is disabled */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_OUERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_OUERR); + } + + /* arbitration lost */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_LOSTARB)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_LOSTARB); + } + + /* bus error */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_BERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_BERR); + } + + /* CRC value doesn't match */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_PECERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_PECERR); + } + /* disable the error interrupt */ + i2c_interrupt_disable(I2C0,I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); +} +#endif + diff --git a/Src/main.c b/Src/main.c new file mode 100644 index 0000000..4579f9c --- /dev/null +++ b/Src/main.c @@ -0,0 +1,213 @@ +/** + * This file is part of the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +#include +#include +#include "gd32f1x0.h" +#include "systick.h" +#include "i2c_it.h" +#include "defines.h" +#include "setup.h" +#include "config.h" +#include "util.h" +#include "mpu6050.h" +#include "mpu6050_dmp.h" + +#ifdef SERIAL_CONTROL +typedef struct{ + uint16_t start; + int16_t roll; + int16_t pitch; + int16_t yaw; + uint16_t sensors; + uint16_t checksum; +} SerialSideboard; +SerialSideboard Sideboard; +#endif + +#ifdef SERIAL_FEEDBACK +typedef struct{ + uint16_t start; + int16_t cmd1; + int16_t cmd2; + int16_t speedR; + int16_t speedL; + int16_t speedR_meas; + int16_t speedL_meas; + int16_t batVoltage; + int16_t boardTemp; + int16_t checksum; +} SerialFeedback; +SerialFeedback Feedback; +SerialFeedback NewFeedback; + +static int16_t timeoutCntSerial = 0; // Timeout counter for Rx Serial command +static uint8_t timeoutFlagSerial = 0; // Timeout Flag for Rx Serial command: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data) +#endif + +extern MPU_Data mpu; // holds the MPU-6050 data +ErrStatus mpuStatus = SUCCESS; // holds the MPU-6050 status: SUCCESS or ERROR + +uint8_t userCommand; // holds the user command input +uint8_t sensor1, sensor2; // holds the sensor1 and sensor 2 values + +static uint32_t main_loop_counter; // main loop counter to perform task squeduling inside main() + + +int main(void) +{ + systick_config(); // SysTick config + gpio_config(); // GPIO config + usart_config(USART_MAIN, USART_MAIN_BAUD); // USART config + i2c_config(); // I2C config + i2c_nvic_config(); // NVIC peripheral config + + #ifdef SERIAL_CONTROL + usart_Tx_DMA_config(USART_MAIN, (uint8_t *)&Sideboard, sizeof(Sideboard)); + #endif + #ifdef SERIAL_FEEDBACK + usart_Rx_DMA_config(USART_MAIN, (uint8_t *)&NewFeedback, sizeof(NewFeedback)); + #endif + + introDemoLED(100); // Short LEDs intro demo with 100 ms delay. This also gives some time for the MPU-6050 to initialize. + if(mpu_config()) { // IMU MPU-6050 config + mpuStatus = ERROR; + } + mpu_handle_input('h'); // Print the User Help commands to serial + + while(1){ + + delay_1ms(DELAY_IN_MAIN_LOOP); + + // ==================================== LEDs Handling ==================================== + // gpio_bit_write(LED4_GPIO_Port, LED4_Pin, (bit_status)(1-gpio_input_bit_get(LED4_GPIO_Port, LED4_Pin))); // Toggle BLUE1 LED + if (SUCCESS == mpuStatus) { + gpio_bit_set(LED2_GPIO_Port, LED2_Pin); // Turn on GREEN LED + } else { + gpio_bit_set(LED1_GPIO_Port, LED1_Pin); // Turn on RED LED + } + + // ==================================== USER Handling ==================================== + #ifdef SERIAL_DEBUG + // Get the user Input as one character from Serial + if(SET == usart_flag_get(USART_MAIN, USART_FLAG_RBNE)) { // Check if Read Buffer Not Empty meanind Serial data is available + userCommand = usart_data_receive(USART_MAIN); + if (userCommand != 10 && userCommand != 13) { // Do not accept 'new line' (ascii 10) and 'carriage return' (ascii 13) commands + log_i("Command = %c\n", userCommand); + mpu_handle_input(userCommand); + } + } + #endif + + + // ==================================== MPU-6050 Handling ==================================== + // Get MPU data. Because the MPU-6050 interrupt pin is not wired we have to check DMP data by pooling periodically + if (SUCCESS == mpuStatus) { + mpu_get_data(); + } + // Print MPU data to Console + if (main_loop_counter % 50 == 0 && SUCCESS == mpuStatus) { + mpu_print_to_console(); + } + + + // ==================================== SENSORS Handling ==================================== + // SENSOR1 + if (gpio_input_bit_get(SENSOR1_GPIO_Port, SENSOR1_Pin)) { + sensor1 = 1; + // Sensor ACTIVE: Do something here + gpio_bit_set(LED4_GPIO_Port, LED4_Pin); + consoleLog("-- SENSOR 1 Active --\n"); + delay_1ms(50); + } else { + sensor1 = 0; + gpio_bit_reset(LED4_GPIO_Port, LED4_Pin); + } + + // SENSOR2 + if (gpio_input_bit_get(SENSOR2_GPIO_Port, SENSOR2_Pin)) { + sensor2 = 1; + // Sensor ACTIVE: Do something here + gpio_bit_set(LED5_GPIO_Port, LED5_Pin); + consoleLog("-- SENSOR 2 Active --\n"); + delay_1ms(50); + } else { + sensor2 = 0; + gpio_bit_reset(LED5_GPIO_Port, LED5_Pin); + } + + + // ==================================== SERIAL Tx/Rx Handling ==================================== + #ifdef SERIAL_CONTROL + // To transmit on USART + if (main_loop_counter % 50 == 0 && SET == dma_flag_get(DMA_CH3, DMA_FLAG_FTF)) { // check if DMA channel transfer complete (Full Transfer Finish flag == 1) + + Sideboard.start = (uint16_t)SERIAL_START_FRAME; + Sideboard.roll = (int16_t)mpu.euler.roll; + Sideboard.pitch = (int16_t)mpu.euler.pitch; + Sideboard.yaw = (int16_t)mpu.euler.yaw; + Sideboard.sensors = (uint16_t)(sensor1 | (sensor2 << 1)); + Sideboard.checksum = (uint16_t)(Sideboard.start ^ Sideboard.roll ^ Sideboard.pitch ^ Sideboard.yaw ^ Sideboard.sensors); + + dma_channel_disable(DMA_CH3); + DMA_CHCNT(DMA_CH3) = sizeof(Sideboard); + DMA_CHMADDR(DMA_CH3) = (uint32_t)&Sideboard; + dma_channel_enable(DMA_CH3); + } + #endif + + #ifdef SERIAL_FEEDBACK + uint16_t checksum; + checksum = (uint16_t)(NewFeedback.start ^ NewFeedback.cmd1 ^ NewFeedback.cmd2 ^ NewFeedback.speedR ^ NewFeedback.speedL + ^ NewFeedback.speedR_meas ^ NewFeedback.speedL_meas ^ NewFeedback.batVoltage ^ NewFeedback.boardTemp); + if (NewFeedback.start == SERIAL_START_FRAME && NewFeedback.checksum == checksum) { + if (timeoutFlagSerial) { // Check for previous timeout flag + if (timeoutCntSerial-- <= 0) // Timeout de-qualification + timeoutFlagSerial = 0; // Timeout flag cleared + } else { + memcpy(&Feedback, &NewFeedback, sizeof(SerialFeedback)); // Copy the new data + NewFeedback.start = 0xFFFF; // Change the Start Frame for timeout detection in the next cycle + timeoutCntSerial = 0; // Reset the timeout counter + } + } else { + if (timeoutCntSerial++ >= SERIAL_TIMEOUT) { // Timeout qualification + timeoutFlagSerial = 1; // Timeout detected + timeoutCntSerial = SERIAL_TIMEOUT; // Limit timout counter value + } + // Check periodically the received Start Frame. If it is NOT OK, most probably we are out-of-sync. Try to re-sync by reseting the DMA + if (main_loop_counter % 50 == 0 && NewFeedback.start != SERIAL_START_FRAME && NewFeedback.start != 0xFFFF) { + dma_channel_disable(DMA_CH4); + usart_Rx_DMA_config(USART_MAIN, (uint8_t *)&NewFeedback, sizeof(NewFeedback)); + } + } + + if (timeoutFlagSerial) { // In case of timeout bring the system to a Safe State and indicate error if desired + gpio_bit_set(LED1_GPIO_Port, LED1_Pin); // Turn on Red LED + } else { + gpio_bit_reset(LED1_GPIO_Port, LED1_Pin); // Follow the Normal behavior + } + #endif + + + main_loop_counter++; + + } +} + + diff --git a/Src/mpu6050.c b/Src/mpu6050.c new file mode 100644 index 0000000..d8166e8 --- /dev/null +++ b/Src/mpu6050.c @@ -0,0 +1,3919 @@ +/** + * This file was taken from InvenSense MotionApps v6.12 library and + * refactored for the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +// Includes +#include +#include +#include +#include +#include "systick.h" +#include "defines.h" +#include "config.h" +#include "util.h" +#include "mpu6050.h" +#include "mpu6050_dmp.h" + + +/* The following functions must be defined for this platform: + * i2c_write(unsigned char slave_addr, unsigned char reg_addr, + * unsigned char length, unsigned char const *data) + * i2c_read(unsigned char slave_addr, unsigned char reg_addr, + * unsigned char length, unsigned char *data) + * delay_ms(unsigned long num_ms) + * get_ms(unsigned long *count) + * labs(long x) + * fabsf(float x) + * min(int a, int b) + */ + + +#if !defined MPU6050 && !defined MPU9150 && !defined MPU6500 && !defined MPU9250 +#error Which gyro are you using? Define MPUxxxx in config.h +#endif + + + +/* Time for some messy macro work. =] + * #define MPU9150 + * is equivalent to.. + * #define MPU6050 + * #define AK8975_SECONDARY + * + * #define MPU9250 + * is equivalent to.. + * #define MPU6500 + * #define AK8963_SECONDARY + */ +#if defined MPU9150 +#ifndef MPU6050 +#define MPU6050 +#endif /* #ifndef MPU6050 */ +#if defined AK8963_SECONDARY +#error "MPU9150 and AK8963_SECONDARY cannot both be defined." +#elif !defined AK8975_SECONDARY /* #if defined AK8963_SECONDARY */ +#define AK8975_SECONDARY +#endif /* #if defined AK8963_SECONDARY */ +#elif defined MPU9250 /* #if defined MPU9150 */ +#ifndef MPU6500 +#define MPU6500 +#endif /* #ifndef MPU6500 */ +#if defined AK8975_SECONDARY +#error "MPU9250 and AK8975_SECONDARY cannot both be defined." +#elif !defined AK8963_SECONDARY /* #if defined AK8975_SECONDARY */ +#define AK8963_SECONDARY +#endif /* #if defined AK8975_SECONDARY */ +#endif /* #if defined MPU9150 */ + +#if defined AK8975_SECONDARY || defined AK8963_SECONDARY +#define AK89xx_SECONDARY +#else +/* #warning "No compass = less profit for Invensense. Lame." */ +#endif + +static int set_int_enable(unsigned char enable); + +/* Hardware registers needed by driver. */ +struct gyro_reg_s { + unsigned char who_am_i; + unsigned char rate_div; + unsigned char lpf; + unsigned char prod_id; + unsigned char user_ctrl; + unsigned char fifo_en; + unsigned char gyro_cfg; + unsigned char accel_cfg; + unsigned char accel_cfg2; + unsigned char lp_accel_odr; + unsigned char motion_thr; + unsigned char motion_dur; + unsigned char fifo_count_h; + unsigned char fifo_r_w; + unsigned char raw_gyro; + unsigned char raw_accel; + unsigned char temp; + unsigned char int_enable; + unsigned char dmp_int_status; + unsigned char int_status; + unsigned char accel_intel; + unsigned char pwr_mgmt_1; + unsigned char pwr_mgmt_2; + unsigned char int_pin_cfg; + unsigned char mem_r_w; + unsigned char accel_offs; + unsigned char i2c_mst; + unsigned char bank_sel; + unsigned char mem_start_addr; + unsigned char prgm_start_h; +#if defined AK89xx_SECONDARY + unsigned char s0_addr; + unsigned char s0_reg; + unsigned char s0_ctrl; + unsigned char s1_addr; + unsigned char s1_reg; + unsigned char s1_ctrl; + unsigned char s4_ctrl; + unsigned char s0_do; + unsigned char s1_do; + unsigned char i2c_delay_ctrl; + unsigned char raw_compass; + /* The I2C_MST_VDDIO bit is in this register. */ + unsigned char yg_offs_tc; +#endif +}; + +/* Information specific to a particular device. */ +struct hw_s { + unsigned char addr; + unsigned short max_fifo; + unsigned char num_reg; + unsigned short temp_sens; + short temp_offset; + unsigned short bank_size; +#if defined AK89xx_SECONDARY + unsigned short compass_fsr; +#endif +}; + +/* When entering motion interrupt mode, the driver keeps track of the + * previous state so that it can be restored at a later time. + * TODO: This is tacky. Fix it. + */ +struct motion_int_cache_s { + unsigned short gyro_fsr; + unsigned char accel_fsr; + unsigned short lpf; + unsigned short sample_rate; + unsigned char sensors_on; + unsigned char fifo_sensors; + unsigned char dmp_on; +}; + +/* Cached chip configuration data. + * TODO: A lot of these can be handled with a bitmask. + */ +struct chip_cfg_s { + /* Matches gyro_cfg >> 3 & 0x03 */ + unsigned char gyro_fsr; + /* Matches accel_cfg >> 3 & 0x03 */ + unsigned char accel_fsr; + /* Enabled sensors. Uses same masks as fifo_en, NOT pwr_mgmt_2. */ + unsigned char sensors; + /* Matches config register. */ + unsigned char lpf; + unsigned char clk_src; + /* Sample rate, NOT rate divider. */ + unsigned short sample_rate; + /* Matches fifo_en register. */ + unsigned char fifo_enable; + /* Matches int enable register. */ + unsigned char int_enable; + /* 1 if devices on auxiliary I2C bus appear on the primary. */ + unsigned char bypass_mode; + /* 1 if half-sensitivity. + * NOTE: This doesn't belong here, but everything else in hw_s is const, + * and this allows us to save some precious RAM. + */ + unsigned char accel_half; + /* 1 if device in low-power accel-only mode. */ + unsigned char lp_accel_mode; + /* 1 if interrupts are only triggered on motion events. */ + unsigned char int_motion_only; + struct motion_int_cache_s cache; + /* 1 for active low interrupts. */ + unsigned char active_low_int; + /* 1 for latched interrupts. */ + unsigned char latched_int; + /* 1 if DMP is enabled. */ + unsigned char dmp_on; + /* Ensures that DMP will only be loaded once. */ + unsigned char dmp_loaded; + /* Sampling rate used when DMP is enabled. */ + unsigned short dmp_sample_rate; +#ifdef AK89xx_SECONDARY + /* Compass sample rate. */ + unsigned short compass_sample_rate; + unsigned char compass_addr; + short mag_sens_adj[3]; +#endif +}; + +/* Information for self-test. */ +struct test_s { + unsigned long gyro_sens; + unsigned long accel_sens; + unsigned char reg_rate_div; + unsigned char reg_lpf; + unsigned char reg_gyro_fsr; + unsigned char reg_accel_fsr; + unsigned short wait_ms; + unsigned char packet_thresh; + float min_dps; + float max_dps; + float max_gyro_var; + float min_g; + float max_g; + float max_accel_var; +#ifdef MPU6500 + float max_g_offset; + unsigned short sample_wait_ms; +#endif +}; + +/* Gyro driver state variables. */ +struct gyro_state_s { + const struct gyro_reg_s *reg; + const struct hw_s *hw; + struct chip_cfg_s chip_cfg; + const struct test_s *test; +}; + +/* Filter configurations. */ +enum lpf_e { + INV_FILTER_256HZ_NOLPF2 = 0, + INV_FILTER_188HZ, + INV_FILTER_98HZ, + INV_FILTER_42HZ, + INV_FILTER_20HZ, + INV_FILTER_10HZ, + INV_FILTER_5HZ, + INV_FILTER_2100HZ_NOLPF, + NUM_FILTER +}; + +/* Full scale ranges. */ +enum gyro_fsr_e { + INV_FSR_250DPS = 0, + INV_FSR_500DPS, + INV_FSR_1000DPS, + INV_FSR_2000DPS, + NUM_GYRO_FSR +}; + +/* Full scale ranges. */ +enum accel_fsr_e { + INV_FSR_2G = 0, + INV_FSR_4G, + INV_FSR_8G, + INV_FSR_16G, + NUM_ACCEL_FSR +}; + +/* Clock sources. */ +enum clock_sel_e { + INV_CLK_INTERNAL = 0, + INV_CLK_PLL, + NUM_CLK +}; + +/* Low-power accel wakeup rates. */ +enum lp_accel_rate_e { +#if defined MPU6050 + INV_LPA_1_25HZ, + INV_LPA_5HZ, + INV_LPA_20HZ, + INV_LPA_40HZ +#elif defined MPU6500 + INV_LPA_0_3125HZ, + INV_LPA_0_625HZ, + INV_LPA_1_25HZ, + INV_LPA_2_5HZ, + INV_LPA_5HZ, + INV_LPA_10HZ, + INV_LPA_20HZ, + INV_LPA_40HZ, + INV_LPA_80HZ, + INV_LPA_160HZ, + INV_LPA_320HZ, + INV_LPA_640HZ +#endif +}; + +#define BIT_I2C_MST_VDDIO (0x80) +#define BIT_FIFO_EN (0x40) +#define BIT_DMP_EN (0x80) +#define BIT_FIFO_RST (0x04) +#define BIT_DMP_RST (0x08) +#define BIT_FIFO_OVERFLOW (0x10) +#define BIT_DATA_RDY_EN (0x01) +#define BIT_DMP_INT_EN (0x02) +#define BIT_MOT_INT_EN (0x40) +#define BITS_FSR (0x18) +#define BITS_LPF (0x07) +#define BITS_HPF (0x07) +#define BITS_CLK (0x07) +#define BIT_FIFO_SIZE_1024 (0x40) +#define BIT_FIFO_SIZE_2048 (0x80) +#define BIT_FIFO_SIZE_4096 (0xC0) +#define BIT_RESET (0x80) +#define BIT_SLEEP (0x40) +#define BIT_S0_DELAY_EN (0x01) +#define BIT_S2_DELAY_EN (0x04) +#define BITS_SLAVE_LENGTH (0x0F) +#define BIT_SLAVE_BYTE_SW (0x40) +#define BIT_SLAVE_GROUP (0x10) +#define BIT_SLAVE_EN (0x80) +#define BIT_I2C_READ (0x80) +#define BITS_I2C_MASTER_DLY (0x1F) +#define BIT_AUX_IF_EN (0x20) +#define BIT_ACTL (0x80) +#define BIT_LATCH_EN (0x20) +#define BIT_ANY_RD_CLR (0x10) +#define BIT_BYPASS_EN (0x02) +#define BITS_WOM_EN (0xC0) +#define BIT_LPA_CYCLE (0x20) +#define BIT_STBY_XA (0x20) +#define BIT_STBY_YA (0x10) +#define BIT_STBY_ZA (0x08) +#define BIT_STBY_XG (0x04) +#define BIT_STBY_YG (0x02) +#define BIT_STBY_ZG (0x01) +#define BIT_STBY_XYZA (BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA) +#define BIT_STBY_XYZG (BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG) + +#if defined AK8975_SECONDARY +#define SUPPORTS_AK89xx_HIGH_SENS (0x00) +#define AK89xx_FSR (9830) +#elif defined AK8963_SECONDARY +#define SUPPORTS_AK89xx_HIGH_SENS (0x10) +#define AK89xx_FSR (4915) +#endif + +#ifdef AK89xx_SECONDARY +#define AKM_REG_WHOAMI (0x00) + +#define AKM_REG_ST1 (0x02) +#define AKM_REG_HXL (0x03) +#define AKM_REG_ST2 (0x09) + +#define AKM_REG_CNTL (0x0A) +#define AKM_REG_ASTC (0x0C) +#define AKM_REG_ASAX (0x10) +#define AKM_REG_ASAY (0x11) +#define AKM_REG_ASAZ (0x12) + +#define AKM_DATA_READY (0x01) +#define AKM_DATA_OVERRUN (0x02) +#define AKM_OVERFLOW (0x80) +#define AKM_DATA_ERROR (0x40) + +#define AKM_BIT_SELF_TEST (0x40) + +#define AKM_POWER_DOWN (0x00 | SUPPORTS_AK89xx_HIGH_SENS) +#define AKM_SINGLE_MEASUREMENT (0x01 | SUPPORTS_AK89xx_HIGH_SENS) +#define AKM_FUSE_ROM_ACCESS (0x0F | SUPPORTS_AK89xx_HIGH_SENS) +#define AKM_MODE_SELF_TEST (0x08 | SUPPORTS_AK89xx_HIGH_SENS) + +#define AKM_WHOAMI (0x48) +#endif + +#if defined MPU6050 +const struct gyro_reg_s reg = { + .who_am_i = 0x75, + .rate_div = 0x19, + .lpf = 0x1A, + .prod_id = 0x0C, + .user_ctrl = 0x6A, + .fifo_en = 0x23, + .gyro_cfg = 0x1B, + .accel_cfg = 0x1C, + .motion_thr = 0x1F, + .motion_dur = 0x20, + .fifo_count_h = 0x72, + .fifo_r_w = 0x74, + .raw_gyro = 0x43, + .raw_accel = 0x3B, + .temp = 0x41, + .int_enable = 0x38, + .dmp_int_status = 0x39, + .int_status = 0x3A, + .pwr_mgmt_1 = 0x6B, + .pwr_mgmt_2 = 0x6C, + .int_pin_cfg = 0x37, + .mem_r_w = 0x6F, + .accel_offs = 0x06, + .i2c_mst = 0x24, + .bank_sel = 0x6D, + .mem_start_addr = 0x6E, + .prgm_start_h = 0x70 +#ifdef AK89xx_SECONDARY + ,.raw_compass = 0x49, + .yg_offs_tc = 0x01, + .s0_addr = 0x25, + .s0_reg = 0x26, + .s0_ctrl = 0x27, + .s1_addr = 0x28, + .s1_reg = 0x29, + .s1_ctrl = 0x2A, + .s4_ctrl = 0x34, + .s0_do = 0x63, + .s1_do = 0x64, + .i2c_delay_ctrl = 0x67 +#endif +}; +const struct hw_s hw = { + .addr = 0x68, + .max_fifo = 1024, + .num_reg = 118, + .temp_sens = 340, + .temp_offset = -521, + .bank_size = 256 +#if defined AK89xx_SECONDARY + ,.compass_fsr = AK89xx_FSR +#endif +}; + +const struct test_s test = { + .gyro_sens = 32768/250, + .accel_sens = 32768/16, + .reg_rate_div = 0, /* 1kHz. */ + .reg_lpf = 1, /* 188Hz. */ + .reg_gyro_fsr = 0, /* 250dps. */ + .reg_accel_fsr = 0x18, /* 16g. */ + .wait_ms = 50, + .packet_thresh = 5, /* 5% */ + .min_dps = 10.f, + .max_dps = 105.f, + .max_gyro_var = 0.14f, + .min_g = 0.3f, + .max_g = 0.95f, + .max_accel_var = 0.14f +}; + +static struct gyro_state_s st = { + .reg = ®, + .hw = &hw, + .test = &test +}; +#elif defined MPU6500 +const struct gyro_reg_s reg = { + .who_am_i = 0x75, + .rate_div = 0x19, + .lpf = 0x1A, + .prod_id = 0x0C, + .user_ctrl = 0x6A, + .fifo_en = 0x23, + .gyro_cfg = 0x1B, + .accel_cfg = 0x1C, + .accel_cfg2 = 0x1D, + .lp_accel_odr = 0x1E, + .motion_thr = 0x1F, + .motion_dur = 0x20, + .fifo_count_h = 0x72, + .fifo_r_w = 0x74, + .raw_gyro = 0x43, + .raw_accel = 0x3B, + .temp = 0x41, + .int_enable = 0x38, + .dmp_int_status = 0x39, + .int_status = 0x3A, + .accel_intel = 0x69, + .pwr_mgmt_1 = 0x6B, + .pwr_mgmt_2 = 0x6C, + .int_pin_cfg = 0x37, + .mem_r_w = 0x6F, + .accel_offs = 0x77, + .i2c_mst = 0x24, + .bank_sel = 0x6D, + .mem_start_addr = 0x6E, + .prgm_start_h = 0x70 +#ifdef AK89xx_SECONDARY + ,.raw_compass = 0x49, + .s0_addr = 0x25, + .s0_reg = 0x26, + .s0_ctrl = 0x27, + .s1_addr = 0x28, + .s1_reg = 0x29, + .s1_ctrl = 0x2A, + .s4_ctrl = 0x34, + .s0_do = 0x63, + .s1_do = 0x64, + .i2c_delay_ctrl = 0x67 +#endif +}; +const struct hw_s hw = { + .addr = 0x68, + .max_fifo = 1024, + .num_reg = 128, + .temp_sens = 321, + .temp_offset = 0, + .bank_size = 256 +#if defined AK89xx_SECONDARY + ,.compass_fsr = AK89xx_FSR +#endif +}; + +const struct test_s test = { + .gyro_sens = 32768/250, + .accel_sens = 32768/2, // FSR = +-2G = 16384 LSB/G + .reg_rate_div = 0, // 1kHz. + .reg_lpf = 2, // 92Hz low pass filter + .reg_gyro_fsr = 0, // 250dps. + .reg_accel_fsr = 0x0, // Accel FSR setting = 2g. + .wait_ms = 200, // 200ms stabilization time + .packet_thresh = 200, // 200 samples + .min_dps = 20.f, // 20 dps for Gyro Criteria C + .max_dps = 60.f, // Must exceed 60 dps threshold for Gyro Criteria B + .max_gyro_var = .5f, // Must exceed +50% variation for Gyro Criteria A + .min_g = .225f, // Accel must exceed Min 225 mg for Criteria B + .max_g = .675f, // Accel cannot exceed Max 675 mg for Criteria B + .max_accel_var = .5f, // Accel must be within 50% variation for Criteria A + .max_g_offset = .5f, // 500 mg for Accel Criteria C + .sample_wait_ms = 10 // 10ms sample time wait +}; + +static struct gyro_state_s st = { + .reg = ®, + .hw = &hw, + .test = &test +}; +#endif + +#define MAX_PACKET_LENGTH (12) +#ifdef MPU6500 +#define HWST_MAX_PACKET_LENGTH (512) +#endif + +#ifdef AK89xx_SECONDARY +static int setup_compass(void); +#define MAX_COMPASS_SAMPLE_RATE (100) +#endif + +/** + * @brief Enable/disable data ready interrupt. + * If the DMP is on, the DMP interrupt is enabled. Otherwise, the data ready + * interrupt is used. + * @param[in] enable 1 to enable interrupt. + * @return 0 if successful. + */ +static int set_int_enable(unsigned char enable) +{ + unsigned char tmp; + + if (st.chip_cfg.dmp_on) { + if (enable) + tmp = BIT_DMP_INT_EN; + else + tmp = 0x00; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &tmp)) + return -1; + st.chip_cfg.int_enable = tmp; + } else { + if (!st.chip_cfg.sensors) + return -1; + if (enable && st.chip_cfg.int_enable) + return 0; + if (enable) + tmp = BIT_DATA_RDY_EN; + else + tmp = 0x00; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &tmp)) + return -1; + st.chip_cfg.int_enable = tmp; + } + return 0; +} + +/** + * @brief Register dump for testing. + * @return 0 if successful. + */ +int mpu_reg_dump(void) +{ + unsigned char ii; + unsigned char data; + + for (ii = 0; ii < st.hw->num_reg; ii++) { + if (ii == st.reg->fifo_r_w || ii == st.reg->mem_r_w) + continue; + if (i2c_read(st.hw->addr, ii, 1, &data)) + return -1; + #ifdef SERIAL_DEBUG + log_i("%#5x: %#5x\r\n", ii, data); + #endif + } + return 0; +} + +/** + * @brief Read from a single register. + * NOTE: The memory and FIFO read/write registers cannot be accessed. + * @param[in] reg Register address. + * @param[out] data Register data. + * @return 0 if successful. + */ +int mpu_read_reg(unsigned char reg, unsigned char *data) +{ + if (reg == st.reg->fifo_r_w || reg == st.reg->mem_r_w) + return -1; + if (reg >= st.hw->num_reg) + return -1; + return i2c_read(st.hw->addr, reg, 1, data); +} + +/** + * @brief Initialize hardware. + * Initial configuration:\n + * Gyro FSR: +/- 2000DPS\n + * Accel FSR +/- 2G\n + * DLPF: 42Hz\n + * FIFO rate: 50Hz\n + * Clock source: Gyro PLL\n + * FIFO: Disabled.\n + * Data ready interrupt: Disabled, active low, unlatched. + * @param[in] int_param Platform-specific parameters to interrupt API. + * @return 0 if successful. + */ +int mpu_init(void) +{ + unsigned char data[6]; + + /* Reset device. */ + data[0] = BIT_RESET; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) + return -1; + delay_ms(100); + + /* Wake up chip. */ + data[0] = 0x00; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) + return -1; + + st.chip_cfg.accel_half = 0; + +#ifdef MPU6500 + /* MPU6500 shares 4kB of memory between the DMP and the FIFO. Since the + * first 3kB are needed by the DMP, we'll use the last 1kB for the FIFO. + */ + data[0] = BIT_FIFO_SIZE_1024 | 0x8; + if (i2c_write(st.hw->addr, st.reg->accel_cfg2, 1, data)) + return -1; +#endif + + /* Set to invalid values to ensure no I2C writes are skipped. */ + st.chip_cfg.sensors = 0xFF; + st.chip_cfg.gyro_fsr = 0xFF; + st.chip_cfg.accel_fsr = 0xFF; + st.chip_cfg.lpf = 0xFF; + st.chip_cfg.sample_rate = 0xFFFF; + st.chip_cfg.fifo_enable = 0xFF; + st.chip_cfg.bypass_mode = 0xFF; +#ifdef AK89xx_SECONDARY + st.chip_cfg.compass_sample_rate = 0xFFFF; +#endif + /* mpu_set_sensors always preserves this setting. */ + st.chip_cfg.clk_src = INV_CLK_PLL; + /* Handled in next call to mpu_set_bypass. */ + st.chip_cfg.active_low_int = 1; + st.chip_cfg.latched_int = 0; + st.chip_cfg.int_motion_only = 0; + st.chip_cfg.lp_accel_mode = 0; + memset(&st.chip_cfg.cache, 0, sizeof(st.chip_cfg.cache)); + st.chip_cfg.dmp_on = 0; + st.chip_cfg.dmp_loaded = 0; + st.chip_cfg.dmp_sample_rate = 0; + + if (mpu_set_gyro_fsr(MPU_GYRO_FSR)) + return -1; + if (mpu_set_accel_fsr(MPU_ACCEL_FSR)) + return -1; + if (mpu_set_lpf(42)) + return -1; + if (mpu_set_sample_rate(50)) + return -1; + if (mpu_configure_fifo(0)) + return -1; + +#ifdef AK89xx_SECONDARY + setup_compass(); + if (mpu_set_compass_sample_rate(10)) + return -1; +#else + /* Already disabled by setup_compass. */ + if (mpu_set_bypass(0)) + return -1; +#endif + + mpu_set_sensors(0); + return 0; +} + +/** + * @brief Enter low-power accel-only mode. + * In low-power accel mode, the chip goes to sleep and only wakes up to sample + * the accelerometer at one of the following frequencies: + * \n MPU6050: 1.25Hz, 5Hz, 20Hz, 40Hz + * \n MPU6500: 1.25Hz, 2.5Hz, 5Hz, 10Hz, 20Hz, 40Hz, 80Hz, 160Hz, 320Hz, 640Hz + * \n If the requested rate is not one listed above, the device will be set to + * the next highest rate. Requesting a rate above the maximum supported + * frequency will result in an error. + * \n To select a fractional wake-up frequency, round down the value passed to + * @e rate. + * @param[in] rate Minimum sampling rate, or zero to disable LP + * accel mode. + * @return 0 if successful. + */ +int mpu_lp_accel_mode(unsigned short rate) +{ + unsigned char tmp[2]; + + if (rate > 40) + return -1; + + if (!rate) { + mpu_set_int_latched(0); + tmp[0] = 0; + tmp[1] = BIT_STBY_XYZG; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp)) + return -1; + st.chip_cfg.lp_accel_mode = 0; + return 0; + } + /* For LP accel, we automatically configure the hardware to produce latched + * interrupts. In LP accel mode, the hardware cycles into sleep mode before + * it gets a chance to deassert the interrupt pin; therefore, we shift this + * responsibility over to the MCU. + * + * Any register read will clear the interrupt. + */ + mpu_set_int_latched(1); +#if defined MPU6050 + tmp[0] = BIT_LPA_CYCLE; + if (rate == 1) { + tmp[1] = INV_LPA_1_25HZ; + mpu_set_lpf(5); + } else if (rate <= 5) { + tmp[1] = INV_LPA_5HZ; + mpu_set_lpf(5); + } else if (rate <= 20) { + tmp[1] = INV_LPA_20HZ; + mpu_set_lpf(10); + } else { + tmp[1] = INV_LPA_40HZ; + mpu_set_lpf(20); + } + tmp[1] = (tmp[1] << 6) | BIT_STBY_XYZG; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp)) + return -1; +#elif defined MPU6500 + /* Set wake frequency. */ + if (rate == 1) + tmp[0] = INV_LPA_1_25HZ; + else if (rate == 2) + tmp[0] = INV_LPA_2_5HZ; + else if (rate <= 5) + tmp[0] = INV_LPA_5HZ; + else if (rate <= 10) + tmp[0] = INV_LPA_10HZ; + else if (rate <= 20) + tmp[0] = INV_LPA_20HZ; + else if (rate <= 40) + tmp[0] = INV_LPA_40HZ; + else if (rate <= 80) + tmp[0] = INV_LPA_80HZ; + else if (rate <= 160) + tmp[0] = INV_LPA_160HZ; + else if (rate <= 320) + tmp[0] = INV_LPA_320HZ; + else + tmp[0] = INV_LPA_640HZ; + if (i2c_write(st.hw->addr, st.reg->lp_accel_odr, 1, tmp)) + return -1; + tmp[0] = BIT_LPA_CYCLE; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, tmp)) + return -1; +#endif + st.chip_cfg.sensors = INV_XYZ_ACCEL; + st.chip_cfg.clk_src = 0; + st.chip_cfg.lp_accel_mode = 1; + mpu_configure_fifo(0); + + return 0; +} + +/** + * @brief Read raw gyro data directly from the registers. + * @param[out] data Raw data in hardware units. + * @param[out] timestamp Timestamp in milliseconds. Null if not needed. + * @return 0 if successful. + */ +int mpu_get_gyro_reg(short *data, unsigned long *timestamp) +{ + unsigned char tmp[6]; + + if (!(st.chip_cfg.sensors & INV_XYZ_GYRO)) + return -1; + + if (i2c_read(st.hw->addr, st.reg->raw_gyro, 6, tmp)) + return -1; + data[0] = (tmp[0] << 8) | tmp[1]; + data[1] = (tmp[2] << 8) | tmp[3]; + data[2] = (tmp[4] << 8) | tmp[5]; + if (timestamp) + get_ms(timestamp); + return 0; +} + +/** + * @brief Read raw accel data directly from the registers. + * @param[out] data Raw data in hardware units. + * @param[out] timestamp Timestamp in milliseconds. Null if not needed. + * @return 0 if successful. + */ +int mpu_get_accel_reg(short *data, unsigned long *timestamp) +{ + unsigned char tmp[6]; + + if (!(st.chip_cfg.sensors & INV_XYZ_ACCEL)) + return -1; + + if (i2c_read(st.hw->addr, st.reg->raw_accel, 6, tmp)) + return -1; + data[0] = (tmp[0] << 8) | tmp[1]; + data[1] = (tmp[2] << 8) | tmp[3]; + data[2] = (tmp[4] << 8) | tmp[5]; + if (timestamp) + get_ms(timestamp); + return 0; +} + +/** + * @brief Read temperature data directly from the registers. + * @param[out] data Data in q16 format. + * @param[out] timestamp Timestamp in milliseconds. Null if not needed. + * @return 0 if successful. + */ +int mpu_get_temperature(long *data, unsigned long *timestamp) +{ + unsigned char tmp[2]; + short raw; + + if (!(st.chip_cfg.sensors)) + return -1; + + if (i2c_read(st.hw->addr, st.reg->temp, 2, tmp)) + return -1; + raw = (tmp[0] << 8) | tmp[1]; + if (timestamp) + get_ms(timestamp); + + data[0] = (long)((35 + ((raw - (float)st.hw->temp_offset) / st.hw->temp_sens)) * 65536L); + return 0; +} + +/** + * @brief Read biases to the accel bias 6500 registers. + * This function reads from the MPU6500 accel offset cancellations registers. + * The format are G in +-8G format. The register is initialized with OTP + * factory trim values. + * @param[in] accel_bias returned structure with the accel bias + * @return 0 if successful. + */ +int mpu_read_6500_accel_bias(long *accel_bias) { + unsigned char data[6]; + if (i2c_read(st.hw->addr, 0x77, 2, &data[0])) + return -1; + if (i2c_read(st.hw->addr, 0x7A, 2, &data[2])) + return -1; + if (i2c_read(st.hw->addr, 0x7D, 2, &data[4])) + return -1; + accel_bias[0] = ((long)data[0]<<8) | data[1]; + accel_bias[1] = ((long)data[2]<<8) | data[3]; + accel_bias[2] = ((long)data[4]<<8) | data[5]; + return 0; +} + +/** + * @brief Read biases to the accel bias 6050 registers. + * This function reads from the MPU6050 accel offset cancellations registers. + * The format are G in +-8G format. The register is initialized with OTP + * factory trim values. + * @param[in] accel_bias returned structure with the accel bias + * @return 0 if successful. + */ +int mpu_read_6050_accel_bias(long *accel_bias) { + unsigned char data[6]; + if (i2c_read(st.hw->addr, 0x06, 2, &data[0])) + return -1; + if (i2c_read(st.hw->addr, 0x08, 2, &data[2])) + return -1; + if (i2c_read(st.hw->addr, 0x0A, 2, &data[4])) + return -1; + accel_bias[0] = ((long)data[0]<<8) | data[1]; + accel_bias[1] = ((long)data[2]<<8) | data[3]; + accel_bias[2] = ((long)data[4]<<8) | data[5]; + return 0; +} + +int mpu_read_6500_gyro_bias(long *gyro_bias) { + unsigned char data[6]; + if (i2c_read(st.hw->addr, 0x13, 2, &data[0])) + return -1; + if (i2c_read(st.hw->addr, 0x15, 2, &data[2])) + return -1; + if (i2c_read(st.hw->addr, 0x17, 2, &data[4])) + return -1; + gyro_bias[0] = ((long)data[0]<<8) | data[1]; + gyro_bias[1] = ((long)data[2]<<8) | data[3]; + gyro_bias[2] = ((long)data[4]<<8) | data[5]; + return 0; +} + +/** + * @brief Push biases to the gyro bias 6500/6050 registers. + * This function expects biases relative to the current sensor output, and + * these biases will be added to the factory-supplied values. Bias inputs are LSB + * in +-1000dps format. + * @param[in] gyro_bias New biases. + * @return 0 if successful. + */ +int mpu_set_gyro_bias_reg(long *gyro_bias) +{ + unsigned char data[6] = {0, 0, 0, 0, 0, 0}; + int i=0; + for(i=0;i<3;i++) { + gyro_bias[i]= (-gyro_bias[i]); + } + data[0] = (gyro_bias[0] >> 8) & 0xff; + data[1] = (gyro_bias[0]) & 0xff; + data[2] = (gyro_bias[1] >> 8) & 0xff; + data[3] = (gyro_bias[1]) & 0xff; + data[4] = (gyro_bias[2] >> 8) & 0xff; + data[5] = (gyro_bias[2]) & 0xff; + if (i2c_write(st.hw->addr, 0x13, 2, &data[0])) + return -1; + if (i2c_write(st.hw->addr, 0x15, 2, &data[2])) + return -1; + if (i2c_write(st.hw->addr, 0x17, 2, &data[4])) + return -1; + return 0; +} + +/** + * @brief Push biases to the accel bias 6050 registers. + * This function expects biases relative to the current sensor output, and + * these biases will be added to the factory-supplied values. Bias inputs are LSB + * in +-16G format. + * @param[in] accel_bias New biases. + * @return 0 if successful. + */ +int mpu_set_accel_bias_6050_reg(const long *accel_bias) { + unsigned char data[6] = {0, 0, 0, 0, 0, 0}; + long accel_reg_bias[3] = {0, 0, 0}; + + if(mpu_read_6050_accel_bias(accel_reg_bias)) + return -1; + + accel_reg_bias[0] -= (accel_bias[0] & ~1); + accel_reg_bias[1] -= (accel_bias[1] & ~1); + accel_reg_bias[2] -= (accel_bias[2] & ~1); + + data[0] = (accel_reg_bias[0] >> 8) & 0xff; + data[1] = (accel_reg_bias[0]) & 0xff; + data[2] = (accel_reg_bias[1] >> 8) & 0xff; + data[3] = (accel_reg_bias[1]) & 0xff; + data[4] = (accel_reg_bias[2] >> 8) & 0xff; + data[5] = (accel_reg_bias[2]) & 0xff; + + if (i2c_write(st.hw->addr, 0x06, 2, &data[0])) + return -1; + if (i2c_write(st.hw->addr, 0x08, 2, &data[2])) + return -1; + if (i2c_write(st.hw->addr, 0x0A, 2, &data[4])) + return -1; + + return 0; +} + + + +/** + * @brief Push biases to the accel bias 6500 registers. + * This function expects biases relative to the current sensor output, and + * these biases will be added to the factory-supplied values. Bias inputs are LSB + * in +-16G format. + * @param[in] accel_bias New biases. + * @return 0 if successful. + */ +int mpu_set_accel_bias_6500_reg(const long *accel_bias) { + unsigned char data[6] = {0, 0, 0, 0, 0, 0}; + long accel_reg_bias[3] = {0, 0, 0}; + + if(mpu_read_6500_accel_bias(accel_reg_bias)) + return -1; + + // Preserve bit 0 of factory value (for temperature compensation) + accel_reg_bias[0] -= (accel_bias[0] & ~1); + accel_reg_bias[1] -= (accel_bias[1] & ~1); + accel_reg_bias[2] -= (accel_bias[2] & ~1); + + data[0] = (accel_reg_bias[0] >> 8) & 0xff; + data[1] = (accel_reg_bias[0]) & 0xff; + data[2] = (accel_reg_bias[1] >> 8) & 0xff; + data[3] = (accel_reg_bias[1]) & 0xff; + data[4] = (accel_reg_bias[2] >> 8) & 0xff; + data[5] = (accel_reg_bias[2]) & 0xff; + + if (i2c_write(st.hw->addr, 0x77, 2, &data[0])) + return -1; + if (i2c_write(st.hw->addr, 0x7A, 2, &data[2])) + return -1; + if (i2c_write(st.hw->addr, 0x7D, 2, &data[4])) + return -1; + + return 0; +} + + +/** + * @brief Reset FIFO read/write pointers. + * @return 0 if successful. + */ +int mpu_reset_fifo(void) +{ + unsigned char data; + + if (!(st.chip_cfg.sensors)) + return -1; + + data = 0; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) + return -1; + + if (st.chip_cfg.dmp_on) { + data = BIT_FIFO_RST | BIT_DMP_RST; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) + return -1; + delay_ms(50); + data = BIT_DMP_EN | BIT_FIFO_EN; + if (st.chip_cfg.sensors & INV_XYZ_COMPASS) + data |= BIT_AUX_IF_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) + return -1; + if (st.chip_cfg.int_enable) + data = BIT_DMP_INT_EN; + else + data = 0; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) + return -1; + data = 0; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &data)) + return -1; + } else { + data = BIT_FIFO_RST; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) + return -1; + if (st.chip_cfg.bypass_mode || !(st.chip_cfg.sensors & INV_XYZ_COMPASS)) + data = BIT_FIFO_EN; + else + data = BIT_FIFO_EN | BIT_AUX_IF_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) + return -1; + delay_ms(50); + if (st.chip_cfg.int_enable) + data = BIT_DATA_RDY_EN; + else + data = 0; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &st.chip_cfg.fifo_enable)) + return -1; + } + return 0; +} + +/** + * @brief Get the gyro full-scale range. + * @param[out] fsr Current full-scale range. + * @return 0 if successful. + */ +int mpu_get_gyro_fsr(unsigned short *fsr) +{ + switch (st.chip_cfg.gyro_fsr) { + case INV_FSR_250DPS: + fsr[0] = 250; + break; + case INV_FSR_500DPS: + fsr[0] = 500; + break; + case INV_FSR_1000DPS: + fsr[0] = 1000; + break; + case INV_FSR_2000DPS: + fsr[0] = 2000; + break; + default: + fsr[0] = 0; + break; + } + return 0; +} + +/** + * @brief Set the gyro full-scale range. + * @param[in] fsr Desired full-scale range. + * @return 0 if successful. + */ +int mpu_set_gyro_fsr(unsigned short fsr) +{ + unsigned char data; + + if (!(st.chip_cfg.sensors)) + return -1; + + switch (fsr) { + case 250: + data = INV_FSR_250DPS << 3; + break; + case 500: + data = INV_FSR_500DPS << 3; + break; + case 1000: + data = INV_FSR_1000DPS << 3; + break; + case 2000: + data = INV_FSR_2000DPS << 3; + break; + default: + return -1; + } + + if (st.chip_cfg.gyro_fsr == (data >> 3)) + return 0; + if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, &data)) + return -1; + st.chip_cfg.gyro_fsr = data >> 3; + return 0; +} + +/** + * @brief Get the accel full-scale range. + * @param[out] fsr Current full-scale range. + * @return 0 if successful. + */ +int mpu_get_accel_fsr(unsigned char *fsr) +{ + switch (st.chip_cfg.accel_fsr) { + case INV_FSR_2G: + fsr[0] = 2; + break; + case INV_FSR_4G: + fsr[0] = 4; + break; + case INV_FSR_8G: + fsr[0] = 8; + break; + case INV_FSR_16G: + fsr[0] = 16; + break; + default: + return -1; + } + if (st.chip_cfg.accel_half) + fsr[0] <<= 1; + return 0; +} + +/** + * @brief Set the accel full-scale range. + * @param[in] fsr Desired full-scale range. + * @return 0 if successful. + */ +int mpu_set_accel_fsr(unsigned char fsr) +{ + unsigned char data; + + if (!(st.chip_cfg.sensors)) + return -1; + + switch (fsr) { + case 2: + data = INV_FSR_2G << 3; + break; + case 4: + data = INV_FSR_4G << 3; + break; + case 8: + data = INV_FSR_8G << 3; + break; + case 16: + data = INV_FSR_16G << 3; + break; + default: + return -1; + } + + if (st.chip_cfg.accel_fsr == (data >> 3)) + return 0; + if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, &data)) + return -1; + st.chip_cfg.accel_fsr = data >> 3; + return 0; +} + +/** + * @brief Get the current DLPF setting. + * @param[out] lpf Current LPF setting. + * 0 if successful. + */ +int mpu_get_lpf(unsigned short *lpf) +{ + switch (st.chip_cfg.lpf) { + case INV_FILTER_188HZ: + lpf[0] = 188; + break; + case INV_FILTER_98HZ: + lpf[0] = 98; + break; + case INV_FILTER_42HZ: + lpf[0] = 42; + break; + case INV_FILTER_20HZ: + lpf[0] = 20; + break; + case INV_FILTER_10HZ: + lpf[0] = 10; + break; + case INV_FILTER_5HZ: + lpf[0] = 5; + break; + case INV_FILTER_256HZ_NOLPF2: + case INV_FILTER_2100HZ_NOLPF: + default: + lpf[0] = 0; + break; + } + return 0; +} + +/** + * @brief Set digital low pass filter. + * The following LPF settings are supported: 188, 98, 42, 20, 10, 5. + * @param[in] lpf Desired LPF setting. + * @return 0 if successful. + */ +int mpu_set_lpf(unsigned short lpf) +{ + unsigned char data; + + if (!(st.chip_cfg.sensors)) + return -1; + + if (lpf >= 188) + data = INV_FILTER_188HZ; + else if (lpf >= 98) + data = INV_FILTER_98HZ; + else if (lpf >= 42) + data = INV_FILTER_42HZ; + else if (lpf >= 20) + data = INV_FILTER_20HZ; + else if (lpf >= 10) + data = INV_FILTER_10HZ; + else + data = INV_FILTER_5HZ; + + if (st.chip_cfg.lpf == data) + return 0; + if (i2c_write(st.hw->addr, st.reg->lpf, 1, &data)) + return -1; + st.chip_cfg.lpf = data; + return 0; +} + +/** + * @brief Get sampling rate. + * @param[out] rate Current sampling rate (Hz). + * @return 0 if successful. + */ +int mpu_get_sample_rate(unsigned short *rate) +{ + if (st.chip_cfg.dmp_on) + return -1; + else + rate[0] = st.chip_cfg.sample_rate; + return 0; +} + +/** + * @brief Set sampling rate. + * Sampling rate must be between 4Hz and 1kHz. + * @param[in] rate Desired sampling rate (Hz). + * @return 0 if successful. + */ +int mpu_set_sample_rate(unsigned short rate) +{ + unsigned char data; + + if (!(st.chip_cfg.sensors)) + return -1; + + if (st.chip_cfg.dmp_on) + return -1; + else { + if (st.chip_cfg.lp_accel_mode) { + if (rate && (rate <= 40)) { + /* Just stay in low-power accel mode. */ + mpu_lp_accel_mode(rate); + return 0; + } + /* Requested rate exceeds the allowed frequencies in LP accel mode, + * switch back to full-power mode. + */ + mpu_lp_accel_mode(0); + } + if (rate < 4) + rate = 4; + else if (rate > 1000) + rate = 1000; + + data = 1000 / rate - 1; + if (i2c_write(st.hw->addr, st.reg->rate_div, 1, &data)) + return -1; + + st.chip_cfg.sample_rate = 1000 / (1 + data); + +#ifdef AK89xx_SECONDARY + mpu_set_compass_sample_rate(min(st.chip_cfg.compass_sample_rate, MAX_COMPASS_SAMPLE_RATE)); +#endif + + /* Automatically set LPF to 1/2 sampling rate. */ + mpu_set_lpf(st.chip_cfg.sample_rate >> 1); + return 0; + } +} + +/** + * @brief Get compass sampling rate. + * @param[out] rate Current compass sampling rate (Hz). + * @return 0 if successful. + */ +int mpu_get_compass_sample_rate(unsigned short *rate) +{ +#ifdef AK89xx_SECONDARY + rate[0] = st.chip_cfg.compass_sample_rate; + return 0; +#else + rate[0] = 0; + return -1; +#endif +} + +/** + * @brief Set compass sampling rate. + * The compass on the auxiliary I2C bus is read by the MPU hardware at a + * maximum of 100Hz. The actual rate can be set to a fraction of the gyro + * sampling rate. + * + * \n WARNING: The new rate may be different than what was requested. Call + * mpu_get_compass_sample_rate to check the actual setting. + * @param[in] rate Desired compass sampling rate (Hz). + * @return 0 if successful. + */ +int mpu_set_compass_sample_rate(unsigned short rate) +{ +#ifdef AK89xx_SECONDARY + unsigned char div; + if (!rate || rate > st.chip_cfg.sample_rate || rate > MAX_COMPASS_SAMPLE_RATE) + return -1; + + div = st.chip_cfg.sample_rate / rate - 1; + if (i2c_write(st.hw->addr, st.reg->s4_ctrl, 1, &div)) + return -1; + st.chip_cfg.compass_sample_rate = st.chip_cfg.sample_rate / (div + 1); + return 0; +#else + return -1; +#endif +} + +/** + * @brief Get gyro sensitivity scale factor. + * @param[out] sens Conversion from hardware units to dps. + * @return 0 if successful. + */ +int mpu_get_gyro_sens(float *sens) +{ + switch (st.chip_cfg.gyro_fsr) { + case INV_FSR_250DPS: + sens[0] = 131.f; + break; + case INV_FSR_500DPS: + sens[0] = 65.5f; + break; + case INV_FSR_1000DPS: + sens[0] = 32.8f; + break; + case INV_FSR_2000DPS: + sens[0] = 16.4f; + break; + default: + return -1; + } + return 0; +} + +/** + * @brief Get accel sensitivity scale factor. + * @param[out] sens Conversion from hardware units to g's. + * @return 0 if successful. + */ +int mpu_get_accel_sens(unsigned short *sens) +{ + switch (st.chip_cfg.accel_fsr) { + case INV_FSR_2G: + sens[0] = 16384; + break; + case INV_FSR_4G: + sens[0] = 8192; + break; + case INV_FSR_8G: + sens[0] = 4096; + break; + case INV_FSR_16G: + sens[0] = 2048; + break; + default: + return -1; + } + if (st.chip_cfg.accel_half) + sens[0] >>= 1; + return 0; +} + +/** + * @brief Get current FIFO configuration. + * @e sensors can contain a combination of the following flags: + * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO + * \n INV_XYZ_GYRO + * \n INV_XYZ_ACCEL + * @param[out] sensors Mask of sensors in FIFO. + * @return 0 if successful. + */ +int mpu_get_fifo_config(unsigned char *sensors) +{ + sensors[0] = st.chip_cfg.fifo_enable; + return 0; +} + +/** + * @brief Select which sensors are pushed to FIFO. + * @e sensors can contain a combination of the following flags: + * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO + * \n INV_XYZ_GYRO + * \n INV_XYZ_ACCEL + * @param[in] sensors Mask of sensors to push to FIFO. + * @return 0 if successful. + */ +int mpu_configure_fifo(unsigned char sensors) +{ + unsigned char prev; + int result = 0; + + /* Compass data isn't going into the FIFO. Stop trying. */ + sensors &= ~INV_XYZ_COMPASS; + + if (st.chip_cfg.dmp_on) + return 0; + else { + if (!(st.chip_cfg.sensors)) + return -1; + prev = st.chip_cfg.fifo_enable; + st.chip_cfg.fifo_enable = sensors & st.chip_cfg.sensors; + if (st.chip_cfg.fifo_enable != sensors) + /* You're not getting what you asked for. Some sensors are + * asleep. + */ + result = -1; + else + result = 0; + if (sensors || st.chip_cfg.lp_accel_mode) + set_int_enable(1); + else + set_int_enable(0); + if (sensors) { + if (mpu_reset_fifo()) { + st.chip_cfg.fifo_enable = prev; + return -1; + } + } + } + + return result; +} + +/** + * @brief Get current power state. + * @param[in] power_on 1 if turned on, 0 if suspended. + * @return 0 if successful. + */ +int mpu_get_power_state(unsigned char *power_on) +{ + if (st.chip_cfg.sensors) + power_on[0] = 1; + else + power_on[0] = 0; + return 0; +} + +/** + * @brief Turn specific sensors on/off. + * @e sensors can contain a combination of the following flags: + * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO + * \n INV_XYZ_GYRO + * \n INV_XYZ_ACCEL + * \n INV_XYZ_COMPASS + * @param[in] sensors Mask of sensors to wake. + * @return 0 if successful. + */ +int mpu_set_sensors(unsigned char sensors) +{ + unsigned char data; +#ifdef AK89xx_SECONDARY + unsigned char user_ctrl; +#endif + + if (sensors & INV_XYZ_GYRO) + data = INV_CLK_PLL; + else if (sensors) + data = 0; + else + data = BIT_SLEEP; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, &data)) { + st.chip_cfg.sensors = 0; + return -1; + } + st.chip_cfg.clk_src = data & ~BIT_SLEEP; + + data = 0; + if (!(sensors & INV_X_GYRO)) + data |= BIT_STBY_XG; + if (!(sensors & INV_Y_GYRO)) + data |= BIT_STBY_YG; + if (!(sensors & INV_Z_GYRO)) + data |= BIT_STBY_ZG; + if (!(sensors & INV_XYZ_ACCEL)) + data |= BIT_STBY_XYZA; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_2, 1, &data)) { + st.chip_cfg.sensors = 0; + return -1; + } + + if (sensors && (sensors != INV_XYZ_ACCEL)) + /* Latched interrupts only used in LP accel mode. */ + mpu_set_int_latched(0); + +#ifdef AK89xx_SECONDARY +#ifdef AK89xx_BYPASS + if (sensors & INV_XYZ_COMPASS) + mpu_set_bypass(1); + else + mpu_set_bypass(0); +#else + if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl)) + return -1; + /* Handle AKM power management. */ + if (sensors & INV_XYZ_COMPASS) { + data = AKM_SINGLE_MEASUREMENT; + user_ctrl |= BIT_AUX_IF_EN; + } else { + data = AKM_POWER_DOWN; + user_ctrl &= ~BIT_AUX_IF_EN; + } + if (st.chip_cfg.dmp_on) + user_ctrl |= BIT_DMP_EN; + else + user_ctrl &= ~BIT_DMP_EN; + if (i2c_write(st.hw->addr, st.reg->s1_do, 1, &data)) + return -1; + /* Enable/disable I2C master mode. */ + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl)) + return -1; +#endif +#endif + + st.chip_cfg.sensors = sensors; + st.chip_cfg.lp_accel_mode = 0; + delay_ms(50); + return 0; +} + +/** + * @brief Read the MPU interrupt status registers. + * @param[out] status Mask of interrupt bits. + * @return 0 if successful. + */ +int mpu_get_int_status(short *status) +{ + unsigned char tmp[2]; + if (!st.chip_cfg.sensors) + return -1; + if (i2c_read(st.hw->addr, st.reg->dmp_int_status, 2, tmp)) + return -1; + status[0] = (tmp[0] << 8) | tmp[1]; + return 0; +} + +/** + * @brief Get one packet from the FIFO. + * If @e sensors does not contain a particular sensor, disregard the data + * returned to that pointer. + * \n @e sensors can contain a combination of the following flags: + * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO + * \n INV_XYZ_GYRO + * \n INV_XYZ_ACCEL + * \n If the FIFO has no new data, @e sensors will be zero. + * \n If the FIFO is disabled, @e sensors will be zero and this function will + * return a non-zero error code. + * @param[out] gyro Gyro data in hardware units. + * @param[out] accel Accel data in hardware units. + * @param[out] timestamp Timestamp in milliseconds. + * @param[out] sensors Mask of sensors read from FIFO. + * @param[out] more Number of remaining packets. + * @return 0 if successful. + */ +int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, + unsigned char *sensors, unsigned char *more) +{ + /* Assumes maximum packet size is gyro (6) + accel (6). */ + unsigned char data[MAX_PACKET_LENGTH]; + unsigned char packet_size = 0; + unsigned short fifo_count, index = 0; + + if (st.chip_cfg.dmp_on) + return -1; + + sensors[0] = 0; + if (!st.chip_cfg.sensors) + return -1; + if (!st.chip_cfg.fifo_enable) + return -1; + + if (st.chip_cfg.fifo_enable & INV_X_GYRO) + packet_size += 2; + if (st.chip_cfg.fifo_enable & INV_Y_GYRO) + packet_size += 2; + if (st.chip_cfg.fifo_enable & INV_Z_GYRO) + packet_size += 2; + if (st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) + packet_size += 6; + + if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) + return -1; + fifo_count = (data[0] << 8) | data[1]; + if (fifo_count < packet_size) + return 0; + // #ifdef SERIAL_DEBUG + // log_i("FIFO count: %hd\n", fifo_count); + // #endif + if (fifo_count > (st.hw->max_fifo >> 1)) { + /* FIFO is 50% full, better check overflow bit. */ + if (i2c_read(st.hw->addr, st.reg->int_status, 1, data)) + return -1; + if (data[0] & BIT_FIFO_OVERFLOW) { + mpu_reset_fifo(); + return -2; + } + } + get_ms((unsigned long*)timestamp); + + if (i2c_read(st.hw->addr, st.reg->fifo_r_w, packet_size, data)) + return -1; + more[0] = fifo_count / packet_size - 1; + sensors[0] = 0; + + if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) { + accel[0] = (data[index+0] << 8) | data[index+1]; + accel[1] = (data[index+2] << 8) | data[index+3]; + accel[2] = (data[index+4] << 8) | data[index+5]; + sensors[0] |= INV_XYZ_ACCEL; + index += 6; + } + if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_X_GYRO) { + gyro[0] = (data[index+0] << 8) | data[index+1]; + sensors[0] |= INV_X_GYRO; + index += 2; + } + if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Y_GYRO) { + gyro[1] = (data[index+0] << 8) | data[index+1]; + sensors[0] |= INV_Y_GYRO; + index += 2; + } + if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Z_GYRO) { + gyro[2] = (data[index+0] << 8) | data[index+1]; + sensors[0] |= INV_Z_GYRO; + index += 2; + } + + return 0; +} + +/** + * @brief Get one unparsed packet from the FIFO. + * This function should be used if the packet is to be parsed elsewhere. + * @param[in] length Length of one FIFO packet. + * @param[in] data FIFO packet. + * @param[in] more Number of remaining packets. + */ +int mpu_read_fifo_stream(unsigned short length, unsigned char *data, + unsigned char *more) +{ + unsigned char tmp[2]; + unsigned short fifo_count; + if (!st.chip_cfg.dmp_on) + return -1; + if (!st.chip_cfg.sensors) + return -1; + + if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, tmp)) + return -1; + fifo_count = (tmp[0] << 8) | tmp[1]; + if (fifo_count < length) { + more[0] = 0; + return -1; + } + if (fifo_count > (st.hw->max_fifo >> 1)) { + /* FIFO is 50% full, better check overflow bit. */ + if (i2c_read(st.hw->addr, st.reg->int_status, 1, tmp)) + return -1; + if (tmp[0] & BIT_FIFO_OVERFLOW) { + mpu_reset_fifo(); + return -2; + } + } + + if (i2c_read(st.hw->addr, st.reg->fifo_r_w, length, data)) + return -1; + more[0] = fifo_count / length - 1; + return 0; +} + +/** + * @brief Set device to bypass mode. + * @param[in] bypass_on 1 to enable bypass mode. + * @return 0 if successful. + */ +int mpu_set_bypass(unsigned char bypass_on) +{ + unsigned char tmp; + + if (st.chip_cfg.bypass_mode == bypass_on) + return 0; + + if (bypass_on) { + if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) + return -1; + tmp &= ~BIT_AUX_IF_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) + return -1; + delay_ms(3); + tmp = BIT_BYPASS_EN; + if (st.chip_cfg.active_low_int) + tmp |= BIT_ACTL; + if (st.chip_cfg.latched_int) + tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR; + if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) + return -1; + } else { + /* Enable I2C master mode if compass is being used. */ + if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) + return -1; + if (st.chip_cfg.sensors & INV_XYZ_COMPASS) + tmp |= BIT_AUX_IF_EN; + else + tmp &= ~BIT_AUX_IF_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) + return -1; + delay_ms(3); + if (st.chip_cfg.active_low_int) + tmp = BIT_ACTL; + else + tmp = 0; + if (st.chip_cfg.latched_int) + tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR; + if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) + return -1; + } + st.chip_cfg.bypass_mode = bypass_on; + return 0; +} + +/** + * @brief Set interrupt level. + * @param[in] active_low 1 for active low, 0 for active high. + * @return 0 if successful. + */ +int mpu_set_int_level(unsigned char active_low) +{ + st.chip_cfg.active_low_int = active_low; + return 0; +} + +/** + * @brief Enable latched interrupts. + * Any MPU register will clear the interrupt. + * @param[in] enable 1 to enable, 0 to disable. + * @return 0 if successful. + */ +int mpu_set_int_latched(unsigned char enable) +{ + unsigned char tmp; + if (st.chip_cfg.latched_int == enable) + return 0; + + if (enable) + tmp = BIT_LATCH_EN | BIT_ANY_RD_CLR; + else + tmp = 0; + if (st.chip_cfg.bypass_mode) + tmp |= BIT_BYPASS_EN; + if (st.chip_cfg.active_low_int) + tmp |= BIT_ACTL; + if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) + return -1; + st.chip_cfg.latched_int = enable; + return 0; +} + +#ifdef MPU6050 +static int get_accel_prod_shift(float *st_shift) +{ + unsigned char tmp[4], shift_code[3], ii; + + if (i2c_read(st.hw->addr, 0x0D, 4, tmp)) + return 0x07; + + shift_code[0] = ((tmp[0] & 0xE0) >> 3) | ((tmp[3] & 0x30) >> 4); + shift_code[1] = ((tmp[1] & 0xE0) >> 3) | ((tmp[3] & 0x0C) >> 2); + shift_code[2] = ((tmp[2] & 0xE0) >> 3) | (tmp[3] & 0x03); + for (ii = 0; ii < 3; ii++) { + if (!shift_code[ii]) { + st_shift[ii] = 0.f; + continue; + } + /* Equivalent to.. + * st_shift[ii] = 0.34f * powf(0.92f/0.34f, (shift_code[ii]-1) / 30.f) + */ + st_shift[ii] = 0.34f; + while (--shift_code[ii]) + st_shift[ii] *= 1.034f; + } + return 0; +} + +static int accel_self_test(long *bias_regular, long *bias_st) +{ + int jj, result = 0; + float st_shift[3], st_shift_cust, st_shift_var; + + get_accel_prod_shift(st_shift); + for(jj = 0; jj < 3; jj++) { + st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f; + if (st_shift[jj]) { + st_shift_var = st_shift_cust / st_shift[jj] - 1.f; + if (fabs(st_shift_var) > test.max_accel_var) + result |= 1 << jj; + } else if ((st_shift_cust < test.min_g) || + (st_shift_cust > test.max_g)) + result |= 1 << jj; + } + + return result; +} + +static int gyro_self_test(long *bias_regular, long *bias_st) +{ + int jj, result = 0; + unsigned char tmp[3]; + float st_shift, st_shift_cust, st_shift_var; + + if (i2c_read(st.hw->addr, 0x0D, 3, tmp)) + return 0x07; + + tmp[0] &= 0x1F; + tmp[1] &= 0x1F; + tmp[2] &= 0x1F; + + for (jj = 0; jj < 3; jj++) { + st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f; + if (tmp[jj]) { + st_shift = 3275.f / test.gyro_sens; + while (--tmp[jj]) + st_shift *= 1.046f; + st_shift_var = st_shift_cust / st_shift - 1.f; + if (fabs(st_shift_var) > test.max_gyro_var) + result |= 1 << jj; + } else if ((st_shift_cust < test.min_dps) || + (st_shift_cust > test.max_dps)) + result |= 1 << jj; + } + return result; +} + +#endif +#ifdef AK89xx_SECONDARY +static int compass_self_test(void) +{ + unsigned char tmp[6]; + unsigned char tries = 10; + int result = 0x07; + short data; + + mpu_set_bypass(1); + + tmp[0] = AKM_POWER_DOWN; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp)) + return 0x07; + tmp[0] = AKM_BIT_SELF_TEST; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp)) + goto AKM_restore; + tmp[0] = AKM_MODE_SELF_TEST; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp)) + goto AKM_restore; + + do { + delay_ms(10); + if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 1, tmp)) + goto AKM_restore; + if (tmp[0] & AKM_DATA_READY) + break; + } while (tries--); + if (!(tmp[0] & AKM_DATA_READY)) + goto AKM_restore; + + if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_HXL, 6, tmp)) + goto AKM_restore; + + result = 0; +#if defined MPU9150 + data = (short)(tmp[1] << 8) | tmp[0]; + if ((data > 100) || (data < -100)) + result |= 0x01; + data = (short)(tmp[3] << 8) | tmp[2]; + if ((data > 100) || (data < -100)) + result |= 0x02; + data = (short)(tmp[5] << 8) | tmp[4]; + if ((data > -300) || (data < -1000)) + result |= 0x04; +#elif defined MPU9250 + data = (short)(tmp[1] << 8) | tmp[0]; + if ((data > 200) || (data < -200)) + result |= 0x01; + data = (short)(tmp[3] << 8) | tmp[2]; + if ((data > 200) || (data < -200)) + result |= 0x02; + data = (short)(tmp[5] << 8) | tmp[4]; + if ((data > -800) || (data < -3200)) + result |= 0x04; +#endif +AKM_restore: + tmp[0] = 0 | SUPPORTS_AK89xx_HIGH_SENS; + i2c_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp); + tmp[0] = SUPPORTS_AK89xx_HIGH_SENS; + i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp); + mpu_set_bypass(0); + return result; +} +#endif + +static int get_st_biases(long *gyro, long *accel, unsigned char hw_test) +{ + unsigned char data[MAX_PACKET_LENGTH]; + unsigned char packet_count, ii; + unsigned short fifo_count; + + data[0] = 0x01; + data[1] = 0; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data)) + return -1; + delay_ms(200); + data[0] = 0; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + data[0] = BIT_FIFO_RST | BIT_DMP_RST; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + delay_ms(15); + data[0] = st.test->reg_lpf; + if (i2c_write(st.hw->addr, st.reg->lpf, 1, data)) + return -1; + data[0] = st.test->reg_rate_div; + if (i2c_write(st.hw->addr, st.reg->rate_div, 1, data)) + return -1; + if (hw_test) + data[0] = st.test->reg_gyro_fsr | 0xE0; + else + data[0] = st.test->reg_gyro_fsr; + if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, data)) + return -1; + + if (hw_test) + data[0] = st.test->reg_accel_fsr | 0xE0; + else + data[0] = test.reg_accel_fsr; + if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, data)) + return -1; + if (hw_test) + delay_ms(200); + + /* Fill FIFO for test.wait_ms milliseconds. */ + data[0] = BIT_FIFO_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + + data[0] = INV_XYZ_GYRO | INV_XYZ_ACCEL; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + delay_ms(test.wait_ms); + data[0] = 0; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + + if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) + return -1; + + fifo_count = (data[0] << 8) | data[1]; + packet_count = fifo_count / MAX_PACKET_LENGTH; + gyro[0] = gyro[1] = gyro[2] = 0; + accel[0] = accel[1] = accel[2] = 0; + + for (ii = 0; ii < packet_count; ii++) { + short accel_cur[3], gyro_cur[3]; + if (i2c_read(st.hw->addr, st.reg->fifo_r_w, MAX_PACKET_LENGTH, data)) + return -1; + accel_cur[0] = ((short)data[0] << 8) | data[1]; + accel_cur[1] = ((short)data[2] << 8) | data[3]; + accel_cur[2] = ((short)data[4] << 8) | data[5]; + accel[0] += (long)accel_cur[0]; + accel[1] += (long)accel_cur[1]; + accel[2] += (long)accel_cur[2]; + gyro_cur[0] = (((short)data[6] << 8) | data[7]); + gyro_cur[1] = (((short)data[8] << 8) | data[9]); + gyro_cur[2] = (((short)data[10] << 8) | data[11]); + gyro[0] += (long)gyro_cur[0]; + gyro[1] += (long)gyro_cur[1]; + gyro[2] += (long)gyro_cur[2]; + } +#ifdef EMPL_NO_64BIT + gyro[0] = (long)(((float)gyro[0]*65536.f) / test.gyro_sens / packet_count); + gyro[1] = (long)(((float)gyro[1]*65536.f) / test.gyro_sens / packet_count); + gyro[2] = (long)(((float)gyro[2]*65536.f) / test.gyro_sens / packet_count); + if (has_accel) { + accel[0] = (long)(((float)accel[0]*65536.f) / test.accel_sens / + packet_count); + accel[1] = (long)(((float)accel[1]*65536.f) / test.accel_sens / + packet_count); + accel[2] = (long)(((float)accel[2]*65536.f) / test.accel_sens / + packet_count); + /* Don't remove gravity! */ + accel[2] -= 65536L; + } +#else + gyro[0] = (long)(((long long)gyro[0]<<16) / test.gyro_sens / packet_count); + gyro[1] = (long)(((long long)gyro[1]<<16) / test.gyro_sens / packet_count); + gyro[2] = (long)(((long long)gyro[2]<<16) / test.gyro_sens / packet_count); + accel[0] = (long)(((long long)accel[0]<<16) / test.accel_sens / + packet_count); + accel[1] = (long)(((long long)accel[1]<<16) / test.accel_sens / + packet_count); + accel[2] = (long)(((long long)accel[2]<<16) / test.accel_sens / + packet_count); + /* Don't remove gravity! */ + if (accel[2] > 0L) + accel[2] -= 65536L; + else + accel[2] += 65536L; +#endif + + return 0; +} + +#ifdef MPU6500 +#define REG_6500_XG_ST_DATA 0x0 +#define REG_6500_XA_ST_DATA 0xD +static const unsigned short mpu_6500_st_tb[256] = { + 2620,2646,2672,2699,2726,2753,2781,2808, //7 + 2837,2865,2894,2923,2952,2981,3011,3041, //15 + 3072,3102,3133,3165,3196,3228,3261,3293, //23 + 3326,3359,3393,3427,3461,3496,3531,3566, //31 + 3602,3638,3674,3711,3748,3786,3823,3862, //39 + 3900,3939,3979,4019,4059,4099,4140,4182, //47 + 4224,4266,4308,4352,4395,4439,4483,4528, //55 + 4574,4619,4665,4712,4759,4807,4855,4903, //63 + 4953,5002,5052,5103,5154,5205,5257,5310, //71 + 5363,5417,5471,5525,5581,5636,5693,5750, //79 + 5807,5865,5924,5983,6043,6104,6165,6226, //87 + 6289,6351,6415,6479,6544,6609,6675,6742, //95 + 6810,6878,6946,7016,7086,7157,7229,7301, //103 + 7374,7448,7522,7597,7673,7750,7828,7906, //111 + 7985,8065,8145,8227,8309,8392,8476,8561, //119 + 8647,8733,8820,8909,8998,9088,9178,9270, + 9363,9457,9551,9647,9743,9841,9939,10038, + 10139,10240,10343,10446,10550,10656,10763,10870, + 10979,11089,11200,11312,11425,11539,11654,11771, + 11889,12008,12128,12249,12371,12495,12620,12746, + 12874,13002,13132,13264,13396,13530,13666,13802, + 13940,14080,14221,14363,14506,14652,14798,14946, + 15096,15247,15399,15553,15709,15866,16024,16184, + 16346,16510,16675,16842,17010,17180,17352,17526, + 17701,17878,18057,18237,18420,18604,18790,18978, + 19167,19359,19553,19748,19946,20145,20347,20550, + 20756,20963,21173,21385,21598,21814,22033,22253, + 22475,22700,22927,23156,23388,23622,23858,24097, + 24338,24581,24827,25075,25326,25579,25835,26093, + 26354,26618,26884,27153,27424,27699,27976,28255, + 28538,28823,29112,29403,29697,29994,30294,30597, + 30903,31212,31524,31839,32157,32479,32804,33132 +}; +static int accel_6500_self_test(long *bias_regular, long *bias_st, int debug) +{ + int i, result = 0, otp_value_zero = 0; + float accel_st_al_min, accel_st_al_max; + float st_shift_cust[3], st_shift_ratio[3], ct_shift_prod[3], accel_offset_max; + unsigned char regs[3]; + if (i2c_read(st.hw->addr, REG_6500_XA_ST_DATA, 3, regs)) { + if(debug) + log_i("Reading OTP Register Error.\n"); + return 0x07; + } + if(debug) + log_i("Accel OTP:%d, %d, %d\n", regs[0], regs[1], regs[2]); + for (i = 0; i < 3; i++) { + if (regs[i] != 0) { + ct_shift_prod[i] = mpu_6500_st_tb[regs[i] - 1]; + ct_shift_prod[i] *= 65536.f; + ct_shift_prod[i] /= test.accel_sens; + } + else { + ct_shift_prod[i] = 0; + otp_value_zero = 1; + } + } + if(otp_value_zero == 0) { + if(debug) + log_i("ACCEL:CRITERIA A\n"); + for (i = 0; i < 3; i++) { + st_shift_cust[i] = bias_st[i] - bias_regular[i]; + if(debug) { + log_i("Bias_Shift=%7.4f, Bias_Reg=%7.4f, Bias_HWST=%7.4f\r\n", + st_shift_cust[i]/1.f, bias_regular[i]/1.f, + bias_st[i]/1.f); + log_i("OTP value: %7.4f\r\n", ct_shift_prod[i]/1.f); + } + + st_shift_ratio[i] = st_shift_cust[i] / ct_shift_prod[i] - 1.f; + + if(debug) + log_i("ratio=%7.4f, threshold=%7.4f\r\n", st_shift_ratio[i]/1.f, + test.max_accel_var/1.f); + + if (fabs(st_shift_ratio[i]) > test.max_accel_var) { + if(debug) + log_i("ACCEL Fail Axis = %d\n", i); + result |= 1 << i; //Error condition + } + } + } + else { + /* Self Test Pass/Fail Criteria B */ + accel_st_al_min = test.min_g * 65536.f; + accel_st_al_max = test.max_g * 65536.f; + + if(debug) { + log_i("ACCEL:CRITERIA B\r\n"); + log_i("Min MG: %7.4f\r\n", accel_st_al_min/1.f); + log_i("Max MG: %7.4f\r\n", accel_st_al_max/1.f); + } + + for (i = 0; i < 3; i++) { + st_shift_cust[i] = bias_st[i] - bias_regular[i]; + + if(debug) + log_i("Bias_shift=%7.4f, st=%7.4f, reg=%7.4f\n", st_shift_cust[i]/1.f, bias_st[i]/1.f, bias_regular[i]/1.f); + if(st_shift_cust[i] < accel_st_al_min || st_shift_cust[i] > accel_st_al_max) { + if(debug) + log_i("Accel FAIL axis:%d <= 225mg or >= 675mg\n", i); + result |= 1 << i; //Error condition + } + } + } + + if(result == 0) { + /* Self Test Pass/Fail Criteria C */ + accel_offset_max = test.max_g_offset * 65536.f; + if(debug) + log_i("Accel:CRITERIA C: bias less than %7.4f\n", accel_offset_max/1.f); + for (i = 0; i < 3; i++) { + if(fabs(bias_regular[i]) > accel_offset_max) { + if(debug) + log_i("FAILED: Accel axis:%d = %ld > 500mg\n", i, bias_regular[i]); + result |= 1 << i; //Error condition + } + } + } + + return result; +} + +static int gyro_6500_self_test(long *bias_regular, long *bias_st, int debug) +{ + int i, result = 0, otp_value_zero = 0; + float gyro_st_al_max; + float st_shift_cust[3], st_shift_ratio[3], ct_shift_prod[3], gyro_offset_max; + unsigned char regs[3]; + + if (i2c_read(st.hw->addr, REG_6500_XG_ST_DATA, 3, regs)) { + if(debug) + log_i("Reading OTP Register Error.\n"); + return 0x07; + } + + if(debug) + log_i("Gyro OTP:%d, %d, %d\r\n", regs[0], regs[1], regs[2]); + + for (i = 0; i < 3; i++) { + if (regs[i] != 0) { + ct_shift_prod[i] = mpu_6500_st_tb[regs[i] - 1]; + ct_shift_prod[i] *= 65536.f; + ct_shift_prod[i] /= test.gyro_sens; + } + else { + ct_shift_prod[i] = 0; + otp_value_zero = 1; + } + } + + if(otp_value_zero == 0) { + if(debug) + log_i("GYRO:CRITERIA A\n"); + /* Self Test Pass/Fail Criteria A */ + for (i = 0; i < 3; i++) { + st_shift_cust[i] = bias_st[i] - bias_regular[i]; + + if(debug) { + log_i("Bias_Shift=%7.4f, Bias_Reg=%7.4f, Bias_HWST=%7.4f\r\n", + st_shift_cust[i]/1.f, bias_regular[i]/1.f, + bias_st[i]/1.f); + log_i("OTP value: %7.4f\r\n", ct_shift_prod[i]/1.f); + } + + st_shift_ratio[i] = st_shift_cust[i] / ct_shift_prod[i]; + + if(debug) + log_i("ratio=%7.4f, threshold=%7.4f\r\n", st_shift_ratio[i]/1.f, + test.max_gyro_var/1.f); + + if (fabs(st_shift_ratio[i]) < test.max_gyro_var) { + if(debug) + log_i("Gyro Fail Axis = %d\n", i); + result |= 1 << i; //Error condition + } + } + } + else { + /* Self Test Pass/Fail Criteria B */ + gyro_st_al_max = test.max_dps * 65536.f; + + if(debug) { + log_i("GYRO:CRITERIA B\r\n"); + log_i("Max DPS: %7.4f\r\n", gyro_st_al_max/1.f); + } + + for (i = 0; i < 3; i++) { + st_shift_cust[i] = bias_st[i] - bias_regular[i]; + + if(debug) + log_i("Bias_shift=%7.4f, st=%7.4f, reg=%7.4f\n", st_shift_cust[i]/1.f, bias_st[i]/1.f, bias_regular[i]/1.f); + if(st_shift_cust[i] < gyro_st_al_max) { + if(debug) + log_i("GYRO FAIL axis:%d greater than 60dps\n", i); + result |= 1 << i; //Error condition + } + } + } + + if(result == 0) { + /* Self Test Pass/Fail Criteria C */ + gyro_offset_max = test.min_dps * 65536.f; + if(debug) + log_i("Gyro:CRITERIA C: bias less than %7.4f\n", gyro_offset_max/1.f); + for (i = 0; i < 3; i++) { + if(fabs(bias_regular[i]) > gyro_offset_max) { + if(debug) + log_i("FAILED: Gyro axis:%d = %ld > 20dps\n", i, bias_regular[i]); + result |= 1 << i; //Error condition + } + } + } + return result; +} + +static int get_st_6500_biases(long *gyro, long *accel, unsigned char hw_test, int debug) +{ + unsigned char data[HWST_MAX_PACKET_LENGTH]; + unsigned char packet_count, ii; + unsigned short fifo_count; + int s = 0, read_size = 0, ind; + + data[0] = 0x01; + data[1] = 0; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data)) + return -1; + delay_ms(200); + data[0] = 0; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data)) + return -1; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + data[0] = BIT_FIFO_RST | BIT_DMP_RST; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + delay_ms(15); + data[0] = st.test->reg_lpf; + if (i2c_write(st.hw->addr, st.reg->lpf, 1, data)) + return -1; + data[0] = st.test->reg_rate_div; + if (i2c_write(st.hw->addr, st.reg->rate_div, 1, data)) + return -1; + if (hw_test) + data[0] = st.test->reg_gyro_fsr | 0xE0; + else + data[0] = st.test->reg_gyro_fsr; + if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, data)) + return -1; + + if (hw_test) + data[0] = st.test->reg_accel_fsr | 0xE0; + else + data[0] = test.reg_accel_fsr; + if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, data)) + return -1; + + delay_ms(test.wait_ms); //wait 200ms for sensors to stabilize + + /* Enable FIFO */ + data[0] = BIT_FIFO_EN; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) + return -1; + data[0] = INV_XYZ_GYRO | INV_XYZ_ACCEL; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + + //initialize the bias return values + gyro[0] = gyro[1] = gyro[2] = 0; + accel[0] = accel[1] = accel[2] = 0; + + if(debug) + log_i("Starting Bias Loop Reads\n"); + + //start reading samples + while (s < test.packet_thresh) { + delay_ms(test.sample_wait_ms); //wait 10ms to fill FIFO + if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) + return -1; + fifo_count = (data[0] << 8) | data[1]; + packet_count = fifo_count / MAX_PACKET_LENGTH; + if ((test.packet_thresh - s) < packet_count) + packet_count = test.packet_thresh - s; + read_size = packet_count * MAX_PACKET_LENGTH; + + //burst read from FIFO + if (i2c_read(st.hw->addr, st.reg->fifo_r_w, read_size, data)) + return -1; + ind = 0; + for (ii = 0; ii < packet_count; ii++) { + short accel_cur[3], gyro_cur[3]; + accel_cur[0] = ((short)data[ind + 0] << 8) | data[ind + 1]; + accel_cur[1] = ((short)data[ind + 2] << 8) | data[ind + 3]; + accel_cur[2] = ((short)data[ind + 4] << 8) | data[ind + 5]; + accel[0] += (long)accel_cur[0]; + accel[1] += (long)accel_cur[1]; + accel[2] += (long)accel_cur[2]; + gyro_cur[0] = (((short)data[ind + 6] << 8) | data[ind + 7]); + gyro_cur[1] = (((short)data[ind + 8] << 8) | data[ind + 9]); + gyro_cur[2] = (((short)data[ind + 10] << 8) | data[ind + 11]); + gyro[0] += (long)gyro_cur[0]; + gyro[1] += (long)gyro_cur[1]; + gyro[2] += (long)gyro_cur[2]; + ind += MAX_PACKET_LENGTH; + } + s += packet_count; + } + + if(debug) + log_i("Samples: %d\n", s); + + //stop FIFO + data[0] = 0; + if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) + return -1; + + gyro[0] = (long)(((long long)gyro[0]<<16) / test.gyro_sens / s); + gyro[1] = (long)(((long long)gyro[1]<<16) / test.gyro_sens / s); + gyro[2] = (long)(((long long)gyro[2]<<16) / test.gyro_sens / s); + accel[0] = (long)(((long long)accel[0]<<16) / test.accel_sens / s); + accel[1] = (long)(((long long)accel[1]<<16) / test.accel_sens / s); + accel[2] = (long)(((long long)accel[2]<<16) / test.accel_sens / s); + /* remove gravity from bias calculation */ + if (accel[2] > 0L) + accel[2] -= 65536L; + else + accel[2] += 65536L; + + + if(debug) { + log_i("Accel offset data HWST bit=%d: %7.4f %7.4f %7.4f\r\n", hw_test, accel[0]/65536.f, accel[1]/65536.f, accel[2]/65536.f); + log_i("Gyro offset data HWST bit=%d: %7.4f %7.4f %7.4f\r\n", hw_test, gyro[0]/65536.f, gyro[1]/65536.f, gyro[2]/65536.f); + } + + return 0; +} +/** + * @brief Trigger gyro/accel/compass self-test for MPU6500/MPU9250 + * On success/error, the self-test returns a mask representing the sensor(s) + * that failed. For each bit, a one (1) represents a "pass" case; conversely, + * a zero (0) indicates a failure. + * + * \n The mask is defined as follows: + * \n Bit 0: Gyro. + * \n Bit 1: Accel. + * \n Bit 2: Compass. + * + * @param[out] gyro Gyro biases in q16 format. + * @param[out] accel Accel biases (if applicable) in q16 format. + * @param[in] debug Debug flag used to print out more detailed logs. Must first set up logging in Motion Driver. + * @return Result mask (see above). + */ +int mpu_run_6500_self_test(long *gyro, long *accel, unsigned char debug) +{ + const unsigned char tries = 2; + long gyro_st[3], accel_st[3]; + unsigned char accel_result, gyro_result; +#ifdef AK89xx_SECONDARY + unsigned char compass_result; +#endif + int ii; + + int result; + unsigned char accel_fsr, fifo_sensors, sensors_on; + unsigned short gyro_fsr, sample_rate, lpf; + unsigned char dmp_was_on; + + + + if(debug) + log_i("Starting MPU6500 HWST!\r\n"); + + if (st.chip_cfg.dmp_on) { + mpu_set_dmp_state(0); + dmp_was_on = 1; + } else + dmp_was_on = 0; + + /* Get initial settings. */ + mpu_get_gyro_fsr(&gyro_fsr); + mpu_get_accel_fsr(&accel_fsr); + mpu_get_lpf(&lpf); + mpu_get_sample_rate(&sample_rate); + sensors_on = st.chip_cfg.sensors; + mpu_get_fifo_config(&fifo_sensors); + + if(debug) + log_i("Retrieving Biases\r\n"); + + for (ii = 0; ii < tries; ii++) + if (!get_st_6500_biases(gyro, accel, 0, debug)) + break; + if (ii == tries) { + /* If we reach this point, we most likely encountered an I2C error. + * We'll just report an error for all three sensors. + */ + if(debug) + log_i("Retrieving Biases Error - possible I2C error\n"); + + result = 0; + goto restore; + } + + if(debug) + log_i("Retrieving ST Biases\n"); + + for (ii = 0; ii < tries; ii++) + if (!get_st_6500_biases(gyro_st, accel_st, 1, debug)) + break; + if (ii == tries) { + + if(debug) + log_i("Retrieving ST Biases Error - possible I2C error\n"); + + /* Again, probably an I2C error. */ + result = 0; + goto restore; + } + + accel_result = accel_6500_self_test(accel, accel_st, debug); + if(debug) + log_i("Accel Self Test Results: %d\n", accel_result); + + gyro_result = gyro_6500_self_test(gyro, gyro_st, debug); + if(debug) + log_i("Gyro Self Test Results: %d\n", gyro_result); + + result = 0; + if (!gyro_result) + result |= 0x01; + if (!accel_result) + result |= 0x02; + +#ifdef AK89xx_SECONDARY + compass_result = compass_self_test(); + if(debug) + log_i("Compass Self Test Results: %d\n", compass_result); + if (!compass_result) + result |= 0x04; +#else + result |= 0x04; +#endif +restore: + if(debug) + log_i("Exiting HWST\n"); + /* Set to invalid values to ensure no I2C writes are skipped. */ + st.chip_cfg.gyro_fsr = 0xFF; + st.chip_cfg.accel_fsr = 0xFF; + st.chip_cfg.lpf = 0xFF; + st.chip_cfg.sample_rate = 0xFFFF; + st.chip_cfg.sensors = 0xFF; + st.chip_cfg.fifo_enable = 0xFF; + st.chip_cfg.clk_src = INV_CLK_PLL; + mpu_set_gyro_fsr(gyro_fsr); + mpu_set_accel_fsr(accel_fsr); + mpu_set_lpf(lpf); + mpu_set_sample_rate(sample_rate); + mpu_set_sensors(sensors_on); + mpu_configure_fifo(fifo_sensors); + + if (dmp_was_on) + mpu_set_dmp_state(1); + + return result; +} +#endif + /* + * \n This function must be called with the device either face-up or face-down + * (z-axis is parallel to gravity). + * @param[out] gyro Gyro biases in q16 format. + * @param[out] accel Accel biases (if applicable) in q16 format. + * @return Result mask (see above). + */ +int mpu_run_self_test(long *gyro, long *accel) +{ +#ifdef MPU6050 + const unsigned char tries = 2; + long gyro_st[3], accel_st[3]; + unsigned char accel_result, gyro_result; +#ifdef AK89xx_SECONDARY + unsigned char compass_result; +#endif + int ii; +#endif + int result; + unsigned char accel_fsr, fifo_sensors, sensors_on; + unsigned short gyro_fsr, sample_rate, lpf; + unsigned char dmp_was_on; + + if (st.chip_cfg.dmp_on) { + mpu_set_dmp_state(0); + dmp_was_on = 1; + } else + dmp_was_on = 0; + + /* Get initial settings. */ + mpu_get_gyro_fsr(&gyro_fsr); + mpu_get_accel_fsr(&accel_fsr); + mpu_get_lpf(&lpf); + mpu_get_sample_rate(&sample_rate); + sensors_on = st.chip_cfg.sensors; + mpu_get_fifo_config(&fifo_sensors); + + /* For older chips, the self-test will be different. */ +#if defined MPU6050 + for (ii = 0; ii < tries; ii++) + if (!get_st_biases(gyro, accel, 0)) + break; + if (ii == tries) { + /* If we reach this point, we most likely encountered an I2C error. + * We'll just report an error for all three sensors. + */ + result = 0; + goto restore; + } + for (ii = 0; ii < tries; ii++) + if (!get_st_biases(gyro_st, accel_st, 1)) + break; + if (ii == tries) { + /* Again, probably an I2C error. */ + result = 0; + goto restore; + } + accel_result = accel_self_test(accel, accel_st); + gyro_result = gyro_self_test(gyro, gyro_st); + + result = 0; + if (!gyro_result) + result |= 0x01; + if (!accel_result) + result |= 0x02; + +#ifdef AK89xx_SECONDARY + compass_result = compass_self_test(); + if (!compass_result) + result |= 0x04; +#else + result |= 0x04; +#endif +restore: +#elif defined MPU6500 + /* For now, this function will return a "pass" result for all three sensors + * for compatibility with current test applications. + */ + get_st_biases(gyro, accel, 0); + result = 0x7; +#endif + /* Set to invalid values to ensure no I2C writes are skipped. */ + st.chip_cfg.gyro_fsr = 0xFF; + st.chip_cfg.accel_fsr = 0xFF; + st.chip_cfg.lpf = 0xFF; + st.chip_cfg.sample_rate = 0xFFFF; + st.chip_cfg.sensors = 0xFF; + st.chip_cfg.fifo_enable = 0xFF; + st.chip_cfg.clk_src = INV_CLK_PLL; + mpu_set_gyro_fsr(gyro_fsr); + mpu_set_accel_fsr(accel_fsr); + mpu_set_lpf(lpf); + mpu_set_sample_rate(sample_rate); + mpu_set_sensors(sensors_on); + mpu_configure_fifo(fifo_sensors); + + if (dmp_was_on) + mpu_set_dmp_state(1); + + return result; +} + +/** + * @brief Write to the DMP memory. + * This function prevents I2C writes past the bank boundaries. The DMP memory + * is only accessible when the chip is awake. + * @param[in] mem_addr Memory location (bank << 8 | start address) + * @param[in] length Number of bytes to write. + * @param[in] data Bytes to write to memory. + * @return 0 if successful. + */ +int mpu_write_mem(unsigned short mem_addr, unsigned short length, + unsigned char *data) +{ + unsigned char tmp[2]; + + if (!data) + return -1; + if (!st.chip_cfg.sensors) + return -1; + + tmp[0] = (unsigned char)(mem_addr >> 8); + tmp[1] = (unsigned char)(mem_addr & 0xFF); + + /* Check bank boundaries. */ + if (tmp[1] + length > st.hw->bank_size) + return -1; + + if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp)) + return -1; + if (i2c_write(st.hw->addr, st.reg->mem_r_w, length, data)) + return -1; + return 0; +} + +/** + * @brief Read from the DMP memory. + * This function prevents I2C reads past the bank boundaries. The DMP memory + * is only accessible when the chip is awake. + * @param[in] mem_addr Memory location (bank << 8 | start address) + * @param[in] length Number of bytes to read. + * @param[out] data Bytes read from memory. + * @return 0 if successful. + */ +int mpu_read_mem(unsigned short mem_addr, unsigned short length, + unsigned char *data) +{ + unsigned char tmp[2]; + + if (!data) + return -1; + if (!st.chip_cfg.sensors) + return -1; + + tmp[0] = (unsigned char)(mem_addr >> 8); + tmp[1] = (unsigned char)(mem_addr & 0xFF); + + /* Check bank boundaries. */ + if (tmp[1] + length > st.hw->bank_size) + return -1; + + if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp)) + return -1; + if (i2c_read(st.hw->addr, st.reg->mem_r_w, length, data)) + return -1; + return 0; +} + +/** + * @brief Load and verify DMP image. + * @param[in] length Length of DMP image. + * @param[in] firmware DMP code. + * @param[in] start_addr Starting address of DMP code memory. + * @param[in] sample_rate Fixed sampling rate used when DMP is enabled. + * @return 0 if successful. + */ +int mpu_load_firmware(unsigned short length, const unsigned char *firmware, + unsigned short start_addr, unsigned short sample_rate) +{ + unsigned short ii; + unsigned short this_write; + /* Must divide evenly into st.hw->bank_size to avoid bank crossings. */ +#define LOAD_CHUNK (16) + unsigned char cur[LOAD_CHUNK], tmp[2]; + + if (st.chip_cfg.dmp_loaded) + /* DMP should only be loaded once. */ + return -1; + + if (!firmware) + return -1; + for (ii = 0; ii < length; ii += this_write) { + this_write = min(LOAD_CHUNK, length - ii); + if (mpu_write_mem(ii, this_write, (unsigned char*)&firmware[ii])) + return -1; + if (mpu_read_mem(ii, this_write, cur)) + return -1; + if (memcmp(firmware+ii, cur, this_write)) + return -2; + } + + /* Set program start address. */ + tmp[0] = start_addr >> 8; + tmp[1] = start_addr & 0xFF; + if (i2c_write(st.hw->addr, st.reg->prgm_start_h, 2, tmp)) + return -1; + + st.chip_cfg.dmp_loaded = 1; + st.chip_cfg.dmp_sample_rate = sample_rate; + return 0; +} + +/** + * @brief Enable/disable DMP support. + * @param[in] enable 1 to turn on the DMP. + * @return 0 if successful. + */ +int mpu_set_dmp_state(unsigned char enable) +{ + unsigned char tmp; + if (st.chip_cfg.dmp_on == enable) + return 0; + + if (enable) { + if (!st.chip_cfg.dmp_loaded) + return -1; + /* Disable data ready interrupt. */ + set_int_enable(0); + /* Disable bypass mode. */ + mpu_set_bypass(0); + /* Keep constant sample rate, FIFO rate controlled by DMP. */ + mpu_set_sample_rate(st.chip_cfg.dmp_sample_rate); + /* Remove FIFO elements. */ + tmp = 0; + i2c_write(st.hw->addr, 0x23, 1, &tmp); + st.chip_cfg.dmp_on = 1; + /* Enable DMP interrupt. */ + set_int_enable(1); + mpu_reset_fifo(); + } else { + /* Disable DMP interrupt. */ + set_int_enable(0); + /* Restore FIFO settings. */ + tmp = st.chip_cfg.fifo_enable; + i2c_write(st.hw->addr, 0x23, 1, &tmp); + st.chip_cfg.dmp_on = 0; + mpu_reset_fifo(); + } + return 0; +} + +/** + * @brief Get DMP state. + * @param[out] enabled 1 if enabled. + * @return 0 if successful. + */ +int mpu_get_dmp_state(unsigned char *enabled) +{ + enabled[0] = st.chip_cfg.dmp_on; + return 0; +} + +#ifdef AK89xx_SECONDARY +/* This initialization is similar to the one in ak8975.c. */ +static int setup_compass(void) +{ + unsigned char data[4], akm_addr; + + mpu_set_bypass(1); + + /* Find compass. Possible addresses range from 0x0C to 0x0F. */ + for (akm_addr = 0x0C; akm_addr <= 0x0F; akm_addr++) { + int result; + result = i2c_read(akm_addr, AKM_REG_WHOAMI, 1, data); + if (!result && (data[0] == AKM_WHOAMI)) + break; + } + + if (akm_addr > 0x0F) { + /* TODO: Handle this case in all compass-related functions. */ + #ifdef SERIAL_DEBUG + log_i("Compass not found.\n"); + #endif + return -1; + } + + st.chip_cfg.compass_addr = akm_addr; + + data[0] = AKM_POWER_DOWN; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) + return -1; + delay_ms(1); + + data[0] = AKM_FUSE_ROM_ACCESS; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) + return -1; + delay_ms(1); + + /* Get sensitivity adjustment data from fuse ROM. */ + if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ASAX, 3, data)) + return -1; + st.chip_cfg.mag_sens_adj[0] = (long)data[0] + 128; + st.chip_cfg.mag_sens_adj[1] = (long)data[1] + 128; + st.chip_cfg.mag_sens_adj[2] = (long)data[2] + 128; + + data[0] = AKM_POWER_DOWN; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) + return -1; + delay_ms(1); + + mpu_set_bypass(0); + + /* Set up master mode, master clock, and ES bit. */ + data[0] = 0x40; + if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data)) + return -1; + + /* Slave 0 reads from AKM data registers. */ + data[0] = BIT_I2C_READ | st.chip_cfg.compass_addr; + if (i2c_write(st.hw->addr, st.reg->s0_addr, 1, data)) + return -1; + + /* Compass reads start at this register. */ + data[0] = AKM_REG_ST1; + if (i2c_write(st.hw->addr, st.reg->s0_reg, 1, data)) + return -1; + + /* Enable slave 0, 8-byte reads. */ + data[0] = BIT_SLAVE_EN | 8; + if (i2c_write(st.hw->addr, st.reg->s0_ctrl, 1, data)) + return -1; + + /* Slave 1 changes AKM measurement mode. */ + data[0] = st.chip_cfg.compass_addr; + if (i2c_write(st.hw->addr, st.reg->s1_addr, 1, data)) + return -1; + + /* AKM measurement mode register. */ + data[0] = AKM_REG_CNTL; + if (i2c_write(st.hw->addr, st.reg->s1_reg, 1, data)) + return -1; + + /* Enable slave 1, 1-byte writes. */ + data[0] = BIT_SLAVE_EN | 1; + if (i2c_write(st.hw->addr, st.reg->s1_ctrl, 1, data)) + return -1; + + /* Set slave 1 data. */ + data[0] = AKM_SINGLE_MEASUREMENT; + if (i2c_write(st.hw->addr, st.reg->s1_do, 1, data)) + return -1; + + /* Trigger slave 0 and slave 1 actions at each sample. */ + data[0] = 0x03; + if (i2c_write(st.hw->addr, st.reg->i2c_delay_ctrl, 1, data)) + return -1; + +#ifdef MPU9150 + /* For the MPU9150, the auxiliary I2C bus needs to be set to VDD. */ + data[0] = BIT_I2C_MST_VDDIO; + if (i2c_write(st.hw->addr, st.reg->yg_offs_tc, 1, data)) + return -1; +#endif + + return 0; +} +#endif + +/** + * @brief Read raw compass data. + * @param[out] data Raw data in hardware units. + * @param[out] timestamp Timestamp in milliseconds. Null if not needed. + * @return 0 if successful. + */ +int mpu_get_compass_reg(short *data, unsigned long *timestamp) +{ +#ifdef AK89xx_SECONDARY + unsigned char tmp[9]; + + if (!(st.chip_cfg.sensors & INV_XYZ_COMPASS)) + return -1; + +#ifdef AK89xx_BYPASS + if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 8, tmp)) + return -1; + tmp[8] = AKM_SINGLE_MEASUREMENT; + if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp+8)) + return -1; +#else + if (i2c_read(st.hw->addr, st.reg->raw_compass, 8, tmp)) + return -1; +#endif + +#if defined AK8975_SECONDARY + /* AK8975 doesn't have the overrun error bit. */ + if (!(tmp[0] & AKM_DATA_READY)) + return -2; + if ((tmp[7] & AKM_OVERFLOW) || (tmp[7] & AKM_DATA_ERROR)) + return -3; +#elif defined AK8963_SECONDARY + /* AK8963 doesn't have the data read error bit. */ + if (!(tmp[0] & AKM_DATA_READY) || (tmp[0] & AKM_DATA_OVERRUN)) + return -2; + if (tmp[7] & AKM_OVERFLOW) + return -3; +#endif + data[0] = (tmp[2] << 8) | tmp[1]; + data[1] = (tmp[4] << 8) | tmp[3]; + data[2] = (tmp[6] << 8) | tmp[5]; + + data[0] = ((long)data[0] * st.chip_cfg.mag_sens_adj[0]) >> 8; + data[1] = ((long)data[1] * st.chip_cfg.mag_sens_adj[1]) >> 8; + data[2] = ((long)data[2] * st.chip_cfg.mag_sens_adj[2]) >> 8; + + if (timestamp) + get_ms(timestamp); + return 0; +#else + return -1; +#endif +} + +/** + * @brief Get the compass full-scale range. + * @param[out] fsr Current full-scale range. + * @return 0 if successful. + */ +int mpu_get_compass_fsr(unsigned short *fsr) +{ +#ifdef AK89xx_SECONDARY + fsr[0] = st.hw->compass_fsr; + return 0; +#else + return -1; +#endif +} + +/** + * @brief Enters LP accel motion interrupt mode. + * The behaviour of this feature is very different between the MPU6050 and the + * MPU6500. Each chip's version of this feature is explained below. + * + * \n The hardware motion threshold can be between 32mg and 8160mg in 32mg + * increments. + * + * \n Low-power accel mode supports the following frequencies: + * \n 1.25Hz, 5Hz, 20Hz, 40Hz + * + * \n MPU6500: + * \n Unlike the MPU6050 version, the hardware does not "lock in" a reference + * sample. The hardware monitors the accel data and detects any large change + * over a short period of time. + * + * \n The hardware motion threshold can be between 4mg and 1020mg in 4mg + * increments. + * + * \n MPU6500 Low-power accel mode supports the following frequencies: + * \n 1.25Hz, 2.5Hz, 5Hz, 10Hz, 20Hz, 40Hz, 80Hz, 160Hz, 320Hz, 640Hz + * + * \n\n NOTES: + * \n The driver will round down @e thresh to the nearest supported value if + * an unsupported threshold is selected. + * \n To select a fractional wake-up frequency, round down the value passed to + * @e lpa_freq. + * \n The MPU6500 does not support a delay parameter. If this function is used + * for the MPU6500, the value passed to @e time will be ignored. + * \n To disable this mode, set @e lpa_freq to zero. The driver will restore + * the previous configuration. + * + * @param[in] thresh Motion threshold in mg. + * @param[in] time Duration in milliseconds that the accel data must + * exceed @e thresh before motion is reported. + * @param[in] lpa_freq Minimum sampling rate, or zero to disable. + * @return 0 if successful. + */ +int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time, unsigned short lpa_freq) +{ + +#if defined MPU6500 + unsigned char data[3]; +#endif + if (lpa_freq) { +#if defined MPU6500 + unsigned char thresh_hw; + + /* 1LSb = 4mg. */ + if (thresh > 1020) + thresh_hw = 255; + else if (thresh < 4) + thresh_hw = 1; + else + thresh_hw = thresh >> 2; +#endif + + if (!time) + /* Minimum duration must be 1ms. */ + time = 1; + +#if defined MPU6500 + if (lpa_freq > 640) + /* At this point, the chip has not been re-configured, so the + * function can safely exit. + */ + return -1; +#endif + + if (!st.chip_cfg.int_motion_only) { + /* Store current settings for later. */ + if (st.chip_cfg.dmp_on) { + mpu_set_dmp_state(0); + st.chip_cfg.cache.dmp_on = 1; + } else + st.chip_cfg.cache.dmp_on = 0; + mpu_get_gyro_fsr(&st.chip_cfg.cache.gyro_fsr); + mpu_get_accel_fsr(&st.chip_cfg.cache.accel_fsr); + mpu_get_lpf(&st.chip_cfg.cache.lpf); + mpu_get_sample_rate(&st.chip_cfg.cache.sample_rate); + st.chip_cfg.cache.sensors_on = st.chip_cfg.sensors; + mpu_get_fifo_config(&st.chip_cfg.cache.fifo_sensors); + } + +#if defined MPU6500 + /* Disable hardware interrupts. */ + set_int_enable(0); + + /* Enter full-power accel-only mode, no FIFO/DMP. */ + data[0] = 0; + data[1] = 0; + data[2] = BIT_STBY_XYZG; + if (i2c_write(st.hw->addr, st.reg->user_ctrl, 3, data)) + goto lp_int_restore; + + /* Set motion threshold. */ + data[0] = thresh_hw; + if (i2c_write(st.hw->addr, st.reg->motion_thr, 1, data)) + goto lp_int_restore; + + /* Set wake frequency. */ + if (lpa_freq == 1) + data[0] = INV_LPA_1_25HZ; + else if (lpa_freq == 2) + data[0] = INV_LPA_2_5HZ; + else if (lpa_freq <= 5) + data[0] = INV_LPA_5HZ; + else if (lpa_freq <= 10) + data[0] = INV_LPA_10HZ; + else if (lpa_freq <= 20) + data[0] = INV_LPA_20HZ; + else if (lpa_freq <= 40) + data[0] = INV_LPA_40HZ; + else if (lpa_freq <= 80) + data[0] = INV_LPA_80HZ; + else if (lpa_freq <= 160) + data[0] = INV_LPA_160HZ; + else if (lpa_freq <= 320) + data[0] = INV_LPA_320HZ; + else + data[0] = INV_LPA_640HZ; + if (i2c_write(st.hw->addr, st.reg->lp_accel_odr, 1, data)) + goto lp_int_restore; + + /* Enable motion interrupt (MPU6500 version). */ + data[0] = BITS_WOM_EN; + if (i2c_write(st.hw->addr, st.reg->accel_intel, 1, data)) + goto lp_int_restore; + + /* Enable cycle mode. */ + data[0] = BIT_LPA_CYCLE; + if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) + goto lp_int_restore; + + /* Enable interrupt. */ + data[0] = BIT_MOT_INT_EN; + if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) + goto lp_int_restore; + + st.chip_cfg.int_motion_only = 1; + return 0; +#endif + } else { + /* Don't "restore" the previous state if no state has been saved. */ + unsigned int ii; + char *cache_ptr = (char*)&st.chip_cfg.cache; + for (ii = 0; ii < sizeof(st.chip_cfg.cache); ii++) { + if (cache_ptr[ii] != 0) + goto lp_int_restore; + } + /* If we reach this point, motion interrupt mode hasn't been used yet. */ + return -1; + } +lp_int_restore: + /* Set to invalid values to ensure no I2C writes are skipped. */ + st.chip_cfg.gyro_fsr = 0xFF; + st.chip_cfg.accel_fsr = 0xFF; + st.chip_cfg.lpf = 0xFF; + st.chip_cfg.sample_rate = 0xFFFF; + st.chip_cfg.sensors = 0xFF; + st.chip_cfg.fifo_enable = 0xFF; + st.chip_cfg.clk_src = INV_CLK_PLL; + mpu_set_sensors(st.chip_cfg.cache.sensors_on); + mpu_set_gyro_fsr(st.chip_cfg.cache.gyro_fsr); + mpu_set_accel_fsr(st.chip_cfg.cache.accel_fsr); + mpu_set_lpf(st.chip_cfg.cache.lpf); + mpu_set_sample_rate(st.chip_cfg.cache.sample_rate); + mpu_configure_fifo(st.chip_cfg.cache.fifo_sensors); + + if (st.chip_cfg.cache.dmp_on) + mpu_set_dmp_state(1); + +#ifdef MPU6500 + /* Disable motion interrupt (MPU6500 version). */ + data[0] = 0; + if (i2c_write(st.hw->addr, st.reg->accel_intel, 1, data)) + goto lp_int_restore; +#endif + + st.chip_cfg.int_motion_only = 0; + return 0; +} + +/* + * This function must be called with the device either face-up or face-down + * (z-axis is parallel to gravity). + */ +void mpu_start_self_test(void) +{ + int result; + long gyro[3], accel[3]; + +#if defined (MPU6500) || defined (MPU9250) + result = mpu_run_6500_self_test(gyro, accel, 0); +#elif defined (MPU6050) || defined (MPU9150) + result = mpu_run_self_test(gyro, accel); +#endif + if (result == 0x7) { + #ifdef SERIAL_DEBUG + consoleLog("Passed!\n"); + log_i("accel: %7.4f %7.4f %7.4f\n", + accel[0]/65536.f, + accel[1]/65536.f, + accel[2]/65536.f); + log_i("gyro: %7.4f %7.4f %7.4f\n", + gyro[0]/65536.f, + gyro[1]/65536.f, + gyro[2]/65536.f); + /* Test passed. We can trust the gyro data here, so now we need to update calibrated data*/ + #endif + +#ifdef USE_CAL_HW_REGISTERS + /* + * This portion of the code uses the HW offset registers that are in the MPUxxxx devices + * instead of pushing the cal data to the MPL software library + */ + unsigned char i = 0; + + for(i = 0; i<3; i++) { + gyro[i] = (long)(gyro[i] * 32.8f); //convert to +-1000dps + accel[i] *= 2048.f; //convert to +-16G + accel[i] = accel[i] >> 16; + gyro[i] = (long)(gyro[i] >> 16); + } + + mpu_set_gyro_bias_reg(gyro); + + #if defined (MPU6500) || defined (MPU9250) + mpu_set_accel_bias_6500_reg(accel); + #elif defined (MPU6050) || defined (MPU9150) + mpu_set_accel_bias_6050_reg(accel); + #endif +#endif + } + else { + if (!(result & 0x1)) + consoleLog("Gyro failed.\n"); + if (!(result & 0x2)) + consoleLog("Accel failed.\n"); + if (!(result & 0x4)) + consoleLog("Compass failed.\n"); + } + +} + +/** + * @} + */ + +//========================================================================================= +//========================================================================================= + +struct hal_s { + unsigned char lp_accel_mode; + unsigned char sensors; + unsigned char dmp_on; + unsigned char wait_for_tap; + volatile unsigned char new_gyro; + unsigned long no_dmp_hz; + unsigned long next_pedo_ms; + unsigned long next_temp_ms; + unsigned int report; + unsigned short dmp_features; +}; +static struct hal_s hal = {0}; + + +/* This fuction handle sensor on/off combinations. */ +void mpu_setup_gyro(void) +{ + unsigned char mask = 0, lp_accel_was_on = 0; + if (hal.sensors & ACCEL_ON) { + mask |= INV_XYZ_ACCEL; + consoleLog("Accel sensor On.\n"); + } else { + consoleLog("Accel sensor Off.\n"); + } + if (hal.sensors & GYRO_ON) { + mask |= INV_XYZ_GYRO; + lp_accel_was_on |= hal.lp_accel_mode; + consoleLog("Gyro sensor On.\n"); + } else { + consoleLog("Gyro sensor Off.\n"); + } +#ifdef COMPASS_ENABLED + if (hal.sensors & COMPASS_ON) { + mask |= INV_XYZ_COMPASS; + lp_accel_was_on |= hal.lp_accel_mode; + } +#endif + /* If you need a power transition, this function should be called with a + * mask of the sensors still enabled. The driver turns off any sensors + * excluded from this mask. + */ + mpu_set_sensors(mask); + mpu_configure_fifo(mask); + if (lp_accel_was_on) { + unsigned short rate; + hal.lp_accel_mode = 0; + /* Switching out of LP accel, notify MPL of new accel sampling rate. */ + mpu_get_sample_rate(&rate); + } +} + + + +/* =========================== MPU-6050 Configuration =========================== */ +int mpu_config(void) +{ + consoleLog("-- Configuring MPU6050... "); + + if(mpu_init()) { + consoleLog("FAIL (MPU).\n"); + return -1; + } + + /* Get/set hardware configuration. Start gyro. */ + /* Wake up all sensors. */ + mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL); + + /* Push both gyro and accel data into the FIFO. */ + mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL); + mpu_set_sample_rate(MPU_DEFAULT_HZ); + + /* Read back configuration in case it was set improperly. */ + // mpu_get_sample_rate(&gyro_rate); + // mpu_get_gyro_fsr(&gyro_fsr); + // mpu_get_accel_fsr(&accel_fsr); + + /* Initialize HAL state variables. */ + hal.sensors = ACCEL_ON | GYRO_ON; + hal.dmp_on = 0; + hal.report = 0; + hal.next_pedo_ms = 0; + hal.next_temp_ms = 0; + +#ifdef MPU_DMP_ENABLE + /* To initialize the DMP: + * 1. Call dmp_load_motion_driver_firmware(). This pushes the DMP image in + * inv_mpu_dmp_motion_driver.h into the MPU memory. + * 2. Push the gyro and accel orientation matrix to the DMP. + * 3. Register gesture callbacks. Don't worry, these callbacks won't be + * executed unless the corresponding feature is enabled. + * 4. Call dmp_enable_feature(mask) to enable different features. + * 5. Call dmp_set_fifo_rate(freq) to select a DMP output rate. + * 6. Call any feature-specific control functions. + * + * To enable the DMP, just call mpu_set_dmp_state(1). This function can + * be called repeatedly to enable and disable the DMP at runtime. + * + * The following is a short summary of the features supported in the DMP + * image provided in inv_mpu_dmp_motion_driver.c: + * DMP_FEATURE_LP_QUAT: Generate a gyro-only quaternion on the DMP at + * 200Hz. Integrating the gyro data at higher rates reduces numerical + * errors (compared to integration on the MCU at a lower sampling rate). + * DMP_FEATURE_6X_LP_QUAT: Generate a gyro/accel quaternion on the DMP at + * 200Hz. Cannot be used in combination with DMP_FEATURE_LP_QUAT. + * DMP_FEATURE_TAP: Detect taps along the X, Y, and Z axes. + * DMP_FEATURE_ANDROID_ORIENT: Google's screen rotation algorithm. Triggers + * an event at the four orientations where the screen should rotate. + * DMP_FEATURE_GYRO_CAL: Calibrates the gyro data after eight seconds of + * no motion. + * DMP_FEATURE_SEND_RAW_ACCEL: Add raw accelerometer data to the FIFO. + * DMP_FEATURE_SEND_RAW_GYRO: Add raw gyro data to the FIFO. + * DMP_FEATURE_SEND_CAL_GYRO: Add calibrated gyro data to the FIFO. Cannot + * be used in combination with DMP_FEATURE_SEND_RAW_GYRO. + */ + consoleLog(" writing DMP... "); + if (dmp_load_motion_driver_firmware()) { + consoleLog(" FAIL (DMP) --\r\n"); + return -1; + } + // dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_pdata.orientation)); + dmp_register_tap_cb(mpu_tap_func); + dmp_register_android_orient_cb(mpu_android_orient_func); + /* + * Known Bug - + * DMP when enabled will sample sensor data at 200Hz and output to FIFO at the rate + * specified in the dmp_set_fifo_rate API. The DMP will then sent an interrupt once + * a sample has been put into the FIFO. Therefore if the dmp_set_fifo_rate is at 25Hz + * there will be a 25Hz interrupt from the MPU device. + * + * There is a known issue in which if you do not enable DMP_FEATURE_TAP + * then the interrupts will be at 200Hz even if fifo rate + * is set at a different rate. To avoid this issue include the DMP_FEATURE_TAP + * + * DMP sensor fusion works only with gyro at +-2000dps and accel +-2G + */ + hal.dmp_features = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT | + DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_RAW_GYRO | DMP_FEATURE_GYRO_CAL; + dmp_enable_feature(hal.dmp_features); + dmp_set_fifo_rate(MPU_DEFAULT_HZ); + mpu_set_dmp_state(1); + hal.dmp_on = 1; +#endif + + consoleLog(" OK --\r\n"); + return 0; +} + + +/* =========================== MPU-6050 Get Packet Data =========================== */ + +MPU_Data mpu; + +void mpu_get_data(void) +{ + + unsigned long sensor_timestamp; + unsigned long timestamp; + unsigned char new_data = 0, new_temp = 0; + uint8_t mpu_int_status; // holds actual interrupt status byte from MPU + + // check for DMP interrupt bit or Data Ready interrupt bit (in case DMP is disabled) -> this interrupt should happen frequently + i2c_readByte(st.hw->addr, st.reg->int_status, &mpu_int_status); + if (mpu_int_status & MPU_INT_STATUS_DMP || mpu_int_status & MPU_INT_STATUS_DATA_READY) { + hal.new_gyro = 1; + } + + get_tick_count_ms(×tamp); + /* Temperature data doesn't need to be read with every gyro sample. + * Let's make them timer-based. + */ + if (timestamp > hal.next_temp_ms) { + hal.next_temp_ms = timestamp + TEMP_READ_MS; + new_temp = 1; + } + + + if (hal.new_gyro && hal.dmp_on) { + short gyro[3], accel[3], sensors; + static long quat[4], temperature; + unsigned char more; + /* This function gets new data from the FIFO when the DMP is in + * use. The FIFO can contain any combination of gyro, accel, + * quaternion, and gesture data. The sensors parameter tells the + * caller which data fields were actually populated with new data. + * For example, if sensors == (INV_XYZ_GYRO | INV_WXYZ_QUAT), then + * the FIFO isn't being filled with accel data. + * The driver parses the gesture data to determine if a gesture + * event has occurred; on an event, the application will be notified + * via a callback (assuming that a callback function was properly + * registered). The more parameter is non-zero if there are + * leftover packets in the FIFO. + */ + dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors, &more); + if (!more) + hal.new_gyro = 0; + if (sensors & INV_XYZ_GYRO) { + mpu.gyro.x = gyro[0]; + mpu.gyro.y = gyro[1]; + mpu.gyro.z = gyro[2]; + new_data = 1; + if (new_temp) { + new_temp = 0; + mpu_get_temperature(&temperature, &sensor_timestamp); + mpu.temp = (int16_t)((temperature*100) >> 16); // Convert temperature[q16] to temperature*100[degC] + } + } + if (sensors & INV_XYZ_ACCEL) { + mpu.accel.x = accel[0]; + mpu.accel.y = accel[1]; + mpu.accel.z = accel[2]; + new_data = 1; + } + if (sensors & INV_WXYZ_QUAT) { + mpu.quat.w = quat[0]; + mpu.quat.x = quat[1]; + mpu.quat.y = quat[2]; + mpu.quat.z = quat[3]; + mpu_calc_euler_angles(); // Calculate Euler angles + new_data = 1; + } + } else if (hal.new_gyro) { + short gyro[3], accel[3]; + long temperature; + unsigned char sensors, more; + /* This function gets new data from the FIFO. The FIFO can contain + * gyro, accel, both, or neither. The sensors parameter tells the + * caller which data fields were actually populated with new data. + * For example, if sensors == INV_XYZ_GYRO, then the FIFO isn't + * being filled with accel data. The more parameter is non-zero if + * there are leftover packets in the FIFO. The HAL can use this + * information to increase the frequency at which this function is + * called. + */ + hal.new_gyro = 0; + mpu_read_fifo(gyro, accel, &sensor_timestamp, &sensors, &more); + if (more) + hal.new_gyro = 1; + if (sensors & INV_XYZ_GYRO) { + mpu.gyro.x = gyro[0]; + mpu.gyro.y = gyro[1]; + mpu.gyro.z = gyro[2]; + new_data = 1; + if (new_temp) { + new_temp = 0; + mpu_get_temperature(&temperature, &sensor_timestamp); + mpu.temp = (int16_t)((temperature*100) >> 16); // Convert temperature[q16] to temperature*100[degC] + } + } + if (sensors & INV_XYZ_ACCEL) { + mpu.accel.x = accel[0]; + mpu.accel.y = accel[1]; + mpu.accel.z = accel[2]; + new_data = 1; + } + } + + if (new_data) { + // do something if needed + } + +} + + +/* =========================== MPU-6050 Post-processing Functions =========================== */ + +void mpu_read_gyro_raw(void) +{ + uint8_t buffer[6]; + + // Read 6 BYTES of data starting from GYRO_XOUT_H register (the MPU-6050 automatically increments the register address) + i2c_readBytes(st.hw->addr, st.reg->raw_accel, 6, buffer); + + mpu.gyro.x = (int16_t)(buffer[0] << 8 | buffer[1]); + mpu.gyro.y = (int16_t)(buffer[2] << 8 | buffer[3]); + mpu.gyro.z = (int16_t)(buffer[4] << 8 | buffer[5]); + + /*** convert the RAW hardware units values into dps (�/s) + we have to divide according to the Full scale value set in FS_SEL, + configured to 2000�/s (check MPU_GYRO_FSR). So we need to divide by 16.4 LSB/�/s + for more details check GYRO_CONFIG Register ****/ + //Gx = mpu.gyro.x / 16.4; + //Gy = mpu.gyro.y / 16.4; + //Gz = mpu.gyro.z / 16.4; +} + + +void mpu_read_accel_raw(void) +{ + uint8_t buffer[6]; + + // Read 6 BYTES of data starting from ACCEL_XOUT_H register (the MPU-6050 automatically increments the register address) + i2c_readBytes(st.hw->addr, st.reg->raw_gyro, 6, buffer); + + mpu.accel.x = (int16_t)(buffer[0] << 8 | buffer[1]); + mpu.accel.y = (int16_t)(buffer[2] << 8 | buffer[3]); + mpu.accel.z = (int16_t)(buffer[4] << 8 | buffer[5]); + + + /*** convert the RAW hardware units into acceleration in 'g' + we have to divide according to the Full scale value set in FS_SEL, + configured to 2g (check MPU_ACCEL_FSR). So we need to divide by 16384.0 LSB/g + for more details check ACCEL_CONFIG Register ****/ + //Ax = mpu.accel.x / 16384.0; + //Ay = mpu.accel.y / 16384.0; + //Az = mpu.accel.z / 16384.0; +} + +/* + * Calculate Euler Angles + * aerospace sequence, to obtain sensor attitude: + * 1. roll (x-axis rotation) + * 2. pitch (y-axis rotation) + * 3. yaw (z-axis rotation) + */ +void mpu_calc_euler_angles(void) { + + float w, x, y, z; + float yaw, pitch, roll; + + // Convert quaternions[q30] to quaternion[float] + w = (float)mpu.quat.w / 1073741824; // 1073741824 = 2^30 + x = (float)mpu.quat.x / 1073741824; + y = (float)mpu.quat.y / 1073741824; + z = (float)mpu.quat.z / 1073741824; + + // Calculate Euler angles: source + roll = atan2(2*(w*x + y*z), 1 - 2*(x*x + y*y)); // roll (x-axis rotation) + pitch = asin(2*(w*y - z*x)); // pitch (y-axis rotation) + yaw = atan2(2*(w*z + x*y), 1 - 2*(y*y + z*z)); // yaw (z-axis rotation) + + // Convert [rad] to [deg*100] + mpu.euler.roll = (int16_t)(roll * RAD2DEG * 100); + mpu.euler.pitch = (int16_t)(pitch * RAD2DEG * 100); + mpu.euler.yaw = (int16_t)(yaw * RAD2DEG * 100); + +} + + +void mpu_tap_func(unsigned char direction, unsigned char count) +{ + switch (direction) { + case TAP_X_UP: + consoleLog("Tap X+ "); + break; + case TAP_X_DOWN: + consoleLog("Tap X- "); + break; + case TAP_Y_UP: + consoleLog("Tap Y+ "); + break; + case TAP_Y_DOWN: + consoleLog("Tap Y- "); + break; + case TAP_Z_UP: + consoleLog("Tap Z+ "); + break; + case TAP_Z_DOWN: + consoleLog("Tap Z- "); + break; + default: + return; + } + #ifdef SERIAL_DEBUG + log_i("x %d\n", count); + #endif + return; +} + + +void mpu_android_orient_func(unsigned char orientation) +{ + switch (orientation) { + case ANDROID_ORIENT_PORTRAIT: + consoleLog("Portrait\n"); + break; + case ANDROID_ORIENT_LANDSCAPE: + consoleLog("Landscape\n"); + break; + case ANDROID_ORIENT_REVERSE_PORTRAIT: + consoleLog("Reverse Portrait\n"); + break; + case ANDROID_ORIENT_REVERSE_LANDSCAPE: + consoleLog("Reverse Landscape\n"); + break; + default: + return; + } +} + + +/* =========================== User Input Handling =========================== */ +void mpu_handle_input(char c) +{ + switch (c) { + /* This command prints the Help text. */ + case 'h': + consoleLog("=================== HELP COMMANDS ===================\n"); + consoleLog("h: Print Help commands\n"); + consoleLog("8: Set Accelerometer sensor on/off\n"); + consoleLog("9: Set Gyroscope sensor on/off\n"); + consoleLog("r: Print Registers value\n"); + consoleLog("a: Print Accelerometer data\n"); + consoleLog("g: Print Gyroscope data\n"); + consoleLog("q: Print Quaternion data\n"); + consoleLog("e: Print Euler angles in degree * 100\n"); + consoleLog("t: Print Temperature in degC * 100\n"); + consoleLog("p: Print Pedometer data\n"); + consoleLog("0: Reset Pedometer\n"); + consoleLog("1: Set DMP/MPU frequency 10 Hz\n"); + consoleLog("2: Set DMP/MPU frequency 20 Hz\n"); + consoleLog("3: Set DMP/MPU frequency 40 Hz\n"); + consoleLog("4: Set DMP/MPU frequency 50 Hz\n"); + consoleLog("5: Set DMP/MPU frequency 100 Hz\n"); + consoleLog(",: Set DMP interrupt to gesture event only\n"); + consoleLog(".: Set DMP interrupt to continuous\n"); + consoleLog("f: Set DMP on/off\n"); + consoleLog("v: Set Quaternion on/off\n"); + consoleLog("w: Test out low-power accel mode\n"); + consoleLog("s: Run self-test (device must be facing up or down)\n"); + consoleLog("=====================================================\n"); + break; + + /* These commands turn off individual sensors. */ + case '8': + hal.sensors ^= ACCEL_ON; + mpu_setup_gyro(); + break; + case '9': + hal.sensors ^= GYRO_ON; + mpu_setup_gyro(); + break; + + /* This command prints out the value of each gyro register for debugging. + * If logging is disabled, this function has no effect. + */ + case 'r': + mpu_reg_dump(); + break; + + /* These commands print individual sensor data. */ + case 'a': + hal.report ^= PRINT_ACCEL; + break; + case 'g': + hal.report ^= PRINT_GYRO; + break; + case 'q': + hal.report ^= PRINT_QUAT; + break; + case 'e': + hal.report ^= PRINT_EULER; + break; + case 't': + hal.report ^= PRINT_TEMP; + break; + case 'p': + /* Toggle pedometer display. */ + hal.report ^= PRINT_PEDO; + break; + case '0': + /* Reset pedometer. */ + dmp_set_pedometer_step_count(0); + dmp_set_pedometer_walk_time(0); + consoleLog("Pedometer reset done.\n"); + break; + + /* Depending on your application, sensor data may be needed at a faster or + * slower rate. These commands can speed up or slow down the rate at which + * the sensor data is received. + */ + case '1': + if (hal.dmp_on) { + if (0 == dmp_set_fifo_rate(10)) {consoleLog("DMP set to 10 Hz.\n");} + } else + if (0 == mpu_set_sample_rate(10)) {consoleLog("MPU set to 10 Hz.\n");} + break; + case '2': + if (hal.dmp_on) { + if (0 == dmp_set_fifo_rate(20)) {consoleLog("DMP set to 20 Hz.\n");} + } else + if (0 == mpu_set_sample_rate(20)) {consoleLog("MPU set to 20 Hz.\n");} + break; + case '3': + if (hal.dmp_on) { + if (0 == dmp_set_fifo_rate(40)) {consoleLog("DMP set to 40 Hz.\n");} + } else + if (0 == mpu_set_sample_rate(40)) {consoleLog("MPU set to 40 Hz.\n");} + break; + case '4': + if (hal.dmp_on) { + if (0 == dmp_set_fifo_rate(50)) {consoleLog("DMP set to 50 Hz.\n");} + } else + if (0 == mpu_set_sample_rate(50)) {consoleLog("MPU set to 50 Hz.\n");} + break; + case '5': + if (hal.dmp_on) { + if (0 == dmp_set_fifo_rate(100)) {consoleLog("DMP set to 100 Hz.\n");} + } else + if (0 == mpu_set_sample_rate(100)) {consoleLog("MPU set to 100 Hz.\n");} + break; + + /* Set hardware to interrupt on gesture event only. This feature is + * useful for keeping the MCU asleep until the DMP detects as a tap or + * orientation event. + */ + case ',': + dmp_set_interrupt_mode(DMP_INT_GESTURE); + break; + case '.': + /* Set hardware to interrupt periodically. */ + dmp_set_interrupt_mode(DMP_INT_CONTINUOUS); + break; + + /* Toggle DMP. */ + case 'f': + if (hal.lp_accel_mode) /* LP accel is not compatible with the DMP. */ + return; + if (hal.dmp_on) { + unsigned short dmp_rate; + unsigned char mask = 0; + hal.dmp_on = 0; + mpu_set_dmp_state(0); + /* Restore FIFO settings. */ + if (hal.sensors & ACCEL_ON) + mask |= INV_XYZ_ACCEL; + if (hal.sensors & GYRO_ON) + mask |= INV_XYZ_GYRO; + if (hal.sensors & COMPASS_ON) + mask |= INV_XYZ_COMPASS; + mpu_configure_fifo(mask); + /* When the DMP is used, the hardware sampling rate is fixed at + * 200Hz, and the DMP is configured to downsample the FIFO output + * using the function dmp_set_fifo_rate. However, when the DMP is + * turned off, the sampling rate remains at 200Hz. This could be + * handled in mpu6050.c, but it would need to know that + * mpu6050_dmp.c exists. To avoid this, we'll just + * put the extra logic in the application layer. + */ + dmp_get_fifo_rate(&dmp_rate); + mpu_set_sample_rate(dmp_rate); + consoleLog("DMP disabled.\n"); + } else { + unsigned short sample_rate; + hal.dmp_on = 1; + /* Preserve current FIFO rate. */ + mpu_get_sample_rate(&sample_rate); + dmp_set_fifo_rate(sample_rate); + mpu_set_dmp_state(1); + consoleLog("DMP enabled.\n"); + } + break; + + case 'v': + /* Toggle LP quaternion. + * The DMP features can be enabled/disabled at runtime. Use this same + * approach for other features. + */ + hal.dmp_features ^= DMP_FEATURE_6X_LP_QUAT; + dmp_enable_feature(hal.dmp_features); + if (!(hal.dmp_features & DMP_FEATURE_6X_LP_QUAT)) { + consoleLog("LP quaternion disabled.\n"); + } else + consoleLog("LP quaternion enabled.\n"); + break; + + /* Test out low-power accel mode. */ + case 'w': + if (hal.dmp_on) { + consoleLog("Warning: For low-power mode, DMP needs to be disabled.\n"); + break; /* LP accel is not compatible with the DMP. */ + } + mpu_lp_accel_mode(20); + /* When LP accel mode is enabled, the driver automatically configures + * the hardware for latched interrupts. However, the MCU sometimes + * misses the rising/falling edge, and the hal.new_gyro flag is never + * set. To avoid getting locked in this state, we're overriding the + * driver's configuration and sticking to unlatched interrupt mode. + * + * TODO: The MCU supports level-triggered interrupts. + */ + mpu_set_int_latched(0); + hal.sensors &= ~(GYRO_ON|COMPASS_ON); + hal.sensors |= ACCEL_ON; + hal.lp_accel_mode = 1; + break; + + /* The hardware self test is completely localized in the gyro driver. + * Logging is assumed to be enabled; otherwise, a couple LEDs could + * probably be used here to display the test results. + */ + case 's': + mpu_start_self_test(); + break; + + default: + break; + } + +} + + +void mpu_print_to_console(void) +{ + #ifdef SERIAL_DEBUG + if (hal.report & PRINT_ACCEL) { + log_i( "Accel[XYZ]: \t %d \t %d \t %d \n", mpu.accel.x, mpu.accel.y, mpu.accel.z); + } + if (hal.report & PRINT_GYRO) { + log_i( "Gyro[XYZ]: \t %d \t %d \t %d \n", mpu.gyro.x, mpu.gyro.y, mpu.gyro.z); + } + if (hal.report & PRINT_QUAT) { + log_i( "Quat[WXYZ]: \t %ld \t %ld \t %ld \t %ld \n", (long)mpu.quat.w, (long)mpu.quat.x, (long)mpu.quat.y, (long)mpu.quat.z); + } + if (hal.report & PRINT_EULER) { + log_i( "Euler[RPY]: \t %d \t %d \t %d \n", mpu.euler.roll, mpu.euler.pitch, mpu.euler.yaw); + } + if (hal.report & PRINT_TEMP) { + log_i( "Temperature: %d \n", mpu.temp); + } + if (hal.report & PRINT_PEDO) { + unsigned long timestamp; + get_tick_count_ms(×tamp); + if (timestamp > hal.next_pedo_ms) { + hal.next_pedo_ms = timestamp + PEDO_READ_MS; + unsigned long step_count, walk_time; + dmp_get_pedometer_step_count(&step_count); + dmp_get_pedometer_walk_time(&walk_time); + log_i( "Walked %ld steps in %ld seconds..\n", step_count, walk_time/1000); + } + } + #endif +} + + + diff --git a/Src/mpu6050_dmp.c b/Src/mpu6050_dmp.c new file mode 100644 index 0000000..0001a78 --- /dev/null +++ b/Src/mpu6050_dmp.c @@ -0,0 +1,1337 @@ +/** + * This file was taken from InvenSense MotionApps v6.12 library and + * refactored for the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +// Includes +#include +#include +#include "systick.h" +#include "mpu6050.h" +#include "mpu6050_dmp.h" +#include "mpu6050_dmpKey.h" +#include "mpu6050_dmpmap.h" + + +/* The following functions must be defined for this platform: + * i2c_write(unsigned char slave_addr, unsigned char reg_addr, + * unsigned char length, unsigned char const *data) + * i2c_read(unsigned char slave_addr, unsigned char reg_addr, + * unsigned char length, unsigned char *data) + * delay_ms(unsigned long num_ms) + * get_ms(unsigned long *count) + */ + +/* These defines are copied from dmpDefaultMPU6050.c in the general MPL + * releases. These defines may change for each DMP image, so be sure to modify + * these values when switching to a new image. + */ +#define CFG_LP_QUAT (2712) +#define END_ORIENT_TEMP (1866) +#define CFG_27 (2742) +#define CFG_20 (2224) +#define CFG_23 (2745) +#define CFG_FIFO_ON_EVENT (2690) +#define END_PREDICTION_UPDATE (1761) +#define CGNOTICE_INTR (2620) +#define X_GRT_Y_TMP (1358) +#define CFG_DR_INT (1029) +#define CFG_AUTH (1035) +#define UPDATE_PROP_ROT (1835) +#define END_COMPARE_Y_X_TMP2 (1455) +#define SKIP_X_GRT_Y_TMP (1359) +#define SKIP_END_COMPARE (1435) +#define FCFG_3 (1088) +#define FCFG_2 (1066) +#define FCFG_1 (1062) +#define END_COMPARE_Y_X_TMP3 (1434) +#define FCFG_7 (1073) +#define FCFG_6 (1106) +#define FLAT_STATE_END (1713) +#define SWING_END_4 (1616) +#define SWING_END_2 (1565) +#define SWING_END_3 (1587) +#define SWING_END_1 (1550) +#define CFG_8 (2718) +#define CFG_15 (2727) +#define CFG_16 (2746) +#define CFG_EXT_GYRO_BIAS (1189) +#define END_COMPARE_Y_X_TMP (1407) +#define DO_NOT_UPDATE_PROP_ROT (1839) +#define CFG_7 (1205) +#define FLAT_STATE_END_TEMP (1683) +#define END_COMPARE_Y_X (1484) +#define SKIP_SWING_END_1 (1551) +#define SKIP_SWING_END_3 (1588) +#define SKIP_SWING_END_2 (1566) +#define TILTG75_START (1672) +#define CFG_6 (2753) +#define TILTL75_END (1669) +#define END_ORIENT (1884) +#define CFG_FLICK_IN (2573) +#define TILTL75_START (1643) +#define CFG_MOTION_BIAS (1208) +#define X_GRT_Y (1408) +#define TEMPLABEL (2324) +#define CFG_ANDROID_ORIENT_INT (1853) +#define CFG_GYRO_RAW_DATA (2722) +#define X_GRT_Y_TMP2 (1379) + +#define D_0_22 (22+512) +#define D_0_24 (24+512) + +#define D_0_36 (36) +#define D_0_52 (52) +#define D_0_96 (96) +#define D_0_104 (104) +#define D_0_108 (108) +#define D_0_163 (163) +#define D_0_188 (188) +#define D_0_192 (192) +#define D_0_224 (224) +#define D_0_228 (228) +#define D_0_232 (232) +#define D_0_236 (236) + +#define D_1_2 (256 + 2) +#define D_1_4 (256 + 4) +#define D_1_8 (256 + 8) +#define D_1_10 (256 + 10) +#define D_1_24 (256 + 24) +#define D_1_28 (256 + 28) +#define D_1_36 (256 + 36) +#define D_1_40 (256 + 40) +#define D_1_44 (256 + 44) +#define D_1_72 (256 + 72) +#define D_1_74 (256 + 74) +#define D_1_79 (256 + 79) +#define D_1_88 (256 + 88) +#define D_1_90 (256 + 90) +#define D_1_92 (256 + 92) +#define D_1_96 (256 + 96) +#define D_1_98 (256 + 98) +#define D_1_106 (256 + 106) +#define D_1_108 (256 + 108) +#define D_1_112 (256 + 112) +#define D_1_128 (256 + 144) +#define D_1_152 (256 + 12) +#define D_1_160 (256 + 160) +#define D_1_176 (256 + 176) +#define D_1_178 (256 + 178) +#define D_1_218 (256 + 218) +#define D_1_232 (256 + 232) +#define D_1_236 (256 + 236) +#define D_1_240 (256 + 240) +#define D_1_244 (256 + 244) +#define D_1_250 (256 + 250) +#define D_1_252 (256 + 252) +#define D_2_12 (512 + 12) +#define D_2_96 (512 + 96) +#define D_2_108 (512 + 108) +#define D_2_208 (512 + 208) +#define D_2_224 (512 + 224) +#define D_2_236 (512 + 236) +#define D_2_244 (512 + 244) +#define D_2_248 (512 + 248) +#define D_2_252 (512 + 252) + +#define CPASS_BIAS_X (35 * 16 + 4) +#define CPASS_BIAS_Y (35 * 16 + 8) +#define CPASS_BIAS_Z (35 * 16 + 12) +#define CPASS_MTX_00 (36 * 16) +#define CPASS_MTX_01 (36 * 16 + 4) +#define CPASS_MTX_02 (36 * 16 + 8) +#define CPASS_MTX_10 (36 * 16 + 12) +#define CPASS_MTX_11 (37 * 16) +#define CPASS_MTX_12 (37 * 16 + 4) +#define CPASS_MTX_20 (37 * 16 + 8) +#define CPASS_MTX_21 (37 * 16 + 12) +#define CPASS_MTX_22 (43 * 16 + 12) +#define D_EXT_GYRO_BIAS_X (61 * 16) +#define D_EXT_GYRO_BIAS_Y (61 * 16) + 4 +#define D_EXT_GYRO_BIAS_Z (61 * 16) + 8 +#define D_ACT0 (40 * 16) +#define D_ACSX (40 * 16 + 4) +#define D_ACSY (40 * 16 + 8) +#define D_ACSZ (40 * 16 + 12) + +#define FLICK_MSG (45 * 16 + 4) +#define FLICK_COUNTER (45 * 16 + 8) +#define FLICK_LOWER (45 * 16 + 12) +#define FLICK_UPPER (46 * 16 + 12) + +#define D_AUTH_OUT (992) +#define D_AUTH_IN (996) +#define D_AUTH_A (1000) +#define D_AUTH_B (1004) + +#define D_PEDSTD_BP_B (768 + 0x1C) +#define D_PEDSTD_HP_A (768 + 0x78) +#define D_PEDSTD_HP_B (768 + 0x7C) +#define D_PEDSTD_BP_A4 (768 + 0x40) +#define D_PEDSTD_BP_A3 (768 + 0x44) +#define D_PEDSTD_BP_A2 (768 + 0x48) +#define D_PEDSTD_BP_A1 (768 + 0x4C) +#define D_PEDSTD_INT_THRSH (768 + 0x68) +#define D_PEDSTD_CLIP (768 + 0x6C) +#define D_PEDSTD_SB (768 + 0x28) +#define D_PEDSTD_SB_TIME (768 + 0x2C) +#define D_PEDSTD_PEAKTHRSH (768 + 0x98) +#define D_PEDSTD_TIML (768 + 0x2A) +#define D_PEDSTD_TIMH (768 + 0x2E) +#define D_PEDSTD_PEAK (768 + 0X94) +#define D_PEDSTD_STEPCTR (768 + 0x60) +#define D_PEDSTD_TIMECTR (964) +#define D_PEDSTD_DECI (768 + 0xA0) + +#define D_HOST_NO_MOT (976) +#define D_ACCEL_BIAS (660) + +#define D_ORIENT_GAP (76) + +#define D_TILT0_H (48) +#define D_TILT0_L (50) +#define D_TILT1_H (52) +#define D_TILT1_L (54) +#define D_TILT2_H (56) +#define D_TILT2_L (58) +#define D_TILT3_H (60) +#define D_TILT3_L (62) + +#define DMP_CODE_SIZE (3062) + +static const unsigned char dmp_memory[DMP_CODE_SIZE] = { + /* bank # 0 */ + 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x65, 0x00, 0x54, 0xff, 0xef, 0x00, 0x00, 0xfa, 0x80, 0x00, 0x0b, 0x12, 0x82, 0x00, 0x01, + 0x03, 0x0c, 0x30, 0xc3, 0x0e, 0x8c, 0x8c, 0xe9, 0x14, 0xd5, 0x40, 0x02, 0x13, 0x71, 0x0f, 0x8e, + 0x38, 0x83, 0xf8, 0x83, 0x30, 0x00, 0xf8, 0x83, 0x25, 0x8e, 0xf8, 0x83, 0x30, 0x00, 0xf8, 0x83, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0xfe, 0xa9, 0xd6, 0x24, 0x00, 0x04, 0x00, 0x1a, 0x82, 0x79, 0xa1, + 0x00, 0x00, 0x00, 0x3c, 0xff, 0xff, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x38, 0x83, 0x6f, 0xa2, + 0x00, 0x3e, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xca, 0xe3, 0x09, 0x3e, 0x80, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x6e, 0x00, 0x00, 0x06, 0x92, 0x0a, 0x16, 0xc0, 0xdf, + 0xff, 0xff, 0x02, 0x56, 0xfd, 0x8c, 0xd3, 0x77, 0xff, 0xe1, 0xc4, 0x96, 0xe0, 0xc5, 0xbe, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x2b, 0x00, 0x00, 0x16, 0x57, 0x00, 0x00, 0x03, 0x59, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xfa, 0x00, 0x02, 0x6c, 0x1d, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xff, 0xdf, 0xeb, 0x00, 0x3e, 0xb3, 0xb6, 0x00, 0x0d, 0x22, 0x78, 0x00, 0x00, 0x2f, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x42, 0xb5, 0x00, 0x00, 0x39, 0xa2, 0x00, 0x00, 0xb3, 0x65, + 0xd9, 0x0e, 0x9f, 0xc9, 0x1d, 0xcf, 0x4c, 0x34, 0x30, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x3b, 0xb6, 0x7a, 0xe8, 0x00, 0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank # 1 */ + 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0xfa, 0x92, 0x10, 0x00, 0x22, 0x5e, 0x00, 0x0d, 0x22, 0x9f, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0x63, 0xd4, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x04, 0xd6, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x72, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x64, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x32, 0xf8, 0x98, 0x00, 0x00, 0xff, 0x65, 0x00, 0x00, 0x83, 0x0f, 0x00, 0x00, + 0xff, 0x9b, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xb2, 0x6a, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x01, 0xfb, 0x83, 0x00, 0x68, 0x00, 0x00, 0x00, 0xd9, 0xfc, 0x00, 0x7c, 0xf1, 0xff, 0x83, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x64, 0x03, 0xe8, 0x00, 0x64, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x10, 0x00, + /* bank # 2 */ + 0x00, 0x28, 0x00, 0x00, 0xff, 0xff, 0x45, 0x81, 0xff, 0xff, 0xfa, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x05, 0x00, 0x05, 0xba, 0xc6, 0x00, 0x47, 0x78, 0xa2, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x25, 0x4d, 0x00, 0x2f, 0x70, 0x6d, 0x00, 0x00, 0x05, 0xae, 0x00, 0x0c, 0x02, 0xd0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x64, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, + 0x00, 0x00, 0x0a, 0xc7, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xff, 0xff, 0xff, 0x9c, + 0x00, 0x00, 0x0b, 0x2b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, + 0xff, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank # 3 */ + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x24, 0x26, 0xd3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x96, 0x00, 0x3c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x0a, 0x4e, 0x68, 0xcd, 0xcf, 0x77, 0x09, 0x50, 0x16, 0x67, 0x59, 0xc6, 0x19, 0xce, 0x82, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd7, 0x84, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x93, 0x8f, 0x9d, 0x1e, 0x1b, 0x1c, 0x19, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x18, 0x85, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x67, 0x7d, 0xdf, 0x7e, 0x72, 0x90, 0x2e, 0x55, 0x4c, 0xf6, 0xe6, 0x88, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* bank # 4 */ + 0xd8, 0xdc, 0xb4, 0xb8, 0xb0, 0xd8, 0xb9, 0xab, 0xf3, 0xf8, 0xfa, 0xb3, 0xb7, 0xbb, 0x8e, 0x9e, + 0xae, 0xf1, 0x32, 0xf5, 0x1b, 0xf1, 0xb4, 0xb8, 0xb0, 0x80, 0x97, 0xf1, 0xa9, 0xdf, 0xdf, 0xdf, + 0xaa, 0xdf, 0xdf, 0xdf, 0xf2, 0xaa, 0xc5, 0xcd, 0xc7, 0xa9, 0x0c, 0xc9, 0x2c, 0x97, 0xf1, 0xa9, + 0x89, 0x26, 0x46, 0x66, 0xb2, 0x89, 0x99, 0xa9, 0x2d, 0x55, 0x7d, 0xb0, 0xb0, 0x8a, 0xa8, 0x96, + 0x36, 0x56, 0x76, 0xf1, 0xba, 0xa3, 0xb4, 0xb2, 0x80, 0xc0, 0xb8, 0xa8, 0x97, 0x11, 0xb2, 0x83, + 0x98, 0xba, 0xa3, 0xf0, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xb2, 0xb9, 0xb4, 0x98, 0x83, 0xf1, + 0xa3, 0x29, 0x55, 0x7d, 0xba, 0xb5, 0xb1, 0xa3, 0x83, 0x93, 0xf0, 0x00, 0x28, 0x50, 0xf5, 0xb2, + 0xb6, 0xaa, 0x83, 0x93, 0x28, 0x54, 0x7c, 0xf1, 0xb9, 0xa3, 0x82, 0x93, 0x61, 0xba, 0xa2, 0xda, + 0xde, 0xdf, 0xdb, 0x81, 0x9a, 0xb9, 0xae, 0xf5, 0x60, 0x68, 0x70, 0xf1, 0xda, 0xba, 0xa2, 0xdf, + 0xd9, 0xba, 0xa2, 0xfa, 0xb9, 0xa3, 0x82, 0x92, 0xdb, 0x31, 0xba, 0xa2, 0xd9, 0xba, 0xa2, 0xf8, + 0xdf, 0x85, 0xa4, 0xd0, 0xc1, 0xbb, 0xad, 0x83, 0xc2, 0xc5, 0xc7, 0xb8, 0xa2, 0xdf, 0xdf, 0xdf, + 0xba, 0xa0, 0xdf, 0xdf, 0xdf, 0xd8, 0xd8, 0xf1, 0xb8, 0xaa, 0xb3, 0x8d, 0xb4, 0x98, 0x0d, 0x35, + 0x5d, 0xb2, 0xb6, 0xba, 0xaf, 0x8c, 0x96, 0x19, 0x8f, 0x9f, 0xa7, 0x0e, 0x16, 0x1e, 0xb4, 0x9a, + 0xb8, 0xaa, 0x87, 0x2c, 0x54, 0x7c, 0xba, 0xa4, 0xb0, 0x8a, 0xb6, 0x91, 0x32, 0x56, 0x76, 0xb2, + 0x84, 0x94, 0xa4, 0xc8, 0x08, 0xcd, 0xd8, 0xb8, 0xb4, 0xb0, 0xf1, 0x99, 0x82, 0xa8, 0x2d, 0x55, + 0x7d, 0x98, 0xa8, 0x0e, 0x16, 0x1e, 0xa2, 0x2c, 0x54, 0x7c, 0x92, 0xa4, 0xf0, 0x2c, 0x50, 0x78, + /* bank # 5 */ + 0xf1, 0x84, 0xa8, 0x98, 0xc4, 0xcd, 0xfc, 0xd8, 0x0d, 0xdb, 0xa8, 0xfc, 0x2d, 0xf3, 0xd9, 0xba, + 0xa6, 0xf8, 0xda, 0xba, 0xa6, 0xde, 0xd8, 0xba, 0xb2, 0xb6, 0x86, 0x96, 0xa6, 0xd0, 0xf3, 0xc8, + 0x41, 0xda, 0xa6, 0xc8, 0xf8, 0xd8, 0xb0, 0xb4, 0xb8, 0x82, 0xa8, 0x92, 0xf5, 0x2c, 0x54, 0x88, + 0x98, 0xf1, 0x35, 0xd9, 0xf4, 0x18, 0xd8, 0xf1, 0xa2, 0xd0, 0xf8, 0xf9, 0xa8, 0x84, 0xd9, 0xc7, + 0xdf, 0xf8, 0xf8, 0x83, 0xc5, 0xda, 0xdf, 0x69, 0xdf, 0x83, 0xc1, 0xd8, 0xf4, 0x01, 0x14, 0xf1, + 0xa8, 0x82, 0x4e, 0xa8, 0x84, 0xf3, 0x11, 0xd1, 0x82, 0xf5, 0xd9, 0x92, 0x28, 0x97, 0x88, 0xf1, + 0x09, 0xf4, 0x1c, 0x1c, 0xd8, 0x84, 0xa8, 0xf3, 0xc0, 0xf9, 0xd1, 0xd9, 0x97, 0x82, 0xf1, 0x29, + 0xf4, 0x0d, 0xd8, 0xf3, 0xf9, 0xf9, 0xd1, 0xd9, 0x82, 0xf4, 0xc2, 0x03, 0xd8, 0xde, 0xdf, 0x1a, + 0xd8, 0xf1, 0xa2, 0xfa, 0xf9, 0xa8, 0x84, 0x98, 0xd9, 0xc7, 0xdf, 0xf8, 0xf8, 0xf8, 0x83, 0xc7, + 0xda, 0xdf, 0x69, 0xdf, 0xf8, 0x83, 0xc3, 0xd8, 0xf4, 0x01, 0x14, 0xf1, 0x98, 0xa8, 0x82, 0x2e, + 0xa8, 0x84, 0xf3, 0x11, 0xd1, 0x82, 0xf5, 0xd9, 0x92, 0x50, 0x97, 0x88, 0xf1, 0x09, 0xf4, 0x1c, + 0xd8, 0x84, 0xa8, 0xf3, 0xc0, 0xf8, 0xf9, 0xd1, 0xd9, 0x97, 0x82, 0xf1, 0x49, 0xf4, 0x0d, 0xd8, + 0xf3, 0xf9, 0xf9, 0xd1, 0xd9, 0x82, 0xf4, 0xc4, 0x03, 0xd8, 0xde, 0xdf, 0xd8, 0xf1, 0xad, 0x88, + 0x98, 0xcc, 0xa8, 0x09, 0xf9, 0xd9, 0x82, 0x92, 0xa8, 0xf5, 0x7c, 0xf1, 0x88, 0x3a, 0xcf, 0x94, + 0x4a, 0x6e, 0x98, 0xdb, 0x69, 0x31, 0xda, 0xad, 0xf2, 0xde, 0xf9, 0xd8, 0x87, 0x95, 0xa8, 0xf2, + 0x21, 0xd1, 0xda, 0xa5, 0xf9, 0xf4, 0x17, 0xd9, 0xf1, 0xae, 0x8e, 0xd0, 0xc0, 0xc3, 0xae, 0x82, + /* bank # 6 */ + 0xc6, 0x84, 0xc3, 0xa8, 0x85, 0x95, 0xc8, 0xa5, 0x88, 0xf2, 0xc0, 0xf1, 0xf4, 0x01, 0x0e, 0xf1, + 0x8e, 0x9e, 0xa8, 0xc6, 0x3e, 0x56, 0xf5, 0x54, 0xf1, 0x88, 0x72, 0xf4, 0x01, 0x15, 0xf1, 0x98, + 0x45, 0x85, 0x6e, 0xf5, 0x8e, 0x9e, 0x04, 0x88, 0xf1, 0x42, 0x98, 0x5a, 0x8e, 0x9e, 0x06, 0x88, + 0x69, 0xf4, 0x01, 0x1c, 0xf1, 0x98, 0x1e, 0x11, 0x08, 0xd0, 0xf5, 0x04, 0xf1, 0x1e, 0x97, 0x02, + 0x02, 0x98, 0x36, 0x25, 0xdb, 0xf9, 0xd9, 0x85, 0xa5, 0xf3, 0xc1, 0xda, 0x85, 0xa5, 0xf3, 0xdf, + 0xd8, 0x85, 0x95, 0xa8, 0xf3, 0x09, 0xda, 0xa5, 0xfa, 0xd8, 0x82, 0x92, 0xa8, 0xf5, 0x78, 0xf1, + 0x88, 0x1a, 0x84, 0x9f, 0x26, 0x88, 0x98, 0x21, 0xda, 0xf4, 0x1d, 0xf3, 0xd8, 0x87, 0x9f, 0x39, + 0xd1, 0xaf, 0xd9, 0xdf, 0xdf, 0xfb, 0xf9, 0xf4, 0x0c, 0xf3, 0xd8, 0xfa, 0xd0, 0xf8, 0xda, 0xf9, + 0xf9, 0xd0, 0xdf, 0xd9, 0xf9, 0xd8, 0xf4, 0x0b, 0xd8, 0xf3, 0x87, 0x9f, 0x39, 0xd1, 0xaf, 0xd9, + 0xdf, 0xdf, 0xf4, 0x1d, 0xf3, 0xd8, 0xfa, 0xfc, 0xa8, 0x69, 0xf9, 0xf9, 0xaf, 0xd0, 0xda, 0xde, + 0xfa, 0xd9, 0xf8, 0x8f, 0x9f, 0xa8, 0xf1, 0xcc, 0xf3, 0x98, 0xdb, 0x45, 0xd9, 0xaf, 0xdf, 0xd0, + 0xf8, 0xd8, 0xf1, 0x8f, 0x9f, 0xa8, 0xca, 0xf3, 0x88, 0x09, 0xda, 0xaf, 0x8f, 0xcb, 0xf8, 0xd8, + 0xf2, 0xad, 0x97, 0x8d, 0x0c, 0xd9, 0xa5, 0xdf, 0xf9, 0xba, 0xa6, 0xf3, 0xfa, 0xf4, 0x12, 0xf2, + 0xd8, 0x95, 0x0d, 0xd1, 0xd9, 0xba, 0xa6, 0xf3, 0xfa, 0xda, 0xa5, 0xf2, 0xc1, 0xba, 0xa6, 0xf3, + 0xdf, 0xd8, 0xf1, 0xba, 0xb2, 0xb6, 0x86, 0x96, 0xa6, 0xd0, 0xca, 0xf3, 0x49, 0xda, 0xa6, 0xcb, + 0xf8, 0xd8, 0xb0, 0xb4, 0xb8, 0xd8, 0xad, 0x84, 0xf2, 0xc0, 0xdf, 0xf1, 0x8f, 0xcb, 0xc3, 0xa8, + /* bank # 7 */ + 0xb2, 0xb6, 0x86, 0x96, 0xc8, 0xc1, 0xcb, 0xc3, 0xf3, 0xb0, 0xb4, 0x88, 0x98, 0xa8, 0x21, 0xdb, + 0x71, 0x8d, 0x9d, 0x71, 0x85, 0x95, 0x21, 0xd9, 0xad, 0xf2, 0xfa, 0xd8, 0x85, 0x97, 0xa8, 0x28, + 0xd9, 0xf4, 0x08, 0xd8, 0xf2, 0x8d, 0x29, 0xda, 0xf4, 0x05, 0xd9, 0xf2, 0x85, 0xa4, 0xc2, 0xf2, + 0xd8, 0xa8, 0x8d, 0x94, 0x01, 0xd1, 0xd9, 0xf4, 0x11, 0xf2, 0xd8, 0x87, 0x21, 0xd8, 0xf4, 0x0a, + 0xd8, 0xf2, 0x84, 0x98, 0xa8, 0xc8, 0x01, 0xd1, 0xd9, 0xf4, 0x11, 0xd8, 0xf3, 0xa4, 0xc8, 0xbb, + 0xaf, 0xd0, 0xf2, 0xde, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xd8, 0xf1, 0xb8, 0xf6, + 0xb5, 0xb9, 0xb0, 0x8a, 0x95, 0xa3, 0xde, 0x3c, 0xa3, 0xd9, 0xf8, 0xd8, 0x5c, 0xa3, 0xd9, 0xf8, + 0xd8, 0x7c, 0xa3, 0xd9, 0xf8, 0xd8, 0xf8, 0xf9, 0xd1, 0xa5, 0xd9, 0xdf, 0xda, 0xfa, 0xd8, 0xb1, + 0x85, 0x30, 0xf7, 0xd9, 0xde, 0xd8, 0xf8, 0x30, 0xad, 0xda, 0xde, 0xd8, 0xf2, 0xb4, 0x8c, 0x99, + 0xa3, 0x2d, 0x55, 0x7d, 0xa0, 0x83, 0xdf, 0xdf, 0xdf, 0xb5, 0x91, 0xa0, 0xf6, 0x29, 0xd9, 0xfb, + 0xd8, 0xa0, 0xfc, 0x29, 0xd9, 0xfa, 0xd8, 0xa0, 0xd0, 0x51, 0xd9, 0xf8, 0xd8, 0xfc, 0x51, 0xd9, + 0xf9, 0xd8, 0x79, 0xd9, 0xfb, 0xd8, 0xa0, 0xd0, 0xfc, 0x79, 0xd9, 0xfa, 0xd8, 0xa1, 0xf9, 0xf9, + 0xf9, 0xf9, 0xf9, 0xa0, 0xda, 0xdf, 0xdf, 0xdf, 0xd8, 0xa1, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xac, + 0xde, 0xf8, 0xad, 0xde, 0x83, 0x93, 0xac, 0x2c, 0x54, 0x7c, 0xf1, 0xa8, 0xdf, 0xdf, 0xdf, 0xf6, + 0x9d, 0x2c, 0xda, 0xa0, 0xdf, 0xd9, 0xfa, 0xdb, 0x2d, 0xf8, 0xd8, 0xa8, 0x50, 0xda, 0xa0, 0xd0, + 0xde, 0xd9, 0xd0, 0xf8, 0xf8, 0xf8, 0xdb, 0x55, 0xf8, 0xd8, 0xa8, 0x78, 0xda, 0xa0, 0xd0, 0xdf, + /* bank # 8 */ + 0xd9, 0xd0, 0xfa, 0xf8, 0xf8, 0xf8, 0xf8, 0xdb, 0x7d, 0xf8, 0xd8, 0x9c, 0xa8, 0x8c, 0xf5, 0x30, + 0xdb, 0x38, 0xd9, 0xd0, 0xde, 0xdf, 0xa0, 0xd0, 0xde, 0xdf, 0xd8, 0xa8, 0x48, 0xdb, 0x58, 0xd9, + 0xdf, 0xd0, 0xde, 0xa0, 0xdf, 0xd0, 0xde, 0xd8, 0xa8, 0x68, 0xdb, 0x70, 0xd9, 0xdf, 0xdf, 0xa0, + 0xdf, 0xdf, 0xd8, 0xf1, 0xa8, 0x88, 0x90, 0x2c, 0x54, 0x7c, 0x98, 0xa8, 0xd0, 0x5c, 0x38, 0xd1, + 0xda, 0xf2, 0xae, 0x8c, 0xdf, 0xf9, 0xd8, 0xb0, 0x87, 0xa8, 0xc1, 0xc1, 0xb1, 0x88, 0xa8, 0xc6, + 0xf9, 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xa8, + 0xf9, 0xda, 0x36, 0xd8, 0xa8, 0xf9, 0xda, 0x36, 0xd8, 0xf7, 0x8d, 0x9d, 0xad, 0xf8, 0x18, 0xda, + 0xf2, 0xae, 0xdf, 0xd8, 0xf7, 0xad, 0xfa, 0x30, 0xd9, 0xa4, 0xde, 0xf9, 0xd8, 0xf2, 0xae, 0xde, + 0xfa, 0xf9, 0x83, 0xa7, 0xd9, 0xc3, 0xc5, 0xc7, 0xf1, 0x88, 0x9b, 0xa7, 0x7a, 0xad, 0xf7, 0xde, + 0xdf, 0xa4, 0xf8, 0x84, 0x94, 0x08, 0xa7, 0x97, 0xf3, 0x00, 0xae, 0xf2, 0x98, 0x19, 0xa4, 0x88, + 0xc6, 0xa3, 0x94, 0x88, 0xf6, 0x32, 0xdf, 0xf2, 0x83, 0x93, 0xdb, 0x09, 0xd9, 0xf2, 0xaa, 0xdf, + 0xd8, 0xd8, 0xae, 0xf8, 0xf9, 0xd1, 0xda, 0xf3, 0xa4, 0xde, 0xa7, 0xf1, 0x88, 0x9b, 0x7a, 0xd8, + 0xf3, 0x84, 0x94, 0xae, 0x19, 0xf9, 0xda, 0xaa, 0xf1, 0xdf, 0xd8, 0xa8, 0x81, 0xc0, 0xc3, 0xc5, + 0xc7, 0xa3, 0x92, 0x83, 0xf6, 0x28, 0xad, 0xde, 0xd9, 0xf8, 0xd8, 0xa3, 0x50, 0xad, 0xd9, 0xf8, + 0xd8, 0xa3, 0x78, 0xad, 0xd9, 0xf8, 0xd8, 0xf8, 0xf9, 0xd1, 0xa1, 0xda, 0xde, 0xc3, 0xc5, 0xc7, + 0xd8, 0xa1, 0x81, 0x94, 0xf8, 0x18, 0xf2, 0xb0, 0x89, 0xac, 0xc3, 0xc5, 0xc7, 0xf1, 0xd8, 0xb8, + /* bank # 9 */ + 0xb4, 0xb0, 0x97, 0x86, 0xa8, 0x31, 0x9b, 0x06, 0x99, 0x07, 0xab, 0x97, 0x28, 0x88, 0x9b, 0xf0, + 0x0c, 0x20, 0x14, 0x40, 0xb0, 0xb4, 0xb8, 0xf0, 0xa8, 0x8a, 0x9a, 0x28, 0x50, 0x78, 0xb7, 0x9b, + 0xa8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xf1, 0xbb, 0xab, + 0x88, 0x00, 0x2c, 0x54, 0x7c, 0xf0, 0xb3, 0x8b, 0xb8, 0xa8, 0x04, 0x28, 0x50, 0x78, 0xf1, 0xb0, + 0x88, 0xb4, 0x97, 0x26, 0xa8, 0x59, 0x98, 0xbb, 0xab, 0xb3, 0x8b, 0x02, 0x26, 0x46, 0x66, 0xb0, + 0xb8, 0xf0, 0x8a, 0x9c, 0xa8, 0x29, 0x51, 0x79, 0x8b, 0x29, 0x51, 0x79, 0x8a, 0x24, 0x70, 0x59, + 0x8b, 0x20, 0x58, 0x71, 0x8a, 0x44, 0x69, 0x38, 0x8b, 0x39, 0x40, 0x68, 0x8a, 0x64, 0x48, 0x31, + 0x8b, 0x30, 0x49, 0x60, 0x88, 0xf1, 0xac, 0x00, 0x2c, 0x54, 0x7c, 0xf0, 0x8c, 0xa8, 0x04, 0x28, + 0x50, 0x78, 0xf1, 0x88, 0x97, 0x26, 0xa8, 0x59, 0x98, 0xac, 0x8c, 0x02, 0x26, 0x46, 0x66, 0xf0, + 0x89, 0x9c, 0xa8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xa9, + 0x88, 0x09, 0x20, 0x59, 0x70, 0xab, 0x11, 0x38, 0x40, 0x69, 0xa8, 0x19, 0x31, 0x48, 0x60, 0x8c, + 0xa8, 0x3c, 0x41, 0x5c, 0x20, 0x7c, 0x00, 0xf1, 0x87, 0x98, 0x19, 0x86, 0xa8, 0x6e, 0x76, 0x7e, + 0xa9, 0x99, 0x88, 0x2d, 0x55, 0x7d, 0xd8, 0xb1, 0xb5, 0xb9, 0xa3, 0xdf, 0xdf, 0xdf, 0xae, 0xd0, + 0xdf, 0xaa, 0xd0, 0xde, 0xf2, 0xab, 0xf8, 0xf9, 0xd9, 0xb0, 0x87, 0xc4, 0xaa, 0xf1, 0xdf, 0xdf, + 0xbb, 0xaf, 0xdf, 0xdf, 0xb9, 0xd8, 0xb1, 0xf1, 0xa3, 0x97, 0x8e, 0x60, 0xdf, 0xb0, 0x84, 0xf2, + 0xc8, 0xf8, 0xf9, 0xd9, 0xde, 0xd8, 0x93, 0x85, 0xf1, 0x4a, 0xb1, 0x83, 0xa3, 0x08, 0xb5, 0x83, + /* bank # 10 */ + 0x9a, 0x08, 0x10, 0xb7, 0x9f, 0x10, 0xd8, 0xf1, 0xb0, 0xba, 0xae, 0xb0, 0x8a, 0xc2, 0xb2, 0xb6, + 0x8e, 0x9e, 0xf1, 0xfb, 0xd9, 0xf4, 0x1d, 0xd8, 0xf9, 0xd9, 0x0c, 0xf1, 0xd8, 0xf8, 0xf8, 0xad, + 0x61, 0xd9, 0xae, 0xfb, 0xd8, 0xf4, 0x0c, 0xf1, 0xd8, 0xf8, 0xf8, 0xad, 0x19, 0xd9, 0xae, 0xfb, + 0xdf, 0xd8, 0xf4, 0x16, 0xf1, 0xd8, 0xf8, 0xad, 0x8d, 0x61, 0xd9, 0xf4, 0xf4, 0xac, 0xf5, 0x9c, + 0x9c, 0x8d, 0xdf, 0x2b, 0xba, 0xb6, 0xae, 0xfa, 0xf8, 0xf4, 0x0b, 0xd8, 0xf1, 0xae, 0xd0, 0xf8, + 0xad, 0x51, 0xda, 0xae, 0xfa, 0xf8, 0xf1, 0xd8, 0xb9, 0xb1, 0xb6, 0xa3, 0x83, 0x9c, 0x08, 0xb9, + 0xb1, 0x83, 0x9a, 0xb5, 0xaa, 0xc0, 0xfd, 0x30, 0x83, 0xb7, 0x9f, 0x10, 0xb5, 0x8b, 0x93, 0xf2, + 0x02, 0x02, 0xd1, 0xab, 0xda, 0xde, 0xd8, 0xf1, 0xb0, 0x80, 0xba, 0xab, 0xc0, 0xc3, 0xb2, 0x84, + 0xc1, 0xc3, 0xd8, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0x09, 0xb4, 0xd9, 0xab, 0xde, 0xb0, + 0x87, 0x9c, 0xb9, 0xa3, 0xdd, 0xf1, 0xb3, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0xb0, 0x87, 0xa3, 0xa3, + 0xa3, 0xa3, 0xb2, 0x8b, 0xb6, 0x9b, 0xf2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xf1, 0xb0, 0x87, 0xb5, 0x9a, 0xa3, 0xf3, 0x9b, 0xa3, 0xa3, 0xdc, 0xba, 0xac, 0xdf, 0xb9, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xd8, 0xd8, 0xd8, 0xbb, 0xb3, 0xb7, 0xf1, 0xaa, 0xf9, 0xda, 0xff, 0xd9, 0x80, 0x9a, 0xaa, 0x28, + 0xb4, 0x80, 0x98, 0xa7, 0x20, 0xb7, 0x97, 0x87, 0xa8, 0x66, 0x88, 0xf0, 0x79, 0x51, 0xf1, 0x90, + 0x2c, 0x87, 0x0c, 0xa7, 0x81, 0x97, 0x62, 0x93, 0xf0, 0x71, 0x71, 0x60, 0x85, 0x94, 0x01, 0x29, + /* bank # 11 */ + 0x51, 0x79, 0x90, 0xa5, 0xf1, 0x28, 0x4c, 0x6c, 0x87, 0x0c, 0x95, 0x18, 0x85, 0x78, 0xa3, 0x83, + 0x90, 0x28, 0x4c, 0x6c, 0x88, 0x6c, 0xd8, 0xf3, 0xa2, 0x82, 0x00, 0xf2, 0x10, 0xa8, 0x92, 0x19, + 0x80, 0xa2, 0xf2, 0xd9, 0x26, 0xd8, 0xf1, 0x88, 0xa8, 0x4d, 0xd9, 0x48, 0xd8, 0x96, 0xa8, 0x39, + 0x80, 0xd9, 0x3c, 0xd8, 0x95, 0x80, 0xa8, 0x39, 0xa6, 0x86, 0x98, 0xd9, 0x2c, 0xda, 0x87, 0xa7, + 0x2c, 0xd8, 0xa8, 0x89, 0x95, 0x19, 0xa9, 0x80, 0xd9, 0x38, 0xd8, 0xa8, 0x89, 0x39, 0xa9, 0x80, + 0xda, 0x3c, 0xd8, 0xa8, 0x2e, 0xa8, 0x39, 0x90, 0xd9, 0x0c, 0xd8, 0xa8, 0x95, 0x31, 0x98, 0xd9, + 0x0c, 0xd8, 0xa8, 0x09, 0xd9, 0xff, 0xd8, 0x01, 0xda, 0xff, 0xd8, 0x95, 0x39, 0xa9, 0xda, 0x26, + 0xff, 0xd8, 0x90, 0xa8, 0x0d, 0x89, 0x99, 0xa8, 0x10, 0x80, 0x98, 0x21, 0xda, 0x2e, 0xd8, 0x89, + 0x99, 0xa8, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, 0x86, 0x96, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, + 0x87, 0x31, 0x80, 0xda, 0x2e, 0xd8, 0xa8, 0x82, 0x92, 0xf3, 0x41, 0x80, 0xf1, 0xd9, 0x2e, 0xd8, + 0xa8, 0x82, 0xf3, 0x19, 0x80, 0xf1, 0xd9, 0x2e, 0xd8, 0x82, 0xac, 0xf3, 0xc0, 0xa2, 0x80, 0x22, + 0xf1, 0xa6, 0x2e, 0xa7, 0x2e, 0xa9, 0x22, 0x98, 0xa8, 0x29, 0xda, 0xac, 0xde, 0xff, 0xd8, 0xa2, + 0xf2, 0x2a, 0xf1, 0xa9, 0x2e, 0x82, 0x92, 0xa8, 0xf2, 0x31, 0x80, 0xa6, 0x96, 0xf1, 0xd9, 0x00, + 0xac, 0x8c, 0x9c, 0x0c, 0x30, 0xac, 0xde, 0xd0, 0xde, 0xff, 0xd8, 0x8c, 0x9c, 0xac, 0xd0, 0x10, + 0xac, 0xde, 0x80, 0x92, 0xa2, 0xf2, 0x4c, 0x82, 0xa8, 0xf1, 0xca, 0xf2, 0x35, 0xf1, 0x96, 0x88, + 0xa6, 0xd9, 0x00, 0xd8, 0xf1, 0xff +}; + +static const unsigned short sStartAddress = 0x0400; + +/* END OF SECTION COPIED FROM dmpDefaultMPU6050.c */ + +#define INT_SRC_TAP (0x01) +#define INT_SRC_ANDROID_ORIENT (0x08) + +#define DMP_FEATURE_SEND_ANY_GYRO (DMP_FEATURE_SEND_RAW_GYRO | \ + DMP_FEATURE_SEND_CAL_GYRO) + +#define MAX_PACKET_LENGTH (32) + +#define DMP_SAMPLE_RATE (200) +#define GYRO_SF (46850825LL * 200 / DMP_SAMPLE_RATE) + +#define FIFO_CORRUPTION_CHECK +#ifdef FIFO_CORRUPTION_CHECK +#define QUAT_ERROR_THRESH (1L<<24) +#define QUAT_MAG_SQ_NORMALIZED (1L<<28) +#define QUAT_MAG_SQ_MIN (QUAT_MAG_SQ_NORMALIZED - QUAT_ERROR_THRESH) +#define QUAT_MAG_SQ_MAX (QUAT_MAG_SQ_NORMALIZED + QUAT_ERROR_THRESH) +#endif + +struct dmp_s { + void (*tap_cb)(unsigned char count, unsigned char direction); + void (*android_orient_cb)(unsigned char orientation); + unsigned short orient; + unsigned short feature_mask; + unsigned short fifo_rate; + unsigned char packet_length; +}; + +static struct dmp_s dmp = { + .tap_cb = NULL, + .android_orient_cb = NULL, + .orient = 0, + .feature_mask = 0, + .fifo_rate = 0, + .packet_length = 0 +}; + +/** + * @brief Load the DMP with this image. + * @return 0 if successful. + */ +int dmp_load_motion_driver_firmware(void) +{ + return mpu_load_firmware(DMP_CODE_SIZE, dmp_memory, sStartAddress, + DMP_SAMPLE_RATE); +} + +/** + * @brief Push gyro and accel orientation to the DMP. + * The orientation is represented here as the output of + * @e inv_orientation_matrix_to_scalar. + * @param[in] orient Gyro and accel orientation in body frame. + * @return 0 if successful. + */ +int dmp_set_orientation(unsigned short orient) +{ + unsigned char gyro_regs[3], accel_regs[3]; + const unsigned char gyro_axes[3] = {DINA4C, DINACD, DINA6C}; + const unsigned char accel_axes[3] = {DINA0C, DINAC9, DINA2C}; + const unsigned char gyro_sign[3] = {DINA36, DINA56, DINA76}; + const unsigned char accel_sign[3] = {DINA26, DINA46, DINA66}; + + gyro_regs[0] = gyro_axes[orient & 3]; + gyro_regs[1] = gyro_axes[(orient >> 3) & 3]; + gyro_regs[2] = gyro_axes[(orient >> 6) & 3]; + accel_regs[0] = accel_axes[orient & 3]; + accel_regs[1] = accel_axes[(orient >> 3) & 3]; + accel_regs[2] = accel_axes[(orient >> 6) & 3]; + + /* Chip-to-body, axes only. */ + if (mpu_write_mem(FCFG_1, 3, gyro_regs)) + return -1; + if (mpu_write_mem(FCFG_2, 3, accel_regs)) + return -1; + + memcpy(gyro_regs, gyro_sign, 3); + memcpy(accel_regs, accel_sign, 3); + if (orient & 4) { + gyro_regs[0] |= 1; + accel_regs[0] |= 1; + } + if (orient & 0x20) { + gyro_regs[1] |= 1; + accel_regs[1] |= 1; + } + if (orient & 0x100) { + gyro_regs[2] |= 1; + accel_regs[2] |= 1; + } + + /* Chip-to-body, sign only. */ + if (mpu_write_mem(FCFG_3, 3, gyro_regs)) + return -1; + if (mpu_write_mem(FCFG_7, 3, accel_regs)) + return -1; + dmp.orient = orient; + return 0; +} + +/** + * @brief Push gyro biases to the DMP. + * Because the gyro integration is handled in the DMP, any gyro biases + * calculated by the MPL should be pushed down to DMP memory to remove + * 3-axis quaternion drift. + * \n NOTE: If the DMP-based gyro calibration is enabled, the DMP will + * overwrite the biases written to this location once a new one is computed. + * @param[in] bias Gyro biases in q16. + * @return 0 if successful. + */ +int dmp_set_gyro_bias(long *bias) +{ + long gyro_bias_body[3]; + unsigned char regs[4]; + + gyro_bias_body[0] = bias[dmp.orient & 3]; + if (dmp.orient & 4) + gyro_bias_body[0] *= -1; + gyro_bias_body[1] = bias[(dmp.orient >> 3) & 3]; + if (dmp.orient & 0x20) + gyro_bias_body[1] *= -1; + gyro_bias_body[2] = bias[(dmp.orient >> 6) & 3]; + if (dmp.orient & 0x100) + gyro_bias_body[2] *= -1; + +#ifdef EMPL_NO_64BIT + gyro_bias_body[0] = (long)(((float)gyro_bias_body[0] * GYRO_SF) / 1073741824.f); + gyro_bias_body[1] = (long)(((float)gyro_bias_body[1] * GYRO_SF) / 1073741824.f); + gyro_bias_body[2] = (long)(((float)gyro_bias_body[2] * GYRO_SF) / 1073741824.f); +#else + gyro_bias_body[0] = (long)(((long long)gyro_bias_body[0] * GYRO_SF) >> 30); + gyro_bias_body[1] = (long)(((long long)gyro_bias_body[1] * GYRO_SF) >> 30); + gyro_bias_body[2] = (long)(((long long)gyro_bias_body[2] * GYRO_SF) >> 30); +#endif + + regs[0] = (unsigned char)((gyro_bias_body[0] >> 24) & 0xFF); + regs[1] = (unsigned char)((gyro_bias_body[0] >> 16) & 0xFF); + regs[2] = (unsigned char)((gyro_bias_body[0] >> 8) & 0xFF); + regs[3] = (unsigned char)(gyro_bias_body[0] & 0xFF); + if (mpu_write_mem(D_EXT_GYRO_BIAS_X, 4, regs)) + return -1; + + regs[0] = (unsigned char)((gyro_bias_body[1] >> 24) & 0xFF); + regs[1] = (unsigned char)((gyro_bias_body[1] >> 16) & 0xFF); + regs[2] = (unsigned char)((gyro_bias_body[1] >> 8) & 0xFF); + regs[3] = (unsigned char)(gyro_bias_body[1] & 0xFF); + if (mpu_write_mem(D_EXT_GYRO_BIAS_Y, 4, regs)) + return -1; + + regs[0] = (unsigned char)((gyro_bias_body[2] >> 24) & 0xFF); + regs[1] = (unsigned char)((gyro_bias_body[2] >> 16) & 0xFF); + regs[2] = (unsigned char)((gyro_bias_body[2] >> 8) & 0xFF); + regs[3] = (unsigned char)(gyro_bias_body[2] & 0xFF); + return mpu_write_mem(D_EXT_GYRO_BIAS_Z, 4, regs); +} + +/** + * @brief Push accel biases to the DMP. + * These biases will be removed from the DMP 6-axis quaternion. + * @param[in] bias Accel biases in q16. + * @return 0 if successful. + */ +int dmp_set_accel_bias(long *bias) +{ + long accel_bias_body[3]; + unsigned char regs[12]; + long long accel_sf; + unsigned short accel_sens; + + mpu_get_accel_sens(&accel_sens); + accel_sf = (long long)accel_sens << 15; + // __no_operation(); + + accel_bias_body[0] = bias[dmp.orient & 3]; + if (dmp.orient & 4) + accel_bias_body[0] *= -1; + accel_bias_body[1] = bias[(dmp.orient >> 3) & 3]; + if (dmp.orient & 0x20) + accel_bias_body[1] *= -1; + accel_bias_body[2] = bias[(dmp.orient >> 6) & 3]; + if (dmp.orient & 0x100) + accel_bias_body[2] *= -1; + +#ifdef EMPL_NO_64BIT + accel_bias_body[0] = (long)(((float)accel_bias_body[0] * accel_sf) / 1073741824.f); + accel_bias_body[1] = (long)(((float)accel_bias_body[1] * accel_sf) / 1073741824.f); + accel_bias_body[2] = (long)(((float)accel_bias_body[2] * accel_sf) / 1073741824.f); +#else + accel_bias_body[0] = (long)(((long long)accel_bias_body[0] * accel_sf) >> 30); + accel_bias_body[1] = (long)(((long long)accel_bias_body[1] * accel_sf) >> 30); + accel_bias_body[2] = (long)(((long long)accel_bias_body[2] * accel_sf) >> 30); +#endif + + regs[0] = (unsigned char)((accel_bias_body[0] >> 24) & 0xFF); + regs[1] = (unsigned char)((accel_bias_body[0] >> 16) & 0xFF); + regs[2] = (unsigned char)((accel_bias_body[0] >> 8) & 0xFF); + regs[3] = (unsigned char)(accel_bias_body[0] & 0xFF); + regs[4] = (unsigned char)((accel_bias_body[1] >> 24) & 0xFF); + regs[5] = (unsigned char)((accel_bias_body[1] >> 16) & 0xFF); + regs[6] = (unsigned char)((accel_bias_body[1] >> 8) & 0xFF); + regs[7] = (unsigned char)(accel_bias_body[1] & 0xFF); + regs[8] = (unsigned char)((accel_bias_body[2] >> 24) & 0xFF); + regs[9] = (unsigned char)((accel_bias_body[2] >> 16) & 0xFF); + regs[10] = (unsigned char)((accel_bias_body[2] >> 8) & 0xFF); + regs[11] = (unsigned char)(accel_bias_body[2] & 0xFF); + return mpu_write_mem(D_ACCEL_BIAS, 12, regs); +} + +/** + * @brief Set DMP output rate. + * Only used when DMP is on. + * @param[in] rate Desired fifo rate (Hz). + * @return 0 if successful. + */ +int dmp_set_fifo_rate(unsigned short rate) +{ + const unsigned char regs_end[12] = {DINAFE, DINAF2, DINAAB, + 0xc4, DINAAA, DINAF1, DINADF, DINADF, 0xBB, 0xAF, DINADF, DINADF}; + unsigned short div; + unsigned char tmp[8]; + + if (rate > DMP_SAMPLE_RATE) + return -1; + div = DMP_SAMPLE_RATE / rate - 1; + tmp[0] = (unsigned char)((div >> 8) & 0xFF); + tmp[1] = (unsigned char)(div & 0xFF); + if (mpu_write_mem(D_0_22, 2, tmp)) + return -1; + if (mpu_write_mem(CFG_6, 12, (unsigned char*)regs_end)) + return -1; + + dmp.fifo_rate = rate; + return 0; +} + +/** + * @brief Get DMP output rate. + * @param[out] rate Current fifo rate (Hz). + * @return 0 if successful. + */ +int dmp_get_fifo_rate(unsigned short *rate) +{ + rate[0] = dmp.fifo_rate; + return 0; +} + +/** + * @brief Set tap threshold for a specific axis. + * @param[in] axis 1, 2, and 4 for XYZ accel, respectively. + * @param[in] thresh Tap threshold, in mg/ms. + * @return 0 if successful. + */ +int dmp_set_tap_thresh(unsigned char axis, unsigned short thresh) +{ + unsigned char tmp[4], accel_fsr; + float scaled_thresh; + unsigned short dmp_thresh, dmp_thresh_2; + if (!(axis & TAP_XYZ) || thresh > 1600) + return -1; + + scaled_thresh = (float)thresh / DMP_SAMPLE_RATE; + + mpu_get_accel_fsr(&accel_fsr); + switch (accel_fsr) { + case 2: + dmp_thresh = (unsigned short)(scaled_thresh * 16384); + /* dmp_thresh * 0.75 */ + dmp_thresh_2 = (unsigned short)(scaled_thresh * 12288); + break; + case 4: + dmp_thresh = (unsigned short)(scaled_thresh * 8192); + /* dmp_thresh * 0.75 */ + dmp_thresh_2 = (unsigned short)(scaled_thresh * 6144); + break; + case 8: + dmp_thresh = (unsigned short)(scaled_thresh * 4096); + /* dmp_thresh * 0.75 */ + dmp_thresh_2 = (unsigned short)(scaled_thresh * 3072); + break; + case 16: + dmp_thresh = (unsigned short)(scaled_thresh * 2048); + /* dmp_thresh * 0.75 */ + dmp_thresh_2 = (unsigned short)(scaled_thresh * 1536); + break; + default: + return -1; + } + tmp[0] = (unsigned char)(dmp_thresh >> 8); + tmp[1] = (unsigned char)(dmp_thresh & 0xFF); + tmp[2] = (unsigned char)(dmp_thresh_2 >> 8); + tmp[3] = (unsigned char)(dmp_thresh_2 & 0xFF); + + if (axis & TAP_X) { + if (mpu_write_mem(DMP_TAP_THX, 2, tmp)) + return -1; + if (mpu_write_mem(D_1_36, 2, tmp+2)) + return -1; + } + if (axis & TAP_Y) { + if (mpu_write_mem(DMP_TAP_THY, 2, tmp)) + return -1; + if (mpu_write_mem(D_1_40, 2, tmp+2)) + return -1; + } + if (axis & TAP_Z) { + if (mpu_write_mem(DMP_TAP_THZ, 2, tmp)) + return -1; + if (mpu_write_mem(D_1_44, 2, tmp+2)) + return -1; + } + return 0; +} + +/** + * @brief Set which axes will register a tap. + * @param[in] axis 1, 2, and 4 for XYZ, respectively. + * @return 0 if successful. + */ +int dmp_set_tap_axes(unsigned char axis) +{ + unsigned char tmp = 0; + + if (axis & TAP_X) + tmp |= 0x30; + if (axis & TAP_Y) + tmp |= 0x0C; + if (axis & TAP_Z) + tmp |= 0x03; + return mpu_write_mem(D_1_72, 1, &tmp); +} + +/** + * @brief Set minimum number of taps needed for an interrupt. + * @param[in] min_taps Minimum consecutive taps (1-4). + * @return 0 if successful. + */ +int dmp_set_tap_count(unsigned char min_taps) +{ + unsigned char tmp; + + if (min_taps < 1) + min_taps = 1; + else if (min_taps > 4) + min_taps = 4; + + tmp = min_taps - 1; + return mpu_write_mem(D_1_79, 1, &tmp); +} + +/** + * @brief Set length between valid taps. + * @param[in] time Milliseconds between taps. + * @return 0 if successful. + */ +int dmp_set_tap_time(unsigned short time) +{ + unsigned short dmp_time; + unsigned char tmp[2]; + + dmp_time = time / (1000 / DMP_SAMPLE_RATE); + tmp[0] = (unsigned char)(dmp_time >> 8); + tmp[1] = (unsigned char)(dmp_time & 0xFF); + return mpu_write_mem(DMP_TAPW_MIN, 2, tmp); +} + +/** + * @brief Set max time between taps to register as a multi-tap. + * @param[in] time Max milliseconds between taps. + * @return 0 if successful. + */ +int dmp_set_tap_time_multi(unsigned short time) +{ + unsigned short dmp_time; + unsigned char tmp[2]; + + dmp_time = time / (1000 / DMP_SAMPLE_RATE); + tmp[0] = (unsigned char)(dmp_time >> 8); + tmp[1] = (unsigned char)(dmp_time & 0xFF); + return mpu_write_mem(D_1_218, 2, tmp); +} + +/** + * @brief Set shake rejection threshold. + * If the DMP detects a gyro sample larger than @e thresh, taps are rejected. + * @param[in] sf Gyro scale factor. + * @param[in] thresh Gyro threshold in dps. + * @return 0 if successful. + */ +int dmp_set_shake_reject_thresh(long sf, unsigned short thresh) +{ + unsigned char tmp[4]; + long thresh_scaled = sf / 1000 * thresh; + tmp[0] = (unsigned char)(((long)thresh_scaled >> 24) & 0xFF); + tmp[1] = (unsigned char)(((long)thresh_scaled >> 16) & 0xFF); + tmp[2] = (unsigned char)(((long)thresh_scaled >> 8) & 0xFF); + tmp[3] = (unsigned char)((long)thresh_scaled & 0xFF); + return mpu_write_mem(D_1_92, 4, tmp); +} + +/** + * @brief Set shake rejection time. + * Sets the length of time that the gyro must be outside of the threshold set + * by @e gyro_set_shake_reject_thresh before taps are rejected. A mandatory + * 60 ms is added to this parameter. + * @param[in] time Time in milliseconds. + * @return 0 if successful. + */ +int dmp_set_shake_reject_time(unsigned short time) +{ + unsigned char tmp[2]; + + time /= (1000 / DMP_SAMPLE_RATE); + tmp[0] = time >> 8; + tmp[1] = time & 0xFF; + return mpu_write_mem(D_1_90,2,tmp); +} + +/** + * @brief Set shake rejection timeout. + * Sets the length of time after a shake rejection that the gyro must stay + * inside of the threshold before taps can be detected again. A mandatory + * 60 ms is added to this parameter. + * @param[in] time Time in milliseconds. + * @return 0 if successful. + */ +int dmp_set_shake_reject_timeout(unsigned short time) +{ + unsigned char tmp[2]; + + time /= (1000 / DMP_SAMPLE_RATE); + tmp[0] = time >> 8; + tmp[1] = time & 0xFF; + return mpu_write_mem(D_1_88,2,tmp); +} + +/** + * @brief Get current step count. + * @param[out] count Number of steps detected. + * @return 0 if successful. + */ +int dmp_get_pedometer_step_count(unsigned long *count) +{ + unsigned char tmp[4]; + if (!count) + return -1; + + if (mpu_read_mem(D_PEDSTD_STEPCTR, 4, tmp)) + return -1; + + count[0] = ((unsigned long)tmp[0] << 24) | ((unsigned long)tmp[1] << 16) | + ((unsigned long)tmp[2] << 8) | tmp[3]; + return 0; +} + +/** + * @brief Overwrite current step count. + * WARNING: This function writes to DMP memory and could potentially encounter + * a race condition if called while the pedometer is enabled. + * @param[in] count New step count. + * @return 0 if successful. + */ +int dmp_set_pedometer_step_count(unsigned long count) +{ + unsigned char tmp[4]; + + tmp[0] = (unsigned char)((count >> 24) & 0xFF); + tmp[1] = (unsigned char)((count >> 16) & 0xFF); + tmp[2] = (unsigned char)((count >> 8) & 0xFF); + tmp[3] = (unsigned char)(count & 0xFF); + return mpu_write_mem(D_PEDSTD_STEPCTR, 4, tmp); +} + +/** + * @brief Get duration of walking time. + * @param[in] time Walk time in milliseconds. + * @return 0 if successful. + */ +int dmp_get_pedometer_walk_time(unsigned long *time) +{ + unsigned char tmp[4]; + if (!time) + return -1; + + if (mpu_read_mem(D_PEDSTD_TIMECTR, 4, tmp)) + return -1; + + time[0] = (((unsigned long)tmp[0] << 24) | ((unsigned long)tmp[1] << 16) | + ((unsigned long)tmp[2] << 8) | tmp[3]) * 20; + return 0; +} + +/** + * @brief Overwrite current walk time. + * WARNING: This function writes to DMP memory and could potentially encounter + * a race condition if called while the pedometer is enabled. + * @param[in] time New walk time in milliseconds. + */ +int dmp_set_pedometer_walk_time(unsigned long time) +{ + unsigned char tmp[4]; + + time /= 20; + + tmp[0] = (unsigned char)((time >> 24) & 0xFF); + tmp[1] = (unsigned char)((time >> 16) & 0xFF); + tmp[2] = (unsigned char)((time >> 8) & 0xFF); + tmp[3] = (unsigned char)(time & 0xFF); + return mpu_write_mem(D_PEDSTD_TIMECTR, 4, tmp); +} + +/** + * @brief Enable DMP features. + * The following \#define's are used in the input mask: + * \n DMP_FEATURE_TAP + * \n DMP_FEATURE_ANDROID_ORIENT + * \n DMP_FEATURE_LP_QUAT + * \n DMP_FEATURE_6X_LP_QUAT + * \n DMP_FEATURE_GYRO_CAL + * \n DMP_FEATURE_SEND_RAW_ACCEL + * \n DMP_FEATURE_SEND_RAW_GYRO + * \n NOTE: DMP_FEATURE_LP_QUAT and DMP_FEATURE_6X_LP_QUAT are mutually exclusive. + * \n NOTE: DMP_FEATURE_SEND_RAW_GYRO and DMP_FEATURE_SEND_CAL_GYRO are also mutually exclusive. + * @param[in] mask Mask of features to enable. + * @return 0 if successful. + */ +int dmp_enable_feature(unsigned short mask) +{ + unsigned char tmp[10]; + + /* TODO: All of these settings can probably be integrated into the default + * DMP image. + */ + /* Set integration scale factor. */ + tmp[0] = (unsigned char)((GYRO_SF >> 24) & 0xFF); + tmp[1] = (unsigned char)((GYRO_SF >> 16) & 0xFF); + tmp[2] = (unsigned char)((GYRO_SF >> 8) & 0xFF); + tmp[3] = (unsigned char)(GYRO_SF & 0xFF); + mpu_write_mem(D_0_104, 4, tmp); + + /* Send sensor data to the FIFO. */ + tmp[0] = 0xA3; + if (mask & DMP_FEATURE_SEND_RAW_ACCEL) { + tmp[1] = 0xC0; + tmp[2] = 0xC8; + tmp[3] = 0xC2; + } else { + tmp[1] = 0xA3; + tmp[2] = 0xA3; + tmp[3] = 0xA3; + } + if (mask & DMP_FEATURE_SEND_ANY_GYRO) { + tmp[4] = 0xC4; + tmp[5] = 0xCC; + tmp[6] = 0xC6; + } else { + tmp[4] = 0xA3; + tmp[5] = 0xA3; + tmp[6] = 0xA3; + } + tmp[7] = 0xA3; + tmp[8] = 0xA3; + tmp[9] = 0xA3; + mpu_write_mem(CFG_15,10,tmp); + + /* Send gesture data to the FIFO. */ + if (mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) + tmp[0] = DINA20; + else + tmp[0] = 0xD8; + mpu_write_mem(CFG_27,1,tmp); + + if (mask & DMP_FEATURE_GYRO_CAL) + dmp_enable_gyro_cal(1); + else + dmp_enable_gyro_cal(0); + + if (mask & DMP_FEATURE_SEND_ANY_GYRO) { + if (mask & DMP_FEATURE_SEND_CAL_GYRO) { + tmp[0] = 0xB2; + tmp[1] = 0x8B; + tmp[2] = 0xB6; + tmp[3] = 0x9B; + } else { + tmp[0] = DINAC0; + tmp[1] = DINA80; + tmp[2] = DINAC2; + tmp[3] = DINA90; + } + mpu_write_mem(CFG_GYRO_RAW_DATA, 4, tmp); + } + + if (mask & DMP_FEATURE_TAP) { + /* Enable tap. */ + tmp[0] = 0xF8; + mpu_write_mem(CFG_20, 1, tmp); + dmp_set_tap_thresh(DMP_TAP_AXES, DMP_TAP_THRESH); + dmp_set_tap_axes(DMP_TAP_AXES); + dmp_set_tap_count(DMP_TAP_COUNT); + dmp_set_tap_time(DMP_TAP_TIME); + dmp_set_tap_time_multi(DMP_TAP_TIME_MULTI); + + dmp_set_shake_reject_thresh(GYRO_SF, DMP_SHAKE_REJECT_THRESH); + dmp_set_shake_reject_time(DMP_SHAKE_REJECT_TIME); + dmp_set_shake_reject_timeout(DMP_SHAKE_REJECT_TIMEOUT); + } else { + tmp[0] = 0xD8; + mpu_write_mem(CFG_20, 1, tmp); + } + + if (mask & DMP_FEATURE_ANDROID_ORIENT) { + tmp[0] = 0xD9; + } else + tmp[0] = 0xD8; + mpu_write_mem(CFG_ANDROID_ORIENT_INT, 1, tmp); + + if (mask & DMP_FEATURE_LP_QUAT) + dmp_enable_lp_quat(1); + else + dmp_enable_lp_quat(0); + + if (mask & DMP_FEATURE_6X_LP_QUAT) + dmp_enable_6x_lp_quat(1); + else + dmp_enable_6x_lp_quat(0); + + /* Pedometer is always enabled. */ + dmp.feature_mask = mask | DMP_FEATURE_PEDOMETER; + mpu_reset_fifo(); + + dmp.packet_length = 0; + if (mask & DMP_FEATURE_SEND_RAW_ACCEL) + dmp.packet_length += 6; + if (mask & DMP_FEATURE_SEND_ANY_GYRO) + dmp.packet_length += 6; + if (mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) + dmp.packet_length += 16; + if (mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) + dmp.packet_length += 4; + + return 0; +} + +/** + * @brief Get list of currently enabled DMP features. + * @param[out] Mask of enabled features. + * @return 0 if successful. + */ +int dmp_get_enabled_features(unsigned short *mask) +{ + mask[0] = dmp.feature_mask; + return 0; +} + +/** + * @brief Calibrate the gyro data in the DMP. + * After eight seconds of no motion, the DMP will compute gyro biases and + * subtract them from the quaternion output. If @e dmp_enable_feature is + * called with @e DMP_FEATURE_SEND_CAL_GYRO, the biases will also be + * subtracted from the gyro output. + * @param[in] enable 1 to enable gyro calibration. + * @return 0 if successful. + */ +int dmp_enable_gyro_cal(unsigned char enable) +{ + if (enable) { + unsigned char regs[9] = {0xb8, 0xaa, 0xb3, 0x8d, 0xb4, 0x98, 0x0d, 0x35, 0x5d}; + return mpu_write_mem(CFG_MOTION_BIAS, 9, regs); + } else { + unsigned char regs[9] = {0xb8, 0xaa, 0xaa, 0xaa, 0xb0, 0x88, 0xc3, 0xc5, 0xc7}; + return mpu_write_mem(CFG_MOTION_BIAS, 9, regs); + } +} + +/** + * @brief Generate 3-axis quaternions from the DMP. + * In this driver, the 3-axis and 6-axis DMP quaternion features are mutually + * exclusive. + * @param[in] enable 1 to enable 3-axis quaternion. + * @return 0 if successful. + */ +int dmp_enable_lp_quat(unsigned char enable) +{ + unsigned char regs[4]; + if (enable) { + regs[0] = DINBC0; + regs[1] = DINBC2; + regs[2] = DINBC4; + regs[3] = DINBC6; + } + else + memset(regs, 0x8B, 4); + + mpu_write_mem(CFG_LP_QUAT, 4, regs); + + return mpu_reset_fifo(); +} + +/** + * @brief Generate 6-axis quaternions from the DMP. + * In this driver, the 3-axis and 6-axis DMP quaternion features are mutually + * exclusive. + * @param[in] enable 1 to enable 6-axis quaternion. + * @return 0 if successful. + */ +int dmp_enable_6x_lp_quat(unsigned char enable) +{ + unsigned char regs[4]; + if (enable) { + regs[0] = DINA20; + regs[1] = DINA28; + regs[2] = DINA30; + regs[3] = DINA38; + } else + memset(regs, 0xA3, 4); + + mpu_write_mem(CFG_8, 4, regs); + + return mpu_reset_fifo(); +} + +/** + * @brief Decode the four-byte gesture data and execute any callbacks. + * @param[in] gesture Gesture data from DMP packet. + * @return 0 if successful. + */ +static int decode_gesture(unsigned char *gesture) +{ + unsigned char tap, android_orient; + + android_orient = gesture[3] & 0xC0; + tap = 0x3F & gesture[3]; + + if (gesture[1] & INT_SRC_TAP) { + unsigned char direction, count; + direction = tap >> 3; + count = (tap % 8) + 1; + if (dmp.tap_cb) + dmp.tap_cb(direction, count); + } + + if (gesture[1] & INT_SRC_ANDROID_ORIENT) { + if (dmp.android_orient_cb) + dmp.android_orient_cb(android_orient >> 6); + } + + return 0; +} + +/** + * @brief Specify when a DMP interrupt should occur. + * A DMP interrupt can be configured to trigger on either of the two + * conditions below: + * \n a. One FIFO period has elapsed (set by @e mpu_set_sample_rate). + * \n b. A tap event has been detected. + * @param[in] mode DMP_INT_GESTURE or DMP_INT_CONTINUOUS. + * @return 0 if successful. + */ +int dmp_set_interrupt_mode(unsigned char mode) +{ + const unsigned char regs_continuous[11] = + {0xd8, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0x09, 0xb4, 0xd9}; + const unsigned char regs_gesture[11] = + {0xda, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0xda, 0xb4, 0xda}; + + switch (mode) { + case DMP_INT_CONTINUOUS: + return mpu_write_mem(CFG_FIFO_ON_EVENT, 11, + (unsigned char*)regs_continuous); + case DMP_INT_GESTURE: + return mpu_write_mem(CFG_FIFO_ON_EVENT, 11, + (unsigned char*)regs_gesture); + default: + return -1; + } +} + +/** + * @brief Get one packet from the FIFO. + * If @e sensors does not contain a particular sensor, disregard the data + * returned to that pointer. + * \n @e sensors can contain a combination of the following flags: + * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO + * \n INV_XYZ_GYRO + * \n INV_XYZ_ACCEL + * \n INV_WXYZ_QUAT + * \n If the FIFO has no new data, @e sensors will be zero. + * \n If the FIFO is disabled, @e sensors will be zero and this function will + * return a non-zero error code. + * @param[out] gyro Gyro data in hardware units. + * @param[out] accel Accel data in hardware units. + * @param[out] quat 3-axis quaternion data in hardware units. + * @param[out] timestamp Timestamp in milliseconds. + * @param[out] sensors Mask of sensors read from FIFO. + * @param[out] more Number of remaining packets. + * @return 0 if successful. + */ +int dmp_read_fifo(short *gyro, short *accel, long *quat, + unsigned long *timestamp, short *sensors, unsigned char *more) +{ + unsigned char fifo_data[MAX_PACKET_LENGTH]; + unsigned char ii = 0; + + /* TODO: sensors[0] only changes when dmp_enable_feature is called. We can + * cache this value and save some cycles. + */ + sensors[0] = 0; + + /* Get a packet. */ + if (mpu_read_fifo_stream(dmp.packet_length, fifo_data, more)) + return -1; + + /* Parse DMP packet. */ + if (dmp.feature_mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) { +#ifdef FIFO_CORRUPTION_CHECK + long quat_q14[4], quat_mag_sq; +#endif + quat[0] = ((long)fifo_data[0] << 24) | ((long)fifo_data[1] << 16) | ((long)fifo_data[2] << 8) | fifo_data[3]; + quat[1] = ((long)fifo_data[4] << 24) | ((long)fifo_data[5] << 16) | ((long)fifo_data[6] << 8) | fifo_data[7]; + quat[2] = ((long)fifo_data[8] << 24) | ((long)fifo_data[9] << 16) | ((long)fifo_data[10] << 8) | fifo_data[11]; + quat[3] = ((long)fifo_data[12] << 24) | ((long)fifo_data[13] << 16) | ((long)fifo_data[14] << 8) | fifo_data[15]; + ii += 16; +#ifdef FIFO_CORRUPTION_CHECK + /* We can detect a corrupted FIFO by monitoring the quaternion data and + * ensuring that the magnitude is always normalized to one. This + * shouldn't happen in normal operation, but if an I2C error occurs, + * the FIFO reads might become misaligned. + * + * Let's start by scaling down the quaternion data to avoid long long + * math. + */ + quat_q14[0] = quat[0] >> 16; + quat_q14[1] = quat[1] >> 16; + quat_q14[2] = quat[2] >> 16; + quat_q14[3] = quat[3] >> 16; + quat_mag_sq = quat_q14[0] * quat_q14[0] + quat_q14[1] * quat_q14[1] + + quat_q14[2] * quat_q14[2] + quat_q14[3] * quat_q14[3]; + if ((quat_mag_sq < QUAT_MAG_SQ_MIN) || + (quat_mag_sq > QUAT_MAG_SQ_MAX)) { + /* Quaternion is outside of the acceptable threshold. */ + mpu_reset_fifo(); + sensors[0] = 0; + return -1; + } + sensors[0] |= INV_WXYZ_QUAT; +#endif + } + + if (dmp.feature_mask & DMP_FEATURE_SEND_RAW_ACCEL) { + accel[0] = ((short)fifo_data[ii+0] << 8) | fifo_data[ii+1]; + accel[1] = ((short)fifo_data[ii+2] << 8) | fifo_data[ii+3]; + accel[2] = ((short)fifo_data[ii+4] << 8) | fifo_data[ii+5]; + ii += 6; + sensors[0] |= INV_XYZ_ACCEL; + } + + if (dmp.feature_mask & DMP_FEATURE_SEND_ANY_GYRO) { + gyro[0] = ((short)fifo_data[ii+0] << 8) | fifo_data[ii+1]; + gyro[1] = ((short)fifo_data[ii+2] << 8) | fifo_data[ii+3]; + gyro[2] = ((short)fifo_data[ii+4] << 8) | fifo_data[ii+5]; + ii += 6; + sensors[0] |= INV_XYZ_GYRO; + } + + /* Gesture data is at the end of the DMP packet. Parse it and call + * the gesture callbacks (if registered). + */ + if (dmp.feature_mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) + decode_gesture(fifo_data + ii); + + get_ms(timestamp); + return 0; +} + +/** + * @brief Register a function to be executed on a tap event. + * The tap direction is represented by one of the following: + * \n TAP_X_UP + * \n TAP_X_DOWN + * \n TAP_Y_UP + * \n TAP_Y_DOWN + * \n TAP_Z_UP + * \n TAP_Z_DOWN + * @param[in] func Callback function. + * @return 0 if successful. + */ +int dmp_register_tap_cb(void (*func)(unsigned char, unsigned char)) +{ + dmp.tap_cb = func; + return 0; +} + +/** + * @brief Register a function to be executed on a android orientation event. + * @param[in] func Callback function. + * @return 0 if successful. + */ +int dmp_register_android_orient_cb(void (*func)(unsigned char)) +{ + dmp.android_orient_cb = func; + return 0; +} + +/** + * @} + */ + + + diff --git a/Src/setup.c b/Src/setup.c new file mode 100644 index 0000000..43cf35e --- /dev/null +++ b/Src/setup.c @@ -0,0 +1,301 @@ +/** + * This file is part of the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +// Includes +#include "gd32f1x0.h" +#include "systick.h" +#include "setup.h" +#include "defines.h" +#include "config.h" +#include "util.h" + +// Global variables +extern volatile ErrStatus status; + +// Private variables +static rcu_periph_enum USART_CLK[USARTn] = {USART_AUX_CLK, + USART_MAIN_CLK + }; + +static uint32_t USART_TX_PIN[USARTn] = {USART_AUX_TX_PIN, + USART_MAIN_TX_PIN + }; + +static uint32_t USART_RX_PIN[USARTn] = {USART_AUX_RX_PIN, + USART_MAIN_RX_PIN + }; + + +void gpio_config(void) { + + /* =========================== Configure LEDs GPIOs =========================== */ + /* enable the GPIO clock */ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + + /* configure GPIO port */ + gpio_mode_set(LED1_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED1_Pin); + gpio_mode_set(LED2_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED2_Pin); + gpio_mode_set(LED3_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED3_Pin); + gpio_mode_set(LED4_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED4_Pin); + gpio_mode_set(LED5_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED5_Pin); + gpio_output_options_set(LED1_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED1_Pin); + gpio_output_options_set(LED2_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED2_Pin); + gpio_output_options_set(LED3_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED3_Pin); + gpio_output_options_set(LED4_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED4_Pin); + gpio_output_options_set(LED5_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED5_Pin); + + /* reset GPIO pin */ + gpio_bit_reset(LED1_GPIO_Port, LED1_Pin); + gpio_bit_reset(LED2_GPIO_Port, LED2_Pin); + gpio_bit_reset(LED3_GPIO_Port, LED3_Pin); + gpio_bit_reset(LED4_GPIO_Port, LED4_Pin); + gpio_bit_reset(LED5_GPIO_Port, LED5_Pin); + + + /* =========================== Configure Sensors GPIOs =========================== */ + /* enable the GPIO clock */ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOC); + + /* configure GPIO port */ + gpio_mode_set(SENSOR1_GPIO_Port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SENSOR1_Pin); + gpio_mode_set(SENSOR2_GPIO_Port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SENSOR2_Pin); + + + /* =========================== Configure I2C GPIOs =========================== */ + /* enable I2C clock */ + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(MPU_RCU_I2C); + + /* connect PB6 to I2C_SCL and PB7 to I2C_SDA */ + gpio_af_set(MPU_SCL_GPIO_Port, GPIO_AF_1, MPU_SCL_Pin); + gpio_af_set(MPU_SDA_GPIO_Port, GPIO_AF_1, MPU_SDA_Pin); + + /* configure GPIO port */ + gpio_mode_set(MPU_SCL_GPIO_Port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, MPU_SCL_Pin); + gpio_output_options_set(MPU_SCL_GPIO_Port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, MPU_SCL_Pin); + gpio_mode_set(MPU_SDA_GPIO_Port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, MPU_SDA_Pin); + gpio_output_options_set(MPU_SDA_GPIO_Port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, MPU_SDA_Pin); + + #ifdef AUX45_USE_I2C + /* enable I2C clock */ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(AUX_RCU_I2C); + + /* connect PB6 to I2C_SCL and PB7 to I2C_SDA */ + gpio_af_set(AUX_SCL_GPIO_Port, GPIO_AF_1, AUX_SCL_Pin); + gpio_af_set(AUX_SDA_GPIO_Port, GPIO_AF_1, AUX_SDA_Pin); + + /* configure GPIO port */ + gpio_mode_set(AUX_SCL_GPIO_Port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, AUX_SCL_Pin); + gpio_output_options_set(AUX_SCL_GPIO_Port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, AUX_SCL_Pin); + gpio_mode_set(AUX_SDA_GPIO_Port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, AUX_SDA_Pin); + gpio_output_options_set(AUX_SDA_GPIO_Port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, AUX_SDA_Pin); + #endif + + + /* =========================== Configure AUX GPIOs =========================== */ + /* configure AUX GPIO port */ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + + /* configure GPIO port - inputs */ + gpio_mode_set(AUX1_PU_GPIO_Port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, AUX1_PU_Pin); + + /* configure GPIO port - outputs */ + gpio_mode_set(AUX2_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, AUX2_Pin); + gpio_mode_set(AUX3_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, AUX3_Pin); + gpio_output_options_set(AUX2_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AUX2_Pin); + gpio_output_options_set(AUX3_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AUX3_Pin); + + /* reset GPIO pin */ + gpio_bit_reset(AUX2_GPIO_Port, AUX2_Pin); + gpio_bit_reset(AUX3_GPIO_Port, AUX3_Pin); + + #ifdef AUX45_USE_GPIO + /* configure GPIO port - outputs */ + gpio_mode_set(AUX4_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, AUX4_Pin); + gpio_mode_set(AUX5_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, AUX5_Pin); + gpio_output_options_set(AUX4_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AUX4_Pin); + gpio_output_options_set(AUX5_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AUX5_Pin); + + /* reset GPIO pin */ + gpio_bit_reset(AUX4_GPIO_Port, AUX4_Pin); + gpio_bit_reset(AUX5_GPIO_Port, AUX5_Pin); + #endif + +} + + +void usart_config(uint32_t selUSART, uint32_t selBaudRate) { + + /* enable GPIO clock */ + uint32_t USART_ID = 0U; + if(selUSART == USART0){ + USART_ID = 0U; + } + if(selUSART == USART1){ + USART_ID = 1U; + } + rcu_periph_clock_enable(USART_GPIO_CLK); + + /* enable USART clock */ + rcu_periph_clock_enable(USART_CLK[USART_ID]); + + /* connect port to USARTx_Tx */ + gpio_af_set(USART_GPIO_PORT, USART_AF, USART_TX_PIN[USART_ID]); + + /* connect port to USARTx_Rx */ + gpio_af_set(USART_GPIO_PORT, USART_AF, USART_RX_PIN[USART_ID]); + + /* configure USART Tx as alternate function push-pull */ + gpio_mode_set(USART_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART_TX_PIN[USART_ID]); + gpio_output_options_set(USART_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, USART_TX_PIN[USART_ID]); + + /* configure USART Rx as alternate function push-pull */ + gpio_mode_set(USART_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART_RX_PIN[USART_ID]); + gpio_output_options_set(USART_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, USART_RX_PIN[USART_ID]); + + /* USART configure */ + usart_deinit(selUSART); + usart_baudrate_set(selUSART, selBaudRate); + usart_transmit_config(selUSART, USART_TRANSMIT_ENABLE); + usart_receive_config(selUSART, USART_RECEIVE_ENABLE); + usart_enable(selUSART); + +} + +// DMA_CH1 = USART0_TX +// DMA_CH2 = USART0_RX +// DMA_CH3 = USART1_TX +// DMA_CH4 = USART1_RX + +void usart_Tx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t Size) { + + dma_parameter_struct dma_init_struct; + + // --------------------------- TX Channel --------------------------- + + /* enable DMA clock */ + rcu_periph_clock_enable(RCU_DMA); + + /* deinitialize DMA channel2 */ + dma_deinit(DMA_CH3); + dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; + dma_init_struct.memory_addr = (uint32_t)pData; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.number = Size; + dma_init_struct.periph_addr = USART1_TDATA_ADDRESS; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; // Priorities: *_LOW, *_MEDIUM, *_HIGH, *_ULTRA_HIGH, + dma_init(DMA_CH3, dma_init_struct); + + /* configure DMA mode */ + dma_circulation_disable(DMA_CH3); + dma_memory_to_memory_disable(DMA_CH3); + + /* enable DMA channel1 */ + dma_channel_enable(DMA_CH3); + + /* USART DMA enable for transmission and reception */ + usart_dma_transmit_config(selUSART, USART_DENT_ENABLE); + + /* wait DMA channel transfer complete */ + // while (RESET == dma_flag_get(DMA_CH3, DMA_FLAG_FTF)); + +} + +void usart_Rx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t Size) { + + dma_parameter_struct dma_init_struct; + + // --------------------------- RX Channel --------------------------- + + /* deinitialize DMA channel4 */ + dma_deinit(DMA_CH4); + dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; + dma_init_struct.memory_addr = (uint32_t)pData; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.number = Size; + dma_init_struct.periph_addr = USART1_RDATA_ADDRESS; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; // Priorities: *_LOW, *_MEDIUM, *_HIGH, *_ULTRA_HIGH, + dma_init(DMA_CH4, dma_init_struct); + + /* configure DMA mode */ + dma_circulation_enable(DMA_CH4); // dma_circulation_disable(DMA_CH4); + dma_memory_to_memory_disable(DMA_CH4); + + dma_channel_enable(DMA_CH4); + usart_dma_receive_config(selUSART, USART_DENR_ENABLE); + + /* wait DMA channel transfer complete */ + // while (RESET == dma_flag_get(DMA_CH4, DMA_FLAG_FTF)); + +} + + +void i2c_config(void) { + + /* I2C clock configure */ + //i2c_clock_config(MPU_I2C, MPU_I2C_SPEED, I2C_DTCY_2); // I2C duty cycle in fast mode + i2c_clock_config(MPU_I2C, MPU_I2C_SPEED, I2C_DTCY_16_9); // I2C duty cycle in fast mode plus + /* I2C address configure */ + i2c_mode_addr_config(MPU_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_OWN_ADDRESS7); + /* enable I2C */ + i2c_enable(MPU_I2C); + /* enable acknowledge */ + i2c_ack_config(MPU_I2C, I2C_ACK_ENABLE); + + #ifdef AUX45_USE_I2C + /* I2C clock configure */ + //i2c_clock_config(AUX_I2C, AUX_I2C_SPEED, I2C_DTCY_2); // I2C duty cycle in fast mode + i2c_clock_config(AUX_I2C, AUX_I2C_SPEED, I2C_DTCY_16_9); // I2C duty cycle in fast mode plus + /* I2C address configure */ + i2c_mode_addr_config(AUX_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, AUX_I2C_OWN_ADDRESS7); + /* enable I2C */ + i2c_enable(AUX_I2C); + /* enable acknowledge */ + i2c_ack_config(AUX_I2C, I2C_ACK_ENABLE); + #endif + +} + + +void i2c_nvic_config(void) +{ + /* configure the NVIC peripheral */ + nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); + + nvic_irq_enable(I2C0_EV_IRQn, 0, 3); + nvic_irq_enable(I2C0_ER_IRQn, 0, 2); + + #ifdef AUX45_USE_I2C + nvic_irq_enable(I2C1_EV_IRQn, 0, 4); + nvic_irq_enable(I2C1_ER_IRQn, 0, 1); + #endif +} + + diff --git a/Src/systick.c b/Src/systick.c new file mode 100644 index 0000000..b58c571 --- /dev/null +++ b/Src/systick.c @@ -0,0 +1,108 @@ +/*! + \file systick.c + \brief the systick configuration file + + \version 2016-01-15, V1.0.0, demo for GD32F1x0 + \version 2016-05-13, V2.0.0, demo for GD32F1x0 + \version 2019-11-20, V3.0.0, demo for GD32F1x0 +*/ + +/* + Copyright (c) 2019, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32f1x0.h" +#include "systick.h" + +volatile static uint32_t delay; +volatile static unsigned long tick_count_ms = 0; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1){ + } + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay){ + } +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} + +/*! + \brief tick count increment in ms + \param[in] none + \param[out] none + \retval none +*/ +void tick_count_increment() +{ + tick_count_ms++; +} + +/*! + \brief get tick count in ms + \param[in] *count: pointer to count + \param[out] none + \retval none +*/ +void get_tick_count_ms(unsigned long *count) +{ + *count = tick_count_ms; +} diff --git a/Src/util.c b/Src/util.c new file mode 100644 index 0000000..4c1df86 --- /dev/null +++ b/Src/util.c @@ -0,0 +1,299 @@ +/** + * This file is part of the hoverboard-sideboard-hack project. + * + * Copyright (C) 2020-2021 Emanuel FERU + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +// Includes +#include +#include "systick.h" +#include "gd32f1x0.h" +#include "defines.h" +#include "config.h" +#include "util.h" + + +// MAIN I2C variables +volatile int8_t i2c_status; +volatile i2c_cmd i2c_ReadWriteCmd; +volatile uint8_t i2c_regAddress; +volatile uint8_t i2c_slaveAddress; +volatile uint8_t* i2c_txbuffer; +volatile uint8_t* i2c_rxbuffer; +volatile uint8_t i2c_nDABytes; +volatile int8_t i2c_nRABytes; +volatile uint8_t buffer[14]; + +#ifdef AUX45_USE_I2C +// AUX I2C variables +volatile int8_t i2c_aux_status; +volatile i2c_cmd i2c_aux_ReadWriteCmd; +volatile uint8_t i2c_aux_regAddress; +volatile uint8_t i2c_aux_slaveAddress; +volatile uint8_t* i2c_aux_txbuffer; +volatile uint8_t* i2c_aux_rxbuffer; +volatile uint8_t i2c_aux_nDABytes; +volatile int8_t i2c_aux_nRABytes; +#endif + + +/* =========================== General Functions =========================== */ + +void consoleLog(char *message) +{ + #ifdef SERIAL_DEBUG + log_i("%s", message); + #endif +} + + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(USART_MAIN, (uint8_t)ch); + while(RESET == usart_flag_get(USART_MAIN, USART_FLAG_TBE)); + return ch; +} + + +void introDemoLED(uint32_t tDelay) +{ + int i; + + for (i = 0; i < 6; i++) { + gpio_bit_set(LED1_GPIO_Port, LED1_Pin); + gpio_bit_reset(LED3_GPIO_Port, LED3_Pin); + delay_1ms(tDelay); + gpio_bit_set(LED2_GPIO_Port, LED2_Pin); + gpio_bit_reset(LED1_GPIO_Port, LED1_Pin); + delay_1ms(tDelay); + gpio_bit_set(LED3_GPIO_Port, LED3_Pin); + gpio_bit_reset(LED2_GPIO_Port, LED2_Pin); + delay_1ms(tDelay); + } + + for (i = 0; i < 2; i++) { + gpio_bit_set(LED1_GPIO_Port, LED1_Pin); + gpio_bit_set(LED2_GPIO_Port, LED2_Pin); + gpio_bit_set(LED3_GPIO_Port, LED3_Pin); + gpio_bit_set(LED4_GPIO_Port, LED4_Pin); + gpio_bit_set(LED5_GPIO_Port, LED5_Pin); + delay_1ms(tDelay); + gpio_bit_reset(LED1_GPIO_Port, LED1_Pin); + gpio_bit_reset(LED2_GPIO_Port, LED2_Pin); + gpio_bit_reset(LED3_GPIO_Port, LED3_Pin); + gpio_bit_reset(LED4_GPIO_Port, LED4_Pin); + gpio_bit_reset(LED5_GPIO_Port, LED5_Pin); + } + +} + +/* =========================== I2C WRITE Functions =========================== */ + +/* + * write bytes to chip register + */ +int8_t i2c_writeBytes(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data) +{ + + // assign WRITE command + i2c_ReadWriteCmd = WRITE; + + // assign inputs + i2c_status = -1; + i2c_slaveAddress = slaveAddr << 1; // Address is shifted one position to the left. LSB is reserved for the Read/Write bit. + i2c_regAddress = regAddr; + i2c_txbuffer = data; + i2c_nDABytes = length; + i2c_nRABytes = 1; + + // enable the I2C0 interrupt + i2c_interrupt_enable(MPU_I2C, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + + // the master waits until the I2C bus is idle + while(i2c_flag_get(MPU_I2C, I2C_FLAG_I2CBSY)); + + // the master sends a start condition to I2C bus + i2c_start_on_bus(MPU_I2C); + + // Wait until all data bytes are sent/received + while(i2c_nDABytes > 0); + + return i2c_status; + +} + + +/* + * write 1 byte to chip register + */ +int8_t i2c_writeByte(uint8_t slaveAddr, uint8_t regAddr, uint8_t data) +{ + return i2c_writeBytes(slaveAddr, regAddr, 1, &data); +} + + +/* + * write one bit to chip register + */ +int8_t i2c_writeBit(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) { + uint8_t b; + i2c_readByte(slaveAddr, regAddr, &b); + b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum)); + return i2c_writeByte(slaveAddr, regAddr, b); +} + + + +/* =========================== I2C READ Functions =========================== */ + +/* + * read bytes from chip register + */ +int8_t i2c_readBytes(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data) +{ + + // assign READ command + i2c_ReadWriteCmd = READ; + + // assign inputs + i2c_status = -1; + i2c_slaveAddress = slaveAddr << 1; // Address is shifted one position to the left. LSB is reserved for the Read/Write bit. + i2c_regAddress = regAddr; + i2c_rxbuffer = data; + i2c_nDABytes = length; + i2c_nRABytes = 1; + + // enable the I2C0 interrupt + i2c_interrupt_enable(MPU_I2C, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + + if(2 == i2c_nDABytes){ + i2c_ackpos_config(MPU_I2C, I2C_ACKPOS_NEXT); // send ACK for the next byte + } + + // the master waits until the I2C bus is idle + while(i2c_flag_get(MPU_I2C, I2C_FLAG_I2CBSY)); + + // the master sends a start condition to I2C bus + i2c_start_on_bus(MPU_I2C); + + // Wait until all data bytes are sent/received + while(i2c_nDABytes > 0); + + // Return status + return i2c_status; + +} + + +/* + * read 1 byte from chip register + */ +int8_t i2c_readByte(uint8_t slaveAddr, uint8_t regAddr, uint8_t *data) +{ + return i2c_readBytes(slaveAddr, regAddr, 1, data); +} + + +/* + * read 1 bit from chip register + */ +int8_t i2c_readBit(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data) +{ + uint8_t b; + int8_t status = i2c_readByte(slaveAddr, regAddr, &b); + *data = b & (1 << bitNum); + return status; +} + + +#ifdef AUX45_USE_I2C +/* + * write bytes to chip register + */ +int8_t i2c_aux_writeBytes(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data) +{ + + // assign WRITE command + i2c_aux_ReadWriteCmd = WRITE; + + // assign inputs + i2c_aux_status = -1; + i2c_aux_slaveAddress = slaveAddr << 1; // Address is shifted one position to the left. LSB is reserved for the Read/Write bit. + i2c_aux_regAddress = regAddr; + i2c_aux_txbuffer = data; + i2c_aux_nDABytes = length; + i2c_aux_nRABytes = 1; + + // enable the I2C0 interrupt + i2c_interrupt_enable(AUX_I2C, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + + // the master waits until the I2C bus is idle + while(i2c_flag_get(AUX_I2C, I2C_FLAG_I2CBSY)); + + // the master sends a start condition to I2C bus + i2c_start_on_bus(AUX_I2C); + + // Wait until all data bytes are sent/received + while(i2c_aux_nDABytes > 0); + + return i2c_aux_status; + +} + +/* + * read bytes from chip register + */ +int8_t i2c_aux_readBytes(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data) +{ + + // assign READ command + i2c_aux_ReadWriteCmd = READ; + + // assign inputs + i2c_aux_status = -1; + i2c_aux_slaveAddress = slaveAddr << 1; // Address is shifted one position to the left. LSB is reserved for the Read/Write bit. + i2c_aux_regAddress = regAddr; + i2c_aux_rxbuffer = data; + i2c_aux_nDABytes = length; + i2c_aux_nRABytes = 1; + + // enable the I2C0 interrupt + i2c_interrupt_enable(AUX_I2C, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + + if(2 == i2c_aux_nDABytes){ + i2c_ackpos_config(AUX_I2C, I2C_ACKPOS_NEXT); // send ACK for the next byte + } + + // the master waits until the I2C bus is idle + while(i2c_flag_get(AUX_I2C, I2C_FLAG_I2CBSY)); + + // the master sends a start condition to I2C bus + i2c_start_on_bus(AUX_I2C); + + // Wait until all data bytes are sent/received + while(i2c_aux_nDABytes > 0); + + // Return status + return i2c_aux_status; + +} +#endif + + + + + diff --git a/build/VARIANT_DEBUG/firmware.axf b/build/VARIANT_DEBUG/firmware.axf new file mode 100644 index 0000000..e9a3e53 Binary files /dev/null and b/build/VARIANT_DEBUG/firmware.axf differ diff --git a/build/VARIANT_DEBUG/firmware.hex b/build/VARIANT_DEBUG/firmware.hex new file mode 100644 index 0000000..ab1acdc --- /dev/null +++ b/build/VARIANT_DEBUG/firmware.hex @@ -0,0 +1,1584 @@ +:020000040800F2 +:10000000D00400207D010008EF0D00087D0B0008E2 +:10001000ED0D0008790B0008890E000800000000B3 +:10002000000000000000000000000000130E0008A7 +:100030007B0B000800000000110E0008150E0008E0 +:100040009701000897010008970100089701000830 +:100050009701000897010008970100089701000820 +:100060009701000897010008970100089701000810 +:100070009701000897010008970100089701000800 +:100080009701000897010008000000009701000890 +:10009000970100089701000897010008830B0008EA +:1000A00097010008970100089701000897010008D0 +:1000B0009701000800000000970100080000000000 +:1000C0007F0B00080000000097010008970100085E +:1000D0009701000897010008970100080000000040 +:1000E00000000000000000009701000897010008D0 +:1000F0009701000897010008970100089701000880 +:1001000097010008000000000000000097010008AF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000097010008970100085F +:100160009701000897010008DFF80CD000F080FC30 +:1001700000480047E5310008D004002006488047C9 +:1001800006480047FEE7FEE7FEE7FEE7FEE7FEE77C +:10019000FEE7FEE7FEE7FEE7250E0008690100081E +:1001A0002DE9F0410024061B254671F1000605DA11 +:1001B00001240027D0EB070067EB0101161E73F145 +:1001C000000605DA0027D2EB0702012567EB0303DF +:1001D00000F01BFA86460E4617469C46AC4204D0F9 +:1001E0000025D0EB050E65EB010624B10020D2EB13 +:1001F000000760EB030C704631463A466346BDE8A3 +:10020000F081D2B201E000F8012B491EFBD2704709 +:100210000022F6E710B513460A4604461946FFF7D2 +:10022000F0FF204610BD30B504460020034600E034 +:100230005B1C934203D2E05CCD5C401BF8D030BD28 +:10024000F0B480EA0102D40F4200B2EB410F02D2B7 +:100250000246084611464A0042D0C30DDDB2C1F342 +:10026000C752AD1A202D35DAC1F3160141F4000250 +:1002700004B15242C5F1200602FA06F12A411044A7 +:10028000B3EBD05F23D0C4B1012DA0EBC35009DC88 +:10029000F0BC4FF0004202EAC352DBB200F50000AE +:1002A00000F0FDB9400000F1807000EBC350A0F1F8 +:1002B000807040EAD170490009E0490841EAC07104 +:1002C000A0EBC35000F50000400800EBC350F0BCA9 +:1002D00000F0DCB96142012202EB4101001BF6E7AC +:1002E000F0BC704781F00041AAE780F00040A7E72A +:1002F00080EA010210B502F00043400022D04A001B +:100300001FD0010E01EB1261C0F35600C2F356027A +:1003100040F4000042F40002A0FB022000047F39F8 +:10032000140400D0401C50EA124001D44000491E81 +:10033000C2B20C0604EBD010401C4008802A02D048 +:1003400003E0002010BD20F00100002900DA0020A9 +:10035000184310BD30B480EA010202F0004530F0CD +:10036000004221F0004013D090B1C30DD40DC2F370 +:100370001601C0F31600E41A41F4000140F4000233 +:100380007D34914201D3641C00E04900002C02DA64 +:1003900030BC002070474FF400000023914201D38D +:1003A000891A034340084FEA4101F7D151B1914204 +:1003B00002D14FF0004105E002D24FF0010101E00F +:1003C0006FF0010103EBC450284430BC00F05EB96B +:1003D000420005D0C0F3C7525242914201DC0020D6 +:1003E000704700EBC15070472DE9FE4F81EA0304CE +:1003F00004F0004421F0004100944FF0000B23F082 +:10040000004350EA01045ED052EA03045BD0C3F318 +:100410000A54C1F30A552C44A4F2F3340194A0FB0E +:100420000254C1F3130141F48011C3F3130343F4E5 +:10043000801301FB024400FB034E840A970A44EA3E +:10044000815447EA8357A4FB076802958D0A05FB90 +:1004500007854FEA932C04FB0C542705029D4FEAB5 +:10046000065847EA1637B5EB08056EEB070C870E02 +:10047000920E47EA811742EA8312A7FB0201B6EB0C +:100480000B0164EB00042B0D43EA0C335E1844EBC4 +:100490001C50DA465146E7FB0201C5F313044FEA4C +:1004A0000B3343EA14534FEA0432019C43EA060338 +:1004B000A4F10C040294009CCDE900B400F02CF9E6 +:1004C00003B0BDE8F08F00200146F9E7C10F80EAD4 +:1004D000E0700844CA079623002100F0E0B8962394 +:1004E0000022114600F0DBB800F0004220F000408E +:1004F000C10DC0F3160040F400007F2901DA00208E +:100500007047962903DCC1F19601C84001E0963995 +:100510008840002AF4D04042704720F00040C10DCE +:10052000C0F3160040F400007F2901DA0020704774 +:10053000962903DCC1F19601C8407047963988407E +:10054000704770B5C1F30A5201F000450024C1F3B1 +:10055000130140F2FF3341F480119A4201DA002086 +:1005600070BD40F233439A42A2F2334203DC52425E +:1005700000F07CF800E090402C43F1D0404270BD88 +:1005800000F0004230F000400AD0C10D01F560716A +:10059000C0F3160042EA0151C208400711437047F8 +:1005A00000200146704701F0004330B421F00041C3 +:1005B00050EA010206D00A0DA2F56072C1F31301E0 +:1005C000002A02DC30BC00207047440F44EAC1041A +:1005D000C100E01830BC00EBC25000F057B830B595 +:1005E0000B46014600202022012409E021FA02F5F1 +:1005F0009D4205D303FA02F5491B04FA02F528448B +:10060000151EA2F10102F1DC30BD2DE9F05F0546B7 +:10061000002092469B4688460646814640241BE0C1 +:10062000284641464746224600F020F853465A469F +:10063000C01A914110D311461846224600F02AFAFA +:100640002D1A67EB01084F4622460120002100F0D9 +:1006500021FA17EB00094E41201EA4F10104DFDC52 +:10066000484631462A464346BDE8F09F202A04DB2F +:10067000203A21FA02F00021704721FA02F3D0401B +:10068000C2F1200291400843194670470029A8BFD3 +:100690007047401C490008BF20F00100704710B4AB +:1006A000B0FA80FC00FA0CF050EA010404BF10BC60 +:1006B000704749B1CCF1200421FA04F411FA0CF18D +:1006C00018BF012121430843A3EB0C01CB1D4FEAC6 +:1006D00000614FEA102042BF002010BC704700EBC1 +:1006E000C35010440029A4BF10BC7047401C4900EF +:1006F00008BF20F0010010BC704710B5141E73F144 +:10070000000408DA401C41F1000192185B411A43D1 +:1007100001D120F0010010BD2DE9F04D92469B461D +:1007200011B1B1FA81F202E0B0FA80F220329046C3 +:1007300000F0B0F904460F4640EA0A0041EA0B0116 +:1007400053465A46084313D0114653EA010019D0C4 +:10075000C8F140025046FFF789FF05460E46504655 +:100760005946424600F096F9084305D0012004E0BE +:1007700020463946BDE8F08D0020054346EAE07684 +:100780002C4337430A986305E40AA0EB08000022D3 +:10079000FD0A44EA47540A3002D500200146E9E741 +:1007A000010510196941DDE9084500196941BDE8F5 +:1007B000F04DA2E72DE9FE4F804681EA0300C00F0D +:1007C0000C46009021F0004123F00045B8EB0200F8 +:1007D000A94105D24046214690461C460B4602469A +:1007E00023F00040104347D0270DC7F30A00C3F39E +:1007F0000A510290401A019040286BDAC3F31300AB +:1008000040F4801B0098924620B10023D2EB030AEB +:1008100063EB0B0B01985946C0F14002504600F0C3 +:1008200039F906460D4650465946019A00F041F9FD +:1008300010EB08006141002487EA115284EAE77353 +:100840001A4340D0009A62B3019A012A4FEA075234 +:1008500015DC001B61EB02014FF0004202EA075277 +:10086000CDE90042001C41F5801132462B46FFF7CE +:1008700053FF03B0BDE8F08F40462146F9E7001B67 +:1008800061EB0201001C41F5801300185B41201848 +:10089000A2F5001747EB030140EAD570B6196D4188 +:1008A00011E06D084FEA360645EAC0754FEA075277 +:1008B000001B61EB0201001C41F5801149084FEA61 +:1008C00030000019514132462B4603B0BDE8F04FCD +:1008D000FFF713BF0098012240000023D0EB020273 +:1008E00063EBE073009821464FEAE074B8EB000038 +:1008F00061EB0401E9E783F000435BE781F000412D +:1009000058E72DE9F04D81EA030404F0004B21F093 +:10091000004514464FF0000A23F0004150EA05025A +:1009200020D054EA01021DD0C5F30A570246C5F390 +:100930001303C1F31300C1F30A5640F4801543F4C6 +:100940008013A7EB0608101BD64608F2FD3873EBA0 +:10095000050002D308F1010801E092185B41B8F1EB +:10096000000F03DA00200146BDE8F08D00204FF4AF +:100970008011064684460EE0171B73EB050705D36E +:10098000121B63EB050306434CEA010C49084FEACE +:10099000300092185B4150EA0107EDD152EA0300A2 +:1009A00012D082EA040083EA0501084305D0101B37 +:1009B000AB4106D20122002306E000224FF00043A3 +:1009C00002E06FF0010253101AEB06004CEB0851E5 +:1009D00010EB0A0041EB0B01BDE8F04DFFF78DBEB7 +:1009E00070B521F0004303430CD0C1F30A55002435 +:1009F000D5EB040564EB0403D617AD1AB34102DB53 +:100A00000020014670BD201841EB025170BDC1F3BA +:100A10000A52C1F3130140F2FF3341F480119A42AC +:100A200002DA00200146704740F233439A42A2F2B4 +:100A3000334202DC5242FFF719BE00F02BB800002F +:100A400030B5041E71F1000404DB4FF00044404255 +:100A500064EB0101141E73F1000405DB1C464FF02A +:100A60000043524263EB0403994208BF904230BDF9 +:100A7000064C074D06E0E06840F0010394E80700EB +:100A800098471034AC42F6D3FFF772FB3862000887 +:100A900058620008202A04DB203A00FA02F1002004 +:100AA00070479140C2F1200320FA03F319439040AC +:100AB0007047202A06DBCB17203A41FA02F043EABE +:100AC000E07306E041FA02F3D040C2F12002914007 +:100AD0000843194670472DE9F04D00231A461B1AAA +:100AE0008A4103DB00200146BDE8F08DC1F30A52C4 +:100AF000C1F3130141F480154FF0000BD10702D16F +:100B000000186D41521E0027044640F2FF1138467E +:100B100001EB620A3E468046024600204FF48011F7 +:100B2000FFF7A4FDC2197141BB1846EB0100B4EBFD +:100B3000030C75EB000C04D3E41A65EB00051746B3 +:100B40000E46241908F101006D4180463428E3DD8A +:100B5000F91946EB0600091BA84103D24FF0FF32FA +:100B6000134601E0002213461BEB070046EB0A5137 +:100B7000BDE8F04DFFF7C1BDFEE77047FEE700F0AE +:100B800003B800F059B8000070B52A4C4FF48065E6 +:100B90002946204602F01EFA18B12946204602F0E6 +:100BA00010FA4FF400452946204602F013FA18B116 +:100BB0002946204602F005FA4FF480452946204692 +:100BC00002F008FA18B12946204602F0FAF94FF46B +:100BD00000652946204602F0FDF918B12946204655 +:100BE00002F0EFF94FF400752946204602F0F2F9C1 +:100BF00018B12946204602F0E4F94FF480752946E1 +:100C0000204602F0E7F918B12946204602F0D9F94A +:100C10004FF480552946204602F0DCF918B12946E8 +:100C2000204602F0CEF92046BDE870404FF4E06166 +:100C300002F0BFB9005400402DE9F05F624801782E +:100C4000624FDFF88C81DFF88CA1634D634C644EFA +:100C50004FF000096FF0010B01290DD0007800283A +:100C60003CD195F900004FF001010028304653DBDC +:100C700002F0B0F928B939E00121304602F0AAF9B2 +:100C800008B15A464CE00221304602F0A3F9002890 +:100C90005BD18021304602F09DF900281ED095F9E5 +:100CA0000000002806DD00BF98F80010304602F072 +:100CB0006AF92DE0207898B14A4A106810F8011BB3 +:100CC0001060304602F05FF92078401E207000204E +:100CD0004FF4FA71401C80B28842FBD3BDE8F09F0C +:100CE000304602F0F0F98AF8009066E002213046C2 +:100CF00002F070F948BB8021304602F06BF9002801 +:100D0000ECD095F900000028CEDC304602F0D6F990 +:100D10002878401E2870E1E702F05CF930B101222A +:100D200039783046BDE8F05F02F070B902213046F4 +:100D300002F050F978B12078012802D020780228FA +:100D400003D10021304602F093F83046BDE8F05F51 +:100D5000022102F036B94021304602F03BF900286A +:100D6000BCD020780028B9D02078032809D10421EC +:100D7000304602F02FF90028F9D00021304602F069 +:100D800077F8304602F0FCF817490246086800F888 +:100D9000012B08602078401E2070207800289DD10B +:100DA000304602F090F98AF800900121304602F0B6 +:100DB0005FF80121304602F065F83046BDE8F05F8B +:100DC0004FF4E06102F0F5B8290000202B0000206C +:100DD0002A000020280000202D0000202C000020E8 +:100DE000005400403000002034000020FEE770472F +:100DF0000907090E002806DA00F00F0000F1E020D4 +:100E000080F8141D704700F1E02080F8001470474E +:100E10007047704710B504F09DFABDE8104001F02E +:100E200087B800001448016841F0010101600168C1 +:100E30008907FCD54168114A114041604168104A58 +:100E400011404160416821F44001416001680D4A50 +:100E500011400160C16A21F00F01C162016B40F2D3 +:100E6000431291430163416B21F001014163002171 +:100E7000816004F027BA0000001002400C00FF0857 +:100E8000FFFFC277FFFFF2FEFEE700000FB4054B45 +:100E900010B503A9044A029800F05CF910BC5DF893 +:100EA00014FB0000FD26000868000020490050EAFD +:100EB000C12018BF04204A0D18BF40F0010040F2C5 +:100EC000FF72B2EB515F08BF40F00200012808BF7B +:100ED000052070472DE9F0414F1E00EBC701044685 +:100EE000D1E9000115461E4637F006020DD02A460C +:100EF0003346FFF779FA7F1E04EBC703D3E90023DB +:100F0000FFF758FC37F00602F1D1022F25D0042F4D +:100F100013D0062F18BFBDE8F0812A463346FFF7ED +:100F200063FAD4E90A23FFF745FC2A463346FFF764 +:100F30005BFAD4E90823FFF73DFC2A463346FFF766 +:100F400053FAD4E90623FFF735FC2A463346FFF768 +:100F50004BFAD4E90423FFF72DFC2A463346FFF76A +:100F600043FAD4E90223FFF725FC2A463346FFF76C +:100F70003BFAD4E90023BDE8F041FFF71BBC012296 +:100F8000FFF72EBDFFF716BC002213461046114690 +:100F9000FFF7B7BC024A00201107FFF721BD000090 +:100FA00001FDFFFF02E008C8121F08C1002AFAD1A4 +:100FB00070477047002001E001C1121F002AFBD1D9 +:100FC0007047000001490860704700006C00002075 +:100FD0002DE9FF5F82B00021DDE90430020DDDF86C +:100FE00040B0034318D044F61050A2F2FF324243FF +:100FF0001514119801281FD0A5EB0B00401C5FEAC7 +:10100000000A4FF000064E4FDFF83891B0465046C8 +:1010100015D5CAF1000413E0119801244AA3012850 +:1010200001D16FEA0B010298119AC0E90031C0E9C1 +:10103000024206B0BDE8F09FCBF10000DFE70446B6 +:101040000021404A491842EB0450CDE9001012E05B +:10105000E00707D032463B4640464946FFF7C4F911 +:101060008046894632463B4610461946FFF7BCF992 +:1010700006460F466410002CEAD1DDE90401DDE9E3 +:101080000023BAF1000F06DAFFF7AEF942464B46ED +:10109000FFF7AAF905E0FFF734FC42464B46FFF79D +:1010A00030FC04460E460022284BFFF7C9FC03D84B +:1010B0004FF0FF30014607E00022254B2046314625 +:1010C000FFF778FBFFF7A3FC102409E0002C0ADBF4 +:1010D0000A220023FFF799FA039B30321A55641E47 +:1010E00050EA0102F2D1641C039AC4F111031444C2 +:1010F000119A012A03D0012208430DD10AE00843C6 +:1011000004D000204FF0110B119072E7A3EB0B05F8 +:101110006D1E0DE05B4504DD4FF0000205F1010599 +:1011200004E003DA4FF00002A5F10105002AECD03B +:1011300002981199C0E90231C0E9004579E7000041 +:10114000000014400000F03F300000000000F043B9 +:101150000000E03F2DE9FF4F95B09B4689460646CB +:1011600000250FE2252877D100242746F84A0121DF +:10117000059400E0044316F8013F203B01FA03F018 +:101180001042F7D130782A2811D06FF02F03307831 +:10119000A0F13002092A16D8059A44F0020402EBA5 +:1011A000820203EB42021044761C0590EFE759F8E7 +:1011B000042B0592002A03DA504244F400540590AF +:1011C00044F00204761C30782E2816D116F8010F50 +:1011D00044F004042A280DD06FF02F023078A0F1DB +:1011E0003003092B09D807EB870302EB4303C71829 +:1011F000761CF3E759F8047B761C30786C280FD006 +:1012000006DC4C2817D068280DD06A2814D104E0D9 +:10121000742810D07A280FD10DE044F400140AE0AD +:1012200044F4801401E044F440147278824202D104 +:1012300004F58014761C761C307866280BD013DCFD +:10124000582877D009DC002875D04528F6D04628E4 +:10125000F4D047281AD19DE118E0632835D06428DE +:1012600079D0652812D195E1702873D008DC672801 +:10127000F1D069286FD06E280DD06F2806D1B5E067 +:1012800073282CD0752875D0782874D05A461799B1 +:1012900090476D1C75E1C4F30250022809D0032861 +:1012A0000DD0D9F8001004280DD00D6009F1040903 +:1012B00067E1D9F80010EA17C1E90052F6E7D9F85A +:1012C00000100D80F2E70D70F0E719F8041B8DF89F +:1012D000001000208DF80100EA46012003E059F8D3 +:1012E00004AB4FF0FF3061074FF0000102D40DE076 +:1012F00008F101018846B9420FDA8045F8DB1AF897 +:1013000008100029F4D108E008F101018846814263 +:10131000FADB1AF808100029F6D105985B46A0EB15 +:10132000080721463846179A00F094FA284400EB43 +:10133000080507E04DE029E10DE01AF8010B5A46D7 +:1013400017999047B8F10108F7D25B462146384615 +:10135000179A13E142E00A220092C4F302524FF0BE +:10136000000A022A08D059F804CB032A4FEAEC718C +:101370000AD00DE029E02AE009F1070121F0070277 +:10138000F2E802C1914609E00FFA8CFC4FEAEC71D9 +:10139000042A03D14FFA8CFC4FEAEC71002907DADA +:1013A0000A460021DCF1000C61EB02012D2202E073 +:1013B000220504D52B228DF80420012203E0E20748 +:1013C00001D02022F7E7904659E00A2102E01022DE +:1013D0000DE010214FF0000A00910BE010224FF0B9 +:1013E000000A44F004040827009203E008224FF0AA +:1013F000000A0092C4F30252022A05D059F804CB25 +:101400000021032A08D009E009F1070121F00702B1 +:10141000F2E802C1914605E01FFA8CFC042A01D1D2 +:101420000CF0FF0C4FF00008220728D5702806D0DA +:10143000009B83F0100353EA0A0305D00EE040221C +:101440008DF80420012208E05CEA010206D0302277 +:101450008DF804208DF8050002229046009B83F051 +:10146000080353EA0A030AD15CEA010201D16207C8 +:1014700005D530228DF804204FF001087F1E582832 +:1014800004D034A003900EA802900DE036A0F9E736 +:1014900053466046009AFFF7B8F884460398825C8A +:1014A0000298401E029002705CEA0100F0D102989E +:1014B00006A9081A00F1200A600702D524F4803436 +:1014C00000E00127574502DDA7EB0A0000E00020FD +:1014D00000EB0A01009005984144401A0590E00392 +:1014E00006D45B462146179A059800F0B3F90544E7 +:1014F000002706E001A85A46C05D179990476D1C69 +:101500007F1C4745F6DBE0030CD55B462146179A66 +:10151000059800F09FF9054404E030205A461799D9 +:1015200090476D1C0099481E00900029F5DC08E0EA +:10153000029802995A460078491C029117999047DF +:101540006D1CBAF10001AAF1010AF1DC65E10000AD +:101550000928010030313233343536373839616289 +:10156000636465660000000030313233343536374D +:1015700038394142434445460000000000F058F924 +:101580000544761C307800287FF4ECAD19B028466D +:10159000BDE8F08F620700D4062709F1070222F0A8 +:1015A000070CFCE80223E14603F000485FEA080C60 +:1015B00002D00FF2702C0DE05FEA045C02D50FF24E +:1015C000682C07E05FEAC47C02D00FF2602C01E0D7 +:1015D000AFF2700C4FF0FF3823F00043CDF850C04D +:1015E00065280CD006DC452809D046281DD04728A0 +:1015F0003DD13DE0662818D067287ED138E0002133 +:10160000112F01DB112000E0781CCDE9000106A9B3 +:101610000EA8FFF7DDFCDDE90F010E9A0391002112 +:10162000009207F1010A04914DE04FF0004000974D +:10163000CDE9011006A90EA8FFF7CAFCDDE90F02EB +:1016400003920E9B11990022DDF80CA000930492E6 +:1016500011B9791C00EB010AB7EB0A0004D4C0F100 +:10166000FF3007F1010A0490AAEB0700019044E063 +:10167000012F00DA01270021112F01DD112000E0E8 +:101680003846CDE9000106A90EA8FFF7A1FCDDE967 +:101690000F010E9A0391002104910092BA4621078E +:1016A0000CD40399514500DA8A46BAF1010F05DDE1 +:1016B000009AAAF10101515C302908D0B84202DA3F +:1016C00010F1040F06DA0121CDE9011015E0AAF1AD +:1016D0000101E9E7002805DC049901440491AAEB23 +:1016E000000102E0411C514500DD8A460499401A80 +:1016F000401C01904FF000400290200704D4019854 +:10170000504501DBCDF8048000208DF84F00029891 +:101710000DF14F07B0F1004F25D02B200E9002980D +:101720004FF0020800280CDA404202902D200E9063 +:1017300007E00A210298FEF752FF3031029007F8C5 +:10174000011DB8F10001A8F10108F2DC029800289F +:10175000EFD1791E0E980870307800F0200040F02C +:10176000450007F8020D12A8C01B00F107081498E5 +:10177000007800B1012000EB0A01019801EBE07153 +:1017800005984144401A401E0590E00306D45B468C +:101790002146179A059800F05DF8054414980078E2 +:1017A00018B15A46179990476D1CE00324D55B4643 +:1017B0002146179A059800F04DF805441CE004985E +:1017C000002807DBDDE90301884203DD0098405C67 +:1017D000179901E0179930205A469047049805F16F +:1017E0000105401C04900198401E019004D12E2058 +:1017F0005A46179990476D1CBAF10001AAF1010AE7 +:10180000DDDC05E017F8010B5A46179990476D1C6F +:10181000B8F10001A8F10108F4DC5B462146179AF3 +:101820000598ABE62D0000002B0000002000000012 +:101830002DE9F041044600251E461746880404D4CD +:1018400005E039462020B0476D1C641EF9D52846B6 +:10185000BDE8F0812DE9F041044600251E46904682 +:10186000C80301D5302700E02027880404D505E00F +:1018700041463846B0476D1C641EF9D52846BDE880 +:10188000F08100002DE9FE4F07460E460025684610 +:1018900000F048FF00246FF00F0AE8464FF00109FE +:1018A00057F8240056F82410401A00D54042FEF79D +:1018B0000DFE5146FEF78CFD58F8241011F0FF4F35 +:1018C0000BD0FEF747FD4FF07E51FEF70BFD0A49A6 +:1018D00020F00040884205DC07E008490844084938 +:1018E000884202D309FA04F00543641C032CD7DBB9 +:1018F0002846BDE8FE8F0000295C0F3E666666C183 +:101900009A99D9002DE9F04D8D4F21F0004A86B00B +:1019100005460C46BA452ADBAAEB070028430AD045 +:101920008848824501DC1AD1CDB106B02846BDE811 +:10193000F04DFFF724BB844A844B2846FEF754FD44 +:1019400007460E46824A834B28462146FEF74CFD49 +:1019500006B03A463346BDE8F04DFEF72BBF0120F6 +:10196000FFF730FB06B0BDE8F04DFFF70DBB7A483E +:10197000824542DABAF1795F0BDA2846FFF796FA28 +:10198000042808BFFFF706FB284606B02146BDE83D +:10199000F08D2A460B461046FEF726FD834602468A +:1019A0006E480E460B4606217844FFF793FA5A46D6 +:1019B0003346FEF719FD804669488A465A46334643 +:1019C00004217844FFF786FA5A463346FEF70CFDA9 +:1019D00000223B46FEF7EEFE02460B4640465146CD +:1019E000FEF78FFF2A462346FEF7FEFC06B02A4686 +:1019F0002346BDE8F04DFEF7DDBE284624F0004149 +:101A000000223D463B46FEF779FF4FF0FF32FEF7DE +:101A1000E7FF0646024653480F460B460621784428 +:101A2000FFF758FA32463B46FEF7DEFCCDE90001EF +:101A30004D4832463B4604217844FFF74BFA324684 +:101A40003B46FEF7D1FC00222B46FEF7B3FE834651 +:101A500002913046394603F00FFC804643480D465C +:101A6000504517DCDDE900015A46029BFEF749FFAD +:101A700042462B46FEF7B8FC42462B46FEF79AFE3E +:101A80000122FEF7ADFF304A304BFEF734FF304AFB +:101A9000304B4CE04FF0000A52460B464046FEF7F2 +:101AA00089FECDE9031052462B4610461946FEF733 +:101AB0009BFC32463B46FEF721FFDDE90332FEF791 +:101AC00020FF06460F46DDE900015A46029BFEF75D +:101AD00018FF83460091012230463946FEF780FF09 +:101AE000194A1A4BFEF70AFF06460F4601224046E6 +:101AF0002946FEF775FF5A46009BFEF775FC3246F5 +:101B00003B46FEF7F8FE06460F46012250462946A0 +:101B1000FEF766FF0E4DDFF858802A464346FEF773 +:101B2000EDFE32463B46FEF7E9FE2A464346FEF707 +:101B3000E5FE002CD8BF81F0004106B0BDE8F08D75 +:101B40000000F03F0000F07F075C143326A6913CB4 +:101B5000182D4454FB21F93F0000E03F9C47000052 +:101B6000B2470000264700003C4700003333EF3FF8 +:101B7000FB21E93F2DE9F84F04460D4621F00040D6 +:101B800000917349814211DC7249884201DC06D11F +:101B90002CB120462946BDE8F84FFFF7F0B96E4852 +:101BA000002DCCBF6D496E49BDE8F88F6D4981426B +:101BB00011DD6D498142D8BF4FF0FF366DDD204603 +:101BC0002946FFF773F9042808BFFFF7E3F9204619 +:101BD0002946BDE8F88F6549654F25F000458142EB +:101BE00033DD6449814219DD002632464FF08043DF +:101BF00020462946FEF7DEFD80468A460122204621 +:101C00002946FEF7EDFE00223B46FEF774FE4246F3 +:101C10005346FEF776FE04460D463EE001260022BE +:101C2000BA463B4620462946FEF7C4FD80460F468D +:101C30000022534620462946FEF75DFE42463B46BB +:101C4000FEF75FFE04460D4627E04B4981421BDD4F +:101C5000DFF828A102260022534620462946FEF737 +:101C6000C3FB00223B46FEF7A5FD80460F4600223F +:101C7000534620462946FEF73EFE42463B46FEF7C7 +:101C800040FE04460D4608E0032622462B4600206F +:101C90003B49FEF736FE04460D4622462B461046CB +:101CA0001946FEF7A1FB8B46824602460B46FEF71D +:101CB0009BFB07460246334888460B46062178447C +:101CC000FFF708F952465B46FEF78EFB82462E4828 +:101CD0008B463A46434605217844FFF7FBF83A46DF +:101CE0004346FEF781FB02460B46002E50465946FE +:101CF0000CDAFEF75FFD22462B46FEF775FB01B0BE +:101D000022462B46BDE8F04FFEF7F8BDFEF752FD28 +:101D100022462B46FEF768FB1C4A7A4402EBC603B8 +:101D2000D3E90023FEF7E7FD22462B46FEF7E3FD4D +:101D3000174A7A4402EBC603D3E90023FEF7DEFD1F +:101D4000009A002AB8BF81F00041BDE8F88F00007A +:101D5000000010440000F07F182D4454FB21F93F8F +:101D6000FB21F9BF0000DC3F0000203E0000F33FF4 +:101D70000000F03F0000E63F008003400000F83F15 +:101D80000000F0BF3E450000FC4400009A44000003 +:101D9000624400002DE9F04D9446CCF1000423F09C +:101DA00000464CEA0404524F46EAD4749A468846E8 +:101DB00021F00042BC4206D8454240EA050442EA0E +:101DC000D474BC4204D9BDE8F04D6246FFF7DAB8DE +:101DD000AAF14055A5F17F6555EA0C040BD0022409 +:101DE00004EAAA74434DDFF810E144EAD87452EAD9 +:101DF000000B04D00CE0BDE8F04DFFF7BBBE002C9B +:101E000014BF012CBDE8F08D022C30D0032C32D051 +:101E100056EA0C0B0AD0BE4220D1BA4209D126F0B4 +:101E2000804622F080423346114617E000291ADB33 +:101E300025E0DFF8C8B0FB44002C04BFDBE900015B +:101E4000BDE8F08D012C02BFDBE9000181F000410B +:101E5000BDE8F08D022C0AD0032C0CD0BA4212D16E +:101E6000B8F1000F0BDA23482549BDE8F08D28466C +:101E70002449BDE8F08D28467146BDE8F08D1D4827 +:101E80002149BDE8F08D921B12153C2AC4BF1948A8 +:101E90001D490EDCBAF1000FBEBF12F13C0F00204D +:101EA000014606DB6246FEF72CFD21F00041FFF7FC +:101EB00061FE002C08BFBDE8F08D012C04BF81F04D +:101EC0000041BDE8F08D114A114B022C07D0FEF7FE +:101ED00012FD2A46BDE8F04D0A4BFEF70CBDFEF799 +:101EE0000AFD2A46BDE8F04D064BFEF707BD00008F +:101EF0000000F07F182D4454FB2109C0F643000078 +:101F0000FB21F9BFFB210940FB21F93F075C14339A +:101F100026A6A13C014601A0FEF7B8BF257300002C +:101F20000249486048680028FCD170472000002022 +:101F300003484168002902D04168491E416070474A +:101F40002000002008B560B120208DF80000282076 +:101F50008DF8010030208DF8020038208DF8030044 +:101F600004E0A32204216846FEF74BF96A460421E7 +:101F700040F69E2002F0FAFF02F088FB08BD000048 +:101F80003EB5044602208DF80000CA208DF80100FD +:101F9000E3208DF8020009208DF803006A46042131 +:101FA000682002F0E3FFA3208DF80000610609D548 +:101FB000C0218DF80110C8218DF80210C2218DF8C2 +:101FC000031005E08DF801008DF802008DF8030084 +:101FD00014F4C07F09D0C4218DF80410CC218DF8F1 +:101FE0000510C6218DF8061005E08DF804008DF867 +:101FF00005008DF806008DF808008DF807008DF8B3 +:1020000009006A460A2140F6A72002F0AFFFA007A8 +:102010004FF0D80503D020208DF8000001E08DF8A6 +:1020200000506A46012140F6B62002F09FFFA0064C +:1020300001D5012000E0002000F08EF814F4C07FEC +:102040001ED0E0050AD5B2208DF800008B208DF857 +:102050000100B6208DF802009B2009E0B0208DF829 +:10206000000080208DF80100B4208DF8020090203F +:102070008DF803006A46042140F6A22002F076FFA4 +:10208000E1074FF40B6022D0F8218DF800106A466A +:10209000012102F06BFFFA21072000F07BFA0720F4 +:1020A00000F047FA012000F064FA642000F006FB1B +:1020B0004FF4FA7000F012FBC821254800F001FA35 +:1020C000282000F016FA0A2000F023FA05E08DF827 +:1020D00000506A46012102F049FFA00703D5D9202C +:1020E0008DF8000001E08DF800506A46012140F2B1 +:1020F0003D7002F03BFF600701D5012000E00020A9 +:1021000000F048F8E00601D5012000E00020FFF7CC +:1021100019FF104D44F00800688102F0B7FA002062 +:10212000A873600601D50620A87314F4C07F02D0FE +:10213000A87B801DA87314F0140F02D0A87B103068 +:10214000A873A00702D0A87B001DA87300203EBD85 +:1021500009E3CA02C00000200EB54FF4976310B126 +:1021600006A107C901E008A207CA8DE807006A4670 +:102170000921184602F0FAFE0EBD0000B8AAB38D80 +:10218000B4980D355D000000B8AAAAAAB088C3C5EE +:10219000C700000008B560B1C0208DF80000C22063 +:1021A0008DF80100C4208DF80200C6208DF80300D0 +:1021B00004E08B2204216846FEF723F86A460421D6 +:1021C00040F6982002F0D2FE02F060FA08BD00004E +:1021D000024989890180002070470000C00000206A +:1021E00038B504004FF0FF3506D06A4604214FF49D +:1021F000587002F0F3F908B1284638BD00989DF8F0 +:10220000031000BA20F0FF0008432060002038BD12 +:1022100038B504004FF0FF3506D06A4604214FF46C +:10222000717002F0DBF908B1284638BD00989DF8BE +:10223000031000BA20F0FF00084300EB800080008C +:102240002060002038BD0000C8234FF4806202499E +:1022500040F6F63001F066BF505500082DE9FF4FFB +:1022600089B01746DDE9165200244C4E8846814657 +:102270002C80A246B07B694602F068F94FF0FF3B24 +:1022800018B158460DB0BDE8F08F708910F0140FEA +:102290003CD0009909BA21F0FF039DF803100B43CD +:1022A0003B6001991B1409BA21F0FF029DF8071049 +:1022B0005B430A437A6002999DF80B4009BA21F00A +:1022C000FF012143B960039C091424BA24F0FF0CD8 +:1022D0009DF80F4012144CEA040CC7F80CC04FEAEA +:1022E0002C47494302FB023207FB0711114410241B +:1022F000A1F17061B1F1007F04D902F0C7F9A5F82E +:1023000000A0BEE7298841F4807129804206694611 +:1023100011D50A19A41D13885BBAA8F80030538898 +:102320005BBAA8F80230928852BAA8F804202A882A +:1023300042F008022A8010F4C07F11D00A19A41DAF +:1023400013885BBAA9F8003053885BBAA9F8023049 +:10235000928852BAA9F804202A8842F070022A8092 +:10236000800716D00C44E07800F0C00500F03F0173 +:102370006078C00706D0C80801F007013268491C20 +:1023800002B190476078000703D5716809B1A809C8 +:1023900088470C9800F0A6FB002073E7C0000020DF +:1023A0000149486000207047C000002001490860D2 +:1023B00000207047C000002030B5044613A285B04D +:1023C00007CA8DE807004FF0FF35C82C16D8C82083 +:1023D000B0FBF4F1491E080A8DF80C008DF80D10C1 +:1023E00003AA022140F2162002F0C0FD30B96A466D +:1023F0000C2140F6C12002F0B9FD10B1284605B00D +:1024000030BD054884810020F9E70000FEF2ABC42E +:10241000AAF1DFDFBBAFDFDFC000002000B50EA1F7 +:1024200087B00EC98DE80E000EA10DF10C0C0EC97F +:102430008CE80E0040F68223012807D0022803D042 +:102440004FF0FF3007B000BD6A4600E003AA0B2141 +:10245000184602F08BFDF5E7D8B1B9F38BA391B61E +:1024600009B4D900DAB1B9F38BA391B6DAB4DA00C2 +:1024700008B5010E8DF80010010C8DF80110010A4D +:102480008DF802108DF803006A4604214FF458704D +:1024900002F06CFD08BD1421B0FBF1F008B5010E8F +:1024A0008DF80010010C8DF80110010A8DF8021052 +:1024B0008DF803006A4604214FF4717002F056FD56 +:1024C00008BD4FF47A7290FBF2F008B54843010E54 +:1024D0008DF80010010C8DF80110010A8DF8021022 +:1024E0008DF803006A4604214FF4AE7002F03EFD01 +:1024F00008BD0521B0FBF1F008B5010A8DF8001008 +:102500008DF801006A4602214FF4AD7002F02EFDF5 +:1025100008BD0521B0FBF1F008B5010A8DF80010E7 +:102520008DF801006A4602214FF4AC7002F01EFDE6 +:1025300008BD08B500218DF80010C10702D0302178 +:102540008DF80010810705D59DF8001041F00C01B1 +:102550008DF80010400705D59DF8000040F00300FD +:102560008DF800006A4601214FF4A47002F0FEFCD1 +:1025700008BD08B560B1042800D90420401E8DF8BC +:1025800000006A46012140F24F1002F0EFFC08BD46 +:102590000120F3E72DE9FC41054640074FF0FF36E7 +:1025A0007CD0B1F5C86F79D80846FDF798FF3E4951 +:1025B000FDF7D0FE074601A801F05AF89DF8040087 +:1025C000022806D004280DD008282ED0102865D166 +:1025D00034E00E213846FDF7FBFEFDF79EFF84B286 +:1025E000324907E00D213846FDF7F2FEFDF795FF71 +:1025F0002F4984B23846FDF77BFEFDF78EFF210A96 +:102600008DF8001080B28DF80140010A8DF802109B +:102610008DF80300E8076C4620D0224602214FF4D3 +:10262000EA7002F0A3FCC8BB11E00C213846FDF7AC +:10263000CFFEFDF772FF84B21E49DBE70B2138465F +:10264000FDF7C6FEFDF769FF84B21B49D2E7A21C65 +:1026500002214FF4927002F089FCF8B9A8070DD559 +:102660006A4602214FF4EC7002F080FCB0B9A21C63 +:1026700002214FF4947002F079FC78B9680710D504 +:102680006A4602214FF4EE7002F070FC30B9A21CD1 +:1026900002214FF4967002F069FC10B13046BDE89B +:1026A000FC810020FBE7000000004843000040469A +:1026B0000000C045000040450000C0440521B0FBBB +:1026C000F1F008B5010A8DF800108DF801006A4696 +:1026D00002214FF4EF7002F049FC08BD0521B0FB68 +:1026E000F1F008B5010A8DF800108DF801006A4676 +:1026F00002214FF4ED7002F039FC08BD70B5084DB1 +:102700000446C1B2284602F0BDFE40F207763146CB +:10271000284602F0D8FE0028F9D0204670BD0000FF +:10272000004400402DE9FE430646264801AB042242 +:1027300040680D21007800F091FC10B10720BDE841 +:10274000FE839DF804101C2000EAD1029DF80710BA +:10275000DFF87490C1F301131A438DF800209DF83F +:102760000520C1F3810300EAD2021A438DF801204B +:102770009DF8062001F0030100EAD200084300247E +:10278000124F8DF80200A0466D46285D10B146F844 +:1027900024900AE046F824800DE000BF56F824009B +:1027A0003946FDF7A5FD46F82400285D401E10F0CF +:1027B000FF002855F2D1641CE4B2032CE5D30020BD +:1027C000BDE700003C0000207B14AE3E1D5A843F54 +:1027D0002DE9FE4F05460120C14E8DF800004FF057 +:1027E00000088DF8018030680C461746417D7068FE +:1027F0006B460222007800F06BFC4FF0FF3A002895 +:102800007AD1C820FFF78CFB8DF8008030686B46CA +:102810000122417C7068007800F05AFC0028EFD15A +:1028200030686B46012241797068007800F050FCF6 +:102830000028E5D130686B460122417D7068007840 +:1028400000F046FC0028DBD130686B460122817E17 +:102850007068007800F03CFC0028D1D130686B46ED +:10286000012201797068007800F032FC0028C7D19D +:102870004FF00C098DF8009030686B460122017909 +:102880007068007800F024FC002835D10F20FFF795 +:1028900047FBB06A6B460122407A8DF80000306831 +:1028A00081787068007800F013FC002824D1B06AA9 +:1028B0006B460122007A8DF800003068417870681C +:1028C000007800F005FC002873D1B06A807A0FB15F +:1028D00040F0E0008DF8000030686B4601228179FD +:1028E0007068007800F0F4FB002862D12FB1B06A64 +:1028F000C07A40F0E00001E04AE018208DF80000C6 +:1029000030686B460122C1797068007800F0E0FB06 +:10291000F0BB17B1C820FFF703FB40208DF8000083 +:1029200030686B46012201797068007800F0D0FBB6 +:1029300070BB78208DF8000030686B460122417929 +:102940007068007800F0C4FB10BB3220FFF7E8FA93 +:102950008DF80080306847466B46417970680122E7 +:10296000007800F0B5FB98B931687068B046097B13 +:1029700000786B46022200F071FB48B9BDF80000F8 +:10298000AF6040BAB0FBF9F06F60C6B22F6000E0F4 +:102990000FE0A76067602760002739E0D8F80010D3 +:1029A000D8F804006B46497B00780C2200F056FBF7 +:1029B00010B15046BDE8FE8FBDF80000236840BA54 +:1029C00002B2BDF80200BDF804101A44226040BAF9 +:1029D000626800B21044606049BAA06809B2084455 +:1029E000A060BDF806002B6840BA02B2BDF808002E +:1029F0001A4440BA01B2BDF80A002A606A6840BAB7 +:102A000011446960A96800B208447F1CFFB2A86045 +:102A1000B742C3D328688322C117090441EA104191 +:102A200000040023FDF7BCFB32460023FDF7B8FB92 +:102A3000286068688322C117090441EA1041000434 +:102A40000023FDF7ADFB32460023FDF7A9FB6860CC +:102A5000A8688322C117090441EA10410004002339 +:102A6000FDF79EFB32460023FDF79AFBA860206825 +:102A70004FF40065C117090441EA104100042A46D9 +:102A80000023FDF78DFB32460023FDF789FB206014 +:102A900060682A46C117090441EA10410004002376 +:102AA000FDF77EFB32460023FDF77AFB6060A068ED +:102AB0002A46C117090441EA104100040023FDF72A +:102AC0006FFB32460023FDF76BFBA060002802DDA0 +:102AD000A0F5803001E000F58030A060002069E7BB +:102AE0003C00002001490968016070472000002077 +:102AF000F0B5036A446A002501260F2706FA05FC93 +:102B00001CEA020F09D04FEA850C07FA0CFE23EAF3 +:102B10000E0301FA0CFE4EEA03036D1CADB2082D44 +:102B2000ECD3082506FA05FC1CEA020F0BD04FEA8D +:102B3000850CACF1200C07FA0CFE24EA0E0401FA15 +:102B40000CFE4EEA04046D1CADB2102DEAD30362F4 +:102B50004462F0BD81627047816170472DE9F047A2 +:102B600040F21156304602F031FB771C384602F035 +:102B70002DFB01234FF0904800221946404600F0FB +:102B8000CAF8DFF880914FF4007423460022012137 +:102B9000484600F0C0F865102B4600220121484647 +:102BA00000F0B9F8202300220121484600F0B3F8D4 +:102BB000102300220121484600F0ADF80123032232 +:102BC0000021404600F0CAF823460322002148466F +:102BD00000F0C4F82B4603220021484600F0BEF85E +:102BE000202303220021484600F0B8F810230322D6 +:102BF0000021484600F0B2F801214046FFF7AAFF45 +:102C000021464846FFF7A6FF29464846FFF7A2FFA0 +:102C100020214846FFF79EFF10214846FFF79AFF04 +:102C2000304602F0D3FAB41C204602F0CFFA00225C +:102C300010231146404600F06EF8AB01324D0022E1 +:102C40001146284600F067F8384602F0BFFA40F215 +:102C5000157002F0BBFA402201214846FFF748FFF9 +:102C6000802201214846FFF743FF40230122022131 +:102C7000484600F050F8402303220121484600F066 +:102C80006DF8802301220221484600F044F8802399 +:102C900003220121484600F061F8304602F096FA1E +:102CA000384602F093FA204602F090FA00224FF4E0 +:102CB00000431146284600F02EF80223002201218D +:102CC000404600F028F84FF480642346002201219A +:102CD000484600F020F8022303220021404600F07D +:102CE0003DF8234603220021484600F037F8022130 +:102CF0004046FFF72FFF21464846BDE8F047FFF763 +:102D000029BF00000004004800080048006908408E +:102D100000D0012070472DE9F047894601689246AE +:102D2000C268002401274FF0030C07FA04F51D4286 +:102D30000BD066000CFA06F5A943AA4309FA06F877 +:102D40000AFA06F548EA01012A43641CA4B2102CD1 +:102D5000EBD30160C260BDE8F0870000F0B5012947 +:102D6000416819D0994341608168002401274FF0E0 +:102D7000030C00BF07FA04F61E4207D066000CFAE7 +:102D800006F521EA050502FA06F12943641CA4B2FE +:102D9000102CEFD38160F0BD1943E4E72DE9F84F23 +:102DA00081462E488846002540686B4603220078FD +:102DB0000D2100F053F910B10720BDE8F88F9DF800 +:102DC0000000002400F01F008DF800009DF80100B5 +:102DD0006FF00F0B00F01F008DF801009DF802004E +:102DE0006E4600F01F008DF802004FF0010A00BF90 +:102DF00059F8241058F82400081A00D54042FDF76D +:102E000065FB5946FDF7E4FA0746305DC0B114484A +:102E100002E01449FDF76CFA315D491E11F0FF0123 +:102E20003155F6D101463846FDF794FA4FF07E5100 +:102E3000FDF758FA0C4920F00040884205DC07E015 +:102E40000A483844B0F1D97F02D90AFA04F00543A0 +:102E5000641C032CCCDB2846AFE700003C000020BC +:102E60000000C84154E3853F295C0F3E0000E0BEEE +:102E70000129016803D021F480610160704741F4A9 +:102E80008061FAE70029016803D021F40061016044 +:102E9000704741F40061FAE770B5044616460D46E6 +:102EA000022002F0DDF8254BB0FBF3F13F2900D3FF +:102EB0003F21626822F03F020A436260204A954245 +:102EC00010D8B0FBF3F1491C3F2900D33F21216208 +:102ED0006900B0FBF1F0042800D20420E169C0F3DE +:102EE0000B0028E0174A954227D84FF496725143B9 +:102EF0004FF47A72B1FBF2F1491C216266B105EB25 +:102F0000C50101EB0511B0FBF1F0E16941F480412D +:102F1000E161010508D009E005EB4501B0FBF1F0E6 +:102F2000E16921F48041F3E740F00100E16941F4F7 +:102F30000041E161E1690143E16170BD40420F0080 +:102F4000A0860100801A060010B50C4C4FF4804298 +:102F500009492046FFF7A0FF0022242311462046FE +:102F600000F05DF8204600F010F82046BDE8104063 +:102F70000121FFF77DBF0000801A060000540040C9 +:102F80000069C0B2704701617047016841F00101FA +:102F900001607047024601F00043002089B2B3F19E +:102FA000004F04D052690A4200D001207047926954 +:102FB000F9E742688A434260704742680A434260C8 +:102FC0007047022903D042698A43426170474169D0 +:102FD0008069704710B5426802F40073426811F0CE +:102FE000FF0F02F4807206D02BB1CA0607D14268E7 +:102FF00002F4806202E011F47F4F05D022B14069F3 +:10300000084000D0012010BD002010BD921C03D04C +:1030100041F001010161704721F00101FAE710B5AB +:10302000046824F002040C4304601A43826010BD5B +:1030300010B54FF4C06002F009F8032200211720F8 +:1030400001F0BEFF02220021BDE81040202001F067 +:10305000B7BF1346012200F001B8000070B5144C50 +:1030600000256570FF2525704000E070A170E360C9 +:103070002271012060710F4D4FF4E0612846FFF787 +:103080009CFF2079022803D100212846FFF7FAFE91 +:10309000094E28463146FFF77DFF0028F9D1284622 +:1030A00000F00CF820790028FCD194F9000070BDE4 +:1030B000280000200054004002000080016841F414 +:1030C000807101607047016841F4007101607047D0 +:1030D00070B5104C01256570FF2626704000E07029 +:1030E000A170A360227165710B4D4FF4E061284619 +:1030F000FFF763FF094E28463146FFF74BFF0028D4 +:10310000F9D12846FFF7DAFF20790028FCD194F99D +:10311000000070BD28000020005400400200008024 +:103120002DE9F0472E4D814600274FF090444FF493 +:1031300080784FF4007601212046FFF70DFD4146CF +:103140002846FFF707FD4846FEF7EAFE31462846C7 +:10315000FFF702FD01212046FFF7FCFC4846FEF781 +:10316000DFFE41462846FFF7F7FC31462846FFF7C9 +:10317000F1FC4846FEF7D4FE7F1C062FDBDB002760 +:1031800001212046FFF7E8FC31462846FFF7E4FC22 +:1031900041462846FFF7E0FC20212846FFF7DCFCEB +:1031A00010212846FFF7D8FC4846FEF7B9FE01215A +:1031B0002046FFF7CFFC31462846FFF7CBFC4146BF +:1031C0002846FFF7C7FC20212846FFF7C3FC102143 +:1031D0002846FFF7BFFC7F1C022FD1DBBDE8F0873C +:1031E0000004004802F096F8FFF7B8FC424E4FF496 +:1031F0001641304602F0E4F8FFF7A6FEFFF718FF8D +:103200006420FFF78DFF00F095F93C4C002500B1DC +:103210002570682000F078FBDFF8E4A040F2057B21 +:103220004FF032084FF4804901270120FEF778FE65 +:10323000207801280BD001214FF09040FFF78CFC43 +:103240005946304602F03FF9012804D012E04FF40D +:1032500000715046F2E7304602F010F9C1B26170D9 +:103260000A2907D00D2905D026A0FDF70FFE6078AA +:1032700000F04AFB2078012801D100F017FA6268BB +:10328000B2FBF8F108FB112020B92078012801D108 +:1032900000F0F4FF10214FF09040FFF737FD58B1D8 +:1032A000A77020215046FFF757FC1AA0FEF732FE08 +:1032B0003220FEF735FE04E0A57020215046FFF7CE +:1032C00049FC49461948FFF721FD58B1E770102124 +:1032D0005046FFF741FC16A0FEF71CFE3220FEF719 +:1032E0001FFE04E0E57010215046FFF733FC6068D4 +:1032F000401C606099E7000000440040040000208A +:1033000000040048436F6D6D616E64203D202563AD +:103310000A0000002D2D2053454E534F52203120DE +:10332000416374697665202D2D0A0000000800486D +:103330002D2D2053454E534F522032204163746946 +:103340007665202D2D0A000040B1012808D0022802 +:1033500008D0032808D105A0FEF7DCBD08A0FBE7D4 +:1033600004A0F9E709A0F7E7704700005265766509 +:10337000727365204C616E6473636170650A00004E +:10338000506F7274726169740A000000526576654C +:1033900072736520506F7274726169740A00000064 +:1033A0002DE9FC5F5F4CE068FDF790F86FF01D05BC +:1033B0002946FDF70DF800902069FDF787F82946AA +:1033C000FDF706F881466069FDF780F82946FCF7AD +:1033D000FFFF8046A069FDF779F82946FCF7F8FF62 +:1033E000064641460846FCF783FF054649460190DC +:1033F0000846FCF77DFF2946FCF722FF0121FCF778 +:10340000E7FF4FF07E51FCF770FFFDF7B9F8074674 +:103410000D4631464046FCF76BFF82464946009810 +:10342000FCF766FF5146FCF70BFF0121FCF7D0FFCC +:10343000FDF7A6F83A462B46FEF7ACFCFDF7B3F8CD +:10344000834649463046FCF753FF054641460098FF +:10345000FCF74EFF2946FCF745FF0121FCF7B8FFBA +:10346000FDF78EF8FEF74EFAFDF79DF882463146DD +:103470000846FCF73DFF01460198FCF7E1FE0121FB +:10348000FCF7A6FF4FF07E51FCF72FFFFDF778F811 +:1034900007460D4641464846FCF72AFF804631461E +:1034A0000098FCF725FF4146FCF7CAFE0121FCF716 +:1034B0008FFFFDF765F83A462B46FEF76BFCFDF7EC +:1034C00072F805465846FDF75BF8174E174F32461F +:1034D0003B46FCF789FFDFF8588000224346FCF7A3 +:1034E00083FFFDF72EF8A0835046FDF749F83246DA +:1034F0003B46FCF779FF00224346FCF775FFFDF7DA +:1035000020F8E0832846FDF73BF832463B46FCF7BF +:103510006BFF00224346FCF767FFFDF712F820849B +:10352000BDE8FC9F9C000020F8C1631ADCA54C405C +:103530000000594070B51EA0FEF7ECFC00F094FDB1 +:103540004FF0FF3508B121A017E0782001F082FB91 +:10355000782000F063F8142001F03CFB1F4C03209E +:1035600000216070A1706161E1601DA02161FEF722 +:10357000D1FCFEF769FE20B11EA0FEF7CBFC284669 +:1035800070BD2148FEF712FF2048FEF709FFF32027 +:103590002083FEF7F5FC1420FEF70EFF012001F05A +:1035A0003FFA0120A0701AA0FEF7B4FC002070BD05 +:1035B0002D2D20436F6E6669677572696E67204DA9 +:1035C0005055363035302E2E2E2000004641494CC5 +:1035D00020284D5055292E0A0000000070000020C0 +:1035E0002077726974696E6720444D502E2E2E200C +:1035F00000000000204641494C2028444D5029201D +:103600002D2D0D0A00000000F94E00084933000876 +:10361000204F4B202D2D0D0A000000002DE9F04118 +:10362000124C20F00101002594F8240010B1002074 +:10363000BDE8F081A07A4FF0FF3668B10840277CE2 +:103640002074884200D0354641B1012001F0E8FDE8 +:1036500001F01CF838B127743046E9E7207D00B14D +:10366000012001F0DDFD2846E2E700003C000020DB +:103670000D494A7A42B1012A08D0022A0FD0032A02 +:103680000FD04FF0FF307047022200E0042202709A +:10369000C97C11B11106C90D0170002070470822C4 +:1036A000F5E71022F3E700003C0000202DE9F0418F +:1036B00052488CB000260168406809AAC97C00788D +:1036C000FFF7C7FC9DF824004D4D80074FF001081F +:1036D00001D085F8048008A8FFF704FA2969089842 +:1036E000814203D200F5FA70012628612879444C02 +:1036F00000272C34F0B3A878E0B30AA906A8CDE9D6 +:10370000000107ABA4F1100204A902A8FEF7A6FD70 +:103710009DF8280000B92F71BDF8180010F0700F47 +:1037200015D0BDF808002080BDF80A006080BDF803 +:103730000C00A0805EB1314807A9001F00F0A6F878 +:103740002E486421001F0068484300146084BDF9BE +:103750001800010708D5BDF81010E180BDF812105F +:103760002181BDF814106181C0050DD524481C309D +:10377000016800E00BE0E1604168216181686161FE +:10378000C068A061FFF70CFE0CB0BDE8F08128799D +:103790000028F9D02F710AA8009005AB07AA03A949 +:1037A00001A800F023FE9DF8280008B185F80480E8 +:1037B0009DF8140010F0700F12D0BDF804002080A6 +:1037C000BDF806006080BDF80800A08046B107A9DA +:1037D00006A800F05BF80698642148430014608452 +:1037E0009DF814000007CFD5BDF80C00E080BDF8AF +:1037F0000E002081BDF810006081C5E73C0000206C +:10380000700000200B49097A39B1012907D002293B +:103810000AD003290BD0002103E0FA2101E04FF484 +:10382000FA710180002070474FF47A71F9E74FF484 +:10383000FA61F6E73C0000200C49C97A072913D247 +:10384000DFE801F01204060A0C0E1000BC2100E0B3 +:1038500062210180002070472A21FAE71421F8E74D +:103860000A21F6E70521F4E70021F2E73C000020F9 +:10387000054991F8242012B14FF0FF307047C989F3 +:1038800001800020704700003C000020F8B51C4C6F +:1038900006460F46A07A4FF0FF3540B120686B46D0 +:1038A0000222017C60680078FFF7D8FB08B1284647 +:1038B000F8BDBDF8000040BA05B217B13846FFF7B1 +:1038C00011F96468E088FCF70AFE0746B4F90800BD +:1038D000FCF7FCFD04462846FCF7F8FD2146FCF702 +:1038E00001FD3946FCF736FD0649FCF7A9FC10211D +:1038F000FCF76EFDFCF7F8FD30600020F8BD00001D +:103900003C00002000000C4238B5724C6528A178BC +:1039100062696DD026DC33286BD009DCA0F12C0065 +:10392000072867D2DFE800F0D19AD09A9BA3B200B3 +:10393000684B38285B7874D00DDC342869D0352882 +:1039400058D100294FF0640068D0FEF735FD0028FB +:1039500050D161A00DE3392866D061287ED182F074 +:1039600001007AE001256638122877D2DFE800F0FE +:10397000B1670976767676767676736A63B0707616 +:10398000AFAE5AA0FEF7C6FA66A0FEF7C3FA6BA068 +:10399000FEF7C0FA72A0FEF7BDFA79A0FEF7BAFAF8 +:1039A0007EA0FEF7B7FA85A0FEF7B4FA8AA0FEF76C +:1039B000B1FA90A0FEF7AEFA98A0FEF7ABFAA0A07D +:1039C000FEF7A8FAA5A0FEF7A5FAA9A0FEF7A2FAAD +:1039D000AFA0FEF79FFAB6A0FEF79CFABCA0FEF7D8 +:1039E00099FAC3A0FEF796FACAA0FEF793FA02E08E +:1039F0002BE05AE032E0D2A0FEF78CFAD9A0FEF715 +:103A000089FADDA0FEF786FAE2A0FEF783FA01E06C +:103A100007E051E2E8A0FEF77DFA00E05CE2F4A0E6 +:103A2000A7E283F0010001E083F002006070BDE8CE +:103A3000384001F06BB9BDE8384000F0F9BD82F0C4 +:103A400002000AE082F0040007E082F0080004E0CF +:103A500082F0100001E082F02000606138BD00209B +:103A6000FEF706FD0020FEF716FDEFA081E24FF005 +:103A70000A0029B1FEF7A0FC0028EFD1F0A078E2FF +:103A800001F0A8F80028E9D1F2A072E24FF014008A +:103A900029B1FEF791FC0028E0D1F3A069E201F022 +:103AA00099F80028DAD1F5A063E24FF0280029B197 +:103AB000FEF782FC0028D1D1F5A05AE201F08AF885 +:103AC0000028CBD1F7A054E20EE20BE24FE241E234 +:103AD00061E20EE270000020444D502073657420B6 +:103AE000746F2031303020487A2E0A003D3D3D3D34 +:103AF0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D2013 +:103B000048454C5020434F4D4D414E4453203D3D80 +:103B10003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DD5 +:103B20003D0A0000683A205072696E742048656C46 +:103B30007020636F6D6D616E64730A00383A2053B4 +:103B4000657420416363656C65726F6D6574657241 +:103B50002073656E736F72206F6E2F6F66660A003A +:103B6000393A20536574204779726F73636F7065BB +:103B70002073656E736F72206F6E2F6F66660A001A +:103B8000723A205072696E74205265676973746569 +:103B900072732076616C75650A000000613A2050EE +:103BA00072696E7420416363656C65726F6D6574D4 +:103BB000657220646174610A00000000673A205059 +:103BC00072696E74204779726F73636F70652064D9 +:103BD0006174610A00000000713A205072696E74CD +:103BE000205175617465726E696F6E2064617461D5 +:103BF0000A000000653A205072696E742045756CA9 +:103C0000657220616E676C657320696E20646567FC +:103C1000726565202A203130300A0000743A205045 +:103C200072696E742054656D706572617475726529 +:103C300020696E2064656743202A203130300A00F5 +:103C4000703A205072696E74205065646F6D6574AF +:103C5000657220646174610A00000000303A2052ED +:103C600065736574205065646F6D657465720A00D4 +:103C7000313A2053657420444D502F4D50552066E5 +:103C800072657175656E637920313020487A0A005B +:103C9000323A2053657420444D502F4D50552066C4 +:103CA00072657175656E637920323020487A0A003A +:103CB000333A2053657420444D502F4D50552066A3 +:103CC00072657175656E637920343020487A0A0018 +:103CD000343A2053657420444D502F4D5055206682 +:103CE00072657175656E637920353020487A0A00F7 +:103CF000353A2053657420444D502F4D5055206661 +:103D000072657175656E63792031303020487A0AAA +:103D1000000000002C3A2053657420444D50206967 +:103D20006E7465727275707420746F206765737439 +:103D3000757265206576656E74206F6E6C790A0009 +:103D40002E3A2053657420444D5020696E7465727C +:103D50007275707420746F20636F6E74696E756F06 +:103D600075730A00663A2053657420444D50206FE5 +:103D70006E2F6F66660A0000763A205365742051F4 +:103D800075617465726E696F6E206F6E2F6F6666F7 +:103D90000A000000773A2054657374206F75742010 +:103DA0006C6F772D706F77657220616363656C202F +:103DB0006D6F64650A000000733A2052756E2073BF +:103DC000656C662D74657374202864657669636517 +:103DD000206D75737420626520666163696E67206B +:103DE0007570206F7220646F776E290A00000000E2 +:103DF0003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DF3 +:103E00003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DE2 +:103E10003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3DD2 +:103E20003D3D3D3D3D0A00005065646F6D65746524 +:103E30007220726573657420646F6E652E0A0000CF +:103E4000444D502073657420746F20313020487ABF +:103E50002E0A00004D50552073657420746F203178 +:103E60003020487A2E0A0000444D5020736574209B +:103E7000746F20323020487A2E0A00004D505520B1 +:103E800073657420746F20323020487A2E0A000047 +:103E9000444D502073657420746F20343020487A6C +:103EA0002E0A00004D50552073657420746F203425 +:103EB0003020487A2E0A00004FF0320031B1FEF770 +:103EC0007BFA00287FF4CAAD35A052E000F082FEF4 +:103ED0000028F7D137A04CE000F07CFE0028F1D19B +:103EE00039A046E0012000E00220BDE83840FEF79E +:103EF00095BA20780028E5D1F9B10025A5702846AB +:103F000000F08EFD6078C10700D00825810701D53B +:103F100045F07005400701D545F001052846FFF73B +:103F20007DFB6846FEF754F9BDF8000000F052FE34 +:103F30002AA000BFFDF7EEFF38BDA5706846FFF769 +:103F400097FCBDF80000FEF737FA012000F068FD8D +:103F500026A0EFE7208B80F010002083FEF710F8FA +:103F6000207EC00601D425A003E02BA001E021B1F2 +:103F70002FA0BDE83840FDF7CDBF142000F022F996 +:103F8000002000F0BFFD607820F0060040F0010046 +:103F90006070257038BDBDE8384000F007BF0000F4 +:103FA000444D502073657420746F20353020487A5A +:103FB0002E0A00004D50552073657420746F203513 +:103FC0003020487A2E0A00004D5055207365742029 +:103FD000746F2031303020487A2E0A00444D502032 +:103FE00064697361626C65642E0A0000444D502060 +:103FF000656E61626C65642E0A0000004C50207191 +:1040000075617465726E696F6E2064697361626C4C +:1040100065642E0A000000004C50207175617465C3 +:10402000726E696F6E20656E61626C65642E0A0047 +:104030005761726E696E673A20466F72206C6F77B7 +:104040002D706F776572206D6F64652C20444D5024 +:10405000206E6565647320746F20626520646973E7 +:1040600061626C65642E0A007CB52D4C80208DF851 +:10407000000020686B460122417D60680078FFF7F0 +:1040800027F84FF0FF36E8BB6420FDF749FF002515 +:104090008DF8005020686B460122417D60680078F1 +:1040A000FFF716F870BBE574FF20A07204F8080F44 +:1040B000310C6070E070E1802072A07201202071EC +:1040C000A0761748E5766573001F257340F81A5FE0 +:1040D0004560856025776577E5834FF4FA6000F0E9 +:1040E000DBFC78B9022000F0F9FB58B92A2000F077 +:1040F0003BFD38B9322000F06DFD18B90020FFF704 +:104100008DFA00E004E018B9002000F01BFC08B1B3 +:1041100030467CBD002000F09DFD00207CBD0000ED +:104120003C0000202DE9FF4FDFF89480064685B063 +:1041300098F8250015460F464FF0FF39B0BBAFB3D6 +:10414000002420E0301B102800DD102080B28346C0 +:104150003A1901469246204600F008FF30BB6A46F5 +:104160005946204600F03AFA00BB50465A46694686 +:10417000FCF759F820B16FF0010009B0BDE8F08FED +:1041800004EB0B0084B2B442DCD3280A8DF8100093 +:104190008DF81150D8F80000444604AB417FD8F8A0 +:1041A000040002220078FEF793FF08B14846E4E7D6 +:1041B000012084F825000898E0840020DDE7000055 +:1041C0003C0000202DE9F84305464FF0FF39282830 +:1041D00044D80727284C00267DB1012000F092FC2E +:1041E00020208DF800004FF00108012D17D0052D7B +:1041F00018D88DF8018005201FE0002000F082FC17 +:104200008DF800608DF8017020686B460222417DB8 +:1042100060680078FEF75CFF00BB267529E08DF82A +:104220000160E8E7142D04D802208DF801000A206F +:1042300003E003208DF80100142000F095FC9DF8A8 +:1042400001006B4607EB80108DF801002068022208 +:10425000417D60680078FEF73BFF10B14846BDE83D +:10426000F8830820A072267384F814800020FFF7DA +:10427000D5F90020F3E700003C0000203EB52B4DAF +:1042800005F12C04287DC00708D0B4F90A30B4F930 +:104290000820B4F9061026A0FCF7F8FD287D800759 +:1042A00008D5B4F90430B4F90220B4F9001028A0FC +:1042B000FCF7ECFD287D400707D5A069009004F1CC +:1042C0000C012AA00EC9FCF7E1FD287D000708D5E6 +:1042D000B4F92030B4F91E20B4F91C102DA0FCF75D +:1042E000D5FD287DC00604D5B4F9221031A0FCF715 +:1042F000CDFD287D800618D501A8FEF7F3FBE968FF +:104300000198814211D200F57A70E8606846FDF7A5 +:1043100067FF02A8FDF77CFF02984FF47A71B0FBAB +:10432000F1F229A00099FCF7B1FD3EBD700000201C +:10433000416363656C5B58595A5D3A2009202564D6 +:1043400020092025642009202564200A000000009F +:104350004779726F5B58595A5D3A200920256420CD +:10436000092025642009202564200A005175617404 +:104370005B5758595A5D3A200920256C6420092062 +:10438000256C64200920256C64200920256C64209C +:104390000A00000045756C65725B5250595D3A2009 +:1043A0000920256420092025642009202564200A8D +:1043B0000000000054656D70657261747572653A35 +:1043C000202564200A00000057616C6B656420257D +:1043D0006C6420737465707320696E20256C642092 +:1043E0007365636F6E64732E2E0A00002DE9FF4F14 +:1043F000814655488846002490F8241083B01E4614 +:1044000025464FF0FF3BD1BB00213170817AB1B31B +:10441000017CA1B34A0600D502248A0600D5A41C5B +:10442000CA0600D5A41C090700D5A41D0168824650 +:104430004068097B6B4600780222FEF70FFEF0B958 +:10444000BDF8000047BAA7427BD3DAF804205088B1 +:10445000B7EB500F14D9DAF800006B46C17C107826 +:104460000122FEF7FBFD50B99DF80000C00607D5FC +:1044700000F00CF96FF0010007B0BDE8F08F0DE01F +:104480000598FEF72FFBDAF80010DAF804006B4607 +:10449000497B00782246FEF7E1FD08B15846EBE77C +:1044A000B7FBF4F01099401E087000203070ECB398 +:1044B0009AF8101050460A07694613D5BDF8002037 +:1044C000062552BAA8F80020BDF8022052BAA8F872 +:1044D0000220BDF8042052BAA8F80420327842F035 +:1044E00008023270A5420CD0027C520609D54A1946 +:1044F000AD1C128852BAA9F80020327842F040026E +:104500003270A5420CD0027C920609D54A19AD1C26 +:10451000128852BAA9F80220327842F02002327092 +:10452000A5420ED09AF81000C00600E009E008D5B8 +:104530004819008840BAA9F80400307840F010000B +:104540003070002098E700003C0000202DE9F8437F +:10455000214C0646174694F8240089464FF0FF3850 +:1045600090B3A07A80B320686B460222017B60681A +:104570000078FEF773FD38BBBDF8000045BAB542C0 +:1045800002D2002038701FE060684188B5EB510FFF +:1045900011D9216800786B46C97C0122FEF75EFDC7 +:1045A00090B99DF80000C00605D500F06FF86FF0D7 +:1045B0000100BDE8F8832068F2B24B46417B606899 +:1045C0000078FEF74BFD08B14046F2E7B5FBF6F088 +:1045D000401E38700020ECE73C000020F8B51600C3 +:1045E0000D464FF0FF371FD0104CA17AE1B1010A00 +:1045F0008DF80010C0B28DF8010041196068428941 +:10460000914211D8216800786B46C97E0222FEF7DC +:104610005FFD48B92068EAB23346017E60680078E1 +:10462000FEF71CFD002800D03846F8BD3C000020F5 +:1046300038B50024104D18E029684A7BA24212D0F8 +:10464000097EA1420FD000786B4601222146FEF779 +:1046500005FD10B14FF0FF3038BD9DF80020214618 +:1046600006A0FCF713FC641CE4B268680179A1425F +:10467000E2D8002038BD00003C000020252335781A +:104680003A20252335780D0A00000000F8B5564C75 +:104690004FF0FF36A07A00287DD000258DF800501D +:1046A00020686B460122417C60680078FEF710FDAF +:1046B000002870D120686B4601224179606800783B +:1046C000FEF706FD002866D120686B4601220179BD +:1046D00060680078FEF7FCFC00285CD194F82400A8 +:1046E000E0B30C208DF8000020686B4601220179B0 +:1046F00060680078FEF7ECFC002872D13220FDF7EC +:104700000FFCC0208DF80000A07AC00702D0E02086 +:104710008DF8000020686B460122017960680078FE +:10472000FEF7D6FC00285CD1607C18B102208DF821 +:10473000000001E08DF8005020686B460122417CAA +:1047400060680078FEF7C4FC28BB8DF80050206834 +:104750006B4601224179606800783EE0FFE7042063 +:104760008DF8000020686B460122017960680078AE +:10477000FEF7AEFC78B9A07C90B9A07AC0070FD044 +:104780005FF060008DF8000020686B46012201791F +:104790006068007800E024E0FEF79AFC08BB01E0C6 +:1047A0004020EFE73220FDF7BBFB607C18B1012011 +:1047B0008DF8000001E08DF8005020686B46012262 +:1047C000417C60680078FEF783FC50B92068064B96 +:1047D00001224179606810330078FEF779FC0028E7 +:1047E00000D03046F8BD00003C0000202DE9F04725 +:1047F000394C82468AB094F82400894620B10020C2 +:1048000000F00EF9012600E0002607A8FEF7FAFFE7 +:1048100006A8FEF72DFF09A8FFF70EF808A8FFF776 +:1048200027F894F80A80277C002500224946504644 +:10483000FDF7CEFF10B16D1C022DF6DB022D1AD054 +:104840000025012203A96846FDF7C2FF10B16D1CC7 +:10485000022DF6DB022D0ED003A94846FDF712F813 +:10486000C5B269465046FEF799FA10F0FF0F4FF0B7 +:10487000000002D002E0002505E001200DB940F063 +:10488000020040F00405FF2020726072E0724FF6D3 +:10489000FF71E181A072207401202073BDF81C001B +:1048A00000F0FAF89DF8180000F018F8BDF82400A0 +:1048B00000F05AF9BDF8200000F08CF9404600F0F5 +:1048C000C9F93846FEF7AAFE16B1012000F0A8F893 +:1048D0000AB02846BDE8F0873C00002038B5184CE7 +:1048E0004FF0FF35A17A19B3022806D0042806D06C +:1048F00008280ED010281BD10DE0002000E0082071 +:104900008DF80000607A9DF80010B0EBD10F04D054 +:1049100005E01020F4E71820F2E7002038BD2068F9 +:104920006B460122C17960680078FEF7D1FB08B1BF +:10493000284638BD9DF80000C0086072EDE7000011 +:104940003C000020F8B5354C0546A07CA84201D1BA +:104950000020F8BD31484FF0FF366B46D0E900101B +:104960004FF001020979007835B3FEF777FB70BB91 +:104970009DF800006B4620F020008DF800002068B4 +:104980000122017960680078FEF7A2FBF8B90320E4 +:10499000FDF7C6FA02208DF8000094F8220078B3E3 +:1049A00082202BE020686B460122C17D6068007880 +:1049B000FEF78EFB58B92EE0FEF750FB38B9A07A0F +:1049C000C0079DF8000003D040F0200002E00CE09A +:1049D00020F020008DF8000020686B46012201794C +:1049E00060680078FEF774FB08B13046F8BD03201C +:1049F000FDF796FA94F8220000B180208DF80000AF +:104A000094F823000028CDD09DF8000040F030003D +:104A10008DF80000C6E7A5749AE700003C0000206E +:104A200038B51C4C94F8241081421DD0002500B3E9 +:104A300094F82500D0B1002000F0F2FB0020FFF731 +:104A400081FFE08C00F0C6F88DF8005060686B467E +:104A5000012200782321FEF73BFB012084F824008B +:104A600000F0DEFBFFF712FE002038BD4FF0FF30F4 +:104A700038BD002000F0D4FB207C8DF80000606879 +:104A80006B46012200782321FEF722FB84F8245094 +:104A9000E8E700003C00002038B5194C4FF0FF3526 +:104AA000A17A31B3FA2809D0B0F5FA7F08D0B0F571 +:104AB0007A7F0FD0B0F5FA6F1BD10DE0002000E037 +:104AC00008208DF80000207A9DF80010B0EBD10F7F +:104AD00004D005E01020F4E71820F2E7002038BDEC +:104AE00020686B460122817960680078FEF7F0FA51 +:104AF00008B1284638BD9DF80000C0082072EDE7D7 +:104B00003C00002038B5174C054694F82300A84215 +:104B100001D1002038BD0DB1302000E000208DF81B +:104B20000000A07C28B19DF8000040F002008DF844 +:104B3000000094F8220028B19DF8000040F08000A9 +:104B40008DF8000020686B460122C17D6068007806 +:104B5000FEF7BEFA10B14FF0FF3038BD84F8235095 +:104B6000D7E700003C00002038B5194C4FF0FF3566 +:104B7000A17A31B3BC2801D3012010E0622801D30F +:104B800002200CE02A2801D3032008E0142801D3D6 +:104B9000042004E00A2801D3052000E006208DF857 +:104BA0000000E07A9DF80010884201D1002038BD55 +:104BB00020686B460122817860680078FEF788FAE9 +:104BC00008B1284638BD9DF80000E072EEE700000D +:104BD0003C000020F8B51E4D04464FF0FF37A87A80 +:104BE00048B395F8240030BB287D4FF47A7648B15D +:104BF00064B1282C03D82046FFF7E4FA26E0002011 +:104C0000FFF7E0FA042C05D2042406E00020FFF7A9 +:104C1000D9FAF9E7B44200D93446B6FBF4F0401EA5 +:104C20008DF8000028686B4601224178686800789A +:104C3000FEF74EFA08B13846F8BD9DF80000401C5A +:104C4000B6FBF0F0E8814008FFF78EFF0020F8BDCA +:104C50003C000020F8B5054610F0700F4FF000063C +:104C600001D0012004E015B18DF8006002E0402081 +:104C70008DF80000244C6B4601222068417D60685D +:104C80000078FEF725FA4FF0FF3760BB9DF8000073 +:104C900020F0400020738DF80060680602D40420E4 +:104CA0008DF80000A80605D49DF8000040F0020031 +:104CB0008DF80000E80605D49DF8000040F00100E2 +:104CC0008DF80000280705D49DF8000040F038005A +:104CD0008DF8000020686B460122817D60680078B5 +:104CE000FEF7F6F910B1A6723846F8BD25B1082DC9 +:104CF00002D00020FFF706FFA57226753220FDF7CF +:104D00000FF90020F8BD00003C000020F8B5124E5D +:104D1000002425467078C00702D008240FA000E0C8 +:104D200013A0FDF7F7F87078800704D544F07004FD +:104D3000357814A000E018A0FDF7ECF82046FFF746 +:104D400089FF2046FEF76AFC002D04D00020307059 +:104D50006846FEF78DFDF8BD700000204163636575 +:104D60006C2073656E736F72204F6E2E0A00000008 +:104D7000416363656C2073656E736F72204F666666 +:104D80002E0A00004779726F2073656E736F722070 +:104D90004F6E2E0A000000004779726F2073656E17 +:104DA000736F72204F66662E0A0000002DE9F041F5 +:104DB0008AB007A904A8FFF719FD0446072802D006 +:104DC000E0074ED050E02EA0FDF7A4F80998FBF7BD +:104DD0007DFB6FF00F084146FBF7FAFAFBF7D0FBBB +:104DE00006460F460898FBF771FB4146FBF7F0FAC1 +:104DF000FBF7C6FB04460D460798FBF767FB4146E9 +:104E0000FBF7E6FAFBF7BCFB8DE8F00002460B4629 +:104E10001EA0FCF73BF80698FBF758FB4146FBF752 +:104E2000D7FAFBF7ADFB06460F460598FBF74EFB9E +:104E30004146FBF7CDFAFBF7A3FB04460D46049869 +:104E4000FBF744FB4146FBF7C3FAFBF799FB8DE800 +:104E5000F00002460B4614A0FCF718F80AB0BDE8B3 +:104E6000F08118A0FDF756F8A00702D419A0FDF7AD +:104E700051F86007F2D41BA0FDF74CF8EEE70000F4 +:104E8000506173736564210A00000000616363650B +:104E90006C3A2025372E34662025372E346620259F +:104EA000372E34660A0000006779726F3A20253782 +:104EB0002E34662025372E34662025372E34660A98 +:104EC000000000004779726F206661696C65642E8E +:104ED0000A000000416363656C206661696C65646B +:104EE0002E0A0000436F6D70617373206661696CF8 +:104EF00065642E0A0000000010B50C46072818D281 +:104F0000DFE800F01704060F1113150009A000E0F8 +:104F10000AA0FCF7FFFF2146BDE8104009A0FBF7FF +:104F2000B5BF0AA0F5E70BA0F3E70CA0F1E70DA0D1 +:104F3000EFE710BD54617020582B200054617020A1 +:104F4000582D2000782025640A000000546170204C +:104F5000592B200054617020592D2000546170207D +:104F60005A2B2000546170205A2D2000F8B51600ED +:104F70000D464FF0FF371FD0104CA17AE1B1010A66 +:104F80008DF80010C0B28DF80100411960684289A7 +:104F9000914211D8216800786B46C97E0222FEF743 +:104FA00097F848B92068EAB23346017E6068007815 +:104FB000FEF78EF8002800D03846F8BD3C000020EF +:104FC00070B5214B00252C461E68C6F30226072E1D +:104FD00014D01E68C6F30226062E11D01E68C6F332 +:104FE0000226052E0FD01E68C6F30226042E0DD011 +:104FF0001B68C3F30223032B0BD00BE0042409E04E +:105000000125032406E002252C4603E003250124A4 +:1050100000E00425C5F104039940C4F104040F2302 +:10502000E34013400B4300F1E022190182F8001421 +:1050300000F01F02012191404009800000F1E020B2 +:10504000C0F8001170BD00000CED00E002490843FB +:1050500002490860704700000000FA050CED00E00E +:105060002DE9F04751A688B05ACE8DE85A0050A3DA +:105070008046D3E90013CDE904134DA10020D1E906 +:105080000031CDE906314D4B0546024659684C4E7C +:10509000C1F3810119B1012901D0022901D03146A2 +:1050A00017E059685C68C1F38341C4F3C0640CB174 +:1050B000113100E0891C5C68C4F300443CB1DC6A37 +:1050C00004F00F04641CB6FBF4F4614301E03D4CB2 +:1050D00061435C68C4F303141DF8047021FA07F4FB +:1050E0005F680DF1100CC7F302271CF8077024FA53 +:1050F00007F95F680DF1180CC7F3C2274FF4004A97 +:105100001CF8077024FA07F7B8F1070F06D2DFE89A +:1051100008F004080A0C0E293100084608B0BDE862 +:10512000F0872046FAE74846F8E73846F6E7186B76 +:10513000C00501D4244D13E05868C0F3813030B16C +:10514000012806D0022806D0032809D107E07D08EF +:1051500006E0BD0804E00620B7FBF0F500E0FD081E +:105160002846DBE7186B400602D448F21200D5E768 +:105170005046D3E7186B80070ED0186B00F0030081 +:1051800001280BD0186B00F00300022808D0186B20 +:10519000C043800706D006E03A4604E00A4602E033 +:1051A000524600E032461046B8E70000000000001A +:1051B0000000000001020304060708090010024075 +:1051C00000127A0000093D00809FD500054901EBDF +:1051D00090110A6800F01F030120984002430A6002 +:1051E0007047000000100240054901EB90110A6869 +:1051F00000F01F030120984082430A6070470000BE +:1052000000100240054901EB90110A6800F01F03ED +:105210000120984002430A607047000000100240DD +:10522000F8B5144C0146224694F82460D2E90002F5 +:1052300000235D1E56B179B1022111E0417C107846 +:105240006B460122FDF744FF68B90EE0A67A56B11D +:1052500011B1617C61B902E08DF80030EEE7012107 +:105260008DF80010EAE72846F8BD9DF8000060744C +:105270000020F8BD3C0000202DE9F04106460F4615 +:10528000FBF729FC041E0D4618BF0120284320F01F +:105290000040C0F17F6000F1E040C00F0ED0301C34 +:1052A00018BF0120384320F00040C0F17F6000F1BA +:1052B000E040C00F04BF0120FBF784FE20462946D2 +:1052C000BDE8F08110484168416041684160416833 +:1052D000416041680D4A1140416041680C4A1143E8 +:1052E0004160016841F08071016001688901FCD56D +:1052F000416821F003014160416841F002014160D1 +:1053000041680907FCD5704700100240FFFFC2F753 +:105310000000040870B50E484FF47A710068B0FBC5 +:10532000F1F0401EB0F1807F11D24FF0E0246061B7 +:1053300065170F212846FBF75BFD0020A0610720C1 +:1053400020612846BDE870400021FBF751BDFEE713 +:105350000000002002480168491C016070470000FD +:105360002000002070B50D46044614490020611845 +:1053700004D0B1F5744F04D1062000E00220FFF7FD +:105380006FFE21684FF6F07209040BD5400000EB68 +:105390005500B0FBF5F000EA0201C0F3420241EA19 +:1053A000020008E000EB5500B0FBF5F101EA020055 +:1053B00001F00F010843E06070BD000000BCFFBFBA +:1053C0002DE9F047894605462949002429488D42A0 +:1053D00002D0854200D1012440F21150FFF7F6FEC1 +:1053E000254830F81400FFF7F1FE234E4FF09048A7 +:1053F000361D012156F824204046FDF779FB06F1C1 +:105400000807012157F824204046FDF771FB56F8A4 +:105410002430012202214046FDF77DFC56F824305D +:10542000012200214046FDF799FC57F82430012263 +:1054300002214046FDF76FFC57F82430012200217D +:105440004046FDF78BFC284600F020F849462846E8 +:10545000FFF788FF0821284600F048F80421284675 +:1054600000F03CF82846BDE8F04700F027B80000FF +:1054700000380140004400400C000020406AC0F3A6 +:1054800008007047C1F30801816270470A4910B5EE +:10549000401805D0B0F5744F0CD140F20E3401E045 +:1054A00040F211442046FFF7ADFE2046BDE8104013 +:1054B000FFF79ABE10BD000000BCFFBF016841F0BD +:1054C00001010160704700EB9110006801F01F02BC +:1054D00001219140084000D001207047026822F06D +:1054E0000402026002680A4302607047026822F008 +:1054F0000802026002680A430260704775191A0CBC +:105500006A231B1C00001F207274433B4138393A48 +:10551000006B6C376F06246D6E70680000047600B7 +:105520005401F7FD000100008300000000080000A6 +:105530000001001832000500000020410000D242A6 +:10554000295C0F3E9A99993E3333733F295C0F3E95 +:1055500000007000000000240000000200030000B2 +:1055600000650054FFEF0000FA80000B128200017A +:10557000030C30C30E8C8CE914D5400213710F8ECE +:105580003883F8833000F883258EF8833000F88361 +:10559000FFFFFFFF0FFEA9D6240004001A8279A1A5 +:1055A0000000003CFFFF00000010000038836FA2E5 +:1055B000003E03304000000002CAE3093E800000C4 +:1055C000200000000000000040000000600000001B +:1055D000000C0000000C186E000006920A16C0DFD6 +:1055E000FFFF0256FD8CD377FFE1C496E0C5BEAA4B +:1055F00000000000FFFF0B2B0000165700000359AE +:105600004000000000001DFA00026C1D00000000B8 +:105610003FFFDFEB003EB3B6000D227800002F3CC9 +:1056200000000000001942B5000039A20000B36577 +:10563000D90E9FC91DCF4C3430000000500000002F +:105640003BB67AE80064000000C8000000000000DB +:10565000100000001000FA921000225E000D229F40 +:105660000001000000320000FF46000063D400008B +:105670001000000004D6000004CC000004CC0000A0 +:105680000000107200000040000000000000000058 +:105690000006000200050007000000000064000092 +:1056A000000000000000000500050064002000006C +:1056B00000000000000000000000400000000300A7 +:1056C00000000032F8980000FF650000830F000022 +:1056D000FF9BFC0000000000000000000000000034 +:1056E00000000000000000000000000000000000BA +:1056F000000000000000000000000000000010009A +:1057000040000000000000060000B26A0002000035 +:105710000001FB830068000000D9FC007CF1FF83DE +:105720000000000000650000006403E80064002839 +:10573000000000250000000016A00000000010007E +:1057400000001000002F0000000001F40000100015 +:1057500000280000FFFF4581FFFFFA7200000000F3 +:1057600000000000004400050005BAC6004778A20A +:10577000000000010000000000000600000000140E +:105780000000254D002F706D000005AE000C02D00A +:105790000000000000000000000000000000000009 +:1057A000001B0000000000000000000000000000DE +:1057B000006400000008000000000000000000007D +:1057C00000000000000000000000000000000000D9 +:1057D00000000000000000000000000000000000C9 +:1057E00000000000000000000000000000000000B9 +:1057F00000000000000000000000000000000000A9 +:105800000000000000000000000000000000000098 +:10581000001B00000000000000000000000E000E51 +:1058200000000AC70004000000000032FFFFFF9CD8 +:1058300000000B2B000000020000000100000064CB +:10584000FFE5000000000000000000000000000074 +:105850000000000100000000000100000000000046 +:10586000000180000001800000018000002426D398 +:105870000000000000000000000600100096003C40 +:105880000000000000000000000000000000000018 +:105890000C0A4E68CDCF770950166759C619CE82CB +:1058A00000000000000000000000000000000000F8 +:1058B000000000000000000017D784000300000073 +:1058C0000000000000000000C7938F9D1E1B1C19E4 +:1058D00000000000000000000000000000000000C8 +:1058E00000000000000000000203188500004000D6 +:1058F00000000003000000030000000000000000A2 +:105900004000000000000000000000000000000057 +:105910000000000000000000000000000000000087 +:105920000000000000000000000000000000000077 +:1059300000000000677DDF7E72902E554CF6E688F1 +:105940000000000000000000000000000000000057 +:10595000D8DCB4B8B0D8B9ABF3F8FAB3B7BB8E9E05 +:10596000AEF132F51BF1B4B8B08097F1A9DFDFDFFB +:10597000AADFDFDFF2AAC5CDC7A90CC92C97F1A910 +:1059800089264666B28999A92D557DB0B08AA89618 +:10599000365676F1BAA3B4B280C0B8A89711B283D4 +:1059A00098BAA3F0240844106418B2B9B49883F1EB +:1059B000A329557DBAB5B1A38393F0002850F5B261 +:1059C000B6AA839328547CF1B9A3829361BAA2DA70 +:1059D000DEDFDB819AB9AEF5606870F1DABAA2DF7A +:1059E000D9BAA2FAB9A38292DB31BAA2D9BAA2F883 +:1059F000DF85A4D0C1BBAD83C2C5C7B8A2DFDFDFDE +:105A0000BAA0DFDFDFD8D8F1B8AAB38DB4980D35CE +:105A10005DB2B6BAAF8C96198F9FA70E161EB49AB8 +:105A2000B8AA872C547CBAA4B08AB691325676B202 +:105A30008494A4C808CDD8B8B4B0F19982A82D55E3 +:105A40007D98A80E161EA22C547C92A4F02C50789F +:105A5000F184A898C4CDFCD80DDBA8FC2DF3D9BAED +:105A6000A6F8DABAA6DED8BAB2B68696A6D0F3C839 +:105A700041DAA6C8F8D8B0B4B882A892F52C5488F8 +:105A800098F135D9F418D8F1A2D0F8F9A884D9C77B +:105A9000DFF8F883C5DADF69DF83C1D8F40114F1D8 +:105AA000A8824EA884F311D182F5D992289788F163 +:105AB00009F41C1CD884A8F3C0F9D1D99782F12924 +:105AC000F40DD8F3F9F9D1D982F4C203D8DEDF1A84 +:105AD000D8F1A2FAF9A88498D9C7DFF8F8F883C7F3 +:105AE000DADF69DFF883C3D8F40114F198A8822EB5 +:105AF000A884F311D182F5D992509788F109F41C4A +:105B0000D884A8F3C0F8F9D1D99782F149F40DD817 +:105B1000F3F9F9D1D982F4C403D8DEDFD8F1AD8826 +:105B200098CCA809F9D98292A8F57CF1883ACF944B +:105B30004A6E98DB6931DAADF2DEF9D88795A8F2C2 +:105B400021D1DAA5F9F417D9F1AE8ED0C0C3AE8257 +:105B5000C684C3A88595C8A588F2C0F1F4010EF1EA +:105B60008E9EA8C63E56F554F18872F40115F19840 +:105B700045856EF58E9E0488F142985A8E9E068861 +:105B800069F4011CF1981E1108D0F504F11E97026A +:105B900002983625DBF9D985A5F3C1DA85A5F3DFAF +:105BA000D88595A8F309DAA5FAD88292A8F578F1F4 +:105BB000881A849F26889821DAF41DF3D8879F39A4 +:105BC000D1AFD9DFDFFBF9F40CF3D8FAD0F8DAF96A +:105BD000F9D0DFD9F9D8F40BD8F3879F39D1AFD9F1 +:105BE000DFDFF41DF3D8FAFCA869F9F9AFD0DADEEB +:105BF000FAD9F88F9FA8F1CCF398DB45D9AFDFD065 +:105C0000F8D8F18F9FA8CAF38809DAAF8FCBF8D8FC +:105C1000F2AD978D0CD9A5DFF9BAA6F3FAF412F21A +:105C2000D8950DD1D9BAA6F3FADAA5F2C1BAA6F37E +:105C3000DFD8F1BAB2B68696A6D0CAF349DAA6CBB7 +:105C4000F8D8B0B4B8D8AD84F2C0DFF18FCBC3A818 +:105C5000B2B68696C8C1CBC3F3B0B48898A821DB8E +:105C6000718D9D71859521D9ADF2FAD88597A828B7 +:105C7000D9F408D8F28D29DAF405D9F285A4C2F254 +:105C8000D8A88D9401D1D9F411F2D88721D8F40A7B +:105C9000D8F28498A8C801D1D9F411D8F3A4C8BB0C +:105CA000AFD0F2DEF8F8F8F8F8F8F8F8D8F1B8F66E +:105CB000B5B9B08A95A3DE3CA3D9F8D85CA3D9F8CE +:105CC000D87CA3D9F8D8F8F9D1A5D9DFDAFAD8B1B8 +:105CD0008530F7D9DED8F830ADDADED8F2B48C9959 +:105CE000A32D557DA083DFDFDFB591A0F629D9FB79 +:105CF000D8A0FC29D9FAD8A0D051D9F8D8FC51D9CC +:105D0000F9D879D9FBD8A0D0FC79D9FAD8A1F9F97A +:105D1000F9F9F9A0DADFDFDFD8A1F8F8F8F8F8AC84 +:105D2000DEF8ADDE8393AC2C547CF1A8DFDFDFF628 +:105D30009D2CDAA0DFD9FADB2DF8D8A850DAA0D054 +:105D4000DED9D0F8F8F8DB55F8D8A878DAA0D0DF9B +:105D5000D9D0FAF8F8F8F8DB7DF8D89CA88CF530A3 +:105D6000DB38D9D0DEDFA0D0DEDFD8A848DB58D9B9 +:105D7000DFD0DEA0DFD0DED8A868DB70D9DFDFA0FF +:105D8000DFDFD8F1A888902C547C98A8D05C38D15B +:105D9000DAF2AE8CDFF9D8B087A8C1C1B188A8C645 +:105DA000F9F9DA36D8A8F9DA36D8A8F9DA36D8A85F +:105DB000F9DA36D8A8F9DA36D8F78D9DADF818DAC1 +:105DC000F2AEDFD8F7ADFA30D9A4DEF9D8F2AEDE04 +:105DD000FAF983A7D9C3C5C7F1889BA77AADF7DEC7 +:105DE000DFA4F8849408A797F300AEF29819A4886A +:105DF000C6A39488F632DFF28393DB09D9F2AADFD7 +:105E0000D8D8AEF8F9D1DAF3A4DEA7F1889B7AD816 +:105E1000F38494AE19F9DAAAF1DFD8A881C0C3C51A +:105E2000C7A39283F628ADDED9F8D8A350ADD9F830 +:105E3000D8A378ADD9F8D8F8F9D1A1DADEC3C5C7AF +:105E4000D8A18194F818F2B089ACC3C5C7F1D8B80D +:105E5000B4B09786A8319B069907AB9728889BF02A +:105E60000C201440B0B4B8F0A88A9A285078B79B98 +:105E7000A8295179247059446938644831F1BBAB81 +:105E800088002C547CF0B38BB8A804285078F1B06B +:105E900088B49726A85998BBABB38B02264666B048 +:105EA000B8F08A9CA82951798B2951798A24705994 +:105EB0008B2058718A4469388B3940688A6448312C +:105EC0008B30496088F1AC002C547CF08CA80428FD +:105ED0005078F1889726A85998AC8C02264666F02F +:105EE000899CA8295179247059446938644831A99A +:105EF0008809205970AB11384069A8193148608C65 +:105F0000A83C415C207C00F187981986A86E767EBB +:105F1000A999882D557DD8B1B5B9A3DFDFDFAED003 +:105F2000DFAAD0DEF2ABF8F9D9B087C4AAF1DFDF7F +:105F3000BBAFDFDFB9D8B1F1A3978E60DFB084F2D9 +:105F4000C8F8F9D9DED89385F14AB183A308B5839F +:105F50009A0810B79F10D8F1B0BAAEB08AC2B2B6E4 +:105F60008E9EF1FBD9F41DD8F9D90CF1D8F8F8AD13 +:105F700061D9AEFBD8F40CF1D8F8F8AD19D9AEFB65 +:105F8000DFD8F416F1D8F8AD8D61D9F4F4ACF59CF6 +:105F90009C8DDF2BBAB6AEFAF8F40BD8F1AED0F880 +:105FA000AD51DAAEFAF8F1D8B9B1B6A3839C08B90D +:105FB000B1839AB5AAC0FD3083B79F10B58B93F219 +:105FC0000202D1ABDADED8F1B080BAABC0C3B28482 +:105FD000C1C3D8B1B9F38BA391B609B4D9ABDEB0C4 +:105FE000879CB9A3DDF1B38B8B8B8B8BB087A3A37D +:105FF000A3A3B28BB69BF2A3A3A3A3A3A3A3A3A320 +:10600000A3F1B087B59AA3F39BA3A3DCBAACDFB925 +:10601000A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A350 +:10602000D8D8D8BBB3B7F1AAF9DAFFD9809AAA2891 +:10603000B48098A720B79787A86688F07951F19027 +:106040002C870CA781976293F07171608594012968 +:10605000517990A5F1284C6C870C95188578A3830D +:1060600090284C6C886CD8F3A28200F210A8921988 +:1060700080A2F2D926D8F188A84DD948D896A83957 +:1060800080D93CD89580A839A68698D92CDA87A7DC +:106090002CD8A8899519A980D938D8A88939A98078 +:1060A000DA3CD8A82EA83990D90CD8A8953198D91F +:1060B0000CD8A809D9FFD801DAFFD89539A9DA2672 +:1060C000FFD890A80D8999A810809821DA2ED88938 +:1060D00099A83180DA2ED8A886963180DA2ED8A8F1 +:1060E000873180DA2ED8A88292F34180F1D92ED858 +:1060F000A882F31980F1D92ED882ACF3C0A28022F5 +:10610000F1A62EA72EA92298A829DAACDEFFD8A2E4 +:10611000F22AF1A92E8292A8F23180A696F1D90036 +:10612000AC8C9C0C30ACDED0DEFFD88C9CACD0109C +:10613000ACDE8092A2F24C82A8F1CAF235F19688C8 +:10614000A6D900D8F1FF0000555555555555C53F06 +:106150007D6FEB0312D6D4BF5544880E55C1C93F9D +:106160003B8F68B52882A4BF88B20175E0EF493F34 +:1061700009F7FD0DE13D023F4B2D8A1C273A03C074 +:10618000C88A599CE52A004059018D1B6C06E6BF60 +:1061900082922EB1C5B8B33F4FBB610567ACDD3FFE +:1061A000182D4454FB21E93F9BF681D20B73EF3F3E +:1061B000182D4454FB21F93FE2652F227F2B7A3CB6 +:1061C000075C143326A6813CBDCBF07A8807703C6F +:1061D000075C143326A6913CC4EB98999999C9BFE2 +:1061E000711623FEC671BCBF6D9A74AFF2B0B3BF17 +:1061F0009AFDDE522DDEADBF2F6C6A2C44B4A2BFD7 +:106200000D5555555555D53FFF8300922449C23F42 +:106210006E204CC5CD45B73F513DD0A0660DB13F76 +:10622000EB0D76244B7BA93F11DA22E33AAD903F88 +:10623000000000000000000058620008000000207C +:1062400070000000A40F0008C86200087000002061 +:1062500060040000B40F000800A24A04010000001E +:10626000000000000E0611070002000004000000FC +:106270000004000008000000000000000000000012 +:10628000000000000000000000000000000000000E +:1062900000000000FC5400081A550008000000002F +:1062A00000000000000000000000000000000000EE +:1062B0000000000000000000000000002855000859 +:0862C0000000000000000000D6 +:040000050800016985 +:00000001FF diff --git a/build/VARIANT_HOVERBOARD/firmware.axf b/build/VARIANT_HOVERBOARD/firmware.axf new file mode 100644 index 0000000..b617357 Binary files /dev/null and b/build/VARIANT_HOVERBOARD/firmware.axf differ diff --git a/build/VARIANT_HOVERBOARD/firmware.hex b/build/VARIANT_HOVERBOARD/firmware.hex new file mode 100644 index 0000000..f1e80e2 --- /dev/null +++ b/build/VARIANT_HOVERBOARD/firmware.hex @@ -0,0 +1,1436 @@ +:020000040800F2 +:10000000080500207D010008870D0008150B000879 +:10001000850D0008110B0008210E000800000000EB +:10002000000000000000000000000000AB0D000810 +:10003000130B000800000000A90D0008AD0D00081A +:100040009701000897010008970100089701000830 +:100050009701000897010008970100089701000820 +:100060009701000897010008970100089701000810 +:100070009701000897010008970100089701000800 +:100080009701000897010008000000009701000890 +:100090009701000897010008970100081B0B000852 +:1000A00097010008970100089701000897010008D0 +:1000B0009701000800000000970100080000000000 +:1000C000170B0008000000009701000897010008C6 +:1000D0009701000897010008970100080000000040 +:1000E00000000000000000009701000897010008D0 +:1000F0009701000897010008970100089701000880 +:1001000097010008000000000000000097010008AF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000097010008970100085F +:100160009701000897010008DFF80CD000F04CFC64 +:10017000004800474129000808050020064880473C +:1001800006480047FEE7FEE7FEE7FEE7FEE7FEE77C +:10019000FEE7FEE7FEE7FEE7BD0D00086901000887 +:1001A0002DE9F0410024061B254671F1000605DA11 +:1001B00001240027D0EB070067EB0101161E73F145 +:1001C000000605DA0027D2EB0702012567EB0303DF +:1001D00000F017FA86460E4617469C46AC4204D0FD +:1001E0000025D0EB050E65EB010624B10020D2EB13 +:1001F000000760EB030C704631463A466346BDE8A3 +:10020000F08140EA01039B0703D009E008C9121FEF +:1002100008C0042AFAD203E011F8013B00F8013BC0 +:10022000521EF9D27047D2B201E000F8012B491EEC +:10023000FBD270470022F6E710B513460A46044683 +:100240001946FFF7F0FF204610BD30B504460020E8 +:10025000034600E05B1C934203D2E05CCD5C401B94 +:10026000F8D030BDF0B480EA0102D40F4200B2EB06 +:10027000410F02D20246084611464A0042D0C30D41 +:10028000DDB2C1F3C752AD1A202D35DAC1F3160124 +:1002900041F4000204B15242C5F1200602FA06F10F +:1002A0002A411044B3EBD05F23D0C4B1012DA0EBA1 +:1002B000C35009DCF0BC4FF0004202EAC352DBB28B +:1002C00000F5000000F0E7B9400000F1807000EB9D +:1002D000C350A0F1807040EAD170490009E049089C +:1002E00041EAC071A0EBC35000F50000400800EBEC +:1002F000C350F0BC00F0C6B96142012202EB4101DB +:10030000001BF6E7F0BC704781F00041AAE780F0DF +:100310000040A7E780EA010210B502F00043400068 +:1003200022D04A001FD0010E01EB1261C0F356002B +:10033000C2F3560240F4000042F40002A0FB022087 +:1003400000047F39140400D0401C50EA124001D44C +:100350004000491EC2B20C0604EBD010401C4008FD +:10036000802A02D003E0002010BD20F00100002907 +:1003700000DA0020184310BD30B480EA010202F018 +:10038000004530F0004221F0004013D090B1C30D81 +:10039000D40DC2F31601C0F31600E41A41F40001B3 +:1003A00040F400027D34914201D3641C00E0490016 +:1003B000002C02DA30BC002070474FF4000000230C +:1003C000914201D3891A034340084FEA4101F7D112 +:1003D00051B1914202D14FF0004105E002D24FF0FD +:1003E000010101E06FF0010103EBC450284430BC6F +:1003F00000F048B9420005D0C0F3C75252429142C2 +:1004000001DC0020704700EBC15070472DE9FE4F22 +:1004100081EA030404F0004421F0004100944FF00D +:10042000000B23F0004350EA01045ED052EA0304BB +:100430005BD0C3F30A54C1F30A552C44A4F2F3343D +:100440000194A0FB0254C1F3130141F48011C3F3E2 +:10045000130343F4801301FB024400FB034E840AA0 +:10046000970A44EA815447EA8357A4FB0768029538 +:100470008D0A05FB07854FEA932C04FB0C542705D6 +:10048000029D4FEA065847EA1637B5EB08056EEBB2 +:10049000070C870E920E47EA811742EA8312A7FBE8 +:1004A0000201B6EB0B0164EB00042B0D43EA0C33A5 +:1004B0005E1844EB1C50DA465146E7FB0201C5F3D7 +:1004C00013044FEA0B3343EA14534FEA0432019CFE +:1004D00043EA0603A4F10C040294009CCDE900B4A5 +:1004E00000F016F903B0BDE8F08F00200146F9E7EF +:1004F000C10F80EAE0700844CA079623002100F08B +:10050000CAB896230022114600F0C5B800F0004298 +:1005100020F00040C10DC0F3160040F400007F2918 +:1005200001DA00207047962903DCC1F19601C8402A +:1005300001E096398840002AF4D04042704720F00C +:100540000040C10DC0F3160040F400007F2901DA1D +:1005500000207047962903DCC1F19601C84070471E +:1005600096398840704770B5C1F30A5201F00045D2 +:100570000024C1F3130140F2FF3341F480119A4289 +:1005800001DA002070BD40F233439A42A2F23342B6 +:1005900003DC524200F066F800E090402C43F1D0BA +:1005A000404270BD00F0004230F000400AD0C10D62 +:1005B00001F56071C0F3160042EA0151C20840071C +:1005C0001143704700200146704701F0004330B4EA +:1005D00021F0004150EA010206D00A0DA2F5607236 +:1005E000C1F31301002A02DC30BC00207047440F25 +:1005F00044EAC104C100E01830BC00EBC25000F076 +:1006000041B82DE9F05F0546002092469B4688469A +:100610000646814640241BE028464146474622467E +:1006200000F020F853465A46C01A914110D31146A3 +:100630001846224600F0FAF92D1A67EB01084F46DA +:1006400022460120002100F0F1F917EB00094E418C +:10065000201EA4F10104DFDC484631462A46434609 +:10066000BDE8F09F202A04DB203A21FA02F00021A5 +:10067000704721FA02F3D040C2F1200291400843B2 +:10068000194670470029A8BF7047401C490008BFA1 +:1006900020F00100704710B4B0FA80FC00FA0CF0B2 +:1006A00050EA010404BF10BC704749B1CCF12004EA +:1006B00021FA04F411FA0CF118BF01212143084377 +:1006C000A3EB0C01CB1D4FEA00614FEA102042BFA3 +:1006D000002010BC704700EBC35010440029A4BF99 +:1006E00010BC7047401C490008BF20F0010010BC3E +:1006F000704710B5141E73F1000408DA401C41F174 +:10070000000192185B411A4301D120F0010010BD95 +:100710002DE9F04D92469B4611B1B1FA81F202E00B +:10072000B0FA80F22032904600F080F904460F467D +:1007300040EA0A0041EA0B0153465A46084313D0E7 +:10074000114653EA010019D0C8F140025046FFF7A4 +:1007500089FF05460E4650465946424600F066F966 +:10076000084305D0012004E020463946BDE8F08D5D +:100770000020054346EAE0762C4337430A98630598 +:10078000E40AA0EB08000022FD0A44EA47540A30BC +:1007900002D500200146E9E7010510196941DDE9AC +:1007A000084500196941BDE8F04DA2E72DE9FE4F6B +:1007B000804681EA0300C00F0C46009021F0004102 +:1007C00023F00045B8EB0200A94105D2404621467E +:1007D00090461C460B46024623F00040104347D08B +:1007E000270DC7F30A00C3F30A510290401A019083 +:1007F00040286BDAC3F3130040F4801B0098924644 +:1008000020B10023D2EB030A63EB0B0B019859468E +:10081000C0F14002504600F009F906460D46504628 +:100820005946019A00F011F910EB080061410024CB +:1008300087EA115284EAE7731A4340D0009A62B300 +:10084000019A012A4FEA075215DC001B61EB0201F5 +:100850004FF0004202EA0752CDE90042001C41F588 +:10086000801132462B46FFF753FF03B0BDE8F08FEF +:1008700040462146F9E7001B61EB0201001C41F5EF +:10088000801300185B412018A2F5001747EB030105 +:1008900040EAD570B6196D4111E06D084FEA360691 +:1008A00045EAC0754FEA0752001B61EB0201001CCC +:1008B00041F5801149084FEA300000195141324694 +:1008C0002B4603B0BDE8F04FFFF713BF009801229D +:1008D00040000023D0EB020263EBE0730098214656 +:1008E0004FEAE074B8EB000061EB0401E9E783F044 +:1008F00000435BE781F0004158E72DE9F04D81EAC4 +:10090000030404F0004B21F0004514464FF0000AA8 +:1009100023F0004150EA050220D054EA01021DD024 +:10092000C5F30A570246C5F31303C1F31300C1F31D +:100930000A5640F4801543F48013A7EB0608101BF9 +:10094000D64608F2FD3873EB050002D308F1010822 +:1009500001E092185B41B8F1000F03DA0020014674 +:10096000BDE8F08D00204FF48011064684460EE06D +:10097000171B73EB050705D3121B63EB0503064337 +:100980004CEA010C49084FEA300092185B4150EAEA +:100990000107EDD152EA030012D082EA040083EA93 +:1009A0000501084305D0101BAB4106D201220023EC +:1009B00006E000224FF0004302E06FF00102531006 +:1009C0001AEB06004CEB085110EB0A0041EB0B014F +:1009D000BDE8F04DFFF78DBE70B521F00043034335 +:1009E0000CD0C1F30A550024D5EB040564EB0403D5 +:1009F000D617AD1AB34102DB0020014670BD2018A6 +:100A000041EB025170BD0000064C074D06E0E06866 +:100A100040F0010394E8070098471034AC42F6D345 +:100A2000FFF7A6FB0059000820590008202A04DB24 +:100A3000203A00FA02F1002070479140C2F12003F1 +:100A400020FA03F3194390407047202A06DBCB17A6 +:100A5000203A41FA02F043EAE07306E041FA02F379 +:100A6000D040C2F1200291400843194670472DE959 +:100A7000F04D00231A461B1A8A4103DB0020014671 +:100A8000BDE8F08DC1F30A52C1F3130141F48015A2 +:100A90004FF0000BD10702D100186D41521E002704 +:100AA000044640F2FF11384601EB620A3E4680469A +:100AB000024600204FF48011FFF7D4FDC2197141A6 +:100AC000BB1846EB0100B4EB030C75EB000C04D330 +:100AD000E41A65EB000517460E46241908F10100DB +:100AE0006D4180463428E3DDF91946EB0600091B09 +:100AF000A84103D24FF0FF32134601E00022134613 +:100B00001BEB070046EB0A51BDE8F04DFFF7F1BDC6 +:100B1000FEE77047FEE700F003B800F059B80000A8 +:100B200070B52A4C4FF480652946204601F000FE3E +:100B300018B12946204601F0F2FD4FF40045294640 +:100B4000204601F0F5FD18B12946204601F0E7FDE9 +:100B50004FF480452946204601F0EAFD18B12946A8 +:100B6000204601F0DCFD4FF400652946204601F0E7 +:100B7000DFFD18B12946204601F0D1FD4FF4007584 +:100B80002946204601F0D4FD18B12946204601F03F +:100B9000C6FD4FF480752946204601F0C9FD18B105 +:100BA0002946204601F0BBFD4FF4805529462046DA +:100BB00001F0BEFD18B12946204601F0B0FD2046E7 +:100BC000BDE870404FF4E06101F0A1BD0054004069 +:100BD0002DE9F05F62480178624FDFF88C81DFF821 +:100BE0008CA1634D634C644E4FF000096FF0010B14 +:100BF00001290DD0007800283CD195F900004FF074 +:100C000001010028304653DB01F092FD28B939E09C +:100C10000121304601F08CFD08B15A464CE002211A +:100C2000304601F085FD00285BD18021304601F07F +:100C30007FFD00281ED095F90000002806DD00BFCA +:100C400098F80010304601F04CFD2DE0207898B166 +:100C50004A4A106810F8011B1060304601F041FD4F +:100C60002078401E207000204FF4FA71401C80B2A2 +:100C70008842FBD3BDE8F09F304601F0D2FD8AF8F0 +:100C8000009066E00221304601F052FD48BB802111 +:100C9000304601F04DFD0028ECD095F90000002809 +:100CA000CEDC304601F0B8FD2878401E2870E1E720 +:100CB00001F03EFD30B1012239783046BDE8F05FE9 +:100CC00001F052BD0221304601F032FD78B12078AA +:100CD000012802D02078022803D10021304601F0FB +:100CE00075FC3046BDE8F05F022101F018BD4021DF +:100CF000304601F01DFD0028BCD020780028B9D076 +:100D00002078032809D10421304601F011FD002884 +:100D1000F9D00021304601F059FC304601F0DEFCEC +:100D200017490246086800F8012B08602078401E29 +:100D30002070207800289DD1304601F072FD8AF89D +:100D400000900121304601F041FC0121304601F0C4 +:100D500047FC3046BDE8F05F4FF4E06101F0D7BCDE +:100D60002D0000202F0000202E0000202C0000204D +:100D700031000020300000200054004034000020EA +:100D800038000020FEE770470907090E002806DA40 +:100D900000F00F0000F1E02080F8141D704700F112 +:100DA000E02080F8001470477047704710B503F0DA +:100DB000CFFDBDE8104000F019BC000014480168E8 +:100DC00041F00101016001688907FCD54168114AC1 +:100DD000114041604168104A11404160416821F46E +:100DE0004001416001680D4A11400160C16A21F073 +:100DF0000F01C162016B40F2431291430163416BE9 +:100E000021F0010141630021816003F059BD000020 +:100E1000001002400C00FF08FFFFC277FFFFF2FE48 +:100E2000FEE7490050EAC12018BF04204A0D18BF50 +:100E300040F0010040F2FF72B2EB515F08BF40F09A +:100E40000200012808BF052070472DE9F0414F1E20 +:100E500000EBC7010446D1E9000115461E4637F0F4 +:100E600006020DD02A463346FFF7D0FA7F1E04EB68 +:100E7000C703D3E90023FFF799FC37F00602F1D14D +:100E8000022F25D0042F13D0062F18BFBDE8F08104 +:100E90002A463346FFF7BAFAD4E90A23FFF786FC5D +:100EA0002A463346FFF7B2FAD4E90823FFF77EFC5F +:100EB0002A463346FFF7AAFAD4E90623FFF776FC61 +:100EC0002A463346FFF7A2FAD4E90423FFF76EFC63 +:100ED0002A463346FFF79AFAD4E90223FFF766FC65 +:100EE0002A463346FFF792FAD4E90023BDE8F041E1 +:100EF000FFF75CBC0122FFF76FBDFFF757BC002274 +:100F0000134610461146FFF7F8BC0000024A0020C5 +:100F10001107FFF761BD000001FDFFFF02E008C8F7 +:100F2000121F08C1002AFAD170477047002001E063 +:100F300001C1121F002AFBD170470000014908605F +:100F4000704700006C0000202DE9FE4F07460E465A +:100F50000025684600F094FF00246FF00F0AE84671 +:100F60004FF0010957F8240056F82410401A00D514 +:100F70004042FFF7BDFA5146FFF73CFA58F82410FB +:100F800011F0FF4F0BD0FFF7F7F94FF07E51FFF74D +:100F9000BBF90A4920F00040884205DC07E0084917 +:100FA00008440849884202D309FA04F00543641C46 +:100FB000032CD7DB2846BDE8FE8F0000295C0F3EDE +:100FC000666666C19A99D9002DE9F04D8D4F21F0E2 +:100FD000004A86B005460C46BA452ADBAAEB070054 +:100FE00028430AD08848824501DC1AD1CDB106B029 +:100FF0002846BDE8F04DFFF77DBF844A844B284664 +:10100000FFF704FA07460E46824A834B28462146DC +:10101000FFF7FCF906B03A463346BDE8F04DFFF75E +:10102000C5BB0120FFF78AFF06B0BDE8F04DFFF712 +:1010300066BF7A48824542DABAF1795F0BDA284610 +:10104000FFF7EFFE042808BFFFF760FF284606B051 +:101050002146BDE8F08D2A460B461046FFF7D6F92B +:10106000834602466E480E460B4606217844FFF73B +:10107000ECFE5A463346FFF7C9F9804669488A466E +:101080005A46334604217844FFF7DFFE5A4633467A +:10109000FFF7BCF900223B46FFF788FB02460B46F0 +:1010A00040465146FFF729FC2A462346FFF7AEF992 +:1010B00006B02A462346BDE8F04DFFF777BB284629 +:1010C00024F0004100223D463B46FFF713FC4FF061 +:1010D000FF32FFF781FC0646024653480F460B4697 +:1010E00006217844FFF7B1FE32463B46FFF78EF902 +:1010F000CDE900014D4832463B4604217844FFF7D4 +:10110000A4FE32463B46FFF781F900222B46FFF74B +:101110004DFB834602913046394603F0ABFB8046D7 +:1011200043480D46504517DCDDE900015A46029B55 +:10113000FFF7E3FB42462B46FFF768F942462B4692 +:10114000FFF734FB0122FFF747FC304A304BFFF733 +:10115000CEFB304A304B4CE04FF0000A52460B4673 +:101160004046FFF723FBCDE9031052462B461046BD +:101170001946FFF74BF932463B46FFF7BBFBDDE96B +:101180000332FFF7BAFB06460F46DDE900015A4677 +:10119000029BFFF7B2FB834600910122304639469D +:1011A000FFF71AFC194A1A4BFFF7A4FB06460F4635 +:1011B000012240462946FFF70FFC5A46009BFFF7E5 +:1011C00025F932463B46FFF792FB06460F460122C1 +:1011D00050462946FFF700FC0E4DDFF858802A469E +:1011E0004346FFF787FB32463B46FFF783FB2A4621 +:1011F0004346FFF77FFB002CD8BF81F0004106B0CB +:10120000BDE8F08D0000F03F0000F07F075C143374 +:1012100026A6913C182D4454FB21F93F0000E03FE5 +:10122000A0470000B64700002A47000040470000E2 +:101230003333EF3FFB21E93F2DE9F84F04460D46DC +:1012400021F0004000917349814211DC72498842CB +:1012500001DC06D12CB120462946BDE8F84FFFF746 +:1012600049BE6E48002DCCBF6D496E49BDE8F88F70 +:101270006D49814211DD6D498142D8BF4FF0FF3683 +:101280006DDD20462946FFF7CCFD042808BFFFF797 +:101290003DFE20462946BDE8F88F6549654F25F09B +:1012A0000045814233DD6449814219DD0026324622 +:1012B0004FF0804320462946FFF778FA80468A4659 +:1012C000012220462946FFF787FB00223B46FFF715 +:1012D0000EFB42465346FFF710FB04460D463EE028 +:1012E00001260022BA463B4620462946FFF75EFA11 +:1012F00080460F460022534620462946FFF7F7FA5C +:1013000042463B46FFF7F9FA04460D4627E04B49B3 +:1013100081421BDDDFF828A1022600225346204629 +:101320002946FFF773F800223B46FFF73FFA804655 +:101330000F460022534620462946FFF7D8FA424678 +:101340003B46FFF7DAFA04460D4608E0032622463C +:101350002B4600203B49FFF7D0FA04460D462246B3 +:101360002B4610461946FFF751F88B468246024637 +:101370000B46FFF74BF807460246334888460B46B4 +:1013800006217844FFF761FD52465B46FFF73EF8C1 +:1013900082462E488B463A46434605217844FFF75D +:1013A00054FD3A464346FFF731F802460B46002EFD +:1013B000504659460CDAFFF7F9F922462B46FFF75B +:1013C00025F801B022462B46BDE8F04FFFF792BA50 +:1013D000FFF7ECF922462B46FFF718F81C4A7A442F +:1013E00002EBC603D3E90023FFF781FA22462B461E +:1013F000FFF77DFA174A7A4402EBC603D3E90023CC +:10140000FFF778FA009A002AB8BF81F00041BDE8E2 +:10141000F88F0000000010440000F07F182D4454A5 +:10142000FB21F93FFB21F9BF0000DC3F0000203E1B +:101430000000F33F0000F03F0000E63F0080034063 +:101440000000F83F0000F0BF4245000000450000EA +:101450009E440000664400002DE9F04D9446CCF116 +:10146000000423F000464CEA0404524F46EAD474C8 +:101470009A46884621F00042BC4206D8454240EADE +:10148000050442EAD474BC4204D9BDE8F04D62467A +:10149000FFF733BDAAF14055A5F17F6555EA0C046D +:1014A0000BD0022404EAAA74434DDFF810E144EAA9 +:1014B000D87452EA000B04D00CE0BDE8F04DFFF701 +:1014C000BBBE002C14BF012CBDE8F08D022C30D027 +:1014D000032C32D056EA0C0B0AD0BE4220D1BA42BD +:1014E00009D126F0804622F080423346114617E0AB +:1014F00000291ADB25E0DFF8C8B0FB44002C04BF4C +:10150000DBE90001BDE8F08D012C02BFDBE9000141 +:1015100081F00041BDE8F08D022C0AD0032C0CD0E4 +:10152000BA4212D1B8F1000F0BDA23482549BDE8C1 +:10153000F08D28462449BDE8F08D28467146BDE867 +:10154000F08D1D482149BDE8F08D921B12153C2AF3 +:10155000C4BF19481D490EDCBAF1000FBEBF12F11D +:101560003C0F0020014606DB6246FFF7C6F921F07A +:101570000041FFF761FE002C08BFBDE8F08D012C93 +:1015800004BF81F00041BDE8F08D114A114B022CDF +:1015900007D0FFF7ACF92A46BDE8F04D0A4BFFF73C +:1015A000A6B9FFF7A4F92A46BDE8F04D064BFFF7B0 +:1015B000A1B900000000F07F182D4454FB2109C0A0 +:1015C000FA430000FB21F9BFFB210940FB21F93F51 +:1015D000075C143326A6A13C70470000024948600E +:1015E00048680028FCD17047240000200348416867 +:1015F000002902D04168491E416070472400002044 +:1016000000EB8000810003480844816821F001015B +:10161000816070470000024000EB800081000348B9 +:101620000844816841F00101816070470000024078 +:1016300000EB8000810003480844816821F020010C +:10164000816070470000024000EB80008100034889 +:101650000844816841F02001816070470000024029 +:101660000A4B00EB800103EB81018A6822F0010242 +:101670008A6000228A60CA600A614A6159688200F1 +:101680000F20904001435960704700000000024065 +:10169000044A1268800081400A4201D0012070474C +:1016A00000207047000002402DE9F0430DF11C08B6 +:1016B00000EB800098E8E0024FEA80081548DDE979 +:1016C0000BC4404401614561C0F80CC081683243DD +:1016D00021F47C510C4322438260816883B121F064 +:1016E00040018160816877B121F08001816081686B +:1016F000B9F1000F0AD041F010018160BDE8F0831C +:1017000041F04001EDE741F08001EFE721F01001E9 +:10171000F3E700000000024000EB80008100034876 +:101720000844816821F480418160704700000240D4 +:1017300008B560B120208DF8000028208DF8010048 +:1017400030208DF8020038208DF8030004E0A32239 +:1017500004216846FEF767FD6A46042140F69E2094 +:1017600002F002FF02F00EFB08BD00003EB5044689 +:1017700002208DF80000CA208DF80100E3208DF8CA +:10178000020009208DF803006A460421682002F057 +:10179000EBFEA3208DF80000610609D5C0218DF86D +:1017A0000110C8218DF80210C2218DF8031005E048 +:1017B0008DF801008DF802008DF8030014F4C07F4D +:1017C00009D0C4218DF80410CC218DF80510C62154 +:1017D0008DF8061005E08DF804008DF805008DF8F1 +:1017E00006008DF808008DF807008DF809006A469C +:1017F0000A2140F6A72002F0B7FEA0074FF0D80557 +:1018000003D020208DF8000001E08DF800506A46DA +:10181000012140F6B62002F0A7FEA00601D5012066 +:1018200000E0002000F08EF814F4C07F1ED0E00528 +:101830000AD5B2208DF800008B208DF80100B6206B +:101840008DF802009B2009E0B0208DF80000802078 +:101850008DF80100B4208DF8020090208DF803006F +:101860006A46042140F6A22002F07EFEE1074FF412 +:101870000B6022D0F8218DF800106A46012102F099 +:1018800073FEFA21072000F047FA072000F013FA50 +:10189000012000F030FA642000F0D2FA4FF4FA7020 +:1018A00000F0DEFAC821254800F0CDF9282000F02C +:1018B000E2F90A2000F0EFF905E08DF800506A46E1 +:1018C000012102F051FEA00703D5D9208DF80000B8 +:1018D00001E08DF800506A46012140F23D7002F0AF +:1018E00043FE600701D5012000E0002000F048F829 +:1018F000E00601D5012000E00020FFF719FF104DA0 +:1019000044F00800688102F03DFA0020A8736006E8 +:1019100001D50620A87314F4C07F02D0A87B801DD7 +:10192000A87314F0140F02D0A87B1030A873A0077E +:1019300002D0A87B001DA87300203EBD09E3CA02A7 +:10194000F40000200EB54FF4976310B106A107C94B +:1019500001E008A207CA8DE807006A460921184677 +:1019600002F002FE0EBD0000B8AAB38DB4980D358A +:101970005D000000B8AAAAAAB088C3C5C7000000CD +:1019800008B560B1C0208DF80000C2208DF80100BC +:10199000C4208DF80200C6208DF8030004E08B22DD +:1019A00004216846FEF73FFC6A46042140F6982071 +:1019B00002F0DAFD02F0E6F908BD0000024989896B +:1019C0000180002070470000F4000020C8234FF47D +:1019D0008062024940F6F63001F0E4BF144C000882 +:1019E0002DE9FF4F89B01746DDE9165200244C4E11 +:1019F000884681462C80A246B07B694602F030F9C9 +:101A00004FF0FF3B18B158460DB0BDE8F08F70891C +:101A100010F0140F3CD0009909BA21F0FF039DF893 +:101A200003100B433B6001991B1409BA21F0FF021C +:101A30009DF807105B430A437A6002999DF80B40BA +:101A400009BA21F0FF012143B960039C091424BAAB +:101A500024F0FF0C9DF80F4012144CEA040CC7F858 +:101A60000CC04FEA2C47494302FB023207FB071127 +:101A700011441024A1F17061B1F1007F04D902F08A +:101A800081F9A5F800A0BEE7298841F4807129807A +:101A90004206694611D50A19A41D13885BBAA8F835 +:101AA000003053885BBAA8F80230928852BAA8F87E +:101AB00004202A8842F008022A8010F4C07F11D046 +:101AC0000A19A41D13885BBAA9F8003053885BBAC1 +:101AD000A9F80230928852BAA9F804202A8842F064 +:101AE00070022A80800716D00C44E07800F0C00510 +:101AF00000F03F016078C00706D0C80801F0070178 +:101B00003268491C02B190476078000703D57168BC +:101B100009B1A80988470C9800F092FB002073E7F0 +:101B2000F40000200149486000207047F4000020C4 +:101B30000149086000207047F400002030B50446D9 +:101B400013A285B007CA8DE807004FF0FF35C82CF7 +:101B500016D8C820B0FBF4F1491E080A8DF80C0015 +:101B60008DF80D1003AA022140F2162002F0FCFCB1 +:101B700030B96A460C2140F6C12002F0F5FC10B1E4 +:101B8000284605B030BD054884810020F9E70000F3 +:101B9000FEF2ABC4AAF1DFDFBBAFDFDFF400002051 +:101BA00000B50EA187B00EC98DE80E000EA10DF193 +:101BB0000C0C0EC98CE80E0040F68223012807D0D9 +:101BC000022803D04FF0FF3007B000BD6A4600E0A6 +:101BD00003AA0B21184602F0C7FCF5E7D8B1B9F308 +:101BE0008BA391B609B4D900DAB1B9F38BA391B63E +:101BF000DAB4DA0008B5010E8DF80010010C8DF88A +:101C00000110010A8DF802108DF803006A460421C4 +:101C10004FF4587002F0A8FC08BD1421B0FBF1F09D +:101C200008B5010E8DF80010010C8DF80110010AA5 +:101C30008DF802108DF803006A4604214FF471708C +:101C400002F092FC08BD4FF47A7290FBF2F008B5F6 +:101C50004843010E8DF80010010C8DF80110010AA7 +:101C60008DF802108DF803006A4604214FF4AE701F +:101C700002F07AFC08BD0521B0FBF1F008B5010ABD +:101C80008DF800108DF801006A4602214FF4AD7006 +:101C900002F06AFC08BD0521B0FBF1F008B5010AAD +:101CA0008DF800108DF801006A4602214FF4AC70E7 +:101CB00002F05AFC08BD08B500218DF80010C107DC +:101CC00002D030218DF80010810705D59DF8001055 +:101CD00041F00C018DF80010400705D59DF800007B +:101CE00040F003008DF800006A4601214FF4A47013 +:101CF00002F03AFC08BD08B560B1042800D9042000 +:101D0000401E8DF800006A46012140F24F1002F09B +:101D10002BFC08BD0120F3E72DE9FC4105464007F7 +:101D20004FF0FF367CD0B1F5C86F79D80846FEF782 +:101D3000E8FB3E49FEF720FB074601A801F0D8F872 +:101D40009DF80400022806D004280DD008282ED0C3 +:101D5000102865D134E00E213846FEF74BFBFEF724 +:101D6000EEFB84B2324907E00D213846FEF742FB14 +:101D7000FEF7E5FB2F4984B23846FEF7CBFAFEF7B3 +:101D8000DEFB210A8DF8001080B28DF80140010AB7 +:101D90008DF802108DF80300E8076C4620D022462B +:101DA00002214FF4EA7002F0DFFBC8BB11E00C2106 +:101DB0003846FEF71FFBFEF7C2FB84B21E49DBE785 +:101DC0000B213846FEF716FBFEF7B9FB84B21B4920 +:101DD000D2E7A21C02214FF4927002F0C5FBF8B9C1 +:101DE000A8070DD56A4602214FF4EC7002F0BCFB47 +:101DF000B0B9A21C02214FF4947002F0B5FB78B97F +:101E0000680710D56A4602214FF4EE7002F0ACFB71 +:101E100030B9A21C02214FF4967002F0A5FB10B15C +:101E20003046BDE8FC810020FBE70000000048438D +:101E3000000040460000C045000040450000C0448E +:101E40000521B0FBF1F008B5010A8DF800108DF8FE +:101E500001006A4602214FF4EF7002F085FB08BDD5 +:101E60000521B0FBF1F008B5010A8DF800108DF8DE +:101E700001006A4602214FF4ED7002F075FB08BDC7 +:101E80002DE9FE430646264801AB042240680D2199 +:101E9000007800F091FC10B10720BDE8FE839DF8AA +:101EA00004101C2000EAD1029DF80710DFF874909E +:101EB000C1F301131A438DF800209DF80520C1F3EA +:101EC000810300EAD2021A438DF801209DF8062012 +:101ED00001F0030100EAD20008430024124F8DF8FC +:101EE0000200A0466D46285D10B146F824900AE035 +:101EF00046F824800DE000BF56F824003946FEF76E +:101F000009FA46F82400285D401E10F0FF0028550D +:101F1000F2D1641CE4B2032CE5D30020BDE700003D +:101F2000400000207B14AE3E1D5A843F2DE9FE4F39 +:101F300005460120C14E8DF800004FF000088DF8D5 +:101F4000018030680C461746417D70686B4602225E +:101F5000007800F06BFC4FF0FF3A00287AD1C820DF +:101F6000FFF73CFB8DF8008030686B460122417C16 +:101F70007068007800F05AFC0028EFD130686B469A +:101F8000012241797068007800F050FC0028E5D10A +:101F900030686B460122417D7068007800F046FC95 +:101FA0000028DBD130686B460122817E70680078A2 +:101FB00000F03CFC0028D1D130686B460122017949 +:101FC0007068007800F032FC0028C7D14FF00C098F +:101FD0008DF8009030686B460122017970680078B6 +:101FE00000F024FC002835D10F20FFF7F7FAB06A83 +:101FF0006B460122407A8DF8000030688178706865 +:10200000007800F013FC002824D1B06A6B4601224E +:10201000007A8DF80000306841787068007800F030 +:1020200005FC002873D1B06A807A0FB140F0E0005F +:102030008DF8000030686B46012281797068007865 +:1020400000F0F4FB002862D12FB1B06AC07A40F0F2 +:10205000E00001E04AE018208DF8000030686B468F +:102060000122C1797068007800F0E0FBF0BB17B185 +:10207000C820FFF7B3FA40208DF8000030686B46A7 +:10208000012201797068007800F0D0FB70BB7820E5 +:102090008DF8000030686B46012241797068007845 +:1020A00000F0C4FB10BB3220FFF798FA8DF80080D7 +:1020B000306847466B46417970680122007800F02D +:1020C000B5FB98B931687068B046097B00786B46FB +:1020D000022200F071FB48B9BDF80000AF6040BAC1 +:1020E000B0FBF9F06F60C6B22F6000E00FE0A760B0 +:1020F00067602760002739E0D8F80010D8F804009E +:102100006B46497B00780C2200F056FB10B150461C +:10211000BDE8FE8FBDF80000236840BA02B2BDF8EA +:102120000200BDF804101A44226040BA626800B28E +:102130001044606049BAA06809B20844A060BDF8C4 +:1021400006002B6840BA02B2BDF808001A4440BA33 +:1021500001B2BDF80A002A606A6840BA1144696099 +:10216000A96800B208447F1CFFB2A860B742C3D37D +:1021700028688322C117090441EA104100040023A2 +:10218000FEF70EF832460023FEF70AF8286068686A +:102190008322C117090441EA104100040023FDF71E +:1021A000FFFF32460023FDF7FBFF6860A86883222B +:1021B000C117090441EA104100040023FDF7F0FFB4 +:1021C00032460023FDF7ECFFA86020684FF400655D +:1021D000C117090441EA104100042A460023FDF713 +:1021E000DFFF32460023FDF7DBFF206060682A46F0 +:1021F000C117090441EA104100040023FDF7D0FF94 +:1022000032460023FDF7CCFF6060A0682A46C11764 +:10221000090441EA104100040023FDF7C1FF3246E2 +:102220000023FDF7BDFFA060002802DDA0F580308F +:1022300001E000F58030A060002069E74000002048 +:10224000014909680160704724000020F0B5036A65 +:10225000446A002501260F2706FA05FC1CEA020F36 +:1022600009D04FEA850C07FA0CFE23EA0E0301FAA7 +:102270000CFE4EEA03036D1CADB2082DECD308250D +:1022800006FA05FC1CEA020F0BD04FEA850CACF1F4 +:10229000200C07FA0CFE24EA0E0401FA0CFE4EEAAA +:1022A00004046D1CADB2102DEAD303624462F0BD8C +:1022B00081627047816170472DE9F04740F2115605 +:1022C000304602F081FA771C384602F07DFA01238D +:1022D0004FF0904800221946404600F0CAF8DFF857 +:1022E00080914FF40074234600220121484600F0FB +:1022F000C0F865102B4600220121484600F0B9F8CD +:10230000202300220121484600F0B3F810230022C8 +:102310000121484600F0ADF8012303220021404688 +:1023200000F0CAF8234603220021484600F0C4F812 +:102330002B4603220021484600F0BEF8202303224A +:102340000021484600F0B8F8102303220021484637 +:1023500000F0B2F801214046FFF7AAFF21464846A7 +:10236000FFF7A6FF29464846FFF7A2FF202148466F +:10237000FFF79EFF10214846FFF79AFF304602F014 +:1023800023FAB41C204602F01FFA00221023114643 +:10239000404600F06EF8AB01324D0022114628464F +:1023A00000F067F8384602F00FFA40F2157002F0BC +:1023B0000BFA402201214846FFF748FF8022012105 +:1023C0004846FFF743FF402301220221484600F020 +:1023D00050F8402303220121484600F06DF8802385 +:1023E00001220221484600F044F880230322012103 +:1023F000484600F061F8304602F0E6F9384602F04F +:10240000E3F9204602F0E0F900224FF400431146C0 +:10241000284600F02EF8022300220121404600F059 +:1024200028F84FF48064234600220121484600F03A +:1024300020F8022303220021404600F03DF8234605 +:1024400003220021484600F037F802214046FFF7FA +:102450002FFF21464846BDE8F047FFF729BF00009F +:1024600000040048000800480069084000D001202E +:1024700070472DE9F047894601689246C2680024FA +:1024800001274FF0030C07FA04F51D420BD066003C +:102490000CFA06F5A943AA4309FA06F80AFA06F562 +:1024A00048EA01012A43641CA4B2102CEBD301605A +:1024B000C260BDE8F0870000F0B50129416819D07D +:1024C000994341608168002401274FF0030C00BF4D +:1024D00007FA04F61E4207D066000CFA06F521EA58 +:1024E000050502FA06F12943641CA4B2102CEFD3AF +:1024F0008160F0BD1943E4E72DE9F84F81462E488D +:102500008846002540686B46032200780D2100F0C4 +:1025100053F910B10720BDE8F88F9DF800000024A2 +:1025200000F01F008DF800009DF801006FF00F0B08 +:1025300000F01F008DF801009DF802006E4600F0CB +:102540001F008DF802004FF0010A00BF59F8241057 +:1025500058F82400081A00D54042FDF7C9FF594633 +:10256000FDF748FF0746305DC0B1144802E014494A +:10257000FDF7D0FE315D491E11F0FF013155F6D156 +:1025800001463846FDF7F8FE4FF07E51FDF7BCFEE0 +:102590000C4920F00040884205DC07E00A48384436 +:1025A000B0F1D97F02D90AFA04F00543641C032C68 +:1025B000CCDB2846AFE70000400000200000C84107 +:1025C00054E3853F295C0F3E0000E0BE012901680D +:1025D00003D021F480610160704741F48061FAE723 +:1025E0000029016803D021F400610160704741F4C3 +:1025F0000061FAE770B5044616460D46022002F067 +:102600002DF8254BB0FBF3F13F2900D33F21626841 +:1026100022F03F020A436260204A954210D8B0FB84 +:10262000F3F1491C3F2900D33F2121626900B0FB2F +:10263000F1F0042800D20420E169C0F30B0028E087 +:10264000174A954227D84FF4967251434FF47A7245 +:10265000B1FBF2F1491C216266B105EBC50101EB4A +:102660000511B0FBF1F0E16941F48041E161010540 +:1026700008D009E005EB4501B0FBF1F0E16921F478 +:102680008041F3E740F00100E16941F40041E1617C +:10269000E1690143E16170BD40420F00A086010085 +:1026A000801A060010B50C4C4FF4804209492046B0 +:1026B000FFF7A0FF002224231146204600F05DF81A +:1026C000204600F010F82046BDE810400121FFF739 +:1026D0007DBF0000801A0600005400400069C0B2AF +:1026E000704701617047016841F001010160704766 +:1026F000024601F00043002089B2B3F1004F04D03C +:1027000052690A4200D0012070479269F9E7426895 +:102710008A434260704742680A4342607047022918 +:1027200003D042698A4342617047416980697047BA +:1027300010B5426802F40073426811F0FF0F02F412 +:10274000807206D02BB1CA0607D1426802F48062BB +:1027500002E011F47F4F05D022B14069084000D05B +:10276000012010BD002010BD921C03D041F00101DA +:102770000161704721F00101FAE710B5046824F007 +:1027800002040C4304601A43826010BD10B54FF47C +:10279000C06001F059FF03220021172001F00EFF55 +:1027A00002220021BDE81040202001F007BF13469F +:1027B000012200F001B8000070B5144C00256570CE +:1027C000FF2525704000E070A170E36022710120B8 +:1027D00060710F4D4FF4E0612846FFF79CFF2079B0 +:1027E000022803D100212846FFF7FAFE094E2846A9 +:1027F0003146FFF77DFF0028F9D1284600F00CF89C +:1028000020790028FCD194F9000070BD2C00002034 +:102810000054004002000080016841F480710160B2 +:102820007047016841F400710160704770B5104C49 +:1028300001256570FF2626704000E070A170A3603E +:10284000227165710B4D4FF4E0612846FFF763FF7D +:10285000094E28463146FFF74BFF0028F9D128469C +:10286000FFF7DAFF20790028FCD194F9000070BD51 +:102870002C00002000540040020000802DE9F047A9 +:102880002E4D814600274FF090444FF480784FF44E +:10289000007601212046FFF70DFD41462846FFF74F +:1028A00007FD4846FEF79AFE31462846FFF702FD2F +:1028B00001212046FFF7FCFC4846FEF78FFE41460B +:1028C0002846FFF7F7FC31462846FFF7F1FC48465B +:1028D000FEF784FE7F1C062FDBDB0027012120464C +:1028E000FFF7E8FC31462846FFF7E4FC414628465E +:1028F000FFF7E0FC20212846FFF7DCFC10212846EA +:10290000FFF7D8FC4846FEF769FE01212046FFF795 +:10291000CFFC31462846FFF7CBFC41462846FFF75F +:10292000C7FC20212846FFF7C3FC10212846FFF7EB +:10293000BFFC7F1C022FD1DBBDE8F08700040048FC +:1029400001F0E6FFFFF7B8FC8C4C4FF4164120462F +:1029500002F09CF8FFF7A6FEFFF718FF0C2288494B +:10296000204602F02FF8864914222031204601F03B +:10297000F7FF6420FFF782FF00F01CFA814C00266D +:1029800000B16670682000F0FFFBDFF8F4B10127AA +:1029900032254AF6AA290BF1200B4FF0904A01206C +:1029A000FEF71CFE6078012808D001214FEA0A00DA +:1029B000FFF780FC6078012804D005E04FF4007137 +:1029C0007148F5E700F0B2FAA068B0FBF5F105FB3D +:1029D000110020B96078012801D101F08FF8102191 +:1029E0005046FFF741FD58B1A77020216648FFF718 +:1029F00061FC66A0FEF7F0FD3220FEF7EFFD04E07B +:102A0000A67020216048FFF753FC4FF480416548D1 +:102A1000FFF72AFD58B1E77010215B48FFF74AFC29 +:102A200061A0FEF7D9FD3220FEF7D8FD04E0E67084 +:102A300010215548FFF73CFCA168B1FBF5F005FB00 +:102A4000101080BB02210320FEF722FE01282AD1AC +:102A50004B495B4ADFF828C1A1F80090938B4B806B +:102A6000D18BACF80410128CACF8062094F802C09C +:102A700094F8038048464CEA480CDFF8048158403B +:102A8000514048404146A8F808C080EA0C004881FF +:102A90000320FEF7B5FD4B480C21816441460165DA +:102AA0000320FEF7B9FDBBF80020BBF80230BBF8ED +:102AB00006C082EA0301BBF8043083EA0C035940E4 +:102AC000BBF808305940BBF80A305940BBF80C300D +:102AD0005940BBF80E305940BBF8103059401FFA2E +:102AE00081FC4A451BD1BBF91200D846604516D17E +:102AF000207838B1B4F90410481EA08000292FDCDA +:102B0000267032E01E4914222031A1F11400FDF795 +:102B100078FB4FF6FF70A8F80000A68025E0B4F916 +:102B20000410481CA0804FF49670814201DB27708E +:102B3000A080A068B0FBF5F105FB110070B94A4513 +:102B40000CD0A2F57F40FF3808D00420FEF758FDD6 +:102B50000B4914222031094801F002FF207820B1EE +:102B600001215046FFF7A6FB03E001215046FFF785 +:102B70009FFBA068401CA06011E7000000440040DB +:102B80007000002004000020000400482D2D205378 +:102B9000454E534F52203120416374697665202D94 +:102BA0002D0A0000000800482D2D2053454E534F9C +:102BB00052203220416374697665202D2D0A000071 +:102BC000D00000200000024040B1012808D00228B7 +:102BD00008D0032808D105A0FEF7FEBC08A0FBE73B +:102BE00004A0F9E709A0F7E7704700005265766591 +:102BF000727365204C616E6473636170650A0000D6 +:102C0000506F7274726169740A00000052657665D3 +:102C100072736520506F7274726169740A000000EB +:102C20002DE9FC5F5F4CE068FDF762FC6FF01D056D +:102C30002946FDF7DFFB00902069FDF759FC294686 +:102C4000FDF7D8FB81466069FDF752FC2946FDF788 +:102C5000D1FB8046A069FDF74BFC2946FDF7CAFB76 +:102C6000064641460846FDF755FB05464946019094 +:102C70000846FDF74FFB2946FDF7F4FA0121FDF761 +:102C8000B9FB4FF07E51FDF742FBFDF78BFC074689 +:102C90000D4631464046FDF73DFB824649460098C9 +:102CA000FDF738FB5146FDF7DDFA0121FDF7A2FBE8 +:102CB000FDF778FC3A462B46FEF7CEFBFDF785FC88 +:102CC000834649463046FDF725FB054641460098B8 +:102CD000FDF720FB2946FDF717FB0121FDF78AFBD5 +:102CE000FDF760FCFEF770F9FDF76FFC8246314698 +:102CF0000846FDF70FFB01460198FDF7B3FA0121E5 +:102D0000FDF778FB4FF07E51FDF701FBFDF74AFC24 +:102D100007460D4641464846FDF7FCFA80463146D7 +:102D20000098FDF7F7FA4146FDF79CFA0121FDF7FF +:102D300061FBFDF737FC3A462B46FEF78DFBFDF7AE +:102D400044FC05465846FDF72DFC174E174F3246FA +:102D50003B46FDF75BFBDFF8588000224346FDF75A +:102D600055FBFDF700FCA0835046FDF71BFC3246E7 +:102D70003B46FDF74BFB00224346FDF747FBFDF7C3 +:102D8000F2FBE0832846FDF70DFC32463B46FDF79B +:102D90003DFB00224346FDF739FBFDF7E4FB2084B1 +:102DA000BDE8FC9FD0000020F8C1631ADCA54C40B0 +:102DB0000000594070B51EA0FEF70EFC00F094FD17 +:102DC0004FF0FF3508B121A017E0782001F0BEFADE +:102DD000782000F063F8142001F078FA1F4C0320EB +:102DE00000216070A1706161E1601DA02161FEF7AA +:102DF000F3FBFEF7EBFD20B11EA0FEF7EDFB28462E +:102E000070BD2148FEF794FE2048FEF78BFEF320AC +:102E10002083FEF7ABFC1420FEF790FE012001F0AA +:102E20007BF90120A0701AA0FEF7D6FB002070BD30 +:102E30002D2D20436F6E6669677572696E67204D30 +:102E40005055363035302E2E2E2000004641494C4C +:102E500020284D5055292E0A00000000A400002013 +:102E60002077726974696E6720444D502E2E2E2093 +:102E700000000000204641494C2028444D502920A4 +:102E80002D2D0D0A000000000D450008C92B00087B +:102E9000204F4B202D2D0D0A000000002DE9F041A0 +:102EA000124C20F00101002594F8240010B10020FC +:102EB000BDE8F081A07A4FF0FF3668B10840277C6A +:102EC0002074884200D0354641B1012001F0A6FCB3 +:102ED00000F058FF38B127743046E9E7207D00B193 +:102EE000012001F09BFC2846E2E7000040000020A2 +:102EF0000D494A7A42B1012A08D0022A0FD0032A8A +:102F00000FD04FF0FF307047022200E00422027021 +:102F1000C97C11B11106C90D01700020704708224B +:102F2000F5E71022F3E70000400000202DE9F04112 +:102F300052488CB000260168406809AAC97C007814 +:102F4000FFF735FC9DF824004D4D80074FF0010838 +:102F500001D085F8048008A8FFF772F9296908985C +:102F6000814203D200F5FA70012628612879444C89 +:102F700000272C34F0B3A878E0B30AA906A8CDE95D +:102F8000000107ABA4F1100204A902A8FEF728FD76 +:102F90009DF8280000B92F71BDF8180010F0700FCF +:102FA00015D0BDF808002080BDF80A006080BDF88B +:102FB0000C00A0805EB1314807A9001F00F0A6F800 +:102FC0002E486421001F0068484300146084BDF946 +:102FD0001800010708D5BDF81010E180BDF81210E7 +:102FE0002181BDF814106181C0050DD524481C3025 +:102FF000016800E00BE0E160416821618168616186 +:10300000C068A061FFF70CFE0CB0BDE8F081287924 +:103010000028F9D02F710AA8009005AB07AA03A9D0 +:1030200001A800F06DFD9DF8280008B185F8048026 +:103030009DF8140010F0700F12D0BDF8040020802D +:10304000BDF806006080BDF80800A08046B107A961 +:1030500006A800F05BF806986421484300146084D9 +:103060009DF814000007CFD5BDF80C00E080BDF836 +:103070000E002081BDF810006081C5E740000020EF +:10308000A40000200B49097A39B1012907D002298F +:103090000AD003290BD0002103E0FA2101E04FF40C +:1030A000FA710180002070474FF47A71F9E74FF40C +:1030B000FA61F6E7400000200C49C97A072913D2CB +:1030C000DFE801F01204060A0C0E1000BC2100E03B +:1030D00062210180002070472A21FAE71421F8E7D5 +:1030E0000A21F6E70521F4E70021F2E7400000207D +:1030F000054991F8242012B14FF0FF307047C9897B +:10310000018000207047000040000020F8B51C4CF2 +:1031100006460F46A07A4FF0FF3540B120686B4657 +:103120000222017C60680078FFF746FB08B1284660 +:10313000F8BDBDF8000040BA05B217B13846FFF738 +:103140007FF86468E088FDF7DCF90746B4F9080009 +:10315000FDF7CEF904462846FDF7CAF92146FDF7EA +:10316000D3F83946FDF708F90649FDF77BF8102139 +:10317000FDF740F9FDF7CAF930600020F8BD000006 +:103180004000002000000C4238B5724C6528A17840 +:1031900062696DD026DC33286BD009DCA0F12C00ED +:1031A000072867D2DFE800F0D19AD09A9BA3B2003B +:1031B000684B38285B7874D00DDC342869D035280A +:1031C00058D100294FF0640068D0FEF7B7FC002802 +:1031D00050D161A00DE3392866D061287ED182F0FC +:1031E00001007AE001256638122877D2DFE800F086 +:1031F000B1670976767676767676736A63B070769E +:10320000AFAE5AA0FEF7E8F966A0FEF7E5F96BA0AD +:10321000FEF7E2F972A0FEF7DFF979A0FEF7DCF91C +:103220007EA0FEF7D9F985A0FEF7D6F98AA0FEF7B1 +:10323000D3F990A0FEF7D0F998A0FEF7CDF9A0A0A1 +:10324000FEF7CAF9A5A0FEF7C7F9A9A0FEF7C4F9D1 +:10325000AFA0FEF7C1F9B6A0FEF7BEF9BCA0FEF71D +:10326000BBF9C3A0FEF7B8F9CAA0FEF7B5F902E0B2 +:103270002BE05AE032E0D2A0FEF7AEF9D9A0FEF77B +:10328000ABF9DDA0FEF7A8F9E2A0FEF7A5F901E091 +:1032900007E051E2E8A0FEF79FF900E05CE2F4A04D +:1032A000A7E283F0010001E083F002006070BDE856 +:1032B000384001F0A7B8BDE8384000F043BD82F0C7 +:1032C00002000AE082F0040007E082F0080004E057 +:1032D00082F0100001E082F02000606138BD002023 +:1032E000FEF788FC0020FEF798FCEFA081E24FF08B +:1032F0000A0029B1FEF722FC0028EFD1F0A078E205 +:1033000000F0E4FF0028E9D1F2A072E24FF01400CF +:1033100029B1FEF713FC0028E0D1F3A069E200F028 +:10332000D5FF0028DAD1F5A063E24FF0280029B1DB +:10333000FEF704FC0028D1D1F5A05AE200F0C6FF48 +:103340000028CBD1F7A054E20EE20BE24FE241E2BB +:1033500061E20EE2A4000020444D50207365742009 +:10336000746F2031303020487A2E0A003D3D3D3DBB +:103370003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D209A +:1033800048454C5020434F4D4D414E4453203D3D08 +:103390003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D5D +:1033A0003D0A0000683A205072696E742048656CCE +:1033B0007020636F6D6D616E64730A00383A20533C +:1033C000657420416363656C65726F6D65746572C9 +:1033D0002073656E736F72206F6E2F6F66660A00C2 +:1033E000393A20536574204779726F73636F706543 +:1033F0002073656E736F72206F6E2F6F66660A00A2 +:10340000723A205072696E742052656769737465F0 +:1034100072732076616C75650A000000613A205075 +:1034200072696E7420416363656C65726F6D65745B +:10343000657220646174610A00000000673A2050E0 +:1034400072696E74204779726F73636F7065206460 +:103450006174610A00000000713A205072696E7454 +:10346000205175617465726E696F6E20646174615C +:103470000A000000653A205072696E742045756C30 +:10348000657220616E676C657320696E2064656784 +:10349000726565202A203130300A0000743A2050CD +:1034A00072696E742054656D7065726174757265B1 +:1034B00020696E2064656743202A203130300A007D +:1034C000703A205072696E74205065646F6D657437 +:1034D000657220646174610A00000000303A205275 +:1034E00065736574205065646F6D657465720A005C +:1034F000313A2053657420444D502F4D505520666D +:1035000072657175656E637920313020487A0A00E2 +:10351000323A2053657420444D502F4D505520664B +:1035200072657175656E637920323020487A0A00C1 +:10353000333A2053657420444D502F4D505520662A +:1035400072657175656E637920343020487A0A009F +:10355000343A2053657420444D502F4D5055206609 +:1035600072657175656E637920353020487A0A007E +:10357000353A2053657420444D502F4D50552066E8 +:1035800072657175656E63792031303020487A0A32 +:10359000000000002C3A2053657420444D502069EF +:1035A0006E7465727275707420746F2067657374C1 +:1035B000757265206576656E74206F6E6C790A0091 +:1035C0002E3A2053657420444D5020696E74657204 +:1035D0007275707420746F20636F6E74696E756F8E +:1035E00075730A00663A2053657420444D50206F6D +:1035F0006E2F6F66660A0000763A2053657420517C +:1036000075617465726E696F6E206F6E2F6F66667E +:103610000A000000773A2054657374206F75742097 +:103620006C6F772D706F77657220616363656C20B6 +:103630006D6F64650A000000733A2052756E207346 +:10364000656C662D7465737420286465766963659E +:10365000206D75737420626520666163696E6720F2 +:103660007570206F7220646F776E290A0000000069 +:103670003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D7A +:103680003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D6A +:103690003D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D5A +:1036A0003D3D3D3D3D0A00005065646F6D657465AC +:1036B0007220726573657420646F6E652E0A000057 +:1036C000444D502073657420746F20313020487A47 +:1036D0002E0A00004D50552073657420746F203100 +:1036E0003020487A2E0A0000444D50207365742023 +:1036F000746F20323020487A2E0A00004D50552039 +:1037000073657420746F20323020487A2E0A0000CE +:10371000444D502073657420746F20343020487AF3 +:103720002E0A00004D50552073657420746F2034AC +:103730003020487A2E0A00004FF0320031B1FEF7F7 +:10374000FDF900287FF4CAAD35A052E000F0BEFDBF +:103750000028F7D137A04CE000F0B8FD0028F1D1E7 +:1037600039A046E0012000E00220BDE83840FEF725 +:1037700017BA20780028E5D1F9B10025A5702846B0 +:1037800000F0CAFC6078C10700D00825810701D588 +:1037900045F07005400701D545F001052846FFF7C3 +:1037A0007DFB6846FEF70AF9BDF8000000F08EFDCB +:1037B0002AA000BFFDF710FF38BDA5706846FFF7CF +:1037C00097FCBDF80000FEF7B9F9012000F0A4FC59 +:1037D00026A0EFE7208B80F010002083FDF7C6FFC6 +:1037E000207EC00601D425A003E02BA001E021B17A +:1037F0002FA0BDE83840FDF7EFBE142000F022F9FD +:10380000002000F0FBFC607820F0060040F0010092 +:103810006070257038BDBDE8384000F043BE000040 +:10382000444D502073657420746F20353020487AE1 +:103830002E0A00004D50552073657420746F20359A +:103840003020487A2E0A00004D50552073657420B0 +:10385000746F2031303020487A2E0A00444D5020B9 +:1038600064697361626C65642E0A0000444D5020E7 +:10387000656E61626C65642E0A0000004C50207118 +:1038800075617465726E696F6E2064697361626CD4 +:1038900065642E0A000000004C502071756174654B +:1038A000726E696F6E20656E61626C65642E0A00CF +:1038B0005761726E696E673A20466F72206C6F773F +:1038C0002D706F776572206D6F64652C20444D50AC +:1038D000206E6565647320746F206265206469736F +:1038E00061626C65642E0A007CB52D4C80208DF8D9 +:1038F000000020686B460122417D60680078FEF779 +:1039000095FF4FF0FF36E8BB6420FDF767FE00250A +:103910008DF8005020686B460122417D6068007878 +:10392000FEF784FF70BBE574FF20A07204F8080F57 +:10393000310C6070E070E1802072A0720120207173 +:10394000A0761748E5766573001F257340F81A5F67 +:103950004560856025776577E5834FF4FA6000F070 +:1039600017FC78B9022000F035FB58B92A2000F086 +:1039700077FC38B9322000F0A9FC18B90020FFF715 +:103980008DFA00E004E018B9002000F057FB08B100 +:1039900030467CBD002000F0D9FC00207CBD00003A +:1039A000400000202DE9FF4FDFF89480064685B0E7 +:1039B00098F8250015460F464FF0FF39B0BBAFB35E +:1039C000002420E0301B102800DD102080B2834648 +:1039D0003A1901469246204600F0C6FD30BB6A46C1 +:1039E0005946204600F084F900BB50465A466946C5 +:1039F000FCF72BFC20B16FF0010009B0BDE8F08F9F +:103A000004EB0B0084B2B442DCD3280A8DF810001A +:103A10008DF81150D8F80000444604AB417FD8F827 +:103A2000040002220078FEF701FF08B14846E4E7EF +:103A3000012084F825000898E0840020DDE70000DC +:103A4000400000202DE9F84305464FF0FF392828B3 +:103A500044D80727284C00267DB1012000F0CEFB7A +:103A600020208DF800004FF00108012D17D0052D02 +:103A700018D88DF8018005201FE0002000F0BEFB63 +:103A80008DF800608DF8017020686B460222417D40 +:103A900060680078FEF7CAFE00BB267529E08DF845 +:103AA0000160E8E7142D04D802208DF801000A20F7 +:103AB00003E003208DF80100142000F0D1FB9DF8F5 +:103AC00001006B4607EB80108DF801002068022290 +:103AD000417D60680078FEF7A9FE10B14846BDE858 +:103AE000F8830820A072267384F814800020FFF762 +:103AF000D5F90020F3E700004000002070470000E7 +:103B00002DE9FF4F814655488846002490F824103F +:103B100083B01E4625464FF0FF3BD1BB00213170DC +:103B2000817AB1B3017CA1B34A0600D502248A068A +:103B300000D5A41CCA0600D5A41C090700D5A41DE5 +:103B4000016882464068097B6B4600780222FEF7D6 +:103B500033FEF0B9BDF8000047BAA7427BD3DAF8CC +:103B600004205088B7EB500F14D9DAF800006B46E8 +:103B7000C17C10780122FEF71FFE50B99DF80000AD +:103B8000C00607D500F0FEF86FF0010007B0BDE8F1 +:103B9000F08F0DE00598FEF753FBDAF80010DAF825 +:103BA00004006B46497B00782246FEF705FE08B10B +:103BB0005846EBE7B7FBF4F01099401E0870002060 +:103BC0003070ECB39AF8101050460A07694613D5C6 +:103BD000BDF80020062552BAA8F80020BDF8022042 +:103BE00052BAA8F80220BDF8042052BAA8F804205E +:103BF000327842F008023270A5420CD0027C5206A4 +:103C000009D54A19AD1C128852BAA9F80020327899 +:103C100042F040023270A5420CD0027C920609D5D7 +:103C20004A19AD1C128852BAA9F80220327842F023 +:103C300020023270A5420ED09AF81000C00600E0B3 +:103C400009E008D54819008840BAA9F8040030787E +:103C500040F010003070002098E700004000002085 +:103C60002DE9F843214C0646174694F8240089466E +:103C70004FF0FF3890B3A07A80B320686B460222E1 +:103C8000017B60680078FEF797FD38BBBDF8000047 +:103C900045BAB54202D2002038701FE06068418802 +:103CA000B5EB510F11D9216800786B46C97C012210 +:103CB000FEF782FD90B99DF80000C00605D500F022 +:103CC00061F86FF00100BDE8F8832068F2B24B465E +:103CD000417B60680078FEF76FFD08B14046F2E76F +:103CE000B5FBF6F0401E38700020ECE740000020E5 +:103CF000F8B516000D464FF0FF371FD0104CA17AD3 +:103D0000E1B1010A8DF80010C0B28DF8010041192F +:103D100060684289914211D8216800786B46C97E5B +:103D20000222FEF783FD48B92068EAB23346017EDD +:103D300060680078FEF740FD002800D03846F8BDE6 +:103D40004000002038B500240D4D12E029684A7B60 +:103D5000A2420CD0097EA14209D000786B46012214 +:103D60002146FEF729FD10B14FF0FF3038BD641C2D +:103D7000E4B268680179A142E8D8002038BD0000AB +:103D800040000020F8B5564C4FF0FF36A07A0028CE +:103D90007DD000258DF8005020686B460122417CC3 +:103DA00060680078FEF742FD002870D120686B46FD +:103DB0000122417960680078FEF738FD002866D15D +:103DC00020686B460122017960680078FEF72EFDBD +:103DD00000285CD194F82400E0B30C208DF800009A +:103DE00020686B460122017960680078FEF71EFDAD +:103DF000002872D13220FDF7F1FBC0208DF80000C1 +:103E0000A07AC00702D0E0208DF8000020686B4641 +:103E10000122017960680078FEF708FD00285CD176 +:103E2000607C18B102208DF8000001E08DF8005090 +:103E300020686B460122417C60680078FEF7F6FC42 +:103E400028BB8DF8005020686B46012241796068DC +:103E500000783EE0FFE704208DF8000020686B4604 +:103E60000122017960680078FEF7E0FC78B9A07C57 +:103E700090B9A07AC0070FD05FF060008DF8000005 +:103E800020686B46012201796068007800E024E038 +:103E9000FEF7CCFC08BB01E04020EFE73220FDF745 +:103EA0009DFB607C18B101208DF8000001E08DF8C9 +:103EB000005020686B460122417C60680078FEF764 +:103EC000B5FC50B92068064B012241796068103377 +:103ED0000078FEF7ABFC002800D03046F8BD0000AB +:103EE000400000202DE9F047394C82468AB094F812 +:103EF0002400894620B1002000F00EF9012600E0E0 +:103F0000002607A8FFF7BEF806A8FEF7F1FF09A8EC +:103F1000FFF7D2F808A8FFF7EBF894F80A80277C9F +:103F20000025002249465046FEF700F810B16D1CEE +:103F3000022DF6DB022D1AD00025012203A96846C6 +:103F4000FDF7F4FF10B16D1C022DF6DB022D0ED033 +:103F500003A94846FCF7F8FFC5B269465046FEF78C +:103F6000CBFA10F0FF0F4FF0000002D002E0002566 +:103F700005E001200DB940F0020040F00405FF20EB +:103F800020726072E0724FF6FF71E181A0722074BE +:103F900001202073BDF81C0000F0FAF89DF818000D +:103FA00000F018F8BDF8240000F05AF9BDF8200020 +:103FB00000F08CF9404600F0C9F93846FEF76EFF74 +:103FC00016B1012000F0A8F80AB02846BDE8F08735 +:103FD0004000002038B5184C4FF0FF35A17A19B3D6 +:103FE000022806D0042806D008280ED010281BD19D +:103FF0000DE0002000E008208DF80000607A9DF8B8 +:104000000010B0EBD10F04D005E01020F4E7182029 +:10401000F2E7002038BD20686B460122C179606854 +:104020000078FEF703FC08B1284638BD9DF8000073 +:10403000C0086072EDE7000040000020F8B5354C84 +:104040000546A07CA84201D10020F8BD31484FF0C0 +:10405000FF366B46D0E900104FF001020979007875 +:1040600035B3FEF7A9FB70BB9DF800006B4620F04E +:1040700020008DF800002068012201796068007836 +:10408000FEF7D4FBF8B90320FDF7A8FA02208DF85B +:10409000000094F8220078B382202BE020686B4661 +:1040A0000122C17D60680078FEF7C0FB58B92EE0A0 +:1040B000FEF782FB38B9A07AC0079DF8000003D054 +:1040C00040F0200002E00CE020F020008DF800001D +:1040D00020686B460122017960680078FEF7A6FB34 +:1040E00008B13046F8BD0320FDF778FA94F82200B5 +:1040F00000B180208DF8000094F823000028CDD076 +:104100009DF8000040F030008DF80000C6E7A5746F +:104110009AE700004000002038B51C4C94F82410A9 +:1041200081421DD0002500B394F82500D0B10020B5 +:1041300000F074FB0020FFF781FFE08C00F0C6F870 +:104140008DF8005060686B46012200782321FEF74D +:104150006DFB012084F8240000F060FBFFF712FEE5 +:10416000002038BD4FF0FF3038BD002000F056FB76 +:10417000207C8DF8000060686B46012200782321C6 +:10418000FEF754FB84F82450E8E7000040000020CC +:1041900038B5194C4FF0FF35A17A31B3FA2809D060 +:1041A000B0F5FA7F08D0B0F57A7F0FD0B0F5FA6F8E +:1041B0001BD10DE0002000E008208DF80000207ADF +:1041C0009DF80010B0EBD10F04D005E01020F4E70B +:1041D0001820F2E7002038BD20686B460122817963 +:1041E00060680078FEF722FB08B1284638BD9DF8CC +:1041F0000000C0082072EDE74000002038B5174CE1 +:10420000054694F82300A84201D1002038BD0DB125 +:10421000302000E000208DF80000A07C28B19DF83F +:10422000000040F002008DF8000094F8220028B150 +:104230009DF8000040F080008DF8000020686B467B +:104240000122C17D60680078FEF7F0FA10B14FF0EE +:10425000FF3038BD84F82350D7E70000400000202D +:1042600038B5194C4FF0FF35A17A31B3BC2801D3D2 +:10427000012010E0622801D302200CE02A2801D39B +:10428000032008E0142801D3042004E00A2801D305 +:10429000052000E006208DF80000E07A9DF800106F +:1042A000884201D1002038BD20686B460122817808 +:1042B00060680078FEF7BAFA08B1284638BD9DF864 +:1042C0000000E072EEE7000040000020F8B51E4D4F +:1042D00004464FF0FF37A87A48B395F8240030BB66 +:1042E000287D4FF47A7648B164B1282C03D8204653 +:1042F000FFF7A8FB26E00020FFF7A4FB042C05D263 +:10430000042406E00020FFF79DFBF9E7B44200D942 +:104310003446B6FBF4F0401E8DF8000028686B466A +:104320000122417868680078FEF780FA08B13846C3 +:10433000F8BD9DF80000401CB6FBF0F0E881400895 +:10434000FFF78EFF0020F8BD40000020F8B50546BD +:1043500010F0700F4FF0000601D0012004E015B1FD +:104360008DF8006002E040208DF80000244C6B4680 +:1043700001222068417D60680078FEF757FA4FF00F +:10438000FF3760BB9DF8000020F0400020738DF8DF +:104390000060680602D404208DF80000A80605D449 +:1043A0009DF8000040F002008DF80000E80605D4FA +:1043B0009DF8000040F001008DF80000280705D4AA +:1043C0009DF8000040F038008DF8000020686B4632 +:1043D0000122817D60680078FEF728FA10B1A6728C +:1043E0003846F8BD25B1082D02D00020FFF706FFA2 +:1043F000A57226753220FDF7F1F80020F8BD000007 +:1044000040000020F8B5124E002425467078C00701 +:1044100002D008240FA000E013A0FDF7DDF87078AB +:10442000800704D544F07004357814A000E018A08B +:10443000FDF7D2F82046FFF789FF2046FEF72EFD54 +:10444000002D04D0002030706846FEF751FEF8BD04 +:10445000A4000020416363656C2073656E736F7206 +:10446000204F6E2E0A000000416363656C20736567 +:104470006E736F72204F66662E0A00004779726F66 +:104480002073656E736F72204F6E2E0A000000005D +:104490004779726F2073656E736F72204F66662E58 +:1044A0000A00000010B586B003A96846FFF71AFDA0 +:1044B000044607280ED0E00702D107A0FDF78CF8CC +:1044C000A00702D408A0FDF787F8600702D40AA06D +:1044D000FDF782F806B010BD4779726F20666169FA +:1044E0006C65642E0A000000416363656C206661A0 +:1044F000696C65642E0A0000436F6D7061737320F0 +:104500006661696C65642E0A00000000072812D2FB +:10451000DFE800F0110406080A0C0E0006A008E00F +:1045200007A006E008A004E009A002E00AA000E05D +:104530000BA0FDF751B8704754617020582B200034 +:1045400054617020582D200054617020592B200098 +:1045500054617020592D2000546170205A2B200086 +:10456000546170205A2D2000F8B516000D464FF00A +:10457000FF371FD0104CA17AE1B1010A8DF800106D +:10458000C0B28DF80100411960684289914211D88A +:10459000216800786B46C97E0222FEF747F948B9C8 +:1045A0002068EAB23346017E60680078FEF73EF983 +:1045B000002800D03846F8BD4000002070B5214BDF +:1045C00000252C461E68C6F30226072E14D01E684E +:1045D000C6F30226062E11D01E68C6F30226052E4B +:1045E0000FD01E68C6F30226042E0DD01B68C3F33D +:1045F0000223032B0BD00BE0042409E00125032444 +:1046000006E002252C4603E00325012400E00425F2 +:10461000C5F104039940C4F104040F23E34013409F +:104620000B4300F1E022190182F8001400F01F0290 +:10463000012191404009800000F1E020C0F8001104 +:1046400070BD00000CED00E002490843024908601B +:10465000704700000000FA050CED00E02DE9F0477E +:1046600051A688B05ACE8DE85A0050A38046D3E9AF +:104670000013CDE904134DA10020D1E90031CDE9AB +:1046800006314D4B0546024659684C4EC1F3810137 +:1046900019B1012901D0022901D0314617E059682A +:1046A0005C68C1F38341C4F3C0640CB1113100E014 +:1046B000891C5C68C4F300443CB1DC6A04F00F045C +:1046C000641CB6FBF4F4614301E03D4C61435C685B +:1046D000C4F303141DF8047021FA07F45F680DF1A8 +:1046E000100CC7F302271CF8077024FA07F95F685B +:1046F0000DF1180CC7F3C2274FF4004A1CF80770DD +:1047000024FA07F7B8F1070F06D2DFE808F004082B +:104710000A0C0E293100084608B0BDE8F087204693 +:10472000FAE74846F8E73846F6E7186BC00501D4C3 +:10473000244D13E05868C0F3813030B1012806D011 +:10474000022806D0032809D107E07D0806E0BD084D +:1047500004E00620B7FBF0F500E0FD082846DBE7A3 +:10476000186B400602D448F21200D5E75046D3E752 +:10477000186B80070ED0186B00F0030001280BD0D7 +:10478000186B00F00300022808D0186BC0438007A4 +:1047900006D006E03A4604E00A4602E0524600E04F +:1047A00032461046B8E7000000000000000000009C +:1047B00001020304060708090010024000127A00F3 +:1047C00000093D00809FD500054901EB90110A6862 +:1047D00000F01F030120984002430A607047000068 +:1047E00000100240054901EB90110A6800F01F0318 +:1047F0000120984082430A60704700000010024088 +:10480000054901EB90110A6800F01F030120984050 +:1048100002430A607047000000100240F8B5144CD3 +:104820000146224694F82460D2E9000200235D1E6E +:1048300056B179B1022111E0417C10786B4601221A +:10484000FDF7F4FF68B90EE0A67A56B111B1617CAC +:1048500061B902E08DF80030EEE701218DF800101B +:10486000EAE72846F8BD9DF8000060740020F8BD16 +:10487000400000202DE9F04106460F46FCF7F7F80E +:10488000041E0D4618BF0120284320F00040C0F14F +:104890007F6000F1E040C00F0ED0301C18BF012037 +:1048A000384320F00040C0F17F6000F1E040C00FCD +:1048B00004BF0120FCF742FB20462946BDE8F081F9 +:1048C0001048416841604168416041684160416809 +:1048D0000D4A1140416041680C4A11434160016832 +:1048E00041F08071016001688901FCD5416821F0C7 +:1048F00003014160416841F00201416041680907DC +:10490000FCD5704700100240FFFFC2F7000004080A +:1049100070B50E484FF47A710068B0FBF1F0401E9C +:10492000B0F1807F11D24FF0E024606165170F2154 +:104930002846FCF729FA0020A061072020612846BC +:10494000BDE870400021FCF71FBAFEE70000002020 +:1049500002480168491C01607047000024000020E3 +:10496000F0B507468FB015460E460420FCF778FEDA +:1049700000240D950C940B94CDE90964104D4FF46F +:104980004050CDE9065401260E90182209A9089638 +:104990006846FBF736FC3346224629460420FCF7DE +:1049A00083FE0420FCF750FE0420FCF7B5FE042033 +:1049B000FCF732FE4021384600F0DEF80FB0F0BDC3 +:1049C00024440040F0B507468FB016460C464FF41D +:1049D000A060FFF7F9FE0320FCF742FE09940125D1 +:1049E0000024CDE90B450D964FF440500F4E0E902C +:1049F0000A940696182209A96846CDE90745FBF7EF +:104A000000FC2B46224631460320FCF74DFE0320D6 +:104A1000FCF70EFE0320FCF77FFE0320FCF7FCFDF5 +:104A20008021384600F0B0F80FB0F0BD28440040B7 +:104A300070B50D46044614490020611804D0B1F544 +:104A4000744F04D1062000E00220FFF707FE216822 +:104A50004FF6F07209040BD5400000EB5500B0FB97 +:104A6000F5F000EA0201C0F3420241EA020008E068 +:104A700000EB5500B0FBF5F101EA020001F00F0177 +:104A80000843E06070BD000000BCFFBF2DE9F047A7 +:104A9000894605462949002429488D4202D085428D +:104AA00000D1012440F21150FFF78EFE254830F866 +:104AB0001400FFF789FE234E4FF09048361D012168 +:104AC00056F824204046FDF7C1FB06F108070121F6 +:104AD00057F824204046FDF7B9FB56F82430012250 +:104AE00002214046FDF7C5FC56F824300122002182 +:104AF0004046FDF7E1FC57F82430012202214046F0 +:104B0000FDF7B7FC57F82430012200214046FDF79D +:104B1000D3FC284600F018F849462846FFF788FFDE +:104B20000821284600F045F80421284600F039F80D +:104B30002846BDE8F04700F02FB8000000380140DB +:104B400000440040100000200A4910B5401805D06C +:104B5000B0F5744F0CD140F20E3401E040F2114434 +:104B60002046FFF74DFE2046BDE81040FFF73ABE55 +:104B700010BD000000BCFFBF826822F040028260CE +:104B800082680A4382607047826822F080028260F5 +:104B900082680A4382607047016841F00101016048 +:104BA0007047026822F00402026002680A43026051 +:104BB0007047026822F00802026002680A4302603D +:104BC000704775191A0C6A231B1C00001F20727491 +:104BD000433B4138393A006B6C376F06246D6E7079 +:104BE0006800000476005401F7FD00018300000016 +:104BF00000080000000100183200050000002041FC +:104C00000000D242295C0F3E9A99993E3333733F9C +:104C1000295C0F3E0000700000000024000000022C +:104C20000003000000650054FFEF0000FA80000B55 +:104C300012820001030C30C30E8C8CE914D54002A3 +:104C400013710F8E3883F8833000F883258EF88334 +:104C50003000F883FFFFFFFF0FFEA9D624000400F9 +:104C60001A8279A10000003CFFFF00000010000044 +:104C700038836FA2003E03304000000002CAE309FF +:104C80003E80000020000000000000004000000006 +:104C900060000000000C0000000C186E000006927E +:104CA0000A16C0DFFFFF0256FD8CD377FFE1C496E2 +:104CB000E0C5BEAA00000000FFFF0B2B0000165746 +:104CC000000003594000000000001DFA00026C1DA6 +:104CD000000000003FFFDFEB003EB3B6000D22787E +:104CE00000002F3C00000000001942B5000039A26E +:104CF0000000B365D90E9FC91DCF4C3430000000B1 +:104D0000500000003BB67AE80064000000C80000D4 +:104D100000000000100000001000FA921000225E57 +:104D2000000D229F0001000000320000FF4600003D +:104D300063D400001000000004D6000004CC000082 +:104D400004CC0000000010720000004000000000D1 +:104D5000000000000006000200050007000000003F +:104D60000064000000000000000000050005006471 +:104D700000200000000000000000000000004000D3 +:104D80000000030000000032F8980000FF650000FA +:104D9000830F0000FF9BFC000000000000000000EB +:104DA0000000000000000000000000000000000003 +:104DB00000000000000000000000000000000000F3 +:104DC0000000100040000000000000060000B26A71 +:104DD000000200000001FB830068000000D9FC0015 +:104DE0007CF1FF830000000000650000006403E820 +:104DF00000640028000000250000000016A000004C +:104E00000000100000001000002F0000000001F45E +:104E10000000100000280000FFFF4581FFFFFA722C +:104E20000000000000000000004400050005BAC6B4 +:104E3000004778A20000000100000000000006000A +:104E4000000000140000254D002F706D000005AE1D +:104E5000000C02D000000000000000000000000074 +:104E600000000000001B0000000000000000000027 +:104E700000000000006400000008000000000000C6 +:104E80000000000000000000000000000000000022 +:104E90000000000000000000000000000000000012 +:104EA0000000000000000000000000000000000002 +:104EB00000000000000000000000000000000000F2 +:104EC00000000000000000000000000000000000E2 +:104ED00000000000001B00000000000000000000B7 +:104EE000000E000E00000AC700040000000000329F +:104EF000FFFFFF9C00000B2B0000000200000001E0 +:104F000000000064FFE50000000000000000000059 +:104F1000000000000000000100000000000100008F +:104F200000000000000180000001800000018000FE +:104F3000002426D30000000000000000000600103E +:104F40000096003C0000000000000000000000008F +:104F5000000000000C0A4E68CDCF77095016675943 +:104F6000C619CE8200000000000000000000000012 +:104F700000000000000000000000000017D78400BF +:104F8000030000000000000000000000C7938F9D98 +:104F90001E1B1C19000000000000000000000000A3 +:104FA000000000000000000000000000020318855F +:104FB00000004000000000030000000300000000AB +:104FC00000000000400000000000000000000000A1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF0000000000000000000677DDF7E72902E55EB +:105000004CF6E688000000000000000000000000F0 +:1050100000000000D8DCB4B8B0D8B9ABF3F8FAB3EC +:10502000B7BB8E9EAEF132F51BF1B4B8B08097F1EC +:10503000A9DFDFDFAADFDFDFF2AAC5CDC7A90CC970 +:105040002C97F1A989264666B28999A92D557DB07C +:10505000B08AA896365676F1BAA3B4B280C0B8A882 +:105060009711B28398BAA3F0240844106418B2B917 +:10507000B49883F1A329557DBAB5B1A38393F00009 +:105080002850F5B2B6AA839328547CF1B9A3829331 +:1050900061BAA2DADEDFDB819AB9AEF5606870F141 +:1050A000DABAA2DFD9BAA2FAB9A38292DB31BAA2E4 +:1050B000D9BAA2F8DF85A4D0C1BBAD83C2C5C7B839 +:1050C000A2DFDFDFBAA0DFDFDFD8D8F1B8AAB38D67 +:1050D000B4980D355DB2B6BAAF8C96198F9FA70EF6 +:1050E000161EB49AB8AA872C547CBAA4B08AB6917A +:1050F000325676B28494A4C808CDD8B8B4B0F19929 +:1051000082A82D557D98A80E161EA22C547C92A420 +:10511000F02C5078F184A898C4CDFCD80DDBA8FC05 +:105120002DF3D9BAA6F8DABAA6DED8BAB2B6869600 +:10513000A6D0F3C841DAA6C8F8D8B0B4B882A8920D +:10514000F52C548898F135D9F418D8F1A2D0F8F993 +:10515000A884D9C7DFF8F883C5DADF69DF83C1D84F +:10516000F40114F1A8824EA884F311D182F5D992EA +:10517000289788F109F41C1CD884A8F3C0F9D1D968 +:105180009782F129F40DD8F3F9F9D1D982F4C20349 +:10519000D8DEDF1AD8F1A2FAF9A88498D9C7DFF8C7 +:1051A000F8F883C7DADF69DFF883C3D8F40114F1B4 +:1051B00098A8822EA884F311D182F5D992509788AD +:1051C000F109F41CD884A8F3C0F8F9D1D99782F179 +:1051D00049F40DD8F3F9F9D1D982F4C403D8DEDF4C +:1051E000D8F1AD8898CCA809F9D98292A8F57CF1BC +:1051F000883ACF944A6E98DB6931DAADF2DEF9D89D +:105200008795A8F221D1DAA5F9F417D9F1AE8ED09D +:10521000C0C3AE82C684C3A88595C8A588F2C0F174 +:10522000F4010EF18E9EA8C63E56F554F18872F434 +:105230000115F19845856EF58E9E0488F142985AC5 +:105240008E9E068869F4011CF1981E1108D0F504A1 +:10525000F11E970202983625DBF9D985A5F3C1DA4C +:1052600085A5F3DFD88595A8F309DAA5FAD8829247 +:10527000A8F578F1881A849F26889821DAF41DF31E +:10528000D8879F39D1AFD9DFDFFBF9F40CF3D8FA17 +:10529000D0F8DAF9F9D0DFD9F9D8F40BD8F3879F31 +:1052A00039D1AFD9DFDFF41DF3D8FAFCA869F9F9D9 +:1052B000AFD0DADEFAD9F88F9FA8F1CCF398DB45AE +:1052C000D9AFDFD0F8D8F18F9FA8CAF38809DAAF39 +:1052D0008FCBF8D8F2AD978D0CD9A5DFF9BAA6F32C +:1052E000FAF412F2D8950DD1D9BAA6F3FADAA5F2EA +:1052F000C1BAA6F3DFD8F1BAB2B68696A6D0CAF381 +:1053000049DAA6CBF8D8B0B4B8D8AD84F2C0DFF192 +:105310008FCBC3A8B2B68696C8C1CBC3F3B0B4884E +:1053200098A821DB718D9D71859521D9ADF2FAD8B0 +:105330008597A828D9F408D8F28D29DAF405D9F28E +:1053400085A4C2F2D8A88D9401D1D9F411F2D887DE +:1053500021D8F40AD8F28498A8C801D1D9F411D878 +:10536000F3A4C8BBAFD0F2DEF8F8F8F8F8F8F8F814 +:10537000D8F1B8F6B5B9B08A95A3DE3CA3D9F8D870 +:105380005CA3D9F8D87CA3D9F8D8F8F9D1A5D9DF8E +:10539000DAFAD8B18530F7D9DED8F830ADDADED810 +:1053A000F2B48C99A32D557DA083DFDFDFB591A0EA +:1053B000F629D9FBD8A0FC29D9FAD8A0D051D9F820 +:1053C000D8FC51D9F9D879D9FBD8A0D0FC79D9FA31 +:1053D000D8A1F9F9F9F9F9A0DADFDFDFD8A1F8F8F7 +:1053E000F8F8F8ACDEF8ADDE8393AC2C547CF1A871 +:1053F000DFDFDFF69D2CDAA0DFD9FADB2DF8D8A8A5 +:1054000050DAA0D0DED9D0F8F8F8DB55F8D8A87873 +:10541000DAA0D0DFD9D0FAF8F8F8F8DB7DF8D89C1C +:10542000A88CF530DB38D9D0DEDFA0D0DEDFD8A8FD +:1054300048DB58D9DFD0DEA0DFD0DED8A868DB702B +:10544000D9DFDFA0DFDFD8F1A888902C547C98A8A2 +:10545000D05C38D1DAF2AE8CDFF9D8B087A8C1C100 +:10546000B188A8C6F9F9DA36D8A8F9DA36D8A8F991 +:10547000DA36D8A8F9DA36D8A8F9DA36D8F78D9D11 +:10548000ADF818DAF2AEDFD8F7ADFA30D9A4DEF90C +:10549000D8F2AEDEFAF983A7D9C3C5C7F1889BA7B6 +:1054A0007AADF7DEDFA4F8849408A797F300AEF294 +:1054B0009819A488C6A39488F632DFF28393DB0997 +:1054C000D9F2AADFD8D8AEF8F9D1DAF3A4DEA7F181 +:1054D000889B7AD8F38494AE19F9DAAAF1DFD8A8B8 +:1054E00081C0C3C5C7A39283F628ADDED9F8D8A37F +:1054F00050ADD9F8D8A378ADD9F8D8F8F9D1A1DA58 +:10550000DEC3C5C7D8A18194F818F2B089ACC3C571 +:10551000C7F1D8B8B4B09786A8319B069907AB9766 +:1055200028889BF00C201440B0B4B8F0A88A9A28C0 +:105530005078B79BA8295179247059446938644838 +:1055400031F1BBAB88002C547CF0B38BB8A8042895 +:105550005078F1B088B49726A85998BBABB38B02AA +:10556000264666B0B8F08A9CA82951798B295179D2 +:105570008A2470598B2058718A4469388B39406865 +:105580008A6448318B30496088F1AC002C547CF03F +:105590008CA804285078F1889726A85998AC8C02DA +:1055A000264666F0899CA8295179247059446938A7 +:1055B000644831A98809205970AB11384069A8198D +:1055C0003148608CA83C415C207C00F187981986AA +:1055D000A86E767EA999882D557DD8B1B5B9A3DF7F +:1055E000DFDFAED0DFAAD0DEF2ABF8F9D9B087C4E6 +:1055F000AAF1DFDFBBAFDFDFB9D8B1F1A3978E60CF +:10560000DFB084F2C8F8F9D9DED89385F14AB183C6 +:10561000A308B5839A0810B79F10D8F1B0BAAEB0FE +:105620008AC2B2B68E9EF1FBD9F41DD8F9D90CF11D +:10563000D8F8F8AD61D9AEFBD8F40CF1D8F8F8ADD4 +:1056400019D9AEFBDFD8F416F1D8F8AD8D61D9F4D5 +:10565000F4ACF59C9C8DDF2BBAB6AEFAF8F40BD8FF +:10566000F1AED0F8AD51DAAEFAF8F1D8B9B1B6A3CF +:10567000839C08B9B1839AB5AAC0FD3083B79F1047 +:10568000B58B93F20202D1ABDADED8F1B080BAABBF +:10569000C0C3B284C1C3D8B1B9F38BA391B609B466 +:1056A000D9ABDEB0879CB9A3DDF1B38B8B8B8B8B31 +:1056B000B087A3A3A3A3B28BB69BF2A3A3A3A3A378 +:1056C000A3A3A3A3A3F1B087B59AA3F39BA3A3DCE1 +:1056D000BAACDFB9A3A3A3A3A3A3A3A3A3A3A3A328 +:1056E000A3A3A3A3D8D8D8BBB3B7F1AAF9DAFFD93B +:1056F000809AAA28B48098A720B79787A86688F0D0 +:105700007951F1902C870CA781976293F0717160A9 +:1057100085940129517990A5F1284C6C870C951836 +:105720008578A38390284C6C886CD8F3A28200F211 +:1057300010A8921980A2F2D926D8F188A84DD9488C +:10574000D896A83980D93CD89580A839A68698D90A +:105750002CDA87A72CD8A8899519A980D938D8A878 +:105760008939A980DA3CD8A82EA83990D90CD8A8B4 +:10577000953198D90CD8A809D9FFD801DAFFD89566 +:1057800039A9DA26FFD890A80D8999A81080982108 +:10579000DA2ED88999A83180DA2ED8A88696318059 +:1057A000DA2ED8A8873180DA2ED8A88292F34180E9 +:1057B000F1D92ED8A882F31980F1D92ED882ACF372 +:1057C000C0A28022F1A62EA72EA92298A829DAAC81 +:1057D000DEFFD8A2F22AF1A92E8292A8F23180A689 +:1057E00096F1D900AC8C9C0C30ACDED0DEFFD88CAE +:1057F0009CACD010ACDE8092A2F24C82A8F1CAF22E +:1058000035F19688A6D900D8F1FF0000000000000D +:10581000555555555555C53F7D6FEB0312D6D4BF31 +:105820005544880E55C1C93F3B8F68B52882A4BF37 +:1058300088B20175E0EF493F09F7FD0DE13D023FF8 +:105840004B2D8A1C273A03C0C88A599CE52A004080 +:1058500059018D1B6C06E6BF82922EB1C5B8B33FCD +:105860004FBB610567ACDD3F182D4454FB21E93F78 +:105870009BF681D20B73EF3F182D4454FB21F93F67 +:10588000E2652F227F2B7A3C075C143326A6813CED +:10589000BDCBF07A8807703C075C143326A6913C98 +:1058A000C4EB98999999C9BF711623FEC671BCBF04 +:1058B0006D9A74AFF2B0B3BF9AFDDE522DDEADBF6C +:1058C0002F6C6A2C44B4A2BF0D5555555555D53F84 +:1058D000FF8300922449C23F6E204CC5CD45B73F9F +:1058E000513DD0A0660DB13FEB0D76244B7BA93F17 +:1058F00011DA22E33AAD903F000000000000000002 +:105900002059000800000020700000001C0F000853 +:105910009059000870000020980400002C0F000827 +:1059200000A24A0400010000000000000000000086 +:105930000E06110700020000040000000004000031 +:10594000080000000000000000000000000000004F +:105950000000000000000000000000000000000047 +:10596000C24B0008E04B00080000000000000000EF +:105970000000000000000000000000000000000027 +:105980000000000000000000EC4B000800000000D8 +:040000050800016985 +:00000001FF diff --git a/docs/1_MPU-6000-Datasheet.pdf b/docs/1_MPU-6000-Datasheet.pdf new file mode 100644 index 0000000..8e5ac97 Binary files /dev/null and b/docs/1_MPU-6000-Datasheet.pdf differ diff --git a/docs/2_MPU-6000-Register-Map.pdf b/docs/2_MPU-6000-Register-Map.pdf new file mode 100644 index 0000000..2677c83 Binary files /dev/null and b/docs/2_MPU-6000-Register-Map.pdf differ diff --git a/docs/3_MPU-6000-Motion-Driver6.12-Getting-Started.pdf b/docs/3_MPU-6000-Motion-Driver6.12-Getting-Started.pdf new file mode 100644 index 0000000..9890692 Binary files /dev/null and b/docs/3_MPU-6000-Motion-Driver6.12-Getting-Started.pdf differ diff --git a/docs/4_MPU-6000-Motion-Driver6.12-Features-Guide.pdf b/docs/4_MPU-6000-Motion-Driver6.12-Features-Guide.pdf new file mode 100644 index 0000000..6c3f1ae Binary files /dev/null and b/docs/4_MPU-6000-Motion-Driver6.12-Features-Guide.pdf differ diff --git a/docs/5_MPU-6000-Motion-Driver6.12-Porting-Guide.pdf b/docs/5_MPU-6000-Motion-Driver6.12-Porting-Guide.pdf new file mode 100644 index 0000000..44ae5dc Binary files /dev/null and b/docs/5_MPU-6000-Motion-Driver6.12-Porting-Guide.pdf differ diff --git a/docs/6_MPU-6000-HW-Offset-Registers1.2.pdf b/docs/6_MPU-6000-HW-Offset-Registers1.2.pdf new file mode 100644 index 0000000..eb87f3a Binary files /dev/null and b/docs/6_MPU-6000-HW-Offset-Registers1.2.pdf differ diff --git a/docs/7_MPU-6000-Orientation-Matrix-Transformation-chart.pdf b/docs/7_MPU-6000-Orientation-Matrix-Transformation-chart.pdf new file mode 100644 index 0000000..6346729 Binary files /dev/null and b/docs/7_MPU-6000-Orientation-Matrix-Transformation-chart.pdf differ diff --git a/docs/GD32F10x_Firmware_Library_User_Guide_V1.0.pdf b/docs/GD32F10x_Firmware_Library_User_Guide_V1.0.pdf new file mode 100644 index 0000000..510acfc Binary files /dev/null and b/docs/GD32F10x_Firmware_Library_User_Guide_V1.0.pdf differ diff --git a/docs/GD32F130xx-Datasheet_Rev3.3.pdf b/docs/GD32F130xx-Datasheet_Rev3.3.pdf new file mode 100644 index 0000000..f849def Binary files /dev/null and b/docs/GD32F130xx-Datasheet_Rev3.3.pdf differ diff --git a/docs/GD32F1x0-User_Manual_EN_v3.1.pdf b/docs/GD32F1x0-User_Manual_EN_v3.1.pdf new file mode 100644 index 0000000..67c442e Binary files /dev/null and b/docs/GD32F1x0-User_Manual_EN_v3.1.pdf differ diff --git a/docs/GD32F1x0_AN007_KEIL5_Pack_Note_Rev1.0.pdf b/docs/GD32F1x0_AN007_KEIL5_Pack_Note_Rev1.0.pdf new file mode 100644 index 0000000..79bd12e Binary files /dev/null and b/docs/GD32F1x0_AN007_KEIL5_Pack_Note_Rev1.0.pdf differ diff --git a/docs/GD32F1x0_Addon_V3.1.0.rar b/docs/GD32F1x0_Addon_V3.1.0.rar new file mode 100644 index 0000000..c0dc160 Binary files /dev/null and b/docs/GD32F1x0_Addon_V3.1.0.rar differ diff --git a/docs/GD32F1x0_Demo_Suites_V3.0.0.rar b/docs/GD32F1x0_Demo_Suites_V3.0.0.rar new file mode 100644 index 0000000..26b1786 Binary files /dev/null and b/docs/GD32F1x0_Demo_Suites_V3.0.0.rar differ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0.rar b/docs/GD32F1x0_Firmware_Library_v3.1.0.rar new file mode 100644 index 0000000..f854abc Binary files /dev/null and b/docs/GD32F1x0_Firmware_Library_v3.1.0.rar differ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/gd32f1x0_it.c new file mode 100644 index 0000000..faa383a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/gd32f1x0_it.c @@ -0,0 +1,128 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/*! + \brief ADC and CMP handle function + \param[in] none + \param[out] none + \retval none +*/ +void ADC_CMP_IRQHandler(void) +{ + /* clear the ADC interrupt or status flag */ + adc_interrupt_flag_clear(ADC_FLAG_WDE); + /* turn on selected led */ + gd_eval_led_on(LED2); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/gd32f1x0_it.h new file mode 100644 index 0000000..e8ba63f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* ADC and CMP handle function */ +void ADC_CMP_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/main.c new file mode 100644 index 0000000..21509f2 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/main.c @@ -0,0 +1,127 @@ +/*! + \file main.c + \brief ADC analog watchdog +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +#ifdef GD32F130_150 +#define BOARD_ADC_CHANNEL ADC_CHANNEL_11 +#define ADC_GPIO_PIN GPIO_PIN_1 +#elif defined GD32F170_190 +#define BOARD_ADC_CHANNEL ADC_CHANNEL_10 +#define ADC_GPIO_PIN GPIO_PIN_0 +#endif + +void rcu_config(void); +void gpio_config(void); +void nvic_config(void); +void adc_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* system clocks configuration */ + rcu_config(); + /* GPIO configuration */ + gpio_config(); + /* NVIC configuration */ + nvic_config(); + /* ADC configuration */ + adc_config(); + + while(1); +} + +/*! + \brief configure the different system clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOC clock */ + rcu_periph_clock_enable(RCU_GPIOC); + /* enable ADC clock */ + rcu_periph_clock_enable(RCU_ADC); + /* config ADC clock */ + rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); +} +/*! + \brief configure the gpio peripheral + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* configure led GPIO */ + gd_eval_led_init(LED2); + /* config the GPIO as analog mode */ + gpio_mode_set(GPIOC,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,ADC_GPIO_PIN); +} + +/*! + \brief configure interrupt priority + \param[in] none + \param[out] none + \retval none +*/ +void nvic_config(void) +{ + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + nvic_irq_enable(ADC_CMP_IRQn, 0, 0); +} + +/*! + \brief configure the adc peripheral + \param[in] none + \param[out] none + \retval none +*/ +void adc_config(void) +{ + /* ADC regular channel length config */ + adc_channel_length_config(ADC_REGULAR_CHANNEL,1); + /* ADC regular channel config */ + adc_regular_channel_config(0,BOARD_ADC_CHANNEL,ADC_SAMPLETIME_239POINT5); + /* ADC external trigger enable */ + adc_external_trigger_config(ADC_REGULAR_CHANNEL,ENABLE); + /* ADC external trigger source config */ + adc_external_trigger_source_config(ADC_REGULAR_CHANNEL,ADC_EXTTRIG_REGULAR_SWRCST); + /* ADC data alignment config */ + adc_data_alignment_config(ADC_DATAALIGN_RIGHT); + /* enable ADC interface */ + adc_enable(); + /* ADC calibration and reset calibration */ + adc_calibration_enable(); + /* ADC contineous function enable */ + adc_special_function_config(ADC_CONTINUOUS_MODE,ENABLE); + + /* ADC analog watchdog threshold config */ + adc_watchdog_threshold_config(0x0400,0x0A00); + /* ADC analog watchdog single channel config */ + adc_watchdog_single_channel_enable(BOARD_ADC_CHANNEL); + /* ADC interrupt config */ + adc_interrupt_enable(ADC_INT_WDE); + + /* ADC software trigger enable */ + adc_software_trigger_enable(ADC_REGULAR_CHANNEL); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/readme.txt new file mode 100644 index 0000000..a6b0338 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Analog_watchdog/readme.txt @@ -0,0 +1,25 @@ +/*! + \file readme.txt + \brief description of the ADC analog watchdog +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/ GD32190R-EVAL board, it shows how to +use the ADC analog watchdog to guard continuously an ADC channel.The ADC is configured +in continuous mode, PC1(GD32150R-EVAL) or PC0(GD32190R-EVAL) is chosen as analog +input pin.The ADC clock is configured to 12MHz(below 14MHz or 28MHz). + + When the channel11(channel10) converted value is over the programmed analog +watchdog high threshold (value 0x0A00) or below the analog watchdog low threshold +(value 0x0400),an AWE interrupt will occur,and LED2 will turn on. + + The analog input pin should configured to AN mode and the ADC clock should +below 14MHz for GD32150R(28MHz for GD32190R-EVAL). diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/gd32f1x0_it.c new file mode 100644 index 0000000..3d6cbb5 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/gd32f1x0_it.c @@ -0,0 +1,120 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "main.h" +#include "systick.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while(1){ + } +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while(1){ + } +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while(1){ + } +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while(1){ + } +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/gd32f1x0_it.h new file mode 100644 index 0000000..a5606b7 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* this function handles NMI exception */ +void NMI_Handler(void); +/* this function handles HardFault exception */ +void HardFault_Handler(void); +/* this function handles MemManage exception */ +void MemManage_Handler(void); +/* this function handles BusFault exception */ +void BusFault_Handler(void); +/* this function handles UsageFault exception */ +void UsageFault_Handler(void); +/* this function handles SVC exception */ +void SVC_Handler(void); +/* this function handles DebugMon exception */ +void DebugMon_Handler(void); +/* this function handles PendSV exception */ +void PendSV_Handler(void); +/* this function handles SysTick exception */ +void SysTick_Handler(void); + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/main.c new file mode 100644 index 0000000..1aa3d3e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/main.c @@ -0,0 +1,145 @@ +/*! + \file main.c + \brief ADC oversample and shift +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" +#include +#include "gd32f1x0_eval.h" + +#define BOARD_ADC_CHANNEL ADC_CHANNEL_10 +#define ADC_GPIO_PORT GPIOC +#define ADC_GPIO_PIN GPIO_PIN_0 + +uint16_t adc_value = 0; + +void rcu_config(void); +void gpio_config(void); +void nvic_config(void); +void adc_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ + +int main(void) +{ + /* system clocks configuration */ + rcu_config(); + /* systick configuration */ + systick_config(); + /* GPIO configuration */ + gpio_config(); + /* NVIC configuration */ + nvic_config(); + /* ADC configuration */ + adc_config(); + /* configures COM port */ + gd_eval_com_init(EVAL_COM1); + + adc_software_trigger_enable(ADC_REGULAR_CHANNEL); + + while(1){ + adc_flag_clear(ADC_FLAG_EOC); + while(SET != adc_flag_get(ADC_FLAG_EOC)){ + } + + adc_value = ADC_RDATA; + printf("16 times sample, 4 bits shift: 0x%x\r\n", adc_value); + delay_1ms(1000); + } +} + +/*! + \brief configure the different system clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOC clock */ + rcu_periph_clock_enable(RCU_GPIOC); + /* enable ADC clock */ + rcu_periph_clock_enable(RCU_ADC); + /* config ADC clock */ + rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); +} + +/*! + \brief configure the GPIO peripheral + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* config the GPIO as analog mode */ + gpio_mode_set(ADC_GPIO_PORT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_GPIO_PIN); +} + +/*! + \brief configure interrupt priority + \param[in] none + \param[out] none + \retval none +*/ +void nvic_config(void) +{ + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + nvic_irq_enable(ADC_CMP_IRQn, 0, 0); +} + +/*! + \brief configure the ADC peripheral + \param[in] none + \param[out] none + \retval none +*/ +void adc_config(void) +{ + /* ADC contineous function enable */ + adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE); + /* ADC trigger config */ + adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_SWRCST); + /* ADC data alignment config */ + adc_data_alignment_config(ADC_DATAALIGN_RIGHT); + /* ADC channel length config */ + adc_channel_length_config(ADC_REGULAR_CHANNEL, 1); + + /* ADC regular channel config */ + adc_regular_channel_config(0, BOARD_ADC_CHANNEL, ADC_SAMPLETIME_55POINT5); + adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE); + + /* 16 times sample, 4 bits shift */ + adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_4B, ADC_OVERSAMPLING_RATIO_MUL16); + adc_oversample_mode_enable(); + + /* enable ADC interface */ + adc_enable(); + delay_1ms(1); + /* ADC calibration and reset calibration */ + adc_calibration_enable(); +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t)ch); + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE)); + + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/readme.txt new file mode 100644 index 0000000..2ea0328 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/readme.txt @@ -0,0 +1,22 @@ +/*! + \file readme.txt + \brief description of the ADC oversample shift example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32190R-EVAL board, it shows how to use +the function of oversample and shift. In this demo, 16 times ratio of +oversample and 4 bits shift are configured. PC0(channel10) is chosen as +analog input pin. The ADC conversion begins by software, the converted +data is printed by USART. + + The analog input pin should configured to analog mode. + Jump the JP14, JP15 to USART. \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/systick.c new file mode 100644 index 0000000..a80b914 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Oversample_shift/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/gd32f1x0_it.c new file mode 100644 index 0000000..4f35e38 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/gd32f1x0_it.c @@ -0,0 +1,116 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" +#include "gd32f1x0_eval.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/gd32f1x0_it.h new file mode 100644 index 0000000..a4c6c0f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/main.c new file mode 100644 index 0000000..b60f7d6 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/main.c @@ -0,0 +1,144 @@ +/*! + \file main.c + \brief ADC discontinuous mode for regular channel +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "systick.h" +#include "gd32f1x0_eval.h" + +uint16_t adc_value[16]; + +void rcu_config(void); +void gpio_config(void); +void dma_config(void); +void adc_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* system clocks configuration */ + rcu_config(); + /* GPIO configuration */ + gpio_config(); + /* SYSTICK configuration */ + systick_config(); + /* DMA configuration */ + dma_config(); + /* ADC configuration */ + adc_config(); + + while(1){ + delay_1ms(1000); + /* ADC software trigger enable */ + adc_software_trigger_enable(ADC_REGULAR_CHANNEL); + } +} + +/*! + \brief configure the different system clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOC clock */ + rcu_periph_clock_enable(RCU_GPIOC); + /* enable ADC clock */ + rcu_periph_clock_enable(RCU_ADC); + /* enable DMA clock */ + rcu_periph_clock_enable(RCU_DMA); + /* config ADC clock */ + rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); +} +/*! + \brief configure the gpio peripheral + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* config the GPIO as analog mode */ + gpio_mode_set(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); + gpio_mode_set(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); +} + +/*! + \brief configure the dma peripheral + \param[in] none + \param[out] none + \retval none +*/ +void dma_config(void) +{ + /* ADC DMA_channel configuration */ + dma_deinit(DMA_CH0); + dma_periph_address_config(DMA_CH0,(uint32_t)(&ADC_RDATA)); + dma_memory_address_config(DMA_CH0,(uint32_t)(adc_value)); + dma_transfer_direction_config(DMA_CH0,DMA_PERIPHERAL_TO_MEMORY); + dma_memory_width_config(DMA_CH0,DMA_MEMORY_WIDTH_16BIT); + dma_periph_width_config(DMA_CH0,DMA_PERIPHERAL_WIDTH_16BIT); + dma_priority_config(DMA_CH0,DMA_PRIORITY_HIGH); + dma_transfer_number_config(DMA_CH0,16); + dma_periph_increase_disable(DMA_CH0); + dma_memory_increase_enable(DMA_CH0); + dma_circulation_enable(DMA_CH0); + dma_channel_enable(DMA_CH0); +} + +/*! + \brief configure the adc peripheral + \param[in] none + \param[out] none + \retval none +*/ +void adc_config(void) +{ + /* ADC channel length config */ + adc_channel_length_config(ADC_REGULAR_CHANNEL,8); + + /* ADC regular channel config */ + adc_regular_channel_config(0,ADC_CHANNEL_0,ADC_SAMPLETIME_239POINT5); + adc_regular_channel_config(1,ADC_CHANNEL_1,ADC_SAMPLETIME_239POINT5); + adc_regular_channel_config(2,ADC_CHANNEL_2,ADC_SAMPLETIME_239POINT5); + adc_regular_channel_config(3,ADC_CHANNEL_3,ADC_SAMPLETIME_239POINT5); + adc_regular_channel_config(4,ADC_CHANNEL_4,ADC_SAMPLETIME_239POINT5); + adc_regular_channel_config(5,ADC_CHANNEL_5,ADC_SAMPLETIME_239POINT5); + adc_regular_channel_config(6,ADC_CHANNEL_6,ADC_SAMPLETIME_239POINT5); + adc_regular_channel_config(7,ADC_CHANNEL_7,ADC_SAMPLETIME_239POINT5); + + /* ADC external trigger enable */ + adc_external_trigger_config(ADC_REGULAR_CHANNEL,ENABLE); + /* ADC external trigger source config */ + adc_external_trigger_source_config(ADC_REGULAR_CHANNEL,ADC_EXTTRIG_REGULAR_SWRCST); + /* ADC data alignment config */ + adc_data_alignment_config(ADC_DATAALIGN_RIGHT); + /* ADC discontinuous mode */ + adc_discontinuous_mode_config(ADC_REGULAR_CHANNEL,3); + /* enable ADC interface */ + adc_enable(); + /* ADC calibration and reset calibration */ + adc_calibration_enable(); + /* ADC DMA function enable */ + adc_dma_mode_enable(); + + /* ADC software trigger enable */ + adc_software_trigger_enable(ADC_REGULAR_CHANNEL); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/readme.txt new file mode 100644 index 0000000..7784bca --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the ADC discontinuous mode +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/ GD32190R-EVAL board, it shows how to +use the ADC discontinuous mode.The ADC is configured in discontinuous mode, group length +is 8,conversion length is 3, using software trigger. Every trigger convert 3 channels. +The ADC clock is configured to 12MHz(below 14MHz or 28MHz). + + You can use the watch window to see the conversion result. + \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/systick.c new file mode 100644 index 0000000..f3c0b9e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/systick.c @@ -0,0 +1,63 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +volatile static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000U)){ + /* capture error */ + while (1){ + } + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00U); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0U != delay){ + } +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0U != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_discontinuous_mode/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_with_DMA/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_with_DMA/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_with_DMA/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_with_DMA/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_with_DMA/main.c new file mode 100644 index 0000000..55daf31 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_with_DMA/main.c @@ -0,0 +1,132 @@ +/*! + \file main.c + \brief ADC_regular_channel_with_DMA +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include + +#ifdef GD32F130_150 +#define BOARD_ADC_CHANNEL ADC_CHANNEL_11 +#define ADC_GPIO_PIN GPIO_PIN_1 +#elif defined GD32F170_190 +#define BOARD_ADC_CHANNEL ADC_CHANNEL_10 +#define ADC_GPIO_PIN GPIO_PIN_0 +#endif /* GD32F130_150 */ + +uint16_t adc_value; + +void rcu_config(void); +void gpio_config(void); +void dma_config(void); +void adc_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* system clocks configuration */ + rcu_config(); + /* GPIO configuration */ + gpio_config(); + /* DMA configuration */ + dma_config(); + /* ADC configuration */ + adc_config(); + + while(1); +} + +/*! + \brief configure the different system clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOC clock */ + rcu_periph_clock_enable(RCU_GPIOC); + /* enable DMA clock */ + rcu_periph_clock_enable(RCU_DMA); + /* enable ADC clock */ + rcu_periph_clock_enable(RCU_ADC); + /* config ADC clock */ + rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); +} +/*! + \brief configure the gpio peripheral + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + gpio_mode_set(GPIOC,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,ADC_GPIO_PIN); +} + +/*! + \brief configure the dma peripheral + \param[in] none + \param[out] none + \retval none +*/ +void dma_config(void) +{ + /* ADC_DMA_channel configuration */ + dma_deinit(DMA_CH0); + dma_periph_address_config(DMA_CH0,(uint32_t)(&ADC_RDATA)); + dma_memory_address_config(DMA_CH0,(uint32_t)(&adc_value)); + dma_transfer_direction_config(DMA_CH0,DMA_PERIPHERAL_TO_MEMORY); + dma_memory_width_config(DMA_CH0,DMA_MEMORY_WIDTH_16BIT); + dma_periph_width_config(DMA_CH0,DMA_PERIPHERAL_WIDTH_16BIT); + dma_priority_config(DMA_CH0,DMA_PRIORITY_HIGH); + dma_transfer_number_config(DMA_CH0,1); + dma_periph_increase_disable(DMA_CH0); + dma_memory_increase_enable(DMA_CH0); + dma_circulation_enable(DMA_CH0); + dma_channel_enable(DMA_CH0); +} + +/*! + \brief configure the adc peripheral + \param[in] none + \param[out] none + \retval none +*/ +void adc_config(void) +{ + /* ADC channel length config */ + adc_channel_length_config(ADC_REGULAR_CHANNEL,1); + /* ADC regular channel config */ + adc_regular_channel_config(0,BOARD_ADC_CHANNEL,ADC_SAMPLETIME_239POINT5); + /* ADC external trigger enable */ + adc_external_trigger_config(ADC_REGULAR_CHANNEL,ENABLE); + /* ADC external trigger source config */ + adc_external_trigger_source_config(ADC_REGULAR_CHANNEL,ADC_EXTTRIG_REGULAR_SWRCST); + /* ADC data alignment config */ + adc_data_alignment_config(ADC_DATAALIGN_RIGHT); + /* enable ADC interface */ + adc_enable(); + /* ADC calibration and reset calibration */ + adc_calibration_enable(); + /* ADC DMA function enable */ + adc_dma_mode_enable(); + /* ADC contineous function enable */ + adc_special_function_config(ADC_CONTINUOUS_MODE,ENABLE); + /* ADC software trigger enable */ + adc_software_trigger_enable(ADC_REGULAR_CHANNEL); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_with_DMA/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_with_DMA/readme.txt new file mode 100644 index 0000000..ccbfd7d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Regular_channel_with_DMA/readme.txt @@ -0,0 +1,25 @@ +/*! + \file readme.txt + \brief description of the ADC regular channel with dma +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +use the ADC to convert analog signal to digital data through DMA.The ADC is +configured in continuous mode, PC1(GD32150R-EVAL) or PC0(GD32190R-EVAL) is chosen +as analog input pin. The ADC clock is configured to 12MHz(below 14MHz or 28MHz). + As the AD convertion begins by software,the converted data from ADC_RDATA register +to SRAM begins continuously.Users can change the VR1 on the GD32150R-EVAL/GD32190R-EVAL +board,measure TP1(GD32150R-EVAL) or TP2(GD32190R-EVAL) pad board,and check if +its value matches the converted data through the watch window. + + The analog input pin should configured to AN mode and the ADC clock should +below 14MHz for GD32150R(28MHz for GD32190R-EVAL). diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/gd32f1x0_it.c new file mode 100644 index 0000000..f1cec28 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/gd32f1x0_it.c @@ -0,0 +1,119 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while(1){ + } +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while(1){ + } +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while(1){ + } +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while(1){ + } +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/gd32f1x0_it.h new file mode 100644 index 0000000..a5606b7 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* this function handles NMI exception */ +void NMI_Handler(void); +/* this function handles HardFault exception */ +void HardFault_Handler(void); +/* this function handles MemManage exception */ +void MemManage_Handler(void); +/* this function handles BusFault exception */ +void BusFault_Handler(void); +/* this function handles UsageFault exception */ +void UsageFault_Handler(void); +/* this function handles SVC exception */ +void SVC_Handler(void); +/* this function handles DebugMon exception */ +void DebugMon_Handler(void); +/* this function handles PendSV exception */ +void PendSV_Handler(void); +/* this function handles SysTick exception */ +void SysTick_Handler(void); + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/main.c new file mode 100644 index 0000000..4224592 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/main.c @@ -0,0 +1,144 @@ +/*! + \file main.c + \brief ADC resolution demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" +#include +#include "gd32f1x0_eval.h" + +#define BOARD_ADC_CHANNEL ADC_CHANNEL_10 +#define ADC_GPIO_PORT GPIOC +#define ADC_GPIO_PIN GPIO_PIN_0 + +uint16_t adc_value; + +void rcu_config(void); +void gpio_config(void); +void nvic_config(void); +void adc_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* system clocks configuration */ + rcu_config(); + /* systick configuration */ + systick_config(); + /* GPIO configuration */ + gpio_config(); + /* NVIC configuration */ + nvic_config(); + /* configures COM port */ + gd_eval_com_init(EVAL_COM1); + + /* ADC configuration */ + adc_config(); + adc_software_trigger_enable(ADC_REGULAR_CHANNEL); + + while(1){ + adc_flag_clear(ADC_FLAG_EOC); + while(SET != adc_flag_get(ADC_FLAG_EOC)){ + } + + adc_value = ADC_RDATA; + printf("6B: 0x%x\r\n", adc_value); + delay_1ms(500); + } +} + +/*! + \brief configure the different system clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOC clock */ + rcu_periph_clock_enable(RCU_GPIOC); + /* enable ADC clock */ + rcu_periph_clock_enable(RCU_ADC); + /* config ADC clock */ + rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); +} + +/*! + \brief configure the GPIO peripheral + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* config the GPIO as analog mode */ + gpio_mode_set(ADC_GPIO_PORT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_GPIO_PIN); +} + +/*! + \brief configure interrupt priority + \param[in] none + \param[out] none + \retval none +*/ +void nvic_config(void) +{ + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + nvic_irq_enable(ADC_CMP_IRQn, 0, 0); +} + +/*! + \brief configure the ADC peripheral + \param[in] none + \param[out] none + \retval none +*/ +void adc_config(void) +{ + /* ADC contineous function enable */ + adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE); + /* ADC trigger config */ + adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_SWRCST); + /* ADC data alignment config */ + adc_data_alignment_config(ADC_DATAALIGN_RIGHT); + /* ADC channel length config */ + adc_channel_length_config(ADC_REGULAR_CHANNEL, 1); + + /* ADC regular channel config */ + adc_regular_channel_config(0, BOARD_ADC_CHANNEL, ADC_SAMPLETIME_55POINT5); + adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE); + + /* ADC resolusion 6B */ + printf("\r\nresolusion 6B:\r\n"); + adc_resolution_config(ADC_RESOLUTION_6B); + + /* enable ADC interface */ + adc_enable(); + delay_1ms(1); + /* ADC calibration and reset calibration */ + adc_calibration_enable(); +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t)ch); + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE)); + + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/readme.txt new file mode 100644 index 0000000..6df29cb --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the ADC resolution demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32190R-EVAL board, it shows how to use +the function of programmble resolusion. In this demo, 6B resolusion +is configured. PC0(channel10) is chosen as analog input pin. The ADC +conversion begins by software, the converted data is printed by USART. + + The analog input pin should configured to analog mode. + Jump the JP14, JP15 to USART. \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/systick.c new file mode 100644 index 0000000..a80b914 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Resolution/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/main.c new file mode 100644 index 0000000..1803b73 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/main.c @@ -0,0 +1,98 @@ +/*! + \file main.c + \brief ADC channel of temperature,Vref and Vbat +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void rcu_config(void); +void adc_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* system clocks configuration */ + rcu_config(); + /* ADC configuration */ + adc_config(); + /* USART configuration */ + gd_eval_com_init(EVAL_COM1); + + printf(" the temperature data is %d\r\n",adc_inserted_data_read(ADC_INSERTED_CHANNEL_0)); + printf(" the reference voltage data is %d\r\n",adc_inserted_data_read(ADC_INSERTED_CHANNEL_1)); + printf(" the battery voltage data is %d\r\n",adc_inserted_data_read(ADC_INSERTED_CHANNEL_2)); + while(1); +} + +/*! + \brief configure the different system clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable ADC clock */ + rcu_periph_clock_enable(RCU_ADC); + /* config ADC clock */ + rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); +} + +/*! + \brief configure the adc peripheral + \param[in] none + \param[out] none + \retval none +*/ +void adc_config(void) +{ + /* ADC channel length config */ + adc_channel_length_config(ADC_INSERTED_CHANNEL,3); + + /* ADC regular channel config */ + adc_inserted_channel_config(0,ADC_CHANNEL_16,ADC_SAMPLETIME_239POINT5); + adc_inserted_channel_config(1,ADC_CHANNEL_17,ADC_SAMPLETIME_239POINT5); + adc_inserted_channel_config(2,ADC_CHANNEL_18,ADC_SAMPLETIME_239POINT5); + + /* ADC external trigger enable */ + adc_external_trigger_config(ADC_INSERTED_CHANNEL,ENABLE); + /* ADC external trigger source config */ + adc_external_trigger_source_config(ADC_INSERTED_CHANNEL,ADC_EXTTRIG_INSERTED_SWRCST); + /* ADC data alignment config */ + adc_data_alignment_config(ADC_DATAALIGN_RIGHT); + /* ADC SCAN function enable */ + adc_special_function_config(ADC_SCAN_MODE,ENABLE); + /* ADC Vbat and temperature channel enable */ + adc_tempsensor_vrefint_enable(); + /* enable ADC interface */ + adc_enable(); + /* ADC calibration and reset calibration */ + adc_calibration_enable(); + + /* ADC software trigger enable */ + adc_software_trigger_enable(ADC_INSERTED_CHANNEL); +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t)ch); + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE)); + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/readme.txt new file mode 100644 index 0000000..3c6aad7 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/readme.txt @@ -0,0 +1,24 @@ +/*! + \file readme.txt + \brief description of the ADC TIMER trigger injected channel +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +use the ADC to convert analog signal to digital data.The ADC is configured +in dependent mode, inner channel16(temperature sensor channel),channel17(VREF channel) +and channel18(VBAT/2 channel) are chosen as analog input pin. The ADC clock +is configured to 12MHz. + As the AD convertion begins by software,the converted data in the ADC_IDTRx register +,where the x is 0 to 2. + + The analog input pin should configured to AN mode and the ADC clock should +below 14MHz for GD32150R(28MHz for GD32190R-EVAL). diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Timer_trigger_injected_channel/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Timer_trigger_injected_channel/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Timer_trigger_injected_channel/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Timer_trigger_injected_channel/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Timer_trigger_injected_channel/main.c new file mode 100644 index 0000000..c8d68d5 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Timer_trigger_injected_channel/main.c @@ -0,0 +1,155 @@ +/*! + \file main.c + \brief TIMER trigger injected channel of ADC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" +#include "systick.h" + +uint16_t adc_value[16]; + +void rcu_config(void); +void gpio_config(void); +void nvic_config(void); +void timer_config(void); +void adc_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* system clocks configuration */ + rcu_config(); + /* GPIO configuration */ + gpio_config(); + /* NVIC configuration */ + nvic_config(); + /* TIMER configuration */ + timer_config(); + /* ADC configuration */ + adc_config(); + + timer_enable(TIMER1); + while(1); +} + +/*! + \brief configure the different system clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOC clock */ + rcu_periph_clock_enable(RCU_GPIOC); + /* enable ADC clock */ + rcu_periph_clock_enable(RCU_ADC); + /* enable timer1 clock */ + rcu_periph_clock_enable(RCU_TIMER1); + /* config ADC clock */ + rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); +} +/*! + \brief configure the gpio peripheral + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* configures led GPIO */ + gd_eval_led_init(LED2); + + /* config the GPIO as analog mode */ + gpio_mode_set(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); +} + +/*! + \brief configure interrupt priority + \param[in] none + \param[out] none + \retval none +*/ +void nvic_config(void) +{ + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + nvic_irq_enable(ADC_CMP_IRQn, 0, 0); +} + +/*! + \brief configure the timer peripheral + \param[in] none + \param[out] none + \retval none +*/ +void timer_config(void) +{ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + + /* TIMER1 configuration */ + timer_initpara.prescaler = 7199; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 9999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER1,&timer_initpara); + + /* CH1,CH2 and CH3 configuration in PWM mode1 */ + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + + timer_channel_output_config(TIMER1,TIMER_CH_0,&timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_0,3999); + timer_channel_output_mode_config(TIMER1,TIMER_CH_0,TIMER_OC_MODE_PWM1); + timer_channel_output_shadow_config(TIMER1,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE); +} + +/*! + \brief configure the adc peripheral + \param[in] none + \param[out] none + \retval none +*/ +void adc_config(void) +{ + /* ADC channel length config */ + adc_channel_length_config(ADC_INSERTED_CHANNEL,4); + + /* ADC inserted channel config */ + adc_inserted_channel_config(0,ADC_CHANNEL_0,ADC_SAMPLETIME_239POINT5); + adc_inserted_channel_config(1,ADC_CHANNEL_1,ADC_SAMPLETIME_239POINT5); + adc_inserted_channel_config(2,ADC_CHANNEL_2,ADC_SAMPLETIME_239POINT5); + adc_inserted_channel_config(3,ADC_CHANNEL_3,ADC_SAMPLETIME_239POINT5); + + /* ADC external trigger enable */ + adc_external_trigger_config(ADC_INSERTED_CHANNEL,ENABLE); + /* ADC external trigger source config */ + adc_external_trigger_source_config(ADC_INSERTED_CHANNEL,ADC_EXTTRIG_INSERTED_T1_CH0); + /* ADC data alignment config */ + adc_data_alignment_config(ADC_DATAALIGN_RIGHT); + /* enable ADC interface */ + adc_enable(); + /* ADC calibration and reset calibration */ + adc_calibration_enable(); + /* ADC SCAN function enable */ + adc_special_function_config(ADC_SCAN_MODE,ENABLE); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Timer_trigger_injected_channel/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Timer_trigger_injected_channel/readme.txt new file mode 100644 index 0000000..1f5ad01 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Timer_trigger_injected_channel/readme.txt @@ -0,0 +1,19 @@ +/*! + \file readme.txt + \brief description of the ADC TIMER trigger injected channel +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/ GD32190R-EVAL board, it shows how to +convert ADC inserted group channels continuously using TIM1 external trigger.The +inserted group length is 4, the scan mode is set, every compare event will trigger +ADC convert all the channels in the inserted group.The ADC clock is configured to +12MHz(below 14MHz or 28MHz). diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/gd32f1x0_it.c new file mode 100644 index 0000000..d57413d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/gd32f1x0_it.c @@ -0,0 +1,153 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" + +can_receive_message_struct receive_message; +extern FlagStatus can0_receive_flag; +extern FlagStatus can1_receive_flag; +extern FlagStatus can0_error_flag; +extern FlagStatus can1_error_flag; +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/*! + \brief this function handles CAN0 RX0 exception + \param[in] none + \param[out] none + \retval none +*/ +void CAN0_RX0_IRQHandler(void) +{ + /* check the receive message */ + can_message_receive(CAN0, CAN_FIFO0, &receive_message); + + if((0x300>>1 == receive_message.rx_sfid)&&(CAN_FF_STANDARD == receive_message.rx_ff)&&(2 == receive_message.rx_dlen)){ + can0_receive_flag = SET; + }else{ + can0_error_flag = SET; + } +} +/*! + \brief this function handles CAN1 RX0 exception + \param[in] none + \param[out] none + \retval none +*/ +void CAN1_RX0_IRQHandler(void) +{ + /* check the receive message */ + can_message_receive(CAN1, CAN_FIFO0, &receive_message); + + if((0x300>>1 == receive_message.rx_sfid)&&(CAN_FF_STANDARD == receive_message.rx_ff)&&(2 == receive_message.rx_dlen)){ + can1_receive_flag = SET; + }else{ + can1_error_flag = SET; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/gd32f1x0_it.h new file mode 100644 index 0000000..17d33a7 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/gd32f1x0_it.h @@ -0,0 +1,44 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* CAN0 RX0 handle function */ +void CAN0_RX0_IRQHandler(void); +/* CAN1 RX0 handle function */ +void CAN1_RX0_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/main.c new file mode 100644 index 0000000..ef7f6ab --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/main.c @@ -0,0 +1,285 @@ +/*! + \file main.c + \brief dual CAN communication in normal mode +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +/* select CAN baudrate */ +/* 1MBps */ +#define CAN_BAUDRATE 1000 +/* 500kBps */ +/* #define CAN_BAUDRATE 500 */ +/* 250kBps */ +/* #define CAN_BAUDRATE 250 */ +/* 125kBps */ +/* #define CAN_BAUDRATE 125 */ +/* 100kBps */ +/* #define CAN_BAUDRATE 100 */ +/* 50kBps */ +/* #define CAN_BAUDRATE 50 */ +/* 20kBps */ +/* #define CAN_BAUDRATE 20 */ + +extern can_receive_message_struct receive_message; +FlagStatus can0_receive_flag; +FlagStatus can1_receive_flag; +FlagStatus can0_error_flag; +FlagStatus can1_error_flag; +can_parameter_struct can_init_parameter; +can_filter_parameter_struct can_filter_parameter; +can_trasnmit_message_struct transmit_message; + +void nvic_config(void); +void led_config(void); +void can_gpio_config(void); +void can_config(can_parameter_struct can_parameter, can_filter_parameter_struct can_filter); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + can0_receive_flag = RESET; + can1_receive_flag = RESET; + can0_error_flag = RESET; + can1_error_flag = RESET; + + /* configure GPIO */ + can_gpio_config(); + + /* configure NVIC */ + nvic_config(); + + /* configure USART */ + gd_eval_com_init(EVAL_COM2); + + /* configure Wakeup key or Tamper key */ + gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO); + gd_eval_key_init(KEY_TAMPER, KEY_MODE_GPIO); + + printf("\r\nGD32F1x0 dual CAN test, please press Wakeup key or Tamper key to start communication!\r\n"); + /* configure leds */ + led_config(); + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + gd_eval_led_off(LED3); + gd_eval_led_off(LED4); + + /* initialize CAN and filter */ + can_config(can_init_parameter, can_filter_parameter); + + /* enable phy */ + can_phy_enable(CAN0); + + /* enable can receive FIFO0 not empty interrupt */ + can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0); + can_interrupt_enable(CAN1, CAN_INTEN_RFNEIE0); + + /* initialize transmit message */ + transmit_message.tx_sfid = 0x300>>1; + transmit_message.tx_efid = 0x00; + transmit_message.tx_ft = CAN_FT_DATA; + transmit_message.tx_ff = CAN_FF_STANDARD; + transmit_message.tx_dlen = 2; + + while(1){ + /* test whether the Tamper key is pressed */ + if(0 == gd_eval_key_state_get(KEY_TAMPER)){ + transmit_message.tx_data[0] = 0x55; + transmit_message.tx_data[1] = 0xAA; + printf("\r\n can0 transmit data:%x,%x", transmit_message.tx_data[0],transmit_message.tx_data[1]); + /* transmit message */ + can_message_transmit(CAN0, &transmit_message); + /* waiting for the Tamper key up */ + while(0 == gd_eval_key_state_get(KEY_TAMPER)); + } + /* test whether the Wakeup key is pressed */ + if(0 == gd_eval_key_state_get(KEY_WAKEUP)){ + transmit_message.tx_data[0] = 0xAA; + transmit_message.tx_data[1] = 0x55; + printf("\r\n can1 transmit data:%x,%x", transmit_message.tx_data[0],transmit_message.tx_data[1]); + /* transmit message */ + can_message_transmit(CAN1, &transmit_message); + /* waiting for the Wakeup key up */ + while(0 == gd_eval_key_state_get(KEY_WAKEUP)); + } + /* CAN0 receive data correctly, the received data is printed */ + if(SET == can0_receive_flag){ + can0_receive_flag = RESET; + printf("\r\n can0 receive data:%x,%x",receive_message.rx_data[0],receive_message.rx_data[1]); + gd_eval_led_toggle(LED3); + } + /* CAN1 receive data correctly, the received data is printed */ + if(SET == can1_receive_flag){ + can1_receive_flag = RESET; + gd_eval_led_toggle(LED4); + printf("\r\n can1 receive data:%x,%x",receive_message.rx_data[0],receive_message.rx_data[1]); + } + /* CAN0 error */ + if(SET == can0_error_flag){ + can0_error_flag = RESET; + printf("\r\n can0 communication error"); + } + /* CAN1 error */ + if(SET == can1_error_flag){ + can1_error_flag = RESET; + printf("\r\n can1 communication error"); + } + } +} + +/*! + \brief initialize CAN and filter + \param[in] can_parameter + \arg can_parameter_struct + \param[in] can_filter + \arg can_filter_parameter_struct + \param[out] none + \retval none +*/ +void can_config(can_parameter_struct can_parameter, can_filter_parameter_struct can_filter) +{ + /* initialize CAN register */ + can_deinit(CAN0); + can_deinit(CAN1); + + /* initialize CAN parameters */ + can_parameter.time_triggered=DISABLE; + can_parameter.auto_bus_off_recovery=DISABLE; + can_parameter.auto_wake_up=DISABLE; + can_parameter.auto_retrans=DISABLE; + can_parameter.rec_fifo_overwrite=DISABLE; + can_parameter.trans_fifo_order=DISABLE; + can_parameter.working_mode=CAN_NORMAL_MODE; + can_parameter.resync_jump_width=CAN_BT_SJW_1TQ; + can_parameter.time_segment_1=CAN_BT_BS1_4TQ; + can_parameter.time_segment_2=CAN_BT_BS2_3TQ; + + /* 1MBps */ +#if CAN_BAUDRATE == 1000 + can_parameter.prescaler =9; + /* 500KBps */ +#elif CAN_BAUDRATE == 500 + can_parameter.prescaler =18; + /* 250KBps */ +#elif CAN_BAUDRATE == 250 + can_parameter.prescaler =36; + /* 125KBps */ +#elif CAN_BAUDRATE == 125 + can_parameter.prescaler =72; + /* 100KBps */ +#elif CAN_BAUDRATE == 100 + can_parameter.prescaler =90; + /* 50KBps */ +#elif CAN_BAUDRATE == 50 + can_parameter.prescaler =180; + /* 20KBps */ +#elif CAN_BAUDRATE == 20 + can_parameter.prescaler =450; +#else + #error "please select list can baudrate in private defines in main.c " +#endif + /* initialize CAN */ + can_init(CAN0, &can_parameter); + can_init(CAN1, &can_parameter); + + /* initialize filter */ + can_filter.filter_number=0; + can_filter.filter_mode = CAN_FILTERMODE_MASK; + can_filter.filter_bits = CAN_FILTERBITS_32BIT; + can_filter.filter_list_high = 0x3000; + can_filter.filter_list_low = 0x0000; + can_filter.filter_mask_high = 0x3000; + can_filter.filter_mask_low = 0x0000; + can_filter.filter_fifo_number = CAN_FIFO0; + can_filter.filter_enable=ENABLE; + + can_filter_init(&can_filter); + + /* CAN1 filter number */ + can_filter.filter_number=15; + can_filter_init(&can_filter); +} + +/*! + \brief configure the nested vectored interrupt controller + \param[in] none + \param[out] none + \retval none +*/ +void nvic_config(void) +{ + /* configure CAN0 NVIC */ + nvic_irq_enable(CAN0_RX0_IRQn,0,0); + + /* configure CAN1 NVIC */ + nvic_irq_enable(CAN1_RX0_IRQn,1,1); +} + +/*! + \brief configure the leds + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_init(LED3); + gd_eval_led_init(LED4); +} + +/*! + \brief configure GPIO + \param[in] none + \param[out] none + \retval none +*/ +void can_gpio_config(void) +{ + /* enable CAN clock */ + rcu_periph_clock_enable(RCU_CAN0); + rcu_periph_clock_enable(RCU_CAN1); + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + + /* configure CAN0 GPIO */ + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5); + gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_5); + + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6); + gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_6); + + /* configure CAN1 GPIO */ + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_12); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12); + gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_12); + + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_13); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13); + gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_13); +} + +/* retarget the C library printf function to the usart */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM2, (uint8_t)ch); + while (RESET == usart_flag_get(EVAL_COM2, USART_FLAG_TBE)); + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/readme.txt new file mode 100644 index 0000000..b858416 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Dual_CAN_communication/readme.txt @@ -0,0 +1,33 @@ +/*! + \file readme.txt + \brief description of the dual can communication demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32190R-EVAL board, it shows how to configure the +CAN0 and CAN1 peripherals to send and receive CAN frames in normal mode. Pressing +Wakeup button or Tamper button: + + When Tamper button is pressed, CAN0 sends a message to CAN1 and print it. +when CAN1 receives correctly this message,the receive data will be printed +and LED4 toggles a time. + + When Wakeup button is pressed, CAN1 sends a message to CAN0 and print it. +when CAN0 receives correctly this message,the receive data will be printed +and LED3 toggles a time. + + User can select one from the preconfigured CAN baud rates from the private +defines in main.c.These baudrates is correct only when the system clock frequency +is 72M. + + Connect JP8 to CAN1 + Connect JP4 CAN_L to JP3 CAN_L + Connect JP4 CAN_H to JP3 CAN_H diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/gd32f1x0_it.c new file mode 100644 index 0000000..fc99b31 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/gd32f1x0_it.c @@ -0,0 +1,171 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" + +extern ErrStatus test_flag_interrupt; +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/*! + \brief this function handles CAN0 RX0 exception + \param[in] none + \param[out] none + \retval none +*/ +void CAN0_RX0_IRQHandler(void) +{ + can_receive_message_struct receive_message; + /* initialize receive message */ + receive_message.rx_sfid=0x00; + receive_message.rx_efid=0x00; + receive_message.rx_ff=0; + receive_message.rx_dlen=0; + receive_message.rx_fi=0; + receive_message.rx_data[0]=0x00; + receive_message.rx_data[1]=0x00; + + /* check the receive message */ + can_message_receive(CAN0, CAN_FIFO0, &receive_message); + + if((0x1234 == receive_message.rx_efid) && (CAN_FF_EXTENDED == receive_message.rx_ff) + && (2 == receive_message.rx_dlen) && (0xCADE == (receive_message.rx_data[1]<<8|receive_message.rx_data[0]))){ + test_flag_interrupt = SUCCESS; + }else{ + test_flag_interrupt = ERROR; + } +} +/*! + \brief this function handles CAN1 RX0 exception + \param[in] none + \param[out] none + \retval none +*/ +void CAN1_RX0_IRQHandler(void) +{ + can_receive_message_struct receive_message; + /* initialize receive message */ + receive_message.rx_sfid=0x00; + receive_message.rx_efid=0x00; + receive_message.rx_ff=0; + receive_message.rx_dlen=0; + receive_message.rx_fi=0; + receive_message.rx_data[0]=0x00; + receive_message.rx_data[1]=0x00; + + /* check the receive message */ + can_message_receive(CAN1, CAN_FIFO0, &receive_message); + + if((0x1234 == receive_message.rx_efid) && (CAN_FF_EXTENDED == receive_message.rx_ff) + && (2 == receive_message.rx_dlen) && (0xCADE == (receive_message.rx_data[1]<<8|receive_message.rx_data[0]))){ + test_flag_interrupt = SUCCESS; + }else{ + test_flag_interrupt = ERROR; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/gd32f1x0_it.h new file mode 100644 index 0000000..17d33a7 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/gd32f1x0_it.h @@ -0,0 +1,44 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* CAN0 RX0 handle function */ +void CAN0_RX0_IRQHandler(void); +/* CAN1 RX0 handle function */ +void CAN1_RX0_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/main.c new file mode 100644 index 0000000..1e5ddeb --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/main.c @@ -0,0 +1,264 @@ +/*! + \file main.c + \brief CAN loopback communication in normal mode +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +/* select CAN */ +#define CAN0_USED +//#define CAN1_USED + +#ifdef CAN0_USED + #define CANX CAN0 +#else + #define CANX CAN1 +#endif + +volatile ErrStatus test_flag; +ErrStatus test_flag_interrupt; + +void nvic_config(void); +void led_config(void); +ErrStatus can_loopback(void); +ErrStatus can_loopback_interrupt(void); +void can_loopback_init(can_parameter_struct can_parameter, can_filter_parameter_struct can_filter); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* enable CAN clock */ + rcu_periph_clock_enable(RCU_CAN0); + rcu_periph_clock_enable(RCU_CAN1); + + /* configure NVIC */ + nvic_config(); + + /* configure leds */ + led_config(); + /* set all the leds off */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + gd_eval_led_off(LED3); + gd_eval_led_off(LED4); + /* loopback of polling */ + test_flag = can_loopback(); + + if(SUCCESS == test_flag){ + /* loopback test is success */ + gd_eval_led_on(LED1); + gd_eval_led_on(LED2); + }else{ + /* loopback test is failed */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + } + /* loopback of interrupt */ + test_flag_interrupt = can_loopback_interrupt(); + + if(SUCCESS == test_flag_interrupt){ + /* interrupt loopback test is success */ + gd_eval_led_on(LED3); + gd_eval_led_on(LED4); + }else{ + /* interrupt loopback test is failed */ + gd_eval_led_off(LED3); + gd_eval_led_off(LED4); + } + while (1); +} + +/*! + \brief function for CAN loopback communication + \param[in] none + \param[out] none + \retval ErrStatus +*/ +ErrStatus can_loopback(void) +{ + can_parameter_struct can_init_parameter; + can_filter_parameter_struct can_filter_parameter; + can_trasnmit_message_struct transmit_message; + can_receive_message_struct receive_message; + uint32_t timeout = 0xFFFF; + uint8_t transmit_mailbox = 0; + /* initialize CAN */ + can_loopback_init(can_init_parameter, can_filter_parameter); + + /* initialize transmit message */ + transmit_message.tx_sfid = 0x11; + transmit_message.tx_ft = CAN_FT_DATA; + transmit_message.tx_ff = CAN_FF_STANDARD; + transmit_message.tx_dlen = 2; + transmit_message.tx_data[0] = 0xAB; + transmit_message.tx_data[1] = 0xCD; + + /* transmit message */ + transmit_mailbox = can_message_transmit(CANX, &transmit_message); + /* waiting for transmit completed */ + while((can_transmit_states(CANX, transmit_mailbox) != CAN_TRANSMIT_OK) && (timeout != 0)){ + timeout--; + } + timeout = 0xFFFF; + /* waiting for receive completed */ + while((can_receive_message_length_get(CANX, CAN_FIFO0) < 1) && (timeout != 0)){ + timeout--; + } + + /* initialize receive message*/ + receive_message.rx_sfid=0x00; + receive_message.rx_ff=0; + receive_message.rx_dlen=0; + receive_message.rx_data[0]=0x00; + receive_message.rx_data[1]=0x00; + can_message_receive(CANX, CAN_FIFO0, &receive_message); + + /* check the receive message */ + if((receive_message.rx_sfid==0x11) && (receive_message.rx_ff==CAN_FF_STANDARD) + && (receive_message.rx_dlen==2) && ((receive_message.rx_data[1]<<8|receive_message.rx_data[0])==0xCDAB)){ + return SUCCESS; + }else{ + return ERROR; + } +} + +/*! + \brief function for CAN loopback interrupt communication + \param[in] none + \param[out] none + \retval ErrStatus +*/ +ErrStatus can_loopback_interrupt(void) +{ + can_parameter_struct can_init_parameter; + can_filter_parameter_struct can_filter_parameter; + can_trasnmit_message_struct transmit_message; + uint32_t timeout = 0x0000FFFF; + + /* initialize CAN and filter */ + can_loopback_init(can_init_parameter, can_filter_parameter); + + /* enable CAN receive FIFO0 not empty interrupt */ + can_interrupt_enable(CANX, CAN_INTEN_RFNEIE0); + + /* initialize transmit message */ + transmit_message.tx_sfid=0; + transmit_message.tx_efid=0x1234; + transmit_message.tx_ff=CAN_FF_EXTENDED; + transmit_message.tx_ft=CAN_FT_DATA; + transmit_message.tx_dlen=2; + transmit_message.tx_data[0]=0xDE; + transmit_message.tx_data[1]=0xCA; + /* transmit a message */ + can_message_transmit(CANX, &transmit_message); + + /* waiting for receive completed */ + while((test_flag_interrupt != SUCCESS) && (timeout != 0)){ + timeout--; + } + if(0 == timeout){ + test_flag_interrupt = ERROR; + } + + /* disable CAN receive FIFO0 not empty interrupt */ + can_interrupt_disable(CANX, CAN_INTEN_RFNEIE0); + + return test_flag_interrupt; +} + +/*! + \brief initialize CAN and filter + \param[in] can_parameter + \arg can_parameter_struct + \param[in] can_filter + \arg can_filter_parameter_struct + \param[out] none + \retval none +*/ +void can_loopback_init(can_parameter_struct can_parameter, can_filter_parameter_struct can_filter) +{ + /* initialize CAN register */ + can_deinit(CANX); + + /* initialize CAN */ + can_parameter.time_triggered=DISABLE; + can_parameter.auto_bus_off_recovery=DISABLE; + can_parameter.auto_wake_up=DISABLE; + can_parameter.auto_retrans=DISABLE; + can_parameter.rec_fifo_overwrite=DISABLE; + can_parameter.trans_fifo_order=DISABLE; + can_parameter.working_mode=CAN_LOOPBACK_MODE; + /* configure baudrate to 125kbps */ + can_parameter.resync_jump_width=CAN_BT_SJW_1TQ; + can_parameter.time_segment_1=CAN_BT_BS1_3TQ; + can_parameter.time_segment_2=CAN_BT_BS2_2TQ; + can_parameter.prescaler=96; + can_init(CANX, &can_parameter); + + /* initialize filter */ +#ifdef CAN0_USED + /* CAN0 filter number */ + can_filter.filter_number=0; +#else + /* CAN1 filter number */ + can_filter.filter_number=15; +#endif + /* initialize filter */ + can_filter.filter_mode = CAN_FILTERMODE_MASK; + can_filter.filter_bits = CAN_FILTERBITS_32BIT; + can_filter.filter_list_high = 0x0000; + can_filter.filter_list_low = 0x0000; + can_filter.filter_mask_high = 0x0000; + can_filter.filter_mask_low = 0x0000; + can_filter.filter_fifo_number = CAN_FIFO0; + can_filter.filter_enable=ENABLE; + can_filter_init(&can_filter); +} + +/*! + \brief configure the nested vectored interrupt controller + \param[in] none + \param[out] none + \retval none +*/ +void nvic_config(void) +{ +#ifdef CAN0_USED + /* configure CAN0 NVIC */ + nvic_irq_enable(CAN0_RX0_IRQn,0,0); +#else + /* configure CAN1 NVIC */ + nvic_irq_enable(CAN1_RX0_IRQn,0,0); +#endif + +} + +/*! + \brief configure the leds + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_init(LED3); + gd_eval_led_init(LED4); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/readme.txt new file mode 100644 index 0000000..899f3be --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Loopback_communication/readme.txt @@ -0,0 +1,24 @@ +/*! + \file readme.txt + \brief description of the can loopback communication demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32190R-EVAL board, it shows how to set a communication +with the CAN in loopback mode. + + The example first performs a transmission and a reception of a standard data frame by +polling at 125 Kbps.If the received frame is successful, the LED1 and LED2 are on. +otherwise,the LED1 and LED2 are off. Then, an extended data frame is transmitted at 125 Kbps. +Reception is done in the interrupt handler when the message becomes pending in the FIFO0. If +the received frame is successful, the LED3 and LED4 are on. otherwise,the LED3 and LED4 are off. + + User can select CAN0 or CAN1 cell using the private defines in main.c. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/gd32f1x0_it.c new file mode 100644 index 0000000..560b6eb --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/gd32f1x0_it.c @@ -0,0 +1,144 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" + +FlagStatus receive_flag; +can_receive_message_struct receive_message; +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/*! + \brief this function handles CAN0 RX0 exception + \param[in] none + \param[out] none + \retval none +*/ +void CAN0_RX0_IRQHandler(void) +{ + /* check the receive message */ + can_message_receive(CAN0, CAN_FIFO0, &receive_message); + if((0x321 == receive_message.rx_sfid)&&(CAN_FF_STANDARD == receive_message.rx_ff) && (1 == receive_message.rx_dlen)){ + receive_flag = SET; + } +} +/*! + \brief this function handles CAN1 RX0 exception + \param[in] none + \param[out] none + \retval none +*/ +void CAN1_RX0_IRQHandler(void) +{ + /* check the receive message */ + can_message_receive(CAN1, CAN_FIFO0, &receive_message); + if((0x321 == receive_message.rx_sfid)&&(CAN_FF_STANDARD == receive_message.rx_ff) && (1 == receive_message.rx_dlen)){ + receive_flag = SET; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/gd32f1x0_it.h new file mode 100644 index 0000000..91c2286 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/gd32f1x0_it.h @@ -0,0 +1,46 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* CAN0 RX0 handle function */ +void CAN0_RX0_IRQHandler(void); +/* CAN1 RX0 handle function */ +void CAN1_RX0_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/main.c new file mode 100644 index 0000000..d9de5ce --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/main.c @@ -0,0 +1,241 @@ +/*! + \file main.c + \brief CAN networking communication in normal mode +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +/* select can */ +//#define CAN0_USED +#define CAN1_USED + +#ifdef CAN0_USED + #define CANX CAN0 +#else + #define CANX CAN1 +#endif + +extern FlagStatus receive_flag; +uint8_t transmit_number = 0x0; +extern can_receive_message_struct receive_message; +can_trasnmit_message_struct transmit_message; + +void nvic_config(void); +void led_config(void); +void gpio_config(void); +ErrStatus can_networking(void); +void can_networking_init(can_parameter_struct can_parameter, can_filter_parameter_struct can_filter); +void delay(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + can_parameter_struct can_init_parameter; + can_filter_parameter_struct can_filter_parameter; + + receive_flag = RESET; + /* configure Tamper key */ + gd_eval_key_init(KEY_TAMPER, KEY_MODE_GPIO); + /* configure GPIO */ + gpio_config(); + /* configure USART */ + gd_eval_com_init(EVAL_COM2); + /* configure NVIC */ + nvic_config(); + /* configure leds */ + led_config(); + /* set all leds off */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + gd_eval_led_off(LED3); + gd_eval_led_off(LED4); + /* initialize CAN */ + can_networking_init(can_init_parameter, can_filter_parameter); + /* enable phy */ +#ifdef CAN0_USED + can_phy_enable(CANX); +#endif + /* enable CAN receive FIFO0 not empty interrupt */ + can_interrupt_enable(CANX, CAN_INTEN_RFNEIE0); + + /* initialize transmit message */ + transmit_message.tx_sfid = 0x321; + transmit_message.tx_efid = 0x01; + transmit_message.tx_ft = CAN_FT_DATA; + transmit_message.tx_ff = CAN_FF_STANDARD; + transmit_message.tx_dlen = 1; + printf("please press the Tamper key to transmit data!\r\n"); + while(1){ + /* waiting for the Tamper key pressed */ + while(0 == gd_eval_key_state_get(KEY_TAMPER)){ + /* if transmit_number is 0x10, set it to 0x00 */ + if(transmit_number == 0x10){ + transmit_number = 0x00; + }else{ + transmit_message.tx_data[0] = transmit_number++; + printf("transmit data: %x\r\n", transmit_message.tx_data[0]); + /* transmit message */ + can_message_transmit(CANX, &transmit_message); + delay(); + /* waiting for Tamper key up */ + while(0 == gd_eval_key_state_get(KEY_TAMPER)); + } + } + if(SET == receive_flag){ + gd_eval_led_toggle(LED1); + receive_flag = RESET; + printf("recive data: %x\r\n", receive_message.rx_data[0]); + } + } +} + +/*! + \brief initialize CAN and filter + \param[in] can_parameter + \arg can_parameter_struct + \param[in] can_filter + \arg can_filter_parameter_struct + \param[out] none + \retval none +*/ +void can_networking_init(can_parameter_struct can_parameter, can_filter_parameter_struct can_filter) +{ + /* initialize CAN register */ + can_deinit(CANX); + + /* initialize CAN */ + can_parameter.time_triggered=DISABLE; + can_parameter.auto_bus_off_recovery=DISABLE; + can_parameter.auto_wake_up=DISABLE; + can_parameter.auto_retrans=DISABLE; + can_parameter.rec_fifo_overwrite=DISABLE; + can_parameter.trans_fifo_order=DISABLE; + can_parameter.working_mode=CAN_NORMAL_MODE; + can_parameter.resync_jump_width=CAN_BT_SJW_1TQ; + can_parameter.time_segment_1=CAN_BT_BS1_3TQ; + can_parameter.time_segment_2=CAN_BT_BS2_2TQ; + /* baudrate 1Mbps */ + can_parameter.prescaler=12; + can_init(CANX, &can_parameter); + + /* initialize filter */ +#ifdef CAN0_USED + /* CAN0 filter number */ + can_filter.filter_number=0; +#else + /* CAN1 filter number */ + can_filter.filter_number=15; +#endif + /* initialize filter */ + can_filter.filter_mode = CAN_FILTERMODE_MASK; + can_filter.filter_bits = CAN_FILTERBITS_32BIT; + can_filter.filter_list_high = 0x0000; + can_filter.filter_list_low = 0x0000; + can_filter.filter_mask_high = 0x0000; + can_filter.filter_mask_low = 0x0000; + can_filter.filter_fifo_number = CAN_FIFO0; + can_filter.filter_enable=ENABLE; + can_filter_init(&can_filter); +} + +/*! + \brief configure the nested vectored interrupt controller + \param[in] none + \param[out] none + \retval none +*/ +void nvic_config(void) +{ +#ifdef CAN0_USED + /* configure CAN0 NVIC */ + nvic_irq_enable(CAN0_RX0_IRQn,0,0); +#else + /* configure CAN1 NVIC */ + nvic_irq_enable(CAN1_RX0_IRQn,0,0); +#endif + +} + +/*! + \brief delay + \param[in] none + \param[out] none + \retval none +*/ +void delay(void) +{ + uint16_t nTime = 0x0000; + + for(nTime = 0; nTime < 0xFFFF; nTime++){ + } +} + +/*! + \brief configure the leds + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_init(LED3); + gd_eval_led_init(LED4); +} + +/*! + \brief configure GPIO + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* enable can clock */ + rcu_periph_clock_enable(RCU_CAN0); + rcu_periph_clock_enable(RCU_CAN1); + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + + /* configure CAN0 GPIO */ + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5); + gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_5); + + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6); + gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_6); + + /* configure CAN1 GPIO */ + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_12); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12); + gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_12); + + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_13); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13); + gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_13); + +} + +/* retarget the C library printf function to the usart */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM2, (uint8_t)ch); + while (RESET == usart_flag_get(EVAL_COM2, USART_FLAG_TBE)); + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/readme.txt new file mode 100644 index 0000000..d1dd24f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CAN/Network_communication/readme.txt @@ -0,0 +1,27 @@ +/*! + \file readme.txt + \brief description of the can network communication demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32190R-EVAL board, it shows how to configure the CAN + peripheral to send and receive CAN frames in normal mode.The frames are sent and print + transmit data by pressing Tamper Key push button. When the frames are received, the receive + data will be printed and the LED1 will toggle. + + Connect JP8 to CAN1 + This example is tested with at least two GD32190R-EVAL boards. The same program example is + loaded in all boards and connect CAN_L and CAN_H pin of CAN0 or CAN1 to bus for sending + and receiving frames. + + User can select CAN0 or CAN1 cell using the private defines in main.c. + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/gd32f1x0_it.c new file mode 100644 index 0000000..8eb6312 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/gd32f1x0_it.c @@ -0,0 +1,237 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" +#include "systick.h" + +/* array1 transmission */ +uint8_t senddata1[2] = {0xA5,0x5A}; +/* array2 transmission */ +uint8_t senddata2[2] = {0x5A,0xA5}; +/* receive array buffer */ +uint8_t rcvdata[10]; +/* sent data pointer */ +uint8_t *transdata; +__IO uint8_t rcvstatus = 0U; +__IO uint8_t send_inc = 0U, rcv_inc = 0U; +uint16_t senderrorcode = 0U; +uint16_t rcverrorcode = 0U; +__IO uint8_t bytenum = 0U; + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} + +/*! + \brief this function handles EXTI0_1 interrupt request + \param[in] none + \param[out] none + \retval none +*/ +#ifdef GD32F170_190 +void EXTI0_1_IRQHandler(void) +{ + if(RESET != exti_flag_get(WAKEUP_KEY_EXTI_LINE)){ + /* Tamper key press */ + bytenum = 2U; + /* send CEC address */ + cec_data_send(0x12U); + /* start transmission */ + transdata = senddata1; + /* start transmission */ + cec_transmission_start(); + exti_flag_clear(WAKEUP_KEY_EXTI_LINE); + } +} +#endif /* GD32F170_190 */ + +/*! + \brief this function handles EXTI4_15 interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void EXTI4_15_IRQHandler(void) +{ +#ifdef GD32F130_150 + if(RESET != exti_flag_get(USER_KEY_EXTI_LINE)){ + /* Tamper key press */ + bytenum = 2U; + /* send CEC address */ + cec_data_send(0x12U); + transdata = senddata1; + /* start transmission */ + cec_transmission_start(); + exti_flag_clear(USER_KEY_EXTI_LINE); + } +#endif /* GD32F130_150 */ + + if(RESET != exti_flag_get(TAMPER_KEY_EXTI_LINE)){ + /* Tamper key press */ + bytenum = 2U; + /* send CEC address */ + cec_data_send(0x12U); + /* start transmission */ + transdata = senddata2; + /* start transmission */ + cec_transmission_start(); + exti_flag_clear(TAMPER_KEY_EXTI_LINE); + } +} + +/*! + \brief this function handles CEC interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void CEC_IRQHandler(void) +{ + /* check if a reception error occured */ + if(cec_interrupt_flag_get(CEC_INTF_RO | CEC_INTF_BRE | CEC_INTF_BPSE | CEC_INTF_BPLE | CEC_INTF_RAE)){ + rcverrorcode = CEC_INTF; + cec_interrupt_flag_clear(CEC_INTF_RO | CEC_INTF_BRE | CEC_INTF_BPSE | CEC_INTF_BPLE | CEC_INTF_RAE); + rcvstatus = 2U; + } + /* receive data */ + if(cec_interrupt_flag_get(CEC_INTF_BR)){ + rcvdata[rcv_inc] = cec_data_receive(); + rcv_inc++; + cec_interrupt_flag_clear(CEC_INTF_BR); + } + /* check if the byte received is the last one of the message */ + if(cec_interrupt_flag_get(CEC_INTF_REND)){ + rcvstatus = 1U; + rcv_inc = 0U; + cec_interrupt_flag_clear(CEC_INTF_REND); + } + + /* check if a transmission error occurred */ + if(cec_interrupt_flag_get(CEC_INTF_ARBF | CEC_INTF_TU | CEC_INTF_TERR | CEC_INTF_TAERR)){ + senderrorcode = CEC_INTF; + cec_interrupt_flag_clear(CEC_INTF_ARBF | CEC_INTF_TU | CEC_INTF_TERR | CEC_INTF_TAERR); + } + + /* check if end of message bit is set in the data to be transmitted */ + if(cec_interrupt_flag_get(CEC_INTF_TEND)){ + cec_interrupt_flag_clear(CEC_INTF_TEND| CEC_INTF_TBR); + send_inc = 0U; + }else if(cec_interrupt_flag_get(CEC_INTF_TBR)){ + /* set EOM bit if the byte to be transmitted is the last one of the senddata */ + if(send_inc++ == (bytenum - 1U)){ + cec_transmission_end(); + cec_data_send(*transdata++); + }else{ + /* send the byte in the transdata */ + cec_data_send(*transdata++); + } + cec_interrupt_flag_clear(CEC_INTF_TBR); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/gd32f1x0_it.h new file mode 100644 index 0000000..0809d6f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/gd32f1x0_it.h @@ -0,0 +1,44 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* EXTI4_15 handle function */ +void EXTI4_15_IRQHandler(void); +/* CEC handle function */ +void CEC_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/main.c new file mode 100644 index 0000000..08cc1b9 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/main.c @@ -0,0 +1,127 @@ +/*! + \file main.c + \brief CEC intercommunication +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include +#include "gd32f1x0_eval.h" +#include "systick.h" + +void cec_config(void); + +extern uint8_t rcvdata[10]; +extern __IO uint8_t rcvstatus; +extern uint8_t rcv_inc; +extern uint8_t bytenum; +__IO uint8_t NUM=0U; + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* GPIO clock enable */ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_GPIOF); + + /* delay time initialize */ + systick_config(); + + /* configure the CEC peripheral */ + cec_config(); + + /* configure the EXTI */ + gd_eval_key_init(KEY_TAMPER, KEY_MODE_EXTI); + +#ifdef GD32F130_150 + + gd_eval_key_init(KEY_USER, KEY_MODE_EXTI); + +#elif defined(GD32F170_190) + + gd_eval_key_init(KEY_WAKEUP, KEY_MODE_EXTI); + +#endif /* GD32F130_150 */ + + /* LED1 LED2 initialize */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + + /* main loop */ + while(1){ + /* wait receive data */ + while(rcvstatus==0U); + + if(rcvstatus == 1U){ + if((rcvdata[1]==0xA5U)&&(rcvdata[2]==0x5AU)){ + gd_eval_led_on(LED1); + delay_1ms(50U); + gd_eval_led_off(LED1); + } + if((rcvdata[1]==0x5AU)&&(rcvdata[2]==0xA5U)){ + gd_eval_led_on(LED2); + delay_1ms(50U); + gd_eval_led_off(LED2); + } + } + /* a reception error occured */ + rcvstatus = 0U; + } +} + +/*! + \brief configure the CEC peripheral + \param[in] none + \param[out] none + \retval none +*/ +void cec_config(void) +{ + /* enable clocks */ + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_CEC); + + /* configure CEC_LINE_GPIO as output open drain */ + gpio_mode_set(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_8); + gpio_output_options_set(GPIOB,GPIO_OTYPE_OD,GPIO_OSPEED_50MHZ,GPIO_PIN_8); + gpio_af_set(GPIOB,GPIO_AF_0,GPIO_PIN_8); + + /* configure priority group */ + nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); + + /* enable the CEC global interrupt (with higher priority) */ + nvic_irq_enable(CEC_IRQn,0U,0U); + + /* configure CEC */ + cec_init(CEC_SFT_START_STAOM,CEC_SFT_1POINT5_PERIOD,CEC_OWN_ADDRESS2); + cec_error_config(CEC_BROADCAST_ERROR_BIT_OFF,CEC_LONG_PERIOD_ERROR_BIT_OFF,CEC_RISING_PERIOD_ERROR_BIT_OFF,CEC_STOP_RISING_ERROR_BIT_OFF); + cec_reception_tolerance_disable(); + + /* activate CEC interrupts associated to the set of TX and RX flags */ + cec_interrupt_enable(CEC_INTEN_TENDIE | CEC_INTEN_TBRIE | CEC_INTEN_RENDIE | CEC_INTEN_BRIE); + + /* activate CEC interrupts associated to the set of TX and RX error */ + cec_interrupt_enable(CEC_INTEN_ROIE | CEC_INTEN_BREIE | CEC_INTEN_BPSEIE | CEC_INTEN_BPLEIE + | CEC_INTEN_RAEIE | CEC_INTEN_ARBFIE | CEC_INTEN_TUIE | CEC_INTEN_TERRIE | CEC_INTEN_TAERRIE ); + + /* enable CEC */ + cec_enable(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/readme.txt new file mode 100644 index 0000000..28551a1 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/readme.txt @@ -0,0 +1,19 @@ +/*! + \file readme.txt + \brief description of CEC intercommunication +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure and use the CEC peripheral to receive and transmit messages. In this +demo, the same program is loaded to two GD32150R-EVAL/GD32190R-EVAL boards, +then they are communicated through connecting respective CEC line(PB8) and GND. +When press the buttons(K3 or K4) on one board, LED1 and LED2 will blink once. + Connect two GD32150R-EVAL/GD32190R-EVAL boards through CEC line(PB8) and GND. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/systick.c new file mode 100644 index 0000000..d736be4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CEC/Intercommunication/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/gd32f1x0_it.c new file mode 100644 index 0000000..4fcaf70 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/gd32f1x0_it.c @@ -0,0 +1,128 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} +/*! + \brief this function handles External lines 21 and 22 interrupt exception + \param[in] none + \param[out] none + \retval none +*/ +void ADC_CMP_IRQHandler(void) +{ + if(RESET != exti_interrupt_flag_get(EXTI_21)){ + gd_eval_led_on(LED2); + exti_interrupt_flag_clear(EXTI_21); + } +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/gd32f1x0_it.h new file mode 100644 index 0000000..08daca4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/gd32f1x0_it.h @@ -0,0 +1,44 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* ADC CMP handle function */ +void ADC_CMP_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/main.c new file mode 100644 index 0000000..80b4312 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/main.c @@ -0,0 +1,70 @@ +/*! + \file main.c + \brief comparator trigger interrupt using an external interrupt line +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void led_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* configure leds */ + led_config(); + + /* enable GPIOA clock */ + rcu_periph_clock_enable(RCU_GPIOA); + + /* configure PA1 as comparator input */ + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1); + gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_PULLUP, GPIO_PIN_1); + + /* enable comparator clock */ + rcu_periph_clock_enable(RCU_CFGCMP); + + /* configure CMP0 */ + cmp_mode_init(CMP0, CMP_VERYLOWSPEED, CMP_1_4VREFINT, CMP_HYSTERESIS_NO); + cmp_output_init(CMP0, CMP_OUTPUT_NONE, CMP_OUTPUT_POLARITY_NOINVERTED); + + /* initialize exti line21 */ + exti_init(EXTI_21, EXTI_INTERRUPT, EXTI_TRIG_RISING); + + /* configure ADC_CMP NVIC */ + nvic_irq_enable(ADC_CMP_IRQn, 0, 0); + + /* enable CMP0 */ + cmp_enable(CMP0); + + while(1); +} + +/*! + \brief configure the leds + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_init(LED3); + gd_eval_led_init(LED4); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/readme.txt new file mode 100644 index 0000000..fc955c1 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Interrupt/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the comparator interrupt demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure the comparator trigger interrupt using an external interrupt line. +In this demo,input 3.3V(GD32150R) or 5V(GD32190R)to PA1, EXTI line 21 is +configured to generate an interrupt on rising edge of the output signal. After +system start-up, enable comparator and trigger interrupt, then LED2 is on. + + Connect PA1 to +3V3 or +5V. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/PWM_signal_control/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/PWM_signal_control/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/PWM_signal_control/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/PWM_signal_control/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/PWM_signal_control/main.c new file mode 100644 index 0000000..d609c48 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/PWM_signal_control/main.c @@ -0,0 +1,124 @@ +/*! + \file main.c + \brief PWM output by using comparator output +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include + +uint16_t period = 65535; + +void rcu_config(void); +void gpio_config(void); +void timer_config(void); +void cmp_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* configure RCU */ + rcu_config(); + + /* configure GPIO */ + gpio_config(); + + /* configure TIMER */ + timer_config(); + + /* configure comparator */ + cmp_config(); + + while(1); +} + +/*! + \brief configure RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_TIMER1); + rcu_periph_clock_enable(RCU_CFGCMP); +} + +/*! + \brief configure GPIO + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* configure PB3 as PWM output */ + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_3); + + /* configure PA1 as comparator input */ + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1); + gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_PULLUP, GPIO_PIN_1); + +} + +/*! + \brief configure TIMER + \param[in] none + \param[out] none + \retval none +*/ +void timer_config(void) +{ + /* initialize TIMER1 */ + timer_parameter_struct timer_init_parameter; + timer_init_parameter.prescaler = 71; + timer_init_parameter.counterdirection = TIMER_COUNTER_UP; + timer_init_parameter.period = 65535; + timer_init_parameter.clockdivision = TIMER_CKDIV_DIV1; + + timer_init(TIMER1, &timer_init_parameter); + + /* PWM1 mode configure channel1 in PWM1 mode */ + timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM1); + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, (period/2) + 1); + timer_channel_output_state_config(TIMER1,TIMER_CH_1, TIMER_CCX_ENABLE); + /* select OCREFCLR as source for clearing OC2REF */ + timer_channel_output_clear_config(TIMER1, TIMER_CH_1, TIMER_OC_CLEAR_ENABLE); + timer_ocpre_clear_source_config(TIMER1, TIMER_OCPRE_CLEAR_SOURCE_CLR); + + /* enable TIMER1 counter */ + timer_enable(TIMER1); +} + +/*! + \brief configure comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_config(void) +{ + /* configure CMP0 */ + cmp_mode_init(CMP0, CMP_HIGHSPEED, CMP_VREFINT, CMP_HYSTERESIS_NO); + cmp_output_init(CMP0, CMP_OUTPUT_TIMER1OCPRECLR, CMP_OUTPUT_POLARITY_NOINVERTED); + + /* enable CMP0 */ + cmp_enable(CMP0); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/PWM_signal_control/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/PWM_signal_control/readme.txt new file mode 100644 index 0000000..de182a4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/PWM_signal_control/readme.txt @@ -0,0 +1,26 @@ +/*! + \file readme.txt + \brief description of the comparator pwm signal control demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to + control PWM output by using comparator output + + - CMP channel0 is configured as following: + - Inverting input is internally connected to VREFINT = 1.22V + - Non Inverting input is connected to PC1(GD32150R)/PC0(GD32190R) + - Output is internally connected to TIMER1 OCREFCLR (output compare reference clear) + + - While PC1/PC0 is lower than VREFINT (1.22V), PWM signal is displayed on PB3 + - While PC1/PC0 is higher than VREFINT, PB3 is displayed in low level. + + Connect PA1 to PC1(GD32150R)/PC0(GD32190R). \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Port_output/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Port_output/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Port_output/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Port_output/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Port_output/main.c new file mode 100644 index 0000000..11b290e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Port_output/main.c @@ -0,0 +1,86 @@ +/*! + \file main.c + \brief comparator portoutput +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void rcu_config(void); +void gpio_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i; + /* configure RCU */ + rcu_config(); + + /* configure GPIO */ + gpio_config(); + + gd_eval_led_init(LED2); + + /* configure CMP0 */ + cmp_mode_init(CMP0, CMP_VERYLOWSPEED, CMP_1_4VREFINT, CMP_HYSTERESIS_NO); + cmp_output_init(CMP0, CMP_OUTPUT_NONE, CMP_OUTPUT_POLARITY_NOINVERTED); + + /* enable CMP0 */ + cmp_enable(CMP0); + + for(i=0; i<100; i++); + + /* get the output level */ + if(CMP_OUTPUTLEVEL_HIGH == cmp_output_level_get(CMP0)){ + gd_eval_led_on(LED2); + }else{ + gd_eval_led_off(LED2); + } + + while (1); +} + +/*! + \brief configure RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOA clock */ + rcu_periph_clock_enable(RCU_GPIOA); + /* enable comparator clock */ + rcu_periph_clock_enable(RCU_CFGCMP); +} + +/*! + \brief configure GPIO + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1); + gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_PULLUP, GPIO_PIN_1); + + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6); + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6); + gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_6); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Port_output/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Port_output/readme.txt new file mode 100644 index 0000000..0f4aa52 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Port_output/readme.txt @@ -0,0 +1,19 @@ +/*! + \file readme.txt + \brief description of the comparator port output demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure the comparator portoutput. In this demo, input 3.3V(GD32150R) or 5V +(GD32190R) to PA1. After system start-up,enable comparator ,then LED2 is on. + + Connect PA1 to +3V3(GD32150R) or +5V(GD32190R). diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Switch/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Switch/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Switch/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Switch/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Switch/main.c new file mode 100644 index 0000000..2af0d16 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Switch/main.c @@ -0,0 +1,97 @@ +/*! + \file main.c + \brief comparator switch +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include + +void rcu_config(void); +void gpio_config(void); +void dac_config(void); +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* configure RCU */ + rcu_config(); + + /* configure GPIO */ + gpio_config(); + + /* configure DAC */ + dac_config(); + + /* set data for DAC0 */ + dac0_data_set(DAC_ALIGN_12B_R, 0xA00); + + dac0_software_trigger_enable(); + + /* configure CMP0 */ + cmp_mode_init(CMP0, CMP_VERYLOWSPEED, CMP_1_2VREFINT, CMP_HYSTERESIS_NO); + cmp_output_init(CMP0, CMP_OUTPUT_NONE, CMP_OUTPUT_POLARITY_NOINVERTED); + + /* enable CMP0 switch */ + cmp_switch_enable(); + + /* enable CMP0 */ + cmp_enable(CMP0); + + while(1); +} + +/*! + \brief configure RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_DAC); + rcu_periph_clock_enable(RCU_CFGCMP); +} + +/*! + \brief configure GPIO + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* configure PA4 */ + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4); + gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_PULLUP, GPIO_PIN_4); + /* configure PA6 */ + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6); + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6); + gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_6); +} + +/*! + \brief configure dac + \param[in] none + \param[out] none + \retval none +*/ +void dac_config(void) +{ + dac0_trigger_source_config(DAC_TRIGGER_SOFTWARE); + dac0_output_buffer_enable(); + dac0_enable(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Switch/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Switch/readme.txt new file mode 100644 index 0000000..b355ac7 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Switch/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the comparator switch demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure the comparator input switch. In this demo, input 3.3V(GD32150R) or 5V +(GD32190R) to PA4 ,turn on comparator input switch,then PA4 will be connected to +CMP1_IP.After system start-up, enable comparator,then LED2 is on. + + Connect PA4 to +3V3(GD32150R) or +5V(GD32190R). + Connect PA6 to PC11(GD32150R) or PA12(GD32190R). diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/gd32f1x0_it.c new file mode 100644 index 0000000..42d125e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/gd32f1x0_it.c @@ -0,0 +1,128 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/*! + \brief this function handles timer1 handle exception + \param[in] none + \param[out] none + \retval none +*/ +void TIMER1_IRQHandler(void) +{ + if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_CH3)){ + gd_eval_led_on(LED3); + timer_interrupt_flag_clear(TIMER1, TIMER_INT_CH3); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/gd32f1x0_it.h new file mode 100644 index 0000000..08daca4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/gd32f1x0_it.h @@ -0,0 +1,44 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* ADC CMP handle function */ +void ADC_CMP_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/main.c new file mode 100644 index 0000000..a687dd7 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/main.c @@ -0,0 +1,112 @@ +/*! + \file main.c + \brief comparator output timer input capture +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void rcu_config(void); +void gpio_config(void); +void timer_config(void); +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* configure RCU */ + rcu_config(); + + /* configure GPIO */ + gpio_config(); + + /* configure leds */ + gd_eval_led_init(LED3); + + /* configure comparator channel0 */ + cmp_mode_init(CMP0, CMP_VERYLOWSPEED, CMP_1_4VREFINT, CMP_HYSTERESIS_NO); + cmp_output_init(CMP0, CMP_OUTPUT_TIMER1IC3, CMP_OUTPUT_POLARITY_NOINVERTED); + + /* configure TIMER */ + timer_config(); + + /* enable CMP0 */ + cmp_enable(CMP0); + while(1); +} + +/*! + \brief configure RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_TIMER1); + rcu_periph_clock_enable(RCU_CFGCMP); +} + +/*! + \brief configure GPIO + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* configure PB11 */ + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_11) ; + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_11); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_11); + + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1) ; + gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_PULLUP, GPIO_PIN_1); +} + +/*! + \brief configure TIMER + \param[in] none + \param[out] none + \retval none +*/ +void timer_config(void) +{ + /* initialize TIMER1 */ + timer_parameter_struct timer_init_parameter; + timer_init_parameter.prescaler = 0; + timer_init_parameter.counterdirection = TIMER_COUNTER_UP; + timer_init_parameter.period = 65535; + timer_init_parameter.clockdivision = TIMER_CKDIV_DIV1; + + timer_init(TIMER1, &timer_init_parameter); + + /* clear flag */ + timer_flag_clear(TIMER1, TIMER_FLAG_UP); + + nvic_irq_enable(TIMER1_IRQn, 0, 0); + + /* reset TIMER1 interrupt flag register */ + TIMER_INTF(TIMER1) = 0; + + timer_interrupt_enable(TIMER1, TIMER_INT_CH3); + + /* enable TIMER1 counter */ + timer_enable(TIMER1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/readme.txt new file mode 100644 index 0000000..bd1ac28 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Timer1_CH3IC/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the comparator output timer input capture demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to + configure the comparator trigger timer 1 channel 3 input capture event, which + is configured to generate an interrupt on both rising and falling edge of the + output signal.In this demo, input 3.3V(GD32150R) or 5V(GD32190R) to CMP1_IP. + After system start-up, enable comparator and trigger interrupt,then LED3 is on. + + Connect PA1 to +3V3(GD32150R) or +5V(GD32190R). \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/gd32f1x0_it.c new file mode 100644 index 0000000..13302e3 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/gd32f1x0_it.c @@ -0,0 +1,140 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "main.h" + +extern uint32_t delayms; + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + if(delayms){ + delayms--; + } +} +/*! + \brief this function handles External lines 21 and 22 interrupt exception + \param[in] none + \param[out] none + \retval none +*/ +void ADC_CMP_IRQHandler(void) +{ + if((RESET != exti_interrupt_flag_get(EXTI_21)) || RESET != (exti_interrupt_flag_get(EXTI_22))){ + /* recover the system clock to 72MHz */ + SystemInit(); + check_state(); + /* clear EXTI line21 bit */ + exti_interrupt_flag_clear(EXTI_21); + /* clear EXTI line22 bit */ + exti_interrupt_flag_clear(EXTI_22); + } +} + + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/gd32f1x0_it.h new file mode 100644 index 0000000..0504cb1 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* ADC CMP handle function */ +void ADC_CMP_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/main.c new file mode 100644 index 0000000..447baea --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/main.c @@ -0,0 +1,185 @@ +/*! + \file main.c + \brief comparator watchdog window +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" +#include "main.h" + +uint32_t delayms; + +void led_config(void); +void deepsleep_mode_config(void); +void cmp_config(void); +void delay_ms(uint32_t time); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + SysTick_Config(72000000/1000); + + /* configure leds */ + led_config(); + + /* configure CMP0 and CMP1 */ + cmp_config(); + + /* configure CMP0 and CMP1 */ + check_state(); + + while(1) + { + /* input voltage is over the thresholds: higher and lower thresholds */ + if(STATE_OVER_THRESHOLD == check_state()){ + gd_eval_led_on(LED1); + gd_eval_led_off(LED2); + gd_eval_led_on(LED3); + gd_eval_led_off(LED4); + } + /* input voltage is within the thresholds: higher and lower thresholds */ + if(STATE_WITHIN_THRESHOLD == check_state()){ + delay_ms(500); + if(STATE_WITHIN_THRESHOLD == check_state()){ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + gd_eval_led_off(LED3); + gd_eval_led_off(LED4); + /* enter deepsleep mode */ + deepsleep_mode_config(); + } + } + /* input voltage is under the thresholds: higher and lower thresholds */ + if(STATE_UNDER_THRESHOLD == check_state()){ + gd_eval_led_off(LED1); + gd_eval_led_on(LED2); + gd_eval_led_off(LED3); + gd_eval_led_on(LED4); + } + } +} + +/*! + \brief configure comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_config(void) +{ + /* enable GPIOA clock */ + rcu_periph_clock_enable(RCU_GPIOA); + + /* configure PA1 as comparator input */ + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1); + gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_PULLUP, GPIO_PIN_1); + + /* enable comparator clock */ + rcu_periph_clock_enable(RCU_CFGCMP); + + /* configure CMP0 */ + cmp_mode_init(CMP0, CMP_LOWSPEED, CMP_VREFINT, CMP_HYSTERESIS_HIGH); + cmp_output_init(CMP0, CMP_OUTPUT_NONE, CMP_OUTPUT_POLARITY_NOINVERTED); + + /* configure CMP1 */ + cmp_mode_init(CMP1, CMP_LOWSPEED, CMP_1_2VREFINT, CMP_HYSTERESIS_HIGH); + cmp_output_init(CMP1, CMP_OUTPUT_NONE, CMP_OUTPUT_POLARITY_NOINVERTED); + + /* configure exti line */ + exti_init(EXTI_21, EXTI_INTERRUPT, EXTI_TRIG_BOTH); + exti_init(EXTI_22, EXTI_INTERRUPT, EXTI_TRIG_BOTH); + + /* configure ADC_CMP nvic */ + nvic_irq_enable(ADC_CMP_IRQn, 0, 0); + + /* enable comparator window */ + cmp_window_enable(); + + /* enable comparator channels */ + cmp_enable(CMP0); + cmp_enable(CMP1); +} + +/*! + \brief configure deepsleep mode + \param[in] none + \param[out] none + \retval none +*/ +void deepsleep_mode_config(void) +{ + /* enable pmu clock */ + rcu_periph_clock_enable(RCU_PMU); + + /* enter to deepsleep mode */ + pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD); +} + +/*! + \brief check comparator output state + \param[in] none + \param[out] none + \retval cmp_state +*/ +cmp_state_enum check_state(void) +{ + cmp_state_enum state; + + /* check if cmp0 output level is high and cmp1 output level is high */ + if ((cmp_output_level_get(CMP0) == CMP_OUTPUTLEVEL_HIGH) + && (cmp_output_level_get(CMP1) == CMP_OUTPUTLEVEL_HIGH)){ + state = STATE_OVER_THRESHOLD; + } + /* check if cmp0 output level is low and cmp1 output level is high */ + if ((cmp_output_level_get(CMP0) == CMP_OUTPUTLEVEL_LOW) + && (cmp_output_level_get(CMP1) == CMP_OUTPUTLEVEL_HIGH)){ + state = STATE_WITHIN_THRESHOLD; + } + /* check if cmp0 output level is low and cmp1 output level is low */ + if ((cmp_output_level_get(CMP0) == CMP_OUTPUTLEVEL_LOW) + && (cmp_output_level_get(CMP1) == CMP_OUTPUTLEVEL_LOW)){ + state = STATE_UNDER_THRESHOLD; + } + return state; +} + +/*! + \brief delay function + \param[in] none + \param[out] none + \retval none +*/ +void delay_ms(uint32_t time) +{ + delayms = time; + while(delayms); +} + +/*! + \brief configure the leds + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_init(LED3); + gd_eval_led_init(LED4); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/main.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/main.h new file mode 100644 index 0000000..e7722db --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/main.h @@ -0,0 +1,27 @@ +/*! + \file main.c + \brief the header file of the main +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef MAIN_H +#define MAIN_H + +typedef enum +{ + STATE_OVER_THRESHOLD , + STATE_WITHIN_THRESHOLD, + STATE_UNDER_THRESHOLD +} cmp_state_enum; + +cmp_state_enum check_state(void); + +#endif /* MAIN_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/readme.txt new file mode 100644 index 0000000..a237db0 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CMP/Window/readme.txt @@ -0,0 +1,27 @@ +/*! + \file readme.txt + \brief description of the comparator window demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to make + an analog watchdog by using comparator + peripherals in window mode: + - The upper threshold is set to VREFINT = 1.22V + - The lower threshold is set to VREFINT / 2 = 1.22V = 0.610V + - The input voltage is configured to be connected to PC1(GD32150R) or PC0(GD32190R) + + If the input voltage is above the higher threshold, LED1 and LED3 are turned on. + If the input voltage is under the lower threshold, LED2 and LED4 are turned on. + If the input voltage is within the thresholds, the MCU remains in deepsleep mode + and all leds are turned off. + + Connect PA1 to PC1(GD32150R) or PC0(GD32190R). diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/gd32f1x0_it.c new file mode 100644 index 0000000..8265ebe --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/gd32f1x0_it.c @@ -0,0 +1,113 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/gd32f1x0_it.h new file mode 100644 index 0000000..a4c6c0f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/main.c new file mode 100644 index 0000000..74db522 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/main.c @@ -0,0 +1,80 @@ +/*! + \file main.c + \brief CRC calculate demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" +#include +#include "gd32f1x0_eval.h" + +uint32_t vab1 = 0, success_flag = 0; +uint32_t read32_1, read32_2, read32_3, read32_4, read32_5, read32_6, read32_7, read32_8; + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gd_eval_led_init(LED1); + + vab1 = (uint32_t)0xabcd1234; + rcu_periph_clock_enable(RCU_CRC); + + crc_deinit(); + read32_1 = crc_single_data_calculate(vab1); + + /* input reverse */ + crc_deinit(); + crc_input_data_reverse_config(CRC_INPUT_DATA_BYTE); + read32_2 = crc_single_data_calculate(vab1); + + crc_deinit(); + crc_input_data_reverse_config(CRC_INPUT_DATA_HALFWORD); + read32_3 = crc_single_data_calculate(vab1); + + crc_deinit(); + crc_input_data_reverse_config(CRC_INPUT_DATA_WORD); + read32_4 = crc_single_data_calculate(vab1); + + /* output reverse */ + crc_deinit(); + crc_reverse_output_data_enable(); + read32_5 = crc_single_data_calculate(vab1); + + crc_deinit(); + crc_input_data_reverse_config(CRC_INPUT_DATA_BYTE); + crc_reverse_output_data_enable(); + read32_6 = crc_single_data_calculate(vab1); + + crc_deinit(); + crc_input_data_reverse_config(CRC_INPUT_DATA_HALFWORD); + crc_reverse_output_data_enable(); + read32_7 = crc_single_data_calculate(vab1); + + crc_deinit(); + crc_input_data_reverse_config(CRC_INPUT_DATA_WORD); + crc_reverse_output_data_enable(); + read32_8 = crc_single_data_calculate(vab1); + + /* check the caculation result */ + if((read32_1 == 0xf7018a40)&&(read32_2 == 0x49fc6721)&&(read32_3 == 0x606444e3)&&(read32_4 == 0x16d70081) + &&(read32_5 == 0x025180ef)&&(read32_6 == 0x84e63f92)&&(read32_7 == 0xc7222606)&&(read32_8 == 0x8100eb68)){ + success_flag = 0x1; + gd_eval_led_on(LED1); + } + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/readme.txt new file mode 100644 index 0000000..9f9b32f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/readme.txt @@ -0,0 +1,19 @@ +/*! + \file readme.txt + \brief description of the CRC calculate demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure the CRC module. In this demo, 8 CRC codes are calculated for a 32-bit +data by configuring various control bits in the CRC control register. + + If the test passes, the success_flag variable equals 0x1 and turn on the LED1. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/systick.c new file mode 100644 index 0000000..d736be4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/CRC/Calculate_demo/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_concurrent_output_voltage/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_concurrent_output_voltage/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_concurrent_output_voltage/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_concurrent_output_voltage/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_concurrent_output_voltage/main.c new file mode 100644 index 0000000..3bf5c4c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_concurrent_output_voltage/main.c @@ -0,0 +1,76 @@ +/*! + \file main.c + \brief DAC concurrent output voltage +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_libopt.h" +#include + +void rcu_config(void); +void gpio_config(void); +void dac_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + rcu_config(); + gpio_config(); + dac_config(); + while(1); +} + +/*! + \brief configure RCU function + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_DAC); +} + +/*! + \brief configure GPIO function + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + gpio_mode_set(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_4 | GPIO_PIN_5); +} + +/*! + \brief configure DAC function + \param[in] none + \param[out] none + \retval none +*/ +void dac_config(void) +{ + dac_trigger_source_config(DAC0,DAC_TRIGGER_SOFTWARE); + dac_trigger_source_config(DAC1,DAC_TRIGGER_SOFTWARE); + dac_concurrent_output_buffer_disable(); + /* set data right 12b alignment */ + dac_concurrent_data_set(DAC_ALIGN_12B_L,0x7FF0,0x1FF0); + /* enable dac concurrent mode */ + dac_concurrent_enable(); + dac_concurrent_software_trigger_enable(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_concurrent_output_voltage/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_concurrent_output_voltage/readme.txt new file mode 100644 index 0000000..4e7b1cd --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_concurrent_output_voltage/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the DAC_concurrent_output_voltage example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32190R-EVAL board, it shows how to use DAC +concurrent mode to generate the different voltage on DAC channel output.The DAC0 +channel output pin is configured PA4, it has an output voltage of VREF/2. The +DAC1 channel output pin is configured PA5, it has an output voltage of VREF/8. + + + Jumper cap (JP6) should be on 1 and 2 diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_output_voltage/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_output_voltage/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_output_voltage/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_output_voltage/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_output_voltage/main.c new file mode 100644 index 0000000..d2efc64 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_output_voltage/main.c @@ -0,0 +1,75 @@ +/*! + \file main.c + \brief DAC0 output voltage +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_libopt.h" +#include + +void rcu_config(void); +void gpio_config(void); +void dac_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + rcu_config(); + gpio_config(); + dac_config(); + while(1); +} + +/*! + \brief configure RCU function + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_DAC); +} + +/*! + \brief configure GPIO function + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + gpio_mode_set(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_4); +} + +/*! + \brief configure DAC function + \param[in] none + \param[out] none + \retval none +*/ +void dac_config(void) +{ + dac0_trigger_source_config(DAC_TRIGGER_SOFTWARE); + dac0_output_buffer_disable(); + /* set data left 12b alignment */ + dac0_data_set(DAC_ALIGN_12B_L,0x7FF0); + /* enable DAC0 */ + dac0_enable(); + dac0_software_trigger_enable(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_output_voltage/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_output_voltage/readme.txt new file mode 100644 index 0000000..a1f430f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DAC/DAC_output_voltage/readme.txt @@ -0,0 +1,17 @@ +/*! + \file readme.txt + \brief description of DAC0_output_voltage example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to use +DAC0 to generate the voltage on DAC channel output.The DAC channel output pin is configured PA4. +DAC0 channel is configured to have an output voltage of VREF/2. \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/gd32f1x0_it.c new file mode 100644 index 0000000..c947950 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/gd32f1x0_it.c @@ -0,0 +1,115 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/gd32f1x0_it.h new file mode 100644 index 0000000..a4c6c0f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/main.c new file mode 100644 index 0000000..de7d8fd --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/main.c @@ -0,0 +1,126 @@ +/*! + \file main.c + \brief debug timer1 when the mcu is in debug mode +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_configuration(void); +void timer_configuration(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + rcu_periph_clock_enable(RCU_GPIOB); + gpio_configuration(); + gd_eval_led_init(LED1); + systick_configuration(); + timer_configuration(); + + /* keep timer1 counter when the mcu is in debug mode */ + dbg_periph_enable(DBG_TIMER1_HOLD); + + while (1) + { + /* toggle LED1 output status every second */ + gd_eval_led_toggle(LED1); + /* you can set breakpoint here, then look over the register in timer1 */ + delay_1ms(1000); + } +} + +/*! + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +void gpio_configuration(void) +{ + /*Configure PB3 PB10 PB11(TIMER1 CH1 CH2 CH3) as alternate function*/ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_3); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_10); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_11); + + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_3); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_10); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_11); +} + +/*! + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none +*/ +void timer_configuration(void) +{ + + /* TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles: + TIMER1CLK = SystemCoreClock / 72 = 1MHz + + TIMER1 Channel1 duty cycle = 4000/ 16000 = 25% + TIMER1 Channel2 duty cycle = 8000/ 16000 = 50% + TIMER1 Channel3 duty cycle = 12000/ 16000 = 75% */ + + timer_parameter_struct timer_initpara; + timer_oc_parameter_struct timer_ocintpara; + + rcu_periph_clock_enable(RCU_TIMER1); + + /* TIMER1 configuration */ + timer_deinit(TIMER1); + /* TIMER1 configuration */ + timer_initpara.prescaler = 71; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 15999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER1,&timer_initpara); + + /* CH1,CH2 and CH3 configuration in PWM mode */ + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_channel_output_config(TIMER1,TIMER_CH_1,&timer_ocintpara); + timer_channel_output_config(TIMER1,TIMER_CH_2,&timer_ocintpara); + timer_channel_output_config(TIMER1,TIMER_CH_3,&timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,3999); + timer_channel_output_mode_config(TIMER1,TIMER_CH_1,TIMER_OC_MODE_PWM1); + timer_channel_output_shadow_config(TIMER1,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE); + + timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,7999); + timer_channel_output_mode_config(TIMER1,TIMER_CH_2,TIMER_OC_MODE_PWM1); + timer_channel_output_shadow_config(TIMER1,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE); + + timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_3,11999); + timer_channel_output_mode_config(TIMER1,TIMER_CH_3,TIMER_OC_MODE_PWM1); + timer_channel_output_shadow_config(TIMER1,TIMER_CH_3,TIMER_OC_SHADOW_DISABLE); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER1); + timer_enable(TIMER1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/readme.txt new file mode 100644 index 0000000..b6ca811 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/readme.txt @@ -0,0 +1,34 @@ +/*! + \file readme.txt + \brief description of the DBG demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows that, when the +DBG_CTL0_TM1_HOLD bit in DBG control register(DBG_CTL0) is set and the core halted, +the TIMER1 counter stop counting and the PWM outputs of all channels are stopped as +well.It's benefit for debuging. + + The TIMER1 counter clock used is 1MHz. +The Three Duty cycles are computed as the following description: +The channel 1 duty cycle is set to 25% +The channel 2 duty cycle is set to 50% +The channel 3 duty cycle is set to 75% + + Connect the TIMER1 pins to an oscilloscope and monitor the different waveforms: +- TIMER1_CH1 pin (PB3) +- TIMER1_CH2 pin (PB10) +- TIMER1_CH3 pin (PB11) + + For Keil,in debug mode,when the core is stopped,update the register window for TIMER1, +you will see that the count value will not change. And at the same time,the PWM outputs of +all the channels of TIMER1 will be stopped. + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/systick.c new file mode 100644 index 0000000..22ed8da --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_configuration(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if(SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if(0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/systick.h new file mode 100644 index 0000000..5c51338 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DBG/DBG_timer1_stop/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_configuration(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/gd32f1x0_it.c new file mode 100644 index 0000000..fdc4192 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/gd32f1x0_it.c @@ -0,0 +1,130 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" + +extern __IO uint32_t int_num; + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/*! + \brief this function handles DMA_Channel0_IRQHandler interrupt + \param[in] none + \param[out] none + \retval none +*/ +void DMA_Channel0_IRQHandler(void) +{ + if(dma_interrupt_flag_get(DMA_CH0,DMA_INT_FLAG_FTF)){ + int_num++; + dma_interrupt_flag_clear(DMA_CH0,DMA_INT_FLAG_FTF); + dma_interrupt_flag_clear(DMA_CH0,DMA_INT_FLAG_G); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/gd32f1x0_it.h new file mode 100644 index 0000000..aa0525e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* DMA_Channel0 handle function */ +void DMA_Channel0_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/main.c new file mode 100644 index 0000000..ff63a6d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/main.c @@ -0,0 +1,200 @@ +/*! + \file main.c + \brief transfer data from FLASH to RAM +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +#define ACCESSSUM 1024 +#define FMC_PAGE_SIZE ((uint16_t)0x400) +#define BANK1_WRITE_START_ADDR ((uint32_t)0x08004000) +#define BANK1_WRITE_END_ADDR ((uint32_t)0x08004800) + +void rcu_config(void); +void nvic_config(void); +void led_config(void); + +__IO ErrStatus accessflag = SUCCESS; +uint32_t destdata[256]; +uint32_t *ptrd; +__IO uint32_t int_num = 0; +uint32_t erasenum = 0x00, address = 0x00 ,wperror = 0,wperror2 = 0; +uint32_t transdata = 0x3210ABCD; +__IO uint32_t pagenum = 0x00; +volatile fmc_state_enum fmcstatus = FMC_READY; + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + uint32_t i; + dma_parameter_struct dma_init_struct; + /* system clocks configuration */ + rcu_config(); + + /* NVIC configuration */ + nvic_config(); + + led_config() ; + + /* unlock the flash bank1 program erase controller */ + fmc_unlock(); + + /* define the number of page to be erased */ + pagenum = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FMC_PAGE_SIZE; + + /* clear all pending flags */ + fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END); + + /* erase the flash pages */ + for(erasenum = 0; erasenum < pagenum; erasenum++){ + fmcstatus = fmc_page_erase(BANK1_WRITE_START_ADDR + (FMC_PAGE_SIZE * erasenum)); + wperror += (fmcstatus == FMC_WPERR); + fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END); + } + + /* unlock the flash bank1 program erase controller */ + fmc_lock(); + + ptrd = (uint32_t*)BANK1_WRITE_START_ADDR; + for(i = 0; i < 256; i++){ + if(0xFFFFFFFF != *ptrd){ + accessflag = ERROR; + break; + } + ptrd++; + } + + /* unlock the flash bank1 program erase controller */ + fmc_unlock(); + + /* define the number of page to be erased */ + pagenum = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FMC_PAGE_SIZE; + + /* clear all pending flags */ + fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END); + + /* program flash bank1 */ + address = BANK1_WRITE_START_ADDR; + wperror2 = 0; + while(address < BANK1_WRITE_END_ADDR){ + fmcstatus = fmc_word_program(address, transdata); + address = address + 4; + wperror2 += (FMC_WPERR == fmcstatus); + fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END); + } + + fmc_lock(); + + /* DMA channel0 initialize */ + dma_deinit(DMA_CH0); + dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; + dma_init_struct.memory_addr = (uint32_t)destdata; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.number = ACCESSSUM; + dma_init_struct.periph_addr = (uint32_t)BANK1_WRITE_START_ADDR; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_ENABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; + dma_init(DMA_CH0,dma_init_struct); + /* DMA channel0 mode configuration */ + dma_circulation_disable(DMA_CH0); + dma_memory_to_memory_enable(DMA_CH0); + /* DMA channel0 interrupt configuration */ + dma_interrupt_enable(DMA_CH0, DMA_INT_FTF); + /* enable DMA transfer */ + dma_channel_enable(DMA_CH0); + + /* wait DMA interrupt */ + for(i = 0; i < 10000; i++){ + if(int_num) + break; + } + + /* compare destdata with transdata */ + ptrd = destdata; + for(i = 0; i < 256; i++){ + if(transdata != *ptrd) + { + accessflag = ERROR; + break; + } + ptrd++; + } + + /* transfer sucess */ + if(accessflag != ERROR){ + gd_eval_led_off(LED1); + gd_eval_led_off(LED3); + gd_eval_led_on(LED2); + gd_eval_led_on(LED4); + }else{ + /* transfer fail */ + gd_eval_led_off(LED2); + gd_eval_led_off(LED4); + gd_eval_led_on(LED1); + gd_eval_led_on(LED3); + } + + while(1); +} + +/*! + \brief configure LED + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + gd_eval_led_init (LED1); + gd_eval_led_init (LED2); + gd_eval_led_init (LED3); + gd_eval_led_init (LED4); + + /* LED off */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED3); + gd_eval_led_off(LED2); + gd_eval_led_off(LED4); +} + +/*! + \brief configure the different system clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable DMA clock */ + rcu_periph_clock_enable(RCU_DMA); +} + +/*! + \brief configure the nested vectored interrupt controller + \param[in] none + \param[out] none + \retval none +*/ +void nvic_config(void) +{ + nvic_irq_enable(DMA_Channel0_IRQn,0,0); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/readme.txt new file mode 100644 index 0000000..796be37 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Flash_to_ram/readme.txt @@ -0,0 +1,28 @@ +/*! + \file readme.txt + \brief description of the DMA flash to ram example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/ GD32190R-EVAL board, it provides a description +of how to use DMA channel0 to transfer data buffer from FLASH memory to embedded SRAM memory. + + Before programming the flash addresses, an erase operation is performed firstly. +After the erase operation, a comparison between FLASH memory and 0xFFFFFFFF(Reset value) +is done to check that the FLASH memory has been correctly erased. + + Once the erase operation is finished correctly, the programming operation will be +performed by using the fmc_programword function. The written data is transfered to +embedded SRAM memory by DMA1 Channel1. The transfer is started by enabling the DMA1 Channel1. +At the end of the transfer, a Transfer Complete interrupt is generated since it +is enabled. A comparison between the FLASH memory and embedded SRAM memory is done to +check that all data have been correctly transferred.If the result of comparison is passed, +LED2 and LED4 light up. Otherwise LED1 and LED3 light up. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_ram/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_ram/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_ram/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_ram/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_ram/main.c new file mode 100644 index 0000000..61b796b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_ram/main.c @@ -0,0 +1,157 @@ +/*! + \file main.c + \brief transfer data from RAM to RAM +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_eval.h" + +#define DATANUM 16 + +__IO ErrStatus transferflag1 = ERROR; +__IO ErrStatus transferflag2 = ERROR; +__IO ErrStatus transferflag3 = ERROR; +__IO ErrStatus transferflag4 = ERROR; +uint8_t source_address[DATANUM]= {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, + 0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10}; +uint8_t destination_address1[DATANUM]; +uint8_t destination_address2[DATANUM]; +uint8_t destination_address3[DATANUM]; +uint8_t destination_address4[DATANUM]; + +void led_config(void); +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i = 0; + dma_parameter_struct dma_init_struct; + /* enable DMA clock */ + rcu_periph_clock_enable(RCU_DMA); + /* initialize LED */ + led_config(); + /* all LED off */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED3); + gd_eval_led_off(LED2); + gd_eval_led_off(LED4); + /* initialize DMA channel1 */ + dma_deinit(DMA_CH1); + dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; + dma_init_struct.memory_addr = (uint32_t)destination_address1; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.number = DATANUM; + dma_init_struct.periph_addr = (uint32_t)source_address; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_ENABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; + dma_init(DMA_CH1,dma_init_struct); + /* configure DMA mode */ + dma_circulation_disable(DMA_CH1); + dma_memory_to_memory_enable(DMA_CH1); + + /* initialize DMA channel2 */ + dma_deinit(DMA_CH2); + dma_init_struct.memory_addr = (uint32_t)destination_address2; + dma_init(DMA_CH2,dma_init_struct); + /* configure DMA mode */ + dma_circulation_disable(DMA_CH2); + dma_memory_to_memory_enable(DMA_CH2); + + /* initialize DMA channel3 */ + dma_deinit(DMA_CH3); + dma_init_struct.memory_addr = (uint32_t)destination_address3; + dma_init(DMA_CH3,dma_init_struct); + /* configure DMA mode */ + dma_circulation_disable(DMA_CH3); + dma_memory_to_memory_enable(DMA_CH3); + + /* initialize DMA channel4 */ + dma_deinit(DMA_CH4); + dma_init_struct.memory_addr = (uint32_t)destination_address4; + dma_init(DMA_CH4,dma_init_struct); + /* configure DMA mode */ + dma_circulation_disable(DMA_CH4); + dma_memory_to_memory_enable(DMA_CH4); + + /* enable DMA channel1~channel4 */ + dma_channel_enable(DMA_CH1); + dma_channel_enable(DMA_CH2); + dma_channel_enable(DMA_CH3); + dma_channel_enable(DMA_CH4); + + /* wait for DMA transfer complete */ + for(i = 0; i < 200; i++); + /* compare the data of source_address with data of destination_address */ + transferflag1 = memory_compare(source_address, destination_address1, DATANUM); + transferflag2 = memory_compare(source_address, destination_address2, DATANUM); + transferflag3 = memory_compare(source_address, destination_address3, DATANUM); + transferflag4 = memory_compare(source_address, destination_address4, DATANUM); + + /* if DMA channel1 transfer success,light LED1 */ + if(SUCCESS == transferflag1){ + gd_eval_led_on(LED1); + } + /* if DMA channel2 transfer success,light LED2 */ + if(SUCCESS == transferflag2){ + gd_eval_led_on(LED2); + } + /* if DMA channel3 transfer success,light LED3 */ + if(SUCCESS == transferflag3){ + gd_eval_led_on(LED3); + } + /* if DMA channel4 transfer success,light LED4 */ + if(SUCCESS == transferflag4){ + gd_eval_led_on(LED4); + } + + while (1); +} + +/*! + \brief LEDs configure + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + gd_eval_led_init (LED1); + gd_eval_led_init (LED2); + gd_eval_led_init (LED3); + gd_eval_led_init (LED4); +} + +/*! + \brief memory compare function + \param[in] src : source data + \param[in] dst : destination data + \param[in] length : the compare data length + \param[out] none + \retval ErrStatus : ERROR or SUCCESS +*/ +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length) +{ + while (length--){ + if (*src++ != *dst++){ + return ERROR; + } + } + return SUCCESS; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_ram/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_ram/readme.txt new file mode 100644 index 0000000..57f3ae5 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_ram/readme.txt @@ -0,0 +1,23 @@ +/*! + \file readme.txt + \brief description of DMA ram to ram +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/ GD32190R-EVAL board, it provides a description +of how to use DMA channel(1 to 4) to transfer data from RAM to RAM.DMA Channel(1 to 4) is +configured to transfer the contents of data buffer stored in "source_address" to the +reception buffer declared in RAM(destination_address1~destination_address4). + + The start of transfer is triggered by software. At the end of the transfer, a comparison +between the source and destination buffers is done to check that all data have been correctly +transferred.If transfer correctly the corresponding LED light.If transfer do not correcly,the +corresponding LED is off. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/gd32f1x0_it.c new file mode 100644 index 0000000..f409070 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/gd32f1x0_it.c @@ -0,0 +1,149 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" + +extern __IO uint32_t transfer; + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +#ifdef GD32F130_150 + +/*! + \brief this function handles DMA_Channel1_2_IRQHandler interrupt + \param[in] none + \param[out] none + \retval none +*/ +void DMA_Channel1_2_IRQHandler(void) +{ + if(dma_interrupt_flag_get(DMA_CH1, DMA_INT_FLAG_FTF)){ + transfer++; + dma_interrupt_flag_clear(DMA_CH1, DMA_INT_FLAG_G); + } +} + +#elif defined GD32F170_190 + +/*! + \brief this function handles DMA_Channel3_4_IRQHandler interrupt + \param[in] none + \param[out] none + \retval none +*/ +void DMA_Channel3_4_IRQHandler(void) +{ + if(dma_interrupt_flag_get(DMA_CH3, DMA_INT_FLAG_FTF)){ + transfer++; + dma_interrupt_flag_clear(DMA_CH3, DMA_INT_FLAG_G); + } +} + +#endif /* GD32F130_150 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/gd32f1x0_it.h new file mode 100644 index 0000000..b84af1b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/gd32f1x0_it.h @@ -0,0 +1,52 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); + +#ifdef GD32F130_150 + + /* DMA_Channel1_2 handle function */ + void DMA_Channel1_2_IRQHandler(void); + +#elif defined GD32F170_190 + + /* DMA_Channel3_4 handle function */ + void DMA_Channel3_4_IRQHandler(void); + +#endif /* GD32F130_150 */ + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/main.c new file mode 100644 index 0000000..2e1ae7c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/main.c @@ -0,0 +1,146 @@ +/*! + \file main.c + \brief transfer data from RAM to USART +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_eval.h" + +#define USART0_DATA_ADDRESS ((uint32_t)0x40013828) /* 130_150 device */ +#define USART1_DATA_ADDRESS ((uint32_t)0x40004428) /* 170_190 device */ +#define ARRAYNUM(arr_nanme) (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme))) + +uint8_t welcome[]="hi,this is a example: RAM_TO_USART by DMA !\n"; +__IO uint32_t transfer; + +void led_config(void); +void nvic_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + dma_parameter_struct dma_init_struct; + /* enable DMA clock */ + rcu_periph_clock_enable(RCU_DMA); + + /* initialize LED */ + led_config(); + + /* all LED off */ + gd_eval_led_off(LED1); + + /*configure DMA interrupt*/ + nvic_config(); + +#ifdef GD32F130_150 + + /* USART configure */ + gd_eval_com_init(EVAL_COM1); + + /* initialize DMA channel1 */ + dma_deinit(DMA_CH1); + dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; + dma_init_struct.memory_addr = (uint32_t)welcome; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.number = ARRAYNUM(welcome); + dma_init_struct.periph_addr = USART0_DATA_ADDRESS; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; + dma_init(DMA_CH1,dma_init_struct); + + /* configure DMA mode */ + dma_circulation_disable(DMA_CH1); + dma_memory_to_memory_disable(DMA_CH1); + + /* USART DMA enable for transmission */ + usart_dma_transmit_config(USART0,USART_DENT_ENABLE); + + /* enable DMA transfer complete interrupt */ + dma_interrupt_enable(DMA_CH1,DMA_CHXCTL_FTFIE); + + /* enable DMA channel1 */ + dma_channel_enable(DMA_CH1); + +#elif defined GD32F170_190 + + /* USART configure */ + gd_eval_COMinit(EVAL_COM2); + + /* initialize DMA channel3 */ + dma_deinit(DMA_CH3); + dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; + dma_init_struct.memory_addr = (uint32_t)welcome; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.number = ARRAYNUM(welcome); + dma_init_struct.periph_addr = USART1_DATA_ADDRESS; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; + dma_init(DMA_CH3,dma_init_struct); + + /* configure DMA mode */ + dma_circulation_disable(DMA_CH3); + dma_memory_to_memory_disable(DMA_CH3); + + /* USART DMA enable for transmission */ + usart_dma_transfer_config(USART1,USART_DENT_ENABLE); + + /* enable DMA transfer complete interrupt */ + dma_interrupt_enable(DMA_CH3,DMA_INT_FTF); + + /* enable DMA channel3 */ + dma_channel_enable(DMA_CH3); + +#endif /* GD32F130_150 */ + + /* waiting for the transfer to complete*/ + while(0 == transfer); + + /* light LED1 */ + gd_eval_led_on(LED1); + + while (1); +} + +/*! + \brief LEDs configure + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + gd_eval_led_init (LED1); +} + +/*! + \brief configure DMA interrupt + \param[in] none + \param[out] none + \retval none +*/ +void nvic_config(void) +{ +#ifdef GD32F130_150 + nvic_irq_enable(DMA_Channel1_2_IRQn,0,0); +#elif defined GD32F170_190 + nvic_irq_enable(DMA_Channel3_4_IRQn,0,0); +#endif +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/readme.txt new file mode 100644 index 0000000..83b2b00 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/DMA/Ram_to_usart/readme.txt @@ -0,0 +1,20 @@ +/*! + \file readme.txt + \brief description of DMA ram to usart +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/ GD32190R-EVAL board, it provides a description +of how to use DMA channel1/ channel3 to transfer data from RAM memory to USART transmit data +register.The start of transfer is triggered by software. At the end of the transfer, a +transfer complete interrupt is generated since it is enabled. If the DMA transfer +operation is finished correctly, data stored array welcome[] will be transfered +to a serial port tool by USART and LED1 light up. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/gd32f1x0_it.c new file mode 100644 index 0000000..eedf701 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/gd32f1x0_it.c @@ -0,0 +1,128 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/*! + \brief this function handles external lines 4 to 15 interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void EXTI4_15_IRQHandler(void) +{ + if (RESET != exti_interrupt_flag_get(TAMPER_KEY_EXTI_LINE)) { + gd_eval_led_toggle(LED2); + exti_interrupt_flag_clear(TAMPER_KEY_EXTI_LINE); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/gd32f1x0_it.h new file mode 100644 index 0000000..f3fad53 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* EXTI4_15 handle function */ +void EXTI4_15_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/main.c new file mode 100644 index 0000000..3f9ddd2 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/main.c @@ -0,0 +1,35 @@ +/*! + \file main.c + \brief the example of EXTI which generates an interrupt request and toggle the LED +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_eval.h" + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* initialize the LEDs and turn on LED1 */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_on(LED1); + + /* configure the tamper key */ + gd_eval_key_init(KEY_TAMPER, KEY_MODE_EXTI); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/readme.txt new file mode 100644 index 0000000..0dcf26b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/EXTI/Key_external_interrupt_mode/readme.txt @@ -0,0 +1,19 @@ +/*! + \file readme.txt + \brief description of the EXTI Key example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +generate the interrupt request, and toggle the LED. After the system start-up, +LED1 is on. When Tamper Key is pressed, LED2 is toggled, it is switched on; when +Tamper Key is pressed once again, LED2 is toggled, it is switched off. + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/main.c new file mode 100644 index 0000000..c1e55d5 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/main.c @@ -0,0 +1,219 @@ +/*! + \file main.c + \brief main flash program, erase and reprogram +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "main.h" +#include "gd32f1x0_eval.h" + +#define FMC_PAGE_SIZE ((uint16_t)0x400U) +#define FMC_WRITE_START_ADDR ((uint32_t)0x08004000U) +#define FMC_WRITE_END_ADDR ((uint32_t)0x08004800U) + +uint32_t *ptrd; +uint32_t address = 0x00U; +uint32_t data0 = 0x01234567U; +uint32_t data1 = 0xd583179bU; +led_typedef_enum lednum = LED4; + +/* calculate the number of page to be programmed/erased */ +uint32_t PageNum = (FMC_WRITE_END_ADDR - FMC_WRITE_START_ADDR) / FMC_PAGE_SIZE; +/* calculate the number of page to be programmed/erased */ +uint32_t WordNum = ((FMC_WRITE_END_ADDR - FMC_WRITE_START_ADDR) >> 2); + +/*! + \brief erase fmc pages from FMC_WRITE_START_ADDR to FMC_WRITE_END_ADDR + \param[in] none + \param[out] none + \retval none +*/ +void fmc_erase_pages(void) +{ + uint32_t EraseCounter; + + /* unlock the flash program/erase controller */ + fmc_unlock(); + + /* clear all pending flags */ + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); + + /* erase the flash pages */ + for(EraseCounter = 0U; EraseCounter < PageNum; EraseCounter++){ + fmc_page_erase(FMC_WRITE_START_ADDR + (FMC_PAGE_SIZE * EraseCounter)); + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); + } + + /* lock the main FMC after the erase operation */ + fmc_lock(); +} + +/*! + \brief program fmc word by word from FMC_WRITE_START_ADDR to FMC_WRITE_END_ADDR + \param[in] none + \param[out] none + \retval none +*/ +void fmc_program(void) +{ + /* unlock the flash program/erase controller */ + fmc_unlock(); + + address = FMC_WRITE_START_ADDR; + + /* program flash */ + while(address < FMC_WRITE_END_ADDR){ + fmc_word_program(address, data0); + address += 4U; + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); + } + + /* lock the main FMC after the program operation */ + fmc_lock(); +} + +#ifdef GD32F170_190 +/*! + \brief reprogram fmc word by word from FMC_WRITE_START_ADDR to FMC_WRITE_END_ADDR + \param[in] none + \param[out] none + \retval none +*/ +void fmc_reprogram(void) +{ + /* unlock the flash program/erase controller */ + fmc_unlock(); + + address = FMC_WRITE_START_ADDR; + + /* reprogram the previous program address */ + while(address < FMC_WRITE_END_ADDR){ + fmc_word_reprogram(address, data1); + address += 4U; + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); + } + + /* lock the main FMC after the reprogram operation */ + fmc_lock(); +} +#endif /* GD32F170_190 */ + +/*! + \brief check fmc erase result + \param[in] none + \param[out] none + \retval none +*/ +void fmc_erase_pages_check(void) +{ + uint32_t i; + + ptrd = (uint32_t *)FMC_WRITE_START_ADDR; + + /* check flash whether has been erased */ + for(i = 0U; i < WordNum; i++){ + if(0xFFFFFFFFU != (*ptrd)){ + lednum = LED1; + gd_eval_led_on(lednum); + break; + }else{ + ptrd++; + } + } +} + +/*! + \brief check fmc program result + \param[in] none + \param[out] none + \retval none +*/ +void fmc_program_check(void) +{ + uint32_t i; + + ptrd = (uint32_t *)FMC_WRITE_START_ADDR; + + /* check flash whether has been programmed */ + for(i = 0U; i < WordNum; i++){ + if((*ptrd) != data0){ + lednum = LED2; + gd_eval_led_on(lednum); + break; + }else{ + ptrd++; + } + } +} + +#ifdef GD32F170_190 +/*! + \brief check fmc reprogram result + \param[in] none + \param[out] none + \retval none +*/ +void fmc_reprogram_check(void) +{ + uint32_t i; + + ptrd = (uint32_t *)FMC_WRITE_START_ADDR; + + /* check reprogram result, only can reprogram corresponding bit value from 1 to 0 */ + for(i = 0U; i < WordNum; i++){ + if(0x01030503U != (*ptrd)){ + lednum = LED3; + gd_eval_led_on(lednum); + break; + }else{ + ptrd++; + } + } +} +#endif /* GD32F170_190 */ + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* initialize led on the board */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_init(LED3); + gd_eval_led_init(LED4); + + /* step1: erase pages and check if it is successful. If not, light the LED1. */ + fmc_erase_pages(); + fmc_erase_pages_check(); + + /* step2: program and check if it is successful. If not, light the LED2. */ + fmc_program(); + fmc_program_check(); + + #ifdef GD32F170_190 + /* step3: reprogram and check if it is successful. If not, light the LED3. */ + fmc_reprogram(); + fmc_reprogram_check(); + #endif /* GD32F170_190 */ + + /* if all the operations are successful, light the LED4. */ + if(LED4 == lednum){ + gd_eval_led_on(LED4); + } + + while(1){ + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/main.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/main.h new file mode 100644 index 0000000..089a358 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/main.h @@ -0,0 +1,36 @@ +/*! + \file main.h + \brief the header file of main +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef MAIN_H +#define MAIN_H + +/* erase fmc pages from FMC_WRITE_START_ADDR to FMC_WRITE_END_ADDR */ +void fmc_erase_pages(void); +/* program fmc word by word from FMC_WRITE_START_ADDR to FMC_WRITE_END_ADDR */ +void fmc_program(void); +#ifdef GD32F170_190 +/* reprogram fmc word by word from FMC_WRITE_START_ADDR to FMC_WRITE_END_ADDR */ +void fmc_reprogram(void); +#endif /* GD32F170_190 */ +/* check fmc erase result */ +void fmc_erase_pages_check(void); +/* check fmc program result */ +void fmc_program_check(void); +#ifdef GD32F170_190 +/* check fmc reprogram result */ +void fmc_reprogram_check(void); +#endif /* GD32F170_190 */ + +#endif + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/readme.txt new file mode 100644 index 0000000..5cafd6f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Erase_program/readme.txt @@ -0,0 +1,31 @@ +/*! + \file readme.txt + \brief description of erase_program example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/GD32190R-EVAL board, it provides a +description of how to erase and program flash memory and reprogram without previous +earse. + + In erasing operation, a comparison between flash memory and 0xffffffff is done to +check whether the flash memory has been correctly erased. If the result is wrong, +LED1 will be on. + + In programming operation, a comparison between flash memory and target data is +done to check whether the flash memory has been correctly programmed. If the result +is wrong, LED2 will be on. + + In reprogramming operation (only exists in GD32190R-EVAL board), corresponding bit +value will be changed from 1 to 0, If the result is wrong, LED3 will be on. + + If all the three operations are successful, LED4 will be on. + \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/gd32f1x0_it.c new file mode 100644 index 0000000..322daed --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/gd32f1x0_it.c @@ -0,0 +1,162 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" +#include "main.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/*! + \brief this function handles external lines 0 to 1 interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void EXTI0_1_IRQHandler(void) +{ + if(RESET != exti_interrupt_flag_get(WAKEUP_KEY_EXTI_LINE)){ + uint16_t wp_pages_bitmap = ((uint16_t)(WRITE_PROTECT_PAGES(WP_PAGES_BIT_1) | WRITE_PROTECT_PAGES(WP_PAGES_BIT_2) | WRITE_PROTECT_PAGES(WP_PAGES_BIT_3))); + + /* enable target pages write protection */ + fmc_ob_write_protection_enable(wp_pages_bitmap); + + /* clear the interrupt flag */ + exti_interrupt_flag_clear(WAKEUP_KEY_EXTI_LINE); + } +} + +/*! + \brief this function handles external lines 4 to 15 interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void EXTI4_15_IRQHandler(void) +{ + if(RESET != exti_interrupt_flag_get(TAMPER_KEY_EXTI_LINE)){ + uint16_t wp_pages_bitmap = ((uint16_t)(WRITE_PROTECT_PAGES(WP_PAGES_BIT_1) | WRITE_PROTECT_PAGES(WP_PAGES_BIT_3))); + + /* disable target pages write protection */ + fmc_ob_write_protection_disable(wp_pages_bitmap); + + /* clear the interrupt flag */ + exti_interrupt_flag_clear(TAMPER_KEY_EXTI_LINE); + } + + if(RESET != exti_interrupt_flag_get(USER_KEY_EXTI_LINE)){ + /* disable target pages write protection */ + fmc_ob_write_protection_disable(WP_ALL_PAGES_BITMAP); + + /* clear the interrupt flag */ + exti_interrupt_flag_clear(USER_KEY_EXTI_LINE); + } +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/gd32f1x0_it.h new file mode 100644 index 0000000..4697a16 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/gd32f1x0_it.h @@ -0,0 +1,46 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* this function handles NMI exception */ +void NMI_Handler(void); +/* this function handles HardFault exception */ +void HardFault_Handler(void); +/* this function handles MemManage exception */ +void MemManage_Handler(void); +/* this function handles BusFault exception */ +void BusFault_Handler(void); +/* this function handles UsageFault exception */ +void UsageFault_Handler(void); +/* this function handles SVC exception */ +void SVC_Handler(void); +/* this function handles DebugMon exception */ +void DebugMon_Handler(void); +/* this function handles PendSV exception */ +void PendSV_Handler(void); +/* this function handles SysTick exception */ +void SysTick_Handler(void); +/* this function handles external lines 0 to 1 interrupt request */ +void EXTI0_1_IRQHandler(void); +/* this function handles external lines 4 to 15 interrupt request */ +void EXTI4_15_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/main.c new file mode 100644 index 0000000..9e88867 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/main.c @@ -0,0 +1,194 @@ +/*! + \file main.c + \brief main flash pages write protection +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_eval.h" +#include "main.h" + +/*! + \brief enable some pages' write protection function by configuring option byte + \param[in] wp_pages_bitmap: bitmap of pages which need to be enabled write protection function + \param[out] none + \retval none +*/ +void fmc_ob_write_protection_enable(uint16_t wp_pages_bitmap) +{ + uint8_t ob_user; + uint16_t ob_data; + uint16_t old_wp, new_wp; + + /* unlock the main flash and option byte */ + fmc_unlock(); + ob_unlock(); + + /* clear all pending flags */ + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); + + /* backup the old OB_USER, OB_DATA and OB_WP */ + ob_user = ob_user_get(); + ob_data = ob_data_get(); + old_wp = ob_write_protection_get(); + + /* it's need to do operation just when the pages indicated by wp_pages_bitmap have not been enabled */ + if(0 != (old_wp & wp_pages_bitmap)){ + /* caculate the new write protectiom bitmap */ + new_wp = ((~old_wp) | wp_pages_bitmap); + + /* erase the option byte before modify the content */ + ob_erase(); + + /* restore the OB_USER and OB_DATA */ + ob_user_write(ob_user); + ob_data_program(OB_DATA_ADDR0, (uint8_t)ob_data); + ob_data_program(OB_DATA_ADDR1, (uint8_t)(ob_data >> 8)); + + /* enable the new write protection in option byte */ + ob_write_protection_enable(new_wp); + + /* lock the option byte firstly and then lock the main flash after operation */ + ob_lock(); + fmc_lock(); + + /* reload the option byte and generate a system reset */ + ob_reset(); + } +} + +/*! + \brief disable some pages' write protection function by configuring option byte + \param[in] wp_pages_bitmap: bitmap of pages which need to be disabled write protection function + \param[out] none + \retval none +*/ +void fmc_ob_write_protection_disable(uint16_t wp_pages_bitmap) +{ + uint8_t ob_user; + uint16_t ob_data; + uint16_t old_wp, new_wp; + + /* unlock the main flash and option byte */ + fmc_unlock(); + ob_unlock(); + + /* clear all pending flags */ + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); + + /* backup the old OB_USER, OB_DATA and OB_WP */ + ob_user = ob_user_get(); + ob_data = ob_data_get(); + old_wp = ob_write_protection_get(); + + /* it's need to do operation just when the pages indicated by wp_pages_bitmap have been enabled */ + if((old_wp & wp_pages_bitmap) != wp_pages_bitmap){ + /* caculate the new write protectiom bitmap */ + new_wp = ~(old_wp | wp_pages_bitmap); + + /* erase the option byte before modify the content */ + ob_erase(); + + /* restore the OB_USER and OB_DATA */ + ob_user_write(ob_user); + ob_data_program(OB_DATA_ADDR0, (uint8_t)ob_data); + ob_data_program(OB_DATA_ADDR1, (uint8_t)(ob_data >> 8)); + + /* enable the new write protection in option byte */ + ob_write_protection_enable(new_wp); + + /* lock the option byte firstly and then lock the main flash after operation */ + ob_lock(); + fmc_lock(); + + /* reload the option byte and generate a system reset */ + ob_reset(); + } +} + +/*! + \brief erase and program flash, meanwhile check the operation result + \param[in] none + \param[out] none + \retval none +*/ +void fmc_erase_and_program(void) +{ + uint32_t *ptr = (uint32_t *)ERASE_PAGE_START_ADDR; + + /* unlock the flash program/erase controller */ + fmc_unlock(); + + /* clear all pending flags */ + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); + + /* erase target page */ + fmc_page_erase(ERASE_PAGE_START_ADDR); + /* check the erase result, light the LED3 if the result is failed */ + if(0xFFFFFFFF != (*ptr)){ + gd_eval_led_on(LED3); + + return; + } + + /* program target address */ + fmc_word_program(PROGRAM_ADDRESS, PROGRAM_DATA); + /* check the program result, light the LED3 if the result is failed */ + if(PROGRAM_DATA != (*ptr)){ + gd_eval_led_on(LED3); + + return; + } + + /* light the LED4 if the erase and program result are both successful */ + gd_eval_led_on(LED4); + + /* clear all pending flags */ + fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); + + /* lock the main FMC after the operation */ + fmc_lock(); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* initialize the LED1 and LED2 */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_init(LED3); + gd_eval_led_init(LED4); + + /* configure the keys */ + gd_eval_key_init(KEY_WAKEUP, KEY_MODE_EXTI); + gd_eval_key_init(KEY_TAMPER, KEY_MODE_EXTI); + gd_eval_key_init(KEY_USER, KEY_MODE_EXTI); + + /* check the write protection result and light corresponding LEDs */ + if(WP_ALL_PAGES_BITMAP == ob_write_protection_get()){ + gd_eval_led_on(LED1); + }else{ + gd_eval_led_on(LED2); + } + + /* erase and program flash, + failure (light LED3) indicates the page is in write protection, + success (light LED4) indicates the page is not in write protection */ + fmc_erase_and_program(); + + while(1); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/main.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/main.h new file mode 100644 index 0000000..c89aa03 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/main.h @@ -0,0 +1,44 @@ +/*! + \file main.h + \brief the header file of main +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef MAIN_H +#define MAIN_H + +/* bit num chosen for this example */ +#define WP_PAGES_BIT_1 (8U) +#define WP_PAGES_BIT_2 (9U) +#define WP_PAGES_BIT_3 (10U) +#define WP_ALL_PAGES_BITMAP (0xFFFFU) + +/* construct the bitmap which pages need to be configured the write protection */ +#define WRITE_PROTECT_PAGES(bit_num) (BIT(bit_num)) + +/* every bit in OB_WP indicates 4 pages if they are in write protection */ +#define PAGE_NUM_PER_WP_BIT (4U) + +/* address and data for fmc operation */ +#define ERASE_PAGE (WP_PAGES_BIT_1 * PAGE_NUM_PER_WP_BIT) +#define ERASE_PAGE_START_ADDR (0x08000000U + 0x400U * ERASE_PAGE) +#define PROGRAM_ADDRESS ERASE_PAGE_START_ADDR +#define PROGRAM_DATA (0x12345678U) + +/* enable some pages' write protection function by configuring option byte */ +void fmc_ob_write_protection_enable(uint16_t wp_pages_bitmap); +/* disable some pages' write protection function by configuring option byte */ +void fmc_ob_write_protection_disable(uint16_t wp_pages_bitmap); +/* erase and program flash, meanwhile check the operation result */ +void fmc_erase_and_program(void); + +#endif + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/readme.txt new file mode 100644 index 0000000..27744a0 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FMC/Write_protection/readme.txt @@ -0,0 +1,41 @@ +/*! + \file readme.txt + \brief description of write_protection example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL board, it provides a description +of how to enable and disable the write protection for the embedded flash. + + After system start-up, LED1 and LED4 usually are lighted. Meanwhile, LED2 and LED3 usually +are off. It indicates that no pages of flash are in write protection and all pages can be +erased/programmed successfully. If not, press the key User to change the board to the normal +condition. + + STEP1: Press the key Wakeup. The LED1 and LED4 will be off and LED2 and LED3 will be on. +It indicates that some pages are in write protection and erasing/programming on them is failed. + + STEP2: Press the key User. The LED1 and LED4 will be on and LED2 and LED3 will be off. +It indicates that those pages are out of write protection and erasing/programming on them is successful. + + STEP3: Repeat the STEP1. + + STEP4: Press the key Tamper. The LED2 and LED4 will be on and LED1 and LED3 will be off. +It indicates that some pages are out of write protection and can be erased/programmed successfully. +But some other pages are still in write protection. + + STEP5: Press the key User. The LED1 and LED4 will be on and LED2 and LED3 will be off. +It indicates that all pages are out of write protection and erasing/programming on them is successful. + + Note: After testing the example, please ensure to press the key User to disable all pages' +write protection. + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/gd32f1x0_it.c new file mode 100644 index 0000000..1ecb14f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/gd32f1x0_it.c @@ -0,0 +1,134 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} + +/*! + \brief this function handles EXTI4_15 interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void EXTI4_15_IRQHandler(void) +{ + /* make sure whether the EXTI Line is interrupted */ + if(RESET != exti_interrupt_flag_get(EXTI_13)){ + /* reload FWDGT counter */ + fwdgt_counter_reload(); + } + + /* clear the interrupt flag bit */ + exti_interrupt_flag_clear(EXTI_13); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/gd32f1x0_it.h new file mode 100644 index 0000000..f3fad53 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* EXTI4_15 handle function */ +void EXTI4_15_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/main.c new file mode 100644 index 0000000..8d8979b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/main.c @@ -0,0 +1,68 @@ +/*! + \file main.c + \brief fwdgt key demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" +#include +#include "gd32f1x0_eval.h" + +void irc40k_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* system clocks configuration */ + irc40k_config(); + systick_config(); + + gd_eval_led_init(LED2); + gd_eval_key_init(KEY_TAMPER,KEY_MODE_EXTI); + delay_1ms(50); + + /* enable write access to FWDGT_PSC and FWDGT_RLD registers. + FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */ + fwdgt_config(625,FWDGT_PSC_DIV64); + fwdgt_enable(); + + /* check if the system has resumed from FWDGT reset */ + if (RESET != rcu_flag_get(RCU_FLAG_FWDGTRST)){ + gd_eval_led_on(LED2); + rcu_all_reset_flag_clear(); + + while(1); + }else{ + gd_eval_led_off(LED2); + } + + while (1); +} + +/*! + \brief IRC40K configuration function + \param[in] none + \param[out] none + \retval none +*/ +void irc40k_config(void) +{ + /* enable IRC40K */ + rcu_osci_on(RCU_IRC40K); + /* wait till IRC40K is ready */ + rcu_osci_stab_wait(RCU_IRC40K); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/readme.txt new file mode 100644 index 0000000..45905e8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/readme.txt @@ -0,0 +1,29 @@ +/*! + \file readme.txt + \brief description of the FWDGT_key example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +reload the FWDGT counter at regulate period using the EXTI interrupt. The FWDGT +timeout is set to 1s (the timeout may varies due to IRC40K frequency dispersion). + + An EXTI is connected to a specific GPIO pin and configured to generate an interrupt +on its falling edge: when the EXTI Line interrupt is triggered (by pressing the Key +push-button on the board), the corresponding interrupt is served. In the ISR, FWDGT +counter is reloaded). As a result, when the FWDGT counter is reloaded, which prevents +any FWDGT reset, LED1 remain illuminated. + + If the EXTI Line interrupt does not occur, the FWDGT counter is not reloaded before +the FWDGT counter reaches 00h, and the FWDGT reset. If the FWDGT reset is generated, LED1 +is turned off with the system reset. + + In this example the system clock is set to 72 MHz. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/systick.c new file mode 100644 index 0000000..d736be4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/FWDGT/FWDGT_key/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/gd32f1x0_it.c new file mode 100644 index 0000000..c947950 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/gd32f1x0_it.c @@ -0,0 +1,115 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/gd32f1x0_it.h new file mode 100644 index 0000000..a4c6c0f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/main.c new file mode 100644 index 0000000..2a5005c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/main.c @@ -0,0 +1,44 @@ +/*! + \file main.c + \brief keyboard polling mode +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_libopt.h" +#include "systick.h" +#include "gd32f1x0_eval.h" + +#include + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + systick_config(); + gd_eval_led_init(LED1); + gd_eval_key_init(KEY_TAMPER,KEY_MODE_GPIO); + + while(1){ + /* check whether the button is pressed */ + if(RESET == gd_eval_key_state_get(KEY_TAMPER)){ + delay_1ms(100); + /* check whether the button is pressed */ + if(RESET == gd_eval_key_state_get(KEY_TAMPER)){ + gd_eval_led_toggle(LED1); + } + } + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/readme.txt new file mode 100644 index 0000000..ad30524 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/readme.txt @@ -0,0 +1,23 @@ +/*! + \file readme.txt + \brief description of the Keyboard_polling_mode example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/ GD32190R-EVAL board, it provides +a description of how to use Tamper key to control the LED1. The example +uses polling mode. Press the key, LED1 will be turn on. Press the Key again, +LED1 will be turn off. + +on the GD32150R-EVAL board,the Tamper key connected to PC13 and the LED1 connected to PC10. +on the GD32190R-EVAL board,the Tamper key connected to PC13 and the LED1 connected to PA11. + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/systick.c new file mode 100644 index 0000000..89a7c16 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Keyboard_polling_mode/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/gd32f1x0_it.c new file mode 100644 index 0000000..c947950 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/gd32f1x0_it.c @@ -0,0 +1,115 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/gd32f1x0_it.h new file mode 100644 index 0000000..a4c6c0f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/main.c new file mode 100644 index 0000000..913a39b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/main.c @@ -0,0 +1,53 @@ +/*! + \file main.c + \brief running led +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform for GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform for GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_libopt.h" +#include "gd32f1x0_eval.h" +#include "systick.h" +#include + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + systick_config(); + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_init(LED3); + gd_eval_led_init(LED4); + + while(1){ + /* turn on led1, turn off led4 */ + gd_eval_led_on(LED1); + gd_eval_led_off(LED4); + delay_1ms(1000); + /* turn on led2, turn off led1 */ + gd_eval_led_on(LED2); + gd_eval_led_off(LED1); + delay_1ms(1000); + /* turn on led3, turn off led2 */ + gd_eval_led_on(LED3); + gd_eval_led_off(LED2); + delay_1ms(1000); + /* turn on led4, turn off led3 */ + gd_eval_led_on(LED4); + gd_eval_led_off(LED3); + delay_1ms(1000); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/readme.txt new file mode 100644 index 0000000..9b24c3c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/readme.txt @@ -0,0 +1,23 @@ +/*! + \file readme.txt + \brief description of the Running_led example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform for GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform for GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/ GD32190R-EVAL board, it provides +a description of Running_led. After system start-up, firstly, LED1 on, then, +LED2 on, four LEDs can light periodically. + + On the GD32150R-EVAL board,LED1 connected to PC10. LED2 connected to PC11. +LED3 connected to PC12. LED4 connected to PD2. + + On the GD32190R-EVAL board,LED1 connected to PA11. LED2 connected to PA12. +LED3 connected to PB6. LED4 connected to PB7. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/systick.c new file mode 100644 index 0000000..89a7c16 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/GPIO/Running_led/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/I2C0_IE.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/I2C0_IE.c new file mode 100644 index 0000000..7714b2a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/I2C0_IE.c @@ -0,0 +1,111 @@ +/*! + \file I2C0_IE.c + \brief I2C0 master receiver interrupt program +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_i2c.h" +#include "I2C_IE.h" + +uint32_t event1; + +/*! + \brief handle I2C0 event interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void I2C0_EventIRQ_Handler(void) +{ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SBSEND)){ + /* the master sends slave address */ + i2c_master_addressing(I2C0, I2C1_SLAVE_ADDRESS7, I2C_RECEIVER); + }else if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND)){ + if((1 == I2C_nBytes)||(2 == I2C_nBytes)){ + /* clear the ACKEN before the ADDSEND is cleared */ + i2c_ack_config(I2C0, I2C_ACK_DISABLE); + /* clear the ADDSEND bit */ + i2c_interrupt_flag_clear(I2C0,I2C_INT_FLAG_ADDSEND); + }else{ + /* clear the ADDSEND bit */ + i2c_interrupt_flag_clear(I2C0,I2C_INT_FLAG_ADDSEND); + } + } + else if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_RBNE)){ + if(I2C_nBytes>0){ + if(3 == I2C_nBytes){ + /* wait until the second last data byte is received into the shift register */ + while(!i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_BTC)); + /* send a NACK for the last data byte */ + i2c_ack_config(I2C0, I2C_ACK_DISABLE); + } + /* read a data byte from I2C_DATA*/ + *i2c_rxbuffer++ = i2c_data_receive(I2C0); + I2C_nBytes--; + if(0 == I2C_nBytes){ + /* send a stop condition */ + i2c_stop_on_bus(I2C0); + status = SUCCESS; + i2c_ack_config(I2C0, I2C_ACK_ENABLE); + i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT); + i2c_interrupt_disable(I2C0, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + } + } + } +} + +/*! + \brief handle I2C0 error interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void I2C0_ErrorIRQ_Handler(void) +{ + /* no acknowledge received */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR); + } + + /* SMBus alert */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBALT)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBALT); + } + + /* bus timeout in SMBus mode */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBTO)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBTO); + } + + /* over-run or under-run when SCL stretch is disabled */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_OUERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR); + } + + /* arbitration lost */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_LOSTARB)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_LOSTARB); + } + + /* bus error */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_BERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_BERR); + } + + /* CRC value doesn't match */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_PECERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_PECERR); + } + + /* disable the error interrupt */ + i2c_interrupt_disable(I2C0,I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/I2C1_IE.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/I2C1_IE.c new file mode 100644 index 0000000..036493d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/I2C1_IE.c @@ -0,0 +1,83 @@ +/*! + \file I2C1_IE.c + \brief I2C1 slave transmitter interrupt program +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_i2c.h" +#include "I2C_IE.h" + +uint32_t event2; + +/*! + \brief handle I2C1 event interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_EventIRQ_Handler(void) +{ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_ADDSEND)){ + /* clear the ADDSEND bit */ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_ADDSEND); + }else if((i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_TBE))&&(!i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_AERR))){ + /* send a data byte */ + i2c_data_transmit(I2C1, *i2c_txbuffer++); + } +} + +/*! + \brief handle I2C1 error interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_ErrorIRQ_Handler(void) +{ + /* no acknowledge received */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_AERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_AERR); + } + + /* SMBus alert */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBALT)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBALT); + } + + /* bus timeout in SMBus mode */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBTO)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBTO); + } + + /* over-run or under-run when SCL stretch is disabled */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_OUERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_OUERR); + } + + /* arbitration lost */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_LOSTARB)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_LOSTARB); + } + + /* bus error */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_BERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_BERR); + } + + /* CRC value doesn't match */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_PECERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_PECERR); + } + + /* disable the error interrupt */ + i2c_interrupt_disable(I2C1, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/I2C_IE.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/I2C_IE.h new file mode 100644 index 0000000..8218005 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/I2C_IE.h @@ -0,0 +1,38 @@ +/*! + \file I2C_IE.h + \brief the header file of I2C0 and I2C1 interrupt +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef I2C_IE_H +#define I2C_IE_H + +#include "gd32f1x0.h" + +#define I2C0_SLAVE_ADDRESS7 0x82 +#define I2C1_SLAVE_ADDRESS7 0x72 + +extern volatile ErrStatus status; +extern volatile uint8_t* i2c_txbuffer; +extern volatile uint8_t* i2c_rxbuffer; +extern volatile uint16_t I2C_nBytes; + +/* function declarations */ +/* handle I2C0 event interrupt request */ +void I2C0_EventIRQ_Handler(void); +/* handle I2C0 error interrupt request */ +void I2C0_ErrorIRQ_Handler(void); +/* handle I2C1 event interrupt request */ +void I2C1_EventIRQ_Handler(void); +/* handle I2C1 error interrupt request */ +void I2C1_ErrorIRQ_Handler(void); + +#endif /* I2C_IE_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/gd32f1x0_it.c new file mode 100644 index 0000000..ba2fc7e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/gd32f1x0_it.c @@ -0,0 +1,149 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "I2C_IE.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles I2C0 event interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C0_EV_IRQHandler(void) +{ + I2C0_EventIRQ_Handler(); +} + +/*! + \brief this function handles I2C0 error interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C0_ER_IRQHandler(void) +{ + I2C0_ErrorIRQ_Handler(); +} + +/*! + \brief this function handles I2C1 event interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_EV_IRQHandler(void) +{ + I2C1_EventIRQ_Handler(); +} + +/*! + \brief this function handles I2C1 error interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_ER_IRQHandler(void) +{ + I2C1_ErrorIRQ_Handler(); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/gd32f1x0_it.h new file mode 100644 index 0000000..3002bc1 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/gd32f1x0_it.h @@ -0,0 +1,48 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* I2C0 event handle function */ +void I2C0_EV_IRQHandler(void); +/* I2C0 error handle function */ +void I2C0_ER_IRQHandler(void); +/* I2C1 event handle function */ +void I2C1_EV_IRQHandler(void); +/* I2C1 error handle function */ +void I2C1_ER_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/main.c new file mode 100644 index 0000000..fb30525 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/main.c @@ -0,0 +1,192 @@ +/*! + \file main.c + \brief master receiver and slave transmitter interrupt +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "I2C_IE.h" +#include "gd32f1x0_eval.h" + +uint8_t i2c_buffer_transmitter[16]; +uint8_t i2c_buffer_receiver[16]; + +volatile uint8_t* i2c_txbuffer; +volatile uint8_t* i2c_rxbuffer; +volatile uint16_t I2C_nBytes; +volatile ErrStatus status; +ErrStatus state = ERROR; + +void rcu_config(void); +void gpio_config(void); +void i2c_config(void); +void i2c_nvic_config(void); +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i; + + /* initialize LED1, LED2, as the transfer instruction */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + rcu_config(); + gpio_config(); + i2c_config(); + i2c_nvic_config(); + + for(i=0; i<16; i++){ + i2c_buffer_transmitter[i] = i + 0x80; + } + /* initialize i2c_txbuffer, i2c_rxbuffer, I2C_nBytes and status */ + i2c_txbuffer = i2c_buffer_transmitter; + i2c_rxbuffer = i2c_buffer_receiver; + I2C_nBytes = 16; + status = ERROR; + + /* enable the I2C0 interrupt */ + i2c_interrupt_enable(I2C0, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + /* enable the I2C1 interrupt */ + i2c_interrupt_enable(I2C1, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + if(2 == I2C_nBytes){ + /* send ACK for the next byte */ + i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT); + } + /* the master waits until the I2C bus is idle */ + while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)); + /* the master sends a start condition to I2C bus */ + i2c_start_on_bus(I2C0); + + while(I2C_nBytes>0); + while(SUCCESS != status); + /* if the transfer is successfully completed, LED1 and LED2 is on */ + state = memory_compare(i2c_buffer_transmitter, i2c_buffer_receiver, 16); + if(SUCCESS == state){ + /* if success, LED1 and LED2 are on */ + gd_eval_led_on(LED1); + gd_eval_led_on(LED2); + }else{ + /* if failed, LED1 and LED2 are off */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + } + while(1) + {} +} + +/*! + \brief memory compare function + \param[in] src : source data + \param[in] dst : destination data + \param[in] length : the compare data length + \param[out] none + \retval ErrStatus : ERROR or SUCCESS +*/ +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length) +{ + while(length--){ + if(*src++ != *dst++){ + return ERROR; + } + } + return SUCCESS; +} + +/*! + \brief enable the peripheral clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + /* enable I2C1 clock */ + rcu_periph_clock_enable(RCU_I2C1); + /* enable I2C0 clock */ + rcu_periph_clock_enable(RCU_I2C0); +} + +/*! + \brief cofigure the GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* I2C0 and I2C1 GPIO ports */ + /* connect PB6 to I2C0_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_6); + /* connect PB7 to I2C0_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_7); + /* connect PB10 to I2C1_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_10); + /* connect PB11 to I2C1_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_11); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_6); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_7); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_10); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_10); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_11); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_11); +} + +/*! + \brief cofigure the I2C0 and I2C1 interfaces + \param[in] none + \param[out] none + \retval none +*/ +void i2c_config(void) +{ + /* I2C clock configure */ + i2c_clock_config(I2C0, 100000, I2C_DTCY_2); + /* I2C address configure */ + i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C0_SLAVE_ADDRESS7); + /* enable I2C0 */ + i2c_enable(I2C0); + /* enable acknowledge */ + i2c_ack_config(I2C0, I2C_ACK_ENABLE); + i2c_clock_config(I2C1, 100000, I2C_DTCY_2); + /* I2C address configure */ + i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_SLAVE_ADDRESS7); + /* enable I2C1 */ + i2c_enable(I2C1); + /* enable acknowledge */ + i2c_ack_config(I2C1, I2C_ACK_ENABLE); +} + +/*! + \brief cofigure the NVIC peripheral + \param[in] none + \param[out] none + \retval none +*/ +void i2c_nvic_config(void) +{ + nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); + nvic_irq_enable(I2C0_EV_IRQn, 0, 3); + nvic_irq_enable(I2C1_EV_IRQn, 0, 4); + nvic_irq_enable(I2C0_ER_IRQn, 0, 2); + nvic_irq_enable(I2C1_ER_IRQn, 0, 1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/readme.txt new file mode 100644 index 0000000..e4c88eb --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver&slave_transmitter_interrupt/readme.txt @@ -0,0 +1,27 @@ +/*! + \file readme.txt + \brief description of the master receiver and slave transmitter interrupt +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/ GD32190R-EVAL board, it shows how to +use the I2C interrupt programming mode in master receiving mode or slave transmitting +mode. In this demo, I2C0 is operated as the master receiver and I2C1 as the slave +transmitter. Moreover,the SCL line and SDA line of I2C0 interface are controled +by the I/O pin PB6 and PB7 respectively. The SCL and SDA of I2C1 are controled +by the pin PB10 and PB11 respectively. + + This demo will send the data of i2c_buffer_transmitter array through I2C1 interface +to the I2C0, and it will store the data received by I2C0 in the i2c_buffer_receiver +array. If transfer is sucessfully completed, LED1 and LED2 are on. + + We shoud use the jumper to connect the PB6 and PB10. The PB7 and PB11 are +connected as well. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver/main.c new file mode 100644 index 0000000..3f4b502 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver/main.c @@ -0,0 +1,167 @@ +/*! + \file main.c + \brief master receiver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" + +#ifdef GD32F130_150 +#define BOARD_I2C I2C0 +#define I2C_SCL_GPIO_PIN GPIO_PIN_6 +#define I2C_SDA_GPIO_PIN GPIO_PIN_7 +#define I2C_RCC RCU_I2C0 +#elif defined GD32F170_190 +#define BOARD_I2C I2C1 +#define I2C_SCL_GPIO_PIN GPIO_PIN_10 +#define I2C_SDA_GPIO_PIN GPIO_PIN_11 +#define I2C_RCC RCU_I2C1 +#endif + +#define I2C_10BIT_ADDRESS 0 + +#define I2C_OWN_ADDRESS7 0x72 +#define I2C_SLAVE_ADDRESS7 0x82 +#define I2C_SLAVE_ADDRESS10 0x0322 + +uint8_t i2c_receiver[16]; + +void rcu_config(void); +void gpio_config(void); +void i2c_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + uint8_t i; + uint8_t slave10_first_byte,slave10_second_byte; + + /* RCU config */ + rcu_config(); + /* GPIO config */ + gpio_config(); + /* I2C config */ + i2c_config(); + + /* wait until I2C bus is idle */ + while(i2c_flag_get(BOARD_I2C, I2C_FLAG_I2CBSY)); + /* send a start condition to I2C bus */ + i2c_start_on_bus(BOARD_I2C); + /* wait until SBSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_SBSEND)); + +#if I2C_10BIT_ADDRESS + slave10_first_byte = (0xF0) | (uint8_t)((I2C_SLAVE_ADDRESS10 & 0x0300)>>7); + /* send slave address first byte to I2C bus */ + i2c_master_addressing(BOARD_I2C, slave10_first_byte, I2C_TRANSMITTER); + /* wait until ADD10SEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_ADD10SEND)); + /* the second byte contains the remaining 8 bits of the 10-bit address */ + slave10_second_byte = (uint8_t)(I2C_SLAVE_ADDRESS10 & 0x00FF); + /* send slave address 2nd byte to I2C bus */ + i2c_master_addressing(BOARD_I2C, slave10_second_byte, I2C_TRANSMITTER); + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_ADDSEND)); + /* clear ADDSEND bit */ + i2c_flag_clear(BOARD_I2C, I2C_FLAG_ADDSEND); + /* send a start condition to I2C bus */ + i2c_start_on_bus(BOARD_I2C); + /* wait until SBSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_SBSEND)); + /* send slave address first byte to I2C bus */ + i2c_master_addressing(BOARD_I2C, slave10_first_byte, I2C_RECEIVER); +#else + /* send slave address to I2C bus */ + i2c_master_addressing(BOARD_I2C, I2C_SLAVE_ADDRESS7, I2C_RECEIVER); +#endif + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_ADDSEND)); + /* clear ADDSEND bit */ + i2c_flag_clear(BOARD_I2C, I2C_FLAG_ADDSEND); + + for(i=0; i<16; i++){ + if(13 == i){ + /* wait until the second last data byte is received into the shift register */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_BTC)); + /* disable acknowledge */ + i2c_ack_config(BOARD_I2C, I2C_ACK_DISABLE); + } + /* wait until the RBNE bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_RBNE)); + /* read a data from I2C_DATA */ + i2c_receiver[i] = i2c_data_receive(BOARD_I2C); + } + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(BOARD_I2C); + while(I2C_CTL0(BOARD_I2C)&0x0200); + /* enable acknowledge */ + i2c_ack_config(BOARD_I2C, I2C_ACK_ENABLE); + + while(1){ + } +} + +/*! + \brief enable the peripheral clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + /* enable I2C clock */ + rcu_periph_clock_enable(I2C_RCC); +} + +/*! + \brief cofigure the GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* I2C GPIO ports */ + /* connect I2C_SCL_GPIO_PIN to I2C SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SCL_GPIO_PIN); + /* connect I2C_SDA_GPIO_PIN to I2C SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SDA_GPIO_PIN); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,I2C_SCL_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,I2C_SCL_GPIO_PIN); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,I2C_SDA_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,I2C_SDA_GPIO_PIN); +} + +/*! + \brief cofigure the I2C interface + \param[in] none + \param[out] none + \retval none +*/ +void i2c_config(void) +{ + /* I2C clock configure */ + i2c_clock_config(BOARD_I2C, 400000, I2C_DTCY_2); + /* I2C address configure */ + i2c_mode_addr_config(BOARD_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_OWN_ADDRESS7); + /* enable I2C */ + i2c_enable(BOARD_I2C); + /* enable acknowledge */ + i2c_ack_config(BOARD_I2C, I2C_ACK_ENABLE); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver/readme.txt new file mode 100644 index 0000000..d75042a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver/readme.txt @@ -0,0 +1,27 @@ +/*! + \file readme.txt + \brief description of the master receiver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows the I2C +programming mode in master receiving mode. In this demo,BOARD_I2C is operated as master +receiver, and the SCL line and SDA line of BOARD_I2C interface are controled by the I/O +pin PB10 and PB11(or PB6 and PB7) respectively. + + This demo shows the receiving data process of the master. And it will store +the received data in the i2c_receiver array. + + This demo doesn't perform the data transfer actually, which is due to no +specific slave.In the specific application, we must send the correct slave +address, and the master and the slave may need to be connected by the jumper +if necessary. When the macro I2C_10BIT_ADDRESS is 1, I2C communicate in 10 bit +addressing mode, otherwise, I2C communicate in 7 bit addressing mode. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_one_byte/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_one_byte/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_one_byte/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_one_byte/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_one_byte/main.c new file mode 100644 index 0000000..50137c3 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_one_byte/main.c @@ -0,0 +1,136 @@ +/*! + \file main.c + \brief master receiver one byte +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" + +#ifdef GD32F130_150 +#define BOARD_I2C I2C0 +#define I2C_SCL_GPIO_PIN GPIO_PIN_6 +#define I2C_SDA_GPIO_PIN GPIO_PIN_7 +#define I2C_RCC RCU_I2C0 +#elif defined GD32F170_190 +#define BOARD_I2C I2C1 +#define I2C_SCL_GPIO_PIN GPIO_PIN_10 +#define I2C_SDA_GPIO_PIN GPIO_PIN_11 +#define I2C_RCC RCU_I2C1 +#endif + +#define I2C_OWN_ADDRESS7 0x72 +#define I2C_SLAVE_ADDRESS7 0x82 + +uint8_t i2c_receiver[16]; + +void rcu_config(void); +void gpio_config(void); +void i2c_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i; + + /* RCU config */ + rcu_config(); + /* GPIO config */ + gpio_config(); + /* I2C config */ + i2c_config(); + + i=0; + /* wait until I2C bus is idle */ + while(i2c_flag_get(BOARD_I2C, I2C_FLAG_I2CBSY)); + /* send a start condition to I2C bus */ + i2c_start_on_bus(BOARD_I2C); + /* wait until SBSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_SBSEND)); + /* send slave address to I2C bus */ + i2c_master_addressing(BOARD_I2C, I2C_SLAVE_ADDRESS7, I2C_RECEIVER); + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_ADDSEND)); + + /* N=1,reset ACKEN bit before clearing ADDRSEND bit */ + i2c_ack_config(BOARD_I2C, I2C_ACK_DISABLE); + /* clear ADDSEND bit */ + i2c_flag_clear(BOARD_I2C, I2C_FLAG_ADDSEND); + /* N=1,send stop condition after clearing ADDRSEND bit */ + i2c_stop_on_bus(BOARD_I2C); + /* wait until the RBNE bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_RBNE)); + /* read a data from I2C_DATA */ + i2c_receiver[i++] = i2c_data_receive(BOARD_I2C); + + while(I2C_CTL0(BOARD_I2C)&0x0200); + /* enable acknowledge */ + i2c_ack_config(BOARD_I2C, I2C_ACK_ENABLE); + + while(1){ + } +} + +/*! + \brief enable the peripheral clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + /* enable I2C clock */ + rcu_periph_clock_enable(I2C_RCC); +} + +/*! + \brief cofigure the GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* I2C GPIO ports */ + /* connect I2C_SCL_GPIO_PIN to I2C_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SCL_GPIO_PIN); + /* connect I2C_SDA_GPIO_PIN to I2C_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SDA_GPIO_PIN); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_GPIO_PIN); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_GPIO_PIN); +} + +/*! + \brief cofigure the I2C interface + \param[in] none + \param[out] none + \retval none +*/ +void i2c_config(void) +{ + /* I2C clock configure */ + i2c_clock_config(BOARD_I2C, 100000, I2C_DTCY_2); + /* I2C address configure */ + i2c_mode_addr_config(BOARD_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_OWN_ADDRESS7); + /* enable I2C */ + i2c_enable(BOARD_I2C); + /* enable acknowledge */ + i2c_ack_config(BOARD_I2C, I2C_ACK_ENABLE); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_one_byte/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_one_byte/readme.txt new file mode 100644 index 0000000..eefab65 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_one_byte/readme.txt @@ -0,0 +1,27 @@ +/*! + \file readme.txt + \brief description of the master receiver one byte +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/ GD32190R-EVAL board, it shows the I2C +programming mode in master receiving mode which the master only want to receive +one byte of data. In this demo, BOARD_I2C is operated as master receiver,and the SCL +line and SDA line of BOARD_I2C interface are controled by the I/O pin PB10 and PB11 +(or PB6 and PB7) respectively. + + This demo shows the receiving one byte process of the master. And it will store +the received data in the i2c_receiver array. + + This demo doesn't perform the data transfer actually, which is due to no +specific slave.In the specific application, we must send the correct slave +address, and the master and the slave may need to be connected by the jumper +if necessary. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_two_bytes/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_two_bytes/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_two_bytes/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_two_bytes/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_two_bytes/main.c new file mode 100644 index 0000000..282b4ad --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_two_bytes/main.c @@ -0,0 +1,144 @@ +/*! + \file main.c + \brief master receiver two bytes +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" + +#ifdef GD32F130_150 +#define BOARD_I2C I2C0 +#define I2C_SCL_GPIO_PIN GPIO_PIN_6 +#define I2C_SDA_GPIO_PIN GPIO_PIN_7 +#define I2C_RCC RCU_I2C0 +#elif defined GD32F170_190 +#define BOARD_I2C I2C1 +#define I2C_SCL_GPIO_PIN GPIO_PIN_10 +#define I2C_SDA_GPIO_PIN GPIO_PIN_11 +#define I2C_RCC RCU_I2C1 +#endif + +#define I2C_OWN_ADDRESS7 0x72 +#define I2C_SLAVE_ADDRESS7 0x82 + +uint8_t i2c_receiver[16]; + +void rcu_config(void); +void gpio_config(void); +void i2c_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i; + + /* RCU config */ + rcu_config(); + /* GPIO config */ + gpio_config(); + /* I2C config */ + i2c_config(); + + i=0; + /* send a NACK for the next data byte which will be received into the shift register */ + i2c_ackpos_config(BOARD_I2C, I2C_ACKPOS_NEXT); + /* wait until I2C bus is idle */ + while(i2c_flag_get(BOARD_I2C, I2C_FLAG_I2CBSY)); + /* send a start condition to I2C bus */ + i2c_start_on_bus(BOARD_I2C); + /* wait until SBSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_SBSEND)); + /* send slave address to I2C bus */ + i2c_master_addressing(BOARD_I2C, I2C_SLAVE_ADDRESS7, I2C_RECEIVER); + /* disable ACK before clearing ADDSEND bit */ + i2c_ack_config(BOARD_I2C, I2C_ACK_DISABLE); + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_ADDSEND)); + /* clear ADDSEND bit */ + i2c_flag_clear(BOARD_I2C, I2C_FLAG_ADDSEND); + /* Wait until the last data byte is received into the shift register */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_BTC)); + /* wait until the RBNE bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_RBNE)); + + /* read a data from I2C_DATA */ + i2c_receiver[i++] = i2c_data_receive(BOARD_I2C); + /* wait until the RBNE bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_RBNE)); + /* read a data from I2C_DATA */ + i2c_receiver[i++] = i2c_data_receive(BOARD_I2C); + /* send a stop condition */ + i2c_stop_on_bus(BOARD_I2C); + while(I2C_CTL0(BOARD_I2C)&0x0200); + i2c_ackpos_config(BOARD_I2C, I2C_ACKPOS_CURRENT); + /* enable acknowledge */ + i2c_ack_config(BOARD_I2C, I2C_ACK_ENABLE); + + while(1){ + } +} + +/*! + \brief enable the peripheral clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + /* enable I2C clock */ + rcu_periph_clock_enable(I2C_RCC); +} + +/*! + \brief cofigure the GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* I2C GPIO ports */ + /* connect I2C_SCL_GPIO_PIN to I2C_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SCL_GPIO_PIN); + /* connect I2C_SDA_GPIO_PIN to I2C_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SDA_GPIO_PIN); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_GPIO_PIN); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_GPIO_PIN); +} + +/*! + \brief cofigure the I2C interface + \param[in] none + \param[out] none + \retval none +*/ +void i2c_config(void) +{ + /* I2C clock configure */ + i2c_clock_config(BOARD_I2C, 100000, I2C_DTCY_2); + /* I2C address configure */ + i2c_mode_addr_config(BOARD_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_OWN_ADDRESS7); + /* enable I2C */ + i2c_enable(BOARD_I2C); + /* enable acknowledge */ + i2c_ack_config(BOARD_I2C, I2C_ACK_ENABLE); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_two_bytes/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_two_bytes/readme.txt new file mode 100644 index 0000000..d09483f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_receiver_two_bytes/readme.txt @@ -0,0 +1,27 @@ +/*! + \file readme.txt + \brief description of the master receiver two bytes +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows the I2C +programming mode in master receiving mode which the master only want to receive +two bytes of data. In this demo, BOARD_I2C is operated as master receiver,and the +SCL line and SDA line of BOARD_I2C interface are controled by the I/O pin PB10 and \ +PB11(or PB6 and PB7) respectively. + + This demo shows the receiving two bytes process of the master. And it will store +the received data in the i2c_receiver array. + + This demo doesn't perform the data transfer actually, which is due to no +specific slave.In the specific application, we must send the correct slave +address, and the master and the slave may need to be connected by the jumper +if necessary. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver/main.c new file mode 100644 index 0000000..8bdc14d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver/main.c @@ -0,0 +1,182 @@ +/*! + \file main.c + \brief master transmitter slave receiver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +#define I2C0_SLAVE_ADDRESS7 0x82 +#define I2C1_SLAVE_ADDRESS7 0x72 + +uint8_t i2c_transmitter[16]; +uint8_t i2c_receiver[16]; +ErrStatus state = ERROR; + +void rcu_config(void); +void gpio_config(void); +void i2c_config(void); +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i; + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + rcu_config(); + gpio_config(); + i2c_config(); + + for(i=0;i<16;i++){ + i2c_transmitter[i]=i+0x80; + } + + /* wait until I2C bus is idle */ + while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)); + + /* send a start condition to I2C bus */ + i2c_start_on_bus(I2C0); + + /* wait until SBSEND bit is set */ + while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)); + + /* send slave address to I2C bus*/ + i2c_master_addressing(I2C0, I2C1_SLAVE_ADDRESS7, I2C_TRANSMITTER); + + /* wait until ADDSEND bit is set*/ + while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)); + while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND)); + /* clear ADDSEND bit */ + i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); + i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND); + for(i=0;i<16;i++){ + /* send a data byte */ + i2c_data_transmit(I2C0,i2c_transmitter[i]); + /* wait until the transmission data register is empty*/ + while(!i2c_flag_get(I2C0, I2C_FLAG_TBE)); + /* wait until the RBNE bit is set */ + while(!i2c_flag_get(I2C1, I2C_FLAG_RBNE)); + /* read a data from I2C_DATA */ + i2c_receiver[i] = i2c_data_receive(I2C1); + } + /* send a stop condition to I2C bus*/ + i2c_stop_on_bus(I2C0); + while(I2C_CTL0(I2C0)&0x0200); + while(!i2c_flag_get(I2C1, I2C_FLAG_STPDET)); + /* clear the STPDET bit */ + i2c_enable(I2C0); + state = memory_compare(i2c_transmitter, i2c_receiver,16); + if(SUCCESS == state){ + gd_eval_led_on(LED1); + gd_eval_led_on(LED2); + }else{ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + } + while(1); +} + +/*! + \brief memory compare function + \param[in] src : source data + \param[in] dst : destination data + \param[in] length : the compare data length + \param[out] none + \retval ErrStatus : ERROR or SUCCESS +*/ +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length) +{ + while(length--){ + if(*src++ != *dst++){ + return ERROR; + } + } + return SUCCESS; +} + +/*! + \brief enable the peripheral clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + /* enable I2C1 clock */ + rcu_periph_clock_enable(RCU_I2C1); + /* enable I2C0 clock */ + rcu_periph_clock_enable(RCU_I2C0); +} + +/*! + \brief cofigure the GPIO ports. + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* I2C0 and I2C1 GPIO ports */ + /* connect PB6 to I2C0_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_6); + /* connect PB7 to I2C0_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_7); + /* connect PB10 to I2C1_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_10); + /* connect PB11 to I2C1_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_11); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_6); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_7); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_10); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_10); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_11); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_11); +} + +/*! + \brief cofigure the I2C0 and I2C1 interfaces + \param[in] none + \param[out] none + \retval none +*/ +void i2c_config(void) +{ + /* configure I2C0 clock */ + i2c_clock_config(I2C0, 100000, I2C_DTCY_2); + /* configure I2C0 address */ + i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C0_SLAVE_ADDRESS7); + /* enable I2C0 */ + i2c_enable(I2C0); + /* enable acknowledge */ + i2c_ack_config(I2C0, I2C_ACK_ENABLE); + /* configure I2C1 clock */ + i2c_clock_config(I2C1, 100000, I2C_DTCY_2); + /* configure I2C1 address */ + i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_SLAVE_ADDRESS7); + /* enable I2C1 */ + i2c_enable(I2C1); + /* enable acknowledge */ + i2c_ack_config(I2C1, I2C_ACK_ENABLE); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver/readme.txt new file mode 100644 index 0000000..65ec710 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver/readme.txt @@ -0,0 +1,25 @@ +/*! + \file readme.txt + \brief description of the master transmitter and slave receiver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/ GD32190R-EVAL board, it shows the I2C programming +mode in master transmitter mode and slave receiving mode. In this demo,I2C0 is operated as +master transmitter ,I2C1 is operated as slave receiver and the SCL line and SDA line of I2C +interface are controled by the I/O pin PB10 and PB11(or PB6 and PB7) respectively. + + This demo shows the sending data process of the master and the receiving data process of the slave. +If transfer is sucessfully completed, LED1 and LED2 is light. + + We shoud use the jumper to connect the PB6 and PB10. The PB7 and PB11 are connected as well. + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/I2C0_IE.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/I2C0_IE.c new file mode 100644 index 0000000..39d6a7d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/I2C0_IE.c @@ -0,0 +1,93 @@ +/*! + \file I2C0_IE.c + \brief I2C0 master transmitter interrupt program +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_i2c.h" +#include "I2C_IE.h" + +uint32_t event1; + +/*! + \brief handle I2C0 event interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void I2C0_EventIRQ_Handler(void) +{ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SBSEND)){ + /* send slave address */ + i2c_master_addressing(I2C0, I2C1_SLAVE_ADDRESS7, I2C_TRANSMITTER); + }else if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND)){ + /*clear ADDSEND bit */ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND); + }else if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)){ + if(I2C_nBytes>0){ + /* the master sends a data byte */ + i2c_data_transmit(I2C0, *i2c_txbuffer++); + I2C_nBytes--; + }else{ + /* the master sends a stop condition to I2C bus */ + i2c_stop_on_bus(I2C0); + /* disable the I2C0 interrupt */ + i2c_interrupt_disable(I2C0, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + } + } +} + +/*! + \brief handle I2C0 error interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void I2C0_ErrorIRQ_Handler(void) +{ + /* no acknowledge received */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR); + } + + /* SMBus alert */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBALT)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBALT); + } + + /* bus timeout in SMBus mode */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBTO)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBTO); + } + + /* over-run or under-run when SCL stretch is disabled */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_OUERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR); + } + + /* arbitration lost */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_LOSTARB)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_LOSTARB); + } + + /* bus error */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_BERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_BERR); + } + + /* CRC value doesn't match */ + if(i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_PECERR)){ + i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_PECERR); + } + /* disable the error interrupt */ + i2c_interrupt_disable(I2C0,I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/I2C1_IE.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/I2C1_IE.c new file mode 100644 index 0000000..6c3799a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/I2C1_IE.c @@ -0,0 +1,88 @@ +/*! + \file I2C1_IE.c + \brief I2C1 slave receiver interrupt program +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_i2c.h" +#include "I2C_IE.h" + +uint32_t event2; + +/*! + \brief handle I2C1 event interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_EventIRQ_Handler(void) +{ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_ADDSEND)){ + /* clear the ADDSEND bit */ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_ADDSEND); + }else if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_RBNE)){ + /* if reception data register is not empty ,I2C1 will read a data from I2C_DATA */ + *i2c_rxbuffer++ = i2c_data_receive(I2C1); + }else if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_STPDET)){ + status = SUCCESS; + /* clear the STPDET bit */ + i2c_enable(I2C1); + /* disable I2C1 interrupt */ + i2c_interrupt_disable(I2C0, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + } +} + +/*! + \brief handle I2C1 error interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_ErrorIRQ_Handler(void) +{ + /* no acknowledge received */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_AERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_AERR); + } + + /* SMBus alert */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBALT)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBALT); + } + + /* bus timeout in SMBus mode */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBTO)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBTO); + } + + /* over-run or under-run when SCL stretch is disabled */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_OUERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_OUERR); + } + + /* arbitration lost */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_LOSTARB)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_LOSTARB); + } + + /* bus error */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_BERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_BERR); + } + + /* CRC value doesn't match */ + if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_PECERR)){ + i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_PECERR); + } + /* disable the error interrupt */ + i2c_interrupt_disable(I2C0,I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/I2C_IE.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/I2C_IE.h new file mode 100644 index 0000000..e764bd5 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/I2C_IE.h @@ -0,0 +1,39 @@ +/*! + \file I2C_IE.h + \brief The header file of I2C0 and I2C1 interrupt +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef I2C_IE_H +#define I2C_IE_H + +#include "gd32f1x0.h" + +#define I2C0_SLAVE_ADDRESS7 0x82 +#define I2C1_SLAVE_ADDRESS7 0x72 + +extern volatile ErrStatus status; +extern volatile uint8_t* i2c_txbuffer; +extern volatile uint8_t* i2c_rxbuffer; +extern volatile uint16_t I2C_nBytes; + +/* function declarations */ +/* handle I2C0 event interrupt request */ +void I2C0_EventIRQ_Handler(void); +/* handle I2C0 error interrupt request */ +void I2C0_ErrorIRQ_Handler(void); +/* handle I2C1 event interrupt request */ +void I2C1_EventIRQ_Handler(void); +/* handle I2C1 error interrupt request */ +void I2C1_ErrorIRQ_Handler(void); + +#endif /* I2C_IE_H */ + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/gd32f1x0_it.c new file mode 100644 index 0000000..ba2fc7e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/gd32f1x0_it.c @@ -0,0 +1,149 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "I2C_IE.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles I2C0 event interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C0_EV_IRQHandler(void) +{ + I2C0_EventIRQ_Handler(); +} + +/*! + \brief this function handles I2C0 error interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C0_ER_IRQHandler(void) +{ + I2C0_ErrorIRQ_Handler(); +} + +/*! + \brief this function handles I2C1 event interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_EV_IRQHandler(void) +{ + I2C1_EventIRQ_Handler(); +} + +/*! + \brief this function handles I2C1 error interrupt request exception + \param[in] none + \param[out] none + \retval none +*/ +void I2C1_ER_IRQHandler(void) +{ + I2C1_ErrorIRQ_Handler(); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/gd32f1x0_it.h new file mode 100644 index 0000000..5f37155 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/gd32f1x0_it.h @@ -0,0 +1,50 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* I2C0 event handle function */ +void I2C0_EV_IRQHandler(void); +/* I2C0 error handle function */ +void I2C0_ER_IRQHandler(void); +/* I2C1 event handle function */ +void I2C1_EV_IRQHandler(void); +/* I2C1 error handle function */ +void I2C1_ER_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/main.c new file mode 100644 index 0000000..f3dce01 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/main.c @@ -0,0 +1,192 @@ +/*! + \file main.c + \brief master transmitter slave receiver interrupt +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "I2C_IE.h" +#include "gd32f1x0_eval.h" + +uint8_t i2c_buffer_transmitter[16]; +uint8_t i2c_buffer_receiver[16]; + +volatile uint8_t* i2c_txbuffer; +volatile uint8_t* i2c_rxbuffer; +volatile uint16_t I2C_nBytes; +volatile ErrStatus status; +ErrStatus state = ERROR; + +void rcu_config(void); +void gpio_config(void); +void i2c_config(void); +void i2c_nvic_config(void); +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i; + + /* initialize LED1, LED2, as the transfer instruction */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + rcu_config(); + gpio_config(); + i2c_config(); + i2c_nvic_config(); + + for(i=0; i<16; i++){ + i2c_buffer_transmitter[i] = i + 0x80; + } + /* initialize i2c_txbuffer, i2c_rxbuffer, I2C_nBytes and status */ + i2c_txbuffer = i2c_buffer_transmitter; + i2c_rxbuffer = i2c_buffer_receiver; + I2C_nBytes = 16; + status = ERROR; + + /* enable the I2C0 interrupt */ + i2c_interrupt_enable(I2C0, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + + /* enable the I2C1 interrupt */ + i2c_interrupt_enable(I2C1, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); + + /* the master waits until the I2C bus is idle */ + while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)); + + /* the master sends a start condition to I2C bus */ + i2c_start_on_bus(I2C0); + + while((I2C_nBytes>0)); + while(SUCCESS != status); + /* if the transfer is successfully completed, LED1 and LED2 is on */ + state = memory_compare(i2c_buffer_transmitter, i2c_buffer_receiver, 16); + if(SUCCESS == state){ + /* if success, LED1 and LED2 are on */ + gd_eval_led_on(LED1); + gd_eval_led_on(LED2); + }else{ + /* if failed, LED1 and LED2 are off */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + } + while(1){ + } +} + +/*! + \brief memory compare function + \param[in] src : source data + \param[in] dst : destination data + \param[in] length : the compare data length + \param[out] none + \retval ErrStatus : ERROR or SUCCESS +*/ +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length) +{ + while(length--){ + if(*src++ != *dst++){ + return ERROR; + } + } + return SUCCESS; +} + +/*! + \brief enable the peripheral clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + /* enable I2C1 clock */ + rcu_periph_clock_enable(RCU_I2C1); + /* enable I2C0 clock */ + rcu_periph_clock_enable(RCU_I2C0); +} + +/*! + \brief cofigure the GPIO ports. + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* I2C0 and I2C1 GPIO ports */ + /* connect PB6 to I2C0_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_6); + /* connect PB7 to I2C0_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_7); + /* connect PB10 to I2C1_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_10); + /* connect PB11 to I2C1_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_11); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_6); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_7); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_10); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_10); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_11); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_11); +} + +/*! + \brief cofigure the I2C0 and I2C1 interfaces.. + \param[in] none + \param[out] none + \retval none +*/ +void i2c_config(void) +{ + /* I2C clock configure */ + i2c_clock_config(I2C0, 100000, I2C_DTCY_2); + /* I2C address configure */ + i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C0_SLAVE_ADDRESS7); + /* enable I2C0 */ + i2c_enable(I2C0); + /* enable acknowledge */ + i2c_ack_config(I2C0, I2C_ACK_ENABLE); + i2c_clock_config(I2C1, 100000, I2C_DTCY_2); + /* I2C address configure */ + i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_SLAVE_ADDRESS7); + /* enable I2C1 */ + i2c_enable(I2C1); + /* enable acknowledge */ + i2c_ack_config(I2C1, I2C_ACK_ENABLE); +} + +/*! + \brief cofigure the NVIC peripheral + \param[in] none + \param[out] none + \retval none +*/ +void i2c_nvic_config(void) +{ + nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); + nvic_irq_enable(I2C0_EV_IRQn, 0, 3); + nvic_irq_enable(I2C1_EV_IRQn, 0, 4); + nvic_irq_enable(I2C0_ER_IRQn, 0, 2); + nvic_irq_enable(I2C1_ER_IRQn, 0, 1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/readme.txt new file mode 100644 index 0000000..3cffb55 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter&slave_receiver_interrupt/readme.txt @@ -0,0 +1,26 @@ +/*! + \file readme.txt + \brief description of the master transmitter and slave receiver interrupt +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/ GD32190R-EVAL board, it shows how to use the +I2C interrupt programming mode in master transmitting mode or slave receivering mode. +In this demo, I2C0 is operated as the master transmitter and I2C1 as the slave receiver. +Moreover, the SCL line and SDA lineof I2C0 interfaceare controled by the I/O pin PB6 and +PB7 respectively. The SCL and SDA of I2C1 are controled by the pin PB10 and PB11 respectively. + + This demo will send the data of i2c_buffer_transmitter array through I2C0 interface +to the I2C1, and it will store the data received by I2C1 in the i2c_buffer_receiver +array. If transfer is sucessfully completed, LED1 and LED2 are on. + + We shoud use the jumper to connect the PB6 and PB10. The PB7 and PB11 are +connected as well. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter/main.c new file mode 100644 index 0000000..35d70e4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter/main.c @@ -0,0 +1,139 @@ +/*! + \file main.c + \brief master transmitter +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" + +#ifdef GD32F130_150 +#define BOARD_I2C I2C0 +#define I2C_SCL_GPIO_PIN GPIO_PIN_6 +#define I2C_SDA_GPIO_PIN GPIO_PIN_7 +#define I2C_RCC RCU_I2C0 +#elif defined GD32F170_190 +#define BOARD_I2C I2C1 +#define I2C_SCL_GPIO_PIN GPIO_PIN_10 +#define I2C_SDA_GPIO_PIN GPIO_PIN_11 +#define I2C_RCC RCU_I2C1 +#endif + +#define I2C_OWN_ADDRESS7 0x72 +#define I2C_SLAVE_ADDRESS7 0x82 + +uint8_t i2c_transmitter[16]; + +void rcu_config(void); +void gpio_config(void); +void i2c_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i; + + /* RCU config */ + rcu_config(); + /* GPIO config */ + gpio_config(); + /* I2C config */ + i2c_config(); + + for(i=0; i<16; i++){ + i2c_transmitter[i]=i+0x80; + } + + /* wait until I2C bus is idle */ + while(i2c_flag_get(BOARD_I2C, I2C_FLAG_I2CBSY)); + /* send a start condition to I2C bus */ + i2c_start_on_bus(BOARD_I2C); + /* wait until SBSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_SBSEND)); + /* send slave address to I2C bus */ + i2c_master_addressing(BOARD_I2C, I2C_SLAVE_ADDRESS7, I2C_TRANSMITTER); + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_ADDSEND)); + /* clear ADDSEND bit */ + i2c_flag_clear(BOARD_I2C, I2C_STAT0_ADDSEND); + /* wait until the transmit data buffer is empty */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_TBE)); + + for(i=0; i<16; i++){ + /* data transmission */ + i2c_data_transmit(BOARD_I2C, i2c_transmitter[i]); + /* wait until the TBE bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_TBE)); + } + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(BOARD_I2C); + while(I2C_CTL0(BOARD_I2C)&0x0200); + + /* infinite loop */ + while(1){ + } +} + +/*! + \brief enable the peripheral clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + /* enable I2C clock */ + rcu_periph_clock_enable(I2C_RCC); +} + +/*! + \brief cofigure the GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* I2C GPIO ports */ + /* connect I2C_SCL_GPIO_PIN to I2C_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SCL_GPIO_PIN); + /* connect I2C_SDA_GPIO_PIN to I2C_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SDA_GPIO_PIN); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_GPIO_PIN); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_GPIO_PIN); +} + +/*! + \brief cofigure the I2C interface + \param[in] none + \param[out] none + \retval none +*/ +void i2c_config(void) +{ + /* I2C clock configure */ + i2c_clock_config(BOARD_I2C, 100000, I2C_DTCY_2); + /* I2C address configure */ + i2c_mode_addr_config(BOARD_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_SLAVE_ADDRESS7); + /* enable I2C */ + i2c_enable(BOARD_I2C); + /* enable acknowledge */ + i2c_ack_config(BOARD_I2C, I2C_ACK_ENABLE); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter/readme.txt new file mode 100644 index 0000000..b00d914 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Master_transmitter/readme.txt @@ -0,0 +1,26 @@ +/*! + \file readme.txt + \brief description of the master transmitter +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/ GD32190R-EVAL board, it shows the I2C +programming mode in master transmitting mode.In this demo, BOARD_I2C is operated as the +master transmitter, and the SCL line and SDA line of BOARD_I2C interface are controled +by the I/O pin PB10 and PB11(or PB6 and PB7) respectively. + + This demo shows the sending process of the master. And it will send the data +in the i2c_transmitter array through BOARD_I2C. + + The demo doesn't perform the data transfer actually, which is due to no specific +slave. In the specific application, we must send the correct slave address, and the +master and the slave may need to be connected by the jumper if necessary. + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_receiver/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_receiver/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_receiver/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_receiver/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_receiver/main.c new file mode 100644 index 0000000..68288e4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_receiver/main.c @@ -0,0 +1,125 @@ +/*! + \file main.c + \brief slave receiver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" + +#ifdef GD32F130_150 +#define BOARD_I2C I2C0 +#define I2C_SCL_GPIO_PIN GPIO_PIN_6 +#define I2C_SDA_GPIO_PIN GPIO_PIN_7 +#define I2C_RCC RCU_I2C0 +#elif defined GD32F170_190 +#define BOARD_I2C I2C1 +#define I2C_SCL_GPIO_PIN GPIO_PIN_10 +#define I2C_SDA_GPIO_PIN GPIO_PIN_11 +#define I2C_RCC RCU_I2C1 +#endif + +#define I2C_OWN_ADDRESS7 0x82 + +uint8_t i2c_receiver[16]; + +void rcu_config(void); +void gpio_config(void); +void i2c_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i; + + /* RCU config */ + rcu_config(); + /* GPIO config */ + gpio_config(); + /* I2C config */ + i2c_config(); + + i=0; + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_ADDSEND)); + /* clear ADDSEND bit */ + i2c_flag_clear(BOARD_I2C, I2C_FLAG_ADDSEND); + for(i=0; i<16; i++){ + /* wait until the RBNE bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_RBNE)); + + /* read a data byte from I2C_DATA */ + i2c_receiver[i] = i2c_data_receive(BOARD_I2C); + } + /* wait until the STPDET bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_STPDET)); + /* clear the STPDET bit */ + i2c_enable(BOARD_I2C); + + while(1){ + } +} + +/*! + \brief enable the peripheral clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + /* enable I2C clock */ + rcu_periph_clock_enable(I2C_RCC); +} + +/*! + \brief cofigure the GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* I2C GPIO ports */ + /* connect I2C_SCL_GPIO_PIN to I2C_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SCL_GPIO_PIN); + /* connect I2C_SDA_GPIO_PIN to I2C_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SDA_GPIO_PIN); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_GPIO_PIN); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_GPIO_PIN); +} + +/*! + \brief cofigure the I2C interface + \param[in] none + \param[out] none + \retval none +*/ +void i2c_config(void) +{ + /* I2C clock configure */ + i2c_clock_config(BOARD_I2C, 100000, I2C_DTCY_2); + /* I2C address configure */ + i2c_mode_addr_config(BOARD_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_OWN_ADDRESS7); + /* enable I2C */ + i2c_enable(BOARD_I2C); + /* enable acknowledge */ + i2c_ack_config(BOARD_I2C, I2C_ACK_ENABLE); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_receiver/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_receiver/readme.txt new file mode 100644 index 0000000..45a3a0e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_receiver/readme.txt @@ -0,0 +1,26 @@ +/*! + \file readme.txt + \brief description of the slave receiver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/ GD32190R-EVAL board, it shows the I2C +programming mode in slave receiving mode. In this demo, BOARD_I2C is operated as slave +receiver, and the SCL line and SDA line of BOARD_I2C interface are controled by the I/O +pin PB10 and PB11(or PB6 and PB7) respectively. + + This demo shows the receving process of the slave. And it will store the +received data in the i2c_receiver array. + + The demo doesn't perform the data transfer actually, which is due to no specific +master.In the specific application, we need config the master to start a data +transmission.In addition,the master and the slave may need to be connected by +the jumper if necessary. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_transmitter/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_transmitter/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_transmitter/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_transmitter/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_transmitter/main.c new file mode 100644 index 0000000..3f89b53 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_transmitter/main.c @@ -0,0 +1,149 @@ +/*! + \file main.c + \brief slave transmitter +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" + +#ifdef GD32F130_150 +#define BOARD_I2C I2C0 +#define I2C_SCL_GPIO_PIN GPIO_PIN_6 +#define I2C_SDA_GPIO_PIN GPIO_PIN_7 +#define I2C_RCC RCU_I2C0 +#elif defined GD32F170_190 +#define BOARD_I2C I2C1 +#define I2C_SCL_GPIO_PIN GPIO_PIN_10 +#define I2C_SDA_GPIO_PIN GPIO_PIN_11 +#define I2C_RCC RCU_I2C1 +#endif + +#define I2C_10BIT_ADDRESS 0 + +#define I2C_OWN_ADDRESS7 0x82 +#define I2C_SLAVE_ADDRESS7 0x72 +#define I2C_OWN_ADDRESS10 0x0322 + +uint8_t i2c_transmitter[16]; + +void rcu_config(void); +void gpio_config(void); +void i2c_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i; + + /* RCU config */ + rcu_config(); + /* GPIO config */ + gpio_config(); + /* I2C config */ + i2c_config(); + + for(i=0; i<16; i++){ + i2c_transmitter[i] = i+0x80; + } + +#if I2C_10BIT_ADDRESS + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_ADDSEND)); + /* clear ADDSEND bit */ + i2c_flag_clear(BOARD_I2C, I2C_FLAG_ADDSEND); + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_ADDSEND)); + /* clear ADDSEND bit */ + i2c_flag_clear(BOARD_I2C, I2C_STAT0_ADDSEND); +#else + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_ADDSEND)); + /* clear ADDSEND bit */ + i2c_flag_clear(BOARD_I2C, I2C_FLAG_ADDSEND); +#endif + /* wait until the transmission data register is empty */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_TBE)); + + for(i=0;i<16;i++){ + /* send a data byte */ + i2c_data_transmit(BOARD_I2C, i2c_transmitter[i]); + /* wait until the transmission data register is empty */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_TBE)); + } + /* the master doesn't acknowledge for the last byte */ + while(!i2c_flag_get(BOARD_I2C, I2C_FLAG_AERR)); + /* clear the bit of AERR */ + i2c_flag_clear(BOARD_I2C, I2C_FLAG_AERR); + + while(1){ + } +} + +/*! + \brief enable the peripheral clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + /* enable I2C clock */ + rcu_periph_clock_enable(I2C_RCC); +} + +/*! + \brief cofigure the GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* I2C GPIO ports */ + /* connect I2C_SCL_GPIO_PIN to I2C_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SCL_GPIO_PIN); + /* connect I2C_SDA_GPIO_PIN to I2C_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, I2C_SDA_GPIO_PIN); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_GPIO_PIN); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_GPIO_PIN); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_GPIO_PIN); +} + +/*! + \brief cofigure the I2C interface + \param[in] none + \param[out] none + \retval none +*/ +void i2c_config(void) +{ + /* I2C clock configure */ + i2c_clock_config(BOARD_I2C, 400000, I2C_DTCY_2); + /* I2C address configure */ +#if I2C_10BIT_ADDRESS + i2c_mode_addr_config(BOARD_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_10BITS, I2C_OWN_ADDRESS10); +#else + i2c_mode_addr_config(BOARD_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_OWN_ADDRESS7); +#endif + /* enable I2C */ + i2c_enable(BOARD_I2C); + /* enable acknowledge */ + i2c_ack_config(BOARD_I2C, I2C_ACK_ENABLE); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_transmitter/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_transmitter/readme.txt new file mode 100644 index 0000000..ccdecd5 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/I2C/Slave_transmitter/readme.txt @@ -0,0 +1,27 @@ +/*! + \file readme.txt + \brief description of the slave transmitter +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/ GD32190R-EVAL board, it shows the +I2C programming mode in slave transmitting mode.In this demo,BOARD_I2C is operated +as slave transmitter,and the SCL line and SDA line of I2C0 interface are controled +by the I/O pin PB10 and PB11(or PB6 and PB7) respectively. + + This demo shows the sending data process of the slave. And it will send the +data in the i2c_transmitter array through the BOARD_I2C. + + The demo doesn't perform the data transfer actually, which is due to no specific +master.In the specific application, we need config the master to start a data +transmission.In addition,the master and the slave may need to be connected by +the jumper if necessary.When the macro I2C_10BIT_ADDRESS is 1, I2C communicate in +10 bit addressing mode, otherwise, I2C communicate in 7 bit addressing mode. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/gd32f1x0_it.c new file mode 100644 index 0000000..26e6373 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/gd32f1x0_it.c @@ -0,0 +1,191 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "rc5_encode.h" +#include "rc5_decode.h" +#include "ir_decode.h" +#include "systick.h" + +uint32_t icvalue1 = 0; +uint32_t icvalue2 = 0; + +extern uint32_t rc5_frame_manchester_format; +extern __IO trc5_packet_struct rc5_tmp_packet; + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement( ); +} + +/*! + \brief this function handles TIMER15 update interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void TIMER15_IRQHandler(void) +{ + rc5_encode_signal_generate(rc5_frame_manchester_format); + + /* clear TIMER15 update interrupt */ + timer_interrupt_flag_clear(TIMER15, TIMER_INT_FLAG_UP); +} + +/*! + \brief this function handles TIMER2 overflow and update interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void TIMER2_IRQHandler(void) +{ +#if defined(GD32F130_150) + /* ic2 interrupt*/ + if((RESET != timer_interrupt_flag_get(IR_TIMER, TIMER_INT_FLAG_CH1))){ + /* clear IR_TIMER CH1 interrupt */ + timer_interrupt_flag_clear(IR_TIMER, TIMER_INT_FLAG_CH1); + /* get the input capture value */ + icvalue2 = TIMER_CH1CV(IR_TIMER); + /* rc5 */ + rc5_data_sampling(icvalue2, 1); + } + + /* ic1 interrupt */ + if((RESET != timer_interrupt_flag_get(IR_TIMER, TIMER_INT_FLAG_CH0))){ + /* clear IR_TIMER CH0 interrupt */ + timer_interrupt_flag_clear(IR_TIMER, TIMER_INT_FLAG_CH0); + /* get the input capture value */ + icvalue1 = TIMER_CH0CV(IR_TIMER) - TIMER_CH1CV(IR_TIMER); + /* rc5 */ + rc5_data_sampling(icvalue1, 0); + } + +#elif defined(GD32F170_190) + /* ic1 interrupt*/ + if((RESET != timer_interrupt_flag_get(IR_TIMER, TIMER_INT_FLAG_CH0 ))){ + /* clear IR_TIMER CH0 interrupt */ + timer_interrupt_flag_clear(IR_TIMER, TIMER_INT_FLAG_CH0); + /* get the input capture value */ + icvalue1 = TIMER_CH0CV(IR_TIMER); + /* rc5 */ + rc5_data_sampling(icvalue1, 1); + } + + /* ic2 interrupt */ + if((RESET != timer_interrupt_flag_get(IR_TIMER, TIMER_INT_FLAG_CH1))){ + /* clear IR_TIMER CH1 interrupt */ + timer_interrupt_flag_clear(IR_TIMER, TIMER_INT_FLAG_CH1); + /* get the input capture value */ + icvalue2 = TIMER_CH1CV(IR_TIMER) - TIMER_CH0CV(IR_TIMER); + /* rc5 */ + rc5_data_sampling(icvalue2, 0); + } + +#endif +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/gd32f1x0_it.h new file mode 100644 index 0000000..8c40ee8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/gd32f1x0_it.h @@ -0,0 +1,44 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* TIMER15 handle function */ +void TIMER15_IRQHandler(void); +/* TIMER2 handle function */ +void TIMER2_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/ir_decode.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/ir_decode.h new file mode 100644 index 0000000..f123071 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/ir_decode.h @@ -0,0 +1,47 @@ +/*! + \file ir_decode.h + \brief the header file of infrared decoding +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef IR_DECODE_H +#define IR_DECODE_H + +#include "gd32f1x0.h" + +typedef enum {NO = 0, YES = !NO} status_yes_or_no; + +#if defined(GD32F130_150) + #define IR_TIMER TIMER2 /*!< timer used for IR decoding */ + #define TIMER_PRESCALER 71 /*!< TIMER prescaler */ + #define IR_TIMER_CLK RCU_TIMER2 /*!< clock of the used timer */ + #define IR_TIMER_IRQn TIMER2_IRQn /*!< IR TIMER IRQ */ + #define IR_TIMER_Channel TIMER_CH_0 /*!< IR TIMER channel */ + + #define IR_GPIO_PORT GPIOC /*!< port which IR output is connected */ + #define IR_GPIO_PORT_CLK RCU_GPIOC /*!< IR pin GPIO clock port */ + #define IR_GPIO_PIN GPIO_PIN_6 /*!< pin which IR is connected */ + #define IR_GPIO_SOURCE GPIO_PINSOURCE6 + +#elif defined(GD32F170_190) + #define IR_TIMER TIMER2 /*!< timer used for IR decoding */ + #define TIMER_PRESCALER 71 /*!< TIMER prescaler */ + #define IR_TIMER_CLK RCU_TIMER2 /*!< clock of the used timer */ + #define IR_TIMER_IRQn TIMER2_IRQn /*!< IR TIMER IRQ */ + #define IR_TIMER_Channel TIMER_CH_1 /*!< IR TIMER channel */ + + #define IR_GPIO_PORT GPIOA /*!< port which IR output is connected */ + #define IR_GPIO_PORT_CLK RCU_GPIOA /*!< IR pin GPIO clock port */ + #define IR_GPIO_PIN GPIO_PIN_7 /*!< pin which IR is connected */ + #define IR_GPIO_SOURCE GPIO_PINSOURCE7 +#endif + +#endif /* IR_DECODE_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/main.c new file mode 100644 index 0000000..a221652 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/main.c @@ -0,0 +1,175 @@ +/*! + \file main.c + \brief IFRR infrared transmit receive demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "rc5_decode.h" +#include "rc5_encode.h" +#include "ir_decode.h" +#include "systick.h" +#include "gd32f1x0_eval.h" + +rc5_frame_struct rc5_frame; + +extern uint8_t address_index; +extern uint8_t instruction_index; +extern rc5_ctrl_enum rc5_ctrl1; + +/* rc5 frame state */ +extern __IO status_yes_or_no rc5_frame_received; +extern __IO uint8_t send_operation_completed; + +void test_status_led_init(void); +void flash_led(int times); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* init test status LED */ + test_status_led_init(); + + /* flash LED for test */ + flash_led(1); + + /* enable the GPIO clock */ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_GPIOF); + + /* initialize the infrared application: rc5 encode*/ + rc5_encode_init(); + + /* initialize the infrared application: rc5 decode*/ + rc5_decode_init(); + + delay_1ms(200); + + /* test */ + { + address_index = 0x06; + instruction_index = 15; + + /*send IR frame (address, command)*/ + rc5_encode_send_frame(address_index, instruction_index, rc5_ctrl1); + + /* if data do not send compelet */ + while(0x00 == send_operation_completed); + + /* if data do not received */ + while(0x00 == rc5_frame_received); + + /* decode the rc5 frame */ + rc5_decode(&rc5_frame); + } + + /* transferstatus ? passed : failed */ + while(1){ + if(15 == rc5_frame.command){ + /* turn on LED1 */ + gd_eval_led_on(LED1); + /* insert 200 ms delay */ + delay_1ms(200); + + /* turn on LED2 */ + gd_eval_led_on(LED2); + /* insert 200 ms delay */ + delay_1ms(200); + + /* turn on LED3 */ + gd_eval_led_on(LED3); + /* insert 200 ms delay */ + delay_1ms(200); + + /* turn on LED4 */ + gd_eval_led_on(LED4); + /* insert 200 ms delay */ + delay_1ms(200); + + /* turn off LEDs */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + gd_eval_led_off(LED3); + gd_eval_led_off(LED4); + + /* insert 200 ms delay */ + delay_1ms(200); + }else{ + /* flash LED for status error */ + flash_led(1); + } + } +} + +/*! + \brief test status led init + \param[in] none + \param[out] none + \retval none +*/ +void test_status_led_init(void) +{ + /* initialize the leds */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_init(LED3); + gd_eval_led_init(LED4); + + /* close all of leds */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + gd_eval_led_off(LED3); + gd_eval_led_off(LED4); + + /* setup SysTick timer for 1 msec interrupts */ + if(SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while(1); + } +} + +/*! + \brief test status leds + \param[in] times: leds blink times + \param[out] none + \retval none +*/ +void flash_led(int times) +{ + int i; + + for(i = 0; i < times; i++){ + /* insert 200 ms delay */ + delay_1ms(200); + + /* turn on leds */ + gd_eval_led_on(LED1); + gd_eval_led_on(LED2); + gd_eval_led_on(LED3); + gd_eval_led_on(LED4); + + /* insert 200 ms delay */ + delay_1ms(200); + + /* turn off LEDs */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + gd_eval_led_off(LED3); + gd_eval_led_off(LED4); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/rc5_decode.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/rc5_decode.c new file mode 100644 index 0000000..b631bfe --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/rc5_decode.c @@ -0,0 +1,359 @@ +/*! + \file rc5_decode.c + \brief the rc5 infrared decoding file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "rc5_decode.h" +#include "ir_decode.h" + +/* logic table for rising edge: every line has values corresponding to previous bit. + in columns are actual bit values for given bit time. */ +const trc5_last_bit_type rc5_logic_table_rising_edge[2][2] = +{ + /* last_bit = ZERO */ + {RC5_ZER ,RC5_INV}, + /* last_bit = ONE */ + {RC5_NAN ,RC5_ZER}, +}; + +/* logic table for falling edge: every line has values corresponding to previous bit. + in columns are actual bit values for given bit time. */ +const trc5_last_bit_type rc5_logic_table_falling_edge[2][2] = +{ + /* last_bit = ZERO */ + {RC5_NAN ,RC5_ONE}, + /* last_bit = ONE */ + {RC5_ONE ,RC5_INV}, +}; + +/* rc5 frame state */ +__IO status_yes_or_no rc5_frame_received = NO; + +/* first empty packet */ +__IO trc5_packet_struct rc5_tmp_packet; + +/* rc5 bits time definitions */ +uint16_t rc5_mint = 0; +uint16_t rc5_maxt = 0; +uint16_t rc5_min2t = 0; +uint16_t rc5_max2t = 0; +uint32_t rc5_data = 0; + +/* timer clock */ +static uint32_t timer_clk_value_khz = 0; + +static uint8_t rc5_get_pulse_length (uint16_t pulse_length); +static void rc5_modify_last_bit(trc5_last_bit_type bit); +static void rc5_write_bit(uint8_t bit_val); +static uint32_t timer_get_counter_clk_value(void); + +/*! + \brief de-initializes the peripherals + \param[in] none + \param[out] none + \retval none +*/ +void rc5_decode_deinit(void) +{ + timer_deinit(IR_TIMER); + gpio_deinit(IR_GPIO_PORT); +} + +/*! + \brief initialize the rc5 decoder module + \param[in] none + \param[out] none + \retval none +*/ +void rc5_decode_init(void) +{ + __IO uint16_t rc5_time_out = 0; + + /* clock configuration for TIMER */ + rcu_periph_clock_enable(IR_TIMER_CLK); + /* enable GPIO clock */ + rcu_periph_clock_enable(IR_GPIO_PORT_CLK); + + /* IR_decode */ + /* GD32150R-EVAL:TIMER2_CH0 PC6 + GD32190R-EVAL:TIMER2_CH1 PA7 + */ + { + /* configure the GPIO ports */ + gpio_mode_set(IR_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, IR_GPIO_PIN); + gpio_output_options_set(IR_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,IR_GPIO_PIN); + +#if defined(GD32F170_190) + gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_7); +#endif + } + + /* enable the TIMER global interrupt */ + nvic_irq_enable(IR_TIMER_IRQn, 0, 1); + + { + timer_ic_parameter_struct timer_icinitpara; + timer_parameter_struct timer_initpara; + + /* deinit IR_TIMER */ + rcu_periph_clock_enable(IR_TIMER_CLK); + + /* TIMER0 configuration */ + timer_deinit(IR_TIMER); + + /* timer base configuration for timer IR_TIMER */ + timer_initpara.prescaler = 0x0; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 0x00; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(IR_TIMER,&timer_initpara); + + /* prescaler configuration */ + timer_prescaler_config(IR_TIMER,TIMER_PRESCALER,TIMER_PSC_RELOAD_NOW); + + /* TIMER2 CH0 input capture configuration */ + timer_icinitpara.icpolarity = TIMER_IC_POLARITY_FALLING; + timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI; + timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1; + timer_icinitpara.icfilter = 0x0; + timer_input_pwm_capture_config(IR_TIMER,IR_TIMER_Channel,&timer_icinitpara); + } + + /* timer clock */ + timer_clk_value_khz = timer_get_counter_clk_value()/1000; + + /* select the TIMER input trigger */ +#if defined(GD32F130_150) + timer_input_trigger_source_select(IR_TIMER, TIMER_SMCFG_TRGSEL_CI0FE0); +#elif defined(GD32F170_190) + timer_input_trigger_source_select(IR_TIMER, TIMER_SMCFG_TRGSEL_CI1FE1); +#endif + + /* select the slave mode: reset mode */ + timer_slave_mode_select(IR_TIMER, TIMER_SLAVE_MODE_RESTART); + + /* configures the TIMER update request interrupt source: counter overflow */ + timer_update_source_config( IR_TIMER, TIMER_UPDATE_SRC_REGULAR ); + + rc5_time_out = timer_clk_value_khz * RC5_TIME_OUT_US/1000; + + /* set the TIMER auto-reload register for each IR protocol */ + TIMER_CAR(IR_TIMER) = rc5_time_out; + + /* clear flag */ + timer_interrupt_flag_clear(IR_TIMER, TIMER_INT_FLAG_UP | TIMER_INT_FLAG_CH0 | TIMER_INT_FLAG_CH1); + + /* enable the CH1 interrupt request */ + timer_interrupt_enable(IR_TIMER, TIMER_INT_CH1); + + /* enable the CH0 interrupt request */ + timer_interrupt_enable(IR_TIMER, TIMER_INT_CH0); + + /* enable the timer */ + timer_enable(IR_TIMER); + + /* bit time range */ + rc5_mint = ( RC5_T_US - RC5_T_TOLERANCE_US ) * timer_clk_value_khz / 1000; + rc5_maxt = ( RC5_T_US + RC5_T_TOLERANCE_US ) * timer_clk_value_khz / 1000; + rc5_min2t = ( 2 * RC5_T_US - RC5_T_TOLERANCE_US ) * timer_clk_value_khz / 1000; + rc5_max2t = ( 2 * RC5_T_US + RC5_T_TOLERANCE_US ) * timer_clk_value_khz / 1000; + + /* default state */ + rc5_reset_packet(); +} + +/*! + \brief decode the IR frame when all the frame is received, the rc5_frame_received will equal to YES + \param[in] rc5_frame: pointer to rc5_frame_struct structure that contains the IR protocol fields + \param[out] none + \retval none +*/ +void rc5_decode(rc5_frame_struct *rc5_frame) +{ + /* if frame received */ + if(rc5_frame_received != NO){ + rc5_data = rc5_tmp_packet.data ; + + /* rc5 frame field decoding */ + rc5_frame->address = (rc5_tmp_packet.data >> 6) & 0x1F; + rc5_frame->command = (rc5_tmp_packet.data) & 0x3F; + rc5_frame->field_bit = (rc5_tmp_packet.data >> 12) & 0x1; + rc5_frame->toggle_bit = (rc5_tmp_packet.data >> 11) & 0x1; + + /* check if command ranges between 64 to 127:upper field */ + if(rc5_frame->field_bit == 0x00){ + rc5_frame->command = (1<<6)| rc5_frame->command; + } + + /* default state */ + rc5_frame_received = NO; + rc5_reset_packet(); + } +} + +/*! + \brief set the incoming packet structure to default state + \param[in] none + \param[out] none + \retval none +*/ +void rc5_reset_packet(void) +{ + rc5_tmp_packet.data = 0; + rc5_tmp_packet.bit_count = RC5_PACKET_BIT_COUNT - 1; + rc5_tmp_packet.last_bit = RC5_ONE; + rc5_tmp_packet.status = RC5_PACKET_STATUS_EMPTY; +} + +/*! + \brief identify the rc5 data bits + \param[in] raw_pulse_length: low/high pulse duration + \param[in] edge: '1' for rising or '0' for falling edge + \param[out] none + \retval none +*/ +void rc5_data_sampling(uint16_t raw_pulse_length, uint8_t edge) +{ + uint8_t pulse; + trc5_last_bit_type tmp_last_bit; + + /* decode the pulse length in protocol units */ + pulse = rc5_get_pulse_length(raw_pulse_length); + + /* on rising edge */ + if(1 == edge){ + if(pulse <= RC5_2T_TIME){ + /* bit determination by the rising edge */ + tmp_last_bit = rc5_logic_table_rising_edge[rc5_tmp_packet.last_bit][pulse]; + rc5_modify_last_bit(tmp_last_bit); + }else{ + rc5_reset_packet(); + } + } + /* on falling edge */ + else { + /* if this is the first falling edge - don't compute anything */ + if(rc5_tmp_packet.status & RC5_PACKET_STATUS_EMPTY){ + rc5_tmp_packet.status &= (uint8_t)~RC5_PACKET_STATUS_EMPTY; + }else{ + if(pulse <= RC5_2T_TIME){ + /* bit determination by the falling edge */ + tmp_last_bit = rc5_logic_table_falling_edge[rc5_tmp_packet.last_bit][pulse]; + rc5_modify_last_bit(tmp_last_bit); + }else{ + rc5_reset_packet(); + } + } + } +} + +/*! + \brief convert raw pulse length expressed in timer ticks to protocol bit times + \param[in] pulse_length: pulse duration + \param[out] none + \retval bit time value +*/ +static uint8_t rc5_get_pulse_length (uint16_t pulse_length) +{ + /* valid bit time */ + if((pulse_length > rc5_mint) && (pulse_length < rc5_maxt)){ + /* found the length,return the correct value */ + return (RC5_1T_TIME); + }else if((pulse_length > rc5_min2t) && (pulse_length < rc5_max2t)){ + /* found the length,return the correct value */ + return (RC5_2T_TIME); + } + /* error */ + return RC5_WRONG_TIME; +} + +/*! + \brief perform checks if the last bit was not incorrect + \param[in] bit: where bit can be RC5_NAN or RC5_INV or RC5_ZER or RC5_ONE + \param[out] none + \retval none +*/ +static void rc5_modify_last_bit(trc5_last_bit_type bit) +{ + if(RC5_NAN != bit){ + if(RC5_INV != rc5_tmp_packet.last_bit){ + /* restore the last bit */ + rc5_tmp_packet.last_bit = bit; + /* insert one bit into the rc5 packet */ + rc5_write_bit(rc5_tmp_packet.last_bit); + }else{ + rc5_reset_packet(); + } + } +} + +/*! + \brief insert one bit into the final data word + \param[in] bit_val: bit value 'RC5_ONE' or 'RC5_ZER' + \param[out] none + \retval none +*/ +static void rc5_write_bit(uint8_t bit_val) +{ + /* first convert rc5 symbols to ones and zeros */ + if(bit_val == RC5_ONE){ + bit_val = 1; + }else if(bit_val == RC5_ZER){ + bit_val = 0; + }else{ + rc5_reset_packet(); + return; + } + + /* write this particular bit to data field */ + rc5_tmp_packet.data |= bit_val; + + /* test the bit number determined */ + /* if this is not the last bit */ + if(0 != rc5_tmp_packet.bit_count){ + /* shift the data field */ + rc5_tmp_packet.data = rc5_tmp_packet.data << 1; + /* decrement the bit_count */ + rc5_tmp_packet.bit_count--; + }else{ + rc5_frame_received = YES; + } +} + +/*! + \brief identify TIMER clock + \param[in] none + \param[out] none + \retval timer clock +*/ +static uint32_t timer_get_counter_clk_value(void) +{ + uint32_t apb_prescaler = 0, apb_frequency = 0; + uint32_t timer_prescaler = 0; + + rcu_clock_freq_get(CK_APB1); + + /* get the clock prescaler of APB1 */ + apb_prescaler = ((RCU_CFG0>> 8) & 0x7); + apb_frequency=rcu_clock_freq_get(CK_APB1); + + timer_prescaler = TIMER_PRESCALER; + + /* if APBx clock div >= 4 */ + if(apb_prescaler >= 4){ + return((apb_frequency * 2)/(timer_prescaler + 1)); + }else{ + return(apb_frequency/(timer_prescaler+ 1)); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/rc5_decode.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/rc5_decode.h new file mode 100644 index 0000000..853a62f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/rc5_decode.h @@ -0,0 +1,74 @@ +/*! + \file rc5_decode.h + \brief the header file of rc5 infrared decoding +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef RC5_DECODE_H +#define RC5_DECODE_H + +#include "gd32f1x0.h" + +/* rc5 frame structure */ +typedef struct +{ + __IO uint8_t field_bit; /*!< field bit */ + __IO uint8_t toggle_bit; /*!< toggle bit field */ + __IO uint8_t address; /*!< address field */ + __IO uint8_t command; /*!< command field */ +} rc5_frame_struct; + +/* rc5 packet structure */ +typedef struct +{ + __IO uint16_t data; /*!< rc5 data */ + __IO uint8_t status; /*!< rc5 status */ + __IO uint8_t last_bit; /*!< rc5 last bit */ + __IO uint8_t bit_count; /*!< rc5 bit count */ +} trc5_packet_struct; + +/* rc5 last bit type enum */ +enum rc5_last_bit_type +{ + RC5_ZER, + RC5_ONE, + RC5_NAN, + RC5_INV +}; + +typedef enum rc5_last_bit_type trc5_last_bit_type; + +#define RC5_1T_TIME 0x00 +#define RC5_2T_TIME 0x01 +#define RC5_WRONG_TIME 0xFF +#define RC5_TIME_OUT_US 3600 + +/* half bit period */ +#define RC5_T_US 900 + +/* tolerance time */ +#define RC5_T_TOLERANCE_US 270 +#define RC5_NUMBER_OF_VALID_PULSE_LENGTH 2 + +/* total bits */ +#define RC5_PACKET_BIT_COUNT 13 + +/* packet struct for reception */ +#define RC5_PACKET_STATUS_EMPTY (uint16_t)(1<<0) + +void menu_rc5decode_func(void); +void rc5_decode_deinit(void); +void rc5_decode_init(void); +void rc5_decode(rc5_frame_struct *rc5_frame); +void rc5_reset_packet(void); +void rc5_data_sampling(uint16_t raw_pulse_length, uint8_t edge); + +#endif /* RC5_DECODE_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/rc5_encode.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/rc5_encode.c new file mode 100644 index 0000000..da48039 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IFRP/Infrared_transmit_receive/rc5_encode.c @@ -0,0 +1,265 @@ +/*! + \file rc5_encode.c + \brief the rc5 infrared encoder file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "rc5_encode.h" +#include "ir_decode.h" + +/* rc5 high level definition*/ +#define RC5_HIGH_STATE ((uint8_t)0x02) +/* rc5 low level definition*/ +#define RC5_LOW_STATE ((uint8_t)0x01) + +rc5_ctrl_enum rc5_ctrl1 = RC5_CTRL_RESET; + +uint8_t rc5_real_frame_length = 14; +uint8_t rc5_global_frame_length = 64; +uint16_t rc5_frame_binary_format = 0; +uint32_t rc5_frame_manchester_format = 0; +uint8_t send_operation_ready = 0; +__IO uint8_t send_operation_completed = 1; +uint8_t bits_sent_counter = 0; + +uint8_t address_index = 0; +uint8_t instruction_index = 0; + +static uint16_t rc5_bin_frame_generation(uint8_t rc5_address, uint8_t rc5_instruction, rc5_ctrl_enum rc5_ctrl); +static uint32_t rc5_manchester_convert(uint16_t rc5_binary_frame_format); + +/*! + \brief init hardware (ips used) for rc5 generation + \param[in] none + \param[out] none + \retval none +*/ +void rc5_encode_init( void ) +{ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + + /* TIMER15 clock enable */ + rcu_periph_clock_enable(RCU_TIMER15); + /* TIMER16 clock enable */ + rcu_periph_clock_enable(RCU_TIMER16); + + { + /* IR_encode */ + /* PB9 IR_OUT pin configuration: output */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); + gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_9); + } + + { + { + /* deinit TIMER16 */ + timer_deinit(TIMER16); + + /* time base = 36Khz */ + /* time base configuration for TIMER16 */ + timer_initpara.prescaler = 0x00; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 1999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER16,&timer_initpara); + + /* prescaler configuration */ + timer_prescaler_config(TIMER16,0,TIMER_PSC_RELOAD_NOW); + + /* output compare timing mode configuration: channel 0N */ + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_LOW; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + timer_channel_output_config(TIMER16,TIMER_CH_0,&timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER16, TIMER_CH_0, (2000/4-1)); + timer_channel_output_mode_config(TIMER16, TIMER_CH_0, TIMER_OC_MODE_PWM1); + timer_channel_output_shadow_config(TIMER16, TIMER_CH_0, TIMER_OC_SHADOW_ENABLE); + + /* TIMER16 enable */ + timer_enable(TIMER16); + /* enable the TIMER16 channel1 output to be connected internly to the IRTIMER */ + timer_primary_output_config(TIMER16, ENABLE); + } + + { + /* deinit TIMER15 */ + timer_deinit(TIMER15); + + /* elementary period 889 us */ + /* time base configuration for TIMER15 */ + timer_initpara.prescaler = 1; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 64008 /2 - 1; + timer_initpara.clockdivision = 0; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER15,&timer_initpara); + + /* duty cycle = 25% */ + /* channel 1 configuration in timing mode */ + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + timer_channel_output_config(TIMER15, TIMER_CH_0, &timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER15, TIMER_CH_0, (64008 /2 /4)); + timer_channel_output_mode_config(TIMER15, TIMER_CH_0, TIMER_OC_MODE_TIMING); + + /* enable the TIMER15 interrupt */ + nvic_priority_group_set(NVIC_PRIGROUP_PRE0_SUB4); + nvic_irq_enable(TIMER15_IRQn, 0, 0); + + /* TIMER15 main output enable */ + timer_primary_output_config(TIMER15, ENABLE); + /* TIMER15 INT disable */ + timer_interrupt_disable(TIMER15, TIMER_INT_UP); + /* TIMER15 disable */ + timer_disable(TIMER15); + } + } +} + +/*! + \brief generate and send the rc5 frame + \param[in] rc5_address: the rc5 device destination + \param[in] rc5_instruction: the rc5 command instruction + \param[in] rc5_ctrl: the rc5 control bit + \param[out] none + \retval none +*/ +void rc5_encode_send_frame(uint8_t rc5_address, uint8_t rc5_instruction, rc5_ctrl_enum rc5_ctrl) +{ + uint16_t rc5_frame_binary_format = 0; + + /* generate a binary format of the frame */ + rc5_frame_binary_format = rc5_bin_frame_generation(rc5_address, rc5_instruction, rc5_ctrl); + + /* generate a manchester format of the frame */ + rc5_frame_manchester_format = rc5_manchester_convert(rc5_frame_binary_format); + + /* set the send operation ready flag to indicate that the frame is ready to be sent */ + send_operation_ready = 1; + + /* TIMER15 INT enable */ + timer_interrupt_enable(TIMER15, TIMER_INT_UP); + + /* enable TIMER15 */ + timer_enable(TIMER15); +} + +/*! + \brief send by hardware manchester format rc5 frame + \param[in] rc5_manchester_frame_format: the rc5 frame in manchester format + \param[out] none + \retval none +*/ +void rc5_encode_signal_generate( uint32_t rc5_manchester_frame_format ) +{ + uint8_t bit_msg = 0; + + if((1 == send_operation_ready ) && ((rc5_global_frame_length * 2) >= bits_sent_counter)){ + send_operation_completed = 0x00; + bit_msg = (uint8_t)((rc5_manchester_frame_format >> bits_sent_counter) & 1); + + if(1 == bit_msg){ + timer_channel_output_mode_config(TIMER15, TIMER_CH_0, TIMER_OC_MODE_HIGH); + }else{ + timer_channel_output_mode_config(TIMER15, TIMER_CH_0, TIMER_OC_MODE_LOW); + } + bits_sent_counter++; + }else{ + send_operation_completed = 0x01; + + /* TIMER15 INT disable */ + timer_interrupt_disable(TIMER15, TIMER_INT_UP); + timer_disable(TIMER15); + + send_operation_ready = 0; + bits_sent_counter = 0; + timer_channel_output_mode_config(TIMER15, TIMER_CH_0, TIMER_OC_MODE_LOW); + } +} + +/*! + \brief generate the binary format of the rc5 frame + \param[in] rc5_address: select the device adress + \param[in] rc5_instruction: select the device instruction + \param[in] rc5_ctrl: select the device control bit status + \param[out] none + \retval binary format of the rc5 frame +*/ +static uint16_t rc5_bin_frame_generation(uint8_t rc5_address, uint8_t rc5_instruction, rc5_ctrl_enum rc5_ctrl) +{ + uint16_t star1 = 0x2000; + uint16_t star2 = 0x1000; + uint16_t addr = 0; + + while(0x00 == send_operation_completed); + + /* check if instruction is 128-bit length */ + if(64 <= rc5_instruction){ + /* reset field bit: command is 7-bit length */ + star2 = 0; + /* keep the lowest 6 bits of the command */ + rc5_instruction &= 0x003F; + } + /* instruction is 64-bit length */ + else{ + /* set field bit: command is 6-bit length */ + star2 = 0x1000; + } + + send_operation_ready = 0; + rc5_frame_manchester_format = 0; + rc5_frame_binary_format = 0; + addr = ((uint16_t)(rc5_address))<<6; + rc5_frame_binary_format = (star1) | (star2) | (rc5_ctrl) | (addr) | (rc5_instruction); + return(rc5_frame_binary_format); +} + +/*! + \brief convert the rc5 frame from binary to manchester format + \param[in] rc5_binary_frame_format: the rc5 frame in binary format + \param[out] none + \retval the rc5 frame in manchester format +*/ +static uint32_t rc5_manchester_convert(uint16_t rc5_binary_frame_format) +{ + uint8_t i=0; + uint16_t mask = 1; + uint16_t bit_format = 0; + uint32_t converted_msg =0; + + for(i = 0; i < rc5_real_frame_length; i++){ + bit_format = ((((uint16_t)(rc5_binary_frame_format))>>i)& mask)< + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/IREF_provides_reference_current/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/IREF_provides_reference_current/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/IREF_provides_reference_current/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/IREF_provides_reference_current/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/IREF_provides_reference_current/main.c new file mode 100644 index 0000000..6eb44ae --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/IREF_provides_reference_current/main.c @@ -0,0 +1,78 @@ +/*! + \file main.c + \brief IREF provides reference current +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_libopt.h" +#include + +void rcu_config(void); +void gpio_config(void); +void iref_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + rcu_config(); + gpio_config(); + iref_config(); + while(1); +} + +/*! + \brief configure RCU function + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* GPIOB clock enable */ + rcu_periph_clock_enable(RCU_GPIOB); + /* IVREF clock enable */ + rcu_periph_clock_enable(RCU_OPAIVREF); +} + + +/*! + \brief configure IREF function + \param[in] none + \param[out] none + \retval none +*/ +void iref_config(void) +{ + ivref_deinit(); + iref_mode_set(IREF_MODE_HIGH_CURRENT); + iref_enable(); + /* set iref sink mode */ + iref_sink_set(IREF_SOURCE_CURRENT); + iref_precision_trim_value_set(IREF_CUR_PRECISION_TRIM_16); + iref_step_data_config(IREF_CUR_STEP_DATA_23); +} + +/*! + \brief configure GPIO function + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + gpio_mode_set(GPIOB,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_0); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/IREF_provides_reference_current/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/IREF_provides_reference_current/readme.txt new file mode 100644 index 0000000..7cad4cf --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/IREF_provides_reference_current/readme.txt @@ -0,0 +1,16 @@ +/*! + \file readme.txt + \brief description of the IREF_provides_reference_current example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32190R-EVAL board, it shows how to use IREF to +generate current on PB0. We can use multimeter on PB0 to get the current value. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/VREF_provides_reference_voltage/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/VREF_provides_reference_voltage/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/VREF_provides_reference_voltage/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/VREF_provides_reference_voltage/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/VREF_provides_reference_voltage/main.c new file mode 100644 index 0000000..882a6dc --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/VREF_provides_reference_voltage/main.c @@ -0,0 +1,74 @@ +/*! + \file main.c + \brief VREF provides reference voltage +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_libopt.h" +#include + +void rcu_config(void); +void gpio_config(void); +void vref_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + rcu_config(); + gpio_config(); + vref_config(); + while(1); +} + +/*! + \brief configure RCU function + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* GPIOB clock enable */ + rcu_periph_clock_enable(RCU_GPIOB); + /* IVREF clock enable */ + rcu_periph_clock_enable(RCU_OPAIVREF); +} + +/*! + \brief configure VREF function + \param[in] none + \param[out] none + \retval none +*/ +void vref_config(void) +{ + ivref_deinit(); + vref_mode_set(VREF_DISCONNECT_EXTERNAL_CAP); + vref_precision_trim_value_set(VREF_VOLT_PRECISION_TRIM_15); + vref_enable(); +} + +/*! + \brief configure GPIO function + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + gpio_mode_set(GPIOB,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/VREF_provides_reference_voltage/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/VREF_provides_reference_voltage/readme.txt new file mode 100644 index 0000000..6bf7413 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/IVREF/VREF_provides_reference_voltage/readme.txt @@ -0,0 +1,18 @@ +/*! + \file readme.txt + \brief description of the VREF_provides_reference_voltage example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32190R-EVAL board, it shows how to use VREF to +generate a voltage on PB1. We can use multimeter or oscilloscope on PB1 to get +the voltage value. + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/gd32f1x0_it.c new file mode 100644 index 0000000..c947950 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/gd32f1x0_it.c @@ -0,0 +1,115 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/gd32f1x0_it.h new file mode 100644 index 0000000..a4c6c0f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/main.c new file mode 100644 index 0000000..f03235f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/main.c @@ -0,0 +1,125 @@ +/*! + \file main.c + \brief OPA amplify +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_libopt.h" +#include "gd32f1x0_eval.h" +#include "systick.h" +#include + +void rcu_config(void); +void gpio_config(void); +void opa_config(void); +void adc_config(void); + +uint16_t data; +float value; + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + rcu_config(); + systick_config(); + gpio_config(); + opa_config(); + adc_config(); + gd_eval_com_init(EVAL_COM2); + while(1){ + delay_1ms(2000); + data = adc_regular_data_read(); + value = (float)data * 5.0 / 4096.0; + printf("\n\rOPA_Out_Value %5.3fV\n\r",value); + printf("\n\r"); + printf("\n\r"); + } +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM2, (uint8_t)ch); + while (RESET == usart_flag_get(EVAL_COM2, USART_FLAG_TC)); + return ch; +} + +/*! + \brief configure RCU function + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + /* ADCCLK = APB2/8 */ + rcu_adc_clock_config(RCU_ADCCK_APB2_DIV8); + /* OPAMP clock enable */ + rcu_periph_clock_enable(RCU_OPAIVREF); + /* GPIOA clock enable */ + rcu_periph_clock_enable(RCU_GPIOA); + /* GPIOC clock enable */ + rcu_periph_clock_enable(RCU_GPIOC); + /* ADC clock enable */ + rcu_periph_clock_enable(RCU_ADC); +} + +/*! + \brief Configure GPIO function + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + gpio_mode_set(GPIOC,GPIO_MODE_ANALOG, GPIO_PUPD_NONE,GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); +} + +/*! + \brief Configure OPA function + \param[in] none + \param[out] none + \retval none +*/ +void opa_config(void) +{ + opa_deinit(); + opa_switch_enable(OPA_S1OPA2); + opa_switch_enable(OPA_S2OPA2); + opa_enable(OPA2); +} + +/*! + \brief Configure ADC function + \param[in] none + \param[out] none + \retval none +*/ +void adc_config(void) +{ + /* configure ADC */ + adc_special_function_config(ADC_SCAN_MODE,ENABLE); + adc_special_function_config(ADC_CONTINUOUS_MODE,ENABLE); + adc_external_trigger_config(ADC_REGULAR_CHANNEL,ENABLE); + adc_external_trigger_source_config(ADC_REGULAR_CHANNEL,ADC_EXTTRIG_REGULAR_SWRCST); + adc_data_alignment_config(ADC_DATAALIGN_RIGHT); + adc_channel_length_config(ADC_REGULAR_CHANNEL,1); + adc_regular_channel_config(0,ADC_CHANNEL_13,ADC_SAMPLETIME_41POINT5); + adc_enable(); + adc_calibration_enable(); + adc_software_trigger_enable(ADC_REGULAR_CHANNEL); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/readme.txt new file mode 100644 index 0000000..682b94a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the OPA_amplify example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32190R-EVAL board. It will show how to use the +OPA2 to amplify the input voltage.The input voltage is connected to the JP8 Pin 1. +The amplifier output pin can be configured to the ADC sample channel 13. We can adjust +the VR2 to change the magnification. The amplified voltage can be measured on the +JP8 pin 2 with a universal meter or oscilloscope. Amplified voltage can also be +sampled by ADC1 and printed out through the serial port. + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/systick.c new file mode 100644 index 0000000..a80b914 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/OPA/OPA_amplify/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/gd32f1x0_it.c new file mode 100644 index 0000000..04dab85 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/gd32f1x0_it.c @@ -0,0 +1,127 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" +#include "main.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + led_spark(); +} +/*! + \brief this function handles EXTI4_15 exception + \param[in] none + \param[out] none + \retval none +*/ +void EXTI4_15_IRQHandler(void) +{ + if(SET == exti_interrupt_flag_get(EXTI_13)) + exti_interrupt_flag_clear(EXTI_13); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/gd32f1x0_it.h new file mode 100644 index 0000000..f3fad53 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* EXTI4_15 handle function */ +void EXTI4_15_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/main.c new file mode 100644 index 0000000..b59af5a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/main.c @@ -0,0 +1,88 @@ +/*! + \file main.c + \brief deepsleep wakeup through exti interrupt +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_eval.h" +#include "systick.h" +#include "main.h" + +void led_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* systick config */ + systick_config(); + /* led config */ + led_config(); + /* clock enable */ + rcu_periph_clock_enable(RCU_PMU); + /* wakeup key config */ + gd_eval_key_init(KEY_WAKEUP,KEY_MODE_GPIO); + /* tamper key EXTI config */ + gd_eval_key_init(KEY_TAMPER,KEY_MODE_EXTI); + /* press wakeup key to enter deepsleep mode and use tamper key generate a exti interrupt to wakeup mcu */ + while(1){ + if(RESET == gpio_input_bit_get(WAKEUP_KEY_GPIO_PORT,WAKEUP_KEY_PIN)) + pmu_to_deepsleepmode(PMU_LDO_LOWPOWER,WFI_CMD); + } +} + +/*! + \brief toggle the led + \param[in] none + \param[out] none + \retval none +*/ +void led_spark(void) +{ + static __IO uint32_t timingdelaylocal = 0; + + if (timingdelaylocal != 0x00){ + + if(timingdelaylocal < 200){ + gd_eval_led_on(LED1); + gd_eval_led_on(LED2); + gd_eval_led_on(LED3); + gd_eval_led_on(LED4); + }else{ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + gd_eval_led_off(LED3); + gd_eval_led_off(LED4); + } + timingdelaylocal--; + }else{ + timingdelaylocal = 400; + } +} + +/*! + \brief led config + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + gd_eval_led_init (LED1); + gd_eval_led_init (LED2); + gd_eval_led_init (LED3); + gd_eval_led_init (LED4); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/main.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/main.h new file mode 100644 index 0000000..0edb942 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/main.h @@ -0,0 +1,21 @@ +/*! + \file main.c + \brief the header file of the main +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef MAIN_H +#define MAIN_H + +/* led spark function */ +void led_spark(void); + +#endif diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/readme.txt new file mode 100644 index 0000000..b3ba7fd --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/readme.txt @@ -0,0 +1,19 @@ +/*! + \file readme.txt + \brief description of the deepsleep wakeup through exti demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows pmu how to +enter deepsleep mode and wakeup it. Press wakeup key to enter deepsleep mode ,led stop flashing. +When you press tamper key to generate an exti interrupt , mcu will be wakeuped from deepsleep mode , +led sparks again. But the led sparks slower, because at this time IRC8M is the system clock. + \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/systick.c new file mode 100644 index 0000000..75edc28 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/systick.c @@ -0,0 +1,62 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)) + { + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Deepsleep_wakeup_exti/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/gd32f1x0_it.c new file mode 100644 index 0000000..e92e310 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/gd32f1x0_it.c @@ -0,0 +1,127 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} +/*! + \brief this function handles LVD exception + \param[in] none + \param[out] none + \retval none +*/ +void LVD_IRQHandler(void) +{ + if(RESET != exti_interrupt_flag_get(EXTI_16)){ + gd_eval_led_toggle(LED1); + exti_interrupt_flag_clear(EXTI_16); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/gd32f1x0_it.h new file mode 100644 index 0000000..8d0ebab --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* LVD handle function */ +void LVD_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/main.c new file mode 100644 index 0000000..775109f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/main.c @@ -0,0 +1,42 @@ +/*! + \file main.c + \brief low voltage detector +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* NVIC config */ + nvic_priority_group_set(NVIC_PRIGROUP_PRE0_SUB4); + nvic_irq_enable(LVD_IRQn,0,0); + /* clock enable */ + rcu_periph_clock_enable(RCU_PMU); + /* led1 config */ + gd_eval_led_init (LED1); + /* led1 turn on */ + gd_eval_led_on(LED1); + /* EXTI_16 config */ + exti_init(EXTI_16, EXTI_INTERRUPT, EXTI_TRIG_BOTH); + /* configure the lvd threshold to 2.9v(gd32f130_150) or 4.5v(gd32f170_190), and enable the lvd */ + pmu_lvd_select(PMU_LVDT_7); + + while(1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/readme.txt new file mode 100644 index 0000000..35d2b48 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Low_voltage_detector/readme.txt @@ -0,0 +1,20 @@ +/*! + \file readme.txt + \brief description of the low voltage detector demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to use low +voltage detector. If VDD/VDDA is higher or lower than the LVD threshold, then a lvd event will occur. +The event is internally connected to the EXTI line 16 and can generate an interrupt if enabled through +the EXTI registers. Use external power connect 3.3v pin and GND pin of the board , adjust voltage higher +or lower than the LVD threshold: 2.9v(GD32150R-EVAL) or 4.5v(GD32190R-EVAL), led1 will toggle. + \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Standby_wakeup_pin/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Standby_wakeup_pin/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Standby_wakeup_pin/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Standby_wakeup_pin/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Standby_wakeup_pin/main.c new file mode 100644 index 0000000..a72eb55 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Standby_wakeup_pin/main.c @@ -0,0 +1,63 @@ +/*! + \file main.c + \brief standby wakeup through wakeup pin +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void led_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* clock enable */ + rcu_periph_clock_enable(RCU_PMU); + /* led configuration and turn on all led */ + led_config(); + gd_eval_led_on(LED1); + gd_eval_led_on(LED3); + gd_eval_led_on(LED2); + gd_eval_led_on(LED4); + /* tamper key configuration */ + gd_eval_key_init(KEY_TAMPER,KEY_MODE_GPIO); + /* wakeup pin enable */ + pmu_wakeup_pin_enable(PMU_WAKEUP_PIN0); + /* press tamper key to enter standby mode and use wakeup key to wakeup mcu */ + while(1){ + if(RESET == gpio_input_bit_get(TAMPER_KEY_GPIO_PORT,TAMPER_KEY_PIN)) + pmu_to_standbymode(WFI_CMD); + } + +} + +/*! + \brief configure led + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + gd_eval_led_init (LED1); + gd_eval_led_init (LED2); + gd_eval_led_init (LED3); + gd_eval_led_init (LED4); +} + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Standby_wakeup_pin/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Standby_wakeup_pin/readme.txt new file mode 100644 index 0000000..5f6edc8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/PMU/Standby_wakeup_pin/readme.txt @@ -0,0 +1,20 @@ +/*! + \file readme.txt + \brief description of the standby wakeup throuht pin demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows pmu how to +enter standby mode and wakeup it.Press tamper key enter standby mode ,led turn off. +When you press wakeup key, mcu will be wakeuped from standby mode, led will be turn on. +when exit from the standby mode, a power-on reset occurs and the mcu will execute +instruction code from the 0x00000000 address. + \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/gd32f1x0_it.c new file mode 100644 index 0000000..4924dd3 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/gd32f1x0_it.c @@ -0,0 +1,119 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles RTC interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void RTC_IRQHandler(void) +{ + if(RESET != rtc_flag_get(RTC_FLAG_ALARM0)){ + rtc_flag_clear(RTC_FLAG_ALARM0); + exti_flag_clear(EXTI_17); + gd_eval_led_toggle(LED2); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/gd32f1x0_it.h new file mode 100644 index 0000000..c50cd69 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* RTC handle function */ +void RTC_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/main.c new file mode 100644 index 0000000..d189343 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/main.c @@ -0,0 +1,280 @@ +/*! + \file main.c + \brief RTC calendar alarm demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +#define RTC_CLOCK_SOURCE_IRC40K +#define BKP_VALUE 0x32F0 + +rtc_parameter_struct rtc_initpara; +rtc_alarm_struct rtc_alarm; +__IO uint32_t prescaler_a = 0, prescaler_s = 0; + +void rtc_setup(void); +void rtc_show_time(void); +void rtc_show_alarm(void); +uint8_t usart_input_threshold(uint32_t value); +void rtc_pre_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gd_eval_com_init(EVAL_COM1); + printf("\n\r ****************** RTC calendar alarm demo ******************\n\r"); + + /* enable PMU clock */ + rcu_periph_clock_enable(RCU_PMU); + /* enable the access of the RTC registers */ + pmu_backup_write_enable(); + + rtc_pre_config(); + + /* check if RTC has aready been configured */ + if (BKP_VALUE != RTC_BKP0){ + rtc_setup(); + }else{ + /* detect the reset source */ + if (RESET != rcu_flag_get(RCU_FLAG_PORRST)){ + printf("power on reset occurred....\n\r"); + }else if (RESET != rcu_flag_get(RCU_FLAG_EPRST)){ + printf("external reset occurred....\n\r"); + } + printf("no need to configure RTC....\n\r"); + + rtc_flag_clear(RTC_FLAG_ALARM0); + exti_flag_clear(EXTI_17); + + rtc_show_time(); + rtc_show_alarm(); + } + + rcu_all_reset_flag_clear(); + /* configure the leds */ + gd_eval_led_init(LED1); + gd_eval_led_on(LED1); + gd_eval_led_init(LED2); + gd_eval_led_on(LED2); + + /* RTC alarm interrupt configuration */ + exti_init(EXTI_17,EXTI_INTERRUPT,EXTI_TRIG_RISING); + nvic_irq_enable(RTC_IRQn,0,0); + + while (1); +} + +/*! + \brief RTC configuration function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_pre_config(void) +{ + #if defined (RTC_CLOCK_SOURCE_IRC40K) + rcu_osci_on(RCU_IRC40K); + rcu_osci_stab_wait(RCU_IRC40K); + rcu_rtc_clock_config(RCU_RTCSRC_IRC40K); + + prescaler_s = 0x18F; + prescaler_a = 0x63; + #elif defined (RTC_CLOCK_SOURCE_LXTAL) + rcu_osci_on(RCU_LXTAL); + rcu_osci_stab_wait(RCU_LXTAL); + rcu_rtc_clock_config(RCU_RTCSRC_LXTAL); + prescaler_s = 0xFF; + prescaler_a = 0x7F; + #else + #error RTC clock source should be defined. + #endif /* RTC_CLOCK_SOURCE_IRC40K */ + + rcu_periph_clock_enable(RCU_RTC); + rtc_register_sync_wait(); +} + +/*! + \brief use hyperterminal to setup RTC time and alarm + \param[in] none + \param[out] none + \retval none +*/ +void rtc_setup(void) +{ + /* setup RTC time value */ + uint32_t tmp_hh = 0xFF, tmp_mm = 0xFF, tmp_ss = 0xFF; + + rtc_initpara.rtc_factor_asyn = prescaler_a; + rtc_initpara.rtc_factor_syn = prescaler_s; + rtc_initpara.rtc_year = 0x16; + rtc_initpara.rtc_day_of_week = RTC_SATURDAY; + rtc_initpara.rtc_month = RTC_APR; + rtc_initpara.rtc_date = 0x30; + rtc_initpara.rtc_display_format = RTC_24HOUR; + rtc_initpara.rtc_am_pm = RTC_AM; + + /* current time input */ + printf("=======Configure RTC Time========\n\r"); + printf(" please input hour:\n\r"); + while (tmp_hh == 0xFF){ + tmp_hh = usart_input_threshold(23); + rtc_initpara.rtc_hour = tmp_hh; + } + printf(" %0.2x\n\r", tmp_hh); + + printf(" please input minute:\n\r"); + while (tmp_mm == 0xFF){ + tmp_mm = usart_input_threshold(59); + rtc_initpara.rtc_minute = tmp_mm; + } + printf(" %0.2x\n\r", tmp_mm); + + printf(" please input second:\n\r"); + while (tmp_ss == 0xFF){ + tmp_ss = usart_input_threshold(59); + rtc_initpara.rtc_second = tmp_ss; + } + printf(" %0.2x\n\r", tmp_ss); + + /* RTC current time configuration */ + if(ERROR == rtc_init(&rtc_initpara)){ + printf("\n\r** RTC time configuration failed! **\n\r"); + }else{ + printf("\n\r** RTC time configuration success! **\n\r"); + rtc_show_time(); + RTC_BKP0 = BKP_VALUE; + } + + /* setup RTC alarm */ + tmp_hh = 0xFF; + tmp_mm = 0xFF; + tmp_ss = 0xFF; + + rtc_alarm_disable(); + printf("=======Input Alarm Value=======\n\r"); + rtc_alarm.rtc_alarm_mask = RTC_ALARM_DATE_MASK|RTC_ALARM_HOUR_MASK|RTC_ALARM_MINUTE_MASK; + rtc_alarm.rtc_weekday_or_date = RTC_ALARM_DATE_SELECTED; + rtc_alarm.rtc_alarm_day = 0x31; + rtc_alarm.rtc_am_pm = RTC_AM; + + /* RTC alarm input */ + printf(" please input Alarm Hour:\n\r"); + while (tmp_hh == 0xFF){ + tmp_hh = usart_input_threshold(23); + rtc_alarm.rtc_alarm_hour = tmp_hh; + } + printf(" %0.2x\n\r", tmp_hh); + + printf(" Please Input Alarm Minute:\n\r"); + while (tmp_mm == 0xFF){ + tmp_mm = usart_input_threshold(59); + rtc_alarm.rtc_alarm_minute = tmp_mm; + } + printf(" %0.2x\n\r", tmp_mm); + + printf(" Please Input Alarm Second:\n\r"); + while (tmp_ss == 0xFF){ + tmp_ss = usart_input_threshold(59); + rtc_alarm.rtc_alarm_second = tmp_ss; + } + printf(" %0.2x", tmp_ss); + + /* RTC alarm configuration */ + rtc_alarm_config(&rtc_alarm); + printf("\n\r** RTC Set Alarm Success! **\n\r"); + rtc_show_alarm(); + + rtc_interrupt_enable(RTC_INT_ALARM); + rtc_alarm_enable(); +} + +/*! + \brief display the current time + \param[in] none + \param[out] none + \retval none +*/ +void rtc_show_time(void) +{ + uint32_t time_subsecond = 0; + uint8_t subsecond_ss = 0,subsecond_ts = 0,subsecond_hs = 0; + + rtc_current_time_get(&rtc_initpara); + + /* get the subsecond value of current time, and convert it into fractional format */ + time_subsecond = rtc_subsecond_get(); + subsecond_ss=(1000-(time_subsecond*1000+1000)/400)/100; + subsecond_ts=(1000-(time_subsecond*1000+1000)/400)%100/10; + subsecond_hs=(1000-(time_subsecond*1000+1000)/400)%10; + + printf("Current time: %0.2x:%0.2x:%0.2x .%d%d%d \n\r", \ + rtc_initpara.rtc_hour, rtc_initpara.rtc_minute, rtc_initpara.rtc_second,\ + subsecond_ss, subsecond_ts, subsecond_hs); +} + +/*! + \brief display the alram value + \param[in] none + \param[out] none + \retval none +*/ +void rtc_show_alarm(void) +{ + rtc_alarm_get(&rtc_alarm); + printf("The alarm: %0.2x:%0.2x:%0.2x \n\r", rtc_alarm.rtc_alarm_hour, rtc_alarm.rtc_alarm_minute,\ + rtc_alarm.rtc_alarm_second); +} + +/*! + \brief get the input character string and check if it is valid + \param[in] none + \param[out] none + \retval input value in BCD mode +*/ +uint8_t usart_input_threshold(uint32_t value) +{ + uint32_t index = 0; + uint32_t tmp[2] = {0, 0}; + + while (index < 2){ + while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_RBNE)); + tmp[index++] = usart_data_receive(EVAL_COM1); + if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39)){ + printf("\n\r please input a valid number between 0 and 9 \n\r"); + index--; + } + } + + index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10); + if (index > value){ + printf("\n\r please input a valid number between 0 and %d \n\r", value); + return 0xFF; + } + + index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) <<4); + return index; +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t) ch); + while (RESET == usart_flag_get(EVAL_COM1,USART_FLAG_TC)); + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/readme.txt new file mode 100644 index 0000000..5626430 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Calendar_alarm/readme.txt @@ -0,0 +1,35 @@ +/*! + \file readme.txt + \brief description of the calendar alarm example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it explains how +to configure the RTC module. In this demo, RTC peripheral is configured to keep +time and generate an alarm interrupt. + + The RTC clock source can be chose to LXTAL or IRC40K by uncomment the corresponding +define in main file. And the HyperTerminal should be connected to the evaluation +board via USART0/USART1. The vbat bin on the board should connect to the CR1220 battery. + + After start-up, the program check if the BKP data register is written to a key +value. If the value is not correct, the program will ask to set the time and alarm +value on the HyperTerminal. If the key value is correct, the time and alarm value +will be displayed on the HyperTerminal. Also the demo shows how to get the cuurent +subsecond value and convert it into fractional format. + + Then LED1 and LED2 is turned on. + + The RTC module is in the Backup Domain, and is not reset by the system reset or +power reset. + + When the alarm interrupt generated, the LED2 toggled. The alarm is configured to +occur once per minute. \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/gd32f1x0_it.c new file mode 100644 index 0000000..6c58b46 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/gd32f1x0_it.c @@ -0,0 +1,129 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" +#include "main.h" + +extern void rtc_show_timestamp(void); +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles RTC interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void RTC_IRQHandler(void) +{ + if(RESET != rtc_flag_get(RTC_FLAG_TAMP0)){ + exti_flag_clear(EXTI_19); + gd_eval_led_toggle(LED1); + + /* if tamper0 event occurs, check if the BKP0 register has been reset or not */ + if(BKP_VALUE != RTC_BKP0) + gd_eval_led_toggle(LED2); + else + gd_eval_led_toggle(LED3); + + rtc_show_timestamp(); + rtc_flag_clear(RTC_FLAG_TIMESTAMP|RTC_FLAG_TIMESTAMP_OVERFLOW|RTC_FLAG_TAMP0); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/gd32f1x0_it.h new file mode 100644 index 0000000..c50cd69 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* RTC handle function */ +void RTC_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/main.c new file mode 100644 index 0000000..37ff27c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/main.c @@ -0,0 +1,257 @@ +/*! + \file main.c + \brief RTC tamper with timestamp demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "main.h" +#include "gd32f1x0_eval.h" + +#define RTC_CLOCK_SOURCE_IRC40K + +rtc_timestamp_struct rtc_timestamp; +rtc_tamper_struct rtc_tamper; +rtc_parameter_struct rtc_initpara; +__IO uint32_t prescaler_a = 0, prescaler_s = 0; + +void rtc_setup(void); +void rtc_show_time(void); +void rtc_show_timestamp(void); +uint8_t usart_input_threshold(uint32_t value); +void rtc_pre_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gd_eval_com_init(EVAL_COM1); + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + printf("\n\r ************* RTC tamper with timestamp demo *************\n\r"); + + /* enable access to RTC registers in backup domain */ + rcu_periph_clock_enable(RCU_PMU); + pmu_backup_write_enable(); + + rtc_pre_config(); + rtc_tamper_disable(RTC_TAMPER0); + + /* check if RTC has aready been configured */ + if (BKP_VALUE != RTC_BKP0){ + rtc_setup(); + }else{ + /* detect the reset source */ + if (RESET != rcu_flag_get(RCU_FLAG_PORRST)){ + printf("power on reset occurred....\n\r"); + }else if (RESET != rcu_flag_get(RCU_FLAG_EPRST)){ + printf("external reset occurred....\n\r"); + } + printf("no need to configure RTC....\n\r"); + + rtc_show_time(); + } + + rcu_all_reset_flag_clear(); + + gd_eval_led_init(LED1); + gd_eval_led_off(LED1); + gd_eval_led_init(LED2); + gd_eval_led_off(LED2); + gd_eval_led_init(LED3); + gd_eval_led_off(LED3); + + exti_flag_clear(EXTI_19); + exti_init(EXTI_19,EXTI_INTERRUPT,EXTI_TRIG_FALLING); + nvic_irq_enable(RTC_IRQn,0,0); + + /* RTC tamper configuration */ + rtc_tamper.rtc_tamper_filter = RTC_FLT_EDGE; + rtc_tamper.rtc_tamper_source = RTC_TAMPER0; + rtc_tamper.rtc_tamper_trigger = RTC_TAMPER_TRIGGER_EDGE_FALLING; + rtc_tamper.rtc_tamper_with_timestamp = ENABLE; + rtc_tamper_enable(&rtc_tamper); + + rtc_interrupt_enable(RTC_INT_TAMP); + rtc_flag_clear(RTC_FLAG_TIMESTAMP|RTC_FLAG_TIMESTAMP_OVERFLOW|RTC_FLAG_TAMP0); + + while (1); +} + +/*! + \brief RTC configuration function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_pre_config(void) +{ + #if defined (RTC_CLOCK_SOURCE_IRC40K) + rcu_osci_on(RCU_IRC40K); + rcu_osci_stab_wait(RCU_IRC40K); + rcu_rtc_clock_config(RCU_RTCSRC_IRC40K); + + prescaler_s = 0x18F; + prescaler_a = 0x63; + #elif defined (RTC_CLOCK_SOURCE_LXTAL) + rcu_osci_on(RCU_LXTAL); + rcu_osci_stab_wait(RCU_LXTAL); + rcu_rtc_clock_config(RCU_RTCSRC_LXTAL); + prescaler_s = 0xFF; + prescaler_a = 0x7F; + #else + #error RTC clock source should be defined. + #endif /* RTC_CLOCK_SOURCE_IRC40K */ + + rcu_periph_clock_enable(RCU_RTC); + rtc_register_sync_wait(); +} + +/*! + \brief use hyperterminal to setup RTC time and alarm + \param[in] none + \param[out] none + \retval none +*/ +void rtc_setup(void) +{ + /* setup RTC time value */ + uint32_t tmp_hh = 0xFF, tmp_mm = 0xFF, tmp_ss = 0xFF; + + rtc_initpara.rtc_factor_asyn = prescaler_a; + rtc_initpara.rtc_factor_syn = prescaler_s; + rtc_initpara.rtc_year = 0x16; + rtc_initpara.rtc_day_of_week = RTC_SATURDAY; + rtc_initpara.rtc_month = RTC_APR; + rtc_initpara.rtc_date = 0x30; + rtc_initpara.rtc_display_format = RTC_24HOUR; + rtc_initpara.rtc_am_pm = RTC_AM; + + /* current time input */ + printf("=======Configure RTC Time========\n\r"); + printf(" please input hour:\n\r"); + while (tmp_hh == 0xFF){ + tmp_hh = usart_input_threshold(23); + rtc_initpara.rtc_hour = tmp_hh; + } + printf(" %0.2x\n\r", tmp_hh); + + printf(" please input minute:\n\r"); + while (tmp_mm == 0xFF){ + tmp_mm = usart_input_threshold(59); + rtc_initpara.rtc_minute = tmp_mm; + } + printf(" %0.2x\n\r", tmp_mm); + + printf(" please input second:\n\r"); + while (tmp_ss == 0xFF){ + tmp_ss = usart_input_threshold(59); + rtc_initpara.rtc_second = tmp_ss; + } + printf(" %0.2x\n\r", tmp_ss); + + /* RTC current time configuration */ + if(ERROR == rtc_init(&rtc_initpara)){ + printf("** RTC time configuration failed! **\n\r"); + }else{ + printf("** RTC time configuration success! **\n\r"); + rtc_show_time(); + RTC_BKP0 = BKP_VALUE; + } +} + +/*! + \brief display the timestamp time + \param[in] none + \param[out] none + \retval none +*/ +void rtc_show_timestamp(void) +{ + uint32_t ts_subsecond = 0; + uint8_t ts_subsecond_ss,ts_subsecond_ts,ts_subsecond_hs ; + + rtc_timestamp_get(&rtc_timestamp); + /* get the subsecond value of timestamp time, and convert it into fractional format */ + ts_subsecond = rtc_timestamp_subsecond_get(); + ts_subsecond_ss=(1000-(ts_subsecond*1000+1000)/400)/100; + ts_subsecond_ts=(1000-(ts_subsecond*1000+1000)/400)%100/10; + ts_subsecond_hs=(1000-(ts_subsecond*1000+1000)/400)%10; + + printf("Get the time-stamp time: %0.2x:%0.2x:%0.2x .%d%d%d \n\r", \ + rtc_timestamp.rtc_timestamp_hour, rtc_timestamp.rtc_timestamp_minute, rtc_timestamp.rtc_timestamp_second,\ + ts_subsecond_ss, ts_subsecond_ts, ts_subsecond_hs); +} + +/*! + \brief display the current time + \param[in] none + \param[out] none + \retval none +*/ +void rtc_show_time(void) +{ + uint32_t time_subsecond = 0; + uint8_t subsecond_ss = 0,subsecond_ts = 0,subsecond_hs = 0; + + rtc_current_time_get(&rtc_initpara); + /* get the subsecond value of current time, and convert it into fractional format */ + time_subsecond = rtc_subsecond_get(); + subsecond_ss=(1000-(time_subsecond*1000+1000)/400)/100; + subsecond_ts=(1000-(time_subsecond*1000+1000)/400)%100/10; + subsecond_hs=(1000-(time_subsecond*1000+1000)/400)%10; + + printf("Current time: %0.2x:%0.2x:%0.2x .%d%d%d \n\r", \ + rtc_initpara.rtc_hour, rtc_initpara.rtc_minute, rtc_initpara.rtc_second,\ + subsecond_ss, subsecond_ts, subsecond_hs); +} + +/*! + \brief get the input character string and check if it is valid + \param[in] none + \param[out] none + \retval input value in BCD mode +*/ +uint8_t usart_input_threshold(uint32_t value) +{ + uint32_t index = 0; + uint32_t tmp[2] = {0, 0}; + + while (index < 2){ + while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_RBNE)); + tmp[index++] = usart_data_receive(EVAL_COM1); + if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39)){ + printf("\n\r please input a valid number between 0 and 9 \n\r"); + index--; + } + } + + index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10); + if (index > value){ + printf("\n\r please input a valid number between 0 and %d \n\r", value); + return 0xFF; + } + + index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) <<4); + return index; +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t) ch); + while (RESET == usart_flag_get(EVAL_COM1,USART_FLAG_TC)); + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/main.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/main.h new file mode 100644 index 0000000..bb12b3a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/main.h @@ -0,0 +1,21 @@ +/*! + \file main.c + \brief the header file of main +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef MAIN_H +#define MAIN_H + +/* constants definitions */ +#define BKP_VALUE 0x32F0 + +#endif diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/readme.txt new file mode 100644 index 0000000..a013adb --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Tamper_with_timestamp/readme.txt @@ -0,0 +1,38 @@ +/*! + \file readme.txt + \brief description of the tamper with timestamp example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it explains how +to configure the RTC module. In this demo, RTC peripheral is configured to keep +time and generate the tamper interrupt. + + The RTC clock source can be chose to LXTAL or IRC40K by uncomment the corresponding +define in main file. And the HyperTerminal should be connected to the evaluation +board via USART0/USART1. The vbat bin on the board should connect to the CR1220 battery. +The tamper key is the tamper0 pin. The tamper0 is configured to used for timestamp function. + + After start-up, the program check if the BKP data register is written to a key +value. If the value is not correct, the program will ask to set the time value on the +HyperTerminal. If the key value is correct, the current time and subsecond will be +displayed on the HyperTerminal. + + The RTC module is in the Backup Domain, and is not reset by the system reset or +power reset. + + When press the tamper key, a tamper0 interrupt will be generated, and the tamper0 event +will reset the BKP0 register, thus if you press the reset key, on the HyperTerminal it asks +you to set the time again. And if the BKP0 register has been reset, when press the tamper key to +come to the interrupt, LED1, LED2 will toggle. If LED3 toggles, there may be other write +operations to BKP0 register has occured. In this example it's configured to enable timestamp +function when the tamper0 event occurs, thus the timestamp value is then be print on the +HyperTerminal to tell the time that tamper0 event occured. \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/gd32f1x0_it.c new file mode 100644 index 0000000..a3b7154 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/gd32f1x0_it.c @@ -0,0 +1,121 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +extern void rtc_show_timestamp(void); +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles RTC interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void RTC_IRQHandler(void) +{ + if(RESET != rtc_flag_get(RTC_FLAG_TIMESTAMP)){ + exti_flag_clear(EXTI_19); + gd_eval_led_toggle(LED1); + rtc_show_timestamp(); + rtc_flag_clear(RTC_FLAG_TIMESTAMP|RTC_FLAG_TIMESTAMP_OVERFLOW); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/gd32f1x0_it.h new file mode 100644 index 0000000..c50cd69 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* RTC handle function */ +void RTC_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/main.c new file mode 100644 index 0000000..3759820 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/main.c @@ -0,0 +1,247 @@ +/*! + \file main.c + \brief RTC timestamp demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +#define RTC_CLOCK_SOURCE_IRC40K +#define BKP_VALUE 0x32F0 + +rtc_timestamp_struct rtc_timestamp; +rtc_parameter_struct rtc_initpara; +__IO uint32_t prescaler_a = 0, prescaler_s = 0; + +void rtc_setup(void); +void rtc_show_time(void); +void rtc_show_timestamp(void); +uint8_t usart_input_threshold(uint32_t value); +void rtc_pre_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gd_eval_com_init(EVAL_COM1); + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + printf("\n\r ****************** RTC time-stamp demo ******************\n\r"); + gd_eval_key_init(KEY_TAMPER,KEY_MODE_GPIO); + + /* enable access to RTC registers in Backup domain */ + rcu_periph_clock_enable(RCU_PMU); + pmu_backup_write_enable(); + + rtc_pre_config(); + + /* check if RTC has aready been configured */ + if (BKP_VALUE != RTC_BKP0){ + rtc_setup(); + }else{ + /* detect the reset source */ + if (RESET != rcu_flag_get(RCU_FLAG_PORRST)){ + printf("power on reset occurred....\n\r"); + }else if (RESET != rcu_flag_get(RCU_FLAG_EPRST)){ + printf("external reset occurred....\n\r"); + } + printf("no need to configure RTC....\n\r"); + + rtc_show_time(); + } + + rcu_all_reset_flag_clear(); + + gd_eval_led_init(LED1); + gd_eval_led_on(LED1); + + exti_flag_clear(EXTI_19); + exti_init(EXTI_19,EXTI_INTERRUPT,EXTI_TRIG_RISING); + nvic_irq_enable(RTC_IRQn,0,0); + + /* RTC timestamp configuration */ + rtc_timestamp_enable(RTC_TIMESTAMP_FALLING_EDGE); + rtc_interrupt_enable(RTC_INT_TIMESTAMP); + rtc_flag_clear(RTC_FLAG_TIMESTAMP|RTC_FLAG_TIMESTAMP_OVERFLOW); + + while (1); +} + +/*! + \brief RTC configuration function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_pre_config(void) +{ + #if defined (RTC_CLOCK_SOURCE_IRC40K) + rcu_osci_on(RCU_IRC40K); + rcu_osci_stab_wait(RCU_IRC40K); + rcu_rtc_clock_config(RCU_RTCSRC_IRC40K); + + prescaler_s = 0x18F; + prescaler_a = 0x63; + #elif defined (RTC_CLOCK_SOURCE_LXTAL) + rcu_osci_on(RCU_LXTAL); + rcu_osci_stab_wait(RCU_LXTAL); + rcu_rtc_clock_config(RCU_RTCSRC_LXTAL); + prescaler_s = 0xFF; + prescaler_a = 0x7F; + #else + #error RTC clock source should be defined. + #endif /* RTC_CLOCK_SOURCE_IRC40K */ + + rcu_periph_clock_enable(RCU_RTC); + rtc_register_sync_wait(); +} + +/*! + \brief use hyperterminal to setup RTC time and alarm + \param[in] none + \param[out] none + \retval none +*/ +void rtc_setup(void) +{ + /* setup RTC time value */ + uint32_t tmp_hh = 0xFF, tmp_mm = 0xFF, tmp_ss = 0xFF; + + rtc_initpara.rtc_factor_asyn = prescaler_a; + rtc_initpara.rtc_factor_syn = prescaler_s; + rtc_initpara.rtc_year = 0x16; + rtc_initpara.rtc_day_of_week = RTC_SATURDAY; + rtc_initpara.rtc_month = RTC_APR; + rtc_initpara.rtc_date = 0x30; + rtc_initpara.rtc_display_format = RTC_24HOUR; + rtc_initpara.rtc_am_pm = RTC_AM; + + /* current time input */ + printf("=======Configure RTC Time========\n\r"); + printf(" please input hour:\n\r"); + while (tmp_hh == 0xFF){ + tmp_hh = usart_input_threshold(23); + rtc_initpara.rtc_hour = tmp_hh; + } + printf(" %0.2x\n\r", tmp_hh); + + printf(" please input minute:\n\r"); + while (tmp_mm == 0xFF){ + tmp_mm = usart_input_threshold(59); + rtc_initpara.rtc_minute = tmp_mm; + } + printf(" %0.2x\n\r", tmp_mm); + + printf(" please input second:\n\r"); + while (tmp_ss == 0xFF){ + tmp_ss = usart_input_threshold(59); + rtc_initpara.rtc_second = tmp_ss; + } + printf(" %0.2x\n\r", tmp_ss); + + /* RTC current time configuration */ + if(ERROR == rtc_init(&rtc_initpara)){ + printf("\n\r** RTC time configuration failed! **\n\r"); + }else{ + printf("\n\r** RTC time configuration success! **\n\r"); + rtc_show_time(); + RTC_BKP0 = BKP_VALUE; + } +} + +/*! + \brief display the timestamp time + \param[in] none + \param[out] none + \retval none +*/ +void rtc_show_timestamp(void) +{ + uint32_t ts_subsecond = 0; + uint8_t ts_subsecond_ss,ts_subsecond_ts,ts_subsecond_hs ; + + rtc_timestamp_get(&rtc_timestamp); + /* get the subsecond value of timestamp time, and convert it into fractional format */ + ts_subsecond = rtc_timestamp_subsecond_get(); + ts_subsecond_ss=(1000-(ts_subsecond*1000+1000)/400)/100; + ts_subsecond_ts=(1000-(ts_subsecond*1000+1000)/400)%100/10; + ts_subsecond_hs=(1000-(ts_subsecond*1000+1000)/400)%10; + + printf("Get the time-stamp time: %0.2x:%0.2x:%0.2x .%d%d%d \n\r", \ + rtc_timestamp.rtc_timestamp_hour, rtc_timestamp.rtc_timestamp_minute, rtc_timestamp.rtc_timestamp_second,\ + ts_subsecond_ss, ts_subsecond_ts, ts_subsecond_hs); +} + +/*! + \brief display the current time + \param[in] none + \param[out] none + \retval none +*/ +void rtc_show_time(void) +{ + uint32_t time_subsecond = 0; + uint8_t subsecond_ss = 0,subsecond_ts = 0,subsecond_hs = 0; + + rtc_current_time_get(&rtc_initpara); + /* get the subsecond value of current time, and convert it into fractional format */ + time_subsecond = rtc_subsecond_get(); + subsecond_ss=(1000-(time_subsecond*1000+1000)/400)/100; + subsecond_ts=(1000-(time_subsecond*1000+1000)/400)%100/10; + subsecond_hs=(1000-(time_subsecond*1000+1000)/400)%10; + + printf("Current time: %0.2x:%0.2x:%0.2x .%d%d%d \n\r", \ + rtc_initpara.rtc_hour, rtc_initpara.rtc_minute, rtc_initpara.rtc_second,\ + subsecond_ss, subsecond_ts, subsecond_hs); +} + +/*! + \brief get the input character string and check if it is valid + \param[in] none + \param[out] none + \retval input value in BCD mode +*/ +uint8_t usart_input_threshold(uint32_t value) +{ + uint32_t index = 0; + uint32_t tmp[2] = {0, 0}; + + while (index < 2){ + while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_RBNE)); + tmp[index++] = usart_data_receive(EVAL_COM1); + if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39)){ + printf("\n\r please input a valid number between 0 and 9 \n\r"); + index--; + } + } + + index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10); + if (index > value){ + printf("\n\r please input a valid number between 0 and %d \n\r", value); + return 0xFF; + } + + index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) <<4); + return index; +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t) ch); + while (RESET == usart_flag_get(EVAL_COM1,USART_FLAG_TC)); + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/readme.txt new file mode 100644 index 0000000..5972fdb --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/RTC/Timestamp/readme.txt @@ -0,0 +1,35 @@ +/*! + \file readme.txt + \brief description of the timestamp example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it explains how +to use the timestamp function of RTC. In this demo, RTC peripheral is configured to keep +time and generate the timestamp interrupt. + + The RTC clock source can be chose to LXTAL or IRC40K by uncomment the corresponding +define in main file. And the HyperTerminal should be connected to the evaluation +board via USART0/USART1. The vbat bin on the board should connect to the CR1220 battery. +The tamper key is the timestamp pin. + + After start-up, the program check if the BKP data register is written to a key +value. If the value is not correct, the program will ask to set the time value on the +HyperTerminal. If the key value is correct, the current time and subsecond value +will be displayed on the HyperTerminal. + + Then LED1 is turned on. + + The RTC module is in the Backup Domain, and is not reset by the system reset or +power reset. + + When press the tamper key, a timestamp interrupt will be generated, the current time +then be print on the HyperTerminal, and LED1 toggles. \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/gd32f1x0_it.c new file mode 100644 index 0000000..c947950 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/gd32f1x0_it.c @@ -0,0 +1,115 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/gd32f1x0_it.h new file mode 100644 index 0000000..b5a9e0b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/main.c new file mode 100644 index 0000000..33749f8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/main.c @@ -0,0 +1,63 @@ +/*! + \file main.c + \brief SLCD digit display +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_libopt.h" +#include +#include "systick.h" +#include "slcd_seg.h" + +void rcu_configuration(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + uint16_t num = 0; + /* system clocks configuration */ + rcu_configuration(); + /* systick config: 1ms delay */ + systick_configuration(); + /* slcd interface configuration */ + slcd_seg_configuration(); + + while(1){ + slcd_seg_number_display(num++); + delay_1ms(1000); + } +} + +/*! + \brief configure the different system clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_configuration(void) +{ + /* enable PMU clock */ + rcu_periph_clock_enable(RCU_PMU); + /* PMU backup domain write enable */ + pmu_backup_write_enable(); + /* enable IRC40K */ + rcu_osci_on(RCU_IRC40K); + /* wait for IRC40K stabilization flags */ + rcu_osci_stab_wait(RCU_IRC40K); + /* configure the RTC clock source selection */ + rcu_slcd_clock_config(RCU_SLCDSRC_IRC40K); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/readme.txt new file mode 100644 index 0000000..c3e8d30 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/readme.txt @@ -0,0 +1,22 @@ +/*! + \file readme.txt + \brief description of the SLCD demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32190R-EVAL board, it shows how to use the SLCD +peripheral to work with glass SLCD. + + For the reason SLCD and RTC share the same clock, we must configure the clock +of RTC first, this demo use RC40K(its frequence is 40K) to drive the SLCD peripheral. + + In this demo, the SLCD peripheral use 1/3 Bias voltage, 1/4 duty, 156.25Hz update +frequence to display numbers. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/slcd_seg.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/slcd_seg.c new file mode 100644 index 0000000..511ea92 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/slcd_seg.c @@ -0,0 +1,457 @@ +/*! + \file slcd_seg.c + \brief source of the slcd segment driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "slcd_seg.h" +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_rcu.h" + +/* digit SLCD DATA buffer */ +uint8_t digit[4]; + +/* table of the digit code for SLCD */ +__I uint32_t numbertable[10]= +{ +/* 0 1 2 3 4 */ +0xDD, 0x88, 0x79, 0xE9, 0xAC, +/* 5 6 7 8 9 */ +0xE5, 0xF5, 0x89, 0xFD, 0xED +}; + +static void digit_to_code(uint8_t c); +static void slcd_gpio_config(void); +static void slcd_seg_digit_write(uint8_t ch, uint8_t position , slcd_display_enum type); + +/*! + \brief convert digit to SLCD code + \param[in] the digit to write + \param[out] none + \retval none +*/ +static void digit_to_code(uint8_t c) +{ + uint8_t ch = 0; + + /* the *c is a number */ + if (c < 10) + ch = numbertable[c]; + + digit[0] = (uint8_t)((ch) & 0x03); + digit[1] = (uint8_t)((ch >> 2) & 0x03); + digit[2] = (uint8_t)((ch >> 4) & 0x03); + digit[3] = (uint8_t)((ch >> 6) & 0x03); +} + +/*! + \brief init the GPIO port of SLCD peripheral + \param[in] none + \param[out] none + \retval none +*/ +static void slcd_gpio_config(void) +{ + /* enable the clock of GPIO */ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_GPIOF); + + /* SLCD GPIO */ + /* configure GPIOA */ + gpio_mode_set(GPIOA,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10); + gpio_output_options_set(GPIOA,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10); + gpio_af_set(GPIOA,GPIO_AF_11,GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10); + + /* configure GPIOB */ + gpio_mode_set(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_9|GPIO_PIN_14|GPIO_PIN_15); + gpio_output_options_set(GPIOB,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9|GPIO_PIN_14|GPIO_PIN_15); + gpio_af_set(GPIOB,GPIO_AF_11,GPIO_PIN_9|GPIO_PIN_14|GPIO_PIN_15); + + /* configure GPIOC */ + gpio_mode_set(GPIOC,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9); + gpio_output_options_set(GPIOC,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9); + gpio_af_set(GPIOC,GPIO_AF_11,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9); + + /* configure GPIOF */ + gpio_mode_set(GPIOF,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); + gpio_output_options_set(GPIOF,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); + gpio_af_set(GPIOF,GPIO_AF_11,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); +} + +/*! + \brief init the GPIO port of the SLCD and SLCD peripheral + \param[in] none + \param[out] none + \retval none +*/ +void slcd_seg_configuration(void) +{ + uint16_t i; + + /* configure the SLCD GPIO pins */ + slcd_gpio_config(); + + /* enable the clock of SLCD */ + rcu_periph_clock_enable(RCU_SLCD); + /* wait 2 RTC clock to write SLCD register */ + for(i = 0;i < 500;i++); + /* config the prescaler and the divider of SLCD clock */ + slcd_clock_config(SLCD_PRESCALER_4,SLCD_DIVIDER_19); + /* SLCD bias voltage select */ + slcd_bias_voltage_select(SLCD_BIAS_1_3); + /* SLCD duty cycle select */ + slcd_duty_select(SLCD_DUTY_1_4); + /* SLCD voltage source select */ + slcd_voltage_source_select(SLCD_VOLTAGE_EXTERNAL); + /* SLCD pulse on duration config */ + slcd_pulse_on_duration_config(SLCD_PULSEON_DURATION_7); + /* SLCD dead time duration config */ + slcd_dead_time_config(SLCD_DEADTIME_PERIOD_7); + /* enable the permanent high drive */ + slcd_high_drive_config(ENABLE); + /* wait for SLCD CFG register synchronization */ + while (!slcd_flag_get(SLCD_FLAG_SYN)); + /* enable SLCD interface */ + slcd_enable(); + /* wait for SLCD controller on flag */ + while (!slcd_flag_get(SLCD_FLAG_ON)); + /* wait for SLCD voltage ready flag */ + while (!slcd_flag_get(SLCD_FLAG_VRDY)); +} + +/*! + \brief this function write one digit to the SLCD DATA register + \param[in] ch: the digit to write + \param[in] position: position in the SLCD of the digit to write + \param[out] none + \retval none +*/ +void slcd_seg_digit_display(uint8_t ch, uint8_t position) +{ + /* wait the last SLCD DATA update request finished */ + while(slcd_flag_get(SLCD_FLAG_UPR)); + + /* SLCD write a char */ + slcd_seg_digit_write(ch, position , INTEGER); + + /* request SLCD DATA update */ + slcd_data_update_request(); +} + +/*! + \brief this function write a integer(6 digits) to SLCD DATA register + \param[in] num: number to send to SLCD(0-999999) + \param[out] none + \retval none +*/ +void slcd_seg_number_display(uint32_t num) +{ + uint8_t i = 0x00 , length , ch[6]; + + ch[5] = num / 100000; + ch[4] = (num % 100000) / 10000; + ch[3] = (num % 10000) / 1000; + ch[2] = (num % 1000) / 100; + ch[1] = (num % 100 )/ 10; + ch[0] = num % 10; + + if(ch[5]){ + length = 6; + }else if(ch[4]){ + length = 5; + }else if(ch[3]){ + length = 4; + }else if(ch[2]){ + length = 3; + }else if(ch[1]){ + length = 2; + }else{ + length = 1; + } + + slcd_seg_clear_all(); + /* wait the last SLCD DATA update request finished */ + while(slcd_flag_get(SLCD_FLAG_UPR)); + + /* send the string character one by one to SLCD */ + while (i < length){ + /* display one digit on SLCD */ + slcd_seg_digit_write( ch[i] , 6-i , INTEGER ); + /* increment the digit counter */ + i++; + } + + /* request SLCD DATA update */ + slcd_data_update_request(); +} + +/*! + \brief this function write a float number(6 digits which has 2 decimal) to SLCD DATA register + \param[in] num: number to send to SLCD + \param[out] none + \retval none +*/ +void slcd_seg_floatnumber_display(float num) +{ + uint8_t i = 0x00 , length , ch[6]; + uint32_t temp; + + temp = (uint32_t)(num * 100); + ch[5] = temp / 100000; + ch[4] = (temp % 100000) / 10000; + ch[3] = (temp % 10000) / 1000; + ch[2] = (temp % 1000) / 100; + ch[1] = (temp % 100) / 10; + ch[0] = temp % 10; + + if(ch[5]){ + length = 6; + }else if(ch[4]){ + length = 5; + }else if(ch[3]){ + length = 4; + }else{ + length = 3; + } + + slcd_seg_clear_all(); + /* wait the last SLCD DATA update request finished */ + while(slcd_flag_get(SLCD_FLAG_UPR)); + + /* send the string character one by one to SLCD */ + while (i < length){ + /* display one digit on SLCD */ + slcd_seg_digit_write(ch[i], 6-i , FLOAT); + /* increment the digit counter */ + i++; + } + + /* request SLCD DATA update */ + slcd_data_update_request(); +} + +/*! + \brief this function write time to SLCD DATA register + \param[in] num: number to send to SLCD + \param[out] none + \retval none +*/ +void slcd_seg_time_display(uint8_t hour, uint8_t minute , uint8_t second) +{ + uint8_t i = 0x00 , ch[6]; + + ch[0] = hour/10; + ch[1] = hour%10; + ch[2] = minute/10; + ch[3] = minute%10; + ch[4] = second/10; + ch[5] = second%10; + + /* wait the last SLCD DATA update request finished */ + while(slcd_flag_get(SLCD_FLAG_UPR)); + + /* send the string character one by one to SLCD */ + while (i < 6){ + /* display one digit on SLCD */ + slcd_seg_digit_write(ch[i], i+1 , TIME); + /* increment the digit counter */ + i++; + } + + /* request SLCD DATA update */ + slcd_data_update_request(); +} + +/*! + \brief this function write a digit to SLCD DATA register + \param[in] ch: the digit to write + \param[in] position: position in the SLCD of the digit to write,which can be 1..6 + \param[in] type: the type of the data + \param[out] none + \retval none +*/ +static void slcd_seg_digit_write(uint8_t ch, uint8_t position , slcd_display_enum type ) +{ + /* convert ASCii to SLCD digit or char */ + digit_to_code(ch); + + switch (position){ + case 6: + /* clear the corresponding segments (COM0..COM3, SEG30..31) */ + SLCD_DATA0 &= (uint32_t)(0x3FFFFFFF); + SLCD_DATA1 &= (uint32_t)(0x3FFFFFFF); + SLCD_DATA2 &= (uint32_t)(0x3FFFFFFF); + SLCD_DATA3 &= (uint32_t)(0x3FFFFFFF); + + /* write the colon of the time (COM0, SEG27) */ + if(type == TIME) + SLCD_DATA0 |= (uint32_t)((uint32_t)0x01 << 31); + /* write the corresponding segments (COM0..COM3, SEG30..31) */ + SLCD_DATA0 |= (uint32_t)(digit[0] << 30); + SLCD_DATA1 |= (uint32_t)(digit[1] << 30); + SLCD_DATA2 |= (uint32_t)(digit[2] << 30); + SLCD_DATA3 |= (uint32_t)(digit[3] << 30); + break; + + case 5: + /* clear the corresponding segments (COM0..COM3, SEG28..29) */ + SLCD_DATA0 &= (uint32_t)(0xCFFFFFFF); + SLCD_DATA1 &= (uint32_t)(0xCFFFFFFF); + SLCD_DATA2 &= (uint32_t)(0xCFFFFFFF); + SLCD_DATA3 &= (uint32_t)(0xCFFFFFFF); + + /* write the corresponding segments (COM0..COM3, SEG28..29) */ + SLCD_DATA0 |= (uint32_t)(digit[0] << 28); + SLCD_DATA1 |= (uint32_t)(digit[1] << 28); + SLCD_DATA2 |= (uint32_t)(digit[2] << 28); + SLCD_DATA3 |= (uint32_t)(digit[3] << 28); + break; + + case 4: + /* clear the corresponding segments (COM0..COM3, SEG26..27) */ + SLCD_DATA0 &= (uint32_t)(0xF3FFFFFF); + SLCD_DATA1 &= (uint32_t)(0xF3FFFFFF); + SLCD_DATA2 &= (uint32_t)(0xF3FFFFFF); + SLCD_DATA3 &= (uint32_t)(0xF3FFFFFF); + + /* write the point (COM0, SEG27) */ + if(type == FLOAT) + SLCD_DATA0 |= (uint32_t)(0x01 << 27); + /* write the corresponding segments (COM0..COM3, SEG26..27) */ + SLCD_DATA0 |= (uint32_t)(digit[0] << 26); + SLCD_DATA1 |= (uint32_t)(digit[1] << 26); + SLCD_DATA2 |= (uint32_t)(digit[2] << 26); + SLCD_DATA3 |= (uint32_t)(digit[3] << 26); + break; + + case 3: + /* clear the corresponding segments (COM0..COM3, SEG24..25) */ + SLCD_DATA0 &= (uint32_t)(0xFCFFFFFF); + SLCD_DATA1 &= (uint32_t)(0xFCFFFFFF); + SLCD_DATA2 &= (uint32_t)(0xFCFFFFFF); + SLCD_DATA3 &= (uint32_t)(0xFCFFFFFF); + + /* write the colon of the time (COM0, SEG25) */ + if(type == TIME) + SLCD_DATA0 |= (uint32_t)(0x01 << 25); + /* write the corresponding segments (COM0..COM3, SEG24..25) */ + SLCD_DATA0 |= (uint32_t)(digit[0] << 24); + SLCD_DATA1 |= (uint32_t)(digit[1] << 24); + SLCD_DATA2 |= (uint32_t)(digit[2] << 24); + SLCD_DATA3 |= (uint32_t)(digit[3] << 24); + break; + + case 2: + /* clear the corresponding segments (COM0..COM3, SEG22..23) */ + SLCD_DATA0 &= (uint32_t)(0xFF3FFFFF); + SLCD_DATA1 &= (uint32_t)(0xFF3FFFFF); + SLCD_DATA2 &= (uint32_t)(0xFF3FFFFF); + SLCD_DATA3 &= (uint32_t)(0xFF3FFFFF); + + /* write the corresponding segments (COM0..COM3, SEG22..23) */ + SLCD_DATA0 |= (uint32_t)(digit[0] << 22); + SLCD_DATA1 |= (uint32_t)(digit[1] << 22); + SLCD_DATA2 |= (uint32_t)(digit[2] << 22); + SLCD_DATA3 |= (uint32_t)(digit[3] << 22); + break; + + + case 1: + /* clear the corresponding segments (COM0..COM3, SEG14..15) */ + SLCD_DATA0 &= (uint32_t)(0xFFFF3FFF); + SLCD_DATA1 &= (uint32_t)(0xFFFF3FFF); + SLCD_DATA2 &= (uint32_t)(0xFFFF3FFF); + SLCD_DATA3 &= (uint32_t)(0xFFFF3FFF); + + /* write the corresponding segments (COM0..COM3, SEG14..15) */ + SLCD_DATA0 |= (uint32_t)(digit[0] << 14); + SLCD_DATA1 |= (uint32_t)(digit[1] << 14); + SLCD_DATA2 |= (uint32_t)(digit[2] << 14); + SLCD_DATA3 |= (uint32_t)(digit[3] << 14); + break; + } +} + +/*! + \brief this function clear data in the SLCD DATA register + \param[in] position: position in the SLCD of the digit to write,which can be 1..6 + \param[out] none + \retval none +*/ +void slcd_seg_digit_clear(uint8_t position) +{ + switch (position){ + case 6: + /* clear the corresponding segments (COM0..COM3, SEG30..31) */ + SLCD_DATA0 &= (uint32_t)(0x3FFFFFFF); + SLCD_DATA1 &= (uint32_t)(0x3FFFFFFF); + SLCD_DATA2 &= (uint32_t)(0x3FFFFFFF); + SLCD_DATA3 &= (uint32_t)(0x3FFFFFFF); + break; + + case 5: + /* clear the corresponding segments (COM0..COM3, SEG28..29) */ + SLCD_DATA0 &= (uint32_t)(0xCFFFFFFF); + SLCD_DATA1 &= (uint32_t)(0xCFFFFFFF); + SLCD_DATA2 &= (uint32_t)(0xCFFFFFFF); + SLCD_DATA3 &= (uint32_t)(0xCFFFFFFF); + break; + + case 4: + /* clear the corresponding segments (COM0..COM3, SEG26..27) */ + SLCD_DATA0 &= (uint32_t)(0xF3FFFFFF); + SLCD_DATA1 &= (uint32_t)(0xF3FFFFFF); + SLCD_DATA2 &= (uint32_t)(0xF3FFFFFF); + SLCD_DATA3 &= (uint32_t)(0xF3FFFFFF); + break; + + case 3: + /* clear the corresponding segments (COM0..COM3, SEG24..25) */ + SLCD_DATA0 &= (uint32_t)(0xFCFFFFFF); + SLCD_DATA1 &= (uint32_t)(0xFCFFFFFF); + SLCD_DATA2 &= (uint32_t)(0xFCFFFFFF); + SLCD_DATA3 &= (uint32_t)(0xFCFFFFFF); + break; + + case 2: + /* clear the corresponding segments (COM0..COM3, SEG22..23) */ + SLCD_DATA0 &= (uint32_t)(0xFF3FFFFF); + SLCD_DATA1 &= (uint32_t)(0xFF3FFFFF); + SLCD_DATA2 &= (uint32_t)(0xFF3FFFFF); + SLCD_DATA3 &= (uint32_t)(0xFF3FFFFF); + break; + + case 1: + /* clear the corresponding segments (COM0..COM3, SEG14..15) */ + SLCD_DATA0 &= (uint32_t)(0xFFFF3FFF); + SLCD_DATA1 &= (uint32_t)(0xFFFF3FFF); + SLCD_DATA2 &= (uint32_t)(0xFFFF3FFF); + SLCD_DATA3 &= (uint32_t)(0xFFFF3FFF); + break; + } +} + +/*! + \brief this function clear all the SLCD DATA register + \param[in] none + \param[out] none + \retval none +*/ +void slcd_seg_clear_all(void) +{ + SLCD_DATA0 = 0x0000; + SLCD_DATA1 = 0x0000; + SLCD_DATA2 = 0x0000; + SLCD_DATA3 = 0x0000; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/slcd_seg.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/slcd_seg.h new file mode 100644 index 0000000..fb3ec40 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/slcd_seg.h @@ -0,0 +1,35 @@ +/*! + \file slcd_seg.h + \brief the header file of the slcd segment driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef LCD_SEG_H +#define LCD_SEG_H + +#include "gd32f1x0.h" + +typedef enum +{ + INTEGER = 0, + FLOAT = 1, + TIME = 2 +}slcd_display_enum; + +void slcd_seg_configuration(void); +void slcd_seg_digit_display(uint8_t ch, uint8_t position); +void slcd_seg_number_display(uint32_t num); +void slcd_seg_floatnumber_display(float num); +void slcd_seg_time_display(uint8_t hour, uint8_t minute , uint8_t second); +void slcd_seg_digit_clear(uint8_t position); +void slcd_seg_clear_all(void); + +#endif /* LCD_SEG_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/systick.c new file mode 100644 index 0000000..22ed8da --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_configuration(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if(SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if(0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/systick.h new file mode 100644 index 0000000..5c51338 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SLCD/Digit_display/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_configuration(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_dma/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_dma/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_dma/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_dma/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_dma/main.c new file mode 100644 index 0000000..33a5691 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_dma/main.c @@ -0,0 +1,209 @@ +/*! + \file main.c + \brief SPI fullduplex communication use DMA +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_eval.h" + +#define arraysize 10 + +uint8_t spi0_send_array[arraysize] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA}; +uint8_t spi1_send_array[arraysize] = {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA}; +uint8_t spi0_receive_array[arraysize]; +uint8_t spi1_receive_array[arraysize]; +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint8_t length); + +void rcu_config(void); +void gpio_config(void); +void dma_config(void); +void spi_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* init led1 and led2 */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + /* peripheral clock enable */ + rcu_config(); + /* GPIO config */ + gpio_config(); + /* DMA config */ + dma_config(); + /* SPI config */ + spi_config(); + + /* SPI enable */ + spi_enable(SPI1); + spi_enable(SPI0); + + /* DMA channel enable */ + /* SPI1_Tx DMA channel */ + dma_channel_enable(DMA_CH4); + /* SPI0_Tx DMA channel */ + dma_channel_enable(DMA_CH2); + /* SPI1_Rx DMA channel */ + dma_channel_enable(DMA_CH3); + /* SPI0_Rx DMA channel */ + dma_channel_enable(DMA_CH1); + + /* SPI DMA enable */ + spi_dma_enable(SPI1, SPI_DMA_TRANSMIT); + spi_dma_enable(SPI1, SPI_DMA_RECEIVE); + spi_dma_enable(SPI0, SPI_DMA_TRANSMIT); + spi_dma_enable(SPI0, SPI_DMA_RECEIVE); + + /* wait dma transmit complete */ + while(!dma_flag_get(DMA_CH2,DMA_INT_FLAG_FTF)); + while(!dma_flag_get(DMA_CH4,DMA_INT_FLAG_FTF)); + while(!dma_flag_get(DMA_CH3,DMA_INT_FLAG_FTF)); + while(!dma_flag_get(DMA_CH1,DMA_INT_FLAG_FTF)); + + /* compare receive data with send data */ + if(memory_compare(spi1_receive_array, spi0_send_array, arraysize)) + gd_eval_led_on(LED1); + else + gd_eval_led_off(LED1); + if(memory_compare(spi0_receive_array, spi1_send_array, arraysize)) + gd_eval_led_on(LED2); + else + gd_eval_led_off(LED2); + + while (1); +} + +/*! + \brief configure different peripheral clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_DMA); + rcu_periph_clock_enable(RCU_SPI0); + rcu_periph_clock_enable(RCU_SPI1); +} + +/*! + \brief configure the GPIO peripheral + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* SPI0 GPIO config: SCK/PA5, MISO/PA6, MOSI/PA7 */ + gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + gpio_output_options_set(GPIOA,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + /* SPI1 GPIO config: SCK/PB13, MISO/PB14, MOSI/PB15 */ + gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); +} + +/*! + \brief configure the DMA peripheral + \param[in] none + \param[out] none + \retval none +*/ +void dma_config(void) +{ + dma_parameter_struct dma_init_struct; + /* SPI0 transmit dma config */ + dma_deinit(DMA_CH2); + dma_init_struct.periph_addr = (uint32_t )&SPI_DATA(SPI0); + dma_init_struct.memory_addr = (uint32_t)spi0_send_array; + dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_HIGH; + dma_init_struct.number = arraysize; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init(DMA_CH2, dma_init_struct); + /* SPI1 transmit dma config */ + dma_deinit(DMA_CH4); + dma_init_struct.periph_addr = (uint32_t )&SPI_DATA(SPI1); + dma_init_struct.memory_addr = (uint32_t)spi1_send_array; + dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH ; + dma_init(DMA_CH4, dma_init_struct); + /* SPI0 receive dma config */ + dma_deinit(DMA_CH1); + dma_init_struct.periph_addr = (uint32_t )&SPI_DATA(SPI0); + dma_init_struct.memory_addr = (uint32_t)spi0_receive_array; + dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; + dma_init_struct.priority = DMA_PRIORITY_LOW; + dma_init(DMA_CH1, dma_init_struct); + /* SPI1 receive dma config */ + dma_deinit(DMA_CH3); + dma_init_struct.periph_addr = (uint32_t )&SPI_DATA(SPI1); + dma_init_struct.memory_addr = (uint32_t)spi1_receive_array; + dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; + dma_init_struct.priority = DMA_PRIORITY_MEDIUM; + dma_init(DMA_CH3, dma_init_struct); +} + +/*! + \brief configure the SPI peripheral + \param[in] none + \param[out] none + \retval none +*/ +void spi_config(void) +{ + spi_parameter_struct spi_init_struct; + + /* SPI0 parameter config */ + spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_init_struct.device_mode = SPI_MASTER; + spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; + spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; + spi_init_struct.nss = SPI_NSS_SOFT; + spi_init_struct.prescale = SPI_PSC_8; + spi_init_struct.endian = SPI_ENDIAN_MSB; + spi_init(SPI0, &spi_init_struct); + + /* SPI1 parameter config */ + spi_init_struct.device_mode = SPI_SLAVE; + spi_init_struct.nss = SPI_NSS_SOFT; + spi_init(SPI1, &spi_init_struct); + +} + +/*! + \brief memory compare function + \param[in] src : source data pointer + \param[in] dst : destination data pointer + \param[in] length : the compare data length + \param[out] none + \retval ErrStatus : ERROR or SUCCESS +*/ +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint8_t length) +{ + while (length--){ + if (*src++ != *dst++) + return ERROR; + } + return SUCCESS; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_dma/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_dma/readme.txt new file mode 100644 index 0000000..643819a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_dma/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the master and slave fullduplex communication use dma demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows SPI0 and SPI1 fullduplex +communication use dma mode.After the communicate is complete,if receive data equal to send data,led1 +and led2 turn on, if not led1 and led2 turn off. + + Connect SPI0 SCK PIN(PA5) TO SPI1 SCK PIN(PB13) + Connect SPI0 MISO PIN(PA6) TO SPI1 MISO PIN(PB14) + Connect SPI0 MOSI PIN(PA7) TO SPI1 MOSI PIN(PB15) \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_polling/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_polling/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_polling/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_polling/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_polling/main.c new file mode 100644 index 0000000..bce890c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_polling/main.c @@ -0,0 +1,150 @@ +/*! + \file main.c + \brief SPI fullduplex communication use polling mode +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_libopt.h" +#include "gd32f1x0_eval.h" + +#define arraysize 10 + +uint32_t send_n = 0, receive_n = 0; +uint8_t spi0_send_array[arraysize] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA }; +uint8_t spi1_send_array[arraysize] = {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA }; +uint8_t spi0_receive_array[arraysize]; +uint8_t spi1_receive_array[arraysize]; +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint8_t length); + +void rcu_config(void); +void gpio_config(void); +void spi_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* init led1 and led2 */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + /* peripheral clock enable */ + rcu_config(); + /* GPIO config */ + gpio_config(); + /* SPI config */ + spi_config(); + /* SPI enable */ + spi_enable(SPI1); + spi_enable(SPI0); + /* wait for transmit complete */ + while(send_n < arraysize){ + while(RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_TBE)); + spi_i2s_data_transmit(SPI1, spi1_send_array[send_n]); + while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)); + spi_i2s_data_transmit(SPI0, spi0_send_array[send_n++]); + while(RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_RBNE)); + spi1_receive_array[receive_n] = spi_i2s_data_receive(SPI1); + while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)); + spi0_receive_array[receive_n++] = spi_i2s_data_receive(SPI0); + } + /* compare receive data with send data */ + if(memory_compare(spi1_receive_array, spi0_send_array, arraysize)) + gd_eval_led_on(LED1); + else + gd_eval_led_off(LED1); + + if(memory_compare(spi0_receive_array, spi1_send_array, arraysize)) + gd_eval_led_on(LED2); + else + gd_eval_led_off(LED2); + + while (1); +} + +/*! + \brief configure different peripheral clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_SPI0); + rcu_periph_clock_enable(RCU_SPI1); +} + +/*! + \brief configure the GPIO peripheral + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* SPI0 GPIO config: SCK/PA5, MISO/PA6, MOSI/PA7 */ + gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + /* SPI1 GPIO config: SCK/PB13, MISO/PB14, MOSI/PB15 */ + gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); +} + +/*! + \brief configure the SPI peripheral + \param[in] none + \param[out] none + \retval none +*/ +void spi_config(void) +{ + spi_parameter_struct spi_init_struct; + + /* SPI0 parameter config */ + spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_init_struct.device_mode = SPI_MASTER; + spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; + spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; + spi_init_struct.nss = SPI_NSS_SOFT; + spi_init_struct.prescale = SPI_PSC_8; + spi_init_struct.endian = SPI_ENDIAN_MSB; + spi_init(SPI0, &spi_init_struct); + + /* SPI1 parameter config */ + spi_init_struct.device_mode = SPI_SLAVE; + spi_init_struct.nss = SPI_NSS_SOFT; + spi_init(SPI1, &spi_init_struct); +} + +/*! + \brief memory compare function + \param[in] src: source data pointer + \param[in] dst: destination data pointer + \param[in] length: the compare data length + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint8_t length) +{ + while (length--){ + if (*src++ != *dst++) + return ERROR; + } + return SUCCESS; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_polling/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_polling/readme.txt new file mode 100644 index 0000000..1f4e8c9 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_slave_fullduplex_polling/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the master and slave fullduplex communication use polling demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows SPI0 and SPI1 fullduplex +communication use polling mode.After the communicate is complete,if receive data equal to send data, +led1 and led2 turn on, if not led1 and led2 turn off. + + Connect SPI0 SCK PIN(PA5) TO SPI1 SCK PIN(PB13) + Connect SPI0 MISO PIN(PA6) TO SPI1 MISO PIN(PB14) + Connect SPI0 MOSI PIN(PA7) TO SPI1 MOSI PIN(PB15) \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/gd32f1x0_it.c new file mode 100644 index 0000000..f81af6f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/gd32f1x0_it.c @@ -0,0 +1,149 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" + +#define arraysize 10 +extern uint8_t spi0_send_array[ ]; +extern uint8_t spi1_receive_array[ ]; +extern uint32_t send_n , receive_n ; + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/*! + \brief this function handles SPI0 Handler exception + \param[in] none + \param[out] none + \retval none +*/ +void SPI0_IRQHandler(void) +{ + if (spi_i2s_interrupt_flag_get(SPI0, SPI_I2S_INT_TBE) != RESET){ + /* send data */ + while (spi_i2s_flag_get(SPI0, SPI_FLAG_TBE) == RESET); + spi_i2s_data_transmit(SPI0, spi0_send_array[send_n++]); + if (arraysize == send_n){ + spi_i2s_interrupt_disable(SPI0, SPI_I2S_INT_TBE); + } + } +} + +/*! + \brief this function handles SPI1 Handler exception + \param[in] none + \param[out] none + \retval none +*/ +void SPI1_IRQHandler(void) +{ + /* received data */ + if (spi_i2s_interrupt_flag_get(SPI1, SPI_I2S_INT_RBNE) != RESET) + spi1_receive_array[receive_n++] = spi_i2s_data_receive(SPI1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/gd32f1x0_it.h new file mode 100644 index 0000000..b3b52b8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/gd32f1x0_it.h @@ -0,0 +1,46 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* SPI0 handle function */ +void SPI0_IRQHandler(void); +/* SPI1 handle function */ +void SPI1_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/main.c new file mode 100644 index 0000000..489f706 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/main.c @@ -0,0 +1,138 @@ +/*! + \file main.c + \brief master send and slave receive data use interrupt mode +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +#define arraysize 10 +uint32_t send_n = 0, receive_n = 0; +uint8_t spi0_send_array[arraysize] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA }; +uint8_t spi1_receive_array[arraysize]; +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint8_t length); + +void rcu_config(void); +void gpio_config(void); +void spi_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* init led1 */ + gd_eval_led_init (LED1); + /* NVIC config */ + nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); + nvic_irq_enable(SPI0_IRQn,1,1); + nvic_irq_enable(SPI1_IRQn,0,1); + /* peripheral clock enable */ + rcu_config(); + /* GPIO config */ + gpio_config(); + /* SPI config */ + spi_config(); + /* SPI int enable */ + spi_i2s_interrupt_enable(SPI0, SPI_I2S_INT_TBE); + spi_i2s_interrupt_enable(SPI1, SPI_I2S_INT_RBNE); + /* SPI enable */ + spi_enable(SPI1); + spi_enable(SPI0); + /* wait transmit complete */ + while(receive_n < arraysize); + /* compare receive data with send data */ + if(memory_compare(spi1_receive_array, spi0_send_array, arraysize)) + gd_eval_led_on(LED1); + else + gd_eval_led_off(LED1); + + while(1); + +} + +/*! + \brief configure different peripheral clocks + \param[in] none + \param[out] none + \retval none +*/ +void rcu_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_SPI0); + rcu_periph_clock_enable(RCU_SPI1); +} + +/*! + \brief configure the GPIO peripheral + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* SPI0 GPIO config */ + gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + /* SPI1 GPIO config */ + gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); +} + +/*! + \brief configure the SPI peripheral + \param[in] none + \param[out] none + \retval none +*/ +void spi_config(void) +{ + spi_parameter_struct spi_init_struct; + /* SPI0 parameter config */ + spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_init_struct.device_mode = SPI_MASTER;; + spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;; + spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; + spi_init_struct.nss = SPI_NSS_SOFT; + spi_init_struct.prescale = SPI_PSC_4 ; + spi_init_struct.endian = SPI_ENDIAN_MSB;; + spi_init(SPI0, &spi_init_struct); + /* SPI1 parameter config */ + spi_init_struct.device_mode = SPI_SLAVE; + spi_init_struct.nss = SPI_NSS_SOFT; + spi_init(SPI1, &spi_init_struct); +} + +/*! + \brief memory compare function + \param[in] src : source data pointer + \param[in] dst : destination data pointer + \param[in] length : the compare data length + \param[out] none + \retval ErrStatus : ERROR or SUCCESS +*/ +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint8_t length) +{ + while (length--){ + if (*src++ != *dst++) + return ERROR; + } + return SUCCESS; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/readme.txt new file mode 100644 index 0000000..900c2a2 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/SPI/SPI_Master_transmit_slave_receive_interrupt/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the master transmit and slave receive through interrupt demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This example is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows master send data and +slave receive data use intterupt mode.After the communicate is complete,if receive data equal +to send data,led1 turn on,if not led1 turn off. + + Connect SPI0 SCK PIN(PA5) TO SPI1 SCK PIN(PB13) + Connect SPI0 MISO PIN(PA6) TO SPI1 MISO PIN(PB14) + Connect SPI0 MOSI PIN(PA7) TO SPI1 MOSI PIN(PB15) \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/gd32f1x0_it.c new file mode 100644 index 0000000..abeadac --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/gd32f1x0_it.c @@ -0,0 +1,244 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" + +__IO uint32_t step = 1; + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + timer_event_software_generate(TIMER0,TIMER_EVENT_SRC_CMTG); +} + +/*! + \brief this function handles TIMER0 interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void TIMER0_BRK_UP_TRG_COM_IRQHandler(void) +{ + timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CMT); + + switch(step){ + /* next step: step 2 configuration .A-C` breakover---------------------------- */ + case 1: + /* channel0 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_ENABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE); + + /* channel1 configuration */ + timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE); + + /* channel2 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE); + + step++; + break; + + /* next step: step 3 configuration .B-C` breakover---------------------------- */ + case 2: + /* channel0 configuration */ + timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE); + + /* channel1 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_ENABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE); + + /* channel2 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_ENABLE); + + step++; + break; + + /* next step: step 4 configuration .B-A` breakover---------------------------- */ + case 3: + /* channel0 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_ENABLE); + + /* channel1 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_ENABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE); + + /* channel2 configuration */ + timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE); + + step++; + break; + + /* next step: step 5 configuration .C-A` breakover---------------------------- */ + case 4: + /* channel0 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_ENABLE); + + /* channel1 configuration */ + timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_DISABLE); + + /* channel2 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_ENABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE); + + step++; + break; + + /* next step: step 6 configuration .C-B` breakover---------------------------- */ + case 5: + /* channel0 configuration */ + timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE); + + /* channel1 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_ENABLE); + + /* channel2 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_ENABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE); + + step++; + break; + + /* next step: step 1 configuration .A-B` breakover---------------------------- */ + case 6: + /* channel0 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCX_ENABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_0,TIMER_CCXN_DISABLE); + + /* channel1 configuration */ + timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0); + timer_channel_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_1,TIMER_CCXN_ENABLE); + + /* channel2 configuration */ + timer_channel_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCX_DISABLE); + timer_channel_complementary_output_state_config(TIMER0,TIMER_CH_2,TIMER_CCXN_DISABLE); + + step = 1; + break; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/gd32f1x0_it.h new file mode 100644 index 0000000..aa4e025 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/gd32f1x0_it.h @@ -0,0 +1,45 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/*TIMER0 handle function*/ +void TIMER0_BRK_UP_TRG_COM_IRQHandler(void); + + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/main.c new file mode 100644 index 0000000..aa6c33b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/main.c @@ -0,0 +1,176 @@ +/*! + \file main.c + \brief TIMER0 6-steps demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" +#include "systick.h" + +void gpio_config(void); +void timer_config(void); +void nvic_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + + /*configure PA8 PA9 PA10(TIMER0 CH0 CH1 CH2) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); + + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); + + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10); + + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_8); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_9); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_10); + + /*configure PB13 PB14 PB15(TIMER0 CH0N CH1N CH2N) as alternate function*/ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_14); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15); + + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_13); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_14); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_15); + + /*configure PA6(TIMER0 BKIN) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_6); +} + +/** + \brief configure the nested vectored interrupt controller + \param[in] none + \param[out] none + \retval none + */ +void nvic_config(void) +{ + nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); + nvic_irq_enable(TIMER0_BRK_UP_TRG_COM_IRQn, 0, 1); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ + /* ----------------------------------------------------------------------- + TIMER0 configuration: + generate 3 complementary PWM signal. + TIMER0CLK is fixed to systemcoreclock, the TIMER0 prescaler is equal to 72 + so the TIMER0 counter clock used is 1MHz. + insert a dead time equal to 72/systemcoreclock =1us + configure the break feature, active at low level, and using the automatic + output enable feature. + use the locking parameters level0. + ----------------------------------------------------------------------- */ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + timer_break_parameter_struct timer_breakpara; + + rcu_periph_clock_enable(RCU_TIMER0); + + timer_deinit(TIMER0); + + /* TIMER0 configuration */ + timer_initpara.prescaler = 71; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 599; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER0, &timer_initpara); + + /* CH0/CH0N,CH1/CH1N and CH2/CH2N configuration in timing mode */ + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH; + + timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocintpara); + timer_channel_output_config(TIMER0, TIMER_CH_1, &timer_ocintpara); + timer_channel_output_config(TIMER0, TIMER_CH_2, &timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0,299); + timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_TIMING); + timer_channel_output_shadow_config(TIMER0, TIMER_CH_0 ,TIMER_OC_SHADOW_ENABLE); + + timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1,299); + timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_TIMING); + timer_channel_output_shadow_config(TIMER0, TIMER_CH_1, TIMER_OC_SHADOW_ENABLE); + + timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_2,299); + timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_TIMING); + timer_channel_output_shadow_config(TIMER0, TIMER_CH_2, TIMER_OC_SHADOW_ENABLE); + + /* automatic output enable, break, dead time and lock configuration*/ + timer_breakpara.runoffstate = TIMER_ROS_STATE_ENABLE; + timer_breakpara.ideloffstate = TIMER_IOS_STATE_ENABLE ; + timer_breakpara.deadtime = 72; + timer_breakpara.breakpolarity = TIMER_BREAK_POLARITY_LOW; + timer_breakpara.outputautostate = TIMER_OUTAUTO_ENABLE; + timer_breakpara.protectmode = TIMER_CCHP_PROT_OFF; + timer_breakpara.breakstate = TIMER_BREAK_ENABLE; + timer_break_config(TIMER0, &timer_breakpara); + + /* TIMER0 primary output function enable */ + timer_primary_output_config(TIMER0, ENABLE); + + /* TIMER0 channel control update interrupt enable */ + timer_interrupt_enable(TIMER0, TIMER_INT_CMT); + /* TIMER0 break interrupt disable */ + timer_interrupt_disable(TIMER0, TIMER_INT_BRK); + + /* TIMER0 counter enable */ + timer_enable(TIMER0); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + systick_config(); + nvic_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/readme.txt new file mode 100644 index 0000000..05d1503 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/readme.txt @@ -0,0 +1,37 @@ +/*! + \file readme.txt + \brief description of the TIMER0 6-steps demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure the TIMER0 peripheral to generate three complementary TIMER0 signals +(for BLDC ) with dead time. + + TIMER0CLK is fixed to systemcoreclock, the TIMER0 prescaler is equal to 72 so the +TIMER0 counter clock used is 1MHz. + + Channel change sequence: + AB`->AC`->BC`->BA`->CA`->CB` +step1:1-0 0-1 0-0 (CH0-CH0N CH1-CH1N CH2-CH2N) +step2:1-0 0-0 0-1 (CH0-CH0N CH1-CH1N CH2-CH2N) +step3:0-0 1-0 0-1 (CH0-CH0N CH1-CH1N CH2-CH2N) +step4:0-1 1-0 0-0 (CH0-CH0N CH1-CH1N CH2-CH2N) +step5:0-1 0-0 1-0 (CH0-CH0N CH1-CH1N CH2-CH2N) +step6:0-0 0-1 1-0 (CH0-CH0N CH1-CH1N CH2-CH2N) + + Connect the TIMER0 pins to an oscilloscope to monitor the different waveforms: + - TIMER0_CH0 pin (PA8) + - TIMER0_CH0N pin (PB13) + - TIMER0_CH1 pin (PA9) + - TIMER0_CH1N pin (PB14) + - TIMER0_CH2 pin (PA10) + - TIMER0_CH2N pin (PB15) diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/systick.c new file mode 100644 index 0000000..1391129 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/systick.c @@ -0,0 +1,63 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 10Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 10U)){ + /* capture error */ + while (1){ + } + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00U); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0U != delay){ + } +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0U != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_6-steps/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_complementarysignals/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_complementarysignals/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_complementarysignals/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_complementarysignals/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_complementarysignals/main.c new file mode 100644 index 0000000..8a7e86d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_complementarysignals/main.c @@ -0,0 +1,139 @@ +/*! + \file main.c + \brief TIMER0 complementary signals demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_config(void); +void timer_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + + /*Configure PA8 PA9 PA10(TIMER0 CH0 CH1 CH2) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); + + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); + + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10); + + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_8); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_9); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_10); + + /*Configure PB13 PB14 PB15(TIMER0 CH0N CH1N CH2N) as alternate function*/ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_14); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15); + + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_13); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_14); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_15); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ +/* ----------------------------------------------------------------------- + TIMER0 configuration to: + generate 3 complementary PWM signals with 3 different duty cycles: + TIMER0CLK is fixed to systemcoreclock, the TIMER0 prescaler is equal to 3600 so the + TIMER0 counter clock used is 20KHz. + the three duty cycles are computed as the following description: + the channel 0 duty cycle is set to 25% so channel 1N is set to 75%. + the channel 1 duty cycle is set to 50% so channel 2N is set to 50%. + the channel 2 duty cycle is set to 75% so channel 3N is set to 25%. + ----------------------------------------------------------------------- */ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + + rcu_periph_clock_enable(RCU_TIMER0); + + timer_deinit(TIMER0); + + /* TIMER0 configuration */ + timer_initpara.prescaler = 3599; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 15999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER0, &timer_initpara); + + /* CH1,CH2 and CH3 configuration in PWM mode 0 */ + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + + timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocintpara); + timer_channel_output_config(TIMER0, TIMER_CH_1, &timer_ocintpara); + timer_channel_output_config(TIMER0, TIMER_CH_2, &timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0,3999); + timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE); + + timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1, 7999); + timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER0, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE); + + timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_2, 11999); + timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER0, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE); + + timer_primary_output_config(TIMER0, ENABLE); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER0); + timer_enable(TIMER0); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_complementarysignals/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_complementarysignals/readme.txt new file mode 100644 index 0000000..3a6e197 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_complementarysignals/readme.txt @@ -0,0 +1,31 @@ +/*! + \file readme.txt + \brief description of the TIMER0 complementary signals demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure the TIMER0 peripheral to generate three complementary TIMER0 signals. + TIMER0CLK is fixed to systemcoreclock, the TIMER0 prescaler is equal to 3600 so the +TIMER0 counter clock used is 20KHz. + + The Three duty cycles are computed as the following description: + The channel 0 duty cycle is set to 25% so channel 0N is set to 75%. + The channel 1 duty cycle is set to 50% so channel 1N is set to 50%. + The channel 2 duty cycle is set to 75% so channel 2N is set to 25%. + + Connect the TIMER0 pins to an oscilloscope to monitor the different waveforms: + - TIMER0_CH0 pin (PA8) + - TIMER0_CH0N pin (PB13) + - TIMER0_CH1 pin (PA9) + - TIMER0_CH1N pin (PB14) + - TIMER0_CH2 pin (PA10) + - TIMER0_CH2N pin (PB15) diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_deadtime_break/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_deadtime_break/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_deadtime_break/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_deadtime_break/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_deadtime_break/main.c new file mode 100644 index 0000000..23a652a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_deadtime_break/main.c @@ -0,0 +1,135 @@ +/*! + \file main.c + \brief TIMER0 deadtime break demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_config(void); +void timer_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + + /*configure PA8(TIMER0 CH0) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_8); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_8); + + /*configure PB13(TIMER0 CH0N) as alternate function*/ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_13); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_13); + + /*configure PA6(TIMER0 BKIN) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_6); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ + /* ----------------------------------------------------------------------- + TIMER0 configuration: + generate 1 complementary PWM signal. + TIMER0CLK is fixed to systemcoreclock, the TIMER0 prescaler is equal to 2 so the + TIMER0 counter clock used is 36MHz. + the duty cycle is computed as the following description: + the channel 0 duty cycle is set to 25% so channel 0N is set to 75%. + + insert a dead time equal to ((32+31)*16*4)/systemcoreclock = 56us + + configure the break feature, active at high level, and using the automatic + output enable feature. + + use the locking parameters level1. + ----------------------------------------------------------------------- */ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + timer_break_parameter_struct timer_breakpara; + + rcu_periph_clock_enable(RCU_TIMER0); + + timer_deinit(TIMER0); + + /* TIMER0 configuration */ + timer_initpara.prescaler = 1; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 15999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV4; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER0,&timer_initpara); + + /* CH0/CH0N configuration in PWM mode 0 */ + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + + timer_channel_output_config(TIMER0,TIMER_CH_0,&timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,3999); + timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER0,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE); + + /* automatic output enable, break, dead time and lock configuration*/ + timer_breakpara.runoffstate = TIMER_ROS_STATE_DISABLE; + timer_breakpara.ideloffstate = TIMER_IOS_STATE_DISABLE ; + timer_breakpara.deadtime = 255; + timer_breakpara.breakpolarity = TIMER_BREAK_POLARITY_LOW; + timer_breakpara.outputautostate = TIMER_OUTAUTO_ENABLE; + timer_breakpara.protectmode = TIMER_CCHP_PROT_0; + timer_breakpara.breakstate = TIMER_BREAK_ENABLE; + timer_break_config(TIMER0,&timer_breakpara); + + /* TIMER0 primary output function enable */ + timer_primary_output_config(TIMER0,ENABLE); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER0); + + /* TIMER0 counter enable */ + timer_enable(TIMER0); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_deadtime_break/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_deadtime_break/readme.txt new file mode 100644 index 0000000..94072dc --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_deadtime_break/readme.txt @@ -0,0 +1,32 @@ +/*! + \file readme.txt + \brief description of the TIMER0 deadtime break demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure the TIMER0 peripheral to generate complementary signals, to insert a +defined dead time value, to use the break feature and to lock the desired +parameters. + + TIMER0CLK is fixed to systemcoreclock, the TIMER0 prescaler is equal to 2 ,so +the TIMER0 counter clock used is 36MHz. + + The duty cycle is computed as the following description: + the channel 0 duty cycle is set to 25% so channel 0N is set to 75%. + + Insert a dead time equal to (63*16*4)/systemcoreclock = 56us + + Configure the break feature, active at Low level(with GND), and using the +automatic output enable feature. + + Use the Locking parameters level1. + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma/main.c new file mode 100644 index 0000000..5ac5466 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma/main.c @@ -0,0 +1,156 @@ +/*! + \file main.c + \brief TIMER0 dma demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +#define TIMER0_CH0CV ((uint32_t)0x040012c34) +uint16_t buffer[3]={249,499,749}; + +void gpio_config(void); +void timer_config(void); +void dma_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + + /*configure PA8(TIMER0 CH0) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); + + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_8); +} + + +/** + \brief configure the DMA peripheral + \param[in] none + \param[out] none + \retval none + */ +void dma_config(void) +{ + dma_parameter_struct dma_init_struct; + + /* enable DMA clock */ + rcu_periph_clock_enable(RCU_DMA); + + /* initialize DMA channel4 */ + dma_deinit(DMA_CH4); + + /* DMA channel4 initialize */ + dma_deinit(DMA_CH4); + dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; + dma_init_struct.memory_addr = (uint32_t)buffer; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT; + dma_init_struct.number = 3; + dma_init_struct.periph_addr = (uint32_t)TIMER0_CH0CV; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT; + dma_init_struct.priority = DMA_PRIORITY_HIGH; + dma_init(DMA_CH4, dma_init_struct); + + /* configure DMA mode */ + dma_circulation_enable(DMA_CH4); + dma_memory_to_memory_disable(DMA_CH4); + + /* enable DMA channel4 */ + dma_channel_enable(DMA_CH4); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ + /* TIMER0 DMA Transfer example ------------------------------------------------- + TIMER0CLK = 72MHz, Prescaler = 72 + TIMER0 counter clock = systemcoreclock/72 = 1MHz. + + the objective is to configure TIMER0 channel 1 to generate PWM + signal with a frequency equal to 1KHz and a variable duty cycle(25%,50%,75%) that is + changed by the DMA after a specific number of update DMA request. + + the number of this repetitive requests is defined by the TIMER0 repetition counter, + each 2 update requests, the TIMER0 Channel 0 duty cycle changes to the next new + value defined by the buffer . + -----------------------------------------------------------------------------*/ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + + rcu_periph_clock_enable(RCU_TIMER0); + + timer_deinit(TIMER0); + + /* TIMER0 configuration */ + timer_initpara.prescaler = 71; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 1; + timer_init(TIMER0,&timer_initpara); + + /* CH0 configuration in PWM1 mode 0 */ + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, buffer[0]); + timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE); + + /* TIMER0 primary output enable */ + timer_primary_output_config(TIMER0, ENABLE); + + /* TIMER0 update DMA request enable */ + timer_dma_enable(TIMER0, TIMER_DMA_UPD); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER0); + + /* TIMER0 counter enable */ + timer_enable(TIMER0); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + dma_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma/readme.txt new file mode 100644 index 0000000..673e53c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma/readme.txt @@ -0,0 +1,28 @@ +/*! + \file readme.txt + \brief description of the TIMER0 DMA demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +use DMA with TIMER0 update request to transfer data from memory to TIMER0 +capture compare register 0. + + TIMER0CLK is fixed to systemcoreclock, the TIMER0 prescaler is equal to 72 +so the TIMER0 counter clock used is 1MHz. + + The objective is to configure TIMER0 channel 0(PA8) to generate PWM signal with +a frequency equal to 1KHz and a variable duty cycle(25%,50%,75%) that is changed +by the DMA after a specific number of Update DMA request. + + The number of this repetitive requests is defined by the TIMER0 repetition counter, +each 2 update requests, the TIMER0 Channel 0 duty cycle changes to the next new +value defined by the buffer. \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma_burst/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma_burst/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma_burst/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma_burst/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma_burst/main.c new file mode 100644 index 0000000..a861ffa --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma_burst/main.c @@ -0,0 +1,189 @@ +/*! + \file main.c + \brief TIMER0 dma burst demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +#define TIMER0_DMATB ((uint32_t)0x040012C4C) +uint16_t buffer[8] = {99,199,299,399,499,599,699,799}; + +void gpio_config(void); +void timer_config(void); +void dma_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + + /*configure PA8(TIMER0 CH0) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_8); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_8); + + /*configure PA9(TIMER0 CH1) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_9); + + /*configure PA10(TIMER0 CH2) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_10); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_10); + + /*configure PA11(TIMER0 CH3) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_11); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_11); +} + +/** + \brief configure the DMA peripheral + \param[in] none + \param[out] none + \retval none + */ +void dma_config(void) +{ + dma_parameter_struct dma_init_struct; + + /* enable DMA clock */ + rcu_periph_clock_enable(RCU_DMA); + + /* initialize DMA channel4 */ + dma_deinit(DMA_CH4); + + /* DMA channel4 initialize */ + dma_deinit(DMA_CH4); + dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; + dma_init_struct.memory_addr = (uint32_t)buffer; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT; + dma_init_struct.number = 8; + dma_init_struct.periph_addr = (uint32_t)TIMER0_DMATB; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT; + dma_init_struct.priority = DMA_PRIORITY_HIGH; + dma_init(DMA_CH4,dma_init_struct); + + /* configure DMA mode */ + dma_circulation_enable(DMA_CH4); + dma_memory_to_memory_disable(DMA_CH4); + + /* enable DMA channel4 */ + dma_channel_enable(DMA_CH4); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ + /* TIMER0 DMA transfer example ---------------------------------------------------- + TIMER0CLK = 72MHz, prescaler = 72 + TIMER0 counter clock = systemcoreclock/72 = 1MHz. + + The objective is to configure TIMER0 channel 0~3(PA8~PA11) to generate PWM signal. + capture compare register 0~3 are to be updated twice per circle. On the first update + DMA request, data1 is transferred to CH0CV, data2 is transferred to CH1CV, data3 is + transferred to CH2CV, data4 is transferred to CH3CV and duty cycle(10%,20%,30%,40%). + On the second update DMA request, data5 is transferred to CH0CV, data6 is transferred + to CH1CV, data7 is transferred to CH2CV, data8 is transferred to CH3CV and duty cycle + (50%,60%,70%,80%). + -----------------------------------------------------------------------------------*/ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + + rcu_periph_clock_enable(RCU_TIMER0); + + timer_deinit(TIMER0); + + /* TIMER0 configuration */ + timer_initpara.prescaler = 71; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER0,&timer_initpara); + + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + + timer_channel_output_config(TIMER0,TIMER_CH_0,&timer_ocintpara); + timer_channel_output_config(TIMER0,TIMER_CH_1,&timer_ocintpara); + timer_channel_output_config(TIMER0,TIMER_CH_2,&timer_ocintpara); + timer_channel_output_config(TIMER0,TIMER_CH_3,&timer_ocintpara); + + /* CH0 configuration in PWM0 mode */ + timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,buffer[0]); + timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER0,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE); + + /* CH1 configuration in PWM0 mode */ + timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_1,buffer[0]); + timer_channel_output_mode_config(TIMER0,TIMER_CH_1,TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER0,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE); + + /* CH2 configuration in PWM0 mode */ + timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_2,buffer[0]); + timer_channel_output_mode_config(TIMER0,TIMER_CH_2,TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER0,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE); + + /* CH3 configuration in PWM0 mode */ + timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_3,buffer[0]); + timer_channel_output_mode_config(TIMER0,TIMER_CH_3,TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER0,TIMER_CH_3,TIMER_OC_SHADOW_DISABLE); + + /* TIMER0 primary output enable */ + timer_primary_output_config(TIMER0,ENABLE); + + /* TIMER0 update DMA request enable */ + timer_dma_transfer_config(TIMER0,TIMER_DMACFG_DMATA_CH0CV,TIMER_DMACFG_DMATC_4TRANSFER); + timer_dma_enable(TIMER0,TIMER_DMA_UPD); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER0); + + /* TIMER0 counter enable */ + timer_enable(TIMER0); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + dma_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma_burst/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma_burst/readme.txt new file mode 100644 index 0000000..6c6be8a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER0_dma_burst/readme.txt @@ -0,0 +1,28 @@ +/*! + \file readme.txt + \brief description of the TIMER0 DMA burst demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +use DMA with TIMER0 update request to transfer data from memory to TIMER0 capture +compare register 0~3. + + TIMER0CLK is fixed to systemcoreclock, the TIMER0 prescaler is equal to 72 +so the TIMER0 counter clock used is 1MHz. + + The objective is to configure TIMER0 channel 0~3(PA8~PA11) to generate PWM signal. +capture compare register 0~3 are to be updated twice per circle. On the first update +DMA request, data1 is transferred to CH0CV, data2 is transferred to CH1CV, data3 is +transferred to CH2CV, data4 is transferred to CH3CV and duty cycle(10%,20%,30%,40%). +On the second update DMA request, data5 is transferred to CH0CV, data6 is transferred +to CH1CV, data7 is transferred to CH2CV, data8 is transferred to CH3CV and duty cycle +(50%,60%,70%,80%). diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_exttrigger/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_exttrigger/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_exttrigger/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_exttrigger/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_exttrigger/main.c new file mode 100644 index 0000000..2618930 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_exttrigger/main.c @@ -0,0 +1,118 @@ +/*! + \file main.c + \brief TIMER1 external trigger demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_config(void); +void timer_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + + /*configure PA2(TIMER1 CH2) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_2); + + /*configure PA5(TIMER1 CH0) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_5); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ + /* Timer with an external trigger ------------------------------------- + TIMER1 is configured as slave timer for an external trigger connected + to TIMER1 CI0 pin : + - The TIMER1 CI0FE0 is used as trigger input + - rising edge is used to start the TIMER1: trigger mode. + - TIMER1 CH2 is used PWM0 Mode + the starts of the TIMER1 counter are controlled by the + external trigger. + -------------------------------------------------------------------- */ + timer_oc_parameter_struct timer_ocinitpara; + timer_parameter_struct timer_initpara; + timer_ic_parameter_struct timer_icinitpara; + + rcu_periph_clock_enable(RCU_TIMER1); + + timer_deinit(TIMER1); + + /* TIMER1 configuration */ + timer_initpara.prescaler = 359; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 7999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER1, &timer_initpara); + + /* CH2 configuration in OC PWM0 mode */ + timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocinitpara.outputstate = TIMER_CCX_ENABLE; + timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + timer_channel_output_config(TIMER1, TIMER_CH_2, &timer_ocinitpara); + + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_2, 3999); + timer_channel_output_mode_config(TIMER1, TIMER_CH_2, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER1, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE); + + /* TIMER1 CH0 input capture configuration */ + timer_icinitpara.icpolarity = TIMER_IC_POLARITY_RISING; + timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI; + timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1; + timer_icinitpara.icfilter = 0x02; + timer_input_capture_config(TIMER1, TIMER_CH_0, &timer_icinitpara); + + /* slave mode selection : TIMER1 */ + /* TIMER1 input trigger : external trigger connected to CI0 */ + timer_input_trigger_source_select(TIMER1, TIMER_SMCFG_TRGSEL_CI0FE0); + timer_slave_mode_select(TIMER1, TIMER_SLAVE_MODE_EVENT); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER1); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_exttrigger/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_exttrigger/readme.txt new file mode 100644 index 0000000..8d2708b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_exttrigger/readme.txt @@ -0,0 +1,27 @@ +/*! + \file readme.txt + \brief description of the TIMER1 external trigger demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +start TIMER peripherals with an external trigger. + + TIMER1 is configured as slave timer for an external trigger connected to +TIMER1 TI0 pin : + - The TIMER1 TI0FP0 is used as trigger input + - Rising edge is used to start the TIMER1: trigger mode. + - TIMER1 is used PWM0 Mode + The starts of the TIMER1 counter are controlled by the external trigger. + + Connect the TIMER1 CH2 pin(PA2) to an oscilloscope to monitor the waveform. + Connect the TIMER1 CH0 pin(PA5) to +3V3 on the board as a external trigger with a +rising edge. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_ocactive/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_ocactive/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_ocactive/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_ocactive/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_ocactive/main.c new file mode 100644 index 0000000..473cd26 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_ocactive/main.c @@ -0,0 +1,116 @@ +/*! + \file main.c + \brief TIMER1 oc active demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_config(void); +void timer_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + + /* configure PA0 PA1 PA2(TIMER1 CH0 CH1 CH2) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0); + + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1); + + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); + + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_0); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_1); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_2); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ + /* --------------------------------------------------------------- + TIMER1 configuration: + TIMER1CLK = SystemCoreClock / 36000 = 2K, + and generate 3 signals with 3 different delays: + TIMER1_CH0 delay = 4000/2000 = 2s + TIMER1_CH1 delay = 8000/2000 = 4s + TIMER1_CH2 delay = 12000/2000 = 6s + --------------------------------------------------------------- */ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + + rcu_periph_clock_enable(RCU_TIMER1); + + timer_deinit(TIMER1); + + /* TIMER1 configuration */ + timer_initpara.prescaler = 35999; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 19999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER1, &timer_initpara); + + /* CH0,CH1 and CH2 configuration in OC active mode */ + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + + timer_channel_output_config(TIMER1, TIMER_CH_0, &timer_ocintpara); + timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocintpara); + timer_channel_output_config(TIMER1, TIMER_CH_2, &timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_0, 3999); + timer_channel_output_mode_config(TIMER1, TIMER_CH_0, TIMER_OC_MODE_ACTIVE); + timer_channel_output_shadow_config(TIMER1, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE); + + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 7999); + timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_ACTIVE); + timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE); + + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_2, 11999); + timer_channel_output_mode_config(TIMER1, TIMER_CH_2, TIMER_OC_MODE_ACTIVE); + timer_channel_output_shadow_config(TIMER1, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER1); + timer_enable(TIMER1); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_ocactive/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_ocactive/readme.txt new file mode 100644 index 0000000..4b0844f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_ocactive/readme.txt @@ -0,0 +1,40 @@ +/*! + \file readme.txt + \brief description of the TIMER1 OC active demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure the TIMER peripheral to generate three different signals with three +different delays. + + The TIMxCLK frequency is set to systemcoreclock (72MHz), the prescaler is 36000 +so the TIMER1 counter clock is 2KHz. + + And generate 3 signals with 3 different delays: + TIMER1_CH0 delay = 4000/2000 = 2s + TIMER1_CH1 delay = 8000/2000 = 4s + TIMER1_CH2 delay = 12000/2000 = 6s + + Connect the TIMER1 pins to leds to watch the signal: + - TIMER1_CH0 pin (PA0) + - TIMER1_CH1 pin (PA1) + - TIMER1_CH2 pin (PA2) + + if use GD32150R-EVAL board: + - LED2 pin (PC11) + - LED3 pin (PC12) + - LED4 pin (PD2) + + if use GD32190R-EVAL board: + - LED2 pin (PA12) + - LED3 pin (PB6) + - LED4 pin (PB7) diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_octoggle/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_octoggle/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_octoggle/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_octoggle/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_octoggle/main.c new file mode 100644 index 0000000..db970e9 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_octoggle/main.c @@ -0,0 +1,94 @@ +/*! + \file main.c + \brief TIMER1 oc toggle demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_config(void); +void timer_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOB); + + /* configure PB3(TIMER1 CH1) as alternate function*/ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3); + + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_3); +} + +/** + \brief configure the timer peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ + /* --------------------------------------------------------------------------- + TIMER1 configuration: output compare toggle mode: + TIMER1CLK = systemcoreclock / 3600 = 20K, + CH1 update rate = TIMER1 counter clock / CH1VAL = 20000/4000 = 5 Hz + ----------------------------------------------------------------------------*/ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + + rcu_periph_clock_enable(RCU_TIMER1); + + timer_deinit(TIMER1); + + /* TIMER1 configuration */ + timer_initpara.prescaler = 3599; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 3999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER1,&timer_initpara); + + /* CH1 configuration in OC TOGGLE mode */ + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 3999); + timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_TOGGLE); + timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER1); + timer_enable(TIMER1); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_octoggle/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_octoggle/readme.txt new file mode 100644 index 0000000..33805c1 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_octoggle/readme.txt @@ -0,0 +1,24 @@ +/*! + \file readme.txt + \brief description of the TIMER1 OC toggle demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure the TIMER peripheral to generate the toggle signal. + + The TIMxCLK frequency is set to systemcoreclock (72MHz), the prescaler is 3600 +so the TIMER1 counter clock is 20KHz. + + TIMER1 configuration: output compare toggle mode: + CH1 update rate = TIMER1 counter clock / CH1VAL = 20000/4000 = 5 Hz. + + Connect the TIMER1 CH1 pin(PB3) to an oscilloscope to monitor the waveform. \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_pwmout/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_pwmout/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_pwmout/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_pwmout/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_pwmout/main.c new file mode 100644 index 0000000..dd5586a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_pwmout/main.c @@ -0,0 +1,120 @@ +/*! + \file main.c + \brief TIMER1 PWM output demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_config(void); +void timer_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOB); + + /*configure PB3 PB10 PB11(TIMER1 CH1 CH2 CH3) as alternate function*/ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11); + + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_3); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_10); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_11); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ + /* ----------------------------------------------------------------------- + TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles: + TIMER1CLK = SystemCoreClock / 72 = 1MHz + + TIMER1 channel 1 duty cycle = (4000/ 16000)* 100 = 25% + TIMER1 channel 2 duty cycle = (8000/ 16000)* 100 = 50% + TIMER1 channel 3 duty cycle = (12000/ 16000)* 100 = 75% + ----------------------------------------------------------------------- */ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + + rcu_periph_clock_enable(RCU_TIMER1); + + timer_deinit(TIMER1); + + /* TIMER1 configuration */ + timer_initpara.prescaler = 71; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 15999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER1,&timer_initpara); + + /* CH1, CH2 and CH3 configuration in PWM0 mode */ + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + + timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocintpara); + timer_channel_output_config(TIMER1, TIMER_CH_2, &timer_ocintpara); + timer_channel_output_config(TIMER1, TIMER_CH_3, &timer_ocintpara); + + /* CH1 configuration in PWM mode1,duty cycle 25% */ + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 3999); + timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE); + + /* CH2 configuration in PWM mode1,duty cycle 50% */ + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_2, 7999); + timer_channel_output_mode_config(TIMER1, TIMER_CH_2, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER1, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE); + + /* CH3 configuration in PWM mode1,duty cycle 75% */ + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_3, 11999); + timer_channel_output_mode_config(TIMER1, TIMER_CH_3, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(TIMER1, TIMER_CH_3, TIMER_OC_SHADOW_DISABLE); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER1); + /* auto-reload preload enable */ + timer_enable(TIMER1); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_pwmout/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_pwmout/readme.txt new file mode 100644 index 0000000..6ed6dd3 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_pwmout/readme.txt @@ -0,0 +1,28 @@ +/*! + \file readme.txt + \brief description of the TIMER1 PWM output demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +configure the TIMER peripheral in PWM (Pulse Width Modulation) mode. + + The TIMxCLK frequency is set to systemcoreclock (72MHz), the prescaler is 72 +so the TIMER1 counter clock is 1MHz. + + TIMER1 Channel1 duty cycle = (4000/ 16000)* 100 = 25%. + TIMER1 Channel2 duty cycle = (8000/ 16000)* 100 = 50%. + TIMER1 Channel3 duty cycle = (12000/ 16000)* 100 = 75%. + + Connect the TIMER1 pins to an oscilloscope to monitor the different waveforms: + - TIMER1_CH1 pin (PB3) + - TIMER1_CH2 pin (PB10) + - TIMER1_CH3 pin (PB11) diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_singlepulse/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_singlepulse/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_singlepulse/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_singlepulse/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_singlepulse/main.c new file mode 100644 index 0000000..977ec27 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_singlepulse/main.c @@ -0,0 +1,121 @@ +/*! + \file main.c + \brief TIMER1 single pulse demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_config(void); +void timer_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + + /*configure PA0 PA1(TIMER1 CH0 CH1) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_0); + + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1); + + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_0); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_1); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ + /* ----------------------------------------------------------------------- + TIMER1 configuration: single pulse mode + the external signal is connected to TIMER1 CH0 pin (PA0) and the falling + edge is used as active edge. + the single pulse signal is output on TIMER1 CH1 pin (PA1). + + the TIMER1CLK frequency is set to systemcoreclock (72MHz),the prescaler is + 4,so the TIMER1 counter clock is 18MHz. + + single pulse value = (TIMER1_Period - TIMER1_Pulse) / TIMER1 counter clock + = (65535 - 11535) / 18MHz = 3.0 ms. + ----------------------------------------------------------------------- */ + timer_oc_parameter_struct timer_ocinitpara; + timer_parameter_struct timer_initpara; + timer_ic_parameter_struct timer_icinitpara; + + rcu_periph_clock_enable(RCU_TIMER1); + + timer_deinit(TIMER1); + + /* TIMER1 configuration */ + timer_initpara.prescaler = 3; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 65535; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER1, &timer_initpara); + + /* auto-reload preload disable */ + timer_auto_reload_shadow_disable(TIMER1); + + /* CH1 configuration in OC PWM2 mode */ + timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocinitpara.outputstate = TIMER_CCX_ENABLE; + timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocinitpara); + + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 11535); + timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM1); + timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE); + + /* TIMER1 CH0 input capture configuration */ + timer_icinitpara.icpolarity = TIMER_IC_POLARITY_FALLING; + timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI; + timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1; + timer_icinitpara.icfilter = 0x00; + timer_input_capture_config(TIMER1, TIMER_CH_0, &timer_icinitpara); + + /* single pulse mode selection */ + timer_single_pulse_mode_config(TIMER1, TIMER_SP_MODE_SINGLE); + + /* slave mode selection : TIMER1 */ + /* TIMER1 input trigger : external trigger connected to CI0 */ + timer_input_trigger_source_select(TIMER1, TIMER_SMCFG_TRGSEL_CI0FE0); + timer_slave_mode_select(TIMER1, TIMER_SLAVE_MODE_EVENT); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_singlepulse/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_singlepulse/readme.txt new file mode 100644 index 0000000..c934272 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER1_singlepulse/readme.txt @@ -0,0 +1,30 @@ +/*! + \file readme.txt + \brief description of the TIMER1 single pulse demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32F150R-EVAL/GD32190R-EVAL board, it shows how +to configure the TIMER1 peripheral in single pulse mode. + The external signal is connected to TIMER1 CH0 pin (PA0) and the falling +edge is used as active edge. + + The single pulse signal is output on TIMER1 CH1 pin (PA1). + + The TIMER1CLK frequency is set to systemcoreclock (72MHz),the prescaler is +4,so the TIMER1 counter clock is 18MHz. + + single pulse value = (TIMER1_period - TIMER1_pulse) / TIMER1 counter clock + = (65535 - 11535) / 18MHz = 3.0 ms. + + Connect the TIMER1 CH0 pin (PA0)to KEY_TAMPER(PC13), When KEY_TAMPER is pressed, +a single pulse is generated. + Connect the TIMER1 CH1 pin (PA1) to an oscilloscope to monitor the waveform. \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/gd32f1x0_it.c new file mode 100644 index 0000000..451cf2d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/gd32f1x0_it.c @@ -0,0 +1,153 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include + +__IO uint16_t readvalue1 = 0, readvalue2 = 0; +__IO uint16_t ccnumber = 0; +__IO uint32_t count = 0; +__IO float fre = 0; + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/** + * @brief This function handles TIMER2 interrupt request. + * @param None + * @retval None + */ +void TIMER2_IRQHandler(void) +{ + if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH0)){ + /* clear channel 0 interrupt bit */ + timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_CH0); + + if(0 == ccnumber){ + /* read channel 0 capture value */ + readvalue1 = timer_channel_capture_value_register_read(TIMER2, TIMER_CH_0); + ccnumber = 1; + }else if(1 == ccnumber){ + /* read channel 0 capture value */ + readvalue2 = timer_channel_capture_value_register_read(TIMER2, TIMER_CH_0); + + if(readvalue2 > readvalue1){ + count = (readvalue2 - readvalue1); + }else{ + count = ((0xFFFF - readvalue1) + readvalue2); + } + + fre = (float)1000000 / count; + printf("\r\nthe value1 is %d, the value2 is %d\n", readvalue1, readvalue2); + printf("\r\nthe count is %d\n", count); + printf("\r\nthe frequence is %f\r\n", fre); + ccnumber = 0; + } + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/gd32f1x0_it.h new file mode 100644 index 0000000..8e4ed00 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/gd32f1x0_it.h @@ -0,0 +1,44 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* TIMER2 handle function */ +void TIMER2_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/main.c new file mode 100644 index 0000000..e09f0c0 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/main.c @@ -0,0 +1,123 @@ +/*! + \file main.c + \brief TIMER2 input capture demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_configuration(void); +void timer_configuration(void); +void nvic_configuration(void); +int fputc(int ch, FILE *f); + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t) ch); + while(usart_flag_get(EVAL_COM1, USART_FLAG_TC) == RESET); + return ch; +} + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_configuration(void) +{ + rcu_periph_clock_enable(RCU_GPIOB); + + /*configure PB4 (TIMER2 CH0) as alternate function*/ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4); + + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_4); +} + +/** + \brief configure the nested vectored interrupt controller + \param[in] none + \param[out] none + \retval none + */ +void nvic_configuration(void) +{ + nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); + nvic_irq_enable(TIMER2_IRQn, 1, 1); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_configuration(void) +{ + /* TIMER2 configuration: input capture mode ------------------- + the external signal is connected to TIMER2 CH0 pin(PB4) + the rising edge is used as active edge. + the TIMER2 CH0CV is used to compute the frequency value. + ------------------------------------------------------------ */ + timer_ic_parameter_struct timer_icinitpara; + timer_parameter_struct timer_initpara; + + rcu_periph_clock_enable(RCU_TIMER2); + + timer_deinit(TIMER2); + + /* TIMER2 configuration */ + timer_initpara.prescaler = 71; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 65535; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER2,&timer_initpara); + + /* TIMER2 configuration */ + /* TIMER2 CH0 input capture configuration */ + timer_icinitpara.icpolarity = TIMER_IC_POLARITY_RISING; + timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI; + timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1; + timer_icinitpara.icfilter = 0x0; + timer_input_capture_config(TIMER2, TIMER_CH_0, &timer_icinitpara); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER2); + /* clear channel 0 interrupt bit */ + timer_interrupt_flag_clear(TIMER2, TIMER_INT_CH0); + /* channel 0 interrupt enable */ + timer_interrupt_enable(TIMER2, TIMER_INT_CH0); + + /* TIMER2 counter enable */ + timer_enable(TIMER2); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_configuration(); + gd_eval_com_init(EVAL_COM1); + nvic_configuration(); + timer_configuration(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/readme.txt new file mode 100644 index 0000000..ffd6271 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_inputcapture/readme.txt @@ -0,0 +1,35 @@ +/*! + \file readme.txt + \brief description of the TIMER2 input capture demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows TIMER +peripheral to measure the frequency of an external signal. + + The TIMxCLK frequency is set to systemcoreclock 72MHz, the prescaler is 72 so +the TIMER2 counter clock is 1MHz. + + The external signal is connected to TIMER2 CH0 pin(PB4). + The amplitude of the external signal is better to be set as 3.3V. + The rising edge is used as active edge. + The TIMER2 CH0CV is used to compute the frequency value. + + The minimum frequence of the input signal to measure is 16 Hz. + + You can use USART to watch the frequency of the input signal.The USART is +configured as follow: + - BaudRate = 115200 baud + - Word Length = 8 Bits + - One Stop Bit + - No parity + - Hardware flow control disabled (RTS and CTS signals) + - Receive and transmit enabled diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/gd32f1x0_it.c new file mode 100644 index 0000000..0da443c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/gd32f1x0_it.c @@ -0,0 +1,151 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include + +__IO uint32_t ic1value = 0,ic2value = 0; +__IO uint16_t dutycycle = 0; +__IO float frequency = 0; + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ +} + +/** + * @brief this function handles TIMER2 interrupt request + * @param None + * @retval None + */ +void TIMER2_IRQHandler(void) +{ + if(SET == timer_interrupt_flag_get(TIMER2,TIMER_INT_FLAG_CH0)){ + /* clear channel 0 interrupt bit */ + timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_CH0); + /* read channel 0 capture value */ + ic1value = timer_channel_capture_value_register_read(TIMER2,TIMER_CH_0)+1; + + if(0 != ic1value){ + /* read channel 1 capture value */ + ic2value = timer_channel_capture_value_register_read(TIMER2,TIMER_CH_1)+1; + + /* calculate the duty cycle value */ + dutycycle = (ic2value * 100) / ic1value; + /* calculate the frequency value */ + frequency = (float)1000000 / ic1value; + + printf("\r\nthe value1 is %d, the value2 is %d\n", ic1value, ic2value); + printf("\r\nthe count is %d\n",(ic1value - ic2value)); + printf("\r\nthe dutycycle is %d\n", dutycycle); + printf("\r\nthe frequence is %f\r\n", frequency); + }else{ + dutycycle = 0; + frequency = 0; + } + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/gd32f1x0_it.h new file mode 100644 index 0000000..d3d5832 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* TIMER2 handle function */ +void TIMER2_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/main.c new file mode 100644 index 0000000..8fc3060 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/main.c @@ -0,0 +1,135 @@ +/*! + \file main.c + \brief TIMER2 PWM input capture demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_configuration(void); +void timer_configuration(void); +void nvic_configuration(void); +int fputc(int ch, FILE *f); + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t) ch); + while (usart_flag_get(EVAL_COM1, USART_FLAG_TC) == RESET); + return ch; +} + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_configuration(void) +{ + rcu_periph_clock_enable(RCU_GPIOB); + + /*configure PB4(TIMER2 CH0) as alternate function*/ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4); + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_4); + + /*configure PB5(TIMER2 CH1) as alternate function*/ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5); + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_5); +} + +/** + \brief configure the nested vectored interrupt controller + \param[in] none + \param[out] none + \retval none + */ +void nvic_configuration(void) +{ + nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); + nvic_irq_enable(TIMER2_IRQn, 1, 1); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_configuration(void) +{ + /* TIMER2 configuration: PWM input mode ------------------------ + the external signal is connected to TIMER2 CH0 pin(PB4) + the rising edge is used as active edge + the TIMER2 CH0CV is used to compute the frequency value. + the TIMER2 CH1CV is used to compute the duty cycle value. + ------------------------------------------------------------ */ + timer_ic_parameter_struct timer_icinitpara; + timer_parameter_struct timer_initpara; + + rcu_periph_clock_enable(RCU_TIMER2); + + timer_deinit(TIMER2); + + /* TIMER2 configuration */ + timer_initpara.prescaler = 71; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 65535; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER2,&timer_initpara); + + /* TIMER2 configuration */ + /* TIMER2 CH0 PWM input capture configuration */ + timer_icinitpara.icpolarity = TIMER_IC_POLARITY_RISING; + timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI; + timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1; + timer_icinitpara.icfilter = 0x0; + timer_input_pwm_capture_config(TIMER2,TIMER_CH_0,&timer_icinitpara); + + /* slave mode selection: TIMER2 */ + timer_input_trigger_source_select(TIMER2,TIMER_SMCFG_TRGSEL_CI0FE0); + timer_slave_mode_select(TIMER2,TIMER_SLAVE_MODE_RESTART); + + /* select the master slave mode */ + timer_master_slave_mode_config(TIMER2,TIMER_MASTER_SLAVE_MODE_ENABLE); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER2); + /* clear channel 0 interrupt bit */ + timer_interrupt_flag_clear(TIMER2,TIMER_INT_CH0); + /* channel 0 interrupt enable */ + timer_interrupt_enable(TIMER2,TIMER_INT_CH0); + + /* TIMER2 counter enable */ + timer_enable(TIMER2); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_configuration(); + gd_eval_com_init(EVAL_COM1); + nvic_configuration(); + timer_configuration(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/readme.txt new file mode 100644 index 0000000..d020d3b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMER2_pwminputcapture/readme.txt @@ -0,0 +1,36 @@ +/*! + \file readme.txt + \brief description of the TIMER2 PWM input capture demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +use the TIMER peripheral to measure the frequency and duty cycle of an external +signal. + + The TIMxCLK frequency is set to systemcoreclock (72MHz), the prescaler is 72 +so the TIMER2 counter clock is 1MHz. + + The external signal is connected to TIMER2 CH0 pin(PB4). + The rising edge is used as active edge. + The TIMER2 CH0CV is used to compute the frequency value. + The TIMER2 CH1CV is used to compute the duty cycle value. + + The minimum frequence of the input signal to measure is 16 Hz. + + You can use USART to watch the frequency and duty cycle of the input signal. +The USART is configured as follow: + - BaudRate = 115200 baud + - Word Length = 8 Bits + - One Stop Bit + - No parity + - Hardware flow control disabled (RTS and CTS signals) + - Receive and transmit enabled diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMERs_cascadesynchro/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMERs_cascadesynchro/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMERs_cascadesynchro/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMERs_cascadesynchro/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMERs_cascadesynchro/main.c new file mode 100644 index 0000000..24899cd --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMERs_cascadesynchro/main.c @@ -0,0 +1,197 @@ +/*! + \file main.c + \brief TIMERs cascade synchro demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +void gpio_config(void); +void timer_config(void); + +/** + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none + */ +void gpio_config(void) +{ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + + /*configure PA6(TIMER2 CH0) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6); + gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_6); + + /*configure PB3(TIMER1 CH1) as alternate function*/ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3); + gpio_af_set(GPIOB, GPIO_AF_2, GPIO_PIN_3); + + /*configure PA8(TIMER0 CH0) as alternate function*/ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); + gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_8); +} + +/** + \brief configure the TIMER peripheral + \param[in] none + \param[out] none + \retval none + */ +void timer_config(void) +{ + /* timers synchronisation in cascade mode ---------------------------- + 1/TIMER1 is configured as master timer: + - PWM mode is used + - The TIMER1 update event is used as trigger output + + 2/TIMER2 is slave for TIMER1 and master for TIMER0, + - PWM mode is used + - The ITR1(TIMER1) is used as input trigger + - external clock mode is used,the counter counts on the rising edges of + the selected trigger. + - the TIMER2 update event is used as trigger output. + + 3/TIMER0 is slave for TIMER2, + - PWM mode is used + - The ITR2(TIMER2) is used as input trigger + - external clock mode is used,the counter counts on the rising edges of + the selected trigger. + -------------------------------------------------------------------- */ + timer_oc_parameter_struct timer_ocintpara; + timer_parameter_struct timer_initpara; + + rcu_periph_clock_enable(RCU_TIMER0); + rcu_periph_clock_enable(RCU_TIMER1); + rcu_periph_clock_enable(RCU_TIMER2); + + /* TIMER1 configuration */ + timer_deinit(TIMER1); + + timer_initpara.prescaler = 3599; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 3999; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER1,&timer_initpara); + + /* CH1 configuration in PWM1 mode */ + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 1999); + timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM1); + timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER1); + /* select the master slave mode */ + timer_master_slave_mode_config(TIMER1, TIMER_MASTER_SLAVE_MODE_ENABLE); + /* TIMER1 update event is used as trigger output */ + timer_master_output_trigger_source_select(TIMER1, TIMER_TRI_OUT_SRC_UPDATE); + + /* TIMER2 configuration */ + timer_deinit(TIMER2); + + timer_initpara.prescaler = 0; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 1; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER2,&timer_initpara); + + /* CH0 configuration in PWM1 mode */ + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + timer_channel_output_config(TIMER2, TIMER_CH_0, &timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 1); + timer_channel_output_mode_config(TIMER2, TIMER_CH_0, TIMER_OC_MODE_PWM1); + timer_channel_output_shadow_config(TIMER2, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER2); + /* slave mode selection: TIMER2 */ + timer_slave_mode_select(TIMER2, TIMER_SLAVE_MODE_EXTERNAL0); + timer_input_trigger_source_select(TIMER2, TIMER_SMCFG_TRGSEL_ITI1); + /* select the master slave mode */ + timer_master_slave_mode_config(TIMER2, TIMER_MASTER_SLAVE_MODE_ENABLE); + /* TIMER2 update event is used as trigger output */ + timer_master_output_trigger_source_select(TIMER2, TIMER_TRI_OUT_SRC_UPDATE); + + /* TIMER0 configuration */ + timer_deinit(TIMER0); + + timer_initpara.prescaler = 0; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 1; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(TIMER0,&timer_initpara); + + /* CH0 configuration in PWM1 mode */ + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocintpara); + + timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, 1); + timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM1); + timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(TIMER0); + /* TIMER0 output enable */ + timer_primary_output_config(TIMER0,ENABLE); + /* slave mode selection: TIMER0 */ + timer_slave_mode_select(TIMER0, TIMER_SLAVE_MODE_EXTERNAL0); + timer_input_trigger_source_select(TIMER0, TIMER_SMCFG_TRGSEL_ITI2); + + /* TIMER counter enable */ + timer_enable(TIMER1); + timer_enable(TIMER2); + timer_enable(TIMER0); +} + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gpio_config(); + timer_config(); + + while (1); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMERs_cascadesynchro/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMERs_cascadesynchro/readme.txt new file mode 100644 index 0000000..1e13469 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TIMER/TIMERs_cascadesynchro/readme.txt @@ -0,0 +1,55 @@ +/*! + \file readme.txt + \brief description of the TIMERs cascade synchro demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to +synchronize TIMER peripherals in cascade mode. + + In this example three timers are used: + 1/TIMER1 is configured as master timer: + - PWM mode is used + - The TIMER1 update event is used as trigger output + + 2/TIMER2 is slave for TIMER1 and master for TIMER0, + - PWM mode is used + - The ITR0(TIMER1) is used as input trigger + - External clock mode is used,the counter counts on the rising edges of + the selected trigger. + - The TIMER2 update event is used as trigger output. + + 3/TIMER0 is slave for TIMER2, + - PWM mode is used + - The ITR1(TIMER2) is used as input trigger + - External clock mode is used,the counter counts on the rising edges of + the selected trigger. + + The TIMERxCLK is fixed to 72 MHz, the TIMER1 counter clock is : +108MHz/3600 = 20 KHz. + + The master timer TIMER1 is running at TIMER1 frequency : + TIMER1 frequency = (TIMER1 counter clock)/ (TIMER1 period + 1) = 5 Hz +and the duty cycle = TIMER1_CH1CV/(TIMER1_CAR + 1) = 50% + + The TIMER2 is running: + - At (TIMER1 frequency)/ (TIMER2 period + 1) = 2.5 Hz and a duty cycle + equal to TIMER2_CH0CV/(TIMER2_CAR + 1) = 50% + + The TIMER0 is running: + - At (TIMER2 frequency)/ (TIMER0 period + 1) = 1.25 Hz and a duty cycle + equal to TIMER0_CH0CV/(TIMER0_CAR + 1) = 50% + + Connect the three pins to a logic analyzer to monitor the different waveforms: + - TIMER1_CH1 pin (PB3) + - TIMER2_CH0 pin (PA6) + - TIMER0_CH0 pin (PA8) + \ No newline at end of file diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_key/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_key/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_key/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_key/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_key/main.c new file mode 100644 index 0000000..6d38798 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_key/main.c @@ -0,0 +1,237 @@ +/*! + \file main.c + \brief show how to use TSI to realize key +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_eval.h" +#include +#include + +#define THRESHOLD1 0x50 +#define THRESHOLD2 0x50 + +/* the current cycle number array of the channel pin */ +uint16_t samplenum[2] = {0,0}; + +/* reference value sample array of TSI group2 */ +uint16_t sample_refnum_array2[20] = {0}; +uint16_t sample_refnum_array3[20] = {0}; + +/* average value of cycles */ +uint16_t sample_refnum[2] = {0}; + +void delay(uint32_t nCount); +void gpio_config(void); +void tsi_config(void); +void led_config(void); +void tsi_transfer_pin(uint32_t TSI_groupx_pin); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int i=0; + + /* TSI peripheral and GPIOB periph clock enable */ + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_TSI); + + /* PB0 TSI_CHCFG_G2P1 SAMPCAP + PB1 TSI_CHCFG_G2P2 CHANNEL + PB2 TSI_CHCFG_G2P3 CHANNEL */ + + /* configure the GPIO ports */ + gpio_config(); + + /* configure the TSI peripheral */ + tsi_config(); + + /* configure the LED */ + led_config(); + + /* reference cycle value acquisition and processing */ + for(i=0;i<20;i++){ + /* get charge transfer complete cycle number of group2 pin2 */ + tsi_transfer_pin(TSI_CHCFG_G2P2); + + /* check the TSI flag:end of acquisition interrupt */ + if(tsi_interrupt_flag_get(TSI_INT_FLAG_CTC) == (uint8_t)SET){ + /* get charge transfer complete cycle number */ + sample_refnum_array2[i] = tsi_group2_cycle_get(); + } + + /* disable the selected pin as channel pin:pin2 */ + tsi_channel_pin_disable(TSI_CHCFG_G2P2); + + /* get charge transfer complete cycle number of group2 pin3 */ + tsi_transfer_pin(TSI_CHCFG_G2P3); + if(tsi_interrupt_flag_get(TSI_INT_FLAG_CTC) == (uint8_t)SET){ + sample_refnum_array3[i] = tsi_group2_cycle_get(); + } + tsi_channel_pin_disable(TSI_CHCFG_G2P3); + /* delay for a period of time while all banks have been acquired */ + delay(0xFFFF); + } + + /* sum of sample_refnum_array */ + for(i=1;i<20;i++){ + sample_refnum[0] += sample_refnum_array2[i]; + sample_refnum[1] += sample_refnum_array3[i]; + } + + /* average channel cycle value are obtained */ + sample_refnum[0] = sample_refnum[0]/19; + sample_refnum[1] = sample_refnum[1]/19; + + while (1){ + /* acquisition group2 pin2 */ + tsi_transfer_pin(TSI_CHCFG_G2P2); + + /* check the TSI flag end of acquisition interrupt */ + if(tsi_interrupt_flag_get(TSI_INT_FLAG_CTC) == (uint8_t)SET){ + /* get charge transfer complete cycle number */ + samplenum[0] = tsi_group2_cycle_get(); + } + + /* light LED1 */ + if((sample_refnum[0]-samplenum[0]) > THRESHOLD1){ + /* group2 pin2 is touched */ + gd_eval_led_on(LED1); + }else{ + gd_eval_led_off(LED1); + } + tsi_channel_pin_disable(TSI_CHCFG_G2P2); + + /* acquisition group2 pin3 */ + tsi_transfer_pin(TSI_CHCFG_G2P3); + if(tsi_interrupt_flag_get(TSI_INT_FLAG_CTC) == (uint8_t)SET){ + samplenum[1] = tsi_group2_cycle_get(); + } + + /* light LED2 */ + if((sample_refnum[1]-samplenum[1]) > THRESHOLD2){ + /* group2 pin3 is touched */ + gd_eval_led_on(LED2); + }else{ + gd_eval_led_off(LED2); + } + tsi_channel_pin_disable(TSI_CHCFG_G2P3); + + /* delay for a period of time while all banks have been acquired */ + delay(0xFFFF); + } +} + +/*! + \brief insert a delay time + \param[in] nCount: specifies the delay time length + \param[out] none + \retval none +*/ +void delay(uint32_t ncount) +{ + for(; ncount != 0; ncount--); +} + +/*! + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* GPIO PB0 */ + /* alternate function output open-drain for sampling capacitor IO */ + gpio_mode_set(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_0); + gpio_output_options_set(GPIOB,GPIO_OTYPE_OD,GPIO_OSPEED_2MHZ,GPIO_PIN_0); + + /* GPIO PB1 GPIO PB2 */ + /* alternate function output push-pull for channel and shield IOs */ + gpio_mode_set(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_1); + gpio_output_options_set(GPIOB,GPIO_OTYPE_PP,GPIO_OSPEED_2MHZ,GPIO_PIN_1); + gpio_mode_set(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_2); + gpio_output_options_set(GPIOB,GPIO_OTYPE_PP,GPIO_OSPEED_2MHZ,GPIO_PIN_2); + + /* connect pin to peripheral */ + gpio_af_set(GPIOB,GPIO_AF_3,GPIO_PIN_0); + gpio_af_set(GPIOB,GPIO_AF_3,GPIO_PIN_1); + gpio_af_set(GPIOB,GPIO_AF_3,GPIO_PIN_2); +} + +/*! + \brief configure the TSI peripheral + \param[in] none + \param[out] none + \retval none +*/ +void tsi_config(void) +{ + /* TSI configure */ + tsi_init(TSI_CTCDIV_DIV8,TSI_CHARGE_4CTCLK,TSI_TRANSFER_8CTCLK,TSI_MAXNUM4095); + tsi_sofeware_mode_config(); + tsi_sample_pin_enable(TSI_SAMPCFG_G2P1); + tsi_group_enable(TSI_GCTL_GE2); + + /* disable hysteresis mode */ + tsi_hysteresis_off(TSI_PHM_G2P1|TSI_PHM_G2P2|TSI_PHM_G2P3); + + /* enable TSI */ + tsi_enable(); +} + +/*! + \brief LEDs configure + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + /* initialize the LEDs */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + + /* close all of LEDs */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); +} + +/*! + \brief acquisition pin y of group x,x=0..5,y=0..3 + \param[in] tsi_groupx_piny:pin y of group x + \param[out] none + \retval none +*/ +void tsi_transfer_pin(uint32_t tsi_groupx_piny) +{ + /* configure the TSI Pin Channel Mode */ + tsi_channel_pin_enable(tsi_groupx_piny); + + /* wait capacitors discharge */ + delay(0xD00); + + /* clear both CMCE and CCTCF flags */ + tsi_interrupt_flag_clear(TSI_INT_FLAG_CTC|TSI_INT_FLAG_MNERR); + + /* start a new acquisition */ + tsi_software_start(); + + /* wait the specified TSI flag state: MCE or CTCF */ + while(RESET==tsi_interrupt_flag_get(TSI_INT_FLAG_CTC|TSI_INT_FLAG_MNERR)); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_key/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_key/readme.txt new file mode 100644 index 0000000..6569c5c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_key/readme.txt @@ -0,0 +1,19 @@ +/*! + \file readme.txt + \brief description of touch key +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32190R-EVAL board, it shows how to use the TSI to +perform continuous acquisitions of two channels in group 2. In this demo, touch +the TouchKey(TK1 or TK2) on the GD32190R-EVAL board, meanwhile, the associated +LED(LED1 or LED2) is on. + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_line/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_line/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_line/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_line/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_line/main.c new file mode 100644 index 0000000..c782724 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_line/main.c @@ -0,0 +1,302 @@ +/*! + \file main.c + \brief use the TSI to perform continuous acquisitions of three channels +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_eval.h" +#include +#include + +/* the flag of touching */ +int keystatus[3] = {0,0,0}; + +/* the current cycle number array of the channel pin */ +uint16_t samplenum[4] = {0,0,0,0}; + +/* reference value sample array of TSI group5 */ +uint16_t sample_refnum_array1[20] = {0}; +uint16_t sample_refnum_array2[20] = {0}; +uint16_t sample_refnum_array3[20] = {0}; + +/* average value of cycles */ +uint16_t sample_refnum[3] = {0}; + +uint16_t threshold1 = 0; +uint16_t threshold2 = 0; + +void delay(uint32_t nCount); +void gpio_config(void); +void tsi_config(void); +void led_config(void); +void tsi_transfer_pin(uint32_t TSI_groupx_pin); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + int m=0; + + /* TSI peripheral and GPIOB Periph clock enable */ + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_TSI); + + /* PB11 TSI_CHCFG_G5P0 SAMPCAP + PB12 TSI_CHCFG_G5P1 CHANNEL + PB13 TSI_CHCFG_G5P2 CHANNEL + PB14 TSI_CHCFG_G5P3 CHANNEL */ + + /* configure the GPIO ports */ + gpio_config(); + + /* configure the TSI peripheral */ + tsi_config(); + + /* configure the LED */ + led_config(); + + /* reference cycle value acquisition and processing */ + for(m=0;m<20;m++){ + /* get charge transfer complete cycle number of group5 pin1 */ + tsi_transfer_pin(TSI_CHCFG_G5P1); + + /* check the TSI flag:end of acquisition interrupt */ + if((uint8_t)SET == tsi_interrupt_flag_get(TSI_INT_FLAG_CTC) ){ + /* get charge transfer complete cycle number */ + sample_refnum_array1[m] = tsi_group5_cycle_get(); + } + + /* disable the selected pin as channel pin */ + tsi_channel_pin_disable(TSI_CHCFG_G5P1); + + /* get charge transfer complete cycle number of group5 pin2 */ + tsi_transfer_pin(TSI_CHCFG_G5P2); + + if((uint8_t)SET == tsi_interrupt_flag_get(TSI_INT_FLAG_CTC)){ + sample_refnum_array2[m] = tsi_group5_cycle_get(); + } + + tsi_channel_pin_disable(TSI_CHCFG_G5P2); + + + /* get charge transfer complete cycle number of group5 pin3 */ + tsi_transfer_pin(TSI_CHCFG_G5P3); + + if((uint8_t)SET == tsi_interrupt_flag_get(TSI_INT_FLAG_CTC)){ + sample_refnum_array3[m] = tsi_group5_cycle_get(); + } + + tsi_channel_pin_disable(TSI_CHCFG_G5P3); + + /* delay for a period of time while all banks have been acquired */ + delay(0x1000); + } + + for(m=1;m<20;m++){ + sample_refnum[0] += sample_refnum_array1[m]; + sample_refnum[1] += sample_refnum_array2[m]; + sample_refnum[2] += sample_refnum_array3[m]; + } + + /* average channel cycle value are obtained */ + sample_refnum[0] = sample_refnum[0]/19; + sample_refnum[1] = sample_refnum[1]/19; + sample_refnum[2] = sample_refnum[2]/19; + + /* set threshold use for determine touch location of TSI_CHCFG_G5P1 */ + threshold1 = sample_refnum[2]- sample_refnum[1]; + threshold2 = sample_refnum[2]- sample_refnum[1]+15; + + while (1){ + /* acquisition pin1 of group5 */ + tsi_transfer_pin(TSI_CHCFG_G5P1); + + /* check the TSI flag--end of acquisition interrupt */ + if((uint8_t)SET == tsi_interrupt_flag_get(TSI_INT_FLAG_CTC)){ + /* get charge transfer complete cycle number */ + samplenum[1] = tsi_group5_cycle_get(); + } + + /* channel 1 touch */ + if((sample_refnum[0]-samplenum[1]) > 0x15){ + /* pin1 of group5 is touched */ + keystatus[0] = 1; + }else{ + keystatus[0] = 0; + gd_eval_led_off(LED1); + gd_eval_led_off(LED4); + } + tsi_channel_pin_disable(TSI_CHCFG_G5P1); + + /* acquisition pin2 of group5 */ + tsi_transfer_pin(TSI_CHCFG_G5P2); + + /* check the TSI flag--end of acquisition interrupt */ + if((uint8_t)SET == tsi_interrupt_flag_get(TSI_INT_FLAG_CTC)){ + samplenum[2] = tsi_group5_cycle_get(); + } + + /* light LED2 */ + if((sample_refnum[1]-samplenum[2]) > 0x20){ + /* TSI_GROUP6_PIN3 is touched */ + keystatus[1] = 1; + gd_eval_led_on(LED2); + }else{ + keystatus[1] = 0; + gd_eval_led_off(LED2); + } + tsi_channel_pin_disable(TSI_CHCFG_G5P2); + + /* acquisition pin3 of group5 */ + tsi_transfer_pin(TSI_CHCFG_G5P3); + + /* check the TSI flag--end of acquisition interrupt */ + if((uint8_t)SET == tsi_interrupt_flag_get(TSI_INT_FLAG_CTC)){ + samplenum[3] = tsi_group5_cycle_get(); + } + /* light LED3 */ + if((sample_refnum[2]-samplenum[3]) > 0x20){ + /* pin3 of group5 is touched */ + keystatus[2] = 1; + gd_eval_led_on(LED3); + }else{ + keystatus[2] = 0; + gd_eval_led_off(LED3); + } + tsi_channel_pin_disable(TSI_CHCFG_G5P3); + + /* judge specific location of channel1 */ + if(1 == keystatus[0]){ + if((samplenum[2]-samplenum[1]+threshold1)<(samplenum[3]-samplenum[1])){ + /* light LED1 when touch the left location */ + gd_eval_led_on(LED1); + }else if((samplenum[2]-samplenum[1]+threshold2)>(samplenum[3]-samplenum[1])){ + /* light LED4 when touch the right location */ + gd_eval_led_on(LED4); + } + } + + /* delay for a period of time while all banks have been acquired */ + delay(0x1FFFFF); + } +} + +/*! + \brief insert a delay time + \param[in] nCount: stall Count + \param[out] none + \retval none +*/ +void delay(uint32_t nCount) +{ + for(; nCount != 0; nCount--); +} + +/*! + \brief configure the GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +void gpio_config(void) +{ + /* GPIOB11 */ + /* alternate function output open-drain for sampling capacitor IO */ + gpio_mode_set(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_11); + gpio_output_options_set(GPIOB,GPIO_OTYPE_OD,GPIO_OSPEED_2MHZ,GPIO_PIN_11); + + /* GPIOB12 GPIOB13 GPIOB14 */ + /* alternate function output push-pull for channel and shield IOs */ + gpio_mode_set(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_12); + gpio_output_options_set(GPIOB,GPIO_OTYPE_PP,GPIO_OSPEED_2MHZ,GPIO_PIN_12); + gpio_mode_set(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_13); + gpio_output_options_set(GPIOB,GPIO_OTYPE_PP,GPIO_OSPEED_2MHZ,GPIO_PIN_13); + gpio_mode_set(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_14); + gpio_output_options_set(GPIOB,GPIO_OTYPE_PP,GPIO_OSPEED_2MHZ,GPIO_PIN_14); + + /* connect pin to peripheral */ + gpio_af_set(GPIOB,GPIO_AF_3,GPIO_PIN_11); + gpio_af_set(GPIOB,GPIO_AF_3,GPIO_PIN_12); + gpio_af_set(GPIOB,GPIO_AF_3,GPIO_PIN_13); + gpio_af_set(GPIOB,GPIO_AF_3,GPIO_PIN_14); +} + +/*! + \brief configure the TSI peripheral + \param[in] none + \param[out] none + \retval none +*/ +void tsi_config(void) +{ + /* TSI configure */ + tsi_init(TSI_CTCDIV_DIV32,TSI_CHARGE_2CTCLK,TSI_TRANSFER_2CTCLK,TSI_MAXNUM2047); + tsi_sofeware_mode_config(); + tsi_sample_pin_enable(TSI_SAMPCFG_G5P0); + tsi_group_enable(TSI_GCTL_GE5); + + /* disable hysteresis mode */ + tsi_hysteresis_off(TSI_PHM_G5P0|TSI_PHM_G5P1|TSI_PHM_G5P2|TSI_PHM_G5P3); + + /* enable TSI */ + tsi_enable(); +} + +/*! + \brief configure led + \param[in] none + \param[out] none + \retval none +*/ +void led_config(void) +{ + /* initialize the LEDs */ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + gd_eval_led_init(LED3); + gd_eval_led_init(LED4); + + /* close all of LEDs */ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + gd_eval_led_off(LED3); + gd_eval_led_off(LED4); +} + +/*! + \brief acquisition pin y of group x,x=0..5,y=0..3 + \param[in] tsi_groupx_piny: TSI_CHCFG_GxPy,pin y of group x + \param[out] none + \retval none +*/ +void tsi_transfer_pin(uint32_t tsi_groupx_piny) +{ + /* configure the TSI pin channel mode */ + tsi_channel_pin_enable(tsi_groupx_piny); + + /* wait capacitors discharge */ + delay(0xD00); + + /* clear both CMCE and CCTCF flags */ + tsi_interrupt_flag_clear(TSI_INT_FLAG_CTC | TSI_INT_FLAG_MNERR); + + /* start a new acquisition */ + tsi_software_start(); + + /* wait the specified TSI flag state: MCE or CTCF */ + while(RESET==tsi_interrupt_flag_get(TSI_INT_FLAG_CTC | TSI_INT_FLAG_MNERR)); +} + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_line/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_line/readme.txt new file mode 100644 index 0000000..3c3d340 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/TSI/Touch_line/readme.txt @@ -0,0 +1,18 @@ +/*! + \file readme.txt + \brief description of touch line +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL board, it shows how to use the TSI to +perform continuous acquisitions of three channels in group 5. In this demo, slide +the Touch Sensor on the GD32150R-EVAL board, meanwhile, light the LED1¡¢LED2¡¢LED3 +and LED4 in trun.With a finger touch the Touch Sensor. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Auto_baudrate_detect/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Auto_baudrate_detect/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Auto_baudrate_detect/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Auto_baudrate_detect/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Auto_baudrate_detect/main.c new file mode 100644 index 0000000..c6c6d6a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Auto_baudrate_detect/main.c @@ -0,0 +1,76 @@ +/*! + \file main.c + \brief Auto baudrate detection +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_eval.h" +#include + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gd_eval_led_init(LED1); + + /* USART configuration */ + gd_eval_com_init(EVAL_COM1); + + printf("\n\rUSART auto baudrate detection example\n\r"); + /* configure the auto-baud rate method */ + usart_autobaud_detection_mode_config(EVAL_COM1, USART_ABDM_FTOF); + + /* enable autobaudrate feature */ + usart_autobaud_detection_enable(EVAL_COM1); + + /* wait until receive enable acknowledge flag is set */ + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_REA)); + + /* wait until transmit enable acknowledge flag is set */ + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TEA)); + + /* loop until the end of autobaudrate phase */ + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_ABD)); + + /* if autobaudbate error occurred */ + if(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_ABDE)){ + /* wait until RBNE flag is set */ + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_RBNE)); + + /* wait until TBE flag is set */ + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE)); + + /* USART auto baud rate detection finshed successfully */ + gd_eval_led_on(LED1); + + /* check the transfer complete flag */ + while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TC)); + + usart_transmit_config(EVAL_COM1, USART_TRANSMIT_DISABLE); + usart_receive_config(EVAL_COM1, USART_RECEIVE_DISABLE); + } + /* USART disable */ + usart_disable(EVAL_COM1); + while(1); +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t) ch); + while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE)); + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Auto_baudrate_detect/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Auto_baudrate_detect/readme.txt new file mode 100644 index 0000000..6540d9e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Auto_baudrate_detect/readme.txt @@ -0,0 +1,22 @@ +/*! + \file readme.txt + \brief description of the auto baudrate detect +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to use the USART +to detect and automatically set the USARTx_BRR value based on the reception of +one character. + In this demo, firstly, the USART sends "\n\rUSART auto baudrate detection example\n\r" +to the hyperterminal USART_ABDM_FTOF is set as the auto baud rate detection mode. If auto +baud rate detection is completed without error, LED1 is on. + You can send any character be in a start 10xxxxxx frame format 1(eg.0x0a or 0x01) +to implement the auto baud rate detection. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/DMA_transmitter&receiver/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/DMA_transmitter&receiver/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/DMA_transmitter&receiver/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/DMA_transmitter&receiver/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/DMA_transmitter&receiver/main.c new file mode 100644 index 0000000..ebc6a29 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/DMA_transmitter&receiver/main.c @@ -0,0 +1,161 @@ +/*! + \file main.c + \brief USART DMA transmitter receiver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +uint8_t rxbuffer[10]; +uint8_t txbuffer[]="\n\rUSART DMA receive and transmit example, please input 10 bytes:\n\r"; +#define ARRAYNUM(arr_nanme) (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme))) +#define USART0_TDATA_ADDRESS ((uint32_t)0x40013828) /* 130_150 device */ +#define USART0_RDATA_ADDRESS ((uint32_t)0x40013824) /* 130_150 device */ +#define USART1_TDATA_ADDRESS ((uint32_t)0x40004428) /* 170_190 device */ +#define USART1_RDATA_ADDRESS ((uint32_t)0x40004424) /* 170_190 device */ + +extern __IO uint8_t txcount; +extern __IO uint16_t rxcount; + + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + dma_parameter_struct dma_init_struct; + /* enable DMA clock */ + rcu_periph_clock_enable(RCU_DMA); +#ifdef GD32F130_150 + gd_eval_com_init(EVAL_COM1); +#elif defined GD32F170_190 + gd_eval_com_init(EVAL_COM2); +#endif /* GD32F130_150 */ + printf("\n\ra usart dma function test example!\n\r"); + +#ifdef GD32F130_150 + /* deinitialize DMA channel1 */ + dma_deinit(DMA_CH1); + dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; + dma_init_struct.memory_addr = (uint32_t)txbuffer; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.number = ARRAYNUM(txbuffer); + dma_init_struct.periph_addr = USART0_TDATA_ADDRESS; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; + dma_init(DMA_CH1, dma_init_struct); + /* configure DMA mode */ + dma_circulation_disable(DMA_CH1); + dma_memory_to_memory_disable(DMA_CH1); + /* enable DMA channel1 */ + dma_channel_enable(DMA_CH1); + /* USART DMA enable for transmission and reception */ + usart_dma_transmit_config(USART0, USART_DENT_ENABLE); + + /* wait DMA channel transfer complete */ + while (RESET == dma_flag_get(DMA_CH1, DMA_FLAG_FTF)); + while(1){ + /* deinitialize DMA channel2 */ + dma_deinit(DMA_CH2); + dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; + dma_init_struct.memory_addr = (uint32_t)rxbuffer; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.number = 10; + dma_init_struct.periph_addr = USART0_RDATA_ADDRESS; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; + dma_init(DMA_CH2, dma_init_struct); + + dma_circulation_disable(DMA_CH2); + dma_memory_to_memory_disable(DMA_CH2); + + dma_channel_enable(DMA_CH2); + usart_dma_receive_config(USART0, USART_DENR_ENABLE); + /* wait DMA channel transfer complete */ + while (RESET == dma_flag_get(DMA_CH2, DMA_FLAG_FTF)); + printf("\n\r%s\n\r",rxbuffer); + + } +#elif defined GD32F170_190 + /* deinitialize DMA channel3 */ + dma_deinit(DMA_CH3); + dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; + dma_init_struct.memory_addr = (uint32_t)txbuffer; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.number = ARRAYNUM(txbuffer); + dma_init_struct.periph_addr = USART1_TDATA_ADDRESS; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; + dma_init(DMA_CH3, dma_init_struct); + /* configure DMA mode */ + dma_circulation_disable(DMA_CH3); + dma_memory_to_memory_disable(DMA_CH3); + /* enable DMA channel3 */ + dma_channel_enable(DMA_CH3); + /* USART DMA enable for transmission and reception */ + usart_dma_transmit_config(USART1, USART_DENT_ENABLE); + + /* wait DMA channel transfer complete */ + while (RESET == dma_flag_get(DMA_CH3, DMA_FLAG_FTF)); + while(1){ + /* initialize DMA channel4 */ + dma_deinit(DMA_CH4); + dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; + dma_init_struct.memory_addr = (uint32_t)rxbuffer; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.number = 10; + dma_init_struct.periph_addr = USART1_RDATA_ADDRESS; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; + dma_init(DMA_CH4, dma_init_struct); + + dma_circulation_disable(DMA_CH4); + dma_memory_to_memory_disable(DMA_CH4); + + dma_channel_enable(DMA_CH4); + usart_dma_receive_config(USART1, USART_DENR_ENABLE); + /* wait DMA channel transfer complete */ + while (RESET == dma_flag_get(DMA_CH4, DMA_FLAG_FTF)); + printf("\n\r%s\n\r",rxbuffer); + } +#endif /* GD32F130_150 */ + +} +#ifdef GD32F130_150 +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t)ch); + while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE)); + return ch; +} +#elif defined GD32F170_190 +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM2, (uint8_t)ch); + while (RESET == usart_flag_get(EVAL_COM2, USART_FLAG_TBE)); + return ch; +} +#endif /* GD32F130_150 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/DMA_transmitter&receiver/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/DMA_transmitter&receiver/readme.txt new file mode 100644 index 0000000..50b670c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/DMA_transmitter&receiver/readme.txt @@ -0,0 +1,19 @@ +/*! + \file readme.txt + \brief description of the USART DMA transmitter receiver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to use the USART +DMA transmit and receive. + Firstly, the USART sends the strings to the hyperterminal and then loops waiting for +receiving max 10 datas from the hyperterminal. Every time if the number of data you enter is +equal to or more than 10 bytes, USART will send 10 bytes to the hyperterminal. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/gd32f1x0_it.c new file mode 100644 index 0000000..208b2c4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/gd32f1x0_it.c @@ -0,0 +1,140 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +__IO uint8_t counter0 = 0x00; +__IO uint8_t counter1 = 0; +extern void LED_Spark(void); + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + if (counter1 == 20){ + LED_Spark(); + /* Reset Counter */ + counter1 = 0; + }else{ + /* increment Counter */ + counter1++; + } +} + +/*! + \brief this function handles USART wakeup from deepsleep interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void USART0_IRQHandler(void) +{ + if (SET == usart_interrupt_flag_get(EVAL_COM1, USART_INT_FLAG_WU)){ + usart_flag_clear(EVAL_COM1, USART_FLAG_WU); + counter0 = 0x01; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/gd32f1x0_it.h new file mode 100644 index 0000000..7e0357c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/gd32f1x0_it.h @@ -0,0 +1,42 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); +/* USART0 handle function */ +void USART0_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/main.c new file mode 100644 index 0000000..17ce78d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/main.c @@ -0,0 +1,160 @@ +/*! + \file main.c + \brief Deepsleep wakeup +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +extern __IO uint8_t counter0; + +static void system_clock_reconfig(void); +void delay_s(uint32_t nTime); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + SysTick_Config((SystemCoreClock / 1000)); + + gd_eval_led_init(LED2); + + /* USART configuration the CK_IRC8M as USART clock */ + rcu_usart_clock_config(RCU_USART0SRC_IRC8M); + gd_eval_com_init(EVAL_COM1); + + nvic_irq_enable(USART0_IRQn, 0, 0); + + delay_s(20); + + { + /* use start bit wakeup mcu */ + usart_wakeup_mode_config(EVAL_COM1, USART_WUM_STARTB); + + /* enable USART */ + usart_enable(EVAL_COM1); + + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_REA)); + + usart_wakeup_enable(EVAL_COM1); + + /* enable the WUIE interrupt */ + usart_interrupt_enable(EVAL_COM1, USART_INT_WU); + + /* enable PWU APB clock */ + rcu_periph_clock_enable(RCU_PMU); + + /* enter deep-sleep mode */ + pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD); + + /* wait a WUIE interrup event */ + while(0x00 == counter0); + + /* disable USART peripheral in deepsleep mode */ + usart_wakeup_disable(EVAL_COM1); + + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_RBNE)); + usart_data_receive(EVAL_COM1); + + usart_receive_config(EVAL_COM1, USART_RECEIVE_ENABLE); + + while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TC)); + + /* disable the USART */ + usart_disable(EVAL_COM1); + } + + /* reconfigure systemclock */ + system_clock_reconfig(); + + /* configure and enable the systick timer to generate an interrupt each 1 ms */ + SysTick_Config((SystemCoreClock / 1000)); + + while (1); +} + +/*! + \brief delay function + \param[in] nTime + \param[out] none + \retval none +*/ +void delay_s(uint32_t nTime) +{ + uint32_t TimingDelay = 7200000*nTime; + while(TimingDelay != 0) + TimingDelay--; +} + +/*! + \brief restore peripheral config before entering deepsleep mode + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_reconfig(void) +{ + __IO uint32_t StartUpCounter = 0, HXTALStatus = 0; + + /* enable HXTAL */ + RCU_CTL0 |= RCU_CTL0_HXTALEN; + + HXTALStatus = rcu_osci_stab_wait(RCU_HXTAL); + if (SUCCESS == HXTALStatus){ + /* configure AHB */ + rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1); + + /* configure APB1, APB2 */ + rcu_apb1_clock_config(RCU_APB1_CKAHB_DIV1); + rcu_apb2_clock_config(RCU_APB2_CKAHB_DIV1); + + /* PLL configuration: = HXTAL * 9 = 72 MHz */ + rcu_hxtal_prediv_config(RCU_PLL_HXTAL_DIV1); + rcu_pll_config(RCU_PLLSRC_HXTAL, RCU_PLL_MUL9); + + /* enable PLL */ + RCU_CTL0 |= RCU_CTL0_PLLEN; + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + } +} + +/*! + \brief LED spark + \param[in] none + \param[out] none + \retval none +*/ +void LED_Spark(void) +{ + static __IO uint32_t TimingDelayLocal = 0; + + if (0x00 != TimingDelayLocal){ + if(TimingDelayLocal < 50){ + /* light on */ + gd_eval_led_on(LED2); + }else{ + /* light off */ + gd_eval_led_off(LED2); + } + TimingDelayLocal--; + }else{ + TimingDelayLocal = 100; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/readme.txt new file mode 100644 index 0000000..80083d8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Deepsleep_wakeup/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the USART wakeup from deepsleep +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to use +USART to wake up the MCU from deepsleep mode. + In this demo, the wake up method is configured as start bit detection. When the MCU +enters into deepsleep mode, LED2 stops in a certain status(on or off). In this +case, you can send some characters to wake up USART and LED2 goes on blink. + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Half_duplex_transmitter&receiver/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Half_duplex_transmitter&receiver/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Half_duplex_transmitter&receiver/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Half_duplex_transmitter&receiver/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Half_duplex_transmitter&receiver/main.c new file mode 100644 index 0000000..57246fe --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Half_duplex_transmitter&receiver/main.c @@ -0,0 +1,144 @@ +/*! + \file main.c + \brief USART HalfDuplex transmitter and receiver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +#define ARRAYNUM(arr_nanme) (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme))) +#define TRANSMIT_SIZE0 (ARRAYNUM(transmitter_buffer0) - 1) +#define TRANSMIT_SIZE1 (ARRAYNUM(transmitter_buffer1) - 1) + +uint8_t transmitter_buffer0[] = "\n\ra usart half-duplex test example!\n\r"; +uint8_t transmitter_buffer1[] = "\n\ra usart half-duplex test example!\n\r"; +uint8_t receiver_buffer0[TRANSMIT_SIZE1]; +uint8_t receiver_buffer1[TRANSMIT_SIZE0]; +uint8_t transfersize0 = TRANSMIT_SIZE0; +uint8_t transfersize1 = TRANSMIT_SIZE1; +__IO uint8_t txcount0 = 0; +__IO uint16_t rxcount0 = 0; +__IO uint8_t txcount1 = 0; +__IO uint16_t rxcount1 = 0; +ErrStatus state1=ERROR; +ErrStatus state2=ERROR; + +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length) ; + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + /* enable USART and GPIOA clock */ + rcu_periph_clock_disable(RCU_DMA); + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_USART0); + rcu_periph_clock_enable(RCU_USART1); + + /* configure the USART0 Tx pin and USART1 Tx pin */ + gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2); + gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_9); + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); + + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); + + /* USART0 and USART1 baudrate configuration */ + usart_baudrate_set(USART0, 115200); + usart_baudrate_set(USART1, 115200); + + /* enable USART0 half duplex mode*/ + usart_halfduplex_enable(USART0); + /* enable USART1 half duplex mode*/ + usart_halfduplex_enable(USART1); + + usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); + usart_receive_config(USART0, USART_RECEIVE_ENABLE); + usart_transmit_config(USART1, USART_TRANSMIT_ENABLE); + usart_receive_config(USART1, USART_RECEIVE_ENABLE); + /* enable USART */ + usart_enable(USART0); + usart_enable(USART1); + + /* USART0 transmit and USART1 receive*/ + usart_data_receive(USART1); + while(transfersize0--) + { + /* wait until end of transmit */ + while(RESET == usart_flag_get(USART0, USART_FLAG_TBE)); + usart_data_transmit(USART0, transmitter_buffer0[txcount0++]); + + while(RESET == usart_flag_get(USART1, USART_FLAG_RBNE)); + /* store the received byte in the receiver_buffer1 */ + receiver_buffer1[rxcount0++] = usart_data_receive(USART1); + } + + usart_data_receive(USART0); + /* USART1 transmit and USART0 receive*/ + while(transfersize1--) + { + /* wait until end of transmit */ + while(RESET == usart_flag_get(USART1, USART_FLAG_TBE)); + usart_data_transmit(USART1, transmitter_buffer1[txcount1++]); + + while(RESET == usart_flag_get(USART0, USART_FLAG_RBNE)); + receiver_buffer0[rxcount1++] = usart_data_receive(USART0); + } + + /* compare the received data with the send ones */ + state1 = memory_compare(transmitter_buffer0, receiver_buffer1, TRANSMIT_SIZE0); + state2 = memory_compare(transmitter_buffer1, receiver_buffer0, TRANSMIT_SIZE1); + if(SUCCESS==state1){ + gd_eval_led_on(LED1); + gd_eval_led_on(LED2); + }else{ + gd_eval_led_off(LED1); + gd_eval_led_off(LED2); + } + while (1) + { + } +} + +/*! + \brief memory compare function + \param[in] src : source data + \param[in] dst : destination data + \param[in] length : the compare data length + \param[out] none + \retval ErrStatus : ERROR or SUCCESS +*/ +ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length) +{ + while (length--){ + if (*src++ != *dst++){ + return ERROR; + } + } + return SUCCESS; +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t) ch); + while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE)); + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Half_duplex_transmitter&receiver/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Half_duplex_transmitter&receiver/readme.txt new file mode 100644 index 0000000..a133b4a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Half_duplex_transmitter&receiver/readme.txt @@ -0,0 +1,23 @@ +/*! + \file readme.txt + \brief description of the USART HalfDuplex +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it provides a basic communication +USART0 whith USART1 in Half-Duplex mode. + The transmitter_buffer0 and transmitter_buffer1 are sent by USART0 and USART1 respectively and +displayed in HyperTerminal. If the data received by USART0 is equal to transmitter_buffer1 and the +data received by USART1 is equal to transmitter_buffer0, LED1 and LED2 is turned on. + + connect USART0_Tx(PA9) to USART1_Tx(PA2) + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Printf/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Printf/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Printf/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Printf/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Printf/main.c new file mode 100644 index 0000000..178edef --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Printf/main.c @@ -0,0 +1,39 @@ +/*! + \file main.c + \brief USART printf +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gd_eval_com_init(EVAL_COM1); + + printf("a usart transmit test example!"); + while (1); +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t)ch); + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE)); + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Printf/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Printf/readme.txt new file mode 100644 index 0000000..652caae --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Printf/readme.txt @@ -0,0 +1,26 @@ +/*! + \file readme.txt + \brief description of the USART printf +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to retarget the C +library printf function to the USART. + + The USARTx is configured as follow: + - BaudRate = 115200 baud + - Word Length = 8 Bits + - One Stop Bit + - No parity + - Hardware flow control disabled (RTS and CTS signals) + - Receive and transmit enabled + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/gd32f1x0_it.c new file mode 100644 index 0000000..b23b3fa --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/gd32f1x0_it.c @@ -0,0 +1,131 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "gd32f1x0_eval.h" + +extern uint8_t rxbuffer[64]; +extern uint8_t txbuffer[64]; +__IO uint8_t txcount = 0; +__IO uint16_t rxcount = 0; +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles USART RBNE interrupt request and TBE interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void USART0_IRQHandler(void) +{ + if(RESET != usart_interrupt_flag_get(EVAL_COM1, USART_INT_FLAG_RBNE)){ + /* receive data */ + rxbuffer[rxcount++] = usart_data_receive(EVAL_COM1); + } + + if(RESET != usart_interrupt_flag_get(EVAL_COM1, USART_INT_FLAG_TBE)){ + /* transmit data */ + usart_data_transmit(EVAL_COM1, txbuffer[txcount++]); + if(txcount >= rxcount) + { + usart_interrupt_disable(EVAL_COM1, USART_INT_TBE); + } + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/gd32f1x0_it.h new file mode 100644 index 0000000..ac20394 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* USART0 handle function */ +void USART0_IRQHandler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/main.c new file mode 100644 index 0000000..8221f01 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Receiver_timeout/main.c @@ -0,0 +1,82 @@ +/*! + \file main.c + \brief UASRT receiver timeout +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include +#include "gd32f1x0_eval.h" + +uint8_t rxbuffer[64]; +uint8_t txbuffer[64]; +extern __IO uint8_t txcount; +extern __IO uint16_t rxcount; +void nvic_config(void); + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + uint32_t i=0, j=0; + nvic_config(); + gd_eval_com_init(EVAL_COM1); + printf("a usart receive timeout test example!"); + + while (1){ + if(0 == rxcount){ + /* enable the USART receive interrupt */ + usart_interrupt_enable(EVAL_COM1, USART_INT_RBNE); + }else{ + /* enable the USART receive timeout and configure the time of timeout */ + usart_receiver_timeout_enable(EVAL_COM1); + usart_receiver_timeout_config(EVAL_COM1, 115200*3); + + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_RT)); + + for(i=0; i +#include "gd32f1x0_eval.h" + +#define ARRAYNUM(arr_nanme) (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme))) +#define TRANSMIT_SIZE (ARRAYNUM(transmitter_buffer) - 1) + +uint8_t transmitter_buffer[] = "\n\rUSART interrupt test\n\r"; +uint8_t receiver_buffer[32]; +uint8_t transfersize = TRANSMIT_SIZE; +uint8_t receivesize = 32; +__IO uint8_t txcount = 0; +__IO uint16_t rxcount = 0; + + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + /* USART interrupt configuration */ + nvic_irq_enable(USART0_IRQn, 0, 0); + + gd_eval_com_init(EVAL_COM1); + + /* enable USART TBE interrupt */ + usart_interrupt_enable(EVAL_COM1, USART_INT_TBE); + + /* wait until USART send the transmitter_buffer */ + while(txcount < transfersize); + + while (RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TC)); + + usart_interrupt_enable(EVAL_COM1, USART_INT_RBNE); + + /* wait until USART receive the receiver_buffer */ + while(rxcount < receivesize); + if(rxcount == receivesize) + printf("\n\rUSART receive successfully!\n\r"); + + while (1); +} + +/* retarget the C library printf function to the USART */ +int fputc(int ch, FILE *f) +{ + usart_data_transmit(EVAL_COM1, (uint8_t)ch); + while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE)); + return ch; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Transmitter&receiver_interrupt/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Transmitter&receiver_interrupt/readme.txt new file mode 100644 index 0000000..d20d9f0 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/USART/Transmitter&receiver_interrupt/readme.txt @@ -0,0 +1,21 @@ +/*! + \file readme.txt + \brief description of the USART transmit and receive interrupt +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows how to use +the USART transmit and receive interrupts to communicate with the hyperterminal. + Firstly, the USART sends the strings to the hyperterminal and still waits for +receiving data from the hyperterminal. Only the number of data you enter is equal to +or more than 32 bytes, USART will send strings: "USART receive successfully!" (the +reception is stopped when this maximum receive value is reached). + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/gd32f1x0_it.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/gd32f1x0_it.c new file mode 100644 index 0000000..10ce395 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/gd32f1x0_it.c @@ -0,0 +1,114 @@ +/*! + \file gd32f1x0_it.c + \brief interrupt service routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_it.h" +#include "systick.h" +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles HardFault exception + \param[in] none + \param[out] none + \retval none +*/ +void HardFault_Handler(void) +{ + /* if Hard Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles MemManage exception + \param[in] none + \param[out] none + \retval none +*/ +void MemManage_Handler(void) +{ + /* if Memory Manage exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while (1); +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} + +/*! + \brief this function handles DebugMon exception + \param[in] none + \param[out] none + \retval none +*/ +void DebugMon_Handler(void) +{ +} + +/*! + \brief this function handles PendSV exception + \param[in] none + \param[out] none + \retval none +*/ +void PendSV_Handler(void) +{ +} + +/*! + \brief this function handles SysTick exception + \param[in] none + \param[out] none + \retval none +*/ +void SysTick_Handler(void) +{ + delay_decrement(); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/gd32f1x0_it.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/gd32f1x0_it.h new file mode 100644 index 0000000..a4c6c0f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/gd32f1x0_it.h @@ -0,0 +1,40 @@ +/*! + \file gd32f1x0_it.h + \brief the header file of the ISR +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_IT_H +#define GD32F1X0_IT_H + +#include "gd32f1x0.h" + +/* function declarations */ +/* NMI handle function */ +void NMI_Handler(void); +/* HardFault handle function */ +void HardFault_Handler(void); +/* MemManage handle function */ +void MemManage_Handler(void); +/* BusFault handle function */ +void BusFault_Handler(void); +/* UsageFault handle function */ +void UsageFault_Handler(void); +/* SVC handle function */ +void SVC_Handler(void); +/* DebugMon handle function */ +void DebugMon_Handler(void); +/* PendSV handle function */ +void PendSV_Handler(void); +/* SysTick handle function */ +void SysTick_Handler(void); + +#endif /* GD32F1X0_IT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/gd32f1x0_libopt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/gd32f1x0_libopt.h new file mode 100644 index 0000000..62d24a8 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/gd32f1x0_libopt.h @@ -0,0 +1,47 @@ +/*! + \file gd32f1x0_libopt.h + \brief library optional for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_LIBOPT_H +#define GD32F1X0_LIBOPT_H + +#include "gd32f1x0_adc.h" +#include "gd32f1x0_cec.h" +#include "gd32f1x0_crc.h" +#include "gd32f1x0_cmp.h" +#include "gd32f1x0_dac.h" +#include "gd32f1x0_dbg.h" +#include "gd32f1x0_dma.h" +#include "gd32f1x0_exti.h" +#include "gd32f1x0_fmc.h" +#include "gd32f1x0_gpio.h" +#include "gd32f1x0_syscfg.h" +#include "gd32f1x0_i2c.h" +#include "gd32f1x0_fwdgt.h" +#include "gd32f1x0_pmu.h" +#include "gd32f1x0_rcu.h" +#include "gd32f1x0_rtc.h" +#include "gd32f1x0_spi.h" +#include "gd32f1x0_timer.h" +#include "gd32f1x0_usart.h" +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_misc.h" +#include "gd32f1x0_tsi.h" +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_opa.h" +#include "gd32f1x0_ivref.h" +#include "gd32f1x0_can.h" +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_LIBOPT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/main.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/main.c new file mode 100644 index 0000000..0790c51 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/main.c @@ -0,0 +1,66 @@ +/*! + \file main.c + \brief wwdgt delay feed demo +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" +#include +#include "gd32f1x0_eval.h" + +/*! + \brief main function + \param[in] none + \param[out] none + \retval none +*/ +int main(void) +{ + gd_eval_led_init(LED1); + gd_eval_led_init(LED2); + + gd_eval_led_on(LED1); + gd_eval_led_on(LED2); + + systick_config(); + + /* check if the system has resumed from WWDGT reset */ + if (RESET != rcu_flag_get(RCU_FLAG_WWDGTRST)){ + /* WWDGTRST flag set */ + gd_eval_led_on(LED1); + rcu_all_reset_flag_clear(); + while(1); + }else{ + delay_1ms(150); + gd_eval_led_off(LED1); + } + + /* enable WWDGT clock */ + rcu_periph_clock_enable(RCU_WWDGT); + + /* enable WWDGT and set counter value to 127, WWDGT timeout = ~455 us * 64 = 29.2 ms. + in this case the refresh window is: ~455 * (127-80)= 21.4ms < refresh window < ~455 * 64 =29.2ms. + set window value to 80; WWDGT counter should be refreshed only when the counter + is below 80 (and greater than 64) otherwise a reset will be generated. + WWDGT clock counter = (PCLK1 (72MHz)/4096)/8 = 2200Hz (~455 us) */ + wwdgt_config(127,80,WWDGT_CFG_PSC_DIV8); + wwdgt_enable(); + + while (1){ + gd_eval_led_toggle(LED2); + /* insert 25 ms delay */ + delay_1ms(25); + + /* update WWDGT counter */ + wwdgt_counter_update(127); + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/readme.txt b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/readme.txt new file mode 100644 index 0000000..722ccbc --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/readme.txt @@ -0,0 +1,27 @@ +/*! + \file readme.txt + \brief description of the WWDGT_delay_feed example +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + This demo is based on the GD32150R-EVAL/GD32190R-EVAL board, it shows the WWDGT +with different counter value and window value make the different WWDGT timeout. As +a result, LED1 and LED2 display a different phenomenon. + + In this demo, the WWDGT counter value is set to 127, the refresh window is set to +80. In this case the WWDGT timeout is set to 29.2ms(the timeout may varies due to +IRC40K frequency dispersion), the value in the delay function is set to 25ms, the WWDGT +counter can reloaded normally,the LED1 is turn off, LED2 is blinking fast. + + If the value in the delay function is not set properly, the WWDGT counter is not +reloaded. As a result, the system reset and the LED1 and LED2 are remain illuminated. + + In this example the system clock is set to 72 MHz. diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/systick.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/systick.c new file mode 100644 index 0000000..d736be4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/systick.c @@ -0,0 +1,61 @@ +/*! + \file systick.c + \brief the systick configuration file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0.h" +#include "systick.h" + +static uint32_t delay; + +/*! + \brief configure systick + \param[in] none + \param[out] none + \retval none +*/ +void systick_config(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if (SysTick_Config(SystemCoreClock / 1000)){ + /* capture error */ + while (1); + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00); +} + +/*! + \brief delay a time in milliseconds + \param[in] count: count in milliseconds + \param[out] none + \retval none +*/ +void delay_1ms(uint32_t count) +{ + delay = count; + + while(0 != delay); +} + +/*! + \brief delay decrement + \param[in] none + \param[out] none + \retval none +*/ +void delay_decrement(void) +{ + if (0 != delay){ + delay--; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/systick.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/systick.h new file mode 100644 index 0000000..11d6e96 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Examples/WWDGT/WWDGT_delay_feed/systick.h @@ -0,0 +1,27 @@ +/*! + \file systick.h + \brief the header file of systick +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef SYS_TICK_H +#define SYS_TICK_H + +#include + +/* configure systick */ +void systick_config(void); +/* delay a time in milliseconds */ +void delay_1ms(uint32_t count); +/* delay decrement */ +void delay_decrement(void); + +#endif /* SYS_TICK_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Include/gd32f1x0.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Include/gd32f1x0.h new file mode 100644 index 0000000..a2ca5f4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Include/gd32f1x0.h @@ -0,0 +1,236 @@ +/*! + \file gd32f1x0.h + \brief general definitions for gd32f1x0 +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_H +#define GD32F1X0_H + +#ifdef cplusplus + extern "C" { +#endif + +/* define GD32F1x0 */ +#if !defined (GD32F1x0) + #define GD32F1x0 +#endif /* define GD32F1x0 */ +#if !defined (GD32F1x0) + #error "Please select the target GD32F1x0 device used in your application (in gd32f1x0.h file)" +#endif /* undefine GD32F1x0 tip */ + +/* define GD32F1x0 device category */ +#if (!defined (GD32F170_190))&&(!defined (GD32F130_150)) + #error "Please select GD32F1x0 device category( GD32F130_150 or GD32F170_190 )" +#endif /* undefine GD32F170_190 or GD32F130_150 tip */ +#if (defined (GD32F170_190))&&(defined (GD32F130_150)) + #error "Please select one GD32F1x0 device category( GD32F130_150 or GD32F170_190 )" +#endif /* define GD32F170_190 and GD32F130_150 tip */ + +/* define value of high speed crystal oscillator (HXTAL) in Hz */ +#if !defined (HXTAL_VALUE) +#define HXTAL_VALUE ((uint32_t)8000000) +#endif /* high speed crystal oscillator value */ + +/* define startup timeout value of high speed crystal oscillator (HXTAL) */ +#if !defined (HXTAL_STARTUP_TIMEOUT) +#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0x0800) +#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 RC oscillator for ADC in Hz */ +#ifdef GD32F170_190 +#if !defined (IRC28M_VALUE) +#define IRC28M_VALUE ((uint32_t)28000000) +#endif /* IRC28M for GD32F170_190 */ +#else +#if !defined (IRC14M_VALUE) +#define IRC14M_VALUE ((uint32_t)14000000) +#endif /* IRC14M for GD32F130_150 */ +#endif /* GD32F170_190 */ + +/* 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 */ + +/* GD32F1x0 firmware library version number V3.0 */ +#define __GD32F1x0_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:24] main version */ +#define __GD32F1x0_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __GD32F1x0_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __GD32F1x0_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __GD32F1x0_STDPERIPH_VERSION ((__GD32F1x0_STDPERIPH_VERSION_MAIN << 24)\ + |(__GD32F1x0_STDPERIPH_VERSION_SUB1 << 16)\ + |(__GD32F1x0_STDPERIPH_VERSION_SUB2 << 8)\ + |(__GD32F1x0_STDPERIPH_VERSION_RC)) + +/* configuration of the Cortex-M3 processor and core peripherals */ +#define __MPU_PRESENT 1 /*!< GD32F1x0 do not provide MPU */ +#define __NVIC_PRIO_BITS 4 /*!< GD32F1x0 uses 4 bits for the priority levels */ +#define __Vendor_SysTickConfig 0 /*!< set to 1 if different sysTick config is used */ + +/* define interrupt number */ +typedef enum IRQn +{ + /* Cortex-M3 processor exceptions numbers */ + NonMaskableInt_IRQn = -14, /*!< 2 non maskable interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 memory management interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 bus fault interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 usage fault interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV call interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 debug monitor interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 pend SV interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 system tick interrupt */ + /* interruput numbers */ + WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */ + LVD_IRQn = 1, /*!< LVD through EXTI line detect interrupt */ + RTC_IRQn = 2, /*!< RTC through EXTI line interrupt */ + FMC_IRQn = 3, /*!< FMC interrupt */ + RCU_IRQn = 4, /*!< RCU interrupt */ + EXTI0_1_IRQn = 5, /*!< EXTI line 0 and 1 interrupts */ + EXTI2_3_IRQn = 6, /*!< EXTI line 2 and 3 interrupts */ + EXTI4_15_IRQn = 7, /*!< EXTI line 4 to 15 interrupts */ + TSI_IRQn = 8, /*!< TSI Interrupt */ + DMA_Channel0_IRQn = 9, /*!< DMA channel 0 interrupt */ + DMA_Channel1_2_IRQn = 10, /*!< DMA channel 1 and channel 2 interrupts */ + DMA_Channel3_4_IRQn = 11, /*!< DMA channel 3 and channel 4 interrupts */ + ADC_CMP_IRQn = 12, /*!< ADC, CMP0 and CMP1 interrupts */ + TIMER0_BRK_UP_TRG_COM_IRQn = 13, /*!< TIMER0 break, update, trigger and commutation interrupts */ + TIMER0_Channel_IRQn = 14, /*!< TIMER0 channel interrupt */ + TIMER1_IRQn = 15, /*!< TIMER1 interrupt */ + TIMER2_IRQn = 16, /*!< TIMER2 interrupt */ + TIMER5_DAC_IRQn = 17, /*!< TIMER5 and DAC interrupts */ + TIMER13_IRQn = 19, /*!< TIMER13 interrupt */ + TIMER14_IRQn = 20, /*!< TIMER14 interrupt */ + TIMER15_IRQn = 21, /*!< TIMER15 interrupt */ + TIMER16_IRQn = 22, /*!< TIMER16 interrupt */ + I2C0_EV_IRQn = 23, /*!< I2C0 event interrupt */ + I2C1_EV_IRQn = 24, /*!< I2C1 event interrupt */ + SPI0_IRQn = 25, /*!< SPI0 interrupt */ + SPI1_IRQn = 26, /*!< SPI1 interrupt */ + USART0_IRQn = 27, /*!< USART0 interrupt */ + USART1_IRQn = 28, /*!< USART1 interrupt */ + CEC_IRQn = 30, /*!< CEC interrupt */ + I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */ + I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */ + I2C2_EV_IRQn = 35, /*!< I2C2 event interrupt */ + I2C2_ER_IRQn = 36, /*!< I2C2 error interrupt */ + USBD_LP_IRQn = 37, /*!< USBD_LP interrupt */ + USBD_HP_IRQn = 38, /*!< USBD_HP interrupt */ + USBDWakeUp_IRQChannel = 42, /*!< USBD_WKUP interrupt */ + CAN0_TX_IRQn = 43, /*!< CAN0 TX interrupt */ + CAN0_RX0_IRQn = 44, /*!< CAN0 RX0 interrupt */ + CAN0_RX1_IRQn = 45, /*!< CAN0 RX1 interrupt */ + CAN0_SCE_IRQn = 46, /*!< CAN0 SCE interrupt */ + SLCD_IRQn = 47, /*!< SLCD interrupt */ + DMA_Channel5_6_IRQn = 48, /*!< DMA1 channel 5 and channel 6 interrupts */ + SPI2_IRQn = 51, /*!< SPI2 global interrupt */ + CAN1_TX_IRQn = 70, /*!< CAN1 TX interrupt */ + CAN1_RX0_IRQn = 71, /*!< CAN1 RX0 interrupt */ + CAN1_RX1_IRQn = 72, /*!< CAN1 RX1 interrupt */ + CAN1_SCE_IRQn = 73, /*!< CAN1 SCE interrupt */ +} IRQn_Type; + +/* includes */ +#include "core_cm3.h" +#include "system_gd32f1x0.h" +#include + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {FALSE = 0, TRUE = !FALSE} bool; +typedef enum {RESET = 0, SET = !RESET} FlagStatus; +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus; + +/* bit operations */ +#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr)) +#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr)) +#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr)) +#define BIT(x) ((uint32_t)((uint32_t)0x01U<<(x))) +#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) +#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start)) + +/* main flash and SRAM memory map */ +#define FLASH_BASE ((uint32_t)0x08000000U) /*!< main FLASH base address */ +#define SRAM_BASE ((uint32_t)0x20000000U) /*!< SRAM base address */ +/* SRAM and peripheral base bit-band region */ +#define SRAM_BB_BASE ((uint32_t)0x22000000U) /*!< SRAM bit-band base address */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000U) /*!< peripheral bit-band base address */ +/* peripheral memory map */ +#define APB1_BUS_BASE ((uint32_t)0x40000000U) /*!< apb1 base address */ +#define APB2_BUS_BASE ((uint32_t)0x40010000U) /*!< apb2 base address */ +#define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */ +#define AHB2_BUS_BASE ((uint32_t)0x48000000U) /*!< ahb2 base address */ +/* advanced peripheral bus 1 memory map */ +#define TIMER_BASE (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address */ +#define SLCD_BASE (APB1_BUS_BASE + 0x00002400U) /*!< SLCD 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 USART_BASE (APB1_BUS_BASE + 0x00004400U) /*!< USART base address */ +#define SPI_BASE (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address */ +#define I2C_BASE (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address */ +#define USBD_BASE (APB1_BUS_BASE + 0x00005C00U) /*!< USBD base address */ +#define USBD_RAM_BASE (APB1_BUS_BASE + 0x00006000U) /*!< USBD RAM base address */ +#define CAN_BASE (APB1_BUS_BASE + 0x00006400U) /*!< CAN base address */ +#define PMU_BASE (APB1_BUS_BASE + 0x00007000U) /*!< PMU base address */ +#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */ +#define CEC_BASE (APB1_BUS_BASE + 0x00007800U) /*!< CEC base address */ +#define OPA_BASE (APB1_BUS_BASE + 0x00007C5CU) /*!< OPA base address */ +#define IVREF_BASE (APB1_BUS_BASE + 0x00007C00U) /*!< IVREF base address */ +/* advanced peripheral bus 2 memory map */ +#define SYSCFG_BASE (APB2_BUS_BASE + 0x00000000U) /*!< SYSCFG base address */ +#define CMP_BASE (APB2_BUS_BASE + 0x0000001CU) /*!< CMP base address */ +#define EXTI_BASE (APB2_BUS_BASE + 0x00000400U) /*!< EXTI base address */ +#define ADC_BASE (APB2_BUS_BASE + 0x00002400U) /*!< ADC base address */ +/* advanced high performance bus 1 memory map */ +#define DMA_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< DMA base address */ +#define DMA_CHANNEL_BASE (DMA_BASE + 0x00000008U) /*!< DMA channel base address */ +#define 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 TSI_BASE (AHB1_BUS_BASE + 0x00004000U) /*!< TSI 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)0xE0042000U) /*!< DBG base address */ + +/* define marco USE_STDPERIPH_DRIVER */ +#if !defined USE_STDPERIPH_DRIVER +#define USE_STDPERIPH_DRIVER +#endif +#ifdef USE_STDPERIPH_DRIVER +#include "gd32f1x0_libopt.h" +#endif /* USE_STDPERIPH_DRIVER */ + +#ifdef cplusplus +} +#endif +#endif + + + + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Include/system_gd32f1x0.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Include/system_gd32f1x0.h new file mode 100644 index 0000000..7de2a68 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Include/system_gd32f1x0.h @@ -0,0 +1,58 @@ +/*! + \file system_gd32f1x0.h + \brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File for + GD32F1x0 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_GD32F1X0_H +#define SYSTEM_GD32F1X0_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_GD32F1X0_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Source/ARM/startup_gd32f1x0.s b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Source/ARM/startup_gd32f1x0.s new file mode 100644 index 0000000..21422d0 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Source/ARM/startup_gd32f1x0.s @@ -0,0 +1,328 @@ +;/*! +; \file startup_gd32f1x0.s +; \brief start up file +;*/ + +;/* +; Copyright (C) 2017 GigaDevice + +; 2014-12-26, V1.0.0, firmware for GD32F1x0(x=3,5) +; 2016-01-15, V2.0.0, firmware for GD32F1x0(x=3,5,7,9) +; 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) +; 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +;*/ + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000400 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; /* reset Vector Mapped to at Address 0 */ + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + +; /* external interrupts handler */ + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect + DCD RTC_IRQHandler ; 18:RTC through EXTI Line + DCD FMC_IRQHandler ; 19:FMC + DCD RCU_IRQHandler ; 20:RCU + DCD EXTI0_1_IRQHandler ; 21:EXTI Line 0 and EXTI Line 1 + DCD EXTI2_3_IRQHandler ; 22:EXTI Line 2 and EXTI Line 3 + DCD EXTI4_15_IRQHandler ; 23:EXTI Line 4 to EXTI Line 15 + DCD TSI_IRQHandler ; 24:TSI + DCD DMA_Channel0_IRQHandler ; 25:DMA Channel 0 + DCD DMA_Channel1_2_IRQHandler ; 26:DMA Channel 1 and DMA Channel 2 + DCD DMA_Channel3_4_IRQHandler ; 27:DMA Channel 3 and DMA Channel 4 + DCD ADC_CMP_IRQHandler ; 28:ADC and Comparator 0-1 + DCD TIMER0_BRK_UP_TRG_COM_IRQHandler ; 29:TIMER0 Break,Update,Trigger and Commutation + DCD TIMER0_Channel_IRQHandler ; 30:TIMER0 Channel + DCD TIMER1_IRQHandler ; 31:TIMER1 + DCD TIMER2_IRQHandler ; 32:TIMER2 + DCD TIMER5_DAC_IRQHandler ; 33:TIMER5 and DAC + DCD 0 ; Reserved + DCD TIMER13_IRQHandler ; 35:TIMER13 + DCD TIMER14_IRQHandler ; 36:TIMER14 + DCD TIMER15_IRQHandler ; 37:TIMER15 + DCD TIMER16_IRQHandler ; 38:TIMER16 + DCD I2C0_EV_IRQHandler ; 39:I2C0 Event + DCD I2C1_EV_IRQHandler ; 40:I2C1 Event + DCD SPI0_IRQHandler ; 41:SPI0 + DCD SPI1_IRQHandler ; 42:SPI1 + DCD USART0_IRQHandler ; 43:USART0 + DCD USART1_IRQHandler ; 44:USART1 + DCD 0 ; Reserved + DCD CEC_IRQHandler ; 46:CEC + DCD 0 ; Reserved + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD 0 ; Reserved + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error + DCD I2C2_EV_IRQHandler ; 51:I2C2 Event + DCD I2C2_ER_IRQHandler ; 52:I2C2 Error + DCD USBD_LP_IRQHandler ; 53:USBD LP + DCD USBD_HP_IRQHandler ; 54:USBD HP + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD USBDWakeUp_IRQHandler ; 58:USBD Wakeup + DCD CAN0_TX_IRQHandler ; 59:CAN0 TX + DCD CAN0_RX0_IRQHandler ; 60:CAN0 RX0 + DCD CAN0_RX1_IRQHandler ; 61:CAN0 RX1 + DCD CAN0_SCE_IRQHandler ; 62:CAN0 SCE + DCD SLCD_IRQHandler ; 63:SLCD + DCD DMA_Channel5_6_IRQHandler ; 64:DMA Channel5 and Channel6 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SPI2_IRQHandler ; 67:SPI2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD CAN1_TX_IRQHandler ; 86:CAN1 TX + DCD CAN1_RX0_IRQHandler ; 87:CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; 88:CAN1 RX1 + DCD CAN1_SCE_IRQHandler ; 89:CAN1 SCE +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +;/* reset Handler */ +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +;/* dummy Exception Handlers */ +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler\ + PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler\ + PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC +; /* external interrupts handler */ + EXPORT WWDGT_IRQHandler [WEAK] + EXPORT LVD_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT RCU_IRQHandler [WEAK] + EXPORT EXTI0_1_IRQHandler [WEAK] + EXPORT EXTI2_3_IRQHandler [WEAK] + EXPORT EXTI4_15_IRQHandler [WEAK] + EXPORT TSI_IRQHandler [WEAK] + EXPORT DMA_Channel0_IRQHandler [WEAK] + EXPORT DMA_Channel1_2_IRQHandler [WEAK] + EXPORT DMA_Channel3_4_IRQHandler [WEAK] + EXPORT ADC_CMP_IRQHandler [WEAK] + EXPORT TIMER0_BRK_UP_TRG_COM_IRQHandler [WEAK] + EXPORT TIMER0_Channel_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT TIMER5_DAC_IRQHandler [WEAK] + EXPORT TIMER13_IRQHandler [WEAK] + EXPORT TIMER14_IRQHandler [WEAK] + EXPORT TIMER15_IRQHandler [WEAK] + EXPORT TIMER16_IRQHandler [WEAK] + EXPORT I2C0_EV_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT SPI0_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT USART0_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT CEC_IRQHandler [WEAK] + EXPORT I2C0_ER_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT USBD_LP_IRQHandler [WEAK] + EXPORT USBD_HP_IRQHandler [WEAK] + EXPORT USBDWakeUp_IRQHandler [WEAK] + EXPORT CAN0_TX_IRQHandler [WEAK] + EXPORT CAN0_RX0_IRQHandler [WEAK] + EXPORT CAN0_RX1_IRQHandler [WEAK] + EXPORT CAN0_SCE_IRQHandler [WEAK] + EXPORT SLCD_IRQHandler [WEAK] + EXPORT DMA_Channel5_6_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT CAN1_TX_IRQHandler [WEAK] + EXPORT CAN1_RX0_IRQHandler [WEAK] + EXPORT CAN1_RX1_IRQHandler [WEAK] + EXPORT CAN1_SCE_IRQHandler [WEAK] + +;/* external interrupts handler */ +WWDGT_IRQHandler +LVD_IRQHandler +RTC_IRQHandler +FMC_IRQHandler +RCU_IRQHandler +EXTI0_1_IRQHandler +EXTI2_3_IRQHandler +EXTI4_15_IRQHandler +TSI_IRQHandler +DMA_Channel0_IRQHandler +DMA_Channel1_2_IRQHandler +DMA_Channel3_4_IRQHandler +ADC_CMP_IRQHandler +TIMER0_BRK_UP_TRG_COM_IRQHandler +TIMER0_Channel_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +TIMER5_DAC_IRQHandler +TIMER13_IRQHandler +TIMER14_IRQHandler +TIMER15_IRQHandler +TIMER16_IRQHandler +I2C0_EV_IRQHandler +I2C1_EV_IRQHandler +SPI0_IRQHandler +SPI1_IRQHandler +USART0_IRQHandler +USART1_IRQHandler +CEC_IRQHandler +I2C0_ER_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +USBD_LP_IRQHandler +USBD_HP_IRQHandler +USBDWakeUp_IRQHandler +CAN0_TX_IRQHandler +CAN0_RX0_IRQHandler +CAN0_RX1_IRQHandler +CAN0_SCE_IRQHandler +SLCD_IRQHandler +DMA_Channel5_6_IRQHandler +SPI2_IRQHandler +CAN1_TX_IRQHandler +CAN1_RX0_IRQHandler +CAN1_RX1_IRQHandler +CAN1_SCE_IRQHandler + B . + ENDP + + ALIGN + +; user Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Source/IAR/startup_gd32f1x0.s b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Source/IAR/startup_gd32f1x0.s new file mode 100644 index 0000000..de9da37 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Source/IAR/startup_gd32f1x0.s @@ -0,0 +1,415 @@ +;/*! +; \file startup_gd32f1x0.s +; \brief start up file +;*/ + +;/* +; Copyright (C) 2016 GigaDevice + +; 2014-12-26, V1.0.0, firmware for GD32F1x0(x=3,5) +; 2016-01-15, V2.0.0, firmware for GD32F1x0(x=3,5,7,9) +; 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) +; 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +;*/ + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) ; top of stack + DCD Reset_Handler ; Vector Number 1,Reset Handler + + DCD NMI_Handler ; Vector Number 2,NMI Handler + DCD HardFault_Handler ; Vector Number 3,Hard Fault Handler + DCD MemManage_Handler ; Vector Number 4,MPU Fault Handler + DCD BusFault_Handler ; Vector Number 5,Bus Fault Handler + DCD UsageFault_Handler ; Vector Number 6,Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; Vector Number 11,SVCall Handler + DCD DebugMon_Handler ; Vector Number 12,Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; Vector Number 14,PendSV Handler + DCD SysTick_Handler ; Vector Number 15,SysTick Handler + + ; External Interrupts + DCD WWDGT_IRQHandler ; Vector Number 16,Window watchdog timer + DCD LVD_IRQHandler ; Vector Number 17,LVD through EXTI Line detect + DCD RTC_IRQHandler ; Vector Number 18,RTC through EXTI Line + DCD FMC_IRQHandler ; Vector Number 19,FMC + DCD RCU_IRQHandler ; Vector Number 20,RCU + DCD EXTI0_1_IRQHandler ; Vector Number 21,EXTI Line 0 and EXTI Line 1 + DCD EXTI2_3_IRQHandler ; Vector Number 22,EXTI Line 2 and EXTI Line 3 + DCD EXTI4_15_IRQHandler ; Vector Number 23,EXTI Line 4 to EXTI Line 15 + DCD TSI_IRQHandler ; Vector Number 24,TSI + DCD DMA_Channel0_IRQHandler ; Vector Number 25,DMA Channel 0 + DCD DMA_Channel1_2_IRQHandler ; Vector Number 26,DMA Channel 1 and DMA Channel 2 + DCD DMA_Channel3_4_IRQHandler ; Vector Number 27,DMA Channel 3 and DMA Channel 4 + DCD ADC_CMP_IRQHandler ; Vector Number 28,ADC and Comparator 1-2 + DCD TIMER0_BRK_UP_TRG_COM_IRQHandler ; Vector Number 29,TIMER0 Break, Update, Trigger and Commutation + DCD TIMER0_Channel_IRQHandler ; Vector Number 30,TIMER0 Channel + DCD TIMER1_IRQHandler ; Vector Number 31,TIMER1 + DCD TIMER2_IRQHandler ; Vector Number 32,TIMER2 + DCD TIMER5_DAC_IRQHandler ; Vector Number 33,TIMER5 and DAC + DCD 0 ; Reserved + DCD TIMER13_IRQHandler ; Vector Number 35,TIMER13 + DCD TIMER14_IRQHandler ; Vector Number 36,TIMER14 + DCD TIMER15_IRQHandler ; Vector Number 37,TIMER15 + DCD TIMER16_IRQHandler ; Vector Number 38,TIMER16 + DCD I2C0_EV_IRQHandler ; Vector Number 39,I2C0 Event + DCD I2C1_EV_IRQHandler ; Vector Number 40,I2C1 Event + DCD SPI0_IRQHandler ; Vector Number 41,SPI0 + DCD SPI1_IRQHandler ; Vector Number 42,SPI1 + DCD USART0_IRQHandler ; Vector Number 43,USART0 + DCD USART1_IRQHandler ; Vector Number 44,USART1 + DCD 0 ; Reserved + DCD CEC_IRQHandler ; Vector Number 46,CEC + DCD 0 ; Reserved + DCD I2C0_ER_IRQHandler ; Vector Number 48,I2C0 Error + DCD 0 ; Reserved + DCD I2C1_ER_IRQHandler ; Vector Number 50,I2C1 Error + DCD I2C2_EV_IRQHandler ; Vector Number 51,I2C2 Event + DCD I2C2_ER_IRQHandler ; Vector Number 52,I2C2 Error + DCD USBD_LP_IRQHandler ; Vector Number 53,USBD LP + DCD USBD_HP_IRQHandler ; Vector Number 54,USBD HP + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD USBDWakeUp_IRQHandler ; Vector Number 58,USBD Wakeup + DCD CAN0_TX_IRQHandler ; Vector Number 59,CAN0 TX + DCD CAN0_RX0_IRQHandler ; Vector Number 60,CAN0 RX0 + DCD CAN0_RX1_IRQHandler ; Vector Number 61,CAN0 RX1 + DCD CAN0_SCE_IRQHandler ; Vector Number 62,CAN0 SCE + DCD SLCD_IRQHandler ; Vector Number 63,SLCD + DCD DMA_Channel5_6_IRQHandler ; Vector Number 64,DMA Channel5 and Channel6 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SPI2_IRQHandler ; Vector Number 67,SPI2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD CAN1_TX_IRQHandler ; Vector Number 86,CAN1 TX + DCD CAN1_RX0_IRQHandler ; Vector Number 87,CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; Vector Number 88,CAN1 RX1 + DCD CAN1_SCE_IRQHandler ; Vector Number 89,CAN1 SCE + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDGT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDGT_IRQHandler + B WWDGT_IRQHandler + + PUBWEAK LVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LVD_IRQHandler + B LVD_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK FMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_IRQHandler + B FMC_IRQHandler + + PUBWEAK RCU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCU_IRQHandler + B RCU_IRQHandler + + PUBWEAK EXTI0_1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_1_IRQHandler + B EXTI0_1_IRQHandler + + PUBWEAK EXTI2_3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_3_IRQHandler + B EXTI2_3_IRQHandler + + PUBWEAK EXTI4_15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_15_IRQHandler + B EXTI4_15_IRQHandler + + PUBWEAK TSI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TSI_IRQHandler + B TSI_IRQHandler + + PUBWEAK DMA_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA_Channel0_IRQHandler + B DMA_Channel0_IRQHandler + + PUBWEAK DMA_Channel1_2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA_Channel1_2_IRQHandler + B DMA_Channel1_2_IRQHandler + + PUBWEAK DMA_Channel3_4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA_Channel3_4_IRQHandler + B DMA_Channel3_4_IRQHandler + + PUBWEAK ADC_CMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_CMP_IRQHandler + B ADC_CMP_IRQHandler + + PUBWEAK TIMER0_BRK_UP_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_BRK_UP_TRG_COM_IRQHandler + B TIMER0_BRK_UP_TRG_COM_IRQHandler + + PUBWEAK TIMER0_Channel_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_Channel_IRQHandler + B TIMER0_Channel_IRQHandler + + PUBWEAK TIMER1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER1_IRQHandler + B TIMER1_IRQHandler + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER2_IRQHandler + B TIMER2_IRQHandler + + PUBWEAK TIMER5_DAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER5_DAC_IRQHandler + B TIMER5_DAC_IRQHandler + + PUBWEAK TIMER13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER13_IRQHandler + B TIMER13_IRQHandler + + PUBWEAK TIMER14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER14_IRQHandler + B TIMER14_IRQHandler + + PUBWEAK TIMER15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER15_IRQHandler + B TIMER15_IRQHandler + + PUBWEAK TIMER16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER16_IRQHandler + B TIMER16_IRQHandler + + PUBWEAK I2C0_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_EV_IRQHandler + B I2C0_EV_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK SPI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI0_IRQHandler + B SPI0_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK USART0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART0_IRQHandler + B USART0_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK CEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CEC_IRQHandler + B CEC_IRQHandler + + PUBWEAK I2C0_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_ER_IRQHandler + B I2C0_ER_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK USBD_LP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBD_LP_IRQHandler + B USBD_LP_IRQHandler + + PUBWEAK USBD_HP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBD_HP_IRQHandler + B USBD_HP_IRQHandler + + PUBWEAK USBDWakeUp_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBDWakeUp_IRQHandler + B USBDWakeUp_IRQHandler + + PUBWEAK CAN0_TX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_TX_IRQHandler + B CAN0_TX_IRQHandler + + PUBWEAK CAN0_RX0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_RX0_IRQHandler + B CAN0_RX0_IRQHandler + + PUBWEAK CAN0_RX1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_RX1_IRQHandler + B CAN0_RX1_IRQHandler + + PUBWEAK CAN0_SCE_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_SCE_IRQHandler + B CAN0_SCE_IRQHandler + + PUBWEAK SLCD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SLCD_IRQHandler + B SLCD_IRQHandler + + PUBWEAK DMA_Channel5_6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA_Channel5_6_IRQHandler + B DMA_Channel5_6_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK CAN1_TX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_TX_IRQHandler + B CAN1_TX_IRQHandler + + PUBWEAK CAN1_RX0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_RX0_IRQHandler + B CAN1_RX0_IRQHandler + + PUBWEAK CAN1_RX1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_RX1_IRQHandler + B CAN1_RX1_IRQHandler + + PUBWEAK CAN1_SCE_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_SCE_IRQHandler + B CAN1_SCE_IRQHandler + END diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Source/system_gd32f1x0.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Source/system_gd32f1x0.c new file mode 100644 index 0000000..586c911 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/GD/GD32F1x0/Source/system_gd32f1x0.c @@ -0,0 +1,333 @@ +/*! + \file system_gd32f1x0.c + \brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File for + GD32F1x0 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 "gd32f1x0.h" + +/* system frequency define */ +#define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */ +#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ +#define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */ + +/* select a system clock by uncommenting the following line */ +//#define __SYSTEM_CLOCK_8M_HXTAL (__HXTAL) +//#define __SYSTEM_CLOCK_8M_IRC8M (__IRC8M) +#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) +//#define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2 (uint32_t)(72000000) + +#define SEL_IRC8M 0x00 +#define SEL_HXTAL 0x01 +#define SEL_PLL 0x02 + +/* set the system clock frequency and declare the system clock configuration function */ +#ifdef __SYSTEM_CLOCK_8M_HXTAL +uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_HXTAL; +static void system_clock_8m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL; +static void system_clock_72m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2; +static void system_clock_72m_irc8m(void); +#else +uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_IRC8M; +static void system_clock_8m_irc8m(void); +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ + +/* configure the system clock */ +static void system_clock_config(void); + +/*! + \brief setup the microcontroller system, initialize the system + \param[in] none + \param[out] none + \retval none +*/ +void SystemInit (void) +{ + /* enable IRC8M */ + RCU_CTL0 |= RCU_CTL0_IRC8MEN; + while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){ + } + /* reset RCU */ +#ifdef GD32F130_150 + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); +#elif defined (GD32F170_190) + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV | RCU_CFG0_PLLDV); +#endif /* GD32F130_150 */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV); +#ifdef GD32F130_150 + RCU_CFG0 &= ~(RCU_CFG0_USBDPSC); +#endif /* GD32F130_150 */ + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS); + RCU_CFG1 &= ~RCU_CFG1_HXTALPREDV; + RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_CECSEL | RCU_CFG2_ADCSEL); +#ifdef GD32F130_150 + RCU_CTL1 &= ~RCU_CTL1_IRC14MEN; +#elif defined (GD32F170_190) + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CTL1 &= ~RCU_CTL1_IRC28MEN; + RCU_CFG3 &= ~RCU_CFG3_CKOUT1SRC; + RCU_CFG3 &= ~RCU_CFG3_CKOUT1DIV; +#endif /* GD32F130_150 */ + RCU_INT = 0x00000000U; + + /* configure system clock */ + system_clock_config(); +} + +/*! + \brief configure the system clock + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_config(void) +{ +#ifdef __SYSTEM_CLOCK_8M_HXTAL + system_clock_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) + system_clock_72m_hxtal(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) + system_clock_72m_irc8m(); +#else + system_clock_8m_irc8m(); +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ +} + +#ifdef __SYSTEM_CLOCK_8M_HXTAL +/*! + \brief configure the system clock to 8M by HXTAL + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_8m_hxtal(void) +{ + uint32_t timeout = 0; + + /* enable HXTAL */ + RCU_CTL0 |= RCU_CTL0_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + while((0 == (RCU_CTL0 & RCU_CTL0_HXTALSTB)) && (HXTAL_STARTUP_TIMEOUT != timeout++)); + + /* if fail */ + if(0 == (RCU_CTL0 & RCU_CTL0_HXTALSTB)) + return; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select HXTAL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_HXTAL; + + /* wait until HXTAL is selected as system clock */ + while(0 == (RCU_CFG0 & RCU_SCSS_HXTAL)); +} + +#elif defined (__SYSTEM_CLOCK_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_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL0 |= RCU_CTL0_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)){ + return; + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* PLL = HXTAL * 9 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL9); + + /* enable PLL */ + RCU_CTL0 |= RCU_CTL0_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL0 & RCU_CTL0_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(0U == (RCU_CFG0 & RCU_SCSS_PLL)){ + } +} + +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) +/*! + \brief configure the system clock to 72M by PLL which selects IRC8M/2 as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_72m_irc8m(void) +{ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + /* PLL = (IRC8M/2) * 18 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF); + RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL18); + + /* enable PLL */ + RCU_CTL0 |= RCU_CTL0_PLLEN; + + /* wait until PLL is stable */ + while(0 == (RCU_CTL0 & RCU_CTL0_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(0 == (RCU_CFG0 & RCU_SCSS_PLL)); +} + +#else +/*! + \brief configure the system clock to 8M by IRC8M + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_8m_irc8m(void) +{ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select IRC8M as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_IRC8M; + + /* wait until IRC8M is selected as system clock */ + while(0 != (RCU_CFG0 & RCU_SCSS_IRC8M)); +} +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ + +/*! + \brief update the SystemCoreClock with current core clock retrieved from cpu registers + \param[in] none + \param[out] none + \retval none +*/ +void SystemCoreClockUpdate (void) +{ + uint32_t sws = 0U; + uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U; + /* exponent of AHB clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC8M is selected as CK_SYS */ + case SEL_IRC8M: + SystemCoreClock = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + SystemCoreClock = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case SEL_PLL: + /* get the value of PLLMF[3:0] */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf4 = GET_BITS(RCU_CFG0, 27, 27); + /* high 16 bits */ + if(1U == pllmf4){ + pllmf += 17U; + }else{ + pllmf += 2U; + } + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = GET_BITS(RCU_CFG0, 16, 16); + if(0U != pllsel){ + prediv = (GET_BITS(RCU_CFG1, 0, 3) + 1U); + SystemCoreClock = (HXTAL_VALUE / prediv) * pllmf; + }else{ + SystemCoreClock = (IRC8M_VALUE >> 1) * 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/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/core_cm3.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/core_cm3.h new file mode 100644 index 0000000..1b661b4 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/CMSIS/core_cm3.h @@ -0,0 +1,1638 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V3.30 + * @date 17. February 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M3 + @{ + */ + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x03) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) /* Cosmic */ + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI__VFP_SUPPORT____ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) /* Cosmic */ + #if ( __CSMC__ & 0x400) // FPU present for parser + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200 + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if (__CM3_REV < 0x0201) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_Firmware_Library_V3.1.0.chm b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_Firmware_Library_V3.1.0.chm new file mode 100644 index 0000000..3b96347 Binary files /dev/null and b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_Firmware_Library_V3.1.0.chm differ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_adc.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_adc.h new file mode 100644 index 0000000..d0e1c2d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_adc.h @@ -0,0 +1,339 @@ +/*! + \file gd32f1x0_adc.h + \brief definitions for the ADC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_ADC_H +#define GD32F1X0_ADC_H + +#include "gd32f1x0.h" + +/* ADC definitions */ +#define ADC ADC_BASE + +/* registers definitions */ +#define ADC_STAT REG32(ADC + 0x00U) /*!< ADC status register */ +#define ADC_CTL0 REG32(ADC + 0x04U) /*!< ADC control register 0 */ +#define ADC_CTL1 REG32(ADC + 0x08U) /*!< ADC control register 1 */ +#define ADC_SAMPT0 REG32(ADC + 0x0CU) /*!< ADC sampling time register 0 */ +#define ADC_SAMPT1 REG32(ADC + 0x10U) /*!< ADC sampling time register 1 */ +#define ADC_IOFF0 REG32(ADC + 0x14U) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1 REG32(ADC + 0x18U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2 REG32(ADC + 0x1CU) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3 REG32(ADC + 0x20U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WDHT REG32(ADC + 0x24U) /*!< ADC watchdog high threshold register */ +#define ADC_WDLT REG32(ADC + 0x28U) /*!< ADC watchdog low threshold register */ +#define ADC_RSQ0 REG32(ADC + 0x2CU) /*!< ADC regular sequence register 0 */ +#define ADC_RSQ1 REG32(ADC + 0x30U) /*!< ADC regular sequence register 1 */ +#define ADC_RSQ2 REG32(ADC + 0x34U) /*!< ADC regular sequence register 2 */ +#define ADC_ISQ REG32(ADC + 0x38U) /*!< ADC inserted sequence register */ +#define ADC_IDATA0 REG32(ADC + 0x3CU) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1 REG32(ADC + 0x40U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2 REG32(ADC + 0x44U) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3 REG32(ADC + 0x48U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA REG32(ADC + 0x4CU) /*!< ADC regular data register */ + +#ifdef GD32F170_190 +#define ADC_OVSAMPCTL REG32(ADC + 0x80U) /*!< ADC oversampling control register */ +#endif /* GD32F170_190 */ + +/* bits definitions */ +/* ADC_STAT */ +#define ADC_STAT_WDE BIT(0) /*!< analog watchdog flag */ +#define ADC_STAT_EOC BIT(1) /*!< end of conversion */ +#define ADC_STAT_EOIC BIT(2) /*!< injected channel end of conversion */ +#define ADC_STAT_STIC BIT(3) /*!< injected channel start flag */ +#define ADC_STAT_STRC BIT(4) /*!< regular channel start flag */ + +/* ADC_CTL0 */ +#define ADC_CTL0_WDCHSEL BITS(0,4) /*!< analog watchdog channel select bits */ +#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ +#define ADC_CTL0_WDEIE BIT(6) /*!< analog watchdog interrupt enable */ +#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for injected channels */ +#define ADC_CTL0_SM BIT(8) /*!< scan mode */ +#define ADC_CTL0_WDSC BIT(9) /*!< enable the watchdog on a single channel in scan mode */ +#define ADC_CTL0_ICA BIT(10) /*!< automatic injected group conversion */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on injected channels */ +#define ADC_CTL0_DISNUM BITS(13,15) /*!< discontinuous mode channel count */ +#define ADC_CTL0_IWDEN BIT(22) /*!< inserted channel analog watchdog enable */ +#define ADC_CTL0_RWDEN BIT(23) /*!< regular channel analog watchdog enable */ + +#ifdef GD32F170_190 +#define ADC_CTL0_DRES BITS(24,25) /*!< ADC resolution */ +#endif /* GD32F170_190 */ + +/* ADC_CTL1 */ +#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter ON */ +#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */ +#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ +#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ +#define ADC_CTL1_DMA BIT(8) /*!< direct memory access mode */ +#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ +#define ADC_CTL1_ETSIC BITS(12,14) /*!< external event select for injected group */ +#define ADC_CTL1_ETEIC BIT(15) /*!< external trigger conversion mode for injected channels */ +#define ADC_CTL1_ETSRC BITS(17,19) /*!< external event select for regular group */ +#define ADC_CTL1_ETERC BIT(20) /*!< external trigger conversion mode for regular channels */ +#define ADC_CTL1_SWICST BIT(21) /*!< start conversion of injected channels */ +#define ADC_CTL1_SWRCST BIT(22) /*!< start conversion of regular channels */ +#define ADC_CTL1_TSVREN BIT(23) /*!< temperature sensor and VREFINT enable */ +#define ADC_CTL1_VBETEN BIT(24) /*!< VBAT enable */ + +/* ADC_SAMPTx x=0..1 */ +#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel x sample time selection */ + +/* ADC_IOFFx x=0..3 */ +#define ADC_IOFFX_IOFF BITS(0,11) /*!< data offset for injected channel x */ + +/* ADC_WHT */ +#define ADC_WDHT_WDHT BITS(0,11) /*!< analog watchdog high threshold */ + +/* ADC_WLT */ +#define ADC_WDLT_WDLT BITS(0,11) /*!< analog watchdog low threshold */ + +/* ADC_RSQx */ +#define ADC_RSQX_RSQN BITS(0,4) /*!< x conversion in regular sequence */ +#define ADC_RSQ0_RL BITS(20,23) /*!< regular channel sequence length */ + +/* ADC_ISQ */ +#define ADC_ISQ_ISQN BITS(0,4) /*!< x conversion in regular sequence */ +#define ADC_ISQ_IL BITS(20,21) /*!< injected sequence length */ + +/* ADC_IDTx x=0..3*/ +#define ADC_IDATAX_IDATAN BITS(0,15) /*!< injected data x */ + +/* ADC_RDT */ +#define ADC_RDATA_RDATA BITS(0,15) /*!< regular data */ + +#ifdef GD32F170_190 +/* ADC_OVCTL */ +#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 */ +#endif /* GD32F170_190 */ + +/* constants definitions */ +/* ADC channel group definitions */ +#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< adc regular channel group */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< adc injected channel group */ +#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and injected channel group */ + +/* ADC inserted channel definitions */ +#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< adc injected channel 0 */ +#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< adc injected channel 1 */ +#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< adc injected channel 2 */ +#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< adc injected channel 3 */ + +/* 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 channel definitions */ +#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC Channel 0 */ +#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC Channel 1 */ +#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC Channel 2 */ +#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC Channel 3 */ +#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC Channel 4 */ +#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC Channel 5 */ +#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC Channel 6 */ +#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC Channel 7 */ +#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC Channel 8 */ +#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC Channel 9 */ +#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC Channel 10 */ +#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC Channel 11 */ +#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC Channel 12 */ +#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC Channel 13 */ +#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC Channel 14 */ +#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC Channel 15 */ +#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC Channel 16 */ +#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC Channel 17 */ +#define ADC_CHANNEL_18 ((uint8_t)0x12U) /*!< ADC Channel 18 */ + +/* ADC channel sample time */ +#define SAMPTX_SPT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define ADC_SAMPLETIME_1POINT5 SAMPTX_SPT(0) /*!< 1.5 sampling cycles */ +#define ADC_SAMPLETIME_7POINT5 SAMPTX_SPT(1) /*!< 7.5 sampling cycles */ +#define ADC_SAMPLETIME_13POINT5 SAMPTX_SPT(2) /*!< 13.5 sampling cycles */ +#define ADC_SAMPLETIME_28POINT5 SAMPTX_SPT(3) /*!< 28.5 sampling cycles */ +#define ADC_SAMPLETIME_41POINT5 SAMPTX_SPT(4) /*!< 41.5 sampling cycles */ +#define ADC_SAMPLETIME_55POINT5 SAMPTX_SPT(5) /*!< 55.5 sampling cycles */ +#define ADC_SAMPLETIME_71POINT5 SAMPTX_SPT(6) /*!< 71.5 sampling cycles */ +#define ADC_SAMPLETIME_239POINT5 SAMPTX_SPT(7) /*!< 239.5 sampling cycles */ + +/* ADC data alignment */ +#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00U) /*!< LSB alignment */ +#define ADC_DATAALIGN_LEFT ((uint32_t)0x01U) /*!< MSB alignment */ + +/* ADC status flag */ +#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of conversion */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< injected channel end of conversion */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< injected channel start flag */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< regular channel start flag */ + +/* ADC interrupt flag */ +#define ADC_INT_WDE ADC_STAT_WDE /*!< analog watchdog 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 */ + +/* ADC interrupt flag */ +#define ADC_INT_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog 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 */ + +/* ADC resolution definitions */ +#define CTL0_DRES(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) +#define ADC_RESOLUTION_12B CTL0_DRES(0) /*!< 12-bit ADC resolution */ +#define ADC_RESOLUTION_10B CTL0_DRES(1) /*!< 10-bit ADC resolution */ +#define ADC_RESOLUTION_8B CTL0_DRES(2) /*!< 8-bit ADC resolution */ +#define ADC_RESOLUTION_6B CTL0_DRES(3) /*!< 6-bit ADC resolution */ + +/* ADC external trigger select for regular channel */ +#define CTL1_ETSRC(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) +#define ADC_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< external trigger timer 0 CH0 event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< external trigger timer 0 CH1 event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< external trigger timer 0 CH2 event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_T1_CH1 CTL1_ETSRC(3) /*!< external trigger timer 1 CH1 event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(4) /*!< external trigger timer 2 TRGO event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_T14_CH0 CTL1_ETSRC(5) /*!< external trigger timer 14 CH0 event select for regular channel */ +#define ADC_EXTTRIG_REGULAR_EXT_IT11 CTL1_ETSRC(6) /*!< external trigger extiline 11 select for regular channel */ +#define ADC_EXTTRIG_REGULAR_SWRCST CTL1_ETSRC(7) /*!< software trigger select for regular channel */ + +/* ADC external trigger select for inserted channel */ +#define CTL1_ETSIC(regval) (BITS(12,14) & ((uint32_t)(regval) << 12)) +#define ADC_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(0) /*!< external trigger timer0 TRGO event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(1) /*!< external trigger timer0 CH3 event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_T1_TRGO CTL1_ETSIC(2) /*!< external trigger timer1 TRGO event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(3) /*!< external trigger timer1 CH0 event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(4) /*!< external trigger timer2 CH3 event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_T14_TRGO CTL1_ETSIC(5) /*!< external trigger timer14 TRGO event select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_EXT_IT15 CTL1_ETSIC(6) /*!< external interrupt line 15 select for inserted channel */ +#define ADC_EXTTRIG_INSERTED_SWRCST CTL1_ETSIC(7) /*!< software trigger select for inserted channel */ + +/* adc_ioffx register value */ +#define IOFFX_IOFF(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +#ifdef GD32F170_190 +/* ADC oversampling mode */ +#define ADC_OVERSAMPLING_ALL_CONVERT 0 /*!< all oversampled conversions for a channel are done consecutively after a trigger */ +#define ADC_OVERSAMPLING_ONE_CONVERT 1 /*!< each oversampled conversion for a channel needs a trigger */ + +/* ADC oversampling shift */ +#define OVSAMPCTL_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) +#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 */ + +/* ADC oversampling ratio */ +#define OVSAMPCTL_OVSR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) +#define ADC_OVERSAMPLING_RATIO_MUL2 OVSAMPCTL_OVSR(0) /*!< oversampling ratio X2 */ +#define ADC_OVERSAMPLING_RATIO_MUL4 OVSAMPCTL_OVSR(1) /*!< oversampling ratio X4 */ +#define ADC_OVERSAMPLING_RATIO_MUL8 OVSAMPCTL_OVSR(2) /*!< oversampling ratio X8 */ +#define ADC_OVERSAMPLING_RATIO_MUL16 OVSAMPCTL_OVSR(3) /*!< oversampling ratio X16 */ +#define ADC_OVERSAMPLING_RATIO_MUL32 OVSAMPCTL_OVSR(4) /*!< oversampling ratio X32 */ +#define ADC_OVERSAMPLING_RATIO_MUL64 OVSAMPCTL_OVSR(5) /*!< oversampling ratio X64 */ +#define ADC_OVERSAMPLING_RATIO_MUL128 OVSAMPCTL_OVSR(6) /*!< oversampling ratio X128 */ +#define ADC_OVERSAMPLING_RATIO_MUL256 OVSAMPCTL_OVSR(7) /*!< oversampling ratio X256 */ +#endif /* GD32F170_190 */ + +/* function declarations */ +/* ADC reset */ +void adc_deinit(void); +/* enable ADC interface */ +void adc_enable(void); +/* disable ADC interface */ +void adc_disable(void); +/* ADC calibration and reset calibration */ +void adc_calibration_enable(void); +/* enable DMA request */ +void adc_dma_mode_enable(void); +/* disable DMA request */ +void adc_dma_mode_disable(void); +/* enable the temperature sensor and Vrefint channel */ +void adc_tempsensor_vrefint_enable(void); +/* disable the temperature sensor and Vrefint channel */ +void adc_tempsensor_vrefint_disable(void); +/* enable the vbat channel */ +void adc_vbat_enable(void); +/* disable the vbat channel */ +void adc_vbat_disable(void); + +/* ADC discontinuous mode */ +void adc_discontinuous_mode_config(uint8_t channel_group,uint8_t length); +/* ADC special function config */ +void adc_special_function_config(uint32_t function, ControlStatus newvalue); +/* ADC data alignment config */ +void adc_data_alignment_config(uint32_t data_alignment); +/* ADC channel length config */ + +void adc_channel_length_config(uint8_t channel_group,uint32_t length); +/* ADC regular channel config */ +void adc_regular_channel_config(uint8_t rank,uint8_t channel,uint32_t sample_time); +/* ADC inserted channel config */ +void adc_inserted_channel_config(uint8_t rank,uint8_t channel,uint32_t sample_time); +/* ADC inserted channel offset config */ +void adc_inserted_channel_offset_config(uint8_t inserted_channel,uint16_t offset); + +/* ADC external trigger enable */ +void adc_external_trigger_config(uint8_t channel_group,ControlStatus newvalue); +/* ADC external trigger source config */ +void adc_external_trigger_source_config(uint8_t channel_group,uint32_t external_trigger_source); +/* ADC software trigger enable */ +void adc_software_trigger_enable(uint8_t channel_group); + +/* ADC regular group data register read */ +uint16_t adc_regular_data_read(void); +/* ADC inserted group data register read */ +uint16_t adc_inserted_data_read(uint8_t inserted_channel); + +/* get the ADC status flag */ +FlagStatus adc_flag_get(uint32_t flag); +/* clear the ADC status flag */ +void adc_flag_clear(uint32_t flag); +/* get the ADC interrupt flag */ +FlagStatus adc_interrupt_flag_get(uint32_t flag); +/* clear the ADC interrupt or status flag */ +void adc_interrupt_flag_clear(uint32_t flag); +/* ADC interrupt enable */ +void adc_interrupt_enable(uint32_t interrupt); +/* ADC interrupt disable */ +void adc_interrupt_disable(uint32_t interrupt); + +/* ADC analog watchdog single channel config */ +void adc_watchdog_single_channel_enable(uint8_t channel); +/* ADC analog watchdog group channel config */ +void adc_watchdog_group_channel_enable(uint8_t channel_group); +/* ADC analog watchdog disable */ +void adc_watchdog_disable(void); +/* ADC analog watchdog threshold config */ +void adc_watchdog_threshold_config(uint16_t low_threshold,uint16_t high_threshold); + +#ifdef GD32F170_190 +/* ADC resolution config */ +void adc_resolution_config(uint32_t resolution); +/* ADC oversample mode config */ +void adc_oversample_mode_config(uint8_t mode,uint16_t shift,uint8_t ratio); +/* enable ADC oversample mode */ +void adc_oversample_mode_enable(void); +/* disable ADC oversample mode */ +void adc_oversample_mode_disable(void); +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_ADC_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_can.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_can.h new file mode 100644 index 0000000..aab19bc --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_can.h @@ -0,0 +1,706 @@ +/*! + \file gd32f1x0_can.h + \brief definitions for the CAN +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 +#ifndef GD32F1X0_CAN_H +#define GD32F1X0_CAN_H + +#include "gd32f1x0.h" + +/* CAN definitions */ +#define CAN0 CAN_BASE /*!< CAN0 base address */ +#define CAN1 (CAN0 + 0x00000400U) /*!< CAN1 base address */ + +/* registers definitions */ +#define CAN_CTL(canx) REG32((canx) + 0x00U) /*!< CAN control register */ +#define CAN_STAT(canx) REG32((canx) + 0x04U) /*!< CAN status register */ +#define CAN_TSTAT(canx) REG32((canx) + 0x08U) /*!< CAN transmit status register*/ +#define CAN_RFIFO0(canx) REG32((canx) + 0x0CU) /*!< CAN receive FIFO0 register */ +#define CAN_RFIFO1(canx) REG32((canx) + 0x10U) /*!< CAN receive FIFO1 register */ +#define CAN_INTEN(canx) REG32((canx) + 0x14U) /*!< CAN interrupt enable register */ +#define CAN_ERR(canx) REG32((canx) + 0x18U) /*!< CAN error register */ +#define CAN_BT(canx) REG32((canx) + 0x1CU) /*!< CAN bit timing register */ +#define CAN_TMI0(canx) REG32((canx) + 0x180U) /*!< CAN transmit mailbox0 identifier register */ +#define CAN_TMP0(canx) REG32((canx) + 0x184U) /*!< CAN transmit mailbox0 property register */ +#define CAN_TMDATA00(canx) REG32((canx) + 0x188U) /*!< CAN transmit mailbox0 data0 register */ +#define CAN_TMDATA10(canx) REG32((canx) + 0x18CU) /*!< CAN transmit mailbox0 data1 register */ +#define CAN_TMI1(canx) REG32((canx) + 0x190U) /*!< CAN transmit mailbox1 identifier register */ +#define CAN_TMP1(canx) REG32((canx) + 0x194U) /*!< CAN transmit mailbox1 property register */ +#define CAN_TMDATA01(canx) REG32((canx) + 0x198U) /*!< CAN transmit mailbox1 data0 register */ +#define CAN_TMDATA11(canx) REG32((canx) + 0x19CU) /*!< CAN transmit mailbox1 data1 register */ +#define CAN_TMI2(canx) REG32((canx) + 0x1A0U) /*!< CAN transmit mailbox2 identifier register */ +#define CAN_TMP2(canx) REG32((canx) + 0x1A4U) /*!< CAN transmit mailbox2 property register */ +#define CAN_TMDATA02(canx) REG32((canx) + 0x1A8U) /*!< CAN transmit mailbox2 data0 register */ +#define CAN_TMDATA12(canx) REG32((canx) + 0x1ACU) /*!< CAN transmit mailbox2 data1 register */ +#define CAN_RFIFOMI0(canx) REG32((canx) + 0x1B0U) /*!< CAN receive FIFO0 mailbox identifier register */ +#define CAN_RFIFOMP0(canx) REG32((canx) + 0x1B4U) /*!< CAN receive FIFO0 mailbox property register */ +#define CAN_RFIFOMDATA00(canx) REG32((canx) + 0x1B8U) /*!< CAN receive FIFO0 mailbox data0 register */ +#define CAN_RFIFOMDATA10(canx) REG32((canx) + 0x1CCU) /*!< CAN receive FIFO0 mailbox data1 register */ +#define CAN_RFIFOMI1(canx) REG32((canx) + 0x1C0U) /*!< CAN receive FIFO1 mailbox identifier register */ +#define CAN_RFIFOMP1(canx) REG32((canx) + 0x1C4U) /*!< CAN receive FIFO1 mailbox property register */ +#define CAN_RFIFOMDATA01(canx) REG32((canx) + 0x1C8U) /*!< CAN receive FIFO1 mailbox data0 register */ +#define CAN_RFIFOMDATA11(canx) REG32((canx) + 0x1CCU) /*!< CAN receive FIFO1 mailbox data1 register */ +#define CAN_FCTL(canx) REG32((canx) + 0x200U) /*!< CAN filter control register */ +#define CAN_FMCFG(canx) REG32((canx) + 0x204U) /*!< CAN filter mode register */ +#define CAN_FSCFG(canx) REG32((canx) + 0x20CU) /*!< CAN filter scale register */ +#define CAN_FAFIFO(canx) REG32((canx) + 0x214U) /*!< CAN filter associated FIFO register */ +#define CAN_FW(canx) REG32((canx) + 0x21CU) /*!< CAN filter working register */ +#define CAN_F0DATA0(canx) REG32((canx) + 0x240U) /*!< CAN filter 0 data 0 register */ +#define CAN_F1DATA0(canx) REG32((canx) + 0x248U) /*!< CAN filter 1 data 0 register */ +#define CAN_F2DATA0(canx) REG32((canx) + 0x250U) /*!< CAN filter 2 data 0 register */ +#define CAN_F3DATA0(canx) REG32((canx) + 0x258U) /*!< CAN filter 3 data 0 register */ +#define CAN_F4DATA0(canx) REG32((canx) + 0x260U) /*!< CAN filter 4 data 0 register */ +#define CAN_F5DATA0(canx) REG32((canx) + 0x268U) /*!< CAN filter 5 data 0 register */ +#define CAN_F6DATA0(canx) REG32((canx) + 0x270U) /*!< CAN filter 6 data 0 register */ +#define CAN_F7DATA0(canx) REG32((canx) + 0x278U) /*!< CAN filter 7 data 0 register */ +#define CAN_F8DATA0(canx) REG32((canx) + 0x280U) /*!< CAN filter 8 data 0 register */ +#define CAN_F9DATA0(canx) REG32((canx) + 0x288U) /*!< CAN filter 9 data 0 register */ +#define CAN_F10DATA0(canx) REG32((canx) + 0x290U) /*!< CAN filter 10 data 0 register */ +#define CAN_F11DATA0(canx) REG32((canx) + 0x298U) /*!< CAN filter 11 data 0 register */ +#define CAN_F12DATA0(canx) REG32((canx) + 0x2A0U) /*!< CAN filter 12 data 0 register */ +#define CAN_F13DATA0(canx) REG32((canx) + 0x2A8U) /*!< CAN filter 13 data 0 register */ +#define CAN_F14DATA0(canx) REG32((canx) + 0x2B0U) /*!< CAN filter 14 data 0 register */ +#define CAN_F15DATA0(canx) REG32((canx) + 0x2B8U) /*!< CAN filter 15 data 0 register */ +#define CAN_F16DATA0(canx) REG32((canx) + 0x2C0U) /*!< CAN filter 16 data 0 register */ +#define CAN_F17DATA0(canx) REG32((canx) + 0x2C8U) /*!< CAN filter 17 data 0 register */ +#define CAN_F18DATA0(canx) REG32((canx) + 0x2D0U) /*!< CAN filter 18 data 0 register */ +#define CAN_F19DATA0(canx) REG32((canx) + 0x2D8U) /*!< CAN filter 19 data 0 register */ +#define CAN_F20DATA0(canx) REG32((canx) + 0x2E0U) /*!< CAN filter 20 data 0 register */ +#define CAN_F21DATA0(canx) REG32((canx) + 0x2E8U) /*!< CAN filter 21 data 0 register */ +#define CAN_F22DATA0(canx) REG32((canx) + 0x2F0U) /*!< CAN filter 22 data 0 register */ +#define CAN_F23DATA0(canx) REG32((canx) + 0x3F8U) /*!< CAN filter 23 data 0 register */ +#define CAN_F24DATA0(canx) REG32((canx) + 0x300U) /*!< CAN filter 24 data 0 register */ +#define CAN_F25DATA0(canx) REG32((canx) + 0x308U) /*!< CAN filter 25 data 0 register */ +#define CAN_F26DATA0(canx) REG32((canx) + 0x310U) /*!< CAN filter 26 data 0 register */ +#define CAN_F27DATA0(canx) REG32((canx) + 0x318U) /*!< CAN filter 27 data 0 register */ +#define CAN_F0DATA1(canx) REG32((canx) + 0x244U) /*!< CAN filter 0 data 1 register */ +#define CAN_F1DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 1 data 1 register */ +#define CAN_F2DATA1(canx) REG32((canx) + 0x254U) /*!< CAN filter 2 data 1 register */ +#define CAN_F3DATA1(canx) REG32((canx) + 0x25CU) /*!< CAN filter 3 data 1 register */ +#define CAN_F4DATA1(canx) REG32((canx) + 0x264U) /*!< CAN filter 4 data 1 register */ +#define CAN_F5DATA1(canx) REG32((canx) + 0x26CU) /*!< CAN filter 5 data 1 register */ +#define CAN_F6DATA1(canx) REG32((canx) + 0x274U) /*!< CAN filter 6 data 1 register */ +#define CAN_F7DATA1(canx) REG32((canx) + 0x27CU) /*!< CAN filter 7 data 1 register */ +#define CAN_F8DATA1(canx) REG32((canx) + 0x284U) /*!< CAN filter 8 data 1 register */ +#define CAN_F9DATA1(canx) REG32((canx) + 0x28CU) /*!< CAN filter 9 data 1 register */ +#define CAN_F10DATA1(canx) REG32((canx) + 0x294U) /*!< CAN filter 10 data 1 register */ +#define CAN_F11DATA1(canx) REG32((canx) + 0x29CU) /*!< CAN filter 11 data 1 register */ +#define CAN_F12DATA1(canx) REG32((canx) + 0x2A4U) /*!< CAN filter 12 data 1 register */ +#define CAN_F13DATA1(canx) REG32((canx) + 0x2ACU) /*!< CAN filter 13 data 1 register */ +#define CAN_F14DATA1(canx) REG32((canx) + 0x2B4U) /*!< CAN filter 14 data 1 register */ +#define CAN_F15DATA1(canx) REG32((canx) + 0x2BCU) /*!< CAN filter 15 data 1 register */ +#define CAN_F16DATA1(canx) REG32((canx) + 0x2C4U) /*!< CAN filter 16 data 1 register */ +#define CAN_F17DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 17 data 1 register */ +#define CAN_F18DATA1(canx) REG32((canx) + 0x2D4U) /*!< CAN filter 18 data 1 register */ +#define CAN_F19DATA1(canx) REG32((canx) + 0x2DCU) /*!< CAN filter 19 data 1 register */ +#define CAN_F20DATA1(canx) REG32((canx) + 0x2E4U) /*!< CAN filter 20 data 1 register */ +#define CAN_F21DATA1(canx) REG32((canx) + 0x2ECU) /*!< CAN filter 21 data 1 register */ +#define CAN_F22DATA1(canx) REG32((canx) + 0x2F4U) /*!< CAN filter 22 data 1 register */ +#define CAN_F23DATA1(canx) REG32((canx) + 0x2FCU) /*!< CAN filter 23 data 1 register */ +#define CAN_F24DATA1(canx) REG32((canx) + 0x304U) /*!< CAN filter 24 data 1 register */ +#define CAN_F25DATA1(canx) REG32((canx) + 0x30CU) /*!< CAN filter 25 data 1 register */ +#define CAN_F26DATA1(canx) REG32((canx) + 0x314U) /*!< CAN filter 26 data 1 register */ +#define CAN_F27DATA1(canx) REG32((canx) + 0x31CU) /*!< CAN filter 27 data 1 register */ +#define CAN_PHYCTL(canx) REG32((canx) + 0x3FCU) /*!< CAN PHY control register */ + +/* CAN transmit mailbox bank */ +#define CAN_TMI(canx, bank) REG32((canx) + 0x180U + ((bank) * 0x10U)) /*!< CAN transmit mailbox identifier register */ +#define CAN_TMP(canx, bank) REG32((canx) + 0x184U + ((bank) * 0x10U)) /*!< CAN transmit mailbox property register */ +#define CAN_TMDATA0(canx, bank) REG32((canx) + 0x188U + ((bank) * 0x10U)) /*!< CAN transmit mailbox data0 register */ +#define CAN_TMDATA1(canx, bank) REG32((canx) + 0x18CU + ((bank) * 0x10U)) /*!< CAN transmit mailbox data1 register */ + +/* CAN filter bank */ +#define CAN_FDATA0(canx, bank) REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x0U) /*!< CAN filter data 0 register */ +#define CAN_FDATA1(canx, bank) REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x4U) /*!< CAN filter data 1 register */ + +/* CAN receive fifo mailbox bank */ +#define CAN_RFIFOMI(canx, bank) REG32((canx) + 0x1B0U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox identifier register */ +#define CAN_RFIFOMP(canx, bank) REG32((canx) + 0x1B4U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox property register */ +#define CAN_RFIFOMDATA0(canx, bank) REG32((canx) + 0x1B8U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox data0 register */ +#define CAN_RFIFOMDATA1(canx, bank) REG32((canx) + 0x1BCU + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox data1 register */ + +/* bits definitions */ +/* CAN_CTL */ +#define CAN_CTL_IWMOD BIT(0) /*!< initial working mode */ +#define CAN_CTL_SLPWMOD BIT(1) /*!< sleep working mode */ +#define CAN_CTL_TFO BIT(2) /*!< transmit FIFO order */ +#define CAN_CTL_RFOD BIT(3) /*!< receive FIFO overwrite disable */ +#define CAN_CTL_ARD BIT(4) /*!< automatic retransmission disable */ +#define CAN_CTL_AWU BIT(5) /*!< automatic wakeup */ +#define CAN_CTL_ABOR BIT(6) /*!< automatic bus-off recovery */ +#define CAN_CTL_TTC BIT(7) /*!< time triggered communication */ +#define CAN_CTL_SWRST BIT(15) /*!< CAN software reset */ +#define CAN_CTL_DFZ BIT(16) /*!< CAN debug freeze */ + +/* CAN_STAT */ +#define CAN_STAT_IWS BIT(0) /*!< initial working state */ +#define CAN_STAT_SLPWS BIT(1) /*!< sleep working state */ +#define CAN_STAT_ERRIF BIT(2) /*!< error interrupt flag*/ +#define CAN_STAT_WUIF BIT(3) /*!< status change interrupt flag of wakeup from sleep working mode */ +#define CAN_STAT_SLPIF BIT(4) /*!< status change interrupt flag of sleep working mode entering */ +#define CAN_STAT_TS BIT(8) /*!< transmitting state */ +#define CAN_STAT_RS BIT(9) /*!< receiving state */ +#define CAN_STAT_LASTRX BIT(10) /*!< last sample value of rx pin */ +#define CAN_STAT_RXL BIT(11) /*!< CAN rx signal */ + +/* CAN_TSTAT */ +#define CAN_TSTAT_MTF0 BIT(0) /*!< mailbox0 transmit finished */ +#define CAN_TSTAT_MTFNERR0 BIT(1) /*!< mailbox0 transmit finished and no error */ +#define CAN_TSTAT_MAL0 BIT(2) /*!< mailbox0 arbitration lost */ +#define CAN_TSTAT_MTE0 BIT(3) /*!< mailbox0 transmit error */ +#define CAN_TSTAT_MST0 BIT(7) /*!< mailbox0 stop transmitting */ +#define CAN_TSTAT_MTF1 BIT(8) /*!< mailbox1 transmit finished */ +#define CAN_TSTAT_MTFNERR1 BIT(9) /*!< mailbox1 transmit finished and no error */ +#define CAN_TSTAT_MAL1 BIT(10) /*!< mailbox1 arbitration lost */ +#define CAN_TSTAT_MTE1 BIT(11) /*!< mailbox1 transmit error */ +#define CAN_TSTAT_MST1 BIT(15) /*!< mailbox1 stop transmitting */ +#define CAN_TSTAT_MTF2 BIT(16) /*!< mailbox2 transmit finished */ +#define CAN_TSTAT_MTFNERR2 BIT(17) /*!< mailbox2 transmit finished and no error */ +#define CAN_TSTAT_MAL2 BIT(18) /*!< mailbox2 arbitration lost */ +#define CAN_TSTAT_MTE2 BIT(19) /*!< mailbox2 transmit error */ +#define CAN_TSTAT_MST2 BIT(23) /*!< mailbox2 stop transmitting */ +#define CAN_TSTAT_NUM BITS(24,25) /*!< mailbox number */ +#define CAN_TSTAT_TME0 BIT(26) /*!< transmit mailbox0 empty */ +#define CAN_TSTAT_TME1 BIT(27) /*!< transmit mailbox1 empty */ +#define CAN_TSTAT_TME2 BIT(28) /*!< transmit mailbox2 empty */ +#define CAN_TSTAT_TMLS0 BIT(29) /*!< last sending priority flag for mailbox0 */ +#define CAN_TSTAT_TMLS1 BIT(30) /*!< last sending priority flag for mailbox1 */ +#define CAN_TSTAT_TMLS2 BIT(31) /*!< last sending priority flag for mailbox2 */ + +/* CAN_RFIFO0 */ +#define CAN_RFIFO0_RFL0 BITS(0,1) /*!< receive FIFO0 length */ +#define CAN_RFIFO0_RFF0 BIT(3) /*!< receive FIFO0 full */ +#define CAN_RFIFO0_RFO0 BIT(4) /*!< receive FIFO0 overfull */ +#define CAN_RFIFO0_RFD0 BIT(5) /*!< receive FIFO0 dequeue */ + +/* CAN_RFIFO1 */ +#define CAN_RFIFO1_RFL1 BITS(0,1) /*!< receive FIFO1 length */ +#define CAN_RFIFO1_RFF1 BIT(3) /*!< receive FIFO1 full */ +#define CAN_RFIFO1_RFO1 BIT(4) /*!< receive FIFO1 overfull */ +#define CAN_RFIFO1_RFD1 BIT(5) /*!< receive FIFO1 dequeue */ + +/* CAN_INTEN */ +#define CAN_INTEN_TMEIE BIT(0) /*!< transmit mailbox empty interrupt enable */ +#define CAN_INTEN_RFNEIE0 BIT(1) /*!< receive FIFO0 not empty interrupt enable */ +#define CAN_INTEN_RFFIE0 BIT(2) /*!< receive FIFO0 full interrupt enable */ +#define CAN_INTEN_RFOIE0 BIT(3) /*!< receive FIFO0 overfull interrupt enable */ +#define CAN_INTEN_RFNEIE1 BIT(4) /*!< receive FIFO1 not empty interrupt enable */ +#define CAN_INTEN_RFFIE1 BIT(5) /*!< receive FIFO1 full interrupt enable */ +#define CAN_INTEN_RFOIE1 BIT(6) /*!< receive FIFO1 overfull interrupt enable */ +#define CAN_INTEN_WERRIE BIT(8) /*!< warning error interrupt enable */ +#define CAN_INTEN_PERRIE BIT(9) /*!< passive error interrupt enable */ +#define CAN_INTEN_BOIE BIT(10) /*!< bus-off interrupt enable */ +#define CAN_INTEN_ERRNIE BIT(11) /*!< error number interrupt enable */ +#define CAN_INTEN_ERRIE BIT(15) /*!< error interrupt enable */ +#define CAN_INTEN_WIE BIT(16) /*!< wakeup interrupt enable */ +#define CAN_INTEN_SLPWIE BIT(17) /*!< sleep working interrupt enable */ + +/* CAN_ERR */ +#define CAN_ERR_WERR BIT(0) /*!< warning error */ +#define CAN_ERR_PERR BIT(1) /*!< passive error */ +#define CAN_ERR_BOERR BIT(2) /*!< bus-off error */ +#define CAN_ERR_ERRN BITS(4,6) /*!< error number */ +#define CAN_ERR_TECNT BITS(16,23) /*!< transmit error count */ +#define CAN_ERR_RECNT BITS(24,31) /*!< receive error count */ + +/* CAN_BT */ +#define CAN_BT_BAUDPSC BITS(0,9) /*!< baudrate prescaler */ +#define CAN_BT_BS1 BITS(16,19) /*!< bit segment 1 */ +#define CAN_BT_BS2 BITS(20,22) /*!< bit segment 2 */ +#define CAN_BT_SJW BITS(24,25) /*!< resynchronization jump width */ +#define CAN_BT_LCMOD BIT(30) /*!< loopback communication mode */ +#define CAN_BT_SCMOD BIT(31) /*!< silent communication mode */ + +/* CAN_TMIx */ +#define CAN_TMI_TEN BIT(0) /*!< transmit enable */ +#define CAN_TMI_FT BIT(1) /*!< frame type */ +#define CAN_TMI_FF BIT(2) /*!< frame format */ +#define CAN_TMI_EFID BITS(3,31) /*!< the frame identifier */ +#define CAN_TMI_SFID BITS(21,31) /*!< the frame identifier */ + +/* CAN_TMPx */ +#define CAN_TMP_DLENC BITS(0,3) /*!< data length code */ +#define CAN_TMP_TSEN BIT(8) /*!< time stamp enable */ +#define CAN_TMP_TS BITS(16,31) /*!< time stamp */ + +/* CAN_TMDATA0x */ +#define CAN_TMDATA0_DB0 BITS(0,7) /*!< transmit data byte 0 */ +#define CAN_TMDATA0_DB1 BITS(8,15) /*!< transmit data byte 1 */ +#define CAN_TMDATA0_DB2 BITS(16,23) /*!< transmit data byte 2 */ +#define CAN_TMDATA0_DB3 BITS(24,31) /*!< transmit data byte 3 */ + +/* CAN_TMDATA1x */ +#define CAN_TMDATA1_DB4 BITS(0,7) /*!< transmit data byte 4 */ +#define CAN_TMDATA1_DB5 BITS(8,15) /*!< transmit data byte 5 */ +#define CAN_TMDATA1_DB6 BITS(16,23) /*!< transmit data byte 6 */ +#define CAN_TMDATA1_DB7 BITS(24,31) /*!< transmit data byte 7 */ + +/* CAN_RFIFOMIx */ +#define CAN_RFIFOMI_FT BIT(1) /*!< frame type */ +#define CAN_RFIFOMI_FF BIT(2) /*!< frame format */ +#define CAN_RFIFOMI_EFID BITS(3,31) /*!< the frame identifier */ +#define CAN_RFIFOMI_SFID BITS(21,31) /*!< the frame identifier */ + +/* CAN_RFIFOMPx */ +#define CAN_RFIFOMP_DLENC BITS(0,3) /*!< receive data length code */ +#define CAN_RFIFOMP_FI BITS(8,15) /*!< filter index */ +#define CAN_RFIFOMP_TS BITS(16,31) /*!< time stamp */ + +/* CAN_RFIFOMDATA0x */ +#define CAN_RFIFOMDATA0_DB0 BITS(0,7) /*!< receive data byte 0 */ +#define CAN_RFIFOMDATA0_DB1 BITS(8,15) /*!< receive data byte 1 */ +#define CAN_RFIFOMDATA0_DB2 BITS(16,23) /*!< receive data byte 2 */ +#define CAN_RFIFOMDATA0_DB3 BITS(24,31) /*!< receive data byte 3 */ + +/* CAN_RFIFOMDATA1x */ +#define CAN_RFIFOMDATA1_DB4 BITS(0,7) /*!< receive data byte 4 */ +#define CAN_RFIFOMDATA1_DB5 BITS(8,15) /*!< receive data byte 5 */ +#define CAN_RFIFOMDATA1_DB6 BITS(16,23) /*!< receive data byte 6 */ +#define CAN_RFIFOMDATA1_DB7 BITS(24,31) /*!< receive data byte 7 */ + +/* CAN_FCTL */ +#define CAN_FCTL_FLD BIT(0) /*!< filter lock disable */ +#define CAN_FCTL_HBC1F BITS(8,13) /*!< header bank of CAN1 filter */ + +/* CAN_FMCFG */ +#define CAN_FMCFG_FMOD(regval) BIT(regval) /*!< filter mode, list or mask*/ + +/* CAN_FSCFG */ +#define CAN_FSCFG_FS(regval) BIT(regval) /*!< filter scale, 32 bits or 16 bits*/ + +/* CAN_FAFIFO */ +#define CAN_FAFIFOR_FAF(regval) BIT(regval) /*!< filter associated with FIFO */ + +/* CAN_FW */ +#define CAN_FW_FW(regval) BIT(regval) /*!< filter working */ + +/* CAN_FxDATAy */ +#define CAN_FDATA_FD BITS(0,31) /*!< filter data */ + +/* CAN_PHYCTL */ +#define CAN_PHYCTL_PHYEN BIT(0) /*!< PHY enable */ +#define CAN_PHYCTL_POMOD BITS(8,9) /*!< PHY mode */ + +/* consts definitions */ +/* define the CAN bit position and its register index offset */ +#define CAN_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define CAN_REG_VAL(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 6))) +#define CAN_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +#define CAN_REGIDX_BITS(regidx, bitpos0, bitpos1) (((uint32_t)(regidx) << 12) | ((uint32_t)(bitpos0) << 6) | (uint32_t)(bitpos1)) +#define CAN_REG_VALS(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 12))) +#define CAN_BIT_POS0(val) (((uint32_t)(val) >> 6) & 0x1FU) +#define CAN_BIT_POS1(val) ((uint32_t)(val) & 0x1FU) + +/* register offset */ +#define STAT_REG_OFFSET ((uint8_t)0x04U) /*!< STAT register offset */ +#define TSTAT_REG_OFFSET ((uint8_t)0x08U) /*!< TSTAT register offset */ +#define RFIFO0_REG_OFFSET ((uint8_t)0x0CU) /*!< RFIFO0 register offset */ +#define RFIFO1_REG_OFFSET ((uint8_t)0x10U) /*!< RFIFO1 register offset */ +#define ERR_REG_OFFSET ((uint8_t)0x18U) /*!< ERR register offset */ + +/* CAN flags */ +typedef enum +{ + /* flags in TSTAT register */ + CAN_FLAG_MTE2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 19U), /*!< mailbox 2 transmit error */ + CAN_FLAG_MTE1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 11U), /*!< mailbox 1 transmit error */ + CAN_FLAG_MTE0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 3U), /*!< mailbox 0 transmit error */ + CAN_FLAG_MTF2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 16U), /*!< mailbox 2 transmit finished */ + CAN_FLAG_MTF1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 8U), /*!< mailbox 1 transmit finished */ + CAN_FLAG_MTF0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 0U), /*!< mailbox 0 transmit finished */ + /* flags in RFIFO0 register */ + CAN_FLAG_RFO0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 4U), /*!< receive FIFO0 overfull */ + CAN_FLAG_RFF0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 3U), /*!< receive FIFO0 full */ + /* flags in RFIFO1 register */ + CAN_FLAG_RFO1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 4U), /*!< receive FIFO1 overfull */ + CAN_FLAG_RFF1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 3U), /*!< receive FIFO1 full */ + /* flags in ERR register */ + CAN_FLAG_BOERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 2U), /*!< bus-off error */ + CAN_FLAG_PERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 1U), /*!< passive error */ + CAN_FLAG_WERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 0U), /*!< warning error */ +}can_flag_enum; + +/* CAN interrupt flags */ +typedef enum +{ + /* interrupt flags in STAT register */ + CAN_INT_FLAG_SLPIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 4U, 17U), /*!< status change interrupt flag of sleep working mode entering */ + CAN_INT_FLAG_WUIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 3U, 16), /*!< status change interrupt flag of wakeup from sleep working mode */ + CAN_INT_FLAG_ERRIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 2U, 15), /*!< error interrupt flag */ + /* interrupt flags in TSTAT register */ + CAN_INT_FLAG_MTF2 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 16U, 0U), /*!< mailbox 2 transmit finished interrupt flag */ + CAN_INT_FLAG_MTF1 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 8U, 0U), /*!< mailbox 1 transmit finished interrupt flag */ + CAN_INT_FLAG_MTF0 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 0U, 0U), /*!< mailbox 0 transmit finished interrupt flag */ + /* interrupt flags in RFIFO0 register */ + CAN_INT_FLAG_RFO0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 4U, 3U), /*!< receive FIFO0 overfull interrupt flag */ + CAN_INT_FLAG_RFF0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 3U, 2U), /*!< receive FIFO0 full interrupt flag */ + /* interrupt flags in RFIFO0 register */ + CAN_INT_FLAG_RFO1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 4U, 6U), /*!< receive FIFO1 overfull interrupt flag */ + CAN_INT_FLAG_RFF1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 3U, 5U), /*!< receive FIFO1 full interrupt flag */ +}can_interrupt_flag_enum; + +/* CAN initiliaze parameters struct */ +typedef struct +{ + uint8_t working_mode; /*!< CAN working mode */ + uint8_t resync_jump_width; /*!< CAN resynchronization jump width */ + uint8_t time_segment_1; /*!< time segment 1 */ + uint8_t time_segment_2; /*!< time segment 2 */ + ControlStatus time_triggered; /*!< time triggered communication mode */ + ControlStatus auto_bus_off_recovery; /*!< automatic bus-off recovery */ + ControlStatus auto_wake_up; /*!< automatic wake-up mode */ + ControlStatus auto_retrans; /*!< automatic retransmission mode */ + ControlStatus rec_fifo_overwrite; /*!< receive FIFO overwrite mode */ + ControlStatus trans_fifo_order; /*!< transmit FIFO order */ + uint16_t prescaler; /*!< baudrate prescaler */ +}can_parameter_struct; + +/* CAN transmit message struct */ +typedef struct +{ + uint32_t tx_sfid; /*!< standard format frame identifier */ + uint32_t tx_efid; /*!< extended format frame identifier */ + uint8_t tx_ff; /*!< format of frame, standard or extended format */ + uint8_t tx_ft; /*!< type of frame, data or remote */ + uint8_t tx_dlen; /*!< data length */ + uint8_t tx_data[8]; /*!< transmit data */ +}can_trasnmit_message_struct; + +/* CAN receive message struct */ +typedef struct +{ + uint32_t rx_sfid; /*!< standard format frame identifier */ + uint32_t rx_efid; /*!< extended format frame identifier */ + uint8_t rx_ff; /*!< format of frame, standard or extended format */ + uint8_t rx_ft; /*!< type of frame, data or remote */ + uint8_t rx_dlen; /*!< data length */ + uint8_t rx_data[8]; /*!< receive data */ + uint8_t rx_fi; /*!< filtering index */ +} can_receive_message_struct; + +/* CAN filter parameters struct */ +typedef struct +{ + uint16_t filter_list_high; /*!< filter list number high bits*/ + uint16_t filter_list_low; /*!< filter list number low bits */ + uint16_t filter_mask_high; /*!< filter mask number high bits */ + uint16_t filter_mask_low; /*!< filter mask number low bits */ + uint16_t filter_fifo_number; /*!< receive FIFO associated with the filter */ + uint16_t filter_number; /*!< filter number */ + uint16_t filter_mode; /*!< filter mode, list or mask */ + uint16_t filter_bits; /*!< filter scale */ + ControlStatus filter_enable; /*!< filter work or not */ +}can_filter_parameter_struct; + +/* CAN errors */ +typedef enum +{ + CAN_ERROR_NONE = 0, /*!< no error */ + CAN_ERROR_FILL, /*!< fill error */ + CAN_ERROR_FORMATE, /*!< format error */ + CAN_ERROR_ACK, /*!< ACK error */ + CAN_ERROR_BITRECESSIVE, /*!< bit recessive error */ + CAN_ERROR_BITDOMINANTER, /*!< bit dominant error */ + CAN_ERROR_CRC, /*!< CRC error */ + CAN_ERROR_SOFTWARECFG, /*!< software configure */ +}can_error_enum; + +/* transmit states */ +typedef enum +{ + CAN_TRANSMIT_FAILED = 0, /*!< CAN transmitted failure */ + CAN_TRANSMIT_OK = 1, /*!< CAN transmitted success */ + CAN_TRANSMIT_PENDING = 2, /*!< CAN transmitted pending */ + CAN_TRANSMIT_NOMAILBOX = 4, /*!< no empty mailbox to be used for CAN */ +}can_transmit_state_enum; + +/* CAN baudrate prescaler*/ +#define BT_BAUDPSC(regval) (BITS(0,9) & ((uint32_t)(regval) << 0)) + +/* CAN bit segment 1*/ +#define BT_BS1(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) + +/* CAN bit segment 2*/ +#define BT_BS2(regval) (BITS(20,22) & ((uint32_t)(regval) << 20)) + +/* CAN resynchronization jump width*/ +#define BT_SJW(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) + +/* CAN communication mode*/ +#define BT_MODE(regval) (BITS(30,31) & ((uint32_t)(regval) << 30)) + +/* CAN FDATA high 16 bits */ +#define FDATA_MASK_HIGH(regval) (BITS(16,31) & ((uint32_t)(regval) << 16)) + +/* CAN FDATA low 16 bits */ +#define FDATA_MASK_LOW(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) + +/* CAN1 filter start bank_number*/ +#define FCTL_HBC1F(regval) (BITS(8,13) & ((uint32_t)(regval) << 8)) + +/* CAN transmit mailbox extended identifier*/ +#define TMI_EFID(regval) (BITS(3,31) & ((uint32_t)(regval) << 3)) + +/* CAN transmit mailbox standard identifier*/ +#define TMI_SFID(regval) (BITS(21,31) & ((uint32_t)(regval) << 21)) + +/* transmit data byte 0 */ +#define TMDATA0_DB0(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* transmit data byte 1 */ +#define TMDATA0_DB1(regval) (BITS(8,15) & ((uint32_t)(regval) << 8)) + +/* transmit data byte 2 */ +#define TMDATA0_DB2(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) + +/* transmit data byte 3 */ +#define TMDATA0_DB3(regval) (BITS(24,31) & ((uint32_t)(regval) << 24)) + +/* transmit data byte 4 */ +#define TMDATA1_DB4(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* transmit data byte 5 */ +#define TMDATA1_DB5(regval) (BITS(8,15) & ((uint32_t)(regval) << 8)) + +/* transmit data byte 6 */ +#define TMDATA1_DB6(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) + +/* transmit data byte 7 */ +#define TMDATA1_DB7(regval) (BITS(24,31) & ((uint32_t)(regval) << 24)) + +/* receive mailbox extended identifier*/ +#define RFIFOMI_EFID(regval) GET_BITS((uint32_t)(regval), 3, 31) + +/* receive mailbox standrad identifier*/ +#define RFIFOMI_SFID(regval) GET_BITS((uint32_t)(regval), 21, 31) + +/* receive data length */ +#define RFIFOMP_DLENC(regval) GET_BITS((uint32_t)(regval), 0, 3) + +/* the index of the filter by which the frame is passed */ +#define RFIFOMP_FI(regval) GET_BITS((uint32_t)(regval), 8, 15) + +/* receive data byte 0 */ +#define RFIFOMDATA0_DB0(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* receive data byte 1 */ +#define RFIFOMDATA0_DB1(regval) GET_BITS((uint32_t)(regval), 8, 15) + +/* receive data byte 2 */ +#define RFIFOMDATA0_DB2(regval) GET_BITS((uint32_t)(regval), 16, 23) + +/* receive data byte 3 */ +#define RFIFOMDATA0_DB3(regval) GET_BITS((uint32_t)(regval), 24, 31) + +/* receive data byte 4 */ +#define RFIFOMDATA1_DB4(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* receive data byte 5 */ +#define RFIFOMDATA1_DB5(regval) GET_BITS((uint32_t)(regval), 8, 15) + +/* receive data byte 6 */ +#define RFIFOMDATA1_DB6(regval) GET_BITS((uint32_t)(regval), 16, 23) + +/* receive data byte 7 */ +#define RFIFOMDATA1_DB7(regval) GET_BITS((uint32_t)(regval), 24, 31) + +/* CAN errors */ +#define ERR_ERRN(regval) (BITS(4,6) & ((uint32_t)(regval) << 4)) +#define CAN_ERRN_0 ERR_ERRN(0) /* no error */ +#define CAN_ERRN_1 ERR_ERRN(1) /*!< fill error */ +#define CAN_ERRN_2 ERR_ERRN(2) /*!< format error */ +#define CAN_ERRN_3 ERR_ERRN(3) /*!< ACK error */ +#define CAN_ERRN_4 ERR_ERRN(4) /*!< bit recessive error */ +#define CAN_ERRN_5 ERR_ERRN(5) /*!< bit dominant error */ +#define CAN_ERRN_6 ERR_ERRN(6) /*!< CRC error */ +#define CAN_ERRN_7 ERR_ERRN(7) /*!< software error */ + +/* CAN phy mode bits */ +#define PHYCTL_POMOD(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) + +#define CAN_PHYCTL_POMODE_0 PHYCTL_POMOD(0) /*!< low slope mode */ +#define CAN_PHYCTL_POMODE_1 PHYCTL_POMOD(1) /*!< middle slope mode */ +#define CAN_PHYCTL_POMODE_2 PHYCTL_POMOD(2) /*!< high slope mode */ +#define CAN_PHYCTL_POMODE_3 PHYCTL_POMOD(3) /*!< high speed mode */ +#define CAN_PHYCTL_POMODE_MASK PHYCTL_POMOD(3) /*!< mask of phy mode */ + +#define CAN_STATE_PENDING ((uint32_t)0x00000000U) /*!< CAN pending */ + +/* CAN communication mode */ +#define CAN_NORMAL_MODE ((uint8_t)0x00U) /*!< normal communication mode */ +#define CAN_LOOPBACK_MODE ((uint8_t)0x01U) /*!< loopback communication mode */ +#define CAN_SILENT_MODE ((uint8_t)0x02U) /*!< silent communication mode */ +#define CAN_SILENT_LOOPBACK_MODE ((uint8_t)0x03U) /*!< loopback and silent communication mode */ + +/* CAN resynchronisation jump width */ +#define CAN_BT_SJW_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_SJW_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_SJW_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_SJW_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ + +/* CAN time segment 1 */ +#define CAN_BT_BS1_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_BS1_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_BS1_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_BS1_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ +#define CAN_BT_BS1_5TQ ((uint8_t)0x04U) /*!< 5 time quanta */ +#define CAN_BT_BS1_6TQ ((uint8_t)0x05U) /*!< 6 time quanta */ +#define CAN_BT_BS1_7TQ ((uint8_t)0x06U) /*!< 7 time quanta */ +#define CAN_BT_BS1_8TQ ((uint8_t)0x07U) /*!< 8 time quanta */ +#define CAN_BT_BS1_9TQ ((uint8_t)0x08U) /*!< 9 time quanta */ +#define CAN_BT_BS1_10TQ ((uint8_t)0x09U) /*!< 10 time quanta */ +#define CAN_BT_BS1_11TQ ((uint8_t)0x0AU) /*!< 11 time quanta */ +#define CAN_BT_BS1_12TQ ((uint8_t)0x0BU) /*!< 12 time quanta */ +#define CAN_BT_BS1_13TQ ((uint8_t)0x0CU) /*!< 13 time quanta */ +#define CAN_BT_BS1_14TQ ((uint8_t)0x0DU) /*!< 14 time quanta */ +#define CAN_BT_BS1_15TQ ((uint8_t)0x0EU) /*!< 15 time quanta */ +#define CAN_BT_BS1_16TQ ((uint8_t)0x0FU) /*!< 16 time quanta */ + +/* CAN time segment 2 */ +#define CAN_BT_BS2_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_BS2_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_BS2_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_BS2_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ +#define CAN_BT_BS2_5TQ ((uint8_t)0x04U) /*!< 5 time quanta */ +#define CAN_BT_BS2_6TQ ((uint8_t)0x05U) /*!< 6 time quanta */ +#define CAN_BT_BS2_7TQ ((uint8_t)0x06U) /*!< 7 time quanta */ +#define CAN_BT_BS2_8TQ ((uint8_t)0x07U) /*!< 8 time quanta */ + +/* CAN mailbox number */ +#define CAN_MAILBOX0 ((uint8_t)0x00U) /*!< mailbox0 */ +#define CAN_MAILBOX1 ((uint8_t)0x01U) /*!< mailbox1 */ +#define CAN_MAILBOX2 ((uint8_t)0x02U) /*!< mailbox2 */ +#define CAN_NOMAILBOX ((uint8_t)0x03U) /*!< no mailbox empty */ + +/* CAN frame format */ +#define CAN_FF_STANDARD ((uint32_t)0x00000000U) /*!< standard frame */ +#define CAN_FF_EXTENDED ((uint32_t)0x00000004U) /*!< extended frame */ + +/* CAN receive fifo */ +#define CAN_FIFO0 ((uint8_t)0x00U) /*!< receive FIFO0 */ +#define CAN_FIFO1 ((uint8_t)0x01U) /*!< receive FIFO1 */ + +/* frame number of receive fifo */ +#define CAN_RFIF_RFL_MASK ((uint32_t)0x00000003U) /*!< mask for frame number in receive FIFOx */ + +#define CAN_SFID_MASK ((uint32_t)0x000007FFU) /*!< mask of standard identifier */ +#define CAN_EFID_MASK ((uint32_t)0x1FFFFFFFU) /*!< mask of extended identifier */ + +/* CAN working mode */ +#define CAN_MODE_INITIALIZE ((uint8_t)0x01U) /*!< CAN initialize mode */ +#define CAN_MODE_NORMAL ((uint8_t)0x02U) /*!< CAN normal mode */ +#define CAN_MODE_SLEEP ((uint8_t)0x04U) /*!< CAN sleep mode */ + +/* filter bits */ +#define CAN_FILTERBITS_16BIT ((uint8_t)0x00U) /*!< CAN filter 16 bits */ +#define CAN_FILTERBITS_32BIT ((uint8_t)0x01U) /*!< CAN filter 32 bits */ + +/* filter mode */ +#define CAN_FILTERMODE_MASK ((uint8_t)0x00U) /*!< mask mode */ +#define CAN_FILTERMODE_LIST ((uint8_t)0x01U) /*!< list mode */ + +/* filter 16 bits mask */ +#define CAN_FILTER_MASK_16BITS ((uint32_t)0x0000FFFFU) + +/* frame type */ +#define CAN_FT_DATA ((uint32_t)0x00000000U) /*!< data frame */ +#define CAN_FT_REMOTE ((uint32_t)0x00000002U) /*!< remote frame */ + +/* CAN timeout */ +#define CAN_TIMEOUT ((uint32_t)0x0000FFFFU) /*!< timeout value */ + +/* interrupt enable bits */ +#define CAN_INT_TME CAN_INTEN_TMEIE /*!< transmit mailbox empty interrupt enable */ +#define CAN_INT_RFNE0 CAN_INTEN_RFNEIE0 /*!< receive FIFO0 not empty interrupt enable */ +#define CAN_INT_RFF0 CAN_INTEN_RFFIE0 /*!< receive FIFO0 full interrupt enable */ +#define CAN_INT_RFO0 CAN_INTEN_RFOIE0 /*!< receive FIFO0 overfull interrupt enable */ +#define CAN_INT_RFNE1 CAN_INTEN_RFNEIE1 /*!< receive FIFO1 not empty interrupt enable */ +#define CAN_INT_RFF1 CAN_INTEN_RFFIE1 /*!< receive FIFO1 full interrupt enable */ +#define CAN_INT_RFO1 CAN_INTEN_RFOIE1 /*!< receive FIFO1 overfull interrupt enable */ +#define CAN_INT_WERR CAN_INTEN_WERRIE /*!< warning error interrupt enable */ +#define CAN_INT_PERR CAN_INTEN_PERRIE /*!< passive error interrupt enable */ +#define CAN_INT_BO CAN_INTEN_BOIE /*!< bus-off interrupt enable */ +#define CAN_INT_ERRN CAN_INTEN_ERRNIE /*!< error number interrupt enable */ +#define CAN_INT_ERR CAN_INTEN_ERRIE /*!< error interrupt enable */ +#define CAN_INT_WAKEUP CAN_INTEN_WIE /*!< wakeup interrupt enable */ +#define CAN_INT_SLPW CAN_INTEN_SLPWIE /*!< sleep working interrupt enable */ + +/* function declarations */ +/* deinitialize CAN */ +void can_deinit(uint32_t can_periph); +/* initialize CAN */ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init); +/* CAN filter init */ +void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init); +/* set can1 fliter start bank number */ +void can1_filter_start_bank(uint8_t start_bank); +/* enable functions */ +/* CAN debug freeze enable */ +void can_debug_freeze_enable(uint32_t can_periph); +/* CAN debug freeze disable */ +void can_debug_freeze_disable(uint32_t can_periph); +/* CAN time triggle mode enable */ +void can_time_trigger_mode_enable(uint32_t can_periph); +/* CAN time triggle mode disable */ +void can_time_trigger_mode_disable(uint32_t can_periph); + +/* transmit functions */ +/* transmit CAN message */ +uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message); +/* get CAN transmit state */ +can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number); +/* stop CAN transmission */ +void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number); +/* CAN receive message */ +void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message); +/* CAN release fifo */ +void can_fifo_release(uint32_t can_periph, uint8_t fifo_number); +/* CAN receive message length */ +uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number); +/* CAN working mode */ +ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode); +/* CAN wakeup from sleep mode */ +ErrStatus can_wakeup(uint32_t can_periph); + +/* CAN get error */ +can_error_enum can_error_get(uint32_t can_periph); +/* get CAN receive error number */ +uint8_t can_receive_error_number_get(uint32_t can_periph); +/* get CAN transmit error number */ +uint8_t can_transmit_error_number_get(uint32_t can_periph); + +/* CAN interrupt enable */ +void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt); +/* CAN interrupt disable */ +void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt); +/* CAN get flag state */ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag); +/* CAN clear flag state */ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag); +/* CAN get interrupt flag state */ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag); +/* CAN clear interrupt flag state */ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag); + +/* enable CAN phy */ +void can_phy_enable(uint32_t can_periph); +/* disable CAN phy */ +void can_phy_disable(uint32_t can_periph); +/* set CAN PHY mode */ +void can_phy_mode(uint32_t can_periph, uint32_t phy_mode); + +#endif /* GD32F1X0_CAN_H */ + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_cec.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_cec.h new file mode 100644 index 0000000..859c4de --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_cec.h @@ -0,0 +1,226 @@ +/*! + \file gd32f1x0_cec.h + \brief definitions for the CEC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_CEC_H +#define GD32F1X0_CEC_H + +#include "gd32f1x0.h" + +/* CEC definitions */ +#define CEC CEC_BASE /*!< CEC base address */ + +/* registers definitions */ +#define CEC_CTL REG32(CEC + 0x00U) /*!< CEC control register */ +#define CEC_CFG REG32(CEC + 0x04U) /*!< CEC configuration register */ +#define CEC_TDATA REG32(CEC + 0x08U) /*!< CEC transmit data register */ +#define CEC_RDATA REG32(CEC + 0x0CU) /*!< CEC receive data register */ +#define CEC_INTF REG32(CEC + 0x10U) /*!< CEC interrupt flag Register */ +#define CEC_INTEN REG32(CEC + 0x14U) /*!< CEC interrupt enable register */ + +/* bits definitions */ +/* CEC_CTL */ +#define CEC_CTL_CECEN BIT(0) /*!< enable or disable HDMI-CEC controller bit */ +#define CEC_CTL_STAOM BIT(1) /*!< start of sending a message. */ +#define CEC_CTL_ENDOM BIT(2) /*!< ENDOM bit value in the next frame in Tx mode */ + +/* CEC_CFG */ +#define CEC_CFG_SFT BITS(0,2) /*!< signal free time */ +#define CEC_CFG_RTOL BIT(3) /*!< reception bit timing tolerance */ +#define CEC_CFG_BRES BIT(4) /*!< whether stop receive message when detected BRE */ +#define CEC_CFG_BREG BIT(5) /*!< generate Error-bit when detected BRE in singlecast */ +#define CEC_CFG_BPLEG BIT(6) /*!< generate Error-bit when detected BPLE in singlecast */ +#define CEC_CFG_BCNG BIT(7) /*!< do not generate Error-bit in broadcast message */ +#define CEC_CFG_SFTOPT BIT(8) /*!< the SFT start option bit */ +#define CEC_CFG_OAD BITS(16,30) /*!< own address */ +#define CEC_CFG_LMEN BIT(31) /*!< listen mode enable bit */ + +/* CEC_TDATA */ +#define CEC_TDATA_TDATA BITS(0,7) /*!< Tx data register */ + +/* CEC_RDATA */ +#define CEC_RDATA_RDATA BITS(0,7) /*!< Rx data register */ + +/* CEC_INTF */ +#define CEC_INTF_BR BIT(0) /*!< Rx-byte data received */ +#define CEC_INTF_REND BIT(1) /*!< end of reception */ +#define CEC_INTF_RO BIT(2) /*!< Rx overrun */ +#define CEC_INTF_BRE BIT(3) /*!< bit rising error */ +#define CEC_INTF_BPSE BIT(4) /*!< short bit period error */ +#define CEC_INTF_BPLE BIT(5) /*!< long bit period error */ +#define CEC_INTF_RAE BIT(6) /*!< Rx ACK error */ +#define CEC_INTF_ARBF BIT(7) /*!< arbitration fail */ +#define CEC_INTF_TBR BIT(8) /*!< Tx-byte data request */ +#define CEC_INTF_TEND BIT(9) /*!< transmission successfully end */ +#define CEC_INTF_TU BIT(10) /*!< Tx data buffer underrun */ +#define CEC_INTF_TERR BIT(11) /*!< Tx-error */ +#define CEC_INTF_TAERR BIT(12) /*!< Tx ACK error flag */ + +/* CEC_INTEN */ +#define CEC_INTEN_BRIE BIT(0) /*!< BR interrupt enable */ +#define CEC_INTEN_RENDIE BIT(1) /*!< REND interrupt enable */ +#define CEC_INTEN_ROIE BIT(2) /*!< RO interrupt enable */ +#define CEC_INTEN_BREIE BIT(3) /*!< BRE interrupt enable. */ +#define CEC_INTEN_BPSEIE BIT(4) /*!< BPSE interrupt enable */ +#define CEC_INTEN_BPLEIE BIT(5) /*!< BPLE interrupt enable. */ +#define CEC_INTEN_RAEIE BIT(6) /*!< RAE interrupt enable */ +#define CEC_INTEN_ARBFIE BIT(7) /*!< ARBF interrupt enable */ +#define CEC_INTEN_TBRIE BIT(8) /*!< TBR interrupt enable */ +#define CEC_INTEN_TENDIE BIT(9) /*!< TEND interrupt enable */ +#define CEC_INTEN_TUIE BIT(10) /*!< TU interrupt enable */ +#define CEC_INTEN_TERRIE BIT(11) /*!< TE interrupt enable */ +#define CEC_INTEN_TAERRIE BIT(12) /*!< TAE interrupt enable */ + +/* constants definitions */ +/* signal free time */ +#define CFG_SFT(regval) (BITS(0, 2) & ((regval) << 0U)) +#define CEC_SFT_PROTOCOL_PERIOD CFG_SFT(0) /*!< the signal free time will perform as HDMI-CEC protocol description */ +#define CEC_SFT_1POINT5_PERIOD CFG_SFT(1) /*!< 1.5 nominal data bit periods */ +#define CEC_SFT_2POINT5_PERIOD CFG_SFT(2) /*!< 2.5 nominal data bit periods */ +#define CEC_SFT_3POINT5_PERIOD CFG_SFT(3) /*!< 3.5 nominal data bit periods */ +#define CEC_SFT_4POINT5_PERIOD CFG_SFT(4) /*!< 4.5 nominal data bit periods */ +#define CEC_SFT_5POINT5_PERIOD CFG_SFT(5) /*!< 5.5 nominal data bit periods */ +#define CEC_SFT_6POINT5_PERIOD CFG_SFT(6) /*!< 6.5 nominal data bit periods */ +#define CEC_SFT_7POINT5_PERIOD CFG_SFT(7) /*!< 7.5 nominal data bit periods */ + +/* signal free time start option */ +#define CEC_SFT_START_STAOM ((uint32_t)0x00000000U) /*!< signal free time counter starts counting when STAOM is asserted */ +#define CEC_SFT_START_LAST CEC_CFG_SFTOPT /*!< signal free time counter starts automatically after transmission/reception end */ + +/* own address */ +#define CEC_OWN_ADDRESS_CLEAR ((uint32_t)0x00000000U) /*!< own address is cleared */ +#define CEC_OWN_ADDRESS0 BIT(16) /*!< own address is 0 */ +#define CEC_OWN_ADDRESS1 BIT(17) /*!< own address is 1 */ +#define CEC_OWN_ADDRESS2 BIT(18) /*!< own address is 2 */ +#define CEC_OWN_ADDRESS3 BIT(19) /*!< own address is 3 */ +#define CEC_OWN_ADDRESS4 BIT(20) /*!< own address is 4 */ +#define CEC_OWN_ADDRESS5 BIT(21) /*!< own address is 5 */ +#define CEC_OWN_ADDRESS6 BIT(22) /*!< own address is 6 */ +#define CEC_OWN_ADDRESS7 BIT(23) /*!< own address is 7 */ +#define CEC_OWN_ADDRESS8 BIT(24) /*!< own address is 8 */ +#define CEC_OWN_ADDRESS9 BIT(25) /*!< own address is 9 */ +#define CEC_OWN_ADDRESS10 BIT(26) /*!< own address is 10 */ +#define CEC_OWN_ADDRESS11 BIT(27) /*!< own address is 11 */ +#define CEC_OWN_ADDRESS12 BIT(28) /*!< own address is 12 */ +#define CEC_OWN_ADDRESS13 BIT(29) /*!< own address is 13 */ +#define CEC_OWN_ADDRESS14 BIT(30) /*!< own address is 14 */ + +/* error-bit generate */ +#define CEC_BROADCAST_ERROR_BIT_ON ((uint32_t)0x00000000U) /*!< generate Error-bit in broadcast */ +#define CEC_BROADCAST_ERROR_BIT_OFF CEC_CFG_BCNG /*!< do not generate Error-bit in broadcast */ +#define CEC_LONG_PERIOD_ERROR_BIT_OFF ((uint32_t)0x00000000U) /*!< generate Error-bit on long bit period error */ +#define CEC_LONG_PERIOD_ERROR_BIT_ON CEC_CFG_BPLEG /*!< do not generate Error-bit on long bit period error */ +#define CEC_RISING_PERIOD_ERROR_BIT_OFF ((uint32_t)0x00000000U) /*!< generate Error-bit on bit rising error */ +#define CEC_RISING_PERIOD_ERROR_BIT_ON CEC_CFG_BREG /*!< do not generate Error-bit on bit rising error */ + +/* whether stop receive message when detected bit rising error */ +#define CEC_STOP_RISING_ERROR_BIT_ON ((uint32_t)0x00000000U) /*!< stop reception when detected bit rising error */ +#define CEC_STOP_RISING_ERROR_BIT_OFF ((uint32_t)0x00000001U) /*!< do not stop reception when detected bit rising error */ + +/* flag bits */ +#define CEC_FLAG_BR CEC_INTF_BR /*!< RX-byte data received */ +#define CEC_FLAG_REND CEC_INTF_REND /*!< end of reception */ +#define CEC_FLAG_RO CEC_INTF_RO /*!< RX overrun */ +#define CEC_FLAG_BRE CEC_INTF_BRE /*!< bit rising error */ +#define CEC_FLAG_BPSE CEC_INTF_BPSE /*!< short bit period error */ +#define CEC_FLAG_BPLE CEC_INTF_BPLE /*!< long bit period error */ +#define CEC_FLAG_RAE CEC_INTF_RAE /*!< RX ACK error */ +#define CEC_FLAG_ARBF CEC_INTF_ARBF /*!< arbitration lost */ +#define CEC_FLAG_TBR CEC_INTF_TBR /*!< TX-byte data request */ +#define CEC_FLAG_TEND CEC_INTF_TEND /*!< transmission successfully end */ +#define CEC_FLAG_TU CEC_INTF_TU /*!< TX data buffer underrun */ +#define CEC_FLAG_TERR CEC_INTF_TERR /*!< TX-error */ +#define CEC_FLAG_TAERR CEC_INTF_TAERR /*!< TX ACK error flag */ + +/* interrupt flag bits */ +#define CEC_INT_FLAG_BR CEC_INTF_BR /*!< RX-byte data received */ +#define CEC_INT_FLAG_REND CEC_INTF_REND /*!< end of reception */ +#define CEC_INT_FLAG_RO CEC_INTF_RO /*!< RX overrun */ +#define CEC_INT_FLAG_BRE CEC_INTF_BRE /*!< bit rising error */ +#define CEC_INT_FLAG_BPSE CEC_INTF_BPSE /*!< short bit period error */ +#define CEC_INT_FLAG_BPLE CEC_INTF_BPLE /*!< long bit period error */ +#define CEC_INT_FLAG_RAE CEC_INTF_RAE /*!< RX ACK error */ +#define CEC_INT_FLAG_ARBF CEC_INTF_ARBF /*!< arbitration lost */ +#define CEC_INT_FLAG_TBR CEC_INTF_TBR /*!< TX-byte data request */ +#define CEC_INT_FLAG_TEND CEC_INTF_TEND /*!< transmission successfully end */ +#define CEC_INT_FLAG_TU CEC_INTF_TU /*!< TX data buffer underrun */ +#define CEC_INT_FLAG_TERR CEC_INTF_TERR /*!< TX-error */ +#define CEC_INT_FLAG_TAERR CEC_INTF_TAERR /*!< TX ACK error flag */ + +/* interrupt enable bits */ +#define CEC_INT_BR CEC_INTEN_BRIE /*!< BR interrupt enable */ +#define CEC_INT_REND CEC_INTEN_RENDIE /*!< REND interrupt enable */ +#define CEC_INT_RO CEC_INTEN_ROIE /*!< RO interrupt enable */ +#define CEC_INT_BRE CEC_INTEN_BREIE /*!< BRE interrupt enable. */ +#define CEC_INT_BPSE CEC_INTEN_BPSEIE /*!< BPSE interrupt enable */ +#define CEC_INT_BPLE CEC_INTEN_BPLEIE /*!< BPLE interrupt enable. */ +#define CEC_INT_RAE CEC_INTEN_RAEIE /*!< RAE interrupt enable */ +#define CEC_INT_ARBF CEC_INTEN_ARBFIE /*!< ALRLST interrupt enable */ +#define CEC_INT_TBR CEC_INTEN_TBRIE /*!< TBR interrupt enable */ +#define CEC_INT_TEND CEC_INTEN_TENDIE /*!< TEND interrupt enable */ +#define CEC_INT_TU CEC_INTEN_TUIE /*!< TU interrupt enable */ +#define CEC_INT_TERR CEC_INTEN_TERRIE /*!< TE interrupt enable */ +#define CEC_INT_TAERR CEC_INTEN_TAERRIE /*!< TAE interrupt enable */ + +/* function declarations */ +/* reset HDMI-CEC controller */ +void cec_deinit(void); +/* configure signal free time,the signal free time counter start option,own address */ +void cec_init(uint32_t sftmopt, uint32_t sft, uint32_t address); +/* configure generate Error-bit, whether stop receive message when detected bit rising error */ +void cec_error_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre, uint32_t rxbrestp); +/* enable HDMI-CEC controller */ +void cec_enable(void); +/* disable HDMI-CEC controller */ +void cec_disable(void); + +/* start CEC message transmission */ +void cec_transmission_start(void); +/* end CEC message transmission */ +void cec_transmission_end(void); +/* enable CEC listen mode */ +void cec_listen_mode_enable(void); +/* disable CEC listen mode */ +void cec_listen_mode_disable(void); +/* configure and clear own address */ +void cec_own_address_config(uint32_t address); +/* configure signal free time and the signal free time counter start option */ +void cec_sft_config(uint32_t sftmopt,uint32_t sft); +/* configure generate Error-bit when detected some abnormal situation or not */ +void cec_generate_errorbit_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre); +/* whether stop receive message when detected bit rising error */ +void cec_stop_receive_bre_config(uint32_t rxbrestp); +/* enable reception bit timing tolerance */ +void cec_reception_tolerance_enable(void); +/* disable reception bit timing tolerance */ +void cec_reception_tolerance_disable(void); +/* send a data by the CEC peripheral */ +void cec_data_send(uint8_t data); +/* receive a data by the CEC peripheral */ +uint8_t cec_data_receive(void); + +/* clear CEC int flag and status */ +FlagStatus cec_interrupt_flag_get(uint32_t flag); +/* clear CEC flag */ +void cec_interrupt_flag_clear(uint32_t flag); +/* enable interrupt */ +void cec_interrupt_enable(uint32_t flag); +/* disable interrupt */ +void cec_interrupt_disable(uint32_t flag); +/* get CEC status */ +FlagStatus cec_flag_get(uint32_t flag); +/* clear CEC status */ +void cec_flag_clear(uint32_t flag); + +#endif /* GD32F1X0_CEC_H */ + diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_cmp.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_cmp.h new file mode 100644 index 0000000..6d88bee --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_cmp.h @@ -0,0 +1,212 @@ +/*! + \file gd32f1x0_cmp.h + \brief definitions for the CMP +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5,9) +*/ + +#ifndef GD32F1X0_CMP_H +#define GD32F1X0_CMP_H + +#include "gd32f1x0.h" + +/* CMP definitions */ +#define CMP CMP_BASE /*!< CMP base address */ + +/* registers definitions */ +#define CMP_CS REG32((CMP) + 0x00U) /*!< CMP control and status register */ + +/* CMP_CS bits definitions */ +#define CMP_CS_CMP0EN BIT(0) /*!< CMP0 enable */ +#define CMP_CS_CMP0SW BIT(1) /*!< CMP0 switch */ +#define CMP_CS_CMP0M BITS(2,3) /*!< CMP0 mode */ +#define CMP_CS_CMP0MSEL BITS(4,6) /*!< COMP0_M input selection */ +#define CMP_CS_CMP0OSEL BITS(8,10) /*!< CMP0 output selection */ +#define CMP_CS_CMP0PL BIT(11) /*!< polarity of CMP0 output */ +#define CMP_CS_CMP0HST BITS(12,13) /*!< CMP0 hysteresis */ +#define CMP_CS_CMP0O BIT(14) /*!< CMP0 output */ +#define CMP_CS_CMP0LK BIT(15) /*!< CMP0 lock */ +#define CMP_CS_CMP1EN BIT(16) /*!< CMP1 enable */ +#define CMP_CS_CMP1M BITS(18,19) /*!< CMP1 mode */ +#define CMP_CS_CMP1MSEL BITS(20,22) /*!< CMP1_M input selection */ +#define CMP_CS_WNDEN BIT(23) /*!< window mode enable */ +#define CMP_CS_CMP1OSEL BITS(24,26) /*!< CMP1 output selection */ +#define CMP_CS_CMP1PL BIT(27) /*!< polarity of CMP1 output */ +#define CMP_CS_CMP1HST BITS(28,29) /*!< CMP1 hysteresis */ +#define CMP_CS_CMP1O BIT(30) /*!< CMP1 output */ +#define CMP_CS_CMP1LK BIT(31) /*!< CMP1 lock */ + +/* consts definitions */ +/* operating mode */ +typedef enum{ + CMP_HIGHSPEED = 0, /*!< high speed mode */ + CMP_MIDDLESPEED, /*!< medium speed mode */ + CMP_LOWSPEED, /*!< low speed mode */ + CMP_VERYLOWSPEED /*!< very-low speed mode */ +}operating_mode_enum; + +/* inverting input */ +typedef enum{ + CMP_1_4VREFINT = 0, /*!< VREFINT /4 input */ + CMP_1_2VREFINT, /*!< VREFINT /2 input */ + CMP_3_4VREFINT, /*!< VREFINT *3/4 input */ + CMP_VREFINT, /*!< VREFINT input */ + CMP_DAC0, /*!< PA4 (DAC0) input */ +#ifdef GD32F170_190 + CMP_DAC1, /*!< DAC1 input */ +#else + CMP_PA5, /*!< PA5 input */ +#endif + CMP_PA_0_2 /*!< PA0 input when CMP0 is selected, PA2 input when CMP1 is selected */ +}inverting_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_TIMER0BKIN, /*!< TIMER 0 break input */ + CMP_OUTPUT_TIMER0IC0, /*!< TIMER 0 channel0 input capture */ + CMP_OUTPUT_TIMER0OCPRECLR, /*!< TIMER 0 OCPRE_CLR input */ + CMP_OUTPUT_TIMER1IC3, /*!< TIMER 1 channel3 input capture */ + CMP_OUTPUT_TIMER1OCPRECLR, /*!< TIMER 1 OCPRE_CLR input */ + CMP_OUTPUT_TIMER2IC0, /*!< TIMER 2 channel0 input capture */ + CMP_OUTPUT_TIMER2OCPRECLR /*!< TIMER 2 OCPRE_CLR input */ +}cmp_output_enum; + +/* CMP0 mode */ +#define CS_CMP0M(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define CS_CMP0M_HIGHSPEED CS_CMP0M(0) /*!< CMP0 mode high speed */ +#define CS_CMP0M_MIDDLESPEED CS_CMP0M(1) /*!< CMP0 mode middle speed */ +#define CS_CMP0M_LOWSPEED CS_CMP0M(2) /*!< CMP0 mode low speed */ +#define CS_CMP0M_VERYLOWSPEED CS_CMP0M(3) /*!< CMP0 mode very low speed */ + +/* comparator 0 inverting input */ +#define CS_CMP0MSEL(regval) (BITS(4,6) & ((uint32_t)(regval) << 4)) + +#define CS_CMP0MSEL_1_4VREFINT CS_CMP0MSEL(0) /*!< CMP0 inverting input 1/4 Vrefint */ +#define CS_CMP0MSEL_1_2VREFINT CS_CMP0MSEL(1) /*!< CMP0 inverting input 1/2 Vrefint */ +#define CS_CMP0MSEL_3_4VREFINT CS_CMP0MSEL(2) /*!< CMP0 inverting input 3/4 Vrefint */ +#define CS_CMP0MSEL_VREFINT CS_CMP0MSEL(3) /*!< CMP0 inverting input Vrefint */ +#define CS_CMP0MSEL_DAC0 CS_CMP0MSEL(4) /*!< CMP0 inverting input DAC0*/ +#define CS_CMP0MSEL_PA5 CS_CMP0MSEL(5) /*!< CMP0 inverting input PA5*/ +#define CS_CMP0MSEL_PA0 CS_CMP0MSEL(6) /*!< CMP0 inverting input PA0*/ + +/* CMP0 output */ +#define CS_CMP0OSEL(regval) (BITS(8,10) & ((uint32_t)(regval) << 8)) + +#define CS_CMP0OSEL_OUTPUT_NONE CS_CMP0OSEL(0) /*!< CMP0 output none */ +#define CS_CMP0OSEL_OUTPUT_TIMER0BKIN CS_CMP0OSEL(1) /*!< CMP0 output TIMER 0 break input */ +#define CS_CMP0OSEL_OUTPUT_TIMER0IC0 CS_CMP0OSEL(2) /*!< CMP0 output TIMER 0 channel 0 input capture */ +#define CS_CMP0OSEL_OUTPUT_TIMER0OCPRECLR CS_CMP0OSEL(3) /*!< CMP0 output TIMER 0 ocpreclear input */ +#define CS_CMP0OSEL_OUTPUT_TIMER1IC3 CS_CMP0OSEL(4) /*!< CMP0 output TIMER 1 channel 3 input capture */ +#define CS_CMP0OSEL_OUTPUT_TIMER1OCPRECLR CS_CMP0OSEL(5) /*!< CMP0 output TIMER 1 ocpreclear input */ +#define CS_CMP0OSEL_OUTPUT_TIMER2IC0 CS_CMP0OSEL(6) /*!< CMP0 output TIMER 2 channle 0 input capture */ +#define CS_CMP0OSEL_OUTPUT_TIMER2OCPRECLR CS_CMP0OSEL(7) /*!< CMP0 output TIMER 2 ocpreclear input */ + +/* CMP0 hysteresis */ +#define CS_CMP0HST(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define CS_CMP0HST_HYSTERESIS_NO CS_CMP0HST(0) /*!< CMP0 output no hysteresis */ +#define CS_CMP0HST_HYSTERESIS_LOW CS_CMP0HST(1) /*!< CMP0 output low hysteresis */ +#define CS_CMP0HST_HYSTERESIS_MIDDLE CS_CMP0HST(2) /*!< CMP0 output middle hysteresis */ +#define CS_CMP0HST_HYSTERESIS_HIGH CS_CMP0HST(3) /*!< CMP0 output high hysteresis */ + +/* CMP1 mode */ +#define CS_CMP1M(regval) (BITS(18,19) & ((uint32_t)(regval) << 18)) +#define CS_CMP1M_HIGHSPEED CS_CMP1M(0) /*!< CMP1 mode high speed */ +#define CS_CMP1M_MIDDLESPEED CS_CMP1M(1) /*!< CMP1 mode middle speed */ +#define CS_CMP1M_LOWSPEED CS_CMP1M(2) /*!< CMP1 mode low speed */ +#define CS_CMP1M_VERYLOWSPEED CS_CMP1M(3) /*!< CMP1 mode very low speed */ + +/* CMP1 inverting input */ +#define CS_CMP1MSEL(regval) (BITS(20,22) & ((uint32_t)(regval) << 20)) + +#define CS_CMP1MSEL_1_4VREFINT CS_CMP1MSEL(0) /*!< CMP1 inverting input 1/4 Vrefint */ +#define CS_CMP1MSEL_1_2VREFINT CS_CMP1MSEL(1) /*!< CMP1 inverting input 1/2 Vrefint */ +#define CS_CMP1MSEL_3_4VREFINT CS_CMP1MSEL(2) /*!< CMP1 inverting input 3/4 Vrefint */ +#define CS_CMP1MSEL_VREFINT CS_CMP1MSEL(3) /*!< CMP1 inverting input Vrefint */ +#define CS_CMP1MSEL_DAC0 CS_CMP1MSEL(4) /*!< CMP1 inverting input DAC0*/ +#ifdef GD32F170_190 +#define CS_CMP1MSEL_PA5 CS_CMP1MSEL(5) /*!< CMP1 inverting input PA5*/ +#else +#define CS_CMP1MSEL_DAC1 CS_CMP1MSEL(5) /*!< CMP1 inverting input DAC1*/ +#endif +#define CS_CMP1MSEL_PA2 CS_CMP1MSEL(6) /*!< CMP1 inverting input PA2*/ + +/* comparator channel1 output */ +#define CS_CMP1OSEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) + +#define CS_CMP1OSEL_OUTPUT_NONE CS_CMP1OSEL(0) /*!< CMP1 output none */ +#define CS_CMP1OSEL_OUTPUT_TIMER0BKIN CS_CMP1OSEL(1) /*!< CMP1 output TIMER 0 break input */ +#define CS_CMP1OSEL_OUTPUT_TIMER0IC0 CS_CMP1OSEL(2) /*!< CMP1 output TIMER 0 channel 0 input capture */ +#define CS_CMP1OSEL_OUTPUT_TIMER0OCPRECLR CS_CMP1OSEL(3) /*!< CMP1 output TIMER 0 ocpreclear input */ +#define CS_CMP1OSEL_OUTPUT_TIMER1IC3 CS_CMP1OSEL(4) /*!< CMP1 output TIMER 1 channel 3 input capture */ +#define CS_CMP1OSEL_OUTPUT_TIMER1OCPRECLR CS_CMP1OSEL(5) /*!< CMP1 output TIMER 1 ocpreclear input */ +#define CS_CMP1OSEL_OUTPUT_TIMER2IC0 CS_CMP1OSEL(6) /*!< CMP1 output TIMER 2 channle 0 input capture */ +#define CS_CMP1OSEL_OUTPUT_TIMER2OCPRECLR CS_CMP1OSEL(7) /*!< CMP1 output TIMER 2 ocpreclear input */ + +/* CMP1 hysteresis */ +#define CS_CMP1HST(regval) (BITS(28,29) & ((uint32_t)(regval) << 28)) +#define CS_CMP1HST_HSTHYSTERESIS_NO CS_CMP1HST(0) /*!< CMP1 output no hysteresis */ +#define CS_CMP1HST_HYSTERESIS_LOW CS_CMP1HST(1) /*!< CMP1 output low hysteresis */ +#define CS_CMP1HST_HYSTERESIS_MIDDLE CS_CMP1HST(2) /*!< CMP1 output middle hysteresis */ +#define CS_CMP1HST_HYSTERESIS_HIGH CS_CMP1HST(3) /*!< CMP1 output high hysteresis */ + +/* comparator x definitions */ +#define CMP0 ((uint32_t)0x00000000) /*!< comparator 0 */ +#define CMP1 ((uint32_t)0x00000010) /*!< comparator 1 */ + +/* comparator output level */ +#define CMP_OUTPUTLEVEL_HIGH ((uint32_t)0x00000001) /*!< comparator output high */ +#define CMP_OUTPUTLEVEL_LOW ((uint32_t)0x00000000) /*!< comparator output low */ + +/* output polarity of comparator */ +#define CMP_OUTPUT_POLARITY_INVERTED ((uint32_t)0x00000001) /*!< output is inverted */ +#define CMP_OUTPUT_POLARITY_NOINVERTED ((uint32_t)0x00000000) /*!< output is not inverted */ + +/* function declarations */ + +/* initialization functions */ +/* CMP deinit */ +void cmp_deinit(void); +/* CMP mode init */ +void cmp_mode_init(uint32_t cmp_periph, operating_mode_enum cmp_operating_mode, inverting_input_enum cmp_inverting_input, cmp_hysteresis_enum output_hysteresis); +/* CMP output init */ +void cmp_output_init(uint32_t cmp_periph, cmp_output_enum cmp_output_slection, uint32_t cmp_output_polarity); + +/* enable functions */ +/* enable CMP */ +void cmp_enable(uint32_t cmp_periph); +/* disable CMP */ +void cmp_disable(uint32_t cmp_periph); +/* enable CMP switch */ +void cmp_switch_enable(void); +/* disable CMP switch */ +void cmp_switch_disable(void); +/* enable the window mode */ +void cmp_window_enable(void); +/* disable the window mode */ +void cmp_window_disable(void); +/* lock the CMP */ +void cmp_lock_enable(uint32_t cmp_periph); +/* unlock the CMP */ +void cmp_lock_disable(uint32_t cmp_periph); + +/* output functions */ +/* get output level */ +uint32_t cmp_output_level_get(uint32_t cmp_periph); + +#endif /* GD32F1X0_CMP_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_crc.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_crc.h new file mode 100644 index 0000000..425c17f --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_crc.h @@ -0,0 +1,84 @@ +/*! + \file gd32f1x0_crc.h + \brief definitions for the CRC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_CRC_H +#define GD32F1X0_CRC_H + +#include "gd32f1x0.h" + +/* CRC definitions */ +#define CRC CRC_BASE + +/* registers definitions */ +#define CRC_DATA REG32(CRC + 0x00U) /*!< CRC data register */ +#define CRC_FDATA REG32(CRC + 0x04U) /*!< CRC free data register */ +#define CRC_CTL REG32(CRC + 0x08U) /*!< CRC control register */ +#define CRC_IDATA REG32(CRC + 0x10U) /*!< CRC initialization data register */ + +/* bits definitions */ + +/* CRC_DATA */ +#define CRC_DATA_DATA BITS(0,31) /*!< CRC calculation result bits */ + +/* CRC_FDATA */ +#define CRC_FDATA_FDATA BITS(0,7) /*!< CRC free data bits */ + +/* CRC_CTL */ +#define CRC_CTL_RST BIT(0) /*!< CRC reset bit */ +#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_IDATA */ +#define CRC_IDATA_IDATA BITS(0,31) /*!< CRC initialization data bits */ + +/* constants definitions */ + +/* 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 */ + +/* 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 initializaiton 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 initializaiton data 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); + +/* CRC calculate a 32-bit data */ +uint32_t crc_single_data_calculate(uint32_t sdata); +/* CRC calculate a 32-bit data array */ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size); + +#endif /* GD32F1X0_CRC_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_dac.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_dac.h new file mode 100644 index 0000000..d8cd18c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_dac.h @@ -0,0 +1,243 @@ +/*! + \file gd32f1x0_dac.h + \brief definitions for the DAC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + +#ifndef GD32F1X0_DAC_H +#define GD32F1X0_DAC_H + +#include "gd32f1x0.h" + +/* DACx(x=0,1) definitions */ +#define DAC DAC_BASE +#define DAC0 0U +#ifdef GD32F170_190 +#define DAC1 1U +#endif /* GD32F170_190 */ + +/* registers definitions */ +#define DAC_CTL REG32(DAC + 0x00U) /*!< DAC control register */ +#define DAC_SWT REG32(DAC + 0x04U) /*!< DAC software trigger register */ +#define DAC0_R12DH REG32(DAC + 0x08U) /*!< DAC0 12-bit right-aligned data holding register */ +#define DAC0_L12DH REG32(DAC + 0x0CU) /*!< DAC0 12-bit left-aligned data holding register */ +#define DAC0_R8DH REG32(DAC + 0x10U) /*!< DAC0 8-bit right-aligned data holding register */ +#ifdef GD32F170_190 +#define DAC1_R12DH REG32(DAC + 0x14U) /*!< DAC1 12-bit right-aligned data holding register */ +#define DAC1_L12DH REG32(DAC + 0x18U) /*!< DAC1 12-bit left-aligned data holding register */ +#define DAC1_R8DH REG32(DAC + 0x1CU) /*!< DAC1 8-bit right-aligned data holding register */ +#define DACC_R12DH REG32(DAC + 0x20U) /*!< DAC concurrent mode 12-bit right-aligned data holding register */ +#define DACC_L12DH REG32(DAC + 0x24U) /*!< DAC concurrent mode 12-bit left-aligned data holding register */ +#define DACC_R8DH REG32(DAC + 0x28U) /*!< DAC concurrent mode 8-bit right-aligned data holding register */ +#endif /* GD32F170_190 */ +#define DAC0_DO REG32(DAC + 0x2CU) /*!< DAC0 output data register */ +#ifdef GD32F170_190 +#define DAC1_DO REG32(DAC + 0x30U) /*!< DAC1 output data register */ +#endif /* GD32F170_190 */ +#define DAC_STAT REG32(DAC + 0x34U) /*!< DAC status register */ + +/* bits definitions */ +/* DAC_CTL */ +#define DAC_CTL_DEN0 BIT(0) /*!< DAC0 enable/disable bit */ +#define DAC_CTL_DBOFF0 BIT(1) /*!< DAC0 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN0 BIT(2) /*!< DAC0 trigger enable/disable bit */ +#define DAC_CTL_DTSEL0 BITS(3,5) /*!< DAC0 trigger source selection enable/disable bits */ +#define DAC_CTL_DDMAEN0 BIT(12) /*!< DAC0 DMA enable/disanle bit */ +#define DAC_CTL_DDUDRIE0 BIT(13) /*!< DAC0 DMA underrun Interrupt enable/disable bit */ +#ifdef GD32F170_190 +#define DAC_CTL_DEN1 BIT(16) /*!< DAC1 enable/disable bit */ +#define DAC_CTL_DBOFF1 BIT(17) /*!< DAC1 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN1 BIT(18) /*!< DAC1 trigger enable/disable bit */ +#define DAC_CTL_DTSEL1 BITS(19,21) /*!< DAC1 trigger source selection enable/disable bits */ +#define DAC_CTL_DDMAEN1 BIT(28) /*!< DAC1 DMA enable/disable bit */ +#define DAC_CTL_DDUDRIE1 BIT(29) /*!< DAC1 DMA underrun interrupt enable/disable bit */ +#endif /* GD32F170_190 */ + +/* DAC_SWT */ +#define DAC_SWT_SWTR0 BIT(0) /*!< DAC0 software trigger bit,cleared by hardware */ +#ifdef GD32F170_190 +#define DAC_SWT_SWTR1 BIT(1) /*!< DAC1 software trigger bit,cleared by hardware */ +#endif /* GD32F170_190 */ + +/* DAC0_R12DH */ +#define DAC0_R12DH_DAC0_DH BITS(0,11) /*!< DAC0 12-bit right-aligned data bits */ + +/* DAC0_L12DH */ +#define DAC0_L12DH_DAC0_DH BITS(4,15) /*!< DAC0 12-bit left-aligned data bits */ + +/* DAC0_R8DH */ +#define DAC0_R8DH_DAC0_DH BITS(0,7) /*!< DAC0 8-bit right-aligned data bits */ + +#ifdef GD32F170_190 +/* DAC1_R12DH */ +#define DAC1_R12DH_DAC1_DH BITS(0,11) /*!< DAC1 12-bit right-aligned data bits */ + +/* DAC1_L12DH */ +#define DAC1_L12DH_DAC1_DH BITS(4,15) /*!< DAC1 12-bit left-aligned data bits */ + +/* DAC1_R8DH */ +#define DAC1_R8DH_DAC1_DH BITS(0,7) /*!< DAC1 8-bit right-aligned data bits */ + +/* DACC_R12DH */ +#define DACC_R12DH_DAC0_DH BITS(0,11) /*!< DAC concurrent mode DAC0 12-bit right-aligned data bits */ +#define DACC_R12DH_DAC1_DH BITS(16,27) /*!< DAC concurrent mode DAC1 12-bit right-aligned data bits */ + +/* DACC_L12DH */ +#define DACC_L12DH_DAC0_DH BITS(4,15) /*!< DAC concurrent mode DAC0 12-bit left-aligned data bits */ +#define DACC_L12DH_DAC1_DH BITS(20,31) /*!< DAC concurrent mode DAC1 12-bit left-aligned data bits */ + +/* DACC_R8DH */ +#define DACC_R8DH_DAC0_DH BITS(0,7) /*!< DAC concurrent mode DAC0 8-bit right-aligned data bits */ +#define DACC_R8DH_DAC1_DH BITS(8,15) /*!< DAC concurrent mode DAC1 8-bit right-aligned data bits */ +#endif /* GD32F170_190 */ + +/* DAC0_DO */ +#define DAC0_DO_DAC0_DO BITS(0,11) /*!< DAC0 12-bit output data bits */ + +#ifdef GD32F170_190 +/* DAC1_DO */ +#define DAC1_DO_DAC1_DO BITS(0,11) /*!< DAC1 12-bit output data bits */ +#endif /* GD32F170_190 */ + +/* DAC_STAT */ +#define DAC_STAT_DDUDR0 BIT(13) /*!< DAC0 DMA underrun flag */ +#ifdef GD32F170_190 +#define DAC_STAT_DDUDR1 BIT(29) /*!< DAC1 DMA underrun flag */ +#endif /* GD32F170_190 */ + +/* constants definitions */ +/* DAC trigger source */ +#define CTL_DTSEL(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) +#define DAC_TRIGGER_T5_TRGO CTL_DTSEL(0) /*!< TIMER5 TRGO */ +#define DAC_TRIGGER_T2_TRGO CTL_DTSEL(1) /*!< TIMER2 TRGO */ +#define DAC_TRIGGER_T14_TRGO CTL_DTSEL(3) /*!< TIMER14 TRGO */ +#define DAC_TRIGGER_T1_TRGO CTL_DTSEL(4) /*!< TIMER1 TRGO */ +#define DAC_TRIGGER_EXTI_9 CTL_DTSEL(6) /*!< EXTI interrupt line9 event */ +#define DAC_TRIGGER_SOFTWARE CTL_DTSEL(7) /*!< software trigger */ + +/* dac data alignment */ +#define DATA_ALIGN(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define DAC_ALIGN_12B_R DATA_ALIGN(0) /*!< data right 12b alignment */ +#define DAC_ALIGN_12B_L DATA_ALIGN(1) /*!< data left 12b alignment */ +#define DAC_ALIGN_8B_R DATA_ALIGN(2) /*!< data right 8b alignment */ + +/* function declarations */ +/* deinit DAC */ +void dac_deinit(void); + +/* enable DAC0 function */ +void dac0_enable(void); +/* disable DAC0 function */ +void dac0_disable(void); +/* enable DAC0 DMA function */ +void dac0_dma_enable(void); +/* disable DAC0 DMA function */ +void dac0_dma_disable(void); +/* enable DAC0 output buffer function */ +void dac0_output_buffer_enable(void); +/* disable DAC0 output buffer function */ +void dac0_output_buffer_disable(void); +/* enable DAC0 trigger function */ +void dac0_trigger_enable(void); +/* disable DAC0 trigger function */ +void dac0_trigger_disable(void); +/* enable DAC0 software trigger function */ +void dac0_software_trigger_enable(void); +/* disable DAC0 software trigger function */ +void dac0_software_trigger_disable(void); +/* enable DAC0 interrupt(DAC0 DMA underrun interrupt) */ +void dac0_interrupt_enable(void); +/* disable DAC0 interrupt(DAC0 DMA underrun interrupt) */ +void dac0_interrupt_disable(void); + +/* set DAC0 tgigger source function */ +void dac0_trigger_source_config(uint32_t triggersource); +/* get the last data output value */ +uint16_t dac0_output_value_get(void); + +/* get the specified DAC0 flag(DAC0 DMA underrun flag) */ +FlagStatus dac0_flag_get(void); +/* clear the specified DAC0 flag(DAC0 DMA underrun flag) */ +void dac0_flag_clear(void); +/* get the specified DAC0 interrupt flag(DAC0 DMA underrun interrupt flag) */ +FlagStatus dac0_interrupt_flag_get(void); +/* clear the specified DAC0 interrupt flag(DAC0 DMA underrun interrupt flag) */ +void dac0_interrupt_flag_clear(void); + +/* set DAC0 data holding register value */ +void dac0_data_set(uint32_t dac_align, uint16_t data); + +#ifdef GD32F170_190 +/* enable DAC */ +void dac_enable(uint32_t dac_periph); +/* disable DAC */ +void dac_disable(uint32_t dac_periph); +/* enable DAC DMA */ +void dac_dma_enable(uint32_t dac_periph); +/* disable DAC DMA */ +void dac_dma_disable(uint32_t dac_periph); +/* enable DAC output buffer */ +void dac_output_buffer_enable(uint32_t dac_periph); +/* disable DAC output buffer */ +void dac_output_buffer_disable(uint32_t dac_periph); +/* enable DAC trigger */ +void dac_trigger_enable(uint32_t dac_periph); +/* disable DAC trigger */ +void dac_trigger_disable(uint32_t dac_periph); +/* enable DAC software trigger */ +void dac_software_trigger_enable(uint32_t dac_periph); +/* disable DAC software trigger */ +void dac_software_trigger_disable(uint32_t dac_periph); +/* enable DAC interrupt(DAC0 DMA underrun interrupt) */ +void dac_interrupt_enable(uint32_t dac_periph); +/* disable DAC interrupt(DAC0 DMA underrun interrupt) */ +void dac_interrupt_disable(uint32_t dac_periph); + +/* set DAC tgigger source */ +void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource); +/* get the last data output value */ +uint16_t dac_output_value_get(uint32_t dac_periph); + +/* get the specified DAC flag(DAC DMA underrun flag) */ +FlagStatus dac_flag_get(uint32_t dac_periph); +/* clear the specified DAC flag(DAC DMA underrun flag) */ +void dac_flag_clear(uint32_t dac_periph); +/* get the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */ +FlagStatus dac_interrupt_flag_get(uint32_t dac_periph); +/* clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */ +void dac_interrupt_flag_clear(uint32_t dac_periph); + +/* enable DAC concurrent mode */ +void dac_concurrent_enable(void); +/* disable DAC concurrent mode */ +void dac_concurrent_disable(void); +/* enable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_enable(void); +/* disable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_disable(void); +/* enable DAC concurrent buffer */ +void dac_concurrent_output_buffer_enable(void); +/* disable DAC concurrent buffer */ +void dac_concurrent_output_buffer_disable(void); +/* enable DAC concurrent interrupt */ +void dac_concurrent_interrupt_enable(void); +/* disable DAC concurrent interrupt */ +void dac_concurrent_interrupt_disable(void); + +/* set DAC data holding register value */ +void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data); +/* set DAC concurrent mode data holding register value */ +void dac_concurrent_data_set(uint32_t dac_align, uint16_t data1, uint16_t data2); + +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_DAC_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_dbg.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_dbg.h new file mode 100644 index 0000000..48cf175 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_dbg.h @@ -0,0 +1,116 @@ +/*! + \file gd32f1x0_dbg.h + \brief definitions for the DBG +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_DBG_H +#define GD32F1X0_DBG_H + +#include "gd32f1x0.h" + +/* DBG definitions */ +#define DBG DBG_BASE + +/* registers definitions */ +#define DBG_ID REG32(DBG + 0x00U) /*!< DBG_ID code register */ +#define DBG_CTL0 REG32(DBG + 0x04U) /*!< DBG control register 0 */ +#define DBG_CTL1 REG32(DBG + 0x08U) /*!< DBG control register 1 */ + +/* bits definitions */ +/* DBG_ID */ +#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG ID code values */ + +/* DBG_CTL0 */ +#define DBG_CTL0_SLP_HOLD BIT(0) /*!< keep debugger connection during sleep mode */ +#define DBG_CTL0_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */ +#define DBG_CTL0_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */ +#define DBG_CTL0_FWDGT_HOLD BIT(8) /*!< debug FWDGT kept when core is halted */ +#define DBG_CTL0_WWDGT_HOLD BIT(9) /*!< debug WWDGT kept when core is halted */ +#define DBG_CTL0_TIMER0_HOLD BIT(10) /*!< TIMER0 counter kept when core is halted */ +#define DBG_CTL0_TIMER1_HOLD BIT(11) /*!< TIMER1 counter kept when core is halted */ +#define DBG_CTL0_TIMER2_HOLD BIT(12) /*!< TIMER2 counter kept when core is halted */ +#define DBG_CTL0_I2C0_HOLD BIT(15) /*!< hold I2C0 smbus when core is halted */ +#define DBG_CTL0_I2C1_HOLD BIT(16) /*!< hold I2C1 smbus when core is halted */ +#define DBG_CTL0_I2C2_HOLD BIT(17) /*!< hold I2C2 smbus when core is halted */ +#ifdef GD32F170_190 +#define DBG_CTL0_CAN0_HOLD BIT(18) /*!< CAN0 counter kept when core is halted */ +#endif /* GD32F170_190 */ +#define DBG_CTL0_TIMER5_HOLD BIT(19) /*!< hold TIMER5 counter when core is halted */ +#ifdef GD32F170_190 +#define DBG_CTL0_CAN1_HOLD BIT(21) /*!< hold CAN1 counter when core is halted */ +#endif /* GD32F170_190 */ +#define DBG_CTL0_TIMER13_HOLD BIT(27) /*!< hold TIMER13 counter when core is halted */ + +/* DBG_CTL1 */ +#define DBG_CTL1_RTC_HOLD BIT(10) /*!< hold RTC calendar and wakeup counter when core is halted */ +#define DBG_CTL1_TIMER14_HOLD BIT(16) /*!< hold TIMER14 counter when core is halted */ +#define DBG_CTL1_TIMER15_HOLD BIT(17) /*!< hold TIMER15 counter when core is halted */ +#define DBG_CTL1_TIMER16_HOLD BIT(18) /*!< hold TIMER16 counter when core is halted */ + +/* constants definitions */ +#define DBG_LOW_POWER_SLEEP DBG_CTL0_SLP_HOLD /*!< keep debugger connection during sleep mode */ +#define DBG_LOW_POWER_DEEPSLEEP DBG_CTL0_DSLP_HOLD /*!< keep debugger connection during deepsleep mode */ +#define DBG_LOW_POWER_STANDBY DBG_CTL0_STB_HOLD /*!< keep debugger connection during standby mode */ + +/* define the peripheral debug hold bit position and its register index offset */ +#define DBG_REGIDX_BIT(regidx, bitpos) (((regidx) << 6) | (bitpos)) +#define DBG_REG_VAL(periph) (REG32(DBG + ((uint32_t)(periph) >> 6))) +#define DBG_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +/* register index */ +enum dbg_reg_idx +{ + DBG_IDX_CTL0 = 0x04U, + DBG_IDX_CTL1 = 0x08U, +}; + +/* peripherals hold bit */ +typedef enum +{ + DBG_FWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 8U), /*!< FWDGT hold bit */ + DBG_WWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 9U), /*!< WWDGT hold bit */ + DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 10U), /*!< TIMER0 hold bit */ + DBG_TIMER1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 11U), /*!< TIMER1 hold bit */ + DBG_TIMER2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 12U), /*!< TIMER2 hold bit */ +#ifdef GD32F170_190 + DBG_CAN0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 14U), /*!< CAN0 hold bit */ +#endif /* GD32F170_190 */ + DBG_I2C0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 15U), /*!< I2C0 hold bit */ + DBG_I2C1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 16U), /*!< I2C1 hold bit */ + DBG_I2C2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 17U), /*!< I2C2 hold bit */ + DBG_TIMER5_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 19U), /*!< TIMER5 hold bit */ +#ifdef GD32F170_190 + DBG_CAN1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 21U), /*!< CAN1 hold bit */ +#endif /* GD32F170_190 */ + DBG_TIMER13_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 27U), /*!< TIMER13 hold bit */ + DBG_RTC_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 10U), /*!< RTC hold bit */ + DBG_TIMER14_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 16U), /*!< TIMER14 hold bit */ + DBG_TIMER15_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 17U), /*!< TIMER15 hold bit */ + DBG_TIMER16_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 18U), /*!< TIMER16 hold bit */ +}dbg_periph_enum; + +/* function declarations */ +/* deinitialize the DBG */ +void dbg_deinit(void); +/* read DBG_ID code register */ +uint32_t dbg_id_get(void); + +/* enable low power behavior when the MCU is in debug mode */ +void dbg_low_power_enable(uint32_t dbg_low_power); +/* disable low power behavior when the MCU is in debug mode */ +void dbg_low_power_disable(uint32_t dbg_low_power); + +/* enable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_enable(dbg_periph_enum dbg_periph); +/* disable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_disable(dbg_periph_enum dbg_periph); +#endif /* GD32F1X0_DBG_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_dma.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_dma.h new file mode 100644 index 0000000..d9cb553 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_dma.h @@ -0,0 +1,249 @@ +/*! + \file gd32f1x0_dma.h + \brief definitions for the DMA +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_DMA_H +#define GD32F1X0_DMA_H + +#include "gd32f1x0.h" + +/* DMA definitions */ +#define DMA DMA_BASE /*!< DMA base address */ + +/* registers definitions */ +#define DMA_INTF REG32(DMA + 0x00U) /*!< DMA interrupt flag register */ +#define DMA_INTC REG32(DMA + 0x04U) /*!< DMA interrupt flag clear register */ + +#define DMA_CH0CTL REG32(DMA + 0x08U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT REG32(DMA + 0x0CU) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR REG32(DMA + 0x10U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0MADDR REG32(DMA + 0x14U) /*!< DMA channel 0 memory base address register */ + +#define DMA_CH1CTL REG32(DMA + 0x1CU) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT REG32(DMA + 0x20U) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR REG32(DMA + 0x24U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1MADDR REG32(DMA + 0x28U) /*!< DMA channel 1 memory base address register */ + +#define DMA_CH2CTL REG32(DMA + 0x30U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT REG32(DMA + 0x34U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR REG32(DMA + 0x38U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2MADDR REG32(DMA + 0x3CU) /*!< DMA channel 2 memory base address register */ + +#define DMA_CH3CTL REG32(DMA + 0x44U) /*!< DMA channel 3 control register */ +#define DMA_CH3CNT REG32(DMA + 0x48U) /*!< DMA channel 3 counter register */ +#define DMA_CH3PADDR REG32(DMA + 0x4CU) /*!< DMA channel 3 peripheral base address register */ +#define DMA_CH3MADDR REG32(DMA + 0x50U) /*!< DMA channel 3 memory base address register */ + +#define DMA_CH4CTL REG32(DMA + 0x58U) /*!< DMA channel 4 control register */ +#define DMA_CH4CNT REG32(DMA + 0x5CU) /*!< DMA channel 4 counter register */ +#define DMA_CH4PADDR REG32(DMA + 0x60U) /*!< DMA channel 4 peripheral base address register */ +#define DMA_CH4MADDR REG32(DMA + 0x64U) /*!< DMA channel 4 memory base address register */ + +#define DMA_CH5CTL REG32(DMA + 0x6CU) /*!< DMA channel 5 control register */ +#define DMA_CH5CNT REG32(DMA + 0x70U) /*!< DMA channel 5 counter register */ +#define DMA_CH5PADDR REG32(DMA + 0x74U) /*!< DMA channel 5 peripheral base address register */ +#define DMA_CH5MADDR REG32(DMA + 0x78U) /*!< DMA channel 5 memory base address register */ + +#define DMA_CH6CTL REG32(DMA + 0x80U) /*!< DMA channel 6 control register */ +#define DMA_CH6CNT REG32(DMA + 0x84U) /*!< DMA channel 6 counter register */ +#define DMA_CH6PADDR REG32(DMA + 0x88U) /*!< DMA channel 6 peripheral base address register */ +#define DMA_CH6MADDR REG32(DMA + 0x8CU) /*!< DMA channel 6 memory base address register */ + +/* bits definitions */ +/* DMA_INTF */ +#define DMA_INTF_GIF BIT(0) /*!< global interrupt flag of channel */ +#define DMA_INTF_FTFIF BIT(1) /*!< transfer complete flag of channel */ +#define DMA_INTF_HTFIF BIT(2) /*!< half transfer complete flag of channel */ +#define DMA_INTF_ERRIF BIT(3) /*!< error flag of channel */ + +/* DMA_INTC */ +#define DMA_INTFC_GIFC BIT(0) /*!< clear global interrupt flag of channel */ +#define DMA_INTFC_FTFIFC BIT(1) /*!< clear transfer complete flag of channel */ +#define DMA_INTFC_HTFIFC BIT(2) /*!< clear half transfer complete flag of channel */ +#define DMA_INTFC_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) /*!< transfer direction */ +#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 */ + +/* constants definitions */ +/* DMA channel select */ +typedef enum +{ + DMA_CH0 = 0, /*!< DMA Channel0 */ + DMA_CH1, /*!< DMA Channel1 */ + DMA_CH2, /*!< DMA Channel2 */ + DMA_CH3, /*!< DMA Channel3 */ + DMA_CH4, /*!< DMA Channel4 */ + DMA_CH5, /*!< DMA Channel5 */ + DMA_CH6 /*!< DMA Channel6 */ +} dma_channel_enum; + +/* DMA initialize struct */ +typedef struct +{ + uint32_t periph_addr; /*!< peripheral base address */ + uint32_t periph_width; /*!< transfer data size of peripheral */ + uint32_t periph_inc; /*!< peripheral increasing mode */ + uint32_t memory_addr; /*!< memory base address */ + uint32_t memory_width; /*!< transfer data size of memory */ + uint32_t memory_inc; /*!< memory increasing mode */ + uint32_t direction; /*!< channel data transfer direction */ + uint32_t number; /*!< channel transfer number */ + uint32_t priority; /*!< channel priority level */ +} dma_parameter_struct; + +/* 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 */ + +/* 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 */ + +/* 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_CHCTL base address */ +#define DMA_CHXCTL_BASE (DMA + 0x08U) /*!< the base address of DMA channel CHXCTL register */ +#define DMA_CHXCNT_BASE (DMA + 0x0CU) /*!< the base address of DMA channel CHXCNT register */ +#define DMA_CHXPADDR_BASE (DMA + 0x10U) /*!< the base address of DMA channel CHXPADDR register */ +#define DMA_CHXMADDR_BASE (DMA + 0x14U) /*!< the base address of DMA channel CHXMADDR 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(channel) REG32(DMA_CHXCTL_BASE + 0x14U*(channel)) /*!< the address of DMA channel CHXCTL register */ +#define DMA_CHCNT(channel) REG32(DMA_CHXCNT_BASE + 0x14U*(channel)) /*!< the address of DMA channel CHXCNT register */ +#define DMA_CHPADDR(channel) REG32(DMA_CHXPADDR_BASE + 0x14U*(channel)) /*!< the address of DMA channel CHXPADDR register */ +#define DMA_CHMADDR(channel) REG32(DMA_CHXMADDR_BASE + 0x14U*(channel)) /*!< the address of DMA channel CHXMADDR register */ + +/* channel priority level */ +#define CHCTL_PRIO(regval) (BITS(12,13) & ((regval) << 12U)) /*!< DMA channel priority level */ +#define DMA_PRIORITY_LOW CHCTL_PRIO(0) /*!< low priority */ +#define DMA_PRIORITY_MEDIUM CHCTL_PRIO(1) /*!< medium priority */ +#define DMA_PRIORITY_HIGH CHCTL_PRIO(2) /*!< high priority */ +#define DMA_PRIORITY_ULTRA_HIGH CHCTL_PRIO(3) /*!< ultra high priority */ + +/* transfer data size of memory */ +#define CHCTL_MSIZE(regval) (BITS(10,11) & ((regval) << 10U)) /*!< transfer data size of memory */ +#define DMA_MEMORY_WIDTH_8BIT CHCTL_MSIZE(0) /*!< transfer data size of memory is 8-bit */ +#define DMA_MEMORY_WIDTH_16BIT CHCTL_MSIZE(1) /*!< transfer data size of memory is 16-bit */ +#define DMA_MEMORY_WIDTH_32BIT CHCTL_MSIZE(2) /*!< transfer data size of memory is 32-bit */ + +/* transfer data size of peripheral */ +#define CHCTL_PSIZE(regval) (BITS(8,9) & ((regval) << 8U)) /*!< transfer data size of peripheral */ +#define DMA_PERIPHERAL_WIDTH_8BIT CHCTL_PSIZE(0) /*!< transfer data size of peripheral is 8-bit */ +#define DMA_PERIPHERAL_WIDTH_16BIT CHCTL_PSIZE(1) /*!< transfer data size of peripheral is 16-bit */ +#define DMA_PERIPHERAL_WIDTH_32BIT CHCTL_PSIZE(2) /*!< transfer data size of peripheral is 32-bit */ + +/* channel data transfer direction */ +#define DMA_PERIPHERAL_TO_MEMORY ((uint32_t)0x00000000U) /*!< read from peripheral and write to memory */ +#define DMA_MEMORY_TO_PERIPHERAL ((uint32_t)0x00000001U) /*!< read from memory and write to peripheral */ + +/* peripheral increasing mode */ +#define DMA_PERIPH_INCREASE_ENABLE ((uint32_t)0x00000000U) /*!< next address of peripheral is increasing address mode */ +#define DMA_PERIPH_INCREASE_DISABLE ((uint32_t)0x00000001U) /*!< next address of peripheral is fixed address mode */ + +/* memory increasing mode */ +#define DMA_MEMORY_INCREASE_ENABLE ((uint32_t)0x00000000U) /*!< next address of memory is increasing address mode */ +#define DMA_MEMORY_INCREASE_DISABLE ((uint32_t)0x00000001U) /*!< next address of memory is fixed address mode */ + +/* DMA reset value */ +#define DMA_CHCTL_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCTL register */ +#define DMA_CHCNT_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCNT register */ +#define DMA_CHPADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXPADDR register */ +#define DMA_CHMADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXMADDR register */ +#define DMA_CHINTF_RESET_VALUE ((uint32_t)0x0000000FU) /*!< clear DMA channel CHXINTFS register */ + +/* function declarations */ +/* deinitialize DMA a channel registers */ +void dma_deinit(dma_channel_enum channelx); +/* initialize DMA channel */ +void dma_init(dma_channel_enum channelx, dma_parameter_struct init_struct); +/* enable DMA circulation mode */ +void dma_circulation_enable(dma_channel_enum channelx); +/* disable DMA circulation mode */ +void dma_circulation_disable(dma_channel_enum channelx); +/* enable memory to memory mode */ +void dma_memory_to_memory_enable(dma_channel_enum channelx); +/* disable memory to memory mode */ +void dma_memory_to_memory_disable(dma_channel_enum channelx); +/* enable DMA channel */ +void dma_channel_enable(dma_channel_enum channelx); +/* disable DMA channel */ +void dma_channel_disable(dma_channel_enum channelx); + +/* set DMA peripheral base address */ +void dma_periph_address_config(dma_channel_enum channelx, uint32_t address); +/* set DMA Memory base address */ +void dma_memory_address_config(dma_channel_enum channelx, uint32_t address); +/* set the number of remaining data to be transferred by the DMA */ +void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number); +/* get the number of remaining data to be transferred by the DMA */ +uint32_t dma_transfer_number_get(dma_channel_enum channelx); +/* configure priority level of DMA channel */ +void dma_priority_config(dma_channel_enum channelx, uint32_t priority); +/* configure transfer data size of memory */ +void dma_memory_width_config (dma_channel_enum channelx, uint32_t msize); +/* configure transfer data size of peripheral */ +void dma_periph_width_config (dma_channel_enum channelx, uint32_t psize); +/* enable next address increasement algorithm of memory */ +void dma_memory_increase_enable(dma_channel_enum channelx); +/* disable next address increasement algorithm of memory */ +void dma_memory_increase_disable(dma_channel_enum channelx); +/* enable next address increasement algorithm of peripheral */ +void dma_periph_increase_enable(dma_channel_enum channelx); +/* disable next address increasement algorithm of peripheral */ +void dma_periph_increase_disable(dma_channel_enum channelx); +/* configure the direction of data transfer on the channel */ +void dma_transfer_direction_config(dma_channel_enum channelx, uint8_t direction); + +/* check DMA flag is set or not */ +FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag); +/* clear DMA a channel flag */ +void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag); +/* enable DMA interrupt */ +void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source); +/* disable DMA interrupt */ +void dma_interrupt_disable(dma_channel_enum channelx,uint32_t source); +/* check DMA flag is set or not */ +FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag); +/* clear DMA a channel flag */ +void dma_flag_clear(dma_channel_enum channelx, uint32_t flag); + +#endif /* GD32F1X0_DMA_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_exti.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_exti.h new file mode 100644 index 0000000..ee2c067 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_exti.h @@ -0,0 +1,262 @@ +/*! + \file gd32f1x0_exti.h + \brief definitions for the EXTI +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_EXTI_H +#define GD32F1X0_EXTI_H + +#include "gd32f1x0.h" + +/* EXTI definitions */ +#define EXTI EXTI_BASE + +/* registers definitions */ +#define EXTI_INTEN REG32(EXTI + 0x00U) /*!< interrupt enable register */ +#define EXTI_EVEN REG32(EXTI + 0x04U) /*!< event enable register */ +#define EXTI_RTEN REG32(EXTI + 0x08U) /*!< rising edge trigger enable register */ +#define EXTI_FTEN REG32(EXTI + 0x0CU) /*!< falling trigger enable register */ +#define EXTI_SWIEV REG32(EXTI + 0x10U) /*!< software interrupt event register */ +#define EXTI_PD REG32(EXTI + 0x14U) /*!< pending register */ + +/* bits definitions */ +/* EXTI_INTEN */ +#define EXTI_INTEN_INTEN0 BIT(0) /*!< interrupt from line 0 */ +#define EXTI_INTEN_INTEN1 BIT(1) /*!< interrupt from line 1 */ +#define EXTI_INTEN_INTEN2 BIT(2) /*!< interrupt from line 2 */ +#define EXTI_INTEN_INTEN3 BIT(3) /*!< interrupt from line 3 */ +#define EXTI_INTEN_INTEN4 BIT(4) /*!< interrupt from line 4 */ +#define EXTI_INTEN_INTEN5 BIT(5) /*!< interrupt from line 5 */ +#define EXTI_INTEN_INTEN6 BIT(6) /*!< interrupt from line 6 */ +#define EXTI_INTEN_INTEN7 BIT(7) /*!< interrupt from line 7 */ +#define EXTI_INTEN_INTEN8 BIT(8) /*!< interrupt from line 8 */ +#define EXTI_INTEN_INTEN9 BIT(9) /*!< interrupt from line 9 */ +#define EXTI_INTEN_INTEN10 BIT(10) /*!< interrupt from line 10 */ +#define EXTI_INTEN_INTEN11 BIT(11) /*!< interrupt from line 11 */ +#define EXTI_INTEN_INTEN12 BIT(12) /*!< interrupt from line 12 */ +#define EXTI_INTEN_INTEN13 BIT(13) /*!< interrupt from line 13 */ +#define EXTI_INTEN_INTEN14 BIT(14) /*!< interrupt from line 14 */ +#define EXTI_INTEN_INTEN15 BIT(15) /*!< interrupt from line 15 */ +#define EXTI_INTEN_INTEN16 BIT(16) /*!< interrupt from line 16 */ +#define EXTI_INTEN_INTEN17 BIT(17) /*!< interrupt from line 17 */ +#define EXTI_INTEN_INTEN18 BIT(18) /*!< interrupt from line 18 */ +#define EXTI_INTEN_INTEN19 BIT(19) /*!< interrupt from line 19 */ +#define EXTI_INTEN_INTEN20 BIT(20) /*!< interrupt from line 20 */ +#define EXTI_INTEN_INTEN21 BIT(21) /*!< interrupt from line 21 */ +#define EXTI_INTEN_INTEN22 BIT(22) /*!< interrupt from line 22 */ +#define EXTI_INTEN_INTEN23 BIT(23) /*!< interrupt from line 23 */ +#define EXTI_INTEN_INTEN24 BIT(24) /*!< interrupt from line 24 */ +#define EXTI_INTEN_INTEN25 BIT(25) /*!< interrupt from line 25 */ +#define EXTI_INTEN_INTEN26 BIT(26) /*!< interrupt from line 26 */ +#define EXTI_INTEN_INTEN27 BIT(27) /*!< interrupt from line 27 */ + +/* 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 */ +#define EXTI_EVEN_EVEN25 BIT(25) /*!< event from line 25 */ +#define EXTI_EVEN_EVEN26 BIT(26) /*!< event from line 26 */ +#define EXTI_EVEN_EVEN27 BIT(27) /*!< event from line 27 */ + +/* 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_RTEN21 BIT(21) /*!< rising edge from line 21 */ +#define EXTI_RTEN_RTEN22 BIT(22) /*!< rising edge from line 22 */ + +/* EXTI_FTEN */ +#define EXTI_FTEN_FTEN0 BIT(0) /*!< falling edge from line 0 */ +#define EXTI_FTEN_FTEN1 BIT(1) /*!< falling edge from line 1 */ +#define EXTI_FTEN_FTEN2 BIT(2) /*!< falling edge from line 2 */ +#define EXTI_FTEN_FTEN3 BIT(3) /*!< falling edge from line 3 */ +#define EXTI_FTEN_FTEN4 BIT(4) /*!< falling edge from line 4 */ +#define EXTI_FTEN_FTEN5 BIT(5) /*!< falling edge from line 5 */ +#define EXTI_FTEN_FTEN6 BIT(6) /*!< falling edge from line 6 */ +#define EXTI_FTEN_FTEN7 BIT(7) /*!< falling edge from line 7 */ +#define EXTI_FTEN_FTEN8 BIT(8) /*!< falling edge from line 8 */ +#define EXTI_FTEN_FTEN9 BIT(9) /*!< falling edge from line 9 */ +#define EXTI_FTEN_FTEN10 BIT(10) /*!< falling edge from line 10 */ +#define EXTI_FTEN_FTEN11 BIT(11) /*!< falling edge from line 11 */ +#define EXTI_FTEN_FTEN12 BIT(12) /*!< falling edge from line 12 */ +#define EXTI_FTEN_FTEN13 BIT(13) /*!< falling edge from line 13 */ +#define EXTI_FTEN_FTEN14 BIT(14) /*!< falling edge from line 14 */ +#define EXTI_FTEN_FTEN15 BIT(15) /*!< falling edge from line 15 */ +#define EXTI_FTEN_FTEN16 BIT(16) /*!< falling edge from line 16 */ +#define EXTI_FTEN_FTEN17 BIT(17) /*!< falling edge from line 17 */ +#define EXTI_FTEN_FTEN18 BIT(18) /*!< falling edge from line 18 */ +#define EXTI_FTEN_FTEN19 BIT(19) /*!< falling edge from line 19 */ +#define EXTI_FTEN_FTEN21 BIT(21) /*!< falling edge from line 21 */ +#define EXTI_FTEN_FTEN22 BIT(22) /*!< falling edge from line 22 */ + +/* EXTI_SWIEV */ +#define EXTI_SWIEV_SWIEV0 BIT(0) /*!< software interrupt/event request from line 0 */ +#define EXTI_SWIEV_SWIEV1 BIT(1) /*!< software interrupt/event request from line 1 */ +#define EXTI_SWIEV_SWIEV2 BIT(2) /*!< software interrupt/event request from line 2 */ +#define EXTI_SWIEV_SWIEV3 BIT(3) /*!< software interrupt/event request from line 3 */ +#define EXTI_SWIEV_SWIEV4 BIT(4) /*!< software interrupt/event request from line 4 */ +#define EXTI_SWIEV_SWIEV5 BIT(5) /*!< software interrupt/event request from line 5 */ +#define EXTI_SWIEV_SWIEV6 BIT(6) /*!< software interrupt/event request from line 6 */ +#define EXTI_SWIEV_SWIEV7 BIT(7) /*!< software interrupt/event request from line 7 */ +#define EXTI_SWIEV_SWIEV8 BIT(8) /*!< software interrupt/event request from line 8 */ +#define EXTI_SWIEV_SWIEV9 BIT(9) /*!< software interrupt/event request from line 9 */ +#define EXTI_SWIEV_SWIEV10 BIT(10) /*!< software interrupt/event request from line 10 */ +#define EXTI_SWIEV_SWIEV11 BIT(11) /*!< software interrupt/event request from line 11 */ +#define EXTI_SWIEV_SWIEV12 BIT(12) /*!< software interrupt/event request from line 12 */ +#define EXTI_SWIEV_SWIEV13 BIT(13) /*!< software interrupt/event request from line 13 */ +#define EXTI_SWIEV_SWIEV14 BIT(14) /*!< software interrupt/event request from line 14 */ +#define EXTI_SWIEV_SWIEV15 BIT(15) /*!< software interrupt/event request from line 15 */ +#define EXTI_SWIEV_SWIEV16 BIT(16) /*!< software interrupt/event request from line 16 */ +#define EXTI_SWIEV_SWIEV17 BIT(17) /*!< software interrupt/event request from line 17 */ +#define EXTI_SWIEV_SWIEV18 BIT(18) /*!< software interrupt/event request from line 18 */ +#define EXTI_SWIEV_SWIEV19 BIT(19) /*!< software interrupt/event request from line 19 */ +#define EXTI_SWIEV_SWIEV21 BIT(21) /*!< software interrupt/event request from line 21 */ +#define EXTI_SWIEV_SWIEV22 BIT(22) /*!< software interrupt/event request from line 22 */ + +/* EXTI_PD */ +#define EXTI_PD_PD0 BIT(0) /*!< interrupt/event pending status from line 0 */ +#define EXTI_PD_PD1 BIT(1) /*!< interrupt/event pending status from line 1 */ +#define EXTI_PD_PD2 BIT(2) /*!< interrupt/event pending status from line 2 */ +#define EXTI_PD_PD3 BIT(3) /*!< interrupt/event pending status from line 3 */ +#define EXTI_PD_PD4 BIT(4) /*!< interrupt/event pending status from line 4 */ +#define EXTI_PD_PD5 BIT(5) /*!< interrupt/event pending status from line 5 */ +#define EXTI_PD_PD6 BIT(6) /*!< interrupt/event pending status from line 6 */ +#define EXTI_PD_PD7 BIT(7) /*!< interrupt/event pending status from line 7 */ +#define EXTI_PD_PD8 BIT(8) /*!< interrupt/event pending status from line 8 */ +#define EXTI_PD_PD9 BIT(9) /*!< interrupt/event pending status from line 9 */ +#define EXTI_PD_PD10 BIT(10) /*!< interrupt/event pending status from line 10 */ +#define EXTI_PD_PD11 BIT(11) /*!< interrupt/event pending status from line 11 */ +#define EXTI_PD_PD12 BIT(12) /*!< interrupt/event pending status from line 12 */ +#define EXTI_PD_PD13 BIT(13) /*!< interrupt/event pending status from line 13 */ +#define EXTI_PD_PD14 BIT(14) /*!< interrupt/event pending status from line 14 */ +#define EXTI_PD_PD15 BIT(15) /*!< interrupt/event pending status from line 15 */ +#define EXTI_PD_PD16 BIT(16) /*!< interrupt/event pending status from line 16 */ +#define EXTI_PD_PD17 BIT(17) /*!< interrupt/event pending status from line 17 */ +#define EXTI_PD_PD18 BIT(18) /*!< interrupt/event pending status from line 18 */ +#define EXTI_PD_PD19 BIT(19) /*!< interrupt/event pending status from line 19 */ +#define EXTI_PD_PD21 BIT(21) /*!< interrupt/event pending status from line 21 */ +#define EXTI_PD_PD22 BIT(22) /*!< interrupt/event pending status from line 22 */ + +/* constants definitions */ +/* EXTI line number */ +typedef enum +{ + EXTI_0 = BIT(0), /*!< EXTI line 0 */ + EXTI_1 = BIT(1), /*!< EXTI line 1 */ + EXTI_2 = BIT(2), /*!< EXTI line 2 */ + EXTI_3 = BIT(3), /*!< EXTI line 3 */ + EXTI_4 = BIT(4), /*!< EXTI line 4 */ + EXTI_5 = BIT(5), /*!< EXTI line 5 */ + EXTI_6 = BIT(6), /*!< EXTI line 6 */ + EXTI_7 = BIT(7), /*!< EXTI line 7 */ + EXTI_8 = BIT(8), /*!< EXTI line 8 */ + EXTI_9 = BIT(9), /*!< EXTI line 9 */ + EXTI_10 = BIT(10), /*!< EXTI line 10 */ + EXTI_11 = BIT(11), /*!< EXTI line 11 */ + EXTI_12 = BIT(12), /*!< EXTI line 12 */ + EXTI_13 = BIT(13), /*!< EXTI line 13 */ + EXTI_14 = BIT(14), /*!< EXTI line 14 */ + EXTI_15 = BIT(15), /*!< EXTI line 15 */ + EXTI_16 = BIT(16), /*!< EXTI line 16 */ + EXTI_17 = BIT(17), /*!< EXTI line 17 */ +#ifdef GD32F130_150 + EXTI_18 = BIT(18), /*!< EXTI line 18 */ +#endif /* GD32F130_150 */ + EXTI_19 = BIT(19), /*!< EXTI line 19 */ + EXTI_21 = BIT(21), /*!< EXTI line 21 */ + EXTI_22 = BIT(22), /*!< EXTI line 22 */ + EXTI_25 = BIT(25), /*!< EXTI line 25 */ + EXTI_27 = BIT(27) /*!< EXTI line 27 */ +}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_type_enum; + +/* function declarations */ +/* deinitialize the EXTI */ +void exti_deinit(void); +/* enable the configuration of EXTI initialize */ +void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type); +/* enable the interrupts from EXTI line x */ +void exti_interrupt_enable(exti_line_enum linex); +/* enable the events from EXTI line x */ +void exti_event_enable(exti_line_enum linex); +/* disable the interrupts from EXTI line x */ +void exti_interrupt_disable(exti_line_enum linex); +/* disable the events from EXTI line x */ +void exti_event_disable(exti_line_enum linex); + +/* get EXTI lines pending flag */ +FlagStatus exti_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_flag_clear(exti_line_enum linex); +/* get EXTI lines flag when the interrupt flag is set */ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_interrupt_flag_clear(exti_line_enum linex); +/* EXTI software interrupt event enable */ +void exti_software_interrupt_enable(exti_line_enum linex); +/* EXTI software interrupt event disable */ +void exti_software_interrupt_disable(exti_line_enum linex); + +#endif /* GD32F1X0_EXTI_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_fmc.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_fmc.h new file mode 100644 index 0000000..bc94da1 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_fmc.h @@ -0,0 +1,239 @@ +/*! + \file gd32f1x0_fmc.h + \brief definitions for the FMC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_FMC_H +#define GD32F1X0_FMC_H + +#include "gd32f1x0.h" + +/* FMC and option byte definition */ +#define FMC FMC_BASE /*!< FMC register base address */ +#define OB OB_BASE /*!< option byte base address */ + +/* registers definitions */ +#define FMC_WS REG32((FMC) + 0x00U) /*!< FMC wait state register */ +#define FMC_KEY REG32((FMC) + 0x04U) /*!< FMC unlock key register */ +#define FMC_OBKEY REG32((FMC) + 0x08U) /*!< FMC option bytes unlock key register */ +#define FMC_STAT REG32((FMC) + 0x0CU) /*!< FMC status register */ +#define FMC_CTL REG32((FMC) + 0x10U) /*!< FMC control register */ +#define FMC_ADDR REG32((FMC) + 0x14U) /*!< FMC address register */ +#define FMC_OBSTAT REG32((FMC) + 0x1CU) /*!< FMC option bytes status register */ +#define FMC_WP REG32((FMC) + 0x20U) /*!< FMC write protection register */ +#define FMC_WSEN REG32((FMC) + 0xFCU) /*!< FMC wait state enable register */ +#define FMC_PID REG32((FMC) + 0x100U) /*!< FMC product ID register */ + +#define OB_SPC REG16((OB) + 0x00U) /*!< option byte security protection value */ +#define OB_USER REG16((OB) + 0x02U) /*!< option byte user value*/ +#define OB_WP0 REG16((OB) + 0x08U) /*!< option byte write protection 0 */ +#define OB_WP1 REG16((OB) + 0x0AU) /*!< option byte write protection 1 */ + +/* bits definitions */ +/* FMC_WS */ +#define FMC_WS_WSCNT BITS(0,2) /*!< wait state counter */ + +/* FMC_KEY */ +#define FMC_KEY_KEY BITS(0,31) /*!< FMC main flash unlock key bits */ + +/* FMC_OBKEY */ +#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option bytes unlock key bits */ + +/* FMC_STAT */ +#define FMC_STAT_BUSY BIT(0) /*!< flash busy flag bit */ +#define FMC_STAT_PGERR BIT(2) /*!< flash program error flag bit */ +#define FMC_STAT_WPERR BIT(4) /*!< flash write protection error flag bit */ +#define FMC_STAT_ENDF BIT(5) /*!< flash end of operation flag bit */ + +/* FMC_CTL */ +#define FMC_CTL_PG BIT(0) /*!< main flash program command bit */ +#define FMC_CTL_PER BIT(1) /*!< main flash page erase bit */ +#define FMC_CTL_MER BIT(2) /*!< main flash mass erase bit */ +#define FMC_CTL_OBPG BIT(4) /*!< option bytes program command bit */ +#define FMC_CTL_OBER BIT(5) /*!< option bytes erase command bit */ +#define FMC_CTL_START BIT(6) /*!< send erase command to FMC bit */ +#define FMC_CTL_LK BIT(7) /*!< flash lock bit */ +#define FMC_CTL_OBWEN BIT(9) /*!< option bytes erase/program enable bit */ +#define FMC_CTL_ERRIE BIT(10) /*!< error interrupt enable bit */ +#define FMC_CTL_ENDIE BIT(12) /*!< end of operation interrupt enable bit */ +#define FMC_CTL_OBRLD BIT(13) /*!< option bytes reload bit */ + +/* FMC_ADDR */ +#define FMC_ADDR_ADDR BITS(0,31) /*!< flash command address bits */ + +/* FMC_OBSTAT */ +#define FMC_OBSTAT_OBERR BIT(0) /*!< option bytes read error bit */ +#define FMC_OBSTAT_PLVL_BIT0 BIT(1) /*!< protection level bit 0 */ +#define FMC_OBSTAT_PLVL_BIT1 BIT(2) /*!< protection level bit 1 */ +#define FMC_OBSTAT_USER BITS(8,15) /*!< option bytes user bits */ +#define FMC_OBSTAT_DATA BITS(16,31) /*!< option byte data bits */ + +/* FMC_WSEN */ +#define FMC_WSEN_WSEN BIT(0) /*!< FMC wait state enable bit */ +#ifdef GD32F170_190 +#define FMC_WSEN_BPEN BIT(1) /*!< FMC bit program enable bit */ +#endif /* GD32F170_190 */ + +/* 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_PGERR, /*!< program error */ + FMC_WPERR, /*!< erase/program protection error */ + FMC_TOERR, /*!< timeout error */ + FMC_OB_HSPC /*!< option byte security protection code high */ +}fmc_state_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_0 ((uint8_t)0x00U) /*!< 0 wait state added */ +#define WS_WSCNT_1 ((uint8_t)0x01U) /*!< 1 wait state added */ +#define WS_WSCNT_2 ((uint8_t)0x02U) /*!< 2 wait state added */ + +/* read protect configure */ +#define FMC_NSPC ((uint8_t)0xA5U) /*!< no security protection */ +#define FMC_LSPC ((uint8_t)0xBBU) /*!< low security protection, any value except 0xA5 or 0xCC */ +#define FMC_HSPC ((uint8_t)0xCCU) /*!< high security protection */ + +/* option byte write protection */ +#define OB_LWP ((uint32_t)0x000000FFU) /*!< write protection low bits */ +#define OB_HWP ((uint32_t)0x0000FF00U) /*!< write protection high bits */ + +/* option byte software/hardware free watchdog timer */ +#define OBUSER_NWDG_HW(regval) (BIT(0) & ((uint32_t)(regval) << 0)) +#define OB_FWDGT_HW OBUSER_NWDG_HW(0) /*!< hardware free watchdog timer */ +#define OB_FWDGT_SW OBUSER_NWDG_HW(1) /*!< software free watchdog timer */ + +/* option byte reset or not entering deep sleep mode */ +#define OBUSER_NRST_DPSLP(regval) (BIT(1) & ((uint32_t)(regval) << 1)) +#define OB_DEEPSLEEP_RST OBUSER_NRST_DPSLP(0) /*!< generate a reset instead of entering deepsleep mode */ +#define OB_DEEPSLEEP_NRST OBUSER_NRST_DPSLP(1) /*!< no reset when entering deepsleep mode */ + +/* option byte reset or not entering standby mode */ +#define OBUSER_NRST_STDBY(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define OB_STDBY_RST OBUSER_NRST_STDBY(0) /*!< generate a reset instead of entering standby mode */ +#define OB_STDBY_NRST OBUSER_NRST_STDBY(1) /*!< no reset when entering deepsleep mode */ + +/* option byte OB_BOOT1_n set */ +#define OBUSER_BOOT1_N(regval) (BIT(4) & ((uint32_t)(regval) << 4)) +#define OB_BOOT1_SET_1 OBUSER_BOOT1_N(0) /*!< BOOT1 bit is 1 */ +#define OB_BOOT1_SET_0 OBUSER_BOOT1_N(1) /*!< BOOT1 bit is 0 */ + +/* option byte VDDA monitor enable/disable */ +#define OBUSER_VDDA_VISOR(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define OB_VDDA_DISABLE OBUSER_VDDA_VISOR(0) /*!< disable VDDA monitor */ +#define OB_VDDA_ENABLE OBUSER_VDDA_VISOR(1) /*!< enable VDDA monitor */ + +/* option byte SRAM parity enable/disable */ +#define OBUSER_SRAM_PARITY(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define OB_SRAM_PARITY_ENABLE OBUSER_SRAM_PARITY(0) /*!< enable SRAM parity check */ +#define OB_SRAM_PARITY_DISABLE OBUSER_SRAM_PARITY(1) /*!< disable SRAM parity check */ + +/* option byte security protection level in FMC_OBSTAT register */ +#define OB_OBSTAT_PLEVEL_NO ((uint32_t)0x00000000U) /*!< no security protection */ +#define OB_OBSTAT_PLEVEL_LOW ((uint32_t)0x00000002U) /*!< low security protection */ +#define OB_OBSTAT_PLEVEL_HIGH ((uint32_t)0x00000006U) /*!< high security protection */ + +/* option byte user mask */ +#define OB_USER_MASK ((uint8_t)0x88U) /*!< OB_USER reserved bit mask */ + +/* option byte data address */ +#define OB_DATA_ADDR0 ((uint32_t)0x1FFFF804U) /*!< option byte data address 0 */ +#define OB_DATA_ADDR1 ((uint32_t)0x1FFFF806U) /*!< option byte data address 1 */ + +/* FMC flags */ +#define FMC_FLAG_BUSY FMC_STAT_BUSY /*!< FMC busy flag */ +#define FMC_FLAG_PGERR FMC_STAT_PGERR /*!< FMC programming error flag */ +#define FMC_FLAG_WPERR FMC_STAT_WPERR /*!< FMC write protection error flag */ +#define FMC_FLAG_END FMC_STAT_ENDF /*!< FMC end of programming flag */ + +/* FMC interrupt enable */ +#define FMC_INTEN_END FMC_CTL_ENDIE /*!< enable FMC end of operation interrupt */ +#define FMC_INTEN_ERR FMC_CTL_ERRIE /*!< enable FMC error interrupt */ + +/* FMC time out */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0x000F0000U) /*!< count to judge of FMC timeout */ + +/* function declarations */ +/* FMC main memory programming functions */ +/* unlock the main FMC operation */ +void fmc_unlock(void); +/* lock the main FMC operation */ +void fmc_lock(void); +/* set the wait state counter value */ +void fmc_wscnt_set(uint8_t wscnt); +/* fmc wait state enable */ +void fmc_wait_state_enable(void); +/* fmc wait state disable */ +void fmc_wait_state_disable(void); +/* FMC erase page */ +fmc_state_enum fmc_page_erase(uint32_t page_address); +/* FMC erase whole chip */ +fmc_state_enum fmc_mass_erase(void); +/* FMC program a word at the corresponding address */ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data); +/* FMC program a half word at the corresponding address */ +fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data); +#ifdef GD32F170_190 +/* FMC program a word at the corresponding address without erasing */ +fmc_state_enum fmc_word_reprogram(uint32_t address, uint32_t data); +#endif /* GD32F170_190 */ + +/* FMC option bytes programming functions */ +/* unlock the option byte operation */ +void ob_unlock(void); +/* lock the option byte operation */ +void ob_lock(void); +/* reload the option byte and generate a system reset */ +void ob_reset(void); +/* erase option byte */ +fmc_state_enum ob_erase(void); +/* enable option byte write protection (OB_WP) */ +fmc_state_enum ob_write_protection_enable(uint32_t ob_wp); +/* configure read out protect */ +fmc_state_enum ob_security_protection_config(uint8_t ob_spc); +/* write the FMC option byte user */ +fmc_state_enum ob_user_write(uint8_t ob_user); +/* write the FMC option byte data */ +fmc_state_enum ob_data_program(uint32_t address, uint8_t data); +/* get the FMC option byte OB_USER */ +uint8_t ob_user_get(void); +/* get the FMC option byte OB_DATA */ +uint16_t ob_data_get(void); +/* get the FMC option byte write protection */ +uint16_t ob_write_protection_get(void); +/* get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register */ +uint32_t ob_obstat_plevel_get(void); + +/* FMC interrupts and flags management functions */ +/* enable FMC interrupt */ +void fmc_interrupt_enable(uint32_t interrupt); +/* disable FMC interrupt */ +void fmc_interrupt_disable(uint32_t interrupt); +/* get flag set or reset */ +FlagStatus fmc_flag_get(uint32_t flag); +/* clear the FMC pending flag */ +void fmc_flag_clear(uint32_t flag); +/* return the FMC state */ +fmc_state_enum fmc_state_get(void); +/* check FMC ready or not */ +fmc_state_enum fmc_ready_wait(uint32_t timeout); + +#endif /* GD32F1X0_FMC_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_fwdgt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_fwdgt.h new file mode 100644 index 0000000..e95721d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_fwdgt.h @@ -0,0 +1,100 @@ +/*! + \file gd32f1x0_fwdgt.h + \brief definitions for the FWDGT +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_FWDGT_H +#define GD32F1X0_FWDGT_H + +#include "gd32f1x0.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE + +/* registers definitions */ +#define FWDGT_CTL REG32((FWDGT) + 0x00U) /*!< FWDGT control register */ +#define FWDGT_PSC REG32((FWDGT) + 0x04U) /*!< FWDGT prescaler register */ +#define FWDGT_RLD REG32((FWDGT) + 0x08U) /*!< FWDGT reload register */ +#define FWDGT_STAT REG32((FWDGT) + 0x0CU) /*!< FWDGT status register */ +#define FWDGT_WND REG32((FWDGT) + 0x10U) /*!< 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 */ +/* ctl register value */ +#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_CTL_CMD bit field */ + +/* 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 */ + +/* rld register value */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_RLD_RLD bit field */ + +/* wnd register value */ +#define WND_WND(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_WND_WND bit field */ + +/* control value */ +#define FWDGT_WRITEACCESS_ENABLE ((uint16_t)0x5555U) /*!< FWDGT_CTL bits write access enable value */ +#define FWDGT_WRITEACCESS_DISABLE ((uint16_t)0x0000U) /*!< FWDGT_CTL bits write access disable value */ +#define FWDGT_KEY_RELOAD ((uint16_t)0xAAAAU) /*!< FWDGT_CTL bits fwdgt counter reload value */ +#define FWDGT_KEY_ENABLE ((uint16_t)0xCCCCU) /*!< FWDGT_CTL bits fwdgt counter enable value */ + +/* FWDGT timeout value */ +#define FWDGT_WND_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_WND register write operation state flag timeout */ +#define FWDGT_PSC_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_PSC register write operation state flag timeout */ +#define FWDGT_RLD_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_RLD register write operation state flag timeout */ + +/* FWDGT flag definitions */ +#define FWDGT_FLAG_PUD FWDGT_STAT_PUD /*!< a write operation to FWDGT_PSC register is on going */ +#define FWDGT_FLAG_RUD FWDGT_STAT_RUD /*!< a write operation to FWDGT_RLD register is on going */ +#define FWDGT_FLAG_WUD FWDGT_STAT_WUD /*!< a write operation to FWDGT_WND register is on going */ + +/* function declarations */ +/* disable write access to FWDGT_PSC,FWDGT_RLD and FWDGT_WND */ +void fwdgt_write_disable(void); +/* start the free watchdog timer counter */ +void fwdgt_enable(void); + +/* configure the free watchdog timer 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 /* GD32F1X0_FWDGT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_gpio.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_gpio.h new file mode 100644 index 0000000..60067ad --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_gpio.h @@ -0,0 +1,378 @@ +/*! + \file gd32f1x0_gpio.h + \brief definitions for the GPIO +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform for GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform for GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_GPIO_H +#define GD32F1X0_GPIO_H + +#include "gd32f1x0.h" + +/* GPIOx(x=A,B,C,D,F) definitions */ +#define GPIOA (GPIO_BASE + 0x00000000U) +#define GPIOB (GPIO_BASE + 0x00000400U) +#define GPIOC (GPIO_BASE + 0x00000800U) +#define GPIOD (GPIO_BASE + 0x00000C00U) +#define GPIOF (GPIO_BASE + 0x00001400U) + +/* registers definitions */ +#define GPIO_CTL(gpiox) REG32((gpiox) + 0x00U) /*!< GPIO port control register */ +#define GPIO_OMODE(gpiox) REG32((gpiox) + 0x04U) /*!< GPIO port output mode register */ +#define GPIO_OSPD(gpiox) REG32((gpiox) + 0x08U) /*!< GPIO port output speed register */ +#define GPIO_PUD(gpiox) REG32((gpiox) + 0x0CU) /*!< GPIO port pull-up/down register */ +#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x10U) /*!< GPIO port input status register */ +#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x14U) /*!< GPIO port output control register */ +#define GPIO_BOP(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port bit operation register */ +#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x1CU) /*!< GPIO port configuration lock register */ +#define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x20U) /*!< GPIO alternate function selected register 0 */ +#define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x24U) /*!< GPIO alternate function selected register 1 */ +#define GPIO_BC(gpiox) REG32((gpiox) + 0x28U) /*!< GPIO bit clear register */ +#define GPIO_TG(gpiox) REG32((gpiox) + 0x2CU) /*!< GPIO port bit toggle register */ + +/* bits definitions */ +/* GPIO_CTL */ +#define GPIO_CTL_CTL0 BITS(0,1) /*!< pin 0 configuration bits */ +#define GPIO_CTL_CTL1 BITS(2,3) /*!< pin 1 configuration bits */ +#define GPIO_CTL_CTL2 BITS(4,5) /*!< pin 2 configuration bits */ +#define GPIO_CTL_CTL3 BITS(6,7) /*!< pin 3 configuration bits */ +#define GPIO_CTL_CTL4 BITS(8,9) /*!< pin 4 configuration bits */ +#define GPIO_CTL_CTL5 BITS(10,11) /*!< pin 5 configuration bits */ +#define GPIO_CTL_CTL6 BITS(12,13) /*!< pin 6 configuration bits */ +#define GPIO_CTL_CTL7 BITS(14,15) /*!< pin 7 configuration bits */ +#define GPIO_CTL_CTL8 BITS(16,17) /*!< pin 8 configuration bits */ +#define GPIO_CTL_CTL9 BITS(18,19) /*!< pin 9 configuration bits */ +#define GPIO_CTL_CTL10 BITS(20,21) /*!< pin 10 configuration bits */ +#define GPIO_CTL_CTL11 BITS(22,23) /*!< pin 11 configuration bits */ +#define GPIO_CTL_CTL12 BITS(24,25) /*!< pin 12 configuration bits */ +#define GPIO_CTL_CTL13 BITS(26,27) /*!< pin 13 configuration bits */ +#define GPIO_CTL_CTL14 BITS(28,29) /*!< pin 14 configuration bits */ +#define GPIO_CTL_CTL15 BITS(30,31) /*!< pin 15 configuration bits */ + +/* GPIO_OMODE */ +#define GPIO_OMODE_OM0 BIT(0) /*!< pin 0 output mode bit */ +#define GPIO_OMODE_OM1 BIT(1) /*!< pin 1 output mode bit */ +#define GPIO_OMODE_OM2 BIT(2) /*!< pin 2 output mode bit */ +#define GPIO_OMODE_OM3 BIT(3) /*!< pin 3 output mode bit */ +#define GPIO_OMODE_OM4 BIT(4) /*!< pin 4 output mode bit */ +#define GPIO_OMODE_OM5 BIT(5) /*!< pin 5 output mode bit */ +#define GPIO_OMODE_OM6 BIT(6) /*!< pin 6 output mode bit */ +#define GPIO_OMODE_OM7 BIT(7) /*!< pin 7 output mode bit */ +#define GPIO_OMODE_OM8 BIT(8) /*!< pin 8 output mode bit */ +#define GPIO_OMODE_OM9 BIT(9) /*!< pin 9 output mode bit */ +#define GPIO_OMODE_OM10 BIT(10) /*!< pin 10 output mode bit */ +#define GPIO_OMODE_OM11 BIT(11) /*!< pin 11 output mode bit */ +#define GPIO_OMODE_OM12 BIT(12) /*!< pin 12 output mode bit */ +#define GPIO_OMODE_OM13 BIT(13) /*!< pin 13 output mode bit */ +#define GPIO_OMODE_OM14 BIT(14) /*!< pin 14 output mode bit */ +#define GPIO_OMODE_OM15 BIT(15) /*!< pin 15 output mode bit */ + +/* GPIO_OSPD */ +#define GPIO_OSPD_OSPD0 BITS(0,1) /*!< pin 0 output max speed bits */ +#define GPIO_OSPD_OSPD1 BITS(2,3) /*!< pin 1 output max speed bits */ +#define GPIO_OSPD_OSPD2 BITS(4,5) /*!< pin 2 output max speed bits */ +#define GPIO_OSPD_OSPD3 BITS(6,7) /*!< pin 3 output max speed bits */ +#define GPIO_OSPD_OSPD4 BITS(8,9) /*!< pin 4 output max speed bits */ +#define GPIO_OSPD_OSPD5 BITS(10,11) /*!< pin 5 output max speed bits */ +#define GPIO_OSPD_OSPD6 BITS(12,13) /*!< pin 6 output max speed bits */ +#define GPIO_OSPD_OSPD7 BITS(14,15) /*!< pin 7 output max speed bits */ +#define GPIO_OSPD_OSPD8 BITS(16,17) /*!< pin 8 output max speed bits */ +#define GPIO_OSPD_OSPD9 BITS(18,19) /*!< pin 9 output max speed bits */ +#define GPIO_OSPD_OSPD10 BITS(20,21) /*!< pin 10 output max speed bits */ +#define GPIO_OSPD_OSPD11 BITS(22,23) /*!< pin 11 output max speed bits */ +#define GPIO_OSPD_OSPD12 BITS(24,25) /*!< pin 12 output max speed bits */ +#define GPIO_OSPD_OSPD13 BITS(26,27) /*!< pin 13 output max speed bits */ +#define GPIO_OSPD_OSPD14 BITS(28,29) /*!< pin 14 output max speed bits */ +#define GPIO_OSPD_OSPD15 BITS(30,31) /*!< pin 15 output max speed bits */ + +/* GPIO_PUD */ +#define GPIO_PUD_PUD0 BITS(0,1) /*!< pin 0 pull-up or pull-down bits */ +#define GPIO_PUD_PUD1 BITS(2,3) /*!< pin 1 pull-up or pull-down bits */ +#define GPIO_PUD_PUD2 BITS(4,5) /*!< pin 2 pull-up or pull-down bits */ +#define GPIO_PUD_PUD3 BITS(6,7) /*!< pin 3 pull-up or pull-down bits */ +#define GPIO_PUD_PUD4 BITS(8,9) /*!< pin 4 pull-up or pull-down bits */ +#define GPIO_PUD_PUD5 BITS(10,11) /*!< pin 5 pull-up or pull-down bits */ +#define GPIO_PUD_PUD6 BITS(12,13) /*!< pin 6 pull-up or pull-down bits */ +#define GPIO_PUD_PUD7 BITS(14,15) /*!< pin 7 pull-up or pull-down bits */ +#define GPIO_PUD_PUD8 BITS(16,17) /*!< pin 8 pull-up or pull-down bits */ +#define GPIO_PUD_PUD9 BITS(18,19) /*!< pin 9 pull-up or pull-down bits */ +#define GPIO_PUD_PUD10 BITS(20,21) /*!< pin 10 pull-up or pull-down bits */ +#define GPIO_PUD_PUD11 BITS(22,23) /*!< pin 11 pull-up or pull-down bits */ +#define GPIO_PUD_PUD12 BITS(24,25) /*!< pin 12 pull-up or pull-down bits */ +#define GPIO_PUD_PUD13 BITS(26,27) /*!< pin 13 pull-up or pull-down bits */ +#define GPIO_PUD_PUD14 BITS(28,29) /*!< pin 14 pull-up or pull-down bits */ +#define GPIO_PUD_PUD15 BITS(30,31) /*!< pin 15 pull-up or pull-down bits */ + +/* GPIO_ISTAT */ +#define GPIO_ISTAT_ISTAT0 BIT(0) /*!< pin 0 input status */ +#define GPIO_ISTAT_ISTAT1 BIT(1) /*!< pin 1 input status */ +#define GPIO_ISTAT_ISTAT2 BIT(2) /*!< pin 2 input status */ +#define GPIO_ISTAT_ISTAT3 BIT(3) /*!< pin 3 input status */ +#define GPIO_ISTAT_ISTAT4 BIT(4) /*!< pin 4 input status */ +#define GPIO_ISTAT_ISTAT5 BIT(5) /*!< pin 5 input status */ +#define GPIO_ISTAT_ISTAT6 BIT(6) /*!< pin 6 input status */ +#define GPIO_ISTAT_ISTAT7 BIT(7) /*!< pin 7 input status */ +#define GPIO_ISTAT_ISTAT8 BIT(8) /*!< pin 8 input status */ +#define GPIO_ISTAT_ISTAT9 BIT(9) /*!< pin 9 input status */ +#define GPIO_ISTAT_ISTAT10 BIT(10) /*!< pin 10 input status */ +#define GPIO_ISTAT_ISTAT11 BIT(11) /*!< pin 11 input status */ +#define GPIO_ISTAT_ISTAT12 BIT(12) /*!< pin 12 input status */ +#define GPIO_ISTAT_ISTAT13 BIT(13) /*!< pin 13 input status */ +#define GPIO_ISTAT_ISTAT14 BIT(14) /*!< pin 14 input status */ +#define GPIO_ISTAT_ISTAT15 BIT(15) /*!< pin 15 input status */ + +/* GPIO_OCTL */ +#define GPIO_OCTL_OCTL0 BIT(0) /*!< pin 0 output bit */ +#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output bit */ +#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output bit */ +#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output bit */ +#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output bit */ +#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output bit */ +#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output bit */ +#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output bit */ +#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output bit */ +#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output bit */ +#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output bit */ +#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output bit */ +#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output bit */ +#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output bit */ +#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output bit */ +#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output bit */ + +/* GPIO_BOP */ +#define GPIO_BOP_BOP0 BIT(0) /*!< pin 0 set bit */ +#define GPIO_BOP_BOP1 BIT(1) /*!< pin 1 set bit */ +#define GPIO_BOP_BOP2 BIT(2) /*!< pin 2 set bit */ +#define GPIO_BOP_BOP3 BIT(3) /*!< pin 3 set bit */ +#define GPIO_BOP_BOP4 BIT(4) /*!< pin 4 set bit */ +#define GPIO_BOP_BOP5 BIT(5) /*!< pin 5 set bit */ +#define GPIO_BOP_BOP6 BIT(6) /*!< pin 6 set bit */ +#define GPIO_BOP_BOP7 BIT(7) /*!< pin 7 set bit */ +#define GPIO_BOP_BOP8 BIT(8) /*!< pin 8 set bit */ +#define GPIO_BOP_BOP9 BIT(9) /*!< pin 9 set bit */ +#define GPIO_BOP_BOP10 BIT(10) /*!< pin 10 set bit */ +#define GPIO_BOP_BOP11 BIT(11) /*!< pin 11 set bit */ +#define GPIO_BOP_BOP12 BIT(12) /*!< pin 12 set bit */ +#define GPIO_BOP_BOP13 BIT(13) /*!< pin 13 set bit */ +#define GPIO_BOP_BOP14 BIT(14) /*!< pin 14 set bit */ +#define GPIO_BOP_BOP15 BIT(15) /*!< pin 15 set bit */ +#define GPIO_BOP_CR0 BIT(16) /*!< pin 0 clear bit */ +#define GPIO_BOP_CR1 BIT(17) /*!< pin 1 clear bit */ +#define GPIO_BOP_CR2 BIT(18) /*!< pin 2 clear bit */ +#define GPIO_BOP_CR3 BIT(19) /*!< pin 3 clear bit */ +#define GPIO_BOP_CR4 BIT(20) /*!< pin 4 clear bit */ +#define GPIO_BOP_CR5 BIT(21) /*!< pin 5 clear bit */ +#define GPIO_BOP_CR6 BIT(22) /*!< pin 6 clear bit */ +#define GPIO_BOP_CR7 BIT(23) /*!< pin 7 clear bit */ +#define GPIO_BOP_CR8 BIT(24) /*!< pin 8 clear bit */ +#define GPIO_BOP_CR9 BIT(25) /*!< pin 9 clear bit */ +#define GPIO_BOP_CR10 BIT(26) /*!< pin 10 clear bit */ +#define GPIO_BOP_CR11 BIT(27) /*!< pin 11 clear bit */ +#define GPIO_BOP_CR12 BIT(28) /*!< pin 12 clear bit */ +#define GPIO_BOP_CR13 BIT(29) /*!< pin 13 clear bit */ +#define GPIO_BOP_CR14 BIT(30) /*!< pin 14 clear bit */ +#define GPIO_BOP_CR15 BIT(31) /*!< pin 15 clear bit */ + +/* GPIO_LOCK */ +#define GPIO_LOCK_LK0 BIT(0) /*!< pin 0 lock bit */ +#define GPIO_LOCK_LK1 BIT(1) /*!< pin 1 lock bit */ +#define GPIO_LOCK_LK2 BIT(2) /*!< pin 2 lock bit */ +#define GPIO_LOCK_LK3 BIT(3) /*!< pin 3 lock bit */ +#define GPIO_LOCK_LK4 BIT(4) /*!< pin 4 lock bit */ +#define GPIO_LOCK_LK5 BIT(5) /*!< pin 5 lock bit */ +#define GPIO_LOCK_LK6 BIT(6) /*!< pin 6 lock bit */ +#define GPIO_LOCK_LK7 BIT(7) /*!< pin 7 lock bit */ +#define GPIO_LOCK_LK8 BIT(8) /*!< pin 8 lock bit */ +#define GPIO_LOCK_LK9 BIT(9) /*!< pin 9 lock bit */ +#define GPIO_LOCK_LK10 BIT(10) /*!< pin 10 lock bit */ +#define GPIO_LOCK_LK11 BIT(11) /*!< pin 11 lock bit */ +#define GPIO_LOCK_LK12 BIT(12) /*!< pin 12 lock bit */ +#define GPIO_LOCK_LK13 BIT(13) /*!< pin 13 lock bit */ +#define GPIO_LOCK_LK14 BIT(14) /*!< pin 14 lock bit */ +#define GPIO_LOCK_LK15 BIT(15) /*!< pin 15 lock bit */ +#define GPIO_LOCK_LKK BIT(16) /*!< pin sequence lock key */ + +/* GPIO_AFSEL0 */ +#define GPIO_AFSEL0_SEL0 BITS(0,3) /*!< pin 0 alternate function selected */ +#define GPIO_AFSEL0_SEL1 BITS(4,7) /*!< pin 1 alternate function selected */ +#define GPIO_AFSEL0_SEL2 BITS(8,11) /*!< pin 2 alternate function selected */ +#define GPIO_AFSEL0_SEL3 BITS(12,15) /*!< pin 3 alternate function selected */ +#define GPIO_AFSEL0_SEL4 BITS(16,19) /*!< pin 4 alternate function selected */ +#define GPIO_AFSEL0_SEL5 BITS(20,23) /*!< pin 5 alternate function selected */ +#define GPIO_AFSEL0_SEL6 BITS(24,27) /*!< pin 6 alternate function selected */ +#define GPIO_AFSEL0_SEL7 BITS(28,31) /*!< pin 7 alternate function selected */ + +/* GPIO_AFSEL1 */ +#define GPIO_AFSEL1_SEL8 BITS(0,3) /*!< pin 8 alternate function selected */ +#define GPIO_AFSEL1_SEL9 BITS(4,7) /*!< pin 9 alternate function selected */ +#define GPIO_AFSEL1_SEL10 BITS(8,11) /*!< pin 10 alternate function selected */ +#define GPIO_AFSEL1_SEL11 BITS(12,15) /*!< pin 11 alternate function selected */ +#define GPIO_AFSEL1_SEL12 BITS(16,19) /*!< pin 12 alternate function selected */ +#define GPIO_AFSEL1_SEL13 BITS(20,23) /*!< pin 13 alternate function selected */ +#define GPIO_AFSEL1_SEL14 BITS(24,27) /*!< pin 14 alternate function selected */ +#define GPIO_AFSEL1_SEL15 BITS(28,31) /*!< pin 15 alternate function selected */ + +/* GPIO_BC */ +#define GPIO_BC_CR0 BIT(0) /*!< pin 0 clear bit */ +#define GPIO_BC_CR1 BIT(1) /*!< pin 1 clear bit */ +#define GPIO_BC_CR2 BIT(2) /*!< pin 2 clear bit */ +#define GPIO_BC_CR3 BIT(3) /*!< pin 3 clear bit */ +#define GPIO_BC_CR4 BIT(4) /*!< pin 4 clear bit */ +#define GPIO_BC_CR5 BIT(5) /*!< pin 5 clear bit */ +#define GPIO_BC_CR6 BIT(6) /*!< pin 6 clear bit */ +#define GPIO_BC_CR7 BIT(7) /*!< pin 7 clear bit */ +#define GPIO_BC_CR8 BIT(8) /*!< pin 8 clear bit */ +#define GPIO_BC_CR9 BIT(9) /*!< pin 9 clear bit */ +#define GPIO_BC_CR10 BIT(10) /*!< pin 10 clear bit */ +#define GPIO_BC_CR11 BIT(11) /*!< pin 11 clear bit */ +#define GPIO_BC_CR12 BIT(12) /*!< pin 12 clear bit */ +#define GPIO_BC_CR13 BIT(13) /*!< pin 13 clear bit */ +#define GPIO_BC_CR14 BIT(14) /*!< pin 14 clear bit */ +#define GPIO_BC_CR15 BIT(15) /*!< pin 15 clear bit */ + +#ifdef GD32F170_190 +/* 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 */ + +#endif /* GD32F170_190 */ + +/* 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) /*!< without weak pull-up and pull-down resistors */ +#define GPIO_PUPD_PULLUP PUD_PUPD(1) /*!< with weak pull-up resistor */ +#define GPIO_PUPD_PULLDOWN PUD_PUPD(2) /*!< with weak pull-down resistor */ + +/* GPIO pin definitions */ +#define GPIO_PIN_0 BIT(0) /*!< GPIO pin 0 */ +#define GPIO_PIN_1 BIT(1) /*!< GPIO pin 1 */ +#define GPIO_PIN_2 BIT(2) /*!< GPIO pin 2 */ +#define GPIO_PIN_3 BIT(3) /*!< GPIO pin 3 */ +#define GPIO_PIN_4 BIT(4) /*!< GPIO pin 4 */ +#define GPIO_PIN_5 BIT(5) /*!< GPIO pin 5 */ +#define GPIO_PIN_6 BIT(6) /*!< GPIO pin 6 */ +#define GPIO_PIN_7 BIT(7) /*!< GPIO pin 7 */ +#define GPIO_PIN_8 BIT(8) /*!< GPIO pin 8 */ +#define GPIO_PIN_9 BIT(9) /*!< GPIO pin 9 */ +#define GPIO_PIN_10 BIT(10) /*!< GPIO pin 10 */ +#define GPIO_PIN_11 BIT(11) /*!< GPIO pin 11 */ +#define GPIO_PIN_12 BIT(12) /*!< GPIO pin 12 */ +#define GPIO_PIN_13 BIT(13) /*!< GPIO pin 13 */ +#define GPIO_PIN_14 BIT(14) /*!< GPIO pin 14 */ +#define GPIO_PIN_15 BIT(15) /*!< GPIO pin 15 */ +#define GPIO_PIN_ALL BITS(0,15) /*!< GPIO pin all */ + +/* GPIO mode configuration values */ +#define GPIO_MODE_SET(n, mode) ((uint32_t)((uint32_t)(mode) << (2U * (n)))) +#define GPIO_MODE_MASK(n) (0x3U << (2U * (n))) + +/* GPIO pull-up/pull-down values */ +#define GPIO_PUPD_SET(n, pupd) ((uint32_t)((uint32_t)(pupd) << (2U * (n)))) +#define GPIO_PUPD_MASK(n) (0x3U << (2U * (n))) + +/* GPIO output speed values */ +#define GPIO_OSPEED_SET(n, speed) ((uint32_t)((uint32_t)(speed) << (2U * (n)))) +#define GPIO_OSPEED_MASK(n) (0x3U << (2U * (n))) + +/* GPIO output type */ +#define GPIO_OTYPE_PP ((uint8_t)(0x00U)) /*!< push pull mode */ +#define GPIO_OTYPE_OD ((uint8_t)(0x01U)) /*!< open drain mode */ + +/* GPIO output max speed value */ +#define OSPD_OSPD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_OSPEED_2MHZ OSPD_OSPD(0) /*!< output max speed 2M */ +#define GPIO_OSPEED_10MHZ OSPD_OSPD(1) /*!< output max speed 10M */ +#define GPIO_OSPEED_50MHZ OSPD_OSPD(3) /*!< output max speed 50M */ + +/* GPIO alternate function values */ +#define GPIO_AFR_SET(n, af) ((uint32_t)((uint32_t)(af) << (4U * (n)))) +#define GPIO_AFR_MASK(n) (0xFU << (4U * (n))) + +/* GPIO alternate function */ +#define AF(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define GPIO_AF_0 AF(0) /*!< alternate function selected 0 */ +#define GPIO_AF_1 AF(1) /*!< alternate function selected 1 */ +#define GPIO_AF_2 AF(2) /*!< alternate function selected 2 */ +#define GPIO_AF_3 AF(3) /*!< alternate function selected 3 */ +#define GPIO_AF_4 AF(4) /*!< alternate function selected 4 */ +#define GPIO_AF_5 AF(5) /*!< alternate function selected 5 */ +#define GPIO_AF_6 AF(6) /*!< alternate function selected 6 */ +#define GPIO_AF_7 AF(7) /*!< alternate function selected 7 */ +#define GPIO_AF_8 AF(8) /*!< alternate function selected 8 */ +#define GPIO_AF_9 AF(9) /*!< alternate function selected 9 */ +#define GPIO_AF_10 AF(10) /*!< alternate function selected 10 */ +#define GPIO_AF_11 AF(11) /*!< alternate function selected 11 */ + +/* 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); + +#ifdef GD32F170_190 + +/* 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 /* GD32F170_190 */ + +#endif /* GD32F1X0_GPIO_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_i2c.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_i2c.h new file mode 100644 index 0000000..909f6ad --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_i2c.h @@ -0,0 +1,341 @@ +/*! + \file gd32f1x0_i2c.h + \brief definitions for the I2C +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_I2C_H +#define GD32F1X0_I2C_H + +#include "gd32f1x0.h" + +/* I2Cx(x=0,1) definitions */ +#define I2C0 I2C_BASE /*!< I2C0 base address */ +#define I2C1 (I2C_BASE+0x400U) /*!< I2C1 base address */ +#ifdef GD32F170_190 +#define I2C2 (I2C_BASE+0x6C00U) /*!< I2C2 base address */ +#endif /* GD32F170_190 */ + +/* registers definitions */ +#define I2C_CTL0(i2cx) REG32((i2cx) + 0x00U) /*!< I2C control register 0 */ +#define I2C_CTL1(i2cx) REG32((i2cx) + 0x04U) /*!< I2C control register 1 */ +#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x08U) /*!< I2C slave address register 0*/ +#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0CU) /*!< I2C slave address register */ +#define I2C_DATA(i2cx) REG32((i2cx) + 0x10U) /*!< I2C transfer buffer register */ +#define I2C_STAT0(i2cx) REG32((i2cx) + 0x14U) /*!< I2C transfer status register 0 */ +#define I2C_STAT1(i2cx) REG32((i2cx) + 0x18U) /*!< I2C transfer status register */ +#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x1CU) /*!< I2C clock configure register */ +#define I2C_RT(i2cx) REG32((i2cx) + 0x20U) /*!< I2C rise time register */ +#ifdef GD32F170_190 +#define I2C_SAMCS(i2cx) REG32((i2cx) + 0x80U) /*!< I2C SAM control and status register */ +#endif /* GD32F170_190 */ + +/* bits definitions */ +/* I2Cx_CTL0 */ +#define I2C_CTL0_I2CEN BIT(0) /*!< peripheral enable */ +#define I2C_CTL0_SMBEN BIT(1) /*!< SMBus mode */ +#define I2C_CTL0_SMBSEL BIT(3) /*!< SMBus type */ +#define I2C_CTL0_ARPEN BIT(4) /*!< ARP enable */ +#define I2C_CTL0_PECEN BIT(5) /*!< PEC enable */ +#define I2C_CTL0_GCEN BIT(6) /*!< general call enable */ +#define I2C_CTL0_DISSTRC BIT(7) /*!< clock stretching disable (slave mode) */ +#define I2C_CTL0_START BIT(8) /*!< start generation */ +#define I2C_CTL0_STOP BIT(9) /*!< stop generation */ +#define I2C_CTL0_ACKEN BIT(10) /*!< acknowledge enable */ +#define I2C_CTL0_POAP BIT(11) /*!< acknowledge/PEC position (for data reception) */ +#define I2C_CTL0_PECTRANS BIT(12) /*!< packet error checking */ +#define I2C_CTL0_SALT BIT(13) /*!< SMBus alert */ +#define I2C_CTL0_SRESET BIT(15) /*!< software reset */ + +/* I2Cx_CTL1 */ +#define I2C_CTL1_I2CCLK BITS(0,5) /*!< I2CCLK[5:0] bits (peripheral clock frequency) */ +#define I2C_CTL1_ERRIE BIT(8) /*!< error interrupt inable */ +#define I2C_CTL1_EVIE BIT(9) /*!< event interrupt enable */ +#define I2C_CTL1_BUFIE BIT(10) /*!< buffer interrupt enable */ +#define I2C_CTL1_DMAON BIT(11) /*!< DMA requests enable */ +#define I2C_CTL1_DMALST BIT(12) /*!< DMA last transfer */ + +/* I2Cx_SADDR0 */ +#define I2C_SADDR0_ADDRESS0 BIT(0) /*!< bit 0 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS BITS(1,7) /*!< 7-bit address or bits 7:1 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS_H BITS(8,9) /*!< highest two bits of a 10-bit address */ +#define I2C_SADDR0_ADDFORMAT BIT(15) /*!< address mode for the I2C slave */ + +/* I2Cx_SADDR1 */ +#define I2C_SADDR1_DUADEN BIT(0) /*!< aual-address mode switch */ +#define I2C_SADDR1_ADDRESS2 BITS(1,7) /*!< second I2C address for the slave in dual-address mode */ + +/* I2Cx_DATA */ +#define I2C_DATA_TRB BITS(0,7) /*!< 8-bit data register */ + +/* I2Cx_STAT0 */ +#define I2C_STAT0_SBSEND BIT(0) /*!< start bit (master mode) */ +#define I2C_STAT0_ADDSEND BIT(1) /*!< address sent (master mode)/matched (slave mode) */ +#define I2C_STAT0_BTC BIT(2) /*!< byte transfer finished */ +#define I2C_STAT0_ADD10SEND BIT(3) /*!< 10-bit header sent (master mode) */ +#define I2C_STAT0_STPDET BIT(4) /*!< stop detection (slave mode) */ +#define I2C_STAT0_RBNE BIT(6) /*!< data register not empty (receivers) */ +#define I2C_STAT0_TBE BIT(7) /*!< data register empty (transmitters) */ +#define I2C_STAT0_BERR BIT(8) /*!< bus error */ +#define I2C_STAT0_LOSTARB BIT(9) /*!< arbitration lost (master mode) */ +#define I2C_STAT0_AERR BIT(10) /*!< acknowledge failure */ +#define I2C_STAT0_OUERR BIT(11) /*!< overrun/underrun */ +#define I2C_STAT0_PECERR BIT(12) /*!< PEC error in reception */ +#define I2C_STAT0_SMBTO BIT(14) /*!< timeout signal in SMBus mode */ +#define I2C_STAT0_SMBALT BIT(15) /*!< SMBus alert status */ + +/* I2Cx_STAT1 */ +#define I2C_STAT1_MASTER BIT(0) /*!< master/slave */ +#define I2C_STAT1_I2CBSY BIT(1) /*!< bus busy */ +#define I2C_STAT1_TRS BIT(2) /*!< transmitter/receiver */ +#define I2C_STAT1_RXGC BIT(4) /*!< general call address (slave mode) */ +#define I2C_STAT1_DEFSMB BIT(5) /*!< SMBus device default address (slave mode) */ +#define I2C_STAT1_HSTSMB BIT(6) /*!< SMBus host header (slave mode) */ +#define I2C_STAT1_DUMODF BIT(7) /*!< dual flag (slave mode) */ +#define I2C_STAT1_ECV BITS(8,15) /*!< packet error checking value */ + +/* I2Cx_CKCFG */ +#define I2C_CKCFG_CLKC BITS(0,11) /*!< clock control register in fast/standard mode (master mode) */ +#define I2C_CKCFG_DTCY BIT(14) /*!< fast mode duty cycle */ +#define I2C_CKCFG_FAST BIT(15) /*!< I2C speed selection in master mode */ + +/* I2Cx_RT */ +#define I2C_RT_RISETIME BITS(0,5) /*!< maximum rise time in fast/standard mode (Master mode) */ + +#ifdef GD32F170_190 +/* I2Cx_SAMCS */ +#define I2C_SAMCS_SAMEN BIT(0) /*!< SAM_V interface enable */ +#define I2C_SAMCS_STOEN BIT(1) /*!< SAM_V interface timeout detect enable */ +#define I2C_SAMCS_TFFIE BIT(4) /*!< txframe fall interrupt enable */ +#define I2C_SAMCS_TFRIE BIT(5) /*!< txframe rise interrupt enable */ +#define I2C_SAMCS_RFFIE BIT(6) /*!< rxframe fall interrupt enable */ +#define I2C_SAMCS_RFRIE BIT(7) /*!< rxframe rise interrupt enable */ +#define I2C_SAMCS_TXF BIT(8) /*!< level of txframe signal */ +#define I2C_SAMCS_RXF BIT(9) /*!< level of rxframe signal */ +#define I2C_SAMCS_TFF BIT(12) /*!< txframe fall flag, cleared by software write 0 */ +#define I2C_SAMCS_TFR BIT(13) /*!< txframe rise flag, cleared by software write 0 */ +#define I2C_SAMCS_RFF BIT(14) /*!< rxframe fall flag, cleared by software write 0 */ +#define I2C_SAMCS_RFR BIT(15) /*!< rxframe rise flag, cleared by software write 0 */ +#endif /* GD32F170_190 */ + +/* constants definitions */ +/* SMBus/I2C mode switch and SMBus type selection */ +#define I2C_I2CMODE_ENABLE ((uint32_t)0x00000000U) /*!< I2C mode */ +#define I2C_SMBUSMODE_ENABLE I2C_CTL0_SMBEN /*!< SMBus mode */ + +/* SMBus/I2C mode switch and SMBus type selection */ +#define I2C_SMBUS_DEVICE ((uint32_t)0x00000000U) /*!< SMBus mode device type */ +#define I2C_SMBUS_HOST I2C_CTL0_SMBSEL /*!< SMBus mode host type */ + +/* I2C transfer direction */ +#define I2C_RECEIVER ((uint32_t)0x00000001U) /*!< receiver */ +#define I2C_TRANSMITTER ((uint32_t)0xFFFFFFFEU) /*!< transmitter */ + +/* whether or not to send an ACK */ +#define I2C_ACK_DISABLE ((uint32_t)0x00000000U) /*!< ACK will be not sent */ +#define I2C_ACK_ENABLE ((uint32_t)0x00000001U) /*!< ACK will be sent */ + +/* I2C POAP position*/ +#define I2C_ACKPOS_NEXT ((uint32_t)0x00000000U) /*!< ACKEN bit decides whether or not to send ACK for the next byte */ +#define I2C_ACKPOS_CURRENT ((uint32_t)0x00000001U) /*!< ACKEN bit decides whether or not to send ACK or not for the current byte */ + +/* I2C dual-address mode switch */ +#define I2C_DUADEN_DISABLE ((uint32_t)0x00000000U) /*!< dual-address mode disabled */ +#define I2C_DUADEN_ENABLE ((uint32_t)0x00000001U) /*!< dual-address mode enabled */ + +/* whether or not to stretch SCL low */ +#define I2C_SCLSTRETCH_ENABLE ((uint32_t)0x00000000U) /*!< SCL stretching is enabled */ +#define I2C_SCLSTRETCH_DISABLE I2C_CTL0_DISSTRC /*!< SCL stretching is disabled */ + +/* whether or not to response to a general call */ +#define I2C_GCEN_ENABLE I2C_CTL0_GCEN /*!< slave will response to a general call */ +#define I2C_GCEN_DISABLE ((uint32_t)0x00000000U) /*!< slave will not response to a general call */ + +/* software reset I2C */ +#define I2C_SRESET_SET I2C_CTL0_SRESET /*!< I2C is under reset */ +#define I2C_SRESET_RESET ((uint32_t)0x00000000U) /*!< I2C is not under reset */ + +/* I2C DMA mode configure */ +/* DMA mode switch */ +#define I2C_DMA_ON I2C_CTL1_DMAON /*!< DMA mode enabled */ +#define I2C_DMA_OFF ((uint32_t)0x00000000U) /*!< DMA mode disabled */ + +/* flag indicating DMA last transfer */ +#define I2C_DMALST_ON I2C_CTL1_DMALST /*!< next DMA EOT is the last transfer */ +#define I2C_DMALST_OFF ((uint32_t)0x00000000U) /*!< next DMA EOT is not the last transfer */ + +/* I2C PEC configure */ +/* PEC enable */ +#define I2C_PEC_ENABLE I2C_CTL0_PECEN /*!< PEC calculation on */ +#define I2C_PEC_DISABLE ((uint32_t)0x00000000U) /*!< PEC calculation off */ + +/* PEC transfer */ +#define I2C_PECTRANS_ENABLE I2C_CTL0_PECTRANS /*!< transfer PEC */ +#define I2C_PECTRANS_DISABLE ((uint32_t)0x00000000U) /*!< not transfer PEC value */ + +/* I2C SMBus configure */ +/* issue or not alert through SMBA pin */ +#define I2C_SALTSEND_ENABLE I2C_CTL0_SALT /*!< issue alert through SMBA pin */ +#define I2C_SALTSEND_DISABLE ((uint32_t)0x00000000U) /*!< not issue alert through SMBA */ + +/* ARP protocol in SMBus switch */ +#define I2C_ARP_ENABLE I2C_CTL0_ARPEN /*!< ARP enable */ +#define I2C_ARP_DISABLE ((uint32_t)0x00000000U) /*!< ARP disable */ + +/* fast mode plus enable */ +#define I2C_FAST_MODE_PLUS_ENABLE I2C_FMPCFG_FMPEN /*!< fast mode plus enable */ +#define I2C_FAST_MODE_PLUS_DISABLE ((uint32_t)0x00000000U) /*!< fast mode plus disable */ + +/* transmit I2C data */ +#define DATA_TRANS(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* receive I2C data */ +#define DATA_RECV(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* I2C flag definitions */ +#define I2C_FLAG_SBSEND BIT(0) /*!< start condition sent out in master mode */ +#define I2C_FLAG_ADDSEND BIT(1) /*!< address is sent in master mode or received and matches in slave mode */ +#define I2C_FLAG_BTC BIT(2) /*!< byte transmission finishes */ +#define I2C_FLAG_ADD10SEND BIT(3) /*!< header of 10-bit address is sent in master mode */ +#define I2C_FLAG_STPDET BIT(4) /*!< etop condition detected in slave mode */ +#define I2C_FLAG_RBNE BIT(6) /*!< I2C_DATA is not Empty during receiving */ +#define I2C_FLAG_TBE BIT(7) /*!< I2C_DATA is empty during transmitting */ +#define I2C_FLAG_BERR BIT(8) /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */ +#define I2C_FLAG_LOSTARB BIT(9) /*!< arbitration lost in master mode */ +#define I2C_FLAG_AERR BIT(10) /*!< acknowledge error */ +#define I2C_FLAG_OUERR BIT(11) /*!< over-run or under-run situation occurs in slave mode */ +#define I2C_FLAG_PECERR BIT(12) /*!< PEC error when receiving data */ +#define I2C_FLAG_SMBTO BIT(14) /*!< timeout signal in SMBus mode */ +#define I2C_FLAG_SMBALT BIT(15) /*!< SMBus alert status */ +#define I2C_FLAG_MASTER (BIT(0)|BIT(31)) /*!< a flag indicating whether I2C block is in master or slave mode */ +#define I2C_FLAG_I2CBSY (BIT(1)|BIT(31)) /*!< busy flag */ +#define I2C_FLAG_TRS (BIT(2)|BIT(31)) /*!< whether the I2C is a transmitter or a receiver */ +#define I2C_FLAG_RXGC (BIT(4)|BIT(31)) /*!< general call address (00h) received */ +#define I2C_FLAG_DEFSMB (BIT(5)|BIT(31)) /*!< default address of SMBus device */ +#define I2C_FLAG_HSTSMB (BIT(6)|BIT(31)) /*!< SMBus host header detected in slave mode */ +#define I2C_FLAG_DUMOD (BIT(7)|BIT(31)) /*!< dual flag in slave mode indicating which address is matched in dual-address mode */ + +/* I2C interrupt flags */ +#define I2C_INT_FLAG_SBSEND I2C_FLAG_SBSEND /*!< start condition sent out in master mode interrupt flag */ +#define I2C_INT_FLAG_ADDSEND I2C_FLAG_ADDSEND /*!< address is sent in master mode or received and matches in slave mode interrupt flag */ +#define I2C_INT_FLAG_BTC I2C_FLAG_BTC /*!< byte transmission finishes */ +#define I2C_INT_FLAG_ADD10SEND I2C_FLAG_ADD10SEND /*!< header of 10-bit address is sent in master mode interrupt flag */ +#define I2C_INT_FLAG_STPDET I2C_FLAG_STPDET /*!< stop condition detected in slave mode interrupt flag */ +#define I2C_INT_FLAG_RBNE I2C_FLAG_RBNE /*!< I2C_DATA is not Empty during receiving interrupt flag */ +#define I2C_INT_FLAG_TBE I2C_FLAG_TBE /*!< I2C_DATA is empty during transmitting interrupt flag */ +#define I2C_INT_FLAG_BERR I2C_FLAG_BERR /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag */ +#define I2C_INT_FLAG_LOSTARB I2C_FLAG_LOSTARB /*!< arbitration lost in master mode interrupt flag */ +#define I2C_INT_FLAG_AERR I2C_FLAG_AERR /*!< acknowledge error interrupt flag */ +#define I2C_INT_FLAG_OUERR I2C_FLAG_OUERR /*!< over-run or under-run situation occurs in slave mode interrupt flag */ +#define I2C_INT_FLAG_PECERR I2C_FLAG_PECERR /*!< PEC error when receiving data interrupt flag */ +#define I2C_INT_FLAG_SMBTO I2C_FLAG_SMBTO /*!< timeout signal in SMBus mode interrupt flag */ +#define I2C_INT_FLAG_SMBALT I2C_FLAG_SMBALT /*!< SMBus Alert status interrupt flag */ + +/* I2C interrupt enable bit */ +#define I2C_INT_ERR I2C_CTL1_ERRIE /*!< error interrupt enable */ +#define I2C_INT_EV I2C_CTL1_EVIE /*!< event interrupt enable */ +#define I2C_INT_BUF I2C_CTL1_BUFIE /*!< buffer interrupt enable */ + +/* I2C duty cycle in fast mode */ +#define CKCFG_DTCY(regval) (BIT(14) & ((uint32_t)(regval) << 14)) +#define I2C_DTCY_2 CKCFG_DTCY(0) /*!< I2C fast mode Tlow/Thigh = 2 */ +#define I2C_DTCY_16_9 CKCFG_DTCY(1) /*!< I2C fast mode Tlow/Thigh = 16/9 */ + +/* address mode for the I2C slave */ +#define SADDR0_ADDFORMAT(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define I2C_ADDFORMAT_7BITS SADDR0_ADDFORMAT(0) /*!< address:7 bits */ +#define I2C_ADDFORMAT_10BITS SADDR0_ADDFORMAT(1) /*!< address:10 bits */ + +/* function declarations */ +/* reset I2C */ +void i2c_deinit(uint32_t i2c_periph); +/* configure I2C clock */ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc); +/* configure I2C address */ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr); +/* SMBus type selection */ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type); +/* whether or not to send an ACK */ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack); +/* configure I2C POAP position */ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos); +/* master send slave address */ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection); +/* dual-address mode switch */ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t dualaddr); + +/* enable I2C */ +void i2c_enable(uint32_t i2c_periph); +/* disable I2C */ +void i2c_disable(uint32_t i2c_periph); +/* generate a START condition on I2C bus */ +void i2c_start_on_bus(uint32_t i2c_periph); +/* generate a STOP condition on I2C bus */ +void i2c_stop_on_bus(uint32_t i2c_periph); +/* I2C transmit data function */ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data); +/* I2C receive data function */ +uint8_t i2c_data_receive(uint32_t i2c_periph); +/* I2C DMA mode enable */ +void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate); +/* flag indicating DMA last transfer */ +void i2c_dma_last_transfer_enable(uint32_t i2c_periph, uint32_t dmalast); +/* whether to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara ); +/* whether or not to response to a general call */ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara); +/* software reset I2C */ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset); + +/* check I2C flag is set or not */ +FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag); +/* clear I2C flag */ +void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag); +/* enable I2C interrupt */ +void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t inttype); +/* disable I2C interrupt */ +void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t inttype); +/* check I2C interrupt flag */ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph,uint32_t intflag); +/* clear I2C interrupt flag */ +void i2c_interrupt_flag_clear(uint32_t i2c_periph,uint32_t intflag); + +/* I2C PEC calculation on or off */ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate); +/* I2C whether to transfer PEC value */ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara); +/* packet error checking value */ +uint8_t i2c_pec_value_get(uint32_t i2c_periph); +/* I2C issue alert through SMBA pin */ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara); +/* I2C ARP protocol in SMBus switch */ +void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate); + +#ifdef GD32F170_190 +/* enable SAM_V interface */ +void i2c_sam_enable(uint32_t i2c_periph); +/* disable SAM_V interface */ +void i2c_sam_disable(uint32_t i2c_periph); +/* enable SAM_V interface timeout detect */ +void i2c_sam_timeout_enable(uint32_t i2c_periph); +/* disable SAM_V interface timeout detect */ +void i2c_sam_timeout_disable(uint32_t i2c_periph); +/* enable the specified I2C SAM interrupt */ +void i2c_sam_interrupt_enable(uint32_t i2c_periph, uint32_t inttype); +/* disable the specified I2C SAM interrupt */ +void i2c_sam_interrupt_disable(uint32_t i2c_periph, uint32_t inttype); +/* check i2c SAM state */ +FlagStatus i2c_sam_flag_get(uint32_t i2c_periph, uint32_t samstate); +/* clear i2c SAM state */ +void i2c_sam_flag_clear(uint32_t i2c_periph, uint32_t samstate); +#endif /*GD32F170_190*/ + +#endif /* GD32F1X0_I2C_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_ivref.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_ivref.h new file mode 100644 index 0000000..df4f146 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_ivref.h @@ -0,0 +1,217 @@ +/*! + \file gd32f1x0_ivref.h + \brief definitions for the IVREF +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 + +#ifndef GD32F1X0_IVREF_H +#define GD32F1X0_IVREF_H + +#include "gd32f1x0.h" + +/* IVREF definitions */ +#define IVREF IVREF_BASE + +/* registers definitions */ +#define IVREF_CTL REG32(IVREF + 0x300U) /*!< IVREF control register */ + +/* bits definitions */ +/* IVREF_CTL */ +#define IVREF_CTL_CSDT BITS(0,5) /*!< current step data */ +#define IVREF_CTL_SCMOD BIT(7) /*!< sink current mode */ +#define IVREF_CTL_CPT BITS(8,12) /*!< current precision trim */ +#define IVREF_CTL_SSEL BIT(14) /*!< step selection */ +#define IVREF_CTL_CREN BIT(15) /*!< current reference enable */ +#define IVREF_CTL_VPT BITS(24,28) /*!< voltage precision trim */ +#define IVREF_CTL_DECAP BIT(30) /*!< connect/disconnect external capacitor */ +#define IVREF_CTL_VREN BIT(31) /*!< voltage reference enable */ + +/* constants definitions */ +/* vref mode selection */ +#define VREF_DISCONNECT_EXTERNAL_CAP BIT(30) /*!< VREF disconnect external capacitor */ +#define VREF_CONNECT_EXTERNAL_CAP ((uint32_t)0x00000000) /*!< VREF connect external capacitor */ + +/* vref voltage precision trim */ +#define CTL_VPT(regval) (BITS(24,28) & ((regval) << 24)) +#define VREF_VOLT_PRECISION_TRIM_0 CTL_VPT(0) /*!< VREF voltage precision trim 0 */ +#define VREF_VOLT_PRECISION_TRIM_1 CTL_VPT(1) /*!< VREF voltage precision trim 1 */ +#define VREF_VOLT_PRECISION_TRIM_2 CTL_VPT(2) /*!< VREF voltage precision trim 2 */ +#define VREF_VOLT_PRECISION_TRIM_3 CTL_VPT(3) /*!< VREF voltage precision trim 3 */ +#define VREF_VOLT_PRECISION_TRIM_4 CTL_VPT(4) /*!< VREF voltage precision trim 4 */ +#define VREF_VOLT_PRECISION_TRIM_5 CTL_VPT(5) /*!< VREF voltage precision trim 5 */ +#define VREF_VOLT_PRECISION_TRIM_6 CTL_VPT(6) /*!< VREF voltage precision trim 6 */ +#define VREF_VOLT_PRECISION_TRIM_7 CTL_VPT(7) /*!< VREF voltage precision trim 7 */ +#define VREF_VOLT_PRECISION_TRIM_8 CTL_VPT(8) /*!< VREF voltage precision trim 8 */ +#define VREF_VOLT_PRECISION_TRIM_9 CTL_VPT(9) /*!< VREF voltage precision trim 9 */ +#define VREF_VOLT_PRECISION_TRIM_10 CTL_VPT(10) /*!< VREF voltage precision trim 10 */ +#define VREF_VOLT_PRECISION_TRIM_11 CTL_VPT(11) /*!< VREF voltage precision trim 11 */ +#define VREF_VOLT_PRECISION_TRIM_12 CTL_VPT(12) /*!< VREF voltage precision trim 12 */ +#define VREF_VOLT_PRECISION_TRIM_13 CTL_VPT(13) /*!< VREF voltage precision trim 13 */ +#define VREF_VOLT_PRECISION_TRIM_14 CTL_VPT(14) /*!< VREF voltage precision trim 14 */ +#define VREF_VOLT_PRECISION_TRIM_15 CTL_VPT(15) /*!< VREF voltage precision trim 15 */ +#define VREF_VOLT_PRECISION_TRIM_16 CTL_VPT(16) /*!< VREF voltage precision trim 16 */ +#define VREF_VOLT_PRECISION_TRIM_17 CTL_VPT(17) /*!< VREF voltage precision trim 17 */ +#define VREF_VOLT_PRECISION_TRIM_18 CTL_VPT(18) /*!< VREF voltage precision trim 18 */ +#define VREF_VOLT_PRECISION_TRIM_19 CTL_VPT(19) /*!< VREF voltage precision trim 19 */ +#define VREF_VOLT_PRECISION_TRIM_20 CTL_VPT(20) /*!< VREF voltage precision trim 20 */ +#define VREF_VOLT_PRECISION_TRIM_21 CTL_VPT(21) /*!< VREF voltage precision trim 21 */ +#define VREF_VOLT_PRECISION_TRIM_22 CTL_VPT(22) /*!< VREF voltage precision trim 22 */ +#define VREF_VOLT_PRECISION_TRIM_23 CTL_VPT(23) /*!< VREF voltage precision trim 23 */ +#define VREF_VOLT_PRECISION_TRIM_24 CTL_VPT(24) /*!< VREF voltage precision trim 24 */ +#define VREF_VOLT_PRECISION_TRIM_25 CTL_VPT(25) /*!< VREF voltage precision trim 25 */ +#define VREF_VOLT_PRECISION_TRIM_26 CTL_VPT(26) /*!< VREF voltage precision trim 26 */ +#define VREF_VOLT_PRECISION_TRIM_27 CTL_VPT(27) /*!< VREF voltage precision trim 27 */ +#define VREF_VOLT_PRECISION_TRIM_28 CTL_VPT(28) /*!< VREF voltage precision trim 28 */ +#define VREF_VOLT_PRECISION_TRIM_29 CTL_VPT(29) /*!< VREF voltage precision trim 29 */ +#define VREF_VOLT_PRECISION_TRIM_30 CTL_VPT(30) /*!< VREF voltage precision trim 30 */ +#define VREF_VOLT_PRECISION_TRIM_31 CTL_VPT(31) /*!< VREF voltage precision trim 31 */ + +/* iref current precision trim */ +#define CTL_CPT(regval) (BITS(8,12) & ((regval) << 8)) +#define IREF_CUR_PRECISION_TRIM_0 CTL_CPT(0) /*!< IREF current precision trim 0 */ +#define IREF_CUR_PRECISION_TRIM_1 CTL_CPT(1) /*!< IREF current precision trim 1 */ +#define IREF_CUR_PRECISION_TRIM_2 CTL_CPT(2) /*!< IREF current precision trim 2 */ +#define IREF_CUR_PRECISION_TRIM_3 CTL_CPT(3) /*!< IREF current precision trim 3 */ +#define IREF_CUR_PRECISION_TRIM_4 CTL_CPT(4) /*!< IREF current precision trim 4 */ +#define IREF_CUR_PRECISION_TRIM_5 CTL_CPT(5) /*!< IREF current precision trim 5 */ +#define IREF_CUR_PRECISION_TRIM_6 CTL_CPT(6) /*!< IREF current precision trim 6 */ +#define IREF_CUR_PRECISION_TRIM_7 CTL_CPT(7) /*!< IREF current precision trim 7 */ +#define IREF_CUR_PRECISION_TRIM_8 CTL_CPT(8) /*!< IREF current precision trim 8 */ +#define IREF_CUR_PRECISION_TRIM_9 CTL_CPT(9) /*!< IREF current precision trim 9 */ +#define IREF_CUR_PRECISION_TRIM_10 CTL_CPT(10) /*!< IREF current precision trim 10 */ +#define IREF_CUR_PRECISION_TRIM_11 CTL_CPT(11) /*!< IREF current precision trim 11 */ +#define IREF_CUR_PRECISION_TRIM_12 CTL_CPT(12) /*!< IREF current precision trim 12 */ +#define IREF_CUR_PRECISION_TRIM_13 CTL_CPT(13) /*!< IREF current precision trim 13 */ +#define IREF_CUR_PRECISION_TRIM_14 CTL_CPT(14) /*!< IREF current precision trim 14 */ +#define IREF_CUR_PRECISION_TRIM_15 CTL_CPT(15) /*!< IREF current precision trim 15 */ +#define IREF_CUR_PRECISION_TRIM_16 CTL_CPT(16) /*!< IREF current precision trim 16 */ +#define IREF_CUR_PRECISION_TRIM_17 CTL_CPT(17) /*!< IREF current precision trim 17 */ +#define IREF_CUR_PRECISION_TRIM_18 CTL_CPT(18) /*!< IREF current precision trim 18 */ +#define IREF_CUR_PRECISION_TRIM_19 CTL_CPT(19) /*!< IREF current precision trim 19 */ +#define IREF_CUR_PRECISION_TRIM_20 CTL_CPT(20) /*!< IREF current precision trim 20 */ +#define IREF_CUR_PRECISION_TRIM_21 CTL_CPT(21) /*!< IREF current precision trim 21 */ +#define IREF_CUR_PRECISION_TRIM_22 CTL_CPT(22) /*!< IREF current precision trim 22 */ +#define IREF_CUR_PRECISION_TRIM_23 CTL_CPT(23) /*!< IREF current precision trim 23 */ +#define IREF_CUR_PRECISION_TRIM_24 CTL_CPT(24) /*!< IREF current precision trim 24 */ +#define IREF_CUR_PRECISION_TRIM_25 CTL_CPT(25) /*!< IREF current precision trim 25 */ +#define IREF_CUR_PRECISION_TRIM_26 CTL_CPT(26) /*!< IREF current precision trim 26 */ +#define IREF_CUR_PRECISION_TRIM_27 CTL_CPT(27) /*!< IREF current precision trim 27 */ +#define IREF_CUR_PRECISION_TRIM_28 CTL_CPT(28) /*!< IREF current precision trim 28 */ +#define IREF_CUR_PRECISION_TRIM_29 CTL_CPT(29) /*!< IREF current precision trim 29 */ +#define IREF_CUR_PRECISION_TRIM_30 CTL_CPT(30) /*!< IREF current precision trim 30 */ +#define IREF_CUR_PRECISION_TRIM_31 CTL_CPT(31) /*!< IREF current precision trim 31 */ + +/* iref mode selection */ +#define IREF_MODE_LOW_POWER ((uint32_t)0x00000000) +#define IREF_MODE_HIGH_CURRENT BIT(14) + +/* iref current step */ +#define CTL_CSDA(regval) (BITS(0,5) & ((regval) << 5)) +#define IREF_CUR_STEP_DATA_0 CTL_CSDA(0) /*!< IREF current step data 0 */ +#define IREF_CUR_STEP_DATA_1 CTL_CSDA(1) /*!< IREF current step data 1 */ +#define IREF_CUR_STEP_DATA_2 CTL_CSDA(2) /*!< IREF current step data 2 */ +#define IREF_CUR_STEP_DATA_3 CTL_CSDA(3) /*!< IREF current step data 3 */ +#define IREF_CUR_STEP_DATA_4 CTL_CSDA(4) /*!< IREF current step data 4 */ +#define IREF_CUR_STEP_DATA_5 CTL_CSDA(5) /*!< IREF current step data 5 */ +#define IREF_CUR_STEP_DATA_6 CTL_CSDA(6) /*!< IREF current step data 6 */ +#define IREF_CUR_STEP_DATA_7 CTL_CSDA(7) /*!< IREF current step data 7 */ +#define IREF_CUR_STEP_DATA_8 CTL_CSDA(8) /*!< IREF current step data 8 */ +#define IREF_CUR_STEP_DATA_9 CTL_CSDA(9) /*!< IREF current step data 9 */ +#define IREF_CUR_STEP_DATA_10 CTL_CSDA(10) /*!< IREF current step data 10 */ +#define IREF_CUR_STEP_DATA_11 CTL_CSDA(11) /*!< IREF current step data 11 */ +#define IREF_CUR_STEP_DATA_12 CTL_CSDA(12) /*!< IREF current step data 12 */ +#define IREF_CUR_STEP_DATA_13 CTL_CSDA(13) /*!< IREF current step data 13 */ +#define IREF_CUR_STEP_DATA_14 CTL_CSDA(14) /*!< IREF current step data 14 */ +#define IREF_CUR_STEP_DATA_15 CTL_CSDA(15) /*!< IREF current step data 15 */ +#define IREF_CUR_STEP_DATA_16 CTL_CSDA(16) /*!< IREF current step data 16 */ +#define IREF_CUR_STEP_DATA_17 CTL_CSDA(17) /*!< IREF current step data 17 */ +#define IREF_CUR_STEP_DATA_18 CTL_CSDA(18) /*!< IREF current step data 18 */ +#define IREF_CUR_STEP_DATA_19 CTL_CSDA(19) /*!< IREF current step data 19 */ +#define IREF_CUR_STEP_DATA_20 CTL_CSDA(20) /*!< IREF current step data 20 */ +#define IREF_CUR_STEP_DATA_21 CTL_CSDA(21) /*!< IREF current step data 21 */ +#define IREF_CUR_STEP_DATA_22 CTL_CSDA(22) /*!< IREF current step data 22 */ +#define IREF_CUR_STEP_DATA_23 CTL_CSDA(23) /*!< IREF current step data 23 */ +#define IREF_CUR_STEP_DATA_24 CTL_CSDA(24) /*!< IREF current step data 24 */ +#define IREF_CUR_STEP_DATA_25 CTL_CSDA(25) /*!< IREF current step data 25 */ +#define IREF_CUR_STEP_DATA_26 CTL_CSDA(26) /*!< IREF current step data 26 */ +#define IREF_CUR_STEP_DATA_27 CTL_CSDA(27) /*!< IREF current step data 27 */ +#define IREF_CUR_STEP_DATA_28 CTL_CSDA(28) /*!< IREF current step data 28 */ +#define IREF_CUR_STEP_DATA_29 CTL_CSDA(29) /*!< IREF current step data 29 */ +#define IREF_CUR_STEP_DATA_30 CTL_CSDA(30) /*!< IREF current step data 30 */ +#define IREF_CUR_STEP_DATA_31 CTL_CSDA(31) /*!< IREF current step data 31 */ +#define IREF_CUR_STEP_DATA_32 CTL_CSDA(32) /*!< IREF current step data 32 */ +#define IREF_CUR_STEP_DATA_33 CTL_CSDA(33) /*!< IREF current step data 33 */ +#define IREF_CUR_STEP_DATA_34 CTL_CSDA(34) /*!< IREF current step data 34 */ +#define IREF_CUR_STEP_DATA_35 CTL_CSDA(35) /*!< IREF current step data 35 */ +#define IREF_CUR_STEP_DATA_36 CTL_CSDA(36) /*!< IREF current step data 36 */ +#define IREF_CUR_STEP_DATA_37 CTL_CSDA(37) /*!< IREF current step data 37 */ +#define IREF_CUR_STEP_DATA_38 CTL_CSDA(38) /*!< IREF current step data 38 */ +#define IREF_CUR_STEP_DATA_39 CTL_CSDA(39) /*!< IREF current step data 39 */ +#define IREF_CUR_STEP_DATA_40 CTL_CSDA(40) /*!< IREF current step data 40 */ +#define IREF_CUR_STEP_DATA_41 CTL_CSDA(41) /*!< IREF current step data 41 */ +#define IREF_CUR_STEP_DATA_42 CTL_CSDA(42) /*!< IREF current step data 42 */ +#define IREF_CUR_STEP_DATA_43 CTL_CSDA(43) /*!< IREF current step data 43 */ +#define IREF_CUR_STEP_DATA_44 CTL_CSDA(44) /*!< IREF current step data 44 */ +#define IREF_CUR_STEP_DATA_45 CTL_CSDA(45) /*!< IREF current step data 45 */ +#define IREF_CUR_STEP_DATA_46 CTL_CSDA(46) /*!< IREF current step data 46 */ +#define IREF_CUR_STEP_DATA_47 CTL_CSDA(47) /*!< IREF current step data 47 */ +#define IREF_CUR_STEP_DATA_48 CTL_CSDA(48) /*!< IREF current step data 48 */ +#define IREF_CUR_STEP_DATA_49 CTL_CSDA(49) /*!< IREF current step data 49 */ +#define IREF_CUR_STEP_DATA_50 CTL_CSDA(50) /*!< IREF current step data 50 */ +#define IREF_CUR_STEP_DATA_51 CTL_CSDA(51) /*!< IREF current step data 51 */ +#define IREF_CUR_STEP_DATA_52 CTL_CSDA(52) /*!< IREF current step data 52 */ +#define IREF_CUR_STEP_DATA_53 CTL_CSDA(53) /*!< IREF current step data 53 */ +#define IREF_CUR_STEP_DATA_54 CTL_CSDA(54) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_55 CTL_CSDA(55) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_56 CTL_CSDA(56) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_57 CTL_CSDA(57) /*!< IREF current step data 57 */ +#define IREF_CUR_STEP_DATA_58 CTL_CSDA(58) /*!< IREF current step data 58 */ +#define IREF_CUR_STEP_DATA_59 CTL_CSDA(59) /*!< IREF current step data 59 */ +#define IREF_CUR_STEP_DATA_60 CTL_CSDA(60) /*!< IREF current step data 60 */ +#define IREF_CUR_STEP_DATA_61 CTL_CSDA(61) /*!< IREF current step data 61 */ +#define IREF_CUR_STEP_DATA_62 CTL_CSDA(62) /*!< IREF current step data 62 */ +#define IREF_CUR_STEP_DATA_63 CTL_CSDA(63) /*!< IREF current step data 63 */ + +/* iref sink current mode*/ +#define IREF_SOURCE_CURRENT ((uint32_t)0x00000000) /*!< IREF source current */ +#define IREF_SINK_CURRENT BIT(7) /*!< IREF sink current */ + +/* function declarations */ + +/* deinit vref */ +void ivref_deinit(void); +/* enable vref */ +void vref_enable(void); +/* disable vref */ +void vref_disable(void); +/* enable vref */ +void iref_enable(void); +/* disable iref */ +void iref_disable(void); + +/* set verf mode */ +void vref_mode_set(uint32_t vrefmode); +/* set vrer voltage precision trim value */ +void vref_precision_trim_value_set(uint32_t precisiontrim); +/* set iref mode*/ +void iref_mode_set(uint32_t irefmode); +/* set iref sink current mode*/ +void iref_sink_set(uint32_t irefsinkmode); +/* set iref current precision trim value */ +void iref_precision_trim_value_set(uint32_t precisiontrim); +/* set iref step data*/ +void iref_step_data_config(uint32_t irefstepdata); + +#endif /* GD32F1X0_IVREF_H */ + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_misc.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_misc.h new file mode 100644 index 0000000..9983c14 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_misc.h @@ -0,0 +1,71 @@ +/*! + \file gd32f1x0_misc.h + \brief definitions for the MISC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_MISC_H +#define GD32F1X0_MISC_H + +#include "gd32f1x0.h" + +/* constants definitions */ +/* set the RAM and FLASH base address */ +#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000U) /*!< RAM base address */ +#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000U) /*!< Flash base address */ + +/* set the NVIC vector table offset mask */ +#define NVIC_VECTTAB_OFFSET_MASK ((uint32_t)0x1FFFFF80U) + +/* the register key mask, if you want to do the write operation, you should write 0x5FA to VECTKEY bits */ +#define NVIC_AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000U) + +/* priority group - define the pre-emption priority and the subpriority */ +#define NVIC_PRIGROUP_PRE0_SUB4 ((uint32_t)0x700U) /*!< 0 bits for pre-emption priority 4 bits for subpriority */ +#define NVIC_PRIGROUP_PRE1_SUB3 ((uint32_t)0x600U) /*!< 1 bits for pre-emption priority 3 bits for subpriority */ +#define NVIC_PRIGROUP_PRE2_SUB2 ((uint32_t)0x500U) /*!< 2 bits for pre-emption priority 2 bits for subpriority */ +#define NVIC_PRIGROUP_PRE3_SUB1 ((uint32_t)0x400U) /*!< 3 bits for pre-emption priority 1 bits for subpriority */ +#define NVIC_PRIGROUP_PRE4_SUB0 ((uint32_t)0x300U) /*!< 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)0x02U) /*!< choose the the system whether enter low power mode by exiting from ISR */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04U) /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10U) /*!< choose the interrupt source that can wake up the lowpower mode */ + +#define SCB_LPM_SLEEP_EXIT_ISR SCB_SCR_SLEEPONEXIT +#define SCB_LPM_DEEPSLEEP SCB_SCR_SLEEPDEEP +#define SCB_LPM_WAKE_BY_ALL_INT SCB_SCR_SEVONPEND + +/* choose the systick clock source */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from HCLK/8 */ +#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U) /*!< systick clock source is from HCLK */ + +/* function declarations */ +/* set the priority group */ +void nvic_priority_group_set(uint32_t nvic_prigroup); + +/* enable NVIC request */ +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority); +/* disable NVIC request */ +void nvic_irq_disable(uint8_t nvic_irq); + +/* set the NVIC vector table base address */ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset); + +/* set the state of the low power mode */ +void system_lowpower_set(uint8_t lowpower_mode); +/* reset the state of the low power mode */ +void system_lowpower_reset(uint8_t lowpower_mode); + +/* set the systick clock source */ +void systick_clksource_set(uint32_t systick_clksource); + +#endif /* GD32F1X0_MISC_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_opa.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_opa.h new file mode 100644 index 0000000..7b2fc1e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_opa.h @@ -0,0 +1,140 @@ +/*! + \file gd32f1x0_opa.h + \brief definitions for the OPA +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 + +#ifndef GD32F1X0_OPA_H +#define GD32F1X0_OPA_H + +#include "gd32f1x0.h" + +/* OPAx(x=0,1,2) definitions */ +#define OPA OPA_BASE +#define OPA0 ((uint32_t)0) +#define OPA1 ((uint32_t)1) +#define OPA2 ((uint32_t)2) + +/* registers definitions */ +#define OPA_CTL REG32(OPA + 0x00U) /*!< OPA control register */ +#define OPA_BT REG32(OPA + 0x04U) /*!< OPA bias trimming register for normal mode */ +#define OPA_LPBT REG32(OPA + 0x08U) /*!< OPA bias trimming register for low power mode */ + +/* bits definitions */ +/* OPA_CLT */ +#define OPA_CTL_OPA0PD BIT(0) /*!< OPA0 power down */ +#define OPA_CTL_T3OPA0 BIT(1) /*!< T3 switch enable for OPA0 */ +#define OPA_CTL_S1OPA0 BIT(2) /*!< S1 switch enable for OPA0 */ +#define OPA_CTL_S2OPA0 BIT(3) /*!< S2 switch enable for OPA0 */ +#define OPA_CTL_S3OPA0 BIT(4) /*!< S3 switch enable for OPA0 */ +#define OPA_CTL_OPA0CAL_L BIT(5) /*!< OPA1 offset calibration for P diff */ +#define OPA_CTL_OPA0CAL_H BIT(6) /*!< OPA1 offset calibration for N diff */ +#define OPA_CTL_OPA0LPM BIT(7) /*!< OPA0 low power mode */ +#define OPA_CTL_OPA1PD BIT(8) /*!< OPA1 power down */ +#define OPA_CTL_T3OPA1 BIT(9) /*!< T3 switch enable for OPA1 */ +#define OPA_CTL_S1OPA1 BIT(10) /*!< S1 switch enable for OPA1 */ +#define OPA_CTL_S2OPA1 BIT(11) /*!< S2 switch enable for OPA1 */ +#define OPA_CTL_S3OPA1 BIT(12) /*!< S3 switch enable for OPA1 */ +#define OPA_CTL_OPA1CAL_L BIT(13) /*!< OPA1 offset calibration for P diff */ +#define OPA_CTL_OPA1CAL_H BIT(14) /*!< OPA1 offset calibration for N diff */ +#define OPA_CTL_OPA1LPM BIT(15) /*!< OPA1 low power mode */ +#define OPA_CTL_OPA2PD BIT(16) /*!< OPA2 power down */ +#define OPA_CTL_T3OPA2 BIT(17) /*!< T3 switch enable for OPA2 */ +#define OPA_CTL_S1OPA2 BIT(18) /*!< S1 switch enable for OPA2 */ +#define OPA_CTL_S2OPA2 BIT(19) /*!< S2 switch enable for OPA2 */ +#define OPA_CTL_S3OPA2 BIT(20) /*!< S3 switch enable for OPA2 */ +#define OPA_CTL_OPA2CAL_L BIT(21) /*!< OPA2 offset calibration for P diff */ +#define OPA_CTL_OPA2CAL_H BIT(22) /*!< OPA2 offset calibration for N diff */ +#define OPA_CTL_OPA2LPM BIT(23) /*!< OPA2 low power mode */ +#define OPA_CTL_S4OPA1 BIT(27) /*!< S4 switch enable for OPA2 */ +#define OPA_CTL_OPA_RANGE BIT(28) /*!< Power supply range */ +#define OPA_CTL_OPA0CALOUT BIT(29) /*!< OPA0 calibration output */ +#define OPA_CTL_OPA1CALOUT BIT(30) /*!< OPA1 calibration output */ +#define OPA_CTL_OPA2CALOUT BIT(31) /*!< OPA2 calibration output */ + +/* OPA_BT */ +#define OPA_BT_OA0_TRIM_LOW BITS(0,4) /*!< OPA0, normal mode 5-bit bias trim value for PMOS pairs */ +#define OPA_BT_OA0_TRIM_HIGH BITS(5,9) /*!< OPA0, normal mode 5-bit bias trim value for NMOS pairs */ +#define OPA_BT_OA1_TRIM_LOW BITS(10,14) /*!< OPA1, normal mode 5-bit bias trim value for PMOS pairs */ +#define OPA_BT_OA1_TRIM_HIGH BITS(15,19) /*!< OPA1, normal mode 5-bit bias trim value for NMOS pairs */ +#define OPA_BT_OA2_TRIM_LOW BITS(20,24) /*!< OPA2, normal mode 5-bit bias trim value for PMOS pairs*/ +#define OPA_BT_OA2_TRIM_HIGH BITS(25,29) /*!< OPA2, normal mode 5-bit bias trim value for NMOS pairs */ +#define OPA_BT_OT_USER BIT(31) /*!< OPA trimming mode */ + +/* OPA_LPBT */ +#define OPA_LPBT_OA0_TRIM_LOW BITS(0,4) /*!< OPA0, low-power mode 5-bit bias trim value for PMOS pairs */ +#define OPA_LPBT_OA0_TRIM_HIGH BITS(5,9) /*!< OPA0, low-power mode 5-bit bias trim value for NMOS pairs */ +#define OPA_LPBT_OA1_TRIM_LOW BITS(10,14) /*!< OPA1, low-power mode 5-bit bias trim value for PMOS pairs */ +#define OPA_LPBT_OA1_TRIM_HIGH BITS(15,19) /*!< OPA1, low-power mode 5-bit bias trim value for NMOS pairs */ +#define OPA_LPBT_OA2_TRIM_LOW BITS(20,24) /*!< OPA2, low-power mode 5-bit bias trim value for PMOS pairs */ +#define OPA_LPBT_OA2_TRIM_HIGH BITS(25,29) /*!< OPA2, low-power mode 5-bit bias trim value for NMOS pairs */ + +/* constants definitions */ +/* opa switch definitions */ +#define OPA_T3OPA0 OPA_CTL_T3OPA0 /*!< T3 switch enable for OPA0 */ +#define OPA_S1OPA0 OPA_CTL_S1OPA0 /*!< S1 switch enable for OPA0 */ +#define OPA_S2OPA0 OPA_CTL_S2OPA0 /*!< S2 switch enable for OPA0 */ +#define OPA_S3OPA0 OPA_CTL_S3OPA0 /*!< S3 switch enable for OPA0 */ +#define OPA_T3OPA1 OPA_CTL_S3OPA1 /*!< T3 switch enable for OPA1 */ +#define OPA_S1OPA1 OPA_CTL_S1OPA1 /*!< S1 switch enable for OPA1 */ +#define OPA_S2OPA1 OPA_CTL_S2OPA1 /*!< S2 switch enable for OPA1 */ +#define OPA_S3OPA1 OPA_CTL_S3OPA1 /*!< S3 switch enable for OPA1 */ +#define OPA_S4OPA1 OPA_CTL_S4OPA1 /*!< S4 switch enable for OPA1 */ +#define OPA_T3OPA2 OPA_CTL_T3OPA2 /*!< T3 switch enable for OPA2 */ +#define OPA_S1OPA2 OPA_CTL_S1OPA2 /*!< S1 switch enable for OPA2 */ +#define OPA_S2OPA2 OPA_CTL_S2OPA2 /*!< S2 switch enable for OPA2 */ +#define OPA_S3OPA2 OPA_CTL_S3OPA2 /*!< S3 switch enable for OPA2 */ + +/* opa trimming mode */ +#define OPA_BT_TRIM_FACTORY ((uint32_t)0x00000000) /*!< factory trimming */ +#define OPA_BT_TRIM_USER OPA_BT_OT_USER /*!< user trimming */ + +/* opa input */ +#define OPA_INPUT_N ((uint32_t)0x00000040) /*!< NMOS input */ +#define OPA_INPUT_P ((uint32_t)0x00000020) /*!< PMOS input */ + +/* opa power range */ +#define OPA_POWRANGE_LOW ((uint32_t)0x00000000) /*!< low power range is selected (VDDA is lower than 3.3V) */ +#define OPA_POWRANGE_HIGH OPA_CTL_OPA_RANGE /*!< high power range is selected (VDDA is higher than 3.3V) */ + +/* function declarations */ + +/* deinit opa */ +void opa_deinit(void); +/* enable opa */ +void opa_enable(uint32_t opa_periph); +/* disable opa */ +void opa_disable(uint32_t opa_periph); +/* enable opa switch */ +void opa_switch_enable(uint32_t opax_swy); +/* disable opa switch */ +void opa_switch_disable(uint32_t opax_swy); +/* enable opa low_power mode */ +void opa_low_power_enable(uint32_t opa_periph); +/* dis opa low_power mode */ +void opa_low_power_disable(uint32_t opa_periph); +/* set opa power range */ +void opa_power_range_config(uint32_t powerrange); +/* set opa bias trimming mode */ +void opa_trim_mode_set(uint32_t opa_trimmode); + +/* set opa bias trimming value normal mode */ +void opa_trim_value_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue); +/* set opa bias trimming value low power mode */ +void opa_trim_value_lp_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue); +/* get opa calibration flag */ +FlagStatus opa_cal_out_get(uint32_t opa_periph); + +#endif /* GD32F1X0_OPA_H */ + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_pmu.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_pmu.h new file mode 100644 index 0000000..86fa4f0 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_pmu.h @@ -0,0 +1,108 @@ +/*! + \file gd32f1x0_pmu.h + \brief definitions for the PMU +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_PMU_H +#define GD32F1X0_PMU_H + +#include "gd32f1x0.h" + +/* PMU definitions */ +#define PMU PMU_BASE + +/* registers definitions */ +#define PMU_CTL REG32((PMU) + 0x00U) /*!< PMU control register */ +#define PMU_CS REG32((PMU) + 0x04U) /*!< PMU control and status register */ + +/* bits definitions */ +/* PMU_CTL */ +#define PMU_CTL_LDOLP BIT(0) /*!< ldo low power mode */ +#define PMU_CTL_STBMOD BIT(1) /*!< standby mode */ +#define PMU_CTL_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL_LVDEN BIT(4) /*!< low voltage detector enable */ +#define PMU_CTL_LVDT BITS(5,7) /*!< low voltage detector threshold */ +#define PMU_CTL_BKPWEN BIT(8) /*!< backup domain write enable */ + +/* PMU_CS */ +#define PMU_CS_WUF BIT(0) /*!< wakeup flag */ +#define PMU_CS_STBF BIT(1) /*!< standby flag */ +#define PMU_CS_LVDF BIT(2) /*!< low voltage detector status flag */ +#define PMU_CS_WUPEN0 BIT(8) /*!< wakeup pin 0 enable */ +#define PMU_CS_WUPEN1 BIT(9) /*!< wakeup pin 1 enable */ + +/* constants definitions */ +/* PMU low voltage detector threshold definitions */ +#define CTL_LVDT(regval) (BITS(5,7)&((uint32_t)(regval) << 5)) +#define PMU_LVDT_0 CTL_LVDT(0) /*!< voltage threshold is 2.2V */ +#define PMU_LVDT_1 CTL_LVDT(1) /*!< voltage threshold is 2.3V */ +#define PMU_LVDT_2 CTL_LVDT(2) /*!< voltage threshold is 2.4V */ +#define PMU_LVDT_3 CTL_LVDT(3) /*!< voltage threshold is 2.5V */ +#define PMU_LVDT_4 CTL_LVDT(4) /*!< voltage threshold is 2.6V */ +#define PMU_LVDT_5 CTL_LVDT(5) /*!< voltage threshold is 2.7V */ +#define PMU_LVDT_6 CTL_LVDT(6) /*!< voltage threshold is 2.8V */ +#define PMU_LVDT_7 CTL_LVDT(7) /*!< voltage threshold is 2.9V */ + +/* 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 */ + +/* PMU ldo definitions */ +#define PMU_LDO_NORMAL ((uint32_t)0x00000000) /*!< LDO normal work when pmu enter deepsleep mode */ +#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when pmu enter deepsleep mode */ + +/* PMU flag reset definitions */ +#define PMU_FLAG_RESET_WAKEUP ((uint8_t)0x00) /*!< wakeup flag reset */ +#define PMU_FLAG_RESET_STANDBY ((uint8_t)0x01) /*!< standby flag reset */ + +/* PMU command constants definitions */ +#define WFI_CMD ((uint8_t)0x00) /*!< use WFI command */ +#define WFE_CMD ((uint8_t)0x01) /*!< use WFE command */ + +/* PMU wakeup pin definitions */ +#define PMU_WAKEUP_PIN0 PMU_CS_WUPEN0 /*!< wakeup pin 0 */ +#define PMU_WAKEUP_PIN1 PMU_CS_WUPEN1 /*!< wakeup pin 1 */ + +/* function declarations */ + +/* PMU reset */ +void pmu_deinit(void); +/* select low voltage detector threshold */ +void pmu_lvd_select(uint32_t lvdt_n); +/* PMU lvd disable */ +void pmu_lvd_disable(void); + +/* PMU work at sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* PMU work at deepsleep mode */ +void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd); +/* PMU work at standby mode */ +void pmu_to_standbymode(uint8_t standbymodecmd); + +/* reset flag bit */ +void pmu_flag_clear(uint32_t flag_reset); +/* get flag state */ +FlagStatus pmu_flag_get(uint32_t flag); + +/* PMU backup domain write enable */ +void pmu_backup_write_enable(void); +/* PMU backup domain write disable */ +void pmu_backup_write_disable(void); + +/* wakeup pin enable */ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin); +/* wakeup pin disable */ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin); + +#endif /* GD32F1X0_PMU_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_rcu.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_rcu.h new file mode 100644 index 0000000..9396151 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_rcu.h @@ -0,0 +1,972 @@ +/*! + \file gd32f1x0_rcu.h + \brief definitions for the RCU +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_RCU_H +#define GD32F1X0_RCU_H + +#include "gd32f1x0.h" + +/* RCU definitions */ +#define RCU RCU_BASE + +/* registers definitions */ +#define RCU_CTL0 REG32(RCU + 0x00U) /*!< control register 0 */ +#define RCU_CFG0 REG32(RCU + 0x04U) /*!< configuration register 0 */ +#define RCU_INT REG32(RCU + 0x08U) /*!< interrupt register */ +#define RCU_APB2RST REG32(RCU + 0x0CU) /*!< APB2 reset register */ +#define RCU_APB1RST REG32(RCU + 0x10U) /*!< APB1 reset register */ +#define RCU_AHBEN REG32(RCU + 0x14U) /*!< AHB enable register */ +#define RCU_APB2EN REG32(RCU + 0x18U) /*!< APB2 enable register */ +#define RCU_APB1EN REG32(RCU + 0x1CU) /*!< APB1 enable register */ +#define RCU_BDCTL REG32(RCU + 0x20U) /*!< backup domain control register */ +#define RCU_RSTSCK REG32(RCU + 0x24U) /*!< reset source /clock register */ +#define RCU_AHBRST REG32(RCU + 0x28U) /*!< AHB reset register */ +#define RCU_CFG1 REG32(RCU + 0x2CU) /*!< configuration register 1 */ +#define RCU_CFG2 REG32(RCU + 0x30U) /*!< configuration register 2 */ +#define RCU_CTL1 REG32(RCU + 0x34U) /*!< control register 1 */ +#ifdef GD32F170_190 +#define RCU_CFG3 REG32(RCU + 0x80U) /*!< configuration register 3 */ +#endif /* GD32F170_190 */ +#define RCU_ADDAPB1EN REG32(RCU + 0xF8U) /*!< APB1 additional enable register */ +#define RCU_ADDAPB1RST REG32(RCU + 0xFCU) /*!< APB1 additional reset register */ +#define RCU_VKEY REG32(RCU + 0x100U) /*!< voltage key register */ +#define RCU_DSV REG32(RCU + 0x134U) /*!< deep-sleep mode voltage register */ +#ifdef GD32F130_150 +#define RCU_PDVSEL REG32(RCU + 0x138U) /*!< power down voltage select register */ +#endif /* GD32F130_150 */ + +/* bits definitions */ +/* RCU_CTL0 */ +#define RCU_CTL0_IRC8MEN BIT(0) /*!< internal high speed oscillator enable */ +#define RCU_CTL0_IRC8MSTB BIT(1) /*!< IRC8M high speed internal oscillator stabilization flag */ +#define RCU_CTL0_IRC8MADJ BITS(3,7) /*!< high speed internal oscillator clock trim adjust value */ +#define RCU_CTL0_IRC8MCALIB BITS(8,15) /*!< high speed internal oscillator calibration value register */ +#define RCU_CTL0_HXTALEN BIT(16) /*!< external high speed oscillator enable */ +#define RCU_CTL0_HXTALSTB BIT(17) /*!< external crystal oscillator clock stabilization flag */ +#define RCU_CTL0_HXTALBPS BIT(18) /*!< external crystal oscillator clock bypass mode enable */ +#define RCU_CTL0_CKMEN BIT(19) /*!< HXTAL clock monitor enable */ +#define RCU_CTL0_PLLEN BIT(24) /*!< PLL enable */ +#define RCU_CTL0_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_ADCPSC BITS(14,15) /*!< ADC clock prescaler selection */ +#define RCU_CFG0_PLLSEL BIT(16) /*!< PLL clock source selection */ +#define RCU_CFG0_PLLPREDV BIT(17) /*!< HXTAL divider for PLL source clock selection */ +#define RCU_CFG0_PLLMF (BIT(27) | BITS(18,21)) /*!< PLL multiply factor */ +#ifdef GD32F130_150 +#define RCU_CFG0_USBDPSC BITS(22,23) /*!< USBD clock prescaler selection */ +#define RCU_CFG0_CKOUTSEL BITS(24,26) /*!< CK_OUT clock source selection */ +#elif defined (GD32F170_190) +#define RCU_CFG0_CKOUT0SEL BITS(24,26) /*!< CK_OUT0 clock source selection */ +#endif /* GD32F130_150 */ +#define RCU_CFG0_PLLMF4 BIT(27) /*!< bit 4 of PLLMF */ +#ifdef GD32F130_150 +#define RCU_CFG0_CKOUTDIV BITS(28,30) /*!< CK_OUT divider which the CK_OUT frequency can be reduced */ +#elif defined (GD32F170_190) +#define RCU_CFG0_CKOUT0DIV BITS(28,30) /*!< CK_OUT0 divider which the CK_OUT0 frequency can be reduced */ +#endif /* GD32F130_150 */ +#define RCU_CFG0_PLLDV BIT(31) /*!< CK_PLL divide by 1 or 2 for CK_OUT(GD32F130_150) or CK_OUT0(GD32F170_190) */ + +/* 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 */ +#ifdef GD32F130_150 +#define RCU_INT_IRC14MSTBIF BIT(5) /*!< IRC14M stabilization interrupt flag */ +#elif defined (GD32F170_190) +#define RCU_INT_IRC28MSTBIF BIT(5) /*!< IRC28M stabilization interrupt flag */ +#endif /* GD32F130_150 */ +#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 */ +#ifdef GD32F130_150 +#define RCU_INT_IRC14MSTBIE BIT(13) /*!< IRC14M stabilization interrupt enable */ +#elif defined (GD32F170_190) +#define RCU_INT_IRC28MSTBIE BIT(13) /*!< IRC28M stabilization interrupt enable */ +#endif /* GD32F130_150 */ +#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 */ +#ifdef GD32F130_150 +#define RCU_INT_IRC14MSTBIC BIT(21) /*!< IRC14M stabilization interrupt clear */ +#elif defined (GD32F170_190) +#define RCU_INT_IRC28MSTBIC BIT(21) /*!< IRC28M stabilization interrupt clear */ +#endif /* GD32F130_150 */ +#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_ADCRST BIT(9) /*!< ADC reset */ +#define RCU_APB2RST_TIMER0RST BIT(11) /*!< TIMER0 reset */ +#define RCU_APB2RST_SPI0RST BIT(12) /*!< SPI0 reset */ +#define RCU_APB2RST_USART0RST BIT(14) /*!< USART0 reset */ +#define RCU_APB2RST_TIMER14RST BIT(16) /*!< TIMER14 reset */ +#define RCU_APB2RST_TIMER15RST BIT(17) /*!< TIMER15 reset */ +#define RCU_APB2RST_TIMER16RST BIT(18) /*!< TIMER16 reset */ + +/* RCU_APB1RST */ +#define RCU_APB1RST_TIMER1RST BIT(0) /*!< TIMER1 timer reset */ +#define RCU_APB1RST_TIMER2RST BIT(1) /*!< TIMER2 timer reset */ +#define RCU_APB1RST_TIMER5RST BIT(4) /*!< TIMER5 timer reset */ +#define RCU_APB1RST_TIMER13RST BIT(8) /*!< TIMER13 timer reset */ +#ifdef GD32F170_190 +#define RCU_APB1RST_SLCDRST BIT(9) /*!< SLCD reset */ +#endif /* GD32F170_190 */ +#define RCU_APB1RST_WWDGTRST BIT(11) /*!< window watchdog timer reset */ +#define RCU_APB1RST_SPI1RST BIT(14) /*!< SPI1 reset */ +#define RCU_APB1RST_SPI2RST BIT(15) /*!< SPI2 reset */ +#define RCU_APB1RST_USART1RST BIT(17) /*!< USART1 reset */ +#define RCU_APB1RST_I2C0RST BIT(21) /*!< I2C0 reset */ +#define RCU_APB1RST_I2C1RST BIT(22) /*!< I2C1 reset */ +#ifdef GD32F130_150 +#define RCU_APB1RST_USBDRST BIT(23) /*!< USBD reset */ +#endif /* GD32F130_150 */ +#ifdef GD32F170_190 +#define RCU_APB1RST_CAN0RST BIT(25) /*!< CAN0 reset */ +#define RCU_APB1RST_CAN1RST BIT(26) /*!< CAN1 reset */ +#endif /* GD32F170_190 */ +#define RCU_APB1RST_PMURST BIT(28) /*!< power control reset */ +#define RCU_APB1RST_DACRST BIT(29) /*!< DAC reset */ +#define RCU_APB1RST_CECRST BIT(30) /*!< HDMI CEC reset */ +#ifdef GD32F170_190 +#define RCU_APB1RST_OPAIVREFRST BIT(31) /*!< OPA and IVREF reset */ +#endif /* GD32F170_190 */ + +/* RCU_AHBEN */ +#define RCU_AHBEN_DMAEN BIT(0) /*!< DMA clock enable */ +#define RCU_AHBEN_SRAMSPEN BIT(2) /*!< SRAM interface clock enable */ +#define RCU_AHBEN_FMCSPEN BIT(4) /*!< FMC clock enable */ +#define RCU_AHBEN_CRCEN BIT(6) /*!< CRC clock enable */ +#define RCU_AHBEN_PAEN BIT(17) /*!< GPIO port A clock enable */ +#define RCU_AHBEN_PBEN BIT(18) /*!< GPIO port B clock enable */ +#define RCU_AHBEN_PCEN BIT(19) /*!< GPIO port C clock enable */ +#define RCU_AHBEN_PDEN BIT(20) /*!< GPIO port D clock enable */ +#define RCU_AHBEN_PFEN BIT(22) /*!< GPIO port F clock enable */ +#define RCU_AHBEN_TSIEN BIT(24) /*!< TSI clock enable */ + +/* RCU_APB2EN */ +#define RCU_APB2EN_CFGCMPEN BIT(0) /*!< system configuration and comparator clock enable */ +#define RCU_APB2EN_ADCEN BIT(9) /*!< ADC interface clock enable */ +#define RCU_APB2EN_TIMER0EN BIT(11) /*!< TIMER0 timer clock enable */ +#define RCU_APB2EN_SPI0EN BIT(12) /*!< SPI0 clock enable */ +#define RCU_APB2EN_USART0EN BIT(14) /*!< USART0 clock enable */ +#define RCU_APB2EN_TIMER14EN BIT(16) /*!< TIMER14 timer clock enable */ +#define RCU_APB2EN_TIMER15EN BIT(17) /*!< TIMER15 timer clock enable */ +#define RCU_APB2EN_TIMER16EN BIT(18) /*!< TIMER16 timer clock enable */ + +/* RCU_APB1EN */ +#define RCU_APB1EN_TIMER1EN BIT(0) /*!< TIMER1 timer clock enable */ +#define RCU_APB1EN_TIMER2EN BIT(1) /*!< TIMER2 timer clock enable */ +#define RCU_APB1EN_TIMER5EN BIT(4) /*!< TIMER5 timer clock enable */ +#define RCU_APB1EN_TIMER13EN BIT(8) /*!< TIMER13 timer clock enable */ +#ifdef GD32F170_190 +#define RCU_APB1EN_SLCDEN BIT(9) /*!< SLCD clock enable */ +#endif /* GD32F170_190 */ +#define RCU_APB1EN_WWDGTEN BIT(11) /*!< window watchdog timer clock enable */ +#define RCU_APB1EN_SPI1EN BIT(14) /*!< SPI1 clock enable */ +#define RCU_APB1EN_SPI2EN BIT(15) /*!< SPI2 clock enable */ +#define RCU_APB1EN_USART1EN BIT(17) /*!< USART1 clock enable */ +#define RCU_APB1EN_I2C0EN BIT(21) /*!< I2C0 clock enable */ +#define RCU_APB1EN_I2C1EN BIT(22) /*!< I2C1 clock enable */ +#ifdef GD32F130_150 +#define RCU_APB1EN_USBDEN BIT(23) /*!< USBD clock enable */ +#endif /* GD32F130_150 */ +#ifdef GD32F170_190 +#define RCU_APB1EN_CAN0EN BIT(25) /*!< CAN0 clock enable */ +#define RCU_APB1EN_CAN1EN BIT(26) /*!< CAN1 clock enable */ +#endif /* GD32F170_190 */ +#define RCU_APB1EN_PMUEN BIT(28) /*!< power interface clock enable */ +#define RCU_APB1EN_DACEN BIT(29) /*!< DAC interface clock enable */ +#define RCU_APB1EN_CECEN BIT(30) /*!< HDMI CEC interface clock enable */ +#ifdef GD32F170_190 +#define RCU_APB1EN_OPAIVREFEN BIT(31) /*!< OPA and IVREF clock enable */ +#endif /* GD32F170_190 */ + +/* RCU_BDCTL */ +#define RCU_BDCTL_LXTALEN BIT(0) /*!< LXTAL enable */ +#define RCU_BDCTL_LXTALSTB BIT(1) /*!< external low-speed oscillator stabilization */ +#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 */ +#define RCU_RSTSCK_V12RSTF BIT(23) /*!< V12 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_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_PFRST BIT(22) /*!< GPIO port F reset */ +#define RCU_AHBRST_TSIRST BIT(24) /*!< TSI unit reset */ + +/* RCU_CFG1 */ +#define RCU_CFG1_HXTALPREDV BITS(0,3) /*!< CK_HXTAL divider previous PLL */ + +/* RCU_CFG2 */ +#define RCU_CFG2_USART0SEL BITS(0,1) /*!< CK_USART0 clock source selection */ +#define RCU_CFG2_CECSEL BIT(6) /*!< CK_CEC clock source selection */ +#define RCU_CFG2_ADCSEL BIT(8) /*!< CK_ADC clock source selection */ +#ifdef GD32F170_190 +#define RCU_CFG2_IRC28MDIV BIT(16) /*!< CK_IRC28M divider 2 or not */ +#endif /* GD32F170_190 */ + +/* RCU_CTL1 */ +#ifdef GD32F130_150 +#define RCU_CTL1_IRC14MEN BIT(0) /*!< IRC14M internal 14M RC oscillator enable */ +#define RCU_CTL1_IRC14MSTB BIT(1) /*!< IRC14M internal 14M RC oscillator stabilization flag */ +#define RCU_CTL1_IRC14MADJ BITS(3,7) /*!< internal 14M RC oscillator clock trim adjust value */ +#define RCU_CTL1_IRC14MCALIB BITS(8,15) /*!< internal 14M RC oscillator calibration value register */ +#elif defined (GD32F170_190) +#define RCU_CTL1_IRC28MEN BIT(0) /*!< IRC28M internal 28M RC oscillator enable */ +#define RCU_CTL1_IRC28MSTB BIT(1) /*!< IRC28M internal 28M RC oscillator stabilization flag */ +#define RCU_CTL1_IRC28MADJ BITS(3,7) /*!< internal 28M RC oscillator clock trim adjust value */ +#define RCU_CTL1_IRC28MCALIB BITS(8,15) /*!< internal 28M RC oscillator calibration value register */ +#endif /* GD32F130_150 */ + +#ifdef GD32F170_190 +/* RCU_CFG3 */ +#define RCU_CFG3_CKOUT1SRC BITS(0,2) /*!< CKOUT1 clock source selection */ +#define RCU_CFG3_CKOUT1DIV BITS(8,13) /*!< CK_OUT1 divider which the CK_OUT1 frequency can be reduced */ +#endif /* GD32F170_190 */ + +/* RCU_ADDAPB1EN */ +#define RCU_ADDAPB1EN_I2C2EN BIT(0) /*!< I2C2 unit clock enable */ + +/* RCU_ADDAPB1RST */ +#define RCU_ADDAPB1RST_I2C2RST BIT(0) /*!< I2C2 unit reset */ + +/* RCU_VKEY */ +#define RCU_VKEY_KEY BITS(0,31) /*!< key of RCU_PDVSEL and RCU_DSV register */ + +/* RCU_DSV */ +#define RCU_DSV_DSLPVS BITS(0,2) /*!< deep-sleep mode voltage select */ + +#ifdef GD32F130_150 +/* RCU_PDVSEL */ +#define RCU_PDVSEL_PDRVS BIT(0) /*!< power down voltage select */ +#endif /* GD32F130_150 */ + +/* constants definitions */ +/* define the peripheral clock enable bit position and its register index offset */ +#define RCU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (bitpos)) +#define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph) >> 6))) +#define RCU_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +/* define the voltage key unlock value */ +#define RCU_VKEY_UNLOCK ((uint32_t)0x1A2B3C4DU) + +/* register index */ +enum reg_idx +{ + /* peripherals enable */ + IDX_AHBEN = 0x14U, + IDX_APB2EN = 0x18U, + IDX_APB1EN = 0x1CU, + IDX_ADDAPB1EN = 0xF8U, + /* peripherals reset */ + IDX_AHBRST = 0x28U, + IDX_APB2RST = 0x0CU, + IDX_APB1RST = 0x10U, + IDX_ADDAPB1RST = 0xFCU, + /* clock stabilization */ + IDX_CTL0 = 0x00U, + IDX_BDCTL = 0x20U, + IDX_STB = 0x24U, + IDX_CTL1 = 0x34U, + /* peripheral reset */ + IDX_RSTSCK = 0x24U, + /* clock stabilization and stuck interrupt */ + IDX_INT = 0x08U, + /* configuration register */ + IDX_CFG0 = 0x04U, + IDX_CFG2 = 0x30U +}; + +/* peripheral clock enable */ +typedef enum +{ + /* AHB peripherals */ + RCU_DMA = RCU_REGIDX_BIT(IDX_AHBEN, 0U), /*!< DMA clock */ + RCU_CRC = RCU_REGIDX_BIT(IDX_AHBEN, 6U), /*!< CRC clock */ + RCU_GPIOA = RCU_REGIDX_BIT(IDX_AHBEN, 17U), /*!< GPIOA clock */ + RCU_GPIOB = RCU_REGIDX_BIT(IDX_AHBEN, 18U), /*!< GPIOB clock */ + RCU_GPIOC = RCU_REGIDX_BIT(IDX_AHBEN, 19U), /*!< GPIOC clock */ + RCU_GPIOD = RCU_REGIDX_BIT(IDX_AHBEN, 20U), /*!< GPIOD clock */ + RCU_GPIOF = RCU_REGIDX_BIT(IDX_AHBEN, 22U), /*!< GPIOF clock */ + RCU_TSI = RCU_REGIDX_BIT(IDX_AHBEN, 24U), /*!< TSI clock */ + + /* APB2 peripherals */ + RCU_CFGCMP = RCU_REGIDX_BIT(IDX_APB2EN, 0U), /*!< CFGCMP clock */ + RCU_ADC = RCU_REGIDX_BIT(IDX_APB2EN, 9U), /*!< ADC clock */ + RCU_TIMER0 = RCU_REGIDX_BIT(IDX_APB2EN, 11U), /*!< TIMER0 clock */ + RCU_SPI0 = RCU_REGIDX_BIT(IDX_APB2EN, 12U), /*!< SPI0 clock */ + RCU_USART0 = RCU_REGIDX_BIT(IDX_APB2EN, 14U), /*!< USART0 clock */ + RCU_TIMER14 = RCU_REGIDX_BIT(IDX_APB2EN, 16U), /*!< TIMER14 clock */ + RCU_TIMER15 = RCU_REGIDX_BIT(IDX_APB2EN, 17U), /*!< TIMER15 clock */ + RCU_TIMER16 = RCU_REGIDX_BIT(IDX_APB2EN, 18U), /*!< TIMER16 clock */ + + /* APB1 peripherals */ + RCU_TIMER1 = RCU_REGIDX_BIT(IDX_APB1EN, 0U), /*!< TIMER1 clock */ + RCU_TIMER2 = RCU_REGIDX_BIT(IDX_APB1EN, 1U), /*!< TIMER2 clock */ + RCU_TIMER5 = RCU_REGIDX_BIT(IDX_APB1EN, 4U), /*!< TIMER5 clock */ + RCU_TIMER13 = RCU_REGIDX_BIT(IDX_APB1EN, 8U), /*!< TIMER13 clock */ +#ifdef GD32F170_190 + RCU_SLCD = RCU_REGIDX_BIT(IDX_APB1EN, 9U), /*!< SLCD clock */ +#endif /* GD32F170_190 */ + RCU_WWDGT = RCU_REGIDX_BIT(IDX_APB1EN, 11U), /*!< WWDGT clock */ + RCU_SPI1 = RCU_REGIDX_BIT(IDX_APB1EN, 14U), /*!< SPI1 clock */ + RCU_SPI2 = RCU_REGIDX_BIT(IDX_APB1EN, 15U), /*!< SPI2 clock */ + RCU_USART1 = RCU_REGIDX_BIT(IDX_APB1EN, 17U), /*!< USART1 clock */ + RCU_I2C0 = RCU_REGIDX_BIT(IDX_APB1EN, 21U), /*!< I2C0 clock */ + RCU_I2C1 = RCU_REGIDX_BIT(IDX_APB1EN, 22U), /*!< I2C1 clock */ +#ifdef GD32F130_150 + RCU_USBD = RCU_REGIDX_BIT(IDX_APB1EN, 23U), /*!< USBD clock */ +#endif /* GD32F130_150 */ +#ifdef GD32F170_190 + RCU_CAN0 = RCU_REGIDX_BIT(IDX_APB1EN, 25U), /*!< CAN0 clock */ + RCU_CAN1 = RCU_REGIDX_BIT(IDX_APB1EN, 26U), /*!< CAN1 clock */ +#endif /* GD32F170_190 */ + RCU_PMU = RCU_REGIDX_BIT(IDX_APB1EN, 28U), /*!< PMU clock */ + RCU_DAC = RCU_REGIDX_BIT(IDX_APB1EN, 29U), /*!< DAC clock */ + RCU_CEC = RCU_REGIDX_BIT(IDX_APB1EN, 30U), /*!< CEC clock */ +#ifdef GD32F170_190 + RCU_OPAIVREF = RCU_REGIDX_BIT(IDX_APB1EN, 31U), /*!< OPAIVREF clock */ +#endif /* GD32F170_190 */ + RCU_RTC = RCU_REGIDX_BIT(IDX_BDCTL, 15U), /*!< RTC clock */ + + /* RCU_ADDAPB1EN */ + RCU_I2C2 = RCU_REGIDX_BIT(IDX_ADDAPB1EN, 0U) /*!< I2C2 clock */ +}rcu_periph_enum; + +/* peripheral clock enable when sleep mode*/ +typedef enum +{ + /* AHB peripherals */ + RCU_SRAM_SLP = RCU_REGIDX_BIT(IDX_AHBEN, 2U), /*!< SRAM clock when sleep mode */ + RCU_FMC_SLP = RCU_REGIDX_BIT(IDX_AHBEN, 4U) /*!< FMC clock when sleep mode */ +}rcu_periph_sleep_enum; + +/* peripherals reset */ +typedef enum +{ + /* AHB peripherals reset */ + RCU_GPIOARST = RCU_REGIDX_BIT(IDX_AHBRST, 17U), /*!< GPIOA reset */ + RCU_GPIOBRST = RCU_REGIDX_BIT(IDX_AHBRST, 18U), /*!< GPIOB reset */ + RCU_GPIOCRST = RCU_REGIDX_BIT(IDX_AHBRST, 19U), /*!< GPIOC reset */ + RCU_GPIODRST = RCU_REGIDX_BIT(IDX_AHBRST, 20U), /*!< GPIOD reset */ + RCU_GPIOFRST = RCU_REGIDX_BIT(IDX_AHBRST, 22U), /*!< GPIOF reset */ + RCU_TSIRST = RCU_REGIDX_BIT(IDX_AHBRST, 24U), /*!< TSI reset */ + + /* APB2 peripherals reset */ + RCU_CFGCMPRST = RCU_REGIDX_BIT(IDX_APB2RST, 0U), /*!< CFGCMP reset */ + RCU_ADCRST = RCU_REGIDX_BIT(IDX_APB2RST, 9U), /*!< ADC reset */ + RCU_TIMER0RST = RCU_REGIDX_BIT(IDX_APB2RST, 11U), /*!< TIMER0 reset */ + RCU_SPI0RST = RCU_REGIDX_BIT(IDX_APB2RST, 12U), /*!< SPI0 reset */ + RCU_USART0RST = RCU_REGIDX_BIT(IDX_APB2RST, 14U), /*!< USART0 reset */ + RCU_TIMER14RST = RCU_REGIDX_BIT(IDX_APB2RST, 16U), /*!< TIMER14 reset */ + RCU_TIMER15RST = RCU_REGIDX_BIT(IDX_APB2RST, 17U), /*!< TIMER15 reset */ + RCU_TIMER16RST = RCU_REGIDX_BIT(IDX_APB2RST, 18U), /*!< TIMER16 reset */ + + /* APB1 peripherals reset */ + RCU_TIMER1RST = RCU_REGIDX_BIT(IDX_APB1RST, 0U), /*!< TIMER1 reset */ + RCU_TIMER2RST = RCU_REGIDX_BIT(IDX_APB1RST, 1U), /*!< TIMER2 reset */ + RCU_TIMER5RST = RCU_REGIDX_BIT(IDX_APB1RST, 4U), /*!< TIMER5 reset */ + RCU_TIMER13RST = RCU_REGIDX_BIT(IDX_APB1RST, 8U), /*!< TIMER13 reset */ +#ifdef GD32F170_190 + RCU_SLCDRST = RCU_REGIDX_BIT(IDX_APB1RST, 9U), /*!< SLCD reset */ +#endif /* GD32F170_190 */ + RCU_WWDGTRST = RCU_REGIDX_BIT(IDX_APB1RST, 11U), /*!< WWDGT reset */ + RCU_SPI1RST = RCU_REGIDX_BIT(IDX_APB1RST, 14U), /*!< SPI1 reset */ + RCU_SPI2RST = RCU_REGIDX_BIT(IDX_APB1RST, 15U), /*!< SPI2 reset */ + RCU_USART1RST = RCU_REGIDX_BIT(IDX_APB1RST, 17U), /*!< USART1 reset */ + RCU_I2C0RST = RCU_REGIDX_BIT(IDX_APB1RST, 21U), /*!< I2C0 reset */ + RCU_I2C1RST = RCU_REGIDX_BIT(IDX_APB1RST, 22U), /*!< I2C1 reset */ +#ifdef GD32F130_150 + RCU_USBDRST = RCU_REGIDX_BIT(IDX_APB1RST, 23U), /*!< USBD reset */ +#endif /* GD32F130_150 */ +#ifdef GD32F170_190 + RCU_CAN0RST = RCU_REGIDX_BIT(IDX_APB1RST, 25U), /*!< CAN0 reset */ + RCU_CAN1RST = RCU_REGIDX_BIT(IDX_APB1RST, 26U), /*!< CAN1 reset */ +#endif /* GD32F170_190 */ + RCU_PMURST = RCU_REGIDX_BIT(IDX_APB1RST, 28U), /*!< PMU reset */ + RCU_DACRST = RCU_REGIDX_BIT(IDX_APB1RST, 29U), /*!< DAC reset */ + RCU_CECRST = RCU_REGIDX_BIT(IDX_APB1RST, 30U), /*!< CEC reset */ +#ifdef GD32F170_190 + RCU_OPAIVREFRST = RCU_REGIDX_BIT(IDX_APB1RST, 31U), /*!< OPAIVREF reset */ +#endif /* GD32F170_190 */ + + /* RCU_ADDAPB1RST */ + RCU_I2C2RST = RCU_REGIDX_BIT(IDX_ADDAPB1RST, 0U), /*!< I2C2 reset */ +}rcu_periph_reset_enum; + +/* clock stabilization and peripheral reset flags */ +typedef enum +{ + RCU_FLAG_IRC40KSTB = RCU_REGIDX_BIT(IDX_STB, 1U), /*!< IRC40K stabilization flags */ + RCU_FLAG_LXTALSTB = RCU_REGIDX_BIT(IDX_BDCTL, 1U), /*!< LXTAL stabilization flags */ + RCU_FLAG_IRC8MSTB = RCU_REGIDX_BIT(IDX_CTL0, 1U), /*!< IRC8M stabilization flags */ + RCU_FLAG_HXTALSTB = RCU_REGIDX_BIT(IDX_CTL0, 17U), /*!< HXTAL stabilization flags */ + RCU_FLAG_PLLSTB = RCU_REGIDX_BIT(IDX_CTL0, 25U), /*!< PLL stabilization flags */ +#ifdef GD32F130_150 + RCU_FLAG_IRC14MSTB = RCU_REGIDX_BIT(IDX_CTL1, 1U), /*!< IRC14M stabilization flags */ +#elif defined (GD32F170_190) + RCU_FLAG_IRC28MSTB = RCU_REGIDX_BIT(IDX_CTL1, 1U), /*!< IRC28M stabilization flags */ +#endif /* GD32F130_150 */ + RCU_FLAG_V12RST = RCU_REGIDX_BIT(IDX_RSTSCK, 23U), /*!< V12 reset flags */ + RCU_FLAG_OBLRST = RCU_REGIDX_BIT(IDX_RSTSCK, 25U), /*!< OBL reset flags */ + RCU_FLAG_EPRST = RCU_REGIDX_BIT(IDX_RSTSCK, 26U), /*!< EPR reset flags */ + RCU_FLAG_PORRST = RCU_REGIDX_BIT(IDX_RSTSCK, 27U), /*!< Power reset flags */ + RCU_FLAG_SWRST = RCU_REGIDX_BIT(IDX_RSTSCK, 28U), /*!< SW reset flags */ + RCU_FLAG_FWDGTRST = RCU_REGIDX_BIT(IDX_RSTSCK, 29U), /*!< FWDGT reset flags */ + RCU_FLAG_WWDGTRST = RCU_REGIDX_BIT(IDX_RSTSCK, 30U), /*!< WWDGT reset flags */ + RCU_FLAG_LPRST = RCU_REGIDX_BIT(IDX_RSTSCK, 31U) /*!< LP reset flags */ +}rcu_flag_enum; + +/* clock stabilization and ckm interrupt flags */ +typedef enum +{ + RCU_INT_FLAG_IRC40KSTB = RCU_INT_IRC40KSTBIF, /*!< IRC40K stabilization interrupt flag */ + RCU_INT_FLAG_LXTALSTB = RCU_INT_LXTALSTBIF, /*!< LXTAL stabilization interrupt flag */ + RCU_INT_FLAG_IRC8MSTB = RCU_INT_IRC8MSTBIF, /*!< IRC8M stabilization interrupt flag */ + RCU_INT_FLAG_HXTALSTB = RCU_INT_HXTALSTBIF, /*!< HXTAL stabilization interrupt flag */ + RCU_INT_FLAG_PLLSTB = RCU_INT_PLLSTBIF, /*!< PLL stabilization interrupt flag */ +#ifdef GD32F130_150 + RCU_INT_FLAG_IRC14MSTB = RCU_INT_IRC14MSTBIF, /*!< IRC14M stabilization interrupt flag */ +#elif defined (GD32F170_190) + RCU_INT_FLAG_IRC28MSTB = RCU_INT_IRC28MSTBIF, /*!< IRC28M stabilization interrupt flag */ +#endif /* GD32F130_150 */ + RCU_INT_FLAG_CKM = RCU_INT_CKMIF /*!< CKM interrupt flag */ +}rcu_int_flag_enum; + +/* clock stabilization and stuck interrupt flags clear */ +typedef enum +{ + RCU_INT_FLAG_IRC40KSTB_CLR = RCU_INT_IRC40KSTBIC, /*!< IRC40K stabilization interrupt flags clear */ + RCU_INT_FLAG_LXTALSTB_CLR = RCU_INT_LXTALSTBIC, /*!< LXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_IRC8MSTB_CLR = RCU_INT_IRC8MSTBIC, /*!< IRC8M stabilization interrupt flags clear */ + RCU_INT_FLAG_HXTALSTB_CLR = RCU_INT_HXTALSTBIC, /*!< HXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLSTB_CLR = RCU_INT_PLLSTBIC, /*!< PLL stabilization interrupt flags clear */ +#ifdef GD32F130_150 + RCU_INT_FLAG_IRC14MSTB_CLR = RCU_INT_IRC14MSTBIC, /*!< IRC14M stabilization interrupt flags clear */ +#elif defined (GD32F170_190) + RCU_INT_FLAG_IRC28MSTB_CLR = RCU_INT_IRC28MSTBIC, /*!< IRC28M stabilization interrupt flags clear */ +#endif /* GD32F130_150 */ + RCU_INT_FLAG_CKM_CLR = RCU_INT_CKMIC /*!< CKM interrupt flags clear */ +}rcu_int_flag_clear_enum; + +/* clock stabilization interrupt enable or disable */ +typedef enum +{ + RCU_INT_IRC40KSTB = RCU_INT_IRC40KSTBIE, /*!< IRC40K stabilization interrupt */ + RCU_INT_LXTALSTB = RCU_INT_LXTALSTBIE, /*!< LXTAL stabilization interrupt */ + RCU_INT_IRC8MSTB = RCU_INT_IRC8MSTBIE, /*!< IRC8M stabilization interrupt */ + RCU_INT_HXTALSTB = RCU_INT_HXTALSTBIE, /*!< HXTAL stabilization interrupt */ + RCU_INT_PLLSTB = RCU_INT_PLLSTBIE, /*!< PLL stabilization interrupt */ +#ifdef GD32F130_150 + RCU_INT_IRC14MSTB = RCU_INT_IRC14MSTBIE /*!< IRC14M stabilization interrupt */ +#elif defined (GD32F170_190) + RCU_INT_IRC28MSTB = RCU_INT_IRC28MSTBIE /*!< IRC28M stabilization interrupt */ +#endif /* GD32F130_150 */ +}rcu_int_enum; + +/* ADC clock source */ +typedef enum +{ +#ifdef GD32F130_150 + RCU_ADCCK_IRC14M = 0, /*!< ADC clock source select IRC14M */ +#elif defined (GD32F170_190) + RCU_ADCCK_IRC28M_DIV2 = 0, /*!< ADC clock source select IRC28M/2 */ + RCU_ADCCK_IRC28M, /*!< ADC clock source select IRC28M */ +#endif /* GD32F130_150 */ + RCU_ADCCK_APB2_DIV2, /*!< ADC clock source select APB2/2 */ + RCU_ADCCK_APB2_DIV4, /*!< ADC clock source select APB2/4 */ + RCU_ADCCK_APB2_DIV6, /*!< ADC clock source select APB2/6 */ + RCU_ADCCK_APB2_DIV8 /*!< ADC clock source select APB2/8 */ +}rcu_adc_clock_enum; + +/* oscillator types */ +typedef enum +{ + RCU_HXTAL = RCU_REGIDX_BIT(IDX_CTL0, 16U), /*!< HXTAL */ + RCU_LXTAL = RCU_REGIDX_BIT(IDX_BDCTL, 0U), /*!< LXTAL */ + RCU_IRC8M = RCU_REGIDX_BIT(IDX_CTL0, 0U), /*!< IRC8M */ +#ifdef GD32F130_150 + RCU_IRC14M = RCU_REGIDX_BIT(IDX_CTL1, 0U), /*!< IRC14M */ +#elif defined (GD32F170_190) + RCU_IRC28M = RCU_REGIDX_BIT(IDX_CTL1, 0U), /*!< IRC28M */ +#endif /* GD32F130_150 */ + RCU_IRC40K = RCU_REGIDX_BIT(IDX_RSTSCK, 0U), /*!< IRC40K */ + RCU_PLL_CK = RCU_REGIDX_BIT(IDX_CTL0, 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_ADC, /*!< ADC clock */ + CK_CEC, /*!< CEC clock */ + CK_USART /*!< USART clock */ +}rcu_clock_freq_enum; + +/* 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 */ + +/* ADC clock prescaler selection */ +#define CFG0_ADCPSC(regval) (BITS(14,15) & ((uint32_t)(regval) << 14)) +#define RCU_ADC_CKAPB2_DIV2 CFG0_ADCPSC(0) /*!< ADC clock prescaler select CK_APB2/2 */ +#define RCU_ADC_CKAPB2_DIV4 CFG0_ADCPSC(1) /*!< ADC clock prescaler select CK_APB2/4 */ +#define RCU_ADC_CKAPB2_DIV6 CFG0_ADCPSC(2) /*!< ADC clock prescaler select CK_APB2/6 */ +#define RCU_ADC_CKAPB2_DIV8 CFG0_ADCPSC(3) /*!< ADC clock prescaler select CK_APB2/8 */ + +/* PLL clock source selection */ +#define RCU_PLLSRC_IRC8M_DIV2 (uint32_t)0x00000000 /*!< PLL clock source select IRC8M/2 */ +#define RCU_PLLSRC_HXTAL RCU_CFG0_PLLSEL /*!< PLL clock source select HXTAL */ + +/* HXTAL divider for PLL source clock selection */ +#define RCU_PLLPREDV_HXTAL (uint32_t)0x00000000 /*!< HXTAL clock selected */ +#define RCU_PLLPREDV_HXTAL_DIV2 RCU_CFG0_PLLPREDV /*!< HXTAL/2 clock selected */ + +/* PLL multiply factor */ +#define CFG0_PLLMF(regval) (BITS(18,21) & ((uint32_t)(regval) << 18)) +#define RCU_PLL_MUL2 CFG0_PLLMF(0) /*!< PLL source clock multiply by 2 */ +#define RCU_PLL_MUL3 CFG0_PLLMF(1) /*!< PLL source clock multiply by 3 */ +#define RCU_PLL_MUL4 CFG0_PLLMF(2) /*!< PLL source clock multiply by 4 */ +#define RCU_PLL_MUL5 CFG0_PLLMF(3) /*!< PLL source clock multiply by 5 */ +#define RCU_PLL_MUL6 CFG0_PLLMF(4) /*!< PLL source clock multiply by 6 */ +#define RCU_PLL_MUL7 CFG0_PLLMF(5) /*!< PLL source clock multiply by 7 */ +#define RCU_PLL_MUL8 CFG0_PLLMF(6) /*!< PLL source clock multiply by 8 */ +#define RCU_PLL_MUL9 CFG0_PLLMF(7) /*!< PLL source clock multiply by 9 */ +#define RCU_PLL_MUL10 CFG0_PLLMF(8) /*!< PLL source clock multiply by 10 */ +#define RCU_PLL_MUL11 CFG0_PLLMF(9) /*!< PLL source clock multiply by 11 */ +#define RCU_PLL_MUL12 CFG0_PLLMF(10) /*!< PLL source clock multiply by 12 */ +#define RCU_PLL_MUL13 CFG0_PLLMF(11) /*!< PLL source clock multiply by 13 */ +#define RCU_PLL_MUL14 CFG0_PLLMF(12) /*!< PLL source clock multiply by 14 */ +#define RCU_PLL_MUL15 CFG0_PLLMF(13) /*!< PLL source clock multiply by 15 */ +#define RCU_PLL_MUL16 CFG0_PLLMF(14) /*!< PLL source clock multiply by 16 */ +#define RCU_PLL_MUL17 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(0)) /*!< PLL source clock multiply by 17 */ +#define RCU_PLL_MUL18 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(1)) /*!< PLL source clock multiply by 18 */ +#define RCU_PLL_MUL19 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(2)) /*!< PLL source clock multiply by 19 */ +#define RCU_PLL_MUL20 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(3)) /*!< PLL source clock multiply by 20 */ +#define RCU_PLL_MUL21 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(4)) /*!< PLL source clock multiply by 21 */ +#define RCU_PLL_MUL22 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(5)) /*!< PLL source clock multiply by 22 */ +#define RCU_PLL_MUL23 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(6)) /*!< PLL source clock multiply by 23 */ +#define RCU_PLL_MUL24 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(7)) /*!< PLL source clock multiply by 24 */ +#define RCU_PLL_MUL25 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(8)) /*!< PLL source clock multiply by 25 */ +#define RCU_PLL_MUL26 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(9)) /*!< PLL source clock multiply by 26 */ +#define RCU_PLL_MUL27 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(10)) /*!< PLL source clock multiply by 27 */ +#define RCU_PLL_MUL28 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(11)) /*!< PLL source clock multiply by 28 */ +#define RCU_PLL_MUL29 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(12)) /*!< PLL source clock multiply by 29 */ +#define RCU_PLL_MUL30 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(13)) /*!< PLL source clock multiply by 30 */ +#define RCU_PLL_MUL31 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(14)) /*!< PLL source clock multiply by 31 */ +#define RCU_PLL_MUL32 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(15)) /*!< PLL source clock multiply by 32 */ + +#ifdef GD32F130_150 +/* USBD clock prescaler selection */ +#define CFG0_USBDPSC(regval) (BITS(22,23) & ((uint32_t)(regval) << 22)) +#define RCU_USBD_CKPLL_DIV1_5 CFG0_USBDPSC(0) /*!< USBD clock prescaler select CK_PLL/1.5 */ +#define RCU_USBD_CKPLL_DIV1 CFG0_USBDPSC(1) /*!< USBD clock prescaler select CK_PLL */ +#define RCU_USBD_CKPLL_DIV2_5 CFG0_USBDPSC(2) /*!< USBD clock prescaler select CK_PLL/2.5 */ +#define RCU_USBD_CKPLL_DIV2 CFG0_USBDPSC(3) /*!< USBD clock prescaler select CK_PLL/2 */ + +/* CK_OUT clock source selection */ +#define CFG0_CKOUTSEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define RCU_CKOUTSRC_NONE CFG0_CKOUTSEL(0) /*!< no clock selected */ +#define RCU_CKOUTSRC_IRC14M CFG0_CKOUTSEL(1) /*!< CK_OUT clock source select IRC14M */ +#define RCU_CKOUTSRC_IRC40K CFG0_CKOUTSEL(2) /*!< CK_OUT clock source select IRC40K */ +#define RCU_CKOUTSRC_LXTAL CFG0_CKOUTSEL(3) /*!< CK_OUT clock source select LXTAL */ +#define RCU_CKOUTSRC_CKSYS CFG0_CKOUTSEL(4) /*!< CK_OUT clock source select CKSYS */ +#define RCU_CKOUTSRC_IRC8M CFG0_CKOUTSEL(5) /*!< CK_OUT clock source select IRC8M */ +#define RCU_CKOUTSRC_HXTAL CFG0_CKOUTSEL(6) /*!< CK_OUT clock source select HXTAL */ +#define RCU_CKOUTSRC_CKPLL_DIV1 (RCU_CFG0_PLLDV | CFG0_CKOUTSEL(7)) /*!< CK_OUT clock source select CK_PLL */ +#define RCU_CKOUTSRC_CKPLL_DIV2 CFG0_CKOUTSEL(7) /*!< CK_OUT clock source select CK_PLL/2 */ + +/* 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 */ +#elif defined (GD32F170_190) +/* CK_OUT0 clock source selection */ +#define CFG0_CKOUT0SEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define RCU_CKOUT0SRC_NONE CFG0_CKOUT0SEL(0) /*!< no clock selected */ +#define RCU_CKOUT0SRC_IRC28M CFG0_CKOUT0SEL(1) /*!< CK_OUT0 clock source select IRC28M */ +#define RCU_CKOUT0SRC_IRC40K CFG0_CKOUT0SEL(2) /*!< CK_OUT0 clock source select IRC40K */ +#define RCU_CKOUT0SRC_LXTAL CFG0_CKOUT0SEL(3) /*!< CK_OUT0 clock source select LXTAL */ +#define RCU_CKOUT0SRC_CKSYS CFG0_CKOUT0SEL(4) /*!< CK_OUT0 clock source select CKSYS */ +#define RCU_CKOUT0SRC_IRC8M CFG0_CKOUT0SEL(5) /*!< CK_OUT0 clock source select IRC8M */ +#define RCU_CKOUT0SRC_HXTAL CFG0_CKOUT0SEL(6) /*!< CK_OUT0 clock source select HXTAL */ +#define RCU_CKOUT0SRC_CKPLL_DIV1 (RCU_CFG0_PLLDV | CFG0_CKOUT0SEL(7)) /*!< CK_OUT0 clock source select CK_PLL */ +#define RCU_CKOUT0SRC_CKPLL_DIV2 CFG0_CKOUT0SEL(7) /*!< CK_OUT0 clock source select CK_PLL/2 */ + +/* CK_OUT0 divider */ +#define CFG0_CKOUT0DIV(regval) (BITS(28,30) & ((uint32_t)(regval) << 28)) +#define RCU_CKOUT0_DIV1 CFG0_CKOUT0DIV(0) /*!< CK_OUT0 is divided by 1 */ +#define RCU_CKOUT0_DIV2 CFG0_CKOUT0DIV(1) /*!< CK_OUT0 is divided by 2 */ +#define RCU_CKOUT0_DIV4 CFG0_CKOUT0DIV(2) /*!< CK_OUT0 is divided by 4 */ +#define RCU_CKOUT0_DIV8 CFG0_CKOUT0DIV(3) /*!< CK_OUT0 is divided by 8 */ +#define RCU_CKOUT0_DIV16 CFG0_CKOUT0DIV(4) /*!< CK_OUT0 is divided by 16 */ +#define RCU_CKOUT0_DIV32 CFG0_CKOUT0DIV(5) /*!< CK_OUT0 is divided by 32 */ +#define RCU_CKOUT0_DIV64 CFG0_CKOUT0DIV(6) /*!< CK_OUT0 is divided by 64 */ +#define RCU_CKOUT0_DIV128 CFG0_CKOUT0DIV(7) /*!< CK_OUT0 is divided by 128 */ +#endif /* GD32F130_150 */ + +/* CK_PLL divide by 1 or 2 for CK_OUT */ +#define RCU_PLLDV_CKPLL_DIV2 (uint32_t)0x00000000U /*!< CK_PLL divide by 2 for CK_OUT */ +#define RCU_PLLDV_CKPLL RCU_CFG0_PLLDV /*!< CK_PLL divide by 1 for CK_OUT */ + +/* 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 selected */ +#define RCU_RTCSRC_LXTAL BDCTL_RTCSRC(1) /*!< LXTAL selected as RTC source clock */ +#define RCU_RTCSRC_IRC40K BDCTL_RTCSRC(2) /*!< IRC40K selected as RTC source clock */ +#define RCU_RTCSRC_HXTAL_DIV32 BDCTL_RTCSRC(3) /*!< HXTAL/32 selected as RTC source clock */ + +#ifdef GD32F170_190 +/* SLCD clock entry selection */ +#define BDCTL_RTCSRC(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define RCU_SLCDSRC_NONE BDCTL_RTCSRC(0) /*!< no clock selected */ +#define RCU_SLCDSRC_LXTAL BDCTL_RTCSRC(1) /*!< LXTAL selected as SLCD source clock */ +#define RCU_SLCDSRC_IRC40K BDCTL_RTCSRC(2) /*!< IRC40K selected as SLCD source clock */ +#define RCU_SLCDSRC_HXTAL_DIV32 BDCTL_RTCSRC(3) /*!< HXTAL/32 selected as SLCD source clock */ +#endif /* GD32F170_190 */ + +/* CK_HXTAL divider previous PLL */ +#define CFG1_HXTALPREDV(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define RCU_PLL_HXTAL_DIV1 CFG1_HXTALPREDV(0) /*!< HXTAL input to PLL not divided */ +#define RCU_PLL_HXTAL_DIV2 CFG1_HXTALPREDV(1) /*!< HXTAL input to PLL divided by 2 */ +#define RCU_PLL_HXTAL_DIV3 CFG1_HXTALPREDV(2) /*!< HXTAL input to PLL divided by 3 */ +#define RCU_PLL_HXTAL_DIV4 CFG1_HXTALPREDV(3) /*!< HXTAL input to PLL divided by 4 */ +#define RCU_PLL_HXTAL_DIV5 CFG1_HXTALPREDV(4) /*!< HXTAL input to PLL divided by 5 */ +#define RCU_PLL_HXTAL_DIV6 CFG1_HXTALPREDV(5) /*!< HXTAL input to PLL divided by 6 */ +#define RCU_PLL_HXTAL_DIV7 CFG1_HXTALPREDV(6) /*!< HXTAL input to PLL divided by 7 */ +#define RCU_PLL_HXTAL_DIV8 CFG1_HXTALPREDV(7) /*!< HXTAL input to PLL divided by 8 */ +#define RCU_PLL_HXTAL_DIV9 CFG1_HXTALPREDV(8) /*!< HXTAL input to PLL divided by 9 */ +#define RCU_PLL_HXTAL_DIV10 CFG1_HXTALPREDV(9) /*!< HXTAL input to PLL divided by 10 */ +#define RCU_PLL_HXTAL_DIV11 CFG1_HXTALPREDV(10) /*!< HXTAL input to PLL divided by 11 */ +#define RCU_PLL_HXTAL_DIV12 CFG1_HXTALPREDV(11) /*!< HXTAL input to PLL divided by 12 */ +#define RCU_PLL_HXTAL_DIV13 CFG1_HXTALPREDV(12) /*!< HXTAL input to PLL divided by 13 */ +#define RCU_PLL_HXTAL_DIV14 CFG1_HXTALPREDV(13) /*!< HXTAL input to PLL divided by 14 */ +#define RCU_PLL_HXTAL_DIV15 CFG1_HXTALPREDV(14) /*!< HXTAL input to PLL divided by 15 */ +#define RCU_PLL_HXTAL_DIV16 CFG1_HXTALPREDV(15) /*!< HXTAL input to PLL divided by 16 */ + +/* USART0 clock source selection */ +#define CFG2_USART0SEL(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_USART0SRC_CKAPB2 CFG2_USART0SEL(0) /*!< CK_USART0 select CK_APB2 */ +#define RCU_USART0SRC_CKSYS CFG2_USART0SEL(1) /*!< CK_USART0 select CK_SYS */ +#define RCU_USART0SRC_LXTAL CFG2_USART0SEL(2) /*!< CK_USART0 select LXTAL */ +#define RCU_USART0SRC_IRC8M CFG2_USART0SEL(3) /*!< CK_USART0 select IRC8M */ + +/* CEC clock source selection */ +#define RCU_CECSRC_IRC8M_DIV244 (uint32_t)0x00000000U /*!< CK_CEC clock source select IRC8M/244 */ +#define RCU_CECSRC_LXTAL RCU_CFG2_CECSEL /*!< CK_CEC clock source select LXTAL */ + +#ifdef GD32F130_150 +/* ADC clock source selection */ +#define RCU_ADCSRC_IRC14M (uint32_t)0x00000000U /*!< ADC clock source select */ +#define RCU_ADCSRC_APB2DIV RCU_CFG2_ADCSEL /*!< ADC clock source select */ +#elif defined (GD32F170_190) +/* ADC clock source selection */ +#define RCU_ADCSRC_IRC28M (uint32_t)0x00000000U /*!< ADC clock source select */ +#define RCU_ADCSRC_APB2DIV RCU_CFG2_ADCSEL /*!< ADC clock source select */ + +/* IRC28M clock divider for ADC */ +#define RCU_ADC_IRC28M_DIV2 (uint32_t)0x00000000U /*!< IRC28M/2 select to ADC clock */ +#define RCU_ADC_IRC28M_DIV1 RCU_CFG2_IRC28MDIV /*!< IRC28M select to ADC clock */ + +/* CK_OUT1 clock source selection */ +#define CFG3_CKOUT1SRC(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define RCU_CKOUT1SRC_NONE CFG3_CKOUT1SRC(0) /*!< no clock selected */ +#define RCU_CKOUT1SRC_IRC28M CFG3_CKOUT1SRC(1) /*!< CK_OUT1 clock source select IRC28M */ +#define RCU_CKOUT1SRC_IRC40K CFG3_CKOUT1SRC(2) /*!< CK_OUT1 clock source select IRC40K */ +#define RCU_CKOUT1SRC_LXTAL CFG3_CKOUT1SRC(3) /*!< CK_OUT1 clock source select LXTAL */ +#define RCU_CKOUT1SRC_CKSYS CFG3_CKOUT1SRC(4) /*!< CK_OUT1 clock source select CKSYS */ +#define RCU_CKOUT1SRC_IRC8M CFG3_CKOUT1SRC(5) /*!< CK_OUT1 clock source select IRC8M */ +#define RCU_CKOUT1SRC_HXTAL CFG3_CKOUT1SRC(6) /*!< CK_OUT1 clock source select HXTAL */ +#define RCU_CKOUT1SRC_CKPLL_DIV1 0x00000007U /*!< CK_OUT1 clock source select CK_PLL */ +#define RCU_CKOUT1SRC_CKPLL_DIV2 0x00000008U /*!< CK_OUT1 clock source select CK_PLL/2 */ + +/* CK_OUT1 divider */ +#define CFG3_CKOUT1DIV(regval) (BITS(8,13) & ((uint32_t)(regval) << 8)) +#define RCU_CKOUT1_DIV1 CFG3_CKOUT1DIV(0) /*!< CK_OUT1 is divided by 1 */ +#define RCU_CKOUT1_DIV2 CFG3_CKOUT1DIV(1) /*!< CK_OUT1 is divided by 2 */ +#define RCU_CKOUT1_DIV3 CFG3_CKOUT1DIV(2) /*!< CK_OUT1 is divided by 3 */ +#define RCU_CKOUT1_DIV4 CFG3_CKOUT1DIV(3) /*!< CK_OUT1 is divided by 4 */ +#define RCU_CKOUT1_DIV5 CFG3_CKOUT1DIV(4) /*!< CK_OUT1 is divided by 5 */ +#define RCU_CKOUT1_DIV6 CFG3_CKOUT1DIV(5) /*!< CK_OUT1 is divided by 6 */ +#define RCU_CKOUT1_DIV7 CFG3_CKOUT1DIV(6) /*!< CK_OUT1 is divided by 7 */ +#define RCU_CKOUT1_DIV8 CFG3_CKOUT1DIV(7) /*!< CK_OUT1 is divided by 8 */ +#define RCU_CKOUT1_DIV9 CFG3_CKOUT1DIV(8) /*!< CK_OUT1 is divided by 9 */ +#define RCU_CKOUT1_DIV10 CFG3_CKOUT1DIV(9) /*!< CK_OUT1 is divided by 10 */ +#define RCU_CKOUT1_DIV11 CFG3_CKOUT1DIV(10) /*!< CK_OUT1 is divided by 11 */ +#define RCU_CKOUT1_DIV12 CFG3_CKOUT1DIV(11) /*!< CK_OUT1 is divided by 12 */ +#define RCU_CKOUT1_DIV13 CFG3_CKOUT1DIV(12) /*!< CK_OUT1 is divided by 13 */ +#define RCU_CKOUT1_DIV14 CFG3_CKOUT1DIV(13) /*!< CK_OUT1 is divided by 14 */ +#define RCU_CKOUT1_DIV15 CFG3_CKOUT1DIV(14) /*!< CK_OUT1 is divided by 15 */ +#define RCU_CKOUT1_DIV16 CFG3_CKOUT1DIV(15) /*!< CK_OUT1 is divided by 16 */ +#define RCU_CKOUT1_DIV17 CFG3_CKOUT1DIV(16) /*!< CK_OUT1 is divided by 17 */ +#define RCU_CKOUT1_DIV18 CFG3_CKOUT1DIV(17) /*!< CK_OUT1 is divided by 18 */ +#define RCU_CKOUT1_DIV19 CFG3_CKOUT1DIV(18) /*!< CK_OUT1 is divided by 19 */ +#define RCU_CKOUT1_DIV20 CFG3_CKOUT1DIV(19) /*!< CK_OUT1 is divided by 20 */ +#define RCU_CKOUT1_DIV21 CFG3_CKOUT1DIV(20) /*!< CK_OUT1 is divided by 21 */ +#define RCU_CKOUT1_DIV22 CFG3_CKOUT1DIV(21) /*!< CK_OUT1 is divided by 22 */ +#define RCU_CKOUT1_DIV23 CFG3_CKOUT1DIV(22) /*!< CK_OUT1 is divided by 23 */ +#define RCU_CKOUT1_DIV24 CFG3_CKOUT1DIV(23) /*!< CK_OUT1 is divided by 24 */ +#define RCU_CKOUT1_DIV25 CFG3_CKOUT1DIV(24) /*!< CK_OUT1 is divided by 25 */ +#define RCU_CKOUT1_DIV26 CFG3_CKOUT1DIV(25) /*!< CK_OUT1 is divided by 26 */ +#define RCU_CKOUT1_DIV27 CFG3_CKOUT1DIV(26) /*!< CK_OUT1 is divided by 27 */ +#define RCU_CKOUT1_DIV28 CFG3_CKOUT1DIV(27) /*!< CK_OUT1 is divided by 28 */ +#define RCU_CKOUT1_DIV29 CFG3_CKOUT1DIV(28) /*!< CK_OUT1 is divided by 29 */ +#define RCU_CKOUT1_DIV30 CFG3_CKOUT1DIV(29) /*!< CK_OUT1 is divided by 30 */ +#define RCU_CKOUT1_DIV31 CFG3_CKOUT1DIV(30) /*!< CK_OUT1 is divided by 31 */ +#define RCU_CKOUT1_DIV32 CFG3_CKOUT1DIV(31) /*!< CK_OUT1 is divided by 32 */ +#define RCU_CKOUT1_DIV33 CFG3_CKOUT1DIV(32) /*!< CK_OUT1 is divided by 33 */ +#define RCU_CKOUT1_DIV34 CFG3_CKOUT1DIV(33) /*!< CK_OUT1 is divided by 34 */ +#define RCU_CKOUT1_DIV35 CFG3_CKOUT1DIV(34) /*!< CK_OUT1 is divided by 35 */ +#define RCU_CKOUT1_DIV36 CFG3_CKOUT1DIV(35) /*!< CK_OUT1 is divided by 36 */ +#define RCU_CKOUT1_DIV37 CFG3_CKOUT1DIV(36) /*!< CK_OUT1 is divided by 37 */ +#define RCU_CKOUT1_DIV38 CFG3_CKOUT1DIV(37) /*!< CK_OUT1 is divided by 38 */ +#define RCU_CKOUT1_DIV39 CFG3_CKOUT1DIV(38) /*!< CK_OUT1 is divided by 39 */ +#define RCU_CKOUT1_DIV40 CFG3_CKOUT1DIV(39) /*!< CK_OUT1 is divided by 40 */ +#define RCU_CKOUT1_DIV41 CFG3_CKOUT1DIV(40) /*!< CK_OUT1 is divided by 41 */ +#define RCU_CKOUT1_DIV42 CFG3_CKOUT1DIV(41) /*!< CK_OUT1 is divided by 42 */ +#define RCU_CKOUT1_DIV43 CFG3_CKOUT1DIV(42) /*!< CK_OUT1 is divided by 43 */ +#define RCU_CKOUT1_DIV44 CFG3_CKOUT1DIV(43) /*!< CK_OUT1 is divided by 44 */ +#define RCU_CKOUT1_DIV45 CFG3_CKOUT1DIV(44) /*!< CK_OUT1 is divided by 45 */ +#define RCU_CKOUT1_DIV46 CFG3_CKOUT1DIV(45) /*!< CK_OUT1 is divided by 46 */ +#define RCU_CKOUT1_DIV47 CFG3_CKOUT1DIV(46) /*!< CK_OUT1 is divided by 47 */ +#define RCU_CKOUT1_DIV48 CFG3_CKOUT1DIV(47) /*!< CK_OUT1 is divided by 48 */ +#define RCU_CKOUT1_DIV49 CFG3_CKOUT1DIV(48) /*!< CK_OUT1 is divided by 49 */ +#define RCU_CKOUT1_DIV50 CFG3_CKOUT1DIV(49) /*!< CK_OUT1 is divided by 50 */ +#define RCU_CKOUT1_DIV51 CFG3_CKOUT1DIV(50) /*!< CK_OUT1 is divided by 51 */ +#define RCU_CKOUT1_DIV52 CFG3_CKOUT1DIV(51) /*!< CK_OUT1 is divided by 52 */ +#define RCU_CKOUT1_DIV53 CFG3_CKOUT1DIV(52) /*!< CK_OUT1 is divided by 53 */ +#define RCU_CKOUT1_DIV54 CFG3_CKOUT1DIV(53) /*!< CK_OUT1 is divided by 54 */ +#define RCU_CKOUT1_DIV55 CFG3_CKOUT1DIV(54) /*!< CK_OUT1 is divided by 55 */ +#define RCU_CKOUT1_DIV56 CFG3_CKOUT1DIV(55) /*!< CK_OUT1 is divided by 56 */ +#define RCU_CKOUT1_DIV57 CFG3_CKOUT1DIV(56) /*!< CK_OUT1 is divided by 57 */ +#define RCU_CKOUT1_DIV58 CFG3_CKOUT1DIV(57) /*!< CK_OUT1 is divided by 58 */ +#define RCU_CKOUT1_DIV59 CFG3_CKOUT1DIV(58) /*!< CK_OUT1 is divided by 59 */ +#define RCU_CKOUT1_DIV60 CFG3_CKOUT1DIV(59) /*!< CK_OUT1 is divided by 60 */ +#define RCU_CKOUT1_DIV61 CFG3_CKOUT1DIV(60) /*!< CK_OUT1 is divided by 61 */ +#define RCU_CKOUT1_DIV62 CFG3_CKOUT1DIV(61) /*!< CK_OUT1 is divided by 62 */ +#define RCU_CKOUT1_DIV63 CFG3_CKOUT1DIV(62) /*!< CK_OUT1 is divided by 63 */ +#define RCU_CKOUT1_DIV64 CFG3_CKOUT1DIV(63) /*!< CK_OUT1 is divided by 64 */ +#endif /* GD32F130_150 */ + +#ifdef GD32F130_150 +/* Deep-sleep mode voltage */ +#define DSV_DSLPVS(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define RCU_DEEPSLEEP_V_1_2 DSV_DSLPVS(0) /*!< core voltage is 1.2V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_1 DSV_DSLPVS(1) /*!< core voltage is 1.1V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_0 DSV_DSLPVS(2) /*!< core voltage is 1.0V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0_9 DSV_DSLPVS(3) /*!< core voltage is 0.9V in deep-sleep mode */ + +/*Power down voltage select*/ +#define RCU_PDR_V_2_6 (uint32_t)0x00000000U /*!< power down voltage is 2.6V */ +#define RCU_PDR_V_1_8 RCU_PDVSEL_PDRVS /*!< power down voltage is 1.8V */ + +#elif defined (GD32F170_190) +/* Deep-sleep mode voltage */ +#define DSV_DSLPVS(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define RCU_DEEPSLEEP_V_1_8 DSV_DSLPVS(0) /*!< core voltage is 1.8V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_6 DSV_DSLPVS(1) /*!< core voltage is 1.6V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_4 DSV_DSLPVS(2) /*!< core voltage is 1.4V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_2 DSV_DSLPVS(3) /*!< core voltage is 1.2V in deep-sleep mode */ +#endif /* GD32F130_150 */ + +/* function declarations */ +/* deinitialize the RCU */ +void rcu_deinit(void); +/* enable the peripherals clock */ +void rcu_periph_clock_enable(rcu_periph_enum periph); +/* disable the peripherals clock */ +void rcu_periph_clock_disable(rcu_periph_enum periph); +/* enable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph); +/* disable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph); +/* reset the peripherals */ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset); +/* disable reset the peripheral */ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset); +/* reset the BKP domain */ +void rcu_bkp_reset_enable(void); +/* disable the BKP domain reset */ +void rcu_bkp_reset_disable(void); + +/* configure the system clock source */ +void rcu_system_clock_source_config(uint32_t ck_sys); +/* get the system clock source */ +uint32_t rcu_system_clock_source_get(void); +/* configure the AHB prescaler selection */ +void rcu_ahb_clock_config(uint32_t ck_ahb); +/* configure the APB1 prescaler selection */ +void rcu_apb1_clock_config(uint32_t ck_apb1); +/* configure the APB2 prescaler selection */ +void rcu_apb2_clock_config(uint32_t ck_apb2); +/* configure the ADC clock source and prescaler selection */ +void rcu_adc_clock_config(rcu_adc_clock_enum ck_adc); +#ifdef GD32F130_150 +/* configure the USBD prescaler selection */ +void rcu_usbd_clock_config(uint32_t ck_usbd); +/* configure the CK_OUT clock source and divider */ +void rcu_ckout_config(uint32_t ckout_src, uint32_t ckout_div); +#elif defined (GD32F170_190) +/* configure the CK_OUT0 clock source and divider */ +void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div); +/* configure the CK_OUT1 clock source and divider */ +void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div); +#endif /* GD32F130_150 */ +/* configure the PLL clock source selection and PLL multiply factor */ +void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul); +/* configure the USART clock source selection */ +void rcu_usart_clock_config(uint32_t ck_usart); +/* configure the CEC clock source selection */ +void rcu_cec_clock_config(uint32_t ck_cec); +/* configure the RTC clock source selection */ +void rcu_rtc_clock_config(uint32_t rtc_clock_source); +#ifdef GD32F170_190 +void rcu_slcd_clock_config(uint32_t slcd_clock_source); +#endif /* GD32F170_190 */ +/* configure the HXTAL divider used as input of PLL */ +void rcu_hxtal_prediv_config(uint32_t hxtal_prediv); +/* configure the LXTAL drive capability */ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap); + +/* get the clock stabilization and periphral reset flags */ +FlagStatus rcu_flag_get(rcu_flag_enum flag); +/* clear the reset flag */ +void rcu_all_reset_flag_clear(void); +/* get the clock stabilization interrupt and ckm flags */ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag); +/* clear the interrupt flags */ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear); +/* enable the stabilization interrupt */ +void rcu_interrupt_enable(rcu_int_enum stab_int); +/* disable the stabilization interrupt */ +void rcu_interrupt_disable(rcu_int_enum stab_int); + +/* wait until oscillator stabilization flags is SET or oscillator startup is timeout */ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci); +/* turn on the oscillator */ +void rcu_osci_on(rcu_osci_type_enum osci); +/* turn off the oscillator */ +void rcu_osci_off(rcu_osci_type_enum osci); +/* enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci); +/* disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci); +/* enable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_enable(void); +/* disable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_disable(void); + +/* set the IRC8M adjust value */ +void rcu_irc8m_adjust_value_set(uint8_t irc8m_adjval); +#ifdef GD32F130_150 +/* set the IRC14M adjust value */ +void rcu_irc14m_adjust_value_set(uint8_t irc14m_adjval); +#elif defined (GD32F170_190) +/* set the IRC28M adjust value */ +void rcu_irc28m_adjust_value_set(uint8_t irc28m_adjval); +#endif /* GD32F130_150 */ +/* unlock the voltage key */ +void rcu_voltage_key_unlock(void); +/* set the deep sleep mode voltage */ +void rcu_deepsleep_voltage_set(uint32_t dsvol); +#ifdef GD32F130_150 +/* set the power down voltage */ +void rcu_power_down_voltage_set(uint32_t pdvol); +#endif /* GD32F130_150 */ + +/* get the system clock, bus and peripheral clock frequency */ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock); + +#endif /* GD32F1X0_RCU_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_rtc.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_rtc.h new file mode 100644 index 0000000..259716b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_rtc.h @@ -0,0 +1,540 @@ +/*! + \file gd32f1x0_rtc.h + \brief definitions for the RTC +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_RTC_H +#define GD32F1X0_RTC_H + +#include "gd32f1x0.h" + +/* RTC definitions */ +#define RTC RTC_BASE + +/* registers definitions */ +#define RTC_TIME REG32((RTC) + 0x00U) /*!< RTC time of day register */ +#define RTC_DATE REG32((RTC) + 0x04U) /*!< RTC date register */ +#define RTC_CTL REG32((RTC) + 0x08U) /*!< RTC control register */ +#define RTC_STAT REG32((RTC) + 0x0CU) /*!< RTC status register */ +#define RTC_PSC REG32((RTC) + 0x10U) /*!< RTC time prescaler register */ +#define RTC_ALRM0TD REG32((RTC) + 0x1CU) /*!< RTC alarm 0 time and date register */ +#define RTC_WPK REG32((RTC) + 0x24U) /*!< RTC write protection key register */ +#define RTC_SS REG32((RTC) + 0x28U) /*!< RTC sub second register */ +#define RTC_SHIFTCTL REG32((RTC) + 0x2CU) /*!< RTC shift function control register */ +#define RTC_TTS REG32((RTC) + 0x30U) /*!< RTC time of timestamp register */ +#define RTC_DTS REG32((RTC) + 0x34U) /*!< RTC date of timestamp register */ +#define RTC_SSTS REG32((RTC) + 0x38U) /*!< RTC sub second of timestamp register */ +#define RTC_HRFC REG32((RTC) + 0x3CU) /*!< RTC high resolution frequency compensation registor */ +#define RTC_TAMP REG32((RTC) + 0x40U) /*!< RTC tamper register */ +#define RTC_ALRM0SS REG32((RTC) + 0x44U) /*!< RTC alarm 0 sub second register */ +#define RTC_BKP0 REG32((RTC) + 0x50U) /*!< RTC backup register */ +#define RTC_BKP1 REG32((RTC) + 0x54U) /*!< RTC backup register */ +#define RTC_BKP2 REG32((RTC) + 0x58U) /*!< RTC backup register */ +#define RTC_BKP3 REG32((RTC) + 0x5CU) /*!< RTC backup register */ +#define RTC_BKP4 REG32((RTC) + 0x60U) /*!< RTC backup register */ + +/* bits definitions */ +/* RTC_TIME */ +#define RTC_TIME_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TIME_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_TIME_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TIME_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TIME_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TIME_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TIME_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DATE */ +#define RTC_DATE_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DATE_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DATE_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DATE_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DATE_DOW BITS(13,15) /*!< day of week units */ +#define RTC_DATE_YRU BITS(16,19) /*!< year units in BCD code */ +#define RTC_DATE_YRT BITS(20,23) /*!< year tens in BCD code */ + +/* RTC_CTL */ +#define RTC_CTL_TSEG BIT(3) /*!< valid event edge of time-stamp */ +#define RTC_CTL_REFEN BIT(4) /*!< reference clock detection function enable */ +#define RTC_CTL_BPSHAD BIT(5) /*!< shadow registers bypass control */ +#define RTC_CTL_CS BIT(6) /*!< display format of clock system */ +#define RTC_CTL_ALRM0EN BIT(8) /*!< alarm function enable */ +#define RTC_CTL_TSEN BIT(11) /*!< time-stamp function enable */ +#define RTC_CTL_ALRM0IE BIT(12) /*!< RTC alarm interrupt enable */ +#define RTC_CTL_TSIE BIT(15) /*!< time-stamp interrupt enable */ +#define RTC_CTL_A1H BIT(16) /*!< add 1 hour(summer time change) */ +#define RTC_CTL_S1H BIT(17) /*!< subtract 1 hour(winter time change) */ +#define RTC_CTL_DSM BIT(18) /*!< daylight saving mark */ +#define RTC_CTL_COS BIT(19) /*!< calibration output selection */ +#define RTC_CTL_OPOL BIT(20) /*!< output polarity */ +#define RTC_CTL_OS BITS(21,22) /*!< output selection */ +#define RTC_CTL_COEN BIT(23) /*!< calibration output enable */ + +/* RTC_STAT */ +#define RTC_STAT_ALRM0WF BIT(0) /*!< alarm configuration can be write flag */ +#define RTC_STAT_SOPF BIT(3) /*!< shift function operation pending flag */ +#define RTC_STAT_YCM BIT(4) /*!< year configuration mark status flag */ +#define RTC_STAT_RSYNF BIT(5) /*!< register synchronization flag */ +#define RTC_STAT_INITF BIT(6) /*!< initialization state flag */ +#define RTC_STAT_INITM BIT(7) /*!< enter initialization mode */ +#define RTC_STAT_ALRM0F BIT(8) /*!< alarm occurs flag */ +#define RTC_STAT_TSF BIT(11) /*!< time-stamp flag */ +#define RTC_STAT_TSOVRF BIT(12) /*!< time-stamp overflow flag */ +#define RTC_STAT_TP0F BIT(13) /*!< RTC tamp 0 detected flag */ +#define RTC_STAT_TP1F BIT(14) /*!< RTC tamp 1 detected flag */ +#define RTC_STAT_SCPF BIT(16) /*!< recalibration pending flag */ + +/* RTC_PSC */ +#define RTC_PSC_FACTOR_S BITS(0,14) /*!< synchronous prescaler factor */ +#define RTC_PSC_FACTOR_A BITS(16,22) /*!< asynchronous prescaler factor */ + +/* RTC_ALRM0TD */ +#define RTC_ALRM0TD_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_ALRM0TD_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_ALRM0TD_MSKS BIT(7) /*!< alarm second mask bit */ +#define RTC_ALRM0TD_MNU BITS(8,11) /*!< minutes units in BCD code */ +#define RTC_ALRM0TD_MNT BITS(12,14) /*!< minutes tens in BCD code */ +#define RTC_ALRM0TD_MSKM BIT(15) /*!< alarm minutes mask bit */ +#define RTC_ALRM0TD_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_ALRM0TD_HRT BITS(20,21) /*!< hour units in BCD code */ +#define RTC_ALRM0TD_PM BIT(22) /*!< AM/PM flag */ +#define RTC_ALRM0TD_MSKH BIT(23) /*!< alarm hour mask bit */ +#define RTC_ALRM0TD_DAYU BITS(24,27) /*!< date units or week day in BCD code */ +#define RTC_ALRM0TD_DAYT BITS(28,29) /*!< date tens in BCD code */ +#define RTC_ALRM0TD_DOWS BIT(30) /*!< day of week selection */ +#define RTC_ALRM0TD_MSKD BIT(31) /*!< alarm date mask bit */ + +/* RTC_WPK */ +#define RTC_WPK_WPK BITS(0,7) /*!< key for write protection */ + +/* RTC_SS */ +#define RTC_SS_SSC BITS(0,15) /*!< sub second value */ + +/* RTC_SHIFTCTL */ +#define RTC_SHIFTCTL_SFS BITS(0,14) /*!< subtract a fraction of a second */ +#define RTC_SHIFTCTL_A1S BIT(31) /*!< one second add */ + +/* RTC_TTS */ +#define RTC_TTS_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TTS_SCT BITS(4,6) /*!< second units in BCD code */ +#define RTC_TTS_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TTS_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TTS_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TTS_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TTS_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DTS */ +#define RTC_DTS_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DTS_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DTS_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DTS_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DTS_DOW BITS(13,15) /*!< day of week units */ + +/* RTC_SSTS */ +#define RTC_SSTS_SSC BITS(0,15) /*!< timestamp sub second units */ + +/* RTC_HRFC */ +#define RTC_HRFC_CMSK BITS(0,8) /*!< calibration mask number */ +#define RTC_HRFC_CWND16 BIT(13) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_CWND8 BIT(14) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_FREQI BIT(15) /*!< increase RTC frequency by 488.5ppm */ + +/* RTC_TAMP */ +#define RTC_TAMP_TP0EN BIT(0) /*!< tamper 0 detection enable */ +#define RTC_TAMP_TP0EG BIT(1) /*!< tamper 0 event trigger edge for RTC tamp 0 input */ +#define RTC_TAMP_TPIE BIT(2) /*!< tamper detection interrupt enable */ +#define RTC_TAMP_TP1EN BIT(3) /*!< tamper 1 detection enable */ +#define RTC_TAMP_TP1EG BIT(4) /*!< tamper 1 event trigger edge for RTC tamp 1 input */ +#define RTC_TAMP_TPTS BIT(7) /*!< make tamper function used for timestamp function */ +#define RTC_TAMP_FREQ BITS(8,10) /*!< sample frequency of tamper event detection */ +#define RTC_TAMP_FLT BITS(11,12) /*!< RTC tamp x filter count setting */ +#define RTC_TAMP_PRCH BITS(13,14) /*!< precharge duration time of RTC tamp x */ +#define RTC_TAMP_DISPU BIT(15) /*!< RTC tamp x pull up disable bit */ +#define RTC_TAMP_PC13VAL BIT(18) /*!< alarm output type control/PC13 output value */ +#define RTC_TAMP_PC13MDE BIT(19) /*!< PC13 mode */ +#define RTC_TAMP_PC14VAL BIT(20) /*!< PC14 output value */ +#define RTC_TAMP_PC14MDE BIT(21) /*!< PC14 mode */ +#define RTC_TAMP_PC15VAL BIT(22) /*!< PC15 output value */ +#define RTC_TAMP_PC15MDE BIT(23) /*!< PC15 mode */ + +/* RTC_ALRM0SS */ +#define RTC_ALRM0SS_SSC BITS(0,14) /*!< alarm sub second value */ +#define RTC_ALRM0SS_MASKSSC BITS(24,27) /*!< mask control bit of SS */ + +/* RTC_BKP0 */ +#define RTC_BKP0_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP1 */ +#define RTC_BKP1_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP2 */ +#define RTC_BKP2_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP3 */ +#define RTC_BKP3_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP4 */ +#define RTC_BKP4_DATA BITS(0,31) /*!< backup domain registers */ + + +/* constants definitions */ +/* structure for initialization of the RTC */ +typedef struct +{ + uint8_t rtc_year; /*!< RTC year value: 0x0 - 0x99(BCD format) */ + uint8_t rtc_month; /*!< RTC month value */ + uint8_t rtc_date; /*!< RTC date value: 0x1 - 0x31(BCD format) */ + uint8_t rtc_day_of_week; /*!< RTC weekday value */ + uint8_t rtc_hour; /*!< RTC hour value */ + uint8_t rtc_minute; /*!< RTC minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_second; /*!< RTC second value: 0x0 - 0x59(BCD format) */ + uint16_t rtc_factor_asyn; /*!< RTC asynchronous prescaler value: 0x0 - 0x7F */ + uint16_t rtc_factor_syn; /*!< RTC synchronous prescaler value: 0x0 - 0x7FFF */ + uint32_t rtc_am_pm; /*!< RTC AM/PM value */ + uint32_t rtc_display_format; /*!< RTC time notation */ +}rtc_parameter_struct; + +/* structure for RTC alarm configuration */ +typedef struct +{ + uint32_t rtc_alarm_mask; /*!< RTC alarm mask */ + uint32_t rtc_weekday_or_date; /*!< specify RTC alarm is on date or weekday */ + uint8_t rtc_alarm_day; /*!< RTC alarm date or weekday value*/ + uint8_t rtc_alarm_hour; /*!< RTC alarm hour value */ + uint8_t rtc_alarm_minute; /*!< RTC alarm minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_alarm_second; /*!< RTC alarm second value: 0x0 - 0x59(BCD format) */ + uint32_t rtc_am_pm; /*!< RTC alarm AM/PM value */ +}rtc_alarm_struct; + +/* structure for RTC time-stamp configuration */ +typedef struct +{ + uint8_t rtc_timestamp_month; /*!< RTC time-stamp month value */ + uint8_t rtc_timestamp_date; /*!< RTC time-stamp date value: 0x1 - 0x31(BCD format) */ + uint8_t rtc_timestamp_day; /*!< RTC time-stamp weekday value */ + uint8_t rtc_timestamp_hour; /*!< RTC time-stamp hour value */ + uint8_t rtc_timestamp_minute; /*!< RTC time-stamp minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_timestamp_second; /*!< RTC time-stamp second value: 0x0 - 0x59(BCD format) */ + uint32_t rtc_am_pm; /*!< RTC time-stamp AM/PM value */ +}rtc_timestamp_struct; + +/* structure for RTC tamper configuration */ +typedef struct +{ + uint32_t rtc_tamper_source; /*!< RTC tamper source */ + uint32_t rtc_tamper_trigger; /*!< RTC tamper trigger */ + uint32_t rtc_tamper_filter; /*!< RTC tamper consecutive samples needed during a voltage level detection */ + uint32_t rtc_tamper_sample_frequency; /*!< RTC tamper sampling frequency during a voltage level detection */ + ControlStatus rtc_tamper_precharge_enable; /*!< RTC tamper precharge feature during a voltage level detection */ + uint32_t rtc_tamper_precharge_time; /*!< RTC tamper precharge duration if precharge feature is enabled */ + ControlStatus rtc_tamper_with_timestamp; /*!< RTC tamper time-stamp feature */ +}rtc_tamper_struct; + +/* time register value */ +#define TIME_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_TIME_SC bit field */ +#define GET_TIME_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TIME_SC bit field */ + +#define TIME_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TIME_MN bit field */ +#define GET_TIME_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TIME_MN bit field */ + +#define TIME_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U))/*!< write value to RTC_TIME_HR bit field */ +#define GET_TIME_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TIME_HR bit field */ + +#define RTC_AM ((uint32_t)0x00000000U) /*!< AM format */ +#define RTC_PM RTC_TIME_PM /*!< PM format */ + +/* date register value */ +#define DATE_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_DATE_DAY bit field */ +#define GET_DATE_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DATE_DAY bit field */ + +#define DATE_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_DATE_MON bit field */ +#define GET_DATE_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DATE_MON bit field */ +#define RTC_JAN ((uint8_t)0x01U) /*!< Janurary */ +#define RTC_FEB ((uint8_t)0x02U) /*!< February */ +#define RTC_MAR ((uint8_t)0x03U) /*!< March */ +#define RTC_APR ((uint8_t)0x04U) /*!< April */ +#define RTC_MAY ((uint8_t)0x05U) /*!< May */ +#define RTC_JUN ((uint8_t)0x06U) /*!< June */ +#define RTC_JUL ((uint8_t)0x07U) /*!< July */ +#define RTC_AUG ((uint8_t)0x08U) /*!< August */ +#define RTC_SEP ((uint8_t)0x09U) /*!< September */ +#define RTC_OCT ((uint8_t)0x10U) /*!< October */ +#define RTC_NOV ((uint8_t)0x11U) /*!< November */ +#define RTC_DEC ((uint8_t)0x12U) /*!< December */ + +#define DATE_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U))/*!< write value to RTC_DATE_DOW bit field */ +#define GET_DATE_DOW(regval) GET_BITS((regval),13,15) /*!< get value of RTC_DATE_DOW bit field */ +#define RTC_MONDAY ((uint8_t)0x01) /*!< Monday */ +#define RTC_TUESDAY ((uint8_t)0x02) /*!< Tuesday */ +#define RTC_WEDSDAY ((uint8_t)0x03) /*!< Wednesday */ +#define RTC_THURSDAY ((uint8_t)0x04) /*!< Thursday */ +#define RTC_FRIDAY ((uint8_t)0x05) /*!< Friday */ +#define RTC_SATURDAY ((uint8_t)0x06) /*!< Saturday */ +#define RTC_SUNDAY ((uint8_t)0x07) /*!< Sunday */ + +#define DATE_YR(regval) (BITS(16,23) & ((uint32_t)(regval) << 16U))/*!< write value to RTC_DATE_YR bit field */ +#define GET_DATE_YR(regval) GET_BITS((regval),16,23) /*!< get value of RTC_DATE_YR bit field */ + +/* ctl register value */ +#define CTL_OS(regval) (BITS(21,22) & ((uint32_t)(regval) << 21U))/*!< write value to RTC_CTL_OS bit field */ +#define RTC_OS_DISABLE CTL_OS(0) /*!< disable output RTC_ALARM */ +#define RTC_OS_ENABLE CTL_OS(1) /*!< enable alarm flag output */ + +#define RTC_CALIBRATION_512HZ RTC_CTL_COEN /*!< calibration output of 512Hz is enable */ +#define RTC_CALIBRATION_1HZ RTC_CTL_COEN | RTC_CTL_COS /*!< calibration output of 1Hz is enable */ +#define RTC_ALARM_HIGH RTC_CTL_OS_ENABLE /*!< enable alarm flag output with high level */ +#define RTC_ALARM_LOW RTC_CTL_OS_ENABLE | RTC_CTL_OPOL /*!< enable alarm flag output with low level*/ + +#define RTC_24HOUR ((uint32_t)0x00000000U) /*!< 24-hour format */ +#define RTC_12HOUR RTC_CTL_CS /*!< 12-hour format */ + +#define RTC_TIMESTAMP_RISING_EDGE ((uint32_t)0x00000000U) /*!< rising edge is valid event edge for time-stamp event */ +#define RTC_TIMESTAMP_FALLING_EDGE RTC_CTL_TSEG /*!< falling edge is valid event edge for time-stamp event */ + +/* psc register value */ +#define PSC_FACTOR_S(regval) (BITS(0,14) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_PSC_FACTOR_S bit field */ +#define GET_PSC_FACTOR_S(regval) GET_BITS((regval),0,14) /*!< get value of RTC_PSC_FACTOR_S bit field */ + +#define PSC_FACTOR_A(regval) (BITS(16,22) & ((uint32_t)(regval) << 16U))/*!< write value to RTC_PSC_FACTOR_A bit field */ +#define GET_PSC_FACTOR_A(regval) GET_BITS((regval),16,22) /*!< get value of RTC_PSC_FACTOR_A bit field */ + +/* alrm0td register value */ +#define ALRM0TD_SC(regval) (BITS(0,6) & ((uint32_t)(regval)<< 0U)) /*!< write value to RTC_ALRM0TD_SC bit field */ +#define GET_ALRM0TD_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_ALRM0TD_SC bit field */ + +#define ALRM0TD_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_ALRM0TD_MN bit field */ +#define GET_ALRM0TD_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_ALRM0TD_MN bit field */ + +#define ALRM0TD_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U))/*!< write value to RTC_ALRM0TD_HR bit field */ +#define GET_ALRM0TD_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_ALRM0TD_HR bit field */ + +#define ALRM0TD_DAY(regval) (BITS(24,29) & ((uint32_t)(regval) << 24U))/*!< write value to RTC_ALRM0TD_DAY bit field */ +#define GET_ALRM0TD_DAY(regval) GET_BITS((regval),24,29) /*!< get value of RTC_ALRM0TD_DAY bit field */ + +#define RTC_ALARM_NONE_MASK ((uint32_t)0x00000000U) /*!< alarm none mask */ +#define RTC_ALARM_DATE_MASK RTC_ALRM0TD_MSKD /*!< alarm date mask */ +#define RTC_ALARM_HOUR_MASK RTC_ALRM0TD_MSKH /*!< alarm hour mask */ +#define RTC_ALARM_MINUTE_MASK RTC_ALRM0TD_MSKM /*!< alarm minute mask */ +#define RTC_ALARM_SECOND_MASK RTC_ALRM0TD_MSKS /*!< alarm second mask */ +#define RTC_ALARM_ALL_MASK (RTC_ALRM0TD_MSKD|RTC_ALRM0TD_MSKH|RTC_ALRM0TD_MSKM|RTC_ALRM0TD_MSKS) /*!< alarm all mask */ + +#define RTC_ALARM_DATE_SELECTED ((uint32_t)0x00000000U) /*!< alarm date format selected */ +#define RTC_ALARM_WEEKDAY_SELECTED RTC_ALRM0TD_DOWS /*!< alarm weekday format selected */ + +/* wpk register value */ +#define WPK_WPK(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_WPK_WPK bit field */ + +/* ss register value */ +#define SS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SS_SSC bit field */ + +/* shiftctl register value */ +#define SHIFTCTL_SFS(regval) (BITS(0,14) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SHIFTCTL_SFS bit field */ + +#define RTC_SHIFT_ADD1S_RESET ((uint32_t)0x00000000U) /*!< not add 1 second */ +#define RTC_SHIFT_ADD1S_SET RTC_SHIFTCTL_A1S /*!< add one second to the clock */ + +/* tts register value */ +#define TTS_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_TTS_SC bit field */ +#define GET_TTS_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TTS_SC bit field */ + +#define TTS_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TTS_MN bit field */ +#define GET_TTS_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TTS_MN bit field */ + +#define TTS_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U))/*!< write value to RTC_TTS_HR bit field */ +#define GET_TTS_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TTS_HR bit field */ + +/* dts register value */ +#define DTS_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_DTS_DAY bit field */ +#define GET_DTS_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DTS_DAY bit field */ + +#define DTS_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_DTS_MON bit field */ +#define GET_DTS_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DTS_MON bit field */ + +#define DTS_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U))/*!< write value to RTC_DTS_DOW bit field */ +#define GET_DTS_DOW(regval) GET_BITS((regval),13,15) /*!< get value of RTC_DTS_DOW bit field */ + +/* ssts register value */ +#define SSTS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SSTS_SSC bit field */ + +/* hrfc register value */ +#define HRFC_CMSK(regval) (BITS(0,8) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_HRFC_CMSK bit field */ + +#define RTC_CALIBRATION_WINDOW_32S ((uint32_t)0x00000000U) /*!< 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_16S RTC_HRFC_CWND16 /*!< 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_8S RTC_HRFC_CWND8 /*!< 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz */ + +#define RTC_CALIBRATION_PLUS_SET RTC_HRFC_FREQI /*!< increase RTC frequency by 488.5ppm */ +#define RTC_CALIBRATION_PLUS_RESET ((uint32_t)0x00000000U) /*!< no effect */ + +/* tamp register value */ +#define TAMP_FREQ(regval) (BITS(8,10) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TAMP_FREQ bit field */ +#define RTC_FREQ_DIV32768 TAMP_FREQ(0) /*!< sample once every 32768 RTCCLK(1Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV16384 TAMP_FREQ(1) /*!< sample once every 16384 RTCCLK(2Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV8192 TAMP_FREQ(2) /*!< sample once every 8192 RTCCLK(4Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV4096 TAMP_FREQ(3) /*!< sample once every 4096 RTCCLK(8Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV2048 TAMP_FREQ(4) /*!< sample once every 2048 RTCCLK(16Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV1024 TAMP_FREQ(5) /*!< sample once every 1024 RTCCLK(32Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV512 TAMP_FREQ(6) /*!< sample once every 512 RTCCLK(64Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV256 TAMP_FREQ(7) /*!< sample once every 256 RTCCLK(128Hz if RTCCLK=32.768KHz) */ + +#define TAMP_FLT(regval) (BITS(11,12) & ((uint32_t)(regval) << 11U))/*!< write value to RTC_TAMP_FLT bit field */ +#define RTC_FLT_EDGE TAMP_FLT(0) /*!< detecting tamper event using edge mode. precharge duration is disabled automatically */ +#define RTC_FLT_2S TAMP_FLT(1) /*!< detecting tamper event using level mode.2 consecutive valid level samples will make a effective tamper event */ +#define RTC_FLT_4S TAMP_FLT(2) /*!< detecting tamper event using level mode.4 consecutive valid level samples will make an effective tamper event */ +#define RTC_FLT_8S TAMP_FLT(3) /*!< detecting tamper event using level mode.8 consecutive valid level samples will make a effective tamper event */ + +#define TAMP_PRCH(regval) (BITS(13,14 ) & ((uint32_t)(regval) << 13U))/*!< write value to RTC_TAMP_PRCH bit field */ +#define RTC_PRCH_1C TAMP_PRCH(0) /*!< 1 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_2C TAMP_PRCH(1) /*!< 2 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_4C TAMP_PRCH(2) /*!< 4 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_8C TAMP_PRCH(3) /*!< 8 RTC clock prechagre time before each sampling */ + +#define RTC_TAMPER0 RTC_TAMP_TP0EN /*!< tamper 0 detection enable */ +#define RTC_TAMPER1 RTC_TAMP_TP1EN /*!< tamper 1 detection enable */ + +#define RTC_TAMPER_TRIGGER_EDGE_RISING ((uint32_t)0x00000000U) /*!< tamper detection is in rising edge mode */ +#define RTC_TAMPER_TRIGGER_EDGE_FALLING RTC_TAMP_TP0EG /*!< tamper detection is in falling edge mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_LOW ((uint32_t)0x00000000U) /*!< tamper detection is in low level mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_HIGH RTC_TAMP_TP0EG /*!< tamper detection is in high level mode */ + +#define RTC_TAMPER_TRIGGER_POS ((uint32_t)0x00000001U) /* shift position of trigger relative to source */ + +#define RTC_ALARM_OUTPUT_OD ((uint32_t)0x00000000U) /*!< RTC alarm output open-drain mode */ +#define RTC_ALARM_OUTPUT_PP RTC_TAMP_PC13VAL /*!< RTC alarm output push-pull mode */ + +/* alrm0ss register value */ +#define ALRM0SS_SSC(regval) (BITS(0,14) & ((uint32_t)(regval)<< 0U)) /*!< write value to RTC_ALRM0SS_SSC bit field */ + +#define ALRM0SS_MASKSSC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24U))/*!< write value to RTC_ALRM0SS_MASKSSC bit field */ +#define RTC_MASKSSC_0_14 ALRM0SS_MASKSSC(0) /*!< mask alarm subsecond configuration */ +#define RTC_MASKSSC_1_14 ALRM0SS_MASKSSC(1) /*!< mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared */ +#define RTC_MASKSSC_2_14 ALRM0SS_MASKSSC(2) /*!< mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared */ +#define RTC_MASKSSC_3_14 ALRM0SS_MASKSSC(3) /*!< mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared */ +#define RTC_MASKSSC_4_14 ALRM0SS_MASKSSC(4) /*!< mask RTC_ALRM0SS_SSC[14:4], and RTC_ALRM0SS_SSC[3:0] is to be compared */ +#define RTC_MASKSSC_5_14 ALRM0SS_MASKSSC(5) /*!< mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared */ +#define RTC_MASKSSC_6_14 ALRM0SS_MASKSSC(6) /*!< mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared */ +#define RTC_MASKSSC_7_14 ALRM0SS_MASKSSC(7) /*!< mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared */ +#define RTC_MASKSSC_8_14 ALRM0SS_MASKSSC(8) /*!< mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared */ +#define RTC_MASKSSC_9_14 ALRM0SS_MASKSSC(9) /*!< mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared */ +#define RTC_MASKSSC_10_14 ALRM0SS_MASKSSC(10) /*!< mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared */ +#define RTC_MASKSSC_11_14 ALRM0SS_MASKSSC(11) /*!< mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared */ +#define RTC_MASKSSC_12_14 ALRM0SS_MASKSSC(12) /*!< mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared */ +#define RTC_MASKSSC_13_14 ALRM0SS_MASKSSC(13) /*!< mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared */ +#define RTC_MASKSSC_14 ALRM0SS_MASKSSC(14) /*!< mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared */ +#define RTC_MASKSSC_NONE ALRM0SS_MASKSSC(15) /*!< mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared */ + +/* RTC interrupt source */ +#define RTC_INT_TIMESTAMP RTC_CTL_TSIE /*!< time-stamp interrupt enable */ +#define RTC_INT_ALARM RTC_CTL_ALRM0IE /*!< RTC alarm interrupt enable */ +#define RTC_INT_TAMP RTC_TAMP_TPIE /*!< tamper detection interrupt enable */ + +/* write protect key */ +#define RTC_UNLOCK_KEY1 ((uint8_t)0xCAU) /*!< RTC unlock key1 */ +#define RTC_UNLOCK_KEY2 ((uint8_t)0x53U) /*!< RTC unlock key2 */ +#define RTC_LOCK_KEY ((uint8_t)0xFFU) /*!< RTC lock key */ + +/* registers reset value */ +#define RTC_REGISTER_RESET ((uint32_t)0x00000000U) /*!< RTC common register reset value */ +#define RTC_DATE_RESET ((uint32_t)0x00002101U) /*!< RTC_DATE register reset value */ +#define RTC_STAT_RESET ((uint32_t)0x00000007U) /*!< RTC_STAT register reset value */ +#define RTC_PSC_RESET ((uint32_t)0x007F00FFU) /*!< RTC_PSC register reset value */ + +/* RTC timeout value */ +#define RTC_INITM_TIMEOUT ((uint32_t)0x00004000U) /*!< initialization state flag timeout */ +#define RTC_RSYNF_TIMEOUT ((uint32_t)0x00008000U) /*!< register synchronization flag timeout */ +#define RTC_HRFC_TIMEOUT ((uint32_t)0x00001000U) /*!< recalibration pending flag timeout */ +#define RTC_SHIFTCTL_TIMEOUT ((uint32_t)0x00001000U) /*!< shift function operation pending flag timeout */ +#define RTC_ALRM0WF_TIMEOUT ((uint32_t)0x00008000U) /*!< alarm configuration can be write flag timeout */ + +/* RTC flag */ +#define RTC_FLAG_RECALIBRATION RTC_STAT_SCPF /*!< recalibration pending flag */ +#define RTC_FLAG_TAMP1 RTC_STAT_TP1F /*!< tamper 1 event flag */ +#define RTC_FLAG_TAMP0 RTC_STAT_TP0F /*!< tamper 0 event flag */ +#define RTC_FLAG_TIMESTAMP_OVERFLOW RTC_STAT_TSOVRF /*!< time-stamp overflow event flag */ +#define RTC_FLAG_TIMESTAMP RTC_STAT_TSF /*!< time-stamp event flag */ +#define RTC_FLAG_ALARM0 RTC_STAT_ALRM0F /*!< alarm event flag */ +#define RTC_FLAG_INIT RTC_STAT_INITF /*!< init mode event flag */ +#define RTC_FLAG_RSYN RTC_STAT_RSYNF /*!< registers synchronized flag */ +#define RTC_FLAG_YCM RTC_STAT_YCM /*!< year parameter configured event flag */ +#define RTC_FLAG_SHIFT RTC_STAT_SOPF /*!< shift operation pending flag */ +#define RTC_FLAG_ALARM0_WRITTEN RTC_STAT_ALRM0WF /*!< alarm written available flag */ + +/* function declarations */ +/* reset most of the RTC registers */ +ErrStatus rtc_deinit(void); +/* initialize RTC registers */ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct); +/* enter RTC init mode */ +ErrStatus rtc_init_mode_enter(void); +/* exit RTC init mode */ +void rtc_init_mode_exit(void); +/* wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow registers are updated */ +ErrStatus rtc_register_sync_wait(void); + +/* get current time and date */ +void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct); +/* get current subsecond value */ +uint32_t rtc_subsecond_get(void); + +/* configure RTC alarm */ +void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time); +/* configure subsecond of RTC alarm */ +void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond); +/* get RTC alarm */ +void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time); +/* get RTC alarm subsecond */ +uint32_t rtc_alarm_subsecond_get(void); +/* enable RTC alarm */ +void rtc_alarm_enable(void); +/* disable RTC alarm */ +ErrStatus rtc_alarm_disable(void); + +/* enable RTC time-stamp */ +void rtc_timestamp_enable(uint32_t edge); +/* disable RTC time-stamp */ +void rtc_timestamp_disable(void); +/* get RTC timestamp time and date */ +void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp); +/* get RTC time-stamp subsecond */ +uint32_t rtc_timestamp_subsecond_get(void); + +/* enable RTC tamper */ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper); +/* disable RTC tamper */ +void rtc_tamper_disable(uint32_t source); + +/* enable specified RTC interrupt */ +void rtc_interrupt_enable(uint32_t interrupt); +/* disble specified RTC interrupt */ +void rtc_interrupt_disable(uint32_t interrupt); +/* check specified flag */ +FlagStatus rtc_flag_get(uint32_t flag); +/* clear specified flag */ +void rtc_flag_clear(uint32_t flag); + +/* configure RTC alternate output source */ +void rtc_alter_output_config(uint32_t source, uint32_t mode); +/* configure RTC calibration register */ +ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus); +/* ajust the daylight saving time by adding or substracting one hour from the current time */ +void rtc_hour_adjust(uint32_t operation); +/* ajust RTC second or subsecond value of current time */ +ErrStatus rtc_second_ajust(uint32_t add, uint32_t minus); +/* enable RTC bypass shadow registers function */ +void rtc_bypass_shadow_enable(void); +/* disable RTC bypass shadow registers function */ +void rtc_bypass_shadow_disable(void); +/* enable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_enable(void); +/* disable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_disable(void); + +#endif /* GD32F1X0_RTC_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_slcd.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_slcd.h new file mode 100644 index 0000000..76e1002 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_slcd.h @@ -0,0 +1,255 @@ +/*! + \file gd32f1x0_slcd.h + \brief definitions for the SLCD +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 +#ifndef GD32F1X0_SLCD_H +#define GD32F1X0_SLCD_H + +#include "gd32f1x0.h" + +/* SLCD definitions */ +#define SLCD SLCD_BASE + +/* registers definitions */ +#define SLCD_CTL REG32(SLCD + 0x00U) /*!< SLCD controller register */ +#define SLCD_CFG REG32(SLCD + 0x04U) /*!< SLCD configuration register */ +#define SLCD_STAT REG32(SLCD + 0x08U) /*!< SLCD status flag register */ +#define SLCD_STATC REG32(SLCD + 0x0CU) /*!< SLCD status flag clear register */ +#define SLCD_DATA0 REG32(SLCD + 0x14U) /*!< SLCD display data register 0 */ +#define SLCD_DATA1 REG32(SLCD + 0x1CU) /*!< SLCD display data register 1 */ +#define SLCD_DATA2 REG32(SLCD + 0x24U) /*!< SLCD display data register 2 */ +#define SLCD_DATA3 REG32(SLCD + 0x2CU) /*!< SLCD display data register 3 */ +#define SLCD_DATA4 REG32(SLCD + 0x34U) /*!< SLCD display data register 4 */ +#define SLCD_DATA5 REG32(SLCD + 0x3CU) /*!< SLCD display data register 5 */ +#define SLCD_DATA6 REG32(SLCD + 0x44U) /*!< SLCD display data register 6 */ +#define SLCD_DATA7 REG32(SLCD + 0x4CU) /*!< SLCD display data register 7 */ + +/* bits definitions */ +/* SLCD_CTL */ +#define SLCD_CTL_LCDON BIT(0) /*!< SLCD controller start */ +#define SLCD_CTL_VSRC BIT(1) /*!< SLCD Voltage source */ +#define SLCD_CTL_DUTY BITS(2,4) /*!< duty select */ +#define SLCD_CTL_BIAS BITS(5,6) /*!< SLCD bias voltage select */ +#define SLCD_CTL_COMS BIT(7) /*!< regular channel start flag */ + +/* SLCD_CFG */ +#define SLCD_CFG_HDEN BIT(0) /*!< high drive enable */ +#define SLCD_CFG_SOFIE BIT(1) /*!< start of frame interrupt enable */ +#define SLCD_CFG_UPDIE BIT(3) /*!< SLCD update done interrupt enable */ +#define SLCD_CFG_PULSE BITS(4,6) /*!< pulse on duration */ +#define SLCD_CFG_DTD BITS(7,9) /*!< dead time duration */ +#define SLCD_CFG_CONR BITS(10,12) /*!< contrast ratio */ +#define SLCD_CFG_BLKDIV BITS(13,15) /*!< blink frequency divider */ +#define SLCD_CFG_BLKMOD BITS(16,17) /*!< blink mode */ +#define SLCD_CFG_DIV BITS(18,21) /*!< SLCD clock divider */ +#define SLCD_CFG_PSC BITS(22,25) /*!< SLCD clock prescaler */ + +/* SLCD_STAT */ +#define SLCD_STAT_ONF BIT(0) /*!< SLCD controller on flag */ +#define SLCD_STAT_SOF BIT(1) /*!< start of frame flag */ +#define SLCD_STAT_UPRF BIT(2) /*!< SLCD data update request flag */ +#define SLCD_STAT_UPDF BIT(3) /*!< update data done flag */ +#define SLCD_STAT_VRDYF BIT(4) /*!< SLCD voltage ready flag */ +#define SLCD_STAT_SYNF BIT(5) /*!< SLCD register synchronization flag */ + +/* SLCD_STATC */ +#define SLCD_STATC_SOFC BIT(1) /*!< start of frame flag clear */ +#define SLCD_STATC_UPDC BIT(3) /*!< SLCD data update done clear bit */ + +/* SLCD_DATAx */ +#define SLCD_DATAx_DATA BITS(0,31) /*!< each bit corresponds to one segment to display */ + +/* constants definitions */ +/* status flag */ +#define SLCD_FLAG_ON SLCD_STAT_ONF /*!< SLCD controller on flag */ +#define SLCD_FLAG_SOF SLCD_STAT_SOF /*!< start of frame flag */ +#define SLCD_FLAG_UPR SLCD_STAT_UPRF /*!< SLCD data update request flag */ +#define SLCD_FLAG_UPD SLCD_STAT_UPDF /*!< update data done flag */ +#define SLCD_FLAG_VRDY SLCD_STAT_VRDYF /*!< SLCD voltage ready flag */ +#define SLCD_FLAG_SYN SLCD_STAT_SYNF /*!< SLCD register synchronization flag */ + +/* interrupt flag */ +#define SLCD_INT_FLAG_SOF ((uint8_t)0x00U) /*!< start of frame interrupt */ +#define SLCD_INT_FLAG_UPD ((uint8_t)0x01U) /*!< update data done interrupt */ + +/* interrupt source */ +#define SLCD_INT_SOF ((uint8_t)0x00U) /*!< start of frame interrupt */ +#define SLCD_INT_UPD ((uint8_t)0x01U) /*!< update data done interrupt */ + +/* voltage source definitions */ +#define SLCD_VOLTAGE_INTERNAL ((uint8_t)0x00U) /*!< SLCD internal voltage source */ +#define SLCD_VOLTAGE_EXTERNAL ((uint8_t)0x01U) /*!< SLCD external voltage source */ + +/* data register definitions */ +#define SLCD_DATA_REG0 ((uint32_t)0x00000000U) /*!< SLCD display data register 0 */ +#define SLCD_DATA_REG1 ((uint32_t)0x00000002U) /*!< SLCD display data register 1 */ +#define SLCD_DATA_REG2 ((uint32_t)0x00000004U) /*!< SLCD display data register 2 */ +#define SLCD_DATA_REG3 ((uint32_t)0x00000006U) /*!< SLCD display data register 3 */ +#define SLCD_DATA_REG4 ((uint32_t)0x00000008U) /*!< SLCD display data register 4 */ +#define SLCD_DATA_REG5 ((uint32_t)0x0000000AU) /*!< SLCD display data register 5 */ +#define SLCD_DATA_REG6 ((uint32_t)0x0000000CU) /*!< SLCD display data register 6 */ +#define SLCD_DATA_REG7 ((uint32_t)0x0000000EU) /*!< SLCD display data register 7 */ + +/* bias voltage definitions */ +#define CTL_BIAS(regval) (BITS(5,6) & ((uint32_t)(regval) << 5U)) +#define SLCD_BIAS_1_4 CTL_BIAS(0) /*!< 1/4 voltage bias */ +#define SLCD_BIAS_1_2 CTL_BIAS(1) /*!< 1/2 voltage bias */ +#define SLCD_BIAS_1_3 CTL_BIAS(2) /*!< 1/3 voltage bias */ + +/* duty select definitions */ +#define CTL_DUTY(regval) (BITS(2,4) & ((uint32_t)(regval) << 2U)) +#define SLCD_DUTY_STATIC CTL_DUTY(0) /*!< static dutycycle */ +#define SLCD_DUTY_1_2 CTL_DUTY(1) /*!< 1/2 dutycycle */ +#define SLCD_DUTY_1_3 CTL_DUTY(2) /*!< 1/3 dutycycle */ +#define SLCD_DUTY_1_4 CTL_DUTY(3) /*!< 1/4 dutycycle */ +#define SLCD_DUTY_1_6 CTL_DUTY(5) /*!< 1/6 dutycycle */ +#define SLCD_DUTY_1_8 CTL_DUTY(4) /*!< 1/8 dutycycle */ + +/* SLCD clock prescaler */ +#define CFG_PRE(regval) (BITS(22,25) & ((uint32_t)(regval) << 22U)) +#define SLCD_PRESCALER_1 CFG_PRE(0) /*!< PRE = 0 */ +#define SLCD_PRESCALER_2 CFG_PRE(1) /*!< PRE = 1 */ +#define SLCD_PRESCALER_4 CFG_PRE(2) /*!< PRE = 2 */ +#define SLCD_PRESCALER_8 CFG_PRE(3) /*!< PRE = 3 */ +#define SLCD_PRESCALER_16 CFG_PRE(4) /*!< PRE = 4 */ +#define SLCD_PRESCALER_32 CFG_PRE(5) /*!< PRE = 5 */ +#define SLCD_PRESCALER_64 CFG_PRE(6) /*!< PRE = 6 */ +#define SLCD_PRESCALER_128 CFG_PRE(7) /*!< PRE = 7 */ +#define SLCD_PRESCALER_256 CFG_PRE(8) /*!< PRE = 8 */ +#define SLCD_PRESCALER_512 CFG_PRE(9) /*!< PRE = 9 */ +#define SLCD_PRESCALER_1024 CFG_PRE(10) /*!< PRE = 10 */ +#define SLCD_PRESCALER_2048 CFG_PRE(11) /*!< PRE = 11 */ +#define SLCD_PRESCALER_4096 CFG_PRE(12) /*!< PRE = 12 */ +#define SLCD_PRESCALER_8192 CFG_PRE(13) /*!< PRE = 13 */ +#define SLCD_PRESCALER_16384 CFG_PRE(14) /*!< PRE = 14 */ +#define SLCD_PRESCALER_32768 CFG_PRE(15) /*!< PRE = 15 */ + +/* SLCD clock divider */ +#define CFG_DIV(regval) (BITS(18,21) & ((uint32_t)(regval) << 18U)) +#define SLCD_DIVIDER_16 CFG_DIV(0) /*!< DIV = 16 */ +#define SLCD_DIVIDER_17 CFG_DIV(1) /*!< DIV = 17 */ +#define SLCD_DIVIDER_18 CFG_DIV(2) /*!< DIV = 18 */ +#define SLCD_DIVIDER_19 CFG_DIV(3) /*!< DIV = 19 */ +#define SLCD_DIVIDER_20 CFG_DIV(4) /*!< DIV = 20 */ +#define SLCD_DIVIDER_21 CFG_DIV(5) /*!< DIV = 21 */ +#define SLCD_DIVIDER_22 CFG_DIV(6) /*!< DIV = 22 */ +#define SLCD_DIVIDER_23 CFG_DIV(7) /*!< DIV = 23 */ +#define SLCD_DIVIDER_24 CFG_DIV(8) /*!< DIV = 24 */ +#define SLCD_DIVIDER_25 CFG_DIV(9) /*!< DIV = 25 */ +#define SLCD_DIVIDER_26 CFG_DIV(10) /*!< DIV = 26 */ +#define SLCD_DIVIDER_27 CFG_DIV(11) /*!< DIV = 27 */ +#define SLCD_DIVIDER_28 CFG_DIV(12) /*!< DIV = 28 */ +#define SLCD_DIVIDER_29 CFG_DIV(13) /*!< DIV = 29 */ +#define SLCD_DIVIDER_30 CFG_DIV(14) /*!< DIV = 30 */ +#define SLCD_DIVIDER_31 CFG_DIV(15) /*!< DIV = 31 */ + +/* SLCD blink mode */ +#define CFG_BLKM(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define SLCD_BLINKMODE_OFF CFG_BLKM(0) /*!< blink disabled */ +#define SLCD_BLINKMODE_SEG0_COM0 CFG_BLKM(1) /*!< blink enabled on SEG[0], COM[0] */ +#define SLCD_BLINKMODE_SEG0_ALLCOM CFG_BLKM(2) /*!< blink enabled on SEG[0], all COM */ +#define SLCD_BLINKMODE_ALLSEG_ALLCOM CFG_BLKM(3) /*!< blink enabled on all SEG and all COM */ + +/* SLCD blink frequency divider */ +#define CFG_BLKDIV(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U)) +#define SLCD_BLINK_FREQUENCY_DIV8 CFG_BLKDIV(0) /*!< blink frequency = fSLCD/8 */ +#define SLCD_BLINK_FREQUENCY_DIV16 CFG_BLKDIV(1) /*!< blink frequency = fSLCD/16 */ +#define SLCD_BLINK_FREQUENCY_DIV32 CFG_BLKDIV(2) /*!< blink frequency = fSLCD/32 */ +#define SLCD_BLINK_FREQUENCY_DIV64 CFG_BLKDIV(3) /*!< blink frequency = fSLCD/64 */ +#define SLCD_BLINK_FREQUENCY_DIV128 CFG_BLKDIV(4) /*!< blink frequency = fSLCD/128 */ +#define SLCD_BLINK_FREQUENCY_DIV256 CFG_BLKDIV(5) /*!< blink frequency = fSLCD/256 */ +#define SLCD_BLINK_FREQUENCY_DIV512 CFG_BLKDIV(6) /*!< blink frequency = fSLCD/512 */ +#define SLCD_BLINK_FREQUENCY_DIV1024 CFG_BLKDIV(7) /*!< blink frequency = fSLCD/1024 */ + +/* SLCD Contrast ratio */ +#define CFG_CONR(regval) (BITS(10,12) & ((uint32_t)(regval) << 10U)) +#define SLCD_CONTRAST_LEVEL_0 CFG_CONR(0) /*!< maximum SLCD Voltage = 2.60V */ +#define SLCD_CONTRAST_LEVEL_1 CFG_CONR(1) /*!< maximum SLCD Voltage = 2.73V */ +#define SLCD_CONTRAST_LEVEL_2 CFG_CONR(2) /*!< maximum SLCD Voltage = 2.86V */ +#define SLCD_CONTRAST_LEVEL_3 CFG_CONR(3) /*!< maximum SLCD Voltage = 2.99V */ +#define SLCD_CONTRAST_LEVEL_4 CFG_CONR(4) /*!< maximum SLCD Voltage = 3.12V */ +#define SLCD_CONTRAST_LEVEL_5 CFG_CONR(5) /*!< maximum SLCD Voltage = 3.25V */ +#define SLCD_CONTRAST_LEVEL_6 CFG_CONR(6) /*!< maximum SLCD Voltage = 3.38V */ +#define SLCD_CONTRAST_LEVEL_7 CFG_CONR(7) /*!< maximum SLCD Voltage = 3.51V */ + +/* dead time duration */ +#define CFG_DD(regval) (BITS(7,9) & ((uint32_t)(regval) << 7U)) +#define SLCD_DEADTIME_PERIOD_0 CFG_DD(0) /*!< no dead time */ +#define SLCD_DEADTIME_PERIOD_1 CFG_DD(1) /*!< 1 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_2 CFG_DD(2) /*!< 2 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_3 CFG_DD(3) /*!< 3 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_4 CFG_DD(4) /*!< 4 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_5 CFG_DD(5) /*!< 5 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_6 CFG_DD(6) /*!< 6 phase inserted between couple of frame */ +#define SLCD_DEADTIME_PERIOD_7 CFG_DD(7) /*!< 7 phase inserted between couple of frame */ + +/* pulse on duration */ +#define CFG_PULSE(regval) (BITS(4,6) & ((uint32_t)(regval) << 4U)) +#define SLCD_PULSEON_DURATION_0 CFG_PULSE(0) /*!< pulse on duration = 0 */ +#define SLCD_PULSEON_DURATION_1 CFG_PULSE(1) /*!< pulse on duration = 1*1/fPRE */ +#define SLCD_PULSEON_DURATION_2 CFG_PULSE(2) /*!< pulse on duration = 2*1/fPRE */ +#define SLCD_PULSEON_DURATION_3 CFG_PULSE(3) /*!< pulse on duration = 3*1/fPRE */ +#define SLCD_PULSEON_DURATION_4 CFG_PULSE(4) /*!< pulse on duration = 4*1/fPRE */ +#define SLCD_PULSEON_DURATION_5 CFG_PULSE(5) /*!< pulse on duration = 5*1/fPRE */ +#define SLCD_PULSEON_DURATION_6 CFG_PULSE(6) /*!< pulse on duration = 6*1/fPRE */ +#define SLCD_PULSEON_DURATION_7 CFG_PULSE(7) /*!< pulse on duration = 7*1/fPRE */ + +/* function declarations */ +/* check the SLCD status flag */ +FlagStatus slcd_flag_get(uint8_t slcd_flag); +/* check the SLCD interrupt flag */ +FlagStatus slcd_interrupt_flag_get(uint8_t slcd_interrupt); +/* clear the SLCD flag */ +void slcd_flag_clear(uint8_t slcd_flag); +/* clear the SLCD interrupt flag */ +void slcd_interrupt_flag_clear(uint8_t slcd_interrupt); +/* the SLCD interrupt config */ +void slcd_interrupt_config(uint8_t slcd_interrupt,ControlStatus newvalue); + +/* SLCD bias voltage select */ +void slcd_bias_voltage_select(uint32_t bias_voltage); +/* SLCD duty select */ +void slcd_duty_select(uint32_t duty); +/* SLCD input clock config */ +void slcd_clock_config(uint32_t prescaler,uint32_t divider); +/* SLCD blink mode config */ +void slcd_blink_mode_config(uint32_t mode,uint32_t blink_divider); +/* SLCD contrast ratio config */ +void slcd_contrast_ratio_config(uint32_t contrast_ratio); +/* SLCD dead time duration config */ +void slcd_dead_time_config(uint32_t dead_time); +/* SLCD pulse on duration config */ +void slcd_pulse_on_duration_config(uint32_t duration); +/* SLCD common/segment pad select */ +void slcd_com_seg_remap(ControlStatus newvalue); +/* SLCD voltage source select */ +void slcd_voltage_source_select(uint8_t voltage_source); +/* SLCD high drive enable */ +void slcd_high_drive_config(ControlStatus newvalue); + +/* SLCD data register write */ +void slcd_data_register_write(uint32_t data_reg,uint32_t data); +/* SLCD data update request */ +void slcd_data_update_request(void); + +/* SLCD reset */ +void slcd_deinit(void); +/* enable SLCD interface */ +void slcd_enable(void); +/* disable SLCD interface */ +void slcd_disable(void); + +#endif /* GD32F1X0_SLCD_H */ + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_spi.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_spi.h new file mode 100644 index 0000000..82ad8a1 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_spi.h @@ -0,0 +1,321 @@ +/*! + \file gd32f1x0_spi.h + \brief definitions for the SPI +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_SPI_H +#define GD32F1X0_SPI_H + +#include "gd32f1x0.h" + +/* SPIx(x=0,1,2) definitions */ +#define SPI0 (SPI_BASE + 0x0000F800U) +#define SPI1 SPI_BASE +#define SPI2 (SPI_BASE + 0x00000400U) + +/* registers definitions */ +#define SPI_CTL0(spix) REG32((spix) + 0x00U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x04U) /*!< SPI control register 1*/ +#define SPI_STAT(spix) REG32((spix) + 0x08U) /*!< SPI status register */ +#define SPI_DATA(spix) REG32((spix) + 0x0CU) /*!< SPI data register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x10U) /*!< SPI CRC polynomial register */ +#define SPI_RCRC(spix) REG32((spix) + 0x14U) /*!< SPI receive CRC register */ +#define SPI_TCRC(spix) REG32((spix) + 0x18U) /*!< SPI transmit CRC register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x1CU) /*!< SPI I2S control register */ +#define SPI_I2SPSC(spix) REG32((spix) + 0x20U) /*!< SPI I2S clock prescaler register */ +#ifdef GD32F170_190 +#define SPI_QCTL(spix) REG32((spix) + 0x80U) /*!< SPI quad wire control register */ +#endif /* GD32F170_190 */ + +/* 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 selection */ +#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 transfer next */ +#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_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 config error */ +#define SPI_STAT_RXORERR BIT(6) /*!< SPI reception overrun error Bit */ +#define SPI_STAT_TRANS BIT(7) /*!< transmitting on-going 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_I2S_PSC */ +#define SPI_I2SPSC_DIV BITS(0,7) /*!< dividing factor for the prescaler */ +#define SPI_I2SPSC_OF BIT(8) /*!< odd factor for the prescaler */ +#define SPI_I2SPSC_MCKOEN BIT(9) /*!< I2S MCK output enable */ + +#ifdef GD32F170_190 +/* SPI_QCTL */ +#define SPI_QCTL_QMOD BIT(0) /*!< quad wire mode enable. */ +#define SPI_QCTL_QRD BIT(1) /*!< quad wire read select. */ +#define SPI_QCTL_IO23_DRV BIT(2) /*!< drive SPI_IO2 and SPI_IO3 */ +#endif /* GD32F170_190 */ + +/* 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 prescale factor */ +#define CTL0_PSC(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) +#define SPI_PSC_2 CTL0_PSC(0) /*!< SPI clock prescale factor is 2 */ +#define SPI_PSC_4 CTL0_PSC(1) /*!< SPI clock prescale factor is 4 */ +#define SPI_PSC_8 CTL0_PSC(2) /*!< SPI clock prescale factor is 8 */ +#define SPI_PSC_16 CTL0_PSC(3) /*!< SPI clock prescale factor is 16 */ +#define SPI_PSC_32 CTL0_PSC(4) /*!< SPI clock prescale factor is 32 */ +#define SPI_PSC_64 CTL0_PSC(5) /*!< SPI clock prescale factor is 64 */ +#define SPI_PSC_128 CTL0_PSC(6) /*!< SPI clock prescale factor is 128 */ +#define SPI_PSC_256 CTL0_PSC(7) /*!< SPI clock prescale factor is 256 */ + +/* I2S audio sample rate */ +#define I2S_AUDIOSAMPLE_8K ((uint32_t)8000U) /*!< I2S audio sample rate is 8KHz */ +#define I2S_AUDIOSAMPLE_11K ((uint32_t)11025U) /*!< I2S audio sample rate is 11KHz */ +#define I2S_AUDIOSAMPLE_16K ((uint32_t)16000U) /*!< I2S audio sample rate is 16KHz */ +#define I2S_AUDIOSAMPLE_22K ((uint32_t)22050U) /*!< I2S audio sample rate is 22KHz */ +#define I2S_AUDIOSAMPLE_32K ((uint32_t)32000U) /*!< I2S audio sample rate is 32KHz */ +#define I2S_AUDIOSAMPLE_44K ((uint32_t)44100U) /*!< I2S audio sample rate is 44KHz */ +#define I2S_AUDIOSAMPLE_48K ((uint32_t)48000U) /*!< I2S audio sample rate is 48KHz */ +#define I2S_AUDIOSAMPLE_96K ((uint32_t)96000U) /*!< I2S audio sample rate is 96KHz */ +#define I2S_AUDIOSAMPLE_192K ((uint32_t)192000U) /*!< I2S audio sample rate is 192KHz */ + +/* I2S frame format */ +#define I2SCTL_DTLEN(regval) (BITS(1,2) & ((uint32_t)(regval) << 1)) +#define I2S_FRAMEFORMAT_DT16B_CH16B I2SCTL_DTLEN(0) /*!< I2S data length is 16 bit and channel length is 16 bit */ +#define I2S_FRAMEFORMAT_DT16B_CH32B (I2SCTL_DTLEN(0) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 16 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT24B_CH32B (I2SCTL_DTLEN(1) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 24 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT32B_CH32B (I2SCTL_DTLEN(2) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 32 bit and channel length is 32 bit */ + +/* I2S master clock output */ +#define I2S_MCKOUT_DISABLE ((uint32_t)0x00000000U) /*!< I2S master clock output disable */ +#define I2S_MCKOUT_ENABLE SPI_I2SPSC_MCKOEN /*!< I2S master clock output enable */ + +/* I2S operation mode */ +#define I2SCTL_I2SOPMOD(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define I2S_MODE_SLAVETX I2SCTL_I2SOPMOD(0) /*!< I2S slave transmit mode */ +#define I2S_MODE_SLAVERX I2SCTL_I2SOPMOD(1) /*!< I2S slave receive mode */ +#define I2S_MODE_MASTERTX I2SCTL_I2SOPMOD(2) /*!< I2S master transmit mode */ +#define I2S_MODE_MASTERRX I2SCTL_I2SOPMOD(3) /*!< I2S master receive mode */ + +/* I2S standard */ +#define I2SCTL_I2SSTD(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define I2S_STD_PHILLIPS I2SCTL_I2SSTD(0) /*!< I2S phillips standard */ +#define I2S_STD_MSB I2SCTL_I2SSTD(1) /*!< I2S MSB standard */ +#define I2S_STD_LSB I2SCTL_I2SSTD(2) /*!< I2S LSB standard */ +#define I2S_STD_PCMSHORT I2SCTL_I2SSTD(3) /*!< I2S PCM short standard */ +#define I2S_STD_PCMLONG (I2SCTL_I2SSTD(3) | SPI_I2SCTL_PCMSMOD) /*!< I2S PCM long standard */ + +/* I2S clock polarity */ +#define I2S_CKPL_LOW ((uint32_t)0x00000000U) /*!< I2S clock polarity low level */ +#define I2S_CKPL_HIGH SPI_I2SCTL_CKPL /*!< I2S clock polarity high level */ + +/* SPI DMA constants definitions */ +#define SPI_DMA_TRANSMIT ((uint8_t)0x00U) /*!< SPI transmit data use DMA */ +#define SPI_DMA_RECEIVE ((uint8_t)0x01U) /*!< SPI receive data use DMA */ + +/* SPI CRC constants definitions */ +#define SPI_CRC_TX ((uint8_t)0x00U) /*!< SPI transmit CRC value */ +#define SPI_CRC_RX ((uint8_t)0x01U) /*!< SPI receive CRC value */ + +/* SPI/I2S interrupt enable/disable constants definitions */ +#define SPI_I2S_INT_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt */ +#define SPI_I2S_INT_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt */ +#define SPI_I2S_INT_ERR ((uint8_t)0x02U) /*!< error interrupt */ + +/* SPI/I2S interrupt flag constants definitions */ +#define SPI_I2S_INT_FLAG_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt */ +#define SPI_I2S_INT_FLAG_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt */ +#define SPI_I2S_INT_FLAG_RXORERR ((uint8_t)0x02U) /*!< overrun interrupt */ +#define SPI_INT_FLAG_CONFERR ((uint8_t)0x03U) /*!< config error interrupt */ +#define SPI_INT_FLAG_CRCERR ((uint8_t)0x04U) /*!< CRC error interrupt */ +#define I2S_INT_FLAG_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt */ + +/* 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 flag */ +#define SPI_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define I2S_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define I2S_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define I2S_FLAG_CH SPI_STAT_I2SCH /*!< transmit buffer empty interrupt */ +#define I2S_FLAG_TXURERR SPI_STAT_TXURERR /*!< underrun error flag */ +#define I2S_FLAG_RXORERR SPI_STAT_RXORERR /*!< overrun flag */ +#define I2S_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ + +/* function declarations */ +/* reset SPI and I2S */ +void spi_i2s_deinit(uint32_t spi_periph); +/* initialize SPI parameter */ +void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct); +/* enable SPI */ +void spi_enable(uint32_t spi_periph); +/* disable SPI */ +void spi_disable(uint32_t spi_periph); + +/* configure I2S prescaler */ +void i2s_psc_config(uint32_t spi_periph,uint32_t audiosample,uint32_t frameformat,uint32_t mckout); +/* initialize I2S parameter */ +void i2s_init(uint32_t spi_periph,uint32_t mode,uint32_t standard,uint32_t ckpl); +/* enable I2S */ +void i2s_enable(uint32_t spi_periph); +/* disable I2S */ +void i2s_disable(uint32_t spi_periph); + +/* 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); + +/* enable SPI DMA */ +void spi_dma_enable(uint32_t spi_periph, uint8_t dma); +/* disable SPI DMA */ +void spi_dma_disable(uint32_t spi_periph, uint8_t dma); + +/* configure SPI/I2S data frame format */ +void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format); +/* SPI transmit data */ +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data); +/* SPI receive data */ +uint16_t spi_i2s_data_receive(uint32_t spi_periph); +/* configure SPI bidirectional transfer direction */ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction); + +/* 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); +/* get SPI and I2S flag status */ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph,uint32_t flag); +/* clear SPI CRC error flag status */ +void spi_crc_error_clear(uint32_t spi_periph); + +/* 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); + +#ifdef GD32F170_190 +/* enable quad wire SPI */ +void qspi_enable(uint32_t spi_periph); +/* disable quad wire SPI */ +void qspi_disable(uint32_t spi_periph); +/* enable quad wire SPI write */ +void qspi_write_enable(uint32_t spi_periph); +/* enable quad wire SPI read */ +void qspi_read_enable(uint32_t spi_periph); +/* enable quad wire SPI_IO2 and SPI_IO3 pin output */ +void qspi_io23_output_enable(uint32_t spi_periph); +/* disable quad wire SPI_IO2 and SPI_IO3 pin output */ +void qspi_io23_output_disable(uint32_t spi_periph); +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_SPI_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_syscfg.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_syscfg.h new file mode 100644 index 0000000..592966e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_syscfg.h @@ -0,0 +1,182 @@ +/*! + \file gd32f1x0_syscfg.h + \brief definitions for the SYSCFG +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_SYSCFG_H +#define GD32F1X0_SYSCFG_H + +#include "gd32f1x0.h" + +/* SYSCFG definitions */ +#define SYSCFG SYSCFG_BASE + +/* registers definitions */ +#define SYSCFG_CFG0 REG32(SYSCFG + 0x00U) /*!< system configuration register 0 */ +#ifdef GD32F170_190 +#define SYSCFG_CFG1 REG32(SYSCFG + 0x04U) /*!< system configuration register 1 */ +#endif /* GD32F170_190 */ +#define SYSCFG_EXTISS0 REG32(SYSCFG + 0x08U) /*!< EXTI sources selection register 0 */ +#define SYSCFG_EXTISS1 REG32(SYSCFG + 0x0CU) /*!< EXTI sources selection register 1 */ +#define SYSCFG_EXTISS2 REG32(SYSCFG + 0x10U) /*!< EXTI sources selection register 2 */ +#define SYSCFG_EXTISS3 REG32(SYSCFG + 0x14U) /*!< EXTI sources selection register 3 */ +#define SYSCFG_CFG2 REG32(SYSCFG + 0x18U) /*!< system configuration register 2 */ + +/* SYSCFG_CFG0 bits definitions */ +#define SYSCFG_CFG0_BOOT_MODE BITS(0,1) /*!< SYSCFG memory remap config */ +#define SYSCFG_CFG0_ADC_DMA_RMP BIT(8) /*!< ADC DMA remap config */ +#define SYSCFG_CFG0_USART0_TX_DMA_RMP BIT(9) /*!< USART0 Tx DMA remap config */ +#define SYSCFG_CFG0_USART0_RX_DMA_RMP BIT(10) /*!< USART0 Rx DMA remap config */ +#define SYSCFG_CFG0_TIMER15_DMA_RMP BIT(11) /*!< TIMER 15 DMA remap config */ +#define SYSCFG_CFG0_TIMER16_DMA_RMP BIT(12) /*!< TIMER 16 DMA remap config */ +#define SYSCFG_CFG0_PB9_HCCE BIT(19) /*!< PB9 pin high current capability enable */ + +#ifdef GD32F170_190 +/* SYSCFG_CFG1 bits definitions */ +#define SYSCFG_CFG1_SLCD_DECA BITS(1,3) /*!< decouping capacitance connection for LCD */ +#endif /* GD32F170_190 */ + +/* SYSCFG_EXTISS0 bits definitions */ +#define SYSCFG_EXTISS0_EXTI0_SS BITS(0,3) /*!< EXTI 0 configuration */ +#define SYSCFG_EXTISS0_EXTI1_SS BITS(4,7) /*!< EXTI 1 configuration */ +#define SYSCFG_EXTISS0_EXTI2_SS BITS(8,11) /*!< EXTI 2 configuration */ +#define SYSCFG_EXTISS0_EXTI3_SS BITS(12,15) /*!< EXTI 3 configuration */ + +/* SYSCFG_EXTISS1 bits definitions */ +#define SYSCFG_EXTISS1_EXTI4_SS BITS(0,3) /*!< EXTI 4 configuration */ +#define SYSCFG_EXTISS1_EXTI5_SS BITS(4,7) /*!< EXTI 5 configuration */ +#define SYSCFG_EXTISS1_EXTI6_SS BITS(8,11) /*!< EXTI 6 configuration */ +#define SYSCFG_EXTISS1_EXTI7_SS BITS(12,15) /*!< EXTI 7 configuration */ + +/* SYSCFG_EXTISS2 bits definitions */ +#define SYSCFG_EXTISS2_EXTI8_SS BITS(0,3) /*!< EXTI 8 configuration */ +#define SYSCFG_EXTISS2_EXTI9_SS BITS(4,7) /*!< EXTI 9 configuration */ +#define SYSCFG_EXTISS2_EXTI10_SS BITS(8,11) /*!< EXTI 10 configuration */ +#define SYSCFG_EXTISS2_EXTI11_SS BITS(12,15) /*!< EXTI 11 configuration */ + +/* SYSCFG_EXTISS3 bits definitions */ +#define SYSCFG_EXTISS3_EXTI12_SS BITS(0,3) /*!< EXTI 12 configuration */ +#define SYSCFG_EXTISS3_EXTI13_SS BITS(4,7) /*!< EXTI 13 configuration */ +#define SYSCFG_EXTISS3_EXTI14_SS BITS(8,11) /*!< EXTI 14 configuration */ +#define SYSCFG_EXTISS3_EXTI15_SS BITS(12,15) /*!< EXTI 15 configuration */ + +/* SYSCFG_CFG2 bits definitions */ +#define SYSCFG_CFG2_LOCKUP_LOCK BIT(0) /*!< enable and lock the LOCKUP (Hardfault) output of Cortex-M4 with break input of TIMER0/14/15/16 */ +#define SYSCFG_CFG2_SRAM_PARITY_ERROR_LOCK BIT(1) /*!< enable and lock the SRAM_PARITY error signal with break input of TIMER0/14/15/16 */ +#define SYSCFG_CFG2_LVD_LOCK BIT(2) /*!< enable and lock the LVD connection with TIMER0 break input and also the LVD_EN and LVDSEL[2:0] bits of the power control interface */ +#define SYSCFG_CFG2_SRAM_PCEF BIT(8) /*!< SRAM parity check error flag */ + +/* constants definitions */ +/* DMA remap definitions */ +#define SYSCFG_DMA_REMAP_ADC SYSCFG_CFG0_ADC_DMA_RMP /*!< ADC DMA remap */ +#define SYSCFG_DMA_REMAP_USART0TX SYSCFG_CFG0_USART0_TX_DMA_RMP /*!< USART0_TX DMA remap */ +#define SYSCFG_DMA_REMAP_USART0RX SYSCFG_CFG0_USART0_RX_DMA_RMP /*!< USART0_RX DMA remap */ +#define SYSCFG_DMA_REMAP_TIMER15 SYSCFG_CFG0_TIMER15_DMA_RMP /*!< TIMER15 DMA remap */ +#define SYSCFG_DMA_REMAP_TIMER16 SYSCFG_CFG0_TIMER16_DMA_RMP /*!< TIMER16 DMA remap */ + +/* high current definitions */ +#define SYSCFG_HIGH_CURRENT_ENABLE SYSCFG_CFG0_PB9_HCCE /*!< high current enable */ +#define SYSCFG_HIGH_CURRENT_DISABLE (~SYSCFG_CFG0_PB9_HCCE) /*!< high current disable */ + +/* EXTI source select definition */ +#define EXTISS0 ((uint8_t)0x00U) /*!< EXTI source select register 0 */ +#define EXTISS1 ((uint8_t)0x01U) /*!< EXTI source select register 1 */ +#define EXTISS2 ((uint8_t)0x02U) /*!< EXTI source select register 2 */ +#define EXTISS3 ((uint8_t)0x03U) /*!< EXTI source select register 3 */ + +/* EXTI source select mask bits definition */ +#define EXTI_SS_MASK BITS(0,3) /*!< EXTI source select mask */ + +/* EXTI source select jumping step definition */ +#define EXTI_SS_JSTEP ((uint8_t)(0x04U)) /*!< EXTI source select jumping step */ + +/* EXTI source select moving step definition */ +#define EXTI_SS_MSTEP(pin) (EXTI_SS_JSTEP * ((pin) % EXTI_SS_JSTEP)) /*!< EXTI source select moving step */ + +/* EXTI source port definitions */ +#define EXTI_SOURCE_GPIOA ((uint8_t)0x00U) /*!< EXTI GPIOA configuration */ +#define EXTI_SOURCE_GPIOB ((uint8_t)0x01U) /*!< EXTI GPIOB configuration */ +#define EXTI_SOURCE_GPIOC ((uint8_t)0x02U) /*!< EXTI GPIOC configuration */ +#define EXTI_SOURCE_GPIOD ((uint8_t)0x03U) /*!< EXTI GPIOD configuration */ +#define EXTI_SOURCE_GPIOF ((uint8_t)0x05U) /*!< EXTI GPIOF configuration */ + +/* EXTI 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_PARITY_ERROR SYSCFG_CFG2_SRAM_PARITY_ERROR_LOCK /*!< SRAM parity error lock */ +#define SYSCFG_LOCK_LVD SYSCFG_CFG2_LVD_LOCK /*!< LVD lock */ + +/* SRAM parity check error flag definitions */ +#define SYSCFG_SRAM_PCEF SYSCFG_CFG2_SRAM_PCEF /*!< SRAM parity check error flag */ + +#ifdef GD32F170_190 +#define SYSCFG_LCD_DECA(regval) (BITS(1,3) & ((uint32_t)(regval) << 1)) +#define SYSCFG_VLCD_RAIL1 SYSCFG_LCD_DECA(2) /*!< VLCD rail1 */ +#define SYSCFG_VLCD_RAIL2 SYSCFG_LCD_DECA(1) /*!< VLCD rail2 */ +#define SYSCFG_VLCD_RAIL3 SYSCFG_LCD_DECA(4) /*!< VLCD rail3 */ + +/* VLCD bias definition */ +#define VLCD_BIAS1_2_RAIL1 ((uint8_t)0) /*!< VLCD bias is 1/2, using VLCDrail1 */ +#define VLCD_BIAS1_2_RAIL2 ((uint8_t)1) /*!< VLCD bias is 1/2, using VLCDrail2 */ +#define VLCD_BIAS1_2_RAIL3 ((uint8_t)2) /*!< VLCD bias is 1/2, using VLCDrail3 */ +#define VLCD_BIAS1_3_RAIL1_2 ((uint8_t)3) /*!< VLCD bias is 1/3, using VLCDrail1 and VLCDrail2 */ +#define VLCD_BIAS1_3_RAIL1_3 ((uint8_t)4) /*!< VLCD bias is 1/3, using VLCDrail1 and VLCDrail3 */ +#define VLCD_BIAS1_4_RAILALL ((uint8_t)5) /*!< VLCD bias is 1/4, using all VLCDrails */ +#endif /* GD32F170_190 */ + +/* function declarations */ +/* deinit syscfg module */ +void syscfg_deinit(void); + +/* enable the DMA channels remapping */ +void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap); +/* disable the DMA channels remapping */ +void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap); + +/* enable PB9 high current capability */ +void syscfg_high_current_enable(void); +/* disable PB9 high current capability */ +void syscfg_high_current_disable(void); + +/* configure the GPIO pin as EXTI Line */ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin); +/* connect TIMER0/14/15/16 break input to the selected parameter */ +void syscfg_lock_config(uint32_t syscfg_lock); + +/* check if the specified flag in SYSCFG_CFG2 is set or not */ +FlagStatus syscfg_flag_get(uint32_t syscfg_flag); +/* clear the flag in SYSCFG_CFG2 by writing 1 */ +void syscfg_flag_clear(uint32_t syscfg_flag); + +#ifdef GD32F170_190 +/* configure the VLCD intermediate voltage rail */ +void syscfg_vlcd_rail_config(uint8_t vlcd_bias); +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_SYSCFG_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_timer.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_timer.h new file mode 100644 index 0000000..f1e377a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_timer.h @@ -0,0 +1,760 @@ +/*! + \file gd32f1x0_timer.h + \brief definitions for the TIMER +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_TIMER_H +#define GD32F1X0_TIMER_H + +#include "gd32f1x0.h" + +/* TIMERx(x=0,1,2,5,13,14,15,16) definitions */ +#define TIMER0 (TIMER_BASE + 0x00012C00U) +#define TIMER1 (TIMER_BASE + 0x00000000U) +#define TIMER2 (TIMER_BASE + 0x00000400U) +#define TIMER5 (TIMER_BASE + 0x00001000U) +#define TIMER13 (TIMER_BASE + 0x00002000U) +#define TIMER14 (TIMER_BASE + 0x00014000U) +#define TIMER15 (TIMER_BASE + 0x00014400U) +#define TIMER16 (TIMER_BASE + 0x00014800U) + +/* registers definitions */ +#define TIMER_CTL0(timerx) REG32((timerx) + 0x00U) /*!< TIMER control register 0 */ +#define TIMER_CTL1(timerx) REG32((timerx) + 0x04U) /*!< TIMER control register 1 */ +#define TIMER_SMCFG(timerx) REG32((timerx) + 0x08U) /*!< TIMER slave mode configuration register */ +#define TIMER_DMAINTEN(timerx) REG32((timerx) + 0x0CU) /*!< TIMER DMA and interrupt enable register */ +#define TIMER_INTF(timerx) REG32((timerx) + 0x10U) /*!< TIMER interrupt flag register */ +#define TIMER_SWEVG(timerx) REG32((timerx) + 0x14U) /*!< TIMER software event generation register */ +#define TIMER_CHCTL0(timerx) REG32((timerx) + 0x18U) /*!< TIMER channel control register 0 */ +#define TIMER_CHCTL1(timerx) REG32((timerx) + 0x1CU) /*!< TIMER channel control register 1 */ +#define TIMER_CHCTL2(timerx) REG32((timerx) + 0x20U) /*!< TIMER channel control register 2 */ +#define TIMER_CNT(timerx) REG32((timerx) + 0x24U) /*!< TIMER counter register */ +#define TIMER_PSC(timerx) REG32((timerx) + 0x28U) /*!< TIMER prescaler register */ +#define TIMER_CAR(timerx) REG32((timerx) + 0x2CU) /*!< TIMER counter auto reload register */ +#define TIMER_CREP(timerx) REG32((timerx) + 0x30U) /*!< TIMER counter repetition register */ +#define TIMER_CH0CV(timerx) REG32((timerx) + 0x34U) /*!< TIMER channel 0 capture/compare value register */ +#define TIMER_CH1CV(timerx) REG32((timerx) + 0x38U) /*!< TIMER channel 1 capture/compare value register */ +#define TIMER_CH2CV(timerx) REG32((timerx) + 0x3CU) /*!< TIMER channel 2 capture/compare value register */ +#define TIMER_CH3CV(timerx) REG32((timerx) + 0x40U) /*!< TIMER channel 3 capture/compare value register */ +#define TIMER_CCHP(timerx) REG32((timerx) + 0x44U) /*!< TIMER complementary channel protection register */ +#define TIMER_DMACFG(timerx) REG32((timerx) + 0x48U) /*!< TIMER DMA configuration register */ +#define TIMER_DMATB(timerx) REG32((timerx) + 0x4CU) /*!< TIMER DMA transfer buffer register */ +#define TIMER_IRMP(timerx) REG32((timerx) + 0x50U) /*!< TIMER channel input remap register(only for TIMER13) */ +#define TIMER_CFG(timerx) REG32((timerx) + 0xFCU) /*!< TIMER configuration register */ + +/* bits definitions */ +/* TIMER_CTL0 */ +#define TIMER_CTL0_CEN BIT(0) /*!< TIMER counter enable */ +#define TIMER_CTL0_UPDIS BIT(1) /*!< update disable */ +#define TIMER_CTL0_UPS BIT(2) /*!< update source */ +#define TIMER_CTL0_SPM BIT(3) /*!< single pulse mode */ +#define TIMER_CTL0_DIR BIT(4) /*!< timer counter direction */ +#define TIMER_CTL0_CAM BITS(5,6) /*!< center-aligned mode selection */ +#define TIMER_CTL0_ARSE BIT(7) /*!< auto-reload shadow enable */ +#define TIMER_CTL0_CKDIV BITS(8,9) /*!< clock division */ + +/* TIMER_CTL1 */ +#define TIMER_CTL1_CCSE BIT(0) /*!< commutation control shadow register enable */ +#define TIMER_CTL1_CCUC BIT(2) /*!< commutation control shadow register update control */ +#define TIMER_CTL1_DMAS BIT(3) /*!< DMA request source selection */ +#define TIMER_CTL1_MMC BITS(4,6) /*!< master mode control */ +#define TIMER_CTL1_TI0S BIT(7) /*!< channel 0 trigger input selection(hall mode selection) */ +#define TIMER_CTL1_ISO0 BIT(8) /*!< idle state of channel 0 output */ +#define TIMER_CTL1_ISO0N BIT(9) /*!< idle state of channel 0 complementary output */ +#define TIMER_CTL1_ISO1 BIT(10) /*!< idle state of channel 1 output */ +#define TIMER_CTL1_ISO1N BIT(11) /*!< idle state of channel 1 complementary output */ +#define TIMER_CTL1_ISO2 BIT(12) /*!< idle state of channel 2 output */ +#define TIMER_CTL1_ISO2N BIT(13) /*!< idle state of channel 2 complementary output */ +#define TIMER_CTL1_ISO3 BIT(14) /*!< idle state of channel 3 output */ + +/* TIMER_SMCFG */ +#define TIMER_SMCFG_SMC BITS(0,2) /*!< slave mode control */ +#define TIMER_SMCFG_OCRC BIT(3) /*!< OCPRE clear source selection */ +#define TIMER_SMCFG_TRGS BITS(4,6) /*!< trigger selection */ +#define TIMER_SMCFG_MSM BIT(7) /*!< master-slave mode */ +#define TIMER_SMCFG_ETFC BITS(8,11) /*!< external trigger filter control */ +#define TIMER_SMCFG_ETPSC BITS(12,13) /*!< external trigger prescaler */ +#define TIMER_SMCFG_SMC1 BIT(14) /*!< part of SMC for enable external clock mode 1 */ +#define TIMER_SMCFG_ETP BIT(15) /*!< external trigger polarity */ + +/* TIMER_DMAINTEN */ +#define TIMER_DMAINTEN_UPIE BIT(0) /*!< update interrupt enable */ +#define TIMER_DMAINTEN_CH0IE BIT(1) /*!< channel 0 interrupt enable */ +#define TIMER_DMAINTEN_CH1IE BIT(2) /*!< channel 1 interrupt enable */ +#define TIMER_DMAINTEN_CH2IE BIT(3) /*!< channel 2 interrupt enable */ +#define TIMER_DMAINTEN_CH3IE BIT(4) /*!< channel 3 interrupt enable */ +#define TIMER_DMAINTEN_CMTIE BIT(5) /*!< commutation DMA request enable */ +#define TIMER_DMAINTEN_TRGIE BIT(6) /*!< trigger interrupt enable */ +#define TIMER_DMAINTEN_BRKIE BIT(7) /*!< break interrupt enable */ +#define TIMER_DMAINTEN_UPDEN BIT(8) /*!< update DMA request enable */ +#define TIMER_DMAINTEN_CH0DEN BIT(9) /*!< channel 0 DMA request enable */ +#define TIMER_DMAINTEN_CH1DEN BIT(10) /*!< channel 1 DMA request enable */ +#define TIMER_DMAINTEN_CH2DEN BIT(11) /*!< channel 2 DMA request enable */ +#define TIMER_DMAINTEN_CH3DEN BIT(12) /*!< channel 3 DMA request enable */ +#define TIMER_DMAINTEN_CMTDEN BIT(13) /*!< channel control update DMA request enable */ +#define TIMER_DMAINTEN_TRGDEN BIT(14) /*!< trigger DMA request enable */ + +/* TIMER_INTF */ +#define TIMER_INTF_UPIF BIT(0) /*!< update interrupt flag */ +#define TIMER_INTF_CH0IF BIT(1) /*!< channel 0 interrupt flag */ +#define TIMER_INTF_CH1IF BIT(2) /*!< channel 1 interrupt flag */ +#define TIMER_INTF_CH2IF BIT(3) /*!< channel 2 interrupt flag */ +#define TIMER_INTF_CH3IF BIT(4) /*!< channel 3 interrupt flag */ +#define TIMER_INTF_CMTIF BIT(5) /*!< channel commutation interrupt flag */ +#define TIMER_INTF_TRGIF BIT(6) /*!< trigger interrupt flag */ +#define TIMER_INTF_BRKIF BIT(7) /*!< break interrupt flag */ +#define TIMER_INTF_CH0OF BIT(9) /*!< channel 0 overcapture flag */ +#define TIMER_INTF_CH1OF BIT(10) /*!< channel 1 overcapture flag */ +#define TIMER_INTF_CH2OF BIT(11) /*!< channel 2 overcapture flag */ +#define TIMER_INTF_CH3OF BIT(12) /*!< channel 3 overcapture flag */ + +/* TIMER_SWEVG */ +#define TIMER_SWEVG_UPG BIT(0) /*!< update event generate */ +#define TIMER_SWEVG_CH0G BIT(1) /*!< channel 0 capture or compare event generation */ +#define TIMER_SWEVG_CH1G BIT(2) /*!< channel 1 capture or compare event generation */ +#define TIMER_SWEVG_CH2G BIT(3) /*!< channel 2 capture or compare event generation */ +#define TIMER_SWEVG_CH3G BIT(4) /*!< channel 3 capture or compare event generation */ +#define TIMER_SWEVG_CMTG BIT(5) /*!< channel commutation event generation */ +#define TIMER_SWEVG_TRGG BIT(6) /*!< trigger event generation */ +#define TIMER_SWEVG_BRKG BIT(7) /*!< break event generation */ + +/* TIMER_CHCTL0 */ +/* output compare mode */ +#define TIMER_CHCTL0_CH0MS BITS(0,1) /*!< channel 0 mode selection */ +#define TIMER_CHCTL0_CH0COMFEN BIT(2) /*!< channel 0 output compare fast enable */ +#define TIMER_CHCTL0_CH0COMSEN BIT(3) /*!< channel 0 output compare shadow enable */ +#define TIMER_CHCTL0_CH0COMCTL BITS(4,6) /*!< channel 0 output compare mode */ +#define TIMER_CHCTL0_CH0COMCEN BIT(7) /*!< channel 0 output compare clear enable */ +#define TIMER_CHCTL0_CH1MS BITS(8,9) /*!< channel 1 mode selection */ +#define TIMER_CHCTL0_CH1COMFEN BIT(10) /*!< channel 1 output compare fast enable */ +#define TIMER_CHCTL0_CH1COMSEN BIT(11) /*!< channel 1 output compare shadow enable */ +#define TIMER_CHCTL0_CH1COMCTL BITS(12,14) /*!< channel 1 output compare mode */ +#define TIMER_CHCTL0_CH1COMCEN BIT(15) /*!< channel 1 output compare clear enable */ +/* input capture mode */ +#define TIMER_CHCTL0_CH0CAPPSC BITS(2,3) /*!< channel 0 input capture prescaler */ +#define TIMER_CHCTL0_CH0CAPFLT BITS(4,7) /*!< channel 0 input capture filter control */ +#define TIMER_CHCTL0_CH1CAPPSC BITS(10,11) /*!< channel 1 input capture prescaler */ +#define TIMER_CHCTL0_CH1CAPFLT BITS(12,15) /*!< channel 1 input capture filter control */ + +/* TIMER_CHCTL1 */ +/* output compare mode */ +#define TIMER_CHCTL1_CH2MS BITS(0,1) /*!< channel 2 mode selection */ +#define TIMER_CHCTL1_CH2COMFEN BIT(2) /*!< channel 2 output compare fast enable */ +#define TIMER_CHCTL1_CH2COMSEN BIT(3) /*!< channel 2 output compare shadow enable */ +#define TIMER_CHCTL1_CH2COMCTL BITS(4,6) /*!< channel 2 output compare mode */ +#define TIMER_CHCTL1_CH2COMCEN BIT(7) /*!< channel 2 output compare clear enable */ +#define TIMER_CHCTL1_CH3MS BITS(8,9) /*!< channel 3 mode selection */ +#define TIMER_CHCTL1_CH3COMFEN BIT(10) /*!< channel 3 output compare fast enable */ +#define TIMER_CHCTL1_CH3COMSEN BIT(11) /*!< channel 3 output compare shadow enable */ +#define TIMER_CHCTL1_CH3COMCTL BITS(12,14) /*!< channel 3 output compare mode */ +#define TIMER_CHCTL1_CH3COMCEN BIT(15) /*!< channel 3 output compare clear enable */ +/* input capture mode */ +#define TIMER_CHCTL1_CH2CAPPSC BITS(2,3) /*!< channel 2 input capture prescaler */ +#define TIMER_CHCTL1_CH2CAPFLT BITS(4,7) /*!< channel 2 input capture filter control */ +#define TIMER_CHCTL1_CH3CAPPSC BITS(10,11) /*!< channel 3 input capture prescaler */ +#define TIMER_CHCTL1_CH3CAPFLT BITS(12,15) /*!< channel 3 input capture filter control */ + +/* TIMER_CHCTL2 */ +#define TIMER_CHCTL2_CH0EN BIT(0) /*!< channel 0 enable */ +#define TIMER_CHCTL2_CH0P BIT(1) /*!< channel 0 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 enable */ +#define TIMER_CHCTL2_CH1P BIT(5) /*!< channel 1 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 enable */ +#define TIMER_CHCTL2_CH2P BIT(9) /*!< channel 2 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 enable */ +#define TIMER_CHCTL2_CH3P BIT(13) /*!< channel 3 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) /*!< capture/compare value of channel 0 */ + +/* TIMER_CH1CV */ +#define TIMER_CH1CV_CH1VAL BITS(0,15) /*!< capture/compare value of channel 1 */ + +/* TIMER_CH2CV */ +#define TIMER_CH2CV_CH2VAL BITS(0,15) /*!< capture/compare value of channel 2 */ + +/* TIMER_CH3CV */ +#define TIMER_CH3CV_CH3VAL BITS(0,15) /*!< capture/compare value of channel 3 */ + +/* TIMER_CCHP */ +#define TIMER_CCHP_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_CCHP_PROT BITS(8,9) /*!< complementary register protect control */ +#define TIMER_CCHP_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_CCHP_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_CCHP_BRKEN BIT(12) /*!< break enable */ +#define TIMER_CCHP_BRKP BIT(13) /*!< break polarity */ +#define TIMER_CCHP_OAEN BIT(14) /*!< output automatic enable */ +#define TIMER_CCHP_POEN BIT(15) /*!< primary output enable */ + +/* TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA BITS(0,4) /*!< DMA transfer access start address */ +#define TIMER_DMACFG_DMATC BITS(8,12) /*!< DMA transfer count */ + +/* TIMER_DMATB */ +#define TIMER_DMATB_DMATB BITS(0,15) /*!< DMA transfer buffer address */ + +/* TIMER_IRMP */ +#define TIMER13_IRMP_CI0_RMP BITS(0,1) /*!< TIMER13 channel 0 input remap */ + +#ifdef GD32F170_190 +/* TIMER_CFG */ +#define TIMER_CFG_OUTSEL BIT(0) /*!< the output value selection */ +#define TIMER_CFG_CHVSEL BIT(1) /*!< write CHxVAL register selection */ +#endif /* GD32F170_190 */ + +/* 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; + +/* channel input parameter struct definitions */ +typedef struct +{ + uint16_t icpolarity; /*!< channel input polarity */ + uint16_t icselection; /*!< channel input mode selection */ + uint16_t icprescaler; /*!< channel input capture prescaler */ + uint16_t icfilter; /*!< channel input capture filter control */ +}timer_ic_parameter_struct; + +/* TIMER interrupt enable or disable */ +#define TIMER_INT_UP TIMER_DMAINTEN_UPIE /*!< update interrupt */ +#define TIMER_INT_CH0 TIMER_DMAINTEN_CH0IE /*!< channel 0 interrupt */ +#define TIMER_INT_CH1 TIMER_DMAINTEN_CH1IE /*!< channel 1 interrupt */ +#define TIMER_INT_CH2 TIMER_DMAINTEN_CH2IE /*!< channel 2 interrupt */ +#define TIMER_INT_CH3 TIMER_DMAINTEN_CH3IE /*!< channel 3 interrupt */ +#define TIMER_INT_CMT TIMER_DMAINTEN_CMTIE /*!< channel commutation interrupt flag */ +#define TIMER_INT_TRG TIMER_DMAINTEN_TRGIE /*!< trigger interrupt */ +#define TIMER_INT_BRK TIMER_DMAINTEN_BRKIE /*!< break interrupt */ + +/* TIMER flag */ +#define TIMER_FLAG_UP TIMER_INTF_UPIF /*!< update flag */ +#define TIMER_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 flag */ +#define TIMER_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 flag */ +#define TIMER_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 flag */ +#define TIMER_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 flag */ +#define TIMER_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation flag */ +#define TIMER_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger flag */ +#define TIMER_FLAG_BRK TIMER_INTF_BRKIF /*!< break flag */ +#define TIMER_FLAG_CH0O TIMER_INTF_CH0OF /*!< channel 0 overcapture flag */ +#define TIMER_FLAG_CH1O TIMER_INTF_CH1OF /*!< channel 1 overcapture flag */ +#define TIMER_FLAG_CH2O TIMER_INTF_CH2OF /*!< channel 2 overcapture flag */ +#define TIMER_FLAG_CH3O TIMER_INTF_CH3OF /*!< channel 3 overcapture flag */ + +/* TIMER interrupt flag */ +#define TIMER_INT_FLAG_UP TIMER_INTF_UPIF /*!< update interrupt flag */ +#define TIMER_INT_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 interrupt flag */ +#define TIMER_INT_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 interrupt flag */ +#define TIMER_INT_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 interrupt flag */ +#define TIMER_INT_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 interrupt flag */ +#define TIMER_INT_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation interrupt flag */ +#define TIMER_INT_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger interrupt flag */ +#define TIMER_INT_FLAG_BRK TIMER_INTF_BRKIF /*!< break interrupt flag */ + +/* TIMER DMA source enable */ +#define TIMER_DMA_UPD ((uint16_t)0x0100U) /*!< update DMA enable */ +#define TIMER_DMA_CH0D ((uint16_t)0x0200U) /*!< channel 0 DMA enable */ +#define TIMER_DMA_CH1D ((uint16_t)0x0400U) /*!< channel 1 DMA enable */ +#define TIMER_DMA_CH2D ((uint16_t)0x0800U) /*!< channel 2 DMA enable */ +#define TIMER_DMA_CH3D ((uint16_t)0x1000U) /*!< channel 3 DMA enable */ +#define TIMER_DMA_CMTD ((uint16_t)0x2000U) /*!< commutation DMA request enable */ +#define TIMER_DMA_TRGD ((uint16_t)0x4000U) /*!< trigger DMA enable */ + +/* update disable */ +#define TIMER_UPDIS_ENABLE TIMER_CTL0_UPDIS /*!< update enable */ +#define TIMER_UPDIS_DISABLE ~TIMER_CTL0_UPDIS /*!< update disable */ + +/* TIMER count enable */ +#define TIMER_COUNTER_ENABLE TIMER_CTL0_CEN /*!< count enable */ +#define TIMER_COUNTER_DISABLE ~TIMER_CTL0_CEN /*!< count disable */ + +/* channel DMA request source selection */ +#define TIMER_DMAREQUEST_UPDATEEVENT ((uint8_t)0x00U) /*!< DMA request of channel y is sent when update event occurs */ +#define TIMER_DMAREQUEST_CHANNELEVENT ((uint8_t)0x01U) /*!< DMA request of channel y is sent when channel y event occurs */ + +/* OCPRE clear source selection */ +#define TIMER_OCPRE_CLEAR_SOURCE_ETIF ((uint8_t)0x01U) /*!< OCPRE_CLR_INT is connected to ETIF */ +#define TIMER_OCPRE_CLEAR_SOURCE_CLR ((uint8_t)0x00U) /*!< OCPRE_CLR_INT is connected to the OCPRE_CLR input */ + +/* DMA access base address */ +#define DMACFG_DMATA(regval) (BITS(0, 4) & ((uint32_t)(regval) << 0U)) +#define TIMER_DMACFG_DMATA_CTL0 DMACFG_DMATA(0) /*!< DMA transfer address is TIMER_CTL0 */ +#define TIMER_DMACFG_DMATA_CTL1 DMACFG_DMATA(1) /*!< DMA transfer address is TIMER_CTL1 */ +#define TIMER_DMACFG_DMATA_SMCFG DMACFG_DMATA(2) /*!< DMA transfer address is TIMER_SMCFG */ +#define TIMER_DMACFG_DMATA_DMAINTEN DMACFG_DMATA(3) /*!< DMA transfer address is TIMER_DMAINTEN */ +#define TIMER_DMACFG_DMATA_INTF DMACFG_DMATA(4) /*!< DMA transfer address is TIMER_INTF */ +#define TIMER_DMACFG_DMATA_SWEVG DMACFG_DMATA(5) /*!< DMA transfer address is TIMER_SWEVG */ +#define TIMER_DMACFG_DMATA_CHCTL0 DMACFG_DMATA(6) /*!< DMA transfer address is TIMER_CHCTL0 */ +#define TIMER_DMACFG_DMATA_CHCTL1 DMACFG_DMATA(7) /*!< DMA transfer address is TIMER_CHCTL1 */ +#define TIMER_DMACFG_DMATA_CHCTL2 DMACFG_DMATA(8) /*!< DMA transfer address is TIMER_CHCTL2 */ +#define TIMER_DMACFG_DMATA_CNT DMACFG_DMATA(9) /*!< DMA transfer address is TIMER_CNT */ +#define TIMER_DMACFG_DMATA_PSC DMACFG_DMATA(10) /*!< DMA transfer address is TIMER_PSC */ +#define TIMER_DMACFG_DMATA_CAR DMACFG_DMATA(11) /*!< DMA transfer address is TIMER_CAR */ +#define TIMER_DMACFG_DMATA_CREP DMACFG_DMATA(12) /*!< DMA transfer address is TIMER_CREP */ +#define TIMER_DMACFG_DMATA_CH0CV DMACFG_DMATA(13) /*!< DMA transfer address is TIMER_CH0CV */ +#define TIMER_DMACFG_DMATA_CH1CV DMACFG_DMATA(14) /*!< DMA transfer address is TIMER_CH1CV */ +#define TIMER_DMACFG_DMATA_CH2CV DMACFG_DMATA(15) /*!< DMA transfer address is TIMER_CH2CV */ +#define TIMER_DMACFG_DMATA_CH3CV DMACFG_DMATA(16) /*!< DMA transfer address is TIMER_CH3CV */ +#define TIMER_DMACFG_DMATA_CCHP DMACFG_DMATA(17) /*!< DMA transfer address is TIMER_CCHP */ +#define TIMER_DMACFG_DMATA_DMACFG DMACFG_DMATA(18) /*!< DMA transfer address is TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA_DMATB DMACFG_DMATA(19) /*!< DMA transfer address is TIMER_DMATB */ + +/* DMA access burst length */ +#define DMACFG_DMATC(regval) (BITS(8, 12) & ((uint32_t)(regval) << 8U)) +#define TIMER_DMACFG_DMATC_1TRANSFER DMACFG_DMATC(0) /*!< DMA transfer 1 time */ +#define TIMER_DMACFG_DMATC_2TRANSFER DMACFG_DMATC(1) /*!< DMA transfer 2 times */ +#define TIMER_DMACFG_DMATC_3TRANSFER DMACFG_DMATC(2) /*!< DMA transfer 3 times */ +#define TIMER_DMACFG_DMATC_4TRANSFER DMACFG_DMATC(3) /*!< DMA transfer 4 times */ +#define TIMER_DMACFG_DMATC_5TRANSFER DMACFG_DMATC(4) /*!< DMA transfer 5 times */ +#define TIMER_DMACFG_DMATC_6TRANSFER DMACFG_DMATC(5) /*!< DMA transfer 6 times */ +#define TIMER_DMACFG_DMATC_7TRANSFER DMACFG_DMATC(6) /*!< DMA transfer 7 times */ +#define TIMER_DMACFG_DMATC_8TRANSFER DMACFG_DMATC(7) /*!< DMA transfer 8 times */ +#define TIMER_DMACFG_DMATC_9TRANSFER DMACFG_DMATC(8) /*!< DMA transfer 9 times */ +#define TIMER_DMACFG_DMATC_10TRANSFER DMACFG_DMATC(9) /*!< DMA transfer 10 times */ +#define TIMER_DMACFG_DMATC_11TRANSFER DMACFG_DMATC(10) /*!< DMA transfer 11 times */ +#define TIMER_DMACFG_DMATC_12TRANSFER DMACFG_DMATC(11) /*!< DMA transfer 12 times */ +#define TIMER_DMACFG_DMATC_13TRANSFER DMACFG_DMATC(12) /*!< DMA transfer 13 times */ +#define TIMER_DMACFG_DMATC_14TRANSFER DMACFG_DMATC(13) /*!< DMA transfer 14 times */ +#define TIMER_DMACFG_DMATC_15TRANSFER DMACFG_DMATC(14) /*!< DMA transfer 15 times */ +#define TIMER_DMACFG_DMATC_16TRANSFER DMACFG_DMATC(15) /*!< DMA transfer 16 times */ +#define TIMER_DMACFG_DMATC_17TRANSFER DMACFG_DMATC(16) /*!< DMA transfer 17 times */ +#define TIMER_DMACFG_DMATC_18TRANSFER DMACFG_DMATC(17) /*!< DMA transfer 18 times */ + +/* TIMER software event generation source */ +#define TIMER_EVENT_SRC_UPG ((uint16_t)0x0001U) /*!< update event generation */ +#define TIMER_EVENT_SRC_CH0G ((uint16_t)0x0002U) /*!< channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH1G ((uint16_t)0x0004U) /*!< channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH2G ((uint16_t)0x0008U) /*!< channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH3G ((uint16_t)0x0010U) /*!< channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CMTG ((uint16_t)0x0020U) /*!< channel commutation event generation */ +#define TIMER_EVENT_SRC_TRGG ((uint16_t)0x0040U) /*!< trigger event generation */ +#define TIMER_EVENT_SRC_BRKG ((uint16_t)0x0080U) /*!< break event generation */ + +/* center-aligned mode selection */ +#define CTL0_CAM(regval) ((uint16_t)(BITS(5, 6) & ((uint32_t)(regval) << 5U))) +#define TIMER_COUNTER_EDGE CTL0_CAM(0) /*!< edge-aligned mode */ +#define TIMER_COUNTER_CENTER_DOWN CTL0_CAM(1) /*!< center-aligned and counting down assert mode */ +#define TIMER_COUNTER_CENTER_UP CTL0_CAM(2) /*!< center-aligned and counting up assert mode */ +#define TIMER_COUNTER_CENTER_BOTH CTL0_CAM(3) /*!< center-aligned and counting up/down assert mode */ + +/* TIMER prescaler reload mode */ +#define TIMER_PSC_RELOAD_NOW ((uint8_t)0x00U) /*!< the prescaler is loaded right now */ +#define TIMER_PSC_RELOAD_UPDATE ((uint8_t)0x01U) /*!< 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)0x0010U) /*!< 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 ((uint8_t)0x00U) /*!< single pulse mode */ +#define TIMER_SP_MODE_REPETITIVE ((uint8_t)0x01U) /*!< repetitive pulse mode */ + +/* auto-reload shadow enable */ +#define TIMER_ARSE_ENABLE TIMER_CTL0_ARSE /*!< auto-reload shadow enable */ +#define TIMER_ARSE_DISABLE ~TIMER_CTL0_ARSE /*!< auto-reload shadow disable */ + +/* update source */ +#define TIMER_UPDATE_SRC_REGULAR ((uint8_t)0x00U) /*!< update generate only by counter overflow/underflow */ +#define TIMER_UPDATE_SRC_GLOBAL ((uint8_t)0x01U) /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */ + +/* run mode off-state configure */ +#define TIMER_ROS_STATE_ENABLE ((uint16_t)0x0800U) /*!< channel OC outputs enable in run mode */ +#define TIMER_ROS_STATE_DISABLE ((uint16_t)0x0000U) /*!< channel OC outputs disable in run mode */ + +/* idle mode off-state configure */ +#define TIMER_IOS_STATE_ENABLE ((uint16_t)0x0400U) /*!< channel OC outputs enable in idle mode */ +#define TIMER_IOS_STATE_DISABLE ((uint16_t)0x0000U) /*!< channel OC outputs disable in idle mode */ + +/* break input polarity */ +#define TIMER_BREAK_POLARITY_LOW ((uint16_t)0x0000U) /*!< break input polarity is low */ +#define TIMER_BREAK_POLARITY_HIGH ((uint16_t)0x2000U) /*!< break input polarity is high */ + +/* output automatic enable */ +#define TIMER_OUTAUTO_ENABLE ((uint16_t)0x4000U) /*!< output automatic enable */ +#define TIMER_OUTAUTO_DISABLE ((uint16_t)0x0000U) /*!< output automatic disable */ + +/* complementary register protect control */ +#define CCHP_PROT(regval) ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CCHP_PROT_OFF CCHP_PROT(0) /*!< protect disable */ +#define TIMER_CCHP_PROT_0 CCHP_PROT(1) /*!< PROT mode 0 */ +#define TIMER_CCHP_PROT_1 CCHP_PROT(2) /*!< PROT mode 1 */ +#define TIMER_CCHP_PROT_2 CCHP_PROT(3) /*!< PROT mode 2 */ + +/* break input enable */ +#define TIMER_BREAK_ENABLE ((uint16_t)0x1000U) /*!< break input enable */ +#define TIMER_BREAK_DISABLE ((uint16_t)0x0000U) /*!< break input disable */ + +/* TIMER channel y(y=0,1,2,3) */ +#define TIMER_CH_0 ((uint16_t)0x0000U) /*!< TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) */ +#define TIMER_CH_1 ((uint16_t)0x0001U) /*!< TIMER channel1(TIMERx(x=0,1,2,14)) */ +#define TIMER_CH_2 ((uint16_t)0x0002U) /*!< TIMER channel2(TIMERx(x=0,1,2)) */ +#define TIMER_CH_3 ((uint16_t)0x0003U) /*!< TIMER channel3(TIMERx(x=0,1,2)) */ + +/* channel enable state*/ +#define TIMER_CCX_ENABLE ((uint16_t)0x0001U) /*!< channel enable */ +#define TIMER_CCX_DISABLE ((uint16_t)0x0000U) /*!< channel disable */ + +/* channel complementary output enable state*/ +#define TIMER_CCXN_ENABLE ((uint16_t)0x0004U) /*!< channel complementary enable */ +#define TIMER_CCXN_DISABLE ((uint16_t)0x0000U) /*!< channel complementary disable */ + +/* channel output polarity */ +#define TIMER_OC_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel output polarity is high */ +#define TIMER_OC_POLARITY_LOW ((uint16_t)0x0002U) /*!< channel output polarity is low */ + +/* channel complementary output polarity */ +#define TIMER_OCN_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel complementary output polarity is high */ +#define TIMER_OCN_POLARITY_LOW ((uint16_t)0x0008U) /*!< channel complementary output polarity is low */ + +/* idle state of channel output */ +#define TIMER_OC_IDLE_STATE_HIGH ((uint16_t)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 */ + +/* channel output compare mode */ +#define TIMER_OC_MODE_TIMING ((uint16_t)0x0000U) /*!< timing mode */ +#define TIMER_OC_MODE_ACTIVE ((uint16_t)0x0010U) /*!< active mode */ +#define TIMER_OC_MODE_INACTIVE ((uint16_t)0x0020U) /*!< inactive mode */ +#define TIMER_OC_MODE_TOGGLE ((uint16_t)0x0030U) /*!< toggle mode */ +#define TIMER_OC_MODE_LOW ((uint16_t)0x0040U) /*!< force low mode */ +#define TIMER_OC_MODE_HIGH ((uint16_t)0x0050U) /*!< force high mode */ +#define TIMER_OC_MODE_PWM0 ((uint16_t)0x0060U) /*!< PWM0 mode */ +#define TIMER_OC_MODE_PWM1 ((uint16_t)0x0070U) /*!< PWM1 mode*/ + +/* channel output compare shadow enable */ +#define TIMER_OC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< channel output shadow state enable */ +#define TIMER_OC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel output shadow state disable */ + +/* channel output compare fast enable */ +#define TIMER_OC_FAST_ENABLE ((uint16_t)0x0004U) /*!< channel output fast function enable */ +#define TIMER_OC_FAST_DISABLE ((uint16_t)0x0000U) /*!< channel output fast function disable */ + +/* channel output compare clear enable. */ +#define TIMER_OC_CLEAR_ENABLE ((uint16_t)0x0080U) /*!< channel output clear function enable */ +#define TIMER_OC_CLEAR_DISABLE ((uint16_t)0x0000U) /*!< channel output clear function disable */ + +/* channel control shadow register update control */ +#define TIMER_UPDATECTL_CCU ((uint8_t)0x00U) /*!< the shadow registers update by when CMTG bit is set */ +#define TIMER_UPDATECTL_CCUTRI ((uint8_t)0x01U) /*!< the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs */ + +/* channel input capture polarity */ +#define TIMER_IC_POLARITY_RISING ((uint16_t)0x0000U) /*!< input capture rising edge */ +#define TIMER_IC_POLARITY_FALLING ((uint16_t)0x0002U) /*!< input capture falling edge */ +#define TIMER_IC_POLARITY_BOTH_EDGE ((uint16_t)0x000AU) /*!< input capture both edge */ + +/* TIMER input capture selection */ +#define TIMER_IC_SELECTION_DIRECTTI ((uint16_t)0x0001U) /*!< channel y is configured as input and icy is mapped on CIy */ +#define TIMER_IC_SELECTION_INDIRECTTI ((uint16_t)0x0002U) /*!< channel y is configured as input and icy is mapped on opposite input */ +#define TIMER_IC_SELECTION_ITS ((uint16_t)0x0003U) /*!< channel y is configured as input and icy is mapped on ITS */ + +/* channel input capture prescaler */ +#define TIMER_IC_PSC_DIV1 ((uint16_t)0x0000U) /*!< no prescaler */ +#define TIMER_IC_PSC_DIV2 ((uint16_t)0x0004U) /*!< divided by 2 */ +#define TIMER_IC_PSC_DIV4 ((uint16_t)0x0008U) /*!< divided by 4*/ +#define TIMER_IC_PSC_DIV8 ((uint16_t)0x000CU) /*!< divided by 8 */ + +/* trigger selection */ +#define SMCFG_TRGSEL(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define TIMER_SMCFG_TRGSEL_ITI0 SMCFG_TRGSEL(0) /*!< internal trigger 0 */ +#define TIMER_SMCFG_TRGSEL_ITI1 SMCFG_TRGSEL(1) /*!< internal trigger 1 */ +#define TIMER_SMCFG_TRGSEL_ITI2 SMCFG_TRGSEL(2) /*!< internal trigger 2 */ +#define TIMER_SMCFG_TRGSEL_ITI3 SMCFG_TRGSEL(3) /*!< internal trigger 3 */ +#define TIMER_SMCFG_TRGSEL_CI0F_ED SMCFG_TRGSEL(4) /*!< TI0 edge detector */ +#define TIMER_SMCFG_TRGSEL_CI0FE0 SMCFG_TRGSEL(5) /*!< filtered TIMER input 0 */ +#define TIMER_SMCFG_TRGSEL_CI1FE1 SMCFG_TRGSEL(6) /*!< filtered TIMER input 1 */ +#define TIMER_SMCFG_TRGSEL_ETIFP SMCFG_TRGSEL(7) /*!< external trigger */ + +/* master mode control */ +#define CTL1_MMC(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define TIMER_TRI_OUT_SRC_RESET CTL1_MMC(0) /*!< the UPG bit as trigger output */ +#define TIMER_TRI_OUT_SRC_ENABLE CTL1_MMC(1) /*!< the counter enable signal TIMER_CTL0_CEN as trigger output */ +#define TIMER_TRI_OUT_SRC_UPDATE CTL1_MMC(2) /*!< update event as trigger output */ +#define TIMER_TRI_OUT_SRC_CH0 CTL1_MMC(3) /*!< a capture or a compare match occurred in channal 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 ((uint8_t)0x00U) /*!< master slave mode enable */ +#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint8_t)0x01U) /*!< 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 ~TIMER_SMCFG_ETP /*!< active high or rising edge active */ + +/* channel 0 trigger input selection */ +#define TIMER_HALLINTERFACE_ENABLE ((uint8_t)0x00U) /*!< TIMER hall sensor mode enable */ +#define TIMER_HALLINTERFACE_DISABLE ((uint8_t)0x01U) /*!< TIMER hall sensor mode disable */ + +/* channel 0 input remap */ +#define IRMP_CI0_RMP(regval) (BITS(0, 1) & ((uint32_t)(regval) << 0U)) +#define TIMER_IRMP_CI0_RMP_GPIO IRMP_CI0_RMP(0) /*!< channel 0 input is connected to GPIO */ +#define TIMER_IRMP_CI0_RTCCLK IRMP_CI0_RMP(1) /*!< channel 0 input is connected to the RTCCLK */ +#define TIMER_IRMP_CI0_HXTALDIV32 IRMP_CI0_RMP(2) /*!< channel 0 input is connected to HXTAL/32 clock */ +#define TIMER_IRMP_CI0_CKOUTSEL IRMP_CI0_RMP(3) /*!< channel 0 input is connected to CKOUTSEL */ + +#ifdef GD32F170_190 +/* write CHxVAL register selection */ +#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CHxVAL register selection disable */ +#define TIMER_CHVSEL_ENABLE ((uint16_t)0x0002U) /*!< write CHxVAL register selection enable */ + +/* the output value selection */ +#define TIMER_OUTSEL_DISABLE ((uint16_t)0x0000U) /*!< output value selection disable */ +#define TIMER_OUTSEL_ENABLE ((uint16_t)0x0001U) /*!< output value selection enable */ +#endif /* GD32F170_190 */ + +/* function declarations */ +/* TIMER timebase*/ +/* deinit a timer */ +void timer_deinit(uint32_t timer_periph); +/* initialize TIMER counter */ +void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara); +/* enable a timer */ +void timer_enable(uint32_t timer_periph); +/* disable a timer */ +void timer_disable(uint32_t timer_periph); + +/* enable the auto reload shadow function */ +void timer_auto_reload_shadow_enable(uint32_t timer_periph); +/* disable the auto reload shadow function */ +void timer_auto_reload_shadow_disable(uint32_t timer_periph); + +/* enable the update event */ +void timer_update_event_enable(uint32_t timer_periph); +/* disable the update event */ +void timer_update_event_disable(uint32_t timer_periph); + +/* set TIMER counter alignment mode */ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned); +/* set TIMER counter up direction */ +void timer_counter_up_direction(uint32_t timer_periph); +/* set TIMER counter down direction */ +void timer_counter_down_direction(uint32_t timer_periph); + +/* configure TIMER prescaler */ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload); +/* configure TIMER repetition counter 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, uint8_t spmode); +/* configure TIMER update source */ +void timer_update_source_config(uint32_t timer_periph, uint8_t update); + +/* TIMER interrupt and flag*/ +/* enable the TIMER interrupt */ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt); +/* disable the TIMER interrupt */ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt); +/* get TIMER interrupt flag */ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt); +/* clear TIMER interrupt flag */ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt); +/* get TIMER flag */ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag); +/* clear TIMER flag */ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag); + +/* TIMER DMA and event*/ +/* enable the TIMER DMA */ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma); +/* disable the TIMER DMA */ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma); +/* channel DMA request source selection */ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request); +/* configure the TIMER DMA transfer */ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth); + +/* software generate events */ +void timer_event_software_generate(uint32_t timer_periph, uint16_t event); + +/* TIMER channel complementary protection */ +/* 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); + +/* channel capture/compare control shadow register enable */ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue); +/* configure TIMER channel control shadow register update control */ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl); +/* select TIMER OCPRE clear source */ +void timer_ocpre_clear_source_config(uint32_t timer_periph, uint8_t ocpreclear); + +/* TIMER channel output */ +/* configure TIMER channel output function */ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct* ocpara); +/* configure TIMER channel output compare mode */ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode); +/* configure TIMER channel output pulse value */ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse); + +/* configure TIMER channel output shadow function */ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow); +/* configure TIMER channel output fast function */ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast); +/* configure TIMER channel output clear function */ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear); + +/* configure TIMER channel output polarity */ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity); +/* configure TIMER channel complementary output polarity */ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity); +/* configure TIMER channel enable state */ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_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 */ +/* 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, uint32_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, uint8_t hallmode); + +/* TIMER master and slave mode */ +/* select TIMER input trigger source */ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger); +/* select TIMER master mode output trigger source */ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t 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, uint8_t masterslave); +/* configure TIMER external trigger input */ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t expolarity, 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 expolarity, 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 expolarity, 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 expolarity, uint32_t extfilter); +/* disable TIMER the external clock mode 1 */ +void timer_external_clock_mode1_disable(uint32_t timer_periph); + +/* configure TIMER13 channel0 remap function */ +void timer_channel_remap_config(uint32_t timer_periph, uint16_t channel, uint32_t remap); + +#ifdef GD32F170_190 +/* configure TIMER cc register selection */ +void timer_write_cc_register_config(uint32_t timer_periph, uint32_t ccsel); +/* configure TIMER output value selection */ +void timer_output_value_selection_config(uint32_t timer_periph, uint32_t outsel); +#endif /* GD32F170_190 */ + +#endif /* GD32F1X0_TIMER_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_tsi.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_tsi.h new file mode 100644 index 0000000..30a4374 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_tsi.h @@ -0,0 +1,340 @@ +/*! + \file gd32f1x0_tsi.h + \brief definitions for the TSI +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_TSI_H +#define GD32F1X0_TSI_H + +#include "gd32f1x0.h" + +/* TSI definitions */ +#define TSI TSI_BASE /*!< TSI base address */ + +/* registers definitions */ +#define TSI_CTL REG32(TSI + 0x00U) /*!< TSI control register */ +#define TSI_INTEN REG32(TSI + 0x04U) /*!< TSI interrupt enable register */ +#define TSI_INTC REG32(TSI + 0x08U) /*!< TSI interrupt flag clear register */ +#define TSI_INTF REG32(TSI + 0x0CU) /*!< TSI interrupt flag register */ +#define TSI_PHM REG32(TSI + 0x10U) /*!< TSI pin hysteresis mode register */ +#define TSI_ASW REG32(TSI + 0x18U) /*!< TSI analog switch register */ +#define TSI_SAMPCFG REG32(TSI + 0x20U) /*!< TSI sample configuration register */ +#define TSI_CHCFG REG32(TSI + 0x28U) /*!< TSI channel configuration register */ +#define TSI_GCTL REG32(TSI + 0x30U) /*!< TSI group control register */ +#define TSI_G0CYCN REG32(TSI + 0x34U) /*!< TSI group 0 cycle number register */ +#define TSI_G1CYCN REG32(TSI + 0x38U) /*!< TSI group 1 cycle number register */ +#define TSI_G2CYCN REG32(TSI + 0x3CU) /*!< TSI group 2 cycle number register */ +#define TSI_G3CYCN REG32(TSI + 0x40U) /*!< TSI group 3 cycle number register */ +#define TSI_G4CYCN REG32(TSI + 0x44U) /*!< TSI group 4 cycle number register */ +#define TSI_G5CYCN REG32(TSI + 0x48U) /*!< TSI group 5 cycle number register */ + +/* bits definitions */ +/* TSI_CTL */ +#define TSI_CTL_TSIEN BIT(0) /*!< TSI enable */ +#define TSI_CTL_TSIS BIT(1) /*!< TSI start */ +#define TSI_CTL_TRGMOD BIT(2) /*!< trigger mode selection */ +#define TSI_CTL_EGSEL BIT(3) /*!< edge selection */ +#define TSI_CTL_PINMOD BIT(4) /*!< pin mode */ +#define TSI_CTL_MCN BITS(5,7) /*!< max cycle number of a sequence */ +#define TSI_CTL_CTCDIV BITS(12,14) /*!< CTCLK clock division factor */ +#define TSI_CTL_ECDIV BIT(15) /*!< ECCLK clock division factor */ +#define TSI_CTL_ECEN BIT(16) /*!< extend charge state enable */ +#define TSI_CTL_ECDT BITS(17,23) /*!< extend charge State maximum duration time */ +#define TSI_CTL_CTDT BITS(24,27) /*!< charge transfer state duration time */ +#define TSI_CTL_CDT BITS(28,31) /*!< charge state duration time */ + +/* TSI_INTEN */ +#define TSI_INTEN_CTCFIE BIT(0) /*!< charge transfer complete flag interrupt enable */ +#define TSI_INTEN_MNERRIE BIT(1) /*!< max cycle number error interrupt enable */ + +/* TSI_INTC */ +#define TSI_INTC_CCTCF BIT(0) /*!< clear charge transfer complete flag */ +#define TSI_INTC_CMNERR BIT(1) /*!< clear max cycle number error */ + +/* TSI_INTF */ +#define TSI_INTF_CTCF BIT(0) /*!< charge transfer complete flag */ +#define TSI_INTF_MNERR BIT(1) /*!< max cycle number error */ + +/* TSI_PHM */ +#define TSI_PHM_G0P0 BIT(0) /*!< pin G0P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G0P1 BIT(1) /*!< pin G0P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G0P2 BIT(2) /*!< pin G0P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G0P3 BIT(3) /*!< pin G0P3 Schmitt trigger hysteresis state */ +#define TSI_PHM_G1P0 BIT(4) /*!< pin G1P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G1P1 BIT(5) /*!< pin G1P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G1P2 BIT(6) /*!< pin G1P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G1P3 BIT(7) /*!< pin G1P3 Schmitt trigger hysteresis state */ +#define TSI_PHM_G2P0 BIT(8) /*!< pin G2P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G2P1 BIT(9) /*!< pin G2P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G2P2 BIT(10) /*!< pin G2P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G2P3 BIT(11) /*!< pin G2P3 Schmitt trigger hysteresis state */ +#define TSI_PHM_G3P0 BIT(12) /*!< pin G3P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G3P1 BIT(13) /*!< pin G3P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G3P2 BIT(14) /*!< pin G3P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G3P3 BIT(15) /*!< pin G3P3 Schmitt trigger hysteresis state */ +#define TSI_PHM_G4P0 BIT(16) /*!< pin G4P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G4P1 BIT(17) /*!< pin G4P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G4P2 BIT(18) /*!< pin G4P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G4P3 BIT(19) /*!< pin G4P3 Schmitt trigger hysteresis state */ +#define TSI_PHM_G5P0 BIT(20) /*!< pin G5P0 Schmitt trigger hysteresis state */ +#define TSI_PHM_G5P1 BIT(21) /*!< pin G5P1 Schmitt trigger hysteresis state */ +#define TSI_PHM_G5P2 BIT(22) /*!< pin G5P2 Schmitt trigger hysteresis state */ +#define TSI_PHM_G5P3 BIT(23) /*!< pin G5P3 Schmitt trigger hysteresis state */ + +/* TSI_ASW */ +#define TSI_ASW_G0P0 BIT(0) /*!< pin G0P0 analog switch state */ +#define TSI_ASW_G0P1 BIT(1) /*!< pin G0P2 analog switch state */ +#define TSI_ASW_G0P2 BIT(2) /*!< pin G0P3 analog switch state */ +#define TSI_ASW_G0P3 BIT(3) /*!< pin G0P4 analog switch state */ +#define TSI_ASW_G1P0 BIT(4) /*!< pin G1P0 analog switch state */ +#define TSI_ASW_G1P1 BIT(5) /*!< pin G1P1 analog switch state */ +#define TSI_ASW_G1P2 BIT(6) /*!< pin G1P2 analog switch state */ +#define TSI_ASW_G1P3 BIT(7) /*!< pin G1P3 analog switch state */ +#define TSI_ASW_G2P0 BIT(8) /*!< pin G2P0 analog switch state */ +#define TSI_ASW_G2P1 BIT(9) /*!< pin G2P1 analog switch state */ +#define TSI_ASW_G2P2 BIT(10) /*!< pin G2P2 analog switch state */ +#define TSI_ASW_G2P3 BIT(11) /*!< pin G2P3 analog switch state */ +#define TSI_ASW_G3P0 BIT(12) /*!< pin G3P0 analog switch state */ +#define TSI_ASW_G3P1 BIT(13) /*!< pin G3P1 analog switch state */ +#define TSI_ASW_G3P2 BIT(14) /*!< pin G3P2 analog switch state */ +#define TSI_ASW_G3P3 BIT(15) /*!< pin G3P3 analog switch state */ +#define TSI_ASW_G4P0 BIT(16) /*!< pin G4P0 analog switch state */ +#define TSI_ASW_G4P1 BIT(17) /*!< pin G4P1 analog switch state */ +#define TSI_ASW_G4P2 BIT(18) /*!< pin G4P2 analog switch state */ +#define TSI_ASW_G4P3 BIT(19) /*!< pin G4P3 analog switch state */ +#define TSI_ASW_G5P0 BIT(20) /*!< pin G5P0 analog switch state */ +#define TSI_ASW_G5P1 BIT(21) /*!< pin G5P1 analog switch state */ +#define TSI_ASW_G5P2 BIT(22) /*!< pin G5P2 analog switch state */ +#define TSI_ASW_G5P3 BIT(23) /*!< pin G5P3 analog switch state */ + +/* TSI_SAMPCFG */ +#define TSI_SAMPCFG_G0P0 BIT(0) /*!< pin G0P0 sample pin mode */ +#define TSI_SAMPCFG_G0P1 BIT(1) /*!< pin G0P1 sample pin mode */ +#define TSI_SAMPCFG_G0P2 BIT(2) /*!< pin G0P2 sample pin mode */ +#define TSI_SAMPCFG_G0P3 BIT(3) /*!< pin G0P3 sample pin mode */ +#define TSI_SAMPCFG_G1P0 BIT(4) /*!< pin G1P0 sample pin mode */ +#define TSI_SAMPCFG_G1P1 BIT(5) /*!< pin G1P1 sample pin mode */ +#define TSI_SAMPCFG_G1P2 BIT(6) /*!< pin G1P2 sample pin mode */ +#define TSI_SAMPCFG_G1P3 BIT(7) /*!< pin G1P3 sample pin mode */ +#define TSI_SAMPCFG_G2P0 BIT(8) /*!< pin G2P0 sample pin mode */ +#define TSI_SAMPCFG_G2P1 BIT(9) /*!< pin G2P1 sample pin mode */ +#define TSI_SAMPCFG_G2P2 BIT(10) /*!< pin G2P2 sample pin mode */ +#define TSI_SAMPCFG_G2P3 BIT(11) /*!< pin G2P3 sample pin mode */ +#define TSI_SAMPCFG_G3P0 BIT(12) /*!< pin G3P0 sample pin mode */ +#define TSI_SAMPCFG_G3P1 BIT(13) /*!< pin G3P1 sample pin mode */ +#define TSI_SAMPCFG_G3P2 BIT(14) /*!< pin G3P2 sample pin mode */ +#define TSI_SAMPCFG_G3P3 BIT(15) /*!< pin G3P3 sample pin mode */ +#define TSI_SAMPCFG_G4P0 BIT(16) /*!< pin G4P0 sample pin mode */ +#define TSI_SAMPCFG_G4P1 BIT(17) /*!< pin G4P1 sample pin mode */ +#define TSI_SAMPCFG_G4P2 BIT(18) /*!< pin G4P2 sample pin mode */ +#define TSI_SAMPCFG_G4P3 BIT(19) /*!< pin G4P3 sample pin mode */ +#define TSI_SAMPCFG_G5P0 BIT(20) /*!< pin G5P0 sample pin mode */ +#define TSI_SAMPCFG_G5P1 BIT(21) /*!< pin G5P1 sample pin mode */ +#define TSI_SAMPCFG_G5P2 BIT(22) /*!< pin G5P2 sample pin mode */ +#define TSI_SAMPCFG_G5P3 BIT(23) /*!< pin G5P3 sample pin mode */ + +/* TSI_CHCFG */ +#define TSI_CHCFG_G0P0 BIT(0) /*!< pin G0P0 channel pin mode */ +#define TSI_CHCFG_G0P1 BIT(1) /*!< pin G0P1 channel pin mode */ +#define TSI_CHCFG_G0P2 BIT(2) /*!< pin G0P2 channel pin mode */ +#define TSI_CHCFG_G0P3 BIT(3) /*!< pin G0P3 channel pin mode */ +#define TSI_CHCFG_G1P0 BIT(4) /*!< pin G1P0 channel pin mode */ +#define TSI_CHCFG_G1P1 BIT(5) /*!< pin G1P1 channel pin mode */ +#define TSI_CHCFG_G1P2 BIT(6) /*!< pin G1P2 channel pin mode */ +#define TSI_CHCFG_G1P3 BIT(7) /*!< pin G1P3 channel pin mode */ +#define TSI_CHCFG_G2P0 BIT(8) /*!< pin G2P0 channel pin mode */ +#define TSI_CHCFG_G2P1 BIT(9) /*!< pin G2P1 channel pin mode */ +#define TSI_CHCFG_G2P2 BIT(10) /*!< pin G2P2 channel pin mode */ +#define TSI_CHCFG_G2P3 BIT(11) /*!< pin G2P3 channel pin mode */ +#define TSI_CHCFG_G3P0 BIT(12) /*!< pin G3P0 channel pin mode */ +#define TSI_CHCFG_G3P1 BIT(13) /*!< pin G3P1 channel pin mode */ +#define TSI_CHCFG_G3P2 BIT(14) /*!< pin G3P2 channel pin mode */ +#define TSI_CHCFG_G3P3 BIT(15) /*!< pin G3P3 channel pin mode */ +#define TSI_CHCFG_G4P0 BIT(16) /*!< pin G4P0 channel pin mode */ +#define TSI_CHCFG_G4P1 BIT(17) /*!< pin G4P1 channel pin mode */ +#define TSI_CHCFG_G4P2 BIT(18) /*!< pin G4P2 channel pin mode */ +#define TSI_CHCFG_G4P3 BIT(19) /*!< pin G4P3 channel pin mode */ +#define TSI_CHCFG_G5P0 BIT(20) /*!< pin G5P0 channel pin mode */ +#define TSI_CHCFG_G5P1 BIT(21) /*!< pin G5P1 channel pin mode */ +#define TSI_CHCFG_G5P2 BIT(22) /*!< pin G5P2 channel pin mode */ +#define TSI_CHCFG_G5P3 BIT(23) /*!< pin G5P3 channel pin mode */ + +/* TSI_GCTL */ +#define TSI_GCTL_GE0 BIT(0) /*!< group0 enable */ +#define TSI_GCTL_GE1 BIT(1) /*!< group1 enable */ +#define TSI_GCTL_GE2 BIT(2) /*!< group2 enable */ +#define TSI_GCTL_GE3 BIT(3) /*!< group3 enable */ +#define TSI_GCTL_GE4 BIT(4) /*!< group4 enable */ +#define TSI_GCTL_GE5 BIT(5) /*!< group5 enable */ +#define TSI_GCTL_GC0 BIT(16) /*!< group0 complete */ +#define TSI_GCTL_GC1 BIT(17) /*!< group1 complete */ +#define TSI_GCTL_GC2 BIT(18) /*!< group2 complete */ +#define TSI_GCTL_GC3 BIT(19) /*!< group3 complete */ +#define TSI_GCTL_GC4 BIT(20) /*!< group4 complete */ +#define TSI_GCTL_GC5 BIT(21) /*!< group5 complete */ + +/* constants definitions */ +/* CTCLK clock division factor */ +#define CTL_CTCDIV(regval) (BITS(12,14) & ((regval) << 12U)) /*!< CTCLK clock division factor */ +#define TSI_CTCDIV_DIV1 CTL_CTCDIV(0) /*!< fCTCLK = fHCLK */ +#define TSI_CTCDIV_DIV2 CTL_CTCDIV(1) /*!< fCTCLK = fHCLK/2 */ +#define TSI_CTCDIV_DIV4 CTL_CTCDIV(2) /*!< fCTCLK = fHCLK/4 */ +#define TSI_CTCDIV_DIV8 CTL_CTCDIV(3) /*!< fCTCLK = fHCLK/8 */ +#define TSI_CTCDIV_DIV16 CTL_CTCDIV(4) /*!< fCTCLK = fHCLK/16 */ +#define TSI_CTCDIV_DIV32 CTL_CTCDIV(5) /*!< fCTCLK = fHCLK/32 */ +#define TSI_CTCDIV_DIV64 CTL_CTCDIV(6) /*!< fCTCLK = fHCLK/64 */ +#define TSI_CTCDIV_DIV128 CTL_CTCDIV(7) /*!< fCTCLK = fHCLK/128 */ + +/* charge transfer state duration Time */ +#define CTL_CTDT(regval) (BITS(24,27) & ((regval) << 24U)) /*!< charge transfer state duration time */ +#define TSI_TRANSFER_1CTCLK CTL_CTDT(0) /*!< the duration time of transfer state is 1 CTCLK */ +#define TSI_TRANSFER_2CTCLK CTL_CTDT(1) /*!< the duration time of transfer state is 2 CTCLK */ +#define TSI_TRANSFER_3CTCLK CTL_CTDT(2) /*!< the duration time of transfer state is 3 CTCLK */ +#define TSI_TRANSFER_4CTCLK CTL_CTDT(3) /*!< the duration time of transfer state is 4 CTCLK */ +#define TSI_TRANSFER_5CTCLK CTL_CTDT(4) /*!< the duration time of transfer state is 5 CTCLK */ +#define TSI_TRANSFER_6CTCLK CTL_CTDT(5) /*!< the duration time of transfer state is 6 CTCLK */ +#define TSI_TRANSFER_7CTCLK CTL_CTDT(6) /*!< the duration time of transfer state is 7 CTCLK */ +#define TSI_TRANSFER_8CTCLK CTL_CTDT(7) /*!< the duration time of transfer state is 8 CTCLK */ +#define TSI_TRANSFER_9CTCLK CTL_CTDT(8) /*!< the duration time of transfer state is 9 CTCLK */ +#define TSI_TRANSFER_10CTCLK CTL_CTDT(9) /*!< the duration time of transfer state is 10 CTCLK */ +#define TSI_TRANSFER_11CTCLK CTL_CTDT(10) /*!< the duration time of transfer state is 11 CTCLK */ +#define TSI_TRANSFER_12CTCLK CTL_CTDT(11) /*!< the duration time of transfer state is 12 CTCLK */ +#define TSI_TRANSFER_13CTCLK CTL_CTDT(12) /*!< the duration time of transfer state is 13 CTCLK */ +#define TSI_TRANSFER_14CTCLK CTL_CTDT(13) /*!< the duration time of transfer state is 14 CTCLK */ +#define TSI_TRANSFER_15CTCLK CTL_CTDT(14) /*!< the duration time of transfer state is 15 CTCLK */ +#define TSI_TRANSFER_16CTCLK CTL_CTDT(15) /*!< the duration time of transfer state is 16 CTCLK */ + +/* charge state duration time */ +#define CTL_CDT(regval) (BITS(28,31) & ((regval) << 28U)) /*!< charge state duration time */ +#define TSI_CHARGE_1CTCLK CTL_CDT(0) /*!< the duration time of charge state is 1 CTCLK */ +#define TSI_CHARGE_2CTCLK CTL_CDT(1) /*!< the duration time of charge state is 2 CTCLK */ +#define TSI_CHARGE_3CTCLK CTL_CDT(2) /*!< the duration time of charge state is 3 CTCLK */ +#define TSI_CHARGE_4CTCLK CTL_CDT(3) /*!< the duration time of charge state is 4 CTCLK */ +#define TSI_CHARGE_5CTCLK CTL_CDT(4) /*!< the duration time of charge state is 5 CTCLK */ +#define TSI_CHARGE_6CTCLK CTL_CDT(5) /*!< the duration time of charge state is 6 CTCLK */ +#define TSI_CHARGE_7CTCLK CTL_CDT(6) /*!< the duration time of charge state is 7 CTCLK */ +#define TSI_CHARGE_8CTCLK CTL_CDT(7) /*!< the duration time of charge state is 8 CTCLK */ +#define TSI_CHARGE_9CTCLK CTL_CDT(8) /*!< the duration time of charge state is 9 CTCLK */ +#define TSI_CHARGE_10CTCLK CTL_CDT(9) /*!< the duration time of charge state is 10 CTCLK */ +#define TSI_CHARGE_11CTCLK CTL_CDT(10) /*!< the duration time of charge state is 11 CTCLK */ +#define TSI_CHARGE_12CTCLK CTL_CDT(11) /*!< the duration time of charge state is 12 CTCLK */ +#define TSI_CHARGE_13CTCLK CTL_CDT(12) /*!< the duration time of charge state is 13 CTCLK */ +#define TSI_CHARGE_14CTCLK CTL_CDT(13) /*!< the duration time of charge state is 14 CTCLK */ +#define TSI_CHARGE_15CTCLK CTL_CDT(14) /*!< the duration time of charge state is 15 CTCLK */ +#define TSI_CHARGE_16CTCLK CTL_CDT(15) /*!< the duration time of charge state is 16 CTCLK */ + +/* max cycle number of a sequence */ +#define CTL_MCN(regval) (BITS(5,7) & ((regval) << 5U)) /*!< max cycle number of a sequence */ +#define TSI_MAXNUM255 CTL_MCN(0) /*!< the max cycle number of a sequence is 255 */ +#define TSI_MAXNUM511 CTL_MCN(1) /*!< the max cycle number of a sequence is 511 */ +#define TSI_MAXNUM1023 CTL_MCN(2) /*!< the max cycle number of a sequence is 1023 */ +#define TSI_MAXNUM2047 CTL_MCN(3) /*!< the max cycle number of a sequence is 2047 */ +#define TSI_MAXNUM4095 CTL_MCN(4) /*!< the max cycle number of a sequence is 4095 */ +#define TSI_MAXNUM8191 CTL_MCN(5) /*!< the max cycle number of a sequence is 8191 */ +#define TSI_MAXNUM16383 CTL_MCN(6) /*!< the max cycle number of a sequence is 16383 */ + +/* ECCLK clock division factor */ +#define TSI_EXTEND_DIV1 ((uint32_t)0x00000000U) /*!< fECCLK = fHCLK */ +#define TSI_EXTEND_DIV2 ((uint32_t)0x00000001U) /*!< fECCLK = fHCLK/2 */ + +/* Extend Charge State Maximum Duration Time */ +#define TSI_EXTENDMAX(regval) (BITS(17,23) & ((regval) << 17U)) /* value range 1...128,extend charge state maximum duration time */ + +/* hardware trigger mode */ +#define TSI_FALLING_TRIGGER ((uint32_t)0x00000000U) /*!< falling edge trigger TSI charge transfer sequence */ +#define TSI_RISING_TRIGGER ((uint32_t)0x00000001U) /*!< rising edge trigger TSI charge transfer sequence */ + +/* pin mode */ +#define TSI_OUTPUT_LOW ((uint32_t)0x00000000U) /*!< TSI pin will output low when IDLE */ +#define TSI_INPUT_FLOATING ((uint32_t)0x00000001U) /*!< TSI pin will keep input_floating when IDLE */ + +/* interrupt enable bits */ +#define TSI_INT_CTCF TSI_INTEN_CTCFIE /*!< charge transfer complete flag interrupt enable */ +#define TSI_INTEN_MNERR TSI_INTEN_MNERRIE /*!< max cycle number error interrupt enable */ + +/* interrupt flag bits */ +#define TSI_INT_FLAG_CTC TSI_INTF_CTCF /*!< charge transfer complete flag */ +#define TSI_INT_FLAG_MNERR TSI_INTF_MNERR /*!< max cycle number error */ + +/* function declarations */ +/* reset TSI peripheral */ +void tsi_deinit(void); +/* initialize TSI plus prescaler,charge plus,transfer plus,max cycle number */ +void tsi_init(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration,uint32_t max_number); +/* enable TSI module */ +void tsi_enable(void); +/* disable TSI module */ +void tsi_disable(void); +/* enable sample pin */ +void tsi_sample_pin_enable(uint32_t sample); +/* disable sample pin */ +void tsi_sample_pin_disable(uint32_t sample); +/* enable channel pin */ +void tsi_channel_pin_enable(uint32_t channel); +/* disable channel pin */ +void tsi_channel_pin_disable(uint32_t channel); + +/* configure TSI triggering by software */ +void tsi_sofeware_mode_config(void); +/* start a charge-transfer sequence when TSI is in software trigger mode */ +void tsi_software_start(void); +/* stop a charge-transfer sequence when TSI is in software trigger mode */ +void tsi_software_stop(void); +/* configure TSI triggering by hardware */ +void tsi_hardware_mode_config(uint8_t trigger_edge); +/* configure TSI pin mode when charge-transfer sequence is IDLE */ +void tsi_pin_mode_config(uint8_t pin_mode); +/* configure extend charge state */ +void tsi_extend_charge_config(ControlStatus extend,uint8_t prescaler,uint32_t max_duration); + +/* configure charge plus and transfer plus */ +void tsi_plus_config(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration); +/* configure the max cycle number of a charge-transfer sequence */ +void tsi_max_number_config(uint32_t max_number); +/* switch on hysteresis pin */ +void tsi_hysteresis_on(uint32_t group_pin); +/* switch off hysteresis pin */ +void tsi_hysteresis_off(uint32_t group_pin); +/* switch on analog pin */ +void tsi_analog_on(uint32_t group_pin); +/* switch off analog pin */ +void tsi_analog_off(uint32_t group_pin); + +/* enable TSI interrupt */ +void tsi_interrupt_enable(uint32_t source); +/* disable TSI interrupt */ +void tsi_interrupt_disable(uint32_t source); +/* clear interrupt flag */ +void tsi_interrupt_flag_clear(uint32_t flag); +/* get TSI module current status */ +FlagStatus tsi_interrupt_flag_get(uint32_t status); + +/* enbale group */ +void tsi_group_enable(uint32_t group); +/* disbale group */ +void tsi_group_disable(uint32_t group); +/* get group complete status */ +FlagStatus tsi_group_status_get(uint32_t group); +/* get the cycle number for group0 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group0_cycle_get(void); +/* get the cycle number for group1 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group1_cycle_get(void); +/* get the cycle number for group2 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group2_cycle_get(void); +/* get the cycle number for group3 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group3_cycle_get(void); +/* get the cycle number for group4 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group4_cycle_get(void); +/* get the cycle number for group5 as soon as a charge-transfer sequence completes */ +uint16_t tsi_group5_cycle_get(void); + +#endif /* GD32F1X0_TSI_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_usart.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_usart.h new file mode 100644 index 0000000..d0ed92d --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_usart.h @@ -0,0 +1,542 @@ +/*! + \file gd32f1x0_usart.h + \brief definitions for the USART +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_USART_H +#define GD32F1X0_USART_H + +#include "gd32f1x0.h" + +/* USARTx(x=0,1) definitions */ +#define USART0 (USART_BASE + 0x0000F400U) +#define USART1 USART_BASE + +/* registers definitions */ +#define USART_CTL0(usartx) REG32((usartx) + 0x00U) /*!< USART control register 0 */ +#define USART_CTL1(usartx) REG32((usartx) + 0x04U) /*!< USART control register 1 */ +#define USART_CTL2(usartx) REG32((usartx) + 0x08U) /*!< USART control register 2 */ +#define USART_BAUD(usartx) REG32((usartx) + 0x0CU) /*!< USART baud rate register */ +#define USART_GP(usartx) REG32((usartx) + 0x10U) /*!< USART guard time and prescaler register */ +#define USART_RT(usartx) REG32((usartx) + 0x14U) /*!< USART receiver timeout register */ +#define USART_CMD(usartx) REG32((usartx) + 0x18U) /*!< USART command register */ +#define USART_STAT(usartx) REG32((usartx) + 0x1CU) /*!< USART status register */ +#define USART_INTC(usartx) REG32((usartx) + 0x20U) /*!< USART status clear register */ +#define USART_RDATA(usartx) REG32((usartx) + 0x24U) /*!< USART receive data register */ +#define USART_TDATA(usartx) REG32((usartx) + 0x28U) /*!< USART transmit data register */ + +/* bits definitions */ +/* USARTx_CTL0 */ +#define USART_CTL0_UEN BIT(0) /*!< USART enable */ +#define USART_CTL0_UESM BIT(1) /*!< USART enable in deep-sleep mode */ +#define USART_CTL0_REN BIT(2) /*!< receiver enable */ +#define USART_CTL0_TEN BIT(3) /*!< transmitter enable */ +#define USART_CTL0_IDLEIE BIT(4) /*!< idle line detected interrupt enable */ +#define USART_CTL0_RBNEIE BIT(5) /*!< read data buffer not empty interrupt and overrun error interrupt enable */ +#define USART_CTL0_TCIE BIT(6) /*!< transmission complete interrupt enable */ +#define USART_CTL0_TBEIE BIT(7) /*!< transmitter register empty interrupt enable */ +#define USART_CTL0_PERRIE BIT(8) /*!< parity error interrupt enable */ +#define USART_CTL0_PM BIT(9) /*!< parity mode */ +#define USART_CTL0_PCEN BIT(10) /*!< parity control enable */ +#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL BIT(12) /*!< word length */ +#define USART_CTL0_MEN BIT(13) /*!< mute mode enable */ +#define USART_CTL0_AMIE BIT(14) /*!< address match interrupt enable */ +#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ +#define USART_CTL0_DED BITS(16,20) /*!< driver enable deassertion time */ +#define USART_CTL0_DEA BITS(21,25) /*!< driver enable assertion time */ +#define USART_CTL0_RTIE BIT(26) /*!< receiver timeout interrupt enable */ +#define USART_CTL0_EBIE BIT(27) /*!< end of block interrupt enable */ + +/* USARTx_CTL1 */ +#define USART_CTL1_ADDM BIT(4) /*!< address detection mode */ +#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ +#define USART_CTL1_LBDIE BIT(6) /*!< LIN break detection interrupt enable */ +#define USART_CTL1_CLEN BIT(8) /*!< last bit clock pulse */ +#define USART_CTL1_CPH BIT(9) /*!< clock phase */ +#define USART_CTL1_CPL BIT(10) /*!< clock polarity */ +#define USART_CTL1_CKEN BIT(11) /*!< ck pin enable */ +#define USART_CTL1_STB BITS(12,13) /*!< stop bits length */ +#define USART_CTL1_LMEN BIT(14) /*!< LIN mode enable */ +#define USART_CTL1_STRP BIT(15) /*!< swap TX/RX pins */ +#define USART_CTL1_RINV BIT(16) /*!< RX pin level inversion */ +#define USART_CTL1_TINV BIT(17) /*!< TX pin level inversion */ +#define USART_CTL1_DINV BIT(18) /*!< data bit level inversion */ +#define USART_CTL1_MSBF BIT(19) /*!< most significant bit first */ +#define USART_CTL1_ABDEN BIT(20) /*!< auto baud rate enable */ +#define USART_CTL1_ABDM BITS(21,22) /*!< auto baud rate mode */ +#define USART_CTL1_RTEN BIT(23) /*!< receiver timeout enable */ +#define USART_CTL1_ADDR BITS(24,31) /*!< address of the USART terminal */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< error interrupt enable in multibuffer communication */ +#define USART_CTL2_IREN BIT(1) /*!< IrDA mode enable */ +#define USART_CTL2_IRLP BIT(2) /*!< IrDA low-power */ +#define USART_CTL2_HDEN BIT(3) /*!< half-duplex enable */ +#define USART_CTL2_NKEN BIT(4) /*!< NACK enable in smartcard mode */ +#define USART_CTL2_SCEN BIT(5) /*!< smartcard mode enable */ +#define USART_CTL2_DENR BIT(6) /*!< DMA enable for reception */ +#define USART_CTL2_DENT BIT(7) /*!< DMA enable for transmission */ +#define USART_CTL2_RTSEN BIT(8) /*!< RTS enable */ +#define USART_CTL2_CTSEN BIT(9) /*!< CTS enable */ +#define USART_CTL2_CTSIE BIT(10) /*!< CTS interrupt enable */ +#define USART_CTL2_OSB BIT(11) /*!< one sample bit mode */ +#define USART_CTL2_OVRD BIT(12) /*!< overrun disable */ +#define USART_CTL2_DDRE BIT(13) /*!< disable DMA on reception error */ +#define USART_CTL2_DEM BIT(14) /*!< driver enable mode */ +#define USART_CTL2_DEP BIT(15) /*!< driver enable polarity mode */ +#define USART_CTL2_SCRTNUM BITS(17,19) /*!< smartcard auto-retry number */ +#define USART_CTL2_WUM BITS(20,21) /*!< wakeup mode from deep-sleep mode */ +#define USART_CTL2_WUIE BIT(22) /*!< wakeup from deep-sleep mode interrupt enable */ + +/* USARTx_BAUD */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer of baud-rate divider */ + +/* USARTx_GP */ +#define USART_GP_PSC BITS(0,7) /*!< prescaler value for dividing the system clock */ +#define USART_GP_GUAT BITS(8,15) /*!< guard time value in smartcard mode */ + +/* USARTx_RT */ +#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ +#define USART_RT_BL BITS(24,31) /*!< block length */ + +/* USARTx_CMD */ +#define USART_CMD_ABDCMD BIT(0) /*!< auto baudrate detection command */ +#define USART_CMD_SBKCMD BIT(1) /*!< send break command */ +#define USART_CMD_MMCMD BIT(2) /*!< mute mode command */ +#define USART_CMD_RXFCMD BIT(3) /*!< receive data flush command */ +#define USART_CMD_TXFCMD BIT(4) /*!< transmit data flush request */ + +/* USARTx_STAT */ +#define USART_STAT_PERR BIT(0) /*!< parity error flag */ +#define USART_STAT_FERR BIT(1) /*!< frame error flag */ +#define USART_STAT_NERR BIT(2) /*!< noise error flag */ +#define USART_STAT_ORERR BIT(3) /*!< overrun error */ +#define USART_STAT_IDLEF BIT(4) /*!< idle line detected flag */ +#define USART_STAT_RBNE BIT(5) /*!< read data buffer not empty */ +#define USART_STAT_TC BIT(6) /*!< transmission completed */ +#define USART_STAT_TBE BIT(7) /*!< transmit data register empty */ +#define USART_STAT_LBDF BIT(8) /*!< LIN break detected flag */ +#define USART_STAT_CTSF BIT(9) /*!< CTS change flag */ +#define USART_STAT_CTS BIT(10) /*!< CTS level */ +#define USART_STAT_RTF BIT(11) /*!< receiver timeout flag */ +#define USART_STAT_EBF BIT(12) /*!< end of block flag */ +#define USART_STAT_ABDE BIT(14) /*!< auto baudrate detection error */ +#define USART_STAT_ABDF BIT(15) /*!< auto baudrate detection flag */ +#define USART_STAT_BSY BIT(16) /*!< busy flag */ +#define USART_STAT_AMF BIT(17) /*!< address match flag */ +#define USART_STAT_SBF BIT(18) /*!< send break flag */ +#define USART_STAT_RWU BIT(19) /*!< receiver wakeup from mute mode */ +#define USART_STAT_WUF BIT(20) /*!< wakeup from deep-sleep mode flag */ +#define USART_STAT_TEA BIT(21) /*!< transmit enable acknowledge flag */ +#define USART_STAT_REA BIT(22) /*!< receive enable acknowledge flag */ + +/* USARTx_INTC */ +#define USART_INTC_PEC BIT(0) /*!< parity error clear */ +#define USART_INTC_FEC BIT(1) /*!< frame error flag clear */ +#define USART_INTC_NEC BIT(2) /*!< noise detected clear */ +#define USART_INTC_OREC BIT(3) /*!< overrun error clear */ +#define USART_INTC_IDLEC BIT(4) /*!< idle line detected clear */ +#define USART_INTC_TCC BIT(6) /*!< transmission complete clear */ +#define USART_INTC_LBDC BIT(8) /*!< LIN break detected clear */ +#define USART_INTC_CTSC BIT(9) /*!< CTS change clear */ +#define USART_INTC_RTC BIT(11) /*!< receiver timeout clear */ +#define USART_INTC_EBC BIT(12) /*!< end of timeout clear */ +#define USART_INTC_AMC BIT(17) /*!< address match clear */ +#define USART_INTC_WUC BIT(20) /*!< wakeup from deep-sleep mode clear */ + +/* USARTx_RDATA */ +#define USART_RDATA_RDATA BITS(0,8) /*!< receive data value */ + +/* USARTx_TDATA */ +#define USART_TDATA_TDATA BITS(0,8) /*!< transmit data value */ + +/* constants definitions */ +/* define the USART bit position and its register index offset */ +#define USART_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define USART_REG_VAL(usartx, offset) (REG32((usartx) + (((uint32_t)(offset) & 0xFFFFU) >> 6))) +#define USART_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#define USART_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define USART_REG_VAL2(usartx, offset) (REG32((usartx) + ((uint32_t)(offset) >> 22))) +#define USART_BIT_POS2(val) (((uint32_t)(val) & 0x1F0000U) >> 16) + +/* register offset */ +#define USART_CTL0_REG_OFFSET 0x00U /*!< CTL0 register offset */ +#define USART_CTL1_REG_OFFSET 0x04U /*!< CTL1 register offset */ +#define USART_CTL2_REG_OFFSET 0x08U /*!< CTL2 register offset */ +#define USART_STAT_REG_OFFSET 0x1CU /*!< STAT 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_ABD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 15U), /*!< auto baudrate detection flag */ + USART_FLAG_ABDE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 14U), /*!< auto baudrate detection error */ + USART_FLAG_EB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 12U), /*!< end of block flag */ + USART_FLAG_RT = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout flag */ + USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 10U), /*!< CTS level */ + USART_FLAG_CTSF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 9U), /*!< CTS change flag */ + USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected flag */ + USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 7U), /*!< transmit data buffer empty */ + USART_FLAG_TC = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 6U), /*!< transmission complete */ + USART_FLAG_RBNE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty */ + USART_FLAG_IDLE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected flag */ + USART_FLAG_ORERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 3U), /*!< overrun error */ + USART_FLAG_NERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 2U), /*!< noise error flag */ + USART_FLAG_FERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 1U), /*!< frame error flag */ + USART_FLAG_PERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 0U), /*!< parity error flag */ +}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 */ +}usart_interrupt_flag_enum; + +/* USART interrupt enable or disable */ +typedef enum +{ + /* interrupt in CTL0 register */ + USART_INT_EB = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 27U), /*!< end of block interrupt */ + USART_INT_RT = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 26U), /*!< receiver timeout interrupt */ + USART_INT_AM = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 14U), /*!< address match interrupt */ + USART_INT_PERR = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 8U), /*!< parity error interrupt */ + USART_INT_TBE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt */ + USART_INT_TC = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 6U), /*!< transmission complete interrupt */ + USART_INT_RBNE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and overrun error interrupt */ + USART_INT_IDLE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 4U), /*!< IDLE line detected interrupt */ + /* interrupt in CTL1 register */ + USART_INT_LBD = USART_REGIDX_BIT(USART_CTL1_REG_OFFSET, 6U), /*!< LIN break detected interrupt */ + /* interrupt in CTL2 register */ + USART_INT_WU = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 22U), /*!< wakeup from deep-sleep mode interrupt */ + USART_INT_CTS = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 10U), /*!< CTS interrupt */ + USART_INT_ERR = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 0U), /*!< error interrupt */ +}usart_interrupt_enum; + +/* USART invert configure */ +typedef enum { + /* data bit level inversion */ + USART_DINV_ENABLE, /*!< data bit level inversion */ + USART_DINV_DISABLE, /*!< data bit level not inversion */ + /* TX pin level inversion */ + USART_TXPIN_ENABLE, /*!< TX pin level inversion */ + USART_TXPIN_DISABLE, /*!< TX pin level not inversion */ + /* RX pin level inversion */ + USART_RXPIN_ENABLE, /*!< RX pin level inversion */ + USART_RXPIN_DISABLE, /*!< RX pin level not inversion */ + /* swap TX/RX pins */ + USART_SWAP_ENABLE, /*!< swap TX/RX pins */ + USART_SWAP_DISABLE, /*!< not swap TX/RX pins */ +}usart_invert_enum; + +/* USART receiver configure */ +#define CTL0_REN(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_RECEIVE_ENABLE CTL0_REN(1) /*!< enable receiver */ +#define USART_RECEIVE_DISABLE CTL0_REN(0) /*!< disable receiver */ + +/* USART transmitter configure */ +#define CTL0_TEN(regval) (BIT(3) & ((uint32_t)(regval) << 3)) +#define USART_TRANSMIT_ENABLE CTL0_TEN(1) /*!< enable transmitter */ +#define USART_TRANSMIT_DISABLE CTL0_TEN(0) /*!< disable transmitter */ + +/* USART parity bits definitions */ +#define CTL0_PM(regval) (BITS(9,10) & ((uint32_t)(regval) << 9)) +#define USART_PM_NONE CTL0_PM(0) /*!< no parity */ +#define USART_PM_EVEN CTL0_PM(2) /*!< even parity */ +#define USART_PM_ODD CTL0_PM(3) /*!< odd parity */ + +/* USART wakeup method in mute mode */ +#define CTL0_WM(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_WM_IDLE CTL0_WM(0) /*!< idle line */ +#define USART_WM_ADDR CTL0_WM(1) /*!< address match */ + +/* USART word length definitions */ +#define CTL0_WL(regval) (BIT(12) & ((uint32_t)(regval) << 12)) +#define USART_WL_8BIT CTL0_WL(0) /*!< 8 bits */ +#define USART_WL_9BIT CTL0_WL(1) /*!< 9 bits */ + +/* USART oversample mode */ +#define CTL0_OVSMOD(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_OVSMOD_8 CTL0_OVSMOD(1) /*!< oversampling by 8 */ +#define USART_OVSMOD_16 CTL0_OVSMOD(0) /*!< oversampling by 16 */ + +/* USART address detection mode */ +#define CTL1_ADDM(regval) (BIT(4) & ((uint32_t)(regval) << 4)) +#define USART_ADDM_4BIT CTL1_ADDM(0) /*!< 4-bit address detection */ +#define USART_ADDM_FULLBIT CTL1_ADDM(1) /*!< full-bit address detection */ + +/* USART LIN break frame length */ +#define CTL1_LBLEN(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define USART_LBLEN_10B CTL1_LBLEN(0) /*!< 10 bits break detection */ +#define USART_LBLEN_11B CTL1_LBLEN(1) /*!< 11 bits break detection */ + +/* USART last bit clock pulse */ +#define CTL1_CLEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_CLEN_NONE CTL1_CLEN(0) /*!< clock pulse of the last data bit (MSB) is not output to the CK pin */ +#define USART_CLEN_EN CTL1_CLEN(1) /*!< clock pulse of the last data bit (MSB) is output to the CK pin */ + +/* USART clock phase */ +#define CTL1_CPH(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CPH_1CK CTL1_CPH(0) /*!< first clock transition is the first data capture edge */ +#define USART_CPH_2CK CTL1_CPH(1) /*!< second clock transition is the first data capture edge */ + +/* USART clock polarity */ +#define CTL1_CPL(regval) (BIT(10) & ((uint32_t)(regval) << 10)) +#define USART_CPL_LOW CTL1_CPL(0) /*!< steady low value on CK pin */ +#define USART_CPL_HIGH CTL1_CPL(1) /*!< steady high value on CK pin */ + +/* USART stop bits definitions */ +#define CTL1_STB(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define USART_STB_1BIT CTL1_STB(0) /*!< 1 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 */ + +/* USART auto baud rate detection mode bits definitions */ +#define CTL1_ABDM(regval) (BITS(21,22) & ((uint32_t)(regval) << 21)) +#define USART_ABDM_FTOR CTL1_ABDM(0) /*!< falling edge to rising edge measurement */ +#define USART_ABDM_FTOF CTL1_ABDM(1) /*!< falling edge to falling edge measurement */ + +/* USART IrDA low-power enable */ +#define CTL2_IRLP(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_IRLP_LOW CTL2_IRLP(1) /*!< low-power */ +#define USART_IRLP_NORMAL CTL2_IRLP(0) /*!< normal */ + +/* DMA enable for reception */ +#define CTL2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define USART_DENR_ENABLE CTL2_DENR(1) /*!< enable for reception */ +#define USART_DENR_DISABLE CTL2_DENR(0) /*!< disable for reception */ + +/* DMA enable for transmission */ +#define CTL2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_DENT_ENABLE CTL2_DENT(1) /*!< enable for transmission */ +#define USART_DENT_DISABLE CTL2_DENT(0) /*!< disable for transmission */ + +/* USART RTS hardware flow control configure */ +#define CTL2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CTL2_RTSEN(1) /*!< RTS hardware flow control enabled */ +#define USART_RTS_DISABLE CTL2_RTSEN(0) /*!< RTS hardware flow control disabled */ + +/* USART CTS hardware flow control configure */ +#define CTL2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CTL2_CTSEN(1) /*!< CTS hardware flow control enabled */ +#define USART_CTS_DISABLE CTL2_CTSEN(0) /*!< CTS hardware flow control disabled */ + +/* USART one sample bit method configure */ +#define CTL2_OSB(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_OSB_1BIT CTL2_OSB(1) /*!< 1 sample bit */ +#define USART_OSB_3BIT CTL2_OSB(0) /*!< 3 sample bits */ + +/* USART driver enable polarity mode */ +#define CTL2_DEP(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_DEP_HIGH CTL2_DEP(0) /*!< DE signal is active high */ +#define USART_DEP_LOW CTL2_DEP(1) /*!< DE signal is active low */ + +/* USART wakeup mode from deep-sleep mode */ +#define CTL2_WUM(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define USART_WUM_ADDR CTL2_WUM(0) /*!< WUF active on address match */ +#define USART_WUM_STARTB CTL2_WUM(2) /*!< WUF active on start bit */ +#define USART_WUM_RBNE CTL2_WUM(3) /*!< WUF active on RBNE */ + +/* 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); + +/* USART normal mode communication */ +/* 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 transmit data function */ +void usart_data_transmit(uint32_t usart_periph, uint32_t data); +/* USART receive data function */ +uint16_t usart_data_receive(uint32_t usart_periph); +/* 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); +/* overrun function is enabled */ +void usart_overrun_enable(uint32_t usart_periph); +/* overrun function is disabled */ +void usart_overrun_disable(uint32_t usart_periph); +/* configure the USART oversample mode */ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp); +/* sample bit method configure */ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb); + +/* auto baud rate detection */ +/* auto baud rate detection enable */ +void usart_autobaud_detection_enable(uint32_t usart_periph); +/* auto baud rate detection disable */ +void usart_autobaud_detection_disable(uint32_t usart_periph); +/* auto baud rate detection mode configure */ +void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod); + +/* multi-processor communication */ +/* 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); +/* address detection mode configure */ +void usart_address_detection_mode_config(uint32_t usart_periph, uint32_t addmod); +/* configure address of the USART */ +void usart_address_config(uint32_t usart_periph, uint8_t addr); +/* 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_config(uint32_t usart_periph, uint32_t rtimeout); + +/* LIN mode communication */ +/* LIN mode enable */ +void usart_lin_mode_enable(uint32_t usart_periph); +/* LIN mode disable */ +void usart_lin_mode_disable(uint32_t usart_periph); +/* LIN break detection length */ +void usart_lin_break_dection_length_config(uint32_t usart_periph, uint32_t lblen); + +/* half-duplex communication */ +/* half-duplex enable */ +void usart_halfduplex_enable(uint32_t usart_periph); +/* half-duplex disable */ +void usart_halfduplex_disable(uint32_t usart_periph); + +/* synchronous communication */ +/* clock enable */ +void usart_clock_enable(uint32_t usart_periph); +/* clock disable*/ +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 */ +/* smartcard mode enable */ +void usart_smartcard_mode_enable(uint32_t usart_periph); +/* smartcard mode disable */ +void usart_smartcard_mode_disable(uint32_t usart_periph); +/* NACK enable in smartcard mode */ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph); +/* NACK disable in smartcard mode */ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph); +/* guard time value configure in smartcard mode */ +void usart_guard_time_config(uint32_t usart_periph, uint32_t guat); +/* block length configure */ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl); +/* smartcard auto-retry number configure */ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum); + +/* 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 IrDA low-power */ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp); +/* configure the peripheral clock prescaler */ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc); + +/* 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); + +/* RS485 driver enable */ +void usart_rs485_driver_enable(uint32_t usart_periph); +/* RS485 driver disable */ +void usart_rs485_driver_disable(uint32_t usart_periph); +/* driver enable assertion time configure */ +void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime); +/* driver enable de-assertion time configure */ +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 for reception */ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd); +/* configure USART DMA for transmission */ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd); +/* disable DMA on reception error */ +void usart_reception_error_dma_disable(uint32_t usart_periph); +/* enable DMA on reception error */ +void usart_reception_error_dma_enable(uint32_t usart_periph); + +/* USART be able to wake up the mcu from deep-sleep mode */ +void usart_wakeup_enable(uint32_t usart_periph); +/* USART be not able to wake up the mcu from deep-sleep mode */ +void usart_wakeup_disable(uint32_t usart_periph); +/* wakeup mode from deep-sleep mode */ +void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum); + +/* flag functions */ +/* get flag in STAT register */ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag); +/* clear flag in STAT register */ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag); + +/* enable USART interrupt */ +void usart_interrupt_enable(uint32_t usart_periph, uint32_t inttype); +/* disable USART interrupt */ +void usart_interrupt_disable(uint32_t usart_periph, uint32_t inttype); +/* enable USART command */ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype); +/* get USART interrupt and flag status */ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag); +/* clear interrupt flag in STAT register */ +void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t flag); +#endif /* GD32F1X0_USART_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_wwdgt.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_wwdgt.h new file mode 100644 index 0000000..1eaf811 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Include/gd32f1x0_wwdgt.h @@ -0,0 +1,72 @@ +/*! + \file gd32f1x0_wwdgt.h + \brief definitions for the WWDGT +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifndef GD32F1X0_WWDGT_H +#define GD32F1X0_WWDGT_H + +#include "gd32f1x0.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE + +/* registers definitions */ +#define WWDGT_CTL REG32((WWDGT) + 0x00U) /*!< WWDGT control register */ +#define WWDGT_CFG REG32((WWDGT) + 0x04U) /*!< WWDGT configuration register */ +#define WWDGT_STAT REG32((WWDGT) + 0x08U) /*!< WWDGT status register */ + +/* bits definitions */ +/* WWDGT_CTL */ +#define WWDGT_CTL_CNT BITS(0,6) /*!< WWDGT counter value */ +#define WWDGT_CTL_WDGTEN BIT(7) /*!< WWDGT counter enable */ + +/* WWDGT_CFG */ +#define WWDGT_CFG_WIN BITS(0,6) /*!< WWDGT counter window value */ +#define WWDGT_CFG_PSC BITS(7,8) /*!< WWDGT prescaler divider value */ +#define WWDGT_CFG_EWIE BIT(9) /*!< early wakeup interrupt enable */ + +/* WWDGT_STAT */ +#define WWDGT_STAT_EWIF BIT(0) /*!< early wakeup interrupt flag */ + +/* constants definitions */ +/* ctl register value */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to WWDGT_CTL_CNT bit field */ + +/* cfg register value */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to WWDGT_CFG_WIN bit field */ + +#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 */ + +/* function declarations */ +/* reset the window watchdog timer configuration */ +void wwdgt_deinit(void); +/* start the window watchdog timer counter */ +void wwdgt_enable(void); + +/* configure the window watchdog timer counter value */ +void wwdgt_counter_update(uint16_t counter_value); +/* configure counter value, window value, and prescaler divider value */ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler); + +/* enable early wakeup interrupt of WWDGT */ +void wwdgt_interrupt_enable(void); +/* check early wakeup interrupt state of WWDGT */ +FlagStatus wwdgt_flag_get(void); +/* clear early wakeup interrupt state of WWDGT */ +void wwdgt_flag_clear(void); + +#endif /* GD32F1X0_WWDGT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_adc.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_adc.c new file mode 100644 index 0000000..c56ab8a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_adc.c @@ -0,0 +1,817 @@ +/*! + \file gd32f1x0_adc.c + \brief ADC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_adc.h" + +/*! + \brief ADC reset + \param[in] none + \param[out] none + \retval none +*/ +void adc_deinit(void) +{ + rcu_periph_reset_enable(RCU_ADCRST); + rcu_periph_reset_disable(RCU_ADCRST); +} + +/*! + \brief enable ADC interface + \param[in] none + \param[out] none + \retval none +*/ +void adc_enable(void) +{ + if(RESET == (ADC_CTL1 & ADC_CTL1_ADCON)){ + ADC_CTL1 |= (uint32_t)ADC_CTL1_ADCON; + } +} + +/*! + \brief disable ADC interface + \param[in] none + \param[out] none + \retval none +*/ +void adc_disable(void) +{ + ADC_CTL1 &= (uint32_t)~(ADC_CTL1_ADCON); +} + +/*! + \brief ADC calibration and reset calibration + \param[in] none + \param[out] none + \retval none +*/ +void adc_calibration_enable(void) +{ + /* reset the selected ADC1 calibration registers */ + ADC_CTL1 |= (uint32_t) ADC_CTL1_RSTCLB; + /* check the RSTCLB bit state */ + while((ADC_CTL1 & ADC_CTL1_RSTCLB)){ + } + /* enable ADC calibration process */ + ADC_CTL1 |= ADC_CTL1_CLB; + /* check the CLB bit state */ + while((ADC_CTL1 & ADC_CTL1_CLB)){ + } +} + +/*! + \brief enable DMA request + \param[in] none + \param[out] none + \retval none +*/ +void adc_dma_mode_enable(void) +{ + ADC_CTL1 |= (uint32_t)(ADC_CTL1_DMA); +} + +/*! + \brief disable DMA request + \param[in] none + \param[out] none + \retval none +*/ +void adc_dma_mode_disable(void) +{ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DMA); +} + +/*! + \brief enable ADC0 temperature sensor and Vrefint channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_tempsensor_vrefint_enable(void) +{ + /* enable the temperature sensor and Vrefint channel */ + ADC_CTL1 |= ADC_CTL1_TSVREN; +} + +/*! + \brief disable ADC0 temperature sensor and Vrefint channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_tempsensor_vrefint_disable(void) +{ + /* disable the temperature sensor and Vrefint channel */ + ADC_CTL1 &= ~ADC_CTL1_TSVREN; +} + +/*! + \brief enable the vbat channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_vbat_enable(void) +{ + /* enable the vbat channel */ + ADC_CTL1 |= ADC_CTL1_VBETEN; +} + +/*! + \brief disable the vbat channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_vbat_disable(void) +{ + /* disable the vbat channel */ + ADC_CTL1 &= ~ADC_CTL1_VBETEN; +} + +/*! + \brief adc discontinuous mode config + \param[in] channel_group: select the channel group + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] length: number of conversions in discontinuous mode,the number can be 1..8 + for regular channel ,the number is insignificant for inserted channel + \param[out] none + \retval none +*/ +void adc_discontinuous_mode_config(uint8_t channel_group,uint8_t length) +{ + ADC_CTL0 &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC)); + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + /* config the number of conversions in discontinuous mode */ + ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DISNUM); + ADC_CTL0 |= (uint32_t)(((uint32_t)length - 1U) << 13U); + + ADC_CTL0 |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t)ADC_CTL0_DISIC; + break; + default: + break; + } +} + +/*! + \brief enable or disable ADC special function + \param[in] function: the function to config + one or more parameters can be selected 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 function, ControlStatus newvalue) +{ + if(newvalue){ + if(RESET != (function & ADC_SCAN_MODE)){ + ADC_CTL0 |= ADC_SCAN_MODE; + } + if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){ + ADC_CTL0 |= ADC_INSERTED_CHANNEL_AUTO; + } + if(RESET != (function & ADC_CONTINUOUS_MODE)){ + ADC_CTL1 |= ADC_CONTINUOUS_MODE; + } + }else{ + if(RESET != (function & ADC_SCAN_MODE)){ + ADC_CTL0 &= ~ADC_SCAN_MODE; + } + if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){ + ADC_CTL0 &= ~ADC_INSERTED_CHANNEL_AUTO; + } + if(RESET != (function & ADC_CONTINUOUS_MODE)){ + ADC_CTL1 &= ~ADC_CONTINUOUS_MODE; + } + } +} + +/*! + \brief adc data alignment config + \param[in] data_alignment: data alignment select + only one parameter can be selected + \arg ADC_DATAALIGN_RIGHT: LSB alignment + \arg ADC_DATAALIGN_LEFT: MSB alignment + \param[out] none + \retval none +*/ +void adc_data_alignment_config(uint32_t data_alignment) +{ + if(data_alignment){ + ADC_CTL1 |= ADC_CTL1_DAL; + }else{ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DAL); + } +} + +/*! + \brief config the length of regular channel group or inserted channel group + \param[in] channel_group: select the channel group + only one parameter can be selected + \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-17 + inserted channel 1-4 + \param[out] none + \retval none +*/ +void adc_channel_length_config(uint8_t channel_group,uint32_t length) +{ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_RSQ0 &= ~(((uint32_t)length - 1U) << 20U); + ADC_RSQ0 |= (((uint32_t)length - 1U) << 20U); + break; + case ADC_INSERTED_CHANNEL: + ADC_ISQ &= ~(((uint32_t)length - 1U) << 20U); + ADC_ISQ |= (((uint32_t)length - 1U) << 20U); + break; + default: + break; + } +} + +/*! + \brief ADC regular channel config + \param[in] rank: the regular group sequencer rank,this parameter must be between 0 to 15 + \param[in] channel: the selected ADC channel + \arg ADC_CHANNEL_x(x=0..18): ADC Channelx + \param[in] sample_time: the sample time value + \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles + \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles + \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles + \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles + \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles + \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles + \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles + \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles + \param[out] none + \retval none +*/ +void adc_regular_channel_config(uint8_t rank, uint8_t channel,uint32_t sample_time) +{ + uint32_t rsq,sampt; + +#ifdef GD32F130_150 + if(ADC_CHANNEL_18 == channel){ + channel = ADC_CHANNEL_0; + } +#endif + + /* configure ADC regular sequence */ + if(rank < 6U){ + rsq = ADC_RSQ2; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank))); + rsq |= ((uint32_t)channel << (5U*rank)); + ADC_RSQ2 = rsq; + }else if(rank < 12U){ + rsq = ADC_RSQ1; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U)))); + rsq |= ((uint32_t)channel << (5U*(rank-6U))); + ADC_RSQ1 = rsq; + }else if(rank < 16U){ + rsq = ADC_RSQ0; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U)))); + rsq |= ((uint32_t)channel << (5U*(rank-12U))); + ADC_RSQ0 = rsq; + }else{ + /* illegal parameters */ + } + + /* configure ADC sampling time */ + if(channel < 10U){ + sampt = ADC_SAMPT1; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel))); + sampt |= (uint32_t)(sample_time << (3U*channel)); + ADC_SAMPT1 = sampt; + }else if(channel < 18U){ + sampt = ADC_SAMPT0; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel-10U)))); + sampt |= (uint32_t)(sample_time << (3U*(channel-10U))); + ADC_SAMPT0 = sampt; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief ADC inserted channel config + \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3 + \param[in] channel: the selected ADC channel + \arg ADC_CHANNEL_x(x=0..18): ADC Channelx + \param[in] sample_time: The sample time value + \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles + \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles + \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles + \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles + \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles + \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles + \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles + \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles + \param[out] none + \retval none +*/ +void adc_inserted_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time) +{ + uint8_t inserted_length; + uint32_t isq,sampt; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20, 21); + if(rank < 5U){ + isq = ADC_ISQ; + isq &= ~((uint32_t)(ADC_ISQ_ISQN << (15U - (inserted_length - rank)*5U))); + isq |= ((uint32_t)channel << (15U - (inserted_length - rank)*5U)); + ADC_ISQ = isq; + } + + if(channel < 10U){ + sampt = ADC_SAMPT1; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel))); + sampt |= (uint32_t) sample_time << (3U*channel); + ADC_SAMPT1 = sampt; + }else if(channel < 19U){ + sampt = ADC_SAMPT0; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel-10U)))); + sampt |= ((uint32_t)sample_time << (3U*(channel-10U))); + ADC_SAMPT0 = sampt; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief adc inserted channel offset config + \param[in] inserted_channel : insert channel select + \arg ADC_INSERTED_CHANNEL_0: inserted channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted channel3 + \param[in] offset : the offset data + \param[out] none + \retval the conversion value +*/ +void adc_inserted_channel_offset_config(uint8_t inserted_channel,uint16_t offset) +{ + uint8_t inserted_length; + uint32_t num = 0U; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20U, 21U); + num = 3U - (inserted_length - inserted_channel); + + if(num <= 3U){ + /* calculate the offset of the register */ + num = num * 4U; + /* config the offset of the selected channels */ + REG32((ADC_BASE) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset); + } +} + +/*! + \brief adc external trigger enable + \param[in] adc_channel_group: select the channel group + \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(uint8_t channel_group,ControlStatus newvalue) +{ + if(newvalue){ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_ETERC; + } + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_ETEIC; + } + }else{ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 &= ~ADC_CTL1_ETERC; + } + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 &= ~ADC_CTL1_ETEIC; + } + } +} + +/*! + \brief adc external trigger source config + \param[in] adc_channel_group: select the channel group + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] external_trigger_source: regular or inserted group trigger source + for regular channel: + \arg ADC_EXTTRIG_REGULAR_T0_CH0: external trigger timer 0 CH0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T0_CH1: external trigger timer 0 CH1 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T0_CH2: external trigger timer 0 CH2 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T1_CH1: external trigger timer 1 CH1 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T2_TRGO: external trigger timer 2 TRGO event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T14_CH0: external trigger timer 14 CH0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_EXT_IT11: external trigger extiline 11 select for regular channel + \arg ADC_EXTTRIG_REGULAR_SWRCST: software trigger select for regular channel + for inserted channel: + \arg ADC_EXTTRIG_INSERTED_T0_TRGO: external trigger timer0 TRGO event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T0_CH3: external trigger timer0 CH3 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T1_TRGO: external trigger timer1 TRGO event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T1_CH0: external trigger timer1 CH0 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T2_CH3: external trigger timer2 CH3 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T14_TRGO: external trigger timer14 TRGO event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_EXT_IT15: external interrupt line 15 select for inserted channel + \arg ADC_EXTTRIG_INSERTED_SWRCST: software trigger select for inserted channel + \param[out] none + \retval none +*/ +void adc_external_trigger_source_config(uint8_t channel_group,uint32_t external_trigger_source) +{ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSRC); + ADC_CTL1 |= (uint32_t)external_trigger_source; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSIC); + ADC_CTL1 |= (uint32_t)external_trigger_source; + break; + default: + break; + } +} + +/*! + \brief adc software trigger enable + \param[in] adc_channel_group: select the channel group + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[out] none + \retval none +*/ +void adc_software_trigger_enable(uint8_t channel_group) +{ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_SWRCST; + } + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_SWICST; + } +} + +/*! + \brief adc regular group data register read + \param[in] none + \param[out] none + \retval the conversion value +*/ +uint16_t adc_regular_data_read(void) +{ + return (uint16_t)(ADC_RDATA); +} + +/*! + \brief adc inserted group data register read + \param[in] inserted_channel : insert channel select + \arg ADC_INSERTED_CHANNEL_0: inserted channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted channel3 + \param[out] none + \retval the conversion value +*/ +uint16_t adc_inserted_data_read(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; + break; + case ADC_INSERTED_CHANNEL_1: + idata = ADC_IDATA1; + break; + case ADC_INSERTED_CHANNEL_2: + idata = ADC_IDATA2; + break; + case ADC_INSERTED_CHANNEL_3: + idata = ADC_IDATA3; + break; + default: + idata = 0U; + break; + } + return (uint16_t)idata; +} + +/*! + \brief get the ADC flag bits + \param[in] flag: the adc flag bits + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_flag_get(uint32_t flag) +{ + FlagStatus reval = RESET; + + if(ADC_STAT & flag){ + reval = SET; + } + return reval; + +} + +/*! + \brief clear the ADC status flag + \param[in] flag: the adc flag bits + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \param[out] none + \retval none +*/ +void adc_flag_clear(uint32_t flag) +{ + ADC_STAT &= ~((uint32_t)flag); +} + +/*! + \brief get the ADC interrupt bits + \param[in] flag: the adc interrupt flag + \arg ADC_INT_FLAG_WDE: analog watchdog 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 + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_interrupt_flag_get(uint32_t flag) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + /* check the interrupt bits */ + switch(flag){ + case ADC_INT_FLAG_WDE: + state = ADC_STAT & ADC_STAT_WDE; + if((ADC_CTL0 & ADC_CTL0_WDEIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOC: + state = ADC_STAT & ADC_STAT_EOC; + if((ADC_CTL0 & ADC_CTL0_EOCIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOIC: + state = ADC_STAT & ADC_STAT_EOIC; + if((ADC_CTL0 & ADC_CTL0_EOICIE) && state){ + interrupt_flag = SET; + } + break; + default: + break; + } + + return interrupt_flag; +} + +/*! + \brief clear the ADC interrupt bits + \param[in] adc_interrupt: the adc interrupt bits + \arg ADC_INT_FLAG_WDE: analog watchdog 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 + \param[out] none + \retval none +*/ +void adc_interrupt_flag_clear(uint32_t flag) +{ + ADC_STAT &= ~((uint32_t)flag); +} + +/*! + \brief enable ADC interrupt + \param[in] adc_periph: ADCx, x=0,1,2 + only one among these parameters can be selected + \param[in] interrupt: the adc interrupt + one or more parameters can be selected + \arg ADC_INT_WDE: analog watchdog interrupt + \arg ADC_INT_EOC: end of group conversion interrupt + \arg ADC_INT_EOIC: end of inserted group conversion interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_enable(uint32_t interrupt) +{ + if(RESET != (interrupt & ADC_INT_WDE)){ + ADC_CTL0 |= (uint32_t) ADC_CTL0_WDEIE; + } + + if(RESET != (interrupt & ADC_INT_EOC)){ + ADC_CTL0 |= (uint32_t) ADC_CTL0_EOCIE; + } + + if(RESET != (interrupt & ADC_INT_EOIC)){ + ADC_CTL0 |= (uint32_t) ADC_CTL0_EOICIE; + } +} + +/*! + \brief disable ADC interrupt + \param[in] adc_periph: ADCx,x=0,1,2 + only one among these parameters can be selected + \param[in] interrupt: the adc interrupt flag + one or more parameters can be selected + \arg ADC_INT_WDE: analog watchdog interrupt flag + \arg ADC_INT_EOC: end of group conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_disable(uint32_t interrupt) +{ + if(RESET != (interrupt & ADC_INT_WDE)){ + ADC_CTL0 &= ~(uint32_t) ADC_CTL0_WDEIE; + } + + if(RESET != (interrupt & ADC_INT_EOC)){ + ADC_CTL0 &= ~(uint32_t) ADC_CTL0_EOCIE; + } + + if(RESET != (interrupt & ADC_INT_EOIC)){ + ADC_CTL0 &= ~(uint32_t) ADC_CTL0_EOICIE; + } +} + +/*! + \brief ADC analog watchdog single channel config + \param[in] channel: the selected ADC channel + \arg ADC_CHANNEL_x: ADC Channelx(x=0..18) + \param[out] none + \retval none +*/ +void adc_watchdog_single_channel_enable(uint8_t channel) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); + + ADC_CTL0 |= (uint32_t)channel; + ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); +} + +/*! + \brief adc analog watchdog group channel config + \param[in] adc_channel_group: the channel group use analog watchdog + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group + \param[out] none + \retval none +*/ +void adc_watchdog_group_channel_enable(uint8_t channel_group) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); + /* select the group */ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL0 |= (uint32_t) ADC_CTL0_RWDEN; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t) ADC_CTL0_IWDEN; + break; + case ADC_REGULAR_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN); + break; + default: + break; + } +} + + + +/*! + \brief ADC analog watchdog disable + \param[in] none + \param[out] none + \retval none +*/ +void adc_watchdog_disable(void) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); +} + +/*! + \brief ADC analog watchdog threshold config + \param[in] low_threshold: analog watchdog low threshold + \param[in] high_threshold: analog watchdog high threshold + \param[out] none + \retval none +*/ +void adc_watchdog_threshold_config(uint16_t low_threshold,uint16_t high_threshold) +{ + ADC_WDLT = (uint32_t)low_threshold; + ADC_WDHT = (uint32_t)high_threshold; +} + +#ifdef GD32F170_190 +/*! + \brief adc resolution config + \param[in] resolution: ADC resolution + \arg ADC_RESOLUTION_12B: 12-bit ADC resolution + \arg ADC_RESOLUTION_10B: 10-bit ADC resolution + \arg ADC_RESOLUTION_8B: 8-bit ADC resolution + \arg ADC_RESOLUTION_6B: 6-bit ADC resolution + \param[out] none + \retval none +*/ +void adc_resolution_config(uint32_t resolution) +{ + ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DRES); + ADC_CTL0 |= (uint32_t)resolution; +} + +/*! + \brief adc oversample mode config + \param[in] mode: ADC oversampling mode + \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 + \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 + \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio X2 + \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio X4 + \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio X8 + \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio X16 + \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio X32 + \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio X64 + \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio X128 + \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio X256 + \param[out] none + \retval none +*/ +void adc_oversample_mode_config(uint8_t mode, uint16_t shift,uint8_t ratio) +{ + if(mode){ + ADC_OVSAMPCTL |= (uint32_t)ADC_OVSAMPCTL_TOVS; + }else{ + ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_TOVS); + } + /* config the shift and ratio */ + ADC_OVSAMPCTL &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS)); + ADC_OVSAMPCTL |= ((uint32_t)shift | (uint32_t)ratio); +} + +/*! + \brief enable ADC oversample mode + \param[in] none + \param[out] none + \retval none +*/ +void adc_oversample_mode_enable(void) +{ + ADC_OVSAMPCTL |= ADC_OVSAMPCTL_OVSEN; +} + +/*! + \brief disable ADC oversample mode + \param[in] none + \param[out] none + \retval none +*/ +void adc_oversample_mode_disable(void) +{ + ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN); +} +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_can.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_can.c new file mode 100644 index 0000000..00cc46e --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_can.c @@ -0,0 +1,893 @@ +/*! + \file gd32f1x0_can.c + \brief CAN driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 + +#include "gd32f1x0_can.h" +#include "gd32f1x0.h" + +/*! + \brief deinitialize CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_deinit(uint32_t can_periph) +{ + if(CAN0 == can_periph){ + rcu_periph_reset_enable(RCU_CAN0RST); + rcu_periph_reset_disable(RCU_CAN0RST); + }else{ + rcu_periph_reset_enable(RCU_CAN1RST); + rcu_periph_reset_disable(RCU_CAN1RST); + } +} + +/*! + \brief initialize CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_parameter_init: parameters for CAN initializtion + \arg working_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE + \arg resync_jump_width: CAN_BT_SJW_xTQ(x=1, 2, 3, 4) + \arg time_segment_1: CAN_BT_BS1_xTQ(1..16) + \arg time_segment_2: CAN_BT_BS2_xTQ(1..8) + \arg time_triggered: ENABLE or DISABLE + \arg auto_bus_off_recovery: ENABLE or DISABLE + \arg auto_wake_up: ENABLE or DISABLE + \arg auto_retrans: ENABLE or DISABLE + \arg rec_fifo_overwrite: ENABLE or DISABLE + \arg trans_fifo_order: ENABLE or DISABLE + \arg prescaler: 0x0001 - 0x03FF + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init) +{ + uint32_t timeout = CAN_TIMEOUT; + ErrStatus flag = ERROR; + + /* disable sleep mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; + /* enable initialize mode */ + CAN_CTL(can_periph) |= CAN_CTL_IWMOD; + /* wait ACK */ + while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){ + timeout--; + } + /* check initialize working success */ + if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + flag = ERROR; + }else{ + /* set the bit timing register */ + CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \ + BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \ + BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \ + BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \ + BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U))); + /* time trigger communication mode */ + if(ENABLE == can_parameter_init->time_triggered){ + CAN_CTL(can_periph) |= CAN_CTL_TTC; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_TTC; + } + /* automatic bus-off managment */ + if(ENABLE == can_parameter_init->auto_bus_off_recovery){ + CAN_CTL(can_periph) |= CAN_CTL_ABOR; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_ABOR; + } + /* automatic wakeup mode */ + if(ENABLE == can_parameter_init->auto_wake_up){ + CAN_CTL(can_periph) |= CAN_CTL_AWU; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_AWU; + } + /* automatic retransmission mode */ + if(ENABLE == can_parameter_init->auto_retrans){ + CAN_CTL(can_periph) |= CAN_CTL_ARD; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_ARD; + } + /* receive fifo overwrite mode */ + if(ENABLE == can_parameter_init->rec_fifo_overwrite){ + CAN_CTL(can_periph) |= CAN_CTL_RFOD; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_RFOD; + } + /* transmit fifo order */ + if(ENABLE == can_parameter_init->trans_fifo_order){ + CAN_CTL(can_periph) |= CAN_CTL_TFO; + }else{ + CAN_CTL(can_periph) &= ~CAN_CTL_TFO; + } + /* disable initialize mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD; + timeout = CAN_TIMEOUT; + /* wait the ACK */ + while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){ + timeout--; + } + /* check exit initialize mode */ + if(CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + flag = SUCCESS; + } + } + return flag; +} + +/*! + \brief initialize CAN filter + \param[in] can_filter_parameter_init: struct for CAN filter initialization + \arg filter_list_high: 0x0000 - 0xFFFF + \arg filter_list_low: 0x0000 - 0xFFFF + \arg filter_mask_high: 0x0000 - 0xFFFF + \arg filter_mask_low: 0x0000 - 0xFFFF + \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1 + \arg filter_number: 0 - 27 + \arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST + \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT + \arg filter_enable: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init) +{ + uint32_t val = 0U; + + val = ((uint32_t)1) << (can_filter_parameter_init->filter_number); + /* filter lock disable */ + CAN_FCTL(CAN0) |= CAN_FCTL_FLD; + /* disable filter */ + CAN_FW(CAN0) &= ~(uint32_t)val; + /* filter 16 bits */ + if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){ + /* set filter 16 bits */ + CAN_FSCFG(CAN0) &= ~(uint32_t)val; + /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */ + CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */ + CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS); + } + /* filter 32 bits */ + if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){ + /* set filter 32 bits */ + CAN_FSCFG(CAN0) |= (uint32_t)val; + /* 32 bits list or first 32 bits list */ + CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + /* 32 bits mask or second 32 bits list */ + CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS); + } + /* filter mode */ + if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){ + /* mask mode */ + CAN_FMCFG(CAN0) &= ~(uint32_t)val; + }else{ + /* list mode */ + CAN_FMCFG(CAN0) |= (uint32_t)val; + } + /* filter FIFO */ + if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){ + /* FIFO0 */ + CAN_FAFIFO(CAN0) &= ~(uint32_t)val; + }else{ + /* FIFO1 */ + CAN_FAFIFO(CAN0) |= (uint32_t)val; + } + /* filter working */ + if(ENABLE == can_filter_parameter_init->filter_enable){ + + CAN_FW(CAN0) |= (uint32_t)val; + } + /* filter lock enable */ + CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; +} + +/*! + \brief set CAN1 fliter start bank number + \param[in] start_bank: CAN1 start bank number + \arg (1..27) + \param[out] none + \retval none +*/ +void can1_filter_start_bank(uint8_t start_bank) +{ + /* filter lock disable */ + CAN_FCTL(CAN0) |= CAN_FCTL_FLD; + /* set CAN1 filter start number */ + CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F; + CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank); + /* filter lock enaable */ + CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; +} + +/*! + \brief enable CAN debug freeze + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_debug_freeze_enable(uint32_t can_periph) +{ + CAN_CTL(can_periph) |= CAN_CTL_DFZ; + + if(CAN0 == can_periph){ + dbg_periph_enable(DBG_CAN0_HOLD); + }else{ + dbg_periph_enable(DBG_CAN1_HOLD); + } +} + +/*! + \brief disable CAN debug freeze + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_debug_freeze_disable(uint32_t can_periph) +{ + CAN_CTL(can_periph) |= CAN_CTL_DFZ; + + if(CAN0 == can_periph){ + dbg_periph_disable(DBG_CAN0_HOLD); + }else{ + dbg_periph_disable(DBG_CAN1_HOLD); + } +} + +/*! + \brief enable CAN time trigger mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_trigger_mode_enable(uint32_t can_periph) +{ + uint8_t mailbox_number; + + /* enable the tcc mode */ + CAN_CTL(can_periph) |= CAN_CTL_TTC; + /* enable time stamp */ + for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){ + CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN; + } +} + +/*! + \brief disable CAN time trigger mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_trigger_mode_disable(uint32_t can_periph) +{ + uint8_t mailbox_number; + + /* disable the TCC mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_TTC; + /* reset TSEN bits */ + for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){ + CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN; + } +} + +/*! + \brief transmit CAN message + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] transmit_message: struct for CAN transmit message + \arg tx_sfid: 0x00000000 - 0x000007FF + \arg tx_efid: 0x00000000 - 0x1FFFFFFF + \arg tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED + \arg tx_ft: CAN_FT_DATA, CAN_FT_REMOTE + \arg tx_dlenc: 1 - 7 + \arg tx_data[]: 0x00 - 0xFF + \param[out] none + \retval mailbox_number +*/ +uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message) +{ + uint8_t mailbox_number = CAN_MAILBOX0; + + /* select one empty mailbox */ + if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){ + mailbox_number = CAN_MAILBOX0; + }else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){ + mailbox_number = CAN_MAILBOX1; + }else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){ + mailbox_number = CAN_MAILBOX2; + }else{ + mailbox_number = CAN_NOMAILBOX; + } + if(CAN_NOMAILBOX == mailbox_number){ + return CAN_NOMAILBOX; + } + + CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN; + if(CAN_FF_STANDARD == transmit_message->tx_ff){ + /* set transmit mailbox standard identifier */ + CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \ + transmit_message->tx_ft); + }else{ + /* set transmit mailbox extended identifier */ + CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \ + transmit_message->tx_ff | \ + transmit_message->tx_ft); + } + /* set the data length */ + CAN_TMP(can_periph, mailbox_number) &= ((uint32_t)~CAN_TMP_DLENC); + CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen; + /* set the data */ + CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \ + TMDATA0_DB2(transmit_message->tx_data[2]) | \ + TMDATA0_DB1(transmit_message->tx_data[1]) | \ + TMDATA0_DB0(transmit_message->tx_data[0]); + CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \ + TMDATA1_DB6(transmit_message->tx_data[6]) | \ + TMDATA1_DB5(transmit_message->tx_data[5]) | \ + TMDATA1_DB4(transmit_message->tx_data[4]); + /* enable transmission */ + CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN; + + return mailbox_number; +} + +/*! + \brief get CAN transmit state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] mailbox_number + \arg CAN_MAILBOX(x=0,1,2) + \param[out] none + \retval can_transmit_state_enum +*/ +can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number) +{ + can_transmit_state_enum state = CAN_TRANSMIT_FAILED; + uint32_t val = 0U; + + switch(mailbox_number){ + case CAN_MAILBOX0: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0); + break; + case CAN_MAILBOX1: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1); + break; + case CAN_MAILBOX2: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2); + break; + default: + val = CAN_TRANSMIT_FAILED; + break; + } + switch(val){ + /* transmit pending */ + case (CAN_STATE_PENDING): + state = CAN_TRANSMIT_PENDING; + break; + /* transmit succeeded */ + case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0): + state = CAN_TRANSMIT_OK; + break; + case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1): + state = CAN_TRANSMIT_OK; + break; + case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2): + state = CAN_TRANSMIT_OK; + break; + default: + state = CAN_TRANSMIT_FAILED; + break; + } + return state; +} + +/*! + \brief stop CAN transmission + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] mailbox_number + only one parameter can be selected which is shown as below: + \arg CAN_MAILBOXx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number) +{ + if(CAN_MAILBOX0 == mailbox_number){ + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0; + }else if(CAN_MAILBOX1 == mailbox_number){ + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1; + }else if(CAN_MAILBOX2 == mailbox_number){ + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief CAN receive message + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + \arg CAN_FIFOx(x=0,1) + \param[out] receive_message: struct for CAN receive message + \arg rx_sfid: 0x00000000 - 0x000007FF + \arg rx_efid: 0x00000000 - 0x1FFFFFFF + \arg rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED + \arg rx_ft: CAN_FT_DATA, CAN_FT_REMOTE + \arg rx_dlenc: 1 - 7 + \arg rx_data[]: 0x00 - 0xFF + \arg rx_fi: 0 - 27 + \retval none +*/ +void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message) +{ + /* get the frame format */ + receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number)); + if(CAN_FF_STANDARD == receive_message->rx_ff){ + /* get standard identifier */ + receive_message -> rx_sfid = (uint32_t)(RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number))); + }else{ + /* get extended identifier */ + receive_message -> rx_efid = (uint32_t)(RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number))); + } + + /* get frame type */ + receive_message -> rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number)); + /* get recevie data length */ + receive_message -> rx_dlen = (uint8_t)(RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number))); + /* filtering index */ + receive_message -> rx_fi = (uint8_t)(RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number))); + + /* receive data */ + receive_message -> rx_data[0] = (uint8_t)(RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[1] = (uint8_t)(RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[2] = (uint8_t)(RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[3] = (uint8_t)(RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[4] = (uint8_t)(RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[5] = (uint8_t)(RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[6] = (uint8_t)(RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[7] = (uint8_t)(RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number))); + + /* release FIFO */ + if(CAN_FIFO0 == fifo_number){ + CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0; + }else{ + CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1; + } +} + +/*! + \brief release FIFO0 + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + \arg CAN_FIFOx(x=0,1) + \param[out] none + \retval none +*/ +void can_fifo_release(uint32_t can_periph, uint8_t fifo_number) +{ + if(CAN_FIFO0 == fifo_number){ + CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0; + }else if(CAN_FIFO1 == fifo_number){ + CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief CAN receive message length + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + \arg CAN_FIFOx(x=0,1) + \param[out] none + \retval message length +*/ +uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number) +{ + uint8_t val = 0U; + + if(CAN_FIFO0 == fifo_number){ + val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK); + }else if(CAN_FIFO1 == fifo_number){ + val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK); + }else{ + /* illegal parameters */ + } + return val; +} + +/*! + \brief set CAN working mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_working_mode + \arg CAN_MODE_INITIALIZE + \arg CAN_MODE_NORMAL + \arg CAN_MODE_SLEEP + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode) +{ + ErrStatus flag = ERROR; + /* timeout for IWS or also for SLPWS bits */ + uint32_t timeout = CAN_TIMEOUT; + + if(CAN_MODE_INITIALIZE == working_mode){ + /* disable sleep mode */ + CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD); + /* set initialize mode */ + CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD; + /* wait the acknowledge */ + while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){ + timeout--; + } + if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + }else if(CAN_MODE_NORMAL == working_mode){ + /* enter normal mode */ + CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD); + /* wait the acknowledge */ + while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)){ + timeout--; + } + if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + }else if(CAN_MODE_SLEEP == working_mode){ + /* disable initialize mode */ + CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD); + /* set sleep mode */ + CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD; + /* wait the acknowledge */ + while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)){ + timeout--; + } + if(CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + }else{ + flag = ERROR; + } + return flag; +} + +/*! + \brief wake up CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus can_wakeup(uint32_t can_periph) +{ + ErrStatus flag = ERROR; + uint32_t timeout = CAN_TIMEOUT; + + /* wakeup */ + CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; + + while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)){ + timeout--; + } + if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){ + flag = ERROR; + }else{ + flag = SUCCESS; + } + return flag; +} + +/*! + \brief get CAN error type + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval can_error_enum +*/ +can_error_enum can_error_get(uint32_t can_periph) +{ + can_error_enum error; + error = CAN_ERROR_NONE; + + /* get error type */ + error = (can_error_enum)((CAN_ERR(can_periph) & CAN_ERR_ERRN) >> 4U); + return error; +} + +/*! + \brief get CAN receive error number + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval error number +*/ +uint8_t can_receive_error_number_get(uint32_t can_periph) +{ + uint8_t val; + + val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_RECNT) >> 24U); + return val; +} + +/*! + \brief get CAN transmit error number + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval error number +*/ +uint8_t can_transmit_error_number_get(uint32_t can_periph) +{ + uint8_t val; + + val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_TECNT) >> 16U); + return val; +} + +/*! + \brief enable CAN interrupt + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] interrupt + \arg CAN_INT_TME: transmit mailbox empty interrupt enable + \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable + \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable + \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable + \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable + \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable + \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable + \arg CAN_INT_WERR: warning error interrupt enable + \arg CAN_INT_PERR: passive error interrupt enable + \arg CAN_INT_BO: bus-off interrupt enable + \arg CAN_INT_ERRN: error number interrupt enable + \arg CAN_INT_ERR: error interrupt enable + \arg CAN_INT_WU: wakeup interrupt enable + \arg CAN_INT_SLPW: sleep working interrupt enable + \param[out] none + \retval none +*/ +void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt) +{ + CAN_INTEN(can_periph) |= interrupt; +} + +/*! + \brief disable CAN interrupt + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] interrupt + \arg CAN_INT_TME: transmit mailbox empty interrupt enable + \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable + \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable + \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable + \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable + \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable + \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable + \arg CAN_INT_WERR: warning error interrupt enable + \arg CAN_INT_PERR: passive error interrupt enable + \arg CAN_INT_BO: bus-off interrupt enable + \arg CAN_INT_ERRN: error number interrupt enable + \arg CAN_INT_ERR: error interrupt enable + \arg CAN_INT_WU: wakeup interrupt enable + \arg CAN_INT_SLPW: sleep working interrupt enable + \param[out] none + \retval none +*/ +void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt) +{ + CAN_INTEN(can_periph) &= ~interrupt; +} + +/*! + \brief get CAN flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_MTE2: mailbox 2 transmit error + \arg CAN_FLAG_MTE1: mailbox 1 transmit error + \arg CAN_FLAG_MTE0: mailbox 0 transmit error + \arg CAN_FLAG_MTF2: mailbox 2 transmit finished + \arg CAN_FLAG_MTF1: mailbox 1 transmit finished + \arg CAN_FLAG_MTF0: mailbox 0 transmit finished + \arg CAN_FLAG_RFO0: receive FIFO0 overfull + \arg CAN_FLAG_RFF0: receive FIFO0 full + \arg CAN_FLAG_RFO1: receive FIFO1 overfull + \arg CAN_FLAG_RFF1: receive FIFO1 full + \arg CAN_FLAG_BOERR: bus-off error + \arg CAN_FLAG_PERR: passive error + \arg CAN_FLAG_WERR: warning error + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag) +{ + if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CAN flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_MTE2: mailbox 2 transmit error + \arg CAN_FLAG_MTE1: mailbox 1 transmit error + \arg CAN_FLAG_MTE0: mailbox 0 transmit error + \arg CAN_FLAG_MTF2: mailbox 2 transmit finished + \arg CAN_FLAG_MTF1: mailbox 1 transmit finished + \arg CAN_FLAG_MTF0: mailbox 0 transmit finished + \arg CAN_FLAG_RFO0: receive FIFO0 overfull + \arg CAN_FLAG_RFF0: receive FIFO0 full + \arg CAN_FLAG_RFO1: receive FIFO1 overfull + \arg CAN_FLAG_RFF1: receive FIFO1 full + \param[out] none + \retval none +*/ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag) +{ + CAN_REG_VAL(can_periph, flag) |= BIT(CAN_BIT_POS(flag)); +} + +/*! + \brief get CAN interrupt flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering + \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode + \arg CAN_INT_FLAG_ERRIF: error interrupt flag + \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag + \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag + \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag + \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag + \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag) +{ + FlagStatus ret1 = RESET; + FlagStatus ret2 = RESET; + + /* get the staus of interrupt flag */ + ret1 = (FlagStatus)(CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag))); + /* get the staus of interrupt enale bit */ + ret2 = (FlagStatus)(CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag))); + if(ret1 && ret2){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CAN interrupt flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering + \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode + \arg CAN_INT_FLAG_ERRIF: error interrupt flag + \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag + \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag + \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag + \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag + \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag + \param[out] none + \retval none +*/ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag) +{ + CAN_REG_VALS(can_periph, flag) |= BIT(CAN_BIT_POS0(flag)); +} + +/*! + \brief enable CAN phy + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_phy_enable(uint32_t can_periph) +{ + CAN_PHYCTL(can_periph) |= CAN_PHYCTL_PHYEN; +} + +/*! + \brief disable CAN phy + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_phy_disable(uint32_t can_periph) +{ + CAN_PHYCTL(can_periph) &= ~CAN_PHYCTL_PHYEN; +} + +/*! + \brief set CAN phy mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_phy_mode + \arg CAN_PHYMODE_LOW_SLOPE + \arg CAN_PHYMODE_MIDDLE_SLOPE + \arg CAN_PHYMODE_HIGH_SLOPE + \arg CAN_PHYMODE_HIGH_SPEED + \param[out] none + \retval none +*/ +void can_phy_mode(uint32_t can_periph, uint32_t phy_mode) +{ + CAN_PHYCTL(can_periph) &= (~CAN_PHYCTL_POMODE_MASK); + switch(phy_mode){ + case CAN_PHYCTL_POMODE_0: + /*!< CAN PHY low slope mode */ + CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_0; + break; + case CAN_PHYCTL_POMODE_1: + /*!< CAN PHY middle slope mode */ + CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_1; + break; + case CAN_PHYCTL_POMODE_2: + /*!< CAN PHY high slope mode */ + CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_2; + break; + case CAN_PHYCTL_POMODE_3: + /*!< CAN PHY high speed mode */ + CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_3; + break; + default: + break; + } +} + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_cec.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_cec.c new file mode 100644 index 0000000..bf3d296 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_cec.c @@ -0,0 +1,452 @@ +/*! + \file gd32f1x0_cec.c + \brief CEC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_cec.h" +#include "gd32f1x0_rcu.h" + +/*! + \brief reset HDMI-CEC controller + \param[in] none + \param[out] none + \retval none +*/ +void cec_deinit(void) +{ + rcu_periph_reset_enable(RCU_CECRST); + rcu_periph_reset_disable(RCU_CECRST); +} + +/*! + \brief configure signal free time,the signal free time counter start option,own address + \param[in] sftmopt: signal free time counter start option + \arg CEC_SFT_START_STAOM: signal free time counter starts counting when STAOM is asserted + \arg CEC_SFT_START_LAST: signal free time counter starts automatically after transmission/reception end + \param[in] sft: signal free time + \arg CEC_SFT_PROTOCOL_PERIOD: the signal free time will perform as HDMI-CEC protocol description + \arg CEC_SFT_1POINT5_PERIOD: 1.5 nominal data bit periods + \arg CEC_SFT_2POINT5_PERIOD: 2.5 nominal data bit periods + \arg CEC_SFT_3POINT5_PERIOD: 3.5 nominal data bit periods + \arg CEC_SFT_4POINT5_PERIOD: 4.5 nominal data bit periods + \arg CEC_SFT_5POINT5_PERIOD: 5.5 nominal data bit periods + \arg CEC_SFT_6POINT5_PERIOD: 6.5 nominal data bit periods + \arg CEC_SFT_7POINT5_PERIOD: 7.5 nominal data bit periods + \param[in] address: own address + \arg CEC_OWN_ADDRESS_CLEAR: own address is cleared + \arg CEC_OWN_ADDRESSx(x=0..14): own address is x + \param[out] none + \retval none +*/ +void cec_init(uint32_t sftopt, uint32_t sft, uint32_t address) +{ + uint32_t cfg; + cfg = CEC_CFG; + /* clear SFTOPT bit,SFT[2:0] */ + cfg &= ~(CEC_CFG_SFTOPT | CEC_CFG_SFT); + /* assign SFTOPT bit,SFT[2:0] */ + cfg |= (sftopt | sft); + CEC_CFG = cfg; + if(CEC_OWN_ADDRESS_CLEAR == address){ + CEC_CFG &= ~CEC_CFG_OAD; + }else{ + CEC_CFG |= address; + } +} + +/*! + \brief configure generate Error-bit when detected some abnormal situation or not, + whether stop receive message when detected bit rising error + \param[in] broadcast: + \arg CEC_BROADCAST_ERROR_BIT_ON:generate Error-bit in broadcast + \arg CEC_BROADCAST_ERROR_BIT_OFF:do not generate Error-bit in broadcast + \param[in] singlecast_lbpe: + \arg CEC_LONG_PERIOD_ERROR_BIT_ON:generate Error-bit on long bit period error + \arg CEC_LONG_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on long bit period error + \param[in] singlecast_bre: + \arg CEC_RISING_PERIOD_ERROR_BIT_ON:generate Error-bit on bit rising error + \arg CEC_RISING_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on bit rising error + \param[in] rxbrestp: + \arg CEC_STOP_RISING_ERROR_BIT_ON: stop reception when detected bit rising error + \arg CEC_STOP_RISING_ERROR_BIT_OFF: do not stop reception when detected bit rising error + \param[out] none + \retval none +*/ +void cec_error_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre, uint32_t rxbrestp) +{ + uint32_t cfg; + cfg = CEC_CFG; + /* clear BCNG bit, BPLEG bit, BREG bit */ + cfg &= ~(CEC_CFG_BCNG | CEC_CFG_BPLEG | CEC_CFG_BREG); + /* assign BCNG bit, BPLEG bit, BREG bit */ + cfg |= (broadcast | singlecast_lbpe | singlecast_bre); + CEC_CFG = cfg; + if(CEC_STOP_RISING_ERROR_BIT_ON == rxbrestp){ + CEC_CFG |= CEC_CFG_BRES; + }else{ + CEC_CFG &= ~CEC_CFG_BRES; + } +} + +/*! + \brief enable HDMI-CEC controller + \param[in] none + \param[out] none + \retval none +*/ +void cec_enable(void) +{ + CEC_CTL |= CEC_CTL_CECEN; +} + +/*! + \brief disable HDMI-CEC controller + \param[in] none + \param[out] none + \retval none +*/ +void cec_disable(void) +{ + CEC_CTL &= ~CEC_CTL_CECEN; +} + +/*! + \brief start CEC message transmission + \param[in] none + \param[out] none + \retval none +*/ +void cec_transmission_start(void) +{ + CEC_CTL |= CEC_CTL_STAOM; +} + +/*! + \brief end CEC message transmission + \param[in] none + \param[out] none + \retval none +*/ +void cec_transmission_end(void) +{ + CEC_CTL |= CEC_CTL_ENDOM; +} + +/*! + \brief enable CEC listen mode. + \param[in] none + \param[out] none + \retval none +*/ +void cec_listen_mode_enable(void) +{ + CEC_CFG |= CEC_CFG_LMEN; +} + +/*! + \brief disable CEC listen mode. + \param[in] none + \param[out] none + \retval none +*/ +void cec_listen_mode_disable(void) +{ + CEC_CFG &= ~CEC_CFG_LMEN; +} + +/*! + \brief configure and clear own address.the controller can be configured to multiple own address + \param[in] address: own address + \arg CEC_OWN_ADDRESS_CLEAR: own address is cleared + \arg CEC_OWN_ADDRESSx(x=0..14): own address is x + \param[out] none + \retval none +*/ +void cec_own_address_config(uint32_t address) +{ + if(CEC_OWN_ADDRESS_CLEAR == address){ + CEC_CFG &= ~CEC_CFG_OAD; + } else { + CEC_CFG |= address; + } +} + +/*! + \brief configure signal free time and the signal free time counter start option + \param[in] sftopt: signal free time counter start option + \arg CEC_SFT_START_STAOM: signal free time counter starts counting when STAOM is asserted + \arg CEC_SFT_START_LAST: signal free time counter starts automatically after transmission/reception end + \param[in] sft: signal free time + \arg CEC_SFT_PROTOCOL_PERIOD: the signal free time will perform as HDMI-CEC protocol description + \arg CEC_SFT_1POINT5_PERIOD: 1.5 nominal data bit periods + \arg CEC_SFT_2POINT5_PERIOD: 2.5 nominal data bit periods + \arg CEC_SFT_3POINT5_PERIOD: 3.5 nominal data bit periods + \arg CEC_SFT_4POINT5_PERIOD: 4.5 nominal data bit periods + \arg CEC_SFT_5POINT5_PERIOD: 5.5 nominal data bit periods + \arg CEC_SFT_6POINT5_PERIOD: 6.5 nominal data bit periods + \arg CEC_SFT_7POINT5_PERIOD: 7.5 nominal data bit periods + \param[out] none + \retval none +*/ +void cec_sft_config(uint32_t sftopt, uint32_t sft) +{ + uint32_t cfg; + cfg = CEC_CFG; + /* clear SFTOPT bit,SFT[2:0] */ + cfg &= ~(CEC_CFG_SFTOPT | CEC_CFG_SFT); + /* assign SFTOPT bit,SFT[2:0] */ + cfg |= (sftopt | sft); + CEC_CFG = cfg; +} + +/*! + \brief configure generate Error-bit when detected some abnormal situation or not + \param[in] broadcast: + \arg CEC_BROADCAST_ERROR_BIT_ON:generate Error-bit in broadcast + \arg CEC_BROADCAST_ERROR_BIT_OFF:do not generate Error-bit in broadcast + \param[in] singlecast_lbpe: + \arg CEC_LONG_PERIOD_ERROR_BIT_ON:generate Error-bit on long bit period error + \arg CEC_LONG_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on long bit period error + \param[in] singlecast_bre: + \arg CEC_RISING_PERIOD_ERROR_BIT_ON:generate Error-bit on bit rising error + \arg CEC_RISING_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on bit rising error + \param[out] none + \retval none +*/ +void cec_generate_errorbit_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre) +{ + uint32_t cfg; + cfg = CEC_CFG; + /* clear BCNG bit, BPLEG bit, BREG bit */ + cfg &= ~(CEC_CFG_BCNG | CEC_CFG_BPLEG | CEC_CFG_BREG); + /* assign BCNG bit, BPLEG bit, BREG bit */ + cfg |= (broadcast | singlecast_lbpe | singlecast_bre); + CEC_CFG = cfg; +} + +/*! + \brief whether stop receive message when detected bit rising error + \param[in] rxbrestp: + \arg CEC_STOP_RISING_ERROR_BIT_ON: stop reception when detected bit rising error + \arg CEC_STOP_RISING_ERROR_BIT_OFF: do not stop reception when detected bit rising error + \param[out] none + \retval none +*/ +void cec_stop_receive_bre_config(uint32_t rxbrestp) +{ + if(CEC_STOP_RISING_ERROR_BIT_ON == rxbrestp){ + CEC_CFG |= CEC_CFG_BRES; + } else { + CEC_CFG &= ~CEC_CFG_BRES; + } +} + +/*! + \brief enable reception bit timing tolerance + \param[in] none + \param[out] none + \retval none +*/ +void cec_reception_tolerance_enable(void) +{ + CEC_CFG |= CEC_CFG_RTOL; +} + +/*! + \brief disable reception bit timing tolerance + \param[in] none + \param[out] none + \retval none +*/ +void cec_reception_tolerance_disable(void) +{ + CEC_CFG &= ~CEC_CFG_RTOL; +} + +/*! + \brief send a data by the CEC peripheral + \param[in] data: the data to transmit + \param[out] none + \retval none +*/ +void cec_data_send(uint8_t data) +{ + CEC_TDATA = (uint32_t)data; +} + +/*! + \brief receive a data by the CEC peripheral + \param[in] data: the data to receive + \param[out] none + \retval none +*/ +uint8_t cec_data_receive(void) +{ + return (uint8_t)CEC_RDATA; +} + +/*! + \brief get CEC int flag + \param[in] flag: specify which flag + \arg CEC_INT_FLAG_BR: Rx-byte data received + \arg CEC_INT_FLAG_REND: end of reception + \arg CEC_INT_FLAG_RO: RX overrun + \arg CEC_INT_FLAG_BRE: bit rising error + \arg CEC_INT_FLAG_BPSE: short bit period error + \arg CEC_INT_FLAG_BPLE: long bit period error + \arg CEC_INT_FLAG_RAE: Rx ACK error + \arg CEC_INT_FLAG_ARBF: arbitration lost + \arg CEC_INT_FLAG_TBR: Tx-byte data request + \arg CEC_INT_FLAG_TEND: transmission successfully end + \arg CEC_INT_FLAG_TU: Tx data buffer underrun + \arg CEC_INT_FLAG_TERR: Tx-error + \arg CEC_INT_FLAG_TAERR: Tx ACK error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus cec_interrupt_flag_get(uint32_t flag) +{ + uint32_t interrupt_enable = 0U,interrupt_flag = 0U; + interrupt_flag = (CEC_INTF & flag); + interrupt_enable = (CEC_INTEN & flag); + if(interrupt_flag && interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CEC int flag and status + \param[in] flag: specify which flag + \arg CEC_INT_FLAG_BR: Rx-byte data received + \arg CEC_INT_FLAG_REND: end of reception + \arg CEC_INT_FLAG_RO: RX overrun + \arg CEC_INT_FLAG_BRE: bit rising error + \arg CEC_INT_FLAG_BPSE: short bit period error + \arg CEC_INT_FLAG_BPLE: long bit period error + \arg CEC_INT_FLAG_RAE: Rx ACK error + \arg CEC_INT_FLAG_ARBF: arbitration lost + \arg CEC_INT_FLAG_TBR: Tx-byte data request + \arg CEC_INT_FLAG_TEND: transmission successfully end + \arg CEC_INT_FLAG_TU: Tx data buffer underrun + \arg CEC_INT_FLAG_TERR: Tx-error + \arg CEC_INT_FLAG_TAERR: Tx ACK error flag + \param[out] none + \retval none +*/ +void cec_interrupt_flag_clear(uint32_t flag) +{ + CEC_INTF = flag; +} + +/*! + \brief enable interrupt + \param[in] flag: specify which flag + \arg CEC_INT_BR: enable Rx-byte data received interrupt + \arg CEC_INT_REND: enable end of reception interrupt + \arg CEC_INT_RO: enable RX overrun interrupt + \arg CEC_INT_BRE: enable bit rising error interrupt + \arg CEC_INT_BPSE: enable short bit period error interrupt + \arg CEC_INT_BPLE: enable long bit period error interrupt + \arg CEC_INT_RAE: enable Rx ACK error interrupt + \arg CEC_INT_ARBF: enable arbitration lost interrupt + \arg CEC_INT_TBR: enable Tx-byte data request interrupt + \arg CEC_INT_TEND: enable transmission successfully end interrupt + \arg CEC_INT_TU: enable Tx data buffer underrun interrupt + \arg CEC_INT_TERR: enable Tx-error interrupt + \arg CEC_INT_TAERR: enable Tx ACK error interrupt + \param[out] none + \retval none +*/ +void cec_interrupt_enable(uint32_t flag) +{ + CEC_INTEN |= flag; +} + +/*! + \brief disable interrupt + \param[in] flag: specify which flag + \arg CEC_INT_BR: disable Rx-byte data received interrupt + \arg CEC_INT_REND: disable end of reception interrupt + \arg CEC_INT_RO: disable RX overrun interrupt + \arg CEC_INT_BRE: disable bit rising error interrupt + \arg CEC_INT_BPSE: disable short bit period error interrupt + \arg CEC_INT_BPLE: disable long bit period error interrupt + \arg CEC_INT_RAE: disable Rx ACK error interrupt + \arg CEC_INT_ARBF: disable arbitration lost interrupt + \arg CEC_INT_TBR: disable Tx-byte data request interrupt + \arg CEC_INT_TEND: disable transmission successfully end interrupt + \arg CEC_INT_TU: disable Tx data buffer underrun interrupt + \arg CEC_INT_TERR: disable Tx-error interrupt + \arg CEC_INT_TAERR: disable Tx ACK error interrupt + + \param[out] none + \retval none +*/ +void cec_interrupt_disable(uint32_t flag) +{ + CEC_INTEN &= ~flag; +} + +/*! + \brief get CEC status + \param[in] flag: specify which flag + \arg CEC_FLAG_BR: Rx-byte data received + \arg CEC_FLAG_REND: end of reception + \arg CEC_FLAG_RO: RX overrun + \arg CEC_FLAG_BRE: bit rising error + \arg CEC_FLAG_BPSE: short bit period error + \arg CEC_FLAG_BPLE: long bit period error + \arg CEC_FLAG_RAE: Rx ACK error + \arg CEC_FLAG_ARBF: arbitration lost + \arg CEC_FLAG_TBR: Tx-byte data request + \arg CEC_FLAG_TEND: transmission successfully end + \arg CEC_FLAG_TU: Tx data buffer underrun + \arg CEC_FLAG_TERR: Tx-error + \arg CEC_FLAG_TAERR Tx ACK error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus cec_flag_get(uint32_t flag) +{ + if(CEC_INTF & flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CEC status + \param[in] flag: specify which flag + \arg CEC_FLAG_BR: Rx-byte data received + \arg CEC_FLAG_REND: end of reception + \arg CEC_FLAG_RO: RX overrun + \arg CEC_FLAG_BRE: bit rising error + \arg CEC_FLAG_BPSE: short bit period error + \arg CEC_FLAG_BPLE: long bit period error + \arg CEC_FLAG_RAE: Rx ACK error + \arg CEC_FLAG_ARBF: arbitration lost + \arg CEC_FLAG_TBR: Tx-byte data request + \arg CEC_FLAG_TEND: transmission successfully end + \arg CEC_FLAG_TU: Tx data buffer underrun + \arg CEC_FLAG_TERR: Tx-error + \arg CEC_FLAG_TAERR Tx ACK error flag + + \param[out] none + \retval FlagStatus: SET or RESET +*/ +void cec_flag_clear(uint32_t flag) +{ + CEC_INTF |= flag; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_cmp.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_cmp.c new file mode 100644 index 0000000..5a866da --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_cmp.c @@ -0,0 +1,244 @@ +/*! + \file gd32f1x0_cmp.c + \brief CMP driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5,9) +*/ + +#include "gd32f1x0_cmp.h" + +/*! + \brief deinitialize comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_deinit(void) +{ + CMP_CS = ((uint32_t)0x00000000); +} + +/*! + \brief initialize comparator mode + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] cmp_operating_mode + \arg CMP_HIGHSPEED: high speed mode + \arg CMP_MIDDLESPEED: medium speed mode + \arg CMP_LOWSPEED: low speed mode + \arg CMP_VERYLOWSPEED: very-low speed mode + \param[in] cmp_inverting_input + \arg CMP_1_4VREFINT: VREFINT *1/4 input + \arg CMP_1_2VREFINT: VREFINT *1/2 input + \arg CMP_3_4VREFINT: VREFINT *3/4 input + \arg CMP_VREFINT: VREFINT input + \arg CMP_DAC: PA4 (DAC) input + \arg CMP_PA5: PA5 input + \arg CMP_PA_0_2: PA0 or PA2 input + \param[in] cmp_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(uint32_t cmp_periph, operating_mode_enum cmp_operating_mode, inverting_input_enum cmp_inverting_input, cmp_hysteresis_enum output_hysteresis) +{ + if(CMP0 == cmp_periph){ + /* initialize comparator 0 mode */ + CMP_CS |= CS_CMP0M(cmp_operating_mode) | CS_CMP0MSEL(cmp_inverting_input) | CS_CMP0HST(output_hysteresis); + }else{ + /* initialize comparator 1 mode */ + CMP_CS |= CS_CMP1M(cmp_operating_mode) | CS_CMP1MSEL(cmp_inverting_input) | CS_CMP1HST(output_hysteresis); + } +} + +/*! + \brief initialize comparator output + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] cmp_output + \arg CMP_OUTPUT_NONE: output no selection + \arg CMP_OUTPUT_TIMER0BKIN: TIMER 0 break input + \arg CMP_OUTPUT_TIMER0IC0: TIMER 0 channel0 input capture + \arg CMP_OUTPUT_TIMER0OCPRECLR: TIMER 0 OCPRE_CLR input + \arg CMP_OUTPUT_TIMER1IC3: TIMER 1 channel3 input capture + \arg CMP_OUTPUT_TIMER1OCPRECLR: TIMER 1 OCPRE_CLR input + \arg CMP_OUTPUT_TIMER2IC0: TIMER 2 channel0 input capture + \arg CMP_OUTPUT_TIMER2OCPRECLR: TIMER 2 OCPRE_CLR input + \param[in] cmp_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(uint32_t cmp_periph, cmp_output_enum cmp_output_slection, uint32_t cmp_output_polarity) +{ + /* initialize comparator 0 output */ + if(CMP0 == cmp_periph){ + CMP_CS |= CS_CMP0OSEL(cmp_output_slection); + /* output polarity */ + if(CMP_OUTPUT_POLARITY_INVERTED == cmp_output_polarity){ + CMP_CS |= CMP_CS_CMP0PL; + }else{ + CMP_CS &= ~CMP_CS_CMP0PL; + } + }else{ + CMP_CS |= CS_CMP1OSEL(cmp_output_slection); + + if(CMP_OUTPUT_POLARITY_INVERTED == cmp_output_polarity){ + CMP_CS |= CMP_CS_CMP1PL; + }else{ + CMP_CS &= ~CMP_CS_CMP1PL; + } + } +} + +/*! + \brief enable comparator + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_enable(uint32_t cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP_CS |= CMP_CS_CMP0EN; + }else{ + CMP_CS |= CMP_CS_CMP1EN; + } +} + +/*! + \brief disable comparator + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_disable(uint32_t cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP_CS &= ~CMP_CS_CMP0EN; + }else{ + CMP_CS &= ~CMP_CS_CMP1EN; + } +} + +/*! + \brief enable comparator switch + \param[in] none + \param[out] none + \retval none +*/ +void cmp_switch_enable(void) +{ + CMP_CS |= CMP_CS_CMP0SW; +} + +/*! + \brief disable comparator switch + \param[in] none + \param[out] none + \retval none +*/ +void cmp_switch_disable(void) +{ + CMP_CS &= ~CMP_CS_CMP0SW; +} + + + +/*! + \brief enable the window mode + \param[in] none + \param[out] none + \retval none +*/ +void cmp_window_enable(void) +{ + CMP_CS |= CMP_CS_WNDEN; +} + +/*! + \brief disable the window mode + \param[in] none + \param[out] none + \retval none +*/ +void cmp_window_disable(void) +{ + CMP_CS &= ~CMP_CS_WNDEN; +} + +/*! + \brief lock the comparator + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_lock_enable(uint32_t cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP_CS |= CMP_CS_CMP0LK; + }else{ + CMP_CS |= CMP_CS_CMP1LK; + } +} + +/*! + \brief unlock the comparator + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_lock_disable(uint32_t cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP_CS &= ~CMP_CS_CMP0LK; + }else{ + CMP_CS &= ~CMP_CS_CMP1LK; + } +} + +/*! + \brief get output level + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval the output level +*/ +uint32_t cmp_output_level_get(uint32_t cmp_periph) +{ + if(CMP0 == cmp_periph){ + if(CMP_CS & CMP_CS_CMP0O){ + return CMP_OUTPUTLEVEL_HIGH; + }else{ + return CMP_OUTPUTLEVEL_LOW; + } + }else{ + if(CMP_CS & CMP_CS_CMP1O){ + return CMP_OUTPUTLEVEL_HIGH; + }else{ + return CMP_OUTPUTLEVEL_LOW; + } + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_crc.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_crc.c new file mode 100644 index 0000000..9528362 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_crc.c @@ -0,0 +1,155 @@ +/*! + \file gd32f1x0_crc.c + \brief CRC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_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_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 initializaiton 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 initializaiton 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 + \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 CRC calculate a 32-bit data + \param[in] sdata: specify 32-bit data + \param[out] none + \retval 32-bit CRC calculate value +*/ +uint32_t crc_single_data_calculate(uint32_t sdata) +{ + CRC_DATA = sdata; + return (CRC_DATA); +} + +/*! + \brief CRC calculate a 32-bit data array + \param[in] array: pointer to an array of 32 bit data words + \param[in] size: size of the array + \param[out] none + \retval 32-bit CRC calculate value +*/ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size) +{ + uint32_t index; + for(index = 0U; index < size; index++){ + CRC_DATA = array[index]; + } + return (CRC_DATA); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_dac.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_dac.c new file mode 100644 index 0000000..a82e9e3 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_dac.c @@ -0,0 +1,792 @@ +/*! + \file gd32f1x0_dac.c + \brief DAC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + + +#include "gd32f1x0_dac.h" + +/*! + \brief deinit 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 DAC0 + \param[in] none + \param[out] none + \retval none +*/ +void dac0_enable(void) +{ + DAC_CTL |= DAC_CTL_DEN0; +} + +/*! + \brief disable DAC0 + \param[in] none + \param[out] none + \retval none +*/ +void dac0_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DEN0; +} + +/*! + \brief enable DAC0 DMA + \param[in] none + \param[out] none + \retval none +*/ +void dac0_dma_enable(void) +{ + DAC_CTL |= DAC_CTL_DDMAEN0; +} + +/*! + \brief disable DAC0 DMA + \param[in] none + \param[out] none + \retval none +*/ +void dac0_dma_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DDMAEN0; +} + +/*! + \brief enable DAC0 output buffer + \param[in] none + \param[out] none + \retval none +*/ +void dac0_output_buffer_enable(void) +{ + DAC_CTL &= ~DAC_CTL_DBOFF0; +} + +/*! + \brief disable DAC0 output buffer + \param[in] none + \param[out] none + \retval none +*/ +void dac0_output_buffer_disable(void) +{ + DAC_CTL |= DAC_CTL_DBOFF0; +} + +/*! + \brief enable DAC0 trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac0_trigger_enable(void) +{ + DAC_CTL |= DAC_CTL_DTEN0; +} + +/*! + \brief disable DAC0 trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac0_trigger_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DTEN0; +} + +/*! + \brief enable DAC0 software trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac0_software_trigger_enable(void) +{ + DAC_SWT |= DAC_SWT_SWTR0; +} + +/*! + \brief disable DAC0 software trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac0_software_trigger_disable(void) +{ + DAC_SWT &= ~DAC_SWT_SWTR0; +} + +/*! + \brief enable DAC0 interrupt(DAC0 DMA underrun interrupt) + \param[in] none + \param[out] none + \retval none +*/ +void dac0_interrupt_enable(void) +{ + DAC_CTL |= DAC_CTL_DDUDRIE0; +} + +/*! + \brief disable DAC0 interrupt(DAC0 DMA underrun interrupt) + \param[in] none + \param[out] none + \retval none +*/ +void dac0_interrupt_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DDUDRIE0; +} + +/*! + \brief set DAC0 tgigger source + \param[in] triggersource: external triggers of DAC + \arg DAC_TRIGGER_T1_TRGO: trigger source is timer1 trgo + \arg DAC_TRIGGER_T2_TRGO: trigger source is timer2 trgo + \arg DAC_TRIGGER_T5_TRGO: trigger source is timer5 trgo + \arg DAC_TRIGGER_T14_TRGO: trigger source is timer14 trgo + \arg DAC_TRIGGER_EXTI_IT9: trigger source is exti interrupt line 9 + \arg DAC_TRIGGER_SOFTWARE: trigger source is software + \param[out] none + \retval none +*/ +void dac0_trigger_source_config(uint32_t triggersource) +{ + DAC_CTL &= ~DAC_CTL_DTSEL0; + DAC_CTL |= triggersource; +} + +/*! + \brief get the last data output value of DAC0 + \param[in] none + \param[out] none + \retval DAC output data +*/ +uint16_t dac0_output_value_get(void) +{ + uint16_t data = 0U; + data = (uint16_t)DAC0_DO; + return data; +} + +/*! + \brief get the specified DAC0 flag(DAC0 DMA underrun flag) + \param[in] none + \param[out] none + \retval the state of dac bit(SET or RESET) +*/ +FlagStatus dac0_flag_get(void) +{ + /* check the DMA underrun flag */ + if((uint8_t)RESET != (DAC_STAT & DAC_STAT_DDUDR0)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the specified DAC0 flag(DAC0 DMA underrun flag) + \param[in] none + \param[out] none + \retval none +*/ +void dac0_flag_clear(void) +{ + DAC_STAT &= ~DAC_STAT_DDUDR0; +} + +/*! + \brief get the specified DAC0 interrupt flag(DAC0 DMA underrun interrupt flag) + \param[in] none + \param[out] none + \retval the state of DAC interrupt flag(SET or RESET) +*/ +FlagStatus dac0_interrupt_flag_get(void) +{ + uint32_t ddudr_flag = 0U, ddudrie_flag = 0U; + ddudr_flag = (DAC_STAT & DAC_STAT_DDUDR0); + ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE0; + /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the specified DAC0 interrupt flag(DAC0 DMA underrun interrupt flag) + \param[in] none + \param[out] none + \retval none +*/ +void dac0_interrupt_flag_clear(void) +{ + DAC_CTL &= ~DAC_CTL_DDUDRIE0; +} + +/*! + \brief set DAC0 data holding register value + \param[in] dac_align + \arg DAC_ALIGN_8B_R: data right 8b alignment + \arg DAC_ALIGN_12B_R: data right 12b alignment + \arg DAC_ALIGN_12B_L: data left 12b alignment + \param[in] data: data to be loaded + \param[out] none + \retval none +*/ +void dac0_data_set(uint32_t dac_align, uint16_t data) +{ + switch(dac_align){ + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + DAC0_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + DAC0_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + DAC0_R8DH = data; + break; + default: + break; + } +} + +#ifdef GD32F170_190 +/*! + \brief enable DAC + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DEN0; + }else{ + DAC_CTL |= DAC_CTL_DEN1; + } +} + +/*! + \brief disable DAC + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DEN0; + }else{ + DAC_CTL &= ~DAC_CTL_DEN1; + } +} + +/*! + \brief enable DAC DMA function + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_dma_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DDMAEN0; + }else{ + DAC_CTL |= DAC_CTL_DDMAEN1; + } +} + +/*! + \brief disable DAC DMA function + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_dma_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DDMAEN0; + }else{ + DAC_CTL &= ~DAC_CTL_DDMAEN1; + } +} + +/*! + \brief enable DAC output buffer + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_output_buffer_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DBOFF0; + }else{ + DAC_CTL &= ~DAC_CTL_DBOFF1; + } +} + +/*! + \brief disable DAC output buffer + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_output_buffer_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DBOFF0; + }else{ + DAC_CTL |= DAC_CTL_DBOFF1; + } +} + +/*! + \brief enable DAC trigger + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_trigger_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DTEN0; + }else{ + DAC_CTL |= DAC_CTL_DTEN1; + } +} + +/*! + \brief disable DAC trigger + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_trigger_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DTEN0; + }else{ + DAC_CTL &= ~DAC_CTL_DTEN1; + } +} + +/*! + \brief enable DAC software trigger + \param[in] dac_periph + \arg DACx(x =0,1) + \retval none +*/ +void dac_software_trigger_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_SWT |= DAC_SWT_SWTR0; + }else{ + DAC_SWT |= DAC_SWT_SWTR1; + } +} + +/*! + \brief disable DAC software trigger + \param[in] dac_periph + \arg DACx(x =0,1) + \param[out] none + \retval none +*/ +void dac_software_trigger_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_SWT &= ~DAC_SWT_SWTR0; + }else{ + DAC_SWT &= ~DAC_SWT_SWTR1; + } +} + +/*! + \brief get DAC output value + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval DAC output data +*/ +uint16_t dac_output_value_get(uint32_t dac_periph) +{ + uint16_t data = 0U; + if(DAC0 == dac_periph){ + data = (uint16_t)DAC0_DO; + }else{ + data = (uint16_t)DAC1_DO; + } + return data; +} + +/*! + \brief enable DAC interrupt(DAC0 DMA underrun interrupt) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_interrupt_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL |= DAC_CTL_DDUDRIE0; + }else{ + DAC_CTL |= DAC_CTL_DDUDRIE1; + } +} + +/*! + \brief disable DAC interrupt(DAC0 DMA underrun interrupt) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_interrupt_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DDUDRIE0; + }else{ + DAC_CTL &= ~DAC_CTL_DDUDRIE1; + } +} + +/*! + \brief set DAC trigger source + \param[in] dac_periph + \arg DACx(x =0,1) + \param[in] triggersource: external triggers of DAC + \arg DAC_TRIGGER_T1_TRGO: trigger source is timer1 trgo + \arg DAC_TRIGGER_T2_TRGO: trigger source is timer2 trgo + \arg DAC_TRIGGER_T5_TRGO: trigger source is timer5 trgo + \arg DAC_TRIGGER_T14_TRGO: trigger source is timer14 trgo + \arg DAC_TRIGGER_EXTI_IT9: trigger source is exti interrupt line 9 + \arg DAC_TRIGGER_SOFTWARE: trigger source is software + \param[out] none + \retval none +*/ +void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DTSEL0; + DAC_CTL |= triggersource; + }else{ + DAC_CTL &= ~DAC_CTL_DTSEL1; + DAC_CTL |= (triggersource <<16); + } +} + +/*! + \brief get the specified DAC flag(DAC DMA underrun flag) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval the state of dac bit(SET or RESET) +*/ +FlagStatus dac_flag_get(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + /* check the DMA underrun flag */ + if(RESET != (DAC_STAT & DAC_STAT_DDUDR0)){ + return SET; + }else{ + return RESET; + } + }else{ + /* check the DMA underrun flag */ + if(RESET != (DAC_STAT & DAC_STAT_DDUDR1)){ + return SET; + }else{ + return RESET; + } + } +} + +/*! + \brief clear the specified DAC flag(DAC DMA underrun flag) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_flag_clear(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_STAT |= DAC_STAT_DDUDR0; + }else{ + DAC_STAT |= DAC_STAT_DDUDR1; + } +} + +/*! + \brief get the specified DAC interrupt flag(DAC DMA underrun interrupt flag) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval the state of DAC interrupt flag(SET or RESET) +*/ +FlagStatus dac_interrupt_flag_get(uint32_t dac_periph) +{ + uint32_t ddudr_flag = 0U, ddudrie_flag = 0U; + if(DAC0 == dac_periph){ + ddudr_flag = DAC_STAT & DAC_STAT_DDUDR0; + ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE0; + /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){ + return SET; + }else{ + return RESET; + } + }else{ + ddudr_flag = DAC_STAT & DAC_STAT_DDUDR1; + ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE1; + /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){ + return SET; + }else{ + return RESET; + } + } +} + +/*! + \brief clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag) + \param[in] dac_periph + \arg DACx(x=0,1) + \param[out] none + \retval none +*/ +void dac_interrupt_flag_clear(uint32_t dac_periph) +{ + if(DAC0 == dac_periph){ + DAC_STAT |= DAC_STAT_DDUDR0; + }else{ + DAC_STAT |= DAC_STAT_DDUDR1; + } +} + +/*! + \brief enable DAC concurrent mode + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1; + DAC_CTL |= (ctl); +} + +/*! + \brief disable DAC concurrent mode + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1; + DAC_CTL &= (~ctl); +} + +/*! + \brief enable DAC concurrent software trigger function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_enable(void) +{ + uint32_t swt = 0U; + swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; + DAC_SWT |= (swt); +} + +/*! + \brief disable DAC concurrent software trigger function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_disable(void) +{ + uint32_t swt = 0U; + swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; + DAC_SWT &= (~swt); +} + +/*! + \brief enable DAC concurrent buffer funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_output_buffer_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1; + DAC_CTL &= (~ctl); +} + +/*! + \brief disable DAC concurrent buffer funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_output_buffer_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1; + DAC_CTL |= (ctl); +} + +/*! + \brief enable DAC concurrent interrupt funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_interrupt_enable(void) +{ + DAC_CTL |= DAC_CTL_DDUDRIE0; + DAC_CTL |= DAC_CTL_DDUDRIE1; +} + +/*! + \brief disable DAC concurrent interrupt funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_interrupt_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DDUDRIE0; + DAC_CTL &= ~DAC_CTL_DDUDRIE1; +} + +/*! + \brief set the DAC specified data holding register value + \param[in] dac_periph + \arg DACx(x=0,1) + \param[in] dac_align + \arg DAC_ALIGN_8B_R: data right 8b alignment + \arg DAC_ALIGN_12B_R: data right 12b alignment + \arg DAC_ALIGN_12B_L: data left 12b alignment + \param[in] data: data to be loaded + \param[out] none + \retval none +*/ +void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data) +{ + if(DAC0 == dac_periph){ + switch(dac_align){ + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + DAC0_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + DAC0_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + DAC0_R8DH = data; + break; + default: + break; + } + }else{ + switch(dac_align){ + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + DAC1_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + DAC1_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + DAC1_R8DH = data; + break; + default: + break; + } + } +} + +/*! + \brief set DAC concurrent mode data holding register value + \param[in] dac_align + \arg DAC_ALIGN_8B_R: data right 8b alignment + \arg DAC_ALIGN_12B_R: data right 12b alignment + \arg DAC_ALIGN_12B_L: data left 12b alignment + \param[in] data1: data to be loaded + \param[in] data2: data to be loaded + \param[out] none + \retval none +*/ +void dac_concurrent_data_set(uint32_t dac_align, uint16_t data1, uint16_t data2) +{ + uint32_t data = 0U; + switch(dac_align){ + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + data = ((uint32_t)data2 << 16U) | data1; + DACC_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + data = ((uint32_t)data2 << 16U) | data1; + DACC_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + data = ((uint32_t)data2 << 8U) | data1; + DACC_R8DH = data; + break; + default: + break; + } +} + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_dbg.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_dbg.c new file mode 100644 index 0000000..05e649b --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_dbg.c @@ -0,0 +1,106 @@ +/*! + \file gd32f1x0_dbg.c + \brief DBG driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_dbg.h" + +#define DBG_RESET_VAL 0x00000000U + +/*! + \brief deinitialize the DBG + \param[in] none + \param[out] none + \retval none +*/ +void dbg_deinit(void) +{ + DBG_CTL0 = DBG_RESET_VAL; + DBG_CTL1 = DBG_RESET_VAL; +} + +/*! + \brief read DBG_ID code register + \param[in] none + \param[out] none + \retval DBG_ID code +*/ +uint32_t dbg_id_get(void) +{ + return DBG_ID; +} + +/*! + \brief enable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + this parameter can be any combination of the following values: + \arg DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_enable(uint32_t dbg_low_power) +{ + DBG_CTL0 |= dbg_low_power; +} + +/*! + \brief disable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + this parameter can be any combination of the following values: + \arg DBG_LOW_POWER_SLEEP: donot keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: donot keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: donot keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_disable(uint32_t dbg_low_power) +{ + DBG_CTL0 &= ~dbg_low_power; +} + +/*! + \brief enable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: refer to dbg_periph_enum + only one parameter can be selected which is shown as below: + \arg DBG_FWDGT_HOLD : debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted + \arg DBG_CANx_HOLD (x=0,1): hold CANx counter when core is halted(170_190 series only) + \arg DBG_I2Cx_HOLD (x=0,1,2): hold I2Cx smbus when core is halted + \arg DBG_TIMERx_HOLD (x=0,1,2,5,13,14,15,16): hold TIMERx counter when core is halted + \arg DBG_RTC_HOLD : hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_enable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph)); +} + +/*! + \brief disable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: refer to dbg_periph_enum + only one parameter can be selected which is shown as below: + \arg DBG_FWDGT_HOLD : debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted + \arg DBG_CANx_HOLD (x=0,1): hold CANx counter when core is halted(170_190 series only) + \arg DBG_I2Cx_HOLD (x=0,1,2): hold I2Cx smbus when core is halted + \arg DBG_TIMERx_HOLD (x=0,1,2,5,13,14,15,16): hold TIMERx counter when core is halted + \arg DBG_RTC_HOLD : hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_disable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) &= ~BIT(DBG_BIT_POS(dbg_periph)); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_dma.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_dma.c new file mode 100644 index 0000000..4cec0fc --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_dma.c @@ -0,0 +1,492 @@ +/*! + \file gd32f1x0_dma.c + \brief DMA driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_dma.h" + +/*! + \brief deinitialize DMA a channel registers + \param[in] channelx: specify which DMA channel is deinitialized + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_deinit(dma_channel_enum channelx) +{ + /* disable DMA a channel */ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN; + /* reset DMA channel registers */ + DMA_CHCTL(channelx) = DMA_CHCTL_RESET_VALUE; + DMA_CHCNT(channelx) = DMA_CHCNT_RESET_VALUE; + DMA_CHPADDR(channelx) = DMA_CHPADDR_RESET_VALUE; + DMA_CHMADDR(channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_INTC |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE,channelx); +} + +/*! + \brief initialize DMA channel + \param[in] channelx: specify which DMA channel is initialized + \arg DMA_CHx(x=0..6) + \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 + \param[out] none + \retval none +*/ +void dma_init(dma_channel_enum channelx, dma_parameter_struct init_struct) +{ + uint32_t ctl; + /* configure peripheral base address */ + DMA_CHPADDR(channelx) = init_struct.periph_addr; + + /* configure memory base address */ + DMA_CHMADDR(channelx) = init_struct.memory_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(channelx) = init_struct.number; + + /* configure peripheral transfer width,memory transfer width, */ + ctl = DMA_CHCTL(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(channelx)=ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct.periph_inc){ + DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA; + }else{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct.memory_inc){ + DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA; + }else{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure the direction of data transfer */ + if(DMA_PERIPHERAL_TO_MEMORY == init_struct.direction){ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR; + }else{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief enable DMA circulation mode + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_circulation_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_CMEN; +} + +/*! + \brief disable DMA circulation mode + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_circulation_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CMEN; +} + +/*! + \brief enable memory to memory mode + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_M2M; +} + +/*! + \brief disable memory to memory mode + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_M2M; +} + +/*! + \brief enable DMA channel + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_channel_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_CHEN; +} + +/*! + \brief disable DMA channel + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_channel_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN; +} + +/*! + \brief set DMA peripheral base address + \param[in] channelx: specify which DMA channel to set peripheral base address + \arg DMA_CHx(x=0..6) + \param[in] address: peripheral base address + \param[out] none + \retval none +*/ +void dma_periph_address_config(dma_channel_enum channelx, uint32_t address) +{ + DMA_CHPADDR(channelx) = address; +} + +/*! + \brief set DMA Memory base address + \param[in] channelx: specify which DMA channel to set Memory base address + \arg DMA_CHx(x=0..6) + \param[in] address: Memory base address + \param[out] none + \retval none +*/ +void dma_memory_address_config(dma_channel_enum channelx, uint32_t address) +{ + DMA_CHMADDR(channelx) = address; +} + +/*! + \brief set the number of remaining data to be transferred by the DMA + \param[in] channelx: specify which DMA channel to set number + \arg DMA_CHx(x=0..6) + \param[in] number: the number of remaining data to be transferred by the DMA + \param[out] none + \retval none +*/ +void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number) +{ + DMA_CHCNT(channelx) = number; +} + +/*! + \brief get the number of remaining data to be transferred by the DMA + \param[in] channelx: specify which DMA channel to set number + \arg DMA_CHx(x=0..6) + \param[out] none + \retval uint32_t: the number of remaining data to be transferred by the DMA +*/ +uint32_t dma_transfer_number_get(dma_channel_enum channelx) +{ + return (uint32_t)DMA_CHCNT(channelx); +} + +/*! + \brief configure priority level of DMA channel + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] priority: priority Level of this channel + \arg DMA_PRIORITY_LOW: low priority + \arg DMA_PRIORITY_MEDIUM: medium priority + \arg DMA_PRIORITY_HIGH: high priority + \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority + \param[out] none + \retval none +*/ +void dma_priority_config(dma_channel_enum channelx, uint32_t priority) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PRIO; + ctl |= priority; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief configure transfer data size of memory + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] msize: transfer data size of memory + \arg DMA_MEMORY_WIDTH_8BIT: transfer data size of memory is 8-bit + \arg DMA_MEMORY_WIDTH_16BIT: transfer data size of memory is 16-bit + \arg DMA_MEMORY_WIDTH_32BIT: transfer data size of memory is 32-bit + \param[out] none + \retval none +*/ +void dma_memory_width_config (dma_channel_enum channelx, uint32_t msize) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MWIDTH; + ctl |= msize; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief configure transfer data size of peripheral + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] msize: transfer data size of peripheral + \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data size of peripheral is 8-bit + \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data size of peripheral is 16-bit + \arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data size of peripheral is 32-bit + \param[out] none + \retval none +*/ +void dma_periph_width_config (dma_channel_enum channelx, uint32_t psize) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PWIDTH; + ctl |= psize; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief enable next address increasement algorithm of memory + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_memory_increase_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA; +} + +/*! + \brief disable next address increasement algorithm of memory + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_memory_increase_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA; +} + +/*! + \brief enable next address increasement algorithm of peripheral + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_periph_increase_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA; +} + +/*! + \brief disable next address increasement algorithm of peripheral + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[out] none + \retval none +*/ +void dma_periph_increase_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA; +} + +/*! + \brief configure the direction of data transfer on the channel + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] direction: specify the direction of data transfer + \arg DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory + \arg DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral + \param[out] none + \retval none +*/ +void dma_transfer_direction_config(dma_channel_enum channelx, uint8_t direction) +{ + if(DMA_PERIPHERAL_TO_MEMORY == direction){ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR; + } else { + DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief check DMA flag and interrupt enable bit is set or not + \param[in] channelx: specify which DMA channel to get flag + \arg DMA_CHx(x=0..6) + \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: full transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_ERR: error interrupt flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag) +{ + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + uint32_t gif_check = 0x0FU, gif_enable = 0x0EU; + + switch(flag){ + case DMA_INT_FLAG_FTF: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_FTFIE; + break; + case DMA_INT_FLAG_HTF: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INT_FLAG_ERR: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL( channelx) & DMA_CHXCTL_ERRIE; + break; + case DMA_INT_FLAG_G: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(gif_check, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL(channelx) & gif_enable; + break; + default: + break; + } + + if(interrupt_flag & interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear DMA a channel flag + \param[in] channelx: specify which DMA channel to clear flag + \arg DMA_CHx(x=0..6) + \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: full transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel + \arg DMA_INT_FLAG_ERR: error interrupt flag of channel + \param[out] none + \retval none +*/ +void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC |= DMA_FLAG_ADD(flag, channelx); +} + +/*! + \brief enable DMA interrupt + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] source: specify which interrupt to enbale + \arg DMA_INT_ERR: channel error interrupt + \arg DMA_INT_HTF: channel transfer half complete interrupt + \arg DMA_INT_FTF: channel transfer complete interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(channelx) |= source; +} + +/*! + \brief disable DMA interrupt + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..6) + \param[in] source: specify which interrupt to disbale + \arg DMA_INT_ERR: channel error interrupt + \arg DMA_INT_HTF: channel transfer half complete interrupt + \arg DMA_INT_FTF: for channel transfer complete interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(channelx) &= ~source; +} + +/*! + \brief check DMA flag is set or not + \param[in] channelx: specify which DMA channel to get flag + \arg DMA_CHx(x=0..6) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag) +{ + FlagStatus reval; + + if(RESET != (DMA_INTF & DMA_FLAG_ADD(flag, channelx))){ + reval = SET; + }else{ + reval = RESET; + } + + return reval; +} + +/*! + \brief clear DMA a channel flag + \param[in] channelx: specify which DMA channel to clear flag + \arg DMA_CHx(x=0..6) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval none +*/ +void dma_flag_clear(dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC |= DMA_FLAG_ADD(flag, channelx); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_exti.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_exti.c new file mode 100644 index 0000000..559171a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_exti.c @@ -0,0 +1,247 @@ +/*! + \file gd32f1x0_exti.c + \brief EXTI driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_exti.h" + +#define EXTI_INTEN_RESET_VAL 0x0F900000U +#define EXTI_EVEN_RESET_VAL 0x00000000U +#define EXTI_RTEN_RESET_VAL 0x00000000U +#define EXTI_FTEN_RESET_VAL 0x00000000U +#define EXTI_SWIEV_RESET_VAL 0x00000000U + +/*! + \brief deinitialize the EXTI + \param[in] none + \param[out] none + \retval none +*/ +void exti_deinit(void) +{ + /* reset the value of the EXTI registers */ + EXTI_INTEN = EXTI_INTEN_RESET_VAL; + EXTI_EVEN = EXTI_EVEN_RESET_VAL; + EXTI_RTEN = EXTI_RTEN_RESET_VAL; + EXTI_FTEN = EXTI_FTEN_RESET_VAL; + EXTI_SWIEV = EXTI_SWIEV_RESET_VAL; +} + +/*! + \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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \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 + \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; + 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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_interrupt_enable(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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_event_enable(exti_line_enum linex) +{ + EXTI_EVEN |= (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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_interrupt_disable(exti_line_enum linex) +{ + EXTI_INTEN &= ~(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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_event_disable(exti_line_enum linex) +{ + EXTI_EVEN &= ~(uint32_t)linex; +} + +/*! + \brief get EXTI lines flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_flag_get(exti_line_enum linex) +{ + if(RESET != (EXTI_PD & (uint32_t)linex)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)linex; +} + +/*! + \brief get EXTI lines flag when the interrupt flag is set + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex) +{ + uint32_t flag_left, flag_right; + flag_left = EXTI_PD & (uint32_t)linex; + flag_right = EXTI_INTEN & (uint32_t)linex; + if((RESET != flag_left) && (RESET != flag_right)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_interrupt_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices) + \param[out] none + \retval none +*/ +void exti_software_interrupt_disable(exti_line_enum linex) +{ + EXTI_SWIEV &= ~(uint32_t)linex; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_fmc.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_fmc.c new file mode 100644 index 0000000..70e9377 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_fmc.c @@ -0,0 +1,664 @@ +/*! + \file gd32f1x0_fmc.c + \brief FMC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_fmc.h" + +/* FMC main memory programming functions */ + +/*! + \brief unlock the main FMC operation + it is better to used in pairs with fmc_lock + \param[in] none + \param[out] none + \retval none +*/ +void fmc_unlock(void) +{ + if((RESET != (FMC_CTL & FMC_CTL_LK))){ + /* write the FMC key */ + FMC_KEY = UNLOCK_KEY0; + FMC_KEY = UNLOCK_KEY1; + } +} + +/*! + \brief lock the main FMC operation + it is better to used in pairs with fmc_unlock after an operation + \param[in] none + \param[out] none + \retval none +*/ +void fmc_lock(void) +{ + /* set the LK bit*/ + FMC_CTL |= FMC_CTL_LK; +} + +/*! + \brief set the wait state counter value + \param[in] wscnt: wait state counter value + \arg WS_WSCNT_0: 0 wait state added + \arg WS_WSCNT_1: 1 wait state added + \arg WS_WSCNT_2: 2 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 fmc wait state enable + \param[in] none + \param[out] none + \retval none +*/ +void fmc_wait_state_enable(void) +{ + /* unlock the main flash */ + fmc_unlock(); + + /* set the WSEN bit in register FMC_WSEN */ + FMC_WSEN |= FMC_WSEN_WSEN; + + /* lock the main flash after operation */ + fmc_lock(); +} + +/*! + \brief fmc wait state disable + \param[in] none + \param[out] none + \retval none +*/ +void fmc_wait_state_disable(void) +{ + /* unlock the main flash */ + fmc_unlock(); + + /* reset the WSEN bit in register FMC_WSEN */ + FMC_WSEN &= ~FMC_WSEN_WSEN; + + /* lock the main flash after operation */ + fmc_lock(); +} + +/*! + \brief erase page + \param[in] page_address: target page start address + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_page_erase(uint32_t page_address) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start page erase */ + FMC_CTL |= FMC_CTL_PER; + FMC_ADDR = page_address; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PER bit */ + FMC_CTL &= ~FMC_CTL_PER; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief erase whole chip + \param[in] none + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_mass_erase(void) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start chip erase */ + FMC_CTL |= FMC_CTL_MER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER bit */ + FMC_CTL &= ~FMC_CTL_MER; + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief program a word at the corresponding address + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + + REG32(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program a half word at the corresponding address + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + + REG16(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +#ifdef GD32F170_190 +/*! + \brief program a word at the corresponding address without erasing + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_word_reprogram(uint32_t address, uint32_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + FMC_WSEN |= FMC_WSEN_BPEN; + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + + REG32(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} +#endif /* GD32F170_190 */ + +/* FMC option bytes programming functions */ + +/*! + \brief unlock the option byte operation + it is better to used in pairs with ob_lock + \param[in] none + \param[out] none + \retval none +*/ +void ob_unlock(void) +{ + if(RESET == (FMC_CTL & FMC_CTL_OBWEN)){ + /* write the FMC key */ + FMC_OBKEY = UNLOCK_KEY0; + FMC_OBKEY = UNLOCK_KEY1; + } +} + +/*! + \brief lock the option byte 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 OBWE bit */ + FMC_CTL &= ~FMC_CTL_OBWEN; +} + +/*! + \brief reload the option byte and generate a system reset + \param[in] none + \param[out] none + \retval none +*/ +void ob_reset(void) +{ + /* set the OBRLD bit */ + FMC_CTL |= FMC_CTL_OBRLD; +} + +/*! + \brief erase the option byte + programmer must ensure FMC & option byte are both unlocked before calling this function + \param[in] none + \param[out] none + \retval fmc_state +*/ +fmc_state_enum ob_erase(void) +{ + uint16_t fmc_spc; + uint32_t fmc_plevel = ob_obstat_plevel_get(); + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* get the original option byte security protection code */ + if(OB_OBSTAT_PLEVEL_NO == fmc_plevel){ + fmc_spc = FMC_NSPC; + }else if(OB_OBSTAT_PLEVEL_LOW == fmc_plevel){ + fmc_spc = FMC_LSPC; + }else{ + fmc_spc = FMC_HSPC; + fmc_state = FMC_OB_HSPC; + } + + if(FMC_READY == fmc_state){ + /* start erase the option byte */ + FMC_CTL |= FMC_CTL_OBER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + + /* set the OBPG bit */ + FMC_CTL |= FMC_CTL_OBPG; + + /* restore the last get option byte security protection code */ + OB_SPC = fmc_spc; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief enable option byte write protection (OB_WP) + \param[in] ob_wp: write protection configuration data + \param[out] none + \retval fmc_state +*/ +fmc_state_enum ob_write_protection_enable(uint32_t ob_wp) +{ + uint16_t ob_wrp0, ob_wrp1; + + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + ob_wp = (uint32_t)(~ob_wp); + ob_wrp0 = (uint16_t)(ob_wp & OB_LWP); + ob_wrp1 = (uint16_t)((ob_wp & OB_HWP) >> 8); + + if(FMC_READY == fmc_state){ + /* set the OBPG bit*/ + FMC_CTL |= FMC_CTL_OBPG; + + if(0xFFU != ob_wrp0){ + OB_WP0 = ob_wrp0; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + if((FMC_READY == fmc_state) && (0xFFU != ob_wrp1)){ + OB_WP1 = ob_wrp1; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure security protection + \param[in] ob_spc: specify security protection code + \arg FMC_NSPC: no security protection + \arg FMC_LSPC: low security protection + \arg FMC_HSPC: high security protection + \param[out] none + \retval fmc_state +*/ +fmc_state_enum ob_security_protection_config(uint8_t ob_spc) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* the OB_SPC byte cannot be reprogrammed if protection level is high */ + if(OB_OBSTAT_PLEVEL_HIGH == ob_obstat_plevel_get()){ + fmc_state = FMC_OB_HSPC; + } + + if(FMC_READY == fmc_state){ + /* start erase the option byte */ + FMC_CTL |= FMC_CTL_OBER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + + /* enable the option bytes programming */ + FMC_CTL |= FMC_CTL_OBPG; + + OB_SPC = ob_spc; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC user option byte + \param[in] ob_user: user option byte + \arg OB_FWDGT_SW: software free watchdog timer + \arg OB_FWDGT_HW: hardware free watchdog timer + \arg OB_DEEPSLEEP_NRST: generate a reset instead of entering deepsleep mode + \arg OB_DEEPSLEEP_RST: no reset when entering deepsleep mode + \arg OB_STDBY_NRST: generate a reset instead of entering standby mode + \arg OB_STDBY_RST: no reset when entering deepsleep mode + \arg OB_BOOT1_SET_1: BOOT1 bit is 1 + \arg OB_BOOT1_SET_0: BOOT1 bit is 0 + \arg OB_VDDA_DISABLE: disable VDDA monitor + \arg OB_VDDA_ENABLE: enable VDDA monitor + \arg OB_SRAM_PARITY_DISABLE: disable sram parity check + \arg OB_SRAM_PARITY_ENABLE: enable sram parity check + \param[out] none + \retval fmc_state +*/ +fmc_state_enum ob_user_write(uint8_t ob_user) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the OBPG bit */ + FMC_CTL |= FMC_CTL_OBPG; + + OB_USER = (uint8_t)(ob_user | OB_USER_MASK); + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC data option byte + \param[in] address: OB_DATA_ADDR0 or OB_DATA_ADDR1 + \arg OB_DATA_ADDR0: option byte data address 0 + \arg OB_DATA_ADDR1: option byte data address 1 + \param[in] data: the byte to be programmed + \param[out] none + \retval fmc_state +*/ +fmc_state_enum ob_data_program(uint32_t address, uint8_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the OBPG bit */ + FMC_CTL |= FMC_CTL_OBPG; + REG16(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief get OB_USER in register FMC_OBSTAT + \param[in] none + \param[out] none + \retval ob_user +*/ +uint8_t ob_user_get(void) +{ + return (uint8_t)(FMC_OBSTAT >> 8); +} + +/*! + \brief get OB_DATA in register FMC_OBSTAT + \param[in] none + \param[out] none + \retval ob_data +*/ +uint16_t ob_data_get(void) +{ + return (uint16_t)(FMC_OBSTAT >> 16); +} + +/*! + \brief get the FMC option byte write protection (OB_WP) in register FMC_WP + \param[in] none + \param[out] none + \retval OB_WP +*/ +uint16_t ob_write_protection_get(void) +{ + return (uint16_t)(FMC_WP); +} + +/*! + \brief get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register + \param[in] none + \param[out] none + \retval the value of PLEVEL +*/ +uint32_t ob_obstat_plevel_get(void) +{ + return (FMC_OBSTAT & (FMC_OBSTAT_PLVL_BIT0 | FMC_OBSTAT_PLVL_BIT1)); +} + +/* FMC interrupts and flags management functions */ +/*! + \brief enable FMC interrupt + \param[in] interrupt: the FMC interrupt source + \arg FMC_INTEN_END: FMC end of operation interrupt + \arg FMC_INTEN_ERR: FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_enable(uint32_t interrupt) +{ + FMC_CTL |= interrupt; +} + +/*! + \brief disable FMC interrupt + \param[in] interrupt: the FMC interrupt source + \arg FMC_INTEN_END: FMC end of operation interrupt + \arg FMC_INTEN_ERR: FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_disable(uint32_t interrupt) +{ + FMC_CTL &= ~(uint32_t)interrupt; +} + +/*! + \brief get flag set or reset + \param[in] flag: check FMC flag + \arg FMC_FLAG_BUSY: FMC busy flag + \arg FMC_FLAG_PGERR: FMC programming error flag + \arg FMC_FLAG_WPERR: FMC write protection error flag + \arg FMC_FLAG_END: FMC end of programming flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flag_get(uint32_t flag) +{ + FlagStatus status = RESET; + + if(FMC_STAT & flag){ + status = SET; + } + /* return the state of corresponding FMC flag */ + return status; +} + +/*! + \brief clear the FMC pending flag by writing 1 + \param[in] flag: clear FMC flag + \arg FMC_FLAG_PGERR: FMC programming error flag + \arg FMC_FLAG_WPERR: FMC write protection error flag + \arg FMC_FLAG_END: fmc end of programming flag + \param[out] none + \retval none +*/ +void fmc_flag_clear(uint32_t flag) +{ + /* clear the flags */ + FMC_STAT = flag; +} + +/*! + \brief get the FMC state + \param[in] none + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_BUSY)){ + fmc_state = FMC_BUSY; + }else{ + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_WPERR)){ + fmc_state = FMC_WPERR; + }else{ + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGERR)){ + fmc_state = FMC_PGERR; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC is ready or not + \param[in] timeout: timeout count + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_ready_wait(uint32_t timeout) +{ + fmc_state_enum fmc_state = FMC_BUSY; + + /* wait for FMC ready */ + do{ + /* get FMC state */ + fmc_state = fmc_state_get(); + timeout--; + }while((FMC_BUSY == fmc_state) && (0U != timeout)); + + if(FMC_BUSY == fmc_state){ + fmc_state = FMC_TOERR; + } + /* return the FMC state */ + return fmc_state; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_fwdgt.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_fwdgt.c new file mode 100644 index 0000000..0c403fa --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_fwdgt.c @@ -0,0 +1,146 @@ +/*! + \file gd32f1x0_fwdgt.c + \brief FWDGT driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_fwdgt.h" + +/*! + \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 reload the counter of FWDGT + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_counter_reload(void) +{ + FWDGT_CTL = FWDGT_KEY_RELOAD; +} + +/*! + \brief start the free watchdog timer counter + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_enable(void) +{ + FWDGT_CTL = FWDGT_KEY_ENABLE; +} + +/*! + \brief configure the free watchdog timer counter window value + \param[in] window_value: specify window value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_window_value_config(uint16_t window_value) +{ + uint32_t time_index = FWDGT_WND_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_WND */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the WUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_WUD; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_WND = WND_WND(window_value); + + return SUCCESS; +} + +/*! + \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 + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC,and FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_div; + + timeout = FWDGT_RLD_TIMEOUT; + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + /* reload the counter */ + FWDGT_CTL = FWDGT_KEY_RELOAD; + + return SUCCESS; +} + +/*! + \brief get flag state of FWDGT + \param[in] flag: flag to get + \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(FWDGT_STAT & flag){ + return SET; + } + + return RESET; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_gpio.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_gpio.c new file mode 100644 index 0000000..0cb8683 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_gpio.c @@ -0,0 +1,337 @@ +/*! + \file gd32f1x0_gpio.c + \brief GPIO driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform for GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform for GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_gpio.h" + +/*! + \brief reset GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[out] none + \retval none +*/ +void gpio_deinit(uint32_t gpio_periph) +{ + switch(gpio_periph){ + case GPIOA: + /* reset GPIOA */ + rcu_periph_reset_enable(RCU_GPIOARST); + rcu_periph_reset_disable(RCU_GPIOARST); + break; + case GPIOB: + /* reset GPIOB */ + rcu_periph_reset_enable(RCU_GPIOBRST); + rcu_periph_reset_disable(RCU_GPIOBRST); + break; + case GPIOC: + /* reset GPIOC */ + rcu_periph_reset_enable(RCU_GPIOCRST); + rcu_periph_reset_disable(RCU_GPIOCRST); + break; + case GPIOD: + /* reset GPIOD */ + rcu_periph_reset_enable(RCU_GPIODRST); + rcu_periph_reset_disable(RCU_GPIODRST); + break; + case GPIOF: + /* reset GPIOF */ + rcu_periph_reset_enable(RCU_GPIOFRST); + rcu_periph_reset_disable(RCU_GPIOFRST); + break; + default: + break; + } +} + +/*! + \brief set GPIO output mode + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] mode: gpio pin mode + \arg GPIO_MODE_INPUT: input mode + \arg GPIO_MODE_OUTPUT: output mode + \arg GPIO_MODE_AF: alternate function mode + \arg GPIO_MODE_ANALOG: analog mode + \param[in] pull_up_down: gpio pin with pull-up or pull-down resistor + \arg GPIO_PUPD_NONE: without weak pull-up and pull-down resistors + \arg GPIO_PUPD_PULLUP: with weak pull-up resistor + \arg GPIO_PUPD_PULLDOWN:with weak pull-down resistor + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_mode_set(uint32_t gpio_periph,uint32_t mode,uint32_t pull_up_down,uint32_t pin) +{ + uint16_t i; + uint32_t ctl, pupd; + + ctl = GPIO_CTL(gpio_periph); + pupd = GPIO_PUD(gpio_periph); + + for (i = 0U; i < 16U; i++){ + if((1U << i) & pin){ + /* clear the specified pin mode bits */ + ctl &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + ctl |= GPIO_MODE_SET(i, mode); + + /* clear the specified pin pupd bits */ + pupd &= ~GPIO_PUPD_MASK(i); + /* set the specified pin pupd bits */ + pupd |= GPIO_PUPD_SET(i, pull_up_down); + } + } + + GPIO_CTL(gpio_periph) = ctl; + GPIO_PUD(gpio_periph) = pupd; +} + +/*! + \brief set GPIO output type and speed + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] otype: gpio pin output mode + \arg GPIO_OTYPE_PP: push pull mode + \arg GPIO_OTYPE_OD: open drain mode + \param[in] speed + \arg GPIO_OSPEED_2MHZ: output max speed 2M + \arg GPIO_OSPEED_10MHZ: output max speed 10M + \arg GPIO_OSPEED_50MHZ: output max speed 50M + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_output_options_set(uint32_t gpio_periph,uint8_t otype,uint32_t speed,uint32_t pin) +{ + uint16_t i; + uint32_t ospeedr; + + if(0x1U == otype){ + GPIO_OMODE(gpio_periph) |= (uint32_t)pin; + }else{ + GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin); + } + + /* get the specified pin output speed bits value */ + ospeedr = GPIO_OSPD(gpio_periph); + + for(i = 0U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin output speed bits */ + ospeedr &= ~GPIO_OSPEED_MASK(i); + /* set the specified pin output speed bits */ + ospeedr |= GPIO_OSPEED_SET(i,speed); + } + } + GPIO_OSPD(gpio_periph) = ospeedr; +} + +/*! + \brief set GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] pin: 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 + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] pin: 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,F) + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[in] bit_value: SET or RESET + \arg RESET: clear the port pin + \arg SET: set the port pin + \param[out] none + \retval none +*/ +void gpio_bit_write(uint32_t gpio_periph,uint32_t pin,bit_status bit_value) +{ + if(RESET != bit_value){ + GPIO_BOP(gpio_periph) = (uint32_t)pin; + }else{ + GPIO_BC(gpio_periph) = (uint32_t)pin; + } +} + +/*! + \brief write data to the specified GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] data: specify the value to be written to the port output control register + \param[out] none + \retval none +*/ +void gpio_port_write(uint32_t gpio_periph,uint16_t data) +{ + GPIO_OCTL(gpio_periph) = (uint32_t)data; +} + +/*! + \brief get GPIO pin input status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval input state of gpio pin: SET or RESET +*/ +FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin) +{ + if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO all pins input status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[out] none + \retval input 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,F) + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval output state of gpio pin: SET or RESET +*/ +FlagStatus gpio_output_bit_get(uint32_t gpio_periph,uint32_t pin) +{ + if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO all pins output status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[out] none + \retval output 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,F) + \param[in] alt_func_num: gpio pin af function, please refer to specific device datasheet + \arg GPIO_AF_0: TIMER2, TIMER13, TIMER14, TIMER16, SPI0, I2S0, SPI1, SPI2, I2S2, CK_OUT, + SWDIO, SWCLK, USART0, CEC, IFRP, I2C0, I2C1, TSI, EVENTOUT + \arg GPIO_AF_1: USART0, USART1, IFRP, CEC, TIMER2, TIMER14, I2C0, I2C1, I2C2, EVENTOUT + \arg GPIO_AF_2: TIMER0, TIMER1, TIMER15, TIMER16, EVENTOUT + \arg GPIO_AF_3: TSI, I2C0, TIMER14, EVENTOUT + \arg GPIO_AF_4(port A,B only): TIMER13, I2C0, I2C1, I2C2, USART1 + \arg GPIO_AF_5(port A,B only): TIMER15, TIMER16, SPI2, I2S2, I2C0, I2C1 + \arg GPIO_AF_6(port A,B only): SPI1, EVENTOUT + \arg GPIO_AF_7(port A,B only): CMP0, CMP1 + \arg GPIO_AF_9(port A,B only): CAN0, CAN1 (for GD32F170xx and GD32F190xx devices) + \arg GPIO_AF_11: SLCD (for GD32F170xx and GD32F190xx devices) + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_af_set(uint32_t gpio_periph,uint32_t alt_func_num,uint32_t pin) +{ + uint16_t i; + uint32_t afrl, afrh; + + afrl = GPIO_AFSEL0(gpio_periph); + afrh = GPIO_AFSEL1(gpio_periph); + + for (i = 0U; i < 8U; i++){ + if((1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrl &= ~GPIO_AFR_MASK(i); + afrl |= GPIO_AFR_SET(i,alt_func_num); + } + } + + for (i = 8U; i < 16U; i++){ + if((1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrh &= ~GPIO_AFR_MASK(i - 8U); + afrh |= GPIO_AFR_SET(i - 8U,alt_func_num); + } + } + + GPIO_AFSEL0(gpio_periph) = afrl; + GPIO_AFSEL1(gpio_periph) = afrh; +} + +/*! + \brief lock GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B) + \param[in] pin: 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); +} + +#ifdef GD32F170_190 +/*! + \brief toggle GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[in] pin: 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 + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + \param[out] none + \retval none +*/ +void gpio_port_toggle(uint32_t gpio_periph) +{ + GPIO_TG(gpio_periph) = 0x0000FFFFU; +} + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_i2c.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_i2c.c new file mode 100644 index 0000000..8b6c994 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_i2c.c @@ -0,0 +1,795 @@ +/*! + \file gd32f1x0_i2c.c + \brief I2C driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_i2c.h" + +#define I2CCLK_MAX 0x3fU /*!< i2cclk max value */ +#define I2C_FLAG_MASK 0x0000FFFFU /*!< i2c flag mask */ + +/*! + \brief reset I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_deinit(uint32_t i2c_periph) +{ + switch(i2c_periph){ + case I2C0: + /* reset I2C0 */ + rcu_periph_reset_enable(RCU_I2C0RST); + rcu_periph_reset_disable(RCU_I2C0RST); + break; + case I2C1: + /* reset I2C1 */ + rcu_periph_reset_enable(RCU_I2C1RST); + rcu_periph_reset_disable(RCU_I2C1RST); + break; +#ifdef GD32F170_190 + case I2C2: + /* reset I2C2 */ + rcu_periph_reset_enable(RCU_I2C2RST); + rcu_periph_reset_disable(RCU_I2C2RST); + break; +#endif /* GD32F170_190 */ + default: + break; + } +} + +/*! + \brief configure I2C clock + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz) + and fast mode plus (up to 1MHz) + \param[in] dutycyc: duty cycle in fast mode or fast mode plus + \arg I2C_DTCY_2: T_low/T_high=2 + \arg I2C_DTCY_16_9: T_low/T_high=16/9 + \param[out] none + \retval none +*/ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc) +{ + uint32_t pclk1,clkc,freq,risetime; + uint32_t temp; + + pclk1 = rcu_clock_freq_get(CK_APB1); + /* I2C peripheral clock frequency */ + freq = (uint32_t)(pclk1/1000000U); + if(freq >= I2CCLK_MAX){ + freq = I2CCLK_MAX; + } + temp = I2C_CTL1(i2c_periph); + temp &= ~I2C_CTL1_I2CCLK; + temp |= freq; + + I2C_CTL1(i2c_periph) = temp; + + if(100000U >= clkspeed){ + /* the maximum SCL rise time is 1000ns in standard mode */ + risetime = (uint32_t)((pclk1/1000000U)+1U); + if(risetime >= I2CCLK_MAX){ + I2C_RT(i2c_periph) = I2CCLK_MAX; + }else{ + I2C_RT(i2c_periph) = risetime; + } + clkc = (uint32_t)(pclk1/(clkspeed*2U)); + if(clkc < 0x04U){ + /* the CLKC in standard mode minmum value is 4 */ + clkc = 0x04U; + } + I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc); + + }else if(400000U >= clkspeed){ + /* the maximum SCL rise time is 300ns in fast mode */ + I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)300U)/(uint32_t)1000U)+(uint32_t)1U); + if(I2C_DTCY_2 == dutycyc){ + /* I2C duty cycle is 2 */ + clkc = (uint32_t)(pclk1/(clkspeed*3U)); + I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY; + }else{ + /* I2C duty cycle is 16/9 */ + clkc = (uint32_t)(pclk1/(clkspeed*25U)); + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY; + } + if(0U == (clkc & I2C_CKCFG_CLKC)){ + /* the CLKC in fast mode minmum value is 1 */ + clkc |= 0x0001U; + } + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST; + I2C_CKCFG(i2c_periph) |= clkc; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure I2C address + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] mode: + \arg I2C_I2CMODE_ENABLE: I2C mode + \arg I2C_SMBUSMODE_ENABLE: SMBus mode + \param[in] addformat: 7bits or 10bits + \arg I2C_ADDFORMAT_7BITS: 7bits + \arg I2C_ADDFORMAT_10BITS: 10bits + \param[in] addr: I2C address + \param[out] none + \retval none +*/ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr) +{ + /* SMBus/I2C mode selected */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SMBEN); + ctl |= mode; + I2C_CTL0(i2c_periph) = ctl; + /* configure address */ + I2C_SADDR0(i2c_periph) = (addformat | addr); +} + +/*! + \brief SMBus type selection + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] ack: + \arg I2C_SMBUS_DEVICE: device + \arg I2C_SMBUS_HOST: host + \param[out] none + \retval none +*/ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type) +{ + if(I2C_SMBUS_HOST == type){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL); + } +} + +/*! + \brief whether or not to send an ACK + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] ack: + \arg I2C_ACK_ENABLE: ACK will be sent + \arg I2C_ACK_DISABLE: ACK will not be sent + \param[out] none + \retval none +*/ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack) +{ + if(I2C_ACK_ENABLE == ack){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN); + } +} + +/*! + \brief I2C POAP position configure + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] pos: + \arg I2C_ACKPOS_CURRENT: whether to send ACK or not for the current + \arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte + \param[out] none + \retval none +*/ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos) +{ + /* configure I2C POAP position */ + if(I2C_ACKPOS_NEXT == pos){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP); + } +} + +/*! + \brief master send slave address + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] addr: slave address + \param[in] trandirection: transmitter or receiver + \arg I2C_TRANSMITTER: transmitter + \arg I2C_RECEIVER: receiver + \param[out] none + \retval none +*/ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection) +{ + if(I2C_TRANSMITTER == trandirection){ + addr = addr & I2C_TRANSMITTER; + }else{ + addr = addr | I2C_RECEIVER; + } + I2C_DATA(i2c_periph) = addr; +} + +/*! + \brief dual-address mode switch + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dualaddr: + \arg I2C_DUADEN_DISABLE: disable dual-address mode + \arg I2C_DUADEN_ENABLE: enable dual-address mode + \param[out] none + \retval none +*/ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t dualaddr) +{ + if(I2C_DUADEN_ENABLE == dualaddr){ + I2C_SADDR1(i2c_periph) |= I2C_SADDR1_DUADEN; + }else{ + I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN); + } +} + +/*! + \brief enable I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN; +} + +/*! + \brief disable I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_I2CEN); +} + +/*! + \brief generate a START condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_start_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_START; +} + +/*! + \brief generate a STOP condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_stop_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP; +} + +/*! + \brief I2C transmit data function + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data) +{ + I2C_DATA(i2c_periph) = DATA_TRANS(data); +} + +/*! + \brief I2C receive data function + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval data of received +*/ +uint8_t i2c_data_receive(uint32_t i2c_periph) +{ + return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph)); +} + +/*! + \brief enable I2C DMA mode + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dmastate: + \arg I2C_DMA_ON: DMA mode enable + \arg I2C_DMA_OFF: DMA mode disable + \param[out] none + \retval none +*/ +void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate) +{ + /* configure I2C DMA function */ + uint32_t ctl = 0U; + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMAON); + ctl |= dmastate; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief flag indicating DMA last transfer + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dmalast: + \arg I2C_DMALST_ON: next DMA EOT is the last transfer + \arg I2C_DMALST_OFF: next DMA EOT is not the last transfer + \param[out] none + \retval none +*/ +void i2c_dma_last_transfer_enable(uint32_t i2c_periph, uint32_t dmalast) +{ + /* configure DMA last transfer */ + uint32_t ctl = 0U; + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMALST); + ctl |= dmalast; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief whether to stretch SCL low when data is not ready in slave mode + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] stretchpara: + \arg I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled + \arg I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara) +{ + /* configure I2C SCL strerching enable or disable */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_DISSTRC); + ctl |= stretchpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief whether or not to response to a general call + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] gcallpara: + \arg I2C_GCEN_ENABLE: slave will response to a general call + \arg I2C_GCEN_DISABLE: slave will not response to a general call + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara) +{ + /* configure slave response to a general call enable or disable */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_GCEN); + ctl |= gcallpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief software reset I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] sreset: + \arg I2C_SRESET_SET: I2C is under reset + \arg I2C_SRESET_RESET: I2C is not under reset + \param[out] none + \retval none +*/ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset) +{ + /* modify CTL0 and configure software reset I2C state */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SRESET); + ctl |= sreset; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief check I2C flag is set or not + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] flag: + \arg I2C_FLAG_SBSEND: start condition send out + \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode + \arg I2C_FLAG_BTC: byte transmission finishes + \arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode + \arg I2C_FLAG_STPDET: stop condition detected in slave mode + \arg I2C_FLAG_RBNE: I2C_DATA is not Empty during receiving + \arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting + \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_AERR: acknowledge error + \arg I2C_FLAG_OUERR: overrun or underrun situation occurs in slave mode + \arg I2C_FLAG_PECERR: PEC error when receiving data + \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode + \arg I2C_FLAG_SMBALT: SMBus alert status + \arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode + \arg I2C_FLAG_I2CBSY: busy flag + \arg I2C_FLAG_TRS: whether the I2C is a transmitter or a receiver + \arg I2C_FLAG_RXGC: general call address (00h) received + \arg I2C_FLAG_DEFSMB: default address of SMBus device + \arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode + \arg I2C_FLAG_DUMODF: dual flag in slave mode indicating which address is matched in dual-address mode + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag) +{ + uint32_t reg = 0U; + FlagStatus reval = RESET; + /* get the flag in which register */ + reg = (BIT(31) & flag); + if((BIT(31) == reg)){ + if((I2C_STAT1(i2c_periph)&(flag & I2C_FLAG_MASK))){ + reval = SET; + }else{ + reval = RESET; + } + }else{ + if((I2C_STAT0(i2c_periph)&(flag & I2C_FLAG_MASK))){ + reval = SET; + }else{ + reval = RESET; + } + } + /* return the flag status */ + return reval; +} + +/*! + \brief clear I2C flag + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] flag: flag type + \arg I2C_FLAG_SMBALT: SMBus Alert status + \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode + \arg I2C_FLAG_PECERR: PEC error when receiving data + \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode + \arg I2C_FLAG_AERR: acknowledge error + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_BERR: a bus error + \arg I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1 + \param[out] none + \retval none +*/ +void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag) +{ + if(I2C_FLAG_ADDSEND == flag){ + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + }else{ + I2C_STAT0(i2c_periph) &= ~(flag); + } +} + +/*! + \brief enable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] inttype: interrupt type + \arg I2C_INT_ERR: error interrupt enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \param[out] none + \retval none +*/ +void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t inttype) +{ + I2C_CTL1(i2c_periph) |= (inttype); +} + +/*! + \brief disable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] inttype: interrupt type + \arg I2C_INT_ERR: error interrupt enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \param[out] none + \retval none +*/ +void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t inttype) +{ + I2C_CTL1(i2c_periph) &= ~(inttype); +} + +/*! + \brief check I2C interrupt flag + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] int_flag: interrupt flag + \arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag + \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag + \arg I2C_INT_FLAG_BTC: byte transmission finishes + \arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag + \arg I2C_INT_FLAG_STPDET: etop condition detected in slave mode interrupt flag + \arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag + \arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag + \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag + \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag + \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag + \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag + \param[out] none + \retval none +*/ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, uint32_t intflag) +{ + uint32_t evie, errie, bufie; + + evie = I2C_CTL1(i2c_periph)&I2C_CTL1_EVIE; + errie = I2C_CTL1(i2c_periph)&I2C_CTL1_ERRIE; + /* check I2C event interrupt enable bit */ + if((intflag&0x00ffU) && evie){ + if(intflag&0x001fU){ + /* check I2C event flags except TBE and RBNE */ + if(intflag & I2C_STAT0(i2c_periph)){ + return SET; + }else{ + return RESET; + } + }else{ + /* check I2C event flags TBE and RBNE */ + bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE; + if(bufie){ + if(intflag & I2C_STAT0(i2c_periph)){ + return SET; + }else{ + return RESET; + } + }else{ + return RESET; + } + } + /* check I2C error interrupt enable bit */ + }else if((intflag&0xff00U) && errie){ + /* check I2C error flags */ + if(intflag & I2C_STAT0(i2c_periph)){ + return SET; + }else{ + return RESET; + } + }else{ + return RESET; + } +} + +/*! + \brief clear I2C interrupt flag + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] intflag: interrupt flag + \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag + \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag + \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag + \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag + \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag + \param[out] none + \retval none +*/ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, uint32_t intflag) +{ + if(I2C_INT_FLAG_ADDSEND == intflag){ + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + }else{ + I2C_STAT0(i2c_periph) &= ~(intflag); + } +} + +/*! + \brief I2C PEC calculation on or off + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] pecpara: + \arg I2C_PEC_ENABLE: PEC calculation on + \arg I2C_PEC_DISABLE: PEC calculation off + \param[out] none + \retval none +*/ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate) +{ + /* on/off PEC calculation */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECEN); + ctl |= pecstate; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief I2C whether to transfer PEC value + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] pecpara: + \arg I2C_PECTRANS_ENABLE: transfer PEC + \arg I2C_PECTRANS_DISABLE: not transfer PEC + \param[out] none + \retval none +*/ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara) +{ + /* whether to transfer PEC */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECTRANS); + ctl |= pecpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief get packet error checking value + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval PEC value +*/ +uint8_t i2c_pec_value_get(uint32_t i2c_periph) +{ + return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_ECV)>>8); +} + +/*! + \brief I2C issue alert through SMBA pin + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] smbuspara: + \arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin + \arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin + \param[out] none + \retval none +*/ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara) +{ + /* issue alert through SMBA pin configure*/ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SALT); + ctl |= smbuspara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief enable or disable I2C ARP protocol in SMBus switch + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] smbuspara: + \arg I2C_ARP_ENABLE: enable ARP + \arg I2C_ARP_DISABLE: disable ARP + \param[out] none + \retval none +*/ +void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate) +{ + /* enable or disable I2C ARP protocol*/ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_ARPEN); + ctl |= arpstate; + I2C_CTL0(i2c_periph) = ctl; +} + +#ifdef GD32F170_190 + +/*! + \brief enable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN; +} + +/*! + \brief disable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN); +} + +/*! + \brief enable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN; +} + +/*! + \brief disable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN); +} + +/*! + \brief enable the specified I2C SAM interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] inttype: interrupt type + \@arg I2C_SAMCS_TFFIE: txframe fall interrupt + \@arg I2C_SAMCS_TFRIE: txframe rise interrupt + \@arg I2C_SAMCS_RFFIE: rxframe fall interrupt + \@arg I2C_SAMCS_RFRIE: rxframe rise interrupt + \param[out] none + \retval none +*/ +void i2c_sam_interrupt_enable(uint32_t i2c_periph, uint32_t inttype) +{ + I2C_SAMCS(i2c_periph) |= (inttype); +} + +/*! + \brief disable i2c interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] inttype: interrupt type + \@arg I2C_SAMCS_TFFIE: txframe fall interrupt + \@arg I2C_SAMCS_TFRIE: txframe rise interrupt + \@arg I2C_SAMCS_RFFIE: rxframe fall interrupt + \@arg I2C_SAMCS_RFRIE: rxframe rise interrupt + \param[out] none + \retval none +*/ +void i2c_sam_interrupt_disable(uint32_t i2c_periph, uint32_t inttype) +{ + I2C_SAMCS(i2c_periph) &= ~(inttype); +} + +/*! + \brief check i2c SAM state + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] samstate: state type + \@arg I2C_SAMCS_TXF: level of txframe signal + \@arg I2C_SAMCS_RXF: level of rxframe signal + \@arg I2C_SAMCS_TFF: txframe fall flag + \@arg I2C_SAMCS_TFR: txframe rise flag + \@arg I2C_SAMCS_RFF: rxframe fall flag + \@arg I2C_SAMCS_RFR: rxframe rise flag + \param[out] none + \retval state of i2c SAM +*/ +FlagStatus i2c_sam_flag_get(uint32_t i2c_periph, uint32_t samstate) +{ + if(I2C_SAMCS(i2c_periph) & samstate){ + return SET; + } + + return RESET; +} +/*! + \brief clear i2c SAM state + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] samstate: state type + \@arg I2C_SAMCS_TFF: txframe fall flag + \@arg I2C_SAMCS_TFR: txframe rise flag + \@arg I2C_SAMCS_RFF: rxframe fall flag + \@arg I2C_SAMCS_RFR: rxframe rise flag + \param[out] none + \retval none +*/ +void i2c_sam_flag_clear(uint32_t i2c_periph, uint32_t samstate) +{ + I2C_SAMCS(i2c_periph) &= ~(samstate); + +} + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_ivref.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_ivref.c new file mode 100644 index 0000000..4737114 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_ivref.c @@ -0,0 +1,180 @@ +/*! + \file gd32f1x0_ivref.c + \brief IVREF driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 + +#include "gd32f1x0_ivref.h" + +/*! + \brief deinit IVREF + \param[in] none + \param[out] none + \retval none +*/ +void ivref_deinit(void) +{ + rcu_periph_reset_enable(RCU_OPAIVREFRST); + rcu_periph_reset_disable(RCU_OPAIVREFRST); +} + +/*! + \brief enable VREF + \param[in] none + \param[out] none + \retval none +*/ +void vref_enable(void) +{ + IVREF_CTL |= IVREF_CTL_VREN; +} + +/*! + \brief disable VREF + \param[in] none + \param[out] none + \retval none +*/ +void vref_disable(void) +{ + IVREF_CTL &= ~IVREF_CTL_VREN; +} + +/*! + \brief set VREF mode + \param[in] vrefmode + \arg VREF_CONNECT_EXTERNAL_CAP: vref connect external capacitor + \arg VREF_DISCONNECT_EXTERNAL_CAP: vref disconnect external capacitor + \param[out] none + \retval none +*/ +void vref_mode_set(uint32_t vrefmode) +{ + uint32_t ctl = 0U; + ctl = IVREF_CTL; + /* clear voltage reference enable bits */ + ctl &= ~IVREF_CTL_DECAP; + ctl |= vrefmode; + IVREF_CTL = ctl; +} + +/*! + \brief set VREF voltage precision trim. + \param[in] precisiontrim + \arg VREF_VOLT_PRECISION_TRIM_X(x=0..31): (-6.4+ 0.4*x)% + \param[out] none + \retval none +*/ +void vref_precision_trim_value_set(uint32_t precisiontrim) +{ + uint32_t ctl = 0U; + ctl = IVREF_CTL; + ctl &= ~IVREF_CTL_VPT; + ctl |= precisiontrim; + IVREF_CTL = ctl; +} + +/*! + \brief enable IREF + \param[in] none + \param[out] none + \retval none +*/ +void iref_enable(void) +{ + IVREF_CTL |= IVREF_CTL_CREN; +} + +/*! + \brief disable IREF + \param[in] none + \param[out] none + \retval none +*/ +void iref_disable(void) +{ + IVREF_CTL &= ~IVREF_CTL_CREN; +} + +/*! + \brief set IREF mode + \param[in] irefmode + \arg IREF_MODE_LOW_POWER: 1uA step + \arg IREF_MODE_HIGH_CURRENT: 8uA step + \param[out] none + \retval none +*/ +void iref_mode_set(uint32_t irefmode) +{ + uint32_t ctl = 0U; + ctl = IVREF_CTL; + ctl &= ~IVREF_CTL_SSEL; + ctl |= irefmode; + IVREF_CTL = ctl; +} + +/*! + \brief set IREF precision_trim_value + \param[in] precisiontrim + \arg IREF_CUR_PRECISION_TRIM_X(x=0..31): (-15+ x)% + \param[out] none + \retval none +*/ +void iref_precision_trim_value_set(uint32_t precisiontrim) +{ + uint32_t ctl = 0U; + ctl = IVREF_CTL; + ctl &= ~IVREF_CTL_CPT; + ctl |= precisiontrim; + IVREF_CTL = ctl; +} + +/*! + \brief set IREF sink mode + \param[in] irefsinkmode + \arg IREF_SOURCE_CURRENT : source current. + \arg IREF_SINK_CURRENT: sink current + \param[out] none + \retval none +*/ +void iref_sink_set(uint32_t irefsinkmode) +{ + uint32_t ctl = 0U; + ctl = IVREF_CTL; + /* clear sink current mode bits */ + ctl &= ~IVREF_CTL_SCMOD; + /* set sink current mode bits */ + ctl |= irefsinkmode; + IVREF_CTL = ctl; +} + +/*! + \brief set IREF step data + \param[in] irefstepdata + \arg IREF_CUR_STEP_DATA_X:(x=0..63): step*x + \param[out] none + \retval none +*/ +void iref_step_data_config(uint32_t irefstepdata) +{ + uint32_t ctl = 0U; + /* get ctl value */ + ctl = IVREF_CTL; + /* clear current step data bits */ + ctl &= ~IVREF_CTL_CSDT; + /* set current step data bits */ + ctl |= irefstepdata; + IVREF_CTL = ctl; +} + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_misc.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_misc.c new file mode 100644 index 0000000..31af322 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_misc.c @@ -0,0 +1,149 @@ +/*! + \file gd32f1x0_misc.c + \brief MISC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_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)0x700)==NVIC_PRIGROUP_PRE0_SUB4){ + temp_pre = 0U; + temp_sub = 0x4U; + }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE1_SUB3){ + temp_pre = 1U; + temp_sub = 0x3U; + }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE2_SUB2){ + temp_pre = 2U; + temp_sub = 0x2U; + }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE3_SUB1){ + temp_pre = 3U; + temp_sub = 0x1U; + }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE4_SUB0){ + temp_pre = 4U; + temp_sub = 0x0U; + }else{ + } + /* get the temp_priority to fill the NVIC->IP register */ + temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre); + temp_priority |= nvic_irq_sub_priority &(0x0FU >> (0x4U - temp_sub)); + temp_priority = temp_priority << 0x04U; + NVIC->IP[nvic_irq] = (uint8_t)temp_priority; + /* enable the selected IRQ */ + NVIC->ISER[nvic_irq >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F); +} + +/*! + \brief disable NVIC request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[out] none + \retval none +*/ +void nvic_irq_disable(uint8_t nvic_irq) +{ + /* disable the selected IRQ.*/ + NVIC->ICER[nvic_irq >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F); +} + +/*! + \brief set the NVIC vector table base address + \param[in] nvic_vict_tab: the RAM or FLASH base address + \arg NVIC_VECTTAB_RAM: RAM base address + \are NVIC_VECTTAB_FLASH: Flash base address + \param[in] offset: Vector Table offset + \param[out] none + \retval none +*/ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset) +{ + SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK); +} + +/*! + \brief set the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up + by all the enable and disable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_set(uint8_t lowpower_mode) +{ + SCB->SCR |= (uint32_t)lowpower_mode; +} + +/*! + \brief reset the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be + woke up by the enable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_reset(uint8_t lowpower_mode) +{ + SCB->SCR &= (~(uint32_t)lowpower_mode); +} + +/*! + \brief set the systick clock source + \param[in] systick_clksource: the systick clock source needed to choose + \arg SYSTICK_CLKSOURCE_HCLK: systick clock source is from HCLK + \arg SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8 + \param[out] none + \retval none +*/ + +void systick_clksource_set(uint32_t systick_clksource) +{ + if(SYSTICK_CLKSOURCE_HCLK == systick_clksource ){ + /* set the systick clock source from HCLK */ + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + }else{ + /* set the systick clock source from HCLK/8 */ + SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8; + } +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_opa.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_opa.c new file mode 100644 index 0000000..9800c26 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_opa.c @@ -0,0 +1,341 @@ +/*! + \file gd32f1x0_opa.c + \brief OPA driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 + +#include "gd32f1x0_opa.h" + +/*! + \brief deinit the OPA register to its default reset value + \param[in] none + \param[out] none + \retval none +*/ +void opa_deinit(void) +{ + rcu_periph_reset_enable(RCU_OPAIVREFRST); + rcu_periph_reset_disable(RCU_OPAIVREFRST); +} + +/*! + \brief enable OPA switch + \param[in] opax_swy + \arg OPA_T3OPA0: T3 switch enable for OPA0 + \arg OPA_S1OPA0: S1 switch enable for OPA0 + \arg OPA_S2OPA0: S2 switch enable for OPA0 + \arg OPA_S3OPA0: S3 switch enable for OPA0 + \arg OPA_T3OPA1: T3 switch enable for OPA1 + \arg OPA_S1OPA1: S1 switch enable for OPA1 + \arg OPA_S2OPA1: S2 switch enable for OPA1 + \arg OPA_S3OPA1: S3 switch enable for OPA1 + \arg OPA_S4OPA1: S4 switch enable for OPA1 + \arg OPA_T3OPA2: T3 switch enable for OPA2 + \arg OPA_S1OPA2: S3 switch enable for OPA2 + \arg OPA_S2OPA2: S3 switch enable for OPA2 + \arg OPA_S3OPA2: S3 switch enable for OPA2 + \param[out] none + \retval none +*/ +void opa_switch_enable(uint32_t opax_swy) +{ + OPA_CTL |= (uint32_t)(opax_swy); +} + +/*! + \brief enable OPA + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[out] none + \retval none +*/ +void opa_enable(uint32_t opa_periph) +{ + if(OPA0 == opa_periph){ + OPA_CTL &= ~OPA_CTL_OPA0PD; + }else if(OPA1 == opa_periph){ + OPA_CTL &= ~OPA_CTL_OPA1PD; + }else{ + OPA_CTL &= ~OPA_CTL_OPA2PD; + } +} + +/*! + \brief disable OPA + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[out] none + \retval none +*/ +void opa_disable(uint32_t opa_periph) +{ + if(OPA0 == opa_periph){ + OPA_CTL |= OPA_CTL_OPA0PD; + }else if(OPA1 == opa_periph){ + OPA_CTL |= OPA_CTL_OPA1PD; + }else{ + OPA_CTL |= OPA_CTL_OPA2PD; + } +} + +/*! + \brief disable OPA switch + \param[in] opax_swy + \arg OPA_T3OPA0: T3 switch enable for OPA0 + \arg OPA_S1OPA0: S1 switch enable for OPA0 + \arg OPA_S2OPA0: S2 switch enable for OPA0 + \arg OPA_S3OPA0: S3 switch enable for OPA0 + \arg OPA_T3OPA1: T3 switch enable for OPA1 + \arg OPA_S1OPA1: S1 switch enable for OPA1 + \arg OPA_S2OPA1: S2 switch enable for OPA1 + \arg OPA_S3OPA1: S3 switch enable for OPA1 + \arg OPA_S4OPA1: S4 switch enable for OPA1 + \arg OPA_T3OPA2: T3 switch enable for OPA2 + \arg OPA_S1OPA2: S3 switch enable for OPA2 + \arg OPA_S2OPA2: S3 switch enable for OPA2 + \arg OPA_S3OPA2: S3 switch enable for OPA2 + \param[out] none + \retval none +*/ +void opa_switch_disable(uint32_t opax_swy) +{ + OPA_CTL &= ~opax_swy; +} + +/*! + \brief enable OPA in low power mode + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[out] none + \retval none +*/ +void opa_low_power_enable(uint32_t opa_periph) +{ + if(OPA0 == opa_periph){ + OPA_CTL &= ~OPA_CTL_OPA0LPM; + }else if(OPA1 == opa_periph){ + OPA_CTL &= ~OPA_CTL_OPA1LPM; + }else{ + OPA_CTL &= ~OPA_CTL_OPA2LPM; + } +} + +/*! + \brief disable OPA in low power mode + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[out] none + \retval none +*/ +void opa_low_power_disable(uint32_t opa_periph) +{ + if(OPA0 == opa_periph){ + OPA_CTL |= OPA_CTL_OPA0LPM; + }else if(OPA1 == opa_periph){ + OPA_CTL |= OPA_CTL_OPA1LPM; + }else{ + OPA_CTL |= OPA_CTL_OPA2LPM; + } +} + +/*! + \brief set OPA power range + \param[in] powerrange + \arg OPA_POWRANGE_LOW: Low power range is selected (VDDA is lower than 3.3V) + \arg OPA_POWRANGE_HIGH: High power range is selected (VDDA is higher than 3.3V) + \param[out] none + \retval none +*/ +void opa_power_range_config(uint32_t powerrange) +{ + OPA_CTL &= ~OPA_CTL_OPA_RANGE; + OPA_CTL |= powerrange; +} + +/*! + \brief set OPA bias trimming mode + \param[in] opa_trimmode + \arg OPA_BT_TRIM_FACTORY: factory trimming values are used for offset calibration + \arg OPA_BT_TRIM_USER: user trimming values are used for offset calibration + \param[out] none + \retval none +*/ +void opa_trim_mode_set(uint32_t opa_trimmode) +{ + OPA_BT &= ~OPA_BT_OT_USER; + OPA_BT |= opa_trimmode; +} + +/*! + \brief set OPA bias trimming value + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[in] opa_input + \arg OPA_INPUT_P: PMOS input is selected to configure the trimming value + \arg OPA_INPUT_N: NMOS input is selected to configure the trimming value + \param[in] opa_trimmode + \arg this parameter can be any value lower or equal to 0x0000001F. + \param[out] none + \retval none +*/ +void opa_trim_value_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue) +{ + uint32_t bt = 0U, ctl = 0U; + ctl = OPA_CTL; + bt = OPA_BT; + + if(OPA0 == opa_periph){ + /* clear the specified opa calibration for N diff and P diff */ + ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H); + /* set the specified opa calibration for N diff or P diff */ + ctl |= opa_input; + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA0_TRIM_LOW); + bt |= (opa_trimvalue); + }else{ + /* clear the specified NMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA0_TRIM_HIGH); + bt |= (opa_trimvalue << 5U); + } + + }else if(OPA1 == opa_periph){ + ctl &= (uint32_t)~(OPA_CTL_OPA1CAL_L | OPA_CTL_OPA1CAL_H); + ctl |= (uint32_t)(opa_input << 8U); + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA1_TRIM_LOW); + bt |= (opa_trimvalue << 10U); + }else{ + /* clear the specified NMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA1_TRIM_HIGH); + bt |= (opa_trimvalue << 15U); + } + }else{ + ctl &= (uint32_t)~(OPA_CTL_OPA2CAL_L | OPA_CTL_OPA2CAL_H); + ctl |= (uint32_t)(opa_input << 16U); + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA2_TRIM_LOW); + bt |= (opa_trimvalue << 20U); + }else{ + /* clear the specified NMOS pairs normal mode 5-bit offset trim value */ + bt &= (~OPA_BT_OA2_TRIM_HIGH); + bt |= (opa_trimvalue << 25U); + } + } + + OPA_CTL = ctl; + OPA_BT = bt; +} + +/*! + \brief set OPA bias trimming value low power + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[in] opa_input + \arg OPA_INPUT_P: PMOS input is selected to configure the trimming value + \arg OPA_INPUT_N: NMOS input is selected to configure the trimming value + \param[in] opa_trimmode + \arg this parameter can be any value lower or equal to 0x0000001F. + \param[out] none + \retval none +*/ +void opa_trim_value_lp_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue) +{ + uint32_t lpbt = 0U, ctl = 0U; + ctl = OPA_CTL; + lpbt = OPA_LPBT; + + if(OPA0 == opa_periph){ + ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H); + ctl |= opa_input; + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA0_TRIM_LOW); + lpbt |= (opa_trimvalue); + }else{ + /* clear the specified NMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA0_TRIM_HIGH); + lpbt |= (opa_trimvalue << 5U); + } + }else if (OPA1 == opa_periph){ + ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H); + ctl |= (uint32_t)(opa_input << 8U); + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA1_TRIM_LOW); + lpbt |= (opa_trimvalue << 10U); + }else{ + /* clear the specified NMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA1_TRIM_HIGH); + lpbt |= (opa_trimvalue << 15U); + } + + }else{ + ctl &= (uint32_t)~(OPA_CTL_OPA2CAL_L | OPA_CTL_OPA2CAL_H); + ctl |= (uint32_t)(opa_input << 16U); + if(OPA_INPUT_P == opa_input){ + /* clear the specified PMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA2_TRIM_LOW); + lpbt |= (opa_trimvalue << 20U); + }else{ + /* clear the specified NMOS pairs low power mode 5-bit offset trim value */ + lpbt &= (~OPA_LPBT_OA2_TRIM_HIGH); + lpbt |= (opa_trimvalue << 25U); + } + } + + OPA_CTL = ctl; + OPA_LPBT = lpbt; +} + +/*! + \brief get OPA calibration flag + \param[in] opa_periph + \arg OPAx(x =0,1,2) + \param[out] none + \retval The state of the OPA calibration flag (SET or RESET) +*/ +FlagStatus opa_cal_out_get(uint32_t opa_periph) +{ + uint32_t data = 0U; + FlagStatus bitstatus = RESET; + data = OPA_CTL; + + if(OPA0 == opa_periph){ + /* get opa0 calibration output bit status */ + if ((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){ + bitstatus = SET; + }else{ + bitstatus = RESET; + } + }else if(OPA1 == opa_periph){ + /* get opa1 calibration output bit status */ + if ((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){ + bitstatus = SET; + }else{ + bitstatus = RESET; + } + }else{ + /* get opa2 calibration output bit status */ + if((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){ + bitstatus = SET; + }else{ + bitstatus = RESET; + } + } + return bitstatus; +} + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_pmu.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_pmu.c new file mode 100644 index 0000000..ee594e6 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_pmu.c @@ -0,0 +1,257 @@ +/*! + \file gd32f1x0_pmu.c + \brief PMU driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_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: + \arg PMU_LVDT_0: voltage threshold is 2.2V (GD32F130_150) or 2.4V (GD32F170_190) + \arg PMU_LVDT_1: voltage threshold is 2.3V (GD32F130_150) or 2.7V (GD32F170_190) + \arg PMU_LVDT_2: voltage threshold is 2.4V (GD32F130_150) or 3.0V (GD32F170_190) + \arg PMU_LVDT_3: voltage threshold is 2.5V (GD32F130_150) or 3.3V (GD32F170_190) + \arg PMU_LVDT_4: voltage threshold is 2.6V (GD32F130_150) or 3.6V (GD32F170_190) + \arg PMU_LVDT_5: voltage threshold is 2.7V (GD32F130_150) or 3.9V (GD32F170_190) + \arg PMU_LVDT_6: voltage threshold is 2.8V (GD32F130_150) or 4.2V (GD32F170_190) + \arg PMU_LVDT_7: voltage threshold is 2.9V (GD32F130_150) or 4.5V (GD32F170_190) + \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 PMU lvd disable + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; +} + +/*! + \brief PMU work at sleep mode + \param[in] sleepmodecmd: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_sleepmode(uint8_t sleepmodecmd) +{ + /* clear sleepdeep bit of Cortex-M3 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + + /* select WFI or WFE command to enter sleep mode */ + if(WFI_CMD == sleepmodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \brief PMU work at deepsleep mode + \param[in] ldo + \arg PMU_LDO_NORMAL: LDO normal work when pmu enter deepsleep mode + \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode + \param[in] deepsleepmodecmd: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd) +{ + static uint32_t reg_snap[ 4 ]; + /* clear stbmod and ldolp bits */ + PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP)); + + /* set ldolp bit according to pmu_ldo */ + PMU_CTL |= ldo; + + /* set sleepdeep bit of Cortex-M3 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + reg_snap[ 0 ] = REG32( 0xE000E010 ); + reg_snap[ 1 ] = REG32( 0xE000E100 ); + reg_snap[ 2 ] = REG32( 0xE000E104 ); + reg_snap[ 3 ] = REG32( 0xE000E108 ); + + REG32( 0xE000E010 ) &= 0x00010004; + REG32( 0xE000E180 ) = 0XB7FFEF19; + REG32( 0xE000E184 ) = 0XFFFFFBFF; + REG32( 0xE000E188 ) = 0xFFFFFFFF; + + /* select WFI or WFE command to enter deepsleep mode */ + if(WFI_CMD == deepsleepmodecmd){ + __WFI(); + }else{ + __SEV(); + __WFE(); + __WFE(); + } + + REG32( 0xE000E010 ) = reg_snap[ 0 ] ; + REG32( 0xE000E100 ) = reg_snap[ 1 ] ; + REG32( 0xE000E104 ) = reg_snap[ 2 ] ; + REG32( 0xE000E108 ) = reg_snap[ 3 ] ; + + /* reset sleepdeep bit of Cortex-M3 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); +} + +/*! + \brief pmu work at standby mode + \param[in] standbymodecmd: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_standbymode(uint8_t standbymodecmd) +{ + /* set sleepdeep bit of Cortex-M3 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* set stbmod bit */ + PMU_CTL |= PMU_CTL_STBMOD; + + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + + /* select WFI or WFE command to enter standby mode */ + if(WFI_CMD == standbymodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \brief clear flag bit + \param[in] flag_reset: + \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag + \arg PMU_FLAG_RESET_STANDBY: reset standby flag + \param[out] none + \retval none +*/ +void pmu_flag_clear(uint32_t flag_reset) +{ + switch(flag_reset){ + case PMU_FLAG_RESET_WAKEUP: + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + break; + case PMU_FLAG_RESET_STANDBY: + /* reset standby flag */ + PMU_CTL |= PMU_CTL_STBRST; + break; + default : + break; + } +} + +/*! + \brief get flag state + \param[in] flag: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \arg PMU_FLAG_LVD: lvd flag + \param[out] none + \retval FlagStatus SET or RESET +*/ +FlagStatus pmu_flag_get(uint32_t flag ) +{ + if(PMU_CS & flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief backup domain write enable + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL |= PMU_CTL_BKPWEN; +} + +/*! + \brief backup domain write disable + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL &= ~PMU_CTL_BKPWEN; +} + +/*! + \brief wakeup pin enable + \param[in] wakeup_pin: + \arg PMU_WAKEUP_PIN0: wakeup pin 0 + \arg PMU_WAKEUP_PIN1: wakeup pin 1 + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin ) +{ + PMU_CS |= wakeup_pin; +} + +/*! + \brief wakeup pin disable + \param[in] wakeup_pin: + \arg PMU_WAKEUP_PIN0: wakeup pin 0 + \arg PMU_WAKEUP_PIN1: wakeup pin 1 + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin ) +{ + PMU_CS &= ~wakeup_pin; + +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_rcu.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_rcu.c new file mode 100644 index 0000000..02f13de --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_rcu.c @@ -0,0 +1,1214 @@ +/*! + \file gd32f1x0_rcu.c + \brief RCU driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_rcu.h" + +#define SEL_IRC8M 0x00U +#define SEL_HXTAL 0x01U +#define SEL_PLL 0x02U + +/* define startup timeout count */ +#define OSC_STARTUP_TIMEOUT ((uint32_t)0xFFFFFU) +#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x3FFFFFFU) + +/*! + \brief deinitialize the RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_deinit(void) +{ + /* enable IRC8M */ + RCU_CTL0 |= RCU_CTL0_IRC8MEN; + while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){ + } + /* reset RCU */ +#ifdef GD32F130_150 + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); +#elif defined (GD32F170_190) + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV | RCU_CFG0_PLLDV); +#endif /* GD32F130_150 */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV); +#ifdef GD32F130_150 + RCU_CFG0 &= ~(RCU_CFG0_USBDPSC); +#endif /* GD32F130_150 */ + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS); + RCU_CFG1 &= ~RCU_CFG1_HXTALPREDV; + RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_CECSEL | RCU_CFG2_ADCSEL); +#ifdef GD32F130_150 + RCU_CTL1 &= ~RCU_CTL1_IRC14MEN; +#elif defined (GD32F170_190) + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CTL1 &= ~RCU_CTL1_IRC28MEN; + RCU_CFG3 &= ~RCU_CFG3_CKOUT1SRC; + RCU_CFG3 &= ~RCU_CFG3_CKOUT1DIV; +#endif /* GD32F130_150 */ + RCU_INT = 0x00000000U; +} + +/*! + \brief enable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + \arg RCU_GPIOx (x=A,B,C,D,F): GPIO ports clock + \arg RCU_DMA: DMA clock + \arg RCU_CRC: CRC clock + \arg RCU_TSI: TSI clock + \arg RCU_CFGCMP: CFGCMP clock + \arg RCU_ADC: ADC clock + \arg RCU_TIMERx (x=0,1,2,5,13,14,15,16): TIMER clock + \arg RCU_SPIx (x=0,1,2): SPI clock + \arg RCU_USARTx (x=0,1): USART clock + \arg RCU_SLCD: SLCD clock, only in GD32F170_190 + \arg RCU_WWDGT: WWDGT clock + \arg RCU_I2Cx (x=0,1,2): I2C clock + \arg RCU_USBD: USBD clock, only in GD32F130_150 + \arg RCU_CANx (x=0,1): CAN clock, only in GD32F170_190 + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC clock + \arg RCU_CEC: CEC clock + \arg RCU_OPAIVREF: OPAIVREF clock, only in GD32F170_190 + \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 + \arg RCU_GPIOx (x=A,B,C,D,F): GPIO ports clock + \arg RCU_DMA: DMA clock + \arg RCU_CRC: CRC clock + \arg RCU_TSI: TSI clock + \arg RCU_CFGCMP: CFGCMP clock + \arg RCU_ADC: ADC clock + \arg RCU_TIMERx (x=0,1,2,5,13,14,15,16): TIMER clock + \arg RCU_SPIx (x=0,1,2): SPI clock + \arg RCU_USARTx (x=0,1): USART clock + \arg RCU_SLCD: SLCD clock, only in GD32F170_190 + \arg RCU_WWDGT: WWDGT clock + \arg RCU_I2Cx (x=0,1,2): I2C clock + \arg RCU_USBD: USBD clock only in GD32F130_150 + \arg RCU_CANx (x=0,1): CAN clock, only in GD32F170_190 + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC clock + \arg RCU_CEC: CEC clock + \arg RCU_OPAIVREF: OPAIVREF clock, only in GD32F170_190 + \arg RCU_RTC: RTC clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_disable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief enable the peripherals clock when sleep mode + \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 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 peripherals + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + \arg RCU_GPIOxRST (x=A,B,C,D,F): reset GPIO ports + \arg RCU_TSIRST: reset TSI + \arg RCU_CFGCMPRST: reset CFGCMP + \arg RCU_ADCRST: reset ADC + \arg RCU_TIMERxRST (x=0,1,2,5,13,14,15,16): reset TIMER + \arg RCU_SPIxRST (x=0,1,2): reset SPI + \arg RCU_USARTxRST (x=0,1): reset USART + \arg RCU_SLCDRST: reset SLCD, only in GD32F170_190 + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_I2CxRST (x=0,1,2): reset I2C + \arg RCU_USBDRST: reset USBD, only in GD32F130_150 + \arg RCU_CANxRST (x=0,1): reset CAN, only in GD32F170_190 + \arg RCU_PMURST: reset PMU + \arg RCU_DACRST: reset DAC + \arg RCU_CECRST: reset CEC + \arg RCU_OPAIVREFRST: reset OPAIVREF, only in GD32F170_190 + \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 + \arg RCU_GPIOxRST (x=A,B,C,D,F): reset GPIO ports + \arg RCU_TSIRST: reset TSI + \arg RCU_CFGCMPRST: reset CFGCMP + \arg RCU_ADCRST: reset ADC + \arg RCU_TIMERxRST (x=0,1,2,5,13,14,15,16): reset TIMER + \arg RCU_SPIxRST (x=0,1,2): reset SPI + \arg RCU_USARTxRST (x=0,1): reset USART + \arg RCU_SLCDRST: reset SLCD, only in GD32F170_190 + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_I2CxRST (x=0,1,2): reset I2C + \arg RCU_USBDRST: reset USBD, only in GD32F130_150 + \arg RCU_CANxRST (x=0,1): reset CAN, only in GD32F170_190 + \arg RCU_PMURST: reset PMU + \arg RCU_DACRST: reset DAC + \arg RCU_CECRST: reset CEC + \arg RCU_OPAIVREFRST: reset OPAIVREF, only in GD32F170_190 + \param[out] none + \retval none +*/ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) &= ~BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief reset the BKP domain + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_enable(void) +{ + RCU_BDCTL |= RCU_BDCTL_BKPRST; +} + +/*! + \brief disable the BKP domain 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 + \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 cksys_source = 0U; + cksys_source = RCU_CFG0; + /* reset the SCS bits and set according to ck_sys */ + cksys_source &= ~RCU_CFG0_SCS; + RCU_CFG0 = (ck_sys | cksys_source); +} + +/*! + \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: select CK_IRC8M as the CK_SYS source + \arg RCU_SCSS_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_SCSS_PLL: select CK_PLL as the CK_SYS source +*/ +uint32_t rcu_system_clock_source_get(void) +{ + return (RCU_CFG0 & 0x0000000CU); +} + +/*! + \brief configure the AHB clock prescaler selection + \param[in] ck_ahb: AHB clock prescaler selection + \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 ahbpsc = 0U; + ahbpsc = RCU_CFG0; + /* reset the AHBPSC bits and set according to ck_ahb */ + ahbpsc &= ~RCU_CFG0_AHBPSC; + RCU_CFG0 = (ck_ahb | ahbpsc); +} + +/*! + \brief configure the APB1 clock prescaler selection + \param[in] ck_apb1: APB1 clock prescaler selection + \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 apb1psc = 0U; + apb1psc = RCU_CFG0; + /* reset the APB1PSC and set according to ck_apb1 */ + apb1psc &= ~RCU_CFG0_APB1PSC; + RCU_CFG0 = (ck_apb1 | apb1psc); +} + +/*! + \brief configure the APB2 clock prescaler selection + \param[in] ck_apb2: APB2 clock prescaler selection + \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 apb2psc = 0U; + apb2psc = RCU_CFG0; + /* reset the APB2PSC and set according to ck_apb2 */ + apb2psc &= ~RCU_CFG0_APB2PSC; + RCU_CFG0 = (ck_apb2 | apb2psc); +} + +/*! + \brief configure the ADC clock prescaler selection + \param[in] ck_adc: ADC clock prescaler selection, refer to rcu_adc_clock_enum + \arg RCU_ADCCK_IRC14M: select CK_IRC14M as CK_ADC, only in GD32F130_150 + \arg RCU_ADCCK_IRC28M_DIV2: select CK_IRC28M/2 as CK_ADC, only in GD32F170_190 + \arg RCU_ADCCK_IRC28M: select CK_IRC28M as CK_ADC, only in GD32F170_190 + \arg RCU_ADCCK_APB2_DIV2: select CK_APB2/2 as CK_ADC + \arg RCU_ADCCK_APB2_DIV4: select CK_APB2/4 as CK_ADC + \arg RCU_ADCCK_APB2_DIV6: select CK_APB2/6 as CK_ADC + \arg RCU_ADCCK_APB2_DIV8: select CK_APB2/8 as CK_ADC + \param[out] none + \retval none +*/ +void rcu_adc_clock_config(rcu_adc_clock_enum ck_adc) +{ + /* reset the ADCPSC, ADCSEL, IRC28MDIV bits */ + RCU_CFG0 &= ~RCU_CFG0_ADCPSC; +#ifdef GD32F130_150 + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; +#elif defined (GD32F170_190) + RCU_CFG2 &= ~(RCU_CFG2_ADCSEL | RCU_CFG2_IRC28MDIV); +#endif /* GD32F130_150 */ + /* set the ADC clock according to ck_adc */ + switch(ck_adc){ +#ifdef GD32F130_150 + case RCU_ADCCK_IRC14M: + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; + break; +#elif defined (GD32F170_190) + case RCU_ADCCK_IRC28M_DIV2: + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_IRC28M: + RCU_CFG2 |= RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; + break; +#endif /* GD32F130_150 */ + case RCU_ADCCK_APB2_DIV2: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV4: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV4; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV6: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV6; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV8: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV8; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + default: + break; + } +} + +#ifdef GD32F130_150 +/*! + \brief configure the USBD clock prescaler selection + \param[in] ck_usbd: USBD clock prescaler selection + \arg RCU_USBD_CKPLL_DIV1_5: select CK_PLL/1.5 as CK_USBD + \arg RCU_USBD_CKPLL_DIV1: select CK_PLL as CK_USBD + \arg RCU_USBD_CKPLL_DIV2_5: select CK_PLL/2.5 as CK_USBD + \arg RCU_USBD_CKPLL_DIV2: select CK_PLL/2 as CK_USBD + \param[out] none + \retval none +*/ +void rcu_usbd_clock_config(uint32_t ck_usbd) +{ + /* reset the USBDPSC bits and set according to ck_usbd */ + RCU_CFG0 &= ~RCU_CFG0_USBDPSC; + RCU_CFG0 |= ck_usbd; +} + +/*! + \brief configure the CK_OUT clock source and divider + \param[in] ckout_src: CK_OUT clock source selection + \arg RCU_CKOUTSRC_NONE: no clock selected + \arg RCU_CKOUTSRC_IRC14M: IRC14M selected + \arg RCU_CKOUTSRC_IRC40K: IRC40K selected + \arg RCU_CKOUTSRC_LXTAL: LXTAL selected + \arg RCU_CKOUTSRC_CKSYS: CKSYS selected + \arg RCU_CKOUTSRC_IRC8M: IRC8M 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); +} +#elif defined (GD32F170_190) +/*! + \brief configure the CK_OUT0 clock source and divider + \param[in] ckout0_src: CK_OUT0 clock source selection + \arg RCU_CKOUT0SRC_NONE: no clock selected + \arg RCU_CKOUT0SRC_IRC28M: IRC28M selected + \arg RCU_CKOUT0SRC_IRC40K: IRC40K selected + \arg RCU_CKOUT0SRC_LXTAL: LXTAL selected + \arg RCU_CKOUT0SRC_CKSYS: CKSYS selected + \arg RCU_CKOUT0SRC_IRC8M: IRC8M selected + \arg RCU_CKOUT0SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT0SRC_CKPLL_DIV1: CK_PLL selected + \arg RCU_CKOUT0SRC_CKPLL_DIV2: CK_PLL/2 selected + \param[in] ckout0_div: CK_OUT0 divider + \arg RCU_CKOUT0_DIVx(x=1,2,4,8,16,32,64,128): CK_OUT0 is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div) +{ + uint32_t ckout0 = 0U; + ckout0 = RCU_CFG0; + /* reset the CKOUT0SEL, CKOUT0DIV and PLLDV bits and set according to ckout0_src and ckout0_div */ + ckout0 &= ~(RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV | RCU_CFG0_PLLDV); + RCU_CFG0 = (ckout0 | ckout0_src | ckout0_div); +} + +/*! + \brief configure the CK_OUT1 clock source and divider + \param[in] ckout1_src: CK_OUT1 clock source selection + \arg RCU_CKOUT1SRC_NONE: no clock selected + \arg RCU_CKOUT1SRC_IRC28M: IRC28M selected + \arg RCU_CKOUT1SRC_IRC40K: IRC40K selected + \arg RCU_CKOUT1SRC_LXTAL: LXTAL selected + \arg RCU_CKOUT1SRC_CKSYS: CKSYS selected + \arg RCU_CKOUT1SRC_IRC8M: IRC8M selected + \arg RCU_CKOUT1SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT1SRC_CKPLL_DIV1: CK_PLL selected + \arg RCU_CKOUT1SRC_CKPLL_DIV2: CK_PLL/2 selected + \param[in] ckout1_div: CK_OUT1 divider + \arg RCU_CKOUT1_DIVx(x=1..64): CK_OUT1 is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div) +{ + uint32_t ckout1 = 0U; + ckout1 = RCU_CFG3; + /* reset the CKOUT1SRC, CKOUT1DIV bits and set according to ckout1_src and ckout1_div */ + ckout1 &= ~(RCU_CFG3_CKOUT1SRC | RCU_CFG3_CKOUT1DIV); + if(RCU_CKOUT1SRC_CKPLL_DIV1 == ckout1_src){ + RCU_CFG0 |= RCU_CFG0_PLLDV; + ckout1_src = CFG3_CKOUT1SRC(7); + }else if(RCU_CKOUT1SRC_CKPLL_DIV2 == ckout1_src){ + RCU_CFG0 &= ~RCU_CFG0_PLLDV; + ckout1_src = CFG3_CKOUT1SRC(7); + }else{ + } + RCU_CFG3 = (ckout1 | ckout1_src | ckout1_div); +} +#endif /* GD32F130_150 */ + +/*! + \brief configure the PLL clock source selection and PLL multiply factor + \param[in] pll_src: PLL clock source selection + \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 + \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 |= (pll_src | pll_mul); +} + +/*! + \brief configure the USART clock source selection + \param[in] ck_usart: USART clock source selection + \arg RCU_USART0SRC_CKAPB2: CK_USART0 select CK_APB2 + \arg RCU_USART0SRC_CKSYS: CK_USART0 select CK_SYS + \arg RCU_USART0SRC_LXTAL: CK_USART0 select CK_LXTAL + \arg RCU_USART0SRC_IRC8M: CK_USART0 select CK_IRC8M + \param[out] none + \retval none +*/ +void rcu_usart_clock_config(uint32_t ck_usart) +{ + /* reset the USART0SEL bits and set according to ck_usart */ + RCU_CFG2 &= ~RCU_CFG2_USART0SEL; + RCU_CFG2 |= ck_usart; +} + +/*! + \brief configure the CEC clock source selection + \param[in] ck_cec: CEC clock source selection + \arg RCU_CECSRC_IRC8M_DIV244: CK_CEC select CK_IRC8M/244 + \arg RCU_CECSRC_LXTAL: CK_CEC select CK_LXTAL + \param[out] none + \retval none +*/ +void rcu_cec_clock_config(uint32_t ck_cec) +{ + /* reset the CECSEL bit and set according to ck_cec */ + RCU_CFG2 &= ~RCU_CFG2_CECSEL; + RCU_CFG2 |= ck_cec; +} + +/*! + \brief configure the RTC clock source selection + \param[in] rtc_clock_source: RTC clock source selection + \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_DIV32: CK_HXTAL/32 selected as RTC source clock + \param[out] none + \retval none +*/ +void rcu_rtc_clock_config(uint32_t rtc_clock_source) +{ + /* reset the RTCSRC bits and set according to rtc_clock_source */ + RCU_BDCTL &= ~RCU_BDCTL_RTCSRC; + RCU_BDCTL |= rtc_clock_source; +} + +#ifdef GD32F170_190 +/*! + \brief configure the SLCD clock source selection + \param[in] slcd_clock_source: SLCD clock source selection + \arg RCU_SLCDSRC_NONE: no clock selected + \arg RCU_SLCDSRC_LXTAL: CK_LXTAL selected as SLCD source clock + \arg RCU_SLCDSRC_IRC40K: CK_IRC40K selected as SLCD source clock + \arg RCU_SLCDSRC_HXTAL_DIV32: CK_HXTAL/32 selected as SLCD source clock + \param[out] none + \retval none +*/ +void rcu_slcd_clock_config(uint32_t slcd_clock_source) +{ + /* reset the bits and set according to rtc_clock_source */ + RCU_BDCTL &= ~RCU_BDCTL_RTCSRC; + RCU_BDCTL |= slcd_clock_source; +} +#endif /* GD32F170_190 */ + +/*! + \brief configure the HXTAL divider used as input of PLL + \param[in] hxtal_prediv: HXTAL divider used as input of PLL + \arg RCU_PLL_HXTAL_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 HXTALPREDV bits and set according to hxtal_prediv */ + prediv &= ~RCU_CFG1_HXTALPREDV; + RCU_CFG1 = (prediv | hxtal_prediv); +} + +/*! + \brief configure the LXTAL drive capability + \param[in] lxtal_dricap: drive capability of LXTAL + \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) +{ + /* reset the LXTALDRI bits and set according to lxtal_dricap */ + RCU_BDCTL &= ~RCU_BDCTL_LXTALDRI; + RCU_BDCTL |= lxtal_dricap; +} + +/*! + \brief get the clock stabilization and periphral reset flags + \param[in] flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum + \arg RCU_FLAG_IRC40KSTB: IRC40K stabilization flag + \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag + \arg RCU_FLAG_IRC8MSTB: IRC8M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_PLLSTB: PLL stabilization flag + \arg RCU_FLAG_IRC14MSTB: IRC14M stabilization flag, only in GD32F130_150 + \arg RCU_FLAG_IRC28MSTB: IRC28M stabilization flag, only in GD32F170_190 + \arg RCU_FLAG_V12RST: V12 domain Power reset flag + \arg RCU_FLAG_OBLRST: Option byte loader reset flag + \arg RCU_FLAG_EPRST: External PIN reset flag + \arg RCU_FLAG_PORRST: Power reset flag + \arg RCU_FLAG_SWRST: Software reset flag + \arg RCU_FLAG_FWDGTRST: Free watchdog timer reset flag + \arg RCU_FLAG_WWDGTRST: Window watchdog timer reset flag + \arg RCU_FLAG_LPRST: Low-power reset flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_flag_get(rcu_flag_enum flag) +{ + if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear 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 + \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_IRC14MSTB: IRC14M stabilization interrupt flag, only in GD32F130_150 + \arg RCU_INT_FLAG_IRC28MSTB: IRC28M stabilization interrupt flag, only in GD32F170_190 + \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) +{ + if(RESET != (RCU_INT & int_flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the interrupt flags + \param[in] int_flag_clear: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum + \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_IRC14MSTB_CLR: IRC14M stabilization interrupt flag clear, only in GD32F130_150 + \arg RCU_INT_FLAG_IRC28MSTB_CLR: IRC28M stabilization interrupt flag clear, only in GD32F170_190 + \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear + \param[out] none + \retval none +*/ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear) +{ + RCU_INT |= (uint32_t)int_flag_clear; +} + +/*! + \brief enable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt enable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable + \arg RCU_INT_IRC14MSTB: IRC14M stabilization interrupt enable, only in GD32F130_150 + \arg RCU_INT_IRC28MSTB: IRC28M stabilization interrupt enable, only in GD32F170_190 + \param[out] none + \retval none +*/ +void rcu_interrupt_enable(rcu_int_enum stab_int) +{ + RCU_INT |= (uint32_t)stab_int; +} + + +/*! + \brief disable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt disable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt disable + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt disable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt disable + \arg RCU_INT_IRC14MSTB: IRC14M stabilization interrupt disable, only in GD32F130_150 + \arg RCU_INT_IRC28MSTB: IRC28M stabilization interrupt disable, only in GD32F170_190 + \param[out] none + \retval none +*/ +void rcu_interrupt_disable(rcu_int_enum stab_int) +{ + RCU_INT &= ~(uint32_t)stab_int; +} + +/*! + \brief wait until oscillator stabilization flags is SET or oscillator startup is timeout + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC14M: IRC14M, only in GD32F130_150 + \arg RCU_IRC28M: IRC28M, only in GD32F170_190 + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: 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; +#ifdef GD32F130_150 + /* wait IRC14M stable */ + case RCU_IRC14M: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC14MSTB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC14MSTB)){ + reval = SUCCESS; + } + break; +#elif defined (GD32F170_190) + /* wait IRC28M stable */ + case RCU_IRC28M: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC28MSTB); + stb_cnt++; + } + + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC28MSTB)){ + reval = SUCCESS; + } + break; +#endif /* GD32F130_150 */ + /* 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 + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC14M: IRC14M, only in GD32F130_150 + \arg RCU_IRC28M: IRC28M, only in GD32F170_190 + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: 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 + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC14M: IRC14M, only in GD32F130_150 + \arg RCU_IRC28M: IRC28M, only in GD32F170_190 + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: 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 + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) +{ + uint32_t reg; + switch(osci){ + case RCU_HXTAL: + /* HXTALEN must be reset before enable the oscillator bypass mode */ + reg = RCU_CTL0; + RCU_CTL0 &= ~RCU_CTL0_HXTALEN; + RCU_CTL0 = (reg | RCU_CTL0_HXTALBPS); + break; + case RCU_LXTAL: + /* LXTALEN must be reset before enable the oscillator bypass mode */ + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg | RCU_BDCTL_LXTALBPS); + break; + case RCU_IRC8M: +#ifdef GD32F130_150 + case RCU_IRC14M: +#elif defined (GD32F170_190) + case RCU_IRC28M: +#endif /* GD32F130_150 */ + case RCU_IRC40K: + case RCU_PLL_CK: + break; + default: + break; + } +} + +/*! + \brief disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci) +{ + uint32_t reg; + switch(osci){ + case RCU_HXTAL: + /* HXTALEN must be reset before disable the oscillator bypass mode */ + reg = RCU_CTL0; + RCU_CTL0 &= ~RCU_CTL0_HXTALEN; + RCU_CTL0 = (reg & (~RCU_CTL0_HXTALBPS)); + break; + case RCU_LXTAL: + /* LXTALEN must be reset before disable the oscillator bypass mode */ + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL =(reg & (~RCU_BDCTL_LXTALBPS)); + break; + case RCU_IRC8M: +#ifdef GD32F130_150 + case RCU_IRC14M: +#elif defined (GD32F170_190) + case RCU_IRC28M: +#endif /* GD32F130_150 */ + case RCU_IRC40K: + case RCU_PLL_CK: + break; + default: + break; + } +} + +/*! + \brief enable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ + +void rcu_hxtal_clock_monitor_enable(void) +{ + RCU_CTL0 |= RCU_CTL0_CKMEN; +} + +/*! + \brief disable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_disable(void) +{ + RCU_CTL0 &= ~RCU_CTL0_CKMEN; +} + +/*! + \brief set the IRC8M adjust value + \param[in] irc8m_adjval: IRC8M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc8m_adjust_value_set(uint8_t irc8m_adjval) +{ + uint32_t adjust = 0U; + adjust = RCU_CTL0; + /* reset the IRC8MADJ bits and set according to irc8m_adjval */ + adjust &= ~RCU_CTL0_IRC8MADJ; + RCU_CTL0 = (adjust | ((uint32_t)(irc8m_adjval)<<3)); +} + +#ifdef GD32F130_150 +/*! + \brief set the IRC14M adjust value + \param[in] irc14m_adjval: IRC14M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc14m_adjust_value_set(uint8_t irc14m_adjval) +{ + uint32_t adjust = 0U; + adjust = RCU_CTL1; + /* reset the IRC14MADJ bits and set according to irc14m_adjval */ + adjust &= ~RCU_CTL1_IRC14MADJ; + RCU_CTL1 = (adjust | ((uint32_t)(irc14m_adjval)<<3)); +} +#elif defined (GD32F170_190) +/*! + \brief set the IRC28M adjust value + \param[in] irc28m_adjval: IRC28M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc28m_adjust_value_set(uint8_t irc28m_adjval) +{ + uint32_t adjust = 0U; + adjust = RCU_CTL1; + /* reset the IRC28MADJ bits and set according to irc28m_adjval */ + adjust &= ~RCU_CTL1_IRC28MADJ; + RCU_CTL1 = (adjust | ((uint32_t)(irc28m_adjval)<<3)); +} +#endif /* GD32F130_150 */ + +/*! + \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 set voltage in deep sleep mode + \param[in] dsvol: deep sleep mode voltage + \arg RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V, only in GD32F130_150 + \arg RCU_DEEPSLEEP_V_1_1: the core voltage is 1.1V, only in GD32F130_150 + \arg RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V, only in GD32F130_150 + \arg RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V, only in GD32F130_150 + + \arg RCU_DEEPSLEEP_V_1_8: the core voltage is 1.8V, only in GD32F170_190 + \arg RCU_DEEPSLEEP_V_1_6: the core voltage is 1.6V, only in GD32F170_190 + \arg RCU_DEEPSLEEP_V_1_4: the core voltage is 1.4V, only in GD32F170_190 + \arg RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V, only in GD32F170_190 + \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; +} + +#ifdef GD32F130_150 +/*! + \brief set the power down voltage + \param[in] pdvol: power down voltage select + \arg RCU_PDR_V_2_6: power down voltage is 2.6V + \arg RCU_PDR_V_1_8: power down voltage is 1.8V + \param[out] none + \retval none +*/ +void rcu_power_down_voltage_set(uint32_t pdvol) +{ + /* reset the PDRVS bits and set according to pdvol */ + RCU_PDVSEL &= ~RCU_PDVSEL_PDRVS; + RCU_PDVSEL |= pdvol; +} +#endif /* GD32F130_150 */ + +/*! + \brief get the system clock, bus and peripheral clock frequency + \param[in] clock: the clock frequency which to get + \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_ADC: ADC clock frequency + \arg CK_CEC: CEC clock frequency + \arg CK_USART: USART clock frequency + \param[out] none + \retval clock frequency of system, AHB, APB1, APB2, ADC, CEC or USRAT +*/ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) +{ + uint32_t sws = 0U, adcps = 0U, ck_freq = 0U; + uint32_t cksys_freq = 0U, ahb_freq = 0U, apb1_freq = 0U, apb2_freq = 0U; + uint32_t adc_freq = 0U, cec_freq = 0U, usart_freq = 0U; + uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U; + /* exponent of AHB, APB1 and APB2 clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + const uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + const uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC8M is selected as CK_SYS */ + case SEL_IRC8M: + cksys_freq = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + cksys_freq = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case SEL_PLL: + /* get the value of PLLMF[3:0] */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf4 = GET_BITS(RCU_CFG0, 27, 27); + /* high 16 bits */ + if(1U == pllmf4){ + pllmf += 17U; + }else{ + pllmf += 2U; + } + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = GET_BITS(RCU_CFG0, 16, 16); + if(0U != pllsel){ + prediv = (GET_BITS(RCU_CFG1,0, 3) + 1U); + cksys_freq = (HXTAL_VALUE / prediv) * pllmf; + }else{ + cksys_freq = (IRC8M_VALUE >> 1) * 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_ADC: + /* calculate ADC clock frequency */ + if(RCU_ADCSRC_APB2DIV != (RCU_CFG2 & RCU_CFG2_ADCSEL)){ +#ifdef GD32F130_150 + adc_freq = IRC14M_VALUE; +#elif defined (GD32F170_190) + if(RCU_ADC_IRC28M_DIV1 != (RCU_CFG2 & RCU_CFG2_IRC28MDIV)){ + adc_freq = IRC28M_VALUE >> 1; + }else{ + adc_freq = IRC28M_VALUE; + } +#endif /* GD32F130_150 */ + }else{ + /* ADC clock select CK_APB2 divided by 2/4/6/8 */ + adcps = GET_BITS(RCU_CFG0, 14, 15); + switch(adcps){ + case 0: + adc_freq = apb2_freq / 2U; + break; + case 1: + adc_freq = apb2_freq / 4U; + break; + case 2: + adc_freq = apb2_freq / 6U; + break; + case 3: + adc_freq = apb2_freq / 8U; + break; + default: + break; + } + } + ck_freq = adc_freq; + break; + case CK_CEC: + /* calculate CEC clock frequency */ + if(RCU_CECSRC_LXTAL != (RCU_CFG2 & RCU_CFG2_CECSEL)){ + cec_freq = IRC8M_VALUE / 244U; + }else{ + cec_freq = LXTAL_VALUE; + } + ck_freq = cec_freq; + break; + case CK_USART: + /* calculate USART clock frequency */ + if(RCU_USART0SRC_CKAPB2 == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = apb2_freq; + }else if(RCU_USART0SRC_CKSYS == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = cksys_freq; + }else if(RCU_USART0SRC_LXTAL == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = LXTAL_VALUE; + }else if(RCU_USART0SRC_IRC8M == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = IRC8M_VALUE; + }else{ + } + ck_freq = usart_freq; + break; + default: + break; + } + return ck_freq; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_rtc.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_rtc.c new file mode 100644 index 0000000..63ac1f5 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_rtc.c @@ -0,0 +1,930 @@ +/*! + \file gd32f1x0_rtc.c + \brief RTC driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_rtc.h" + +/*! + \brief reset most of the RTC registers + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_deinit(void) +{ + ErrStatus error_status = ERROR; + + /* RTC_TAMP register is not under write protection */ + RTC_TAMP = RTC_REGISTER_RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* reset RTC_CTL register, this can be done without the init mode */ + RTC_CTL &= RTC_REGISTER_RESET; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition. + in order to read calendar from shadow register, not the real registers being reset */ + RTC_TIME = RTC_REGISTER_RESET; + RTC_DATE = RTC_DATE_RESET; + + RTC_PSC = RTC_PSC_RESET; + + /* reset RTC_STAT register, also exit init mode. + at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */ + RTC_STAT = RTC_STAT_RESET; + + /* to write RTC_ALRM0SS register, ALRM0EN bit in RTC_CTL register should be reset as the condition */ + RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM0SS = RTC_REGISTER_RESET; + + /* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */ + RTC_SHIFTCTL = RTC_REGISTER_RESET; + RTC_HRFC = RTC_REGISTER_RESET; + + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief initialize RTC registers + \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + rtc_year: 0x0 - 0x99(BCD format) + rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_date: 0x1 - 0x31(BCD format) + rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose + rtc_minute: 0x0 - 0x59(BCD format) + rtc_second: 0x0 - 0x59(BCD format) + rtc_factor_asyn: 0x0 - 0x7F + rtc_factor_syn: 0x0 - 0x7FFF + rtc_am_pm: RTC_AM, RTC_PM + rtc_display_format: RTC_24HOUR, RTC_12HOUR + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct) +{ + ErrStatus error_status = ERROR; + uint32_t reg_time = 0U, reg_date = 0U; + + reg_date = (DATE_YR(rtc_initpara_struct->rtc_year) | \ + DATE_DOW(rtc_initpara_struct->rtc_day_of_week) | \ + DATE_MON(rtc_initpara_struct->rtc_month) | \ + DATE_DAY(rtc_initpara_struct->rtc_date)); + + reg_time = (rtc_initpara_struct->rtc_am_pm| \ + TIME_HR(rtc_initpara_struct->rtc_hour) | \ + TIME_MN(rtc_initpara_struct->rtc_minute) | \ + TIME_SC(rtc_initpara_struct->rtc_second)); + + /* 1st: disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* 2nd: enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->rtc_factor_asyn)| \ + PSC_FACTOR_S(rtc_initpara_struct->rtc_factor_syn)); + + RTC_TIME = (uint32_t)reg_time; + RTC_DATE = (uint32_t)reg_date; + + RTC_CTL &= (uint32_t)(~RTC_CTL_CS); + RTC_CTL |= rtc_initpara_struct->rtc_display_format; + + /* 3rd: exit init mode */ + rtc_init_mode_exit(); + + /* 4th: wait the RSYNF flag to set */ + error_status = rtc_register_sync_wait(); + } + + /* 5th: enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enter RTC init mode + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init_mode_enter(void) +{ + uint32_t time_index = RTC_INITM_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + /* check whether it has been in init mode */ + if ((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){ + RTC_STAT |= RTC_STAT_INITM; + + /* wait until the INITF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_INITF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + }else{ + error_status = SUCCESS; + } + return error_status; +} + +/*! + \brief exit RTC init mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_init_mode_exit(void) +{ + RTC_STAT &= (uint32_t)(~RTC_STAT_INITM); +} + +/*! + \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow + registers are updated + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_register_sync_wait(void) +{ + volatile uint32_t time_index = RTC_RSYNF_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + if ((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* firstly clear RSYNF flag */ + RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF); + + /* wait until RSYNF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_RSYNF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + }else{ + error_status = SUCCESS; + } + + return error_status; +} + +/*! + \brief get current time and date + \param[in] none + \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + rtc_year: 0x0 - 0x99(BCD format) + rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_date: 0x1 - 0x31(BCD format) + rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose + rtc_minute: 0x0 - 0x59(BCD format) + rtc_second: 0x0 - 0x59(BCD format) + rtc_factor_asyn: 0x0 - 0x7F + rtc_factor_syn: 0x0 - 0x7FFF + rtc_am_pm: RTC_AM, RTC_PM + rtc_display_format: RTC_24HOUR, RTC_12HOUR + \retval none +*/ +void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct) +{ + uint32_t temp_tr = 0U, temp_dr = 0U, temp_pscr = 0U, temp_ctlr = 0U; + + temp_tr = (uint32_t)RTC_TIME; + temp_dr = (uint32_t)RTC_DATE; + temp_pscr = (uint32_t)RTC_PSC; + temp_ctlr = (uint32_t)RTC_CTL; + + /* get current time and construct rtc_parameter_struct structure */ + rtc_initpara_struct->rtc_year = (uint8_t)GET_DATE_YR(temp_dr); + rtc_initpara_struct->rtc_month = (uint8_t)GET_DATE_MON(temp_dr); + rtc_initpara_struct->rtc_date = (uint8_t)GET_DATE_DAY(temp_dr); + rtc_initpara_struct->rtc_day_of_week = (uint8_t)GET_DATE_DOW(temp_dr); + rtc_initpara_struct->rtc_hour = (uint8_t)GET_TIME_HR(temp_tr); + rtc_initpara_struct->rtc_minute = (uint8_t)GET_TIME_MN(temp_tr); + rtc_initpara_struct->rtc_second = (uint8_t)GET_TIME_SC(temp_tr); + rtc_initpara_struct->rtc_factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr); + rtc_initpara_struct->rtc_factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr); + rtc_initpara_struct->rtc_am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM); + rtc_initpara_struct->rtc_display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS); +} + +/*! + \brief get current subsecond value + \param[in] none + \param[out] none + \retval current subsecond value +*/ +uint32_t rtc_subsecond_get(void) +{ + uint32_t reg = 0U; + /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */ + reg = (uint32_t)RTC_SS; + /* read RTC_DATE to unlock the 3 shadow registers */ + (void) (RTC_DATE); + + return reg; +} + +/*! + \brief configure RTC alarm + \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_alarm_minute: 0x0 - 0x59(BCD format) + rtc_alarm_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \param[out] none + \retval none +*/ +void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time) +{ + uint32_t reg_alrm0td = 0U; + + reg_alrm0td = (rtc_alarm_time->rtc_alarm_mask | \ + rtc_alarm_time->rtc_weekday_or_date | \ + rtc_alarm_time->rtc_am_pm | \ + ALRM0TD_DAY(rtc_alarm_time->rtc_alarm_day) | \ + ALRM0TD_HR(rtc_alarm_time->rtc_alarm_hour) | \ + ALRM0TD_MN(rtc_alarm_time->rtc_alarm_minute) | \ + ALRM0TD_SC(rtc_alarm_time->rtc_alarm_second)); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_ALRM0TD = (uint32_t)reg_alrm0td; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure subsecond of RTC alarm + \param[in] mask_subsecond: alarm subsecond mask + \arg RTC_MASKSSC_0_14: mask alarm subsecond configuration + \arg RTC_MASKSSC_1_14: mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared + \arg RTC_MASKSSC_2_14: mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared + \arg RTC_MASKSSC_3_14: mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared + \arg RTC_MASKSSC_4_14: mask RTC_ALRM0SS_SSC[14:4]], and RTC_ALRM0SS_SSC[3:0] is to be compared + \arg RTC_MASKSSC_5_14: mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared + \arg RTC_MASKSSC_6_14: mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared + \arg RTC_MASKSSC_7_14: mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared + \arg RTC_MASKSSC_8_14: mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared + \arg RTC_MASKSSC_9_14: mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared + \arg RTC_MASKSSC_10_14: mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared + \arg RTC_MASKSSC_11_14: mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared + \arg RTC_MASKSSC_12_14: mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared + \arg RTC_MASKSSC_13_14: mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared + \arg RTC_MASKSSC_14: mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared + \arg RTC_MASKSSC_NONE: mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared + \param[in] subsecond: alarm subsecond value(0x000 - 0x7FFF) + \param[out] none + \retval none +*/ +void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_ALRM0SS = mask_subsecond | subsecond; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC alarm + \param[in] none + \param[out] none + \retval none +*/ +void rtc_alarm_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= RTC_CTL_ALRM0EN; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC alarm + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_alarm_disable(void) +{ + volatile uint32_t time_index = RTC_ALRM0WF_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the state of alarm */ + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN); + + /* wait until ALRM0WF flag to be set after the alarm is disabled */ + do{ + flag_status = RTC_STAT & RTC_STAT_ALRM0WF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief get RTC alarm + \param[in] none + \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_alarm_minute: 0x0 - 0x59(BCD format) + rtc_alarm_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time) +{ + uint32_t reg_alrm0td = 0U; + + /* get the value of RTC_ALRM0TD register */ + reg_alrm0td = RTC_ALRM0TD; + + /* get alarm parameters and construct the rtc_alarm_struct structure */ + rtc_alarm_time->rtc_alarm_mask = reg_alrm0td & RTC_ALARM_ALL_MASK; + rtc_alarm_time->rtc_am_pm = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_PM); + rtc_alarm_time->rtc_weekday_or_date = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_DOWS); + rtc_alarm_time->rtc_alarm_day = (uint8_t)GET_ALRM0TD_DAY(reg_alrm0td); + rtc_alarm_time->rtc_alarm_hour = (uint8_t)GET_ALRM0TD_HR(reg_alrm0td); + rtc_alarm_time->rtc_alarm_minute = (uint8_t)GET_ALRM0TD_MN(reg_alrm0td); + rtc_alarm_time->rtc_alarm_second = (uint8_t)GET_ALRM0TD_SC(reg_alrm0td); +} + +/*! + \brief get RTC alarm subsecond + \param[in] none + \param[out] none + \retval RTC alarm subsecond value +*/ +uint32_t rtc_alarm_subsecond_get(void) +{ + return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC)); +} + +/*! + \brief enable RTC time-stamp + \param[in] edge: specify which edge to detect of time-stamp + \arg RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event + \arg RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event + \param[out] none + \retval none +*/ +void rtc_timestamp_enable(uint32_t edge) +{ + uint32_t reg_ctl = 0U; + + /* clear the bits to be configured in RTC_CTL */ + reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN))); + + /* new configuration */ + reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL = (uint32_t)reg_ctl; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC time-stamp + \param[in] none + \param[out] none + \retval none +*/ +void rtc_timestamp_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the TSEN bit */ + RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief get RTC timestamp time and date + \param[in] none + \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains + parameters for RTC time-stamp configuration + members of the structure and the member values are shown as below: + rtc_timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_timestamp_date: 0x1 - 0x31(BCD format) + rtc_timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_timestamp_minute: 0x0 - 0x59(BCD format) + rtc_timestamp_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp) +{ + uint32_t temp_tts = 0U, temp_dts = 0U; + + /* get the value of time_stamp registers */ + temp_tts = (uint32_t)RTC_TTS; + temp_dts = (uint32_t)RTC_DTS; + + /* get timestamp time and construct the rtc_timestamp_struct structure */ + rtc_timestamp->rtc_am_pm = (uint32_t)(temp_tts & RTC_TTS_PM); + rtc_timestamp->rtc_timestamp_month = (uint8_t)GET_DTS_MON(temp_dts); + rtc_timestamp->rtc_timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts); + rtc_timestamp->rtc_timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts); + rtc_timestamp->rtc_timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts); + rtc_timestamp->rtc_timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts); + rtc_timestamp->rtc_timestamp_second = (uint8_t)GET_TTS_SC(temp_tts); +} + +/*! + \brief get RTC time-stamp subsecond + \param[in] none + \param[out] none + \retval RTC time-stamp subsecond value +*/ +uint32_t rtc_timestamp_subsecond_get(void) +{ + return ((uint32_t)RTC_SSTS); +} + +/*! + \brief enable RTC tamper + \param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains + parameters for RTC tamper configuration + members of the structure and the member values are shown as below: + rtc_tamper_source: RTC_TAMPER0, RTC_TAMPER1 + rtc_tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING + RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH + rtc_tamper_filter: RTC_FLT_EDGE, RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S + rtc_tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192, + RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024, + RTC_FREQ_DIV512, RTC_FREQ_DIV256 + rtc_tamper_precharge_enable: DISABLE, ENABLE + rtc_tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C + rtc_tamper_with_timestamp: DISABLE, ENABLE + \param[out] none + \retval none +*/ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~(rtc_tamper->rtc_tamper_source); + + /* tamper filter must be used when the tamper source is voltage level detection */ + RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT; + + /* the tamper source is voltage level detection */ + if(rtc_tamper->rtc_tamper_filter != RTC_FLT_EDGE ){ + RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT); + + /* check if the tamper pin need precharge, if need, then configure the precharge time */ + if(DISABLE == rtc_tamper->rtc_tamper_precharge_enable){ + RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU; + }else{ + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_precharge_time); + } + + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_sample_frequency); + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_filter); + } + + RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS; + + if(DISABLE != rtc_tamper->rtc_tamper_with_timestamp){ + /* the tamper event also cause a time-stamp event */ + RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS; + } + + /* configure the tamper trigger */ + RTC_TAMP &= ((uint32_t)~((rtc_tamper->rtc_tamper_source) << RTC_TAMPER_TRIGGER_POS)); + if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->rtc_tamper_trigger){ + RTC_TAMP |= (uint32_t)((rtc_tamper->rtc_tamper_source)<< RTC_TAMPER_TRIGGER_POS); + } + /* enable tamper */ + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_source); +} + +/*! + \brief disable RTC tamper + \param[in] source: specify which tamper source to be disabled + \arg RTC_TAMPER0 + \arg RTC_TAMPER1 + \param[out] none + \retval none +*/ +void rtc_tamper_disable(uint32_t source) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~source; + +} + +/*! + \brief enable specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be enabled + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_TAMP: tamp interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_enable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enable the interrupts in RTC_CTL register */ + RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE); + /* enable the interrupts in RTC_TAMP register */ + RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disble specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be disabled + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_TAMP: tamp interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_disable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* disable the interrupts in RTC_CTL register */ + RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE); + /* disable the interrupts in RTC_TAMP register */ + RTC_TAMP &= (uint32_t)~(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief check specified flag + \param[in] flag: specify which flag to check + \arg RTC_FLAG_RECALIBRATION: recalibration pending flag + \arg RTC_FLAG_TAMP1: tamper 1 event flag + \arg RTC_FLAG_TAMP0: tamper 0 event flag + \arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag + \arg RTC_FLAG_TIMESTAMP: time-stamp event flag + \arg RTC_FLAG_ALARM0: alarm event flag + \arg RTC_FLAG_INIT: init mode event flag + \arg RTC_FLAG_RSYN: time and date registers synchronized event flag + \arg RTC_FLAG_YCM: year parameter configured event flag + \arg RTC_FLAG_SHIFT: shift operation pending flag + \arg RTC_FLAG_ALARM0_WRITTEN: alarm writen available flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rtc_flag_get(uint32_t flag) +{ + FlagStatus flag_state = RESET; + + if ((uint32_t)RESET != (RTC_STAT & flag)){ + flag_state = SET; + } + return flag_state; +} + +/*! + \brief clear specified flag + \param[in] flag: specify which flag to clear + \arg RTC_FLAG_TAMP1: tamper 1 event flag + \arg RTC_FLAG_TAMP0: tamper 0 event flag + \arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag + \arg RTC_FLAG_TIMESTAMP: time-stamp event flag + \arg RTC_FLAG_ALARM0: alarm event flag + \arg RTC_FLAG_RSYN: time and date registers synchronized event flag + \param[out] none + \retval none +*/ +void rtc_flag_clear(uint32_t flag) +{ + RTC_STAT &= (uint32_t)(~flag); +} + +/*! + \brief configure rtc alternate output source + \param[in] source: specify signal to output + \arg RTC_CALIBRATION_512HZ: when the LXTAL freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \arg RTC_CALIBRATION_1HZ: when the LXTAL freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \arg RTC_ALARM_HIGH: when the alarm flag is set, the output pin is high + \arg RTC_ALARM_LOW: when the Alarm flag is set, the output pin is low + \param[in] mode: specify the output pin (PC13) mode when output alarm signal + \arg RTC_ALARM_OUTPUT_OD: open drain mode + \arg RTC_ALARM_OUTPUT_PP: push pull mode + \param[out] none + \retval none +*/ +void rtc_alter_output_config(uint32_t source, uint32_t mode) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_OS | RTC_CTL_OPOL | RTC_CTL_COS); + + RTC_CTL |= (uint32_t)(source); + + /* alarm output */ + if((uint32_t)RESET != (source & RTC_OS_ENABLE)){ + RTC_TAMP &= (uint32_t)~(RTC_TAMP_PC13VAL); + RTC_TAMP |= (uint32_t)(mode); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief ajust the daylight saving time by adding or substracting one hour from the current time + \param[in] operation: hour ajustment operation + \arg RTC_CTL_A1H: add one hour + \arg RTC_CTL_S1H: substract one hour + \param[out] none + \retval none +*/ +void rtc_hour_adjust(uint32_t operation) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint32_t)(operation); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint8_t)RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint8_t)~RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_enable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL |= (uint32_t)RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief disable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_disable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL &= (uint32_t)~RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief ajust RTC second or subsecond value of current time + \param[in] add: add 1s to current time or not + \arg RTC_SHIFT_ADD1S_RESET: no effect + \arg RTC_SHIFT_ADD1S_SET: add 1s to current time + \param[in] minus: number of subsecond to minus from current time(0x0 - 0x7FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_second_ajust(uint32_t add, uint32_t minus) +{ + uint32_t time_index = RTC_SHIFTCTL_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + uint32_t temp=0U; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a shift operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SOPF; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + temp = RTC_CTL & RTC_CTL_REFEN; + /* check if the function of reference clock detection is disabled */ + if(((uint32_t)RESET == flag_status) && (RESET == temp)){ + RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus)); + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief configure RTC calibration register + \param[in] window: select calibration window + \arg RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz + \param[in] plus: add RTC clock or not + \arg RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock + \arg RTC_CALIBRATION_PLUS_RESET: no effect + \param[in] minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus) +{ + uint32_t time_index = RTC_HRFC_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a calibration operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SCPF; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + if((uint32_t)RESET == flag_status){ + RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus)); + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_slcd.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_slcd.c new file mode 100644 index 0000000..232683c --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_slcd.c @@ -0,0 +1,445 @@ +/*! + \file gd32f1x0_slcd.c + \brief SLCD driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#ifdef GD32F170_190 +#include "gd32f1x0_slcd.h" +#include "gd32f1x0_rcu.h" + +/*! + \brief SLCD reset + \param[in] none + \param[out] none + \retval none +*/ +void slcd_deinit(void) +{ + rcu_periph_reset_enable(RCU_SLCDRST); + rcu_periph_reset_disable(RCU_SLCDRST); +} + +/*! + \brief get the SLCD status flag + \param[in] slcd_flag: the adc status flag bits + \arg SLCD_FLAG_ON: SLCD controller on flag + \arg SLCD_FLAG_SOF: start of frame flag + \arg SLCD_FLAG_UPR: SLCD data update request flag + \arg SLCD_FLAG_UPD: update LCDS data done flag + \arg SLCD_FLAG_VRDY: SLCD voltage ready flag + \arg SLCD_FLAG_SYN: SLCD CFG register synchronization flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus slcd_flag_get(uint8_t slcd_flag) +{ + if(SLCD_STAT & slcd_flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get the SLCD interrupt flag + \param[in] slcd_interrupt: the adc interrupt flag bits + \arg SLCD_INT_FLAG_SOF: start of frame interrupt + \arg SLCD_INT_FLAG_UPD: SLCD update done interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus slcd_interrupt_flag_get(uint8_t slcd_interrupt) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + /* check the interrupt bits */ + switch(slcd_interrupt){ + case SLCD_INT_FLAG_SOF: + state = SLCD_STAT & SLCD_FLAG_SOF; + if((SLCD_CFG & SLCD_CFG_SOFIE) && state){ + interrupt_flag = SET; + } + break; + case SLCD_INT_FLAG_UPD: + state = SLCD_STAT & SLCD_FLAG_UPD; + if((SLCD_CFG & SLCD_CFG_UPDIE) && state){ + interrupt_flag = SET; + } + break; + default: + break; + } + return interrupt_flag; +} + +/*! + \brief clear the SLCD flag + \param[in] slcd_flag: the adc status flag bits + \arg SLCD_FLAG_SOF: start of frame flag + \arg SLCD_FLAG_UPD: update LCDS data done flag + \param[out] none + \retval none +*/ +void slcd_flag_clear(uint8_t slcd_flag) +{ + /* check the interrupt bits */ + switch(slcd_flag){ + case SLCD_FLAG_SOF: + SLCD_STATC |= SLCD_STATC_SOFC; + break; + case SLCD_FLAG_UPD: + SLCD_STATC |= SLCD_STATC_UPDC; + break; + default: + break; + } +} + +/*! + \brief clear the SLCD interrupt flag + \param[in] slcd_interrupt: the adc interrupt bits + \arg SLCD_INT_FLAG_SOF: start of frame interrupt + \arg SLCD_INT_FLAG_UPD: SLCD update done interrupt + \param[out] none + \retval none +*/ +void slcd_interrupt_flag_clear(uint8_t slcd_interrupt) +{ + /* check the interrupt bits */ + switch(slcd_interrupt){ + case SLCD_INT_FLAG_SOF: + SLCD_STATC |= SLCD_STATC_SOFC; + break; + case SLCD_INT_FLAG_UPD: + SLCD_STATC |= SLCD_STATC_UPDC; + break; + default: + break; + } +} + +/*! + \brief the SLCD interrupt config + \param[in] slcd_interrupt: the adc interrupt bits + \arg SLCD_INT_SOF: start of frame interrupt + \arg SLCD_INT_UPD: SLCD update done interrupt + \param[out] none + \retval none +*/ +void slcd_interrupt_config(uint8_t slcd_interrupt,ControlStatus newvalue) +{ + /* ENABLE or DISABLE the interrupt */ + if(newvalue){ + /* select the interrupt source */ + switch(slcd_interrupt){ + case SLCD_INT_SOF: + SLCD_CFG |= (uint32_t) SLCD_CFG_SOFIE; + break; + case SLCD_INT_UPD: + SLCD_CFG |= (uint32_t) SLCD_CFG_UPDIE; + break; + default: + break; + } + }else{ + switch(slcd_interrupt){ + /* select the interrupt source */ + case SLCD_INT_SOF: + SLCD_CFG &= (uint32_t)~(SLCD_CFG_SOFIE); + break; + case SLCD_INT_UPD: + SLCD_CFG &= (uint32_t)~(SLCD_CFG_UPDIE); + break; + default: + break; + } + } +} + +/*! + \brief SLCD bias voltage select + \param[in] bias_voltage: the SLCD voltage bias + \arg SLCD_BIAS_1_4: 1/4 voltage bias + \arg SLCD_BIAS_1_2: 1/2 voltage bias + \arg SLCD_BIAS_1_3: 1/3 voltage bias + \param[out] none + \retval none +*/ +void slcd_bias_voltage_select(uint32_t bias_voltage) +{ + SLCD_CTL &= (uint32_t)~(SLCD_CTL_BIAS); + SLCD_CTL |= (uint32_t)bias_voltage; +} + +/*! + \brief SLCD duty cycle select + \param[in] duty: the adc flag bits + \arg SLCD_DUTY_STATIC: static dutycycle + \arg SLCD_DUTY_1_2: 1/2 dutycycle + \arg SLCD_DUTY_1_3: 1/3 dutycycle + \arg SLCD_DUTY_1_4: 1/4 dutycycle + \arg SLCD_DUTY_1_6: 1/6 dutycycle + \arg SLCD_DUTY_1_8: 1/8 dutycycle + \param[out] none + \retval none +*/ +void slcd_duty_select(uint32_t duty) +{ + SLCD_CTL &= (uint32_t)~(SLCD_CTL_DUTY); + SLCD_CTL |= (uint32_t)duty; +} + +/*! + \brief config the prescaler and the divider of SLCD clock + fSLCD = finclk/( pow( 2 , PRE )* DIV ) + \param[in] prescaler: the prescaler factor + \arg SLCD_PRESCALER_1: PRE = 0 + \arg SLCD_PRESCALER_2: PRE = 1 + \arg SLCD_PRESCALER_4: PRE = 2 + \arg SLCD_PRESCALER_8: PRE = 3 + \arg SLCD_PRESCALER_16: PRE = 4 + \arg SLCD_PRESCALER_32: PRE = 5 + \arg SLCD_PRESCALER_64: PRE = 6 + \arg SLCD_PRESCALER_128: PRE = 7 + \arg SLCD_PRESCALER_256: PRE = 8 + \arg SLCD_PRESCALER_512: PRE = 9 + \arg SLCD_PRESCALER_1024: PRE = 10 + \arg SLCD_PRESCALER_2048: PRE = 11 + \arg SLCD_PRESCALER_4096: PRE = 12 + \arg SLCD_PRESCALER_8192: PRE = 13 + \arg SLCD_PRESCALER_16384: PRE = 14 + \arg SLCD_PRESCALER_32768: PRE = 15 + \param[in] divider: the divider factor + \arg SLCD_DIVIDER_x: x= 16..31 ,DIV = 16..31 + \param[out] none + \retval none +*/ +void slcd_clock_config(uint32_t prescaler,uint32_t divider) +{ + uint32_t cfg; + + /* config the prescaler and the divider */ + cfg = SLCD_CFG; + cfg &= (uint32_t)~(SLCD_CFG_PSC | SLCD_CFG_DIV); + cfg |= (uint32_t)(prescaler | divider); + SLCD_CFG = cfg; +} + +/*! + \brief SLCD blink mode config + \param[in] mode: the prescaler factor + \arg SLCD_BLINKMODE_OFF: blink disabled + \arg SLCD_BLINKMODE_SEG0_COM0: blink enabled on SEG[0], COM[0] + \arg SLCD_BLINKMODE_SEG0_ALLCOM: blink enabled on SEG[0], all COM + \arg SLCD_BLINKMODE_ALLSEG_ALLCOM: blink enabled on all SEG and all COM + \param[in] blink_divider: the divider factor + \arg SLCD_BLINK_FREQUENCY_DIV8: blink frequency = fSLCD/8 + \arg SLCD_BLINK_FREQUENCY_DIV16: blink frequency = fSLCD/16 + \arg SLCD_BLINK_FREQUENCY_DIV32: blink frequency = fSLCD/32 + \arg SLCD_BLINK_FREQUENCY_DIV64: blink frequency = fSLCD/64 + \arg SLCD_BLINK_FREQUENCY_DIV128: blink frequency = fSLCD/128 + \arg SLCD_BLINK_FREQUENCY_DIV256: blink frequency = fSLCD/256 + \arg SLCD_BLINK_FREQUENCY_DIV512: blink frequency = fSLCD/512 + \arg SLCD_BLINK_FREQUENCY_DIV1024: blink frequency = fSLCD/1024 + \param[out] none + \retval none +*/ +void slcd_blink_mode_config(uint32_t mode,uint32_t blink_divider) +{ + SLCD_CFG &= (uint32_t)~(SLCD_CFG_BLKMOD | SLCD_CFG_BLKDIV); + SLCD_CFG |= (uint32_t)(mode | blink_divider); +} + +/*! + \brief SLCD contrast ratio config + \param[in] contrast_ratio: specify the VSLCD voltage ,when chosing the internal voltage source + \arg SLCD_CONTRAST_LEVEL_0: maximum SLCD Voltage = 2.60V + \arg SLCD_CONTRAST_LEVEL_1: maximum SLCD Voltage = 2.73V + \arg SLCD_CONTRAST_LEVEL_2: maximum SLCD Voltage = 2.86V + \arg SLCD_CONTRAST_LEVEL_3: maximum SLCD Voltage = 2.99V + \arg SLCD_CONTRAST_LEVEL_4: maximum SLCD Voltage = 3.12V + \arg SLCD_CONTRAST_LEVEL_5: maximum SLCD Voltage = 3.25V + \arg SLCD_CONTRAST_LEVEL_6: maximum SLCD Voltage = 3.38V + \arg SLCD_CONTRAST_LEVEL_7: maximum SLCD Voltage = 3.51V + \param[out] none + \retval none +*/ +void slcd_contrast_ratio_config(uint32_t contrast_ratio) +{ + uint32_t cfg; + + /* config the contrast ratio */ + cfg = SLCD_CFG; + cfg &= (uint32_t)~(SLCD_CFG_CONR); + cfg |= (uint32_t)contrast_ratio; + SLCD_CFG = cfg; +} + +/*! + \brief SLCD dead time duration config + \param[in] dead_time: configure the length of the dead time between frames + \arg SLCD_DEADTIME_PERIOD_0: no dead time + \arg SLCD_DEADTIME_PERIOD_1: 1 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_2: 2 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_3: 3 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_4: 4 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_5: 5 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_6: 6 phase inserted between couple of frame + \arg SLCD_DEADTIME_PERIOD_7: 7 phase inserted between couple of frame + \param[out] none + \retval none +*/ +void slcd_dead_time_config(uint32_t dead_time) +{ + uint32_t cfg; + + /* config dead time duration */ + cfg = SLCD_CFG; + cfg &= (uint32_t)~(SLCD_CFG_DTD); + cfg |= (uint32_t)dead_time; + SLCD_CFG = cfg; +} + +/*! + \brief SLCD pulse on duration config + \param[in] duration: configure the length of the dead time between frames + \arg SLCD_PULSEON_DURATION_0: pulse on duration = 0 + \arg SLCD_PULSEON_DURATION_1: pulse on duration = 1*1/fPRE + \arg SLCD_PULSEON_DURATION_2: pulse on duration = 2*1/fPRE + \arg SLCD_PULSEON_DURATION_3: pulse on duration = 3*1/fPRE + \arg SLCD_PULSEON_DURATION_4: pulse on duration = 4*1/fPRE + \arg SLCD_PULSEON_DURATION_5: pulse on duration = 5*1/fPRE + \arg SLCD_PULSEON_DURATION_6: pulse on duration = 6*1/fPRE + \arg SLCD_PULSEON_DURATION_7: pulse on duration = 7*1/fPRE + \param[out] none + \retval none +*/ +void slcd_pulse_on_duration_config(uint32_t duration) +{ + uint32_t cfg; + + /* config pulse on duration */ + cfg = SLCD_CFG; + cfg &= (uint32_t)~(SLCD_CFG_PULSE); + cfg |= (uint32_t)duration; + SLCD_CFG = cfg; +} + +/*! + \brief SLCD common/segment pad select + \param[in] NewValue: ENABLE or DISABLE + \arg ENABLE: LCD_COM[7:4] pad select LCD_SEG[31:28] + \arg DISABLE: LCD_COM[7:4] pad select LCD_COM[7:4] + \param[out] none + \retval none +*/ +void slcd_com_seg_remap(ControlStatus newvalue) +{ + if( ENABLE == newvalue ){ + SLCD_CTL |= SLCD_CTL_COMS; + }else{ + SLCD_CTL &= ~(SLCD_CTL_COMS); + } +} + +/*! + \brief SLCD voltage source select + \param[in] voltage_source: the SLCD voltage source + \arg SLCD_VOLTAGE_INTERNAL: internal source + \arg SLCD_VOLTAGE_EXTERNAL: external source (VSLCD pin) + \param[out] none + \retval none +*/ +void slcd_voltage_source_select(uint8_t voltage_source) +{ + if( SLCD_VOLTAGE_EXTERNAL == voltage_source ){ + SLCD_CTL |= SLCD_CTL_VSRC; + }else{ + SLCD_CTL &= ~(SLCD_CTL_VSRC); + } +} + +/*! + \brief enable or disable permanent high drive + \param[in] NewValue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void slcd_high_drive_config(ControlStatus newvalue) +{ + if( ENABLE == newvalue ){ + SLCD_CFG |= SLCD_CFG_HDEN; + }else{ + SLCD_CFG &= ~(SLCD_CFG_HDEN); + } +} + +/*! + \brief SLCD voltage source select + \param[in] data_reg: the SLCD data register + \arg SLCD_DATA_REG0: SLCD_DATA register 0 + \arg SLCD_DATA_REG1: SLCD_DATA Register 1 + \arg SLCD_DATA_REG2: SLCD_DATA register 2 + \arg SLCD_DATA_REG3: SLCD_DATA Register 3 + \arg SLCD_DATA_REG4: SLCD_DATA register 4 + \arg SLCD_DATA_REG5: SLCD_DATA Register 5 + \arg SLCD_DATA_REG6: SLCD_DATA register 6 + \arg SLCD_DATA_REG7: SLCD_DATA Register 7 + \param[in] data: the data write to the register + \param[out] none + \retval none +*/ +void slcd_data_register_write(uint32_t data_reg,uint32_t data) +{ + volatile uint32_t *pdata; + + /* point to DATA register */ + pdata = &SLCD_DATA0; + + /* wtite data word to DATA register */ + *(pdata + data_reg) = (uint32_t)data; +} + +/*! + \brief SLCD data update request + \param[in] none + \param[out] none + \retval none +*/ +void slcd_data_update_request(void) +{ + SLCD_STAT |= SLCD_STAT_UPRF; +} + +/*! + \brief enable SLCD interface + \param[in] none + \param[out] none + \retval none +*/ +void slcd_enable(void) +{ + SLCD_CTL |= SLCD_CTL_LCDON; +} + +/*! + \brief disable SLCD interface + \param[in] none + \param[out] none + \retval none +*/ +void slcd_disable(void) +{ + SLCD_CTL &= ~(SLCD_CTL_LCDON); +} + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_spi.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_spi.c new file mode 100644 index 0000000..356e342 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_spi.c @@ -0,0 +1,679 @@ +/*! + \file gd32f1x0_spi.c + \brief SPI driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_spi.h" + +#define SPI_INIT_MASK ((uint32_t)0x00003040U) +#define I2S_INIT_MASK ((uint32_t)0x0000F047U) +#define SPI_I2SPSC_RESET ((uint32_t)0x00000002U) /*!< I2S clock prescaler register reset value */ + +/*! + \brief reset SPI and I2S + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_i2s_deinit(uint32_t spi_periph) +{ + switch(spi_periph){ + case SPI0: + /* reset SPI0 and I2S0 */ + rcu_periph_reset_enable(RCU_SPI0RST); + rcu_periph_reset_disable(RCU_SPI0RST); + break; + case SPI1: + /* reset SPI1 */ + rcu_periph_reset_enable(RCU_SPI1RST); + rcu_periph_reset_disable(RCU_SPI1RST); + break; + case SPI2: + /* reset SPI2 and I2S2 */ + rcu_periph_reset_enable(RCU_SPI2RST); + rcu_periph_reset_disable(RCU_SPI2RST); + break; + default : + break; + } +} + +/*! + \brief initialize SPI parameter + \param[in] spi_periph: SPIx(x=0,1,2) + \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; + + /* select SPI mode */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL); +} + +/*! + \brief enable SPI + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_enable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN; +} + +/*! + \brief disable SPI + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_disable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN); +} + +/*! + \brief configure I2S prescaler + \param[in] spi_periph: SPIx(only x=0,2) + \param[in] audiosample: I2S audio sample rate + \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] frameformat: I2S data length and channel length + \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] mckout: I2S master clock output + \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 audiosample,uint32_t frameformat,uint32_t mckout) +{ + uint32_t i2sdiv = 2U, i2sof = 0U; + uint32_t clks = 0U; + uint32_t i2sclock = 0U; + + /* deinit SPI_I2SPSC register */ + SPI_I2SPSC(spi_periph) = SPI_I2SPSC_RESET; + + /* get system clock */ + i2sclock =rcu_clock_freq_get(CK_SYS); + /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */ + if(I2S_MCKOUT_ENABLE == mckout){ + clks = (uint32_t)(((i2sclock / 256U) * 10U) / audiosample); + }else{ + if(I2S_FRAMEFORMAT_DT16B_CH16B == frameformat){ + clks = (uint32_t)(((i2sclock / 32U) *10U ) / audiosample); + }else{ + clks = (uint32_t)(((i2sclock / 64U) *10U ) / audiosample); + } + } + /* remove the flaoting 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 | 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)frameformat; +} + +/*! + \brief initialize I2S parameter + \param[in] spi_periph: SPIx(only x=0,2) + \param[in] mode: I2S operation mode + \arg I2S_MODE_SLAVETX : I2S slave transmit mode + \arg I2S_MODE_SLAVERX : I2S slave receive mode + \arg I2S_MODE_MASTERTX : I2S master transmit mode + \arg I2S_MODE_MASTERRX : I2S master receive mode + \param[in] standard: I2S standard + \arg I2S_STD_PHILLIPS : I2S phillips standard + \arg I2S_STD_MSB : I2S MSB standard + \arg I2S_STD_LSB : I2S LSB standard + \arg I2S_STD_PCMSHORT : I2S PCM short standard + \arg I2S_STD_PCMLONG : I2S PCM long standard + \param[in] ckpl: I2S idle state clock polarity + \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 mode,uint32_t standard,uint32_t ckpl) +{ + uint32_t reg= 0U; + reg= SPI_I2SCTL(spi_periph); + reg &= I2S_INIT_MASK; + + /* enable I2S */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)mode; + /* select I2S standard */ + reg |= (uint32_t)standard; + /* select I2S polarity */ + reg |= (uint32_t)ckpl; + /* write to SPI_I2SCTL register */ + SPI_I2SCTL(spi_periph) = (uint32_t)reg; +} + +/*! + \brief I2S enable + \param[in] spi_periph: SPIx(x=0,2) + \param[out] none + \retval none +*/ +void i2s_enable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN; +} + +/*! + \brief I2S disable + \param[in] spi_periph: SPIx(x=0,2) + \param[out] none + \retval none +*/ +void i2s_disable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN); +} + +/*! + \brief SPI NSS output enable + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_nss_output_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV; +} + +/*! + \brief SPI NSS output disable + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_nss_output_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV); +} + +/*! + \brief SPI NSS pin high level in software mode + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_nss_internal_high(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS; +} + +/*! + \brief SPI NSS pin low level in software mode + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_nss_internal_low(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS); +} + +/*! + \brief enable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] dma: SPI DMA mode + \arg SPI_DMA_TRANSMIT: SPI transmit data use DMA + \arg SPI_DMA_RECEIVE: SPI receive data use DMA + \param[out] none + \retval none +*/ +void spi_dma_enable(uint32_t spi_periph,uint8_t dma) +{ + if(SPI_DMA_TRANSMIT == dma){ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN; + }else{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN; + } +} + +/*! + \brief disable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] dma: SPI DMA mode + \arg SPI_DMA_TRANSMIT: SPI transmit data use DMA + \arg SPI_DMA_RECEIVE: SPI receive data use DMA + \param[out] none + \retval none +*/ +void spi_dma_disable(uint32_t spi_periph,uint8_t dma) +{ + if(SPI_DMA_TRANSMIT == dma){ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN); + }else{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN); + } +} + +/*! + \brief configure SPI/I2S data frame format + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] frame_format: SPI frame size + \arg SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits + \arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits + \param[out] none + \retval none +*/ +void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format) +{ + /* clear SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16); + /* configure SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) |= (uint32_t)frame_format; +} + +/*! + \brief SPI transmit data + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] data: 16-bit data + \param[out] none + \retval none +*/ +void spi_i2s_data_transmit(uint32_t spi_periph,uint16_t data) +{ + SPI_DATA(spi_periph) = (uint32_t)data; +} + +/*! + \brief SPI receive data + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval 16-bit data +*/ +uint16_t spi_i2s_data_receive(uint32_t spi_periph) +{ + return ((uint16_t)SPI_DATA(spi_periph)); +} + +/*! + \brief configure SPI bidirectional transfer direction + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] transfer_direction: SPI transfer direction + \arg SPI_BIDIRECTIONAL_TRANSMIT: SPI work in transmit-only mode + \arg SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode + \retval none +*/ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction) +{ + if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction){ + /* set the transmit only mode */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT; + }else{ + /* set the receive only mode */ + SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE; + } +} + +/*! + \brief enable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] interrupt: + \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 + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_enable(uint32_t spi_periph,uint8_t interrupt) +{ + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_TBE : + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE; + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_RBNE : + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE; + break; + /* SPI/I2S error */ + case SPI_I2S_INT_ERR : + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE; + break; + default : + break; + } +} + +/*! + \brief disable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] interrupt: + \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 + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_disable(uint32_t spi_periph,uint8_t interrupt) +{ + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_TBE : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE); + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_RBNE : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE); + break; + /* SPI/I2S error */ + case SPI_I2S_INT_ERR : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE); + break; + default : + break; + } +} +/*! + \brief get SPI and I2S interrupt flag status + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] interrupt: SPI/I2S interrupt flag status + \arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt. + \arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt. + \arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt. + \arg SPI_INT_FLAG_CONFERR: config error interrupt. + \arg SPI_INT_FLAG_CRCERR: CRC error interrupt. + \arg I2S_INT_FLAG_TXURERR: underrun error interrupt. + \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; + default : + break; + } + /*get SPI/I2S interrupt flag status */ + if(reg1 && reg2){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get SPI and I2S flag status + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] flag: SPI/I2S flag status + \arg SPI_FLAG_TBE: transmit buffer empty flag. + \arg SPI_FLAG_RBNE: receive buffer not empty flag. + \arg SPI_FLAG_TRANS: transmit on-going flag. + \arg SPI_FLAG_RXORERR: receive overrun error flag. + \arg SPI_FLAG_CONFERR: mode config error flag. + \arg SPI_FLAG_CRCERR: CRC error flag. + \arg 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. + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph,uint32_t flag) +{ + if(SPI_STAT(spi_periph) & flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear SPI CRC error flag status + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_crc_error_clear(uint32_t spi_periph) +{ + SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR); +} + +/*! + \brief turn on CRC function + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_crc_on(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; +} + +/*! + \brief turn off CRC function + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_crc_off(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN); +} + +/*! + \brief set CRC polynomial + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] crc_poly: CRC polynomial value + \param[out] none + \retval none +*/ +void spi_crc_polynomial_set(uint32_t spi_periph,uint16_t crc_poly) +{ + /* set SPI CRC polynomial */ + SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly; +} + +/*! + \brief get SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1,2) + \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 SPI next data is CRC value + \param[in] spi_periph: SPIx(x=0,1,2) + \param[out] none + \retval none +*/ +void spi_crc_next(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT; +} + +/*! + \brief get SPI CRC send value or receive value + \param[in] spi_periph: SPIx(x=0,1,2) + \param[in] crc: SPI CRC value + \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))); + } +} + +#ifdef GD32F170_190 +/*! + \brief enable quad wire SPI + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ +void qspi_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD; +} + +/*! + \brief disable quad wire SPI + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ +void qspi_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= ~SPI_QCTL_QMOD ; +} + +/*! + \brief enable quad wire SPI write + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ +void qspi_write_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD); +} + +/*! + \brief enable quad wire SPI read + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ +void qspi_read_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD; +} + +/*! + \brief enable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ +void qspi_io23_output_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV; +} + + /*! + \brief disable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(only x=1) + \param[out] none + \retval none +*/ + void qspi_io23_output_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV); +} +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_syscfg.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_syscfg.c new file mode 100644 index 0000000..70be0e7 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_syscfg.c @@ -0,0 +1,214 @@ +/*! + \file gd32f1x0_syscfg.c + \brief SYSCFG driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_syscfg.h" + +/*! + \brief reset the SYSCFG registers + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_deinit(void) +{ + rcu_periph_reset_enable(RCU_CFGCMPRST); + rcu_periph_reset_disable(RCU_CFGCMPRST); +} + +/*! + \brief enable the DMA channels remapping + \param[in] syscfg_dma_remap: specify the DMA channels to remap + \arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0) + \arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2) + \arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2) + \arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1) + \arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1 + \param[out] none + \retval none +*/ +void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap) +{ + SYSCFG_CFG0 |= syscfg_dma_remap; +} + +/*! + \brief disable the DMA channels remapping + \param[in] syscfg_dma_remap: specify the DMA channels to remap + \arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0) + \arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2) + \arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2) + \arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1) + \arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1 + \param[out] none + \retval none +*/ +void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap) +{ + SYSCFG_CFG0 &= ~syscfg_dma_remap; +} + +/*! + \brief enable PB9 high current capability + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_high_current_enable(void) +{ + SYSCFG_CFG0 |= SYSCFG_HIGH_CURRENT_ENABLE; +} + +/*! + \brief disable PB9 high current capability + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_high_current_disable(void) +{ + SYSCFG_CFG0 &= SYSCFG_HIGH_CURRENT_DISABLE; +} + +#ifdef GD32F170_190 +/*! + \brief configure the VLCD intermediate voltage rail + \param[in] vlcd_bias: specify VLCD bias + \arg VLCD_BIAS1_2_RAIL1: VLCD bias is 1/2, using rail1 + \arg VLCD_BIAS1_2_RAIL2: VLCD bias is 1/2, using rail2 + \arg VLCD_BIAS1_2_RAIL3: VLCD bias is 1/2, using rail3 + \arg VLCD_BIAS1_3_RAIL1_2: VLCD bias is 1/3, using rail1 and rail2 + \arg VLCD_BIAS1_3_RAIL1_3: VLCD bias is 1/3, using rail1 and rail3 + \arg VLCD_BIAS1_4_RAILALL: VLCD bias is 1/4, using all rails + \param[out] none + \retval none +*/ +void syscfg_vlcd_rail_config(uint8_t vlcd_bias) +{ + uint32_t cfg1 = SYSCFG_CFG1; + + /* Clear system configuration register 1 */ + SYSCFG_CFG1 = 0U; + + switch(vlcd_bias){ + /* according to VLCD bias, configure rails combination */ + case VLCD_BIAS1_2_RAIL1: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL1; + break; + case VLCD_BIAS1_2_RAIL2: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL2; + break; + case VLCD_BIAS1_2_RAIL3: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3; + break; + case VLCD_BIAS1_3_RAIL1_2: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL2 | SYSCFG_VLCD_RAIL1; + break; + case VLCD_BIAS1_3_RAIL1_3: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3 | SYSCFG_VLCD_RAIL1; + break; + case VLCD_BIAS1_4_RAILALL: + SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3 | SYSCFG_VLCD_RAIL2 | SYSCFG_VLCD_RAIL1; + break; + default: + SYSCFG_CFG1 = cfg1; + break; + } +} +#endif /* GD32F170_190 */ + +/*! + \brief configure the GPIO pin as EXTI Line + \param[in] exti_port: specify the GPIO port used in EXTI + \arg EXTI_SOURCE_GPIOx(x = A,B,C,D,F): EXTI GPIO port + \param[in] exti_pin: specify the EXTI line + \arg EXTI_SOURCE_PINx(x = 0..15): EXTI GPIO pin + \param[out] none + \retval none +*/ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin) +{ + uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin))); + uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin)); + + switch(exti_pin / EXTI_SS_JSTEP){ + case EXTISS0: + /* clear EXTI source line(0..3) */ + SYSCFG_EXTISS0 &= clear_exti_mask; + /* configure EXTI soure line(0..3) */ + SYSCFG_EXTISS0 |= config_exti_mask; + break; + case EXTISS1: + /* clear EXTI soure line(4..7) */ + SYSCFG_EXTISS1 &= clear_exti_mask; + /* configure EXTI soure line(4..7) */ + SYSCFG_EXTISS1 |= config_exti_mask; + break; + case EXTISS2: + /* clear EXTI soure line(8..11) */ + SYSCFG_EXTISS2 &= clear_exti_mask; + /* configure EXTI soure line(8..11) */ + SYSCFG_EXTISS2 |= config_exti_mask; + break; + case EXTISS3: + /* clear EXTI soure line(12..15) */ + SYSCFG_EXTISS3 &= clear_exti_mask; + /* configure EXTI soure line(12..15) */ + SYSCFG_EXTISS3 |= config_exti_mask; + break; + default: + break; + } +} + +/*! + \brief connect TIMER0/14/15/16 break input to the selected parameter + \param[in] syscfg_lock: Specify the parameter to be connected + \arg SYSCFG_LOCK_LOCKUP: Cortex-M3 lockup output connected to the break input + \arg SYSCFG_LOCK_SRAM_PARITY_ERROR: SRAM_PARITY 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 check if the specified flag in SYSCFG_CFG2 is set or not. + \param[in] syscfg_flag: specify the flag in SYSCFG_CFG2 to check. + \arg SYSCFG_SRAM_PCEF: SRAM parity check error flag. + \param[out] none + \retval the syscfg_flag state returned (SET or RESET). + */ +FlagStatus syscfg_flag_get(uint32_t syscfg_flag) +{ + if((SYSCFG_CFG2 & syscfg_flag) != (uint32_t)RESET){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the flag in SYSCFG_CFG2 by writing 1. + \param[in] syscfg_flag: Specify the flag in SYSCFG_CFG2 to clear. + \arg SYSCFG_SRAM_PCEF: SRAM parity check error flag. + \param[out] none + \retval none +*/ +void syscfg_flag_clear(uint32_t syscfg_flag) +{ + SYSCFG_CFG2 |= (uint32_t) syscfg_flag; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_timer.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_timer.c new file mode 100644 index 0000000..4dad636 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_timer.c @@ -0,0 +1,1887 @@ +/*! + \file gd32f1x0_timer.c + \brief TIMER driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_timer.h" + +/*! + \brief deinit a timer + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_deinit(uint32_t timer_periph) +{ + switch(timer_periph){ + case TIMER0: + /* reset TIMER0 */ + rcu_periph_reset_enable(RCU_TIMER0RST); + rcu_periph_reset_disable(RCU_TIMER0RST); + break; + case TIMER1: + /* reset TIMER1 */ + rcu_periph_reset_enable(RCU_TIMER1RST); + rcu_periph_reset_disable(RCU_TIMER1RST); + break; + case TIMER2: + /* reset TIMER2 */ + rcu_periph_reset_enable(RCU_TIMER2RST); + rcu_periph_reset_disable(RCU_TIMER2RST); + break; + case TIMER5: + /* reset TIMER5 */ + rcu_periph_reset_enable(RCU_TIMER5RST); + rcu_periph_reset_disable(RCU_TIMER5RST); + break; + case TIMER13: + /* reset TIMER13 */ + rcu_periph_reset_enable(RCU_TIMER13RST); + rcu_periph_reset_disable(RCU_TIMER13RST); + break; + case TIMER14: + /* reset TIMER14 */ + rcu_periph_reset_enable(RCU_TIMER14RST); + rcu_periph_reset_disable(RCU_TIMER14RST); + break; + case TIMER15: + /* reset TIMER15 */ + rcu_periph_reset_enable(RCU_TIMER15RST); + rcu_periph_reset_disable(RCU_TIMER15RST); + break; + case TIMER16: + /* reset TIMER16 */ + rcu_periph_reset_enable(RCU_TIMER16RST); + rcu_periph_reset_disable(RCU_TIMER16RST); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER counter + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] initpara: init parameter struct + prescaler: prescaler value of the counter clock,0~65535 + alignedmode: TIMER_COUNTER_EDGE,TIMER_COUNTER_CENTER_DOWN,TIMER_COUNTER_CENTER_UP,TIMER_COUNTER_CENTER_BOTH + counterdirection: TIMER_COUNTER_UP,TIMER_COUNTER_DOWN + period: counter auto reload value + clockdivision: TIMER_CKDIV_DIV1,TIMER_CKDIV_DIV2,TIMER_CKDIV_DIV4 + repetitioncounter: counter repetition value,0~255 + \param[out] none + \retval none +*/ +void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara) +{ + /* configure the counter prescaler value */ + TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler; + + /* configure the counter direction and aligned mode */ + if((TIMER0 == timer_periph) || (TIMER1 == timer_periph) || (TIMER2 == timer_periph)){ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_DIR|TIMER_CTL0_CAM); + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->alignedmode; + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->counterdirection; + }else{ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_DIR); + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->counterdirection; + } + + /* configure the autoreload value */ + TIMER_CAR(timer_periph) = (uint32_t)initpara->period; + + if((TIMER5 != timer_periph)){ + /* reset the CKDIV bit */ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_CKDIV); + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->clockdivision; + } + + if((TIMER0 == timer_periph) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph)|| (TIMER16 == timer_periph)){ + /* configure the repetition counter value */ + TIMER_CREP(timer_periph) = (uint32_t)initpara->repetitioncounter; + } + + /* generate an update event */ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_PSC_RELOAD_NOW; +} + +/*! + \brief enable a timer + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_COUNTER_ENABLE; +} + +/*! + \brief disable a timer + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (uint32_t)TIMER_COUNTER_DISABLE; +} + +/*! + \brief enable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_ARSE_ENABLE; +} + +/*! + \brief disable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (uint32_t) TIMER_ARSE_DISABLE; +} + +/*! + \brief enable the update event + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_update_event_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_UPDIS_ENABLE; +} + +/*! + \brief disable the update event + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_update_event_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (uint32_t) TIMER_UPDIS_DISABLE; +} + +/*! + \brief set TIMER counter alignment mode + \param[in] timer_periph: TIMERx(x=0,1,2) + \param[in] aligned: + \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,2,5,13,14,15,16) + \param[out] none + \retval none +*/ +void timer_counter_up_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_DIR); + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_COUNTER_UP; +} + +/*! + \brief set TIMER counter down direction + \param[in] timer_periph: TIMERx(x=0,1,2) + \param[out] none + \retval none +*/ +void timer_counter_down_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (uint32_t)(~ TIMER_CTL0_DIR); + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_COUNTER_DOWN; +} + +/*! + \brief configure TIMER prescaler + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] prescaler: prescaler value + \param[in] pscreload: prescaler reload mode + \arg TIMER_PSC_RELOAD_NOW: the prescaler is loaded right now + \arg TIMER_PSC_RELOAD_UPDATE: the prescaler is loaded at the next update event + \param[out] none + \retval none +*/ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload) +{ + TIMER_PSC(timer_periph) = (uint32_t)prescaler; + + if(TIMER_PSC_RELOAD_NOW == pscreload){ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; + } +} + +/*! + \brief configure TIMER repetition register value + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[in] repetition: the counter repetition value + \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,2,5,13,14,15,16) + \param[in] autoreload: the counter auto-reload value + \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,2,5,13,14,15,16) + \param[in] counter: the counter value + \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,2,5,13,14,15,16) + \param[out] none + \retval counter value +*/ +uint32_t timer_counter_read(uint32_t timer_periph) +{ + uint32_t count_value = 0U; + count_value = TIMER_CNT(timer_periph); + return (count_value); +} + +/*! + \brief read TIMER prescaler value + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[out] none + \retval prescaler register value +*/ +uint16_t timer_prescaler_read(uint32_t timer_periph) +{ + uint16_t prescaler_value = 0U; + prescaler_value = (uint16_t)(TIMER_PSC(timer_periph)); + return (prescaler_value); +} + +/*! + \brief configure TIMER single pulse mode + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] spmode: + \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, uint8_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{ + } +} + +/*! + \brief configure TIMER update source + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] update: + \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, uint8_t update) +{ + if(TIMER_UPDATE_SRC_REGULAR == update){ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS; + }else if(update == TIMER_UPDATE_SRC_GLOBAL){ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS; + }else{ + } +} + +/*! + \brief enable the TIMER interrupt + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] interrupt: timer interrupt enable source + \arg TIMER_INT_UP: update interrupt enable + \arg TIMER_INT_CH0: channel 0 interrupt enable + \arg TIMER_INT_CH1: channel 1 interrupt enable + \arg TIMER_INT_CH2: channel 2 interrupt enable + \arg TIMER_INT_CH3: channel 3 interrupt enable + \arg TIMER_INT_CMT: commutation interrupt enable + \arg TIMER_INT_TRG: trigger interrupt enable + \arg TIMER_INT_BRK: break interrupt enable + \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,2,5,13,14,15,16) + \param[in] interrupt: timer interrupt source enable + \arg TIMER_INT_UP: update interrupt enable + \arg TIMER_INT_CH0: channel 0 interrupt enable + \arg TIMER_INT_CH1: channel 1 interrupt enable + \arg TIMER_INT_CH2: channel 2 interrupt enable + \arg TIMER_INT_CH3: channel 3 interrupt enable + \arg TIMER_INT_CMT: commutation interrupt enable + \arg TIMER_INT_TRG: trigger interrupt enable + \arg TIMER_INT_BRK: break interrupt enable + \param[out] none + \retval none +*/ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) &= (uint32_t)(~ interrupt); +} + +/*! + \brief get timer interrupt flag + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] interrupt: the timer interrupt bits + \arg TIMER_INT_FLAG_UP: update interrupt flag + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag + \arg TIMER_INT_FLAG_BRK: break interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt) +{ + uint16_t intval = 0U, intenable = 0U; + + intval = (uint16_t)(TIMER_INTF(timer_periph) & interrupt); + intenable = (uint16_t)(TIMER_DMAINTEN(timer_periph) & interrupt); + + if(((uint16_t)RESET != intval ) && (((uint16_t)RESET) != intenable)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER interrupt flag + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] interrupt: the timer interrupt bits + \arg TIMER_INT_FLAG_UP: update interrupt flag + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag + \arg TIMER_INT_FLAG_BRK: break interrupt flag + \param[out] none + \retval none +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_INTF(timer_periph) &= (uint32_t)(~(uint32_t)interrupt); +} + +/*! + \brief get TIMER flags + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] flag: the timer interrupt flags + \arg TIMER_FLAG_UP: update flag + \arg TIMER_FLAG_CH0: channel 0 flag + \arg TIMER_FLAG_CH1: channel 1 flag + \arg TIMER_FLAG_CH2: channel 2 flag + \arg TIMER_FLAG_CH3: channel 3 flag + \arg TIMER_FLAG_CMT: channel commutation flag + \arg TIMER_FLAG_TRG: trigger flag + \arg TIMER_FLAG_BRK: break flag + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) +{ + if(((uint16_t)RESET) != ((uint16_t)(TIMER_INTF(timer_periph) & flag))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER flags + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] flag: the timer interrupt flags + \arg TIMER_FLAG_UP: update flag + \arg TIMER_FLAG_CH0: channel 0 flag + \arg TIMER_FLAG_CH1: channel 1 flag + \arg TIMER_FLAG_CH2: channel 2 flag + \arg TIMER_FLAG_CH3: channel 3 flag + \arg TIMER_FLAG_CMT: channel commutation flag + \arg TIMER_FLAG_TRG: trigger flag + \arg TIMER_FLAG_BRK: break flag + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag + \param[out] none + \retval none +*/ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag) +{ + TIMER_INTF(timer_periph) &= (uint32_t)(~(uint32_t)flag); +} + +/*! + \brief enable the TIMER DMA + \param[in] timer_periph: TIMERx(x=0,1,2,5,14,15,16) + \param[in] dma: timer DMA source enable + \arg TIMER_DMA_UPD: update DMA enable + \arg TIMER_DMA_CH0D: channel 0 DMA enable + \arg TIMER_DMA_CH1D: channel 1 DMA enable + \arg TIMER_DMA_CH2D: channel 2 DMA enable + \arg TIMER_DMA_CH3D: channel 3 DMA enable + \arg TIMER_DMA_CMTD: channel commutation DMA request enable + \arg TIMER_DMA_TRGD: trigger DMA enable + \param[out] none + \retval none +*/ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; +} + +/*! + \brief disable the TIMER DMA + \param[in] timer_periph: TIMERx(x=0,1,2,5,14,15,16) + \param[in] dma: timer DMA source enable + \arg TIMER_DMA_UPD: update DMA enable + \arg TIMER_DMA_CH0D: channel 0 DMA enable + \arg TIMER_DMA_CH1D: channel 1 DMA enable + \arg TIMER_DMA_CH2D: channel 2 DMA enable + \arg TIMER_DMA_CH3D: channel 3 DMA enable + \arg TIMER_DMA_CMTD: channel commutation DMA request enable + \arg TIMER_DMA_TRGD: trigger DMA enable + \param[out] none + \retval none +*/ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) &= ~(uint32_t)dma; +} + +/*! + \brief channel DMA request source selection + \param[in] timer_periph: TIMERx(x=0,1,2,5,14,15,16) + \param[in] dma_request: channel DMA request source selection + \arg TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel y is sent when channel y event occurs + \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel y is sent when update event occurs + \param[out] none + \retval none +*/ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request) +{ + if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS; + }else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request){ + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_DMAS; + }else{ + } +} + +/*! + \brief configure the TIMER DMA transfer + \param[in] timer_periph: TIMERx(x=0,1,2,5,14,15,16) + \param[in] dma_baseaddr: + \arg TIMER_DMACFG_DMATA_CTL0: DMA transfer address is TIMER_CTL0 + \arg TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1 + \arg TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG + \arg TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN + \arg TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF + \arg TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG + \arg TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0 + \arg TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1 + \arg TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2 + \arg TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT + \arg TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC + \arg TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR + \arg TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP + \arg TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV + \arg TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV + \arg TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV + \arg TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV + \arg TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP + \arg TIMER_DMACFG_DMATA_DMACFG: DMA transfer address is TIMER_DMACFG + \arg TIMER_DMACFG_DMATA_DMATB: DMA transfer address is TIMER_DMATB + \param[in] dma_lenth: + \arg TIMER_DMACFG_DMATC_xTRANSFER(x=1..18): DMA transfer x time + \param[out] none + \retval none +*/ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth) +{ + TIMER_DMACFG(timer_periph) &= (uint32_t)(~(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC)); + TIMER_DMACFG(timer_periph) |= (uint32_t)(dma_baseaddr | dma_lenth); +} + +/*! + \brief software generate events + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] event: the timer software event generation sources + \arg TIMER_EVENT_SRC_UPG: update event generation + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation + \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation + \arg TIMER_EVENT_SRC_TRGG: trigger event generation + \arg TIMER_EVENT_SRC_BRKG: break event generation + \param[out] none + \retval none +*/ +void timer_event_software_generate(uint32_t timer_periph, uint16_t event) +{ + TIMER_SWEVG(timer_periph) |= (uint32_t)event; +} + +/*! + \brief configure TIMER break function + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[in] breakpara: TIMER break parameter struct + runoffstate: TIMER_ROS_STATE_ENABLE,TIMER_ROS_STATE_DISABLE + ideloffstate: TIMER_IOS_STATE_ENABLE,TIMER_IOS_STATE_DISABLE + deadtime: 0~255 + 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,14,15,16) + \param[out] none + \retval none +*/ +void timer_break_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_BREAK_ENABLE; +} + +/*! + \brief disable TIMER break function + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[out] none + \retval none +*/ +void timer_break_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= (uint32_t)TIMER_BREAK_DISABLE; +} + +/*! + \brief enable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[out] none + \retval none +*/ +void timer_automatic_output_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_OUTAUTO_ENABLE; +} + +/*! + \brief disable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[out] none + \retval none +*/ +void timer_automatic_output_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= (uint32_t)TIMER_OUTAUTO_DISABLE; +} + +/*! + \brief configure TIMER primary output function + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_primary_output_config(uint32_t timer_periph,ControlStatus newvalue) +{ + if(newvalue){ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_POEN; + }else{ + TIMER_CCHP(timer_periph) &= (uint32_t)(~ TIMER_CCHP_POEN); + } +} + +/*! + \brief channel capture/compare control shadow register enable + \param[in] timer_periph: TIMERx(x=0,14,15,16) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(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,1,2) + \param[in] ccuctl: channel control shadow register update control + \arg TIMER_UPDATECTL_CCU: the shadow registers update by when CMTG bit is set + \arg TIMER_UPDATECTL_CCUTRI: the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl) +{ + if(TIMER_UPDATECTL_CCU == ccuctl){ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC); + }else if(TIMER_UPDATECTL_CCUTRI == ccuctl){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC; + }else{ + } +} + +/*! + \brief configure TIMER channel output function + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] ocpara: TIMER channeln output parameter struct + outputstate: TIMER_CCX_ENABLE,TIMER_CCX_DISABLE + outputnstate: TIMER_CCXN_ENABLE,TIMER_CCXN_DISABLE + ocpolarity: TIMER_OC_POLARITY_HIGH,TIMER_OC_POLARITY_LOW + ocnpolarity: TIMER_OCN_POLARITY_HIGH,TIMER_OCN_POLARITY_LOW + ocidlestate: TIMER_OC_IDLE_STATE_LOW,TIMER_OC_IDLE_STATE_HIGH + ocnidlestate: TIMER_OCN_IDLE_STATE_LOW,TIMER_OCN_IDLE_STATE_HIGH + \param[out] none + \retval none +*/ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct* ocpara) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0EN); + /* 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) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){ + /* reset the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0NEN); + /* set the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputnstate; + /* reset the CH0NP bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0NP); + /* set the CH0NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocnpolarity; + /* reset the ISO0 bit */ + TIMER_CTL1(timer_periph) &=(uint32_t)(~TIMER_CTL1_ISO0); + /* set the ISO0 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocidlestate; + /* reset the ISO0N bit */ + TIMER_CTL1(timer_periph) &=(uint32_t)(~TIMER_CTL1_ISO0N); + /* set the ISO0N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocnidlestate; + } + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1EN); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 4); + /* 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 << 4); + + if((TIMER0 == timer_periph)){ + /* reset the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1NEN); + /* set the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputnstate << 4); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1NP); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->ocnpolarity << 4); + /* 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 << 2); + /* 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 << 2); + } + 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 << 8); + /* 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 << 8); + + if((TIMER0 == timer_periph)){ + /* reset the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH2NEN); + /* set the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputnstate << 8); + /* reset the CH2NP bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH2NP); + /* set the CH2NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->ocnpolarity << 8); + /* 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 << 4); + /* 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 << 4); + } + 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 << 12); + /* 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 << 12); + + if((TIMER0 == timer_periph)){ + /* reset the ISO3 bit */ + TIMER_CTL1(timer_periph) &=(uint32_t)(~TIMER_CTL1_ISO3); + /* set the ISO3 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)ocpara->ocidlestate << 6); + } + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output compare mode + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] ocmode: channel output compare mode + \arg TIMER_OC_MODE_TIMING: timing mode + \arg TIMER_OC_MODE_ACTIVE: active mode + \arg TIMER_OC_MODE_INACTIVE: inactive mode + \arg TIMER_OC_MODE_TOGGLE: toggle mode + \arg TIMER_OC_MODE_LOW: force low mode + \arg TIMER_OC_MODE_HIGH: force high mode + \arg TIMER_OC_MODE_PWM0: PWM0 mode + \arg TIMER_OC_MODE_PWM1: PWM1 mode + \param[out] none + \retval none +*/ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocmode << 8); + 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 << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output pulse value + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \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; + default: + break; + } +} + +/*! + \brief configure TIMER channel output shadow function + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] ocshadow: channel output shadow state + \arg TIMER_OC_SHADOW_ENABLE: channel output shadow state enable + \arg TIMER_OC_SHADOW_DISABLE: channel output shadow state disable + \param[out] none + \retval none +*/ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocshadow << 8); + 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 << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output fast function + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] ocfast: channel output fast function + \arg TIMER_OC_FAST_ENABLE: channel output fast function enable + \arg TIMER_OC_FAST_DISABLE: channel output fast function disable + \param[out] none + \retval none +*/ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &=(uint32_t)(~TIMER_CHCTL1_CH2COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &=(uint32_t)(~TIMER_CHCTL1_CH3COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output clear function + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] occlear: channel output clear function + \arg TIMER_OC_CLEAR_ENABLE: channel output clear function enable + \arg TIMER_OC_CLEAR_DISABLE: channel output clear function disable + \param[out] none + \retval none +*/ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)occlear << 8); + 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 << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output polarity + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] ocpolarity: channel output polarity + \arg TIMER_OC_POLARITY_HIGH: channel output polarity is high + \arg TIMER_OC_POLARITY_LOW: channel output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 4); + 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 << 8); + 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 << 12); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output polarity + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \param[in] ocnpolarity: channel complementary output polarity + \arg TIMER_OCN_POLARITY_HIGH: channel complementary output polarity is high + \arg TIMER_OCN_POLARITY_LOW: channel complementary output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 4); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH2NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER OCPRE clear source selection + \param[in] timer_periph: TIMERx(x=0,1,2) + \param[in] clear: OCPRE clear source + \arg TIMER_OCPRE_CLEAR_SOURCE_ETIF: OCPRE_CLR_INT is connected to ETIF + \arg TIMER_OCPRE_CLEAR_SOURCE_CLR: OCPRE_CLR_INT is connected to the OCPRE_CLR input + \param[out] none + \retval none +*/ +void timer_ocpre_clear_source_config(uint32_t timer_periph, uint8_t ocpreclear) +{ + if(TIMER_OCPRE_CLEAR_SOURCE_ETIF == ocpreclear){ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_OCRC; + }else if(TIMER_OCPRE_CLEAR_SOURCE_CLR == ocpreclear){ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_OCRC; + }else{ + } +} + +/*! + \brief configure TIMER channel enable state + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] state: TIMER channel enable state + \arg TIMER_CCX_ENABLE: channel enable + \arg TIMER_CCX_DISABLE: channel disable + \param[out] none + \retval none +*/ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_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 << 4); + 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 << 8); + 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 << 12); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output enable state + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \param[in] ocnstate: TIMER channel complementary output enable state + \arg TIMER_CCXN_ENABLE: channel complementary enable + \arg TIMER_CCXN_DISABLE: channel complementary disable + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnstate; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 4); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH2NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 8); + break; + default: + break; + } +} + +/*! + \brief configure TIMER input capture parameter + \param[in] timer_periph: TIMERx(x=0,1,2,5,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] icpara: TIMER channel intput parameter struct + icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING,TIMER_IC_POLARITY_BOTH_EDGE + icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI,TIMER_IC_SELECTION_ITS + icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_capture_config(uint32_t timer_periph,uint16_t channel,timer_ic_parameter_struct* icpara) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0EN); + + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpara->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpara->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(((uint32_t)icpara->icfilter << 4)); + + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1EN); + + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpara->icpolarity << 4); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icpara->icselection << 8); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH1CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icpara->icfilter << 12); + + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH2EN); + + /* reset the CH2P and CH2NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH2P|TIMER_CHCTL2_CH2NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpara->icpolarity << 8); + /* reset the CH2MS bit */ + TIMER_CHCTL1(timer_periph) &=(uint32_t)(~TIMER_CHCTL1_CH2MS); + 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<< 4); + + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH3EN); + + /* reset the CH3P bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH3P)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpara->icpolarity << 12); + /* reset the CH3MS bit */ + TIMER_CHCTL1(timer_periph) &=(uint32_t)(~TIMER_CHCTL1_CH3MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)icpara->icselection << 8); + /* reset the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &=(uint32_t)(~TIMER_CHCTL1_CH3CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)icpara->icfilter << 12); + + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN; + break; + default: + break; + } + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, channel,(uint32_t)icpara->icprescaler); +} + +/*! + \brief configure TIMER channel input capture prescaler value + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[in] prescaler: channel input capture prescaler value + \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, uint32_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 << 8); + 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 << 8); + break; + default: + break; + } +} + +/*! + \brief read TIMER channel capture compare register value + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,13,14,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,1,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,1,2)) + \param[out] none + \retval channel capture compare register value +*/ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel) +{ + uint32_t count_value=0U; + + switch(channel){ + case TIMER_CH_0: + count_value = TIMER_CH0CV(timer_periph); + break; + case TIMER_CH_1: + count_value = TIMER_CH1CV(timer_periph); + break; + case TIMER_CH_2: + count_value = TIMER_CH2CV(timer_periph); + break; + case TIMER_CH_3: + count_value = TIMER_CH3CV(timer_periph); + break; + default: + break; + } + return (count_value); +} + +/*! + \brief configure TIMER input pwm capture function + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,1,2,14)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,1,2,14)) + \param[in] icpwm:TIMER channel intput pwm parameter struct + icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING + icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI + icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm) +{ + uint16_t icpolarity = 0x0U; + uint16_t icselection = 0x0U; + + if(TIMER_IC_POLARITY_RISING == icpwm->icpolarity){ + icpolarity = TIMER_IC_POLARITY_FALLING; + }else{ + icpolarity = TIMER_IC_POLARITY_RISING; + } + + if(TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection){ + icselection = TIMER_IC_SELECTION_INDIRECTTI; + }else{ + icselection = TIMER_IC_SELECTION_DIRECTTI; + } + + if(TIMER_CH_0 == channel){ + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpwm->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpwm->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpwm->icfilter); + /* 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,(uint32_t)icpwm->icprescaler); + + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpolarity << 4); + /* 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 << 8); + /* 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 << 8); + /* 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,(uint32_t)icpwm->icprescaler); + }else{ + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpwm->icpolarity << 4); + /* 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 << 8); + /* 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 << 8); + /* 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,(uint32_t)icpwm->icprescaler); + + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)icpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)icselection; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &=(uint32_t)(~TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)icpwm->icfilter; + /* 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,(uint32_t)icpwm->icprescaler); + } +} + +/*! + \brief configure TIMER hall sensor mode + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] hallmode: + \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, uint8_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{ + } +} + +/*! + \brief select TIMER input trigger source + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] intrigger: + \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 + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0 + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1 + \arg TIMER_SMCFG_TRGSEL_ETIFP: external trigger + \param[out] none + \retval none +*/ +void timer_input_trigger_source_select(uint32_t timer_periph,uint32_t intrigger) +{ + TIMER_SMCFG(timer_periph) &=(uint32_t)(~TIMER_SMCFG_TRGS); + TIMER_SMCFG(timer_periph) |= (uint32_t)intrigger; +} + +/*! + \brief select TIMER master mode output trigger source + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] outrigger: + \arg TIMER_TRI_OUT_SRC_RESET: the UPG bit as trigger output + \arg TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output + \arg TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output + \arg TIMER_TRI_OUT_SRC_CH0: a capture or a compare match occurred in channal0 as trigger output TRGO + \arg TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output + \arg TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output + \arg TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output + \arg TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output + \param[out] none + \retval none +*/ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger) +{ + TIMER_CTL1(timer_periph) &=(uint32_t)(~TIMER_CTL1_MMC); + TIMER_CTL1(timer_periph) |= (uint32_t)outrigger; +} + +/*! + \brief select TIMER slave mode + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] slavemode: + \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) +{ + TIMER_SMCFG(timer_periph) &=(uint32_t)(~TIMER_SMCFG_SMC); + + TIMER_SMCFG(timer_periph) |= (uint32_t)slavemode; +} + +/*! + \brief configure TIMER master slave mode + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] masterslave: + \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, uint8_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{ + } +} + +/*! + \brief configure TIMER external trigger input + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] extprescaler: + \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] expolarity: + \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 0x00 and 0x0F + \param[out] none + \retval none +*/ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t expolarity, 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|expolarity); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extfilter << (uint16_t)8); +} + +/*! + \brief configure TIMER quadrature decoder mode + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] decomode: + \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: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[in] ic1polarity: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[out] none + \retval none +*/ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity) +{ + TIMER_SMCFG(timer_periph) &=(uint32_t)(~TIMER_SMCFG_SMC); + TIMER_SMCFG(timer_periph) |= (uint32_t)decomode; + + TIMER_CHCTL0(timer_periph) &= (uint32_t)(((uint32_t)(~TIMER_CHCTL0_CH0MS))&((uint32_t)(~TIMER_CHCTL0_CH1MS))); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI|((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8)); + + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)(ic0polarity|((uint32_t)ic1polarity << 4U)); +} + +/*! + \brief configure TIMER internal clock mode + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[out] none + \retval none +*/ +void timer_internal_clock_config(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= (uint32_t)TIMER_SLAVE_MODE_DISABLE; +} + +/*! + \brief configure TIMER the internal trigger as external clock input + \param[in] timer_periph: TIMERx(x=0,1,2,14) + \param[in] intrigger: + \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,2,14) + \param[in] extrigger: + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0 + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1 + \param[in] expolarity: + \arg TIMER_IC_POLARITY_RISING: active low or falling edge active + \arg TIMER_IC_POLARITY_FALLING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t expolarity, uint32_t extfilter) +{ + if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger){ + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH1EN); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)expolarity << 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 << 8U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + }else{ + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &=(uint32_t)(~(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)expolarity; + /* 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; + /* 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,2) + \param[in] extprescaler: + \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] expolarity: + \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 expolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, expolarity, extfilter); + + /* 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; + + /* reset the TRGS bit */ + TIMER_SMCFG(timer_periph) &=(uint32_t)(~TIMER_SMCFG_TRGS); + /* set the TRGS bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_TRGSEL_ETIFP; +} + +/*! + \brief configure TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0,1,2) + \param[in] extprescaler: + \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] expolarity: + \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 expolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, expolarity, extfilter); + + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief disable TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_disable(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief configure TIMER13 channel0 remap function + \param[in] timer_periph: TIMERx(x=13) + \param[in] channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=13)) + \param[in] remap: + \arg TIMER_IRMP_CI0_RMP_GPIO: channel 0 input is connected to GPIO + \arg TIMER_IRMP_CI0_RTCCLK: channel 0 input is connected to the RTCCLK + \arg TIMER_IRMP_CI0_HXTALDIV32: channel 0 input is connected to HXTAL/32 clock + \arg TIMER_IRMP_CI0_CKOUTSEL: channel 0 input is connected to CKOUTSEL + \param[out] none + \retval none +*/ +void timer_channel_remap_config(uint32_t timer_periph, uint16_t channel, uint32_t remap) +{ + if(TIMER_CH_0 == channel){ + TIMER_IRMP(timer_periph) = (uint32_t)remap; + } +} + +#ifdef GD32F170_190 + +/*! + \brief configure TIMER cc register selection + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] ccsel: + \arg TIMER_CHVSEL_DISABLE: write CHxVAL register selection disable + \arg TIMER_CHVSEL_ENABLE: write CHxVAL register selection enable + \param[out] none + \retval none +*/ +void timer_write_cc_register_config(uint32_t timer_periph, uint32_t ccsel) +{ + if(ccsel){ + TIMER_CFG(timer_periph) |= (uint32_t)ccsel; + }else{ + TIMER_CFG(timer_periph) &= (uint32_t)ccsel; + } +} + +/*! + \brief configure TIMER output value selection + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] outsel: + \arg TIMER_OUTSEL_DISABLE: output value selection disable + \arg TIMER_OUTSEL_ENABLE: output value selection enable + \param[out] none + \retval none +*/ +void timer_output_value_selection_config(uint32_t timer_periph, uint32_t outsel) +{ + if(outsel){ + TIMER_CFG(timer_periph) |= (uint32_t)outsel; + }else{ + TIMER_CFG(timer_periph) &= (uint32_t)outsel; + } +} + +#endif /* GD32F170_190 */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_tsi.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_tsi.c new file mode 100644 index 0000000..a9b6899 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_tsi.c @@ -0,0 +1,518 @@ +/*! + \file gd32f1x0_tsi.c + \brief TSI driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_tsi.h" +#include "gd32f1x0_rcu.h" + +/*! + \brief reset TSI peripheral + \param[in] none + \param[out] none + \retval none +*/ +void tsi_deinit(void) +{ + rcu_periph_reset_enable(RCU_TSIRST); + rcu_periph_reset_disable(RCU_TSIRST); +} + +/*! + \brief initialize TSI plus prescaler,charge plus,transfer plus,max cycle number + \param[in] prescaler: CTCLK clock division factor + \arg TSI_CTCDIV_DIV1: fCTCLK = fHCLK + \arg TSI_CTCDIV_DIV2: fCTCLK = fHCLK/2 + \arg TSI_CTCDIV_DIV4: fCTCLK = fHCLK/4 + \arg TSI_CTCDIV_DIV8: fCTCLK = fHCLK/8 + \arg TSI_CTCDIV_DIV16: fCTCLK = fHCLK/16 + \arg TSI_CTCDIV_DIV32: fCTCLK = fHCLK/32 + \arg TSI_CTCDIV_DIV64: fCTCLK = fHCLK/64 + \arg TSI_CTCDIV_DIV128: fCTCLK = fHCLK/128 + \param[in] charge_duration: charge state duration time + \arg TSI_CHARGE_1CTCLK(x=1..16): the duration time of charge state is x CTCLK + \param[in] transfer_duration: charge transfer state duration time + \arg TSI_TRANSFER_xCTCLK(x=1..16): the duration time of transfer state is x CTCLK + \param[in] max_number: max cycle number + \arg TSI_MAXNUM255: the max cycle number of a sequence is 255 + \arg TSI_MAXNUM511: the max cycle number of a sequence is 511 + \arg TSI_MAXNUM1023: the max cycle number of a sequence is 1023 + \arg TSI_MAXNUM2047: the max cycle number of a sequence is 2047 + \arg TSI_MAXNUM4095: the max cycle number of a sequence is 4095 + \arg TSI_MAXNUM8191: the max cycle number of a sequence is 8191 + \arg TSI_MAXNUM16383: the max cycle number of a sequence is 16383 + \param[out] none + \retval none +*/ +void tsi_init(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration,uint32_t max_number) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + uint32_t ctl; + ctl = TSI_CTL; + /*configure TSI clock division factor,charge state duration time,charge transfer state duration time */ + ctl &= ~(TSI_CTL_CTCDIV|TSI_CTL_CTDT|TSI_CTL_CDT|TSI_CTL_MCN); + ctl |= (prescaler|charge_duration|transfer_duration|max_number); + TSI_CTL = ctl; + } +} + +/*! + \brief enable sample pin + \param[in] sample: sample pin + \arg TSI_SAMPCFG_GxPy( x=0..5,y=0..3):pin y of group x is sample pin + \param[out] none + \retval none +*/ +void tsi_sample_pin_enable(uint32_t sample) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + TSI_SAMPCFG |= sample; + } +} + +/*! + \brief disable sample pin + \param[in] sample: sample pin + \arg TSI_SAMPCFG_GxPy( x=0..5,y=0..3): pin y of group x is sample pin + \param[out] none + \retval none +*/ +void tsi_sample_pin_disable(uint32_t sample) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + TSI_SAMPCFG &= ~sample; + } +} + +/*! + \brief enable channel pin + \param[in] channel: channel pin + \arg TSI_CHCFG_GxPy( x=0..5,y=0..3): pin y of group x + \param[out] none + \retval none +*/ +void tsi_channel_pin_enable(uint32_t channel) +{ + TSI_CHCFG |= channel; +} + +/*! + \brief disable channel pin + \param[in] channel: channel pin + \arg TSI_CHCFG_GxPy( x=0..5,y=0..3): pin y of group x + \param[out] none + \retval none +*/ +void tsi_channel_pin_disable(uint32_t channel) +{ + TSI_CHCFG &= ~channel; +} + +/*! + \brief configure charge plus and transfer plus + \param[in] prescaler: CTCLK clock division factor + \arg TSI_CTCDIV_DIV1: fCTCLK = fHCLK + \arg TSI_CTCDIV_DIV2: fCTCLK = fHCLK/2 + \arg TSI_CTCDIV_DIV4: fCTCLK = fHCLK/4 + \arg TSI_CTCDIV_DIV8: fCTCLK = fHCLK/6 + \arg TSI_CTCDIV_DIV16: fCTCLK = fHCLK/8 + \arg TSI_CTCDIV_DIV32: fCTCLK = fHCLK/32 + \arg TSI_CTCDIV_DIV64: fCTCLK = fHCLK/64 + \arg TSI_CTCDIV_DIV128: fCTCLK = fHCLK/128 + \param[in] charge_duration: charge state duration time + \arg TSI_CHARGE_xCTCLK(x=1..16): the duration time of charge state is x CTCLK + \param[in] transfer_duration: charge transfer state duration time + \arg TSI_TRANSFER_xCTCLK(x=1..16): the duration time of transfer state is x CTCLK + \param[out] none + \retval none +*/ +void tsi_plus_config(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + uint32_t ctl; + ctl = TSI_CTL; + /*configure TSI clock division factor,charge state duration time,charge transfer state duration time */ + ctl &= ~(TSI_CTL_CTCDIV|TSI_CTL_CTDT|TSI_CTL_CDT); + ctl |= (prescaler|charge_duration|transfer_duration); + TSI_CTL = ctl; + } +} + +/*! + \brief configure TSI triggering by software + \param[in] none + \param[out] none + \retval none +*/ +void tsi_sofeware_mode_config(void) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + TSI_CTL &= ~TSI_CTL_TRGMOD; + } +} + +/*! + \brief configure TSI triggering by hardware + \param[in] trigger_edge: the edge type in hardware trigger mode + \arg TSI_FALLING_TRIGGER: falling edge trigger TSI charge transfer sequence + \arg TSI_RISING_TRIGGER: rising edge trigger TSI charge transfer sequence + \param[out] none + \retval none +*/ +void tsi_hardware_mode_config(uint8_t trigger_edge) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + /*enable hardware mode*/ + TSI_CTL |= TSI_CTL_TRGMOD; + /*configure the edge type in hardware trigger mode*/ + if(TSI_FALLING_TRIGGER == (uint32_t)trigger_edge){ + TSI_CTL &= ~TSI_CTL_EGSEL; + }else{ + TSI_CTL |= TSI_CTL_EGSEL; + } + } +} + +/*! + \brief configure TSI pin mode when charge-transfer sequence is IDLE + \param[in] pin_mode: pin mode when charge-transfer sequence is IDLE + \arg TSI_OUTPUT_LOW: TSI pin will output low when IDLE + \arg TSI_INPUT_FLOATING: TSI pin will keep input_floating when IDLE + \param[out] none + \retval none +*/ +void tsi_pin_mode_config(uint8_t pin_mode) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + if(TSI_OUTPUT_LOW == pin_mode){ + TSI_CTL &= ~TSI_CTL_PINMOD; + }else{ + TSI_CTL |= TSI_CTL_PINMOD; + } + } +} + +/*! + \brief configure the max cycle number of a charge-transfer sequence + \param[in] max_number: max cycle number + \arg TSI_MAXNUM255: the max cycle number of a sequence is 255 + \arg TSI_MAXNUM511: the max cycle number of a sequence is 511 + \arg TSI_MAXNUM1023: the max cycle number of a sequence is 1023 + \arg TSI_MAXNUM2047: the max cycle number of a sequence is 2047 + \arg TSI_MAXNUM4095: the max cycle number of a sequence is 4095 + \arg TSI_MAXNUM8191: the max cycle number of a sequence is 8191 + \arg TSI_MAXNUM16383: the max cycle number of a sequence is 16383 + \param[out] none + \retval none +*/ +void tsi_max_number_config(uint32_t max_number) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + uint32_t maxnum; + maxnum = TSI_CTL; + /*configure the max cycle number of a charge-transfer sequence*/ + maxnum &= ~TSI_CTL_MCN; + maxnum |= max_number; + TSI_CTL = maxnum; + } +} + +/*! + \brief start a charge-transfer sequence when TSI is in software trigger mode + \param[in] none + \param[out] none + \retval none +*/ +void tsi_software_start(void) +{ + TSI_CTL |= TSI_CTL_TSIS; +} + +/*! + \brief stop a charge-transfer sequence when TSI is in software trigger mode + \param[in] none + \param[out] none + \retval none +*/ +void tsi_software_stop(void) +{ + TSI_CTL &= ~TSI_CTL_TSIS; +} + +/*! + \brief enable TSI module + \param[in] none + \param[out] none + \retval none +*/ +void tsi_enable(void) +{ + TSI_CTL |= TSI_CTL_TSIEN; +} + +/*! + \brief disable TSI module + \param[in] none + \param[out] none + \retval none +*/ +void tsi_disable(void) +{ + TSI_CTL &= ~TSI_CTL_TSIEN; +} + +/*! + \brief configure extend charge state + \param[in] extend: enable or disable extend charge state + \arg ENABLE: enable extend charge state + \arg DISABLE: disable extend charge state + \param[in] prescaler: ECCLK clock division factor + \arg TSI_EXTEND_DIV1: fECCLK = fHCLK + \arg TSI_EXTEND_DIV2: fECCLK = fHCLK/2 + \param[in] max_duration: value range 1...128,extend charge state maximum duration time is 1*tECCLK~128*tECCLK + \param[out] none + \retval none +*/ +void tsi_extend_charge_config(ControlStatus extend,uint8_t prescaler,uint32_t max_duration) +{ + if(RESET == (TSI_CTL & TSI_CTL_TSIS)){ + uint32_t ctl; + if(DISABLE == extend){ + /*disable extend charge state*/ + TSI_CTL &= ~TSI_CTL_ECEN; + }else{ + /*configure extend charge state maximum duration time*/ + ctl = TSI_CTL; + ctl &= ~TSI_CTL_ECDT; + ctl |= TSI_EXTENDMAX((uint32_t)(max_duration-1U)); + TSI_CTL = ctl; + /*configure ECCLK clock division factor*/ + if(TSI_EXTEND_DIV1 == prescaler){ + TSI_CTL &= ~TSI_CTL_ECDIV; + }else{ + TSI_CTL |= TSI_CTL_ECDIV; + } + /*enable extend charge state*/ + TSI_CTL |= TSI_CTL_ECEN; + } + } +} + +/*! + \brief enable TSI interrupt + \param[in] source: select interrupt which will be enabled + \arg TSI_INT_CTCF: charge-transfer complete flag interrupt enable + \arg TSI_INTEN_MNERR: max cycle number error interrupt enable + \param[out] none + \retval none +*/ +void tsi_interrupt_enable(uint32_t source) +{ + TSI_INTEN |= source; +} + +/*! + \brief disable TSI interrupt + \param[in] source: select interrupt which will be disabled + \arg TSI_INT_CTCF: charge-transfer complete flag interrupt disable + \arg TSI_INTEN_MNERR: max cycle number error interrupt disable + \param[out] none + \retval none +*/ +void tsi_interrupt_disable(uint32_t source) +{ + TSI_INTEN &= ~source; +} + +/*! + \brief clear flag + \param[in] source: select flag which will be cleared + \arg TSI_INT_FLAG_CTC: clear charge-transfer complete flag + \arg TSI_INT_FLAG_MNERR: clear max cycle number error + \param[out] none + \retval none +*/ +void tsi_interrupt_flag_clear(uint32_t flag) +{ + TSI_INTC |= flag; +} + +/*! + \brief get TSI module current status + \param[in] status: + \arg TSI_INT_FLAG_CTC: charge-transfer complete flag + \arg TSI_INT_FLAG_MNERR: max Cycle Number Error + \param[out] none + \retval FlagStatus:SET or RESET +*/ +FlagStatus tsi_interrupt_flag_get(uint32_t status) +{ + if(TSI_INTF & status){ + return SET; + } else { + return RESET; + } +} + +/*! + \brief switch on hysteresis pin + \param[in] group_pin: select pin which will be switched on hysteresis + \arg TSI_PHM_GxPy(x=0..5,y=0..3): pin y of group x switch on hysteresis + \param[out] none + \retval none +*/ +void tsi_hysteresis_on(uint32_t group_pin) +{ + TSI_PHM |= group_pin; +} + +/*! + \brief switch off hysteresis pin + \param[in] group_pin: select pin which will be switched off hysteresis + \arg TSI_PHM_GxPy(x=0..5,y=0..3): pin y of group x switch off hysteresis + \param[out] none + \retval none +*/ +void tsi_hysteresis_off(uint32_t group_pin) +{ + TSI_PHM &= ~group_pin; +} + +/*! + \brief switch on analog pin + \param[in] group_pin: select pin which will be switched on analog + \arg TSI_ASW_GxPy(x=0..5,y=0..3):pin y of group x switch on analog + \param[out] none + \retval none +*/ +void tsi_analog_on(uint32_t group_pin) +{ + TSI_ASW |= group_pin; +} + +/*! + \brief switch off analog pin + \param[in] group_pin: select pin which will be switched off analog + \arg TSI_ASW_GxPy(x=0..5,y=0..3):pin y of group x switch off analog + \param[out] none + \retval none +*/ +void tsi_analog_off(uint32_t group_pin) +{ + TSI_ASW &= ~group_pin; +} + +/*! + \brief enbale group + \param[in] group: select group to be enabled + \arg TSI_GCTL_GEx(x=0..5): the x group will be enabled + \param[out] none + \retval none +*/ +void tsi_group_enable(uint32_t group) +{ + TSI_GCTL |= group; +} + +/*! + \brief disbale group + \param[in] group: select group to be disabled + \arg TSI_GCTL_GEx(x=0..5):the x group will be disabled + \param[out] none + \retval none +*/ +void tsi_group_disable(uint32_t group) +{ + TSI_GCTL &= ~group; +} + +/*! + \brief get group complete status + \param[in] group: select group + \arg TSI_GCTL_GCx(x=0..5): get the complete status of group x + \param[out] none + \retval FlagStatus: group complete status,SET or RESET +*/ +FlagStatus tsi_group_status_get(uint32_t group) +{ + if(TSI_GCTL & group){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get the cycle number for group0 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group0 cycle number +*/ +uint16_t tsi_group0_cycle_get(void) +{ + return (uint16_t)TSI_G0CYCN; +} + +/*! + \brief get the cycle number for group1 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group1 cycle number +*/ +uint16_t tsi_group1_cycle_get(void) +{ + return (uint16_t)TSI_G1CYCN; +} + +/*! + \brief get the cycle number for group2 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group2 cycle number +*/ +uint16_t tsi_group2_cycle_get(void) +{ + return (uint16_t)TSI_G2CYCN; +} + +/*! + \brief get the cycle number for group3 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group3 cycle number +*/ +uint16_t tsi_group3_cycle_get(void) +{ + return (uint16_t)TSI_G3CYCN; +} + +/*! + \brief get the cycle number for group4 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group4 cycle number +*/ +uint16_t tsi_group4_cycle_get(void) +{ + return (uint16_t)TSI_G4CYCN; +} + +/*! + \brief get the cycle number for group5 as soon as a charge-transfer sequence completes + \param[in] none + \param[out] none + \retval group5 cycle number +*/ +uint16_t tsi_group5_cycle_get(void) +{ + return (uint16_t)TSI_G5CYCN; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_usart.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_usart.c new file mode 100644 index 0000000..08410fd --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_usart.c @@ -0,0 +1,1162 @@ +/*! + \file gd32f1x0_usart.c + \brief USART driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.1, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_usart.h" +#include "gd32f1x0_rcu.h" + +/*! + \brief reset USART + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_deinit(uint32_t usart_periph) +{ + switch(usart_periph){ + case USART0: + rcu_periph_reset_enable(RCU_USART0RST); + rcu_periph_reset_disable(RCU_USART0RST); + break; + case USART1: + rcu_periph_reset_enable(RCU_USART1RST); + rcu_periph_reset_disable(RCU_USART1RST); + break; + default: + break; + } +} + +/*! + \brief configure USART baud rate value + \param[in] usart_periph: USARTx(x=0,1) + \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){ + case USART0: + uclk = rcu_clock_freq_get(CK_USART); + break; + case USART1: + uclk = rcu_clock_freq_get(CK_APB1); + break; + default: + break; + } + if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD){ + /* when oversampling by 8,configure the value of USART_BAUD */ + udiv = ((2U*uclk)+baudval/2U)/baudval; + intdiv = udiv & 0xfff0U; + fradiv = (udiv>>1U) & 0x7U; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + }else{ + /* when oversampling by 16,configure the value of USART_BAUD */ + udiv = (uclk+baudval/2U)/baudval; + intdiv = udiv & 0xfff0U; + fradiv = udiv & 0xfU; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } +} + +/*! + \brief configure USART parity + \param[in] usart_periph: USARTx(x=0,1) + \param[in] paritycfg: USART parity configure + \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) + \param[in] wlen: USART word length configure + \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) + \param[in] stblen: USART stop bit configure + \arg USART_STB_1BIT: 1 bit + \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) + \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) + \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) + \param[in] txconfig: enable or disable USART transmitter + \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) + \param[in] rxconfig: enable or disable USART receiver + \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 USART transmit data function + \param[in] usart_periph: USARTx(x=0,1) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void usart_data_transmit(uint32_t usart_periph, uint32_t data) +{ + USART_TDATA(usart_periph) = (USART_TDATA_TDATA & data); +} + +/*! + \brief USART receive data function + \param[in] usart_periph: USARTx(x=0,1) + \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 data is transmitted/received with the LSB/MSB first + \param[in] usart_periph: USARTx(x=0,1) + \param[in] msbf: LSB/MSB + \arg USART_MSBF_LSB: LSB first + \arg USART_MSBF_MSB: MSB first + \param[out] none + \retval none +*/ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* configure LSB or MSB first */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_MSBF); + USART_CTL1(usart_periph) |= (USART_CTL1_MSBF & msbf) ; +} + +/*! + \brief USART inverted configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] invertpara: refer to usart_invert_enum + \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_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_TINV); + break; + case USART_RXPIN_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_RINV); + break; + case USART_SWAP_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_STRP); + break; + case USART_TXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_TINV; + break; + case USART_RXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_RINV; + break; + case USART_SWAP_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_STRP; + break; + default: + break; + } +} + +/*! + \brief overrun function is enabled + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_overrun_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_OVRD); +} + +/*! + \brief overrun function is disabled + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_overrun_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) |= USART_CTL2_OVRD; +} + +/*! + \brief configure the USART oversample mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] oversamp: oversample value + \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 sample bit method configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] osb: sample bit + \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 auto baud rate detection enable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_autobaud_detection_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_ABDEN; +} + +/*! + \brief auto baud rate detection disable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_autobaud_detection_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDEN); +} + +/*! + \brief auto baud rate detection mode configure + \param[in] usart_periph: USARTx(x=0) + \param[in] abdmod: auto baud rate detection mode + \arg USART_ABDM_FTOR: falling edge to rising edge measurement + \arg USART_ABDM_FTOF: falling edge to falling edge measurement + \param[out] none + \retval none +*/ +void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod) +{ + /* reset ABDM bits */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDM); + USART_CTL1(usart_periph) |= (abdmod); +} + +/*! + \brief mute mode enable + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_mute_mode_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_MEN; +} + +/*! + \brief mute mode disable + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_mute_mode_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_MEN); +} + +/*! + \brief wakeup method in mute mode configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] wmethod: two methods be used to enter or exit the mute mode + \arg USART_WM_IDLE: idle line + \arg USART_WM_ADDR: address mark + \param[out] none + \retval none +*/ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL0(usart_periph) &= ~(USART_CTL0_WM); + USART_CTL0(usart_periph) |= wmethod; +} + +/*! + \brief address detection mode configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] addmod: address detection mode + \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 address of the USART terminal + \param[in] usart_periph: USARTx(x=0,1) + \param[in] addr: 0x00-0xFF, address of USART terminal + \param[out] none + \retval none +*/ +void usart_address_config(uint32_t usart_periph, uint8_t addr) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & (((uint32_t)addr) << 24)); +} + +/*! + \brief receiver timeout enable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_RTEN; +} + +/*! + \brief receiver timeout disable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_RTEN); +} + +/*! + \brief receiver timeout threshold configure + \param[in] usart_periph: USARTx(x=0) + \param[in] rtimeout: 0x000000-0xFFFFFF, receiver timeout value in terms of number of baud clocks + \param[out] none + \retval none +*/ +void usart_receiver_timeout_config(uint32_t usart_periph, uint32_t rtimeout) +{ + USART_RT(usart_periph) &= ~(USART_RT_RT); + USART_RT(usart_periph) |= (rtimeout); +} + +/*! + \brief LIN mode enable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_lin_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_LMEN; +} + +/*! + \brief LIN mode disable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_lin_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); +} + +/*! + \brief LIN break detection length + \param[in] usart_periph: USARTx(x=0) + \param[in] lblen: LIN break detection length + \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_dection_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 & (lblen)); +} + +/*! + \brief half-duplex enable + \param[in] usart_periph: USARTx(x=0,1) + \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 half-duplex disable + \param[in] usart_periph: USARTx(x=0,1) + \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 clock enable + \param[in] usart_periph: USARTx(x=0) + \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 clock disable + \param[in] usart_periph: USARTx(x=0) + \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) + \param[in] clen: last bit clock pulse + \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 + \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 + \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 smartcard mode enable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_SCEN; +} + +/*! + \brief smartcard mode disable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN); +} + +/*! + \brief NACK enable in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_NKEN; +} + +/*! + \brief NACK disable in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN); +} + +/*! + \brief guard time value configure in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[in] guat: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_guard_time_config(uint32_t usart_periph, 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 block length configure + \param[in] usart_periph: USARTx(x=0) + \param[in] bl: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl) +{ + USART_RT(usart_periph) &= ~(USART_RT_BL); + USART_RT(usart_periph) |= (USART_RT_BL & ((bl) << 24)); +} + +/*! + \brief smartcard auto-retry number configure + \param[in] usart_periph: USARTx(x=0) + \param[in] scrtnum: 0x0-0x7, 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 IrDA mode enable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_irda_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_IREN; +} + +/*! + \brief IrDA mode disable + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_irda_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN); +} + +/*! + \brief IrDA low-power configure + \param[in] usart_periph: USARTx(x=0) + \param[in] irlp: IrDA low-power or normal + \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 & irlp); +} + +/*! + \brief configure the peripheral clock prescaler in USART IrDA low-power mode or in USART SmartCard mode + \param[in] usart_periph: USARTx(x=0) + \param[in] psc: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_prescaler_config(uint32_t usart_periph, 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 hardware flow control RTS + \param[in] usart_periph: USARTx(x=0,1) + \param[in] rtsconfig: enable or disable RTS + \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) + \param[in] ctsconfig: enable or disable CTS + \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 RS485 driver enable + \param[in] usart_periph: USARTx(x=0,1) + \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 RS485 driver disable + \param[in] usart_periph: USARTx(x=0,1) + \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 driver enable assertion time configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] deatime: 0x00-0x1F + \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 driver enable de-assertion time configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dedtime: 0x00-0x1F + \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) + \param[in] dep: DE signal + \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) + \param[in] dmacmd: enable or disable DMA for reception + \arg USART_DENR_ENABLE: DMA enable for reception + \arg USART_DENR_DISABLE: DMA disable for reception + \param[out] none + \retval none +*/ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~USART_CTL2_DENR; + /* configure DMA reception */ + USART_CTL2(usart_periph) |= dmacmd; +} + +/*! + \brief configure USART DMA transmission + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dmacmd: enable or disable DMA for transmission + \arg USART_DENT_ENABLE: DMA enable for transmission + \arg USART_DENT_DISABLE: DMA disable for transmission + \param[out] none + \retval none +*/ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~USART_CTL2_DENT; + /* configure DMA transmission */ + USART_CTL2(usart_periph) |= dmacmd; +} + +/*! + \brief disable DMA on reception error + \param[in] usart_periph: USARTx(x=0,1) + \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) + \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 USART be able to wake up the MCU from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_wakeup_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UESM; +} + +/*! + \brief USART be not able to wake up the MCU from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_wakeup_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UESM); +} + +/*! + \brief wakeup mode from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[in] wum: wakeup mode + \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 get flag in STAT register + \param[in] usart_periph: USARTx(x=0,1) + \param[in] flag: flag type + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise error flag + \arg USART_FLAG_ORERR: overrun error + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_TC: transmission completed + \arg USART_FLAG_TBE: transmit data register empty + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_CTS: CTS level + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_ABDE: auto baudrate detection error + \arg USART_FLAG_ABD: auto baudrate detection flag + \arg USART_FLAG_BSY: busy flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_SB: send break flag + \arg USART_FLAG_RWU: receiver wakeup from mute mode. + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_FLAG_TEA: transmit enable acknowledge flag + \arg USART_FLAG_REA: receive enable acknowledge 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) + \param[in] flag: flag type + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise detected flag + \arg USART_FLAG_ORERR:overrun error flag + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_TC: transmission complete flag + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \param[out] none + \retval none +*/ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) +{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS(flag)); +} + +/*! + \brief enable USART interrupt + \param[in] usart_periph: USARTx(x=0,1) + \param[in] inttype: interrupt type + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and + overrun error interrupt enable interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \param[out] none + \retval none +*/ +void usart_interrupt_enable(uint32_t usart_periph, uint32_t inttype) +{ + USART_REG_VAL(usart_periph, inttype) |= BIT(USART_BIT_POS(inttype)); +} + +/*! + \brief disable USART interrupt + \param[in] usart_periph: USARTx(x=0,1) + \param[in] inttype: interrupt type + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and + overrun error interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \param[out] none + \retval none +*/ +void usart_interrupt_disable(uint32_t usart_periph, uint32_t inttype) +{ + USART_REG_VAL(usart_periph, inttype) &= ~BIT(USART_BIT_POS(inttype)); +} + +/*! + \brief enable USART command + \param[in] usart_periph: USARTx(x=0,1) + \param[in] cmdtype: command type + \arg USART_CMD_ABDCMD: auto baudrate detection command + \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 get USART interrupt and flag status + \param[in] usart_periph: USARTx(x=0,1) + \param[in] int_flag: interrupt and flag type, refer to usart_interrupt_flag_enum + \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 + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t 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 in STAT register + \param[in] usart_periph: USARTx(x=0,1) + \param[in] flag: USART interrupt flag + \arg USART_INT_FLAG_PERR: parity error flag + \arg USART_INT_FLAG_FERR: frame error flag + \arg USART_INT_FLAG_NERR: noise detected flag + \arg USART_INT_FLAG_ORERR:overrun error flag + \arg USART_INT_FLAG_IDLE: idle line detected flag + \arg USART_INT_FLAG_TC: transmission complete flag + \arg USART_INT_FLAG_LBD: LIN break detected flag + \arg USART_INT_FLAG_CTS: CTS change flag + \arg USART_INT_FLAG_RT: receiver timeout flag + \arg USART_INT_FLAG_EB: end of block flag + \arg USART_INT_FLAG_AM: address match flag + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode flag + \param[out] none + \retval none +*/ +void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t flag) +{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS2(flag)); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_wwdgt.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_wwdgt.c new file mode 100644 index 0000000..7a762cc --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_standard_peripheral/Source/gd32f1x0_wwdgt.c @@ -0,0 +1,121 @@ +/*! + \file gd32f1x0_wwdgt.c + \brief WWDGT driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9) +*/ + +#include "gd32f1x0_wwdgt.h" +#include "gd32f1x0_rcu.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 configure the window watchdog timer counter value + \param[in] counter_value: 0x00 - 0x7F + \param[out] none + \retval none +*/ +void wwdgt_counter_update(uint16_t counter_value) +{ + uint32_t reg = 0U; + + reg = WWDGT_CTL & (~WWDGT_CTL_CNT); + reg |= (uint32_t)(CTL_CNT((uint32_t)counter_value)); + + WWDGT_CTL = (uint32_t)reg; +} + +/*! + \brief start the window watchdog timer counter + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_enable(void) +{ + WWDGT_CTL |= WWDGT_CTL_WDGTEN; +} + +/*! + \brief configure counter value, window value, and prescaler divider value + \param[in] counter: 0x00 - 0x7F + \param[in] window: 0x00 - 0x7F + \param[in] prescaler: wwdgt prescaler value + \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) +{ + uint32_t reg_cfg = 0U, reg_ctl = 0U; + + /* clear WIN and PSC bits, clear CNT bit */ + reg_cfg = WWDGT_CFG &(~(WWDGT_CFG_WIN | WWDGT_CFG_PSC)); + reg_ctl = WWDGT_CTL &(~(uint32_t)WWDGT_CTL_CNT); + + /* configure WIN and PSC bits, configure CNT bit */ + reg_cfg |= (uint32_t)(CFG_WIN(window)); + reg_cfg |= (uint32_t)(prescaler); + reg_ctl |= (uint32_t)(CTL_CNT(counter)); + + WWDGT_CFG = (uint32_t)reg_cfg; + WWDGT_CTL = (uint32_t)reg_ctl; +} + +/*! + \brief enable early wakeup interrupt of WWDGT + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_interrupt_enable(void) +{ + WWDGT_CFG |= WWDGT_CFG_EWIE; +} + +/*! + \brief check early wakeup interrupt state of WWDGT + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus wwdgt_flag_get(void) +{ + if(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)(~(uint32_t)WWDGT_STAT_EWIF); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_core.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_core.h new file mode 100644 index 0000000..1f2c777 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_core.h @@ -0,0 +1,183 @@ +/*! + \file usbd_core.h + \brief usb device driver core +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5) +*/ + +#ifndef USBD_CORE_H +#define USBD_CORE_H + +#include "usbd_conf.h" +#include "usbd_regs.h" + +/* interrupt flag mask which decide what event should be handled by application */ +#define IER_MASK (CTL_STIE | CTL_WKUPIE | CTL_SPSIE | CTL_SOFIE \ + | CTL_ESOFIE | CTL_RSTIE) + +/* USB device endpoint0 max packet size */ +#define USBD_EP0_MAX_SIZE 64U + +#define USBD_CONTRL_STATUS_TX() do \ +{ \ + pbuf_reg->tx_count = 0U; \ + USBD_ENDP_TX_STATUS_SET(EP0, EPTX_VALID); \ +} while(0) + +#define USBD_CONTRL_STATUS_RX() do \ +{ \ + USBD_STATUS_OUT_SET(EP0); \ + USBD_ENDP_RX_STATUS_SET(EP0, EPRX_VALID); \ +} while(0) + +#define ENDP_BUF_ADDR (uint32_t)(sizeof(usbd_ep_buf_struct) * EP_COUNT) + +/* USB device endpoint type */ +typedef enum +{ + ENDP_CONTROL = 0, /*!< control endpoint type value */ + ENDP_ISOC, /*!< isochronous endpoint type value */ + ENDP_BULK, /*!< bulk endpoint type value */ + ENDP_INT /*!< interupt endpoint type value */ +}usbd_eptype_enum; + +/* USB device endpoint kind */ +typedef enum +{ + ENDP_SNG_BUF = 0, /*!< single buffer endpoint type value */ + ENDP_DBL_BUF /*!< double buffer endpoint type value */ +}usbd_epkind_enum; + +/* transfer direction */ +typedef enum +{ + USBD_RX = 0, /*!< receive direction type value */ + USBD_TX /*!< transmit direction type value */ +}usbd_dir_enum; + +/* USB device status */ +typedef enum +{ + USBD_UNCONNECTED = 0, /*!< USB device unconnected status */ + USBD_DEFAULT, /*!< USB device default status */ + USBD_ADDRESSED, /*!< USB device addressed status */ + USBD_CONFIGURED, /*!< USB device configured status */ + USBD_SUSPENDED, /*!< USB device suspended status */ + USBD_CONNECTED /*!< USB device connected status */ +}usbd_run_status_enum; + +/* USB device operation state */ +typedef enum +{ + USBD_OK = 0, /*!< USB device ok */ + USBD_BUSY, /*!< USB device busy */ + USBD_FAIL /*!< USB device fail */ +}usbd_status_enum; + +typedef struct +{ + uint16_t tx_addr; /*!< transmission address */ + uint16_t reserved0; + uint16_t tx_count; /*!< transmission count */ + uint16_t reserved1; + uint16_t rx_addr; /*!< reception address */ + uint16_t reserved2; + uint16_t rx_count; /*!< reception count */ + uint16_t reserved3; +}usbd_ep_buf_struct; + +/* USB endpoint structure */ +typedef struct +{ + /* basic parameters */ + uint8_t stall; /*!< endpoint stall status */ + uint32_t maxpacket; /*!< the maxpacket of the endpoint */ + + /* transaction level parameters */ + uint8_t *trs_buf; /*!< transaction buffer address */ + uint32_t trs_len; /*!< transaction buffer length */ + uint32_t trs_count; /*!< transaction data counts */ +}usb_ep_struct; + +/* USB standard device request structure */ +typedef struct +{ + uint8_t bmRequestType; /*!< the property of the request */ + uint8_t bRequest; /*!< the code of the request */ + uint16_t wValue; /*!< the value of the request which used to choose the different request in the same code request */ + uint16_t wIndex; /*!< USB standard device request index */ + uint16_t wLength; /*!< the return datas length that the host wants to get */ +}usb_device_req_struct; + +/* USB core driver struct */ +typedef struct +{ + /* basic parameters */ + uint8_t config_num; /*!< the number of the USB device configuration */ + __IO uint8_t status; /*!< USB device status */ + uint8_t prev_status; /*!< the previous USB device status */ + uint8_t remote_wakeup; /*!< the flag that point out the device whether support the + remte wakeup function */ + + /* the parameters which needs in control transfer */ + uint8_t setup_packet[8]; /*!< the buffer used to store the setup packet */ + uint32_t ctl_count; /*!< the datas length of control transfer request */ + + /* device endpoints */ + usb_ep_struct in_ep[EP_COUNT]; /*!< the IN direction endpoints */ + usb_ep_struct out_ep[EP_COUNT]; /*!< the OUT direction endpoints */ + + uint8_t *dev_desc; /*!< device descriptor */ + uint8_t *config_desc; /*!< configuration descriptor */ + void* const *strings; /*!< configuration strings */ + + /* device class handler */ + usbd_status_enum (*class_init) (void *pudev, uint8_t config_index); + usbd_status_enum (*class_deinit) (void *pudev, uint8_t config_index); + usbd_status_enum (*class_req_handler) (void *pudev, usb_device_req_struct *req); + usbd_status_enum (*class_data_handler) (void *pudev, usbd_dir_enum rx_tx, uint8_t ep_num); +}usbd_core_handle_struct; + +extern uint32_t g_free_buf_addr; +extern usbd_ep_buf_struct *pbuf_reg; + +/* function declarations */ +/* device core register initialization */ +void usbd_core_init (usbd_core_handle_struct *pudev); +/* device core register configure when stop device */ +void usbd_core_deinit (void); + +/* free buffer used from application by toggling the SW_BUF byte */ +void user_buffer_free (uint8_t ep_num, uint8_t dir); + +/* endpoint initialization */ +void usbd_ep_init (usbd_core_handle_struct *pudev, usbd_epkind_enum buf_kind, const void *ep_desc); +/* configure the endpoint when it is disabled */ +void usbd_ep_deinit (usbd_core_handle_struct *pudev, uint8_t ep_addr); +/* endpoint prepare to transmit data */ +void usbd_ep_tx (usbd_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len); +/* endpoint prepare to receive data */ +void usbd_ep_rx (usbd_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len); +/* set an endpoint to STALL status */ +void usbd_ep_stall (usbd_core_handle_struct *pudev, uint8_t ep_addr); +/* clear endpoint stalled status */ +void usbd_ep_clear_stall (usbd_core_handle_struct *pudev, uint8_t ep_addr); +/* write datas from user fifo to USBRAM */ +void usbd_ep_data_write (uint8_t *user_fifo, uint16_t usbram_addr, uint16_t bytes); +/* read datas from USBRAM to user fifo */ +void usbd_ep_data_read (uint8_t *user_fifo, uint16_t usbram_addr, uint16_t bytes); + +/* get the endpoint status */ +uint8_t usbd_ep_status_get (usbd_core_handle_struct *pudev, uint8_t ep_addr); + +/* get the received data length */ +uint16_t usbd_rx_count_get (usbd_core_handle_struct *pudev, uint8_t ep_num); + +#endif /* USBD_CORE_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_int.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_int.h new file mode 100644 index 0000000..545c7db --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_int.h @@ -0,0 +1,37 @@ +/*! + \file usbd_int.h + \brief usb device interrupt handler header file +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5) +*/ + +#ifndef USBD_INT_H +#define USBD_INT_H + +#include "usbd_core.h" +#include "usbd_std.h" +#include "usbd_pwr.h" + +extern usbd_core_handle_struct usb_device_dev; + +typedef struct +{ + uint8_t (*SOF) (usbd_core_handle_struct *pudev); /*!< SOF ISR callback */ +}usbd_int_cb_struct; + +extern usbd_int_cb_struct *usbd_int_fops; + +/* function declarations */ +/* USB device interrupt service routine */ +void usbd_isr (void); +/* handle USB high priority successful transfer event */ +uint8_t usbd_intf_hpst (usbd_core_handle_struct *pudev); + +#endif /* USBD_INT_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_pwr.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_pwr.h new file mode 100644 index 0000000..d57a2b1 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_pwr.h @@ -0,0 +1,28 @@ +/*! + \file usbd_pwr.h + \brief USB device power management functions prototype +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5) +*/ + +#ifndef USBD_PWR_H +#define USBD_PWR_H + +#include "usbd_core.h" + +/* function declarations */ +/* USB wakeup first operation is to wakeup mcu */ +void resume_mcu (void); +/* set USB device to suspend mode */ +void usbd_suspend (void); +/* start to remote wakeup */ +void usbd_remote_wakeup_active (void); + +#endif /* USBD_PWR_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_regs.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_regs.h new file mode 100644 index 0000000..cf76af1 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_regs.h @@ -0,0 +1,272 @@ +/*! + \file usbd_regs.h + \brief usb device registers +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5) +*/ + +#ifndef USBD_REGS_H +#define USBD_REGS_H + +#include "usbd_conf.h" + +/* USB device registers base address */ +#define USBD USBD_BASE +#define USBD_RAM USBD_RAM_BASE + +/* registers definitions */ +/* common registers */ +#define USBD_CTL (REG32(USBD + 0x40U)) /*!< control register */ +#define USBD_INTF (REG32(USBD + 0x44U)) /*!< interrupt flag register */ +#define USBD_STAT (REG32(USBD + 0x48U)) /*!< status register */ +#define USBD_DADDR (REG32(USBD + 0x4CU)) /*!< device address register */ +#define USBD_BADDR (REG32(USBD + 0x50U)) /*!< buffer address register */ + +/* endpoint control and status register */ +#define USBD_EPxCS(ep_num) (REG32(USBD + (ep_num) * 4U)) /*!< endpoint x control and status register address */ + +/* bits definitions */ +/* USBD_CTL */ +#define CTL_STIE BIT(15) /*!< successful transfer interrupt enable mask */ +#define CTL_PMOUIE BIT(14) /*!< packet memory overrun/underrun interrupt enable mask */ +#define CTL_ERRIE BIT(13) /*!< error interrupt enable mask */ +#define CTL_WKUPIE BIT(12) /*!< wakeup interrupt enable mask */ +#define CTL_SPSIE BIT(11) /*!< suspend state interrupt enable mask */ +#define CTL_RSTIE BIT(10) /*!< reset interrupt enable mask */ +#define CTL_SOFIE BIT(9) /*!< start of frame interrupt enable mask */ +#define CTL_ESOFIE BIT(8) /*!< expected start of frame interrupt enable mask */ +#define CTL_RSREQ BIT(4) /*!< resume request */ +#define CTL_SETSPS BIT(3) /*!< set suspend state */ +#define CTL_LOWM BIT(2) /*!< low-power mode at suspend state */ +#define CTL_CLOSE BIT(1) /*!< goes to close state */ +#define CTL_SETRST BIT(0) /*!< set USB reset */ + +/* USBD_INTF */ +#define INTF_STIF BIT(15) /*!< successful transfer interrupt flag (read only bit) */ +#define INTF_PMOUIF BIT(14) /*!< packet memory overrun/underrun interrupt flag (clear-only bit) */ +#define INTF_ERRIF BIT(13) /*!< error interrupt flag (clear-only bit) */ +#define INTF_WKUPIF BIT(12) /*!< wakeup interrupt flag (clear-only bit) */ +#define INTF_SPSIF BIT(11) /*!< suspend state interrupt flag (clear-only bit) */ +#define INTF_RSTIF BIT(10) /*!< reset interrupt flag (clear-only bit) */ +#define INTF_SOFIF BIT(9) /*!< start of frame interrupt flag (clear-only bit) */ +#define INTF_ESOFIF BIT(8) /*!< expected start of frame interrupt flag(clear-only bit) */ +#define INTF_DIR BIT(4) /*!< direction of transaction (read-only bit) */ +#define INTF_EPNUM BITS(0, 3) /*!< endpoint number (read-only bit) */ + +/* USBD_STAT */ +#define STAT_RXDP BIT(15) /*!< data plus line status */ +#define STAT_RXDM BIT(14) /*!< data minus line status */ +#define STAT_LOCK BIT(13) /*!< locked the USB */ +#define STAT_SOFLN BITS(11, 12) /*!< SOF lost number */ +#define STAT_FCNT BITS(0, 10) /*!< frame number count */ + +/* USBD_DADDR */ +#define DADDR_USBEN BIT(7) /*!< USB module enable */ +#define DADDR_USBDADDR BITS(0, 6) /*!< USB device address */ + +/* USBD_EPxCS */ +#define EPxCS_RX_ST BIT(15) /*!< endpoint reception successful transferred */ +#define EPxCS_RX_DTG BIT(14) /*!< endpoint reception data PID toggle */ +#define EPxCS_RX_STA BITS(12, 13) /*!< endpoint reception status bits */ +#define EPxCS_SETUP BIT(11) /*!< endpoint setup transaction completed */ +#define EPxCS_CTL BITS(9, 10) /*!< endpoint type control */ +#define EPxCS_KCTL BIT(8) /*!< endpoint kind control */ +#define EPxCS_TX_ST BIT(7) /*!< endpoint transmission successful transfer */ +#define EPxCS_TX_DTG BIT(6) /*!< endpoint transmission data toggle */ +#define EPxCS_TX_STA BITS(4, 5) /*!< endpoint transmission transfers status bits */ +#define EPxCS_ADDR BITS(0, 3) /*!< endpoint address */ + +/* constants definitions */ +/* endpoint control and status register mask (no toggle fields) */ +#define EPCS_MASK (EPxCS_RX_ST|EPxCS_SETUP|EPxCS_CTL|EPxCS_KCTL|EPxCS_TX_ST|EPxCS_ADDR) + +/* EPxCS_CTL[1:0] endpoint type control */ +#define ENDP_TYPE(regval) (EPxCS_CTL & ((regval) << 9U)) + +#define EP_BULK ENDP_TYPE(0U) /* bulk transfers */ +#define EP_CONTROL ENDP_TYPE(1U) /* control transfers */ +#define EP_ISO ENDP_TYPE(2U) /* isochronous transfers */ +#define EP_INTERRUPT ENDP_TYPE(3U) /* interrupt transfers */ +#define EP_CTL_MASK (~EPxCS_CTL & EPCS_MASK) + +/* endpoint kind control mask */ +#define EPKCTL_MASK (~EPxCS_KCTL & EPCS_MASK) + +/* EPxCS_TX_STA[1:0] status for Tx transfer */ +#define ENDP_TXSTAT(regval) (EPxCS_TX_STA & ((regval) << 4U)) + +#define EPTX_DISABLED ENDP_TXSTAT(0U) /* transmission state is disabled */ +#define EPTX_STALL ENDP_TXSTAT(1U) /* transmission state is STALL */ +#define EPTX_NAK ENDP_TXSTAT(2U) /* transmission state is NAK */ +#define EPTX_VALID ENDP_TXSTAT(3U) /* transmission state is enabled */ +#define EPTX_DTGMASK (EPxCS_TX_STA | EPCS_MASK) + +/* EPxCS_RX_STA[1:0] status for Rx transfer */ +#define ENDP_RXSTAT(regval) (EPxCS_RX_STA & ((regval) << 12U)) + +#define EPRX_DISABLED ENDP_RXSTAT(0U) /* reception state is disabled */ +#define EPRX_STALL ENDP_RXSTAT(1U) /* reception state is STALL */ +#define EPRX_NAK ENDP_RXSTAT(2U) /* reception state is NAK */ +#define EPRX_VALID ENDP_RXSTAT(3U) /* reception state is enabled */ +#define EPRX_DTGMASK (EPxCS_RX_STA | EPCS_MASK) + +/* endpoint receive/transmission counter register bit definitions */ +#define EPRCNT_BLKSIZ BIT(15) /* reception data block size */ +#define EPRCNT_BLKNUM BITS(10, 14) /* reception data block number */ +#define EPRCNT_CNT BITS(0, 9) /* reception data count */ + +#define EPTCNT_CNT BITS(0, 9) /* transmisson data count */ + +/* interrupt flag clear bits */ +#define CLR_STIF (~INTF_STIF) +#define CLR_PMOUIF (~INTF_PMOUIF) +#define CLR_ERRIF (~INTF_ERRIF) +#define CLR_WKUPIF (~INTF_WKUPIF) +#define CLR_SPSIF (~INTF_SPSIF) +#define CLR_RSTIF (~INTF_RSTIF) +#define CLR_SOFIF (~INTF_SOFIF) +#define CLR_ESOFIF (~INTF_ESOFIF) + +#define ATTR_BREMOTEWAKE BIT(8) +#define ATTR_HIRD BITS(4, 7) +#define ATTR_BLINKSTATE BITS(0, 3) + +/* STAT_TX[1:0] status for Tx transfer */ +#define SUBEP_STAT(regval) (SUB_STA & ((regval) << 12)) + +#define SUBEP_DISABLE SUBEP_STAT(0) +#define SUBEP_STALL SUBEP_STAT(1) +#define SUBEP_NYET SUBEP_STAT(2) +#define SUBEP_VALID SUBEP_STAT(3) + +/* endpoint receive/transmission counter register bit offset */ +#define BLKSIZE_OFFSET (0x01U) +#define BLKNUM_OFFSET (0x05U) +#define RXCNT_OFFSET (0x0AU) + +#define TXCNT_OFFSET (0x0AU) + +#define BLKSIZE32_MASK (0x1fU) +#define BLKSIZE2_MASK (0x01U) + +#define BLKSIZE32_OFFSETMASK (0x05U) +#define BLKSIZE2_OFFSETMASK (0x01U) + +/* double buffer endpoint direction */ +typedef enum +{ + DBUF_EP_IN, /* double buffer IN direction */ + DBUF_EP_OUT, /* double buffer OUT direction */ + DBUF_EP_ERR, /* double buffer errer direction */ +}dbuf_ep_dir_enum; + +/* endpoints address */ +/* first bit is direction(0 for Rx and 1 for Tx) */ +#define EP0_OUT ((uint8_t)0x00) /* OUT endpoint 0 address */ +#define EP0_IN ((uint8_t)0x80) /* IN endpoint 0 address */ +#define EP1_OUT ((uint8_t)0x01) /* OUT endpoint 1 address */ +#define EP1_IN ((uint8_t)0x81) /* IN endpoint 1 address */ +#define EP2_OUT ((uint8_t)0x02) /* OUT endpoint 2 address */ +#define EP2_IN ((uint8_t)0x82) /* IN endpoint 2 address */ +#define EP3_OUT ((uint8_t)0x03) /* OUT endpoint 3 address */ +#define EP3_IN ((uint8_t)0x83) /* IN endpoint 3 address */ +#define EP4_OUT ((uint8_t)0x04) /* OUT endpoint 4 address */ +#define EP4_IN ((uint8_t)0x84) /* IN endpoint 4 address */ +#define EP5_OUT ((uint8_t)0x05) /* OUT endpoint 5 address */ +#define EP5_IN ((uint8_t)0x85) /* IN endpoint 5 address */ +#define EP6_OUT ((uint8_t)0x06) /* OUT endpoint 6 address */ +#define EP6_IN ((uint8_t)0x86) /* IN endpoint 6 address */ +#define EP7_OUT ((uint8_t)0x07) /* OUT endpoint 7 address */ +#define EP7_IN ((uint8_t)0x87) /* IN endpoint 7 address */ + +/* endpoints_Identifier */ +#define EP0 ((uint8_t)0) /* endpoint 0 ID */ +#define EP1 ((uint8_t)1) /* endpoint 1 ID */ +#define EP2 ((uint8_t)2) /* endpoint 2 ID */ +#define EP3 ((uint8_t)3) /* endpoint 3 ID */ +#define EP4 ((uint8_t)4) /* endpoint 4 ID */ +#define EP5 ((uint8_t)5) /* endpoint 5 ID */ +#define EP6 ((uint8_t)6) /* endpoint 6 ID */ +#define EP7 ((uint8_t)7) /* endpoint 7 ID */ + +/* USBD operation macros */ + +/* set register value */ +#define USBD_REG_SET(reg, regvalue) ((reg) = (uint16_t)(regvalue)) + +/* get register value */ +#define USBD_REG_GET(reg) ((uint16_t)(reg)) + +#define _EP_ADDR_SET(ep_num, addr) USBD_REG_SET(USBD_EPxCS(ep_num), (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPCS_MASK) | (addr)) + +/* Tx or Rx transfer status setting (bits EPTX_STA[1:0]) */ +#define USBD_ENDP_TX_STATUS_SET(ep_num, state) do {\ + register uint16_t _regval; \ + _regval = USBD_REG_GET(USBD_EPxCS(ep_num)) & (uint16_t)EPTX_DTGMASK;\ + USBD_REG_SET(USBD_EPxCS(ep_num), ((_regval) ^ (state))); \ +} while(0) + +#define USBD_ENDP_RX_STATUS_SET(ep_num, state) do {\ + register uint16_t _regval; \ + _regval = USBD_REG_GET(USBD_EPxCS(ep_num)) & (uint16_t)EPRX_DTGMASK;\ + USBD_REG_SET(USBD_EPxCS(ep_num), ((_regval) ^ (state))); \ +} while(0) + +/* Tx or Rx transfer status getting (bits EPxCS_RX_STA[1:0]) */ +#define USBD_ENDP_TX_STATUS_GET(ep_num) (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPxCS_TX_STA) +#define USBD_ENDP_RX_STATUS_GET(ep_num) (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPxCS_RX_STA) + +/* Rx and Tx transfer status setting (bits EPxCS_RX_STA[1:0] & EPxCS_TX_STA[1:0]) */ +#define USBD_ENDP_RX_TX_STATUS_SET(ep_num, state_rx, state_tx) do {\ + register uint16_t _regval; \ + _regval = USBD_REG_GET(USBD_EPxCS(ep_num)) & (uint16_t)(EPRX_DTGMASK | EPxCS_TX_STA) ;\ + USBD_REG_SET(USBD_EPxCS(ep_num), (((_regval) ^ (state_rx)) ^ (state_tx))); \ +} while(0) + +/* set and clear endpoint kind (bit EPxCS_KCTL) */ +#define USBD_ENDP_KIND_SET(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), ((USBD_REG_GET(USBD_EPxCS(ep_num)) | EPxCS_KCTL) & EPCS_MASK))) +#define USBD_ENDP_KIND_CLEAR(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPKCTL_MASK))) + +/* set and clear directly STATUS_OUT state of endpoint */ +#define USBD_STATUS_OUT_SET(ep_num) USBD_ENDP_KIND_SET(ep_num) +#define USBD_STATUS_OUT_CLEAR(ep_num) USBD_ENDP_KIND_CLEAR(ep_num) + +/* clear bit EPxCS_RX_ST/EPxCS_TX_ST in the endpoint control and status register */ +#define USBD_ENDP_RX_STAT_CLEAR(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), USBD_REG_GET(USBD_EPxCS(ep_num)) & 0x7FFFU & (uint16_t)EPCS_MASK)) +#define USBD_ENDP_TX_STAT_CLEAR(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), USBD_REG_GET(USBD_EPxCS(ep_num)) & 0xFF7FU & (uint16_t)EPCS_MASK)) + +/* toggle EPxCS_RX_DTG or EPxCS_TX_DTG bit in the endpoint control and status register */ +#define USBD_DTG_RX_TOGGLE(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), EPxCS_RX_DTG | (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPCS_MASK))) +#define USBD_DTG_TX_TOGGLE(ep_num) (USBD_REG_SET(USBD_EPxCS(ep_num), EPxCS_TX_DTG | (USBD_REG_GET(USBD_EPxCS(ep_num)) & EPCS_MASK))) + +/* clear EPxCS_RX_DTG or EPxCS_TX_DTG bit in the endpoint control and status register */ +#define USBD_DTG_RX_CLEAR(ep_num) do {\ + if ((USBD_REG_GET(USBD_EPxCS(ep_num)) & EPxCS_RX_DTG) != 0U) {\ + USBD_DTG_RX_TOGGLE(ep_num);\ + } else {\ + }\ +} while(0) + +#define USBD_DTG_TX_CLEAR(ep_num) do {\ + if ((USBD_REG_GET(USBD_EPxCS(ep_num)) & EPxCS_TX_DTG) != 0U) {\ + USBD_DTG_TX_TOGGLE(ep_num);\ + } else {\ + }\ +} while(0) + +/* set and clear directly double buffered feature of endpoint */ +#define USBD_ENDP_DOUBLE_BUF_SET(ep_num) USBD_ENDP_KIND_SET(ep_num) +#define USBD_ENDP_DOUBLE_BUF_CLEAR(ep_num) USBD_ENDP_KIND_CLEAR(ep_num) + +/* toggle SW_BUF bit in the double buffered endpoint */ +#define USBD_SWBUF_TX_TOGGLE(ep_num) USBD_DTG_RX_TOGGLE(ep_num) +#define USBD_SWBUF_RX_TOGGLE(ep_num) USBD_DTG_TX_TOGGLE(ep_num) + +#endif /* USBD_REGS_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_std.h b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_std.h new file mode 100644 index 0000000..0fd8e66 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Include/usbd_std.h @@ -0,0 +1,197 @@ +/*! + \file usbd_std.h + \brief USB standard definitions +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5) +*/ + +#ifndef USBD_STD_H +#define USBD_STD_H + +#include "usbd_core.h" +#include + +#ifndef NULL +#define NULL 0U +#endif + +/* constants definitions */ +#define USB_DEV_QUALIFIER_DESC_LEN 0x0AU /* device qualifier descriptor length */ +#define USB_CFG_DESC_LEN 0x09U /* configuration descriptor length */ + +#define USBD_LANGID_STR_IDX 0x00U /* language ID string index */ +#define USBD_MFC_STR_IDX 0x01U /* manufacturer string index */ +#define USBD_PRODUCT_STR_IDX 0x02U /* product string index */ +#define USBD_SERIAL_STR_IDX 0x03U /* serial string index */ +#define USBD_CONFIG_STR_IDX 0x04U /* configuration string index */ +#define USBD_INTERFACE_STR_IDX 0x05U /* interface string index */ + +#define USB_STANDARD_REQ 0x00U /* standard request */ +#define USB_CLASS_REQ 0x20U /* device class request */ +#define USB_VENDOR_REQ 0x40U /* vendor request */ +#define USB_REQ_MASK 0x60U /* request type mask */ + +#define USB_REQTYPE_DEVICE 0x00U /* request recipient is device */ +#define USB_REQTYPE_INTERFACE 0x01U /* request recipient is interface */ +#define USB_REQTYPE_ENDPOINT 0x02U /* request recipient is endpoint */ +#define USB_REQ_RECIPIENT_MASK 0x1fU /* request recipient mask */ + +#define USBREQ_GET_STATUS 0x00U /* Get_Status standard requeset */ +#define USBREQ_CLEAR_FEATURE 0x01U /* Clear_Feature standard requeset */ +#define USBREQ_SET_FEATURE 0x03U /* Set_Feature standard requeset */ +#define USBREQ_SET_ADDRESS 0x05U /* Set_Address standard requeset */ +#define USBREQ_GET_DESCRIPTOR 0x06U /* Get_Descriptor standard requeset */ +#define USBREQ_GET_CONFIGURATION 0x08U /* Get_Configuration standard requeset */ +#define USBREQ_SET_CONFIGURATION 0x09U /* Set_Configuration standard requeset */ +#define USBREQ_GET_INTERFACE 0x0AU /* Get_Interface standard requeset */ +#define USBREQ_SET_INTERFACE 0x0BU /* Set_Interface standard requeset */ + +#define USB_DESCTYPE_DEVICE 0x01U /* device descriptor type */ +#define USB_DESCTYPE_CONFIGURATION 0x02U /* configuration descriptor type */ +#define USB_DESCTYPE_STRING 0x03U /* string descriptor type */ +#define USB_DESCTYPE_INTERFACE 0x04U /* interface descriptor type */ +#define USB_DESCTYPE_ENDPOINT 0x05U /* endpoint descriptor type */ +#define USB_DESCTYPE_DEVICE_QUALIFIER 0x06U /* device qualifier descriptor type */ +#define USB_DESCTYPE_OTHER_SPEED_CONFIGURATION 0x07U /* other speed configuration descriptor type */ +#define USB_DESCTYPE_BOS 0x0FU /* BOS descriptor type */ + +#define USB_STATUS_REMOTE_WAKEUP 2U /* USB is in remote wakeup status */ +#define USB_STATUS_SELF_POWERED 1U /* USB is in self powered status */ + +#define USB_FEATURE_ENDP_HALT 0U /* USB has endpoint halt feature */ +#define USB_FEATURE_REMOTE_WAKEUP 1U /* USB has endpoint remote wakeup feature */ +#define USB_FEATURE_TEST_MODE 2U /* USB has endpoint test mode feature */ + +#define ENG_LANGID 0x0409U /* english language ID */ +#define CHN_LANGID 0x0804U /* chinese language ID */ + +#define USB_EPTYPE_MASK 0x03U + +#define USB_DEVICE_DESC_SIZE 0x12U + +/* USB device exported macros */ +#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ + (uint16_t)(((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U)) + +#define LOWBYTE(x) ((uint8_t)((x) & 0x00FFU)) +#define HIGHBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#define IS_NOT_EP0(ep_addr) (((ep_addr) != 0x00U) && ((ep_addr) != 0x80U)) + +#define WIDE_STRING(string) _WIDE_STRING(string) +#define _WIDE_STRING(string) L##string + +#define USBD_STRING_DESC(string) \ + (void *)&(const struct { \ + uint8_t _len; \ + uint8_t _type; \ + wchar_t _data[sizeof(string)]; \ + }) { \ + sizeof(WIDE_STRING(string)) + 2U - 2U, \ + USB_DESCTYPE_STRING, \ + WIDE_STRING(string) \ + } + +typedef struct +{ + uint8_t bLength; /*!< size of the descriptor */ + uint8_t bDescriptorType; /*!< type of the descriptor */ +} usb_descriptor_header_struct; + +typedef struct +{ + usb_descriptor_header_struct Header; /*!< descriptor header, including type and size */ + + uint16_t bcdUSB; /*!< BCD of the supported USB specification */ + uint8_t bDeviceClass; /*!< USB device class */ + uint8_t bDeviceSubClass; /*!< USB device subclass */ + uint8_t bDeviceProtocol; /*!< USB device protocol */ + uint8_t bMaxPacketSize0; /*!< size of the control (address 0) endpoint's bank in bytes */ + uint16_t idVendor; /*!< vendor ID for the USB product */ + uint16_t idProduct; /*!< unique product ID for the USB product */ + uint16_t bcdDevice; /*!< product release (version) number */ + uint8_t iManufacturer; /*!< string index for the manufacturer's name */ + uint8_t iProduct; /*!< string index for the product name/details */ + uint8_t iSerialNumber; /*!< string index for the product's globally unique hexadecimal serial number */ + uint8_t bNumberConfigurations; /*!< total number of configurations supported by the device */ +} usb_descriptor_device_struct; + +#pragma pack(1) + +typedef struct +{ + usb_descriptor_header_struct Header; /*!< descriptor header, including type and size */ + + uint16_t wTotalLength; /*!< size of the configuration descriptor header,and all sub descriptors inside the configuration */ + uint8_t bNumInterfaces; /*!< total number of interfaces in the configuration */ + uint8_t bConfigurationValue; /*!< configuration index of the current configuration */ + uint8_t iConfiguration; /*!< index of a string descriptor describing the configuration */ + uint8_t bmAttributes; /*!< configuration attributes */ + uint8_t bMaxPower; /*!< maximum power consumption of the device while in the current configuration */ +} usb_descriptor_configuration_struct; + +#pragma pack() + +typedef struct +{ + usb_descriptor_header_struct Header; /*!< descriptor header, including type and size */ + + uint8_t bInterfaceNumber; /*!< index of the interface in the current configuration */ + uint8_t bAlternateSetting; /*!< alternate setting for the interface number */ + uint8_t bNumEndpoints; /*!< total number of endpoints in the interface */ + uint8_t bInterfaceClass; /*!< interface class ID */ + uint8_t bInterfaceSubClass; /*!< interface subclass ID */ + uint8_t bInterfaceProtocol; /*!< interface protocol ID */ + uint8_t iInterface; /*!< index of the string descriptor describing the interface */ +} usb_descriptor_interface_struct; + +#pragma pack(1) + +typedef struct +{ + usb_descriptor_header_struct Header; /*!< descriptor header, including type and size. */ + + uint8_t bEndpointAddress; /*!< logical address of the endpoint */ + uint8_t bmAttributes; /*!< endpoint attributes */ + uint16_t wMaxPacketSize; /*!< size of the endpoint bank, in bytes */ + uint8_t bInterval; /*!< polling interval in milliseconds for the endpoint if it is an INTERRUPT or ISOCHRONOUS type */ +} usb_descriptor_endpoint_struct; + +typedef struct +{ + usb_descriptor_header_struct Header; /*!< descriptor header, including type and size. */ + uint16_t wLANGID; /*!< LANGID code */ +}usb_descriptor_language_id_struct; + +#pragma pack() + +/* function declarations */ +/* USB SETUP transaction processing */ +uint8_t usbd_setup_transaction (usbd_core_handle_struct *pudev); +/* USB OUT transaction processing */ +uint8_t usbd_out_transaction (usbd_core_handle_struct *pudev, uint8_t ep_num); +/* USB IN transaction processing */ +uint8_t usbd_in_transaction (usbd_core_handle_struct *pudev, uint8_t ep_num); + +/* handle USB standard device request */ +uint8_t usbd_standard_request (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +/* handle device class request */ +uint8_t usbd_device_class_request (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +/* handle USB vendor request */ +uint8_t usbd_vendor_request (usbd_core_handle_struct *pudev, usb_device_req_struct *req); + +/* decode setup data packet */ +void usbd_setup_request_parse (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +/* handle USB enumeration error event */ +void usbd_enum_error (usbd_core_handle_struct *pudev, usb_device_req_struct *req); + +#endif /* USBD_STD_H */ diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_core.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_core.c new file mode 100644 index 0000000..72e9849 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_core.c @@ -0,0 +1,425 @@ +/*! + \file usbd_core.c + \brief USB device driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5) +*/ + +#include "usbd_core.h" +#include "usbd_std.h" + +uint32_t g_interrupt_mask = 0U; +uint32_t g_free_buf_addr = ENDP_BUF_ADDR; + +usbd_ep_buf_struct *pbuf_reg = (usbd_ep_buf_struct *)USBD_RAM; + +/*! + \brief device core register initialization + \param[in] none + \param[out] none + \retval none +*/ +void usbd_core_init (usbd_core_handle_struct *pudev) +{ + /* disable remote wakeup feature */ + pudev->remote_wakeup = 0U; + + /* just reset the CLOSE bit */ + USBD_REG_SET(USBD_CTL, CTL_SETRST); + + /* may be need wait some time(tSTARTUP) ... */ + + /* clear SETRST bit in USBD_CTL register */ + USBD_REG_SET(USBD_CTL, 0U); + + /* clear all pending interrupts */ + USBD_REG_SET(USBD_INTF, 0U); + + /* set allocation buffer address */ + USBD_REG_SET(USBD_BADDR, BUFFER_ADDRESS & 0xFFF8U); + + g_interrupt_mask = IER_MASK; + + /* enable all interrupts mask bits */ + USBD_REG_SET(USBD_CTL, g_interrupt_mask); +} + +/*! + \brief free buffer used from application by toggling the SW_BUF byte + \param[in] ep_num: endpoint identifier (0..7) + \param[in] dir: endpoint direction which can be OUT(0) or IN(1) + \param[out] none + \retval None +*/ +void user_buffer_free (uint8_t ep_num, uint8_t dir) +{ + if (DBUF_EP_OUT == dir) { + USBD_SWBUF_RX_TOGGLE(ep_num); + } else if (DBUF_EP_IN == dir) { + USBD_SWBUF_TX_TOGGLE(ep_num); + } else { + /* no operation */ + } +} + +/*! + \brief device core register configure when stop device + \param[in] none + \param[out] none + \retval none +*/ +void usbd_core_deinit (void) +{ + /* disable all interrupts and set USB reset */ + USBD_REG_SET(USBD_CTL, CTL_SETRST); + + /* clear all interrupt flags */ + USBD_REG_SET(USBD_INTF, 0U); + + /* close device */ + USBD_REG_SET(USBD_CTL, CTL_SETRST | CTL_CLOSE); +} + +/*! + \brief endpoint initialization + \param[in] pudev: pointer to USB core instance + \param[in] pep_desc: pointer to endpoint descriptor + \param[out] none + \retval none +*/ +void usbd_ep_init (usbd_core_handle_struct *pudev, usbd_epkind_enum buf_kind, const void *ep_desc) +{ + usb_descriptor_endpoint_struct *desc_ep = (usb_descriptor_endpoint_struct *)ep_desc; + + uint8_t ep_num = desc_ep->bEndpointAddress & 0x0FU; + uint32_t reg_value = 0; + + /* set the endpoint type */ + switch (desc_ep->bmAttributes & USB_EPTYPE_MASK) { + case ENDP_CONTROL: + reg_value = EP_CONTROL; + break; + case ENDP_BULK: + reg_value = EP_BULK; + break; + case ENDP_INT: + reg_value = EP_INTERRUPT; + break; + case ENDP_ISOC: + reg_value = EP_ISO; + break; + default: + break; + } + + USBD_REG_SET(USBD_EPxCS(ep_num), reg_value | ep_num); + + reg_value = desc_ep->wMaxPacketSize; + + if (desc_ep->bEndpointAddress >> 7U) { + usb_ep_struct *ep = &pudev->in_ep[ep_num]; + + ep->maxpacket = reg_value; + + /* set the endpoint transmit buffer address */ + (pbuf_reg + ep_num)->tx_addr = (uint16_t)g_free_buf_addr; + + reg_value = (reg_value + 1U) & ~1U; + + g_free_buf_addr += reg_value; + + if (ENDP_DBL_BUF == buf_kind) { + USBD_ENDP_DOUBLE_BUF_SET(ep_num); + + (pbuf_reg + ep_num)->rx_addr = (uint16_t)g_free_buf_addr; + + g_free_buf_addr += reg_value; + + USBD_ENDP_TX_STATUS_SET(ep_num, EPTX_VALID); + USBD_ENDP_RX_STATUS_SET(ep_num, EPRX_DISABLED); + } else { + /* configure the endpoint status as NAK status */ + USBD_ENDP_TX_STATUS_SET(ep_num, EPTX_NAK); + } + } else { + usb_ep_struct *ep = &pudev->out_ep[ep_num]; + + ep->maxpacket = reg_value; + + if (ENDP_DBL_BUF == buf_kind) { + USBD_ENDP_DOUBLE_BUF_SET(ep_num); + + USBD_DTG_TX_TOGGLE(ep_num); + + /* set the endpoint transmit buffer address */ + (pbuf_reg + ep_num)->tx_addr = (uint16_t)g_free_buf_addr; + + if (reg_value > 62U) { + reg_value = (reg_value + 31U) & ~31U; + (pbuf_reg + ep_num)->tx_count = (uint16_t)(((reg_value << 5U) - 1U) | 0x8000U); + } else { + reg_value = (reg_value + 1U) & ~1U; + (pbuf_reg + ep_num)->rx_count = (uint16_t)(reg_value << 9U); + } + + g_free_buf_addr += reg_value; + } + + reg_value = desc_ep->wMaxPacketSize; + + /* set the endpoint receive buffer address */ + (pbuf_reg + ep_num)->rx_addr = (uint16_t)g_free_buf_addr; + + if (reg_value > 62U) { + reg_value = (reg_value + 31U) & ~31U; + (pbuf_reg + ep_num)->rx_count = (uint16_t)(((reg_value << 5U) - 1U) | 0x8000U); + } else { + reg_value = (reg_value + 1U) & ~1U; + (pbuf_reg + ep_num)->rx_count = (uint16_t)(reg_value << 9U); + } + + if (ENDP_DBL_BUF == buf_kind) { + USBD_ENDP_RX_STATUS_SET(ep_num, EPRX_DISABLED); + USBD_ENDP_TX_STATUS_SET(ep_num, EPTX_NAK); + } else { + /* configure the endpoint status as NAK status */ + USBD_ENDP_RX_STATUS_SET(ep_num, EPRX_NAK); + } + } +} + +/*! + \brief configure the endpoint when it is disabled + \param[in] pudev: pointer to USB core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[out] none + \retval none +*/ +void usbd_ep_deinit (usbd_core_handle_struct *pudev, uint8_t ep_addr) +{ + uint8_t ep_num = ep_addr & 0x7FU; + + if (ep_addr >> 7) { + USBD_DTG_TX_CLEAR(ep_num); + + /* configure the endpoint status as DISABLED */ + USBD_ENDP_TX_STATUS_SET(ep_num, EPTX_DISABLED); + } else { + USBD_DTG_RX_CLEAR(ep_num); + + /* configure the endpoint status as DISABLED */ + USBD_ENDP_RX_STATUS_SET(ep_num, EPRX_DISABLED); + } +} + +/*! + \brief endpoint prepare to receive data + \param[in] pudev: pointer to usb core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[in] pbuf: user buffer address pointer + \param[in] buf_len: buffer length + \param[out] none + \retval none +*/ +void usbd_ep_rx (usbd_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len) +{ + usb_ep_struct *ep; + uint8_t ep_num = ep_addr & 0x7FU; + + ep = &pudev->out_ep[ep_num]; + + /* configure the transaction level parameters */ + ep->trs_buf = pbuf; + ep->trs_len = buf_len; + + /* enable endpoint to receive */ + USBD_ENDP_RX_STATUS_SET(ep_num, EPRX_VALID); +} + +/*! + \brief endpoint prepare to transmit data + \param[in] pudev: pointer to USB core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[in] pbuf: transmit buffer address pointer + \param[in] buf_len: buffer length + \param[out] none + \retval none +*/ +void usbd_ep_tx (usbd_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len) +{ + __IO uint32_t len = 0U; + uint8_t ep_num = ep_addr & 0x7FU; + usb_ep_struct *ep = &pudev->in_ep[ep_num]; + + /* configure the transaction level parameters */ + ep->trs_buf = pbuf; + ep->trs_len = buf_len; + ep->trs_count = 0U; + + /* transmit length is more than one packet */ + if (ep->trs_len > ep->maxpacket) { + len = ep->maxpacket; + } else { + len = ep->trs_len; + } + + usbd_ep_data_write(ep->trs_buf, (pbuf_reg + ep_num)->tx_addr, (uint16_t)len); + (pbuf_reg + ep_num)->tx_count = (uint16_t)len; + + /* enable endpoint to transmit */ + USBD_ENDP_TX_STATUS_SET(ep_num, EPTX_VALID); +} + +/*! + \brief set an endpoint to STALL status + \param[in] pudev: pointer to usb core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[out] none + \retval none +*/ +void usbd_ep_stall (usbd_core_handle_struct *pudev, uint8_t ep_addr) +{ + uint8_t ep_num = ep_addr & 0x7FU; + usb_ep_struct *ep; + + if (ep_addr >> 7U) { + ep = &pudev->in_ep[ep_num]; + + USBD_ENDP_TX_STATUS_SET(ep_num, EPTX_STALL); + } else { + ep = &pudev->out_ep[ep_num]; + + USBD_ENDP_RX_STATUS_SET(ep_num, EPRX_STALL); + } + + ep->stall = 1U; + + if (0U == ep_num) { + /* control endpoint need to be stalled in two directions */ + USBD_ENDP_RX_TX_STATUS_SET(ep_num, EPRX_STALL, EPTX_STALL); + } +} + +/*! + \brief clear endpoint stalled status + \param[in] pudev: pointer to usb core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[out] none + \retval none +*/ +void usbd_ep_clear_stall (usbd_core_handle_struct *pudev, uint8_t ep_addr) +{ + uint8_t ep_num = ep_addr & 0x7FU; + usb_ep_struct *ep; + + if (ep_addr >> 7U) { + ep = &pudev->in_ep[ep_num]; + + /* clear endpoint data toggle bit */ + USBD_DTG_TX_CLEAR(ep_num); + + /* clear endpoint stall status */ + USBD_ENDP_TX_STATUS_SET(ep_num, EPTX_VALID); + } else { + ep = &pudev->out_ep[ep_num]; + + /* clear endpoint data toggle bit */ + USBD_DTG_RX_CLEAR(ep_num); + + /* clear endpoint stall status */ + USBD_ENDP_RX_STATUS_SET(ep_num, EPRX_VALID); + } + + ep->stall = 0U; +} + +/*! + \brief get the endpoint status + \param[in] pudev: pointer to usb core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[out] none + \retval endpoint status +*/ +uint8_t usbd_ep_status_get (usbd_core_handle_struct *pudev, uint8_t ep_addr) +{ + if (ep_addr >> 7U) { + return (uint8_t)USBD_ENDP_TX_STATUS_GET((ep_addr & 0x7FU)); + } else { + return (uint8_t)USBD_ENDP_RX_STATUS_GET(ep_addr); + } +} + +/*! + \brief write datas from user fifo to USBRAM + \param[in] user_fifo: pointer to user fifo + \param[in] usbram_addr: the allocation buffer address of the endpoint + \param[in] bytes: the bytes count of the write datas + \param[out] none + \retval none +*/ +void usbd_ep_data_write(uint8_t *user_fifo, uint16_t usbram_addr, uint16_t bytes) +{ + uint32_t n; + uint32_t *write_addr = (uint32_t *)((uint32_t)(usbram_addr * 2U + USBD_RAM)); + + for (n = 0U; n < (bytes + 1U) / 2U; n++) { + *write_addr++ = *((__packed uint16_t*)user_fifo); + user_fifo += 2U; + } +} + +/*! + \brief read datas from USBRAM to user fifo + \param[in] user_fifo: pointer to user fifo + \param[in] usbram_addr: the allocation buffer address of the endpoint + \param[in] bytes: the bytes count of the read datas + \param[out] none + \retval none +*/ +void usbd_ep_data_read(uint8_t *user_fifo, uint16_t usbram_addr, uint16_t bytes) +{ + uint32_t n; + uint32_t *read_addr = (uint32_t *)((uint32_t)(usbram_addr * 2U + USBD_RAM)); + + for (n = 0U; n < (bytes + 1U) / 2U; n++) { + *((__packed uint16_t*)user_fifo) = (uint16_t)*read_addr++; + user_fifo += 2U; + } +} + +/*! + \brief get the received data length + \param[in] pudev: pointer to USB core instance + \param[in] ep_num: endpoint identifier which is in (0..7) + \param[out] none + \retval received data length +*/ +uint16_t usbd_rx_count_get (usbd_core_handle_struct *pudev, uint8_t ep_num) +{ + return (uint16_t)pudev->out_ep[ep_num].trs_count; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_int.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_int.c new file mode 100644 index 0000000..478c94a --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_int.c @@ -0,0 +1,395 @@ +/*! + \file usbd_int.c + \brief USB device interrupt routines +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5) +*/ + +#include "usbd_int.h" + +extern uint32_t g_interrupt_mask; +extern __IO uint8_t g_suspend_enabled; +extern __IO uint8_t g_remote_wakeup_on; +extern __IO uint8_t g_ESOF_count; + + +static uint8_t usbd_intf_lpst (usbd_core_handle_struct *pudev); +static uint8_t usbd_intf_sof (usbd_core_handle_struct *pudev); +static uint8_t usbd_intf_esof (usbd_core_handle_struct *pudev); +static uint8_t usbd_intf_reset (usbd_core_handle_struct *pudev); +static uint8_t usbd_intf_suspend (usbd_core_handle_struct *pudev); +static uint8_t usbd_intf_wakeup (usbd_core_handle_struct *pudev); + +/*! + \brief USB interrupt events service routine + \param[in] none + \param[out] none + \retval none +*/ +void usbd_isr (void) +{ + __IO uint16_t interrupt_flag = 0U; + __IO uint16_t ctlr = 0U; + + interrupt_flag = USBD_REG_GET(USBD_INTF); + + if (g_interrupt_mask & INTF_STIF & interrupt_flag) { + /* the endpoint successful transfer interrupt service */ + usbd_intf_lpst(&usb_device_dev); + } + + if (g_interrupt_mask & INTF_WKUPIF & interrupt_flag) { + /* clear wakeup interrupt flag in INTF */ + USBD_REG_SET(USBD_INTF, (uint16_t)CLR_WKUPIF); + + /* USB wakeup interrupt handle */ + usbd_intf_wakeup(&usb_device_dev); + + } + + if (g_interrupt_mask & INTF_SPSIF & interrupt_flag) { + if(!(USBD_REG_GET(USBD_CTL) & CTL_RSREQ)) { + /* process library core layer suspend routine*/ + usbd_intf_suspend(&usb_device_dev); + + /* clear of suspend interrupt flag bit must be done after setting of CTLR_SETSPS */ + USBD_REG_SET(USBD_INTF, (uint16_t)CLR_SPSIF); + } + } + + if (g_interrupt_mask & INTF_SOFIF & interrupt_flag) { + /* clear SOF interrupt flag in INTF */ + USBD_REG_SET(USBD_INTF, (uint16_t)CLR_SOFIF); + + /* USB SOF interrupt handle */ + usbd_intf_sof(&usb_device_dev); + } + + if (g_interrupt_mask & INTF_ESOFIF & interrupt_flag) { + /* clear ESOF interrupt flag in INTF */ + USBD_REG_SET(USBD_INTF, (uint16_t)CLR_ESOFIF); + + /* USB ESOF interrupt handle */ + usbd_intf_esof(&usb_device_dev); + } + + if (g_interrupt_mask & INTF_RSTIF & interrupt_flag) { + /* clear reset interrupt flag in INTF */ + USBD_REG_SET(USBD_INTF, (uint16_t)CLR_RSTIF); + + /* USB reset interrupt handle */ + usbd_intf_reset(&usb_device_dev); + } +} + +/*! + \brief handle USB high priority successful transfer event + \param[in] pudev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +uint8_t usbd_intf_hpst (usbd_core_handle_struct *pudev) +{ + uint8_t ep_num = 0U; + + __IO uint16_t int_status = 0U; + __IO uint16_t ep_value = 0U; + + usb_ep_struct *ep = NULL; + + /* wait till interrupts are not pending */ + while (0U != ((int_status = USBD_INTF) & (uint16_t)INTF_STIF)) { + /* get endpoint number and the value of control and state register */ + ep_num = (uint8_t)(int_status & INTF_EPNUM); + ep_value = USBD_EPxCS(ep_num); + + if (0U == (int_status & INTF_DIR)) { + /* handle the in direction transaction */ + + ep = &(pudev->in_ep[ep_num]); + + if (0U != (ep_value & EPxCS_TX_ST)) { + /* clear successful transmit interrupt flag */ + USBD_ENDP_TX_STAT_CLEAR(ep_num); + + if (ep_value & EPxCS_TX_DTG) { + /* just handle single buffer situation */ + ep->trs_count = (pbuf_reg + ep_num)->tx_count & EPTCNT_CNT; + } + + /* maybe mutiple packets */ + ep->trs_buf += ep->trs_count; + + usbd_in_transaction(pudev, ep_num); + } + } else { + /* handle the out direction transaction */ + + uint16_t count = 0U; + + ep = &(pudev->out_ep[ep_num]); + + if (0U != (ep_value & EPxCS_RX_ST)) { + /* clear successful receive interrupt flag */ + USBD_ENDP_RX_STAT_CLEAR(ep_num); + + if (ep_value & EPxCS_TX_DTG) { + count = (pbuf_reg + ep_num)->tx_count & (uint16_t)EPRCNT_CNT; + + if (0U != count) { + usbd_ep_data_read(ep->trs_buf, (pbuf_reg + ep_num)->tx_addr, count); + } + } else { + count = (pbuf_reg + ep_num)->rx_count & (uint16_t)EPRCNT_CNT; + + if (0U != count) { + usbd_ep_data_read(ep->trs_buf, (pbuf_reg + ep_num)->rx_addr, count); + } + } + + user_buffer_free(ep_num, DBUF_EP_OUT); + + /* maybe mutiple packets */ + ep->trs_count += count; + ep->trs_buf += count; + ep->trs_len -= count; + + if ((0U == ep->trs_len) || (count < ep->maxpacket)) { + USBD_ENDP_TX_STATUS_SET(ep_num, EPRX_NAK); + + /* enter data OUT status */ + usbd_out_transaction(pudev, ep_num); + + ep->trs_count = 0U; + } + } + } + } + + return USBD_OK; +} + +/*! + \brief handle USB low priority successful transfer event + \param[in] pudev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +static uint8_t usbd_intf_lpst (usbd_core_handle_struct *pudev) +{ + uint8_t ep_num = 0U; + + __IO uint16_t int_status = 0U; + __IO uint16_t ep_value = 0U; + + usb_ep_struct *ep = NULL; + + /* wait till interrupts are not pending */ + while (0U != ((int_status = USBD_REG_GET(USBD_INTF)) & (uint16_t)INTF_STIF)) { + /* get endpoint number and the value of control and state register */ + ep_num = (uint8_t)(int_status & INTF_EPNUM); + ep_value = USBD_REG_GET(USBD_EPxCS(ep_num)); + + if (0U == (int_status & INTF_DIR)) { + /* handle the in direction transaction */ + + ep = &(pudev->in_ep[ep_num]); + + if (0U != (ep_value & EPxCS_TX_ST)) { + /* clear successful transmit interrupt flag */ + USBD_ENDP_TX_STAT_CLEAR(ep_num); + + /* just handle single buffer situation */ + ep->trs_count = (pbuf_reg + ep_num)->tx_count & EPTCNT_CNT; + + /* maybe mutiple packets */ + ep->trs_buf += ep->trs_count; + + usbd_in_transaction(pudev, ep_num); + } + } else { + /* handle the out direction transaction */ + + uint16_t count = 0U; + + ep = &(pudev->out_ep[ep_num]); + + if (0U != (ep_value & EPxCS_RX_ST)) { + /* clear successful receive interrupt flag */ + USBD_ENDP_RX_STAT_CLEAR(ep_num); + + count = (pbuf_reg + ep_num)->rx_count & (uint16_t)EPRCNT_CNT; + + if (0U != count) { + if (0U != (ep_value & EPxCS_SETUP)) { + /* handle setup packet */ + usbd_ep_data_read(&(pudev->setup_packet[0U]), pbuf_reg->rx_addr, count); + + /* enter setup status */ + usbd_setup_transaction(pudev); + + return USBD_OK; + } else { + usbd_ep_data_read(ep->trs_buf, (pbuf_reg + ep_num)->rx_addr, count); + } + } + + /* maybe mutiple packets */ + ep->trs_count += count; + ep->trs_buf += count; + ep->trs_len -= count; + + if ((0U == ep->trs_len) || (count < ep->maxpacket)) { + /* enter data OUT status */ + usbd_out_transaction(pudev, ep_num); + + ep->trs_count = 0U; + } else { + usbd_ep_rx(pudev, ep_num, ep->trs_buf, (uint16_t)ep->trs_len); + } + } + } + } + + return USBD_OK; +} + +/*! + \brief handle USB SOF event + \param[in] pudev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +static uint8_t usbd_intf_sof (usbd_core_handle_struct *pudev) +{ + /* if necessary, user can add code here */ + if (NULL != usbd_int_fops) { + usbd_int_fops->SOF(pudev); + } + + return USBD_OK; +} + +/*! + \brief handle USB expect SOF event + \param[in] pudev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +static uint8_t usbd_intf_esof (usbd_core_handle_struct *pudev) +{ + /* control resume time by ESOFs */ + if (g_ESOF_count > 0U) { + g_ESOF_count--; + + if (0U == g_ESOF_count) { + if (1U == g_remote_wakeup_on) { + USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) & ~CTL_RSREQ); + + g_remote_wakeup_on = 0U; + } else { + USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) | CTL_RSREQ); + + g_ESOF_count = 3U; + g_remote_wakeup_on = 1U; + } + } + } + + return USBD_OK; +} + +/*! + \brief handle USB reset event + \param[in] pudev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +static uint8_t usbd_intf_reset (usbd_core_handle_struct *pudev) +{ + uint8_t i; + + g_free_buf_addr = ENDP_BUF_ADDR; + + /* configure endpoint 0 buffer */ + pbuf_reg->tx_addr = (uint16_t)g_free_buf_addr; + g_free_buf_addr += USBD_EP0_MAX_SIZE; + + pbuf_reg->rx_addr = (uint16_t)g_free_buf_addr; + g_free_buf_addr += USBD_EP0_MAX_SIZE; + + /* configure endpoint 0 Rx count */ + if (USBD_EP0_MAX_SIZE > 62U) { + pbuf_reg->rx_count = ((USBD_EP0_MAX_SIZE << 5U) - 1U) | 0x8000U; + } else { + pbuf_reg->rx_count = ((USBD_EP0_MAX_SIZE + 1U) & ~1U) << 9U; + } + + pudev->in_ep[EP0].maxpacket = USBD_EP0_MAX_SIZE; + pudev->out_ep[EP0].maxpacket = USBD_EP0_MAX_SIZE; + + /* set endpoints address */ + for (i = 0U; i < EP_COUNT; i++) + { + _EP_ADDR_SET(i, i); + } + + USBD_REG_SET(USBD_EPxCS(EP0), EP_CONTROL | EPRX_VALID | EPTX_NAK); + + /* set device address as default address 0 */ + USBD_REG_SET(USBD_DADDR, DADDR_USBEN); + + pudev->status = USBD_DEFAULT; + + return USBD_OK; +} + +/*! + \brief handle USB suspend event + \param[in] pudev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +static uint8_t usbd_intf_suspend (usbd_core_handle_struct *pudev) +{ + /* store the device current status */ + pudev->prev_status = pudev->status; + + /* set device in suspended state */ + pudev->status = USBD_SUSPENDED; + + /* enter USB in suspend and mcu system in low power mode */ + if (g_suspend_enabled) { + usbd_suspend(); + } else { + /* if not possible then resume after xx ms */ + g_ESOF_count = 3U; + } + + return USBD_OK; +} + +/*! + \brief handle USB wakeup event + \param[in] pudev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +static uint8_t usbd_intf_wakeup (usbd_core_handle_struct *pudev) +{ + /* restore the old status */ + pudev->status = pudev->prev_status; + + if (0U == g_remote_wakeup_on) { + resume_mcu(); + } + + return USBD_OK; +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_pwr.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_pwr.c new file mode 100644 index 0000000..fe84c05 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_pwr.c @@ -0,0 +1,124 @@ +/*! + \file usbd_pwr.c + \brief USB device power management driver +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5) +*/ + +#include "usbd_pwr.h" + +#ifdef USBD_LOWPWR_MODE_ENABLE +static void lowpower_mode_exit (void); +#endif /* USBD_LOWPWR_MODE_ENABLE */ + +__IO uint8_t g_ESOF_count = 0U; +__IO uint8_t g_suspend_enabled = 1U; +__IO uint8_t g_remote_wakeup_on = 0U; + +/*! + \brief USB wakeup first operation is to wakeup mcu + \param[in] none + \param[out] none + \retval none +*/ +void resume_mcu (void) +{ + /* clear low_power mode bit in USBD_CTL */ + USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) & (~CTL_LOWM)); + +#ifdef USBD_LOWPWR_MODE_ENABLE + + /* restore normal operations */ + lowpower_mode_exit(); + +#endif /* USBD_LOWPWR_MODE_ENABLE */ + + /* clear SETSPS bit */ + USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) & (~CTL_SETSPS)); +} + +#ifdef USBD_LOWPWR_MODE_ENABLE + +/*! + \brief restore system clocks and power while exiting suspend mode + \param[in] none + \param[out] none + \retval none +*/ +static void lowpower_mode_exit (void) +{ + /* restore system clock */ + + /* enable HXTAL */ + rcu_osci_on(RCU_HXTAL); + + /* wait till HXTAL is ready */ + while(RESET == rcu_flag_get(RCU_FLAG_HXTALSTB)); + + /* enable PLL */ + rcu_osci_on(RCU_PLL_CK); + + /* wait till PLL is ready */ + while(RESET == rcu_flag_get(RCU_FLAG_PLLSTB)); + + /* select PLL as system clock source */ + rcu_system_clock_source_config(RCU_CKSYSSRC_PLL); + + /* wait till PLL is used as system clock source */ + while(0x08 != rcu_system_clock_source_get()); + + /* low power sleep on exit disabled */ + system_lowpower_reset(SCB_LPM_DEEPSLEEP); +} + +#endif /* USBD_LOWPWR_MODE_ENABLE */ + +/*! + \brief set USB device to suspend mode + \param[in] none + \param[out] none + \retval none +*/ +void usbd_suspend (void) +{ + /* set usb module to suspend and low-power mode */ + USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) | CTL_SETSPS | CTL_LOWM); + +#ifdef USBD_LOWPWR_MODE_ENABLE + + /* check wakeup flag is set */ + if (0 == (USBD_REG_GET(USBD_INTF) & INTF_WKUPIF)) { + /* enter DEEP_SLEEP mode with LDO in low power mode */ + pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD); + } else { + /* clear wakeup interrupt flag */ + USBD_REG_SET(USBD_INTF, CLR_WKUPIF); + + /* clear set_suspend flag */ + USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) & ~CTL_SETSPS); + } + +#endif /* USBD_LOWPWR_MODE_ENABLE */ +} + +/*! + \brief start to remote wakeup + \param[in] none + \param[out] none + \retval none +*/ +void usbd_remote_wakeup_active(void) +{ + resume_mcu(); + g_remote_wakeup_on = 1U; + + g_ESOF_count = 15U; + USBD_REG_SET(USBD_CTL, USBD_REG_GET(USBD_CTL) | CTL_RSREQ); +} diff --git a/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_std.c b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_std.c new file mode 100644 index 0000000..ddfb160 --- /dev/null +++ b/docs/GD32F1x0_Firmware_Library_v3.1.0/Firmware/GD32F1x0_usbd_driver/Source/usbd_std.c @@ -0,0 +1,817 @@ +/*! + \file usbd_std.c + \brief USB device standard routines + \note about USB standard, please refer to the USB2.0 protocol +*/ + +/* + Copyright (C) 2017 GigaDevice + + 2014-12-26, V1.0.0, platform GD32F1x0(x=5) + 2016-01-15, V2.0.0, platform GD32F1x0(x=5) + 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5) + 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5) +*/ + +#include "usbd_std.h" + +uint8_t g_device_address = 0U; + +/* USB enumeration handle functions */ +static void usbd_getdescriptor (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_setaddress (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_setconfiguration (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_getconfiguration (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_getstatus (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_setfeature (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_clearfeature (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_reserved (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_setdescriptor (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_getinterface (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_setinterface (usbd_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_synchframe (usbd_core_handle_struct *pudev, usb_device_req_struct *req); + +static uint8_t* usbd_device_descriptor_get (usbd_core_handle_struct *pudev, + uint8_t index, + uint16_t *pLen); + +static uint8_t* usbd_configuration_descriptor_get (usbd_core_handle_struct *pudev, + uint8_t index, + uint16_t *pLen); + +static uint8_t* usbd_string_descriptor_get (usbd_core_handle_struct *pudev, + uint8_t index, + uint16_t *pLen); + +/* standard device request handler */ +static void (*standard_device_request[])(usbd_core_handle_struct *pudev, usb_device_req_struct *req) = +{ + usbd_getstatus, + usbd_clearfeature, + usbd_reserved, + usbd_setfeature, + usbd_reserved, + usbd_setaddress, + usbd_getdescriptor, + usbd_setdescriptor, + usbd_getconfiguration, + usbd_setconfiguration, + usbd_getinterface, + usbd_setinterface, + usbd_synchframe, +}; + +/* get standard descriptor handler */ +static uint8_t* (*standard_descriptor_get[])(usbd_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) = +{ + usbd_device_descriptor_get, + usbd_configuration_descriptor_get, + usbd_string_descriptor_get +}; + +/*! + \brief USB setup stage processing + \param[in] pudev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +uint8_t usbd_setup_transaction (usbd_core_handle_struct *pudev) +{ + usb_device_req_struct req; + + usbd_setup_request_parse (pudev, &req); + + switch (req.bmRequestType & USB_REQ_MASK) { + /* standard device request */ + case USB_STANDARD_REQ: + usbd_standard_request(pudev, &req); + break; + /* device class request */ + case USB_CLASS_REQ: + usbd_device_class_request(pudev, &req); + break; + /* vendor defined request */ + case USB_VENDOR_REQ: + usbd_vendor_request(pudev, &req); + break; + default: + usbd_ep_stall(pudev, 0x00U); + break; + } + return USBD_OK; +} + +/*! + \brief data out stage processing + \param[in] pudev: pointer to USB device instance + \param[in] ep_num: endpoint identifier(0..7) + \param[out] none + \retval USB device operation status +*/ +uint8_t usbd_out_transaction (usbd_core_handle_struct *pudev, uint8_t ep_num) +{ + usb_ep_struct *ep = &pudev->out_ep[ep_num]; + + if (0U == ep_num) { + if (0U != pudev->ctl_count) { + if (ep->trs_len > ep->maxpacket) { + /* one data packet has been received, update trs_len */ + ep->trs_len -= ep->maxpacket; + + /* continue to receive remain data */ + usbd_ep_rx(pudev, EP0_OUT, ep->trs_buf, (uint16_t)ep->trs_len); + } else { + if (USBD_CONFIGURED == pudev->status) { + /* device class handle */ + pudev->class_data_handler(pudev, USBD_RX, EP0); + } + + /* enter the control transaction status stage */ + USBD_CONTRL_STATUS_TX(); + + pudev->ctl_count = 0U; + } + } else { + /* clear endpoint status_out status */ + USBD_STATUS_OUT_CLEAR(EP0); + } + } else { + if (USBD_CONFIGURED == pudev->status) { + pudev->class_data_handler(pudev, USBD_RX, ep_num); + } + } + return USBD_OK; +} + +/*! + \brief data in stage processing + \param[in] pudev: pointer to USB device instance + \param[in] ep_num: endpoint identifier(0..7) + \param[out] none + \retval USB device operation status +*/ +uint8_t usbd_in_transaction (usbd_core_handle_struct *pudev, uint8_t ep_num) +{ + usb_ep_struct *ep = &pudev->in_ep[ep_num]; + + if (0U == ep_num) { + if (0U != pudev->ctl_count) { + if (ep->trs_len > ep->maxpacket) { + /* one data packet has been transmited, update trs_len */ + ep->trs_len -= ep->maxpacket; + + /* continue to transmit remain data */ + usbd_ep_tx (pudev, EP0_IN, ep->trs_buf, (uint16_t)ep->trs_len); + + usbd_ep_rx (pudev, 0U, NULL, 0U); + } else { +#ifndef USB_DFU + /* transmit length is maxpacket multiple, so send zero length packet */ + if ((0U == (ep->trs_len % ep->maxpacket)) && (ep->trs_len < pudev->ctl_count)) { + usbd_ep_tx (pudev, EP0_IN, NULL, 0U); + + pudev->ctl_count = 0U; + + usbd_ep_rx (pudev, 0U, NULL, 0U); + } else +#endif /* USB_DFU */ + { + ep->trs_len = 0U; + + if (USBD_CONFIGURED == pudev->status) { + pudev->class_data_handler(pudev, USBD_TX, EP0); + } + + USBD_CONTRL_STATUS_RX(); + + pudev->ctl_count = 0U; + } + } + } else { + if (0U != g_device_address) { + USBD_REG_SET(USBD_DADDR, DADDR_USBEN | g_device_address); + g_device_address = 0U; + } + } + } else { + ep->trs_len -= ep->trs_count; + + if (0U == ep->trs_len) { + if (USBD_CONFIGURED == pudev->status) { + pudev->class_data_handler(pudev, USBD_TX, ep_num); + } + } else { + usbd_ep_tx(pudev, ep_num, ep->trs_buf, (uint16_t)ep->trs_len); + } + } + + return USBD_OK; +} + +/*! + \brief handle USB standard device request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device operation status +*/ +uint8_t usbd_standard_request (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + /* call device request handle function */ + (*standard_device_request[req->bRequest])(pudev, req); + + return USBD_OK; +} + +/*! + \brief handle USB device class request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device class request + \param[out] none + \retval USB device operation status +*/ +uint8_t usbd_device_class_request (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + usbd_status_enum ret; + + switch (pudev->status) { + case USBD_CONFIGURED: + if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) { + /* call device class handle function */ + ret = (usbd_status_enum)(pudev->class_req_handler(pudev, req)); + + if ((0U == req->wLength) && (USBD_OK == ret)) { + /* no data stage */ + USBD_CONTRL_STATUS_TX(); + } + } else { + usbd_enum_error(pudev, req); + } + break; + default: + usbd_enum_error(pudev, req); + break; + } + + return USBD_OK; +} + +/*! + \brief handle USB vendor request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB vendor request + \param[out] none + \retval USB device operation status +*/ +uint8_t usbd_vendor_request (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + /* added by user */ + + return USBD_OK; +} + +/*! + \brief no operation, just for reserved + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_reserved (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + /* no operation */ +} + +/*! + \brief get the device descriptor + \param[in] pudev: pointer to USB device instance + \param[in] index: no use + \param[out] pLen: data length pointer + \retval descriptor buffer pointer +*/ +static uint8_t* usbd_device_descriptor_get (usbd_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) +{ + *pLen = pudev->dev_desc[0]; + + return pudev->dev_desc; +} + +/*! + \brief get the configuration descriptor + \brief[in] pudev: pointer to USB device instance + \brief[in] index: no use + \param[out] pLen: data length pointer + \retval descriptor buffer pointer +*/ +static uint8_t* usbd_configuration_descriptor_get (usbd_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) +{ + *pLen = pudev->config_desc[2]; + + return pudev->config_desc; +} + +/*! + \brief get string descriptor + \param[in] pudev: pointer to USB device instance + \param[in] index: string descriptor index + \param[out] pLen: pointer to string length + \retval none +*/ +static uint8_t* usbd_string_descriptor_get (usbd_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) +{ + uint8_t *desc = pudev->strings[index]; + + *pLen = desc[0]; + + return desc; +} + +/*! + \brief handle Get_Status request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_getstatus (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + uint8_t ep_addr; + uint16_t config_status = 0x0000U; + uint16_t endp_status = 0x0000U; + + switch(req->bmRequestType & USB_REQ_RECIPIENT_MASK) { + case USB_REQTYPE_DEVICE: + switch (pudev->status) { + case USBD_ADDRESSED: + case USBD_CONFIGURED: + +#ifdef USBD_SELF_POWERED + config_status = USB_STATUS_SELF_POWERED; +#endif /* USBD_SELF_POWERED */ + + if (pudev->remote_wakeup) { + config_status |= USB_STATUS_REMOTE_WAKEUP; + } + + usbd_ep_tx(pudev, EP0_IN, (uint8_t *)&config_status, 2U); + break; + default: + break; + } + break; + case USB_REQTYPE_INTERFACE: + switch (pudev->status) { + case USBD_ADDRESSED: + usbd_enum_error(pudev, req); + break; + case USBD_CONFIGURED: + if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) { + usbd_ep_tx(pudev, EP0_IN, (uint8_t *)&config_status, 2U); + } else { + usbd_enum_error(pudev, req); + } + break; + default: + break; + } + break; + case USB_REQTYPE_ENDPOINT: + /* get enndpoint address */ + ep_addr = LOWBYTE(req->wIndex); + + switch (pudev->status) { + case USBD_ADDRESSED: + if (IS_NOT_EP0(ep_addr)) { + usbd_enum_error(pudev, req); + } + break; + case USBD_CONFIGURED: + if ((ep_addr & 0x80U) == 0x80U) { + if(pudev->in_ep[ep_addr & 0x7FU].stall) { + endp_status = 0x0001U; + } + } else { + if (pudev->out_ep[ep_addr].stall) { + endp_status = 0x0001U; + } + } + usbd_ep_tx(pudev, EP0_IN, (uint8_t *)&endp_status, 2U); + break; + + default: + break; + } + break; + default: + usbd_enum_error(pudev, req); + break; + } +} + +/*! + \brief handle USB Clear_Feature request + \param[in] pudev: pointer to USB device instance + \param[in] req: USB device request + \param[out] none + \retval none +*/ +static void usbd_clearfeature (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + uint8_t ep_addr = 0U; + + switch (req->bmRequestType & USB_REQ_RECIPIENT_MASK) { + case USB_REQTYPE_DEVICE: + switch (pudev->status) { + case USBD_ADDRESSED: + case USBD_CONFIGURED: + /* clear device remote wakeup feature */ + if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) { + pudev->remote_wakeup = 0U; + pudev->class_req_handler(pudev, req); + USBD_CONTRL_STATUS_TX(); + } else if (USB_FEATURE_TEST_MODE == req->wValue) { + /* can not clear test_mode feature */ + usbd_enum_error(pudev, req); + } else { + /* no operation */ + } + break; + default: + break; + } + break; + case USB_REQTYPE_INTERFACE: + switch (pudev->status) { + case USBD_ADDRESSED: + usbd_enum_error (pudev, req); + break; + case USBD_CONFIGURED: + if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) { + /* no operation */ + } else { + usbd_enum_error(pudev, req); + } + break; + default: + break; + } + break; + case USB_REQTYPE_ENDPOINT: + /* get endpoint address */ + ep_addr = LOWBYTE(req->wIndex); + + switch (pudev->status) { + case USBD_ADDRESSED: + if (IS_NOT_EP0(ep_addr)) { + usbd_enum_error(pudev, req); + } + break; + case USBD_CONFIGURED: + /* clear endpoint halt feature */ + if (USB_FEATURE_ENDP_HALT == req->wValue) { + if (IS_NOT_EP0(ep_addr)) { + usbd_ep_clear_stall(pudev, ep_addr); + } + } + + pudev->class_req_handler(pudev, req); + + USBD_CONTRL_STATUS_TX(); + break; + default: + break; + } + break; + default: + usbd_enum_error(pudev, req); + break; + } +} + +/*! + \brief handle USB Set_Feature request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_setfeature (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + uint8_t ep_addr = 0U; + + switch (req->bmRequestType & USB_REQ_RECIPIENT_MASK) { + case USB_REQTYPE_DEVICE: + switch (pudev->status) { + case USBD_ADDRESSED: + case USBD_CONFIGURED: + /* set device remote wakeup feature */ + if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) { + pudev->remote_wakeup = 1U; + + USBD_CONTRL_STATUS_TX(); + } + break; + default: + break; + } + break; + case USB_REQTYPE_INTERFACE: + switch (pudev->status) { + case USBD_ADDRESSED: + usbd_enum_error(pudev, req); + break; + case USBD_CONFIGURED: + if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) { + /* no operation */ + } else { + usbd_enum_error(pudev, req); + } + break; + default: + break; + } + break; + case USB_REQTYPE_ENDPOINT: + /* get endpoint address */ + ep_addr = LOWBYTE(req->wIndex); + + switch (pudev->status) { + case USBD_ADDRESSED: + if (IS_NOT_EP0(ep_addr)) { + usbd_enum_error(pudev, req); + } + break; + case USBD_CONFIGURED: + /* set endpoint halt feature */ + if (USB_FEATURE_ENDP_HALT == req->wValue) { + if (IS_NOT_EP0(ep_addr)) { + usbd_ep_stall(pudev, ep_addr); + } + } + USBD_CONTRL_STATUS_TX(); + break; + default: + break; + } + break; + default: + usbd_enum_error(pudev, req); + break; + } +} + +/*! + \brief handle USB Set_Address request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_setaddress (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + if ((0U == req->wIndex) && (0U == req->wLength)) { + g_device_address = (uint8_t)(req->wValue) & 0x7FU; + + if (USBD_CONFIGURED == pudev->status) { + usbd_enum_error(pudev, req); + } else { + USBD_CONTRL_STATUS_TX(); + + if (0U != g_device_address) { + pudev->status = USBD_ADDRESSED; + } else { + pudev->status = USBD_DEFAULT; + } + } + } else { + usbd_enum_error(pudev, req); + } +} + +/*! + \brief handle USB Get_Descriptor request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_getdescriptor (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + if (USB_REQTYPE_DEVICE == (req->bmRequestType & USB_REQ_RECIPIENT_MASK)) { + uint8_t *pbuf = NULL; + uint8_t desc_type = (uint8_t)(req->wValue >> 8); + uint8_t desc_index = (uint8_t)(req->wValue) & 0xFFU; + uint16_t len = 0U; + + if ((desc_type <= 0x03U) && (desc_index <= 0x05U)) { + /* call corresponding descriptor get function */ + pbuf = standard_descriptor_get[desc_type - 1U](pudev, desc_index, &len); + + if ((0U != len) && (0U != req->wLength)) { + len = MIN(len, req->wLength); + + usbd_ep_tx (pudev, EP0_IN, pbuf, len); + } + } else { + usbd_enum_error(pudev, req); + } + } else if (USB_REQTYPE_INTERFACE == (req->bmRequestType & USB_REQ_RECIPIENT_MASK)) { + if (NULL != pudev->class_req_handler) { + /* get device class special descriptor */ + pudev->class_req_handler(pudev, req); + } + } else { + /* no operation */ + } +} + +/*! + \brief handle USB Set_Descriptor request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_setdescriptor (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + /* no handle */ +} + +/*! + \brief handle USB Get_Configuration request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_getconfiguration (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + uint32_t usbd_default_config = 0U; + + if (req->wLength != 1U) { + usbd_enum_error(pudev, req); + } else { + switch (pudev->status) { + case USBD_ADDRESSED: + usbd_ep_tx (pudev, EP0_IN, (uint8_t *)&usbd_default_config, 1U); + break; + case USBD_CONFIGURED: + usbd_ep_tx (pudev, EP0_IN, &pudev->config_num, 1U); + break; + default: + usbd_enum_error(pudev, req); + break; + } + } +} + +/*! + \brief handle USB Set_Configuration request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_setconfiguration (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + static uint8_t cfgidx; + + cfgidx = (uint8_t)(req->wValue); + + if (cfgidx > USBD_CFG_MAX_NUM) { + usbd_enum_error(pudev, req); + } else { + switch (pudev->status) { + case USBD_ADDRESSED: + if (cfgidx){ + pudev->config_num = cfgidx; + pudev->status = USBD_CONFIGURED; + pudev->class_init(pudev, cfgidx); + USBD_CONTRL_STATUS_TX(); + } else { + USBD_CONTRL_STATUS_TX(); + } + break; + case USBD_CONFIGURED: + if (0U == cfgidx) { + pudev->status = USBD_ADDRESSED; + pudev->config_num = cfgidx; + pudev->class_deinit(pudev, cfgidx); + USBD_CONTRL_STATUS_TX(); + } else if (cfgidx != pudev->config_num) { + /* clear old configuration */ + pudev->class_deinit(pudev, pudev->config_num); + + /* set new configuration */ + pudev->config_num = cfgidx; + pudev->class_init(pudev, cfgidx); + USBD_CONTRL_STATUS_TX(); + } else { + USBD_CONTRL_STATUS_TX(); + } + break; + default: + break; + } + } +} + +/*! + \brief handle USB Get_Interface request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_getinterface (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + switch (pudev->status) { + case USBD_ADDRESSED: + usbd_enum_error(pudev, req); + break; + case USBD_CONFIGURED: + if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) { + if (NULL != pudev->class_req_handler) { + pudev->class_req_handler(pudev, req); + } + } else { + usbd_enum_error(pudev, req); + } + break; + default: + break; + } +} + +/*! + \brief handle USB Set_Interface request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_setinterface (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + switch (pudev->status) { + case USBD_ADDRESSED: + usbd_enum_error(pudev, req); + break; + case USBD_CONFIGURED: + if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) { + if (NULL != pudev->class_req_handler) { + pudev->class_req_handler(pudev, req); + } + + USBD_CONTRL_STATUS_TX(); + } else { + usbd_enum_error(pudev, req); + } + break; + default: + break; + } +} + +/*! + \brief handle USB SynchFrame request + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +static void usbd_synchframe (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + /* no handle */ +} + +/*! + \brief decode setup data packet + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +void usbd_setup_request_parse (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + uint8_t *setup_data = pudev->setup_packet; + + req->bmRequestType = *setup_data; + req->bRequest = *(uint8_t *)(setup_data + 1U); + req->wValue = SWAPBYTE (setup_data + 2U); + req->wIndex = SWAPBYTE (setup_data + 4U); + req->wLength = SWAPBYTE (setup_data + 6U); + + pudev->ctl_count = req->wLength; +} + +/*! + \brief handle USB enumeration error event + \param[in] pudev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +void usbd_enum_error (usbd_core_handle_struct *pudev, usb_device_req_struct *req) +{ + usbd_ep_stall(pudev, EP0); +} diff --git a/docs/motion_driver_6.12.zip b/docs/motion_driver_6.12.zip new file mode 100644 index 0000000..6c40bdb Binary files /dev/null and b/docs/motion_driver_6.12.zip differ diff --git a/docs/pictures/GD_CubeMXprj_forView.ioc b/docs/pictures/GD_CubeMXprj_forView.ioc new file mode 100644 index 0000000..53678db --- /dev/null +++ b/docs/pictures/GD_CubeMXprj_forView.ioc @@ -0,0 +1,183 @@ +#MicroXplorer Configuration settings - do not modify +File.Version=6 +I2C1.I2C_Mode=I2C_Standard +I2C1.IPParameters=I2C_Mode +KeepUserPlacement=false +Mcu.Family=STM32F1 +Mcu.IP0=I2C1 +Mcu.IP1=NVIC +Mcu.IP2=RCC +Mcu.IP3=SYS +Mcu.IP4=USART2 +Mcu.IPNb=5 +Mcu.Name=STM32F103C(8-B)Tx +Mcu.Package=LQFP48 +Mcu.Pin0=PC14-OSC32_IN +Mcu.Pin1=PC15-OSC32_OUT +Mcu.Pin10=PA13 +Mcu.Pin11=PA14 +Mcu.Pin12=PB4 +Mcu.Pin13=PB5 +Mcu.Pin14=PB6 +Mcu.Pin15=PB7 +Mcu.Pin16=PB8 +Mcu.Pin17=PB9 +Mcu.Pin18=VP_SYS_VS_Systick +Mcu.Pin2=PA0-WKUP +Mcu.Pin3=PA1 +Mcu.Pin4=PA2 +Mcu.Pin5=PA3 +Mcu.Pin6=PA4 +Mcu.Pin7=PB10 +Mcu.Pin8=PA9 +Mcu.Pin9=PA10 +Mcu.PinsNb=19 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32F103C8Tx +MxCube.Version=5.1.0 +MxDb.Version=DB.5.0.10 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false +PA0-WKUP.GPIOParameters=GPIO_Label +PA0-WKUP.GPIO_Label=LED1 +PA0-WKUP.Locked=true +PA0-WKUP.Signal=GPIO_Output +PA1.GPIOParameters=GPIO_Label +PA1.GPIO_Label=AUX2 +PA1.Locked=true +PA1.Signal=GPIO_Output +PA10.GPIOParameters=GPIO_Label +PA10.GPIO_Label=AUX4 +PA10.Locked=true +PA10.Signal=GPIO_Input +PA13.Locked=true +PA13.Mode=Serial_Wire +PA13.Signal=SYS_JTMS-SWDIO +PA14.Locked=true +PA14.Mode=Serial_Wire +PA14.Signal=SYS_JTCK-SWCLK +PA2.GPIOParameters=GPIO_Label +PA2.GPIO_Label=USART_MAIN_TX +PA2.Mode=Asynchronous +PA2.Signal=USART2_TX +PA3.GPIOParameters=GPIO_Label +PA3.GPIO_Label=USART_MAIN_RX +PA3.Locked=true +PA3.Mode=Asynchronous +PA3.Signal=USART2_RX +PA4.GPIOParameters=GPIO_Label +PA4.GPIO_Label=SENSOR1 +PA4.Locked=true +PA4.Signal=GPIO_Input +PA9.GPIOParameters=GPIO_Label +PA9.GPIO_Label=AUX5 +PA9.Locked=true +PA9.Signal=GPIO_Input +PB10.GPIOParameters=GPIO_Label +PB10.GPIO_Label=AUX3 +PB10.Locked=true +PB10.Signal=GPIO_Output +PB4.GPIOParameters=GPIO_Label +PB4.GPIO_Label=LED5 +PB4.Locked=true +PB4.Signal=GPIO_Output +PB5.GPIOParameters=GPIO_Label +PB5.GPIO_Label=LED4 +PB5.Locked=true +PB5.Signal=GPIO_Output +PB6.GPIOParameters=GPIO_Label +PB6.GPIO_Label=MPU_SCL +PB6.Locked=true +PB6.Mode=I2C +PB6.Signal=I2C1_SCL +PB7.GPIOParameters=GPIO_Label +PB7.GPIO_Label=MPU_SDA +PB7.Locked=true +PB7.Mode=I2C +PB7.Signal=I2C1_SDA +PB8.GPIOParameters=GPIO_Label +PB8.GPIO_Label=LED3 +PB8.Locked=true +PB8.Signal=GPIO_Output +PB9.GPIOParameters=GPIO_Label +PB9.GPIO_Label=LED2 +PB9.Locked=true +PB9.Signal=GPIO_Output +PC14-OSC32_IN.GPIOParameters=GPIO_Label +PC14-OSC32_IN.GPIO_Label=SENSOR2 +PC14-OSC32_IN.Locked=true +PC14-OSC32_IN.Signal=GPIO_Input +PC15-OSC32_OUT.GPIOParameters=GPIO_Label +PC15-OSC32_OUT.GPIO_Label=AUX1_PU +PC15-OSC32_OUT.Locked=true +PC15-OSC32_OUT.Signal=GPIO_Input +PCC.Checker=false +PCC.Line=STM32F103 +PCC.MCU=STM32F103C(8-B)Tx +PCC.PartNumber=STM32F103C8Tx +PCC.Seq0=0 +PCC.Series=STM32F1 +PCC.Temperature=25 +PCC.Vdd=3.3 +PinOutPanel.RotationAngle=-90 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=true +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32F103C8Tx +ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.7.0 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=GD_CubeMXprj_forView.ioc +ProjectManager.ProjectName=GD_CubeMXprj_forView +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=Other Toolchains (GPDSC) +ProjectManager.ToolChainLocation= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_I2C1_Init-I2C1-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true +RCC.ADCFreqValue=24000000 +RCC.AHBFreq_Value=48000000 +RCC.APB1CLKDivider=RCC_HCLK_DIV2 +RCC.APB1Freq_Value=24000000 +RCC.APB1TimFreq_Value=48000000 +RCC.APB2Freq_Value=48000000 +RCC.APB2TimFreq_Value=48000000 +RCC.FCLKCortexFreq_Value=48000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=48000000 +RCC.IPParameters=ADCFreqValue,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USBFreq_Value +RCC.MCOFreq_Value=48000000 +RCC.PLLCLKFreq_Value=48000000 +RCC.PLLMCOFreq_Value=24000000 +RCC.PLLMUL=RCC_PLL_MUL12 +RCC.SYSCLKFreq_VALUE=48000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.TimSysFreq_Value=48000000 +RCC.USBFreq_Value=48000000 +USART2.BaudRate=38400 +USART2.IPParameters=VirtualMode,BaudRate +USART2.VirtualMode=VM_ASYNC +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +board=custom diff --git a/docs/pictures/GD_pics.pptx b/docs/pictures/GD_pics.pptx new file mode 100644 index 0000000..2962326 Binary files /dev/null and b/docs/pictures/GD_pics.pptx differ diff --git a/docs/pictures/GD_pinout.psd b/docs/pictures/GD_pinout.psd new file mode 100644 index 0000000..d3bb984 Binary files /dev/null and b/docs/pictures/GD_pinout.psd differ diff --git a/docs/pictures/MCU_pinout.png b/docs/pictures/MCU_pinout.png new file mode 100644 index 0000000..c668a75 Binary files /dev/null and b/docs/pictures/MCU_pinout.png differ diff --git a/docs/pictures/MPU6050_pinout.png b/docs/pictures/MPU6050_pinout.png new file mode 100644 index 0000000..c844d65 Binary files /dev/null and b/docs/pictures/MPU6050_pinout.png differ diff --git a/docs/pictures/back.png b/docs/pictures/back.png new file mode 100644 index 0000000..f4c2133 Binary files /dev/null and b/docs/pictures/back.png differ diff --git a/docs/pictures/front.png b/docs/pictures/front.png new file mode 100644 index 0000000..e702171 Binary files /dev/null and b/docs/pictures/front.png differ diff --git a/docs/pictures/sideboard_pinout.png b/docs/pictures/sideboard_pinout.png new file mode 100644 index 0000000..a0b1c40 Binary files /dev/null and b/docs/pictures/sideboard_pinout.png differ diff --git a/docs/pictures/sketch_processing_pic.png b/docs/pictures/sketch_processing_pic.png new file mode 100644 index 0000000..ca37c04 Binary files /dev/null and b/docs/pictures/sketch_processing_pic.png differ diff --git a/docs/sketch_processing/sketch_processing.pde b/docs/sketch_processing/sketch_processing.pde new file mode 100644 index 0000000..45a0079 --- /dev/null +++ b/docs/sketch_processing/sketch_processing.pde @@ -0,0 +1,82 @@ +/* + hoverboard-sidebboard-hack MPU6050 IMU - 3D Visualization Example + Copyright (C) 2020-2021 Emanuel FERU +*/ +import processing.serial.*; +import java.awt.event.KeyEvent; +import java.io.IOException; + +Serial myPort; +float roll, pitch,yaw; +int idx = 0; +int inBytePrev; +short bufWord; + +void setup() { + size (1400, 800, P3D); + printArray(Serial.list()); // List all the available serial ports + myPort = new Serial(this, "COM5", 38400); // starts the serial communication + +} + +void draw() { + + while (myPort.available() > 0) { + int inByte = myPort.read(); + bufWord = (short)(inBytePrev | (inByte << 8)); + idx++; + if(bufWord == -21846) { // check START_FRAME = 0xAAAA + idx = 0; + } + if (idx == 2) { + roll = float(bufWord) / 100; + } + if (idx == 4) { + pitch = float(bufWord) / 100; + } + if (idx == 6) { + yaw = float(bufWord) / 100; + } + inBytePrev = inByte; + } + + // println(bufWord); //<>// + + translate(width/2, height/2, 0); + background(51); + textSize(22); + text("Roll: " + roll + " Pitch: " + pitch + " Yaw: " + yaw, -200, 300); + + // Rotate the object + rotateX(radians(roll)); + rotateZ(radians(-pitch)); + rotateY(radians(yaw)); + + // 3D 0bject + + // Draw box with text + fill(35, 133, 54); // Make board GREEN + box (426, 30, 220); + textSize(25); + fill(255, 255, 255); + text("MPU-6050 DMP DEMO", -150, 10, 111); + + // Add other boxes + translate(-70, -18, -30); + fill(100, 100, 100); + box (20, 5, 20); // MPU-6050 + + translate(70, 0, 0); + box (40, 5, 40); // GD32 + + translate(0, 0, -70); + fill(255, 255, 255); + box (50, 40, 15); // USART Main + + translate(0, 0, 200); + box (50, 40, 15); // Color Led connector + + translate(-60, 0, 0); + box (40, 40, 15); // Blue Led connector + +} diff --git a/startup_gd32f1x0.s b/startup_gd32f1x0.s new file mode 100644 index 0000000..f87b2df --- /dev/null +++ b/startup_gd32f1x0.s @@ -0,0 +1,377 @@ + /* This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Configure the clock system + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M3 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + */ + + + .syntax unified + .cpu cortex-m3 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + +.equ BootRAM, 0xF108F85F +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss + +/* Call the clock system intitialization function.*/ + bl SystemInit +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl main + bx lr +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word LVD_IRQHandler + .word RTC_IRQHandler + .word FMC_IRQHandler + .word RCU_IRQHandler + .word EXTI0_1_IRQHandler + .word EXTI2_3_IRQHandler + .word EXTI4_15_IRQHandler + .word TSI_IRQHandler + .word DMA_Channel0_IRQHandler + .word DMA_Channel1_2_IRQHandler + .word DMA_Channel3_4_IRQHandler + .word ADC_CMP_IRQHandler + .word TIMER0_BRK_UP_TRG_COM_IRQHandler + .word TIMER0_Channel_IRQHandler + .word TIMER1_IRQHandler + .word TIMER2_IRQHandler + .word TIMER5_DAC_IRQHandler + .word 0 + .word TIMER13_IRQHandler + .word TIMER14_IRQHandler + .word TIMER15_IRQHandler + .word TIMER16_IRQHandler + .word I2C0_EV_IRQHandler + .word I2C1_EV_IRQHandler + .word SPI0_IRQHandler + .word SPI1_IRQHandler + .word USART0_IRQHandler + .word USART1_IRQHandler + .word 0 + .word CEC_IRQHandler + .word 0 + .word I2C0_ER_IRQHandler + .word 0 + .word I2C1_ER_IRQHandler + .word I2C2_EV_IRQHandler + .word I2C2_ER_IRQHandler + .word USBD_LP_IRQHandler + .word USBD_HP_IRQHandler + .word 0 + .word 0 + .word 0 + .word USBDWakeUp_IRQHandler + .word CAN0_TX_IRQHandler + .word CAN0_RX0_IRQHandler + .word CAN0_RX1_IRQHandler + .word CAN0_SCE_IRQHandler + .word SLCD_IRQHandler + .word DMA_Channel5_6_IRQHandler + .word 0 + .word 0 + .word SPI2_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word CAN1_TX_IRQHandler + .word CAN1_RX0_IRQHandler + .word CAN1_RX1_IRQHandler + .word CAN1_SCE_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak LVD_IRQHandler + .thumb_set LVD_IRQHandler,Default_Handler + + .weak RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak FMC_IRQHandler + .thumb_set FMC_IRQHandler,Default_Handler + + .weak RCU_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_1_IRQHandler + .thumb_set EXTI0_1_IRQHandler,Default_Handler + + .weak EXTI2_3_IRQHandler + .thumb_set EXTI2_3_IRQHandler,Default_Handler + + .weak EXTI4_15_IRQHandler + .thumb_set EXTI4_15_IRQHandler,Default_Handler + + .weak TSI_IRQHandler + .thumb_set TSI_IRQHandler,Default_Handler + + .weak DMA_Channel0_IRQHandler + .thumb_set DMA_Channel0_IRQHandler,Default_Handler + + .weak DMA_Channel1_2_IRQHandler + .thumb_set DMA_Channel1_2_IRQHandler,Default_Handler + + .weak DMA_Channel3_4_IRQHandler + .thumb_set DMA_Channel3_4_IRQHandler,Default_Handler + + .weak ADC_CMP_IRQHandler + .thumb_set ADC_CMP_IRQHandler,Default_Handler + + .weak TIMER0_BRK_UP_TRG_COM_IRQHandler + .thumb_set TIMER0_BRK_UP_TRG_COM_IRQHandler,Default_Handler + + .weak TIMER0_Channel_IRQHandler + .thumb_set TIMER0_Channel_IRQHandler,Default_Handler + + .weak TIMER1_IRQHandler + .thumb_set TIMER1_IRQHandler,Default_Handler + + .weak TIMER2_IRQHandler + .thumb_set TIMER2_IRQHandler,Default_Handler + + .weak TIMER5_DAC_IRQHandler + .thumb_set TIMER5_DAC_IRQHandler,Default_Handler + + .weak TIMER13_IRQHandler + .thumb_set TIMER13_IRQHandler,Default_Handler + + .weak TIMER14_IRQHandler + .thumb_set TIMER14_IRQHandler,Default_Handler + + .weak TIMER15_IRQHandler + .thumb_set TIMER15_IRQHandler,Default_Handler + + .weak TIMER16_IRQHandler + .thumb_set TIMER16_IRQHandler,Default_Handler + + .weak I2C0_EV_IRQHandler + .thumb_set I2C0_EV_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak SPI0_IRQHandler + .thumb_set SPI0_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak USART0_IRQHandler + .thumb_set USART0_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak CEC_IRQHandler + .thumb_set CEC_IRQHandler,Default_Handler + + .weak I2C0_ER_IRQHandler + .thumb_set I2C0_ER_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak USBD_LP_IRQHandler + .thumb_set USBD_LP_IRQHandler,Default_Handler + + .weak USBD_HP_IRQHandler + .thumb_set USBD_HP_IRQHandler,Default_Handler + + .weak USBDWakeUp_IRQHandler + .thumb_set USBDWakeUp_IRQHandler,Default_Handler + + .weak CAN0_TX_IRQHandler + .thumb_set CAN0_TX_IRQHandler,Default_Handler + + .weak CAN0_RX0_IRQHandler + .thumb_set CAN0_RX0_IRQHandler,Default_Handler + + .weak CAN0_RX1_IRQHandler + .thumb_set CAN0_RX1_IRQHandler,Default_Handler + + .weak CAN0_SCE_IRQHandler + .thumb_set CAN0_SCE_IRQHandler,Default_Handler + + .weak SLCD_IRQHandler + .thumb_set SLCD_IRQHandler,Default_Handler + + .weak DMA_Channel5_6_IRQHandler + .thumb_set DMA_Channel5_6_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak CAN1_TX_IRQHandler + .thumb_set CAN1_TX_IRQHandler,Default_Handler + + .weak CAN1_RX0_IRQHandler + .thumb_set CAN1_RX0_IRQHandler,Default_Handler + + .weak CAN1_RX1_IRQHandler + .thumb_set CAN1_RX1_IRQHandler,Default_Handler + + .weak CAN1_SCE_IRQHandler + .thumb_set CAN1_SCE_IRQHandler,Default_Handler