diff --git a/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Include/gd32f4xx.h b/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Include/gd32f4xx.h new file mode 100644 index 0000000000..722e943b88 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Include/gd32f4xx.h @@ -0,0 +1,265 @@ +/*! + \file gd32f4xx.h + \brief general definitions for GD32F4xx +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware update for GD32F4xx +*/ + +#ifndef GD32F4XX_H +#define GD32F4XX_H + +#ifdef cplusplus + extern "C" { +#endif + +/* define GD32F4xx */ +#if !defined (GD32F4xx) + #define GD32F4xx +#endif /* define GD32F4xx */ +#if !defined (GD32F4xx) + #error "Please select the target GD32F4xx device used in your application (in gd32f4xx.h file)" +#endif /* undefine GD32F4xx tip */ + +/* define value of high speed crystal oscillator (HXTAL) in Hz */ +#if !defined (HXTAL_VALUE) +#define HXTAL_VALUE ((uint32_t)25000000) +#endif /* high speed crystal oscillator value */ + +/* define startup timeout value of high speed crystal oscillator (HXTAL) */ +#if !defined (HXTAL_STARTUP_TIMEOUT) +#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0x0800) +#endif /* high speed crystal oscillator startup timeout */ + +/* define value of internal 16MHz RC oscillator (IRC16M) in Hz */ +#if !defined (IRC16M_VALUE) +#define IRC16M_VALUE ((uint32_t)16000000) +#endif /* internal 16MHz RC oscillator value */ + +/* define startup timeout value of internal 16MHz RC oscillator (IRC16M) */ +#if !defined (IRC16M_STARTUP_TIMEOUT) +#define IRC16M_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* internal 16MHz RC oscillator startup timeout */ + +/* define value of internal 32KHz RC oscillator(IRC32K) in Hz */ +#if !defined (IRC32K_VALUE) +#define IRC32K_VALUE ((uint32_t)32000) +#endif /* internal 32KHz RC oscillator value */ + +/* define value of low speed crystal oscillator (LXTAL)in Hz */ +#if !defined (LXTAL_VALUE) +#define LXTAL_VALUE ((uint32_t)32768) +#endif /* low speed crystal oscillator value */ + +/* I2S external clock in selection */ +//#define I2S_EXTERNAL_CLOCK_IN (uint32_t)12288000U + +/* GD32F4xx firmware library version number V1.0 */ +#define __GD32F4xx_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:24] main version */ +#define __GD32F4xx_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __GD32F4xx_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __GD32F4xx_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __GD32F4xx_STDPERIPH_VERSION ((__GD32F4xx_STDPERIPH_VERSION_MAIN << 24)\ + |(__GD32F4xx_STDPERIPH_VERSION_SUB1 << 16)\ + |(__GD32F4xx_STDPERIPH_VERSION_SUB2 << 8)\ + |(__GD32F4xx_STDPERIPH_VERSION_RC)) + +/* configuration of the Cortex-M4 processor and core peripherals */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< GD32F4xx do not provide MPU */ +#define __NVIC_PRIO_BITS 4 /*!< GD32F4xx uses 4 bits for the priority levels */ +#define __VENDOR_SYSTICKCONFIG 0 /*!< set to 1 if different sysTick config is used */ +#define __FPU_PRESENT 1 /*!< FPU present */ +/* define interrupt number */ +typedef enum IRQn +{ + /* Cortex-M4 processor exceptions numbers */ + NonMaskableInt_IRQn = -14, /*!< 2 non maskable interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 memory management interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M4 bus fault interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M4 usage fault interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV call interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 debug monitor interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M4 pend SV interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M4 system tick interrupt */ + /* interruput numbers */ + WWDGT_IRQn = 0, /*!< window watchDog timer interrupt */ + LVD_IRQn = 1, /*!< LVD through EXTI line detect interrupt */ + TAMPER_STAMP_IRQn = 2, /*!< Tamper and TimeStamp through EXTI Line detect */ + RTC_WKUP_IRQn = 3, /*!< RTC Wakeup through EXTI line interrupt */ + FMC_IRQn = 4, /*!< FMC interrupt */ + RCU_CTC_IRQn = 5, /*!< RCU and CTC interrupt */ + EXTI0_IRQn = 6, /*!< EXTI line 0 interrupts */ + EXTI1_IRQn = 7, /*!< EXTI line 1 interrupts */ + EXTI2_IRQn = 8, /*!< EXTI line 2 interrupts */ + EXTI3_IRQn = 9, /*!< EXTI line 3 interrupts */ + EXTI4_IRQn = 10, /*!< EXTI line 4 interrupts */ + DMA0_Channel0_IRQn = 11, /*!< DMA0 Channel0 Interrupt */ + DMA0_Channel1_IRQn = 12, /*!< DMA0 Channel1 Interrupt */ + DMA0_Channel2_IRQn = 13, /*!< DMA0 Channel2 Interrupt */ + DMA0_Channel3_IRQn = 14, /*!< DMA0 Channel3 Interrupt */ + DMA0_Channel4_IRQn = 15, /*!< DMA0 Channel4 Interrupt */ + DMA0_Channel5_IRQn = 16, /*!< DMA0 Channel5 Interrupt */ + DMA0_Channel6_IRQn = 17, /*!< DMA0 Channel6 Interrupt */ + ADC_IRQn = 18, /*!< ADC interrupt */ + CAN0_TX_IRQn = 19, /*!< CAN0 TX interrupts */ + CAN0_RX0_IRQn = 20, /*!< CAN0 RX0 interrupts */ + CAN0_RX1_IRQn = 21, /*!< CAN0 RX1 interrupts */ + CAN0_EWMC_IRQn = 22, /*!< CAN0 EWMC interrupts */ + EXTI5_9_IRQn = 23, /*!< EXTI[9:5] interrupts */ + TIMER0_BRK_TIMER8_IRQn = 24, /*!< TIMER0 Break and TIMER8 interrupts */ + TIMER0_UP_TIMER9_IRQn = 25, /*!< TIMER0 Update and TIMER9 interrupts */ + TIMER0_TRG_CMT_TIMER10_IRQn = 26, /*!< TIMER0 Trigger and Commutation and TIMER10 interrupts */ + TIMER0_CC_IRQn = 27, /*!< TIMER0 Capture Compare interrupts */ + TIMER1_IRQn = 28, /*!< TIMER1 interrupt */ + TIMER2_IRQn = 29, /*!< TIMER2 interrupt */ + TIMER3_IRQn = 30, /*!< TIMER3 interrupts */ + I2C0_EV_IRQn = 31, /*!< I2C0 event interrupt */ + I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */ + I2C1_EV_IRQn = 33, /*!< I2C1 event interrupt */ + I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */ + SPI0_IRQn = 35, /*!< SPI0 interrupt */ + SPI1_IRQn = 36, /*!< SPI1 interrupt */ + USART0_IRQn = 37, /*!< USART0 interrupt */ + USART1_IRQn = 38, /*!< USART1 interrupt */ + USART2_IRQn = 39, /*!< USART2 interrupt */ + EXTI10_15_IRQn = 40, /*!< EXTI[15:10] interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm interrupt */ + USBFS_WKUP_IRQn = 42, /*!< USBFS Wakeup interrupt */ + TIMER7_BRK_TIMER11_IRQn = 43, /*!< TIMER7 Break and TIMER11 interrupts */ + TIMER7_UP_TIMER12_IRQn = 44, /*!< TIMER7 Update and TIMER12 interrupts */ + TIMER7_TRG_CMT_TIMER13_IRQn = 45, /*!< TIMER7 Trigger and Commutation and TIMER13 interrupts */ + TIMER7_CC_IRQn = 46, /*!< TIMER7 Capture Compare interrupts */ + DMA0_Channel7_IRQn = 47, /*!< DMA0 Channel7 Interrupt */ + EXMC_IRQn = 48, /*!< EXMC Interrupt */ + SDIO_IRQn = 49, /*!< SDIO Interrupt */ + TIMER4_IRQn = 50, /*!< TIMER4 Interrupt */ + SPI2_IRQn = 51, /*!< SPI2 Interrupt */ + UART3_IRQn = 52, /*!< UART3 Interrupt */ + UART4_IRQn = 53, /*!< UART4 Interrupt */ + TIMER5_DAC_IRQn = 54, /*!< TIMER5 and DAC0 DAC1 Underrun error Interrupt */ + TIMER6_IRQn = 55, /*!< TIMER6 Interrupt */ + DMA1_Channel0_IRQn = 56, /*!< DMA1 Channel0 Interrupt */ + DMA1_Channel1_IRQn = 57, /*!< DMA1 Channel1 Interrupt */ + DMA1_Channel2_IRQn = 58, /*!< DMA1 Channel2 Interrupt */ + DMA1_Channel3_IRQn = 59, /*!< DMA1 Channel3 Interrupt */ + DMA1_Channel4_IRQn = 60, /*!< DMA1 Channel4 Interrupt */ + ENET_IRQn = 61, /*!< Ethernet Interrupt */ + ENET_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI Line Interrupt */ + CAN1_TX_IRQn = 63, /*!< CAN1 TX Interrupt */ + CAN1_RX0_IRQn = 64, /*!< CAN1 RX0 Interrupt */ + CAN1_RX1_IRQn = 65, /*!< CAN1 RX1 Interrupt */ + CAN1_EWMC_IRQn = 66, /*!< CAN1 EWMC Interrupt */ + USBFS_IRQn = 67, /*!< USBFS Interrupt */ + DMA1_Channel5_IRQn = 68, /*!< DMA1 Channel5 Interrupt */ + DMA1_Channel6_IRQn = 69, /*!< DMA1 Channel6 Interrupt */ + DMA1_Channel7_IRQn = 70, /*!< DMA1 Channel7 Interrupt */ + USART5_IRQn = 71, /*!< USART5 Interrupt */ + I2C2_EV_IRQn = 72, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 73, /*!< I2C2 Error Interrupt */ + USBHS_EP1_Out_IRQn = 74, /*!< USBHS Endpoint 1 Out Interrupt */ + USBHS_EP1_In_IRQn = 75, /*!< USBHS Endpoint 1 in Interrupt */ + USBHS_WKUP_IRQn = 76, /*!< USBHS Wakeup through EXTI Line Interrupt */ + USBHS_IRQn = 77, /*!< USBHS Interrupt */ + DCI_IRQn = 78, /*!< DCI Interrupt */ + TRNG_IRQn = 80, /*!< TRNG Interrupt */ + FPU_IRQn = 81, /*!< FPU Interrupt */ + UART6_IRQn = 82, /*!< UART6 Interrupt */ + UART7_IRQn = 83, /*!< UART7 Interrupt */ + SPI3_IRQn = 84, /*!< SPI3 Interrupt */ + SPI4_IRQn = 85, /*!< SPI4 Interrupt */ + SPI5_IRQn = 86, /*!< SPI5 Interrupt */ + TLI_IRQn = 88, /*!< TLI Interrupt */ + TLI_ER_IRQn = 89, /*!< TLI Error Interrupt */ + IPA_IRQn = 90, /*!< IPA Interrupt */ +} IRQn_Type; + +/* includes */ +#include "core_cm4.h" +#include "system_gd32f4xx.h" +#include + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {FALSE = 0, TRUE = !FALSE} bool; +typedef enum {RESET = 0, SET = !RESET} FlagStatus; +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus; + +/* bit operations */ +#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr)) +#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr)) +#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr)) +#define BIT(x) ((uint32_t)((uint32_t)0x01U<<(x))) +#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) +#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start)) + +/* main flash and SRAM memory map */ +#define FLASH_BASE ((uint32_t)0x08000000U) /*!< main FLASH base address */ +#define TCMSRAM_BASE ((uint32_t)0x10000000U) /*!< TCMSRAM(64KB) base address */ +#define OPTION_BASE ((uint32_t)0x1FFEC000U) /*!< Option bytes base address */ +#define SRAM_BASE ((uint32_t)0x20000000U) /*!< SRAM0 base address */ + +/* peripheral memory map */ +#define APB1_BUS_BASE ((uint32_t)0x40000000U) /*!< apb1 base address */ +#define APB2_BUS_BASE ((uint32_t)0x40010000U) /*!< apb2 base address */ +#define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */ +#define AHB2_BUS_BASE ((uint32_t)0x50000000U) /*!< ahb2 base address */ + +/* EXMC memory map */ +#define EXMC_BASE ((uint32_t)0xA0000000U) /*!< EXMC register base address */ + +/* advanced peripheral bus 1 memory map */ +#define TIMER_BASE (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address */ +#define RTC_BASE (APB1_BUS_BASE + 0x00002800U) /*!< RTC base address */ +#define WWDGT_BASE (APB1_BUS_BASE + 0x00002C00U) /*!< WWDGT base address */ +#define FWDGT_BASE (APB1_BUS_BASE + 0x00003000U) /*!< FWDGT base address */ +#define I2S_ADD_BASE (APB1_BUS_BASE + 0x00003400U) /*!< I2S1_add base address */ +#define SPI_BASE (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address */ +#define USART_BASE (APB1_BUS_BASE + 0x00004400U) /*!< USART base address */ +#define I2C_BASE (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address */ +#define CAN_BASE (APB1_BUS_BASE + 0x00006400U) /*!< CAN base address */ +#define CTC_BASE (APB1_BUS_BASE + 0x00006C00U) /*!< CTC base address */ +#define PMU_BASE (APB1_BUS_BASE + 0x00007000U) /*!< PMU base address */ +#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */ +#define IREF_BASE (APB1_BUS_BASE + 0x0000C400U) /*!< IREF base address */ + +/* advanced peripheral bus 2 memory map */ +#define TLI_BASE (APB2_BUS_BASE + 0x00006800U) /*!< TLI base address */ +#define SYSCFG_BASE (APB2_BUS_BASE + 0x00003800U) /*!< SYSCFG base address */ +#define EXTI_BASE (APB2_BUS_BASE + 0x00003C00U) /*!< EXTI base address */ +#define SDIO_BASE (APB2_BUS_BASE + 0x00002C00U) /*!< SDIO base address */ +#define ADC_BASE (APB2_BUS_BASE + 0x00002000U) /*!< ADC base address */ +/* advanced high performance bus 1 memory map */ +#define GPIO_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< GPIO base address */ +#define CRC_BASE (AHB1_BUS_BASE + 0x00003000U) /*!< CRC base address */ +#define RCU_BASE (AHB1_BUS_BASE + 0x00003800U) /*!< RCU base address */ +#define FMC_BASE (AHB1_BUS_BASE + 0x00003C00U) /*!< FMC base address */ +#define BKPSRAM_BASE (AHB1_BUS_BASE + 0x00004000U) /*!< BKPSRAM base address */ +#define DMA_BASE (AHB1_BUS_BASE + 0x00006000U) /*!< DMA base address */ +#define ENET_BASE (AHB1_BUS_BASE + 0x00008000U) /*!< ENET base address */ +#define IPA_BASE (AHB1_BUS_BASE + 0x0000B000U) /*!< IPA base address */ +#define USBHS_BASE (AHB1_BUS_BASE + 0x00020000U) /*!< USBHS base address */ + +/* advanced high performance bus 2 memory map */ +#define USBFS_BASE (AHB2_BUS_BASE + 0x00000000U) /*!< USBFS base address */ +#define DCI_BASE (AHB2_BUS_BASE + 0x00050000U) /*!< DCI base address */ +#define TRNG_BASE (AHB2_BUS_BASE + 0x00060800U) /*!< TRNG base address */ +/* option byte and debug memory map */ +#define OB_BASE ((uint32_t)0x1FFEC000U) /*!< OB base address */ +#define DBG_BASE ((uint32_t)0xE0042000U) /*!< DBG base address */ + +/* define marco USE_STDPERIPH_DRIVER */ +#if !defined USE_STDPERIPH_DRIVER +#define USE_STDPERIPH_DRIVER +#endif +#ifdef USE_STDPERIPH_DRIVER +#include "gd32f4xx_libopt.h" +#endif /* USE_STDPERIPH_DRIVER */ + +#ifdef cplusplus +} +#endif +#endif diff --git a/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Include/system_gd32f4xx.h b/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Include/system_gd32f4xx.h new file mode 100644 index 0000000000..ab8e80e7e9 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Include/system_gd32f4xx.h @@ -0,0 +1,58 @@ +/*! + \file system_gd32f4xx.h + \brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File for + GD32F4xx Device Series +*/ + +/* Copyright (c) 2012 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#ifndef SYSTEM_GD32F4XX_H +#define SYSTEM_GD32F4XX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* system clock frequency (core clock) */ +extern uint32_t SystemCoreClock; + +/* function declarations */ +/* initialize the system and update the SystemCoreClock variable */ +extern void SystemInit (void); +/* update the SystemCoreClock with current core clock retrieved from cpu registers */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_GD32F4XX_H */ diff --git a/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s b/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s new file mode 100644 index 0000000000..eb11e413dc --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s @@ -0,0 +1,427 @@ +;/*! +; \file startup_gd32f4xx.s +; \brief start up file +;*/ + +;/* +; Copyright (C) 2016 GigaDevice + +; 2016-08-15, V1.0.0, firmware for GD32F4xx +;*/ + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000400 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; /* reset Vector Mapped to at Address 0 */ + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + +; /* external interrupts handler */ + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect + DCD TAMPER_STAMP_IRQHandler ; 18:Tamper and TimeStamp through EXTI Line detect + DCD RTC_WKUP_IRQHandler ; 19:RTC Wakeup through EXTI Line + DCD FMC_IRQHandler ; 20:FMC + DCD RCU_CTC_IRQHandler ; 21:RCU and CTC + DCD EXTI0_IRQHandler ; 22:EXTI Line 0 + DCD EXTI1_IRQHandler ; 23:EXTI Line 1 + DCD EXTI2_IRQHandler ; 24:EXTI Line 2 + DCD EXTI3_IRQHandler ; 25:EXTI Line 3 + DCD EXTI4_IRQHandler ; 26:EXTI Line 4 + DCD DMA0_Channel0_IRQHandler ; 27:DMA0 Channel0 + DCD DMA0_Channel1_IRQHandler ; 28:DMA0 Channel1 + DCD DMA0_Channel2_IRQHandler ; 29:DMA0 Channel2 + DCD DMA0_Channel3_IRQHandler ; 30:DMA0 Channel3 + DCD DMA0_Channel4_IRQHandler ; 31:DMA0 Channel4 + DCD DMA0_Channel5_IRQHandler ; 32:DMA0 Channel5 + DCD DMA0_Channel6_IRQHandler ; 33:DMA0 Channel6 + DCD ADC_IRQHandler ; 34:ADC + DCD CAN0_TX_IRQHandler ; 35:CAN0 TX + DCD CAN0_RX0_IRQHandler ; 36:CAN0 RX0 + DCD CAN0_RX1_IRQHandler ; 37:CAN0 RX1 + DCD CAN0_EWMC_IRQHandler ; 38:CAN0 EWMC + DCD EXTI5_9_IRQHandler ; 39:EXTI5 to EXTI9 + DCD TIMER0_BRK_TIMER8_IRQHandler ; 40:TIMER0 Break and TIMER8 + DCD TIMER0_UP_TIMER9_IRQHandler ; 41:TIMER0 Update and TIMER9 + DCD TIMER0_TRG_CMT_TIMER10_IRQHandler ; 42:TIMER0 Trigger and Commutation and TIMER10 + DCD TIMER0_CC_IRQHandler ; 43:TIMER0 Capture Compare + DCD TIMER1_IRQHandler ; 44:TIMER1 + DCD TIMER2_IRQHandler ; 45:TIMER2 + DCD TIMER3_IRQHandler ; 46:TIMER3 + DCD I2C0_EV_IRQHandler ; 47:I2C0 Event + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD I2C1_EV_IRQHandler ; 49:I2C1 Event + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error + DCD SPI0_IRQHandler ; 51:SPI0 + DCD SPI1_IRQHandler ; 52:SPI1 + DCD USART0_IRQHandler ; 53:USART0 + DCD USART1_IRQHandler ; 54:USART1 + DCD USART2_IRQHandler ; 55:USART2 + DCD EXTI10_15_IRQHandler ; 56:EXTI10 to EXTI15 + DCD RTC_Alarm_IRQHandler ; 57:RTC Alarm + DCD USBFS_WKUP_IRQHandler ; 58:USBFS Wakeup + DCD TIMER7_BRK_TIMER11_IRQHandler ; 59:TIMER7 Break and TIMER11 + DCD TIMER7_UP_TIMER12_IRQHandler ; 60:TIMER7 Update and TIMER12 + DCD TIMER7_TRG_CMT_TIMER13_IRQHandler ; 61:TIMER7 Trigger and Commutation and TIMER13 + DCD TIMER7_CC_IRQHandler ; 62:TIMER7 Capture Compare + DCD DMA0_Channel7_IRQHandler ; 63:DMA0 Channel7 + DCD EXMC_IRQHandler ; 64:EXMC + DCD SDIO_IRQHandler ; 65:SDIO + DCD TIMER4_IRQHandler ; 66:TIMER4 + DCD SPI2_IRQHandler ; 67:SPI2 + DCD UART3_IRQHandler ; 68:UART3 + DCD UART4_IRQHandler ; 69:UART4 + DCD TIMER5_DAC_IRQHandler ; 70:TIMER5 and DAC0 DAC1 Underrun error + DCD TIMER6_IRQHandler ; 71:TIMER6 + DCD DMA1_Channel0_IRQHandler ; 72:DMA1 Channel0 + DCD DMA1_Channel1_IRQHandler ; 73:DMA1 Channel1 + DCD DMA1_Channel2_IRQHandler ; 74:DMA1 Channel2 + DCD DMA1_Channel3_IRQHandler ; 75:DMA1 Channel3 + DCD DMA1_Channel4_IRQHandler ; 76:DMA1 Channel4 + DCD ENET_IRQHandler ; 77:Ethernet + DCD ENET_WKUP_IRQHandler ; 78:Ethernet Wakeup through EXTI Line + DCD CAN1_TX_IRQHandler ; 79:CAN1 TX + DCD CAN1_RX0_IRQHandler ; 80:CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; 81:CAN1 RX1 + DCD CAN1_EWMC_IRQHandler ; 82:CAN1 EWMC + DCD USBFS_IRQHandler ; 83:USBFS + DCD DMA1_Channel5_IRQHandler ; 84:DMA1 Channel5 + DCD DMA1_Channel6_IRQHandler ; 85:DMA1 Channel6 + DCD DMA1_Channel7_IRQHandler ; 86:DMA1 Channel7 + DCD USART5_IRQHandler ; 87:USART5 + DCD I2C2_EV_IRQHandler ; 88:I2C2 Event + DCD I2C2_ER_IRQHandler ; 89:I2C2 Error + DCD USBHS_EP1_Out_IRQHandler ; 90:USBHS Endpoint 1 Out + DCD USBHS_EP1_In_IRQHandler ; 91:USBHS Endpoint 1 in + DCD USBHS_WKUP_IRQHandler ; 92:USBHS Wakeup through EXTI Line + DCD USBHS_IRQHandler ; 93:USBHS + DCD DCI_IRQHandler ; 94:DCI + DCD 0 ; 95:Reserved + DCD TRNG_IRQHandler ; 96:TRNG + DCD FPU_IRQHandler ; 97:FPU + DCD UART6_IRQHandler ; 98:UART6 + DCD UART7_IRQHandler ; 98:UART7 + DCD SPI3_IRQHandler ; 100:SPI3 + DCD SPI4_IRQHandler ; 101:SPI4 + DCD SPI5_IRQHandler ; 102:SPI5 + DCD TLI_IRQHandler ; 104:TLI + DCD TLI_ER_IRQHandler ; 105:TLI Error + DCD IPA_IRQHandler ; 106:IPA + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +;/* reset Handler */ +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +;/* dummy Exception Handlers */ +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler\ + PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler\ + PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC +; /* external interrupts handler */ + EXPORT WWDGT_IRQHandler [WEAK] + EXPORT LVD_IRQHandler [WEAK] + EXPORT TAMPER_STAMP_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT RCU_CTC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA0_Channel0_IRQHandler [WEAK] + EXPORT DMA0_Channel1_IRQHandler [WEAK] + EXPORT DMA0_Channel2_IRQHandler [WEAK] + EXPORT DMA0_Channel3_IRQHandler [WEAK] + EXPORT DMA0_Channel4_IRQHandler [WEAK] + EXPORT DMA0_Channel5_IRQHandler [WEAK] + EXPORT DMA0_Channel6_IRQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT CAN0_TX_IRQHandler [WEAK] + EXPORT CAN0_RX0_IRQHandler [WEAK] + EXPORT CAN0_RX1_IRQHandler [WEAK] + EXPORT CAN0_EWMC_IRQHandler [WEAK] + EXPORT EXTI5_9_IRQHandler [WEAK] + EXPORT TIMER0_BRK_TIMER8_IRQHandler [WEAK] + EXPORT TIMER0_UP_TIMER9_IRQHandler [WEAK] + EXPORT TIMER0_TRG_CMT_TIMER10_IRQHandler [WEAK] + EXPORT TIMER0_CC_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT TIMER3_IRQHandler [WEAK] + EXPORT I2C0_EV_IRQHandler [WEAK] + EXPORT I2C0_ER_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT SPI0_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT USART0_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT EXTI10_15_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT USBFS_WKUP_IRQHandler [WEAK] + EXPORT TIMER7_BRK_TIMER11_IRQHandler [WEAK] + EXPORT TIMER7_UP_TIMER12_IRQHandler [WEAK] + EXPORT TIMER7_TRG_CMT_TIMER13_IRQHandler [WEAK] + EXPORT TIMER7_CC_IRQHandler [WEAK] + EXPORT DMA0_Channel7_IRQHandler [WEAK] + EXPORT EXMC_IRQHandler [WEAK] + EXPORT SDIO_IRQHandler [WEAK] + EXPORT TIMER4_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT UART3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT TIMER5_DAC_IRQHandler [WEAK] + EXPORT TIMER6_IRQHandler [WEAK] + EXPORT DMA1_Channel0_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT ENET_IRQHandler [WEAK] + EXPORT ENET_WKUP_IRQHandler [WEAK] + EXPORT CAN1_TX_IRQHandler [WEAK] + EXPORT CAN1_RX0_IRQHandler [WEAK] + EXPORT CAN1_RX1_IRQHandler [WEAK] + EXPORT CAN1_EWMC_IRQHandler [WEAK] + EXPORT USBFS_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT USART5_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT USBHS_EP1_Out_IRQHandler [WEAK] + EXPORT USBHS_EP1_In_IRQHandler [WEAK] + EXPORT USBHS_WKUP_IRQHandler [WEAK] + EXPORT USBHS_IRQHandler [WEAK] + EXPORT DCI_IRQHandler [WEAK] + EXPORT TRNG_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT UART6_IRQHandler [WEAK] + EXPORT UART7_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT SPI4_IRQHandler [WEAK] + EXPORT SPI5_IRQHandler [WEAK] + EXPORT TLI_IRQHandler [WEAK] + EXPORT TLI_ER_IRQHandler [WEAK] + EXPORT IPA_IRQHandler [WEAK] + +;/* external interrupts handler */ +WWDGT_IRQHandler +LVD_IRQHandler +TAMPER_STAMP_IRQHandler +RTC_WKUP_IRQHandler +FMC_IRQHandler +RCU_CTC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA0_Channel0_IRQHandler +DMA0_Channel1_IRQHandler +DMA0_Channel2_IRQHandler +DMA0_Channel3_IRQHandler +DMA0_Channel4_IRQHandler +DMA0_Channel5_IRQHandler +DMA0_Channel6_IRQHandler +ADC_IRQHandler +CAN0_TX_IRQHandler +CAN0_RX0_IRQHandler +CAN0_RX1_IRQHandler +CAN0_EWMC_IRQHandler +EXTI5_9_IRQHandler +TIMER0_BRK_TIMER8_IRQHandler +TIMER0_UP_TIMER9_IRQHandler +TIMER0_TRG_CMT_TIMER10_IRQHandler +TIMER0_CC_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +TIMER3_IRQHandler +I2C0_EV_IRQHandler +I2C0_ER_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +SPI0_IRQHandler +SPI1_IRQHandler +USART0_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +EXTI10_15_IRQHandler +RTC_Alarm_IRQHandler +USBFS_WKUP_IRQHandler +TIMER7_BRK_TIMER11_IRQHandler +TIMER7_UP_TIMER12_IRQHandler +TIMER7_TRG_CMT_TIMER13_IRQHandler +TIMER7_CC_IRQHandler +DMA0_Channel7_IRQHandler +EXMC_IRQHandler +SDIO_IRQHandler +TIMER4_IRQHandler +SPI2_IRQHandler +UART3_IRQHandler +UART4_IRQHandler +TIMER5_DAC_IRQHandler +TIMER6_IRQHandler +DMA1_Channel0_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +ENET_IRQHandler +ENET_WKUP_IRQHandler +CAN1_TX_IRQHandler +CAN1_RX0_IRQHandler +CAN1_RX1_IRQHandler +CAN1_EWMC_IRQHandler +USBFS_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +USART5_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +USBHS_EP1_Out_IRQHandler +USBHS_EP1_In_IRQHandler +USBHS_WKUP_IRQHandler +USBHS_IRQHandler +DCI_IRQHandler +TRNG_IRQHandler +FPU_IRQHandler +UART6_IRQHandler +UART7_IRQHandler +SPI3_IRQHandler +SPI4_IRQHandler +SPI5_IRQHandler +TLI_IRQHandler +TLI_ER_IRQHandler +IPA_IRQHandler + + B . + ENDP + + ALIGN + +; user Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s b/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s new file mode 100644 index 0000000000..87bf921267 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s @@ -0,0 +1,640 @@ +;/*! +; \file startup_gd32f4xx.s +; \brief start up file +;*/ + +;/* +; Copyright (C) 2016 GigaDevice + +; 2016-08-15, V1.0.0, firmware for GD32F4xx + +;*/ + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) ; top of stack + DCD Reset_Handler ; Vector Number 1,Reset Handler + + DCD NMI_Handler ; Vector Number 2,NMI Handler + DCD HardFault_Handler ; Vector Number 3,Hard Fault Handler + DCD MemManage_Handler ; Vector Number 4,MPU Fault Handler + DCD BusFault_Handler ; Vector Number 5,Bus Fault Handler + DCD UsageFault_Handler ; Vector Number 6,Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; Vector Number 11,SVCall Handler + DCD DebugMon_Handler ; Vector Number 12,Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; Vector Number 14,PendSV Handler + DCD SysTick_Handler ; Vector Number 15,SysTick Handler + + ; External Interrupts + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect + DCD TAMPER_STAMP_IRQHandler ; 18:Tamper and TimeStamp through EXTI Line detect + DCD RTC_WKUP_IRQHandler ; 19:RTC Wakeup through EXTI Line + DCD FMC_IRQHandler ; 20:FMC + DCD RCU_CTC_IRQHandler ; 21:RCU and CTC + DCD EXTI0_IRQHandler ; 22:EXTI Line 0 + DCD EXTI1_IRQHandler ; 23:EXTI Line 1 + DCD EXTI2_IRQHandler ; 24:EXTI Line 2 + DCD EXTI3_IRQHandler ; 25:EXTI Line 3 + DCD EXTI4_IRQHandler ; 26:EXTI Line 4 + DCD DMA0_Channel0_IRQHandler ; 27:DMA0 Channel0 + DCD DMA0_Channel1_IRQHandler ; 28:DMA0 Channel1 + DCD DMA0_Channel2_IRQHandler ; 29:DMA0 Channel2 + DCD DMA0_Channel3_IRQHandler ; 30:DMA0 Channel3 + DCD DMA0_Channel4_IRQHandler ; 31:DMA0 Channel4 + DCD DMA0_Channel5_IRQHandler ; 32:DMA0 Channel5 + DCD DMA0_Channel6_IRQHandler ; 33:DMA0 Channel6 + DCD ADC_IRQHandler ; 34:ADC + DCD CAN0_TX_IRQHandler ; 35:CAN0 TX + DCD CAN0_RX0_IRQHandler ; 36:CAN0 RX0 + DCD CAN0_RX1_IRQHandler ; 37:CAN0 RX1 + DCD CAN0_EWMC_IRQHandler ; 38:CAN0 EWMC + DCD EXTI5_9_IRQHandler ; 39:EXTI5 to EXTI9 + DCD TIMER0_BRK_TIMER8_IRQHandler ; 40:TIMER0 Break and TIMER8 + DCD TIMER0_UP_TIMER9_IRQHandler ; 41:TIMER0 Update and TIMER9 + DCD TIMER0_TRG_CMT_TIMER10_IRQHandler ; 42:TIMER0 Trigger and Commucation and TIMER10 + DCD TIMER0_CC_IRQHandler ; 43:TIMER0 Capture Compare + DCD TIMER1_IRQHandler ; 44:TIMER1 + DCD TIMER2_IRQHandler ; 45:TIMER2 + DCD TIMER3_IRQHandler ; 46:TIMER3 + DCD I2C0_EV_IRQHandler ; 47:I2C0 Event + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD I2C1_EV_IRQHandler ; 49:I2C1 Event + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error + DCD SPI0_IRQHandler ; 51:SPI0 + DCD SPI1_IRQHandler ; 52:SPI1 + DCD USART0_IRQHandler ; 53:USART0 + DCD USART1_IRQHandler ; 54:USART1 + DCD USART2_IRQHandler ; 55:USART2 + DCD EXTI10_15_IRQHandler ; 56:EXTI10 to EXTI15 + DCD RTC_Alarm_IRQHandler ; 57:RTC Alarm + DCD USBFS_WKUP_IRQHandler ; 58:USBFS Wakeup + DCD TIMER7_BRK_TIMER11_IRQHandler ; 59:TIMER7 Break and TIMER11 + DCD TIMER7_UP_TIMER12_IRQHandler ; 60:TIMER7 Update and TIMER12 + DCD TIMER7_TRG_CMT_TIMER13_IRQHandler ; 61:TIMER7 Trigger and Commucation and TIMER13 + DCD TIMER7_CC_IRQHandler ; 62:TIMER7 Capture Compare + DCD DMA0_Channel7_IRQHandler ; 63:DMA0 Channel7 + DCD EXMC_IRQHandler ; 64:EXMC + DCD SDIO_IRQHandler ; 65:SDIO + DCD TIMER4_IRQHandler ; 66:TIMER4 + DCD SPI2_IRQHandler ; 67:SPI2 + DCD UART3_IRQHandler ; 68:UART3 + DCD UART4_IRQHandler ; 69:UART4 + DCD TIMER5_DAC_IRQHandler ; 70:TIMER5 and DAC0 DAC1 Underrun error + DCD TIMER6_IRQHandler ; 71:TIMER6 + DCD DMA1_Channel0_IRQHandler ; 72:DMA1 Channel0 + DCD DMA1_Channel1_IRQHandler ; 73:DMA1 Channel1 + DCD DMA1_Channel2_IRQHandler ; 74:DMA1 Channel2 + DCD DMA1_Channel3_IRQHandler ; 75:DMA1 Channel3 + DCD DMA1_Channel4_IRQHandler ; 76:DMA1 Channel4 + DCD ENET_IRQHandler ; 77:Ethernet + DCD ENET_WKUP_IRQHandler ; 78:Ethernet Wakeup through EXTI Line + DCD CAN1_TX_IRQHandler ; 79:CAN1 TX + DCD CAN1_RX0_IRQHandler ; 80:CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; 81:CAN1 RX1 + DCD CAN1_EWMC_IRQHandler ; 82:CAN1 EWMC + DCD USBFS_IRQHandler ; 83:USBFS + DCD DMA1_Channel5_IRQHandler ; 84:DMA1 Channel5 + DCD DMA1_Channel6_IRQHandler ; 85:DMA1 Channel6 + DCD DMA1_Channel7_IRQHandler ; 86:DMA1 Channel7 + DCD USART5_IRQHandler ; 87:USART5 + DCD I2C2_EV_IRQHandler ; 88:I2C2 Event + DCD I2C2_ER_IRQHandler ; 89:I2C2 Error + DCD USBHS_EP1_Out_IRQHandler ; 90:USBHS Endpoint 1 Out + DCD USBHS_EP1_In_IRQHandler ; 91:USBHS Endpoint 1 in + DCD USBHS_WKUP_IRQHandler ; 92:USBHS Wakeup through EXTI Line + DCD USBHS_IRQHandler ; 93:USBHS + DCD DCI_IRQHandler ; 94:DCI + DCD 0 ; 95:Reserved + DCD TRNG_IRQHandler ; 96:TRNG + DCD FPU_IRQHandler ; 97:FPU + DCD UART6_IRQHandler ; 98:UART6 + DCD UART7_IRQHandler ; 98:UART7 + DCD SPI3_IRQHandler ; 100:SPI3 + DCD SPI4_IRQHandler ; 101:SPI4 + DCD SPI5_IRQHandler ; 102:SPI5 + DCD TLI_IRQHandler ; 104:TLI + DCD TLI_ER_IRQHandler ; 105:TLI Error + DCD IPA_IRQHandler ; 106:IPA + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDGT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDGT_IRQHandler + B WWDGT_IRQHandler + + PUBWEAK LVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LVD_IRQHandler + B LVD_IRQHandler + + PUBWEAK TAMPER_STAMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMPER_STAMP_IRQHandler + B TAMPER_STAMP_IRQHandler + + PUBWEAK RTC_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_WKUP_IRQHandler + B RTC_WKUP_IRQHandler + + PUBWEAK FMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_IRQHandler + B FMC_IRQHandler + + PUBWEAK RCU_CTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCU_CTC_IRQHandler + B RCU_CTC_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK DMA0_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel0_IRQHandler + B DMA0_Channel0_IRQHandler + + PUBWEAK DMA0_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel1_IRQHandler + B DMA0_Channel1_IRQHandler + + PUBWEAK DMA0_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel2_IRQHandler + B DMA0_Channel2_IRQHandler + + PUBWEAK DMA0_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel3_IRQHandler + B DMA0_Channel3_IRQHandler + + PUBWEAK DMA0_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel4_IRQHandler + B DMA0_Channel4_IRQHandler + + PUBWEAK DMA0_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel5_IRQHandler + B DMA0_Channel5_IRQHandler + + PUBWEAK DMA0_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel6_IRQHandler + B DMA0_Channel6_IRQHandler + + PUBWEAK ADC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_IRQHandler + B ADC_IRQHandler + + PUBWEAK CAN0_TX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_TX_IRQHandler + B CAN0_TX_IRQHandler + + PUBWEAK CAN0_RX0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_RX0_IRQHandler + B CAN0_RX0_IRQHandler + + PUBWEAK CAN0_RX1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_RX1_IRQHandler + B CAN0_RX1_IRQHandler + + PUBWEAK CAN0_EWMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_EWMC_IRQHandler + B CAN0_EWMC_IRQHandler + + PUBWEAK EXTI5_9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI5_9_IRQHandler + B EXTI5_9_IRQHandler + + PUBWEAK TIMER0_BRK_TIMER8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_BRK_TIMER8_IRQHandler + B TIMER0_BRK_TIMER8_IRQHandler + + PUBWEAK TIMER0_UP_TIMER9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_UP_TIMER9_IRQHandler + B TIMER0_UP_TIMER9_IRQHandler + + PUBWEAK TIMER0_TRG_CMT_TIMER10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_TRG_CMT_TIMER10_IRQHandler + B TIMER0_TRG_CMT_TIMER10_IRQHandler + + PUBWEAK TIMER0_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_CC_IRQHandler + B TIMER0_CC_IRQHandler + + PUBWEAK TIMER1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER1_IRQHandler + B TIMER1_IRQHandler + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER2_IRQHandler + B TIMER2_IRQHandler + + PUBWEAK TIMER3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER3_IRQHandler + B TIMER3_IRQHandler + + PUBWEAK I2C0_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_EV_IRQHandler + B I2C0_EV_IRQHandler + + PUBWEAK I2C0_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_ER_IRQHandler + B I2C0_ER_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK SPI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI0_IRQHandler + B SPI0_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK USART0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART0_IRQHandler + B USART0_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK EXTI10_15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI10_15_IRQHandler + B EXTI10_15_IRQHandler + + PUBWEAK RTC_Alarm_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_Alarm_IRQHandler + B RTC_Alarm_IRQHandler + + PUBWEAK USBFS_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBFS_WKUP_IRQHandler + B USBFS_WKUP_IRQHandler + + PUBWEAK TIMER7_BRK_TIMER11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_BRK_TIMER11_IRQHandler + B TIMER7_BRK_TIMER11_IRQHandler + + PUBWEAK TIMER7_UP_TIMER12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_UP_TIMER12_IRQHandler + B TIMER7_UP_TIMER12_IRQHandler + + PUBWEAK TIMER7_TRG_CMT_TIMER13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_TRG_CMT_TIMER13_IRQHandler + B TIMER7_TRG_CMT_TIMER13_IRQHandler + + PUBWEAK TIMER7_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_CC_IRQHandler + B TIMER7_CC_IRQHandler + + PUBWEAK DMA0_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel7_IRQHandler + B DMA0_Channel7_IRQHandler + + PUBWEAK EXMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXMC_IRQHandler + B EXMC_IRQHandler + + PUBWEAK SDIO_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDIO_IRQHandler + B SDIO_IRQHandler + + PUBWEAK TIMER4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER4_IRQHandler + B TIMER4_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK UART3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART3_IRQHandler + B UART3_IRQHandler + + PUBWEAK UART4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART4_IRQHandler + B UART4_IRQHandler + + PUBWEAK TIMER5_DAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER5_DAC_IRQHandler + B TIMER5_DAC_IRQHandler + + PUBWEAK TIMER6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER6_IRQHandler + B TIMER6_IRQHandler + + PUBWEAK DMA1_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel0_IRQHandler + B DMA1_Channel0_IRQHandler + + PUBWEAK DMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel1_IRQHandler + B DMA1_Channel1_IRQHandler + + PUBWEAK DMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel2_IRQHandler + B DMA1_Channel2_IRQHandler + + PUBWEAK DMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel3_IRQHandler + B DMA1_Channel3_IRQHandler + + PUBWEAK DMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel4_IRQHandler + B DMA1_Channel4_IRQHandler + + PUBWEAK ENET_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ENET_IRQHandler + B ENET_IRQHandler + + PUBWEAK ENET_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ENET_WKUP_IRQHandler + B ENET_WKUP_IRQHandler + + PUBWEAK CAN1_TX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_TX_IRQHandler + B CAN1_TX_IRQHandler + + PUBWEAK CAN1_RX0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_RX0_IRQHandler + B CAN1_RX0_IRQHandler + + PUBWEAK CAN1_RX1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_RX1_IRQHandler + B CAN1_RX1_IRQHandler + + PUBWEAK CAN1_EWMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_EWMC_IRQHandler + B CAN1_EWMC_IRQHandler + + PUBWEAK USBFS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBFS_IRQHandler + B USBFS_IRQHandler + + PUBWEAK DMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel5_IRQHandler + B DMA1_Channel5_IRQHandler + + PUBWEAK DMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel6_IRQHandler + B DMA1_Channel6_IRQHandler + + PUBWEAK DMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel7_IRQHandler + B DMA1_Channel7_IRQHandler + + PUBWEAK USART5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART5_IRQHandler + B USART5_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK USBHS_EP1_Out_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS_EP1_Out_IRQHandler + B USBHS_EP1_Out_IRQHandler + + PUBWEAK USBHS_EP1_In_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS_EP1_In_IRQHandler + B USBHS_EP1_In_IRQHandler + + PUBWEAK USBHS_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS_WKUP_IRQHandler + B USBHS_WKUP_IRQHandler + + PUBWEAK USBHS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS_IRQHandler + B USBHS_IRQHandler + + PUBWEAK DCI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DCI_IRQHandler + B DCI_IRQHandler + + PUBWEAK TRNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TRNG_IRQHandler + B TRNG_IRQHandler + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FPU_IRQHandler + B FPU_IRQHandler + + PUBWEAK UART6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART6_IRQHandler + B UART6_IRQHandler + + PUBWEAK UART7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART7_IRQHandler + B UART7_IRQHandler + + PUBWEAK SPI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI3_IRQHandler + B SPI3_IRQHandler + + PUBWEAK SPI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI4_IRQHandler + B SPI4_IRQHandler + + PUBWEAK SPI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI5_IRQHandler + B SPI5_IRQHandler + + PUBWEAK TLI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TLI_IRQHandler + B TLI_IRQHandler + + PUBWEAK TLI_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TLI_ER_IRQHandler + B TLI_ER_IRQHandler + + PUBWEAK IPA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPA_IRQHandler + B IPA_IRQHandler + END \ No newline at end of file diff --git a/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c b/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c new file mode 100644 index 0000000000..6da45fa40e --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c @@ -0,0 +1,941 @@ +/*! + \file system_gd32f4xx.c + \brief CMSIS Cortex-M4 Device Peripheral Access Layer Source File for + GD32F4xx Device Series +*/ + +/* Copyright (c) 2012 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#include "gd32f4xx.h" + +/* system frequency define */ +#define __IRC16M (IRC16M_VALUE) /* internal 16 MHz RC oscillator frequency */ +#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ +#define __SYS_OSC_CLK (__IRC16M) /* main oscillator frequency */ + +/* select a system clock by uncommenting the following line */ +//#define __SYSTEM_CLOCK_IRC16M (uint32_t)(__IRC16M) +//#define __SYSTEM_CLOCK_HXTAL (uint32_t)(__HXTAL) +//#define __SYSTEM_CLOCK_120M_PLL_IRC16M (uint32_t)(120000000) +//#define __SYSTEM_CLOCK_120M_PLL_8M_HXTAL (uint32_t)(120000000) +//#define __SYSTEM_CLOCK_120M_PLL_25M_HXTAL (uint32_t)(120000000) +//#define __SYSTEM_CLOCK_168M_PLL_IRC16M (uint32_t)(168000000) +//#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL (uint32_t)(168000000) +//#define __SYSTEM_CLOCK_168M_PLL_25M_HXTAL (uint32_t)(168000000) +//#define __SYSTEM_CLOCK_200M_PLL_IRC16M (uint32_t)(200000000) +//#define __SYSTEM_CLOCK_200M_PLL_8M_HXTAL (uint32_t)(200000000) +#define __SYSTEM_CLOCK_200M_PLL_25M_HXTAL (uint32_t)(200000000) + +#define SEL_IRC16M 0x00U +#define SEL_HXTAL 0x01U +#define SEL_PLLP 0x02U + +/* set the system clock frequency and declare the system clock configuration function */ +#ifdef __SYSTEM_CLOCK_IRC16M +uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC16M; +static void system_clock_16m_irc16m(void); +#elif defined (__SYSTEM_CLOCK_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL; +static void system_clock_hxtal(void); +#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC16M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_IRC16M; +static void system_clock_120m_irc16m(void); +#elif defined (__SYSTEM_CLOCK_120M_PLL_8M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_8M_HXTAL; +static void system_clock_120m_8m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_120M_PLL_25M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_25M_HXTAL; +static void system_clock_120m_25m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC16M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_IRC16M; +static void system_clock_168m_irc16m(void); +#elif defined (__SYSTEM_CLOCK_168M_PLL_8M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_8M_HXTAL; +static void system_clock_168m_8m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_168M_PLL_25M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_25M_HXTAL; +static void system_clock_168m_25m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_200M_PLL_IRC16M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL_IRC16M; +static void system_clock_200m_irc16m(void); +#elif defined (__SYSTEM_CLOCK_200M_PLL_8M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL_8M_HXTAL; +static void system_clock_200m_8m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_200M_PLL_25M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL_25M_HXTAL; +static void system_clock_200m_25m_hxtal(void); + +#endif /* __SYSTEM_CLOCK_IRC16M */ + +/* configure the system clock */ +static void system_clock_config(void); + +/*! + \brief setup the microcontroller system, initialize the system + \param[in] none + \param[out] none + \retval none +*/ +void SystemInit (void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set IRC16MEN bit */ + RCU_CTL |= RCU_CTL_IRC16MEN; + + /* Reset CFG0 register */ + RCU_CFG0 = 0x00000000U; + + /* Reset HXTALEN, CKMEN and PLLEN bits */ + RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN); + + /* Reset PLLCFGR register */ + RCU_PLL = 0x24003010U; + + /* Reset HSEBYP bit */ + RCU_CTL &= ~(RCU_CTL_HXTALBPS); + + /* Disable all interrupts */ + RCU_INT = 0x00000000U; + + /* Configure the System clock source, PLL Multiplier and Divider factors, + AHB/APBx prescalers and Flash settings ----------------------------------*/ + system_clock_config(); + + +} +/*! + \brief configure the system clock + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_config(void) +{ +#ifdef __SYSTEM_CLOCK_IRC16M + system_clock_16m_irc16m(); +#elif defined (__SYSTEM_CLOCK_HXTAL) + system_clock_hxtal(); +#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC16M) + system_clock_120m_irc16m(); +#elif defined (__SYSTEM_CLOCK_120M_PLL_8M_HXTAL) + system_clock_120m_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_120M_PLL_25M_HXTAL) + system_clock_120m_25m_hxtal(); +#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC16M) + system_clock_168m_irc16m(); +#elif defined (__SYSTEM_CLOCK_168M_PLL_8M_HXTAL) + system_clock_168m_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_168M_PLL_25M_HXTAL) + system_clock_168m_25m_hxtal(); +#elif defined (__SYSTEM_CLOCK_200M_PLL_IRC16M) + system_clock_200m_irc16m(); +#elif defined (__SYSTEM_CLOCK_200M_PLL_8M_HXTAL) + system_clock_200m_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_200M_PLL_25M_HXTAL) + system_clock_200m_25m_hxtal(); +#endif /* __SYSTEM_CLOCK_IRC16M */ +} + +#ifdef __SYSTEM_CLOCK_IRC16M +/*! + \brief configure the system clock to 16M by IRC16M + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_16m_irc16m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + + /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB); + } + while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){ + while(1){ + } + } + + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select IRC16M as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_IRC16M; + + /* wait until IRC16M is selected as system clock */ + while(0 != (RCU_CFG0 & RCU_SCSS_IRC16M)){ + } +} + +#elif defined (__SYSTEM_CLOCK_HXTAL) +/*! + \brief configure the system clock to HXTAL + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select HXTAL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_HXTAL; + + /* wait until HXTAL is selected as system clock */ + while(0 == (RCU_CFG0 & RCU_SCSS_HXTAL)){ + } +} + +#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC16M) +/*! + \brief configure the system clock to 120M by PLL which selects IRC16M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_120m_irc16m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + + /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB); + } + while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* IRC16M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PLL_M = 16, PLL_N = 240, PLL_P = 2, PLL_Q = 5 */ + RCU_PLL = (16U | (240U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_IRC16M) | (5U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 120 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)) + { + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)) + { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_120M_PLL_8M_HXTAL) +/*! + \brief configure the system clock to 120M by PLL which selects HXTAL(8M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_120m_8m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PLL_M = 8, PLL_N = 240, PLL_P = 2, PLL_Q = 5 */ + RCU_PLL = (8U | (240U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (5U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 120 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)) + { + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)) + { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_120M_PLL_25M_HXTAL) +/*! + \brief configure the system clock to 120M by PLL which selects HXTAL(25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_120m_25m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PLL_M = 25, PLL_N = 240, PLL_P = 2, PLL_Q = 5 */ + RCU_PLL = (25U | (240U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (5U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 120 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)) + { + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)) + { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC16M) +/*! + \brief configure the system clock to 168M by PLL which selects IRC16M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_168m_irc16m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + + /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB); + } + while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* IRC16M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PLL_M = 16, PLL_N = 336, PLL_P = 2, PLL_Q = 7 */ + RCU_PLL = (16U | (336U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_IRC16M) | (7U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 168 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)) + { + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)) + { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_168M_PLL_8M_HXTAL) +/*! + \brief configure the system clock to 168M by PLL which selects HXTAL(8M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_168m_8m_hxtal(void) +{ + uint32_t timeout = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + while((0U == (RCU_CTL & RCU_CTL_HXTALSTB)) && (HXTAL_STARTUP_TIMEOUT != timeout++)){ + } + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PLL_M = 8, PLL_N = 336, PLL_P = 2, PLL_Q = 7 */ + RCU_PLL = (8U | (336 << 6U) | (((2 >> 1U) -1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (7 << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 168 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)) + { + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)) + { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_168M_PLL_25M_HXTAL) +/*! + \brief configure the system clock to 168M by PLL which selects HXTAL(25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_168m_25m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PLL_M = 25, PLL_N = 336, PLL_P = 2, PLL_Q = 7 */ + RCU_PLL = (25U | (336U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (7U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 168 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)) + { + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)) + { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_200M_PLL_IRC16M) +/*! + \brief configure the system clock to 200M by PLL which selects IRC16M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_200m_irc16m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + + /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB); + } + while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* IRC16M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PLL_M = 16, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */ + RCU_PLL = (16U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_IRC16M) | (9U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 200 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)) + { + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)) + { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_200M_PLL_8M_HXTAL) +/*! + \brief configure the system clock to 200M by PLL which selects HXTAL(8M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_200m_8m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PLL_M = 8, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */ + RCU_PLL = (8U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (9U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 200 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)) + { + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)) + { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_200M_PLL_25M_HXTAL) +/*! + \brief configure the system clock to 200M by PLL which selects HXTAL(25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_200m_25m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PLL_M = 25, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */ + RCU_PLL = (25U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (9U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 200 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)) + { + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)) + { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#endif /* __SYSTEM_CLOCK_IRC16M */ +/*! + \brief update the SystemCoreClock with current core clock retrieved from cpu registers + \param[in] none + \param[out] none + \retval none +*/ +void SystemCoreClockUpdate (void) +{ + uint32_t sws; + uint32_t pllpsc, plln, pllsel, pllp, ck_src, idx, clk_exp; + + /* exponent of AHB, APB1 and APB2 clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC16M is selected as CK_SYS */ + case SEL_IRC16M: + SystemCoreClock = IRC16M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + SystemCoreClock = HXTAL_VALUE; + break; + /* PLLP is selected as CK_SYS */ + case SEL_PLLP: + /* get the value of PLLPSC[5:0] */ + pllpsc = GET_BITS(RCU_PLL, 0U, 5U); + plln = GET_BITS(RCU_PLL, 6U, 14U); + pllp = (GET_BITS(RCU_PLL, 16U, 17U) + 1U) * 2U; + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = (RCU_PLL & RCU_PLL_PLLSEL); + if (RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else { + ck_src = IRC16M_VALUE; + } + SystemCoreClock = ((ck_src / pllpsc) * plln)/pllp; + break; + /* IRC16M is selected as CK_SYS */ + default: + SystemCoreClock = IRC16M_VALUE; + break; + } + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + SystemCoreClock = SystemCoreClock >> clk_exp; +} diff --git a/bsp/gd32450z-eval/Libraries/CMSIS/core_cm4.h b/bsp/gd32450z-eval/Libraries/CMSIS/core_cm4.h new file mode 100644 index 0000000000..d82841442c --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/CMSIS/core_cm4.h @@ -0,0 +1,1790 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V3.30 + * @date 17. February 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) /* Cosmic */ + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __CSMC__ ) /* Cosmic */ + #if ( __CSMC__ & 0x400) // FPU present for parser + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ +#include /* Compiler specific SIMD Intrinsics */ + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000 + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0 + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register */ +#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register */ +#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register */ +#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ +/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/bsp/gd32450z-eval/Libraries/CMSIS/core_cm4_simd.h b/bsp/gd32450z-eval/Libraries/CMSIS/core_cm4_simd.h new file mode 100644 index 0000000000..f9bceff1e5 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/CMSIS/core_cm4_simd.h @@ -0,0 +1,697 @@ +/**************************************************************************//** + * @file core_cm4_simd.h + * @brief CMSIS Cortex-M4 SIMD Header File + * @version V3.30 + * @date 17. February 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_CM4_SIMD_H +#define __CORE_CM4_SIMD_H + +#ifdef __cplusplus + extern "C" { +#endif + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32) ) >> 32)) + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ +#include + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ +/* not yet supported */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_SIMD_H */ diff --git a/bsp/gd32450z-eval/Libraries/CMSIS/core_cmFunc.h b/bsp/gd32450z-eval/Libraries/CMSIS/core_cmFunc.h new file mode 100644 index 0000000000..b6ad0a4c5f --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/CMSIS/core_cmFunc.h @@ -0,0 +1,664 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V4.10 + * @date 18. March 2015 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xff); +} + + +/** \brief Set Base Priority with condition + + This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xff); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1); +} + +#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ + + +#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */ + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +/** \brief Set Base Priority with condition + + This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory"); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} + +#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ +#include + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + +#endif /* __CORE_CMFUNC_H */ diff --git a/bsp/gd32450z-eval/Libraries/CMSIS/core_cmInstr.h b/bsp/gd32450z-eval/Libraries/CMSIS/core_cmInstr.h new file mode 100644 index 0000000000..fca425c51d --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/CMSIS/core_cmInstr.h @@ -0,0 +1,916 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V4.10 + * @date 18. March 2015 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0) + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0) + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0) + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end + + result = value; // r will be reversed bits of v; first get LSB of v + for (value >>= 1; value; value >>= 1) + { + result <<= 1; + result |= value & 1; + s--; + } + result <<= s; // shift when v's highest bits are zero + return(result); +} +#endif + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + +/** \brief LDR Exclusive (8 bit) + + This function executes a exclusive LDR instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function executes a exclusive LDR instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function executes a exclusive LDR instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function executes a exclusive STR instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function executes a exclusive STR instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function executes a exclusive STR instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** \brief Rotate Right with Extend (32 bit) + + This function moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** \brief LDRT Unprivileged (8 bit) + + This function executes a Unprivileged LDRT instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** \brief LDRT Unprivileged (16 bit) + + This function executes a Unprivileged LDRT instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** \brief LDRT Unprivileged (32 bit) + + This function executes a Unprivileged LDRT instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** \brief STRT Unprivileged (8 bit) + + This function executes a Unprivileged STRT instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** \brief STRT Unprivileged (16 bit) + + This function executes a Unprivileged STRT instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** \brief STRT Unprivileged (32 bit) + + This function executes a Unprivileged STRT instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constrant "l" + * Otherwise, use general registers, specified by constrant "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__((always_inline)) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__((always_inline)) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__((always_inline)) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__((always_inline)) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__((always_inline)) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__((always_inline)) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + uint32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32 - op2)); +} + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end + + result = value; // r will be reversed bits of v; first get LSB of v + for (value >>= 1; value; value >>= 1) + { + result <<= 1; + result |= value & 1; + s--; + } + result <<= s; // shift when v's highest bits are zero +#endif + return(result); +} + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz + + +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + +/** \brief LDR Exclusive (8 bit) + + This function executes a exclusive LDR instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDR Exclusive (16 bit) + + This function executes a exclusive LDR instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDR Exclusive (32 bit) + + This function executes a exclusive LDR instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function executes a exclusive STR instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function executes a exclusive STR instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function executes a exclusive STR instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Rotate Right with Extend (32 bit) + + This function moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + + \param [in] value Value to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** \brief LDRT Unprivileged (8 bit) + + This function executes a Unprivileged LDRT instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDRT Unprivileged (16 bit) + + This function executes a Unprivileged LDRT instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDRT Unprivileged (32 bit) + + This function executes a Unprivileged LDRT instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** \brief STRT Unprivileged (8 bit) + + This function executes a Unprivileged STRT instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); +} + + +/** \brief STRT Unprivileged (16 bit) + + This function executes a Unprivileged STRT instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); +} + + +/** \brief STRT Unprivileged (32 bit) + + This function executes a Unprivileged STRT instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) ); +} + +#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ +#include + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h new file mode 100644 index 0000000000..694428f07c --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h @@ -0,0 +1,461 @@ +/*! + \file gd32f4xx_adc.h + \brief definitions for the ADC +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_ADC_H +#define GD32F4XX_ADC_H + +#include "gd32f4xx.h" + +/* ADC definitions */ +#define ADC0 ADC_BASE +#define ADC1 (ADC_BASE + 0x100U) +#define ADC2 (ADC_BASE + 0x200U) + +/* registers definitions */ +#define ADC_STAT(adcx) REG32((adcx) + 0x00U) /*!< ADC status register */ +#define ADC_CTL0(adcx) REG32((adcx) + 0x04U) /*!< ADC control register 0 */ +#define ADC_CTL1(adcx) REG32((adcx) + 0x08U) /*!< ADC control register 1 */ +#define ADC_SAMPT0(adcx) REG32((adcx) + 0x0CU) /*!< ADC sampling time register 0 */ +#define ADC_SAMPT1(adcx) REG32((adcx) + 0x10U) /*!< ADC sampling time register 1 */ +#define ADC_IOFF0(adcx) REG32((adcx) + 0x14U) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1(adcx) REG32((adcx) + 0x18U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2(adcx) REG32((adcx) + 0x1CU) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3(adcx) REG32((adcx) + 0x20U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WDHT(adcx) REG32((adcx) + 0x24U) /*!< ADC watchdog high threshold register */ +#define ADC_WDLT(adcx) REG32((adcx) + 0x28U) /*!< ADC watchdog low threshold register */ +#define ADC_RSQ0(adcx) REG32((adcx) + 0x2CU) /*!< ADC regular sequence register 0 */ +#define ADC_RSQ1(adcx) REG32((adcx) + 0x30U) /*!< ADC regular sequence register 1 */ +#define ADC_RSQ2(adcx) REG32((adcx) + 0x34U) /*!< ADC regular sequence register 2 */ +#define ADC_ISQ(adcx) REG32((adcx) + 0x38U) /*!< ADC inserted sequence register */ +#define ADC_IDATA0(adcx) REG32((adcx) + 0x3CU) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1(adcx) REG32((adcx) + 0x40U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2(adcx) REG32((adcx) + 0x44U) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3(adcx) REG32((adcx) + 0x48U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA(adcx) REG32((adcx) + 0x4CU) /*!< ADC regular data register */ +#define ADC_OVSAMPCTL(adcx) REG32((adcx) + 0x80U) /*!< ADC oversampling control register */ +#define ADC_SSTAT REG32((ADC_BASE) + 0x300U) /*!< ADC summary status register */ +#define ADC_SYNCCTL REG32((ADC_BASE) + 0x304U) /*!< ADC synchronization control register */ +#define ADC_SYNCDATA REG32((ADC_BASE) + 0x308U) /*!< ADC synchronization regular data register */ + +/* bits definitions */ +/* ADC_STAT */ +#define ADC_STAT_WDE BIT(0) /*!< analog watchdog event flag */ +#define ADC_STAT_EOC BIT(1) /*!< end of conversion */ +#define ADC_STAT_EOIC BIT(2) /*!< inserted channel end of conversion */ +#define ADC_STAT_STIC BIT(3) /*!< inserted channel start flag */ +#define ADC_STAT_STRC BIT(4) /*!< regular channel start flag */ +#define ADC_STAT_ROVF BIT(5) /*!< regular data register overflow */ + +/* ADC_CTL0 */ +#define ADC_CTL0_WDCHSEL BITS(0,4) /*!< analog watchdog channel select bits */ +#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ +#define ADC_CTL0_WDEIE BIT(6) /*!< analog watchdog interrupt enable */ +#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for inserted channels */ +#define ADC_CTL0_SM BIT(8) /*!< scan mode */ +#define ADC_CTL0_WDSC BIT(9) /*!< when in scan mode, analog watchdog is effective on a single channel */ +#define ADC_CTL0_ICA BIT(10) /*!< automatic inserted group conversion */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ +#define ADC_CTL0_DISNUM BITS(13,15) /*!< discontinuous mode channel count */ +#define ADC_CTL0_IWDEN BIT(22) /*!< analog watchdog enable on inserted channels */ +#define ADC_CTL0_RWDEN BIT(23) /*!< analog watchdog enable on regular channels */ +#define ADC_CTL0_DRES BITS(24,25) /*!< ADC data resolution */ +#define ADC_CTL0_ROVFIE BIT(26) /*!< interrupt enable for ROVF */ + +/* ADC_CTL1 */ +#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter on */ +#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */ +#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ +#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ +#define ADC_CTL1_DMA BIT(8) /*!< direct memory access mode */ +#define ADC_CTL1_DDM BIT(9) /*!< DMA disable mode */ +#define ADC_CTL1_EOCM BIT(10) /*!< end of conversion mode */ +#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ +#define ADC_CTL1_ETSIC BITS(16,19) /*!< external event select for inserted group */ +#define ADC_CTL1_ETMIC BITS(20,21) /*!< external trigger conversion mode for inserted channels */ +#define ADC_CTL1_SWICST BIT(22) /*!< start conversion of inserted channels */ +#define ADC_CTL1_ETSRC BITS(24,27) /*!< external event select for regular group */ +#define ADC_CTL1_ETMRC BITS(28,29) /*!< external trigger conversion mode for regular channels */ +#define ADC_CTL1_SWRCST BIT(30) /*!< start conversion of regular channels */ + +/* ADC_SAMPTx x=0..1 */ +#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel x sample time selection */ + +/* ADC_IOFFx x=0..3 */ +#define ADC_IOFFX_IOFF BITS(0,11) /*!< data offset for inserted channel x */ + +/* ADC_WDHT */ +#define ADC_WDHT_WDHT BITS(0,11) /*!< analog watchdog high threshold */ + +/* ADC_WDLT */ +#define ADC_WDLT_WDLT BITS(0,11) /*!< analog watchdog low threshold */ + +/* ADC_RSQx */ +#define ADC_RSQX_RSQN BITS(0,4) /*!< x conversion in regular sequence */ +#define ADC_RSQ0_RL BITS(20,23) /*!< regular channel sequence length */ + +/* ADC_ISQ */ +#define ADC_ISQ_ISQN BITS(0,4) /*!< x conversion in regular sequence */ +#define ADC_ISQ_IL BITS(20,21) /*!< inserted sequence length */ + +/* ADC_IDATAx x=0..3*/ +#define ADC_IDATAX_IDATAN BITS(0,15) /*!< inserted data x */ + +/* ADC_RDATA */ +#define ADC_RDATA_RDATA BITS(0,15) /*!< regular data */ + +/* ADC_OVSAMPCTL */ +#define ADC_OVSAMPCTL_OVSEN BIT(0) /*!< oversampling enable */ +#define ADC_OVSAMPCTL_OVSR BITS(2,4) /*!< oversampling ratio */ +#define ADC_OVSAMPCTL_OVSS BITS(5,8) /*!< oversampling shift */ +#define ADC_OVSAMPCTL_TOVS BIT(9) /*!< triggered oversampling */ + +/* ADC_SSTAT */ +#define ADC_SSTAT_WDE0 BIT(0) /*!< the mirror image of the WDE bit of ADC0 */ +#define ADC_SSTAT_EOC0 BIT(1) /*!< the mirror image of the EOC bit of ADC0 */ +#define ADC_SSTAT_EOIC0 BIT(2) /*!< the mirror image of the EOIC bit of ADC0 */ +#define ADC_SSTAT_STIC0 BIT(3) /*!< the mirror image of the STIC bit of ADC0 */ +#define ADC_SSTAT_STRC0 BIT(4) /*!< the mirror image of the STRC bit of ADC0 */ +#define ADC_SSTAT_ROVF0 BIT(5) /*!< the mirror image of the ROVF bit of ADC0 */ +#define ADC_SSTAT_WDE1 BIT(8) /*!< the mirror image of the WDE bit of ADC1 */ +#define ADC_SSTAT_EOC1 BIT(9) /*!< the mirror image of the EOC bit of ADC1 */ +#define ADC_SSTAT_EOIC1 BIT(10) /*!< the mirror image of the EOIC bit of ADC1 */ +#define ADC_SSTAT_STIC1 BIT(11) /*!< the mirror image of the STIC bit of ADC1 */ +#define ADC_SSTAT_STRC1 BIT(12) /*!< the mirror image of the STRC bit of ADC1 */ +#define ADC_SSTAT_ROVF1 BIT(13) /*!< the mirror image of the ROVF bit of ADC1 */ +#define ADC_SSTAT_WDE2 BIT(16) /*!< the mirror image of the WDE bit of ADC2 */ +#define ADC_SSTAT_EOC2 BIT(17) /*!< the mirror image of the EOC bit of ADC2 */ +#define ADC_SSTAT_EOIC2 BIT(18) /*!< the mirror image of the EOIC bit of ADC2 */ +#define ADC_SSTAT_STIC2 BIT(19) /*!< the mirror image of the STIC bit of ADC2 */ +#define ADC_SSTAT_STRC2 BIT(20) /*!< the mirror image of the STRC bit of ADC2 */ +#define ADC_SSTAT_ROVF2 BIT(21) /*!< the mirror image of the ROVF bit of ADC2 */ + +/* ADC_SYNCCTL */ +#define ADC_SYNCCTL_SYNCM BITS(0,4) /*!< ADC synchronization mode */ +#define ADC_SYNCCTL_SYNCDLY BITS(8,11) /*!< ADC synchronization delay */ +#define ADC_SYNCCTL_SYNCDDM BIT(13) /*!< ADC synchronization DMA disable mode */ +#define ADC_SYNCCTL_SYNCDMA BITS(14,15) /*!< ADC synchronization DMA mode selection */ +#define ADC_SYNCCTL_ADCCK BITS(16,18) /*!< ADC clock */ +#define ADC_SYNCCTL_VBATEN BIT(22) /*!< channel 18 (1/4 voltate of external battery) enable of ADC0 */ +#define ADC_SYNCCTL_TSVREN BIT(23) /*!< channel 16 (temperature sensor) and 17 (internal reference voltage) enable of ADC0 */ + +/* ADC_SYNCDATA */ +#define ADC_SYNCDATA_SYNCDATA0 BITS(0,15) /*!< regular data1 in ADC synchronization mode */ +#define ADC_SYNCDATA_SYNCDATA1 BITS(16,31) /*!< regular data2 in ADC synchronization mode */ + +/* constants definitions */ +/* ADC channel group definitions */ +#define ADC_REGULAR_CHANNEL ((uint8_t)0x00U) /*!< adc regular channel group */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x01U) /*!< adc inserted channel group */ +#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< both regular and inserted channel group */ + +/* external trigger mode for regular and inserted channel */ +#define EXTERNAL_TRIGGER_DISABLE ((uint32_t)0x00000000U) /*!< external trigger disable */ +#define EXTERNAL_TRIGGER_RISING ((uint32_t)0x00000001U) /*!< rising edge of external trigger */ +#define EXTERNAL_TRIGGER_FALLING ((uint32_t)0x00000002U) /*!< falling edge of external trigger */ +#define EXTERNAL_TRIGGER_RISING_FALLING ((uint32_t)0x00000003U) /*!< rising and falling edge of external trigger */ + +/* ADC inserted channel definitions */ +#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< adc inserted channel 0 */ +#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< adc inserted channel 1 */ +#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< adc inserted channel 2 */ +#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< adc inserted channel 3 */ + +/* ADC special function definitions */ +#define ADC_SCAN_MODE ((uint8_t)0x00U) /*!< scan mode */ +#define ADC_INSERTED_CHANNEL_AUTO ((uint8_t)0x01U) /*!< inserted channel group convert automatically */ +#define ADC_VBAT_CHANNEL_SWITCH ((uint8_t)0x02U) /*!< VBAT channel */ +#define ADC_TEMP_VREF_CHANNEL_SWITCH ((uint8_t)0x03U) /*!< Vref and Vtemp channel */ +#define ADC_CONTINUOUS_MODE ((uint8_t)0x04U) /*!< 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 ADC_SAMPLETIME_3 ((uint8_t)0x00U) /*!< 3 sampling cycles */ +#define ADC_SAMPLETIME_15 ((uint8_t)0x01U) /*!< 15 sampling cycles */ +#define ADC_SAMPLETIME_28 ((uint8_t)0x02U) /*!< 28 sampling cycles */ +#define ADC_SAMPLETIME_56 ((uint8_t)0x03U) /*!< 56 sampling cycles */ +#define ADC_SAMPLETIME_84 ((uint8_t)0x04U) /*!< 84 sampling cycles */ +#define ADC_SAMPLETIME_112 ((uint8_t)0x05U) /*!< 112 sampling cycles */ +#define ADC_SAMPLETIME_144 ((uint8_t)0x06U) /*!< 144 sampling cycles */ +#define ADC_SAMPLETIME_480 ((uint8_t)0x07U) /*!< 480 sampling cycles */ + +/* ADC data alignment */ +#define ADC_DATAALIGN_RIGHT ((uint8_t)0x00U) /*!< LSB alignment */ +#define ADC_DATAALIGN_LEFT ((uint8_t)0x01U) /*!< MSB alignment */ + +/* ADC status flag */ +#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of conversion */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< inserted channel end of conversion */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< inserted channel start flag */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< regular channel start flag */ +#define ADC_FLAG_ROVF ADC_STAT_ROVF /*!< regular data register overflow */ + +/* ADC interrupt flag */ +#define ADC_INT_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt */ +#define ADC_INT_EOC ADC_STAT_EOC /*!< end of group conversion interrupt */ +#define ADC_INT_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt */ +#define ADC_INT_ROVF ADC_STAT_ROVF /*!< regular data register overflow */ + +/* 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(24,27) & ((uint32_t)(regval) << 24)) +#define ADC_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< timer 0 CC0 event select */ +#define ADC_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< timer 0 CC1 event select */ +#define ADC_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< timer 0 CC2 event select */ +#define ADC_EXTTRIG_REGULAR_T1_CH1 CTL1_ETSRC(3) /*!< timer 1 CC1 event select */ +#define ADC_EXTTRIG_REGULAR_T1_CH2 CTL1_ETSRC(4) /*!< timer 1 CC2 event select */ +#define ADC_EXTTRIG_REGULAR_T1_CH3 CTL1_ETSRC(5) /*!< timer 1 CC3 event select */ +#define ADC_EXTTRIG_REGULAR_T1_TRGO CTL1_ETSRC(6) /*!< timer 1 TRGO event select */ +#define ADC_EXTTRIG_REGULAR_T2_CH0 CTL1_ETSRC(7) /*!< timer 2 CC0 event select */ +#define ADC_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(8) /*!< timer 2 TRGO event select */ +#define ADC_EXTTRIG_REGULAR_T3_CH3 CTL1_ETSRC(9) /*!< timer 3 CC3 event select */ +#define ADC_EXTTRIG_REGULAR_T4_CH0 CTL1_ETSRC(10) /*!< timer 4 CC0 event select */ +#define ADC_EXTTRIG_REGULAR_T4_CH1 CTL1_ETSRC(11) /*!< timer 4 CC1 event select */ +#define ADC_EXTTRIG_REGULAR_T4_CH2 CTL1_ETSRC(12) /*!< timer 4 CC2 event select */ +#define ADC_EXTTRIG_REGULAR_T7_CH0 CTL1_ETSRC(13) /*!< timer 7 CC0 event select */ +#define ADC_EXTTRIG_REGULAR_T7_TRGO CTL1_ETSRC(14) /*!< timer 7 TRGO event select */ +#define ADC_EXTTRIG_REGULAR_EXTI_11 CTL1_ETSRC(15) /*!< extiline 11 select */ + +/* ADC external trigger select for inserted channel */ +#define CTL1_ETSIC(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) +#define ADC_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(0) /*!< timer0 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(1) /*!< timer0 TRGO event */ +#define ADC_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(2) /*!< timer1 capture compare 0 */ +#define ADC_EXTTRIG_INSERTED_T1_TRGO CTL1_ETSIC(3) /*!< timer1 TRGO event */ +#define ADC_EXTTRIG_INSERTED_T2_CH1 CTL1_ETSIC(4) /*!< timer2 capture compare 1 */ +#define ADC_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(5) /*!< timer2 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_T3_CH0 CTL1_ETSIC(6) /*!< timer3 capture compare 0 */ +#define ADC_EXTTRIG_INSERTED_T3_CH1 CTL1_ETSIC(7) /*!< timer3 capture compare 1 */ +#define ADC_EXTTRIG_INSERTED_T3_CH2 CTL1_ETSIC(8) /*!< timer3 capture compare 2 */ +#define ADC_EXTTRIG_INSERTED_T3_TRGO CTL1_ETSIC(9) /*!< timer3 capture compare TRGO */ +#define ADC_EXTTRIG_INSERTED_T4_CH3 CTL1_ETSIC(10) /*!< timer4 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_T4_TRGO CTL1_ETSIC(11) /*!< timer4 capture compare TRGO */ +#define ADC_EXTTRIG_INSERTED_T7_CH1 CTL1_ETSIC(12) /*!< timer7 capture compare 1 */ +#define ADC_EXTTRIG_INSERTED_T7_CH2 CTL1_ETSIC(13) /*!< timer7 capture compare 2 */ +#define ADC_EXTTRIG_INSERTED_T7_CH3 CTL1_ETSIC(14) /*!< timer7 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(15) /*!< external interrupt line 15 */ + +/* ADC oversampling mode */ +#define ADC_OVERSAMPLING_ALL_CONVERT 0U /*!< all oversampled conversions for a channel are done consecutively after a trigger */ +#define ADC_OVERSAMPLING_ONE_CONVERT 1U /*!< each oversampled conversion for a channel needs a trigger */ + +/* ADC oversampling shift */ +#define OVCTL_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) +#define ADC_OVERSAMPLING_SHIFT_NONE OVCTL_OVSS(0) /*!< no oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_1B OVCTL_OVSS(1) /*!< 1-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_2B OVCTL_OVSS(2) /*!< 2-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_3B OVCTL_OVSS(3) /*!< 3-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_4B OVCTL_OVSS(4) /*!< 4-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_5B OVCTL_OVSS(5) /*!< 5-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_6B OVCTL_OVSS(6) /*!< 6-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_7B OVCTL_OVSS(7) /*!< 7-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_8B OVCTL_OVSS(8) /*!< 8-bit oversampling shift */ + +/* ADC oversampling ratio */ +#define OVCTL_OVSR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) +#define ADC_OVERSAMPLING_RATIO_MUL2 OVCTL_OVSR(0) /*!< oversampling ratio multiple 2 */ +#define ADC_OVERSAMPLING_RATIO_MUL4 OVCTL_OVSR(1) /*!< oversampling ratio multiple 4 */ +#define ADC_OVERSAMPLING_RATIO_MUL8 OVCTL_OVSR(2) /*!< oversampling ratio multiple 8 */ +#define ADC_OVERSAMPLING_RATIO_MUL16 OVCTL_OVSR(3) /*!< oversampling ratio multiple 16 */ +#define ADC_OVERSAMPLING_RATIO_MUL32 OVCTL_OVSR(4) /*!< oversampling ratio multiple 32 */ +#define ADC_OVERSAMPLING_RATIO_MUL64 OVCTL_OVSR(5) /*!< oversampling ratio multiple 64 */ +#define ADC_OVERSAMPLING_RATIO_MUL128 OVCTL_OVSR(6) /*!< oversampling ratio multiple 128 */ +#define ADC_OVERSAMPLING_RATIO_MUL256 OVCTL_OVSR(7) /*!< oversampling ratio multiple 256 */ + +/* configure the ADC clock for all the ADCs */ +#define SYNCCTL_ADCCK(regval) (BITS(16,18) & ((uint32_t)(regval) << 16)) +#define ADC_ADCCK_PCLK2_DIV2 SYNCCTL_ADCCK(0) /*!< PCLK2 div2 */ +#define ADC_ADCCK_PCLK2_DIV4 SYNCCTL_ADCCK(1) /*!< PCLK2 div4 */ +#define ADC_ADCCK_PCLK2_DIV6 SYNCCTL_ADCCK(2) /*!< PCLK2 div6 */ +#define ADC_ADCCK_PCLK2_DIV8 SYNCCTL_ADCCK(3) /*!< PCLK2 div8 */ +#define ADC_ADCCK_HCLK_DIV5 SYNCCTL_ADCCK(4) /*!< HCLK div5 */ +#define ADC_ADCCK_HCLK_DIV6 SYNCCTL_ADCCK(5) /*!< HCLK div6 */ +#define ADC_ADCCK_HCLK_DIV10 SYNCCTL_ADCCK(6) /*!< HCLK div10 */ +#define ADC_ADCCK_HCLK_DIV20 SYNCCTL_ADCCK(7) /*!< HCLK div20 */ + +/* ADC synchronization mode */ +#define ADC_SYNC_MODE_INDEPENDENT ((uint32_t)0x00000000U) /*!< ADC synchronization mode disabled.All the ADCs work independently */ +#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL ((uint32_t)0x00000001U) /*!< ADC0 and ADC1 work in combined regular parallel & inserted parallel mode. ADC2 works independently */ +#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION ((uint32_t)0x00000002U) /*!< ADC0 and ADC1 work in combined regular parallel & trigger rotation mode. ADC2 works independently */ +#define ADC_DAUL_INSERTED_PARALLEL ((uint32_t)0x00000005U) /*!< ADC0 and ADC1 work in inserted parallel mode. ADC2 works independently */ +#define ADC_DAUL_REGULAL_PARALLEL ((uint32_t)0x00000006U) /*!< ADC0 and ADC1 work in regular parallel mode. ADC2 works independently */ +#define ADC_DAUL_REGULAL_FOLLOW_UP ((uint32_t)0x00000007U) /*!< ADC0 and ADC1 work in follow-up mode. ADC2 works independently */ +#define ADC_DAUL_INSERTED_TRRIGGER_ROTATION ((uint32_t)0x00000009U) /*!< ADC0 and ADC1 work in trigger rotation mode. ADC2 works independently */ +#define ADC_ALL_REGULAL_PARALLEL_INSERTED_PARALLEL ((uint32_t)0x00000011U) /*!< all ADCs work in combined regular parallel & inserted parallel mode */ +#define ADC_ALL_REGULAL_PARALLEL_INSERTED_ROTATION ((uint32_t)0x00000012U) /*!< all ADCs work in combined regular parallel & trigger rotation mode */ +#define ADC_ALL_INSERTED_PARALLEL ((uint32_t)0x00000015U) /*!< all ADCs work in inserted parallel mode */ +#define ADC_ALL_REGULAL_PARALLEL ((uint32_t)0x00000016U) /*!< all ADCs work in regular parallel mode */ +#define ADC_ALL_REGULAL_FOLLOW_UP ((uint32_t)0x00000017U) /*!< all ADCs work in follow-up mode */ +#define ADC_ALL_INSERTED_TRRIGGER_ROTATION ((uint32_t)0x00000019U) /*!< all ADCs work in trigger rotation mode */ + +/* ADC synchronization delay */ +#define ADC_SYNC_DELAY_5CYCLE ((uint32_t)0x00000000U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 5 ADC clock cycles. */ +#define ADC_SYNC_DELAY_6CYCLE ((uint32_t)0x00000100U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 6 ADC clock cycles. */ +#define ADC_SYNC_DELAY_7CYCLE ((uint32_t)0x00000200U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 7 ADC clock cycles. */ +#define ADC_SYNC_DELAY_8CYCLE ((uint32_t)0x00000300U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 8 ADC clock cycles. */ +#define ADC_SYNC_DELAY_9CYCLE ((uint32_t)0x00000400U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 9 ADC clock cycles. */ +#define ADC_SYNC_DELAY_10CYCLE ((uint32_t)0x00000500U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 10 ADC clock cycles. */ +#define ADC_SYNC_DELAY_11CYCLE ((uint32_t)0x00000600U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 11 ADC clock cycles. */ +#define ADC_SYNC_DELAY_12CYCLE ((uint32_t)0x00000700U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 12 ADC clock cycles. */ +#define ADC_SYNC_DELAY_13CYCLE ((uint32_t)0x00000800U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 13 ADC clock cycles. */ +#define ADC_SYNC_DELAY_14CYCLE ((uint32_t)0x00000900U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 14 ADC clock cycles. */ +#define ADC_SYNC_DELAY_15CYCLE ((uint32_t)0x00000A00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 15 ADC clock cycles. */ +#define ADC_SYNC_DELAY_16CYCLE ((uint32_t)0x00000B00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 16 ADC clock cycles. */ +#define ADC_SYNC_DELAY_17CYCLE ((uint32_t)0x00000C00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 17 ADC clock cycles. */ +#define ADC_SYNC_DELAY_18CYCLE ((uint32_t)0x00000D00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 18 ADC clock cycles. */ +#define ADC_SYNC_DELAY_19CYCLE ((uint32_t)0x00000E00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 19 ADC clock cycles. */ +#define ADC_SYNC_DELAY_20CYCLE ((uint32_t)0x00000F00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 20 ADC clock cycles. */ + +/* ADC synchronization DMA mode selection */ +#define ADC_SYNC_DMA_DISABLE ((uint32_t)0x00000000U) /*!< ADC synchronization DMA disabled */ +#define ADC_SYNC_DMA_MODE0 ((uint32_t)0x00004000U) /*!< ADC synchronization DMA mode 0 */ +#define ADC_SYNC_DMA_MODE1 ((uint32_t)0x00008000U) /*!< ADC synchronization DMA mode 1 */ + +/* end of conversion mode */ +#define ADC_EOC_SET_SEQUENCE ((uint8_t)0x00U) /*!< only at the end of a sequence of regular conversions, the EOC bit is set */ +#define ADC_EOC_SET_CONVERSION ((uint8_t)0x01U) /*!< at the end of each regular conversion, the EOC bit is set */ + +/* function declarations */ +/* ADC reset */ +void adc_deinit(void); +/* enable ADC interface */ +void adc_enable(uint32_t adc_periph); +/* disable ADC interface */ +void adc_disable(uint32_t adc_periph); +/* ADC data alignment config */ +void adc_data_alignment_config(uint32_t adc_periph , uint8_t data_alignment); +/* ADC resolution config */ +void adc_resolution_config(uint32_t adc_periph , uint32_t resolution); +/* ADC calibration and reset calibration */ +void adc_calibration_enable(uint32_t adc_periph); +/* ADC discontinuous mode config */ +void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_channel_group , uint8_t length); +/* config end of conversion mode */ +void adc_end_of_conversion_config(uint32_t adc_periph , uint8_t end_selection); +/* ADC special function enable or disable */ +void adc_special_function_config(uint32_t adc_periph , uint8_t function , ControlStatus newvalue); +/* configure the ADC clock for all the ADCs */ +void adc_clock_config(uint32_t prescaler); + +/* ADC channel */ +/* configure the ADC clock for all the ADCs */ +void adc_channel_16_to_18(uint8_t function,ControlStatus newvalue); +/* config the length of regular channel group or inserted channel group */ +void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t length); + +/* ADC trigger */ +/* ADC external trigger enable */ +void adc_external_trigger_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t trigger_mode); +/* ADC external trigger source config */ +void adc_external_trigger_source_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t external_trigger_source); +/* ADC software trigger enable */ +void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_channel_group); + +/* ADC flag and interrupt */ +/* get the ADC flag bits */ +FlagStatus adc_flag_get(uint32_t adc_periph , uint32_t adc_flag); +/* clear the ADC flag bits */ +void adc_flag_clear(uint32_t adc_periph , uint32_t adc_flag); +/* get the ADC interrupt bits */ +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph , uint32_t adc_interrupt); +/* clear the ADC flag */ +void adc_interrupt_flag_clear(uint32_t adc_periph , uint32_t adc_interrupt); +/* ADC interrupt enable */ +void adc_interrupt_enable(uint32_t adc_periph , uint32_t adc_interrupt); +/* ADC interrupt disable */ +void adc_interrupt_disable(uint32_t adc_periph , uint32_t adc_interrupt); + +/* ADC analog watchdog */ +/* ADC analog watchdog single channel disable */ +void adc_watchdog_single_channel_disable(uint32_t adc_periph ); +/* ADC analog watchdog single channel enable */ +void adc_watchdog_single_channel_enable(uint32_t adc_periph , uint8_t adc_channel); +/* adc analog watchdog group channel config */ +void adc_watchdog_enable(uint32_t adc_periph , uint8_t adc_channel_group); +/* ADC analog watchdog disable */ +void adc_watchdog_disable(uint32_t adc_periph , uint8_t adc_channel_group); +/* ADC analog watchdog threshold config */ +void adc_watchdog_threshold_config(uint32_t adc_periph , uint16_t low_threshold , uint16_t high_threshold); + +/* regular channel */ +/* ADC regular channel config */ +void adc_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time); +/* ADC regular group data register read */ +uint16_t adc_regular_data_read(uint32_t adc_periph); + +/* inserted channel */ +/* ADC inserted channel config */ +void adc_inserted_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint8_t sample_time); +/* ADC inserted channel offset config */ +void adc_inserted_channel_offset_config(uint32_t adc_periph , uint8_t inserted_channel , uint16_t offset); +/* ADC inserted group data register read */ +uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel); + +/* ADC DMA */ +/* DMA request enable */ +void adc_dma_mode_enable(uint32_t adc_periph); +/* DMA request disable */ +void adc_dma_mode_disable(uint32_t adc_periph); +/* when DMA=1, the DMA engine issues a request at end of each regular conversion */ +void adc_dma_request_after_last_enable(uint32_t adc_periph); +/* the DMA engine is disabled after the end of transfer signal from DMA controller is detected */ +void adc_dma_request_after_last_disable(uint32_t adc_periph); + +/* ADC oversample */ +/* ADC oversample mode config */ +void adc_oversample_mode_config(uint32_t adc_periph , uint8_t mode , uint16_t shift , uint8_t ratio); +/* ADC oversample mode enable */ +void adc_oversample_mode_enable(uint32_t adc_periph ); +/* ADC oversample mode disable */ +void adc_oversample_mode_disable(uint32_t adc_periph ); + +/* ADC synchronization */ +/* configure the ADC sync mode */ +void adc_sync_mode_config(uint32_t sync_mode); +/* configure the delay between 2 sampling phases in ADC sync modes */ +void adc_sync_delay_config(uint32_t sample_delay); +/* configure ADC sync DMA mode selection */ +void adc_sync_dma_config(uint32_t dma_mode ); +/* configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected */ +void adc_sync_dma_request_after_last_enable(void); +/* configure ADC sync DMA engine issues requests according to the SYNCDMA bits */ +void adc_sync_dma_request_after_last_disable(void); +/* ADC sync regular data register read */ +uint32_t adc_sync_regular_data_read(void); + +#endif /* GD32F4XX_ADC_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h new file mode 100644 index 0000000000..2be5832462 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h @@ -0,0 +1,652 @@ +/*! + \file gd32f4xx_can.h + \brief definitions for the CAN +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_CAN_H +#define GD32F4XX_CAN_H + +#include "gd32f4xx.h" + +/* CAN definitions */ +#define CAN0 CAN_BASE /*!< CAN0 base address */ +#define CAN1 (CAN0 + 0x00000400U) /*!< CAN1 base address */ + +/* registers definitions */ +#define CAN_CTL(canx) REG32((canx) + 0x00U) /*!< CAN control register */ +#define CAN_STAT(canx) REG32((canx) + 0x04U) /*!< CAN status register */ +#define CAN_TSTAT(canx) REG32((canx) + 0x08U) /*!< CAN transmit status register*/ +#define CAN_RFIFO0(canx) REG32((canx) + 0x0CU) /*!< CAN receive FIFO0 register */ +#define CAN_RFIFO1(canx) REG32((canx) + 0x10U) /*!< CAN receive FIFO1 register */ +#define CAN_INTEN(canx) REG32((canx) + 0x14U) /*!< CAN interrupt enable register */ +#define CAN_ERR(canx) REG32((canx) + 0x18U) /*!< CAN error register */ +#define CAN_BT(canx) REG32((canx) + 0x1CU) /*!< CAN bit timing register */ +#define CAN_TMI0(canx) REG32((canx) + 0x180U) /*!< CAN transmit mailbox0 identifier register */ +#define CAN_TMP0(canx) REG32((canx) + 0x184U) /*!< CAN transmit mailbox0 property register */ +#define CAN_TMDATA00(canx) REG32((canx) + 0x188U) /*!< CAN transmit mailbox0 data0 register */ +#define CAN_TMDATA10(canx) REG32((canx) + 0x18CU) /*!< CAN transmit mailbox0 data1 register */ +#define CAN_TMI1(canx) REG32((canx) + 0x190U) /*!< CAN transmit mailbox1 identifier register */ +#define CAN_TMP1(canx) REG32((canx) + 0x194U) /*!< CAN transmit mailbox1 property register */ +#define CAN_TMDATA01(canx) REG32((canx) + 0x198U) /*!< CAN transmit mailbox1 data0 register */ +#define CAN_TMDATA11(canx) REG32((canx) + 0x19CU) /*!< CAN transmit mailbox1 data1 register */ +#define CAN_TMI2(canx) REG32((canx) + 0x1A0U) /*!< CAN transmit mailbox2 identifier register */ +#define CAN_TMP2(canx) REG32((canx) + 0x1A4U) /*!< CAN transmit mailbox2 property register */ +#define CAN_TMDATA02(canx) REG32((canx) + 0x1A8U) /*!< CAN transmit mailbox2 data0 register */ +#define CAN_TMDATA12(canx) REG32((canx) + 0x1ACU) /*!< CAN transmit mailbox2 data1 register */ +#define CAN_RFIFOMI0(canx) REG32((canx) + 0x1B0U) /*!< CAN receive FIFO0 mailbox identifier register */ +#define CAN_RFIFOMP0(canx) REG32((canx) + 0x1B4U) /*!< CAN receive FIFO0 mailbox property register */ +#define CAN_RFIFOMDATA00(canx) REG32((canx) + 0x1B8U) /*!< CAN receive FIFO0 mailbox data0 register */ +#define CAN_RFIFOMDATA10(canx) REG32((canx) + 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 */ + +/* 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_WUIE 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 */ + +/* 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) + +/* 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_SLPIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 4U), /*!< status change interrupt flag of sleep working mode entering */ + CAN_INT_WUIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 3U), /*!< status change interrupt flag of wakeup from sleep working mode */ + CAN_INT_ERRIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 2U), /*!< error interrupt flag */ +}can_interrupt_flag_enum; + +/* CAN initiliaze parameters struct */ +typedef struct +{ + uint8_t working_mode; /*!< CAN working mode */ + uint8_t resync_jump_width; /*!< CAN resynchronization jump width */ + uint8_t time_segment_1; /*!< time segment 1 */ + uint8_t time_segment_2; /*!< time segment 2 */ + ControlStatus time_triggered; /*!< time triggered communication mode */ + ControlStatus auto_bus_off_recovery; /*!< automatic bus-off recovery */ + ControlStatus auto_wake_up; /*!< automatic wake-up mode */ + ControlStatus 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) + +#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 */ + +#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_RFIFO_RFL0_MASK ((uint32_t)0x00000003U) /*!< mask for frame number in receive FIFO0 */ + +#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 */ + +/* function declarations */ +/* initialization functions */ +/* CAN deinit */ +void can_deinit(uint32_t can_periph); +/* CAN init */ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init); + +/* transmit functions */ +/* CAN transmit message */ +uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message); +/* CAN transmit state */ +can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number); +/* CAN stop transmission */ +void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number); +/* CAN transmit error number */ +uint8_t can_transmit_error_number(uint32_t can_periph); + +/* filter functions */ +/* 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); +/* 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); + +/* receive functions */ +/* 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(uint32_t can_periph, uint8_t fifo_number); +/* CAN receive error number */ +uint8_t can_receive_error_number(uint32_t can_periph); + +/* mode functions */ +/* 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); + +/* flag functions */ +/* CAN get error */ +can_error_enum can_error_get(uint32_t can_periph); +/* CAN get flag state */ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag); +/* CAN clear flag state */ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag); +/* CAN get interrupt flag state */ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag); +/* CAN clear interrupt flag state */ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag); + +#endif /* GD32F4XX_CAN_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h new file mode 100644 index 0000000000..983dd944a5 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h @@ -0,0 +1,55 @@ +/*! + \file gd32f4xx_crc.h + \brief definitions for the CRC +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_CRC_H +#define GD32F4XX_CRC_H + +#include "gd32f4xx.h" + +/* CRC definitions */ +#define CRC CRC_BASE + +/* registers definitions */ +#define CRC_DATA REG32(CRC + 0x00U) /*!< CRC data register */ +#define CRC_FDATA REG32(CRC + 0x04U) /*!< CRC free data register */ +#define CRC_CTL REG32(CRC + 0x08U) /*!< CRC control register */ + +/* bits definitions */ +/* CRC_DATA */ +#define CRC_DATA_DATA BITS(0,31) /*!< CRC calculation result bits */ + +/* CRC_FDATA */ +#define CRC_FDATA_FDATA BITS(0,7) /*!< CRC free data bits */ + +/* CRC_CTL */ +#define CRC_CTL_RST BIT(0) /*!< CRC reset CRC_DATA register bit */ + + +/* function declarations */ +/* deinit CRC calculation unit */ +void crc_deinit(void); + +/* reset data register 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); + +/* 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 /* GD32F4XX_CRC_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h new file mode 100644 index 0000000000..605d5530d5 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h @@ -0,0 +1,168 @@ +/*! + \file gd32f4xx_ctc.h + \brief definitions for the CTC +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_CTC_H +#define GD32F4XX_CTC_H + +#include "gd32f4xx.h" + +/* CTC definitions */ +#define CTC CTC_BASE + +/* registers definitions */ +#define CTC_CTL0 REG32((CTC) + 0x00U) /*!< CTC control register 0 */ +#define CTC_CTL1 REG32((CTC) + 0x04U) /*!< CTC control register 1 */ +#define CTC_STAT REG32((CTC) + 0x08U) /*!< CTC status register */ +#define CTC_INTC REG32((CTC) + 0x0CU) /*!< CTC interrupt clear register */ + +/* bits definitions */ +/* CTC_CTL0 */ +#define CTC_CTL0_CKOKIE BIT(0) /*!< clock trim OK(CKOKIF) interrupt enable */ +#define CTC_CTL0_CKWARNIE BIT(1) /*!< clock trim warning(CKWARNIF) interrupt enable */ +#define CTC_CTL0_ERRIE BIT(2) /*!< error(ERRIF) interrupt enable */ +#define CTC_CTL0_EREFIE BIT(3) /*!< EREFIF interrupt enable */ +#define CTC_CTL0_CNTEN BIT(5) /*!< CTC counter enable */ +#define CTC_CTL0_AUTOTRIM BIT(6) /*!< hardware automatically trim mode */ +#define CTC_CTL0_SWREFPUL BIT(7) /*!< software reference source sync pulse */ +#define CTC_CTL0_TRIMVALUE BITS(8,13) /*!< IRC48M trim value */ + +/* CTC_CTL1 */ +#define CTC_CTL1_RLVALUE BITS(0,15) /*!< CTC counter reload value */ +#define CTC_CTL1_CKLIM BITS(16,23) /*!< clock trim base limit value */ +#define CTC_CTL1_REFPSC BITS(24,26) /*!< reference signal source prescaler */ +#define CTC_CTL1_REFSEL BITS(28,29) /*!< reference signal source selection */ +#define CTC_CTL1_USBSOFSEL BIT(30) /*!< USBFS or USBHS SOF signal selection */ +#define CTC_CTL1_REFPOL BIT(31) /*!< reference signal source polarity */ + +/* CTC_STAT */ +#define CTC_STAT_CKOKIF BIT(0) /*!< clock trim OK interrupt flag */ +#define CTC_STAT_CKWARNIF BIT(1) /*!< clock trim warning interrupt flag */ +#define CTC_STAT_ERRIF BIT(2) /*!< error interrupt flag */ +#define CTC_STAT_EREFIF BIT(3) /*!< expect reference interrupt flag */ +#define CTC_STAT_CKERR BIT(8) /*!< clock trim error bit */ +#define CTC_STAT_REFMISS BIT(9) /*!< reference sync pulse miss */ +#define CTC_STAT_TRIMERR BIT(10) /*!< trim value error bit */ +#define CTC_STAT_REFDIR BIT(15) /*!< CTC trim counter direction when reference sync pulse occurred */ +#define CTC_STAT_REFCAP BITS(16,31) /*!< CTC counter capture when reference sync pulse occurred */ + +/* CTC_INTC */ +#define CTC_INTC_CKOKIC BIT(0) /*!< CKOKIF interrupt clear bit */ +#define CTC_INTC_CKWARNIC BIT(1) /*!< CKWARNIF interrupt clear bit */ +#define CTC_INTC_ERRIC BIT(2) /*!< ERRIF interrupt clear bit */ +#define CTC_INTC_EREFIC BIT(3) /*!< EREFIF interrupt clear bit */ + +/* constants definitions */ +/* hardware automatically trim mode definitions */ +#define CTC_HARDWARE_TRIM_MODE_ENABLE CTC_CTL0_AUTOTRIM /*!< hardware automatically trim mode enable*/ +#define CTC_HARDWARE_TRIM_MODE_DISABLE ((uint32_t)0x00000000U) /*!< hardware automatically trim mode disable*/ + +/* reference signal source polarity definitions */ +#define CTC_REFSOURCE_POLARITY_FALLING CTC_CTL1_REFPOL /*!< reference signal source polarity is falling edge*/ +#define CTC_REFSOURCE_POLARITY_RISING ((uint32_t)0x00000000U) /*!< reference signal source polarity is rising edge*/ + +/* USBFS or USBHS SOF signal selection definitions */ +#define CTC_USBSOFSEL_USBHS CTC_CTL1_USBSOFSEL /*!< USBHS SOF signal is selected*/ +#define CTC_USBSOFSEL_USBFS ((uint32_t)0x00000000U) /*!< USBFS SOF signal is selected*/ + +/* reference signal source selection definitions */ +#define CTL1_REFSEL(regval) (BITS(28,29) & ((uint32_t)(regval) << 28)) +#define CTC_REFSOURCE_GPIO CTL1_REFSEL(0) /*!< GPIO is selected */ +#define CTC_REFSOURCE_LXTAL CTL1_REFSEL(1) /*!< LXTAL is clock selected */ +#define CTC_REFSOURCE_USBSOF CTL1_REFSEL(2) /*!< USBSOF is selected */ + +/* reference signal source prescaler definitions */ +#define CTL1_REFPSC(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define CTC_REFSOURCE_PSC_OFF CTL1_REFPSC(0) /*!< reference signal not divided */ +#define CTC_REFSOURCE_PSC_DIV2 CTL1_REFPSC(1) /*!< reference signal divided by 2 */ +#define CTC_REFSOURCE_PSC_DIV4 CTL1_REFPSC(2) /*!< reference signal divided by 4 */ +#define CTC_REFSOURCE_PSC_DIV8 CTL1_REFPSC(3) /*!< reference signal divided by 8 */ +#define CTC_REFSOURCE_PSC_DIV16 CTL1_REFPSC(4) /*!< reference signal divided by 16 */ +#define CTC_REFSOURCE_PSC_DIV32 CTL1_REFPSC(5) /*!< reference signal divided by 32 */ +#define CTC_REFSOURCE_PSC_DIV64 CTL1_REFPSC(6) /*!< reference signal divided by 64 */ +#define CTC_REFSOURCE_PSC_DIV128 CTL1_REFPSC(7) /*!< reference signal divided by 128 */ + +/* CTC interrupt enable definitions */ +#define CTC_INT_CKOKIE CTC_CTL0_CKOKIE /*!< clock trim OK interrupt enable */ +#define CTC_INT_CKWARNIE CTC_CTL0_CKWARNIE /*!< clock trim warning interrupt enable */ +#define CTC_INT_ERRIE CTC_CTL0_ERRIE /*!< error interrupt enable */ +#define CTC_INT_EREFIE CTC_CTL0_EREFIE /*!< expect reference interrupt enable */ + +/* CTC interrupt source definitions */ +#define CTC_INT_CKOK CTC_STAT_CKOKIF /*!< clock trim OK interrupt flag */ +#define CTC_INT_CKWARN CTC_STAT_CKWARNIF /*!< clock trim warning interrupt flag */ +#define CTC_INT_ERR CTC_STAT_ERRIF /*!< error interrupt flag */ +#define CTC_INT_EREF CTC_STAT_EREFIF /*!< expect reference interrupt flag */ +#define CTC_INT_CKERR CTC_STAT_CKERR /*!< clock trim error bit */ +#define CTC_INT_REFMISS CTC_STAT_REFMISS /*!< reference sync pulse miss */ +#define CTC_INT_TRIMERR CTC_STAT_TRIMERR /*!< trim value error */ + +/* CTC flag definitions */ +#define CTC_FLAG_CKOK CTC_STAT_CKOKIF /*!< clock trim OK flag */ +#define CTC_FLAG_CKWARN CTC_STAT_CKWARNIF /*!< clock trim warning flag */ +#define CTC_FLAG_ERR CTC_STAT_ERRIF /*!< error flag */ +#define CTC_FLAG_EREF CTC_STAT_EREFIF /*!< expect reference flag */ +#define CTC_FLAG_CKERR CTC_STAT_CKERR /*!< clock trim error bit */ +#define CTC_FLAG_REFMISS CTC_STAT_REFMISS /*!< reference sync pulse miss */ +#define CTC_FLAG_TRIMERR CTC_STAT_TRIMERR /*!< trim value error bit */ + +/* function declarations */ +/* reset ctc clock trim controller */ +void ctc_deinit(void); + +/* enable the CTC interrupt */ +void ctc_interrupt_enable(uint32_t ctc_interrupt); +/* disable the CTC interrupt */ +void ctc_interrupt_disable(uint32_t ctc_interrupt); +/* get CTC interrupt flag */ +FlagStatus ctc_interrupt_flag_get(uint32_t ctc_interrupt); +/* clear CTC interrupt flag */ +void ctc_interrupt_flag_clear(uint32_t ctc_interrupt); + +/* get CTC flag */ +FlagStatus ctc_flag_get(uint32_t ctc_flag); +/* clear CTC flag */ +void ctc_flag_clear(uint32_t ctc_flag); + +/* configure the IRC48M trim value */ +void ctc_irc48m_trim_value_config(uint8_t ctc_trim_value); +/* generate software reference source sync pulse */ +void ctc_software_refsource_pulse_generate(void); +/* configure hardware automatically trim mode */ +void ctc_hardware_trim_mode_config(uint32_t ctc_hardmode); + +/* enable CTC counter */ +void ctc_counter_enable(void); +/* disable CTC counter */ +void ctc_counter_disable(void); + +/* configure reference signal source polarity */ +void ctc_refsource_polarity_config(uint32_t ctc_polarity); +/* select USBFS or USBHS SOF signal */ +void ctc_usbsof_signal_select(uint32_t ctc_usbsof); +/* select reference signal source */ +void ctc_refsource_signal_select(uint32_t ctc_refs); +/* configure reference signal source prescaler */ +void ctc_refsource_prescaler_config(uint32_t ctc_prescaler); +/* configure clock trim base limit value */ +void ctc_clock_limit_value_config(uint8_t ctc_limit_value); +/* configure CTC counter reload value */ +void ctc_counter_reload_value_config(uint16_t ctc_reload_value); + +/* read CTC counter capture value when reference sync pulse occurred */ +uint16_t ctc_counter_capture_value_read(void); +/* read CTC trim counter direction when reference sync pulse occurred */ +FlagStatus ctc_counter_direction_read(void); +/* read CTC counter reload value */ +uint16_t ctc_counter_reload_value_read(void); +/* read the IRC48M trim value */ +uint8_t ctc_irc48m_trim_value_read(void); + +#endif /* GD32F4XX_CTC_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h new file mode 100644 index 0000000000..8a668fcc0c --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h @@ -0,0 +1,240 @@ +/*! + \file gd32f4xx_dac.h + \brief definitions for the DAC +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_DAC_H +#define GD32F4XX_DAC_H + +#include "gd32f4xx.h" + +/* DACx(x=0,1) definitions */ +#define DAC DAC_BASE +#define DAC0 0U +#define DAC1 1U + +/* registers definitions */ +#define DAC_CTL REG32(DAC + 0x00U) /*!< DAC control register */ +#define DAC_SWT REG32(DAC + 0x04U) /*!< DAC software trigger register */ +#define DAC0_R12DH REG32(DAC + 0x08U) /*!< DAC0 12-bit right-aligned data holding register */ +#define DAC0_L12DH REG32(DAC + 0x0CU) /*!< DAC0 12-bit left-aligned data holding register */ +#define DAC0_R8DH REG32(DAC + 0x10U) /*!< DAC0 8-bit right-aligned data holding register */ +#define DAC1_R12DH REG32(DAC + 0x14U) /*!< DAC1 12-bit right-aligned data holding register */ +#define DAC1_L12DH REG32(DAC + 0x18U) /*!< DAC1 12-bit left-aligned data holding register */ +#define DAC1_R8DH REG32(DAC + 0x1CU) /*!< DAC1 8-bit right-aligned data holding register */ +#define DACC_R12DH REG32(DAC + 0x20U) /*!< DAC concurrent mode 12-bit right-aligned data holding register */ +#define DACC_L12DH REG32(DAC + 0x24U) /*!< DAC concurrent mode 12-bit left-aligned data holding register */ +#define DACC_R8DH REG32(DAC + 0x28U) /*!< DAC concurrent mode 8-bit right-aligned data holding register */ +#define DAC0_DO REG32(DAC + 0x2CU) /*!< DAC0 data output register */ +#define DAC1_DO REG32(DAC + 0x30U) /*!< DAC1 data output register */ +#define DAC_STAT REG32(DAC + 0x34U) /*!< DAC status register */ + +/* bits definitions */ +/* DAC_CLT */ +#define DAC_CTL_DEN0 BIT(0) /*!< DAC0 enable/disable bit */ +#define DAC_CTL_DBOFF0 BIT(1) /*!< DAC0 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN0 BIT(2) /*!< DAC0 trigger enable/disable bit */ +#define DAC_CTL_DTSEL0 BITS(3,5) /*!< DAC0 trigger source selection enable/disable bits */ +#define DAC_CTL_DWM0 BITS(6,7) /*!< DAC0 noise wave mode */ +#define DAC_CTL_DWBW0 BITS(8,11) /*!< DAC0 noise wave bit width */ +#define DAC_CTL_DDMAEN0 BIT(12) /*!< DAC0 DMA enable/disanle bit */ +#define DAC_CTL_DDUDRIE0 BIT(13) /*!< DAC0 DMA underrun interrupt enable/disable bit */ +#define DAC_CTL_DEN1 BIT(16) /*!< DAC1 enable/disable bit */ +#define DAC_CTL_DBOFF1 BIT(17) /*!< DAC1 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN1 BIT(18) /*!< DAC1 trigger enable/disable bit */ +#define DAC_CTL_DTSEL1 BITS(19,21) /*!< DAC1 trigger source selection enable/disable bits */ +#define DAC_CTL_DWM1 BITS(22,23) /*!< DAC1 noise wave mode */ +#define DAC_CTL_DWBW1 BITS(24,27) /*!< DAC1 noise wave bit width */ +#define DAC_CTL_DDMAEN1 BIT(28) /*!< DAC1 DMA enable/disanle bit */ +#define DAC_CTL_DDUDRIE1 BIT(29) /*!< DAC1 DMA underrun interrupt enable/disable bit */ + +/* DAC_SWT */ +#define DAC_SWT_SWTR0 BIT(0) /*!< DAC0 software trigger bit, cleared by hardware */ +#define DAC_SWT_SWTR1 BIT(1) /*!< DAC1 software trigger bit, cleared by hardware */ + +/* DAC0_R12DH */ +#define DAC0_R12DH_DAC0_DH BITS(0,11) /*!< DAC0 12-bit right-aligned data bits */ + +/* DAC0_L12DH */ +#define DAC0_L12DH_DAC0_DH BITS(4,15) /*!< DAC0 12-bit left-aligned data bits */ + +/* DAC0_R8DH */ +#define DAC0_R8DH_DAC0_DH BITS(0,7) /*!< DAC0 8-bit right-aligned data bits */ + +/* DAC1_R12DH */ +#define DAC1_R12DH_DAC1_DH BITS(0,11) /*!< DAC1 12-bit right-aligned data bits */ + +/* DAC1_L12DH */ +#define DAC1_L12DH_DAC1_DH BITS(4,15) /*!< DAC1 12-bit left-aligned data bits */ + +/* DAC1_R8DH */ +#define DAC1_R8DH_DAC1_DH BITS(0,7) /*!< DAC1 8-bit right-aligned data bits */ + +/* DACC_R12DH */ +#define DACC_R12DH_DAC0_DH BITS(0,11) /*!< DAC concurrent mode DAC0 12-bit right-aligned data bits */ +#define DACC_R12DH_DAC1_DH BITS(16,27) /*!< DAC concurrent mode DAC1 12-bit right-aligned data bits */ + +/* DACC_L12DH */ +#define DACC_L12DH_DAC0_DH BITS(4,15) /*!< DAC concurrent mode DAC0 12-bit left-aligned data bits */ +#define DACC_L12DH_DAC1_DH BITS(20,31) /*!< DAC concurrent mode DAC1 12-bit left-aligned data bits */ + +/* DACC_R8DH */ +#define DACC_R8DH_DAC0_DH BITS(0,7) /*!< DAC concurrent mode DAC0 8-bit right-aligned data bits */ +#define DACC_R8DH_DAC1_DH BITS(16,23) /*!< DAC concurrent mode DAC1 8-bit right-aligned data bits */ + +/* DAC0_DO */ +#define DAC0_DO_DAC0_DO BITS(0,11) /*!< DAC0 12-bit output data bits */ + +/* DAC1_DO */ +#define DAC1_DO_DAC1_DO BITS(0,11) /*!< DAC1 12-bit output data bits */ + +/* DAC_STAT */ +#define DAC_STAT_DDUDR0 BIT(13) /*!< DAC0 DMA underrun flag */ +#define DAC_STAT_DDUDR1 BIT(29) /*!< DAC1 DMA underrun flag */ + +/* constants definitions */ +/* DAC trigger source */ +#define CTL_DTSEL(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) +#define DAC_TRIGGER_T5_TRGO CTL_DTSEL(0) /*!< TIMER5 TRGO */ +#define DAC_TRIGGER_T7_TRGO CTL_DTSEL(1) /*!< TIMER7 TRGO */ +#define DAC_TRIGGER_T6_TRGO CTL_DTSEL(2) /*!< TIMER6 TRGO */ +#define DAC_TRIGGER_T4_TRGO CTL_DTSEL(3) /*!< TIMER4 TRGO */ +#define DAC_TRIGGER_T1_TRGO CTL_DTSEL(4) /*!< TIMER1 TRGO */ +#define DAC_TRIGGER_T3_TRGO CTL_DTSEL(5) /*!< TIMER3 TRGO */ +#define DAC_TRIGGER_EXTI_9 CTL_DTSEL(6) /*!< EXTI interrupt line9 event */ +#define DAC_TRIGGER_SOFTWARE CTL_DTSEL(7) /*!< software trigger */ + +/* DAC noise wave mode */ +#define CTL_DWM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6)) +#define DAC_WAVE_DISABLE CTL_DWM(0) /*!< wave disable */ +#define DAC_WAVE_MODE_LFSR CTL_DWM(1) /*!< LFSR noise mode */ +#define DAC_WAVE_MODE_TRIANGLE CTL_DWM(2) /*!< triangle noise mode */ + +/* DAC noise wave bit width */ +#define DWBW(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) +#define DAC_WAVE_BIT_WIDTH_1 DWBW(0) /*!< bit width of the wave signal is 1 */ +#define DAC_WAVE_BIT_WIDTH_2 DWBW(1) /*!< bit width of the wave signal is 2 */ +#define DAC_WAVE_BIT_WIDTH_3 DWBW(2) /*!< bit width of the wave signal is 3 */ +#define DAC_WAVE_BIT_WIDTH_4 DWBW(3) /*!< bit width of the wave signal is 4 */ +#define DAC_WAVE_BIT_WIDTH_5 DWBW(4) /*!< bit width of the wave signal is 5 */ +#define DAC_WAVE_BIT_WIDTH_6 DWBW(5) /*!< bit width of the wave signal is 6 */ +#define DAC_WAVE_BIT_WIDTH_7 DWBW(6) /*!< bit width of the wave signal is 7 */ +#define DAC_WAVE_BIT_WIDTH_8 DWBW(7) /*!< bit width of the wave signal is 8 */ +#define DAC_WAVE_BIT_WIDTH_9 DWBW(8) /*!< bit width of the wave signal is 9 */ +#define DAC_WAVE_BIT_WIDTH_10 DWBW(9) /*!< bit width of the wave signal is 10 */ +#define DAC_WAVE_BIT_WIDTH_11 DWBW(10) /*!< bit width of the wave signal is 11 */ +#define DAC_WAVE_BIT_WIDTH_12 DWBW(11) /*!< bit width of the wave signal is 12 */ + +/* unmask LFSR bits in DAC LFSR noise mode */ +#define DAC_LFSR_BIT0 DAC_WAVE_BIT_WIDTH_1 /*!< unmask the LFSR bit0 */ +#define DAC_LFSR_BITS1_0 DAC_WAVE_BIT_WIDTH_2 /*!< unmask the LFSR bits[1:0] */ +#define DAC_LFSR_BITS2_0 DAC_WAVE_BIT_WIDTH_3 /*!< unmask the LFSR bits[2:0] */ +#define DAC_LFSR_BITS3_0 DAC_WAVE_BIT_WIDTH_4 /*!< unmask the LFSR bits[3:0] */ +#define DAC_LFSR_BITS4_0 DAC_WAVE_BIT_WIDTH_5 /*!< unmask the LFSR bits[4:0] */ +#define DAC_LFSR_BITS5_0 DAC_WAVE_BIT_WIDTH_6 /*!< unmask the LFSR bits[5:0] */ +#define DAC_LFSR_BITS6_0 DAC_WAVE_BIT_WIDTH_7 /*!< unmask the LFSR bits[6:0] */ +#define DAC_LFSR_BITS7_0 DAC_WAVE_BIT_WIDTH_8 /*!< unmask the LFSR bits[7:0] */ +#define DAC_LFSR_BITS8_0 DAC_WAVE_BIT_WIDTH_9 /*!< unmask the LFSR bits[8:0] */ +#define DAC_LFSR_BITS9_0 DAC_WAVE_BIT_WIDTH_10 /*!< unmask the LFSR bits[9:0] */ +#define DAC_LFSR_BITS10_0 DAC_WAVE_BIT_WIDTH_11 /*!< unmask the LFSR bits[10:0] */ +#define DAC_LFSR_BITS11_0 DAC_WAVE_BIT_WIDTH_12 /*!< unmask the LFSR bits[11:0] */ + +/* triangle amplitude in DAC triangle noise mode */ +#define DAC_TRIANGLE_AMPLITUDE_1 DAC_WAVE_BIT_WIDTH_1 /*!< triangle amplitude is 1 */ +#define DAC_TRIANGLE_AMPLITUDE_3 DAC_WAVE_BIT_WIDTH_2 /*!< triangle amplitude is 3 */ +#define DAC_TRIANGLE_AMPLITUDE_7 DAC_WAVE_BIT_WIDTH_3 /*!< triangle amplitude is 7 */ +#define DAC_TRIANGLE_AMPLITUDE_15 DAC_WAVE_BIT_WIDTH_4 /*!< triangle amplitude is 15 */ +#define DAC_TRIANGLE_AMPLITUDE_31 DAC_WAVE_BIT_WIDTH_5 /*!< triangle amplitude is 31 */ +#define DAC_TRIANGLE_AMPLITUDE_63 DAC_WAVE_BIT_WIDTH_6 /*!< triangle amplitude is 63 */ +#define DAC_TRIANGLE_AMPLITUDE_127 DAC_WAVE_BIT_WIDTH_7 /*!< triangle amplitude is 127 */ +#define DAC_TRIANGLE_AMPLITUDE_255 DAC_WAVE_BIT_WIDTH_8 /*!< triangle amplitude is 255 */ +#define DAC_TRIANGLE_AMPLITUDE_511 DAC_WAVE_BIT_WIDTH_9 /*!< triangle amplitude is 511 */ +#define DAC_TRIANGLE_AMPLITUDE_1023 DAC_WAVE_BIT_WIDTH_10 /*!< triangle amplitude is 1023 */ +#define DAC_TRIANGLE_AMPLITUDE_2047 DAC_WAVE_BIT_WIDTH_11 /*!< triangle amplitude is 2047 */ +#define DAC_TRIANGLE_AMPLITUDE_4095 DAC_WAVE_BIT_WIDTH_12 /*!< triangle amplitude is 4095 */ + +/* DAC 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 */ +/* deinitialize DAC */ +void dac_deinit(void); +/* enable DAC */ +void dac_enable(uint32_t dac_periph); +/* disable DAC */ +void dac_disable(uint32_t dac_periph); +/* enable DAC DMA */ +void dac_dma_enable(uint32_t dac_periph); +/* disable DAC DMA */ +void dac_dma_disable(uint32_t dac_periph); +/* enable DAC output buffer */ +void dac_output_buffer_enable(uint32_t dac_periph); +/* disable DAC output buffer */ +void dac_output_buffer_disable(uint32_t dac_periph); +/* 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); + +/* configure DAC trigger source */ +void dac_trigger_source_config(uint32_t dac_periph, uint32_t triggersource); +/* configure DAC wave mode */ +void dac_wave_mode_config(uint32_t dac_periph, uint32_t wave_mode); +/* configure DAC wave bit width */ +void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width); +/* configure DAC LFSR noise mode */ +void dac_lfsr_noise_config(uint32_t dac_periph, uint32_t unmask_bits); +/* configure DAC triangle noise mode */ +void dac_triangle_noise_config(uint32_t dac_periph, uint32_t amplitude); +/* get the last data output value */ +uint16_t dac_output_value_get(uint32_t dac_periph); + +/* set DAC data holding register value */ +void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data); +/* set DAC concurrent mode data holding register value */ +void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1); + +/* enable DAC concurrent mode */ +void dac_concurrent_enable(void); +/* disable DAC concurrent mode */ +void dac_concurrent_disable(void); +/* enable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_enable(void); +/* disable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_disable(void); +/* enable DAC concurrent buffer function */ +void dac_concurrent_output_buffer_enable(void); +/* disable DAC concurrent buffer function */ +void dac_concurrent_output_buffer_disable(void); +/* enable DAC concurrent interrupt */ +void dac_concurrent_interrupt_enable(void); +/* disable DAC concurrent interrupt */ +void dac_concurrent_interrupt_disable(void); + +/* get the specified DAC flag(DAC DMA underrun flag) */ +FlagStatus dac_flag_get(uint32_t dac_periph); +/* clear the specified DAC flag(DAC DMA underrun flag) */ +void dac_flag_clear(uint32_t dac_periph); +/* get the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */ +FlagStatus dac_interrupt_flag_get(uint32_t dac_periph); +/* clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */ +void dac_interrupt_flag_clear(uint32_t dac_periph); + +#endif /* GD32F4XX_DAC_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h new file mode 100644 index 0000000000..273b13e7fb --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h @@ -0,0 +1,121 @@ +/*! + \file gd32f4xx_dbg.h + \brief definitions for the DBG +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_DBG_H +#define GD32F4XX_DBG_H + +#include "gd32f4xx.h" + +/* DBG definitions */ +#define DBG DBG_BASE + +/* registers definitions */ +#define DBG_ID REG32(DBG + 0x00U) /*!< DBG_ID code register */ +#define DBG_CTL0 REG32(DBG + 0x04U) /*!< DBG control register 0 */ +#define DBG_CTL1 REG32(DBG + 0x08U) /*!< DBG control register 1 */ +#define DBG_CTL2 REG32(DBG + 0x0CU) /*!< DBG control register 2 */ + +/* bits definitions */ +/* DBG_ID */ +#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG ID code values */ + +/* DBG_CTL0 */ +#define DBG_CTL0_SLP_HOLD BIT(0) /*!< keep debugger connection during sleep mode */ +#define DBG_CTL0_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */ +#define DBG_CTL0_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */ +#define DBG_CTL0_TRACE_IOEN BIT(5) /*!< enable trace pin assignment */ +#define DBG_CTL0_TRACE_MODE BITS(6,7) /*!< trace pin mode selection */ + +/* DBG_CTL1 */ +#define DBG_CTL1_TIMER1_HOLD BIT(0) /*!< hold TIMER1 counter when core is halted */ +#define DBG_CTL1_TIMER2_HOLD BIT(1) /*!< hold TIMER2 counter when core is halted */ +#define DBG_CTL1_TIMER3_HOLD BIT(2) /*!< hold TIMER3 counter when core is halted */ +#define DBG_CTL1_TIMER4_HOLD BIT(3) /*!< hold TIMER4 counter when core is halted */ +#define DBG_CTL1_TIMER5_HOLD BIT(4) /*!< hold TIMER5 counter when core is halted */ +#define DBG_CTL1_TIMER6_HOLD BIT(5) /*!< hold TIMER6 counter when core is halted */ +#define DBG_CTL1_TIMER11_HOLD BIT(6) /*!< hold TIMER11 counter when core is halted */ +#define DBG_CTL1_TIMER12_HOLD BIT(7) /*!< hold TIMER12 counter when core is halted */ +#define DBG_CTL1_TIMER13_HOLD BIT(8) /*!< hold TIMER13 counter when core is halted */ +#define DBG_CTL1_RTC_HOLD BIT(10) /*!< hold RTC calendar and wakeup counter when core is halted */ +#define DBG_CTL1_WWDGT_HOLD BIT(11) /*!< debug WWDGT kept when core is halted */ +#define DBG_CTL1_FWDGT_HOLD BIT(12) /*!< debug FWDGT kept when core is halted */ +#define DBG_CTL1_I2C0_HOLD BIT(21) /*!< hold I2C0 smbus when core is halted */ +#define DBG_CTL1_I2C1_HOLD BIT(22) /*!< hold I2C1 smbus when core is halted */ +#define DBG_CTL1_I2C2_HOLD BIT(23) /*!< hold I2C2 smbus when core is halted */ +#define DBG_CTL1_CAN0_HOLD BIT(25) /*!< debug CAN0 kept when core is halted */ +#define DBG_CTL1_CAN1_HOLD BIT(26) /*!< debug CAN1 kept when core is halted */ + +/* DBG_CTL2 */ +#define DBG_CTL2_TIMER0_HOLD BIT(0) /*!< hold TIMER0 counter when core is halted */ +#define DBG_CTL2_TIMER7_HOLD BIT(1) /*!< hold TIMER7 counter when core is halted */ +#define DBG_CTL2_TIMER8_HOLD BIT(16) /*!< hold TIMER8 counter when core is halted */ +#define DBG_CTL2_TIMER9_HOLD BIT(17) /*!< hold TIMER9 counter when core is halted */ +#define DBG_CTL2_TIMER10_HOLD BIT(18) /*!< hold TIMER10 counter when core is halted */ + +/* constants definitions */ +#define DBG_LOW_POWER_SLEEP DBG_CTL0_SLP_HOLD /*!< keep debugger connection during sleep mode */ +#define DBG_LOW_POWER_DEEPSLEEP DBG_CTL0_DSLP_HOLD /*!< keep debugger connection during deepsleep mode */ +#define DBG_LOW_POWER_STANDBY DBG_CTL0_STB_HOLD /*!< keep debugger connection during standby mode */ + +typedef enum +{ + DBG_TIMER1_HOLD = BIT(0), /*!< hold TIMER1 counter when core is halted */ + DBG_TIMER2_HOLD = BIT(1), /*!< hold TIMER2 counter when core is halted */ + DBG_TIMER3_HOLD = BIT(2), /*!< hold TIMER3 counter when core is halted */ + DBG_TIMER4_HOLD = BIT(3), /*!< hold TIMER4 counter when core is halted */ + DBG_TIMER5_HOLD = BIT(4), /*!< hold TIMER5 counter when core is halted */ + DBG_TIMER6_HOLD = BIT(5), /*!< hold TIMER6 counter when core is halted */ + DBG_TIMER11_HOLD = BIT(6), /*!< hold TIMER11 counter when core is halted */ + DBG_TIMER12_HOLD = BIT(7), /*!< hold TIMER12 counter when core is halted */ + DBG_TIMER13_HOLD = BIT(8), /*!< hold TIMER13 counter when core is halted */ + DBG_RTC_HOLD = BIT(10), /*!< hold RTC calendar and wakeup counter when core is halted */ + DBG_WWDGT_HOLD = BIT(11), /*!< debug WWDGT kept when core is halted */ + DBG_FWDGT_HOLD = BIT(12), /*!< debug FWDGT kept when core is halted */ + DBG_I2C0_HOLD = BIT(21), /*!< hold I2C0 smbus when core is halted */ + DBG_I2C1_HOLD = BIT(22), /*!< hold I2C1 smbus when core is halted */ + DBG_I2C2_HOLD = BIT(23), /*!< hold I2C2 smbus when core is halted */ + DBG_CAN0_HOLD = BIT(25), /*!< debug CAN0 kept when core is halted */ + DBG_CAN1_HOLD = BIT(26), /*!< debug CAN1 kept when core is halted */ + DBG_TIMER0_HOLD = (BIT(0) | BIT(30)), /*!< hold TIMER0 counter when core is halted */ + DBG_TIMER7_HOLD = (BIT(1) | BIT(30)), /*!< hold TIMER7 counter when core is halted */ + DBG_TIMER8_HOLD = (BIT(16) | BIT(30)), /*!< hold TIMER8 counter when core is halted */ + DBG_TIMER9_HOLD = (BIT(17) | BIT(30)), /*!< hold TIMER9 counter when core is halted */ + DBG_TIMER10_HOLD = (BIT(18) | BIT(30)), /*!< hold TIMER10 counter when core is halted */ +}dbg_periph_enum; + +#define CTL0_TRACE_MODE(regval) (BITS(6,7)&((uint32_t)(regval)<<6)) +#define TRACE_MODE_ASYNC CTL0_TRACE_MODE(0) /*!< trace pin used for async mode */ +#define TRACE_MODE_SYNC_DATASIZE_1 CTL0_TRACE_MODE(1) /*!< trace pin used for sync mode and data size is 1 */ +#define TRACE_MODE_SYNC_DATASIZE_2 CTL0_TRACE_MODE(2) /*!< trace pin used for sync mode and data size is 2 */ +#define TRACE_MODE_SYNC_DATASIZE_4 CTL0_TRACE_MODE(3) /*!< trace pin used for sync mode and data size is 4 */ + +/* function declarations */ +/* read DBG_ID code register */ +uint32_t dbg_id_get(void); + +/* enable low power behavior when the MCU is in debug mode */ +void dbg_low_power_enable(uint32_t dbg_low_power); +/* disable low power behavior when the MCU is in debug mode */ +void dbg_low_power_disable(uint32_t dbg_low_power); + +/* enable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_enable(dbg_periph_enum dbg_periph); +/* disable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_disable(dbg_periph_enum dbg_periph); + +/* enable trace pin assignment */ +void dbg_trace_pin_enable(void); +/* disable trace pin assignment */ +void dbg_trace_pin_disable(void); +/* set trace pin mode */ +void dbg_trace_pin_mode_set(uint32_t trace_mode); + +#endif /* GD32F4XX_DBG_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h new file mode 100644 index 0000000000..7c9b445138 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h @@ -0,0 +1,200 @@ +/*! + \file gd32f4xx_dci.h + \brief definitions for the DCI +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_DCI_H +#define GD32F4XX_DCI_H + +#include "gd32f4xx.h" + +/* DCI definitions */ +#define DCI DCI_BASE + +/* registers definitions */ +#define DCI_CTL REG32(DCI + 0x00U) /*!< DCI control register */ +#define DCI_STAT0 REG32(DCI + 0x04U) /*!< DCI status register 0 */ +#define DCI_STAT1 REG32(DCI + 0x08U) /*!< DCI status register 1 */ +#define DCI_INTEN REG32(DCI + 0x0CU) /*!< DCI interrupt enable register */ +#define DCI_INTF REG32(DCI + 0x10U) /*!< DCI interrupt flag register */ +#define DCI_INTC REG32(DCI + 0x14U) /*!< DCI interrupt clear register */ +#define DCI_SC REG32(DCI + 0x18U) /*!< DCI synchronization codes register */ +#define DCI_SCUMSK REG32(DCI + 0x1CU) /*!< DCI synchronization codes unmask register */ +#define DCI_CWSPOS REG32(DCI + 0x20U) /*!< DCI cropping window start position register */ +#define DCI_CWSZ REG32(DCI + 0x24U) /*!< DCI cropping window size register */ +#define DCI_DATA REG32(DCI + 0x28U) /*!< DCI data register */ + +/* bits definitions */ +/* DCI_CTL */ +#define DCI_CTL_CAP BIT(0) /*!< capture enable */ +#define DCI_CTL_SNAP BIT(1) /*!< snapshot mode */ +#define DCI_CTL_WDEN BIT(2) /*!< window enable */ +#define DCI_CTL_JM BIT(3) /*!< jpeg mode */ +#define DCI_CTL_ESM BIT(4) /*!< embedded synchronous mode */ +#define DCI_CTL_CKS BIT(5) /*!< clock polarity selection */ +#define DCI_CTL_HPS BIT(6) /*!< horizontal polarity selection */ +#define DCI_CTL_VPS BIT(7) /*!< vertical polarity selection */ +#define DCI_CTL_FR BITS(8,9) /*!< frame rate */ +#define DCI_CTL_DCIF BITS(10,11) /*!< digital camera interface format */ +#define DCI_CTL_DCIEN BIT(14) /*!< dci enable */ + +/* DCI_STAT0 */ +#define DCI_STAT0_HS BIT(0) /*!< HS line status */ +#define DCI_STAT0_VS BIT(1) /*!< VS line status */ +#define DCI_STAT0_FV BIT(2) /*!< FIFO valid */ + +/* DCI_STAT1 */ +#define DCI_STAT1_EFF BIT(0) /*!< end of frame flag */ +#define DCI_STAT1_OVRF BIT(1) /*!< FIFO overrun flag */ +#define DCI_STAT1_ESEF BIT(2) /*!< embedded synchronous error flag */ +#define DCI_STAT1_VSF BIT(3) /*!< vsync flag */ +#define DCI_STAT1_ELF BIT(4) /*!< end of line flag */ + +/* DCI_INTEN */ +#define DCI_INTEN_EFIE BIT(0) /*!< end of frame interrupt enable */ +#define DCI_INTEN_OVRIE BIT(1) /*!< FIFO overrun interrupt enable */ +#define DCI_INTEN_ESEIE BIT(2) /*!< embedded synchronous error interrupt enable */ +#define DCI_INTEN_VSIE BIT(3) /*!< vsync interrupt enable */ +#define DCI_INTEN_ELIE BIT(4) /*!< end of line interrupt enable */ + +/* DCI_INTF */ +#define DCI_INTF_EFIF BIT(0) /*!< end of frame interrupt flag */ +#define DCI_INTF_OVRIF BIT(1) /*!< FIFO overrun interrupt flag */ +#define DCI_INTF_ESEIF BIT(2) /*!< embedded synchronous error interrupt flag */ +#define DCI_INTF_VSIF BIT(3) /*!< vsync interrupt flag */ +#define DCI_INTF_ELIF BIT(4) /*!< end of line interrupt flag */ + +/* DCI_INTC */ +#define DCI_INTC_EFFC BIT(0) /*!< clear end of frame flag */ +#define DCI_INTC_OVRFC BIT(1) /*!< clear FIFO overrun flag */ +#define DCI_INTC_ESEFC BIT(2) /*!< clear embedded synchronous error flag */ +#define DCI_INTC_VSFC BIT(3) /*!< vsync flag clear */ +#define DCI_INTC_ELFC BIT(4) /*!< end of line flag clear */ + +/* DCI_SC */ +#define DCI_SC_FS BITS(0,7) /*!< frame start code in embedded synchronous mode */ +#define DCI_SC_LS BITS(8,15) /*!< line start code in embedded synchronous mode */ +#define DCI_SC_LE BITS(16,23) /*!< line end code in embedded synchronous mode */ +#define DCI_SC_FE BITS(24,31) /*!< frame end code in embedded synchronous mode */ + +/* DCI_SCUNMSK */ +#define DCI_SCUMSK_FSM BITS(0,7) /*!< frame start code unmask bits in embedded synchronous mode */ +#define DCI_SCUMSK_LSM BITS(8,15) /*!< line start code unmask bits in embedded synchronous mode */ +#define DCI_SCUMSK_LEM BITS(16,23) /*!< line end code unmask bits in embedded synchronous mode */ +#define DCI_SCUMSK_FEM BITS(24,31) /*!< frame end code unmask bits in embedded synchronous mode */ + +/* DCI_CWSPOS */ +#define DCI_CWSPOS_WHSP BITS(0,13) /*!< window horizontal start position */ +#define DCI_CWSPOS_WVSP BITS(16,28) /*!< window vertical start position */ + +/* DCI_CWSZ */ +#define DCI_CWSZ_WHSZ BITS(0,13) /*!< window horizontal size */ +#define DCI_CWSZ_WVSZ BITS(16,29) /*!< window vertical size */ + +/* constants definitions */ +/* DCI parameter struct definitions */ +typedef struct +{ + uint32_t capture_mode; /*!< DCI capture mode: continuous or snapshot */ + uint32_t clock_polarity; /*!< clock polarity selection */ + uint32_t hsync_polarity; /*!< horizontal polarity selection */ + uint32_t vsync_polarity; /*!< vertical polarity selection */ + uint32_t frame_rate; /*!< frame capture rate */ + uint32_t interface_format; /*!< digital camera interface format */ +}dci_parameter_struct; + +#define DCI_CAPTURE_MODE_CONTINUOUS ((uint32_t)0x00000000U) /*!< continuous capture mode */ +#define DCI_CAPTURE_MODE_SNAPSHOT DCI_CTL_SNAP /*!< snapshot capture mode */ + +#define DCI_CK_POLARITY_FALLING ((uint32_t)0x00000000U) /*!< capture at falling edge */ +#define DCI_CK_POLARITY_RISING DCI_CTL_CKS /*!< capture at rising edge */ + +#define DCI_HSYNC_POLARITY_LOW ((uint32_t)0x00000000U) /*!< low level during blanking period */ +#define DCI_HSYNC_POLARITY_HIGH DCI_CTL_HPS /*!< high level during blanking period */ + +#define DCI_VSYNC_POLARITY_LOW ((uint32_t)0x00000000U) /*!< low level during blanking period */ +#define DCI_VSYNC_POLARITY_HIGH DCI_CTL_VPS /*!< high level during blanking period*/ + +#define CTL_FR(regval) (BITS(8,9)&((uint32_t)(regval) << 8U)) +#define DCI_FRAME_RATE_ALL CTL_FR(0) /*!< capture all frames */ +#define DCI_FRAME_RATE_1_2 CTL_FR(1) /*!< capture one in 2 frames */ +#define DCI_FRAME_RATE_1_4 CTL_FR(2) /*!< capture one in 4 frames */ + +#define CTL_DCIF(regval) (BITS(10,11)&((uint32_t)(regval) << 10U)) +#define DCI_INTERFACE_FORMAT_8BITS CTL_DCIF(0) /*!< 8-bit data on every pixel clock */ +#define DCI_INTERFACE_FORMAT_10BITS CTL_DCIF(1) /*!< 10-bit data on every pixel clock */ +#define DCI_INTERFACE_FORMAT_12BITS CTL_DCIF(2) /*!< 12-bit data on every pixel clock */ +#define DCI_INTERFACE_FORMAT_14BITS CTL_DCIF(3) /*!< 14-bit data on every pixel clock */ + +/* DCI interrupt constants definitions */ +#define DCI_INT_EF ((uint32_t)0x00000001U) /*!< end of frame interrupt */ +#define DCI_INT_OVR ((uint32_t)0x00000002U) /*!< FIFO overrun interrupt */ +#define DCI_INT_ESE ((uint32_t)0x00000004U) /*!< embedded synchronous error interrupt */ +#define DCI_INT_VS ((uint32_t)0x00000008U) /*!< vsync interrupt */ +#define DCI_INT_EL ((uint32_t)0x00000010U) /*!< end of line interrupt */ + +/* DCI flag definitions */ +#define DCI_FLAG_HS ((uint8_t)0x01U) /*!< HS line status */ +#define DCI_FLAG_VS ((uint8_t)0x02U) /*!< VS line status */ +#define DCI_FLAG_FV ((uint8_t)0x03U) /*!< FIFO valid */ +#define DCI_FLAG_EFF ((uint8_t)0x04U) /*!< end of frame flag */ +#define DCI_FLAG_OVRF ((uint8_t)0x05U) /*!< FIFO overrun flag */ +#define DCI_FLAG_ESEF ((uint8_t)0x06U) /*!< embedded synchronous error flag */ +#define DCI_FLAG_VSF ((uint8_t)0x07U) /*!< vsync flag */ +#define DCI_FLAG_ELF ((uint8_t)0x08U) /*!< end of line flag */ + +/* function declarations */ +/* DCI deinit */ +void dci_deinit(void); +/* initialize DCI registers */ +void dci_init(dci_parameter_struct* dci_struct); + +/* enable DCI function */ +void dci_enable(void); +/* disble DCI function */ +void dci_disable(void); +/* enable DCI capture */ +void dci_capture_enable(void); +/* disble DCI capture */ +void dci_capture_disable(void); +/* enable DCI jpeg mode */ +void dci_jpeg_enable(void); +/* disble DCI jpeg mode */ +void dci_jpeg_disable(void); + +/* enable cropping window function */ +void dci_crop_window_enable(void); +/* disble cropping window function */ +void dci_crop_window_disable(void); +/* config DCI cropping window */ +void dci_crop_window_config(uint16_t start_x, uint16_t start_y, uint16_t size_width, uint16_t size_height); + +/* enable sync codes function */ +void dci_sync_codes_enable(void); +/* disble sync codes function */ +void dci_sync_codes_disable(void); +/* config sync codes */ +void dci_sync_codes_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end); +/* config sync codes unmask */ +void dci_sync_codes_unmask_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end); + +/* read DCI data register */ +uint32_t dci_data_read(void); + +/* enable specified DCI interrupt */ +void dci_interrupt_enable(uint32_t interrupt); +/* disble specified DCI interrupt */ +void dci_interrupt_disable(uint32_t interrupt); +/* clear specified interrupt */ +void dci_interrupt_clear(uint32_t interrupt); +/* get specified flag */ +FlagStatus dci_flag_get(uint32_t flag); +/* get specified interrupt flag */ +FlagStatus dci_interrupt_flag_get(uint32_t interrupt); +#endif /* GD32F4XX_DCI_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h new file mode 100644 index 0000000000..be59a229f6 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h @@ -0,0 +1,380 @@ +/*! + \file gd32f4xx_dma.h + \brief definitions for the DMA +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_DMA_H +#define GD32F4XX_DMA_H + +#include "gd32f4xx.h" + +/* DMA definitions */ +#define DMA0 (DMA_BASE) /*!< DMA0 base address */ +#define DMA1 (DMA_BASE + 0x0400U) /*!< DMA1 base address */ + +/* registers definitions */ +#define DMA_INTF0(dmax) REG32((dmax) + 0x00U) /*!< DMA interrupt flag register 0 */ +#define DMA_INTF1(dmax) REG32((dmax) + 0x04U) /*!< DMA interrupt flag register 1 */ +#define DMA_INTC0(dmax) REG32((dmax) + 0x08U) /*!< DMA interrupt flag clear register 0 */ +#define DMA_INTC1(dmax) REG32((dmax) + 0x0CU) /*!< DMA interrupt flag clear register 1 */ + +#define DMA_CH0CTL(dmax) REG32((dmax) + 0x10U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT(dmax) REG32((dmax) + 0x14U) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR(dmax) REG32((dmax) + 0x18U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0M0ADDR(dmax) REG32((dmax) + 0x1CU) /*!< DMA channel 0 memory 0 base address register */ +#define DMA_CH0M1ADDR(dmax) REG32((dmax) + 0x20U) /*!< DMA channel 0 memory 1 base address register */ +#define DMA_CH0FCTL(dmax) REG32((dmax) + 0x24U) /*!< DMA channel 0 FIFO control register */ + +#define DMA_CH1CTL(dmax) REG32((dmax) + 0x28U) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT(dmax) REG32((dmax) + 0x2CU) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR(dmax) REG32((dmax) + 0x30U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1M0ADDR(dmax) REG32((dmax) + 0x34U) /*!< DMA channel 1 memory 0 base address register */ +#define DMA_CH1M1ADDR(dmax) REG32((dmax) + 0x38U) /*!< DMA channel 1 memory 1 base address register */ +#define DMA_CH1FCTL(dmax) REG32((dmax) + 0x3CU) /*!< DMA channel 1 FIFO control register */ + +#define DMA_CH2CTL(dmax) REG32((dmax) + 0x40U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT(dmax) REG32((dmax) + 0x44U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR(dmax) REG32((dmax) + 0x48U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2M0ADDR(dmax) REG32((dmax) + 0x4CU) /*!< DMA channel 2 memory 0 base address register */ +#define DMA_CH2M1ADDR(dmax) REG32((dmax) + 0x50U) /*!< DMA channel 2 memory 1 base address register */ +#define DMA_CH2FCTL(dmax) REG32((dmax) + 0x54U) /*!< DMA channel 2 FIFO control register */ + +#define DMA_CH3CTL(dmax) REG32((dmax) + 0x58U) /*!< DMA channel 3 control register */ +#define DMA_CH3CNT(dmax) REG32((dmax) + 0x5CU) /*!< DMA channel 3 counter register */ +#define DMA_CH3PADDR(dmax) REG32((dmax) + 0x60U) /*!< DMA channel 3 peripheral base address register */ +#define DMA_CH3M0ADDR(dmax) REG32((dmax) + 0x64U) /*!< DMA channel 3 memory 0 base address register */ +#define DMA_CH3M1ADDR(dmax) REG32((dmax) + 0x68U) /*!< DMA channel 3 memory 1 base address register */ +#define DMA_CH3FCTL(dmax) REG32((dmax) + 0x6CU) /*!< DMA channel 3 FIFO control register */ + +#define DMA_CH4CTL(dmax) REG32((dmax) + 0x70U) /*!< DMA channel 4 control register */ +#define DMA_CH4CNT(dmax) REG32((dmax) + 0x74U) /*!< DMA channel 4 counter register */ +#define DMA_CH4PADDR(dmax) REG32((dmax) + 0x78U) /*!< DMA channel 4 peripheral base address register */ +#define DMA_CH4M0ADDR(dmax) REG32((dmax) + 0x7CU) /*!< DMA channel 4 memory 0 base address register */ +#define DMA_CH4M1ADDR(dmax) REG32((dmax) + 0x80U) /*!< DMA channel 4 memory 1 base address register */ +#define DMA_CH4FCTL(dmax) REG32((dmax) + 0x84U) /*!< DMA channel 4 FIFO control register */ + +#define DMA_CH5CTL(dmax) REG32((dmax) + 0x88U) /*!< DMA channel 5 control register */ +#define DMA_CH5CNT(dmax) REG32((dmax) + 0x8CU) /*!< DMA channel 5 counter register */ +#define DMA_CH5PADDR(dmax) REG32((dmax) + 0x90U) /*!< DMA channel 5 peripheral base address register */ +#define DMA_CH5M0ADDR(dmax) REG32((dmax) + 0x94U) /*!< DMA channel 5 memory 0 base address register */ +#define DMA_CH5M1ADDR(dmax) REG32((dmax) + 0x98U) /*!< DMA channel 5 memory 1 base address register */ +#define DMA_CH5FCTL(dmax) REG32((dmax) + 0x9CU) /*!< DMA channel 5 FIFO control register */ + +#define DMA_CH6CTL(dmax) REG32((dmax) + 0xA0U) /*!< DMA channel 6 control register */ +#define DMA_CH6CNT(dmax) REG32((dmax) + 0xA4U) /*!< DMA channel 6 counter register */ +#define DMA_CH6PADDR(dmax) REG32((dmax) + 0xA8U) /*!< DMA channel 6 peripheral base address register */ +#define DMA_CH6M0ADDR(dmax) REG32((dmax) + 0xACU) /*!< DMA channel 6 memory 0 base address register */ +#define DMA_CH6M1ADDR(dmax) REG32((dmax) + 0xB0U) /*!< DMA channel 6 memory 1 base address register */ +#define DMA_CH6FCTL(dmax) REG32((dmax) + 0xB4U) /*!< DMA channel 6 FIFO control register */ + +#define DMA_CH7CTL(dmax) REG32((dmax) + 0xB8U) /*!< DMA channel 7 control register */ +#define DMA_CH7CNT(dmax) REG32((dmax) + 0xBCU) /*!< DMA channel 7 counter register */ +#define DMA_CH7PADDR(dmax) REG32((dmax) + 0xC0U) /*!< DMA channel 7 peripheral base address register */ +#define DMA_CH7M0ADDR(dmax) REG32((dmax) + 0xC4U) /*!< DMA channel 7 memory 0 base address register */ +#define DMA_CH7M1ADDR(dmax) REG32((dmax) + 0xC8U) /*!< DMA channel 7 memory 1 base address register */ +#define DMA_CH7FCTL(dmax) REG32((dmax) + 0xCCU) /*!< DMA channel 7 FIFO control register */ + +/* bits definitions */ +/* DMA_INTF */ +#define DMA_INTF_FEEIF BIT(0) /*!< FIFO error and exception flag */ +#define DMA_INTF_SDEIF BIT(2) /*!< single data mode exception flag */ +#define DMA_INTF_TAEIF BIT(3) /*!< transfer access error flag */ +#define DMA_INTF_HTFIF BIT(4) /*!< half transfer finish flag */ +#define DMA_INTF_FTFIF BIT(5) /*!< full transger finish flag */ + +/* DMA_INTC */ +#define DMA_INTC_FEEIFC BIT(0) /*!< clear FIFO error and exception flag */ +#define DMA_INTC_SDEIFC BIT(2) /*!< clear single data mode exception flag */ +#define DMA_INTC_TAEIFC BIT(3) /*!< clear single data mode exception flag */ +#define DMA_INTC_HTFIFC BIT(4) /*!< clear half transfer finish flag */ +#define DMA_INTC_FTFIFC BIT(5) /*!< clear full transger finish flag */ + +/* DMA_CHxCTL,x=0..7 */ +#define DMA_CHXCTL_CHEN BIT(0) /*!< channel x enable */ +#define DMA_CHXCTL_SDEIE BIT(1) /*!< enable bit for channel x single data mode exception interrupt */ +#define DMA_CHXCTL_TAEIE BIT(2) /*!< enable bit for channel x tranfer access error interrupt */ +#define DMA_CHXCTL_HTFIE BIT(3) /*!< enable bit for channel x half transfer finish interrupt */ +#define DMA_CHXCTL_FTFIE BIT(4) /*!< enable bit for channel x full transfer finish interrupt */ +#define DMA_CHXCTL_TFCS BIT(5) /*!< transfer flow controller select */ +#define DMA_CHXCTL_TM BITS(6,7) /*!< transfer mode */ +#define DMA_CHXCTL_CMEN BIT(8) /*!< circulation mode */ +#define DMA_CHXCTL_PNAGA BIT(9) /*!< next address generation algorithm of peripheral */ +#define DMA_CHXCTL_MNAGA BIT(10) /*!< next address generation algorithm of memory */ +#define DMA_CHXCTL_PWIDTH BITS(11,12) /*!< transfer width of peipheral */ +#define DMA_CHXCTL_MWIDTH BITS(13,14) /*!< transfer width of memory */ +#define DMA_CHXCTL_PAIF BIT(15) /*!< peripheral address increment fixed */ +#define DMA_CHXCTL_PRIO BITS(16,17) /*!< priority level */ +#define DMA_CHXCTL_SBMEN BIT(18) /*!< switch-buffer mode enable */ +#define DMA_CHXCTL_MBS BIT(19) /*!< memory buffer select */ +#define DMA_CHXCTL_PBURST BITS(21,22) /*!< transfer burst type of peripheral */ +#define DMA_CHXCTL_MBURST BITS(23,24) /*!< transfer burst type of memory */ +#define DMA_CHXCTL_PERIEN BITS(25,27) /*!< peripheral enable */ + +/* DMA_CHxCNT,x=0..7 */ +#define DMA_CHXCNT_CNT BITS(0,15) /*!< transfer counter */ + +/* DMA_CHxPADDR,x=0..7 */ +#define DMA_CHXPADDR_PADDR BITS(0,31) /*!< peripheral base address */ + +/* DMA_CHxM0ADDR,x=0..7 */ +#define DMA_CHXM0ADDR_PADDR BITS(0,31) /*!< memory 0 base address */ + +/* DMA_CHxM1ADDR,x=0..7 */ +#define DMA_CHXM1ADDR_PADDR BITS(0,31) /*!< memory 1 base address */ + +/* DMA_CHxFCTL,x=0..7 */ +#define DMA_CHXFCTL_FCCV BITS(0,1) /*!< FIFO counter critical value */ +#define DMA_CHXFCTL_MDMEN BIT(2) /*!< multi-data mode enable */ +#define DMA_CHXFCTL_FCNT BITS(3,5) /*!< FIFO counter */ +#define DMA_CHXFCTL_FEEIE BIT(7) /*!< FIFO exception interrupt enable */ + +/* constants definitions */ +/* DMA channel select */ +typedef enum +{ + DMA_CH0 = 0, /*!< DMA Channel 0 */ + DMA_CH1, /*!< DMA Channel 1 */ + DMA_CH2, /*!< DMA Channel 2 */ + DMA_CH3, /*!< DMA Channel 3 */ + DMA_CH4, /*!< DMA Channel 4 */ + DMA_CH5, /*!< DMA Channel 5 */ + DMA_CH6, /*!< DMA Channel 6 */ + DMA_CH7 /*!< DMA Channel 7 */ +} dma_channel_enum; + +/* DMA peripheral select */ +typedef enum +{ + DMA_SUBPERI0 = 0, /*!< DMA Peripheral 0 */ + DMA_SUBPERI1, /*!< DMA Peripheral 1 */ + DMA_SUBPERI2, /*!< DMA Peripheral 2 */ + DMA_SUBPERI3, /*!< DMA Peripheral 3 */ + DMA_SUBPERI4, /*!< DMA Peripheral 4 */ + DMA_SUBPERI5, /*!< DMA Peripheral 5 */ + DMA_SUBPERI6, /*!< DMA Peripheral 6 */ + DMA_SUBPERI7 /*!< DMA Peripheral 7 */ +} dma_subperipheral_enum; + +/* DMA multidata mode initialize struct */ +typedef struct +{ + uint32_t periph_addr; /*!< peripheral base address */ + uint32_t periph_width; /*!< transfer data size of peripheral */ + uint32_t periph_inc; /*!< peripheral increasing mode */ + + uint32_t memory0_addr; /*!< memory 0 base address */ + uint32_t memory_width; /*!< transfer data size of memory */ + uint32_t memory_inc; /*!< memory increasing mode */ + + uint32_t memory_burst_width; /*!< multi data mode enable */ + uint32_t periph_burst_width; /*!< multi data mode enable */ + uint32_t critical_value; /*!< FIFO critical */ + + uint32_t circular_mode; + uint32_t direction; /*!< channel data transfer direction */ + uint32_t number; /*!< channel transfer number */ + uint32_t priority; /*!< channel priority level */ +}dma_multi_data_parameter_struct; + +/* DMA singledata mode initialize struct */ +typedef struct +{ + uint32_t periph_addr; /*!< peripheral base address */ + uint32_t periph_inc; /*!< peripheral increasing mode */ + + uint32_t memory0_addr; /*!< memory 0 base address */ + uint32_t memory_inc; /*!< memory increasing mode */ + + uint32_t periph_memory_width; /*!< transfer data size of peripheral */ + + uint32_t circular_mode; /*!< DMA circular mode */ + uint32_t direction; /*!< channel data transfer direction */ + uint32_t number; /*!< channel transfer number */ + uint32_t priority; /*!< channel priority level */ +} dma_single_data_parameter_struct; + +#define DMA_FLAG_ADD(flag,channel) ((uint32_t)((flag)<<((((uint32_t)(channel)*6U))+((uint32_t)(((uint32_t)(channel)) >> 1U)&0x01U)*4U))) /*!< DMA channel flag shift */ + +/* DMA_register address */ +#define DMA_CHCTL(dma,channel) REG32(((dma) + 0x10U) + 0x18U*(channel)) /*!< the address of DMA channel CHXCTL register */ +#define DMA_CHCNT(dma,channel) REG32(((dma) + 0x14U) + 0x18U*(channel)) /*!< the address of DMA channel CHXCNT register */ +#define DMA_CHPADDR(dma,channel) REG32(((dma) + 0x18U) + 0x18U*(channel)) /*!< the address of DMA channel CHXPADDR register */ +#define DMA_CHM0ADDR(dma,channel) REG32(((dma) + 0x1CU) + 0x18U*(channel)) /*!< the address of DMA channel CHXM0ADDR register */ +#define DMA_CHM1ADDR(dma,channel) REG32(((dma) + 0x20U) + 0x18U*(channel)) /*!< the address of DMA channel CHXM1ADDR register */ +#define DMA_CHFCTL(dma,channel) REG32(((dma) + 0x24U) + 0x18U*(channel)) /*!< the address of DMA channel CHXMADDR register */ + +/* peripheral select */ +#define CHCTL_PERIEN(regval) (BITS(25,27) & ((uint32_t)(regval) << 25)) +#define DMA_PERIPH_0_SELECT CHCTL_PERIEN(0) /*!< peripheral 0 select */ +#define DMA_PERIPH_1_SELECT CHCTL_PERIEN(1) /*!< peripheral 1 select */ +#define DMA_PERIPH_2_SELECT CHCTL_PERIEN(2) /*!< peripheral 2 select */ +#define DMA_PERIPH_3_SELECT CHCTL_PERIEN(3) /*!< peripheral 3 select */ +#define DMA_PERIPH_4_SELECT CHCTL_PERIEN(4) /*!< peripheral 4 select */ +#define DMA_PERIPH_5_SELECT CHCTL_PERIEN(5) /*!< peripheral 5 select */ +#define DMA_PERIPH_6_SELECT CHCTL_PERIEN(6) /*!< peripheral 6 select */ +#define DMA_PERIPH_7_SELECT CHCTL_PERIEN(7) /*!< peripheral 7 select */ + +/* burst type of memory */ +#define CHCTL_MBURST(regval) (BITS(23,24) & ((uint32_t)(regval) << 23)) +#define DMA_MEMORY_BURST_SINGLE CHCTL_MBURST(0) /*!< single burst */ +#define DMA_MEMORY_BURST_4_BEAT CHCTL_MBURST(1) /*!< 4-beat burst */ +#define DMA_MEMORY_BURST_8_BEAT CHCTL_MBURST(2) /*!< 8-beat burst */ +#define DMA_MEMORY_BURST_16_BEAT CHCTL_MBURST(3) /*!< 16-beat burst */ + +/* burst type of peripheral */ +#define CHCTL_PBURST(regval) (BITS(21,22) & ((uint32_t)(regval) << 21)) +#define DMA_PERIPH_BURST_SINGLE CHCTL_PBURST(0) /*!< single burst */ +#define DMA_PERIPH_BURST_4_BEAT CHCTL_PBURST(1) /*!< 4-beat burst */ +#define DMA_PERIPH_BURST_8_BEAT CHCTL_PBURST(2) /*!< 8-beat burst */ +#define DMA_PERIPH_BURST_16_BEAT CHCTL_PBURST(3) /*!< 16-beat burst */ + +/* channel priority level */ +#define CHCTL_PRIO(regval) (BITS(16,17) & ((uint32_t)(regval) << 16)) +#define DMA_PRIORITY_LOW CHCTL_PRIO(0) /*!< low priority */ +#define DMA_PRIORITY_MEDIUM CHCTL_PRIO(1) /*!< medium priority */ +#define DMA_PRIORITY_HIGH CHCTL_PRIO(2) /*!< high priority */ +#define DMA_PRIORITY_ULTRA_HIGH CHCTL_PRIO(3) /*!< ultra high priority */ + +/* transfer data width of memory */ +#define CHCTL_MWIDTH(regval) (BITS(13,14) & ((uint32_t)(regval) << 13)) +#define DMA_MEMORY_WIDTH_8BIT CHCTL_MWIDTH(0) /*!< transfer data width of memory is 8-bit */ +#define DMA_MEMORY_WIDTH_16BIT CHCTL_MWIDTH(1) /*!< transfer data width of memory is 16-bit */ +#define DMA_MEMORY_WIDTH_32BIT CHCTL_MWIDTH(2) /*!< transfer data width of memory is 32-bit */ + +/* transfer data width of peripheral */ +#define CHCTL_PWIDTH(regval) (BITS(11,12) & ((uint32_t)(regval) << 11)) +#define DMA_PERIPH_WIDTH_8BIT CHCTL_PWIDTH(0) /*!< transfer data width of peripheral is 8-bit */ +#define DMA_PERIPH_WIDTH_16BIT CHCTL_PWIDTH(1) /*!< transfer data width of peripheral is 16-bit */ +#define DMA_PERIPH_WIDTH_32BIT CHCTL_PWIDTH(2) /*!< transfer data width of peripheral is 32-bit */ + +/* channel transfer mode */ +#define CHCTL_TM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6)) +#define DMA_PERIPH_TO_MEMORY CHCTL_TM(0) /*!< read from peripheral and write to memory */ +#define DMA_MEMORY_TO_PERIPH CHCTL_TM(1) /*!< read from memory and write to peripheral */ +#define DMA_MEMORY_TO_MEMORY CHCTL_TM(2) /*!< read from memory and write to memory */ + +/* FIFO counter critical value */ +#define CHFCTL_FCCV(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define DMA_FIFO_1_WORD CHFCTL_FCCV(0) /*!< critical value 1 word */ +#define DMA_FIFO_2_WORD CHFCTL_FCCV(1) /*!< critical value 2 word */ +#define DMA_FIFO_3_WORD CHFCTL_FCCV(2) /*!< critical value 3 word */ +#define DMA_FIFO_4_WORD CHFCTL_FCCV(3) /*!< critical value 4 word */ + +/* memory select */ +#define DMA_MEMORY_0 ((uint32_t)0x00000000U) /*!< select memory 0 */ +#define DMA_MEMORY_1 ((uint32_t)0x00000001U) /*!< select memory 1 */ + +/* DMA circular mode */ +#define DMA_CIRCULAR_MODE_ENABLE ((uint32_t)0x00000000U) /*!< circular mode enable */ +#define DMA_CIRCULAR_MODE_DISABLE ((uint32_t)0x00000001U) /*!< circular mode disable */ + +/* DMA flow controller select */ +#define DMA_FLOW_CONTROLLER_DMA ((uint32_t)0x00000000U) /*!< DMA is the flow controler */ +#define DMA_FLOW_CONTROLLER_PERI ((uint32_t)0x00000001U) /*!< peripheral is the flow controler */ + +/* peripheral increasing mode */ +#define DMA_PERIPH_INCREASE_ENABLE ((uint32_t)0x00000000U) /*!< next address of peripheral is increasing address mode */ +#define DMA_PERIPH_INCREASE_DISABLE ((uint32_t)0x00000001U) /*!< next address of peripheral is fixed address mode */ +#define DMA_PERIPH_INCREASE_FIX ((uint32_t)0x00000002U) /*!< next address of peripheral is increasing fixed */ + +/* memory increasing mode */ +#define DMA_MEMORY_INCREASE_ENABLE ((uint32_t)0x00000000U) /*!< next address of memory is increasing address mode */ +#define DMA_MEMORY_INCREASE_DISABLE ((uint32_t)0x00000001U) /*!< next address of memory is fixed address mode */ + +/* FIFO status */ +#define DMA_FIFO_STATUS_NODATA ((uint32_t)0x00000000U) /*!< the data in the FIFO less than 1 word */ +#define DMA_FIFO_STATUS_1_WORD ((uint32_t)0x00000001U) /*!< the data in the FIFO more than 1 word, less than 2 words */ +#define DMA_FIFO_STATUS_2_WORD ((uint32_t)0x00000002U) /*!< the data in the FIFO more than 2 word, less than 3 words */ +#define DMA_FIFO_STATUS_3_WORD ((uint32_t)0x00000003U) /*!< the data in the FIFO more than 3 word, less than 4 words */ +#define DMA_FIFO_STATUS_EMPTY ((uint32_t)0x00000004U) /*!< the data in the FIFO is empty */ +#define DMA_FIFO_STATUS_FULL ((uint32_t)0x00000005U) /*!< the data in the FIFO is full */ + +/* DMA reset value */ +#define DMA_CHCTL_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCTL register */ +#define DMA_CHCNT_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCNT register */ +#define DMA_CHPADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXPADDR register */ +#define DMA_CHMADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXMADDR register */ +#define DMA_CHINTF_RESET_VALUE ((uint32_t)0x0000003DU) /*!< clear DMA channel CHXINTFS register */ +#define DMA_CHFCTL_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXFCTL register */ + +/* function declarations */ +/* deinitialize DMA a channel registers */ +void dma_deinit(uint32_t dma_periph,dma_channel_enum channelx); +/* DMA single data mode initialize */ +void dma_single_data_mode_init(uint32_t dma_periph,dma_channel_enum channelx,dma_single_data_parameter_struct init_struct); +/* DMA multi data mode initialize */ +void dma_multi_data_mode_init(uint32_t dma_periph,dma_channel_enum channelx,dma_multi_data_parameter_struct init_struct); + +/* set DMA peripheral base address */ +void dma_periph_address_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t address); +/* set DMA Memory base address */ +void dma_memory_address_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t memory_flag,uint32_t address); + +/* set the number of remaining data to be transferred by the DMA */ +void dma_transfer_number_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t number); +/* get the number of remaining data to be transferred by the DMA */ +uint32_t dma_transfer_number_get(uint32_t dma_periph,dma_channel_enum channelx); + +/* configure priority level of DMA channel */ +void dma_priority_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t priority); + +/* configure transfer burst beats of memory */ +void dma_memory_burst_beats_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t mbeat); +/* configure transfer burst beats of peripheral */ +void dma_periph_burst_beats_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t pbeat); +/* configure transfer data size of memory */ +void dma_memory_width_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t msize); +/* configure transfer data size of peripheral */ +void dma_periph_width_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t psize); + +/* configure next address increasement algorithm of memory */ +void dma_memory_address_generation_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t generation_algorithm); +/* configure next address increasement algorithm of peripheral */ +void dma_peripheral_address_generation_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t generation_algorithm); + +/* enable DMA circulation mode */ +void dma_circulation_enable(uint32_t dma_periph,dma_channel_enum channelx); +/* disable DMA circulation mode */ +void dma_circulation_disable(uint32_t dma_periph,dma_channel_enum channelx); +/* enable DMA channel */ +void dma_channel_enable(uint32_t dma_periph,dma_channel_enum channelx); +/* disable DMA channel */ +void dma_channel_disable(uint32_t dma_periph,dma_channel_enum channelx); + +/* configure the direction of data transfer on the channel */ +void dma_transfer_direction_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t direction); + +/* DMA switch buffer mode config */ +void dma_switch_buffer_mode_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t memory1_addr,uint32_t memory_select); +/* DMA using memory get */ +uint32_t dma_using_memory_get(uint32_t dma_periph,dma_channel_enum channelx); + +/* DMA channel peripheral select */ +void dma_channel_subperipheral_select(uint32_t dma_periph,dma_channel_enum channelx,dma_subperipheral_enum sub_periph); +/* DMA flow controller configure */ +void dma_flow_controller_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t controller); +/* DMA flow controller enable */ +void dma_switch_buffer_mode_enable(uint32_t dma_periph,dma_channel_enum channelx,ControlStatus newvalue); +/* DMA FIFO status get */ +uint32_t dma_fifo_status_get(uint32_t dma_periph,dma_channel_enum channelx); + +/* check DMA flag is set or not */ +FlagStatus dma_flag_get(uint32_t dma_periph,dma_channel_enum channelx,uint32_t flag); +/* clear DMA a channel flag */ +void dma_flag_clear(uint32_t dma_periph,dma_channel_enum channelx,uint32_t flag); +/* check DMA flag is set or not */ +FlagStatus dma_interrupt_flag_get(uint32_t dma_periph,dma_channel_enum channelx,uint32_t interrupt); +/* clear DMA a channel flag */ +void dma_interrupt_flag_clear(uint32_t dma_periph,dma_channel_enum channelx,uint32_t interrupt); +/* enable DMA interrupt */ +void dma_interrupt_enable(uint32_t dma_periph,dma_channel_enum channelx,uint32_t source); +/* disable DMA interrupt */ +void dma_interrupt_disable(uint32_t dma_periph,dma_channel_enum channelx,uint32_t source); + +#endif /* GD32F4XX_DMA_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h new file mode 100644 index 0000000000..7a0de03860 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h @@ -0,0 +1,1664 @@ +/*! + \file gd32f4xx_enet.h + \brief definitions for the ENET +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.1, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_ENET_H +#define GD32F4XX_ENET_H + +#include "gd32f4xx.h" +#include + +#define IF_USE_EXTERNPHY_LIB 0 +#if (1 == IF_USE_EXTERNPHY_LIB) +#include "phy.h" +#endif + +#ifndef ENET_RXBUF_NUM +#define ENET_RXBUF_NUM 5U /*!< ethernet Rx DMA descriptor number */ +#endif + +#ifndef ENET_TXBUF_NUM +#define ENET_TXBUF_NUM 5U /*!< ethernet Tx DMA descriptor number */ +#endif + +#ifndef ENET_RXBUF_SIZE +#define ENET_RXBUF_SIZE ENET_MAX_FRAME_SIZE /*!< ethernet receive buffer size */ +#endif + +#ifndef ENET_TXBUF_SIZE +#define ENET_TXBUF_SIZE ENET_MAX_FRAME_SIZE /*!< ethernet transmit buffer size */ +#endif + +//#define SELECT_DESCRIPTORS_ENHANCED_MODE + +//#define USE_DELAY + +#ifndef _PHY_H_ +#define DP83848 0 +#define LAN8700 1 +#define PHY_TYPE DP83848 + +#define PHY_ADDRESS ((uint16_t)1U) /*!< phy address determined by the hardware */ + +/* PHY read write timeouts */ +#define PHY_READ_TO ((uint32_t)0x0004FFFFU) /*!< PHY read timeout */ +#define PHY_WRITE_TO ((uint32_t)0x0004FFFFU) /*!< PHY write timeout */ + +/* PHY delay */ +#define PHY_RESETDELAY ((uint32_t)0x008FFFFFU) /*!< PHY reset delay */ +#define PHY_CONFIGDELAY ((uint32_t)0x00FFFFFFU) /*!< PHY configure delay */ + +/* PHY register address */ +#define PHY_REG_BCR 0U /*!< tranceiver basic control register */ +#define PHY_REG_BSR 1U /*!< tranceiver basic status register */ + +/* PHY basic control register */ +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< enable phy loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< configure speed to 100 Mbit/s and the full-duplex mode */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< configure speed to 100 Mbit/s and the half-duplex mode */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< configure speed to 10 Mbit/s and the full-duplex mode */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< configure speed to 10 Mbit/s and the half-duplex mode */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< enable the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< isolate PHY from MII */ + +/* PHY basic status register */ +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< auto-negotioation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< jabber condition detected */ + +#if(PHY_TYPE == LAN8700) +#define PHY_SR 31U /*!< tranceiver status register */ +#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< configured information of speed: 10Mbit/s */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< configured information of duplex: full-duplex */ +#elif(PHY_TYPE == DP83848) +#define PHY_SR 16U /*!< tranceiver status register */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< configured information of speed: 10Mbit/s */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< configured information of duplex: full-duplex */ +#endif /* PHY_TYPE */ + +#endif /* _PHY_H_ */ + + +/* ENET definitions */ +#define ENET ENET_BASE + +/* registers definitions */ +#define ENET_MAC_CFG REG32((ENET) + 0x00U) /*!< ethernet MAC configuration register */ +#define ENET_MAC_FRMF REG32((ENET) + 0x04U) /*!< ethernet MAC frame filter register */ +#define ENET_MAC_HLH REG32((ENET) + 0x08U) /*!< ethernet MAC hash list high register */ +#define ENET_MAC_HLL REG32((ENET) + 0x0CU) /*!< ethernet MAC hash list low register */ +#define ENET_MAC_PHY_CTL REG32((ENET) + 0x10U) /*!< ethernet MAC PHY control register */ +#define ENET_MAC_PHY_DATA REG32((ENET) + 0x14U) /*!< ethernet MAC MII data register */ +#define ENET_MAC_FCTL REG32((ENET) + 0x18U) /*!< ethernet MAC flow control register */ +#define ENET_MAC_VLT REG32((ENET) + 0x1CU) /*!< ethernet MAC VLAN tag register */ +#define ENET_MAC_RWFF REG32((ENET) + 0x28U) /*!< ethernet MAC remote wakeup frame filter register */ +#define ENET_MAC_WUM REG32((ENET) + 0x2CU) /*!< ethernet MAC wakeup management register */ +#define ENET_MAC_DBG REG32((ENET) + 0x34U) /*!< ethernet MAC debug register */ +#define ENET_MAC_INTF REG32((ENET) + 0x38U) /*!< ethernet MAC interrupt flag register */ +#define ENET_MAC_INTMSK REG32((ENET) + 0x3CU) /*!< ethernet MAC interrupt mask register */ +#define ENET_MAC_ADDR0H REG32((ENET) + 0x40U) /*!< ethernet MAC address 0 high register */ +#define ENET_MAC_ADDR0L REG32((ENET) + 0x44U) /*!< ethernet MAC address 0 low register */ +#define ENET_MAC_ADDR1H REG32((ENET) + 0x48U) /*!< ethernet MAC address 1 high register */ +#define ENET_MAC_ADDR1L REG32((ENET) + 0x4CU) /*!< ethernet MAC address 1 low register */ +#define ENET_MAC_ADDT2H REG32((ENET) + 0x50U) /*!< ethernet MAC address 2 high register */ +#define ENET_MAC_ADDR2L REG32((ENET) + 0x54U) /*!< ethernet MAC address 2 low register */ +#define ENET_MAC_ADDR3H REG32((ENET) + 0x58U) /*!< ethernet MAC address 3 high register */ +#define ENET_MAC_ADDR3L REG32((ENET) + 0x5CU) /*!< ethernet MAC address 3 low register */ +#define ENET_MAC_FCTH REG32((ENET) + 0x1080U) /*!< ethernet MAC flow control threshold register */ + +#define ENET_MSC_CTL REG32((ENET) + 0x100U) /*!< ethernet MSC control register */ +#define ENET_MSC_RINTF REG32((ENET) + 0x104U) /*!< ethernet MSC receive interrupt flag register */ +#define ENET_MSC_TINTF REG32((ENET) + 0x108U) /*!< ethernet MSC transmit interrupt flag register */ +#define ENET_MSC_RINTMSK REG32((ENET) + 0x10CU) /*!< ethernet MSC receive interrupt mask register */ +#define ENET_MSC_TINTMSK REG32((ENET) + 0x110U) /*!< ethernet MSC transmit interrupt mask register */ +#define ENET_MSC_SCCNT REG32((ENET) + 0x14CU) /*!< ethernet MSC transmitted good frames after a single collision counter register */ +#define ENET_MSC_MSCCNT REG32((ENET) + 0x150U) /*!< ethernet MSC transmitted good frames after more than a single collision counter register */ +#define ENET_MSC_TGFCNT REG32((ENET) + 0x168U) /*!< ethernet MSC transmitted good frames counter register */ +#define ENET_MSC_RFCECNT REG32((ENET) + 0x194U) /*!< ethernet MSC received frames with CRC error counter register */ +#define ENET_MSC_RFAECNT REG32((ENET) + 0x198U) /*!< ethernet MSC received frames with alignment error counter register */ +#define ENET_MSC_RGUFCNT REG32((ENET) + 0x1C4U) /*!< ethernet MSC received good unicast frames counter register */ + +#define ENET_PTP_TSCTL REG32((ENET) + 0x700U) /*!< ethernet PTP time stamp control register */ +#define ENET_PTP_SSINC REG32((ENET) + 0x704U) /*!< ethernet PTP subsecond increment register */ +#define ENET_PTP_TSH REG32((ENET) + 0x708U) /*!< ethernet PTP time stamp high register */ +#define ENET_PTP_TSL REG32((ENET) + 0x70CU) /*!< ethernet PTP time stamp low register */ +#define ENET_PTP_TSUH REG32((ENET) + 0x710U) /*!< ethernet PTP time stamp update high register */ +#define ENET_PTP_TSUL REG32((ENET) + 0x714U) /*!< ethernet PTP time stamp update low register */ +#define ENET_PTP_TSADDEND REG32((ENET) + 0x718U) /*!< ethernet PTP time stamp addend register */ +#define ENET_PTP_ETH REG32((ENET) + 0x71CU) /*!< ethernet PTP expected time high register */ +#define ENET_PTP_ETL REG32((ENET) + 0x720U) /*!< ethernet PTP expected time low register */ +#define ENET_PTP_TSF REG32((ENET) + 0x728U) /*!< ethernet PTP time stamp flag register */ +#define ENET_PTP_PPSCTL REG32((ENET) + 0x72CU) /*!< ethernet PTP PPS control register */ + +#define ENET_DMA_BCTL REG32((ENET) + 0x1000U) /*!< ethernet DMA bus control register */ +#define ENET_DMA_TPEN REG32((ENET) + 0x1004U) /*!< ethernet DMA transmit poll enable register */ +#define ENET_DMA_RPEN REG32((ENET) + 0x1008U) /*!< ethernet DMA receive poll enable register */ +#define ENET_DMA_RDTADDR REG32((ENET) + 0x100CU) /*!< ethernet DMA receive descriptor table address register */ +#define ENET_DMA_TDTADDR REG32((ENET) + 0x1010U) /*!< ethernet DMA transmit descriptor table address register */ +#define ENET_DMA_STAT REG32((ENET) + 0x1014U) /*!< ethernet DMA status register */ +#define ENET_DMA_CTL REG32((ENET) + 0x1018U) /*!< ethernet DMA control register */ +#define ENET_DMA_INTEN REG32((ENET) + 0x101CU) /*!< ethernet DMA interrupt enable register */ +#define ENET_DMA_MFBOCNT REG32((ENET) + 0x1020U) /*!< ethernet DMA missed frame and buffer overflow counter register */ +#define ENET_DMA_RSWDC REG32((ENET) + 0x1024U) /*!< ethernet DMA receive state watchdog counter register */ +#define ENET_DMA_CTDADDR REG32((ENET) + 0x1048U) /*!< ethernet DMA current transmit descriptor address register */ +#define ENET_DMA_CRDADDR REG32((ENET) + 0x104CU) /*!< ethernet DMA current receive descriptor address register */ +#define ENET_DMA_CTBADDR REG32((ENET) + 0x1050U) /*!< ethernet DMA current transmit buffer address register */ +#define ENET_DMA_CRBADDR REG32((ENET) + 0x1054U) /*!< ethernet DMA current receive buffer address register */ + +/* bits definitions */ +/* ENET_MAC_CFG */ +#define ENET_MAC_CFG_REN BIT(2) /*!< receiver enable */ +#define ENET_MAC_CFG_TEN BIT(3) /*!< transmitter enable */ +#define ENET_MAC_CFG_DFC BIT(4) /*!< defferal check */ +#define ENET_MAC_CFG_BOL BITS(5,6) /*!< back-off limit */ +#define ENET_MAC_CFG_APCD BIT(7) /*!< automatic pad/CRC drop */ +#define ENET_MAC_CFG_RTD BIT(9) /*!< retry disable */ +#define ENET_MAC_CFG_IPFCO BIT(10) /*!< IP frame checksum offload */ +#define ENET_MAC_CFG_DPM BIT(11) /*!< duplex mode */ +#define ENET_MAC_CFG_LBM BIT(12) /*!< loopback mode */ +#define ENET_MAC_CFG_ROD BIT(13) /*!< receive own disable */ +#define ENET_MAC_CFG_SPD BIT(14) /*!< fast eneternet speed */ +#define ENET_MAC_CFG_CSD BIT(16) /*!< carrier sense disable */ +#define ENET_MAC_CFG_IGBS BITS(17,19) /*!< inter-frame gap bit selection */ +#define ENET_MAC_CFG_JBD BIT(22) /*!< jabber disable */ +#define ENET_MAC_CFG_WDD BIT(23) /*!< watchdog disable */ +#define ENET_MAC_CFG_TFCD BIT(25) /*!< type frame CRC dropping */ + +/* ENET_MAC_FRMF */ +#define ENET_MAC_FRMF_PM BIT(0) /*!< promiscuous mode */ +#define ENET_MAC_FRMF_HUF BIT(1) /*!< hash unicast filter */ +#define ENET_MAC_FRMF_HMF BIT(2) /*!< hash multicast filter */ +#define ENET_MAC_FRMF_DAIFLT BIT(3) /*!< destination address inverse filtering enable */ +#define ENET_MAC_FRMF_MFD BIT(4) /*!< multicast filter disable */ +#define ENET_MAC_FRMF_BFRMD BIT(5) /*!< broadcast frame disable */ +#define ENET_MAC_FRMF_PCFRM BITS(6,7) /*!< pass control frames */ +#define ENET_MAC_FRMF_SAIFLT BIT(8) /*!< source address inverse filtering */ +#define ENET_MAC_FRMF_SAFLT BIT(9) /*!< source address filter */ +#define ENET_MAC_FRMF_HPFLT BIT(10) /*!< hash or perfect filter */ +#define ENET_MAC_FRMF_FAR BIT(31) /*!< frames all receive */ + +/* ENET_MAC_HLH */ +#define ENET_MAC_HLH_HLH BITS(0,31) /*!< hash list high */ + +/* ENET_MAC_HLL */ +#define ENET_MAC_HLL_HLL BITS(0,31) /*!< hash list low */ + +/* ENET_MAC_PHY_CTL */ +#define ENET_MAC_PHY_CTL_PB BIT(0) /*!< PHY busy */ +#define ENET_MAC_PHY_CTL_PW BIT(1) /*!< PHY write */ +#define ENET_MAC_PHY_CTL_CLR BITS(2,4) /*!< clock range */ +#define ENET_MAC_PHY_CTL_PR BITS(6,10) /*!< PHY register */ +#define ENET_MAC_PHY_CTL_PA BITS(11,15) /*!< PHY address */ + +/* ENET_MAC_PHY_DATA */ +#define ENET_MAC_PHY_DATA_PD BITS(0,15) /*!< PHY data */ + +/* ENET_MAC_FCTL */ +#define ENET_MAC_FCTL_FLCBBKPA BIT(0) /*!< flow control busy(in full duplex mode)/backpressure activate(in half duplex mode) */ +#define ENET_MAC_FCTL_TFCEN BIT(1) /*!< transmit flow control enable */ +#define ENET_MAC_FCTL_RFCEN BIT(2) /*!< receive flow control enable */ +#define ENET_MAC_FCTL_UPFDT BIT(3) /*!< unicast pause frame detect */ +#define ENET_MAC_FCTL_PLTS BITS(4,5) /*!< pause low threshold */ +#define ENET_MAC_FCTL_DZQP BIT(7) /*!< disable zero-quanta pause */ +#define ENET_MAC_FCTL_PTM BITS(16,31) /*!< pause time */ + +/* ENET_MAC_VLT */ +#define ENET_MAC_VLT_VLTI BITS(0,15) /*!< VLAN tag identifier(for receive frames) */ +#define ENET_MAC_VLT_VLTC BIT(16) /*!< 12-bit VLAN tag comparison */ + +/* ENET_MAC_RWFF */ +#define ENET_MAC_RWFF_DATA BITS(0,31) /*!< wakeup frame filter register data */ + +/* ENET_MAC_WUM */ +#define ENET_MAC_WUM_PWD BIT(0) /*!< power down */ +#define ENET_MAC_WUM_MPEN BIT(1) /*!< magic packet enable */ +#define ENET_MAC_WUM_WFEN BIT(2) /*!< wakeup frame enable */ +#define ENET_MAC_WUM_MPKR BIT(5) /*!< magic packet received */ +#define ENET_MAC_WUM_WUFR BIT(6) /*!< wakeup frame received */ +#define ENET_MAC_WUM_GU BIT(9) /*!< global unicast */ +#define ENET_MAC_WUM_WUFFRPR BIT(31) /*!< wakeup frame filter register pointer reset */ + +/* ENET_MAC_DBG */ +#define ENET_MAC_DBG_MRNI BIT(0) /*!< MAC receive state not idle */ +#define ENET_MAC_DBG_RXAFS BITS(1,2) /*!< Rx asynchronous FIFO status */ +#define ENET_MAC_DBG_RXFW BIT(4) /*!< RxFIFO is writing */ +#define ENET_MAC_DBG_RXFRS BITS(5,6) /*!< RxFIFO read operation status */ +#define ENET_MAC_DBG_RXFS BITS(8,9) /*!< RxFIFO state */ +#define ENET_MAC_DBG_MTNI BIT(16) /*!< MAC transmit state not idle */ +#define ENET_MAC_DBG_SOMT BITS(17,18) /*!< status of mac transmitter */ +#define ENET_MAC_DBG_PCS BIT(19) /*!< pause condition status */ +#define ENET_MAC_DBG_TXFRS BITS(20,21) /*!< TxFIFO read operation status */ +#define ENET_MAC_DBG_TXFW BIT(22) /*!< TxFIFO is writing */ +#define ENET_MAC_DBG_TXFNE BIT(24) /*!< TxFIFO not empty flag */ +#define ENET_MAC_DBG_TXFF BIT(25) /*!< TxFIFO full flag */ + +/* ENET_MAC_INTF */ +#define ENET_MAC_INTF_WUM BIT(3) /*!< WUM status */ +#define ENET_MAC_INTF_MSC BIT(4) /*!< MSC status */ +#define ENET_MAC_INTF_MSCR BIT(5) /*!< MSC receive status */ +#define ENET_MAC_INTF_MSCT BIT(6) /*!< MSC transmit status */ +#define ENET_MAC_INTF_TMST BIT(9) /*!< timestamp trigger status */ + +/* ENET_MAC_INTMSK */ +#define ENET_MAC_INTMSK_WUMIM BIT(3) /*!< WUM interrupt mask */ +#define ENET_MAC_INTMSK_TMSTIM BIT(9) /*!< timestamp trigger interrupt mask */ + +/* ENET_MAC_ADDR0H */ +#define ENET_MAC_ADDR0H_ADDR0H BITS(0,15) /*!< MAC address0 high */ +#define ENET_MAC_ADDR0H_MO BIT(31) /*!< always read 1 and must be kept */ + +/* ENET_MAC_ADDR0L */ +#define ENET_MAC_ADDR0L_ADDR0L BITS(0,31) /*!< MAC address0 low */ + +/* ENET_MAC_ADDR1H */ +#define ENET_MAC_ADDR1H_ADDR1H BITS(0,15) /*!< MAC address1 high */ +#define ENET_MAC_ADDR1H_MB BITS(24,29) /*!< mask byte */ +#define ENET_MAC_ADDR1H_SAF BIT(30) /*!< source address filter */ +#define ENET_MAC_ADDR1H_AFE BIT(31) /*!< address filter enable */ + +/* ENET_MAC_ADDR1L */ +#define ENET_MAC_ADDR1L_ADDR1L BITS(0,31) /*!< MAC address1 low */ + +/* ENET_MAC_ADDR2H */ +#define ENET_MAC_ADDR2H_ADDR2H BITS(0,15) /*!< MAC address2 high */ +#define ENET_MAC_ADDR2H_MB BITS(24,29) /*!< mask byte */ +#define ENET_MAC_ADDR2H_SAF BIT(30) /*!< source address filter */ +#define ENET_MAC_ADDR2H_AFE BIT(31) /*!< address filter enable */ + +/* ENET_MAC_ADDR2L */ +#define ENET_MAC_ADDR2L_ADDR2L BITS(0,31) /*!< MAC address2 low */ + +/* ENET_MAC_ADDR3H */ +#define ENET_MAC_ADDR3H_ADDR3H BITS(0,15) /*!< MAC address3 high */ +#define ENET_MAC_ADDR3H_MB BITS(24,29) /*!< mask byte */ +#define ENET_MAC_ADDR3H_SAF BIT(30) /*!< source address filter */ +#define ENET_MAC_ADDR3H_AFE BIT(31) /*!< address filter enable */ + +/* ENET_MAC_ADDR3L */ +#define ENET_MAC_ADDR3L_ADDR3L BITS(0,31) /*!< MAC address3 low */ + +/* ENET_MAC_FCTH */ +#define ENET_MAC_FCTH_RFA BITS(0,2) /*!< threshold of active flow control */ +#define ENET_MAC_FCTH_RFD BITS(4,6) /*!< threshold of deactive flow control */ + +/* ENET_MSC_CTL */ +#define ENET_MSC_CTL_CTR BIT(0) /*!< counter reset */ +#define ENET_MSC_CTL_CTSR BIT(1) /*!< counter stop rollover */ +#define ENET_MSC_CTL_RTOR BIT(2) /*!< reset on read */ +#define ENET_MSC_CTL_MCFZ BIT(3) /*!< MSC counter freeze */ +#define ENET_MSC_CTL_PMC BIT(4) /*!< preset MSC counter */ +#define ENET_MSC_CTL_AFHPM BIT(5) /*!< almost full or half preset mode */ + +/* ENET_MSC_RINTF */ +#define ENET_MSC_RINTF_RFCE BIT(5) /*!< received frames CRC error */ +#define ENET_MSC_RINTF_RFAE BIT(6) /*!< received frames alignment error */ +#define ENET_MSC_RINTF_RGUF BIT(17) /*!< receive good unicast frames */ + +/* ENET_MSC_TINTF */ +#define ENET_MSC_TINTF_TGFSC BIT(14) /*!< transmitted good frames single collision */ +#define ENET_MSC_TINTF_TGFMSC BIT(15) /*!< transmitted good frames more single collision */ +#define ENET_MSC_TINTF_TGF BIT(21) /*!< transmitted good frames */ + +/* ENET_MSC_RINTMSK */ +#define ENET_MSC_RINTMSK_RFCEIM BIT(5) /*!< received frame CRC error interrupt mask */ +#define ENET_MSC_RINTMSK_RFAEIM BIT(6) /*!< received frames alignment error interrupt mask */ +#define ENET_MSC_RINTMSK_RGUFIM BIT(17) /*!< received good unicast frames interrupt mask */ + +/* ENET_MSC_TINTMSK */ +#define ENET_MSC_TINTMSK_TGFSCIM BIT(14) /*!< transmitted good frames single collision interrupt mask */ +#define ENET_MSC_TINTMSK_TGFMSCIM BIT(15) /*!< transmitted good frames more single collision interrupt mask */ +#define ENET_MSC_TINTMSK_TGFIM BIT(21) /*!< transmitted good frames interrupt mask */ + +/* ENET_MSC_SCCNT */ +#define ENET_MSC_SCCNT_SCC BITS(0,31) /*!< transmitted good frames single collision counter */ + +/* ENET_MSC_MSCCNT */ +#define ENET_MSC_MSCCNT_MSCC BITS(0,31) /*!< transmitted good frames more one single collision counter */ + +/* ENET_MSC_TGFCNT */ +#define ENET_MSC_TGFCNT_TGF BITS(0,31) /*!< transmitted good frames counter */ + +/* ENET_MSC_RFCECNT */ +#define ENET_MSC_RFCECNT_RFCER BITS(0,31) /*!< received frames with CRC error counter */ + +/* ENET_MSC_RFAECNT */ +#define ENET_MSC_RFAECNT_RFAER BITS(0,31) /*!< received frames alignment error counter */ + +/* ENET_MSC_RGUFCNT */ +#define ENET_MSC_RGUFCNT_RGUF BITS(0,31) /*!< received good unicast frames counter */ + +/* ENET_PTP_TSCTL */ +#define PTP_TSCTL_CKNT(regval) (BITS(16,17) & ((uint32_t)(regval) << 16)) /*!< write value to ENET_PTP_TSCTL_CKNT bit field */ + +#define ENET_PTP_TSCTL_TMSEN BIT(0) /*!< timestamp enable */ +#define ENET_PTP_TSCTL_TMSFCU BIT(1) /*!< timestamp fine or coarse update */ +#define ENET_PTP_TSCTL_TMSSTI BIT(2) /*!< timestamp system time initialize */ +#define ENET_PTP_TSCTL_TMSSTU BIT(3) /*!< timestamp system time update */ +#define ENET_PTP_TSCTL_TMSITEN BIT(4) /*!< timestamp interrupt trigger enable */ +#define ENET_PTP_TSCTL_TMSARU BIT(5) /*!< timestamp addend register update */ +#define ENET_PTP_TSCTL_ARFSEN BIT(8) /*!< all received frames snapshot enable */ +#define ENET_PTP_TSCTL_SCROM BIT(9) /*!< subsecond counter rollover mode */ +#define ENET_PTP_TSCTL_PFSV BIT(10) /*!< PTP frame snooping version */ +#define ENET_PTP_TSCTL_ESEN BIT(11) /*!< received Ethernet snapshot enable */ +#define ENET_PTP_TSCTL_IP6SEN BIT(12) /*!< received IPv6 snapshot enable */ +#define ENET_PTP_TSCTL_IP4SEN BIT(13) /*!< received IPv4 snapshot enable */ +#define ENET_PTP_TSCTL_ETMSEN BIT(14) /*!< received event type message snapshot enable */ +#define ENET_PTP_TSCTL_MNMSEN BIT(15) /*!< received master node message snapshot enable */ +#define ENET_PTP_TSCTL_CKNT BITS(16,17) /*!< clock node type for time stamp */ +#define ENET_PTP_TSCTL_MAFEN BIT(18) /*!< MAC address filter enable for PTP frame */ + +/* ENET_PTP_SSINC */ +#define ENET_PTP_SSINC_STMSSI BITS(0,7) /*!< system time subsecond increment */ + +/* ENET_PTP_TSH */ +#define ENET_PTP_TSH_STMS BITS(0,31) /*!< system time second */ + +/* ENET_PTP_TSL */ +#define ENET_PTP_TSL_STMSS BITS(0,30) /*!< system time subseconds */ +#define ENET_PTP_TSL_STS BIT(31) /*!< system time sign */ + +/* ENET_PTP_TSUH */ +#define ENET_PTP_TSUH_TMSUS BITS(0,31) /*!< timestamp update seconds */ + +/* ENET_PTP_TSUL */ +#define ENET_PTP_TSUL_TMSUSS BITS(0,30) /*!< timestamp update subseconds */ +#define ENET_PTP_TSUL_TMSUPNS BIT(31) /*!< timestamp update positive or negative sign */ + +/* ENET_PTP_TSADDAND */ +#define ENET_PTP_TSADDAND_TMSA BITS(0,31) /*!< timestamp addend */ + +/* ENET_PTP_ETH */ +#define ENET_PTP_ETH_ETSH BITS(0,31) /*!< expected time high */ + +/* ENET_PTP_ETL */ +#define ENET_PTP_ETL_ETSL BITS(0,31) /*!< expected time low */ + +/* ENET_PTP_TSF */ +#define ENET_PTP_TSF_TSSCO BIT(0) /*!< timestamp second counter overflow */ +#define ENET_PTP_TSF_TTM BIT(1) /*!< target time match */ + +/* ENET_PTP_PPSCTL */ +#define ENET_PTP_PPSCTL_PPSOFC BITS(0,3) /*!< PPS output frequency configure */ + +/* ENET_DMA_BCTL */ +#define ENET_DMA_BCTL_SWR BIT(0) /*!< software reset */ +#define ENET_DMA_BCTL_DAB BIT(1) /*!< DMA arbitration */ +#define ENET_DMA_BCTL_DPSL BITS(2,6) /*!< descriptor skip length */ +#define ENET_DMA_BCTL_DFM BIT(7) /*!< descriptor format mode */ +#define ENET_DMA_BCTL_PGBL BITS(8,13) /*!< programmable burst length */ +#define ENET_DMA_BCTL_RTPR BITS(14,15) /*!< RxDMA and TxDMA transfer priority ratio */ +#define ENET_DMA_BCTL_FB BIT(16) /*!< fixed Burst */ +#define ENET_DMA_BCTL_RXDP BITS(17,22) /*!< RxDMA PGBL */ +#define ENET_DMA_BCTL_UIP BIT(23) /*!< use independent PGBL */ +#define ENET_DMA_BCTL_FPBL BIT(24) /*!< four times PGBL mode */ +#define ENET_DMA_BCTL_AA BIT(25) /*!< address-aligned */ +#define ENET_DMA_BCTL_MB BIT(26) /*!< mixed burst */ + +/* ENET_DMA_TPEN */ +#define ENET_DMA_TPEN_TPE BITS(0,31) /*!< transmit poll enable */ + +/* ENET_DMA_RPEN */ +#define ENET_DMA_RPEN_RPE BITS(0,31) /*!< receive poll enable */ + +/* ENET_DMA_RDTADDR */ +#define ENET_DMA_RDTADDR_SRT BITS(0,31) /*!< start address of receive table */ + +/* ENET_DMA_TDTADDR */ +#define ENET_DMA_TDTADDR_STT BITS(0,31) /*!< start address of transmit table */ + +/* ENET_DMA_STAT */ +#define ENET_DMA_STAT_TS BIT(0) /*!< transmit status */ +#define ENET_DMA_STAT_TPS BIT(1) /*!< transmit process stopped status */ +#define ENET_DMA_STAT_TBU BIT(2) /*!< transmit buffer unavailable status */ +#define ENET_DMA_STAT_TJT BIT(3) /*!< transmit jabber timeout status */ +#define ENET_DMA_STAT_RO BIT(4) /*!< receive overflow status */ +#define ENET_DMA_STAT_TU BIT(5) /*!< transmit underflow status */ +#define ENET_DMA_STAT_RS BIT(6) /*!< receive status */ +#define ENET_DMA_STAT_RBU BIT(7) /*!< receive buffer unavailable status */ +#define ENET_DMA_STAT_RPS BIT(8) /*!< receive process stopped status */ +#define ENET_DMA_STAT_RWT BIT(9) /*!< receive watchdog timeout status */ +#define ENET_DMA_STAT_ET BIT(10) /*!< early transmit status */ +#define ENET_DMA_STAT_FBE BIT(13) /*!< fatal bus error status */ +#define ENET_DMA_STAT_ER BIT(14) /*!< early receive status */ +#define ENET_DMA_STAT_AI BIT(15) /*!< abnormal interrupt summary */ +#define ENET_DMA_STAT_NI BIT(16) /*!< normal interrupt summary */ +#define ENET_DMA_STAT_RP BITS(17,19) /*!< receive process state */ +#define ENET_DMA_STAT_TP BITS(20,22) /*!< transmit process state */ +#define ENET_DMA_STAT_EB BITS(23,25) /*!< error bits status */ +#define ENET_DMA_STAT_MSC BIT(27) /*!< MSC status */ +#define ENET_DMA_STAT_WUM BIT(28) /*!< WUM status */ +#define ENET_DMA_STAT_TST BIT(29) /*!< timestamp trigger status */ + +/* ENET_DMA_CTL */ +#define ENET_DMA_CTL_SRE BIT(1) /*!< start/stop receive enable */ +#define ENET_DMA_CTL_OSF BIT(2) /*!< operate on second frame */ +#define ENET_DMA_CTL_RTHC BITS(3,4) /*!< receive threshold control */ +#define ENET_DMA_CTL_FUF BIT(6) /*!< forward undersized good frames */ +#define ENET_DMA_CTL_FERF BIT(7) /*!< forward error frames */ +#define ENET_DMA_CTL_STE BIT(13) /*!< start/stop transmission enable */ +#define ENET_DMA_CTL_TTHC BITS(14,16) /*!< transmit threshold control */ +#define ENET_DMA_CTL_FTF BIT(20) /*!< flush transmit FIFO */ +#define ENET_DMA_CTL_TSFD BIT(21) /*!< transmit store-and-forward */ +#define ENET_DMA_CTL_DAFRF BIT(24) /*!< disable flushing of received frames */ +#define ENET_DMA_CTL_RSFD BIT(25) /*!< receive store-and-forward */ +#define ENET_DMA_CTL_DTCERFD BIT(26) /*!< dropping of TCP/IP checksum error frames disable */ + +/* ENET_DMA_INTEN */ +#define ENET_DMA_INTEN_TIE BIT(0) /*!< transmit interrupt enable */ +#define ENET_DMA_INTEN_TPSIE BIT(1) /*!< transmit process stopped interrupt enable */ +#define ENET_DMA_INTEN_TBUIE BIT(2) /*!< transmit buffer unavailable interrupt enable */ +#define ENET_DMA_INTEN_TJTIE BIT(3) /*!< transmit jabber timeout interrupt enable */ +#define ENET_DMA_INTEN_ROIE BIT(4) /*!< receive overflow interrupt enable */ +#define ENET_DMA_INTEN_TUIE BIT(5) /*!< transmit underflow interrupt enable */ +#define ENET_DMA_INTEN_RIE BIT(6) /*!< receive interrupt enable */ +#define ENET_DMA_INTEN_RBUIE BIT(7) /*!< receive buffer unavailable interrupt enable */ +#define ENET_DMA_INTEN_RPSIE BIT(8) /*!< receive process stopped interrupt enable */ +#define ENET_DMA_INTEN_RWTIE BIT(9) /*!< receive watchdog timeout interrupt enable */ +#define ENET_DMA_INTEN_ETIE BIT(10) /*!< early transmit interrupt enable */ +#define ENET_DMA_INTEN_FBEIE BIT(13) /*!< fatal bus error interrupt enable */ +#define ENET_DMA_INTEN_ERIE BIT(14) /*!< early receive interrupt enable */ +#define ENET_DMA_INTEN_AIE BIT(15) /*!< abnormal interrupt summary enable */ +#define ENET_DMA_INTEN_NIE BIT(16) /*!< normal interrupt summary enable */ + +/* ENET_DMA_MFBOCNT */ +#define ENET_DMA_MFBOCNT_MSFC BITS(0,15) /*!< missed frames by the controller */ +#define ENET_DMA_MFBOCNT_MSFA BITS(17,27) /*!< missed frames by the application */ + +/* ENET_DMA_RSWDC */ +#define ENET_DMA_RSWDC_WDCFRS BITS(0,7) /*!< watchdog counter for receive status (RS) */ + +/* ENET_DMA_CTDADDR */ +#define ENET_DMA_CTDADDR_TDAP BITS(0,31) /*!< transmit descriptor address pointer */ + +/* ENET_DMA_CRDADDR */ +#define ENET_DMA_CRDADDR_RDAP BITS(0,31) /*!< receive descriptor address pointer */ + +/* ENET_DMA_CTBADDR */ +#define ENET_DMA_CTBADDR_TBAP BITS(0,31) /*!< transmit buffer address pointer */ + +/* ENET_DMA_CRBADDR */ +#define ENET_DMA_CRBADDR_RBAP BITS(0,31) /*!< receive buffer address pointer */ + +/* ENET DMA Tx descriptor TDES0 */ +#define ENET_TDES0_DB BIT(0) /*!< deferred */ +#define ENET_TDES0_UFE BIT(1) /*!< underflow error */ +#define ENET_TDES0_EXD BIT(2) /*!< excessive deferral */ +#define ENET_TDES0_COCNT BITS(3,6) /*!< collision count */ +#define ENET_TDES0_VFRM BIT(7) /*!< VLAN frame */ +#define ENET_TDES0_ECO BIT(8) /*!< excessive collision */ +#define ENET_TDES0_LCO BIT(9) /*!< late collision */ +#define ENET_TDES0_NCA BIT(10) /*!< no carrier */ +#define ENET_TDES0_LCA BIT(11) /*!< loss of carrier */ +#define ENET_TDES0_IPPE BIT(12) /*!< IP payload error */ +#define ENET_TDES0_FRMF BIT(13) /*!< frame flushed */ +#define ENET_TDES0_JT BIT(14) /*!< jabber timeout */ +#define ENET_TDES0_ES BIT(15) /*!< error summary */ +#define ENET_TDES0_IPHE BIT(16) /*!< IP header error */ +#define ENET_TDES0_TTMSS BIT(17) /*!< transmit timestamp status */ +#define ENET_TDES0_TCHM BIT(20) /*!< the second address chained mode */ +#define ENET_TDES0_TERM BIT(21) /*!< transmit end of ring mode*/ +#define ENET_TDES0_CM BITS(22,23) /*!< checksum mode */ +#define ENET_TDES0_TTSEN BIT(25) /*!< transmit timestamp function enable */ +#define ENET_TDES0_DPAD BIT(26) /*!< disable adding pad */ +#define ENET_TDES0_DCRC BIT(27) /*!< disable CRC */ +#define ENET_TDES0_FSG BIT(28) /*!< first segment */ +#define ENET_TDES0_LSG BIT(29) /*!< last segment */ +#define ENET_TDES0_INTC BIT(30) /*!< interrupt on completion */ +#define ENET_TDES0_DAV BIT(31) /*!< DAV bit */ + +/* ENET DMA Tx descriptor TDES1 */ +#define ENET_TDES1_TB1S BITS(0,12) /*!< transmit buffer 1 size */ +#define ENET_TDES1_TB2S BITS(16,28) /*!< transmit buffer 2 size */ + +/* ENET DMA Tx descriptor TDES2 */ +#define ENET_TDES2_TB1AP BITS(0,31) /*!< transmit buffer 1 address pointer/transmit frame timestamp low 32-bit value */ + +/* ENET DMA Tx descriptor TDES3 */ +#define ENET_TDES3_TB2AP BITS(0,31) /*!< transmit buffer 2 address pointer (or next descriptor address) / transmit frame timestamp high 32-bit value */ + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE +/* ENET DMA Tx descriptor TDES6 */ +#define ENET_TDES6_TTSL BITS(0,31) /*!< transmit frame timestamp low 32-bit value */ + +/* ENET DMA Tx descriptor TDES7 */ +#define ENET_TDES7_TTSH BITS(0,31) /*!< transmit frame timestamp high 32-bit value */ +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/* ENET DMA Rx descriptor RDES0 */ +#define ENET_RDES0_PCERR BIT(0) /*!< payload checksum error */ +#define ENET_RDES0_EXSV BIT(0) /*!< extended status valid */ +#define ENET_RDES0_CERR BIT(1) /*!< CRC error */ +#define ENET_RDES0_DBERR BIT(2) /*!< dribble bit error */ +#define ENET_RDES0_RERR BIT(3) /*!< receive error */ +#define ENET_RDES0_RWDT BIT(4) /*!< receive watchdog timeout */ +#define ENET_RDES0_FRMT BIT(5) /*!< frame type */ +#define ENET_RDES0_LCO BIT(6) /*!< late collision */ +#define ENET_RDES0_IPHERR BIT(7) /*!< IP frame header error */ +#define ENET_RDES0_TSV BIT(7) /*!< timestamp valid */ +#define ENET_RDES0_LDES BIT(8) /*!< last descriptor */ +#define ENET_RDES0_FDES BIT(9) /*!< first descriptor */ +#define ENET_RDES0_VTAG BIT(10) /*!< VLAN tag */ +#define ENET_RDES0_OERR BIT(11) /*!< overflow Error */ +#define ENET_RDES0_LERR BIT(12) /*!< length error */ +#define ENET_RDES0_SAFF BIT(13) /*!< SA filter fail */ +#define ENET_RDES0_DERR BIT(14) /*!< descriptor error */ +#define ENET_RDES0_ERRS BIT(15) /*!< error summary */ +#define ENET_RDES0_FRML BITS(16,29) /*!< frame length */ +#define ENET_RDES0_DAFF BIT(30) /*!< destination address filter fail */ +#define ENET_RDES0_DAV BIT(31) /*!< descriptor available */ + +/* ENET DMA Rx descriptor RDES1 */ +#define ENET_RDES1_RB1S BITS(0,12) /*!< receive buffer 1 size */ +#define ENET_RDES1_RCHM BIT(14) /*!< receive chained mode for second address */ +#define ENET_RDES1_RERM BIT(15) /*!< receive end of ring mode*/ +#define ENET_RDES1_RB2S BITS(16,28) /*!< receive buffer 2 size */ +#define ENET_RDES1_DINTC BIT(31) /*!< disable interrupt on completion */ + +/* ENET DMA Rx descriptor RDES2 */ +#define ENET_RDES2_RB1AP BITS(0,31) /*!< receive buffer 1 address pointer / receive frame timestamp low 32-bit */ + +/* ENET DMA Rx descriptor RDES3 */ +#define ENET_RDES3_RB2AP BITS(0,31) /*!< receive buffer 2 address pointer (next descriptor address)/receive frame timestamp high 32-bit value */ + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE +/* ENET DMA Rx descriptor RDES4 */ +#define ENET_RDES4_IPPLDT BITS(0,2) /*!< IP frame payload type */ +#define ENET_RDES4_IPHERR BIT(3) /*!< IP frame header error */ +#define ENET_RDES4_IPPLDERR BIT(4) /*!< IP frame payload error */ +#define ENET_RDES4_IPCKSB BIT(5) /*!< IP frame checksum bypassed */ +#define ENET_RDES4_IPF4 BIT(6) /*!< IP frame in version 4 */ +#define ENET_RDES4_IPF6 BIT(7) /*!< IP frame in version 6 */ +#define ENET_RDES4_PTPMT BITS(8,11) /*!< PTP message type */ +#define ENET_RDES4_PTPOEF BIT(12) /*!< PTP on ethernet frame */ +#define ENET_RDES4_PTPVF BIT(13) /*!< PTP version format */ + +/* ENET DMA Rx descriptor RDES6 */ +#define ENET_RDES6_RTSL BITS(0,31) /*!< receive frame timestamp low 32-bit value */ + +/* ENET DMA Rx descriptor RDES7 */ +#define ENET_RDES7_RTSH BITS(0,31) /*!< receive frame timestamp high 32-bit value */ +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/* constants definitions */ +/* define bit position and its register index offset */ +#define ENET_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define ENET_REG_VAL(periph) (REG32(ENET + ((uint32_t)(periph)>>6))) +#define ENET_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +/* ENET clock range judgement */ +#define ENET_RANGE(hclk, n, m) (((hclk) >= (n))&&((hclk) < (m))) + +/* define MAC address configuration and reference address */ +#define ENET_SET_MACADDRH(p) (((uint32_t)(p)[5] << 8) | (uint32_t)(p)[4]) +#define ENET_SET_MACADDRL(p) (((uint32_t)(p)[3] << 24) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[1] << 8) | (uint32_t)(p)[0]) +#define ENET_ADDRH_BASE ((ENET) + 0x40U) +#define ENET_ADDRL_BASE ((ENET) + 0x44U) +#define ENET_GET_MACADDR(offset, n) ((uint8_t)((REG32((ENET_ADDRL_BASE + (offset)) - (((n) / 4U) * 4U)) >> (8U * ((n) % 4U))) & 0xFFU)) + +/* register offset */ +#define MAC_FCTL_REG_OFFSET 0x0018U /*!< MAC flow control register offset */ +#define MAC_WUM_REG_OFFSET 0x002CU /*!< MAC wakeup management register offset */ +#define MAC_INTF_REG_OFFSET 0x0038U /*!< MAC interrupt flag register offset */ +#define MAC_INTMSK_REG_OFFSET 0x003CU /*!< MAC interrupt mask register offset */ + +#define MSC_RINTF_REG_OFFSET 0x0104U /*!< MSC receive interrupt flag register offset */ +#define MSC_TINTF_REG_OFFSET 0x0108U /*!< MSC transmit interrupt flag register offset */ +#define MSC_RINTMSK_REG_OFFSET 0x010CU /*!< MSC receive interrupt mask register offset */ +#define MSC_TINTMSK_REG_OFFSET 0x0110U /*!< MSC transmit interrupt mask register offset */ +#define MSC_SCCNT_REG_OFFSET 0x014CU /*!< MSC transmitted good frames after a single collision counter register offset */ +#define MSC_MSCCNT_REG_OFFSET 0x0150U /*!< MSC transmitted good frames after more than a single collision counter register offset */ +#define MSC_TGFCNT_REG_OFFSET 0x0168U /*!< MSC transmitted good frames counter register offset */ +#define MSC_RFCECNT_REG_OFFSET 0x0194U /*!< MSC received frames with CRC error counter register offset */ +#define MSC_RFAECNT_REG_OFFSET 0x0198U /*!< MSC received frames with alignment error counter register offset */ +#define MSC_RGUFCNT_REG_OFFSET 0x01C4U /*!< MSC received good unicast frames counter register offset */ + +#define PTP_TSF_REG_OFFSET 0x0728U /*!< PTP time stamp flag register offset */ + +#define DMA_STAT_REG_OFFSET 0x1014U /*!< DMA status register offset */ +#define DMA_INTEN_REG_OFFSET 0x101CU /*!< DMA interrupt enable register offset */ +#define DMA_TDTADDR_REG_OFFSET 0x1010U /*!< DMA transmit descriptor table address register offset */ +#define DMA_CTDADDR_REG_OFFSET 0x1048U /*!< DMA current transmit descriptor address register */ +#define DMA_CTBADDR_REG_OFFSET 0x1050U /*!< DMA current transmit buffer address register */ +#define DMA_RDTADDR_REG_OFFSET 0x100CU /*!< DMA receive descriptor table address register */ +#define DMA_CRDADDR_REG_OFFSET 0x104CU /*!< DMA current receive descriptor address register */ +#define DMA_CRBADDR_REG_OFFSET 0x1054U /*!< DMA current receive buffer address register */ + +/* ENET status flag get */ +typedef enum +{ + /* ENET_MAC_WUM register */ + ENET_MAC_FLAG_MPKR = ENET_REGIDX_BIT(MAC_WUM_REG_OFFSET, 5U), /*!< magic packet received flag */ + ENET_MAC_FLAG_WUFR = ENET_REGIDX_BIT(MAC_WUM_REG_OFFSET, 6U), /*!< wakeup frame received flag */ + /* ENET_MAC_FCTL register */ + ENET_MAC_FLAG_FLOWCONTROL = ENET_REGIDX_BIT(MAC_FCTL_REG_OFFSET, 0U), /*!< flow control status flag */ + /* ENET_MAC_INTF register */ + ENET_MAC_FLAG_WUM = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 3U), /*!< WUM status flag */ + ENET_MAC_FLAG_MSC = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 4U), /*!< MSC status flag */ + ENET_MAC_FLAG_MSCR = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 5U), /*!< MSC receive status flag */ + ENET_MAC_FLAG_MSCT = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 6U), /*!< MSC transmit status flag */ + ENET_MAC_FLAG_TMST = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 9U), /*!< timestamp trigger status flag */ + /* ENET_PTP_TSF register */ + ENET_PTP_FLAG_TSSCO = ENET_REGIDX_BIT(PTP_TSF_REG_OFFSET, 0U), /*!< timestamp second counter overflow flag */ + ENET_PTP_FLAG_TTM = ENET_REGIDX_BIT(PTP_TSF_REG_OFFSET, 1U), /*!< target time match flag */ + /* ENET_MSC_RINTF register */ + ENET_MSC_FLAG_RFCE = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 5U), /*!< received frames CRC error flag */ + ENET_MSC_FLAG_RFAE = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 6U), /*!< received frames alignment error flag */ + ENET_MSC_FLAG_RGUF = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 17U), /*!< received good unicast frames flag */ + /* ENET_MSC_TINTF register */ + ENET_MSC_FLAG_TGFSC = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 14U), /*!< transmitted good frames single collision flag */ + ENET_MSC_FLAG_TGFMSC = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 15U), /*!< transmitted good frames more single collision flag */ + ENET_MSC_FLAG_TGF = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 21U), /*!< transmitted good frames flag */ + /* ENET_DMA_STAT register */ + ENET_DMA_FLAG_TS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U), /*!< transmit status flag */ + ENET_DMA_FLAG_TPS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U), /*!< transmit process stopped status flag */ + ENET_DMA_FLAG_TBU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U), /*!< transmit buffer unavailable status flag */ + ENET_DMA_FLAG_TJT = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U), /*!< transmit jabber timeout status flag */ + ENET_DMA_FLAG_RO = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U), /*!< receive overflow status flag */ + ENET_DMA_FLAG_TU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U), /*!< transmit underflow status flag */ + ENET_DMA_FLAG_RS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U), /*!< receive status flag */ + ENET_DMA_FLAG_RBU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U), /*!< receive buffer unavailable status flag */ + ENET_DMA_FLAG_RPS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U), /*!< receive process stopped status flag */ + ENET_DMA_FLAG_RWT = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U), /*!< receive watchdog timeout status flag */ + ENET_DMA_FLAG_ET = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U), /*!< early transmit status flag */ + ENET_DMA_FLAG_FBE = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U), /*!< fatal bus error status flag */ + ENET_DMA_FLAG_ER = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U), /*!< early receive status flag */ + ENET_DMA_FLAG_AI = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U), /*!< abnormal interrupt summary flag */ + ENET_DMA_FLAG_NI = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U), /*!< normal interrupt summary flag */ + ENET_DMA_FLAG_EB_DMA_ERROR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 23U), /*!< error during data transfer by RxDMA/TxDMA flag */ + ENET_DMA_FLAG_EB_TRANSFER_ERROR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 24U), /*!< error during write/read transfer flag */ + ENET_DMA_FLAG_EB_ACCESS_ERROR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 25U), /*!< error during data buffer/descriptor access flag */ + ENET_DMA_FLAG_MSC = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 27U), /*!< MSC status flag */ + ENET_DMA_FLAG_WUM = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 28U), /*!< WUM status flag */ + ENET_DMA_FLAG_TST = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 29U), /*!< timestamp trigger status flag */ +}enet_flag_enum; + +/* ENET stutus flag clear */ +typedef enum +{ + /* ENET_DMA_STAT register */ + ENET_DMA_FLAG_TS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U), /*!< transmit status flag */ + ENET_DMA_FLAG_TPS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U), /*!< transmit process stopped status flag */ + ENET_DMA_FLAG_TBU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U), /*!< transmit buffer unavailable status flag */ + ENET_DMA_FLAG_TJT_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U), /*!< transmit jabber timeout status flag */ + ENET_DMA_FLAG_RO_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U), /*!< receive overflow status flag */ + ENET_DMA_FLAG_TU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U), /*!< transmit underflow status flag */ + ENET_DMA_FLAG_RS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U), /*!< receive status flag */ + ENET_DMA_FLAG_RBU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U), /*!< receive buffer unavailable status flag */ + ENET_DMA_FLAG_RPS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U), /*!< receive process stopped status flag */ + ENET_DMA_FLAG_RWT_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U), /*!< receive watchdog timeout status flag */ + ENET_DMA_FLAG_ET_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U), /*!< early transmit status flag */ + ENET_DMA_FLAG_FBE_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U), /*!< fatal bus error status flag */ + ENET_DMA_FLAG_ER_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U), /*!< early receive status flag */ + ENET_DMA_FLAG_AI_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U), /*!< abnormal interrupt summary flag */ + ENET_DMA_FLAG_NI_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U), /*!< normal interrupt summary flag */ +}enet_flag_clear_enum; + +/* ENET interrupt enable/disable */ +typedef enum +{ + /* ENET_MAC_INTMSK register */ + ENET_MAC_INT_WUMIM = ENET_REGIDX_BIT(MAC_INTMSK_REG_OFFSET, 3U), /*!< WUM interrupt mask */ + ENET_MAC_INT_TMSTIM = ENET_REGIDX_BIT(MAC_INTMSK_REG_OFFSET, 9U), /*!< timestamp trigger interrupt mask */ + /* ENET_MSC_RINTMSK register */ + ENET_MSC_INT_RFCEIM = ENET_REGIDX_BIT(MSC_RINTMSK_REG_OFFSET, 5U), /*!< received frame CRC error interrupt mask */ + ENET_MSC_INT_RFAEIM = ENET_REGIDX_BIT(MSC_RINTMSK_REG_OFFSET, 6U), /*!< received frames alignment error interrupt mask */ + ENET_MSC_INT_RGUFIM = ENET_REGIDX_BIT(MSC_RINTMSK_REG_OFFSET, 17U), /*!< received good unicast frames interrupt mask */ + /* ENET_MSC_TINTMSK register */ + ENET_MSC_INT_TGFSCIM = ENET_REGIDX_BIT(MSC_TINTMSK_REG_OFFSET, 14U), /*!< transmitted good frames single collision interrupt mask */ + ENET_MSC_INT_TGFMSCIM = ENET_REGIDX_BIT(MSC_TINTMSK_REG_OFFSET, 15U), /*!< transmitted good frames more single collision interrupt mask */ + ENET_MSC_INT_TGFIM = ENET_REGIDX_BIT(MSC_TINTMSK_REG_OFFSET, 21U), /*!< transmitted good frames interrupt mask */ + /* ENET_DMA_INTEN register */ + ENET_DMA_INT_TIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 0U), /*!< transmit interrupt enable */ + ENET_DMA_INT_TPSIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 1U), /*!< transmit process stopped interrupt enable */ + ENET_DMA_INT_TBUIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 2U), /*!< transmit buffer unavailable interrupt enable */ + ENET_DMA_INT_TJTIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 3U), /*!< transmit jabber timeout interrupt enable */ + ENET_DMA_INT_ROIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 4U), /*!< receive overflow interrupt enable */ + ENET_DMA_INT_TUIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 5U), /*!< transmit underflow interrupt enable */ + ENET_DMA_INT_RIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 6U), /*!< receive interrupt enable */ + ENET_DMA_INT_RBUIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 7U), /*!< receive buffer unavailable interrupt enable */ + ENET_DMA_INT_RPSIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 8U), /*!< receive process stopped interrupt enable */ + ENET_DMA_INT_RWTIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 9U), /*!< receive watchdog timeout interrupt enable */ + ENET_DMA_INT_ETIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 10U), /*!< early transmit interrupt enable */ + ENET_DMA_INT_FBEIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 13U), /*!< fatal bus error interrupt enable */ + ENET_DMA_INT_ERIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 14U), /*!< early receive interrupt enable */ + ENET_DMA_INT_AIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 15U), /*!< abnormal interrupt summary enable */ + ENET_DMA_INT_NIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 16U), /*!< normal interrupt summary enable */ +}enet_int_enum; + +/* ENET interrupt flag get */ +typedef enum +{ + /* ENET_MAC_INTF register */ + ENET_MAC_INT_FLAG_WUM = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 3U), /*!< WUM status flag */ + ENET_MAC_INT_FLAG_MSC = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 4U), /*!< MSC status flag */ + ENET_MAC_INT_FLAG_MSCR = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 5U), /*!< MSC receive status flag */ + ENET_MAC_INT_FLAG_MSCT = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 6U), /*!< MSC transmit status flag */ + ENET_MAC_INT_FLAG_TMST = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 9U), /*!< timestamp trigger status flag */ + /* ENET_MSC_RINTF register */ + ENET_MSC_INT_FLAG_RFCE = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 5U), /*!< received frames CRC error flag */ + ENET_MSC_INT_FLAG_RFAE = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 6U), /*!< received frames alignment error flag */ + ENET_MSC_INT_FLAG_RGUF = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 17U), /*!< received good unicast frames flag */ + /* ENET_MSC_TINTF register */ + ENET_MSC_INT_FLAG_TGFSC = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 14U), /*!< transmitted good frames single collision flag */ + ENET_MSC_INT_FLAG_TGFMSC = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 15U), /*!< transmitted good frames more single collision flag */ + ENET_MSC_INT_FLAG_TGF = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 21U), /*!< transmitted good frames flag */ + /* ENET_DMA_STAT register */ + ENET_DMA_INT_FLAG_TS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U), /*!< transmit status flag */ + ENET_DMA_INT_FLAG_TPS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U), /*!< transmit process stopped status flag */ + ENET_DMA_INT_FLAG_TBU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U), /*!< transmit buffer unavailable status flag */ + ENET_DMA_INT_FLAG_TJT = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U), /*!< transmit jabber timeout status flag */ + ENET_DMA_INT_FLAG_RO = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U), /*!< receive overflow status flag */ + ENET_DMA_INT_FLAG_TU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U), /*!< transmit underflow status flag */ + ENET_DMA_INT_FLAG_RS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U), /*!< receive status flag */ + ENET_DMA_INT_FLAG_RBU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U), /*!< receive buffer unavailable status flag */ + ENET_DMA_INT_FLAG_RPS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U), /*!< receive process stopped status flag */ + ENET_DMA_INT_FLAG_RWT = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U), /*!< receive watchdog timeout status flag */ + ENET_DMA_INT_FLAG_ET = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U), /*!< early transmit status flag */ + ENET_DMA_INT_FLAG_FBE = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U), /*!< fatal bus error status flag */ + ENET_DMA_INT_FLAG_ER = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U), /*!< early receive status flag */ + ENET_DMA_INT_FLAG_AI = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U), /*!< abnormal interrupt summary flag */ + ENET_DMA_INT_FLAG_NI = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U), /*!< normal interrupt summary flag */ + ENET_DMA_INT_FLAG_MSC = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 27U), /*!< MSC status flag */ + ENET_DMA_INT_FLAG_WUM = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 28U), /*!< WUM status flag */ + ENET_DMA_INT_FLAG_TST = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 29U), /*!< timestamp trigger status flag */ +}enet_int_flag_enum; + +/* ENET interrupt flag clear */ +typedef enum +{ + /* ENET_DMA_STAT register */ + ENET_DMA_INT_FLAG_TS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U), /*!< transmit status flag */ + ENET_DMA_INT_FLAG_TPS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U), /*!< transmit process stopped status flag */ + ENET_DMA_INT_FLAG_TBU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U), /*!< transmit buffer unavailable status flag */ + ENET_DMA_INT_FLAG_TJT_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U), /*!< transmit jabber timeout status flag */ + ENET_DMA_INT_FLAG_RO_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U), /*!< receive overflow status flag */ + ENET_DMA_INT_FLAG_TU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U), /*!< transmit underflow status flag */ + ENET_DMA_INT_FLAG_RS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U), /*!< receive status flag */ + ENET_DMA_INT_FLAG_RBU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U), /*!< receive buffer unavailable status flag */ + ENET_DMA_INT_FLAG_RPS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U), /*!< receive process stopped status flag */ + ENET_DMA_INT_FLAG_RWT_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U), /*!< receive watchdog timeout status flag */ + ENET_DMA_INT_FLAG_ET_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U), /*!< early transmit status flag */ + ENET_DMA_INT_FLAG_FBE_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U), /*!< fatal bus error status flag */ + ENET_DMA_INT_FLAG_ER_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U), /*!< early receive status flag */ + ENET_DMA_INT_FLAG_AI_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U), /*!< abnormal interrupt summary flag */ + ENET_DMA_INT_FLAG_NI_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U), /*!< normal interrupt summary flag */ +}enet_int_flag_clear_enum; + +/* current RX/TX descriptor/buffer/descriptor table address get */ +typedef enum +{ + ENET_RX_DESC_TABLE = DMA_RDTADDR_REG_OFFSET, /*!< RX descriptor table */ + ENET_RX_CURRENT_DESC = DMA_CRDADDR_REG_OFFSET, /*!< current RX descriptor */ + ENET_RX_CURRENT_BUFFER = DMA_CRBADDR_REG_OFFSET, /*!< current RX buffer */ + ENET_TX_DESC_TABLE = DMA_TDTADDR_REG_OFFSET, /*!< TX descriptor table */ + ENET_TX_CURRENT_DESC = DMA_CTDADDR_REG_OFFSET, /*!< current TX descriptor */ + ENET_TX_CURRENT_BUFFER = DMA_CTBADDR_REG_OFFSET /*!< current TX buffer */ +}enet_desc_reg_enum; + +/* MAC statistics counter get */ +typedef enum +{ + ENET_MSC_TX_SCCNT = MSC_SCCNT_REG_OFFSET, /*!< MSC transmitted good frames after a single collision counter */ + ENET_MSC_TX_MSCCNT = MSC_MSCCNT_REG_OFFSET, /*!< MSC transmitted good frames after more than a single collision counter */ + ENET_MSC_TX_TGFCNT = MSC_TGFCNT_REG_OFFSET, /*!< MSC transmitted good frames counter */ + ENET_MSC_RX_RFCECNT = MSC_RFCECNT_REG_OFFSET, /*!< MSC received frames with CRC error counter */ + ENET_MSC_RX_RFAECNT = MSC_RFAECNT_REG_OFFSET, /*!< MSC received frames with alignment error counter */ + ENET_MSC_RX_RGUFCNT = MSC_RGUFCNT_REG_OFFSET /*!< MSC received good unicast frames counter */ +}enet_msc_counter_enum; + +/* function option, used for ENET initialization */ +typedef enum +{ + FORWARD_OPTION = BIT(0), /*!< configure the frame forward related parameters */ + DMABUS_OPTION = BIT(1), /*!< configure the DMA bus mode related parameters */ + DMA_MAXBURST_OPTION = BIT(2), /*!< configure the DMA max burst related parameters */ + DMA_ARBITRATION_OPTION = BIT(3), /*!< configure the DMA arbitration related parameters */ + STORE_OPTION = BIT(4), /*!< configure the store forward mode related parameters */ + DMA_OPTION = BIT(5), /*!< configure the DMA control related parameters */ + VLAN_OPTION = BIT(6), /*!< configure the VLAN tag related parameters */ + FLOWCTL_OPTION = BIT(7), /*!< configure the flow control related parameters */ + HASHH_OPTION = BIT(8), /*!< configure the hash list high 32-bit related parameters */ + HASHL_OPTION = BIT(9), /*!< configure the hash list low 32-bit related parameters */ + FILTER_OPTION = BIT(10), /*!< configure the frame filter control related parameters */ + HALFDUPLEX_OPTION = BIT(11), /*!< configure the halfduplex related parameters */ + TIMER_OPTION = BIT(12), /*!< configure the frame timer related parameters */ + INTERFRAMEGAP_OPTION = BIT(13), /*!< configure the inter frame gap related parameters */ +}enet_option_enum; + +/* phy mode and mac loopback configurations */ +typedef enum +{ + ENET_AUTO_NEGOTIATION = 0x01u, /*!< PHY auto negotiation */ + ENET_100M_FULLDUPLEX = (ENET_MAC_CFG_SPD | ENET_MAC_CFG_DPM), /*!< 100Mbit/s, full-duplex */ + ENET_100M_HALFDUPLEX = ENET_MAC_CFG_SPD , /*!< 100Mbit/s, half-duplex */ + ENET_10M_FULLDUPLEX = ENET_MAC_CFG_DPM, /*!< 10Mbit/s, full-duplex */ + ENET_10M_HALFDUPLEX = (uint32_t)0x00000000U, /*!< 10Mbit/s, half-duplex */ + ENET_LOOPBACKMODE = (ENET_MAC_CFG_LBM | ENET_MAC_CFG_DPM) /*!< MAC in loopback mode at the MII */ +}enet_mediamode_enum; + +/* IP frame checksum function */ +typedef enum +{ + ENET_NO_AUTOCHECKSUM = (uint32_t)0x00000000U, /*!< disable IP frame checksum function */ + ENET_AUTOCHECKSUM_DROP_FAILFRAMES = ENET_MAC_CFG_IPFCO, /*!< enable IP frame checksum function */ + ENET_AUTOCHECKSUM_ACCEPT_FAILFRAMES = (ENET_MAC_CFG_IPFCO|ENET_DMA_CTL_DTCERFD) /*!< enable IP frame checksum function, and the received frame + with only payload error but no other errors will not be dropped */ +}enet_chksumconf_enum; + +/* received frame filter function */ +typedef enum +{ + ENET_PROMISCUOUS_MODE = ENET_MAC_FRMF_PM, /*!< promiscuous mode enabled */ + ENET_RECEIVEALL = (int32_t)ENET_MAC_FRMF_FAR, /*!< all received frame are forwarded to application */ + ENET_BROADCAST_FRAMES_PASS = (uint32_t)0x00000000U, /*!< the address filters pass all received broadcast frames */ + ENET_BROADCAST_FRAMES_DROP = ENET_MAC_FRMF_BFRMD /*!< the address filters filter all incoming broadcast frames */ +}enet_frmrecept_enum; + +/* register group value get */ +typedef enum +{ + ALL_MAC_REG = 0, /*!< MAC register group */ + ALL_MSC_REG = 22, /*!< MSC register group */ + ALL_PTP_REG = 33, /*!< PTP register group */ + ALL_DMA_REG = 44, /*!< DMA register group */ +}enet_registers_type_enum; + +/* dma direction select */ +typedef enum +{ + ENET_DMA_TX = ENET_DMA_STAT_TP, /*!< DMA transmit direction */ + ENET_DMA_RX = ENET_DMA_STAT_RP /*!< DMA receive direction */ +}enet_dmadirection_enum; + +/* PHY operation direction select */ +typedef enum +{ + ENET_PHY_READ = (uint32_t)0x00000000, /*!< read PHY */ + ENET_PHY_WRITE = ENET_MAC_PHY_CTL_PW /*!< write PHY */ +}enet_phydirection_enum; + +/* register operation direction select */ +typedef enum +{ + ENET_REG_READ, /*!< read register */ + ENET_REG_WRITE /*!< write register */ +}enet_regdirection_enum; + +/* ENET MAC addresses */ +typedef enum +{ + ENET_MAC_ADDRESS0 = ((uint32_t)0x00000000), /*!< MAC address0 */ + ENET_MAC_ADDRESS1 = ((uint32_t)0x00000008), /*!< MAC address1 */ + ENET_MAC_ADDRESS2 = ((uint32_t)0x00000010), /*!< MAC address2 */ + ENET_MAC_ADDRESS3 = ((uint32_t)0x00000018) /*!< MAC address3 */ +}enet_macaddress_enum; + +/* descriptor information */ +typedef enum +{ + TXDESC_COLLISION_COUNT, /*!< the number of collisions occurred before the frame was transmitted */ + TXDESC_BUFFER_1_ADDR, /*!< transmit frame buffer 1 address */ + RXDESC_FRAME_LENGTH, /*!< the byte length of the received frame that was transferred to the buffer */ + RXDESC_BUFFER_1_SIZE, /*!< receive buffer 1 size */ + RXDESC_BUFFER_2_SIZE, /*!< receive buffer 2 size */ + RXDESC_BUFFER_1_ADDR /*!< receive frame buffer 1 address */ +}enet_descstate_enum; + +/* MSC counters preset mode */ +typedef enum +{ + ENET_MSC_PRESET_NONE = 0U, /*!< do not preset MSC counter */ + ENET_MSC_PRESET_HALF = ENET_MSC_CTL_PMC, /*!< preset all MSC counters to almost-half(0x7FFF FFF0) value */ + ENET_MSC_PRESET_FULL = ENET_MSC_CTL_PMC | ENET_MSC_CTL_AFHPM /*!< preset all MSC counters to almost-full(0xFFFF FFF0) value */ +}enet_msc_preset_enum; + +typedef enum{ + ENET_CKNT_ORDINARY = PTP_TSCTL_CKNT(0), /*!< type of ordinary clock node type for timestamp */ + ENET_CKNT_BOUNDARY = PTP_TSCTL_CKNT(1), /*!< type of boundary clock node type for timestamp */ + ENET_CKNT_END_TO_END = PTP_TSCTL_CKNT(2), /*!< type of end-to-end transparent clock node type for timestamp */ + ENET_CKNT_PEER_TO_PEER = PTP_TSCTL_CKNT(3), /*!< type of peer-to-peer transparent clock node type for timestamp */ + ENET_PTP_SYSTIME_INIT = ENET_PTP_TSCTL_TMSSTI, /*!< timestamp initialize */ + ENET_PTP_SYSTIME_UPDATE = ENET_PTP_TSCTL_TMSSTU, /*!< timestamp update */ + ENET_PTP_ADDEND_UPDATE = ENET_PTP_TSCTL_TMSARU, /*!< addend register update */ + ENET_PTP_FINEMODE = (int32_t)(ENET_PTP_TSCTL_TMSFCU| BIT(31)), /*!< the system timestamp uses the fine method for updating */ + ENET_PTP_COARSEMODE = ENET_PTP_TSCTL_TMSFCU, /*!< the system timestamp uses the coarse method for updating */ + ENET_SUBSECOND_DIGITAL_ROLLOVER = (int32_t)(ENET_PTP_TSCTL_SCROM | BIT(31)), /*!< digital rollover mode */ + ENET_SUBSECOND_BINARY_ROLLOVER = ENET_PTP_TSCTL_SCROM, /*!< binary rollover mode */ + ENET_SNOOPING_PTP_VERSION_2 = (int32_t)(ENET_PTP_TSCTL_PFSV| BIT(31)), /*!< version 2 */ + ENET_SNOOPING_PTP_VERSION_1 = ENET_PTP_TSCTL_PFSV, /*!< version 1 */ + ENET_EVENT_TYPE_MESSAGES_SNAPSHOT = (int32_t)(ENET_PTP_TSCTL_ETMSEN| BIT(31)), /*!< only event type messages are taken snapshot */ + ENET_ALL_TYPE_MESSAGES_SNAPSHOT = ENET_PTP_TSCTL_ETMSEN, /*!< all type messages are taken snapshot except announce, management and signaling message */ + ENET_MASTER_NODE_MESSAGE_SNAPSHOT = (int32_t)(ENET_PTP_TSCTL_MNMSEN| BIT(31)), /*!< snapshot is only take for master node message */ + ENET_SLAVE_NODE_MESSAGE_SNAPSHOT = ENET_PTP_TSCTL_MNMSEN, /*!< snapshot is only taken for slave node message */ +}enet_ptp_function_enum; + +/* structure for initialization of the ENET */ +typedef struct +{ + uint32_t option_enable; /*!< select which function to configure */ + uint32_t forward_frame; /*!< frame forward related parameters */ + uint32_t dmabus_mode; /*!< DMA bus mode related parameters */ + uint32_t dma_maxburst; /*!< DMA max burst related parameters */ + uint32_t dma_arbitration; /*!< DMA Tx and Rx arbitration related parameters */ + uint32_t store_forward_mode; /*!< store forward mode related parameters */ + uint32_t dma_function; /*!< DMA control related parameters */ + uint32_t vlan_config; /*!< VLAN tag related parameters */ + uint32_t flow_control; /*!< flow control related parameters */ + uint32_t hashtable_high; /*!< hash list high 32-bit related parameters */ + uint32_t hashtable_low; /*!< hash list low 32-bit related parameters */ + uint32_t framesfilter_mode; /*!< frame filter control related parameters */ + uint32_t halfduplex_param; /*!< halfduplex related parameters */ + uint32_t timer_config; /*!< frame timer related parameters */ + uint32_t interframegap; /*!< inter frame gap related parameters */ +}enet_initpara_struct; + +/* structure for ENET DMA desciptors */ +typedef struct +{ + uint32_t status; /*!< status */ + uint32_t control_buffer_size; /*!< control and buffer1, buffer2 lengths */ + uint32_t buffer1_addr; /*!< buffer1 address pointer/timestamp low */ + uint32_t buffer2_next_desc_addr; /*!< buffer2 or next descriptor address pointer/timestamp high */ + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE + uint32_t extended_status; /*!< extended status */ + uint32_t reserved; /*!< reserved */ + uint32_t timestamp_low; /*!< timestamp low */ + uint32_t timestamp_high; /*!< timestamp high */ +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +} enet_descriptors_struct; + +/* structure of PTP system time */ +typedef struct +{ + uint32_t second; /*!< second of system time */ + uint32_t subsecond; /*!< subsecond of system time */ + uint32_t sign; /*!< sign of system time */ +}enet_ptp_systime_struct; + +/* mac_cfg register value */ +#define MAC_CFG_BOL(regval) (BITS(5,6) & ((uint32_t)(regval) << 5)) /*!< write value to ENET_MAC_CFG_BOL bit field */ +#define ENET_BACKOFFLIMIT_10 MAC_CFG_BOL(0) /*!< min (n, 10) */ +#define ENET_BACKOFFLIMIT_8 MAC_CFG_BOL(1) /*!< min (n, 8) */ +#define ENET_BACKOFFLIMIT_4 MAC_CFG_BOL(2) /*!< min (n, 4) */ +#define ENET_BACKOFFLIMIT_1 MAC_CFG_BOL(3) /*!< min (n, 1) */ + +#define MAC_CFG_IGBS(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) /*!< write value to ENET_MAC_CFG_IGBS bit field */ +#define ENET_INTERFRAMEGAP_96BIT MAC_CFG_IGBS(0) /*!< minimum 96 bit times */ +#define ENET_INTERFRAMEGAP_88BIT MAC_CFG_IGBS(1) /*!< minimum 88 bit times */ +#define ENET_INTERFRAMEGAP_80BIT MAC_CFG_IGBS(2) /*!< minimum 80 bit times */ +#define ENET_INTERFRAMEGAP_72BIT MAC_CFG_IGBS(3) /*!< minimum 72 bit times */ +#define ENET_INTERFRAMEGAP_64BIT MAC_CFG_IGBS(4) /*!< minimum 64 bit times */ +#define ENET_INTERFRAMEGAP_56BIT MAC_CFG_IGBS(5) /*!< minimum 56 bit times */ +#define ENET_INTERFRAMEGAP_48BIT MAC_CFG_IGBS(6) /*!< minimum 48 bit times */ +#define ENET_INTERFRAMEGAP_40BIT MAC_CFG_IGBS(7) /*!< minimum 40 bit times */ + +#define ENET_TYPEFRAME_CRC_DROP_ENABLE ENET_MAC_CFG_TFCD /*!< FCS field(last 4 bytes) of frame will be dropped before forwarding */ +#define ENET_TYPEFRAME_CRC_DROP_DISABLE ((uint32_t)0x00000000U) /*!< FCS field(last 4 bytes) of frame will not be dropped before forwarding */ +#define ENET_TYPEFRAME_CRC_DROP ENET_MAC_CFG_TFCD /*!< the function that FCS field(last 4 bytes) of frame will be dropped before forwarding */ + +#define ENET_WATCHDOG_ENABLE ((uint32_t)0x00000000U) /*!< the MAC allows no more than 2048 bytes of the frame being received */ +#define ENET_WATCHDOG_DISABLE ENET_MAC_CFG_WDD /*!< the MAC disables the watchdog timer on the receiver, and can receive frames of up to 16384 bytes */ + +#define ENET_JABBER_ENABLE ((uint32_t)0x00000000U) /*!< the maximum transmission byte is 2048 */ +#define ENET_JABBER_DISABLE ENET_MAC_CFG_JBD /*!< the maximum transmission byte can be 16384 */ + +#define ENET_CARRIERSENSE_ENABLE ((uint32_t)0x00000000U) /*!< the MAC transmitter generates carrier sense error and aborts the transmission */ +#define ENET_CARRIERSENSE_DISABLE ENET_MAC_CFG_CSD /*!< the MAC transmitter ignores the MII CRS signal during frame transmission in half-duplex mode */ + +#define ENET_SPEEDMODE_10M ((uint32_t)0x00000000U) /*!< 10 Mbit/s */ +#define ENET_SPEEDMODE_100M ENET_MAC_CFG_SPD /*!< 100 Mbit/s */ + +#define ENET_RECEIVEOWN_ENABLE ((uint32_t)0x00000000U) /*!< the MAC receives all packets that are given by the PHY while transmitting */ +#define ENET_RECEIVEOWN_DISABLE ENET_MAC_CFG_ROD /*!< the MAC disables the reception of frames in half-duplex mode */ + +#define ENET_LOOPBACKMODE_ENABLE ENET_MAC_CFG_LBM /*!< the MAC operates in loopback mode at the MII */ +#define ENET_LOOPBACKMODE_DISABLE ((uint32_t)0x00000000U) /*!< the MAC operates in normal mode */ + +#define ENET_MODE_FULLDUPLEX ENET_MAC_CFG_DPM /*!< full-duplex mode enable */ +#define ENET_MODE_HALFDUPLEX ((uint32_t)0x00000000U) /*!< half-duplex mode enable */ + +#define ENET_CHECKSUMOFFLOAD_ENABLE ENET_MAC_CFG_IPFCO /*!< IP frame checksum offload function enabled for received IP frame */ +#define ENET_CHECKSUMOFFLOAD_DISABLE ((uint32_t)0x00000000U) /*!< the checksum offload function in the receiver is disabled */ + +#define ENET_RETRYTRANSMISSION_ENABLE ((uint32_t)0x00000000U) /*!< the MAC attempts retries up to 16 times based on the settings of BOL*/ +#define ENET_RETRYTRANSMISSION_DISABLE ENET_MAC_CFG_RTD /*!< the MAC attempts only 1 transmission */ + +#define ENET_AUTO_PADCRC_DROP_ENABLE ENET_MAC_CFG_APCD /*!< the MAC strips the Pad/FCS field on received frames */ +#define ENET_AUTO_PADCRC_DROP_DISABLE ((uint32_t)0x00000000U) /*!< the MAC forwards all received frames without modify it */ +#define ENET_AUTO_PADCRC_DROP ENET_MAC_CFG_APCD /*!< the function of the MAC strips the Pad/FCS field on received frames */ + +#define ENET_DEFERRALCHECK_ENABLE ENET_MAC_CFG_DFC /*!< the deferral check function is enabled in the MAC */ +#define ENET_DEFERRALCHECK_DISABLE ((uint32_t)0x00000000U) /*!< the deferral check function is disabled */ + +/* mac_frmf register value */ +#define MAC_FRMF_PCFRM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6)) /*!< write value to ENET_MAC_FRMF_PCFRM bit field */ +#define ENET_PCFRM_PREVENT_ALL MAC_FRMF_PCFRM(0) /*!< MAC prevents all control frames from reaching the application */ +#define ENET_PCFRM_PREVENT_PAUSEFRAME MAC_FRMF_PCFRM(1) /*!< MAC only forwards all other control frames except pause control frame */ +#define ENET_PCFRM_FORWARD_ALL MAC_FRMF_PCFRM(2) /*!< MAC forwards all control frames to application even if they fail the address filter */ +#define ENET_PCFRM_FORWARD_FILTERED MAC_FRMF_PCFRM(3) /*!< MAC forwards control frames that only pass the address filter */ + +#define ENET_RX_FILTER_DISABLE ENET_MAC_FRMF_FAR /*!< all received frame are forwarded to application */ +#define ENET_RX_FILTER_ENABLE ((uint32_t)0x00000000U) /*!< only the frame passed the filter can be forwarded to application */ + +#define ENET_SRC_FILTER_NORMAL_ENABLE ENET_MAC_FRMF_SAFLT /*!< filter source address */ +#define ENET_SRC_FILTER_INVERSE_ENABLE (ENET_MAC_FRMF_SAFLT | ENET_MAC_FRMF_SAIFLT) /*!< inverse source address filtering result */ +#define ENET_SRC_FILTER_DISABLE ((uint32_t)0x00000000U) /*!< source address function in filter disable */ +#define ENET_SRC_FILTER ENET_MAC_FRMF_SAFLT /*!< filter source address function */ +#define ENET_SRC_FILTER_INVERSE ENET_MAC_FRMF_SAIFLT /*!< inverse source address filtering result function */ + +#define ENET_BROADCASTFRAMES_ENABLE ((uint32_t)0x00000000U) /*!< the address filters pass all received broadcast frames */ +#define ENET_BROADCASTFRAMES_DISABLE ENET_MAC_FRMF_BFRMD /*!< the address filters filter all incoming broadcast frames */ + +#define ENET_DEST_FILTER_INVERSE_ENABLE ENET_MAC_FRMF_DAIFLT /*!< inverse DA filtering result */ +#define ENET_DEST_FILTER_INVERSE_DISABLE ((uint32_t)0x00000000U) /*!< not inverse DA filtering result */ +#define ENET_DEST_FILTER_INVERSE ENET_MAC_FRMF_DAIFLT /*!< inverse DA filtering result function */ + +#define ENET_PROMISCUOUS_ENABLE ENET_MAC_FRMF_PM /*!< promiscuous mode enabled */ +#define ENET_PROMISCUOUS_DISABLE ((uint32_t)0x00000000U) /*!< promiscuous mode disabled */ + +#define ENET_MULTICAST_FILTER_HASH_OR_PERFECT (ENET_MAC_FRMF_HMF | ENET_MAC_FRMF_HPFLT) /*!< pass multicast frames that match either the perfect or the hash filtering */ +#define ENET_MULTICAST_FILTER_HASH ENET_MAC_FRMF_HMF /*!< pass multicast frames that match the hash filtering */ +#define ENET_MULTICAST_FILTER_PERFECT ((uint32_t)0x00000000U) /*!< pass multicast frames that match the perfect filtering */ +#define ENET_MULTICAST_FILTER_NONE ENET_MAC_FRMF_MFD /*!< all multicast frames are passed */ +#define ENET_MULTICAST_FILTER_PASS ENET_MAC_FRMF_MFD /*!< pass all multicast frames function */ +#define ENET_MULTICAST_FILTER_HASH_MODE ENET_MAC_FRMF_HMF /*!< HASH multicast filter function */ +#define ENET_FILTER_MODE_EITHER ENET_MAC_FRMF_HPFLT /*!< HASH or perfect filter function */ + +#define ENET_UNICAST_FILTER_EITHER (ENET_MAC_FRMF_HUF | ENET_MAC_FRMF_HPFLT) /*!< pass unicast frames that match either the perfect or the hash filtering */ +#define ENET_UNICAST_FILTER_HASH ENET_MAC_FRMF_HUF /*!< pass unicast frames that match the hash filtering */ +#define ENET_UNICAST_FILTER_PERFECT ((uint32_t)0x00000000U) /*!< pass unicast frames that match the perfect filtering */ +#define ENET_UNICAST_FILTER_HASH_MODE ENET_MAC_FRMF_HUF /*!< HASH unicast filter function */ + +/* mac_phy_ctl register value */ +#define MAC_PHY_CTL_CLR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) /*!< write value to ENET_MAC_PHY_CTL_CLR bit field */ +#define ENET_MDC_HCLK_DIV42 MAC_PHY_CTL_CLR(0) /*!< HCLK:60-100 MHz; MDC clock= HCLK/42 */ +#define ENET_MDC_HCLK_DIV62 MAC_PHY_CTL_CLR(1) /*!< HCLK:100-150 MHz; MDC clock= HCLK/62 */ +#define ENET_MDC_HCLK_DIV16 MAC_PHY_CTL_CLR(2) /*!< HCLK:20-35 MHz; MDC clock= HCLK/16 */ +#define ENET_MDC_HCLK_DIV26 MAC_PHY_CTL_CLR(3) /*!< HCLK:35-60 MHz; MDC clock= HCLK/26 */ +#define ENET_MDC_HCLK_DIV102 MAC_PHY_CTL_CLR(4) /*!< HCLK:150-200 MHz; MDC clock= HCLK/102 */ + +#define MAC_PHY_CTL_PR(regval) (BITS(6,10) & ((uint32_t)(regval) << 6)) /*!< write value to ENET_MAC_PHY_CTL_PR bit field */ + +#define MAC_PHY_CTL_PA(regval) (BITS(11,15) & ((uint32_t)(regval) << 11)) /*!< write value to ENET_MAC_PHY_CTL_PA bit field */ + +/* mac_phy_data register value */ +#define MAC_PHY_DATA_PD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) /*!< write value to ENET_MAC_PHY_DATA_PD bit field */ + +/* mac_fctl register value */ +#define MAC_FCTL_PLTS(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) /*!< write value to ENET_MAC_FCTL_PLTS bit field */ +#define ENET_PAUSETIME_MINUS4 MAC_FCTL_PLTS(0) /*!< pause time minus 4 slot times */ +#define ENET_PAUSETIME_MINUS28 MAC_FCTL_PLTS(1) /*!< pause time minus 28 slot times */ +#define ENET_PAUSETIME_MINUS144 MAC_FCTL_PLTS(2) /*!< pause time minus 144 slot times */ +#define ENET_PAUSETIME_MINUS256 MAC_FCTL_PLTS(3) /*!< pause time minus 256 slot times */ + +#define ENET_ZERO_QUANTA_PAUSE_ENABLE ((uint32_t)0x00000000U) /*!< enable the automatic zero-quanta generation function */ +#define ENET_ZERO_QUANTA_PAUSE_DISABLE ENET_MAC_FCTL_DZQP /*!< disable the automatic zero-quanta generation function */ +#define ENET_ZERO_QUANTA_PAUSE ENET_MAC_FCTL_DZQP /*!< the automatic zero-quanta generation function */ + +#define ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT ENET_MAC_FCTL_UPFDT /*!< besides the unique multicast address, MAC also use the MAC0 address to detect pause frame */ +#define ENET_UNIQUE_PAUSEDETECT ((uint32_t)0x00000000U) /*!< only the unique multicast address for pause frame which is specified in IEEE802.3 can be detected */ + +#define ENET_RX_FLOWCONTROL_ENABLE ENET_MAC_FCTL_RFCEN /*!< enable decoding function for the received pause frame and process it */ +#define ENET_RX_FLOWCONTROL_DISABLE ((uint32_t)0x00000000U) /*!< decode function for pause frame is disabled */ +#define ENET_RX_FLOWCONTROL ENET_MAC_FCTL_RFCEN /*!< decoding function for the received pause frame and process it */ + +#define ENET_TX_FLOWCONTROL_ENABLE ENET_MAC_FCTL_TFCEN /*!< enable the flow control operation in the MAC */ +#define ENET_TX_FLOWCONTROL_DISABLE ((uint32_t)0x00000000U) /*!< disable the flow control operation in the MAC */ +#define ENET_TX_FLOWCONTROL ENET_MAC_FCTL_TFCEN /*!< the flow control operation in the MAC */ + +#define ENET_BACK_PRESSURE_ENABLE ENET_MAC_FCTL_FLCBBKPA /*!< enable the back pressure operation in the MAC */ +#define ENET_BACK_PRESSURE_DISABLE ((uint32_t)0x00000000U) /*!< disable the back pressure operation in the MAC */ +#define ENET_BACK_PRESSURE ENET_MAC_FCTL_FLCBBKPA /*!< the back pressure operation in the MAC */ + +#define MAC_FCTL_PTM(regval) (BITS(16,31) & ((uint32_t)(regval) << 16)) /*!< write value to ENET_MAC_FCTL_PTM bit field */ +/* mac_vlt register value */ +#define MAC_VLT_VLTI(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) /*!< write value to ENET_MAC_VLT_VLTI bit field */ + +#define ENET_VLANTAGCOMPARISON_12BIT ENET_MAC_VLT_VLTC /*!< only low 12 bits of the VLAN tag are used for comparison */ +#define ENET_VLANTAGCOMPARISON_16BIT ((uint32_t)0x00000000U) /*!< all 16 bits of the VLAN tag are used for comparison */ + +/* mac_wum register value */ +#define ENET_WUM_FLAG_WUFFRPR ENET_MAC_WUM_WUFFRPR /*!< wakeup frame filter register poniter reset */ +#define ENET_WUM_FLAG_WUFR ENET_MAC_WUM_WUFR /*!< wakeup frame received */ +#define ENET_WUM_FLAG_MPKR ENET_MAC_WUM_MPKR /*!< magic packet received */ +#define ENET_WUM_POWER_DOWN ENET_MAC_WUM_PWD /*!< power down mode */ +#define ENET_WUM_MAGIC_PACKET_FRAME ENET_MAC_WUM_MPEN /*!< enable a wakeup event due to magic packet reception */ +#define ENET_WUM_WAKE_UP_FRAME ENET_MAC_WUM_WFEN /*!< enable a wakeup event due to wakeup frame reception */ +#define ENET_WUM_GLOBAL_UNICAST ENET_MAC_WUM_GU /*!< any received unicast frame passed filter is considered to be a wakeup frame */ +/* mac_dbg register value */ +#define ENET_MAC_RECEIVER_NOT_IDLE ENET_MAC_DBG_MRNI /*!< MAC receiver is not in idle state */ +#define ENET_RX_ASYNCHRONOUS_FIFO_STATE ENET_MAC_DBG_RXAFS /*!< Rx asynchronous FIFO status */ +#define ENET_RXFIFO_NOT_WRITING ENET_MAC_DBG_RXFW /*!< RxFIFO is not doing write operation */ +#define ENET_RXFIFO_READ_STATUS ENET_MAC_DBG_RXFRS /*!< RxFIFO read operation status */ +#define ENET_RXFIFO_STATE ENET_MAC_DBG_RXFS /*!< RxFIFO state */ +#define ENET_MAC_TRANSMITTER_NOT_IDLE ENET_MAC_DBG_MTNI /*!< MAC transmitter is not in idle state */ +#define ENET_MAC_TRANSMITTER_STATUS ENET_MAC_DBG_SOMT /*!< status of MAC transmitter */ +#define ENET_PAUSE_CONDITION_STATUS ENET_MAC_DBG_PCS /*!< pause condition status */ +#define ENET_TXFIFO_READ_STATUS ENET_MAC_DBG_TXFRS /*!< TxFIFO read operation status */ +#define ENET_TXFIFO_NOT_WRITING ENET_MAC_DBG_TXFW /*!< TxFIFO is not doing write operation */ +#define ENET_TXFIFO_NOT_EMPTY ENET_MAC_DBG_TXFNE /*!< TxFIFO is not empty */ +#define ENET_TXFIFO_FULL ENET_MAC_DBG_TXFF /*!< TxFIFO is full */ + +#define GET_MAC_DBG_RXAFS(regval) GET_BITS((regval),1,2) /*!< get value of ENET_MAC_DBG_RXAFS bit field */ + +#define GET_MAC_DBG_RXFRS(regval) GET_BITS((regval),5,6) /*!< get value of ENET_MAC_DBG_RXFRS bit field */ + +#define GET_MAC_DBG_RXFS(regval) GET_BITS((regval),8,9) /*!< get value of ENET_MAC_DBG_RXFS bit field */ + +#define GET_MAC_DBG_SOMT(regval) GET_BITS((regval),17,18) /*!< get value of ENET_MAC_DBG_SOMT bit field */ + +#define GET_MAC_DBG_TXFRS(regval) GET_BITS((regval),20,21) /*!< get value of ENET_MAC_DBG_TXFRS bit field */ + +/* mac_addr0h register value */ +#define MAC_ADDR0H_ADDR0H(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) /*!< write value to ENET_MAC_ADDR0H_ADDR0H bit field */ + +/* mac_addrxh register value, x = 1,2,3 */ +#define MAC_ADDR123H_ADDR123H(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) /*!< write value to ENET_MAC_ADDRxH_ADDRxH(x=1,2,3) bit field */ + +#define ENET_ADDRESS_MASK_BYTE0 BIT(24) /*!< low register bits [7:0] */ +#define ENET_ADDRESS_MASK_BYTE1 BIT(25) /*!< low register bits [15:8] */ +#define ENET_ADDRESS_MASK_BYTE2 BIT(26) /*!< low register bits [23:16] */ +#define ENET_ADDRESS_MASK_BYTE3 BIT(27) /*!< low register bits [31:24] */ +#define ENET_ADDRESS_MASK_BYTE4 BIT(28) /*!< high register bits [7:0] */ +#define ENET_ADDRESS_MASK_BYTE5 BIT(29) /*!< high register bits [15:8] */ + +#define ENET_ADDRESS_FILTER_SA BIT(30) /*!< use MAC address[47:0] is to compare with the SA fields of the received frame */ +#define ENET_ADDRESS_FILTER_DA ((uint32_t)0x00000000) /*!< use MAC address[47:0] is to compare with the DA fields of the received frame */ + +/* mac_fcth register value */ +#define MAC_FCTH_RFA(regval) ((BITS(0,2) & ((uint32_t)(regval) << 0))<<8) /*!< write value to ENET_MAC_FCTH_RFA bit field */ +#define ENET_ACTIVE_THRESHOLD_256BYTES MAC_FCTH_RFA(0) /*!< threshold level is 256 bytes */ +#define ENET_ACTIVE_THRESHOLD_512BYTES MAC_FCTH_RFA(1) /*!< threshold level is 512 bytes */ +#define ENET_ACTIVE_THRESHOLD_768BYTES MAC_FCTH_RFA(2) /*!< threshold level is 768 bytes */ +#define ENET_ACTIVE_THRESHOLD_1024BYTES MAC_FCTH_RFA(3) /*!< threshold level is 1024 bytes */ +#define ENET_ACTIVE_THRESHOLD_1280BYTES MAC_FCTH_RFA(4) /*!< threshold level is 1280 bytes */ +#define ENET_ACTIVE_THRESHOLD_1536BYTES MAC_FCTH_RFA(5) /*!< threshold level is 1536 bytes */ +#define ENET_ACTIVE_THRESHOLD_1792BYTES MAC_FCTH_RFA(6) /*!< threshold level is 1792 bytes */ + +#define MAC_FCTH_RFD(regval) ((BITS(4,6) & ((uint32_t)(regval) << 4))<<8) /*!< write value to ENET_MAC_FCTH_RFD bit field */ +#define ENET_DEACTIVE_THRESHOLD_256BYTES MAC_FCTH_RFD(0) /*!< threshold level is 256 bytes */ +#define ENET_DEACTIVE_THRESHOLD_512BYTES MAC_FCTH_RFD(1) /*!< threshold level is 512 bytes */ +#define ENET_DEACTIVE_THRESHOLD_768BYTES MAC_FCTH_RFD(2) /*!< threshold level is 768 bytes */ +#define ENET_DEACTIVE_THRESHOLD_1024BYTES MAC_FCTH_RFD(3) /*!< threshold level is 1024 bytes */ +#define ENET_DEACTIVE_THRESHOLD_1280BYTES MAC_FCTH_RFD(4) /*!< threshold level is 1280 bytes */ +#define ENET_DEACTIVE_THRESHOLD_1536BYTES MAC_FCTH_RFD(5) /*!< threshold level is 1536 bytes */ +#define ENET_DEACTIVE_THRESHOLD_1792BYTES MAC_FCTH_RFD(6) /*!< threshold level is 1792 bytes */ + +/* msc_ctl register value */ +#define ENET_MSC_COUNTER_STOP_ROLLOVER ENET_MSC_CTL_CTSR /*!< counter stop rollover */ +#define ENET_MSC_RESET_ON_READ ENET_MSC_CTL_RTOR /*!< reset on read */ +#define ENET_MSC_COUNTERS_FREEZE ENET_MSC_CTL_MCFZ /*!< MSC counter freeze */ + +/* ptp_tsctl register value */ +#define ENET_RXTX_TIMESTAMP ENET_PTP_TSCTL_TMSEN /*!< enable timestamp function for transmit and receive frames */ +#define ENET_PTP_TIMESTAMP_INT ENET_PTP_TSCTL_TMSITEN /*!< timestamp interrupt trigger enable */ +#define ENET_ALL_RX_TIMESTAMP ENET_PTP_TSCTL_ARFSEN /*!< all received frames are taken snapshot */ +#define ENET_NONTYPE_FRAME_SNAPSHOT ENET_PTP_TSCTL_ESEN /*!< take snapshot when received non type frame */ +#define ENET_IPV6_FRAME_SNAPSHOT ENET_PTP_TSCTL_IP6SEN /*!< take snapshot for IPv6 frame */ +#define ENET_IPV4_FRAME_SNAPSHOT ENET_PTP_TSCTL_IP4SEN /*!< take snapshot for IPv4 frame */ +#define ENET_PTP_FRAME_USE_MACADDRESS_FILTER ENET_PTP_TSCTL_MAFEN /*!< enable MAC address1-3 to filter the PTP frame */ + +/* ptp_ssinc register value */ +#define PTP_SSINC_STMSSI(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) /*!< write value to ENET_PTP_SSINC_STMSSI bit field */ + +/* ptp_tsl register value */ +#define GET_PTP_TSL_STMSS(regval) GET_BITS((uint32_t)(regval),0,30) /*!< get value of ENET_PTP_TSL_STMSS bit field */ + +#define ENET_PTP_TIME_POSITIVE ((uint32_t)0x00000000) /*!< time value is positive */ +#define ENET_PTP_TIME_NEGATIVE ENET_PTP_TSL_STS /*!< time value is negative */ + +#define GET_PTP_TSL_STS(regval) (((regval) & BIT(31)) >> (31U)) /*!< get value of ENET_PTP_TSL_STS bit field */ + +/* ptp_tsul register value */ +#define PTP_TSUL_TMSUSS(regval) (BITS(0,30) & ((uint32_t)(regval) << 0)) /*!< write value to ENET_PTP_TSUL_TMSUSS bit field */ + +#define ENET_PTP_ADD_TO_TIME ((uint32_t)0x00000000) /*!< timestamp update value is added to system time */ +#define ENET_PTP_SUBSTRACT_FROM_TIME ENET_PTP_TSUL_TMSUPNS /*!< timestamp update value is subtracted from system time */ + +/* ptp_ppsctl register value */ +#define PTP_PPSCTL_PPSOFC(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) /*!< write value to ENET_PTP_PPSCTL_PPSOFC bit field */ +#define ENET_PPSOFC_1HZ PTP_PPSCTL_PPSOFC(0) /*!< PPS output 1Hz frequency */ +#define ENET_PPSOFC_2HZ PTP_PPSCTL_PPSOFC(1) /*!< PPS output 2Hz frequency */ +#define ENET_PPSOFC_4HZ PTP_PPSCTL_PPSOFC(2) /*!< PPS output 4Hz frequency */ +#define ENET_PPSOFC_8HZ PTP_PPSCTL_PPSOFC(3) /*!< PPS output 8Hz frequency */ +#define ENET_PPSOFC_16HZ PTP_PPSCTL_PPSOFC(4) /*!< PPS output 16Hz frequency */ +#define ENET_PPSOFC_32HZ PTP_PPSCTL_PPSOFC(5) /*!< PPS output 32Hz frequency */ +#define ENET_PPSOFC_64HZ PTP_PPSCTL_PPSOFC(6) /*!< PPS output 64Hz frequency */ +#define ENET_PPSOFC_128HZ PTP_PPSCTL_PPSOFC(7) /*!< PPS output 128Hz frequency */ +#define ENET_PPSOFC_256HZ PTP_PPSCTL_PPSOFC(8) /*!< PPS output 256Hz frequency */ +#define ENET_PPSOFC_512HZ PTP_PPSCTL_PPSOFC(9) /*!< PPS output 512Hz frequency */ +#define ENET_PPSOFC_1024HZ PTP_PPSCTL_PPSOFC(10) /*!< PPS output 1024Hz frequency */ +#define ENET_PPSOFC_2048HZ PTP_PPSCTL_PPSOFC(11) /*!< PPS output 2048Hz frequency */ +#define ENET_PPSOFC_4096HZ PTP_PPSCTL_PPSOFC(12) /*!< PPS output 4096Hz frequency */ +#define ENET_PPSOFC_8192HZ PTP_PPSCTL_PPSOFC(13) /*!< PPS output 8192Hz frequency */ +#define ENET_PPSOFC_16384HZ PTP_PPSCTL_PPSOFC(14) /*!< PPS output 16384Hz frequency */ +#define ENET_PPSOFC_32768HZ PTP_PPSCTL_PPSOFC(15) /*!< PPS output 32768Hz frequency */ + +/* dma_bctl register value */ +#define DMA_BCTL_DPSL(regval) (BITS(2,6) & ((uint32_t)(regval) << 2)) /*!< write value to ENET_DMA_BCTL_DPSL bit field */ +#define GET_DMA_BCTL_DPSL(regval) GET_BITS((regval),2,6) /*!< get value of ENET_DMA_BCTL_DPSL bit field */ + +#define ENET_ENHANCED_DESCRIPTOR ENET_DMA_BCTL_DFM /*!< enhanced mode descriptor */ +#define ENET_NORMAL_DESCRIPTOR ((uint32_t)0x00000000) /*!< normal mode descriptor */ + +#define DMA_BCTL_PGBL(regval) (BITS(8,13) & ((uint32_t)(regval) << 8)) /*!< write value to ENET_DMA_BCTL_PGBL bit field */ +#define ENET_PGBL_1BEAT DMA_BCTL_PGBL(1) /*!< maximum number of beats is 1 */ +#define ENET_PGBL_2BEAT DMA_BCTL_PGBL(2) /*!< maximum number of beats is 2 */ +#define ENET_PGBL_4BEAT DMA_BCTL_PGBL(4) /*!< maximum number of beats is 4 */ +#define ENET_PGBL_8BEAT DMA_BCTL_PGBL(8) /*!< maximum number of beats is 8 */ +#define ENET_PGBL_16BEAT DMA_BCTL_PGBL(16) /*!< maximum number of beats is 16 */ +#define ENET_PGBL_32BEAT DMA_BCTL_PGBL(32) /*!< maximum number of beats is 32 */ +#define ENET_PGBL_4xPGBL_4BEAT (DMA_BCTL_PGBL(1)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 4 */ +#define ENET_PGBL_4xPGBL_8BEAT (DMA_BCTL_PGBL(2)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 8 */ +#define ENET_PGBL_4xPGBL_16BEAT (DMA_BCTL_PGBL(4)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 16 */ +#define ENET_PGBL_4xPGBL_32BEAT (DMA_BCTL_PGBL(8)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 32 */ +#define ENET_PGBL_4xPGBL_64BEAT (DMA_BCTL_PGBL(16)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 64 */ +#define ENET_PGBL_4xPGBL_128BEAT (DMA_BCTL_PGBL(32)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 128 */ + +#define DMA_BCTL_RTPR(regval) (BITS(14,15) & ((uint32_t)(regval) << 14)) /*!< write value to ENET_DMA_BCTL_RTPR bit field */ +#define ENET_ARBITRATION_RXTX_1_1 DMA_BCTL_RTPR(0) /*!< receive and transmit priority ratio is 1:1*/ +#define ENET_ARBITRATION_RXTX_2_1 DMA_BCTL_RTPR(1) /*!< receive and transmit priority ratio is 2:1*/ +#define ENET_ARBITRATION_RXTX_3_1 DMA_BCTL_RTPR(2) /*!< receive and transmit priority ratio is 3:1 */ +#define ENET_ARBITRATION_RXTX_4_1 DMA_BCTL_RTPR(3) /*!< receive and transmit priority ratio is 4:1 */ +#define ENET_ARBITRATION_RXPRIORTX ENET_DMA_BCTL_DAB /*!< RxDMA has higher priority than TxDMA */ + +#define ENET_FIXED_BURST_ENABLE ENET_DMA_BCTL_FB /*!< AHB can only use SINGLE/INCR4/INCR8/INCR16 during start of normal burst transfers */ +#define ENET_FIXED_BURST_DISABLE ((uint32_t)0x00000000) /*!< AHB can use SINGLE/INCR burst transfer operations */ + +#define DMA_BCTL_RXDP(regval) (BITS(17,22) & ((uint32_t)(regval) << 17)) /*!< write value to ENET_DMA_BCTL_RXDP bit field */ +#define ENET_RXDP_1BEAT DMA_BCTL_RXDP(1) /*!< maximum number of beats 1 */ +#define ENET_RXDP_2BEAT DMA_BCTL_RXDP(2) /*!< maximum number of beats 2 */ +#define ENET_RXDP_4BEAT DMA_BCTL_RXDP(4) /*!< maximum number of beats 4 */ +#define ENET_RXDP_8BEAT DMA_BCTL_RXDP(8) /*!< maximum number of beats 8 */ +#define ENET_RXDP_16BEAT DMA_BCTL_RXDP(16) /*!< maximum number of beats 16 */ +#define ENET_RXDP_32BEAT DMA_BCTL_RXDP(32) /*!< maximum number of beats 32 */ +#define ENET_RXDP_4xPGBL_4BEAT (DMA_BCTL_RXDP(1)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 4 */ +#define ENET_RXDP_4xPGBL_8BEAT (DMA_BCTL_RXDP(2)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 8 */ +#define ENET_RXDP_4xPGBL_16BEAT (DMA_BCTL_RXDP(4)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 16 */ +#define ENET_RXDP_4xPGBL_32BEAT (DMA_BCTL_RXDP(8)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 32 */ +#define ENET_RXDP_4xPGBL_64BEAT (DMA_BCTL_RXDP(16)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 64 */ +#define ENET_RXDP_4xPGBL_128BEAT (DMA_BCTL_RXDP(32)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 128 */ + +#define ENET_RXTX_DIFFERENT_PGBL ENET_DMA_BCTL_UIP /*!< RxDMA uses the RXDP[5:0], while TxDMA uses the PGBL[5:0] */ +#define ENET_RXTX_SAME_PGBL ((uint32_t)0x00000000) /*!< RxDMA/TxDMA uses PGBL[5:0] */ + +#define ENET_ADDRESS_ALIGN_ENABLE ENET_DMA_BCTL_AA /*!< enabled address-aligned */ +#define ENET_ADDRESS_ALIGN_DISABLE ((uint32_t)0x00000000) /*!< disable address-aligned */ + +#define ENET_MIXED_BURST_ENABLE ENET_DMA_BCTL_MB /*!< AHB master interface transfer burst length greater than 16 with INCR */ +#define ENET_MIXED_BURST_DISABLE ((uint32_t)0x00000000) /*!< AHB master interface only transfer fixed burst length with 16 and below */ + +/* dma_stat register value */ +#define GET_DMA_STAT_RP(regval) GET_BITS((uint32_t)(regval),17,19) /*!< get value of ENET_DMA_STAT_RP bit field */ +#define ENET_RX_STATE_STOPPED ((uint32_t)0x00000000) /*!< reset or stop rx command issued */ +#define ENET_RX_STATE_FETCHING BIT(17) /*!< fetching the Rx descriptor */ +#define ENET_RX_STATE_WAITING (BIT(17)|BIT(18)) /*!< waiting for receive packet */ +#define ENET_RX_STATE_SUSPENDED BIT(19) /*!< Rx descriptor unavailable */ +#define ENET_RX_STATE_CLOSING (BIT(17)|BIT(19)) /*!< closing receive descriptor */ +#define ENET_RX_STATE_QUEUING ENET_DMA_STAT_RP /*!< transferring the receive packet data from recevie buffer to host memory */ + +#define GET_DMA_STAT_TP(regval) GET_BITS((uint32_t)(regval),20,22) /*!< get value of ENET_DMA_STAT_TP bit field */ +#define ENET_TX_STATE_STOPPED ((uint32_t)0x00000000) /*!< reset or stop Tx Command issued */ +#define ENET_TX_STATE_FETCHING BIT(20) /*!< fetching the Tx descriptor */ +#define ENET_TX_STATE_WAITING BIT(21) /*!< waiting for status */ +#define ENET_TX_STATE_READING (BIT(20)|BIT(21)) /*!< reading the data from host memory buffer and queuing it to transmit buffer */ +#define ENET_TX_STATE_SUSPENDED (BIT(21)|BIT(22)) /*!< Tx descriptor unavailabe or transmit buffer underflow */ +#define ENET_TX_STATE_CLOSING ENET_DMA_STAT_TP /*!< closing Tx descriptor */ + +#define GET_DMA_STAT_EB(regval) GET_BITS((uint32_t)(regval),23,25) /*!< get value of ENET_DMA_STAT_EB bit field */ +#define ENET_ERROR_TXDATA_TRANSFER BIT(23) /*!< error during data transfer by TxDMA or RxDMA */ +#define ENET_ERROR_READ_TRANSFER BIT(24) /*!< error during write transfer or read transfer */ +#define ENET_ERROR_DESC_ACCESS BIT(25) /*!< error during descriptor or buffer access */ + +/* dma_ctl register value */ +#define DMA_CTL_RTHC(regval) (BITS(3,4) & ((uint32_t)(regval) << 3)) /*!< write value to ENET_DMA_CTL_RTHC bit field */ +#define ENET_RX_THRESHOLD_64BYTES DMA_CTL_RTHC(0) /*!< threshold level is 64 Bytes */ +#define ENET_RX_THRESHOLD_32BYTES DMA_CTL_RTHC(1) /*!< threshold level is 32 Bytes */ +#define ENET_RX_THRESHOLD_96BYTES DMA_CTL_RTHC(2) /*!< threshold level is 96 Bytes */ +#define ENET_RX_THRESHOLD_128BYTES DMA_CTL_RTHC(3) /*!< threshold level is 128 Bytes */ + +#define DMA_CTL_TTHC(regval) (BITS(14,16) & ((uint32_t)(regval) << 14)) /*!< write value to ENET_DMA_CTL_TTHC bit field */ +#define ENET_TX_THRESHOLD_64BYTES DMA_CTL_TTHC(0) /*!< threshold level is 64 Bytes */ +#define ENET_TX_THRESHOLD_128BYTES DMA_CTL_TTHC(1) /*!< threshold level is 128 Bytes */ +#define ENET_TX_THRESHOLD_192BYTES DMA_CTL_TTHC(2) /*!< threshold level is 192 Bytes */ +#define ENET_TX_THRESHOLD_256BYTES DMA_CTL_TTHC(3) /*!< threshold level is 256 Bytes */ +#define ENET_TX_THRESHOLD_40BYTES DMA_CTL_TTHC(4) /*!< threshold level is 40 Bytes */ +#define ENET_TX_THRESHOLD_32BYTES DMA_CTL_TTHC(5) /*!< threshold level is 32 Bytes */ +#define ENET_TX_THRESHOLD_24BYTES DMA_CTL_TTHC(6) /*!< threshold level is 24 Bytes */ +#define ENET_TX_THRESHOLD_16BYTES DMA_CTL_TTHC(7) /*!< threshold level is 16 Bytes */ + +#define ENET_TCPIP_CKSUMERROR_ACCEPT ENET_DMA_CTL_DTCERFD /*!< Rx frame with only payload error but no other errors will not be dropped */ +#define ENET_TCPIP_CKSUMERROR_DROP ((uint32_t)0x00000000) /*!< all error frames will be dropped when FERF = 0 */ + +#define ENET_RX_MODE_STOREFORWARD ENET_DMA_CTL_RSFD /*!< RxFIFO operates in store-and-forward mode */ +#define ENET_RX_MODE_CUTTHROUGH ((uint32_t)0x00000000) /*!< RxFIFO operates in cut-through mode */ + +#define ENET_FLUSH_RXFRAME_ENABLE ((uint32_t)0x00000000) /*!< RxDMA flushes all frames */ +#define ENET_FLUSH_RXFRAME_DISABLE ENET_DMA_CTL_DAFRF /*!< RxDMA does not flush any frames */ +#define ENET_FLUSH_RXFRAME ENET_DMA_CTL_DAFRF /*!< RxDMA flushes frames function */ + +#define ENET_TX_MODE_STOREFORWARD ENET_DMA_CTL_TSFD /*!< TxFIFO operates in store-and-forward mode */ +#define ENET_TX_MODE_CUTTHROUGH ((uint32_t)0x00000000) /*!< TxFIFO operates in cut-through mode */ + +#define ENET_FORWARD_ERRFRAMES_ENABLE (ENET_DMA_CTL_FERF<<2) /*!< all frame received with error except runt error are forwarded to memory */ +#define ENET_FORWARD_ERRFRAMES_DISABLE ((uint32_t)0x00000000) /*!< RxFIFO drop error frame */ +#define ENET_FORWARD_ERRFRAMES (ENET_DMA_CTL_FERF<<2) /*!< the function that all frame received with error except runt error are forwarded to memory */ + +#define ENET_FORWARD_UNDERSZ_GOODFRAMES_ENABLE (ENET_DMA_CTL_FUF<<2) /*!< forward undersized good frames */ +#define ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE ((uint32_t)0x00000000) /*!< RxFIFO drops all frames whose length is less than 64 bytes */ +#define ENET_FORWARD_UNDERSZ_GOODFRAMES (ENET_DMA_CTL_FUF<<2) /*!< the function that forwarding undersized good frames */ + +#define ENET_SECONDFRAME_OPT_ENABLE ENET_DMA_CTL_OSF /*!< TxDMA controller operate on second frame mode enable*/ +#define ENET_SECONDFRAME_OPT_DISABLE ((uint32_t)0x00000000) /*!< TxDMA controller operate on second frame mode disable */ +#define ENET_SECONDFRAME_OPT ENET_DMA_CTL_OSF /*!< TxDMA controller operate on second frame function */ +/* dma_mfbocnt register value */ +#define GET_DMA_MFBOCNT_MSFC(regval) GET_BITS((regval),0,15) /*!< get value of ENET_DMA_MFBOCNT_MSFC bit field */ + +#define GET_DMA_MFBOCNT_MSFA(regval) GET_BITS((regval),17,27) /*!< get value of ENET_DMA_MFBOCNT_MSFA bit field */ + +/* dma_rswdc register value */ +#define DMA_RSWDC_WDCFRS(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) /*!< write value to ENET_DMA_RSWDC_WDCFRS bit field */ + +/* dma tx descriptor tdes0 register value */ +#define TDES0_CONT(regval) (BITS(3,6) & ((uint32_t)(regval) << 3)) /*!< write value to ENET DMA TDES0 CONT bit field */ +#define GET_TDES0_COCNT(regval) GET_BITS((regval),3,6) /*!< get value of ENET DMA TDES0 CONT bit field */ + +#define TDES0_CM(regval) (BITS(22,23) & ((uint32_t)(regval) << 22)) /*!< write value to ENET DMA TDES0 CM bit field */ +#define ENET_CHECKSUM_DISABLE TDES0_CM(0) /*!< checksum insertion disabled */ +#define ENET_CHECKSUM_IPV4HEADER TDES0_CM(1) /*!< only IP header checksum calculation and insertion are enabled */ +#define ENET_CHECKSUM_TCPUDPICMP_SEGMENT TDES0_CM(2) /*!< TCP/UDP/ICMP checksum insertion calculated but pseudo-header */ +#define ENET_CHECKSUM_TCPUDPICMP_FULL TDES0_CM(3) /*!< TCP/UDP/ICMP checksum insertion fully calculated */ + +/* dma tx descriptor tdes1 register value */ +#define TDES1_TB1S(regval) (BITS(0,12) & ((uint32_t)(regval) << 0)) /*!< write value to ENET DMA TDES1 TB1S bit field */ + +#define TDES1_TB2S(regval) (BITS(16,28) & ((uint32_t)(regval) << 16)) /*!< write value to ENET DMA TDES1 TB2S bit field */ + +/* dma rx descriptor rdes0 register value */ +#define RDES0_FRML(regval) (BITS(16,29) & ((uint32_t)(regval) << 16)) /*!< write value to ENET DMA RDES0 FRML bit field */ +#define GET_RDES0_FRML(regval) GET_BITS((regval),16,29) /*!< get value of ENET DMA RDES0 FRML bit field */ + +/* dma rx descriptor rdes1 register value */ +#define ENET_RECEIVE_COMPLETE_INT_ENABLE ((uint32_t)0x00000000U) /*!< RS bit immediately set after Rx completed */ +#define ENET_RECEIVE_COMPLETE_INT_DISABLE ENET_RDES1_DINTC /*!< RS bit not immediately set after Rx completed */ + +#define GET_RDES1_RB1S(regval) GET_BITS((regval),0,12) /*!< get value of ENET DMA RDES1 RB1S bit field */ + +#define GET_RDES1_RB2S(regval) GET_BITS((regval),16,28) /*!< get value of ENET DMA RDES1 RB2S bit field */ + +/* dma rx descriptor rdes4 register value */ +#define RDES4_IPPLDT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) /*!< write value to ENET DMA RDES4 IPPLDT bit field */ +#define GET_RDES4_IPPLDT(regval) GET_BITS((regval),0,2) /*!< get value of ENET DMA RDES4 IPPLDT bit field */ + +#define RDES4_PTPMT(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) /*!< write value to ENET DMA RDES4 PTPMT bit field */ +#define GET_RDES4_PTPMT(regval) GET_BITS((regval),8,11) /*!< get value of ENET DMA RDES4 PTPMT bit field */ + +/* ENET register mask value */ +#define MAC_CFG_MASK ((uint32_t)0xFD30810FU) /*!< ENET_MAC_CFG register mask */ +#define MAC_FCTL_MASK ((uint32_t)0x0000FF41U) /*!< ENET_MAC_FCTL register mask */ +#define DMA_CTL_MASK ((uint32_t)0xF8DE3F23U) /*!< ENET_DMA_CTL register mask */ +#define DMA_BCTL_MASK ((uint32_t)0xF800007DU) /*!< ENET_DMA_BCTL register mask */ +#define ENET_MSC_PRESET_MASK (~(ENET_MSC_CTL_PMC | ENET_MSC_CTL_AFHPM)) /*!< ENET_MSC_CTL preset mask */ + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE +#define ETH_DMATXDESC_SIZE 0x20U /*!< TxDMA enhanced descriptor size */ +#define ETH_DMARXDESC_SIZE 0x20U /*!< RxDMA enhanced descriptor size */ +#else +#define ETH_DMATXDESC_SIZE 0x10U /*!< TxDMA descriptor size */ +#define ETH_DMARXDESC_SIZE 0x10U /*!< RxDMA descriptor size */ +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/* ENET remote wake-up frame register length */ +#define ETH_WAKEUP_REGISTER_LENGTH 8U /*!< remote wake-up frame register length */ + +/* ENET frame size */ +#define ENET_MAX_FRAME_SIZE 1524U /*!< header + frame_extra + payload + CRC */ + +/* ENET delay timeout */ +#define ENET_DELAY_TO ((uint32_t)0x0004FFFFU) /*!< ENET delay timeout */ +#define ENET_RESET_TO ((uint32_t)0x000004FFU) /*!< ENET reset timeout */ + + + +/* function declarations */ +/* main function */ +/* deinitialize the ENET, and reset structure parameters for ENET initialization */ +void enet_deinit(void); +/* configure the parameters which are usually less cared for initialization */ +void enet_initpara_config(enet_option_enum option, uint32_t para); +/* initialize ENET peripheral with generally concerned parameters and the less cared parameters */ +ErrStatus enet_init(enet_mediamode_enum mediamode, enet_chksumconf_enum checksum, enet_frmrecept_enum recept); +/* reset all core internal registers located in CLK_TX and CLK_RX */ +ErrStatus enet_software_reset(void); +/* check receive frame valid and return frame size */ +uint32_t enet_rxframe_size_get(void); +/* initialize the dma tx/rx descriptors's parameters in chain mode */ +void enet_descriptors_chain_init(enet_dmadirection_enum direction); +/* initialize the dma tx/rx descriptors's parameters in ring mode */ +void enet_descriptors_ring_init(enet_dmadirection_enum direction); +/* handle current received frame data to application buffer */ +ErrStatus enet_frame_receive(uint8_t *buffer, uint32_t bufsize); +/* handle current received frame but without data copy to application buffer */ +#define ENET_NOCOPY_FRAME_RECEIVE() enet_frame_receive(NULL, 0U) +/* handle application buffer data to transmit it */ +ErrStatus enet_frame_transmit(uint8_t *buffer, uint32_t length); +/* handle current transmit frame but without data copy from application buffer */ +#define ENET_NOCOPY_FRAME_TRANSMIT(len) enet_frame_transmit(NULL, (len)) +/* configure the transmit IP frame checksum offload calculation and insertion */ +void enet_transmit_checksum_config(enet_descriptors_struct *desc, uint32_t checksum); +/* ENET Tx and Rx function enable (include MAC and DMA module) */ +void enet_enable(void); +/* ENET Tx and Rx function disable (include MAC and DMA module) */ +void enet_disable(void); +/* configure MAC address */ +void enet_mac_address_set(enet_macaddress_enum mac_addr, uint8_t paddr[]); +/* get MAC address */ +void enet_mac_address_get(enet_macaddress_enum mac_addr, uint8_t paddr[]); + +/* get the ENET MAC/MSC/PTP/DMA status flag */ +FlagStatus enet_flag_get(enet_flag_enum enet_flag); +/* clear the ENET DMA status flag */ +void enet_flag_clear(enet_flag_clear_enum enet_flag); +/* enable ENET MAC/MSC/DMA interrupt */ +void enet_interrupt_enable(enet_int_enum enet_int); +/* disable ENET MAC/MSC/DMA interrupt */ +void enet_interrupt_disable(enet_int_enum enet_int); +/* get ENET MAC/MSC/DMA interrupt flag */ +FlagStatus enet_interrupt_flag_get(enet_int_flag_enum int_flag); +/* clear ENET DMA interrupt flag */ +void enet_interrupt_flag_clear(enet_int_flag_clear_enum int_flag_clear); + +/* MAC function */ +/* ENET Tx function enable (include MAC and DMA module) */ +void enet_tx_enable(void); +/* ENET Tx function disable (include MAC and DMA module) */ +void enet_tx_disable(void); +/* ENET Rx function enable (include MAC and DMA module) */ +void enet_rx_enable(void); +/* ENET Rx function disable (include MAC and DMA module) */ +void enet_rx_disable(void); +/* put registers value into the application buffer */ +void enet_registers_get(enet_registers_type_enum type, uint32_t *preg, uint32_t num); +/* get the enet debug status from the debug register */ +uint32_t enet_debug_status_get(uint32_t mac_debug); +/* enable the MAC address filter */ +void enet_address_filter_enable(enet_macaddress_enum mac_addr); +/* disable the MAC address filter */ +void enet_address_filter_disable(enet_macaddress_enum mac_addr); +/* configure the MAC address filter */ +void enet_address_filter_config(enet_macaddress_enum mac_addr, uint32_t addr_mask, uint32_t filter_type); +/* PHY interface configuration (configure SMI clock and reset PHY chip) */ +ErrStatus enet_phy_config(void); +/* write to/read from a PHY register */ +ErrStatus enet_phy_write_read(enet_phydirection_enum direction, uint16_t phy_address, uint16_t phy_reg, uint16_t *pvalue); +/* enable the loopback function of phy chip */ +ErrStatus enet_phyloopback_enable(void); +/* disable the loopback function of phy chip */ +ErrStatus enet_phyloopback_disable(void); +/* enable ENET forward feature */ +void enet_forward_feature_enable(uint32_t feature); +/* disable ENET forward feature */ +void enet_forward_feature_disable(uint32_t feature); +/* enable ENET fliter feature */ +void enet_fliter_feature_enable(uint32_t feature); +/* disable ENET fliter feature */ +void enet_fliter_feature_disable(uint32_t feature); + +/* flow control function */ +/* generate the pause frame, ENET will send pause frame after enable transmit flow control */ +ErrStatus enet_pauseframe_generate(void); +/* configure the pause frame detect type */ +void enet_pauseframe_detect_config(uint32_t detect); +/* configure the pause frame parameters */ +void enet_pauseframe_config(uint32_t pausetime, uint32_t pause_threshold); +/* configure the threshold of the flow control(deactive and active threshold) */ +void enet_flowcontrol_threshold_config(uint32_t deactive, uint32_t active); +/* enable ENET flow control feature */ +void enet_flowcontrol_feature_enable(uint32_t feature); +/* disable ENET flow control feature */ +void enet_flowcontrol_feature_disable(uint32_t feature); + +/* DMA function */ +/* get the dma transmit/receive process state */ +uint32_t enet_dmaprocess_state_get(enet_dmadirection_enum direction); +/* poll the dma transmission/reception enable */ +void enet_dmaprocess_resume(enet_dmadirection_enum direction); +/* check and recover the Rx process */ +void enet_rxprocess_check_recovery(void); +/* flush the ENET transmit fifo, and wait until the flush operation completes */ +ErrStatus enet_txfifo_flush(void); +/* get the transmit/receive address of current descriptor, or current buffer, or descriptor table */ +uint32_t enet_current_desc_address_get(enet_desc_reg_enum addr_get); +/* get the Tx or Rx descriptor information */ +uint32_t enet_desc_information_get(enet_descriptors_struct *desc, enet_descstate_enum info_get); +/* get the number of missed frames during receiving */ +void enet_missed_frame_counter_get(uint32_t *rxfifo_drop, uint32_t *rxdma_drop); + +/* descriptor function */ +/* get the bit flag of ENET dma descriptor */ +FlagStatus enet_desc_flag_get(enet_descriptors_struct *desc, uint32_t desc_flag); +/* set the bit flag of ENET dma tx descriptor */ +void enet_desc_flag_set(enet_descriptors_struct *desc, uint32_t desc_flag); +/* clear the bit flag of ENET dma tx descriptor */ +void enet_desc_flag_clear(enet_descriptors_struct *desc, uint32_t desc_flag); +/* when receiving the completed, set RS bit in ENET_DMA_STAT register will immediately set */ +void enet_rx_desc_immediate_receive_complete_interrupt(enet_descriptors_struct *desc); +/* when receiving the completed, set RS bit in ENET_DMA_STAT register will is set after a configurable delay time */ +void enet_rx_desc_delay_receive_complete_interrupt(enet_descriptors_struct *desc, uint32_t delay_time); +/* drop current receive frame */ +void enet_rxframe_drop(void); +/* enable DMA feature */ +void enet_dma_feature_enable(uint32_t feature); +/* disable DMA feature */ +void enet_dma_feature_disable(uint32_t feature); + + +/* special enhanced mode function */ +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE +/* get the bit of extended status flag in ENET DMA descriptor */ +uint32_t enet_rx_desc_enhanced_status_get(enet_descriptors_struct *desc, uint32_t desc_status); +/* configure descriptor to work in enhanced mode */ +void enet_desc_select_enhanced_mode(void); +/* initialize the dma Tx/Rx descriptors's parameters in enhanced chain mode with ptp function */ +void enet_ptp_enhanced_descriptors_chain_init(enet_dmadirection_enum direction); +/* initialize the dma Tx/Rx descriptors's parameters in enhanced ring mode with ptp function */ +void enet_ptp_enhanced_descriptors_ring_init(enet_dmadirection_enum direction); +/* receive a packet data with timestamp values to application buffer, when the DMA is in enhanced mode */ +ErrStatus enet_ptpframe_receive_enhanced_mode(uint8_t *buffer, uint32_t bufsize, uint32_t timestamp[]); +/* handle current received frame but without data copy to application buffer in PTP enhanced mode */ +#define ENET_NOCOPY_PTPFRAME_RECEIVE_ENHANCED_MODE(ptr) enet_ptpframe_receive_enhanced_mode(NULL, 0U, (ptr)) +/* send data with timestamp values in application buffer as a transmit packet, when the DMA is in enhanced mode */ +ErrStatus enet_ptpframe_transmit_enhanced_mode(uint8_t *buffer, uint32_t length, uint32_t timestamp[]); +/* handle current transmit frame but without data copy from application buffer in PTP enhanced mode */ +#define ENET_NOCOPY_PTPFRAME_TRANSMIT_ENHANCED_MODE(len, ptr) enet_ptpframe_transmit_enhanced_mode(NULL, (len), (ptr)) + +#else + +/* configure descriptor to work in normal mode */ +void enet_desc_select_normal_mode(void); +/* initialize the dma Tx/Rx descriptors's parameters in normal chain mode with ptp function */ +void enet_ptp_normal_descriptors_chain_init(enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab); +/* initialize the dma Tx/Rx descriptors's parameters in normal ring mode with ptp function */ +void enet_ptp_normal_descriptors_ring_init(enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab); +/* receive a packet data with timestamp values to application buffer, when the DMA is in normal mode */ +ErrStatus enet_ptpframe_receive_normal_mode(uint8_t *buffer, uint32_t bufsize, uint32_t timestamp[]); +/* handle current received frame but without data copy to application buffer in PTP normal mode */ +#define ENET_NOCOPY_PTPFRAME_RECEIVE_NORMAL_MODE(ptr) enet_ptpframe_receive_normal_mode(NULL, 0U, (ptr)) +/* send data with timestamp values in application buffer as a transmit packet, when the DMA is in normal mode */ +ErrStatus enet_ptpframe_transmit_normal_mode(uint8_t *buffer, uint32_t length, uint32_t timestamp[]); +/* handle current transmit frame but without data copy from application buffer in PTP normal mode */ +#define ENET_NOCOPY_PTPFRAME_TRANSMIT_NORMAL_MODE(len, ptr) enet_ptpframe_transmit_normal_mode(NULL, (len), (ptr)) + +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/* WUM function */ +/* wakeup frame filter register pointer reset */ +void enet_wum_filter_register_pointer_reset(void); +/* set the remote wakeup frame registers */ +void enet_wum_filter_config(uint32_t pdata[]); +/* enable wakeup management features */ +void enet_wum_feature_enable(uint32_t feature); +/* disable wakeup management features */ +void enet_wum_feature_disable(uint32_t feature); + +/* MSC function */ +/* reset the MAC statistics counters */ +void enet_msc_counters_reset(void); +/* enable the MAC statistics counter features */ +void enet_msc_feature_enable(uint32_t feature); +/* disable the MAC statistics counter features */ +void enet_msc_feature_disable(uint32_t feature); +/* configure MAC statistics counters preset mode */ +void enet_msc_counters_preset_config(enet_msc_preset_enum mode); +/* get MAC statistics counter */ +uint32_t enet_msc_counters_get(enet_msc_counter_enum counter); + +/* PTP function */ +/* enable the PTP features */ +void enet_ptp_feature_enable(uint32_t feature); +/* disable the PTP features */ +void enet_ptp_feature_disable(uint32_t feature); +/* configure the PTP timestamp function */ +ErrStatus enet_ptp_timestamp_function_config(enet_ptp_function_enum func); +/* configure the PTP system time subsecond increment value */ +void enet_ptp_subsecond_increment_config(uint32_t subsecond); +/* adjusting the PTP clock frequency only in fine update mode */ +void enet_ptp_timestamp_addend_config(uint32_t add); +/* initializing or adding/subtracting to second of the PTP system time */ +void enet_ptp_timestamp_update_config(uint32_t sign, uint32_t second, uint32_t subsecond); +/* configure the PTP expected target time */ +void enet_ptp_expected_time_config(uint32_t second, uint32_t nanosecond); +/* get the PTP current system time */ +void enet_ptp_system_time_get(enet_ptp_systime_struct *systime_struct); +/* configure the PPS output frequency */ +void enet_ptp_pps_output_frequency_config(uint32_t freq); + + +/* internal function */ +/* reset the ENET initpara struct, call it before using enet_initpara_config() */ +void enet_initpara_reset(void); +/* initialize ENET peripheral with generally concerned parameters, call it by enet_init() */ +static void enet_default_init(void); +#ifdef USE_DELAY +/* user can provide more timing precise _ENET_DELAY_ function */ +#define _ENET_DELAY_ delay_ms +#else +/* insert a delay time */ +static void enet_delay(uint32_t ncount); +/* default _ENET_DELAY_ function with less precise timing */ +#define _ENET_DELAY_ enet_delay +#endif + +#endif /* GD32F4XX_ENET_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h new file mode 100644 index 0000000000..3844c699d2 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h @@ -0,0 +1,781 @@ +/*! + \file gd32f4xx_exmc.h + \brief definitions for the EXMC +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_EXMC_H +#define GD32F4XX_EXMC_H + +#include "gd32f4xx.h" + +/* EXMC definitions */ +#define EXMC (EXMC_BASE) /*!< EXMC register base address */ +#define EXMC_NOR_PSRAM (EXMC_BASE - 0x40000000) /*!< EXMC NOR/PSRAM base address */ +#define EXMC_NAND (EXMC_BASE - 0x30000000) /*!< EXMC NAND base address */ +#define EXMC_PCCARD (EXMC_BASE - 0x10000000) /*!< EXMC PC card base address */ +#define EXMC_SDRAM (EXMC_BASE + 0x20000000) /*!< EXMC SDRAM base address */ + +/* registers definitions */ +/* NOR/PSRAM */ +#define EXMC_SNCTL0 REG32(EXMC + 0x00U) /*!< EXMC SRAM/NOR flash control register */ +#define EXMC_SNTCFG0 REG32(EXMC + 0x04U) /*!< EXMC SRAM/NOR flash timing configuration register */ +#define EXMC_SNWTCFG0 REG32(EXMC + 0x104U) /*!< EXMC SRAM/NOR flash write timing configuration register */ + +#define EXMC_SNCTL1 REG32(EXMC + 0x08U) /*!< EXMC SRAM/NOR flash control register */ +#define EXMC_SNTCFG1 REG32(EXMC + 0x0CU) /*!< EXMC SRAM/NOR flash timing configuration register */ +#define EXMC_SNWTCFG1 REG32(EXMC + 0x10CU) /*!< EXMC SRAM/NOR flash write timing configuration register */ + +#define EXMC_SNCTL2 REG32(EXMC + 0x10U) /*!< EXMC SRAM/NOR flash control register */ +#define EXMC_SNTCFG2 REG32(EXMC + 0x14U) /*!< EXMC SRAM/NOR flash timing configuration register */ +#define EXMC_SNWTCFG2 REG32(EXMC + 0x114U) /*!< EXMC SRAM/NOR flash write timing configuration register */ + +#define EXMC_SNCTL3 REG32(EXMC + 0x18U) /*!< EXMC SRAM/NOR flash control register */ +#define EXMC_SNTCFG3 REG32(EXMC + 0x1CU) /*!< EXMC SRAM/NOR flash timing configuration register */ +#define EXMC_SNWTCFG3 REG32(EXMC + 0x11CU) /*!< EXMC SRAM/NOR flash write timing configuration register */ + +/* NAND/PC card */ +#define EXMC_NPCTL1 REG32(EXMC + 0x40U) /*!< EXMC NAND/PC card control register */ +#define EXMC_NPINTEN1 REG32(EXMC + 0x44U) /*!< EXMC NAND/PC card interrupt enable register */ +#define EXMC_NPCTCFG1 REG32(EXMC + 0x48U) /*!< EXMC NAND/PC card common space timing configuration register */ +#define EXMC_NPATCFG1 REG32(EXMC + 0x4CU) /*!< EXMC NAND/PC card attribute space timing configuration register */ +#define EXMC_NECC1 REG32(EXMC + 0x54U) /*!< EXMC NAND ECC register */ + +#define EXMC_NPCTL2 REG32(EXMC + 0x60U) /*!< EXMC NAND/PC card control register */ +#define EXMC_NPINTEN2 REG32(EXMC + 0x64U) /*!< EXMC NAND/PC card interrupt enable register */ +#define EXMC_NPCTCFG2 REG32(EXMC + 0x68U) /*!< EXMC NAND/PC card common space timing configuration register */ +#define EXMC_NPATCFG2 REG32(EXMC + 0x6CU) /*!< EXMC NAND/PC card attribute space timing configuration register */ +#define EXMC_NECC2 REG32(EXMC + 0x74U) /*!< EXMC NAND ECC register */ + +#define EXMC_NPCTL3 REG32(EXMC + 0x80U) /*!< EXMC NAND/PC card control register */ +#define EXMC_NPINTEN3 REG32(EXMC + 0x84U) /*!< EXMC NAND/PC card interrupt enable register */ +#define EXMC_NPCTCFG3 REG32(EXMC + 0x88U) /*!< EXMC NAND/PC card common space timing configuration register */ +#define EXMC_NPATCFG3 REG32(EXMC + 0x8CU) /*!< EXMC NAND/PC card attribute space timing configuration register */ +#define EXMC_PIOTCFG3 REG32(EXMC + 0xB0U) /*!< EXMC PC card I/O space timing configuration register */ + +/* SDRAM */ +#define EXMC_SDCTL0 REG32(EXMC + 0x140U) /*!< EXMC SDRAM control register */ +#define EXMC_SDTCFG0 REG32(EXMC + 0x148U) /*!< EXMC SDRAM timing configuration register register */ + +#define EXMC_SDCTL1 REG32(EXMC + 0x144U) /*!< EXMC SDRAM control register */ +#define EXMC_SDTCFG1 REG32(EXMC + 0x14CU) /*!< EXMC SDRAM timing configuration register register */ + +#define EXMC_SDCMD REG32(EXMC + 0x150U) /*!< EXMC SDRAM command register */ +#define EXMC_SDARI REG32(EXMC + 0x154U) /*!< EXMC SDRAM auto-refresh interval register */ +#define EXMC_SDSTAT REG32(EXMC + 0x158U) /*!< EXMC SDRAM status register */ +#define EXMC_SDRSCTL REG32(EXMC + 0x180U) /*!< EXMC SDRAM read sample control register */ + +/* SQPI PSRAM */ +#define EXMC_SINIT REG32(EXMC + 0x310U) /*!< EXMC SPI initialization register */ +#define EXMC_SRCMD REG32(EXMC + 0x320U) /*!< EXMC SPI read command register */ +#define EXMC_SWCMD REG32(EXMC + 0x330U) /*!< EXMC SPI write command register */ +#define EXMC_SIDL REG32(EXMC + 0x340U) /*!< EXMC SPI ID low register */ +#define EXMC_SIDH REG32(EXMC + 0x350U) /*!< EXMC SPI ID high register */ + +/* bits definitions */ +/* EXMC_SNCTLx,x=0..3 */ +#define EXMC_SNCTL_NRBKEN BIT(0) /*!< NOR bank enable */ +#define EXMC_SNCTL_NRMUX BIT(1) /*!< NOR bank memory address/data multiplexing */ +#define EXMC_SNCTL_NRTP BITS(2,3) /*!< NOR bank memory type */ +#define EXMC_SNCTL_NRW BITS(4,5) /*!< NOR bank memory data bus width */ +#define EXMC_SNCTL_NREN BIT(6) /*!< NOR flash access enable */ +#define EXMC_SNCTL_SBRSTEN BIT(8) /*!< synchronous burst enable */ +#define EXMC_SNCTL_NRWTPOL BIT(9) /*!< NWAIT signal polarity */ +#define EXMC_SNCTL_WRAPEN BIT(10) /*!< wrapped burst mode enable */ +#define EXMC_SNCTL_NRWTCFG BIT(11) /*!< NWAIT signal configuration, only work in synchronous mode */ +#define EXMC_SNCTL_WREN BIT(12) /*!< write enable */ +#define EXMC_SNCTL_NRWTEN BIT(13) /*!< NWAIT signal enable */ +#define EXMC_SNCTL_EXMODEN BIT(14) /*!< extended mode enable */ +#define EXMC_SNCTL_ASYNCWAIT BIT(15) /*!< asynchronous wait */ +#define EXMC_SNCTL_CPS BITS(16,18) /*!< CRAM page size */ +#define EXMC_SNCTL_SYNCWR BIT(19) /*!< synchronous write */ +#define EXMC_SNCTL_CCK BIT(20) /*!< consecutive clock */ + +/* EXMC_SNTCFGx,x=0..3 */ +#define EXMC_SNTCFG_ASET BITS(0,3) /*!< address setup time */ +#define EXMC_SNTCFG_AHLD BITS(4,7) /*!< address hold time */ +#define EXMC_SNTCFG_DSET BITS(8,15) /*!< data setup time */ +#define EXMC_SNTCFG_BUSLAT BITS(16,19) /*!< bus latency */ +#define EXMC_SNTCFG_CKDIV BITS(20,23) /*!< synchronous clock divide ratio */ +#define EXMC_SNTCFG_DLAT BITS(24,27) /*!< data latency for NOR flash */ +#define EXMC_SNTCFG_ASYNCMOD BITS(28,29) /*!< asynchronous access mode */ + +/* EXMC_SNWTCFGx,x=0..3 */ +#define EXMC_SNWTCFG_WASET BITS(0,3) /*!< address setup time */ +#define EXMC_SNWTCFG_WAHLD BITS(4,7) /*!< address hold time */ +#define EXMC_SNWTCFG_WDSET BITS(8,15) /*!< data setup time */ +#define EXMC_SNWTCFG_WBUSLAT BITS(16,19) /*!< bus latency */ +#define EXMC_SNWTCFG_WASYNCMOD BITS(28,29) /*!< asynchronous access mode */ + +/* EXMC_NPCTLx,x=1..3 */ +#define EXMC_NPCTL_NDWTEN BIT(1) /*!< wait feature enable */ +#define EXMC_NPCTL_NDBKEN BIT(2) /*!< NAND bank enable */ +#define EXMC_NPCTL_NDTP BIT(3) /*!< NAND bank memory type */ +#define EXMC_NPCTL_NDW BITS(4,5) /*!< NAND bank memory data bus width */ +#define EXMC_NPCTL_ECCEN BIT(6) /*!< ECC enable */ +#define EXMC_NPCTL_CTR BITS(9,12) /*!< CLE to RE delay */ +#define EXMC_NPCTL_ATR BITS(13,16) /*!< ALE to RE delay */ +#define EXMC_NPCTL_ECCSZ BITS(17,19) /*!< ECC size */ + +/* EXMC_NPINTENx,x=1..3 */ +#define EXMC_NPINTEN_INTRS BIT(0) /*!< interrupt rising edge status */ +#define EXMC_NPINTEN_INTHS BIT(1) /*!< interrupt high-level status */ +#define EXMC_NPINTEN_INTFS BIT(2) /*!< interrupt falling edge status */ +#define EXMC_NPINTEN_INTREN BIT(3) /*!< interrupt rising edge detection enable */ +#define EXMC_NPINTEN_INTHEN BIT(4) /*!< interrupt high-level detection enable */ +#define EXMC_NPINTEN_INTFEN BIT(5) /*!< interrupt falling edge detection enable */ +#define EXMC_NPINTEN_INTEPT BIT(6) /*!< FIFO empty flag */ + +/* EXMC_NPCTCFGx,x=1..3 */ +#define EXMC_NPCTCFG_COMSET BITS(0,7) /*!< common memory data bus HiZ time */ +#define EXMC_NPCTCFG_COMWAIT BITS(8,15) /*!< common memory hold time */ +#define EXMC_NPCTCFG_COMHLD BITS(16,23) /*!< common memory wait time */ +#define EXMC_NPCTCFG_COMHIZ BITS(24,31) /*!< common memory setup time */ + +/* EXMC_NPATCFGx,x=1..3 */ +#define EXMC_NPATCFG_ATTSET BITS(0,7) /*!< attribute memory data bus HiZ time */ +#define EXMC_NPATCFG_ATTWAIT BITS(8,15) /*!< attribute memory hold time */ +#define EXMC_NPATCFG_ATTHLD BITS(16,23) /*!< attribute memory wait time */ +#define EXMC_NPATCFG_ATTHIZ BITS(24,31) /*!< attribute memory setup time */ + +/* EXMC_PIOTCFG3 */ +#define EXMC_PIOTCFG3_IOSET BITS(0,7) /*!< IO space data bus HiZ time */ +#define EXMC_PIOTCFG3_IOWAIT BITS(8,15) /*!< IO space hold time */ +#define EXMC_PIOTCFG3_IOHLD BITS(16,23) /*!< IO space wait time */ +#define EXMC_PIOTCFG3_IOHIZ BITS(24,31) /*!< IO space setup time */ + +/* EXMC_NECCx,x=1..2 */ +#define EXMC_NECC_ECC BITS(0,31) /*!< ECC result */ + +/* EXMC_SDCTLx,x=0..1 */ +#define EXMC_SDCTL_CAW BITS(0,1) /*!< column address bit width */ +#define EXMC_SDCTL_RAW BITS(2,3) /*!< row address bit width */ +#define EXMC_SDCTL_SDW BITS(4,5) /*!< SDRAM data bus width */ +#define EXMC_SDCTL_NBK BIT(6) /*!< number of banks */ +#define EXMC_SDCTL_CL BIT(7,8) /*!< CAS Latency */ +#define EXMC_SDCTL_WPEN BIT(9) /*!< write protection enable */ +#define EXMC_SDCTL_SDCLK BITS(10,11) /*!< SDRAM clock configuration */ +#define EXMC_SDCTL_BRSTRD BIT(12) /*!< burst read */ +#define EXMC_SDCTL_PIPED BITS(13,14) /*!< pipeline delay */ + +/* EXMC_SDTCFGx,x=0..1 */ +#define EXMC_SDTCFG_LMRD BITS(0,3) /*!< load mode register delay */ +#define EXMC_SDTCFG_XSRD BITS(4,7) /*!< exit self-refresh delay */ +#define EXMC_SDTCFG_RASD BITS(8,11) /*!< row address select delay */ +#define EXMC_SDTCFG_ARFD BITS(12,15) /*!< auto refresh delay */ +#define EXMC_SDTCFG_WRD BITS(16,19) /*!< write recovery delay */ +#define EXMC_SDTCFG_RPD BITS(20,23) /*!< row precharge delay */ +#define EXMC_SDTCFG_RCD BITS(24,27) /*!< row to column delay */ + +/* EXMC_SDCMD */ +#define EXMC_SDCMD_CMD BITS(0,2) /*!< command */ +#define EXMC_SDCMD_DS1 BIT(3) /*!< device select 1 */ +#define EXMC_SDCMD_DS0 BIT(4) /*!< device select 0 */ +#define EXMC_SDCMD_NARF BITS(5,8) /*!< number of successive auto-refresh */ +#define EXMC_SDCMD_MRC BITS(9,21) /*!< mode register content */ + +/* EXMC_SDARI */ +#define EXMC_SDARI_REC BIT(0) /*!< refresh error flag clear */ +#define EXMC_SDARI_ARINTV BITS(1,13) /*!< auto-refresh interval */ +#define EXMC_SDARI_REIE BIT(14) /*!< interrupt refresh error enable */ + +/* EXMC_SDSTAT */ +#define EXMC_SDSDAT_REIF BIT(0) /*!< refresh error interrupt flag */ +#define EXMC_SDSDAT_STA0 BITS(1,2) /*!< device 0 status */ +#define EXMC_SDSDAT_STA1 BITS(3,4) /*!< device 1 status */ +#define EXMC_SDSDAT_NRDY BIT(5) /*!< not ready status */ + +/* EXMC_SDRSCTL */ +#define EXMC_SDRSCTL_RSEN BIT(0) /*!< read sample enable */ +#define EXMC_SDRSCTL_SSCR BIT(1) /*!< select sample cycle of read data */ +#define EXMC_SDRSCTL_SDSC BITS(4,7) /*!< select the delayed sample clock of read data */ + +/* EXMC_SINIT */ +#define EXMC_SINIT_CMDBIT BITS(16,17) /*!< bit number of SPI PSRAM command phase */ +#define EXMC_SINIT_ARDBIT BITS(24,28) /*!< bit number of SPI PSRAM address phase */ +#define EXMC_SINIT_IDL BITS(29,30) /*!< SPI PSRAM ID length */ +#define EXMC_SINIT_POL BIT(31) /*!< read data sample polarity */ + +/* EXMC_SRCMD */ +#define EXMC_SRCMD_RCMD BITS(0,15) /*!< SPI read command for AHB read transfer */ +#define EXMC_SRCMD_RWAITCYCLE BITS(16,19) /*!< SPI read wait cycle number after address phase */ +#define EXMC_SRCMD_RMODE BITS(20,21) /*!< SPI PSRAM read command mode */ +#define EXMC_SRCMD_RDID BIT(31) /*!< send SPI read ID command */ + +/* EXMC_SWCMD */ +#define EXMC_SWCMD_WCMD BITS(0,15) /*!< send SPI special command */ +#define EXMC_SWCMD_WWAITCYCLE BITS(16,19) /*!< SPI PSRAM write command mode */ +#define EXMC_SWCMD_WMODE BITS(20,21) /*!< SPI write wait cycle number after address phase */ +#define EXMC_SWCMD_SC BIT(31) /*!< SPI write command for AHB write transfer */ + +/* EXMC_SIDL */ +#define EXMC_SIDL_SIDL BITS(0,31) /*!< ID low data saved for SPI read ID command */ + +/* EXMC_SIDH */ +#define EXMC_SIDL_SIDH BITS(0,31) /*!< ID high Data saved for SPI read ID command */ + +/* constants definitions */ +/* EXMC NOR/SRAM timing initialize struct */ +typedef struct +{ + uint32_t asyn_access_mode; /*!< asynchronous access mode */ + uint32_t syn_data_latency; /*!< configure the data latency */ + uint32_t syn_clk_division; /*!< configure the clock divide ratio */ + uint32_t bus_latency; /*!< configure the bus latency */ + uint32_t asyn_data_setuptime; /*!< configure the data setup time,asynchronous access mode valid */ + uint32_t asyn_address_holdtime; /*!< configure the address hold time,asynchronous access mode valid */ + uint32_t asyn_address_setuptime; /*!< configure the data setup time,asynchronous access mode valid */ +}exmc_norsram_timing_parameter_struct; + +/* EXMC NOR/SRAM initialize struct */ +typedef struct +{ + uint32_t norsram_region; /*!< select the region of EXMC NOR/SRAM bank */ + uint32_t write_mode; /*!< the write mode, synchronous mode or asynchronous mode */ + uint32_t extended_mode; /*!< enable or disable the extended mode */ + uint32_t asyn_wait; /*!< enable or disable the asynchronous wait function */ + uint32_t nwait_signal; /*!< enable or disable the NWAIT signal while in synchronous bust mode */ + uint32_t memory_write; /*!< enable or disable the write operation */ + uint32_t nwait_config; /*!< NWAIT signal configuration */ + uint32_t wrap_burst_mode; /*!< enable or disable the wrap burst mode */ + uint32_t nwait_polarity; /*!< specifies the polarity of NWAIT signal from memory */ + uint32_t burst_mode; /*!< enable or disable the burst mode */ + uint32_t databus_width; /*!< specifies the databus width of external memory */ + uint32_t memory_type; /*!< specifies the type of external memory */ + uint32_t address_data_mux; /*!< specifies whether the data bus and address bus are multiplexed */ + exmc_norsram_timing_parameter_struct* read_write_timing; /*!< timing parameters for read and write if the extendedmode is not used or the timing + parameters for read if the extendedmode is used. */ + exmc_norsram_timing_parameter_struct* write_timing; /*!< timing parameters for write when the extendedmode is used. */ +}exmc_norsram_parameter_struct; + +/* EXMC NAND/PC card timing initialize struct */ +typedef struct +{ + uint32_t databus_hiztime; /*!< configure the dadtabus HiZ time for write operation */ + uint32_t holdtime; /*!< configure the address hold time(or the data hold time for write operation) */ + uint32_t waittime; /*!< configure the minimum wait time */ + uint32_t setuptime; /*!< configure the address setup time */ +}exmc_nand_pccard_timing_parameter_struct; + +/* EXMC NAND initialize struct */ +typedef struct +{ + uint32_t nand_bank; /*!< select the bank of NAND */ + uint32_t ecc_size; /*!< the page size for the ECC calculation */ + uint32_t atr_latency; /*!< configure the latency of ALE low to RB low */ + uint32_t ctr_latency; /*!< configure the latency of CLE low to RB low */ + uint32_t ecc_logic; /*!< enable or disable the ECC calculation logic */ + uint32_t databus_width; /*!< the NAND flash databus width */ + uint32_t wait_feature; /*!< enables or disables the wait feature */ + exmc_nand_pccard_timing_parameter_struct* common_space_timing; /*!< the timing parameters for NAND flash Common Space */ + exmc_nand_pccard_timing_parameter_struct* attribute_space_timing; /*!< the timing parameters for NAND flash Attribute Space */ +}exmc_nand_parameter_struct; + +/* EXMC PC card initialize struct */ +typedef struct +{ + uint32_t atr_latency; /*!< configure the latency of ALE low to RB low */ + uint32_t ctr_latency; /*!< configure the latency of CLE low to RB low */ + uint32_t wait_feature; /*!< enables or disables the Wait feature */ + exmc_nand_pccard_timing_parameter_struct* common_space_timing; /*!< the timing parameters for NAND flash Common Space */ + exmc_nand_pccard_timing_parameter_struct* attribute_space_timing; /*!< the timing parameters for NAND flash Attribute Space */ + exmc_nand_pccard_timing_parameter_struct* io_space_timing; /*!< the timing parameters for NAND flash IO Space */ +}exmc_pccard_parameter_struct;; + +/* EXMC SDRAM timing initialize struct */ +typedef struct +{ + uint32_t row_to_column_delay; /*!< configure the row to column delay */ + uint32_t row_precharge_delay; /*!< configure the row precharge delay */ + uint32_t write_recovery_delay; /*!< configure the write recovery delay */ + uint32_t auto_refresh_delay; /*!< configure the auto refresh delay */ + uint32_t row_address_select_delay; /*!< configure the row address select delay */ + uint32_t exit_selfrefresh_delay; /*!< configure the exit self-refresh delay */ + uint32_t load_mode_register_delay; /*!< configure the load mode register delay */ +}exmc_sdram_timing_parameter_struct; + +/* EXMC SDRAM initialize struct */ +typedef struct +{ + uint32_t sdram_device; /*!< device of SDRAM */ + uint32_t pipeline_read_delay; /*!< the delay for reading data after CAS latency in HCLK clock cycles */ + uint32_t brust_read_switch; /*!< enable or disable the burst read */ + uint32_t sdclock_config; /*!< the SDCLK memory clock for both SDRAM banks */ + uint32_t write_protection; /*!< enable or disable SDRAM bank write protection function */ + uint32_t cas_latency; /*!< configure the SDRAM CAS latency */ + uint32_t internal_bank_number; /*!< the number internal banks */ + uint32_t data_width; /*!< the databus width of SDRAM memory */ + uint32_t row_address_width; /*!< the bit width of a row address */ + uint32_t column_address_width; /*!< the bit width of a column address */ + exmc_sdram_timing_parameter_struct* timing; /*!< the timing parameters for write and read SDRAM */ +}exmc_sdram_parameter_struct; + +/* EXMC SDRAM command initialize struct */ +typedef struct +{ + uint32_t mode_register_content; /*!< the SDRAM mode register content */ + uint32_t auto_refresh_number; /*!< the number of successive auto-refresh cycles will be send when CMD = 011 */ + uint32_t bank_select; /*!< the bank which command will be sent to */ + uint32_t command; /*!< the commands that will be sent to SDRAM */ +}exmc_sdram_command_parameter_struct; + +/* EXMC SQPISRAM initialize struct */ +typedef struct{ + uint32_t sample_polarity; /*!< read data sample polarity */ + uint32_t id_length; /*!< SPI PSRAM ID length */ + uint32_t address_bits; /*!< bit number of SPI PSRAM address phase */ + uint32_t command_bits; /*!< bit number of SPI PSRAM command phase */ +}exmc_sqpipsram_parameter_struct; + +/* EXMC_register address */ +#define EXMC_SNCTL(bank) REG32(EXMC + 0x08U*((uint32_t)(bank))) /*!< EXMC SRAM/NOR flash control register */ +#define EXMC_SNTCFG(bank) REG32(EXMC + 0x04U + 0x08U*(bank)) /*!< EXMC SRAM/NOR flash timing configuration register */ +#define EXMC_SNWTCFG(bank) REG32(EXMC + 0x104U + 0x08U*(bank)) /*!< EXMC SRAM/NOR flash write timing configuration register */ + +#define EXMC_NPCTL(bank) REG32(EXMC + 0x40U + 0x20U*(bank)) /*!< EXMC NAND/PC card control register */ +#define EXMC_NPINTEN(bank) REG32(EXMC + 0x44U + 0x20U*(bank)) /*!< EXMC NAND/PC card interrupt enable register */ +#define EXMC_NPCTCFG(bank) REG32(EXMC + 0x48U + 0x20U*(bank)) /*!< EXMC NAND/PC card common space timing configuration register */ +#define EXMC_NPATCFG(bank) REG32(EXMC + 0x4CU + 0x20U*(bank)) /*!< EXMC NAND/PC card attribute space timing configuration register */ +#define EXMC_NECC(bank) REG32(EXMC + 0x54U + 0x20U*(bank)) /*!< EXMC NAND ECC register */ + +#define EXMC_SDCTL(bank) REG32(EXMC + 0x140U + 0x4U*((bank) - 0x4U)) /*!< EXMC SDRAM control register */ +#define EXMC_SDTCFG(bank) REG32(EXMC + 0x148U + 0x4U*((bank) - 0x4U)) /*!< EXMC SDRAM timing configuration register */ + +/* CRAM page size */ +#define SNCTL_CPS(regval) (BITS(16,18) & ((uint32_t)(regval) << 16)) +#define EXMC_CRAM_AUTO_SPLIT SNCTL_CPS(0) /*!< automatic burst split on page boundary crossing */ +#define EXMC_CRAM_PAGE_SIZE_128_BYTES SNCTL_CPS(1) /*!< page size is 128 bytes */ +#define EXMC_CRAM_PAGE_SIZE_256_BYTES SNCTL_CPS(2) /*!< page size is 256 bytes */ +#define EXMC_CRAM_PAGE_SIZE_512_BYTES SNCTL_CPS(3) /*!< page size is 512 bytes */ +#define EXMC_CRAM_PAGE_SIZE_1024_BYTES SNCTL_CPS(4) /*!< page size is 1024 bytes */ + +/* NOR bank memory data bus width */ +#define SNCTL_NRW(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define EXMC_NOR_DATABUS_WIDTH_8B SNCTL_NRW(0) /*!< NOR data width 8 bits */ +#define EXMC_NOR_DATABUS_WIDTH_16B SNCTL_NRW(1) /*!< NOR data width 16 bits */ + +/* NOR bank memory type */ +#define SNCTL_NRTP(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define EXMC_MEMORY_TYPE_SRAM SNCTL_NRTP(0) /*!< SRAM,ROM */ +#define EXMC_MEMORY_TYPE_PSRAM SNCTL_NRTP(1) /*!< PSRAM,CRAM */ +#define EXMC_MEMORY_TYPE_NOR SNCTL_NRTP(2) /*!< NOR flash */ + +/* asynchronous access mode */ +#define SNTCFG_ASYNCMOD(regval) (BITS(28,29) & ((uint32_t)(regval) << 28)) +#define EXMC_ACCESS_MODE_A SNTCFG_ASYNCMOD(0) /*!< mode A access */ +#define EXMC_ACCESS_MODE_B SNTCFG_ASYNCMOD(1) /*!< mode B access */ +#define EXMC_ACCESS_MODE_C SNTCFG_ASYNCMOD(2) /*!< mode C access */ +#define EXMC_ACCESS_MODE_D SNTCFG_ASYNCMOD(3) /*!< mode D access */ + +/* data latency for NOR flash */ +#define SNTCFG_DLAT(regval) (BITS(24,27) & ((uint32_t)(regval) << 24)) +#define EXMC_DATALAT_2_CLK SNTCFG_DLAT(0) /*!< data latency 2 EXMC_CLK */ +#define EXMC_DATALAT_3_CLK SNTCFG_DLAT(1) /*!< data latency 3 EXMC_CLK */ +#define EXMC_DATALAT_4_CLK SNTCFG_DLAT(2) /*!< data latency 4 EXMC_CLK */ +#define EXMC_DATALAT_5_CLK SNTCFG_DLAT(3) /*!< data latency 5 EXMC_CLK */ +#define EXMC_DATALAT_6_CLK SNTCFG_DLAT(4) /*!< data latency 6 EXMC_CLK */ +#define EXMC_DATALAT_7_CLK SNTCFG_DLAT(5) /*!< data latency 7 EXMC_CLK */ +#define EXMC_DATALAT_8_CLK SNTCFG_DLAT(6) /*!< data latency 8 EXMC_CLK */ +#define EXMC_DATALAT_9_CLK SNTCFG_DLAT(7) /*!< data latency 9 EXMC_CLK */ +#define EXMC_DATALAT_10_CLK SNTCFG_DLAT(8) /*!< data latency 10 EXMC_CLK */ +#define EXMC_DATALAT_11_CLK SNTCFG_DLAT(9) /*!< data latency 11 EXMC_CLK */ +#define EXMC_DATALAT_12_CLK SNTCFG_DLAT(10) /*!< data latency 12 EXMC_CLK */ +#define EXMC_DATALAT_13_CLK SNTCFG_DLAT(11) /*!< data latency 13 EXMC_CLK */ +#define EXMC_DATALAT_14_CLK SNTCFG_DLAT(12) /*!< data latency 14 EXMC_CLK */ +#define EXMC_DATALAT_15_CLK SNTCFG_DLAT(13) /*!< data latency 15 EXMC_CLK */ +#define EXMC_DATALAT_16_CLK SNTCFG_DLAT(14) /*!< data latency 16 EXMC_CLK */ +#define EXMC_DATALAT_17_CLK SNTCFG_DLAT(15) /*!< data latency 17 EXMC_CLK */ + +/* synchronous clock divide ratio */ +#define SNTCFG_CKDIV(regval) (BITS(20,23) & ((uint32_t)(regval) << 20)) +#define EXMC_SYN_CLOCK_RATIO_DISABLE SNTCFG_CKDIV(0) /*!< EXMC_CLK disable */ +#define EXMC_SYN_CLOCK_RATIO_2_CLK SNTCFG_CKDIV(1) /*!< EXMC_CLK = 2*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_3_CLK SNTCFG_CKDIV(2) /*!< EXMC_CLK = 3*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_4_CLK SNTCFG_CKDIV(3) /*!< EXMC_CLK = 4*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_5_CLK SNTCFG_CKDIV(4) /*!< EXMC_CLK = 5*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_6_CLK SNTCFG_CKDIV(5) /*!< EXMC_CLK = 6*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_7_CLK SNTCFG_CKDIV(6) /*!< EXMC_CLK = 7*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_8_CLK SNTCFG_CKDIV(7) /*!< EXMC_CLK = 8*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_9_CLK SNTCFG_CKDIV(8) /*!< EXMC_CLK = 9*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_10_CLK SNTCFG_CKDIV(9) /*!< EXMC_CLK = 10*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_11_CLK SNTCFG_CKDIV(10) /*!< EXMC_CLK = 11*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_12_CLK SNTCFG_CKDIV(11) /*!< EXMC_CLK = 12*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_13_CLK SNTCFG_CKDIV(12) /*!< EXMC_CLK = 13*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_14_CLK SNTCFG_CKDIV(13) /*!< EXMC_CLK = 14*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_15_CLK SNTCFG_CKDIV(14) /*!< EXMC_CLK = 15*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_16_CLK SNTCFG_CKDIV(15) /*!< EXMC_CLK = 16*HCLK */ + +/* ECC size */ +#define NPCTL_ECCSZ(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) +#define EXMC_ECC_SIZE_256BYTES NPCTL_ECCSZ(0) /* 256 bytes */ +#define EXMC_ECC_SIZE_512BYTES NPCTL_ECCSZ(1) /* 512 bytes */ +#define EXMC_ECC_SIZE_1024BYTES NPCTL_ECCSZ(2) /* 1024 bytes */ +#define EXMC_ECC_SIZE_2048BYTES NPCTL_ECCSZ(3) /* 2048 bytes */ +#define EXMC_ECC_SIZE_4096BYTES NPCTL_ECCSZ(4) /* 4096 bytes */ +#define EXMC_ECC_SIZE_8192BYTES NPCTL_ECCSZ(5) /* 8192 bytes */ + +/* ALE to RE delay */ +#define NPCTL_ATR(regval) (BITS(13,16) & ((uint32_t)(regval) << 13)) +#define EXMC_ALE_RE_DELAY_1_HCLK NPCTL_ATR(0) /* ALE to RE delay = 1*HCLK */ +#define EXMC_ALE_RE_DELAY_2_HCLK NPCTL_ATR(1) /* ALE to RE delay = 2*HCLK */ +#define EXMC_ALE_RE_DELAY_3_HCLK NPCTL_ATR(2) /* ALE to RE delay = 3*HCLK */ +#define EXMC_ALE_RE_DELAY_4_HCLK NPCTL_ATR(3) /* ALE to RE delay = 4*HCLK */ +#define EXMC_ALE_RE_DELAY_5_HCLK NPCTL_ATR(4) /* ALE to RE delay = 5*HCLK */ +#define EXMC_ALE_RE_DELAY_6_HCLK NPCTL_ATR(5) /* ALE to RE delay = 6*HCLK */ +#define EXMC_ALE_RE_DELAY_7_HCLK NPCTL_ATR(6) /* ALE to RE delay = 7*HCLK */ +#define EXMC_ALE_RE_DELAY_8_HCLK NPCTL_ATR(7) /* ALE to RE delay = 8*HCLK */ +#define EXMC_ALE_RE_DELAY_9_HCLK NPCTL_ATR(8) /* ALE to RE delay = 9*HCLK */ +#define EXMC_ALE_RE_DELAY_10_HCLK NPCTL_ATR(9) /* ALE to RE delay = 10*HCLK */ +#define EXMC_ALE_RE_DELAY_11_HCLK NPCTL_ATR(10) /* ALE to RE delay = 11*HCLK */ +#define EXMC_ALE_RE_DELAY_12_HCLK NPCTL_ATR(11) /* ALE to RE delay = 12*HCLK */ +#define EXMC_ALE_RE_DELAY_13_HCLK NPCTL_ATR(12) /* ALE to RE delay = 13*HCLK */ +#define EXMC_ALE_RE_DELAY_14_HCLK NPCTL_ATR(13) /* ALE to RE delay = 14*HCLK */ +#define EXMC_ALE_RE_DELAY_15_HCLK NPCTL_ATR(14) /* ALE to RE delay = 15*HCLK */ +#define EXMC_ALE_RE_DELAY_16_HCLK NPCTL_ATR(15) /* ALE to RE delay = 16*HCLK */ + +/* CLE to RE delay */ +#define NPCTL_CTR(regval) (BITS(9,12) & ((uint32_t)(regval) << 9)) +#define EXMC_CLE_RE_DELAY_1_HCLK NPCTL_CTR(0) /* CLE to RE delay = 1*HCLK */ +#define EXMC_CLE_RE_DELAY_2_HCLK NPCTL_CTR(1) /* CLE to RE delay = 2*HCLK */ +#define EXMC_CLE_RE_DELAY_3_HCLK NPCTL_CTR(2) /* CLE to RE delay = 3*HCLK */ +#define EXMC_CLE_RE_DELAY_4_HCLK NPCTL_CTR(3) /* CLE to RE delay = 4*HCLK */ +#define EXMC_CLE_RE_DELAY_5_HCLK NPCTL_CTR(4) /* CLE to RE delay = 5*HCLK */ +#define EXMC_CLE_RE_DELAY_6_HCLK NPCTL_CTR(5) /* CLE to RE delay = 6*HCLK */ +#define EXMC_CLE_RE_DELAY_7_HCLK NPCTL_CTR(6) /* CLE to RE delay = 7*HCLK */ +#define EXMC_CLE_RE_DELAY_8_HCLK NPCTL_CTR(7) /* CLE to RE delay = 8*HCLK */ +#define EXMC_CLE_RE_DELAY_9_HCLK NPCTL_CTR(8) /* CLE to RE delay = 9*HCLK */ +#define EXMC_CLE_RE_DELAY_10_HCLK NPCTL_CTR(9) /* CLE to RE delay = 10*HCLK */ +#define EXMC_CLE_RE_DELAY_11_HCLK NPCTL_CTR(10) /* CLE to RE delay = 11*HCLK */ +#define EXMC_CLE_RE_DELAY_12_HCLK NPCTL_CTR(11) /* CLE to RE delay = 12*HCLK */ +#define EXMC_CLE_RE_DELAY_13_HCLK NPCTL_CTR(12) /* CLE to RE delay = 13*HCLK */ +#define EXMC_CLE_RE_DELAY_14_HCLK NPCTL_CTR(13) /* CLE to RE delay = 14*HCLK */ +#define EXMC_CLE_RE_DELAY_15_HCLK NPCTL_CTR(14) /* CLE to RE delay = 15*HCLK */ +#define EXMC_CLE_RE_DELAY_16_HCLK NPCTL_CTR(15) /* CLE to RE delay = 16*HCLK */ + +/* NAND bank memory data bus width */ +#define NPCTL_NDW(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define EXMC_NAND_DATABUS_WIDTH_8B NPCTL_NDW(0) /*!< NAND data width 8 bits */ +#define EXMC_NAND_DATABUS_WIDTH_16B NPCTL_NDW(1) /*!< NAND data width 16 bits */ + +/* SDRAM pipeline delay */ +#define SDCTL_PIPED(regval) (BITS(13,14) & ((uint32_t)(regval) << 13)) +#define EXMC_PIPELINE_DELAY_0_HCLK SDCTL_PIPED(0) /*!< 0 HCLK clock cycle delay */ +#define EXMC_PIPELINE_DELAY_1_HCLK SDCTL_PIPED(1) /*!< 1 HCLK clock cycle delay */ +#define EXMC_PIPELINE_DELAY_2_HCLK SDCTL_PIPED(2) /*!< 2 HCLK clock cycle delay */ + +/* SDRAM clock configuration */ +#define SDCTL_SDCLK(regval) (BITS(10,11) & ((uint32_t)(regval) << 10)) +#define EXMC_SDCLK_DISABLE SDCTL_SDCLK(0) /*!< SDCLK memory clock disabled */ +#define EXMC_SDCLK_PERIODS_2_HCLK SDCTL_SDCLK(2) /*!< SDCLK memory period = 2*HCLK */ +#define EXMC_SDCLK_PERIODS_3_HCLK SDCTL_SDCLK(3) /*!< SDCLK memory period = 3*HCLK */ + +/* CAS latency */ +#define SDCTL_CL(regval) (BITS(7,8) & ((uint32_t)(regval) << 7)) +#define EXMC_CAS_LATENCY_1_SDCLK SDCTL_CL(1) /*!< CAS latency is 1 memory clock cycle */ +#define EXMC_CAS_LATENCY_2_SDCLK SDCTL_CL(2) /*!< CAS latency is 2 memory clock cycle */ +#define EXMC_CAS_LATENCY_3_SDCLK SDCTL_CL(3) /*!< CAS latency is 3 memory clock cycle */ + +/* SDRAM data bus width */ +#define SDCTL_SDW(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define EXMC_SDRAM_DATABUS_WIDTH_8B SDCTL_SDW(0) /*!< SDRAM data width 8 bits */ +#define EXMC_SDRAM_DATABUS_WIDTH_16B SDCTL_SDW(1) /*!< SDRAM data width 16 bits */ +#define EXMC_SDRAM_DATABUS_WIDTH_32B SDCTL_SDW(2) /*!< SDRAM data width 32 bits */ + +/* SDRAM row address bit width */ +#define SDCTL_RAW(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define EXMC_SDRAM_ROW_ADDRESS_11 SDCTL_RAW(0) /*!< row address bit width is 11 bits */ +#define EXMC_SDRAM_ROW_ADDRESS_12 SDCTL_RAW(1) /*!< row address bit width is 12 bits */ +#define EXMC_SDRAM_ROW_ADDRESS_13 SDCTL_RAW(2) /*!< row address bit width is 13 bits */ + +/* SDRAM column address bit width */ +#define SDCTL_CAW(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define EXMC_SDRAM_COW_ADDRESS_8 SDCTL_CAW(0) /*!< column address bit width is 8 bits */ +#define EXMC_SDRAM_COW_ADDRESS_9 SDCTL_CAW(1) /*!< column address bit width is 9 bits */ +#define EXMC_SDRAM_COW_ADDRESS_10 SDCTL_CAW(2) /*!< column address bit width is 10 bits */ +#define EXMC_SDRAM_COW_ADDRESS_11 SDCTL_CAW(3) /*!< column address bit width is 11 bits */ + +/* SDRAM number of successive auto-refresh */ +#define SDCMD_NARF(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) +#define EXMC_SDRAM_AUTO_REFLESH_1_SDCLK SDCMD_NARF(0) /*!< 1 auto-refresh cycle */ +#define EXMC_SDRAM_AUTO_REFLESH_2_SDCLK SDCMD_NARF(1) /*!< 2 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_3_SDCLK SDCMD_NARF(2) /*!< 3 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_4_SDCLK SDCMD_NARF(3) /*!< 4 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_5_SDCLK SDCMD_NARF(4) /*!< 5 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_6_SDCLK SDCMD_NARF(5) /*!< 6 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_7_SDCLK SDCMD_NARF(6) /*!< 7 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_8_SDCLK SDCMD_NARF(7) /*!< 8 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_9_SDCLK SDCMD_NARF(8) /*!< 9 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_10_SDCLK SDCMD_NARF(9) /*!< 10 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_11_SDCLK SDCMD_NARF(10) /*!< 11 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_12_SDCLK SDCMD_NARF(11) /*!< 12 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_13_SDCLK SDCMD_NARF(12) /*!< 13 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_14_SDCLK SDCMD_NARF(13) /*!< 14 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_15_SDCLK SDCMD_NARF(14) /*!< 15 auto-refresh cycles */ + +/* SDRAM command select */ +#define SDCMD_CMD(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define EXMC_SDRAM_NORMAL_OPERATION SDCMD_CMD(0) /*!< normal operation command */ +#define EXMC_SDRAM_CLOCK_ENABLE SDCMD_CMD(1) /*!< clock enable command */ +#define EXMC_SDRAM_PRECHARGE_ALL SDCMD_CMD(2) /*!< precharge all command */ +#define EXMC_SDRAM_AUTO_REFRESH SDCMD_CMD(3) /*!< auto-refresh command */ +#define EXMC_SDRAM_LOAD_MODE_REGISTER SDCMD_CMD(4) /*!< load mode register command */ +#define EXMC_SDRAM_SELF_REFRESH SDCMD_CMD(5) /*!< self-refresh command */ +#define EXMC_SDRAM_POWERDOWN_ENTRY SDCMD_CMD(6) /*!< power-down entry command */ + +/* SDRAM the delayed sample clock of read data */ +#define SDRSCTL_SDSC(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define EXMC_SDRAM_0_DELAY_CELL SDRSCTL_SDSC(0) /*!< select the clock after 0 delay cell */ +#define EXMC_SDRAM_1_DELAY_CELL SDRSCTL_SDSC(1) /*!< select the clock after 1 delay cell */ +#define EXMC_SDRAM_2_DELAY_CELL SDRSCTL_SDSC(2) /*!< select the clock after 2 delay cell */ +#define EXMC_SDRAM_3_DELAY_CELL SDRSCTL_SDSC(3) /*!< select the clock after 3 delay cell */ +#define EXMC_SDRAM_4_DELAY_CELL SDRSCTL_SDSC(4) /*!< select the clock after 4 delay cell */ +#define EXMC_SDRAM_5_DELAY_CELL SDRSCTL_SDSC(5) /*!< select the clock after 5 delay cell */ +#define EXMC_SDRAM_6_DELAY_CELL SDRSCTL_SDSC(6) /*!< select the clock after 6 delay cell */ +#define EXMC_SDRAM_7_DELAY_CELL SDRSCTL_SDSC(7) /*!< select the clock after 7 delay cell */ +#define EXMC_SDRAM_8_DELAY_CELL SDRSCTL_SDSC(8) /*!< select the clock after 8 delay cell */ +#define EXMC_SDRAM_9_DELAY_CELL SDRSCTL_SDSC(9) /*!< select the clock after 9 delay cell */ +#define EXMC_SDRAM_10_DELAY_CELL SDRSCTL_SDSC(10) /*!< select the clock after 10 delay cell */ +#define EXMC_SDRAM_11_DELAY_CELL SDRSCTL_SDSC(11) /*!< select the clock after 11 delay cell */ +#define EXMC_SDRAM_12_DELAY_CELL SDRSCTL_SDSC(12) /*!< select the clock after 12 delay cell */ +#define EXMC_SDRAM_13_DELAY_CELL SDRSCTL_SDSC(13) /*!< select the clock after 13 delay cell */ +#define EXMC_SDRAM_14_DELAY_CELL SDRSCTL_SDSC(14) /*!< select the clock after 14 delay cell */ +#define EXMC_SDRAM_15_DELAY_CELL SDRSCTL_SDSC(15) /*!< select the clock after 15 delay cell */ + +/* SPI PSRAM ID length */ +#define SINIT_IDL(regval) (BITS(29,30) & ((uint32_t)(regval) << 29)) +#define EXMC_SQPIPSRAM_ID_LENGTH_64B SINIT_IDL(0) /*!< SPI PSRAM ID length is 64 bits */ +#define EXMC_SQPIPSRAM_ID_LENGTH_32B SINIT_IDL(1) /*!< SPI PSRAM ID length is 32 bits */ +#define EXMC_SQPIPSRAM_ID_LENGTH_16B SINIT_IDL(2) /*!< SPI PSRAM ID length is 16 bits */ +#define EXMC_SQPIPSRAM_ID_LENGTH_8B SINIT_IDL(3) /*!< SPI PSRAM ID length is 8 bits */ + +/* SPI PSRAM bit number of address phase */ +#define SINIT_ADRBIT(regval) (BITS(24,28) & ((uint32_t)(regval) << 24)) +#define EXMC_SQPIPSRAM_ADDR_LENGTH_1B SINIT_ADRBIT(1) /*!< SPI PSRAM address is 1 bit */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_2B SINIT_ADRBIT(2) /*!< SPI PSRAM address is 2 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_3B SINIT_ADRBIT(3) /*!< SPI PSRAM address is 3 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_4B SINIT_ADRBIT(4) /*!< SPI PSRAM address is 4 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_5B SINIT_ADRBIT(5) /*!< SPI PSRAM address is 5 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_6B SINIT_ADRBIT(6) /*!< SPI PSRAM address is 6 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_7B SINIT_ADRBIT(7) /*!< SPI PSRAM address is 7 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_8B SINIT_ADRBIT(8) /*!< SPI PSRAM address is 8 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_9B SINIT_ADRBIT(9) /*!< SPI PSRAM address is 9 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_10B SINIT_ADRBIT(10) /*!< SPI PSRAM address is 10 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_11B SINIT_ADRBIT(11) /*!< SPI PSRAM address is 11 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_12B SINIT_ADRBIT(12) /*!< SPI PSRAM address is 12 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_13B SINIT_ADRBIT(13) /*!< SPI PSRAM address is 13 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_14B SINIT_ADRBIT(14) /*!< SPI PSRAM address is 14 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_15B SINIT_ADRBIT(15) /*!< SPI PSRAM address is 15 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_16B SINIT_ADRBIT(16) /*!< SPI PSRAM address is 16 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_17B SINIT_ADRBIT(17) /*!< SPI PSRAM address is 17 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_18B SINIT_ADRBIT(18) /*!< SPI PSRAM address is 18 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_19B SINIT_ADRBIT(19) /*!< SPI PSRAM address is 19 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_20B SINIT_ADRBIT(20) /*!< SPI PSRAM address is 20 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_21B SINIT_ADRBIT(21) /*!< SPI PSRAM address is 21 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_22B SINIT_ADRBIT(22) /*!< SPI PSRAM address is 22 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_23B SINIT_ADRBIT(23) /*!< SPI PSRAM address is 23 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_24B SINIT_ADRBIT(24) /*!< SPI PSRAM address is 24 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_25B SINIT_ADRBIT(25) /*!< SPI PSRAM address is 25 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_26B SINIT_ADRBIT(26) /*!< SPI PSRAM address is 26 bits */ + +/* SPI PSRAM bit number of command phase */ +#define SINIT_CMDBIT(regval) (BITS(16,17) & ((uint32_t)(regval) << 16)) +#define EXMC_SQPIPSRAM_COMMAND_LENGTH_4B SINIT_CMDBIT(0) /*!< SPI PSRAM command is 4 bits */ +#define EXMC_SQPIPSRAM_COMMAND_LENGTH_8B SINIT_CMDBIT(1) /*!< SPI PSRAM command is 8 bits */ +#define EXMC_SQPIPSRAM_COMMAND_LENGTH_16B SINIT_CMDBIT(2) /*!< SPI PSRAM command is 16 bits */ + +/* SPI PSRAM read command mode */ +#define SRCMD_RMODE(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define EXMC_SQPIPSRAM_READ_MODE_DISABLE SRCMD_RMODE(0) /*!< not SPI mode */ +#define EXMC_SQPIPSRAM_READ_MODE_SPI SRCMD_RMODE(1) /*!< SPI mode */ +#define EXMC_SQPIPSRAM_READ_MODE_SQPI SRCMD_RMODE(2) /*!< SQPI mode */ +#define EXMC_SQPIPSRAM_READ_MODE_QPI SRCMD_RMODE(3) /*!< QPI mode */ + +/* SPI PSRAM write command mode */ +#define SRCMD_WMODE(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define EXMC_SQPIPSRAM_WRITE_MODE_DISABLE SRCMD_WMODE(0) /*!< not SPI mode */ +#define EXMC_SQPIPSRAM_WRITE_MODE_SPI SRCMD_WMODE(1) /*!< SPI mode */ +#define EXMC_SQPIPSRAM_WRITE_MODE_SQPI SRCMD_WMODE(2) /*!< SQPI mode */ +#define EXMC_SQPIPSRAM_WRITE_MODE_QPI SRCMD_WMODE(3) /*!< QPI mode */ + +/* EXMC NOR/SRAM bank region definition */ +#define EXMC_BANK0_NORSRAM_REGION0 ((uint32_t)0x00000000U) /*!< bank0 NOR/SRAM region0 */ +#define EXMC_BANK0_NORSRAM_REGION1 ((uint32_t)0x00000001U) /*!< bank0 NOR/SRAM region1 */ +#define EXMC_BANK0_NORSRAM_REGION2 ((uint32_t)0x00000002U) /*!< bank0 NOR/SRAM region2 */ +#define EXMC_BANK0_NORSRAM_REGION3 ((uint32_t)0x00000003U) /*!< bank0 NOR/SRAM region3 */ + +/* EXMC consecutive clock */ +#define EXMC_CLOCK_SYN_MODE ((uint32_t)0x00000000U) /*!< EXMC_CLK is generated only during synchronous access */ +#define EXMC_CLOCK_UNCONDITIONALLY ((uint32_t)0x00010000U) /*!< EXMC_CLK is generated unconditionally */ + +/* EXMC NOR/SRAM write mode */ +#define EXMC_ASYN_WRITE ((uint32_t)0x00000000U) /*!< asynchronous write mode */ +#define EXMC_SYN_WRITE ((uint32_t)0x00008000U) /*!< synchronous write mode */ + +/* EXMC NWAIT signal configuration */ +#define EXMC_NWAIT_CONFIG_BEFORE ((uint32_t)0x00000000U) /*!< NWAIT signal is active one data cycle before wait state */ +#define EXMC_NWAIT_CONFIG_DURING ((uint32_t)0x00000800U) /*!< NWAIT signal is active during wait state */ + +/* EXMC NWAIT signal polarity configuration */ +#define EXMC_NWAIT_POLARITY_LOW ((uint32_t)0x00000000U) /*!< low level is active of NWAIT */ +#define EXMC_NWAIT_POLARITY_HIGH ((uint32_t)0x00000200U) /*!< high level is active of NWAIT */ + +/* EXMC NAND/PC card bank definition */ +#define EXMC_BANK1_NAND ((uint32_t)0x00000001U) /*!< bank1 NAND flash */ +#define EXMC_BANK2_NAND ((uint32_t)0x00000002U) /*!< bank2 NAND flash */ +#define EXMC_BANK3_PCCARD ((uint32_t)0x00000003U) /*!< bank3 PC card */ + +/* EXMC SDRAM bank definition */ +#define EXMC_SDRAM_DEVICE0 ((uint32_t)0x00000004U) /*!< SDRAM device0 */ +#define EXMC_SDRAM_DEVICE1 ((uint32_t)0x00000005U) /*!< SDRAM device1 */ + +/* EXMC SDRAM internal banks */ +#define EXMC_SDRAM_2_INTER_BANK ((uint32_t)0x00000000U) /*!< 2 internal banks */ +#define EXMC_SDRAM_4_INTER_BANK ((uint32_t)0x00000040U) /*!< 4 internal banks */ + +/* SDRAM device0 select */ +#define EXMC_SDRAM_DEVICE0_UNSELECT ((uint32_t)0x00000000U) /*!< NAND data width 8 bits */ +#define EXMC_SDRAM_DEVICE0_SELECT ((uint32_t)0x00000010U) /*!< NAND data width 16 bits */ + +/* SDRAM device1 select */ +#define EXMC_SDRAM_DEVICE1_UNSELECT ((uint32_t)0x00000000U) /*!< NAND data width 8 bits */ +#define EXMC_SDRAM_DEVICE1_SELECT ((uint32_t)0x00000008U) /*!< NAND data width 16 bits */ + +/* SDRAM device status */ +#define EXMC_SDRAM_DEVICE_NORMAL ((uint32_t)0x00000000U) /*!< normal status */ +#define EXMC_SDRAM_DEVICE_SELF_REFRESH ((uint32_t)0x00000001U) /*!< self refresh status */ +#define EXMC_SDRAM_DEVICE_POWER_DOWN ((uint32_t)0x00000002U) /*!< power down status */ + +/* sample cycle of read data */ +#define EXMC_SDRAM_READSAMPLE_0_EXTRAHCLK ((uint32_t)0x00000000U) /*!< add 0 extra HCLK cycle to the read data sample clock besides the delay chain */ +#define EXMC_SDRAM_READSAMPLE_1_EXTRAHCLK ((uint32_t)0x00000002U) /*!< add 1 extra HCLK cycle to the read data sample clock besides the delay chain */ + +/* read data sample polarity */ +#define EXMC_SDRAM_SAMPLE_RISING_EDGE ((uint32_t)0x00000000U) /*!< sample data at rising edge */ +#define EXMC_SDRAM_SAMPLE_FALLING_EDGE ((uint32_t)0x80000000U) /*!< sample data at falling edge */ + +/* SQPI SRAM command flag */ +#define EXMC_SEND_COMMAND_FLAG_RDID EXMC_SRCMD_RDID /*!< EXMC_SRCMD_RDID flag bit */ +#define EXMC_SEND_COMMAND_FLAG_SC EXMC_SWCMD_SC /*!< EXMC_SWCMD_SC flag bit */ + +/* EXMC flag bits */ +#define EXMC_NAND_PCCARD_FLAG_RISE EXMC_NPINTENx_INTRS /*!< interrupt rising edge status */ +#define EXMC_NAND_PCCARD_FLAG_LEVEL EXMC_NPINTENx_INTHS /*!< interrupt high-level status */ +#define EXMC_NAND_PCCARD_FLAG_FALL EXMC_NPINTENx_INTFS /*!< interrupt falling edge status */ +#define EXMC_NAND_PCCARD_FLAG_FIFOE EXMC_NPINTENx_INTEPT /*!< FIFO empty flag */ +#define EXMC_SDRAM_FLAG_REFRESH EXMC_SDSDAT_REIF /*!< refresh error interrupt flag */ +#define EXMC_SDRAM_FLAG_NREADY EXMC_SDSDAT_NRDY /*!< not ready status */ + +/* EXMC interrupt flag bits */ +#define EXMC_NAND_PCCARD_INT_RISE EXMC_NPINTENx_INTREN /*!< interrupt rising edge detection enable */ +#define EXMC_NAND_PCCARD_INT_LEVEL EXMC_NPINTENx_INTHEN /*!< interrupt high-level detection enable */ +#define EXMC_NAND_PCCARD_INT_FALL EXMC_NPINTENx_INTFEN /*!< interrupt falling edge detection enable */ +#define EXMC_SDRAM_INT_REFRESH EXMC_SDARI_REIE /*!< interrupt refresh error enable */ + +/* function declarations */ +/* deinitialize EXMC NOR/SRAM region */ +void exmc_norsram_deinit(uint32_t exmc_norsram_region); +/* initialize EXMC NOR/SRAM region */ +void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct); +/* exmc_norsram_parameter_struct parameter initialize */ +void exmc_norsram_parameter_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct); +/* consecutive clock configure */ +void exmc_norsram_consecutive_clock_config(uint32_t clock_mode); +/* CRAM page size configure */ +void exmc_norsram_page_size_config(uint32_t page_size); +/* EXMC NOR/SRAM bank enable */ +void exmc_norsram_enable(uint32_t exmc_norsram_region); +/* EXMC NOR/SRAM bank disable */ +void exmc_norsram_disable(uint32_t exmc_norsram_region); + + +/* deinitialize EXMC NAND bank */ +void exmc_nand_deinit(uint32_t exmc_nand_bank); +/* initialize EXMC NAND bank */ +void exmc_nand_init(exmc_nand_parameter_struct* exmc_nand_init_struct); +/* exmc_norsram_parameter_struct parameter initialize */ +void exmc_nand_parameter_init(exmc_nand_parameter_struct* exmc_nand_init_struct); +/* EXMC NAND bank enable */ +void exmc_nand_enable(uint32_t exmc_nand_bank); +/* EXMC NAND bank disable */ +void exmc_nand_disable(uint32_t exmc_nand_bank); +/* enable or disable the EXMC NAND ECC function */ +void exmc_nand_ecc_config(uint32_t exmc_nand_bank, ControlStatus newvalue); +/* get the EXMC ECC value */ +uint32_t exmc_ecc_get(uint32_t exmc_nand_bank); + + +/* deinitialize EXMC PC card bank */ +void exmc_pccard_deinit(void); +/* initialize EXMC PC card bank */ +void exmc_pccard_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct); +/* exmc_pccard_parameter_struct parameter initialize */ +void exmc_pccard_parameter_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct); +/* EXMC PC card bank enable */ +void exmc_pccard_enable(void); +/* EXMC PC card bank disable */ +void exmc_pccard_disable(void); + + +/* deinitialize EXMC SDRAM device */ +void exmc_sdram_deinit(uint32_t exmc_sdram_device); +/* initialize EXMC SDRAM device */ +void exmc_sdram_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct); +/* exmc_sdram_parameter_struct parameter initialize */ +void exmc_sdram_parameter_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct); +/* configure the SDRAM memory command */ +void exmc_sdram_command_config(exmc_sdram_command_parameter_struct* exmc_sdram_command_init_struct); +/* set auto-refresh interval */ +void exmc_sdram_refresh_count_set(uint32_t exmc_count); +/* set the number of successive auto-refresh command */ +void exmc_sdram_autorefresh_number_set(uint32_t exmc_number); +/* config the write protection function */ +void exmc_sdram_write_protection_config(uint32_t exmc_sdram_device, ControlStatus newvalue); +/* get the status of SDRAM device0 or device1 */ +uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device); +/* configure the delayed sample clock of read data */ +void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_hclk); +/* enable or disable read sample */ +void exmc_sdram_readsample_enable(ControlStatus newvalue); + + +/* deinitialize EXMC SQPIPSRAM */ +void exmc_sqpipsram_deinit(void); +/* initialize EXMC SQPIPSRAM */ +void exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct); +/* exmc_sqpipsram_parameter_struct parameter initialize */ +void exmc_sqpipsram_parameter_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct); +/* set the read command */ +void exmc_sqpipsram_read_command_set(uint32_t read_command_mode,uint32_t read_wait_cycle,uint32_t read_command_code); +/* set the write command */ +void exmc_sqpipsram_write_command_set(uint32_t write_command_mode,uint32_t write_wait_cycle,uint32_t write_command_code); +/* send SPI read ID command */ +void exmc_sqpipsram_read_id_command_send(void); +/* send SPI special command which does not have address and data phase */ +void exmc_sqpipsram_write_cmd_send(void); +/* get the EXMC SPI ID low data */ +uint32_t exmc_sqpipsram_low_id_get(void); +/* get the EXMC SPI ID high data */ +uint32_t exmc_sqpipsram_high_id_get(void); +/* get the bit value of EXMC send write command bit or read ID command */ +FlagStatus exmc_sqpipsram_send_command_state_get(uint32_t send_command_flag); + + +/* check EXMC flag is set or not */ +FlagStatus exmc_flag_get(uint32_t exmc_bank,uint32_t flag); +/* clear EXMC flag */ +void exmc_flag_clear(uint32_t exmc_bank,uint32_t flag); +/* check EXMC flag is set or not */ +FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank,uint32_t interrupt_source); +/* clear EXMC one channel flag */ +void exmc_interrupt_flag_clear(uint32_t exmc_bank,uint32_t interrupt_source); +/* enable EXMC interrupt */ +void exmc_interrupt_enable(uint32_t exmc_bank,uint32_t interrupt_source); +/* disable EXMC interrupt */ +void exmc_interrupt_disable(uint32_t exmc_bank,uint32_t interrupt_source); + +#endif /* GD32F4XX_EXMC_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h new file mode 100644 index 0000000000..a0ad59400a --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h @@ -0,0 +1,246 @@ +/*! + \file gd32f4xx_exti.h + \brief definitions for the EXTI +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_EXTI_H +#define GD32F4XX_EXTI_H + +#include "gd32f4xx.h" + +/* EXTI definitions */ +#define EXTI EXTI_BASE + +/* registers definitions */ +#define EXTI_INTEN REG32(EXTI + 0x00U) /*!< interrupt enable register */ +#define EXTI_EVEN REG32(EXTI + 0x04U) /*!< event enable register */ +#define EXTI_RTEN REG32(EXTI + 0x08U) /*!< rising edge trigger enable register */ +#define EXTI_FTEN REG32(EXTI + 0x0CU) /*!< falling trigger enable register */ +#define EXTI_SWIEV REG32(EXTI + 0x10U) /*!< software interrupt event register */ +#define EXTI_PD REG32(EXTI + 0x14U) /*!< pending register */ + +/* bits definitions */ +/* EXTI_INTEN */ +#define EXTI_INTEN_INTEN0 BIT(0) /*!< interrupt from line 0 */ +#define EXTI_INTEN_INTEN1 BIT(1) /*!< interrupt from line 1 */ +#define EXTI_INTEN_INTEN2 BIT(2) /*!< interrupt from line 2 */ +#define EXTI_INTEN_INTEN3 BIT(3) /*!< interrupt from line 3 */ +#define EXTI_INTEN_INTEN4 BIT(4) /*!< interrupt from line 4 */ +#define EXTI_INTEN_INTEN5 BIT(5) /*!< interrupt from line 5 */ +#define EXTI_INTEN_INTEN6 BIT(6) /*!< interrupt from line 6 */ +#define EXTI_INTEN_INTEN7 BIT(7) /*!< interrupt from line 7 */ +#define EXTI_INTEN_INTEN8 BIT(8) /*!< interrupt from line 8 */ +#define EXTI_INTEN_INTEN9 BIT(9) /*!< interrupt from line 9 */ +#define EXTI_INTEN_INTEN10 BIT(10) /*!< interrupt from line 10 */ +#define EXTI_INTEN_INTEN11 BIT(11) /*!< interrupt from line 11 */ +#define EXTI_INTEN_INTEN12 BIT(12) /*!< interrupt from line 12 */ +#define EXTI_INTEN_INTEN13 BIT(13) /*!< interrupt from line 13 */ +#define EXTI_INTEN_INTEN14 BIT(14) /*!< interrupt from line 14 */ +#define EXTI_INTEN_INTEN15 BIT(15) /*!< interrupt from line 15 */ +#define EXTI_INTEN_INTEN16 BIT(16) /*!< interrupt from line 16 */ +#define EXTI_INTEN_INTEN17 BIT(17) /*!< interrupt from line 17 */ +#define EXTI_INTEN_INTEN18 BIT(18) /*!< interrupt from line 18 */ +#define EXTI_INTEN_INTEN19 BIT(19) /*!< interrupt from line 19 */ +#define EXTI_INTEN_INTEN20 BIT(20) /*!< interrupt from line 20 */ +#define EXTI_INTEN_INTEN21 BIT(21) /*!< interrupt from line 21 */ +#define EXTI_INTEN_INTEN22 BIT(22) /*!< interrupt from line 22 */ + +/* EXTI_EVEN */ +#define EXTI_EVEN_EVEN0 BIT(0) /*!< event from line 0 */ +#define EXTI_EVEN_EVEN1 BIT(1) /*!< event from line 1 */ +#define EXTI_EVEN_EVEN2 BIT(2) /*!< event from line 2 */ +#define EXTI_EVEN_EVEN3 BIT(3) /*!< event from line 3 */ +#define EXTI_EVEN_EVEN4 BIT(4) /*!< event from line 4 */ +#define EXTI_EVEN_EVEN5 BIT(5) /*!< event from line 5 */ +#define EXTI_EVEN_EVEN6 BIT(6) /*!< event from line 6 */ +#define EXTI_EVEN_EVEN7 BIT(7) /*!< event from line 7 */ +#define EXTI_EVEN_EVEN8 BIT(8) /*!< event from line 8 */ +#define EXTI_EVEN_EVEN9 BIT(9) /*!< event from line 9 */ +#define EXTI_EVEN_EVEN10 BIT(10) /*!< event from line 10 */ +#define EXTI_EVEN_EVEN11 BIT(11) /*!< event from line 11 */ +#define EXTI_EVEN_EVEN12 BIT(12) /*!< event from line 12 */ +#define EXTI_EVEN_EVEN13 BIT(13) /*!< event from line 13 */ +#define EXTI_EVEN_EVEN14 BIT(14) /*!< event from line 14 */ +#define EXTI_EVEN_EVEN15 BIT(15) /*!< event from line 15 */ +#define EXTI_EVEN_EVEN16 BIT(16) /*!< event from line 16 */ +#define EXTI_EVEN_EVEN17 BIT(17) /*!< event from line 17 */ +#define EXTI_EVEN_EVEN18 BIT(18) /*!< event from line 18 */ +#define EXTI_EVEN_EVEN19 BIT(19) /*!< event from line 19 */ +#define EXTI_EVEN_EVEN20 BIT(20) /*!< event from line 20 */ +#define EXTI_EVEN_EVEN21 BIT(21) /*!< event from line 21 */ +#define EXTI_EVEN_EVEN22 BIT(22) /*!< event from line 22 */ + +/* EXTI_RTEN */ +#define EXTI_RTEN_RTEN0 BIT(0) /*!< rising edge from line 0 */ +#define EXTI_RTEN_RTEN1 BIT(1) /*!< rising edge from line 1 */ +#define EXTI_RTEN_RTEN2 BIT(2) /*!< rising edge from line 2 */ +#define EXTI_RTEN_RTEN3 BIT(3) /*!< rising edge from line 3 */ +#define EXTI_RTEN_RTEN4 BIT(4) /*!< rising edge from line 4 */ +#define EXTI_RTEN_RTEN5 BIT(5) /*!< rising edge from line 5 */ +#define EXTI_RTEN_RTEN6 BIT(6) /*!< rising edge from line 6 */ +#define EXTI_RTEN_RTEN7 BIT(7) /*!< rising edge from line 7 */ +#define EXTI_RTEN_RTEN8 BIT(8) /*!< rising edge from line 8 */ +#define EXTI_RTEN_RTEN9 BIT(9) /*!< rising edge from line 9 */ +#define EXTI_RTEN_RTEN10 BIT(10) /*!< rising edge from line 10 */ +#define EXTI_RTEN_RTEN11 BIT(11) /*!< rising edge from line 11 */ +#define EXTI_RTEN_RTEN12 BIT(12) /*!< rising edge from line 12 */ +#define EXTI_RTEN_RTEN13 BIT(13) /*!< rising edge from line 13 */ +#define EXTI_RTEN_RTEN14 BIT(14) /*!< rising edge from line 14 */ +#define EXTI_RTEN_RTEN15 BIT(15) /*!< rising edge from line 15 */ +#define EXTI_RTEN_RTEN16 BIT(16) /*!< rising edge from line 16 */ +#define EXTI_RTEN_RTEN17 BIT(17) /*!< rising edge from line 17 */ +#define EXTI_RTEN_RTEN18 BIT(18) /*!< rising edge from line 18 */ +#define EXTI_RTEN_RTEN19 BIT(19) /*!< rising edge from line 19 */ +#define EXTI_RTEN_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 */ + EXTI_18 = BIT(18), /*!< EXTI line 18 */ + EXTI_19 = BIT(19), /*!< EXTI line 19 */ + EXTI_20 = BIT(20), /*!< EXTI line 20 */ + EXTI_21 = BIT(21), /*!< EXTI line 21 */ + EXTI_22 = BIT(22), /*!< EXTI line 22 */ +}exti_line_enum; + +/* external interrupt and event */ +typedef enum +{ + EXTI_INTERRUPT = 0, /*!< EXTI interrupt mode */ + EXTI_EVENT /*!< EXTI event mode */ +}exti_mode_enum; + +/* interrupt trigger mode */ +typedef enum +{ + EXTI_TRIG_RISING = 0, /*!< EXTI rising edge trigger */ + EXTI_TRIG_FALLING, /*!< EXTI falling edge trigger */ + EXTI_TRIG_BOTH /*!< EXTI rising and falling edge trigger */ +}exti_trig_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 /* GD32F4XX_EXTI_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h new file mode 100644 index 0000000000..c3b360ab02 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h @@ -0,0 +1,371 @@ +/*! + \file gd32f4xx_fmc.h + \brief definitions for the FMC +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ +#ifndef GD32F4XX_FMC_H +#define GD32F4XX_FMC_H + +#include "gd32f4xx.h" + +/* FMC and option byte definition */ +#define FMC FMC_BASE /*!< FMC register base address */ +#define OB OB_BASE /*!< option byte base address */ + +/* registers definitions */ +#define FMC_WS REG32((FMC) + 0x00U) /*!< FMC wait state register */ +#define FMC_KEY REG32((FMC) + 0x04U) /*!< FMC unlock key register */ +#define FMC_OBKEY REG32((FMC) + 0x08U) /*!< FMC option byte unlock key register */ +#define FMC_STAT REG32((FMC) + 0x0CU) /*!< FMC status register */ +#define FMC_CTL REG32((FMC) + 0x10U) /*!< FMC control register */ +#define FMC_OBCTL0 REG32((FMC) + 0x14U) /*!< FMC option byte control register 0 */ +#define FMC_OBCTL1 REG32((FMC) + 0x18U) /*!< FMC option byte control register 1 */ +#define FMC_WSEN REG32((FMC) + 0xFCU) /*!< FMC wait state enable register */ +#define FMC_PID REG32((FMC) + 0x100U) /*!< FMC product ID register */ + +#define OB_WP1 REG32((OB) + 0x00000008U) /*!< option byte write protection 1 */ +#define OB_USER REG32((OB) + 0x00010000U) /*!< option byte user value*/ +#define OB_SPC REG32((OB) + 0x00010001U) /*!< option byte security protection value */ +#define OB_WP0 REG32((OB) + 0x00010008U) /*!< option byte write protection 0 */ + +/* bits definitions */ +/* FMC_WS */ +#define FMC_WC_WSCNT BITS(0,3) /*!< wait state counter */ + +/* FMC_KEY */ +#define FMC_KEY_KEY BITS(0,31) /*!< FMC main flash key bits */ + +/* FMC_OBKEY */ +#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option byte key bits */ + +/* FMC_STAT */ +#define FMC_STAT_END BIT(0) /*!< end of operation flag bit */ +#define FMC_STAT_OPERR BIT(1) /*!< flash operation error flag bit */ +#define FMC_STAT_WPERR BIT(4) /*!< erase/Program protection error flag bit */ +#define FMC_STAT_PGMERR BIT(6) /*!< program size not match error flag bit */ +#define FMC_STAT_PGSERR BIT(7) /*!< program sequence error flag bit */ +#define FMC_STAT_RDDERR BIT(8) /*!< read D-bus protection error flag bit */ +#define FMC_STAT_BUSY BIT(16) /*!< flash busy flag bit */ + +/* FMC_CTL */ +#define FMC_CTL_PG BIT(0) /*!< main flash program command bit */ +#define FMC_CTL_SER BIT(1) /*!< main flash sector erase command bit */ +#define FMC_CTL_MER0 BIT(2) /*!< main flash mass erase for bank0 command bit */ +#define FMC_CTL_SN BITS(3,7) /*!< select which sector number to be erased */ +#define FMC_CTL_PSZ BITS(8,9) /*!< program size bit */ +#define FMC_CTL_MER1 BIT(15) /*!< main flash mass erase for bank1 command bit */ +#define FMC_CTL_START BIT(16) /*!< send erase command to FMC bit */ +#define FMC_CTL_ENDIE BIT(24) /*!< end of operation interrupt enable bit */ +#define FMC_CTL_ERRIE BIT(25) /*!< error interrupt enable bit */ +#define FMC_CTL_LK BIT(31) /*!< FMC_CTL lock bit */ + +/* FMC_OBCTL0 */ +#define FMC_OBCTL0_OB_LK BIT(0) /*!< FMC_OBCTL0 lock bit */ +#define FMC_OBCTL0_OB_START BIT(1) /*!< send option byte change command to FMC bit */ +#define FMC_OBCTL0_BOR_TH BITS(2,3) /*!< option byte BOR threshold value */ +#define FMC_OBCTL0_BB BIT(4) /*!< option byte boot bank value */ +#define FMC_OBCTL0_NWDG_HW BIT(5) /*!< option byte watchdog value */ +#define FMC_OBCTL0_NRST_DPSLP BIT(6) /*!< option byte deepsleep reset value */ +#define FMC_OBCTL0_NRST_STDBY BIT(7) /*!< option byte standby reset value */ +#define FMC_OBCTL0_SPC BITS(8,15) /*!< option byte Security Protection code */ +#define FMC_OBCTL0_WP0 BITS(16,27) /*!< erase/program protection of each sector when DRP is 0 */ +#define FMC_OBCTL0_DBS BIT(30) /*!< double banks or single bank selection when flash size is 1M bytes */ +#define FMC_OBCTL0_DRP BIT(31) /*!< D-bus read protection bit */ + +/* FMC_OBCTL1 */ +#define FMC_OBCTL1_WP1 BITS(16,27) /*!< erase/program protection of each sector when DRP is 0 */ + +/* FMC_WSEN */ +#define FMC_WSEN_WSEN BIT(0) /*!< FMC wait state enable bit */ + +/* FMC_PID */ +#define FMC_PID_PID BITS(0,31) /*!< product ID bits */ + +/* constants definitions */ +/* fmc state */ +typedef enum +{ + FMC_READY, /*!< the operation has been completed */ + FMC_BUSY, /*!< the operation is in progress */ + FMC_RDDERR, /*!< read D-bus protection error */ + FMC_PGSERR, /*!< program sequence error */ + FMC_PGMERR, /*!< program size not match error */ + FMC_WPERR, /*!< erase/program protection error */ + FMC_OPERR, /*!< operation error */ + FMC_PGERR, /*!< program error */ + FMC_TOERR /*!< timeout error */ +}fmc_state_enum; + +/* unlock key */ +#define UNLOCK_KEY0 ((uint32_t)0x45670123U) /*!< unlock key 0 */ +#define UNLOCK_KEY1 ((uint32_t)0xCDEF89ABU) /*!< unlock key 1 */ + +#define OB_UNLOCK_KEY0 ((uint32_t)0x08192A3BU) /*!< ob unlock key 0 */ +#define OB_UNLOCK_KEY1 ((uint32_t)0x4C5D6E7FU) /*!< ob unlock key 1 */ + +/* FMC time out */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0x000F0000) /*!< enable FMC error timeout */ + +/* option byte write protection */ +#define OB_LWP ((uint32_t)0x000000FFU) /*!< write protection low bits */ +#define OB_HWP ((uint32_t)0x0000FF00U) /*!< write protection high bits */ + +/* FMC wait state counter */ +#define WC_WSCNT(regval) (BITS(0,3) & ((uint32_t)(regval))) +#define WS_WSCNT_0 WC_WSCNT(0) /*!< FMC 0 wait */ +#define WS_WSCNT_1 WC_WSCNT(1) /*!< FMC 1 wait */ +#define WS_WSCNT_2 WC_WSCNT(2) /*!< FMC 2 wait */ +#define WS_WSCNT_3 WC_WSCNT(3) /*!< FMC 3 wait */ +#define WS_WSCNT_4 WC_WSCNT(4) /*!< FMC 4 wait */ +#define WS_WSCNT_5 WC_WSCNT(5) /*!< FMC 5 wait */ +#define WS_WSCNT_6 WC_WSCNT(6) /*!< FMC 6 wait */ +#define WS_WSCNT_7 WC_WSCNT(7) /*!< FMC 7 wait */ +#define WS_WSCNT_8 WC_WSCNT(8) /*!< FMC 8 wait */ +#define WS_WSCNT_9 WC_WSCNT(9) /*!< FMC 9 wait */ +#define WS_WSCNT_10 WC_WSCNT(10) /*!< FMC 10 wait */ +#define WS_WSCNT_11 WC_WSCNT(11) /*!< FMC 11 wait */ +#define WS_WSCNT_12 WC_WSCNT(12) /*!< FMC 12 wait */ +#define WS_WSCNT_13 WC_WSCNT(13) /*!< FMC 13 wait */ +#define WS_WSCNT_14 WC_WSCNT(14) /*!< FMC 14 wait */ +#define WS_WSCNT_15 WC_WSCNT(15) /*!< FMC 15 wait */ + +/* option byte BOR threshold value */ +#define OBCTL0_BOR_TH(regval) (BITS(2,3) & ((uint32_t)(regval))<< 2) +#define OB_BOR_TH_VALUE3 OBCTL0_BOR_TH(0) /*!< BOR threshold value 3 */ +#define OB_BOR_TH_VALUE2 OBCTL0_BOR_TH(1) /*!< BOR threshold value 2 */ +#define OB_BOR_TH_VALUE1 OBCTL0_BOR_TH(2) /*!< BOR threshold value 1 */ +#define OB_BOR_TH_OFF OBCTL0_BOR_TH(3) /*!< no BOR function */ + +/* option byte boot bank value */ +#define OBCTL0_BB(regval) (BIT(4) & ((uint32_t)(regval)<<4)) +#define OB_BB_DISABLE OBCTL0_BB(0) /*!< boot from bank0 */ +#define OB_BB_ENABLE OBCTL0_BB(1) /*!< boot from bank1 or bank0 if bank1 is void */ + +/* option byte software/hardware free watch dog timer */ +#define OBCTL0_NWDG_HW(regval) (BIT(5) & ((uint32_t)(regval))<< 5) +#define OB_FWDGT_SW OBCTL0_NWDG_HW(1) /*!< software free watchdog */ +#define OB_FWDGT_HW OBCTL0_NWDG_HW(0) /*!< hardware free watchdog */ + +/* option byte reset or not entering deep sleep mode */ +#define OBCTL0_NRST_DPSLP(regval) (BIT(6) & ((uint32_t)(regval))<< 6) +#define OB_DEEPSLEEP_NRST OBCTL0_NRST_DPSLP(1) /*!< no reset when entering deepsleep mode */ +#define OB_DEEPSLEEP_RST OBCTL0_NRST_DPSLP(0) /*!< generate a reset instead of entering deepsleep mode */ + +/* option byte reset or not entering standby mode */ +#define OBCTL0_NRST_STDBY(regval) (BIT(7) & ((uint32_t)(regval))<< 7) +#define OB_STDBY_NRST OBCTL0_NRST_STDBY(1) /*!< no reset when entering deepsleep mode */ +#define OB_STDBY_RST OBCTL0_NRST_STDBY(0) /*!< generate a reset instead of entering standby mode */ + +/* read protect configure */ +#define FMC_NSPC ((uint8_t)0xAAU) /*!< no security protection */ +#define FMC_LSPC ((uint8_t)0xABU) /*!< low security protection */ +#define FMC_HSPC ((uint8_t)0xCCU) /*!< high security protection */ + +/* option bytes write protection */ +#define OB_WP_0 ((uint32_t)0x00000001U) /*!< erase/program protection of sector 0 */ +#define OB_WP_1 ((uint32_t)0x00000002U) /*!< erase/program protection of sector 1 */ +#define OB_WP_2 ((uint32_t)0x00000004U) /*!< erase/program protection of sector 2 */ +#define OB_WP_3 ((uint32_t)0x00000008U) /*!< erase/program protection of sector 3 */ +#define OB_WP_4 ((uint32_t)0x00000010U) /*!< erase/program protection of sector 4 */ +#define OB_WP_5 ((uint32_t)0x00000020U) /*!< erase/program protection of sector 5 */ +#define OB_WP_6 ((uint32_t)0x00000040U) /*!< erase/program protection of sector 6 */ +#define OB_WP_7 ((uint32_t)0x00000080U) /*!< erase/program protection of sector 7 */ +#define OB_WP_8 ((uint32_t)0x00000100U) /*!< erase/program protection of sector 8 */ +#define OB_WP_9 ((uint32_t)0x00000200U) /*!< erase/program protection of sector 9 */ +#define OB_WP_10 ((uint32_t)0x00000400U) /*!< erase/program protection of sector 10 */ +#define OB_WP_11 ((uint32_t)0x00000800U) /*!< erase/program protection of sector 11 */ +#define OB_WP_12 ((uint32_t)0x00000001U) /*!< erase/program protection of sector 12 */ +#define OB_WP_13 ((uint32_t)0x00000002U) /*!< erase/program protection of sector 13 */ +#define OB_WP_14 ((uint32_t)0x00000004U) /*!< erase/program protection of sector 14 */ +#define OB_WP_15 ((uint32_t)0x00000008U) /*!< erase/program protection of sector 15 */ +#define OB_WP_16 ((uint32_t)0x00000010U) /*!< erase/program protection of sector 16 */ +#define OB_WP_17 ((uint32_t)0x00000020U) /*!< erase/program protection of sector 17 */ +#define OB_WP_18 ((uint32_t)0x00000040U) /*!< erase/program protection of sector 18 */ +#define OB_WP_19 ((uint32_t)0x00000080U) /*!< erase/program protection of sector 19 */ +#define OB_WP_20 ((uint32_t)0x00000100U) /*!< erase/program protection of sector 20 */ +#define OB_WP_21 ((uint32_t)0x00000200U) /*!< erase/program protection of sector 21 */ +#define OB_WP_22 ((uint32_t)0x00000400U) /*!< erase/program protection of sector 22 */ +#define OB_WP_23_30 ((uint32_t)0x00000800U) /*!< erase/program protection of sector 23~30 */ +#define OB_WP_ALL ((uint32_t)0x00000FFFU) /*!< erase/program protection of all sectors */ + +/* option bytes D-bus read protection */ +#define OB_DRP_0 ((uint32_t)0x00000001U) /*!< D-bus read protection protection of sector 0 */ +#define OB_DRP_1 ((uint32_t)0x00000002U) /*!< D-bus read protection protection of sector 1 */ +#define OB_DRP_2 ((uint32_t)0x00000004U) /*!< D-bus read protection protection of sector 2 */ +#define OB_DRP_3 ((uint32_t)0x00000008U) /*!< D-bus read protection protection of sector 3 */ +#define OB_DRP_4 ((uint32_t)0x00000010U) /*!< D-bus read protection protection of sector 4 */ +#define OB_DRP_5 ((uint32_t)0x00000020U) /*!< D-bus read protection protection of sector 5 */ +#define OB_DRP_6 ((uint32_t)0x00000040U) /*!< D-bus read protection protection of sector 6 */ +#define OB_DRP_7 ((uint32_t)0x00000080U) /*!< D-bus read protection protection of sector 7 */ +#define OB_DRP_8 ((uint32_t)0x00000100U) /*!< D-bus read protection protection of sector 8 */ +#define OB_DRP_9 ((uint32_t)0x00000200U) /*!< D-bus read protection protection of sector 9 */ +#define OB_DRP_10 ((uint32_t)0x00000400U) /*!< D-bus read protection protection of sector 10 */ +#define OB_DRP_11 ((uint32_t)0x00000800U) /*!< D-bus read protection protection of sector 11 */ +#define OB_DRP_12 ((uint32_t)0x00000001U) /*!< D-bus read protection protection of sector 12 */ +#define OB_DRP_13 ((uint32_t)0x00000002U) /*!< D-bus read protection protection of sector 13 */ +#define OB_DRP_14 ((uint32_t)0x00000004U) /*!< D-bus read protection protection of sector 14 */ +#define OB_DRP_15 ((uint32_t)0x00000008U) /*!< D-bus read protection protection of sector 15 */ +#define OB_DRP_16 ((uint32_t)0x00000010U) /*!< D-bus read protection protection of sector 16 */ +#define OB_DRP_17 ((uint32_t)0x00000020U) /*!< D-bus read protection protection of sector 17 */ +#define OB_DRP_18 ((uint32_t)0x00000040U) /*!< D-bus read protection protection of sector 18 */ +#define OB_DRP_19 ((uint32_t)0x00000080U) /*!< D-bus read protection protection of sector 19 */ +#define OB_DRP_20 ((uint32_t)0x00000100U) /*!< D-bus read protection protection of sector 20 */ +#define OB_DRP_21 ((uint32_t)0x00000200U) /*!< D-bus read protection protection of sector 21 */ +#define OB_DRP_22 ((uint32_t)0x00000400U) /*!< D-bus read protection protection of sector 22 */ +#define OB_DRP_23_30 ((uint32_t)0x00000800U) /*!< D-bus read protection protection of sector 23~30 */ +#define OB_DRP_ALL ((uint32_t)0x00000FFFU) /*!< D-bus read protection protection of all sectors */ + +/* double banks or single bank selection when flash size is 1M bytes */ +#define OBCTL0_DBS(regval) (BIT(30) & ((uint32_t)(regval)<<30)) +#define OB_DBS_DISABLE OBCTL0_DBS(0) /*!< single bank when flash size is 1M bytes */ +#define OB_DBS_ENABLE OBCTL0_DBS(1) /*!< double bank when flash size is 1M bytes */ + +/* option bytes D-bus read protection mode */ +#define OBCTL0_DRP(regval) (BIT(31) & ((uint32_t)(regval)<<31)) +#define OB_DRP_DISABLE OBCTL0_DRP(0) /*!< the WPx bits used as erase/program protection of each sector */ +#define OB_DRP_ENABLE OBCTL0_DRP(1) /*!< the WPx bits used as erase/program protection and D-bus read protection of each sector */ + +/* FMC sectors */ +#define CTL_SN(regval) (BITS(3,7) & ((uint32_t)(regval))<< 3) +#define CTL_SECTOR_NUMBER_0 CTL_SN(0) /*!< sector 0 */ +#define CTL_SECTOR_NUMBER_1 CTL_SN(1) /*!< sector 1 */ +#define CTL_SECTOR_NUMBER_2 CTL_SN(2) /*!< sector 2 */ +#define CTL_SECTOR_NUMBER_3 CTL_SN(3) /*!< sector 3 */ +#define CTL_SECTOR_NUMBER_4 CTL_SN(4) /*!< sector 4 */ +#define CTL_SECTOR_NUMBER_5 CTL_SN(5) /*!< sector 5 */ +#define CTL_SECTOR_NUMBER_6 CTL_SN(6) /*!< sector 6 */ +#define CTL_SECTOR_NUMBER_7 CTL_SN(7) /*!< sector 7 */ +#define CTL_SECTOR_NUMBER_8 CTL_SN(8) /*!< sector 8 */ +#define CTL_SECTOR_NUMBER_9 CTL_SN(9) /*!< sector 9 */ +#define CTL_SECTOR_NUMBER_10 CTL_SN(10) /*!< sector 10 */ +#define CTL_SECTOR_NUMBER_11 CTL_SN(11) /*!< sector 11 */ +#define CTL_SECTOR_NUMBER_24 CTL_SN(12) /*!< sector 24 */ +#define CTL_SECTOR_NUMBER_25 CTL_SN(13) /*!< sector 25 */ +#define CTL_SECTOR_NUMBER_26 CTL_SN(14) /*!< sector 26 */ +#define CTL_SECTOR_NUMBER_27 CTL_SN(15) /*!< sector 27 */ +#define CTL_SECTOR_NUMBER_12 CTL_SN(16) /*!< sector 12 */ +#define CTL_SECTOR_NUMBER_13 CTL_SN(17) /*!< sector 13 */ +#define CTL_SECTOR_NUMBER_14 CTL_SN(18) /*!< sector 14 */ +#define CTL_SECTOR_NUMBER_15 CTL_SN(19) /*!< sector 15 */ +#define CTL_SECTOR_NUMBER_16 CTL_SN(20) /*!< sector 16 */ +#define CTL_SECTOR_NUMBER_17 CTL_SN(21) /*!< sector 17 */ +#define CTL_SECTOR_NUMBER_18 CTL_SN(22) /*!< sector 18 */ +#define CTL_SECTOR_NUMBER_19 CTL_SN(23) /*!< sector 19 */ +#define CTL_SECTOR_NUMBER_20 CTL_SN(24) /*!< sector 20 */ +#define CTL_SECTOR_NUMBER_21 CTL_SN(25) /*!< sector 21 */ +#define CTL_SECTOR_NUMBER_22 CTL_SN(26) /*!< sector 22 */ +#define CTL_SECTOR_NUMBER_23 CTL_SN(27) /*!< sector 23 */ +#define CTL_SECTOR_NUMBER_28 CTL_SN(28) /*!< sector 28 */ +#define CTL_SECTOR_NUMBER_29 CTL_SN(29) /*!< sector 29 */ +#define CTL_SECTOR_NUMBER_30 CTL_SN(30) /*!< sector 30 */ + +/* FMC program size */ +#define CTL_PSZ(regval) (BITS(8,9) & ((uint32_t)(regval))<< 8) +#define CTL_PSZ_BYTE CTL_PSZ(0) /*!< FMC program by byte access */ +#define CTL_PSZ_HALF_WORD CTL_PSZ(1) /*!< FMC program by half-word access */ +#define CTL_PSZ_WORD CTL_PSZ(2) /*!< FMC program by word access */ + +/* FMC interrupt enable */ +#define FMC_INTEN_END ((uint32_t)0x01000000U) /*!< enable FMC end of program interrupt */ +#define FMC_INTEN_ERR ((uint32_t)0x02000000U) /*!< enable FMC error interrupt */ + +/* FMC flags */ +#define FMC_FLAG_END ((uint32_t)0x00000001U) /*!< FMC end of operation flag bit */ +#define FMC_FLAG_OPERR ((uint32_t)0x00000002U) /*!< FMC operation error flag bit */ +#define FMC_FLAG_WPERR ((uint32_t)0x00000010U) /*!< FMC erase/program protection error flag bit */ +#define FMC_FLAG_PGMERR ((uint32_t)0x00000040U) /*!< FMC program size not match error flag bit */ +#define FMC_FLAG_PGSERR ((uint32_t)0x00000080U) /*!< FMC program sequence error flag bit */ +#define FMC_FLAG_RDDERR ((uint32_t)0x00000100U) /*!< FMC read D-bus protection error flag bit */ +#define FMC_FLAG_BUSY ((uint32_t)0x00010000U) /*!< FMC busy flag */ + +/* function declarations */ +/* FMC main memory programming functions */ +/* set the FMC wait state counter */ +void fmc_wscnt_set(uint32_t wscnt); +/* unlock the main FMC operation */ +void fmc_unlock(void); +/* lock the main FMC operation */ +void fmc_lock(void); +/* FMC erase sector */ +fmc_state_enum fmc_sector_erase(uint32_t fmc_sector); +/* FMC erase whole chip */ +fmc_state_enum fmc_mass_erase(void); +/* FMC erase whole bank0 */ +fmc_state_enum fmc_bank0_erase(void); +/* FMC erase whole bank1 */ +fmc_state_enum fmc_bank1_erase(void); +/* FMC program a word at the corresponding address */ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data); +/* FMC program a half word at the corresponding address */ +fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data); +/* FMC program a byte at the corresponding address */ +fmc_state_enum fmc_byte_program(uint32_t address, uint8_t data); + +/* FMC option bytes programming functions */ +/* unlock the option byte operation */ +void ob_unlock(void); +/* lock the option byte operation */ +void ob_lock(void); +/* send option byte change command */ +void ob_start(void); +/* enable write protect */ +void ob_write_protection0_enable(uint32_t ob_wp); +/* disable write protect */ +void ob_write_protection0_disable(uint32_t ob_wp); +/* enable write protect */ +void ob_write_protection1_enable(uint32_t ob_wp); +/* disable write protect */ +void ob_write_protection1_disable(uint32_t ob_wp); +/* configure the erase/program protection mode */ +void ob_drp_config(uint32_t ob_drp); +/* enable the erase/program protection mode */ +void ob_drp0_enable(uint32_t ob_drp); +/* disable the erase/program protection mode */ +void ob_drp0_disable(uint32_t ob_drp); +/* enable the erase/program protection mode */ +void ob_drp1_enable(uint32_t ob_drp); +/* disable the erase/program protection mode */ +void ob_drp1_disable(uint32_t ob_drp); +/* set the option byte security protection level */ +void ob_security_protection_config(uint8_t ob_spc); +/* write the FMC option byte user */ +void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby); +/* option byte BOR threshold value */ +void ob_user_bor_threshold(uint32_t ob_bor_th); +/* configure the boot mode */ +void ob_boot_mode_config(uint32_t boot_mode); +/* get the FMC option byte user */ +uint8_t ob_user_get(void); +/* get the FMC option byte write protection */ +uint16_t ob_write_protection0_get(void); +/* get the FMC option byte write protection */ +uint16_t ob_write_protection1_get(void); +/* get the FMC erase/program protection and D-bus read protection option bytes value */ +uint16_t ob_drp0_get(void); +/* get the FMC erase/program protection and D-bus read protection option bytes value */ +uint16_t ob_drp1_get(void); +/* get option byte security protection code value */ +FlagStatus ob_spc_get(void); +/* get the FMC threshold value */ +uint8_t ob_user_bor_threshold_get(void); + +/* FMC interrupts and flags management functions */ +/* enable FMC interrupt */ +void fmc_interrupt_enable(uint32_t fmc_int); +/* disable FMC interrupt */ +void fmc_interrupt_disable(uint32_t fmc_int); +/* get flag set or reset */ +FlagStatus fmc_flag_get(uint32_t fmc_flag); +/* clear the FMC pending flag */ +void fmc_flag_clear(uint32_t fmc_flag); +/* return the FMC state */ +fmc_state_enum fmc_state_get(void); +/* check FMC ready or not */ +fmc_state_enum fmc_ready_wait(uint32_t count); + +#endif /* GD32F4XX_FMC_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h new file mode 100644 index 0000000000..b63efc9293 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h @@ -0,0 +1,75 @@ +/*! + \file gd32f4xx_fwdgt.h + \brief definitions for the FWDGT +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_FWDGT_H +#define GD32F4XX_FWDGT_H + +#include "gd32f4xx.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE + +/* registers definitions */ +#define FWDGT_CTL REG32((FWDGT) + 0x00U) /*!< FWDGT control register */ +#define FWDGT_PSC REG32((FWDGT) + 0x04U) /*!< FWDGT prescaler register */ +#define FWDGT_RLD REG32((FWDGT) + 0x08U) /*!< FWDGT reload register */ +#define FWDGT_STAT REG32((FWDGT) + 0x0CU) /*!< FWDGT status register */ + +/* bits definitions */ +/* FWDGT_CTL */ +#define FWDGT_CTL_CMD BITS(0,15) /*!< FWDGT command value */ + +/* FWDGT_PSC */ +#define FWDGT_PSC_PSC BITS(0,2) /*!< FWDGT prescaler divider value */ + +/* FWDGT_RLD */ +#define FWDGT_RLD_RLD BITS(0,11) /*!< FWDGT counter reload value */ + +/* FWDGT_STAT */ +#define FWDGT_STAT_PUD BIT(0) /*!< FWDGT prescaler divider value update */ +#define FWDGT_STAT_RUD BIT(1) /*!< FWDGT counter reload value update */ + +/* constants definitions */ +/* psc register value */ +#define PSC_PSC(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define FWDGT_PSC_DIV4 ((uint8_t)PSC_PSC(0)) /*!< FWDGT prescaler set to 4 */ +#define FWDGT_PSC_DIV8 ((uint8_t)PSC_PSC(1)) /*!< FWDGT prescaler set to 8 */ +#define FWDGT_PSC_DIV16 ((uint8_t)PSC_PSC(2)) /*!< FWDGT prescaler set to 16 */ +#define FWDGT_PSC_DIV32 ((uint8_t)PSC_PSC(3)) /*!< FWDGT prescaler set to 32 */ +#define FWDGT_PSC_DIV64 ((uint8_t)PSC_PSC(4)) /*!< FWDGT prescaler set to 64 */ +#define FWDGT_PSC_DIV128 ((uint8_t)PSC_PSC(5)) /*!< FWDGT prescaler set to 128 */ +#define FWDGT_PSC_DIV256 ((uint8_t)PSC_PSC(6)) /*!< FWDGT prescaler set to 256 */ + +/* control value */ +#define FWDGT_WRITEACCESS_ENABLE ((uint16_t)0x5555U) /*!< FWDGT_CTL bits write access enable value */ +#define FWDGT_WRITEACCESS_DISABLE ((uint16_t)0x0000U) /*!< FWDGT_CTL bits write access disable value */ +#define FWDGT_KEY_RELOAD ((uint16_t)0xAAAAU) /*!< FWDGT_CTL bits fwdgt counter reload value */ +#define FWDGT_KEY_ENABLE ((uint16_t)0xCCCCU) /*!< FWDGT_CTL bits fwdgt counter enable value */ + +/* FWDGT timeout value */ +#define FWDGT_PSC_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_PSC register write operation state flag timeout */ +#define FWDGT_RLD_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_RLD register write operation state flag timeout */ + +/* function declarations */ +/* disable write access to FWDGT_PSC and FWDGT_RLD */ +void fwdgt_write_disable(void); +/* start the free watchdog timer counter */ +void fwdgt_enable(void); + +/* reload the counter of FWDGT */ +void fwdgt_counter_reload(void); +/* configure counter reload value, and prescaler divider value */ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div); + +/* get flag state of FWDGT */ +FlagStatus fwdgt_flag_get(uint16_t flag); + +#endif /* GD32F4XX_FWDGT_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h new file mode 100644 index 0000000000..257962d6de --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h @@ -0,0 +1,383 @@ +/*! + \file gd32f4xx_gpio.h + \brief definitions for the GPIO +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_GPIO_H +#define GD32F4XX_GPIO_H + +#include "gd32f4xx.h" + +/* GPIOx(x=A,B,C,D,E,F,G,H,I) definitions */ +#define GPIOA (GPIO_BASE + 0x00000000U) +#define GPIOB (GPIO_BASE + 0x00000400U) +#define GPIOC (GPIO_BASE + 0x00000800U) +#define GPIOD (GPIO_BASE + 0x00000C00U) +#define GPIOE (GPIO_BASE + 0x00001000U) +#define GPIOF (GPIO_BASE + 0x00001400U) +#define GPIOG (GPIO_BASE + 0x00001800U) +#define GPIOH (GPIO_BASE + 0x00001C00U) +#define GPIOI (GPIO_BASE + 0x00002000U) + +/* registers definitions */ +#define GPIO_CTL(gpiox) REG32((gpiox) + 0x00U) /*!< GPIO port control register */ +#define GPIO_OMODE(gpiox) REG32((gpiox) + 0x04U) /*!< GPIO port output mode register */ +#define GPIO_OSPD(gpiox) REG32((gpiox) + 0x08U) /*!< GPIO port output speed register */ +#define GPIO_PUD(gpiox) REG32((gpiox) + 0x0CU) /*!< GPIO port pull-up/pull-down register */ +#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x10U) /*!< GPIO port input status register */ +#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x14U) /*!< GPIO port output control register */ +#define GPIO_BOP(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port bit operation register */ +#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x1CU) /*!< GPIO port configuration lock register */ +#define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x20U) /*!< GPIO alternate function selected register 0 */ +#define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x24U) /*!< GPIO alternate function selected register 1 */ +#define GPIO_BC(gpiox) REG32((gpiox) + 0x28U) /*!< GPIO bit clear register */ +#define GPIO_TG(gpiox) REG32((gpiox) + 0x2CU) /*!< GPIO port bit toggle register */ + +/* bits definitions */ +/* GPIO_CTL */ +#define GPIO_CTL_CTL0 BITS(0,1) /*!< pin 0 configuration bits */ +#define GPIO_CTL_CTL1 BITS(2,3) /*!< pin 1 configuration bits */ +#define GPIO_CTL_CTL2 BITS(4,5) /*!< pin 2 configuration bits */ +#define GPIO_CTL_CTL3 BITS(6,7) /*!< pin 3 configuration bits */ +#define GPIO_CTL_CTL4 BITS(8,9) /*!< pin 4 configuration bits */ +#define GPIO_CTL_CTL5 BITS(10,11) /*!< pin 5 configuration bits */ +#define GPIO_CTL_CTL6 BITS(12,13) /*!< pin 6 configuration bits */ +#define GPIO_CTL_CTL7 BITS(14,15) /*!< pin 7 configuration bits */ +#define GPIO_CTL_CTL8 BITS(16,17) /*!< pin 8 configuration bits */ +#define GPIO_CTL_CTL9 BITS(18,19) /*!< pin 9 configuration bits */ +#define GPIO_CTL_CTL10 BITS(20,21) /*!< pin 10 configuration bits */ +#define GPIO_CTL_CTL11 BITS(22,23) /*!< pin 11 configuration bits */ +#define GPIO_CTL_CTL12 BITS(24,25) /*!< pin 12 configuration bits */ +#define GPIO_CTL_CTL13 BITS(26,27) /*!< pin 13 configuration bits */ +#define GPIO_CTL_CTL14 BITS(28,29) /*!< pin 14 configuration bits */ +#define GPIO_CTL_CTL15 BITS(30,31) /*!< pin 15 configuration bits */ + +/* GPIO_OMODE */ +#define GPIO_OMODE_OM0 BIT(0) /*!< pin 0 output mode bit */ +#define GPIO_OMODE_OM1 BIT(1) /*!< pin 1 output mode bit */ +#define GPIO_OMODE_OM2 BIT(2) /*!< pin 2 output mode bit */ +#define GPIO_OMODE_OM3 BIT(3) /*!< pin 3 output mode bit */ +#define GPIO_OMODE_OM4 BIT(4) /*!< pin 4 output mode bit */ +#define GPIO_OMODE_OM5 BIT(5) /*!< pin 5 output mode bit */ +#define GPIO_OMODE_OM6 BIT(6) /*!< pin 6 output mode bit */ +#define GPIO_OMODE_OM7 BIT(7) /*!< pin 7 output mode bit */ +#define GPIO_OMODE_OM8 BIT(8) /*!< pin 8 output mode bit */ +#define GPIO_OMODE_OM9 BIT(9) /*!< pin 9 output mode bit */ +#define GPIO_OMODE_OM10 BIT(10) /*!< pin 10 output mode bit */ +#define GPIO_OMODE_OM11 BIT(11) /*!< pin 11 output mode bit */ +#define GPIO_OMODE_OM12 BIT(12) /*!< pin 12 output mode bit */ +#define GPIO_OMODE_OM13 BIT(13) /*!< pin 13 output mode bit */ +#define GPIO_OMODE_OM14 BIT(14) /*!< pin 14 output mode bit */ +#define GPIO_OMODE_OM15 BIT(15) /*!< pin 15 output mode bit */ + +/* GPIO_OSPD */ +#define GPIO_OSPD_OSPD0 BITS(0,1) /*!< pin 0 output max speed bits */ +#define GPIO_OSPD_OSPD1 BITS(2,3) /*!< pin 1 output max speed bits */ +#define GPIO_OSPD_OSPD2 BITS(4,5) /*!< pin 2 output max speed bits */ +#define GPIO_OSPD_OSPD3 BITS(6,7) /*!< pin 3 output max speed bits */ +#define GPIO_OSPD_OSPD4 BITS(8,9) /*!< pin 4 output max speed bits */ +#define GPIO_OSPD_OSPD5 BITS(10,11) /*!< pin 5 output max speed bits */ +#define GPIO_OSPD_OSPD6 BITS(12,13) /*!< pin 6 output max speed bits */ +#define GPIO_OSPD_OSPD7 BITS(14,15) /*!< pin 7 output max speed bits */ +#define GPIO_OSPD_OSPD8 BITS(16,17) /*!< pin 8 output max speed bits */ +#define GPIO_OSPD_OSPD9 BITS(18,19) /*!< pin 9 output max speed bits */ +#define GPIO_OSPD_OSPD10 BITS(20,21) /*!< pin 10 output max speed bits */ +#define GPIO_OSPD_OSPD11 BITS(22,23) /*!< pin 11 output max speed bits */ +#define GPIO_OSPD_OSPD12 BITS(24,25) /*!< pin 12 output max speed bits */ +#define GPIO_OSPD_OSPD13 BITS(26,27) /*!< pin 13 output max speed bits */ +#define GPIO_OSPD_OSPD14 BITS(28,29) /*!< pin 14 output max speed bits */ +#define GPIO_OSPD_OSPD15 BITS(30,31) /*!< pin 15 output max speed bits */ + +/* GPIO_PUD */ +#define GPIO_PUD_PUD0 BITS(0,1) /*!< pin 0 pull-up or pull-down bits */ +#define GPIO_PUD_PUD1 BITS(2,3) /*!< pin 1 pull-up or pull-down bits */ +#define GPIO_PUD_PUD2 BITS(4,5) /*!< pin 2 pull-up or pull-down bits */ +#define GPIO_PUD_PUD3 BITS(6,7) /*!< pin 3 pull-up or pull-down bits */ +#define GPIO_PUD_PUD4 BITS(8,9) /*!< pin 4 pull-up or pull-down bits */ +#define GPIO_PUD_PUD5 BITS(10,11) /*!< pin 5 pull-up or pull-down bits */ +#define GPIO_PUD_PUD6 BITS(12,13) /*!< pin 6 pull-up or pull-down bits */ +#define GPIO_PUD_PUD7 BITS(14,15) /*!< pin 7 pull-up or pull-down bits */ +#define GPIO_PUD_PUD8 BITS(16,17) /*!< pin 8 pull-up or pull-down bits */ +#define GPIO_PUD_PUD9 BITS(18,19) /*!< pin 9 pull-up or pull-down bits */ +#define GPIO_PUD_PUD10 BITS(20,21) /*!< pin 10 pull-up or pull-down bits */ +#define GPIO_PUD_PUD11 BITS(22,23) /*!< pin 11 pull-up or pull-down bits */ +#define GPIO_PUD_PUD12 BITS(24,25) /*!< pin 12 pull-up or pull-down bits */ +#define GPIO_PUD_PUD13 BITS(26,27) /*!< pin 13 pull-up or pull-down bits */ +#define GPIO_PUD_PUD14 BITS(28,29) /*!< pin 14 pull-up or pull-down bits */ +#define GPIO_PUD_PUD15 BITS(30,31) /*!< pin 15 pull-up or pull-down bits */ + +/* GPIO_ISTAT */ +#define GPIO_ISTAT_ISTAT0 BIT(0) /*!< pin 0 input status */ +#define GPIO_ISTAT_ISTAT1 BIT(1) /*!< pin 1 input status */ +#define GPIO_ISTAT_ISTAT2 BIT(2) /*!< pin 2 input status */ +#define GPIO_ISTAT_ISTAT3 BIT(3) /*!< pin 3 input status */ +#define GPIO_ISTAT_ISTAT4 BIT(4) /*!< pin 4 input status */ +#define GPIO_ISTAT_ISTAT5 BIT(5) /*!< pin 5 input status */ +#define GPIO_ISTAT_ISTAT6 BIT(6) /*!< pin 6 input status */ +#define GPIO_ISTAT_ISTAT7 BIT(7) /*!< pin 7 input status */ +#define GPIO_ISTAT_ISTAT8 BIT(8) /*!< pin 8 input status */ +#define GPIO_ISTAT_ISTAT9 BIT(9) /*!< pin 9 input status */ +#define GPIO_ISTAT_ISTAT10 BIT(10) /*!< pin 10 input status */ +#define GPIO_ISTAT_ISTAT11 BIT(11) /*!< pin 11 input status */ +#define GPIO_ISTAT_ISTAT12 BIT(12) /*!< pin 12 input status */ +#define GPIO_ISTAT_ISTAT13 BIT(13) /*!< pin 13 input status */ +#define GPIO_ISTAT_ISTAT14 BIT(14) /*!< pin 14 input status */ +#define GPIO_ISTAT_ISTAT15 BIT(15) /*!< pin 15 input status */ + +/* GPIO_OCTL */ +#define GPIO_OCTL_OCTL0 BIT(0) /*!< pin 0 output bit */ +#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output bit */ +#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output bit */ +#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output bit */ +#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output bit */ +#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output bit */ +#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output bit */ +#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output bit */ +#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output bit */ +#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output bit */ +#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output bit */ +#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output bit */ +#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output bit */ +#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output bit */ +#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output bit */ +#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output bit */ + +/* GPIO_BOP */ +#define GPIO_BOP_BOP0 BIT(0) /*!< pin 0 set bit */ +#define GPIO_BOP_BOP1 BIT(1) /*!< pin 1 set bit */ +#define GPIO_BOP_BOP2 BIT(2) /*!< pin 2 set bit */ +#define GPIO_BOP_BOP3 BIT(3) /*!< pin 3 set bit */ +#define GPIO_BOP_BOP4 BIT(4) /*!< pin 4 set bit */ +#define GPIO_BOP_BOP5 BIT(5) /*!< pin 5 set bit */ +#define GPIO_BOP_BOP6 BIT(6) /*!< pin 6 set bit */ +#define GPIO_BOP_BOP7 BIT(7) /*!< pin 7 set bit */ +#define GPIO_BOP_BOP8 BIT(8) /*!< pin 8 set bit */ +#define GPIO_BOP_BOP9 BIT(9) /*!< pin 9 set bit */ +#define GPIO_BOP_BOP10 BIT(10) /*!< pin 10 set bit */ +#define GPIO_BOP_BOP11 BIT(11) /*!< pin 11 set bit */ +#define GPIO_BOP_BOP12 BIT(12) /*!< pin 12 set bit */ +#define GPIO_BOP_BOP13 BIT(13) /*!< pin 13 set bit */ +#define GPIO_BOP_BOP14 BIT(14) /*!< pin 14 set bit */ +#define GPIO_BOP_BOP15 BIT(15) /*!< pin 15 set bit */ +#define GPIO_BOP_CR0 BIT(16) /*!< pin 0 clear bit */ +#define GPIO_BOP_CR1 BIT(17) /*!< pin 1 clear bit */ +#define GPIO_BOP_CR2 BIT(18) /*!< pin 2 clear bit */ +#define GPIO_BOP_CR3 BIT(19) /*!< pin 3 clear bit */ +#define GPIO_BOP_CR4 BIT(20) /*!< pin 4 clear bit */ +#define GPIO_BOP_CR5 BIT(21) /*!< pin 5 clear bit */ +#define GPIO_BOP_CR6 BIT(22) /*!< pin 6 clear bit */ +#define GPIO_BOP_CR7 BIT(23) /*!< pin 7 clear bit */ +#define GPIO_BOP_CR8 BIT(24) /*!< pin 8 clear bit */ +#define GPIO_BOP_CR9 BIT(25) /*!< pin 9 clear bit */ +#define GPIO_BOP_CR10 BIT(26) /*!< pin 10 clear bit */ +#define GPIO_BOP_CR11 BIT(27) /*!< pin 11 clear bit */ +#define GPIO_BOP_CR12 BIT(28) /*!< pin 12 clear bit */ +#define GPIO_BOP_CR13 BIT(29) /*!< pin 13 clear bit */ +#define GPIO_BOP_CR14 BIT(30) /*!< pin 14 clear bit */ +#define GPIO_BOP_CR15 BIT(31) /*!< pin 15 clear bit */ + +/* GPIO_LOCK */ +#define GPIO_LOCK_LK0 BIT(0) /*!< pin 0 lock bit */ +#define GPIO_LOCK_LK1 BIT(1) /*!< pin 1 lock bit */ +#define GPIO_LOCK_LK2 BIT(2) /*!< pin 2 lock bit */ +#define GPIO_LOCK_LK3 BIT(3) /*!< pin 3 lock bit */ +#define GPIO_LOCK_LK4 BIT(4) /*!< pin 4 lock bit */ +#define GPIO_LOCK_LK5 BIT(5) /*!< pin 5 lock bit */ +#define GPIO_LOCK_LK6 BIT(6) /*!< pin 6 lock bit */ +#define GPIO_LOCK_LK7 BIT(7) /*!< pin 7 lock bit */ +#define GPIO_LOCK_LK8 BIT(8) /*!< pin 8 lock bit */ +#define GPIO_LOCK_LK9 BIT(9) /*!< pin 9 lock bit */ +#define GPIO_LOCK_LK10 BIT(10) /*!< pin 10 lock bit */ +#define GPIO_LOCK_LK11 BIT(11) /*!< pin 11 lock bit */ +#define GPIO_LOCK_LK12 BIT(12) /*!< pin 12 lock bit */ +#define GPIO_LOCK_LK13 BIT(13) /*!< pin 13 lock bit */ +#define GPIO_LOCK_LK14 BIT(14) /*!< pin 14 lock bit */ +#define GPIO_LOCK_LK15 BIT(15) /*!< pin 15 lock bit */ +#define GPIO_LOCK_LKK BIT(16) /*!< pin sequence lock key */ + +/* GPIO_AFSEL0 */ +#define GPIO_AFSEL0_SEL0 BITS(0,3) /*!< pin 0 alternate function selected */ +#define GPIO_AFSEL0_SEL1 BITS(4,7) /*!< pin 1 alternate function selected */ +#define GPIO_AFSEL0_SEL2 BITS(8,11) /*!< pin 2 alternate function selected */ +#define GPIO_AFSEL0_SEL3 BITS(12,15) /*!< pin 3 alternate function selected */ +#define GPIO_AFSEL0_SEL4 BITS(16,19) /*!< pin 4 alternate function selected */ +#define GPIO_AFSEL0_SEL5 BITS(20,23) /*!< pin 5 alternate function selected */ +#define GPIO_AFSEL0_SEL6 BITS(24,27) /*!< pin 6 alternate function selected */ +#define GPIO_AFSEL0_SEL7 BITS(28,31) /*!< pin 7 alternate function selected */ + +/* GPIO_AFSEL1 */ +#define GPIO_AFSEL1_SEL8 BITS(0,3) /*!< pin 8 alternate function selected */ +#define GPIO_AFSEL1_SEL9 BITS(4,7) /*!< pin 9 alternate function selected */ +#define GPIO_AFSEL1_SEL10 BITS(8,11) /*!< pin 10 alternate function selected */ +#define GPIO_AFSEL1_SEL11 BITS(12,15) /*!< pin 11 alternate function selected */ +#define GPIO_AFSEL1_SEL12 BITS(16,19) /*!< pin 12 alternate function selected */ +#define GPIO_AFSEL1_SEL13 BITS(20,23) /*!< pin 13 alternate function selected */ +#define GPIO_AFSEL1_SEL14 BITS(24,27) /*!< pin 14 alternate function selected */ +#define GPIO_AFSEL1_SEL15 BITS(28,31) /*!< pin 15 alternate function selected */ + +/* GPIO_BC */ +#define GPIO_BC_CR0 BIT(0) /*!< pin 0 clear bit */ +#define GPIO_BC_CR1 BIT(1) /*!< pin 1 clear bit */ +#define GPIO_BC_CR2 BIT(2) /*!< pin 2 clear bit */ +#define GPIO_BC_CR3 BIT(3) /*!< pin 3 clear bit */ +#define GPIO_BC_CR4 BIT(4) /*!< pin 4 clear bit */ +#define GPIO_BC_CR5 BIT(5) /*!< pin 5 clear bit */ +#define GPIO_BC_CR6 BIT(6) /*!< pin 6 clear bit */ +#define GPIO_BC_CR7 BIT(7) /*!< pin 7 clear bit */ +#define GPIO_BC_CR8 BIT(8) /*!< pin 8 clear bit */ +#define GPIO_BC_CR9 BIT(9) /*!< pin 9 clear bit */ +#define GPIO_BC_CR10 BIT(10) /*!< pin 10 clear bit */ +#define GPIO_BC_CR11 BIT(11) /*!< pin 11 clear bit */ +#define GPIO_BC_CR12 BIT(12) /*!< pin 12 clear bit */ +#define GPIO_BC_CR13 BIT(13) /*!< pin 13 clear bit */ +#define GPIO_BC_CR14 BIT(14) /*!< pin 14 clear bit */ +#define GPIO_BC_CR15 BIT(15) /*!< pin 15 clear bit */ + +/* GPIO_TG */ +#define GPIO_TG_TG0 BIT(0) /*!< pin 0 toggle bit */ +#define GPIO_TG_TG1 BIT(1) /*!< pin 1 toggle bit */ +#define GPIO_TG_TG2 BIT(2) /*!< pin 2 toggle bit */ +#define GPIO_TG_TG3 BIT(3) /*!< pin 3 toggle bit */ +#define GPIO_TG_TG4 BIT(4) /*!< pin 4 toggle bit */ +#define GPIO_TG_TG5 BIT(5) /*!< pin 5 toggle bit */ +#define GPIO_TG_TG6 BIT(6) /*!< pin 6 toggle bit */ +#define GPIO_TG_TG7 BIT(7) /*!< pin 7 toggle bit */ +#define GPIO_TG_TG8 BIT(8) /*!< pin 8 toggle bit */ +#define GPIO_TG_TG9 BIT(9) /*!< pin 9 toggle bit */ +#define GPIO_TG_TG10 BIT(10) /*!< pin 10 toggle bit */ +#define GPIO_TG_TG11 BIT(11) /*!< pin 11 toggle bit */ +#define GPIO_TG_TG12 BIT(12) /*!< pin 12 toggle bit */ +#define GPIO_TG_TG13 BIT(13) /*!< pin 13 toggle bit */ +#define GPIO_TG_TG14 BIT(14) /*!< pin 14 toggle bit */ +#define GPIO_TG_TG15 BIT(15) /*!< pin 15 toggle bit */ + +/* constants definitions */ +typedef FlagStatus bit_status; + +/* output mode definitions */ +#define CTL_CLTR(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_MODE_INPUT CTL_CLTR(0) /*!< input mode */ +#define GPIO_MODE_OUTPUT CTL_CLTR(1) /*!< output mode */ +#define GPIO_MODE_AF CTL_CLTR(2) /*!< alternate function mode */ +#define GPIO_MODE_ANALOG CTL_CLTR(3) /*!< analog mode */ + +/* pull up pull down definitions */ +#define PUD_PUPD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_PUPD_NONE PUD_PUPD(0) /*!< 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 ((uint32_t)(0xFFFF)) /*!< GPIO pin all */ + +/* gpio ctlr 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)(0x00)) /*!< push pull mode */ +#define GPIO_OTYPE_OD ((uint8_t)(0x01)) /*!< open drain mode */ + +/* gpio output max speed level */ +#define OSPD_OSPD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_OSPEED_LEVEL0 OSPD_OSPD(0) /*!< output max speed level 0 */ +#define GPIO_OSPEED_LEVEL1 OSPD_OSPD(1) /*!< output max speed level 1 */ +#define GPIO_OSPEED_LEVEL2 OSPD_OSPD(2) /*!< output max speed level 2 */ +#define GPIO_OSPEED_LEVEL3 OSPD_OSPD(3) /*!< output max speed level 3 */ + +/* gpio output max speed value */ +#define GPIO_OSPEED_2MHZ GPIO_OSPEED_LEVEL0 /*!< output max speed 2M */ +#define GPIO_OSPEED_25MHZ GPIO_OSPEED_LEVEL1 /*!< output max speed 25M */ +#define GPIO_OSPEED_50MHZ GPIO_OSPEED_LEVEL2 /*!< output max speed 50M */ +#define GPIO_OSPEED_200MHZ GPIO_OSPEED_LEVEL3 /*!< output max speed 200M */ + +/* 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 */ +#define GPIO_AF_12 AF(12) /*!< alternate function selected 12 */ +#define GPIO_AF_13 AF(13) /*!< alternate function selected 13 */ +#define GPIO_AF_14 AF(14) /*!< alternate function selected 14 */ +#define GPIO_AF_15 AF(15) /*!< alternate function selected 15 */ + +/* function declarations */ +/* reset gpio port */ +void gpio_deinit(uint32_t gpio_periph); +/* set gpio mode */ +void gpio_mode_set(uint32_t gpio_periph,uint32_t mode,uint32_t pull_up_down,uint32_t pin); +/* set gpio output type and speed */ +void gpio_output_options_set(uint32_t gpio_periph,uint8_t otype,uint32_t speed,uint32_t pin); + +/* set gpio pin bit */ +void gpio_bit_set(uint32_t gpio_periph,uint32_t pin); +/* reset gpio pin bit */ +void gpio_bit_reset(uint32_t gpio_periph,uint32_t pin); +/* write data to the specified gpio pin */ +void gpio_bit_write(uint32_t gpio_periph,uint32_t pin,bit_status bit_value); +/* write data to the specified gpio port */ +void gpio_port_write(uint32_t gpio_periph,uint16_t data); + +/* get gpio pin input status */ +FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin); +/* get gpio port input status */ +uint16_t gpio_input_port_get(uint32_t gpio_periph); +/* get gpio pin output status */ +FlagStatus gpio_output_bit_get(uint32_t gpio_periph,uint32_t pin); +/* get gpio port output status */ +uint16_t gpio_output_port_get(uint32_t gpio_periph); + +/* set gpio alternate function */ +void gpio_af_set(uint32_t gpio_periph,uint32_t alt_func_num,uint32_t pin); +/* lock gpio pin bit */ +void gpio_pin_lock(uint32_t gpio_periph,uint32_t pin); + +/* toggle gpio pin status */ +void gpio_bit_toggle(uint32_t gpio_periph,uint32_t pin); +/* toggle gpio port status */ +void gpio_port_toggle(uint32_t gpio_periph); + +#endif /* GD32F4XX_GPIO_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h new file mode 100644 index 0000000000..f7e93d3357 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h @@ -0,0 +1,331 @@ +/*! + \file gd32f4xx_i2c.h + \brief definitions for the I2C +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_I2C_H +#define GD32F4XX_I2C_H + +#include "gd32f4xx.h" + +/* I2Cx(x=0,1,2) definitions */ +#define I2C0 I2C_BASE +#define I2C1 (I2C_BASE+0x400U) +#define I2C2 (I2C_BASE+0x800U) + +/* 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 */ +#define I2C_FCTL(i2cx) REG32((i2cx) + 0x24U) /*!< I2C filter control register */ +#define I2C_SAMCS(i2cx) REG32((i2cx) + 0x80U) /*!< I2C SAM control and status register */ + + +/* bits definitions */ +/* I2Cx_CTL0 */ +#define I2C_CTL0_I2CEN BIT(0) /*!< peripheral enable */ +#define I2C_CTL0_SMBEN BIT(1) /*!< SMBus mode */ +#define I2C_CTL0_SMBSEL BIT(3) /*!< SMBus type */ +#define I2C_CTL0_ARPEN BIT(4) /*!< ARP enable */ +#define I2C_CTL0_PECEN BIT(5) /*!< PEC enable */ +#define I2C_CTL0_GCEN BIT(6) /*!< general call enable */ +#define I2C_CTL0_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 register */ + +/* I2Cx_CKCFG */ +#define I2C_CKCFG_CLKC BITS(0,11) /*!< clock control register in fast/standard mode (master mode) */ +#define I2C_CKCFG_DTCY BIT(14) /*!< fast mode duty cycle */ +#define I2C_CKCFG_FAST BIT(15) /*!< I2C speed selection in master mode */ + +/* I2Cx_RT */ +#define I2C_RT_RISETIME BITS(0,5) /*!< maximum rise time in fast/standard mode (Master mode) */ + +/* I2Cx_FCTL */ +#define I2C_FCTL_DF BITS(0,3) /*!< digital noise filter */ +#define I2C_FCTL_AFD BIT(4) /*!< analog noise filter disable */ + +/* I2Cx_SAMCS */ +#define I2C_SAMCS_SAMEN BIT(0) /*!< SAM_V interface enable */ +#define I2C_SAMCS_STOEN BIT(1) /*!< SAM_V interface timeout detect enable */ +#define I2C_SAMCS_TFFIE BIT(4) /*!< txframe fall interrupt enable */ +#define I2C_SAMCS_TFRIE BIT(5) /*!< txframe rise interrupt enable */ +#define I2C_SAMCS_RFFIE BIT(6) /*!< rxframe fall interrupt enable */ +#define I2C_SAMCS_RFRIE BIT(7) /*!< rxframe rise interrupt enable */ +#define I2C_SAMCS_TXF BIT(8) /*!< level of txframe signal */ +#define I2C_SAMCS_RXF BIT(9) /*!< level of rxframe signal */ +#define I2C_SAMCS_TFF BIT(12) /*!< txframe fall flag, cleared by software write 0 */ +#define I2C_SAMCS_TFR BIT(13) /*!< txframe rise flag, cleared by software write 0 */ +#define I2C_SAMCS_RFF BIT(14) /*!< rxframe fall flag, cleared by software write 0 */ +#define I2C_SAMCS_RFR BIT(15) /*!< rxframe rise flag, cleared by software write 0 */ + + +/* constants definitions */ + +/* the digital noise filter can filter spikes's length */ +typedef enum { + I2C_DF_DISABLE, /*!< disable digital noise filter */ + I2C_DF_1PCLK, /*!< enable digital noise filter and the maximum filtered spiker's length 1 PCLK1 */ + I2C_DF_2PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 2 PCLK1 */ + I2C_DF_3PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 3 PCLK1 */ + I2C_DF_4PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 4 PCLK1 */ + I2C_DF_5PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 5 PCLK1 */ + I2C_DF_6PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 6 PCLK1 */ + I2C_DF_7PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 7 PCLK1 */ + I2C_DF_8PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 8 PCLK1 */ + I2C_DF_9PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 9 PCLK1 */ + I2C_DF_10PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 10 PCLK1 */ + I2C_DF_11PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 11 PCLK1 */ + I2C_DF_12PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 12 PCLK1 */ + I2C_DF_13PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 13 PCLK1 */ + I2C_DF_14PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 14 PCLK1 */ + I2C_DF_15PCLKS /*!< enable digital noise filter and the maximum filtered spiker's length 15 PCLK1 */ +}i2c_digital_filter_enum; + +/* 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_TRANSMITTER (~BIT(0)) /*!< transmitter */ +#define I2C_RECEIVER BIT(0) /*!< receiver */ + +/* whether or not to send an ACK */ +#define I2C_ACK_ENABLE ((uint8_t)0x01U) /*!< ACK will be sent */ +#define I2C_ACK_DISABLE ((uint8_t)0x00U) /*!< ACK will be not sent */ + +/* I2C POAP position*/ +#define I2C_ACKPOS_CURRENT ((uint8_t)0x01U) /*!< ACKEN bit decides whether to send ACK or not for the current */ +#define I2C_ACKPOS_NEXT ((uint8_t)0x00U) /*!< ACKEN bit decides whether to send ACK or not for the next byte */ + +/* I2C dual-address mode switch */ +#define I2C_DUADEN_DISABLE ((uint8_t)0x00U) /*!< dual-address mode disabled */ +#define I2C_DUADEN_ENABLE ((uint8_t)0x01U) /*!< 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 is enabled */ +#define I2C_ARP_DISABLE ((uint32_t)0x00000000U) /*!< ARP is disabled */ + +/* I2C state */ +/* I2C bit state */ +#define I2C_SBSEND BIT(0) /*!< start condition sent out in master mode */ +#define I2C_ADDSEND BIT(1) /*!< address is sent in master mode or received and matches in slave mode */ +#define I2C_BTC BIT(2) /*!< byte transmission finishes */ +#define I2C_ADD10SEND BIT(3) /*!< header of 10-bit address is sent in master mode */ +#define I2C_STPDET BIT(4) /*!< etop condition detected in slave mode */ +#define I2C_RBNE BIT(6) /*!< I2C_DATA is not Empty during receiving */ +#define I2C_TBE BIT(7) /*!< I2C_DATA is empty during transmitting */ +#define I2C_BERR BIT(8) /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */ +#define I2C_LOSTARB BIT(9) /*!< arbitration lost in master mode */ +#define I2C_AERR BIT(10) /*!< acknowledge error */ +#define I2C_OUERR BIT(11) /*!< over-run or under-run situation occurs in slave mode */ +#define I2C_PECERR BIT(12) /*!< PEC error when receiving data */ +#define I2C_SMBTO BIT(14) /*!< timeout signal in SMBus mode */ +#define I2C_SMBALT BIT(15) /*!< SMBus alert status */ +#define I2C_MASTER (BIT(0)|BIT(31)) /*!< a flag indicating whether I2C block is in master or slave mode */ +#define I2C_I2CBSY (BIT(1)|BIT(31)) /*!< busy flag */ +#define I2C_TRS (BIT(2)|BIT(31)) /*!< whether the I2C is a transmitter or a receiver */ +#define I2C_RXGC (BIT(4)|BIT(31)) /*!< general call address (00h) received */ +#define I2C_DEFSMB (BIT(5)|BIT(31)) /*!< default address of SMBus device */ +#define I2C_HSTSMB (BIT(6)|BIT(31)) /*!< SMBus host header detected in slave mode */ +#define I2C_DUMODF (BIT(7)|BIT(31)) /*!< dual flag in slave mode indicating which address is matched in dual-address mode */ + +/* 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) & ((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); +/* I2C clock configure */ +void i2c_clock_config(uint32_t i2c_periph,uint32_t clkspeed,uint32_t dutycyc); +/* I2C address configure */ +void i2c_mode_addr_config(uint32_t i2c_periph,uint32_t i2cmod,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,uint8_t ack); +/* I2C POAP position configure */ +void i2c_ackpos_config(uint32_t i2c_periph,uint8_t pos); +/* master send slave address */ +void i2c_master_addressing(uint32_t i2c_periph,uint8_t addr,uint32_t trandirection); +/* dual-address mode switch */ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint8_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_transmit_data(uint32_t i2c_periph,uint8_t data); +/* i2c receive data function */ +uint8_t i2c_receive_data(uint32_t i2c_periph); +/* I2C DMA mode enable */ +void i2c_dma_enable(uint32_t i2c_periph,uint32_t dmastste); +/* 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 state */ +FlagStatus i2c_flag_get(uint32_t i2c_periph,uint32_t state); +/* clear i2c state */ +void i2c_flag_clear(uint32_t i2c_periph,uint32_t state); +/* 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); + +/* 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(uint32_t i2c_periph); + +/* I2C issue alert through SMBA pin */ +void i2c_smbus_alert_issue(uint32_t i2c_periph,uint32_t smbuspara); +/* I2C ARP protocol in SMBus switch */ +void i2c_smbus_arp_enable(uint32_t i2c_periph,uint32_t arpstate); + +/* I2C analog noise filter disable */ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph); +/* I2C analog noise filter enable */ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph); +/* digital noise filter */ +void i2c_digital_noise_filter_config(uint32_t i2c_periph,i2c_digital_filter_enum dfilterpara); + +/* enable SAM_V interface */ +void i2c_sam_enable(uint32_t i2c_periph); +/* disable SAM_V interface */ +void i2c_sam_disable(uint32_t i2c_periph); +/* enable SAM_V interface timeout detect */ +void i2c_sam_timeout_enable(uint32_t i2c_periph); +/* disable SAM_V interface timeout detect */ +void i2c_sam_timeout_disable(uint32_t i2c_periph); +/* 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 /* GD32F4XX_I2C_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h new file mode 100644 index 0000000000..d356ac8c3d --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h @@ -0,0 +1,320 @@ +/*! + \file gd32f4xx_ipa.h + \brief definitions for the IPA +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_IPA_H +#define GD32F4XX_IPA_H + +#include "gd32f4xx.h" + +/* TLI definitions */ +#define IPA IPA_BASE /*!< IPA base address */ + +/* bits definitions */ +/* registers definitions */ +#define IPA_CTL REG32(IPA + 0x00U) /*!< IPA control register */ +#define IPA_INTF REG32(IPA + 0x04U) /*!< IPA interrupt flag register */ +#define IPA_INTC REG32(IPA + 0x08U) /*!< IPA interrupt flag clear register */ +#define IPA_FMADDR REG32(IPA + 0x0CU) /*!< IPA foreground memory base address register */ +#define IPA_FLOFF REG32(IPA + 0x10U) /*!< IPA foreground line offset register */ +#define IPA_BMADDR REG32(IPA + 0x14U) /*!< IPA background memory base address register */ +#define IPA_BLOFF REG32(IPA + 0x18U) /*!< IPA background line offset register */ +#define IPA_FPCTL REG32(IPA + 0x1CU) /*!< IPA foreground pixel control register */ +#define IPA_FPV REG32(IPA + 0x20U) /*!< IPA foreground pixel value register */ +#define IPA_BPCTL REG32(IPA + 0x24U) /*!< IPA background pixel control register */ +#define IPA_BPV REG32(IPA + 0x28U) /*!< IPA background pixel value register */ +#define IPA_FLMADDR REG32(IPA + 0x2CU) /*!< IPA foreground LUT memory base address register */ +#define IPA_BLMADDR REG32(IPA + 0x30U) /*!< IPA background LUT memory base address register */ +#define IPA_DPCTL REG32(IPA + 0x34U) /*!< IPA destination pixel control register */ +#define IPA_DPV REG32(IPA + 0x38U) /*!< IPA destination pixel value register */ +#define IPA_DMADDR REG32(IPA + 0x3CU) /*!< IPA destination memory base address register */ +#define IPA_DLOFF REG32(IPA + 0x40U) /*!< IPA destination line offset register */ +#define IPA_IMS REG32(IPA + 0x44U) /*!< IPA image size register */ +#define IPA_LM REG32(IPA + 0x48U) /*!< IPA line mark register */ +#define IPA_ITCTL REG32(IPA + 0x4CU) /*!< IPA inter-timer control register */ + +/* IPA_CTL */ +#define IPA_CTL_TEN BIT(0) /*!< transfer enable */ +#define IPA_CTL_THU BIT(1) /*!< transfer hang up */ +#define IPA_CTL_TST BIT(2) /*!< transfer stop */ +#define IPA_CTL_TAEIE BIT(8) /*!< enable bit for transfer access error interrupt */ +#define IPA_CTL_FTFIE BIT(9) /*!< enable bit for full transfer finish interrup */ +#define IPA_CTL_TLMIE BIT(10) /*!< enable bit for transfer line mark interrupt */ +#define IPA_CTL_LACIE BIT(11) /*!< enable bit for LUT access conflict interrupt */ +#define IPA_CTL_LLFIE BIT(12) /*!< enable bit for LUT loading finish interrupt */ +#define IPA_CTL_WCFIE BIT(13) /*!< enable bit for wrong configuration interrupt */ +#define IPA_CTL_PFCM BITS(16,17) /*!< pixel format convert mode */ + +/* IPA_INTF */ +#define IPA_INTF_TAEIF BIT(0) /*!< transfer access error interrupt flag */ +#define IPA_INTF_FTFIF BIT(1) /*!< full transfer finish interrupt flag */ +#define IPA_INTF_TLMIF BIT(2) /*!< transfer line mark interrupt flag */ +#define IPA_INTF_LACIF BIT(3) /*!< LUT access conflict interrupt flag */ +#define IPA_INTF_LLFIF BIT(4) /*!< LUT loading finish interrupt flag */ +#define IPA_INTF_WCFIF BIT(5) /*!< wrong configuration interrupt flag */ + +/* IPA_INTC */ +#define IPA_INTC_TAEIFC BIT(0) /*!< clear bit for transfer access error interrupt flag */ +#define IPA_INTC_FTFIFC BIT(1) /*!< clear bit for full transfer finish interrupt flag */ +#define IPA_INTC_TLMIFC BIT(2) /*!< clear bit for transfer line mark interrupt flag */ +#define IPA_INTC_LACIFC BIT(3) /*!< clear bit for LUT access conflict interrupt flag */ +#define IPA_INTC_LLFIFC BIT(4) /*!< clear bit for LUT loading finish interrupt flag */ +#define IPA_INTC_WCFIFC BIT(5) /*!< clear bit for wrong configuration interrupt flag */ + +/* IPA_FMADDR */ +#define IPA_FMADDR_FMADDR BITS(0,31) /*!< foreground memory base address */ + +/* IPA_FLOFF */ +#define IPA_FLOFF_FLOFF BITS(0,13) /*!< foreground line offset */ + +/* IPA_BMADDR */ +#define IPA_BMADDR_BMADDR BITS(0,31) /*!< background memory base address */ + +/* IPA_BLOFF */ +#define IPA_BLOFF_BLOFF BITS(0,13) /*!< background line offset */ + +/* IPA_FPCTL */ +#define IPA_FPCTL_FPF BITS(0,3) /*!< foreground pixel format */ +#define IPA_FPCTL_FLPF BIT(4) /*!< foreground LUT pixel format */ +#define IPA_FPCTL_FLLEN BIT(5) /*!< foreground LUT loading enable */ +#define IPA_FPCTL_FCNP BITS(8,15) /*!< foreground LUT number of pixel */ +#define IPA_FPCTL_FAVCA BITS(16,17) /*!< foreground alpha value calculation algorithm */ +#define IPA_FPCTL_FPDAV BITS(24,31) /*!< foreground pre- defined alpha value */ + +/* IPA_FPV */ +#define IPA_FPV_FPDBV BITS(0,7) /*!< foreground pre-defined red value */ +#define IPA_FPV_FPDGV BITS(8,15) /*!< foreground pre-defined green value */ +#define IPA_FPV_FPDRV BITS(16,23) /*!< foreground pre-defined red value */ + +/* IPA_BPCTL */ +#define IPA_BPCTL_BPF BITS(0,3) /*!< background pixel format */ +#define IPA_BPCTL_BLPF BIT(4) /*!< background LUT pixel format */ +#define IPA_BPCTL_BLLEN BIT(5) /*!< background LUT loading enable */ +#define IPA_BPCTL_BCNP BITS(8,15) /*!< background LUT number of pixel */ +#define IPA_BPCTL_BAVCA BITS(16,17) /*!< background alpha value calculation algorithm */ +#define IPA_BPCTL_BPDAV BITS(24,31) /*!< background pre- defined alpha value */ + +/* IPA_BPV */ +#define IPA_BPV_BPDBV BITS(0,7) /*!< background pre-defined blue value */ +#define IPA_BPV_BPDGV BITS(8,15) /*!< background pre-defined green value */ +#define IPA_BPV_BPDRV BITS(16,23) /*!< background pre-defined red value */ + +/* IPA_FLMADDR */ +#define IPA_FLMADDR_FLMADDR BITS(0,31) /*!< foreground LUT memory base address */ + +/* IPA_BLMADDR */ +#define IPA_BLMADDR_BLMADDR BITS(0,31) /*!< background LUT memory base address */ + +/* IPA_DPCTL */ +#define IPA_DPCTL_DPF BITS(0,2) /*!< destination pixel control register */ + +/* IPA_DPV */ +/* destination pixel format ARGB8888 */ +#define IPA_DPV_DPDBV_0 BITS(0,7) /*!< destination pre-defined blue value */ +#define IPA_DPV_DPDGV_0 BITS(8,15) /*!< destination pre-defined green value */ +#define IPA_DPV_DPDRV_0 BITS(16,23) /*!< destination pre-defined red value */ +#define IPA_DPV_DPDAV_0 BITS(24,31) /*!< destination pre-defined alpha value */ + +/* destination pixel format RGB8888 */ +#define IPA_DPV_DPDBV_1 BITS(0,7) /*!< destination pre-defined blue value */ +#define IPA_DPV_DPDGV_1 BITS(8,15) /*!< destination pre-defined green value */ +#define IPA_DPV_DPDRV_1 BITS(16,23) /*!< destination pre-defined red value */ + +/* destination pixel format RGB565 */ +#define IPA_DPV_DPDBV_2 BITS(0,4) /*!< destination pre-defined blue value */ +#define IPA_DPV_DPDGV_2 BITS(5,10) /*!< destination pre-defined green value */ +#define IPA_DPV_DPDRV_2 BITS(11,15) /*!< destination pre-defined red value */ + +/* destination pixel format ARGB1555 */ +#define IPA_DPV_DPDBV_3 BITS(0,4) /*!< destination pre-defined blue value */ +#define IPA_DPV_DPDGV_3 BITS(5,9) /*!< destination pre-defined green value */ +#define IPA_DPV_DPDRV_3 BITS(10,14) /*!< destination pre-defined red value */ +#define IPA_DPV_DPDAV_3 BIT(15) /*!< destination pre-defined alpha value */ + +/* destination pixel format ARGB4444 */ +#define IPA_DPV_DPDBV_4 BITS(0,3) /*!< destination pre-defined blue value */ +#define IPA_DPV_DPDGV_4 BITS(4,7) /*!< destination pre-defined green value */ +#define IPA_DPV_DPDRV_4 BITS(8,11) /*!< destination pre-defined red value */ +#define IPA_DPV_DPDAV_4 BITS(12,15) /*!< destination pre-defined alpha value */ + +/* IPA_DMADDR */ +#define IPA_DMADDR_DMADDR BITS(0,31) /*!< destination memory base address */ + +/* IPA_DLOFF */ +#define IPA_DLOFF_DLOFF BITS(0,13) /*!< destination line offset */ + +/* IPA_IMS */ +#define IPA_IMS_HEIGHT BITS(0,15) /*!< height of the image to be processed */ +#define IPA_IMS_WIDTH BITS(16,29) /*!< width of the image to be processed */ + +/* IPA_LM */ +#define IPA_LM_LM BITS(0,15) /*!< line mark */ + +/* IPA_ITCTL */ +#define IPA_ITCTL_ITEN BIT(0) /*!< inter-timer enable */ +#define IPA_ITCTL_NCCI BITS(8,15) /*!< number of clock cycles interval */ + + +/* constants definitions */ +/* IPA foreground parameter struct definitions */ +typedef struct +{ + uint32_t foreground_memaddr; /*!< foreground memory base address */ + uint32_t foreground_lineoff; /*!< foreground line offset */ + uint32_t foreground_prealpha; /*!< foreground pre-defined alpha value */ + uint32_t foreground_alpha_algorithm; /*!< foreground alpha value calculation algorithm */ + uint32_t foreground_pf; /*!< foreground pixel format */ + uint32_t foreground_prered; /*!< foreground pre-defined red value */ + uint32_t foreground_pregreen; /*!< foreground pre-defined green value */ + uint32_t foreground_preblue; /*!< foreground pre-defined blue value */ +}ipa_foreground_parameter_struct; + +/* IPA background parameter struct definitions */ +typedef struct +{ + uint32_t background_memaddr; /*!< background memory base address */ + uint32_t background_lineoff; /*!< background line offset */ + uint32_t background_prealpha; /*!< background pre-defined alpha value */ + uint32_t background_alpha_algorithm; /*!< background alpha value calculation algorithm */ + uint32_t background_pf; /*!< background pixel format */ + uint32_t background_prered; /*!< background pre-defined red value */ + uint32_t background_pregreen; /*!< background pre-defined green value */ + uint32_t background_preblue; /*!< background pre-defined blue value */ +}ipa_background_parameter_struct; + +/* IPA destination parameter struct definitions */ +typedef struct +{ + uint32_t destination_memaddr; /*!< destination memory base address */ + uint32_t destination_lineoff; /*!< destination line offset */ + uint32_t destination_prealpha; /*!< destination pre-defined alpha value */ + uint32_t destination_pf; /*!< destination pixel format */ + uint32_t destination_prered; /*!< destination pre-defined red value */ + uint32_t destination_pregreen; /*!< destination pre-defined green value */ + uint32_t destination_preblue; /*!< destination pre-defined blue value */ + uint32_t image_width; /*!< width of the image to be processed */ + uint32_t image_height; /*!< height of the image to be processed */ +}ipa_destination_parameter_struct; + +/* destination pixel format */ +typedef enum +{ + IPA_DPF_ARGB8888, /*!< destination pixel format ARGB8888 */ + IPA_DPF_RGB888, /*!< destination pixel format RGB888 */ + IPA_DPF_RGB565, /*!< destination pixel format RGB565 */ + IPA_DPF_ARGB1555, /*!< destination pixel format ARGB1555 */ + IPA_DPF_ARGB4444 /*!< destination pixel format ARGB4444 */ +} ipa_dpf_enum; + +/* LUT pixel format */ +#define IPA_LUT_PF_ARGB8888 ((uint8_t)0x00U) /*!< LUT pixel format ARGB8888 */ +#define IPA_LUT_PF_RGB888 ((uint8_t)0x01U) /*!< LUT pixel format RGB888 */ + +/* Inter-timer */ +#define IPA_INTER_TIMER_DISABLE ((uint8_t)0x00U) /*!< Inter-timer disable */ +#define IPA_INTER_TIMER_ENABLE ((uint8_t)0x01U) /*!< Inter-timer enable */ + +/* IPA pixel format convert mode */ +#define CTL_PFCM(regval) (BITS(16,17) & ((regval) << 16)) +#define IPA_FGTODE CTL_PFCM(0) /*!< foreground memory to destination memory without pixel format convert */ +#define IPA_FGTODE_PF_CONVERT CTL_PFCM(1) /*!< foreground memory to destination memory with pixel format convert */ +#define IPA_FGBGTODE CTL_PFCM(2) /*!< blending foreground and background memory to destination memory */ +#define IPA_FILL_UP_DE CTL_PFCM(3) /*!< fill up destination memory with specific color */ + +/* foreground alpha value calculation algorithm */ +#define FPCTL_FAVCA(regval) (BITS(16,17) & ((regval) << 16)) +#define IPA_FG_ALPHA_MODE_0 FPCTL_FAVCA(0) /*!< no effect */ +#define IPA_FG_ALPHA_MODE_1 FPCTL_FAVCA(1) /*!< FPDAV[7:0] is selected as the foreground alpha value */ +#define IPA_FG_ALPHA_MODE_2 FPCTL_FAVCA(2) /*!< FPDAV[7:0] multiplied by read alpha value */ + +/* background alpha value calculation algorithm */ +#define BPCTL_BAVCA(regval) (BITS(16,17) & ((regval) << 16)) +#define IPA_BG_ALPHA_MODE_0 BPCTL_BAVCA(0) /*!< no effect */ +#define IPA_BG_ALPHA_MODE_1 BPCTL_BAVCA(1) /*!< BPDAV[7:0] is selected as the background alpha value */ +#define IPA_BG_ALPHA_MODE_2 BPCTL_BAVCA(2) /*!< BPDAV[7:0] multiplied by read alpha value */ + +/* foreground pixel format */ +#define FPCTL_PPF(regval) (BITS(0,3) & ((regval))) +#define FOREGROUND_PPF_ARGB8888 FPCTL_PPF(0) /*!< foreground pixel format ARGB8888 */ +#define FOREGROUND_PPF_RGB888 FPCTL_PPF(1) /*!< foreground pixel format RGB888 */ +#define FOREGROUND_PPF_RGB565 FPCTL_PPF(2) /*!< foreground pixel format RGB565 */ +#define FOREGROUND_PPF_ARG1555 FPCTL_PPF(3) /*!< foreground pixel format ARGB1555 */ +#define FOREGROUND_PPF_ARGB4444 FPCTL_PPF(4) /*!< foreground pixel format ARGB4444 */ +#define FOREGROUND_PPF_L8 FPCTL_PPF(5) /*!< foreground pixel format L8 */ +#define FOREGROUND_PPF_AL44 FPCTL_PPF(6) /*!< foreground pixel format AL44 */ +#define FOREGROUND_PPF_AL88 FPCTL_PPF(7) /*!< foreground pixel format AL88 */ +#define FOREGROUND_PPF_L4 FPCTL_PPF(8) /*!< foreground pixel format L4 */ +#define FOREGROUND_PPF_A8 FPCTL_PPF(9) /*!< foreground pixel format A8 */ +#define FOREGROUND_PPF_A4 FPCTL_PPF(10) /*!< foreground pixel format A4 */ + +/* background pixel format */ +#define BPCTL_PPF(regval) (BITS(0,3) & ((regval))) +#define BACKGROUND_PPF_ARGB8888 BPCTL_PPF(0) /*!< background pixel format ARGB8888 */ +#define BACKGROUND_PPF_RGB888 BPCTL_PPF(1) /*!< background pixel format RGB888 */ +#define BACKGROUND_PPF_RGB565 BPCTL_PPF(2) /*!< background pixel format RGB565 */ +#define BACKGROUND_PPF_ARG1555 BPCTL_PPF(3) /*!< background pixel format ARGB1555 */ +#define BACKGROUND_PPF_ARGB4444 BPCTL_PPF(4) /*!< background pixel format ARGB4444 */ +#define BACKGROUND_PPF_L8 BPCTL_PPF(5) /*!< background pixel format L8 */ +#define BACKGROUND_PPF_AL44 BPCTL_PPF(6) /*!< background pixel format AL44 */ +#define BACKGROUND_PPF_AL88 BPCTL_PPF(7) /*!< background pixel format AL88 */ +#define BACKGROUND_PPF_L4 BPCTL_PPF(8) /*!< background pixel format L4 */ +#define BACKGROUND_PPF_A8 BPCTL_PPF(9) /*!< background pixel format A8 */ +#define BACKGROUND_PPF_A4 BPCTL_PPF(10) /*!< background pixel format A4 */ + + +/* function declarations */ + +/* deinitialize IPA */ +void ipa_deinit(void); +/* IPA transfer enable */ +void ipa_transfer_enable(void); +/* IPA transfer hang up enable */ +void ipa_transfer_hangup_enable(void); +/* IPA transfer hang up disable */ +void ipa_transfer_hangup_disable(void); +/* IPA transfer stop enable */ +void ipa_transfer_stop_enable(void); +/* IPA transfer stop disable */ +void ipa_transfer_stop_disable(void); +/* IPA foreground LUT loading enable */ +void ipa_foreground_lut_loading_enable(void); +/* IPA background LUT loading enable */ +void ipa_background_lut_loading_enable(void); +/* IPA transfer enable */ +void ipa_pixel_format_convert_mod(uint32_t pfcm); + +/* initialize foreground parameters */ +void ipa_foreground_init(ipa_foreground_parameter_struct* foreground_struct); +/* initialize background parameters */ +void ipa_background_init(ipa_background_parameter_struct* background_struct); +/* initialize destination parameters */ +void ipa_destination_init(ipa_destination_parameter_struct* destination_struct); +/* initialize IPA foreground LUT parameters */ +void ipa_foreground_lut_init(uint32_t fg_lut_num,uint8_t fg_lut_pf, uint32_t fg_lut_addr); +/* initialize IPA background LUT parameters */ +void ipa_background_lut_init(uint32_t bg_lut_num,uint8_t bg_lut_pf, uint32_t bg_lut_addr); + +/* configure line mark */ +void ipa_line_mark_config(uint32_t linenum); +/* Inter-timer enable or disable */ +void ipa_inter_timer_config(uint8_t timercfg); +/* number of clock cycles interval set */ +void ipa_interval_clock_num_config(uint32_t clk_num ); + +/* IPA interrupt enable */ +void ipa_interrupt_enable(uint32_t inttype); +/* IPA interrupt disable */ +void ipa_interrupt_disable(uint32_t inttype); +/* get IPA interrupt flag */ +FlagStatus ipa_interrupt_flag_get(uint32_t intflag); +/* clear IPA interrupt flag */ +void ipa_interrupt_flag_clear(uint32_t intflag); + +#endif /* GD32F4XX_IPA_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h new file mode 100644 index 0000000000..0b7b3224d9 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h @@ -0,0 +1,161 @@ +/*! + \file gd32f4xx_iref.h + \brief definitions for the IREF +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_IREF_H +#define GD32F4XX_IREF_H + +#include "gd32f4xx.h" + +/* IREF definitions */ +#define IREF IREF_BASE /*!< IREF base address */ + +/* registers definitions */ +#define IREF_CTL REG32(IREF + 0x300U) /*!< IREF control register */ + +/* bits definitions */ +/* IREF_CTL */ +#define IREF_CTL_CSDT BITS(0,5) /*!< current step data */ +#define IREF_CTL_SCMOD BIT(7) /*!< sink current mode */ +#define IREF_CTL_CPT BITS(8,12) /*!< current precision trim */ +#define IREF_CTL_SSEL BIT(14) /*!< step selection */ +#define IREF_CTL_CREN BIT(15) /*!< current reference enable */ + +/* constants definitions */ +/* IREF current precision trim */ +#define CTL_CPT(regval) (BITS(8,12) & ((uint32_t)(regval) << 8)) +#define IREF_CUR_PRECISION_TRIM_0 CTL_CPT(0) /*!< IREF current precision trim 0 */ +#define IREF_CUR_PRECISION_TRIM_1 CTL_CPT(1) /*!< IREF current precision trim 1 */ +#define IREF_CUR_PRECISION_TRIM_2 CTL_CPT(2) /*!< IREF current precision trim 2 */ +#define IREF_CUR_PRECISION_TRIM_3 CTL_CPT(3) /*!< IREF current precision trim 3 */ +#define IREF_CUR_PRECISION_TRIM_4 CTL_CPT(4) /*!< IREF current precision trim 4 */ +#define IREF_CUR_PRECISION_TRIM_5 CTL_CPT(5) /*!< IREF current precision trim 5 */ +#define IREF_CUR_PRECISION_TRIM_6 CTL_CPT(6) /*!< IREF current precision trim 6 */ +#define IREF_CUR_PRECISION_TRIM_7 CTL_CPT(7) /*!< IREF current precision trim 7 */ +#define IREF_CUR_PRECISION_TRIM_8 CTL_CPT(8) /*!< IREF current precision trim 8 */ +#define IREF_CUR_PRECISION_TRIM_9 CTL_CPT(9) /*!< IREF current precision trim 9 */ +#define IREF_CUR_PRECISION_TRIM_10 CTL_CPT(10) /*!< IREF current precision trim 10 */ +#define IREF_CUR_PRECISION_TRIM_11 CTL_CPT(11) /*!< IREF current precision trim 11 */ +#define IREF_CUR_PRECISION_TRIM_12 CTL_CPT(12) /*!< IREF current precision trim 12 */ +#define IREF_CUR_PRECISION_TRIM_13 CTL_CPT(13) /*!< IREF current precision trim 13 */ +#define IREF_CUR_PRECISION_TRIM_14 CTL_CPT(14) /*!< IREF current precision trim 14 */ +#define IREF_CUR_PRECISION_TRIM_15 CTL_CPT(15) /*!< IREF current precision trim 15 */ +#define IREF_CUR_PRECISION_TRIM_16 CTL_CPT(16) /*!< IREF current precision trim 16 */ +#define IREF_CUR_PRECISION_TRIM_17 CTL_CPT(17) /*!< IREF current precision trim 17 */ +#define IREF_CUR_PRECISION_TRIM_18 CTL_CPT(18) /*!< IREF current precision trim 18 */ +#define IREF_CUR_PRECISION_TRIM_19 CTL_CPT(19) /*!< IREF current precision trim 19 */ +#define IREF_CUR_PRECISION_TRIM_20 CTL_CPT(20) /*!< IREF current precision trim 20 */ +#define IREF_CUR_PRECISION_TRIM_21 CTL_CPT(21) /*!< IREF current precision trim 21 */ +#define IREF_CUR_PRECISION_TRIM_22 CTL_CPT(22) /*!< IREF current precision trim 22 */ +#define IREF_CUR_PRECISION_TRIM_23 CTL_CPT(23) /*!< IREF current precision trim 23 */ +#define IREF_CUR_PRECISION_TRIM_24 CTL_CPT(24) /*!< IREF current precision trim 24 */ +#define IREF_CUR_PRECISION_TRIM_25 CTL_CPT(25) /*!< IREF current precision trim 25 */ +#define IREF_CUR_PRECISION_TRIM_26 CTL_CPT(26) /*!< IREF current precision trim 26 */ +#define IREF_CUR_PRECISION_TRIM_27 CTL_CPT(27) /*!< IREF current precision trim 27 */ +#define IREF_CUR_PRECISION_TRIM_28 CTL_CPT(28) /*!< IREF current precision trim 28 */ +#define IREF_CUR_PRECISION_TRIM_29 CTL_CPT(29) /*!< IREF current precision trim 29 */ +#define IREF_CUR_PRECISION_TRIM_30 CTL_CPT(30) /*!< IREF current precision trim 30 */ +#define IREF_CUR_PRECISION_TRIM_31 CTL_CPT(31) /*!< IREF current precision trim 31 */ + +/* IREF current step */ +#define CTL_CSDT(regval) (BITS(0,5) & ((uint32_t)(regval) << 0)) +#define IREF_CUR_STEP_DATA_0 CTL_CSDT(0) /*!< IREF current step data 0 */ +#define IREF_CUR_STEP_DATA_1 CTL_CSDT(1) /*!< IREF current step data 1 */ +#define IREF_CUR_STEP_DATA_2 CTL_CSDT(2) /*!< IREF current step data 2 */ +#define IREF_CUR_STEP_DATA_3 CTL_CSDT(3) /*!< IREF current step data 3 */ +#define IREF_CUR_STEP_DATA_4 CTL_CSDT(4) /*!< IREF current step data 4 */ +#define IREF_CUR_STEP_DATA_5 CTL_CSDT(5) /*!< IREF current step data 5 */ +#define IREF_CUR_STEP_DATA_6 CTL_CSDT(6) /*!< IREF current step data 6 */ +#define IREF_CUR_STEP_DATA_7 CTL_CSDT(7) /*!< IREF current step data 7 */ +#define IREF_CUR_STEP_DATA_8 CTL_CSDT(8) /*!< IREF current step data 8 */ +#define IREF_CUR_STEP_DATA_9 CTL_CSDT(9) /*!< IREF current step data 9 */ +#define IREF_CUR_STEP_DATA_10 CTL_CSDT(10) /*!< IREF current step data 10 */ +#define IREF_CUR_STEP_DATA_11 CTL_CSDT(11) /*!< IREF current step data 11 */ +#define IREF_CUR_STEP_DATA_12 CTL_CSDT(12) /*!< IREF current step data 12 */ +#define IREF_CUR_STEP_DATA_13 CTL_CSDT(13) /*!< IREF current step data 13 */ +#define IREF_CUR_STEP_DATA_14 CTL_CSDT(14) /*!< IREF current step data 14 */ +#define IREF_CUR_STEP_DATA_15 CTL_CSDT(15) /*!< IREF current step data 15 */ +#define IREF_CUR_STEP_DATA_16 CTL_CSDT(16) /*!< IREF current step data 16 */ +#define IREF_CUR_STEP_DATA_17 CTL_CSDT(17) /*!< IREF current step data 17 */ +#define IREF_CUR_STEP_DATA_18 CTL_CSDT(18) /*!< IREF current step data 18 */ +#define IREF_CUR_STEP_DATA_19 CTL_CSDT(19) /*!< IREF current step data 19 */ +#define IREF_CUR_STEP_DATA_20 CTL_CSDT(20) /*!< IREF current step data 20 */ +#define IREF_CUR_STEP_DATA_21 CTL_CSDT(21) /*!< IREF current step data 21 */ +#define IREF_CUR_STEP_DATA_22 CTL_CSDT(22) /*!< IREF current step data 22 */ +#define IREF_CUR_STEP_DATA_23 CTL_CSDT(23) /*!< IREF current step data 23 */ +#define IREF_CUR_STEP_DATA_24 CTL_CSDT(24) /*!< IREF current step data 24 */ +#define IREF_CUR_STEP_DATA_25 CTL_CSDT(25) /*!< IREF current step data 25 */ +#define IREF_CUR_STEP_DATA_26 CTL_CSDT(26) /*!< IREF current step data 26 */ +#define IREF_CUR_STEP_DATA_27 CTL_CSDT(27) /*!< IREF current step data 27 */ +#define IREF_CUR_STEP_DATA_28 CTL_CSDT(28) /*!< IREF current step data 28 */ +#define IREF_CUR_STEP_DATA_29 CTL_CSDT(29) /*!< IREF current step data 29 */ +#define IREF_CUR_STEP_DATA_30 CTL_CSDT(30) /*!< IREF current step data 30 */ +#define IREF_CUR_STEP_DATA_31 CTL_CSDT(31) /*!< IREF current step data 31 */ +#define IREF_CUR_STEP_DATA_32 CTL_CSDT(32) /*!< IREF current step data 32 */ +#define IREF_CUR_STEP_DATA_33 CTL_CSDT(33) /*!< IREF current step data 33 */ +#define IREF_CUR_STEP_DATA_34 CTL_CSDT(34) /*!< IREF current step data 34 */ +#define IREF_CUR_STEP_DATA_35 CTL_CSDT(35) /*!< IREF current step data 35 */ +#define IREF_CUR_STEP_DATA_36 CTL_CSDT(36) /*!< IREF current step data 36 */ +#define IREF_CUR_STEP_DATA_37 CTL_CSDT(37) /*!< IREF current step data 37 */ +#define IREF_CUR_STEP_DATA_38 CTL_CSDT(38) /*!< IREF current step data 38 */ +#define IREF_CUR_STEP_DATA_39 CTL_CSDT(39) /*!< IREF current step data 39 */ +#define IREF_CUR_STEP_DATA_40 CTL_CSDT(40) /*!< IREF current step data 40 */ +#define IREF_CUR_STEP_DATA_41 CTL_CSDT(41) /*!< IREF current step data 41 */ +#define IREF_CUR_STEP_DATA_42 CTL_CSDT(42) /*!< IREF current step data 42 */ +#define IREF_CUR_STEP_DATA_43 CTL_CSDT(43) /*!< IREF current step data 43 */ +#define IREF_CUR_STEP_DATA_44 CTL_CSDT(44) /*!< IREF current step data 44 */ +#define IREF_CUR_STEP_DATA_45 CTL_CSDT(45) /*!< IREF current step data 45 */ +#define IREF_CUR_STEP_DATA_46 CTL_CSDT(46) /*!< IREF current step data 46 */ +#define IREF_CUR_STEP_DATA_47 CTL_CSDT(47) /*!< IREF current step data 47 */ +#define IREF_CUR_STEP_DATA_48 CTL_CSDT(48) /*!< IREF current step data 48 */ +#define IREF_CUR_STEP_DATA_49 CTL_CSDT(49) /*!< IREF current step data 49 */ +#define IREF_CUR_STEP_DATA_50 CTL_CSDT(50) /*!< IREF current step data 50 */ +#define IREF_CUR_STEP_DATA_51 CTL_CSDT(51) /*!< IREF current step data 51 */ +#define IREF_CUR_STEP_DATA_52 CTL_CSDT(52) /*!< IREF current step data 52 */ +#define IREF_CUR_STEP_DATA_53 CTL_CSDT(53) /*!< IREF current step data 53 */ +#define IREF_CUR_STEP_DATA_54 CTL_CSDT(54) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_55 CTL_CSDT(55) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_56 CTL_CSDT(56) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_57 CTL_CSDT(57) /*!< IREF current step data 57 */ +#define IREF_CUR_STEP_DATA_58 CTL_CSDT(58) /*!< IREF current step data 58 */ +#define IREF_CUR_STEP_DATA_59 CTL_CSDT(59) /*!< IREF current step data 59 */ +#define IREF_CUR_STEP_DATA_60 CTL_CSDT(60) /*!< IREF current step data 60 */ +#define IREF_CUR_STEP_DATA_61 CTL_CSDT(61) /*!< IREF current step data 61 */ +#define IREF_CUR_STEP_DATA_62 CTL_CSDT(62) /*!< IREF current step data 62 */ +#define IREF_CUR_STEP_DATA_63 CTL_CSDT(63) /*!< IREF current step data 63 */ + +/* IREF mode selection */ +#define IREF_STEP(regval) (BIT(14) & ((uint32_t)(regval) << 14)) +#define IREF_MODE_LOW_POWER IREF_STEP(0) /*!< low power, 1uA step */ +#define IREF_MODE_HIGH_CURRENT IREF_STEP(1) /*!< high current, 8uA step */ + +/* IREF sink current mode*/ +#define IREF_CURRENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define IREF_SOURCE_CURRENT IREF_CURRENT(0) /*!< IREF source current */ +#define IREF_SINK_CURRENT IREF_CURRENT(1) /*!< IREF sink current */ + +/* function declarations */ +/* deinit IREF */ +void iref_deinit(void); +/* enable IREF */ +void iref_enable(void); +/* disable IREF */ +void iref_disable(void); + +/* set IREF mode*/ +void iref_mode_set(uint32_t step); +/* set IREF sink current mode*/ +void iref_sink_set(uint32_t sinkmode); +/* set IREF current precision trim value */ +void iref_precision_trim_value_set(uint32_t precisiontrim); +/* set IREF step data*/ +void iref_step_data_config(uint32_t stepdata); + +#endif /* GD32F4XX_IREF_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h new file mode 100644 index 0000000000..2052abe9a0 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h @@ -0,0 +1,68 @@ +/*! + \file gd32f4xx_misc.h + \brief definitions for the MISC +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_MISC_H +#define GD32F4XX_MISC_H + +#include "gd32f4xx.h" + +/* constants definitions */ +/* set the RAM and FLASH base address */ +#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000) /*!< RAM base address */ +#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000) /*!< Flash base address */ + +/* set the NVIC vector table offset mask */ +#define NVIC_VECTTAB_OFFSET_MASK ((uint32_t)0x1FFFFF80) + +/* the register key mask, if you want to do the write operation, you should write 0x5FA to VECTKEY bits */ +#define NVIC_AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) + +/* priority group - define the pre-emption priority and the subpriority */ +#define NVIC_PRIGROUP_PRE0_SUB4 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 4 bits for subpriority */ +#define NVIC_PRIGROUP_PRE1_SUB3 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 3 bits for subpriority */ +#define NVIC_PRIGROUP_PRE2_SUB2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 2 bits for subpriority */ +#define NVIC_PRIGROUP_PRE3_SUB1 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 1 bits for subpriority */ +#define NVIC_PRIGROUP_PRE4_SUB0 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 0 bits for subpriority */ + +/* choose the method to enter or exit the lowpower mode */ +#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< choose the the system whether enter low power mode by exiting from ISR */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< choose the interrupt source that can wake up the lowpower mode */ + +#define SCB_LPM_SLEEP_EXIT_ISR SCB_SCR_SLEEPONEXIT +#define SCB_LPM_DEEPSLEEP SCB_SCR_SLEEPDEEP +#define SCB_LPM_WAKE_BY_ALL_INT SCB_SCR_SEVONPEND + +/* choose the systick clock source */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from HCLK/8 */ +#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U) /*!< systick clock source is from HCLK */ + +/* function declarations */ +/* set the priority group */ +void nvic_priority_group_set(uint32_t nvic_prigroup); + +/* enable NVIC request */ +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority); +/* disable NVIC request */ +void nvic_irq_disable(uint8_t nvic_irq); + +/* set the NVIC vector table base address */ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset); + +/* set the state of the low power mode */ +void system_lowpower_set(uint8_t lowpower_mode); +/* reset the state of the low power mode */ +void system_lowpower_reset(uint8_t lowpower_mode); + +/* set the systick clock source */ +void systick_clksource_set(uint32_t systick_clksource); + +#endif /* GD32F4XX_MISC_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h new file mode 100644 index 0000000000..74a857e96c --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h @@ -0,0 +1,173 @@ +/*! + \file gd32f4xx_pmu.h + \brief definitions for the PMU +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_PMU_H +#define GD32F4XX_PMU_H + +#include "gd32f4xx.h" + +/* PMU definitions */ +#define PMU PMU_BASE /*!< PMU base address */ + +/* registers definitions */ +#define PMU_CTL REG32((PMU) + 0x00U) /*!< PMU control register */ +#define PMU_CS REG32((PMU) + 0x04U) /*!< PMU control and status register */ + +/* bits definitions */ +/* PMU_CTL */ +#define PMU_CTL_LDOLP BIT(0) /*!< LDO low power mode */ +#define PMU_CTL_STBMOD BIT(1) /*!< standby mode */ +#define PMU_CTL_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL_LVDEN BIT(4) /*!< low voltage detector enable */ +#define PMU_CTL_LVDT BITS(5,7) /*!< low voltage detector threshold */ +#define PMU_CTL_BKPWEN BIT(8) /*!< backup domain write enable */ +#define PMU_CTL_LDLP BIT(10) /*!< low-driver mode when use low power LDO */ +#define PMU_CTL_LDNP BIT(11) /*!< low-driver mode when use normal power LDO */ +#define PMU_CTL_LDOVS BITS(14,15) /*!< LDO output voltage select */ +#define PMU_CTL_HDEN BIT(16) /*!< high-driver mode enable */ +#define PMU_CTL_HDS BIT(17) /*!< high-driver mode switch */ +#define PMU_CTL_LDEN BITS(18,19) /*!< low-driver mode enable in deep-sleep mode */ + +/* PMU_CS */ +#define PMU_CS_WUF BIT(0) /*!< wakeup flag */ +#define PMU_CS_STBF BIT(1) /*!< standby flag */ +#define PMU_CS_LVDF BIT(2) /*!< low voltage detector status flag */ +#define PMU_CS_BLDORF BIT(3) /*!< backup SRAM LDO ready flag */ +#define PMU_CS_WUPEN BIT(8) /*!< wakeup pin enable */ +#define PMU_CS_BLDOON BIT(9) /*!< backup SRAM LDO on */ +#define PMU_CS_LDOVSRF BIT(14) /*!< LDO voltage select ready flag */ +#define PMU_CS_HDRF BIT(16) /*!< high-driver ready flag */ +#define PMU_CS_HDSRF BIT(17) /*!< high-driver switch ready flag */ +#define PMU_CS_LDRF BITS(18,19) /*!< Low-driver mode ready flag */ + +/* constants definitions */ +/* PMU low voltage detector threshold definitions */ +#define CTL_LVDT(regval) (BITS(5,7)&((uint32_t)(regval)<<5)) +#define PMU_LVDT_0 CTL_LVDT(0) /*!< voltage threshold is 2.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 LDO output voltage select definitions */ +#define CTL_LDOVS(regval) (BITS(14,15)&((uint32_t)(regval)<<14)) +#define PMU_LDOVS_LOW CTL_LDOVS(1) /*!< LDO output voltage low mode */ +#define PMU_LDOVS_MID CTL_LDOVS(2) /*!< LDO output voltage mid mode */ +#define PMU_LDOVS_HIGH CTL_LDOVS(3) /*!< LDO output voltage high mode */ + +/* PMU low-driver mode enable in deep-sleep mode */ +#define CTL_LDEN(regval) (BITS(18,19)&((uint32_t)(regval)<<18)) +#define PMU_LOWDRIVER_DISABLE CTL_LDEN(0) /*!< low-driver mode disable in deep-sleep mode */ +#define PMU_LOWDRIVER_ENABLE CTL_LDEN(3) /*!< low-driver mode enable in deep-sleep mode */ + +/* PMU high-driver mode switch */ +#define CTL_HDS(regval) (BIT(17)&((uint32_t)(regval)<<17)) +#define PMU_HIGHDR_SWITCH_NONE CTL_HDS(0) /*!< no high-driver mode switch */ +#define PMU_HIGHDR_SWITCH_EN CTL_HDS(1) /*!< high-driver mode switch */ + +/* PMU low-driver mode when use low power LDO */ +#define CTL_LDLP(regval) (BIT(10)&((uint32_t)(regval)<<10)) +#define PMU_NORMALDR_LOWPWR CTL_LDLP(0) /*!< normal driver when use low power LDO */ +#define PMU_LOWDR_LOWPWR CTL_LDLP(1) /*!< low-driver mode enabled when LDEN is 11 and use low power LDO */ + +/* PMU low-driver mode when use normal power LDO */ +#define CTL_LDNP(regval) (BIT(11)&((uint32_t)(regval)<<11)) +#define PMU_NORMALDR_NORMALPWR CTL_LDNP(0) /*!< normal driver when use normal power LDO */ +#define PMU_LOWDR_NORMALPWR CTL_LDNP(1) /*!< low-driver mode enabled when LDEN is 11 and use normal power LDO */ + +/* PMU low power mode ready flag definitions */ +#define CS_LDRF(regval) (BITS(18,19)&((uint32_t)(regval)<<18)) +#define PMU_LDRF_NORMAL CS_LDRF(0) /*!< normal driver in deep-sleep mode */ +#define PMU_LDRF_LOWDRIVER CS_LDRF(3) /*!< low-driver mode in deep-sleep mode */ + +/* PMU backup SRAM LDO on or off */ +#define CS_BLDOON(regval) (BIT(9)&((uint32_t)(regval)<<9)) +#define PMU_BLDOON_OFF CS_BLDOON(0) /*!< backup SRAM LDO off */ +#define PMU_BLDOON_ON CS_BLDOON(1) /*!< the backup SRAM LDO on */ + +/* PMU flag definitions */ +#define PMU_FLAG_WAKEUP PMU_CS_WUF /*!< wakeup flag status */ +#define PMU_FLAG_STANDBY PMU_CS_STBF /*!< standby flag status */ +#define PMU_FLAG_LVD PMU_CS_LVDF /*!< lvd flag status */ +#define PMU_FLAG_BLDORF PMU_CS_BLDORF /*!< backup SRAM LDO ready flag */ +#define PMU_FLAG_LDOVSRF PMU_CS_LDOVSRF /*!< LDO voltage select ready flag */ +#define PMU_FLAG_HDRF PMU_CS_HDRF /*!< high-driver ready flag */ +#define PMU_FLAG_HDSRF PMU_CS_HDSRF /*!< high-driver switch ready flag */ +#define PMU_FLAG_LDRF PMU_CS_LDRF /*!< low-driver mode ready flag */ + +/* PMU ldo definitions */ +#define PMU_LDO_NORMAL ((uint32_t)0x00000000U) /*!< LDO normal work when PMU enter deepsleep mode */ +#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when PMU enter deepsleep mode */ + +/* PMU flag reset definitions */ +#define PMU_FLAG_RESET_WAKEUP ((uint8_t)0x00U) /*!< wakeup flag reset */ +#define PMU_FLAG_RESET_STANDBY ((uint8_t)0x01U) /*!< standby flag reset */ + +/* PMU command constants definitions */ +#define WFI_CMD ((uint8_t)0x00U) /*!< use WFI command */ +#define WFE_CMD ((uint8_t)0x01U) /*!< use WFE command */ + +/* function declarations */ +/* reset PMU register */ +void pmu_deinit(void); + +/* select low voltage detector threshold */ +void pmu_lvd_select(uint32_t pmu_lvdt_n); +/* LDO output voltage select */ +void pmu_ldo_output_select(uint32_t ldo_output); +/* PMU lvd disable */ +void pmu_lvd_disable(void); + +/* functions of low-driver mode and high-driver mode in deep-sleep mode */ +/* high-driver mode switch */ +void pmu_highdriver_switch_select(uint32_t highdr_switch); +/* high-driver mode enable */ +void pmu_highdriver_mode_enable(void); +/* high-driver mode disable */ +void pmu_highdriver_mode_disable(void); +/* low-driver mode enable in deep-sleep mode */ +void pmu_low_driver_mode_enable(uint32_t lowdr_mode); +/* in deep-sleep mode, low-driver mode when use low power LDO */ +void pmu_lowdriver_lowpower_config(uint32_t mode); +/* in deep-sleep mode, low-driver mode when use normal power LDO */ +void pmu_lowdriver_normalpower_config(uint32_t mode); + +/* set PMU mode */ +/* PMU work at sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* PMU work at deepsleep mode */ +void pmu_to_deepsleepmode(uint32_t pmu_ldo, uint8_t deepsleepmodecmd); +/* PMU work at standby mode */ +void pmu_to_standbymode(uint8_t standbymodecmd); +/* PMU wakeup pin enable */ +void pmu_wakeup_pin_enable(void); +/* PMU wakeup pin disable */ +void pmu_wakeup_pin_disable(void); + +/* backup related functions */ +/* backup SRAM LDO on */ +void pmu_backup_ldo_config(uint32_t bkp_ldo); +/* backup domain write enable */ +void pmu_backup_write_enable(void); +/* backup domain write disable */ +void pmu_backup_write_disable(void); + +/* flag functions */ +/* reset flag bit */ +void pmu_flag_reset(uint32_t flag_reset); +/* get flag status */ +FlagStatus pmu_flag_get(uint32_t pmu_flag); + +#endif /* GD32F4XX_PMU_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h new file mode 100644 index 0000000000..6851c2e22f --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h @@ -0,0 +1,1152 @@ +/*! + \file gd32f4xx_rcu.h + \brief definitions for the RCU +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_RCU_H +#define GD32F4XX_RCU_H + +#include "gd32f4xx.h" + +/* RCU definitions */ +#define RCU RCU_BASE + +/* registers definitions */ +#define RCU_CTL REG32(RCU + 0x00U) /*!< control register */ +#define RCU_PLL REG32(RCU + 0x04U) /*!< PLL register */ +#define RCU_CFG0 REG32(RCU + 0x08U) /*!< clock configuration register 0 */ +#define RCU_INT REG32(RCU + 0x0CU) /*!< clock interrupt register */ +#define RCU_AHB1RST REG32(RCU + 0x10U) /*!< AHB1 reset register */ +#define RCU_AHB2RST REG32(RCU + 0x14U) /*!< AHB2 reset register */ +#define RCU_AHB3RST REG32(RCU + 0x18U) /*!< AHB3 reset register */ +#define RCU_APB1RST REG32(RCU + 0x20U) /*!< APB1 reset register */ +#define RCU_APB2RST REG32(RCU + 0x24U) /*!< APB2 reset register */ +#define RCU_AHB1EN REG32(RCU + 0x30U) /*!< AHB1 enable register */ +#define RCU_AHB2EN REG32(RCU + 0x34U) /*!< AHB2 enable register */ +#define RCU_AHB3EN REG32(RCU + 0x38U) /*!< AHB3 enable register */ +#define RCU_APB1EN REG32(RCU + 0x40U) /*!< APB1 enable register */ +#define RCU_APB2EN REG32(RCU + 0x44U) /*!< APB2 enable register */ +#define RCU_AHB1SPEN REG32(RCU + 0x50U) /*!< AHB1 sleep mode enable register */ +#define RCU_AHB2SPEN REG32(RCU + 0x54U) /*!< AHB2 sleep mode enable register */ +#define RCU_AHB3SPEN REG32(RCU + 0x58U) /*!< AHB3 sleep mode enable register */ +#define RCU_APB1SPEN REG32(RCU + 0x60U) /*!< APB1 sleep mode enable register */ +#define RCU_APB2SPEN REG32(RCU + 0x64U) /*!< APB2 sleep mode enable register */ +#define RCU_BDCTL REG32(RCU + 0x70U) /*!< backup domain control register */ +#define RCU_RSTSCK REG32(RCU + 0x74U) /*!< reset source / clock register */ +#define RCU_PLLSSCTL REG32(RCU + 0x80U) /*!< PLL clock spread spectrum control register */ +#define RCU_PLLI2S REG32(RCU + 0x84U) /*!< PLLI2S register */ +#define RCU_PLLSAI REG32(RCU + 0x88U) /*!< PLLSAI register */ +#define RCU_CFG1 REG32(RCU + 0x8CU) /*!< clock configuration register 1 */ +#define RCU_ADDCTL REG32(RCU + 0xC0U) /*!< Additional clock control register */ +#define RCU_ADDINT REG32(RCU + 0xCCU) /*!< Additional clock interrupt register */ +#define RCU_ADDAPB1RST REG32(RCU + 0xE0U) /*!< APB1 additional reset register */ +#define RCU_ADDAPB1EN REG32(RCU + 0xE4U) /*!< APB1 additional enable register */ +#define RCU_ADDAPB1SPEN REG32(RCU + 0xE8U) /*!< APB1 additional sleep mode enable register */ +#define RCU_VKEY REG32(RCU + 0x100U) /*!< voltage key register */ +#define RCU_DSV REG32(RCU + 0x134U) /*!< deep-sleep mode voltage register */ + +/* bits definitions */ +/* RCU_CTL */ +#define RCU_CTL_IRC16MEN BIT(0) /*!< internal high speed oscillator enable */ +#define RCU_CTL_IRC16MSTB BIT(1) /*!< IRC8M high speed internal oscillator stabilization flag */ +#define RCU_CTL_IRC16MADJ BITS(3,7) /*!< high speed internal oscillator clock trim adjust value */ +#define RCU_CTL_IRC16MCALIB BITS(8,15) /*!< high speed internal oscillator calibration value register */ +#define RCU_CTL_HXTALEN BIT(16) /*!< external high speed oscillator enable */ +#define RCU_CTL_HXTALSTB BIT(17) /*!< external crystal oscillator clock stabilization flag */ +#define RCU_CTL_HXTALBPS BIT(18) /*!< external crystal oscillator clock bypass mode enable */ +#define RCU_CTL_CKMEN BIT(19) /*!< HXTAL clock monitor enable */ +#define RCU_CTL_PLLEN BIT(24) /*!< PLL enable */ +#define RCU_CTL_PLLSTB BIT(25) /*!< PLL Clock Stabilization Flag */ +#define RCU_CTL_PLLI2SEN BIT(26) /*!< PLLI2S enable */ +#define RCU_CTL_PLLI2STB BIT(27) /*!< PLLI2S Clock Stabilization Flag */ +#define RCU_CTL_PLLSAIEN BIT(28) /*!< PLLSAI enable */ +#define RCU_CTL_PLLSAISTB BIT(29) /*!< PLLSAI Clock Stabilization Flag */ + +/* RCU_PLL */ +#define RCU_PLL_PLLPSC BITS(0,5) /*!< The PLL VCO source clock prescaler */ +#define RCU_PLL_PLLN BITS(6,14) /*!< The PLL VCO clock multi factor */ +#define RCU_PLL_PLLP BITS(16,17) /*!< The PLLP output frequency division factor from PLL VCO clock */ +#define RCU_PLL_PLLSEL BIT(22) /*!< PLL Clock Source Selection */ +#define RCU_PLL_PLLQ BITS(24,27) /*!< The PLL Q output frequency division factor from PLL VCO clock */ + +/* RCU_CFG0 */ +#define RCU_CFG0_SCS BITS(0,1) /*!< system clock switch */ +#define RCU_CFG0_SCSS BITS(2,3) /*!< system clock switch status */ +#define RCU_CFG0_AHBPSC BITS(4,7) /*!< AHB prescaler selection */ +#define RCU_CFG0_APB1PSC BITS(10,12) /*!< APB1 prescaler selection */ +#define RCU_CFG0_APB2PSC BITS(13,15) /*!< APB2 prescaler selection */ +#define RCU_CFG0_RTCDIV BITS(16,20) /*!< RTC clock divider factor */ +#define RCU_CFG0_CKOUT0SEL BITS(21,22) /*!< CKOUT0 Clock Source Selection */ +#define RCU_CFG0_I2SSEL BIT(23) /*!< I2S Clock Source Selection */ +#define RCU_CFG0_CKOUT0DIV BITS(24,26) /*!< The CK_OUT0 divider which the CK_OUT0 frequency can be reduced */ +#define RCU_CFG0_CKOUT1DIV BITS(27,29) /*!< The CK_OUT1 divider which the CK_OUT1 frequency can be reduced */ +#define RCU_CFG0_CKOUT1SEL BITS(30,31) /*!< CKOUT1 Clock Source Selection */ + +/* RCU_INT */ +#define RCU_INT_IRC32KSTBIF BIT(0) /*!< IRC32K stabilization interrupt flag */ +#define RCU_INT_LXTALSTBIF BIT(1) /*!< LXTAL stabilization interrupt flag */ +#define RCU_INT_IRC16MSTBIF BIT(2) /*!< IRC16M stabilization interrupt flag */ +#define RCU_INT_HXTALSTBIF BIT(3) /*!< HXTAL stabilization interrupt flag */ +#define RCU_INT_PLLSTBIF BIT(4) /*!< PLL stabilization interrupt flag */ +#define RCU_INT_PLLI2SSTBIF BIT(5) /*!< PLLI2S stabilization interrupt flag */ +#define RCU_INT_PLLSAISTBIF BIT(6) /*!< PLLSAI stabilization interrupt flag */ +#define RCU_INT_CKMIF BIT(7) /*!< HXTAL clock stuck interrupt flag */ +#define RCU_INT_IRC32KSTBIE BIT(8) /*!< IRC32K stabilization interrupt enable */ +#define RCU_INT_LXTALSTBIE BIT(9) /*!< LXTAL stabilization interrupt enable */ +#define RCU_INT_IRC16MSTBIE BIT(10) /*!< IRC16M stabilization interrupt enable */ +#define RCU_INT_HXTALSTBIE BIT(11) /*!< HXTAL stabilization interrupt enable */ +#define RCU_INT_PLLSTBIE BIT(12) /*!< PLL stabilization interrupt enable */ +#define RCU_INT_PLLI2SSTBIE BIT(13) /*!< PLLI2S Stabilization Interrupt Enable */ +#define RCU_INT_PLLSAISTBIE BIT(14) /*!< PLLSAI Stabilization Interrupt Enable */ +#define RCU_INT_IRC32KSTBIC BIT(16) /*!< IRC32K Stabilization Interrupt Clear */ +#define RCU_INT_LXTALSTBIC BIT(17) /*!< LXTAL Stabilization Interrupt Clear */ +#define RCU_INT_IRC16MSTBIC BIT(18) /*!< IRC16M Stabilization Interrupt Clear */ +#define RCU_INT_HXTALSTBIC BIT(19) /*!< HXTAL Stabilization Interrupt Clear */ +#define RCU_INT_PLLSTBIC BIT(20) /*!< PLL stabilization Interrupt Clear */ +#define RCU_INT_PLLI2SSTBIC BIT(21) /*!< PLLI2S stabilization Interrupt Clear */ +#define RCU_INT_PLLSAISTBIC BIT(22) /*!< PLLSAI stabilization Interrupt Clear */ +#define RCU_INT_CKMIC BIT(23) /*!< HXTAL Clock Stuck Interrupt Clear */ + +/* RCU_AHB1RST */ +#define RCU_AHB1RST_PARST BIT(0) /*!< GPIO port A reset */ +#define RCU_AHB1RST_PBRST BIT(1) /*!< GPIO port B reset */ +#define RCU_AHB1RST_PCRST BIT(2) /*!< GPIO port C reset */ +#define RCU_AHB1RST_PDRST BIT(3) /*!< GPIO port D reset */ +#define RCU_AHB1RST_PERST BIT(4) /*!< GPIO port E reset */ +#define RCU_AHB1RST_PFRST BIT(5) /*!< GPIO port F reset */ +#define RCU_AHB1RST_PGRST BIT(6) /*!< GPIO port G reset */ +#define RCU_AHB1RST_PHRST BIT(7) /*!< GPIO port H reset */ +#define RCU_AHB1RST_PIRST BIT(8) /*!< GPIO port I reset */ +#define RCU_AHB1RST_CRCRST BIT(12) /*!< CRC reset */ +#define RCU_AHB1RST_DMA0RST BIT(21) /*!< DMA0 reset */ +#define RCU_AHB1RST_DMA1RST BIT(22) /*!< DMA1 reset */ +#define RCU_AHB1RST_IPARST BIT(23) /*!< IPA reset */ +#define RCU_AHB1RST_ENETRST BIT(25) /*!< ENET reset */ +#define RCU_AHB1RST_USBHSRST BIT(29) /*!< USBHS reset */ + +/* RCU_AHB2RST */ +#define RCU_AHB2RST_DCIRST BIT(0) /*!< DCI reset */ +#define RCU_AHB2RST_TRNGRST BIT(6) /*!< TRNG reset */ +#define RCU_AHB2RST_USBFSRST BIT(7) /*!< USBFS reset */ + +/* RCU_AHB3RST */ +#define RCU_AHB3RST_EXMCRST BIT(0) /*!< EXMC reset */ + +/* RCU_APB1RST */ +#define RCU_APB1RST_TIMER1RST BIT(0) /*!< TIMER1 reset */ +#define RCU_APB1RST_TIMER2RST BIT(1) /*!< TIMER2 reset */ +#define RCU_APB1RST_TIMER3RST BIT(2) /*!< TIMER3 reset */ +#define RCU_APB1RST_TIMER4RST BIT(3) /*!< TIMER4 reset */ +#define RCU_APB1RST_TIMER5RST BIT(4) /*!< TIMER5 reset */ +#define RCU_APB1RST_TIMER6RST BIT(5) /*!< TIMER6 reset */ +#define RCU_APB1RST_TIMER11RST BIT(6) /*!< TIMER11 reset */ +#define RCU_APB1RST_TIMER12RST BIT(7) /*!< TIMER12 reset */ +#define RCU_APB1RST_TIMER13RST BIT(8) /*!< TIMER13 reset */ +#define RCU_APB1RST_WWDGTRST BIT(11) /*!< WWDGT reset */ +#define RCU_APB1RST_SPI1RST BIT(14) /*!< SPI1 reset */ +#define RCU_APB1RST_SPI2RST BIT(15) /*!< SPI2 reset */ +#define RCU_APB1RST_USART1RST BIT(17) /*!< USART1 reset */ +#define RCU_APB1RST_USART2RST BIT(18) /*!< USART2 reset */ +#define RCU_APB1RST_UART3RST BIT(19) /*!< UART3 reset */ +#define RCU_APB1RST_UART4RST BIT(20) /*!< UART4 reset */ +#define RCU_APB1RST_I2C0RST BIT(21) /*!< I2C0 reset */ +#define RCU_APB1RST_I2C1RST BIT(22) /*!< I2C1 reset */ +#define RCU_APB1RST_I2C2RST BIT(23) /*!< I2C2 reset */ +#define RCU_APB1RST_CAN0RST BIT(25) /*!< CAN0 reset */ +#define RCU_APB1RST_CAN1RST BIT(26) /*!< CAN1 reset */ +#define RCU_APB1RST_PMURST BIT(28) /*!< PMU reset */ +#define RCU_APB1RST_DACRST BIT(29) /*!< DAC reset */ +#define RCU_APB1RST_UART6RST BIT(30) /*!< UART6 reset */ +#define RCU_APB1RST_UART7RST BIT(31) /*!< UART7 reset */ + +/* RCU_APB2RST */ +#define RCU_APB2RST_TIMER0RST BIT(0) /*!< TIMER0 reset */ +#define RCU_APB2RST_TIMER7RST BIT(1) /*!< TIMER7 reset */ +#define RCU_APB2RST_USART0RST BIT(4) /*!< USART0 reset */ +#define RCU_APB2RST_USART5RST BIT(5) /*!< USART5 reset */ +#define RCU_APB2RST_ADCRST BIT(8) /*!< ADC reset */ +#define RCU_APB2RST_SDIORST BIT(11) /*!< SDIO reset */ +#define RCU_APB2RST_SPI0RST BIT(12) /*!< SPI0 reset */ +#define RCU_APB2RST_SPI3RST BIT(13) /*!< SPI3 reset */ +#define RCU_APB2RST_SYSCFGRST BIT(14) /*!< SYSCFG reset */ +#define RCU_APB2RST_TIMER8RST BIT(16) /*!< TIMER8 reset */ +#define RCU_APB2RST_TIMER9RST BIT(17) /*!< TIMER9 reset */ +#define RCU_APB2RST_TIMER10RST BIT(18) /*!< TIMER10 reset */ +#define RCU_APB2RST_SPI4RST BIT(20) /*!< SPI4 reset */ +#define RCU_APB2RST_SPI5RST BIT(21) /*!< SPI5 reset */ +#define RCU_APB2RST_TLIRST BIT(26) /*!< TLI reset */ + +/* RCU_AHB1EN */ +#define RCU_AHB1EN_PAEN BIT(0) /*!< GPIO port A clock enable */ +#define RCU_AHB1EN_PBEN BIT(1) /*!< GPIO port B clock enable */ +#define RCU_AHB1EN_PCEN BIT(2) /*!< GPIO port C clock enable */ +#define RCU_AHB1EN_PDEN BIT(3) /*!< GPIO port D clock enable */ +#define RCU_AHB1EN_PEEN BIT(4) /*!< GPIO port E clock enable */ +#define RCU_AHB1EN_PFEN BIT(5) /*!< GPIO port F clock enable */ +#define RCU_AHB1EN_PGEN BIT(6) /*!< GPIO port G clock enable */ +#define RCU_AHB1EN_PHEN BIT(7) /*!< GPIO port H clock enable */ +#define RCU_AHB1EN_PIEN BIT(8) /*!< GPIO port I clock enable */ +#define RCU_AHB1EN_CRCEN BIT(12) /*!< CRC clock enable */ +#define RCU_AHB1EN_BKPSRAMEN BIT(18) /*!< BKPSRAM clock enable */ +#define RCU_AHB1EN_TCMSRAMEN BIT(20) /*!< TCMSRAM clock enable */ +#define RCU_AHB1EN_DMA0EN BIT(21) /*!< DMA0 clock enable */ +#define RCU_AHB1EN_DMA1EN BIT(22) /*!< DMA1 clock enable */ +#define RCU_AHB1EN_IPAEN BIT(23) /*!< IPA clock enable */ +#define RCU_AHB1EN_ENETEN BIT(25) /*!< ENET clock enable */ +#define RCU_AHB1EN_ENETTXEN BIT(26) /*!< Ethernet TX clock enable */ +#define RCU_AHB1EN_ENETRXEN BIT(27) /*!< Ethernet RX clock enable */ +#define RCU_AHB1EN_ENETPTPEN BIT(28) /*!< Ethernet PTP clock enable */ +#define RCU_AHB1EN_USBHSEN BIT(29) /*!< USBHS clock enable */ +#define RCU_AHB1EN_USBHSULPIEN BIT(30) /*!< USBHS ULPI clock enable */ + +/* RCU_AHB2EN */ +#define RCU_AHB2EN_DCIEN BIT(0) /*!< DCI clock enable */ +#define RCU_AHB2EN_TRNGEN BIT(6) /*!< TRNG clock enable */ +#define RCU_AHB2EN_USBFSEN BIT(7) /*!< USBFS clock enable */ + +/* RCU_AHB3EN */ +#define RCU_AHB3EN_EXMCEN BIT(0) /*!< EXMC clock enable */ + +/* RCU_APB1EN */ +#define RCU_APB1EN_TIMER1EN BIT(0) /*!< TIMER1 clock enable */ +#define RCU_APB1EN_TIMER2EN BIT(1) /*!< TIMER2 clock enable */ +#define RCU_APB1EN_TIMER3EN BIT(2) /*!< TIMER3 clock enable */ +#define RCU_APB1EN_TIMER4EN BIT(3) /*!< TIMER4 clock enable */ +#define RCU_APB1EN_TIMER5EN BIT(4) /*!< TIMER5 clock enable */ +#define RCU_APB1EN_TIMER6EN BIT(5) /*!< TIMER6 clock enable */ +#define RCU_APB1EN_TIMER11EN BIT(6) /*!< TIMER11 clock enable */ +#define RCU_APB1EN_TIMER12EN BIT(7) /*!< TIMER12 clock enable */ +#define RCU_APB1EN_TIMER13EN BIT(8) /*!< TIMER13 clock enable */ +#define RCU_APB1EN_WWDGTEN BIT(11) /*!< WWDGT clock enable */ +#define RCU_APB1EN_SPI1EN BIT(14) /*!< SPI1 clock enable */ +#define RCU_APB1EN_SPI2EN BIT(15) /*!< SPI2 clock enable */ +#define RCU_APB1EN_USART1EN BIT(17) /*!< USART1 clock enable */ +#define RCU_APB1EN_USART2EN BIT(18) /*!< USART2 clock enable */ +#define RCU_APB1EN_UART3EN BIT(19) /*!< UART3 clock enable */ +#define RCU_APB1EN_UART4EN BIT(20) /*!< UART4 clock enable */ +#define RCU_APB1EN_I2C0EN BIT(21) /*!< I2C0 clock enable */ +#define RCU_APB1EN_I2C1EN BIT(22) /*!< I2C1 clock enable */ +#define RCU_APB1EN_I2C2EN BIT(23) /*!< I2C2 clock enable */ +#define RCU_APB1EN_CAN0EN BIT(25) /*!< CAN0 clock enable */ +#define RCU_APB1EN_CAN1EN BIT(26) /*!< CAN1 clock enable */ +#define RCU_APB1EN_PMUEN BIT(28) /*!< PMU clock enable */ +#define RCU_APB1EN_DACEN BIT(29) /*!< DAC clock enable */ +#define RCU_APB1EN_UART6EN BIT(30) /*!< UART6 clock enable */ +#define RCU_APB1EN_UART7EN BIT(31) /*!< UART7 clock enable */ + +/* RCU_APB2EN */ +#define RCU_APB2EN_TIMER0EN BIT(0) /*!< TIMER0 clock enable */ +#define RCU_APB2EN_TIMER7EN BIT(1) /*!< TIMER7 clock enable */ +#define RCU_APB2EN_USART0EN BIT(4) /*!< USART0 clock enable */ +#define RCU_APB2EN_USART5EN BIT(5) /*!< USART5 clock enable */ +#define RCU_APB2EN_ADC0EN BIT(8) /*!< ADC0 clock enable */ +#define RCU_APB2EN_ADC1EN BIT(9) /*!< ADC1 clock enable */ +#define RCU_APB2EN_ADC2EN BIT(10) /*!< ADC2 clock enable */ +#define RCU_APB2EN_SDIOEN BIT(11) /*!< SDIO clock enable */ +#define RCU_APB2EN_SPI0EN BIT(12) /*!< SPI0 clock enable */ +#define RCU_APB2EN_SPI3EN BIT(13) /*!< SPI3 clock enable */ +#define RCU_APB2EN_SYSCFGEN BIT(14) /*!< SYSCFG clock enable */ +#define RCU_APB2EN_TIMER8EN BIT(16) /*!< TIMER8 clock enable */ +#define RCU_APB2EN_TIMER9EN BIT(17) /*!< TIMER9 clock enable */ +#define RCU_APB2EN_TIMER10EN BIT(18) /*!< TIMER10 clock enable */ +#define RCU_APB2EN_SPI4EN BIT(20) /*!< SPI4 clock enable */ +#define RCU_APB2EN_SPI5EN BIT(21) /*!< SPI5 clock enable */ +#define RCU_APB2EN_TLIEN BIT(26) /*!< TLI clock enable */ + +/* RCU_AHB1SPEN */ +#define RCU_AHB1SPEN_PASPEN BIT(0) /*!< GPIO port A clock enable when sleep mode */ +#define RCU_AHB1SPEN_PBSPEN BIT(1) /*!< GPIO port B clock enable when sleep mode */ +#define RCU_AHB1SPEN_PCSPEN BIT(2) /*!< GPIO port C clock enable when sleep mode */ +#define RCU_AHB1SPEN_PDSPEN BIT(3) /*!< GPIO port D clock enable when sleep mode */ +#define RCU_AHB1SPEN_PESPEN BIT(4) /*!< GPIO port E clock enable when sleep mode */ +#define RCU_AHB1SPEN_PFSPEN BIT(5) /*!< GPIO port F clock enable when sleep mode */ +#define RCU_AHB1SPEN_PGSPEN BIT(6) /*!< GPIO port G clock enable when sleep mode */ +#define RCU_AHB1SPEN_PHSPEN BIT(7) /*!< GPIO port H clock enable when sleep mode */ +#define RCU_AHB1SPEN_PISPEN BIT(8) /*!< GPIO port I clock enable when sleep mode */ +#define RCU_AHB1SPEN_CRCSPEN BIT(12) /*!< CRC clock enable when sleep mode */ +#define RCU_AHB1SPEN_FMCSPEN BIT(15) /*!< FMC clock enable when sleep mode */ +#define RCU_AHB1SPEN_SRAM0SPEN BIT(16) /*!< SRAM0 clock enable when sleep mode */ +#define RCU_AHB1SPEN_SRAM1SPEN BIT(17) /*!< SRAM1 clock enable when sleep mode */ +#define RCU_AHB1SPEN_BKPSRAMSPEN BIT(18) /*!< BKPSRAM clock enable when sleep mode */ +#define RCU_AHB1SPEN_SRAM2SPEN BIT(19) /*!< SRAM2 clock enable when sleep mode */ +#define RCU_AHB1SPEN_DMA0SPEN BIT(21) /*!< DMA0 clock when sleep mode enable */ +#define RCU_AHB1SPEN_DMA1SPEN BIT(22) /*!< DMA1 clock when sleep mode enable */ +#define RCU_AHB1SPEN_IPASPEN BIT(23) /*!< IPA clock enable when sleep mode */ +#define RCU_AHB1SPEN_ENETSPEN BIT(25) /*!< ENET clock enable when sleep mode */ +#define RCU_AHB1SPEN_ENETTXSPEN BIT(26) /*!< Ethernet TX clock enable when sleep mode */ +#define RCU_AHB1SPEN_ENETRXSPEN BIT(27) /*!< Ethernet RX clock enable when sleep mode */ +#define RCU_AHB1SPEN_ENETPTPSPEN BIT(28) /*!< Ethernet PTP clock enable when sleep mode */ +#define RCU_AHB1SPEN_USBHSSPEN BIT(29) /*!< USBHS clock enable when sleep mode */ +#define RCU_AHB1SPEN_USBHSULPISPEN BIT(30) /*!< USBHS ULPI clock enable when sleep mode */ + +/* RCU_AHB2SPEN */ +#define RCU_AHB2SPEN_DCISPEN BIT(0) /*!< DCI clock enable when sleep mode */ +#define RCU_AHB2SPEN_TRNGSPEN BIT(6) /*!< TRNG clock enable when sleep mode */ +#define RCU_AHB2SPEN_USBFSSPEN BIT(7) /*!< USBFS clock enable when sleep mode */ + +/* RCU_AHB3SPEN */ +#define RCU_AHB3SPEN_EXMCSPEN BIT(0) /*!< EXMC clock enable when sleep mode */ + +/* RCU_APB1SPEN */ +#define RCU_APB1SPEN_TIMER1SPEN BIT(0) /*!< TIMER1 clock enable when sleep mode */ +#define RCU_APB1SPEN_TIMER2SPEN BIT(1) /*!< TIMER2 clock enable when sleep mode */ +#define RCU_APB1SPEN_TIMER3SPEN BIT(2) /*!< TIMER3 clock enable when sleep mode */ +#define RCU_APB1SPEN_TIMER4SPEN BIT(3) /*!< TIMER4 clock enable when sleep mode */ +#define RCU_APB1SPEN_TIMER5SPEN BIT(4) /*!< TIMER5 clock enable when sleep mode */ +#define RCU_APB1SPEN_TIMER6SPEN BIT(5) /*!< TIMER6 clock enable when sleep mode */ +#define RCU_APB1SPEN_TIMER11SPEN BIT(6) /*!< TIMER11 clock enable when sleep mode */ +#define RCU_APB1SPEN_TIMER12SPEN BIT(7) /*!< TIMER12 clock enable when sleep mode */ +#define RCU_APB1SPEN_TIMER13SPEN BIT(8) /*!< TIMER13 clock enable when sleep mode */ +#define RCU_APB1SPEN_WWDGTSPEN BIT(11) /*!< WWDGT clock enable when sleep mode */ +#define RCU_APB1SPEN_SPI1SPEN BIT(14) /*!< SPI1 clock enable when sleep mode */ +#define RCU_APB1SPEN_SPI2SPEN BIT(15) /*!< SPI2 clock enable when sleep mode */ +#define RCU_APB1SPEN_USART1SPEN BIT(17) /*!< USART1 clock enable when sleep mode*/ +#define RCU_APB1SPEN_USART2SPEN BIT(18) /*!< USART2 clock enable when sleep mode*/ +#define RCU_APB1SPEN_UART3SPEN BIT(19) /*!< UART3 clock enable when sleep mode*/ +#define RCU_APB1SPEN_UART4SPEN BIT(20) /*!< UART4 clock enable when sleep mode */ +#define RCU_APB1SPEN_I2C0SPEN BIT(21) /*!< I2C0 clock enable when sleep mode */ +#define RCU_APB1SPEN_I2C1SPEN BIT(22) /*!< I2C1 clock enable when sleep mode*/ +#define RCU_APB1SPEN_I2C2SPEN BIT(23) /*!< I2C2 clock enable when sleep mode */ +#define RCU_APB1SPEN_CAN0SPEN BIT(25) /*!< CAN0 clock enable when sleep mode*/ +#define RCU_APB1SPEN_CAN1SPEN BIT(26) /*!< CAN1 clock enable when sleep mode */ +#define RCU_APB1SPEN_PMUSPEN BIT(28) /*!< PMU clock enable when sleep mode */ +#define RCU_APB1SPEN_DACSPEN BIT(29) /*!< DAC clock enable when sleep mode */ +#define RCU_APB1SPEN_UART6SPEN BIT(30) /*!< UART6 clock enable when sleep mode */ +#define RCU_APB1SPEN_UART7SPEN BIT(31) /*!< UART7 clock enable when sleep mode */ + +/* RCU_APB2SPEN */ +#define RCU_APB2SPEN_TIMER0SPEN BIT(0) /*!< TIMER0 clock enable when sleep mode */ +#define RCU_APB2SPEN_TIMER7SPEN BIT(1) /*!< TIMER7 clock enable when sleep mode */ +#define RCU_APB2SPEN_USART0SPEN BIT(4) /*!< USART0 clock enable when sleep mode */ +#define RCU_APB2SPEN_USART5SPEN BIT(5) /*!< USART5 clock enable when sleep mode */ +#define RCU_APB2SPEN_ADC0SPEN BIT(8) /*!< ADC0 clock enable when sleep mode */ +#define RCU_APB2SPEN_ADC1SPEN BIT(9) /*!< ADC1 clock enable when sleep mode */ +#define RCU_APB2SPEN_ADC2SPEN BIT(10) /*!< ADC2 clock enable when sleep mode */ +#define RCU_APB2SPEN_SDIOSPEN BIT(11) /*!< SDIO clock enable when sleep mode */ +#define RCU_APB2SPEN_SPI0SPEN BIT(12) /*!< SPI0 clock enable when sleep mode */ +#define RCU_APB2SPEN_SPI3SPEN BIT(13) /*!< SPI3 clock enable when sleep mode */ +#define RCU_APB2SPEN_SYSCFGSPEN BIT(14) /*!< SYSCFG clock enable when sleep mode */ +#define RCU_APB2SPEN_TIMER8SPEN BIT(16) /*!< TIMER8 clock enable when sleep mode */ +#define RCU_APB2SPEN_TIMER9SPEN BIT(17) /*!< TIMER9 clock enable when sleep mode */ +#define RCU_APB2SPEN_TIMER10SPEN BIT(18) /*!< TIMER10 clock enable when sleep mode */ +#define RCU_APB2SPEN_SPI4SPEN BIT(20) /*!< SPI4 clock enable when sleep mode */ +#define RCU_APB2SPEN_SPI5SPEN BIT(21) /*!< SPI5 clock enable when sleep mode */ +#define RCU_APB2SPEN_TLISPEN BIT(26) /*!< TLI clock enable when sleep mode*/ + +/* RCU_BDCTL */ +#define RCU_BDCTL_LXTALEN BIT(0) /*!< LXTAL enable */ +#define RCU_BDCTL_LXTALSTB BIT(1) /*!< low speed crystal oscillator stabilization flag */ +#define RCU_BDCTL_LXTALBPS BIT(2) /*!< LXTAL bypass mode enable */ +#define RCU_BDCTL_LXTALDRI BIT(3) /*!< LXTAL drive capability */ +#define RCU_BDCTL_RTCSRC BITS(8,9) /*!< RTC clock entry selection */ +#define RCU_BDCTL_RTCEN BIT(15) /*!< RTC clock enable */ +#define RCU_BDCTL_BKPRST BIT(16) /*!< backup domain reset */ + +/* RCU_RSTSCK */ +#define RCU_RSTSCK_IRC32KEN BIT(0) /*!< IRC32K enable */ +#define RCU_RSTSCK_IRC32KSTB BIT(1) /*!< IRC32K stabilization flag */ +#define RCU_RSTSCK_RSTFC BIT(24) /*!< reset flag clear */ +#define RCU_RSTSCK_BORRSTF BIT(25) /*!< BOR reset flag */ +#define RCU_RSTSCK_EPRSTF BIT(26) /*!< external pin reset flag */ +#define RCU_RSTSCK_PORRSTF BIT(27) /*!< power reset flag */ +#define RCU_RSTSCK_SWRSTF BIT(28) /*!< software reset flag */ +#define RCU_RSTSCK_FWDGTRSTF BIT(29) /*!< free watchdog timer reset flag */ +#define RCU_RSTSCK_WWDGTRSTF BIT(30) /*!< window watchdog timer reset flag */ +#define RCU_RSTSCK_LPRSTF BIT(31) /*!< low-power reset flag */ + +/* RCU_PLLSSCTL */ +#define RCU_PLLSSCTL_MODCNT BITS(0,12) /*!< these bits configure PLL spread spectrum modulation + profile amplitude and frequency. the following criteria + must be met: MODSTEP*MODCNT=215-1 */ +#define RCU_PLLSSCTL_MODSTEP BITS(13,27) /*!< these bits configure PLL spread spectrum modulation + profile amplitude and frequency. the following criteria + must be met: MODSTEP*MODCNT=215-1 */ +#define RCU_PLLSSCTL_SS_TYPE BIT(30) /*!< PLL spread spectrum modulation type select */ +#define RCU_PLLSSCTL_SSCGON BIT(31) /*!< PLL spread spectrum modulation enable */ + +/* RCU_PLLI2S */ +#define RCU_PLLI2S_PLLI2SN BITS(6,14) /*!< the PLLI2S VCO clock multi factor */ +#define RCU_PLLI2S_PLLI2SQ BITS(24,27) /*!< the PLLI2S Q output frequency division factor from PLLI2S VCO clock */ +#define RCU_PLLI2S_PLLI2SR BITS(28,30) /*!< the PLLI2S R output frequency division factor from PLLI2S VCO clock */ + +/* RCU_PLLSAI */ +#define RCU_PLLSAI_PLLSAIN BITS(6,14) /*!< the PLLSAI VCO clock multi factor */ +#define RCU_PLLSAI_PLLSAIP BITS(16,17) /*!< the PLLSAI P output frequency division factor from PLLSAI VCO clock */ +#define RCU_PLLSAI_PLLSAIQ BITS(24,27) /*!< the PLLSAI Q output frequency division factor from PLLSAI VCO clock */ +#define RCU_PLLSAI_PLLSAIR BITS(28,30) /*!< the PLLSAI R output frequency division factor from PLLSAI VCO clock */ + +/* RCU_CFG1 */ +#define RCU_CFG1_PLLSAIRDIV BITS(16,17) /*!< the divider factor from PLLSAIR clock */ +#define RCU_CFG1_TIMERSEL BIT(24) /*!< TIMER clock selection */ + +/* RCU_ADDCTL */ +#define RCU_ADDCTL_CK48MSEL BIT(0) /*!< 48MHz clock selection */ +#define RCU_ADDCTL_PLL48MSEL BIT(1) /*!< PLL48M clock selection */ +#define RCU_ADDCTL_IRC48MEN BIT(16) /*!< internal 48MHz RC oscillator enable */ +#define RCU_ADDCTL_IRC48MSTB BIT(17) /*!< internal 48MHz RC oscillator clock stabilization flag */ +#define RCU_ADDCTL_IRC48MCAL BITS(24,31) /*!< internal 48MHz RC oscillator calibration value register */ + +/* RCU_ADDINT */ +#define RCU_ADDINT_IRC48MSTBIF BIT(6) /*!< IRC48M stabilization interrupt flag */ +#define RCU_ADDINT_IRC48MSTBIE BIT(14) /*!< internal 48 MHz RC oscillator stabilization interrupt enable */ +#define RCU_ADDINT_IRC48MSTBIC BIT(22) /*!< internal 48 MHz RC oscillator stabilization interrupt clear */ + +/* RCU_ADDAPB1RST */ +#define RCU_ADDAPB1RST_CTCRST BIT(27) /*!< CTC reset */ +#define RCU_ADDAPB1RST_IREFRST BIT(31) /*!< IREF reset */ + +/* RCU_ADDAPB1EN */ +#define RCU_ADDAPB1EN_CTCEN BIT(27) /*!< CTC clock enable */ +#define RCU_ADDAPB1EN_IREFEN BIT(31) /*!< IREF interface clock enable */ + +/* RCU_ADDAPB1SPEN */ +#define RCU_ADDAPB1SPEN_CTCSPEN BIT(27) /*!< CTC clock enable during sleep mode */ +#define RCU_ADDAPB1SPEN_IREFSPEN BIT(31) /*!< IREF interface clock enable during sleep mode */ + +/* RCU_VKEY */ +#define RCU_VKEY_KEY BITS(0,31) /*!< RCU_DSV key register */ + +/* RCU_DSV */ +#define RCU_DSV_DSLPVS BITS(0,2) /*!< deep-sleep mode voltage select */ + +/* constants definitions */ +/* define the peripheral clock enable bit position and its register index offset */ +#define RCU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph) >> 6))) +#define RCU_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +/* define the voltage key unlock value */ +#define RCU_VKEY_UNLOCK ((uint32_t)0x1A2B3C4DU) + +/* register offset */ +/* peripherals enable */ +#define AHB1EN_REG_OFFSET 0x30U /*!< AHB1 enable register offset */ +#define AHB2EN_REG_OFFSET 0x34U /*!< AHB2 enable register offset */ +#define AHB3EN_REG_OFFSET 0x38U /*!< AHB3 enable register offset */ +#define APB1EN_REG_OFFSET 0x40U /*!< APB1 enable register offset */ +#define APB2EN_REG_OFFSET 0x44U /*!< APB2 enable register offset */ +#define AHB1SPEN_REG_OFFSET 0x50U /*!< AHB1 sleep mode enable register offset */ +#define AHB2SPEN_REG_OFFSET 0x54U /*!< AHB2 sleep mode enable register offset */ +#define AHB3SPEN_REG_OFFSET 0x58U /*!< AHB3 sleep mode enable register offset */ +#define APB1SPEN_REG_OFFSET 0x60U /*!< APB1 sleep mode enable register offset */ +#define APB2SPEN_REG_OFFSET 0x64U /*!< APB2 sleep mode enable register offset */ +#define ADD_APB1EN_REG_OFFSET 0xE4U /*!< APB1 additional enable register offset */ +#define ADD_APB1SPEN_REG_OFFSET 0xE8U /*!< APB1 additional sleep mode enable register offset */ + +/* peripherals reset */ +#define AHB1RST_REG_OFFSET 0x10U /*!< AHB1 reset register offset */ +#define AHB2RST_REG_OFFSET 0x14U /*!< AHB2 reset register offset */ +#define AHB3RST_REG_OFFSET 0x18U /*!< AHB3 reset register offset */ +#define APB1RST_REG_OFFSET 0x20U /*!< APB1 reset register offset */ +#define APB2RST_REG_OFFSET 0x24U /*!< APB2 reset register offset */ +#define ADD_APB1RST_REG_OFFSET 0xE0U /*!< APB1 additional reset register offset */ +#define RSTSCK_REG_OFFSET 0x74U /*!< reset source/clock register offset */ + +/* clock control */ +#define CTL_REG_OFFSET 0x00U /*!< control register offset */ +#define BDCTL_REG_OFFSET 0x70U /*!< backup domain control register offset */ +#define ADDCTL_REG_OFFSET 0xC0U /*!< additional clock control register offset */ + +/* clock stabilization and stuck interrupt */ +#define INT_REG_OFFSET 0x0CU /*!< clock interrupt register offset */ +#define ADDINT_REG_OFFSET 0xCCU /*!< additional clock interrupt register offset */ + +/* configuration register */ +#define PLL_REG_OFFSET 0x04U /*!< PLL register offset */ +#define CFG0_REG_OFFSET 0x08U /*!< clock configuration register 0 offset */ +#define PLLSSCTL_REG_OFFSET 0x80U /*!< PLL clock spread spectrum control register offset */ +#define PLLI2S_REG_OFFSET 0x84U /*!< PLLI2S register offset */ +#define PLLSAI_REG_OFFSET 0x88U /*!< PLLSAI register offset */ +#define CFG1_REG_OFFSET 0x8CU /*!< clock configuration register 1 offset */ + +/* peripheral clock enable */ +typedef enum +{ + /* AHB1 peripherals */ + RCU_GPIOA = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 0U), /*!< GPIOA clock */ + RCU_GPIOB = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 1U), /*!< GPIOB clock */ + RCU_GPIOC = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 2U), /*!< GPIOC clock */ + RCU_GPIOD = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 3U), /*!< GPIOD clock */ + RCU_GPIOE = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 4U), /*!< GPIOE clock */ + RCU_GPIOF = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 5U), /*!< GPIOF clock */ + RCU_GPIOG = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 6U), /*!< GPIOG clock */ + RCU_GPIOH = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 7U), /*!< GPIOH clock */ + RCU_GPIOI = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 8U), /*!< GPIOI clock */ + RCU_CRC = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 12U), /*!< CRC clock */ + RCU_BKPSRAM = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 18U), /*!< BKPSRAM clock */ + RCU_TCMSRAM = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 20U), /*!< TCMSRAM clock */ + RCU_DMA0 = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 21U), /*!< DMA0 clock */ + RCU_DMA1 = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 22U), /*!< DMA1 clock */ + RCU_IPA = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 23U), /*!< IPA clock */ + RCU_ENET = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 25U), /*!< ENET clock */ + RCU_ENETTX = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 26U), /*!< ENETTX clock */ + RCU_ENETRX = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 27U), /*!< ENETRX clock */ + RCU_ENETPTP = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 28U), /*!< ENETPTP clock */ + RCU_USBHS = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 29U), /*!< USBHS clock */ + RCU_USBHSULPI = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 30U), /*!< USBHSULPI clock */ + /* AHB2 peripherals */ + RCU_DCI = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 0U), /*!< DCI clock */ + RCU_TRNG = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 6U), /*!< TRNG clock */ + RCU_USBFS = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 7U), /*!< USBFS clock */ + /* AHB3 peripherals */ + RCU_EXMC = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 0U), /*!< EXMC clock */ + /* APB1 peripherals */ + RCU_TIMER1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 0U), /*!< TIMER1 clock */ + RCU_TIMER2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 1U), /*!< TIMER2 clock */ + RCU_TIMER3 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 2U), /*!< TIMER3 clock */ + RCU_TIMER4 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 3U), /*!< TIMER4 clock */ + RCU_TIMER5 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 4U), /*!< TIMER5 clock */ + RCU_TIMER6 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 5U), /*!< TIMER6 clock */ + RCU_TIMER11 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 6U), /*!< TIMER11 clock */ + RCU_TIMER12 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 7U), /*!< TIMER12 clock */ + RCU_TIMER13 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 8U), /*!< TIMER13 clock */ + RCU_WWDGT = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 11U), /*!< WWDGT clock */ + RCU_SPI1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 14U), /*!< SPI1 clock */ + RCU_SPI2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 15U), /*!< SPI2 clock */ + RCU_USART1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 17U), /*!< USART1 clock */ + RCU_USART2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 18U), /*!< USART2 clock */ + RCU_UART3 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 19U), /*!< UART3 clock */ + RCU_UART4 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 20U), /*!< UART4 clock */ + RCU_I2C0 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 21U), /*!< I2C0 clock */ + RCU_I2C1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 22U), /*!< I2C1 clock */ + RCU_I2C2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 23U), /*!< I2C2 clock */ + RCU_CAN0 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 25U), /*!< CAN0 clock */ + RCU_CAN1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 26U), /*!< CAN1 clock */ + RCU_PMU = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 28U), /*!< PMU clock */ + RCU_DAC = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 29U), /*!< DAC clock */ + RCU_UART6 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 30U), /*!< UART6 clock */ + RCU_UART7 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 31U), /*!< UART7 clock */ + RCU_RTC = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 15U), /*!< RTC clock */ + /* APB2 peripherals */ + RCU_TIMER0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 0U), /*!< TIMER0 clock */ + RCU_TIMER7 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 1U), /*!< TIMER7 clock */ + RCU_USART0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 4U), /*!< USART0 clock */ + RCU_USART5 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 5U), /*!< USART5 clock */ + RCU_ADC0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 8U), /*!< ADC0 clock */ + RCU_ADC1 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 9U), /*!< ADC1 clock */ + RCU_ADC2 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 10U), /*!< ADC2 clock */ + RCU_SDIO = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 11U), /*!< SDIO clock */ + RCU_SPI0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 12U), /*!< SPI0 clock */ + RCU_SPI3 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 13U), /*!< SPI3 clock */ + RCU_SYSCFG = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 14U), /*!< SYSCFG clock */ + RCU_TIMER8 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 16U), /*!< TIMER8 clock */ + RCU_TIMER9 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 17U), /*!< TIMER9 clock */ + RCU_TIMER10 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 18U), /*!< TIMER10 clock */ + RCU_SPI4 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 20U), /*!< SPI4 clock */ + RCU_SPI5 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 21U), /*!< SPI5 clock */ + RCU_TLI = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 26U), /*!< TLI clock */ + /* APB2 additional peripherals */ + RCU_CTC = RCU_REGIDX_BIT(ADD_APB1EN_REG_OFFSET, 27U), /*!< CTC clock */ + RCU_IREF = RCU_REGIDX_BIT(ADD_APB1EN_REG_OFFSET, 31U), /*!< IREF clock */ +}rcu_periph_enum; + +/* peripheral clock enable when sleep mode*/ +typedef enum +{ + /* AHB1 peripherals */ + RCU_GPIOA_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 0U), /*!< GPIOA clock */ + RCU_GPIOB_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 1U), /*!< GPIOB clock */ + RCU_GPIOC_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 2U), /*!< GPIOC clock */ + RCU_GPIOD_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 3U), /*!< GPIOD clock */ + RCU_GPIOE_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 4U), /*!< GPIOE clock */ + RCU_GPIOF_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 5U), /*!< GPIOF clock */ + RCU_GPIOG_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 6U), /*!< GPIOG clock */ + RCU_GPIOH_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 7U), /*!< GPIOH clock */ + RCU_GPIOI_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 8U), /*!< GPIOI clock */ + RCU_CRC_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 12U), /*!< CRC clock */ + RCU_FMC_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 15U), /*!< FMC clock */ + RCU_SRAM0_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 16U), /*!< SRAM0 clock */ + RCU_SRAM1_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 17U), /*!< SRAM1 clock */ + RCU_BKPSRAM_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 18U), /*!< BKPSRAM clock */ + RCU_SRAM2_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 19U), /*!< SRAM2 clock */ + RCU_DMA0_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 21U), /*!< DMA0 clock */ + RCU_DMA1_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 22U), /*!< DMA1 clock */ + RCU_IPA_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 23U), /*!< IPA clock */ + RCU_ENET_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 25U), /*!< ENET clock */ + RCU_ENETTX_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 26U), /*!< ENETTX clock */ + RCU_ENETRX_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 27U), /*!< ENETRX clock */ + RCU_ENETPTP_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 28U), /*!< ENETPTP clock */ + RCU_USBHS_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 29U), /*!< USBHS clock */ + RCU_USBHSULPI_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 30U), /*!< USBHSULPI clock */ + /* AHB2 peripherals */ + RCU_DCI_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 0U), /*!< DCI clock */ + RCU_TRNG_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 6U), /*!< TRNG clock */ + RCU_USBFS_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 7U), /*!< USBFS clock */ + /* AHB3 peripherals */ + RCU_EXMC_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 0U), /*!< EXMC clock */ + /* APB1 peripherals */ + RCU_TIMER1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 0U), /*!< TIMER1 clock */ + RCU_TIMER2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 1U), /*!< TIMER2 clock */ + RCU_TIMER3_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 2U), /*!< TIMER3 clock */ + RCU_TIMER4_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 3U), /*!< TIMER4 clock */ + RCU_TIMER5_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 4U), /*!< TIMER5 clock */ + RCU_TIMER6_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 5U), /*!< TIMER6 clock */ + RCU_TIMER11_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 6U), /*!< TIMER11 clock */ + RCU_TIMER12_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 7U), /*!< TIMER12 clock */ + RCU_TIMER13_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 8U), /*!< TIMER13 clock */ + RCU_WWDGT_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 11U), /*!< WWDGT clock */ + RCU_SPI1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 14U), /*!< SPI1 clock */ + RCU_SPI2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 15U), /*!< SPI2 clock */ + RCU_USART1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 17U), /*!< USART1 clock */ + RCU_USART2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 18U), /*!< USART2 clock */ + RCU_UART3_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 19U), /*!< UART3 clock */ + RCU_UART4_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 20U), /*!< UART4 clock */ + RCU_I2C0_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 21U), /*!< I2C0 clock */ + RCU_I2C1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 22U), /*!< I2C1 clock */ + RCU_I2C2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 23U), /*!< I2C2 clock */ + RCU_CAN0_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 25U), /*!< CAN0 clock */ + RCU_CAN1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 26U), /*!< CAN1 clock */ + RCU_PMU_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 28U), /*!< PMU clock */ + RCU_DAC_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 29U), /*!< DAC clock */ + RCU_UART6_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 30U), /*!< UART6 clock */ + RCU_UART7_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 31U), /*!< UART7 clock */ + /* APB2 peripherals */ + RCU_TIMER0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 0U), /*!< TIMER0 clock */ + RCU_TIMER7_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 1U), /*!< TIMER7 clock */ + RCU_USART0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 4U), /*!< USART0 clock */ + RCU_USART5_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 5U), /*!< USART5 clock */ + RCU_ADC0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 8U), /*!< ADC0 clock */ + RCU_ADC1_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 9U), /*!< ADC1 clock */ + RCU_ADC2_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 10U), /*!< ADC2 clock */ + RCU_SDIO_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 11U), /*!< SDIO clock */ + RCU_SPI0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 12U), /*!< SPI0 clock */ + RCU_SPI3_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 13U), /*!< SPI3 clock */ + RCU_SYSCFG_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 14U), /*!< SYSCFG clock */ + RCU_TIMER8_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 16U), /*!< TIMER8 clock */ + RCU_TIMER9_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 17U), /*!< TIMER9 clock */ + RCU_TIMER10_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 18U), /*!< TIMER10 clock */ + RCU_SPI4_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 20U), /*!< SPI4 clock */ + RCU_SPI5_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 21U), /*!< SPI5 clock */ + RCU_TLI_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 26U), /*!< TLI clock */ + /* APB1 additional peripherals */ + RCU_CTC_SLP = RCU_REGIDX_BIT(ADD_APB1SPEN_REG_OFFSET, 27U), /*!< CTC clock */ + RCU_IREF_SLP = RCU_REGIDX_BIT(ADD_APB1SPEN_REG_OFFSET, 31U), /*!< IREF clock */ +}rcu_periph_sleep_enum; + +/* peripherals reset */ +typedef enum +{ + /* AHB1 peripherals */ + RCU_GPIOARST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 0U), /*!< GPIOA clock reset */ + RCU_GPIOBRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 1U), /*!< GPIOB clock reset */ + RCU_GPIOCRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 2U), /*!< GPIOC clock reset */ + RCU_GPIODRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 3U), /*!< GPIOD clock reset */ + RCU_GPIOERST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 4U), /*!< GPIOE clock reset */ + RCU_GPIOFRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 5U), /*!< GPIOF clock reset */ + RCU_GPIOGRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 6U), /*!< GPIOG clock reset */ + RCU_GPIOHRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 7U), /*!< GPIOH clock reset */ + RCU_GPIOIRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 8U), /*!< GPIOI clock reset */ + RCU_CRCRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 12U), /*!< CRC clock reset */ + RCU_DMA0RST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 21U), /*!< DMA0 clock reset */ + RCU_DMA1RST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 22U), /*!< DMA1 clock reset */ + RCU_IPAENRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 23U), /*!< IPA clock reset */ + RCU_ENETRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 25U), /*!< ENET clock reset */ + RCU_USBHSRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 29U), /*!< USBHS clock reset */ + /* AHB2 peripherals */ + RCU_DCIRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 0U), /*!< DCI clock reset */ + RCU_TRNGRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 6U), /*!< TRNG clock reset */ + RCU_USBFSRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 7U), /*!< USBFS clock reset */ + /* AHB3 peripherals */ + RCU_EXMCRST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 0U), /*!< EXMC clock reset */ + /* APB1 peripherals */ + RCU_TIMER1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 0U), /*!< TIMER1 clock reset */ + RCU_TIMER2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 1U), /*!< TIMER2 clock reset */ + RCU_TIMER3RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 2U), /*!< TIMER3 clock reset */ + RCU_TIMER4RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 3U), /*!< TIMER4 clock reset */ + RCU_TIMER5RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 4U), /*!< TIMER5 clock reset */ + RCU_TIMER6RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 5U), /*!< TIMER6 clock reset */ + RCU_TIMER11RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 6U), /*!< TIMER11 clock reset */ + RCU_TIMER12RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 7U), /*!< TIMER12 clock reset */ + RCU_TIMER13RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 8U), /*!< TIMER13 clock reset */ + RCU_WWDGTRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 11U), /*!< WWDGT clock reset */ + RCU_SPI1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 14U), /*!< SPI1 clock reset */ + RCU_SPI2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 15U), /*!< SPI2 clock reset */ + RCU_USART1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 17U), /*!< USART1 clock reset */ + RCU_USART2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 18U), /*!< USART2 clock reset */ + RCU_UART3RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 19U), /*!< UART3 clock reset */ + RCU_UART4RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 20U), /*!< UART4 clock reset */ + RCU_I2C0RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 21U), /*!< I2C0 clock reset */ + RCU_I2C1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 22U), /*!< I2C1 clock reset */ + RCU_I2C2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 23U), /*!< I2C2 clock reset */ + RCU_CAN0RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 25U), /*!< CAN0 clock reset */ + RCU_CAN1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 26U), /*!< CAN1 clock reset */ + RCU_PMURST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 28U), /*!< PMU clock reset */ + RCU_DACRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 29U), /*!< DAC clock reset */ + RCU_UART6RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 30U), /*!< UART6 clock reset */ + RCU_UART7RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 31U), /*!< UART7 clock reset */ + /* APB2 peripherals */ + RCU_TIMER0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 0U), /*!< TIMER0 clock reset */ + RCU_TIMER7RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 1U), /*!< TIMER7 clock reset */ + RCU_USART0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 4U), /*!< USART0 clock reset */ + RCU_USART5RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 5U), /*!< USART5 clock reset */ + RCU_ADCRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 8U), /*!< ADCs all clock reset */ + RCU_SDIORST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 11U), /*!< SDIO clock reset */ + RCU_SPI0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 12U), /*!< SPI0 clock reset */ + RCU_SPI3RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 13U), /*!< SPI3 clock reset */ + RCU_SYSCFGRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 14U), /*!< SYSCFG clock reset */ + RCU_TIMER8RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 16U), /*!< TIMER8 clock reset */ + RCU_TIMER9RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 17U), /*!< TIMER9 clock reset */ + RCU_TIMER10RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 18U), /*!< TIMER10 clock reset */ + RCU_SPI4RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 20U), /*!< SPI4 clock reset */ + RCU_SPI5RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 21U), /*!< SPI5 clock reset */ + RCU_TLIRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 26U), /*!< TLI clock reset */ + /* APB2 additional peripherals */ + RCU_CTCRST = RCU_REGIDX_BIT(ADD_APB1RST_REG_OFFSET, 27U), /*!< CTC clock reset */ + RCU_IREFRST = RCU_REGIDX_BIT(ADD_APB1RST_REG_OFFSET, 31U) /*!< IREF clock reset */ +}rcu_periph_reset_enum; + +/* clock stabilization and peripheral reset flags */ +typedef enum +{ + /* clock stabilization flags */ + RCU_FLAG_IRC16MSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 1U), /*!< IRC16M stabilization flags */ + RCU_FLAG_HXTALSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 17U), /*!< HXTAL stabilization flags */ + RCU_FLAG_PLLSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 25U), /*!< PLL stabilization flags */ + RCU_FLAG_PLLI2SSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 27U), /*!< PLLI2S stabilization flags */ + RCU_FLAG_PLLSAISTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 29U), /*!< PLLSAI stabilization flags */ + RCU_FLAG_LXTALSTB = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 1U), /*!< LXTAL stabilization flags */ + RCU_FLAG_IRC32KSTB = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 1U), /*!< IRC32K stabilization flags */ + RCU_FLAG_IRC48MSTB = RCU_REGIDX_BIT(ADDCTL_REG_OFFSET, 17U), /*!< IRC48M stabilization flags */ + /* reset source flags */ + RCU_FLAG_BORRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 25U), /*!< BOR reset flags */ + RCU_FLAG_EPRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 26U), /*!< External PIN reset flags */ + RCU_FLAG_PORRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 27U), /*!< power reset flags */ + RCU_FLAG_SWRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 28U), /*!< Software reset flags */ + RCU_FLAG_FWDGTRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 29U), /*!< FWDGT reset flags */ + RCU_FLAG_WWDGTRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 30U), /*!< WWDGT reset flags */ + RCU_FLAG_LPRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 31U), /*!< Low-power reset flags */ +}rcu_flag_enum; + +/* clock stabilization and ckm interrupt flags */ +typedef enum +{ + RCU_INT_FLAG_IRC32KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 0U), /*!< IRC32K stabilization interrupt flag */ + RCU_INT_FLAG_LXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 1U), /*!< LXTAL stabilization interrupt flag */ + RCU_INT_FLAG_IRC8MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 2U), /*!< IRC8M stabilization interrupt flag */ + RCU_INT_FLAG_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 3U), /*!< HXTAL stabilization interrupt flag */ + RCU_INT_FLAG_PLLSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 4U), /*!< PLL stabilization interrupt flag */ + RCU_INT_FLAG_PLLI2SSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 5U), /*!< PLLI2S stabilization interrupt flag */ + RCU_INT_FLAG_PLLSAISTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 6U), /*!< PLLSAI stabilization interrupt flag */ + RCU_INT_FLAG_CKM = RCU_REGIDX_BIT(INT_REG_OFFSET, 7U), /*!< HXTAL clock stuck interrupt flag */ + RCU_INT_FLAG_IRC48MSTB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 6U), /*!< IRC48M stabilization interrupt flag */ +}rcu_int_flag_enum; + +/* clock stabilization and stuck interrupt flags clear */ +typedef enum +{ + RCU_INT_FLAG_IRC32KSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 16U), /*!< IRC32K stabilization interrupt flags clear */ + RCU_INT_FLAG_LXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 17U), /*!< LXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_IRC16MSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 18U), /*!< IRC16M stabilization interrupt flags clear */ + RCU_INT_FLAG_HXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 19U), /*!< HXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 20U), /*!< PLL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLI2SSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 21U), /*!< PLLI2S stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLSAISTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 22U), /*!< PLLSAI stabilization interrupt flags clear */ + RCU_INT_FLAG_CKM_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 23U), /*!< CKM interrupt flags clear */ + RCU_INT_FLAG_IRC48MSTB_CLR = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 22U), /*!< internal 48 MHz RC oscillator stabilization interrupt clear */ +}rcu_int_flag_clear_enum; + +/* clock stabilization interrupt enable or disable */ +typedef enum +{ + RCU_INT_IRC32KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 8U), /*!< IRC32K stabilization interrupt */ + RCU_INT_LXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 9U), /*!< LXTAL stabilization interrupt */ + RCU_INT_IRC16MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 10U), /*!< IRC8M stabilization interrupt */ + RCU_INT_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 11U), /*!< HXTAL stabilization interrupt */ + RCU_INT_PLLSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 12U), /*!< PLL stabilization interrupt */ + RCU_INT_PLLI2SSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 13U), /*!< PLLI2S stabilization interrupt */ + RCU_INT_PLLSAISTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 14U), /*!< PLLSAI stabilization interrupt */ + RCU_INT_IRC48MSTB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 14U), /*!< internal 48 MHz RC oscillator stabilization interrupt */ +}rcu_int_enum; + +/* oscillator types */ +typedef enum +{ + RCU_HXTAL = RCU_REGIDX_BIT(CTL_REG_OFFSET, 16U), /*!< HXTAL */ + RCU_LXTAL = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 0U), /*!< LXTAL */ + RCU_IRC16M = RCU_REGIDX_BIT(CTL_REG_OFFSET, 0U), /*!< IRC16M */ + RCU_IRC48M = RCU_REGIDX_BIT(ADDCTL_REG_OFFSET, 16U), /*!< IRC48M */ + RCU_IRC32K = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 0U), /*!< IRC32K */ + RCU_PLL_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 24U), /*!< PLL */ + RCU_PLLI2S_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 26U), /*!< PLLI2S */ + RCU_PLLSAI_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 28U), /*!< PLLSAI */ +}rcu_osci_type_enum; + +/* rcu clock frequency */ +typedef enum +{ + CK_SYS = 0, /*!< system clock */ + CK_AHB, /*!< AHB clock */ + CK_APB1, /*!< APB1 clock */ + CK_APB2, /*!< APB2 clock */ +}rcu_clock_freq_enum; + +/* RCU_CFG0 register bit define */ +/* system clock source select */ +#define CFG0_SCS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_CKSYSSRC_IRC16M CFG0_SCS(0) /*!< system clock source select IRC16M */ +#define RCU_CKSYSSRC_HXTAL CFG0_SCS(1) /*!< system clock source select HXTAL */ +#define RCU_CKSYSSRC_PLLP CFG0_SCS(2) /*!< system clock source select PLLP */ + +/* system clock source select status */ +#define CFG0_SCSS(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define RCU_SCSS_IRC16M CFG0_SCSS(0) /*!< system clock source select IRC16M */ +#define RCU_SCSS_HXTAL CFG0_SCSS(1) /*!< system clock source select HXTAL */ +#define RCU_SCSS_PLLP CFG0_SCSS(2) /*!< system clock source select PLLP */ + +/* AHB prescaler selection */ +#define CFG0_AHBPSC(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define RCU_AHB_CKSYS_DIV1 CFG0_AHBPSC(0) /*!< AHB prescaler select CK_SYS */ +#define RCU_AHB_CKSYS_DIV2 CFG0_AHBPSC(8) /*!< AHB prescaler select CK_SYS/2 */ +#define RCU_AHB_CKSYS_DIV4 CFG0_AHBPSC(9) /*!< AHB prescaler select CK_SYS/4 */ +#define RCU_AHB_CKSYS_DIV8 CFG0_AHBPSC(10) /*!< AHB prescaler select CK_SYS/8 */ +#define RCU_AHB_CKSYS_DIV16 CFG0_AHBPSC(11) /*!< AHB prescaler select CK_SYS/16 */ +#define RCU_AHB_CKSYS_DIV64 CFG0_AHBPSC(12) /*!< AHB prescaler select CK_SYS/64 */ +#define RCU_AHB_CKSYS_DIV128 CFG0_AHBPSC(13) /*!< AHB prescaler select CK_SYS/128 */ +#define RCU_AHB_CKSYS_DIV256 CFG0_AHBPSC(14) /*!< AHB prescaler select CK_SYS/256 */ +#define RCU_AHB_CKSYS_DIV512 CFG0_AHBPSC(15) /*!< AHB prescaler select CK_SYS/512 */ + +/* APB1 prescaler selection */ +#define CFG0_APB1PSC(regval) (BITS(10,12) & ((uint32_t)(regval) << 10)) +#define RCU_APB1_CKAHB_DIV1 CFG0_APB1PSC(0) /*!< APB1 prescaler select CK_AHB */ +#define RCU_APB1_CKAHB_DIV2 CFG0_APB1PSC(4) /*!< APB1 prescaler select CK_AHB/2 */ +#define RCU_APB1_CKAHB_DIV4 CFG0_APB1PSC(5) /*!< APB1 prescaler select CK_AHB/4 */ +#define RCU_APB1_CKAHB_DIV8 CFG0_APB1PSC(6) /*!< APB1 prescaler select CK_AHB/8 */ +#define RCU_APB1_CKAHB_DIV16 CFG0_APB1PSC(7) /*!< APB1 prescaler select CK_AHB/16 */ + +/* APB2 prescaler selection */ +#define CFG0_APB2PSC(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) +#define RCU_APB2_CKAHB_DIV1 CFG0_APB2PSC(0) /*!< APB2 prescaler select CK_AHB */ +#define RCU_APB2_CKAHB_DIV2 CFG0_APB2PSC(4) /*!< APB2 prescaler select CK_AHB/2 */ +#define RCU_APB2_CKAHB_DIV4 CFG0_APB2PSC(5) /*!< APB2 prescaler select CK_AHB/4 */ +#define RCU_APB2_CKAHB_DIV8 CFG0_APB2PSC(6) /*!< APB2 prescaler select CK_AHB/8 */ +#define RCU_APB2_CKAHB_DIV16 CFG0_APB2PSC(7) /*!< APB2 prescaler select CK_AHB/16 */ + +/* RTC clock divider factor from HXTAL clock */ +#define CFG0_RTCDIV(regval) (BITS(16,20) & ((uint32_t)(regval) << 16)) +#define RCU_RTC_HXTAL_NONE CFG0_RTCDIV(0) /*!< no clock for RTC */ +#define RCU_RTC_HXTAL_DIV2 CFG0_RTCDIV(2) /*!< RTCDIV clock select CK_HXTAL/2 */ +#define RCU_RTC_HXTAL_DIV3 CFG0_RTCDIV(3) /*!< RTCDIV clock select CK_HXTAL/3 */ +#define RCU_RTC_HXTAL_DIV4 CFG0_RTCDIV(4) /*!< RTCDIV clock select CK_HXTAL/4 */ +#define RCU_RTC_HXTAL_DIV5 CFG0_RTCDIV(5) /*!< RTCDIV clock select CK_HXTAL/5 */ +#define RCU_RTC_HXTAL_DIV6 CFG0_RTCDIV(6) /*!< RTCDIV clock select CK_HXTAL/6 */ +#define RCU_RTC_HXTAL_DIV7 CFG0_RTCDIV(7) /*!< RTCDIV clock select CK_HXTAL/7 */ +#define RCU_RTC_HXTAL_DIV8 CFG0_RTCDIV(8) /*!< RTCDIV clock select CK_HXTAL/8 */ +#define RCU_RTC_HXTAL_DIV9 CFG0_RTCDIV(9) /*!< RTCDIV clock select CK_HXTAL/9 */ +#define RCU_RTC_HXTAL_DIV10 CFG0_RTCDIV(10) /*!< RTCDIV clock select CK_HXTAL/10 */ +#define RCU_RTC_HXTAL_DIV11 CFG0_RTCDIV(11) /*!< RTCDIV clock select CK_HXTAL/11 */ +#define RCU_RTC_HXTAL_DIV12 CFG0_RTCDIV(12) /*!< RTCDIV clock select CK_HXTAL/12 */ +#define RCU_RTC_HXTAL_DIV13 CFG0_RTCDIV(13) /*!< RTCDIV clock select CK_HXTAL/13 */ +#define RCU_RTC_HXTAL_DIV14 CFG0_RTCDIV(14) /*!< RTCDIV clock select CK_HXTAL/14 */ +#define RCU_RTC_HXTAL_DIV15 CFG0_RTCDIV(15) /*!< RTCDIV clock select CK_HXTAL/15 */ +#define RCU_RTC_HXTAL_DIV16 CFG0_RTCDIV(16) /*!< RTCDIV clock select CK_HXTAL/16 */ +#define RCU_RTC_HXTAL_DIV17 CFG0_RTCDIV(17) /*!< RTCDIV clock select CK_HXTAL/17 */ +#define RCU_RTC_HXTAL_DIV18 CFG0_RTCDIV(18) /*!< RTCDIV clock select CK_HXTAL/18 */ +#define RCU_RTC_HXTAL_DIV19 CFG0_RTCDIV(19) /*!< RTCDIV clock select CK_HXTAL/19 */ +#define RCU_RTC_HXTAL_DIV20 CFG0_RTCDIV(20) /*!< RTCDIV clock select CK_HXTAL/20 */ +#define RCU_RTC_HXTAL_DIV21 CFG0_RTCDIV(21) /*!< RTCDIV clock select CK_HXTAL/21 */ +#define RCU_RTC_HXTAL_DIV22 CFG0_RTCDIV(22) /*!< RTCDIV clock select CK_HXTAL/22 */ +#define RCU_RTC_HXTAL_DIV23 CFG0_RTCDIV(23) /*!< RTCDIV clock select CK_HXTAL/23 */ +#define RCU_RTC_HXTAL_DIV24 CFG0_RTCDIV(24) /*!< RTCDIV clock select CK_HXTAL/24 */ +#define RCU_RTC_HXTAL_DIV25 CFG0_RTCDIV(25) /*!< RTCDIV clock select CK_HXTAL/25 */ +#define RCU_RTC_HXTAL_DIV26 CFG0_RTCDIV(26) /*!< RTCDIV clock select CK_HXTAL/26 */ +#define RCU_RTC_HXTAL_DIV27 CFG0_RTCDIV(27) /*!< RTCDIV clock select CK_HXTAL/27 */ +#define RCU_RTC_HXTAL_DIV28 CFG0_RTCDIV(28) /*!< RTCDIV clock select CK_HXTAL/28 */ +#define RCU_RTC_HXTAL_DIV29 CFG0_RTCDIV(29) /*!< RTCDIV clock select CK_HXTAL/29 */ +#define RCU_RTC_HXTAL_DIV30 CFG0_RTCDIV(30) /*!< RTCDIV clock select CK_HXTAL/30 */ +#define RCU_RTC_HXTAL_DIV31 CFG0_RTCDIV(31) /*!< RTCDIV clock select CK_HXTAL/31 */ + +/* CKOUT0 Clock source selection */ +#define CFG0_CKOUT0SEL(regval) (BITS(21,22) & ((uint32_t)(regval) << 21)) +#define RCU_CKOUT0SRC_IRC16M CFG0_CKOUT0SEL(0) /*!< internal 16M RC oscillator clock selected */ +#define RCU_CKOUT0SRC_LXTAL CFG0_CKOUT0SEL(1) /*!< low speed crystal oscillator clock (LXTAL) selected */ +#define RCU_CKOUT0SRC_HXTAL CFG0_CKOUT0SEL(2) /*!< high speed crystal oscillator clock (HXTAL) selected */ +#define RCU_CKOUT0SRC_PLLP CFG0_CKOUT0SEL(3) /*!< CK_PLLP clock selected */ + +/* I2S Clock source selection */ +#define RCU_I2SSRC_PLLI2S ((uint32_t)0x00000000U) /*!< PLLI2S output clock selected as I2S source clock */ +#define RCU_I2SSRC_I2S_CKIN RCU_CFG0_I2SSEL /*!< external I2S_CKIN pin selected as I2S source clock */ + +/* The CK_OUT0 divider */ +#define CFG0_CKOUT0DIV(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define RCU_CKOUT0_DIV1 CFG0_CKOUT0DIV(0) /*!< CK_OUT0 is divided by 1 */ +#define RCU_CKOUT0_DIV2 CFG0_CKOUT0DIV(4) /*!< CK_OUT0 is divided by 2 */ +#define RCU_CKOUT0_DIV3 CFG0_CKOUT0DIV(5) /*!< CK_OUT0 is divided by 3 */ +#define RCU_CKOUT0_DIV4 CFG0_CKOUT0DIV(6) /*!< CK_OUT0 is divided by 4 */ +#define RCU_CKOUT0_DIV5 CFG0_CKOUT0DIV(7) /*!< CK_OUT0 is divided by 5 */ + +/* The CK_OUT1 divider */ +#define CFG0_CKOUT1DIV(regval) (BITS(27,29) & ((uint32_t)(regval) << 27)) +#define RCU_CKOUT1_DIV1 CFG0_CKOUT1DIV(0) /*!< CK_OUT1 is divided by 1 */ +#define RCU_CKOUT1_DIV2 CFG0_CKOUT1DIV(4) /*!< CK_OUT1 is divided by 2 */ +#define RCU_CKOUT1_DIV3 CFG0_CKOUT1DIV(5) /*!< CK_OUT1 is divided by 3 */ +#define RCU_CKOUT1_DIV4 CFG0_CKOUT1DIV(6) /*!< CK_OUT1 is divided by 4 */ +#define RCU_CKOUT1_DIV5 CFG0_CKOUT1DIV(7) /*!< CK_OUT1 is divided by 5 */ + +/* CKOUT1 Clock source selection */ +#define CFG0_CKOUT1SEL(regval) (BITS(30,31) & ((uint32_t)(regval) << 30)) +#define RCU_CKOUT1SRC_SYSTEMCLOCK CFG0_CKOUT1SEL(0) /*!< system clock selected */ +#define RCU_CKOUT1SRC_PLLI2SR CFG0_CKOUT1SEL(1) /*!< low speed crystal oscillator clock (LXTAL) selected */ +#define RCU_CKOUT1SRC_HXTAL CFG0_CKOUT1SEL(2) /*!< high speed crystal oscillator clock (HXTAL) selected */ +#define RCU_CKOUT1SRC_PLLP CFG0_CKOUT1SEL(3) /*!< CK_PLLP clock selected */ + +/* RCU_CFG1 register bit define */ +/* the divider factor from PLLI2SQ clock */ +#define CFG1_PLLI2SQDIV(regval) (BITS(0,4) & ((uint32_t)(regval) << 0)) +#define RCU_PLLI2SQ_DIV1 CFG1_PLLI2SQDIV(0) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/1 */ +#define RCU_PLLI2SQ_DIV2 CFG1_PLLI2SQDIV(1) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/2 */ +#define RCU_PLLI2SQ_DIV3 CFG1_PLLI2SQDIV(2) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/3 */ +#define RCU_PLLI2SQ_DIV4 CFG1_PLLI2SQDIV(3) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/4 */ +#define RCU_PLLI2SQ_DIV5 CFG1_PLLI2SQDIV(4) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/5 */ +#define RCU_PLLI2SQ_DIV6 CFG1_PLLI2SQDIV(5) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/6 */ +#define RCU_PLLI2SQ_DIV7 CFG1_PLLI2SQDIV(6) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/7 */ +#define RCU_PLLI2SQ_DIV8 CFG1_PLLI2SQDIV(7) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/8 */ +#define RCU_PLLI2SQ_DIV9 CFG1_PLLI2SQDIV(8) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/9 */ +#define RCU_PLLI2SQ_DIV10 CFG1_PLLI2SQDIV(9) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/10 */ +#define RCU_PLLI2SQ_DIV11 CFG1_PLLI2SQDIV(10) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/11 */ +#define RCU_PLLI2SQ_DIV12 CFG1_PLLI2SQDIV(11) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/12 */ +#define RCU_PLLI2SQ_DIV13 CFG1_PLLI2SQDIV(12) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/13 */ +#define RCU_PLLI2SQ_DIV14 CFG1_PLLI2SQDIV(13) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/14 */ +#define RCU_PLLI2SQ_DIV15 CFG1_PLLI2SQDIV(14) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/15 */ +#define RCU_PLLI2SQ_DIV16 CFG1_PLLI2SQDIV(15) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/16 */ +#define RCU_PLLI2SQ_DIV17 CFG1_PLLI2SQDIV(16) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/17 */ +#define RCU_PLLI2SQ_DIV18 CFG1_PLLI2SQDIV(17) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/18 */ +#define RCU_PLLI2SQ_DIV19 CFG1_PLLI2SQDIV(18) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/19 */ +#define RCU_PLLI2SQ_DIV20 CFG1_PLLI2SQDIV(19) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/20 */ +#define RCU_PLLI2SQ_DIV21 CFG1_PLLI2SQDIV(20) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/21 */ +#define RCU_PLLI2SQ_DIV22 CFG1_PLLI2SQDIV(21) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/22 */ +#define RCU_PLLI2SQ_DIV23 CFG1_PLLI2SQDIV(22) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/23 */ +#define RCU_PLLI2SQ_DIV24 CFG1_PLLI2SQDIV(23) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/24 */ +#define RCU_PLLI2SQ_DIV25 CFG1_PLLI2SQDIV(24) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/25 */ +#define RCU_PLLI2SQ_DIV26 CFG1_PLLI2SQDIV(25) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/26 */ +#define RCU_PLLI2SQ_DIV27 CFG1_PLLI2SQDIV(26) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/27 */ +#define RCU_PLLI2SQ_DIV28 CFG1_PLLI2SQDIV(27) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/28 */ +#define RCU_PLLI2SQ_DIV29 CFG1_PLLI2SQDIV(28) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/29 */ +#define RCU_PLLI2SQ_DIV30 CFG1_PLLI2SQDIV(29) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/30 */ +#define RCU_PLLI2SQ_DIV31 CFG1_PLLI2SQDIV(30) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/31 */ +#define RCU_PLLI2SQ_DIV32 CFG1_PLLI2SQDIV(31) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/32 */ + +/* the divider factor from PLLSAIR clock */ +#define CFG1_PLLSAIRDIV(regval) (BITS(16,17) & ((uint32_t)(regval) << 16)) +#define RCU_PLLSAIR_DIV2 CFG1_PLLSAIRDIV(0) /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/2 */ +#define RCU_PLLSAIR_DIV4 CFG1_PLLSAIRDIV(1) /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/4 */ +#define RCU_PLLSAIR_DIV8 CFG1_PLLSAIRDIV(2) /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/8 */ +#define RCU_PLLSAIR_DIV16 CFG1_PLLSAIRDIV(3) /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/16 */ + +/* TIMER clock selection */ +#define RCU_TIMER_PSC_MUL2 ~RCU_CFG1_TIMERSEL /*!< if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB) + or 0b100(CK_APBx = CK_AHB/2), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). + or else, the TIMER clock is twice the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 2 x CK_APB1; + TIMER in APB2 domain: CK_TIMERx = 2 x CK_APB2) */ +#define RCU_TIMER_PSC_MUL4 RCU_CFG1_TIMERSEL /*!< if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB), + 0b100(CK_APBx = CK_AHB/2), or 0b101(CK_APBx = CK_AHB/4), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). + or else, the TIMER clock is four timers the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 4 x CK_APB1; + TIMER in APB2 domain: CK_TIMERx = 4 x CK_APB2) */ + +/* RCU_PLLSSCTL register bit define */ +/* PLL spread spectrum modulation type select */ +#define RCU_SS_TYPE_CENTER ((uint32_t)0x00000000U) /*!< center type is selected */ +#define RCU_SS_TYPE_DOWN RCU_PLLSSCTL_SS_TYPE /*!< down type is selected */ + +/* RCU_PLL register bit define */ +/* The PLL VCO source clock prescaler */ +#define RCU_PLLPSC_DIV_MIN ((uint32_t)2U) /*!< PLLPSC_DIV min value */ +#define RCU_PLLPSC_DIV_MAX ((uint32_t)63U) /*!< PLLPSC_DIV max value */ + +/* The PLL VCO clock multi factor */ +#define RCU_PLLN_MUL_MIN ((uint32_t)64U) /*!< PLLN_MUL min value */ +#define RCU_PLLN_MUL_MAX ((uint32_t)500U) /*!< PLLN_MUL max value */ +#define RCU_SS_MODULATION_CENTER_INC ((uint32_t)5U) /*!< minimum factor of PLLN in center mode */ +#define RCU_SS_MODULATION_DOWN_INC ((uint32_t)7U) /*!< minimum factor of PLLN in down mode */ + +/* The PLLP output frequency division factor from PLL VCO clock */ +#define RCU_PLLP_DIV_MIN ((uint32_t)2U) /*!< PLLP_DIV min value */ +#define RCU_PLLP_DIV_MAX ((uint32_t)8U) /*!< PLLP_DIV max value */ + +/* PLL Clock Source Selection */ +#define RCU_PLLSRC_IRC16M ((uint32_t)0x00000000U) /*!< IRC16M clock selected as source clock of PLL, PLLSAI, PLLI2S */ +#define RCU_PLLSRC_HXTAL RCU_PLL_PLLSEL /*!< HXTAL clock selected as source clock of PLL, PLLSAI, PLLI2S */ + +/* The PLL Q output frequency division factor from PLL VCO clock */ +#define RCU_PLLQ_DIV_MIN ((uint32_t)2U) /*!< PLLQ_DIV min value */ +#define RCU_PLLQ_DIV_MAX ((uint32_t)15U) /*!< PLLQ_DIV max value */ + +#define CHECK_PLL_PSC_VALID(val) (((val) >= RCU_PLLPSC_DIV_MIN)&&((val) <= RCU_PLLPSC_DIV_MAX)) +#define CHECK_PLL_N_VALID(val, inc) (((val) >= (RCU_PLLN_MUL_MIN + (inc)))&&((val) <= RCU_PLLN_MUL_MAX)) +#define CHECK_PLL_P_VALID(val) (((val) == 2U) || ((val) == 4U) || ((val) == 6U) || ((val) == 8U)) +#define CHECK_PLL_Q_VALID(val) (((val) >= RCU_PLLQ_DIV_MIN)&&((val) <= RCU_PLLQ_DIV_MAX)) + +/* RCU_BDCTL register bit define */ +/* LXTAL drive capability */ +#define RCU_LXTALDRI_LOWER_DRIVE ((uint32_t)0x00000000) /*!< LXTAL drive capability is selected lower */ +#define RCU_LXTALDRI_HIGHER_DRIVE RCU_BDCTL_LXTALDRI /*!< LXTAL drive capability is selected higher */ + +/* RTC clock entry selection */ +#define BDCTL_RTCSRC(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define RCU_RTCSRC_NONE BDCTL_RTCSRC(0) /*!< no clock selected */ +#define RCU_RTCSRC_LXTAL BDCTL_RTCSRC(1) /*!< RTC source clock select LXTAL */ +#define RCU_RTCSRC_IRC32K BDCTL_RTCSRC(2) /*!< RTC source clock select IRC32K */ +#define RCU_RTCSRC_HXTAL_DIV_RTCDIV BDCTL_RTCSRC(3) /*!< RTC source clock select HXTAL/RTCDIV */ + +/* RCU_PLLI2S register bit define */ +/* The PLLI2S VCO clock multi factor */ +#define RCU_PLLI2SN_MUL_MIN 50U +#define RCU_PLLI2SN_MUL_MAX 500U + +/* The PLLI2S Q output frequency division factor from PLLI2S VCO clock */ +#define RCU_PLLI2SQ_DIV_MIN 2U +#define RCU_PLLI2SQ_DIV_MAX 15U + +/* The PLLI2S R output frequency division factor from PLLI2S VCO clock */ +#define RCU_PLLI2SR_DIV_MIN 2U +#define RCU_PLLI2SR_DIV_MAX 7U + +/* RCU_PLLSAI register bit define */ +/* The PLLSAI VCO clock multi factor */ +#define RCU_PLLSAIN_MUL_MIN 50U +#define RCU_PLLSAIN_MUL_MAX 500U + +/* The PLLSAI P output frequency division factor from PLLSAI VCO clock */ +#define RCU_PLLSAIP_DIV_MIN 2U +#define RCU_PLLSAIP_DIV_MAX 8U + +/* The PLLSAI Q output frequency division factor from PLLSAI VCO clock */ +#define RCU_PLLSAIQ_DIV_MIN 2U +#define RCU_PLLSAIQ_DIV_MAX 15U + +/* The PLLSAI R output frequency division factor from PLLSAI VCO clock */ +#define RCU_PLLSAIR_DIV_MIN 2U +#define RCU_PLLSAIR_DIV_MAX 7U + +#define CHECK_PLLI2S_PSC_VALID(val) (((val) >= RCU_PLLI2SPSC_DIV_MIN)&&((val) <= RCU_PLLI2SPSC_DIV_MAX)) +#define CHECK_PLLI2S_N_VALID(val) (((val) >= RCU_PLLI2SN_MUL_MIN)&&((val) <= RCU_PLLI2SN_MUL_MAX)) +#define CHECK_PLLI2S_Q_VALID(val) (((val) >= RCU_PLLI2SQ_DIV_MIN)&&((val) <= RCU_PLLI2SQ_DIV_MAX)) +#define CHECK_PLLI2S_R_VALID(val) (((val) >= RCU_PLLI2SR_DIV_MIN)&&((val) <= RCU_PLLI2SR_DIV_MAX)) + +#define CHECK_PLLSAI_N_VALID(val) (((val) >= (RCU_PLLSAIN_MUL_MIN))&&((val) <= RCU_PLLSAIN_MUL_MAX)) +#define CHECK_PLLSAI_P_VALID(val) (((val) == 2U) || ((val) == 4U) || ((val) == 6U) || ((val) == 8U)) +#define CHECK_PLLSAI_Q_VALID(val) (((val) >= RCU_PLLSAIQ_DIV_MIN)&&((val) <= RCU_PLLSAIQ_DIV_MAX)) +#define CHECK_PLLSAI_R_VALID(val) (((val) >= RCU_PLLSAIR_DIV_MIN)&&((val) <= RCU_PLLSAIR_DIV_MAX)) + +/* RCU_ADDCTL register bit define */ +/* 48MHz clock selection */ +#define RCU_CK48MSRC_PLL48M ((uint32_t)0x00000000U) /*!< CK48M source clock select PLL48M */ +#define RCU_CK48MSRC_IRC48M RCU_ADDCTL_CK48MSEL /*!< CK48M source clock select IRC48M */ + +/* PLL48M clock selection */ +#define RCU_PLL48MSRC_PLLQ ((uint32_t)0x00000000U) /*!< PLL48M source clock select PLLQ */ +#define RCU_PLL48MSRC_PLLSAIP RCU_ADDCTL_PLL48MSEL /*!< PLL48M source clock select PLLSAIP */ + +/* Deep-sleep mode voltage */ +#define DSV_DSLPVS(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define RCU_DEEPSLEEP_V_1_2 DSV_DSLPVS(0) /*!< core voltage is 1.2V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_1 DSV_DSLPVS(1) /*!< core voltage is 1.1V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_0 DSV_DSLPVS(2) /*!< core voltage is 1.0V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0_9 DSV_DSLPVS(3) /*!< core voltage is 0.9V in deep-sleep mode */ + + +/* function declarations */ +/* deinitialize the RCU */ +void rcu_deinit(void); +/* enable the peripherals clock */ +void rcu_periph_clock_enable(rcu_periph_enum periph); +/* disable the peripherals clock */ +void rcu_periph_clock_disable(rcu_periph_enum periph); +/* enable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph); +/* disable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph); +/* reset the peripherals */ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset); +/* disable reset the peripheral */ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset); +/* reset the BKP */ +void rcu_bkp_reset_enable(void); +/* disable the BKP reset */ +void rcu_bkp_reset_disable(void); + +/* configure the system clock source */ +void rcu_system_clock_source_config(uint32_t ck_sys); +/* get the system clock source */ +uint32_t rcu_system_clock_source_get(void); +/* configure the AHB prescaler selection */ +void rcu_ahb_clock_config(uint32_t ck_ahb); +/* configure the APB1 prescaler selection */ +void rcu_apb1_clock_config(uint32_t ck_apb1); +/* configure the APB2 prescaler selection */ +void rcu_apb2_clock_config(uint32_t ck_apb2); +/* configure the CK_OUT0 clock source and divider */ +void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div); +/* configure the CK_OUT1 clock source and divider */ +void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div); +/* configure the PLL clock source selection and PLL multiply factor */ +ErrStatus rcu_pll_config(uint32_t pll_src, uint32_t pll_psc, uint32_t pll_n, uint32_t pll_p, uint32_t pll_q); +/* configure the PLLI2S clock */ +ErrStatus rcu_plli2s_config(uint32_t plli2s_n, uint32_t plli2s_q, uint32_t plli2s_r); +/* configure the PLLSAI clock */ +ErrStatus rcu_pllsai_config(uint32_t pllsai_n, uint32_t pllsai_p, uint32_t pllsai_q, uint32_t pllsai_r); +/* configure the RTC clock source selection */ +void rcu_rtc_clock_config(uint32_t rtc_clock_source); +/* configure the I2S clock source selection */ +void rcu_i2s_clock_config(uint32_t i2s_clock_source); +/* configure the CK48M clock selection */ +void rcu_ck48m_clock_config(uint32_t ck48m_clock_source); +/* configure the PLL48M clock selection */ +void rcu_pll48m_clock_config(uint32_t pll48m_clock_source); +/* configure the TIMER clock prescaler selection */ +void rcu_timer_clock_prescaler_config(uint32_t timer_clock_prescaler); +/* configure the TLI clock division selection */ +void rcu_tli_clock_div_config(uint32_t pllsai_r_div); + + +/* get the clock stabilization and periphral reset flags */ +FlagStatus rcu_flag_get(rcu_flag_enum flag); +/* clear the reset flag */ +void rcu_all_reset_flag_clear(void); +/* get the clock stabilization interrupt and ckm flags */ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag); +/* clear the interrupt flags */ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_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); + +/* configure the LXTAL drive capability */ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap); +/* wait for oscillator stabilization flags is SET or oscillator startup is timeout */ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci); +/* turn on the oscillator */ +void rcu_osci_on(rcu_osci_type_enum osci); +/* turn off the oscillator */ +void rcu_osci_off(rcu_osci_type_enum osci); +/* enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci); +/* disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci); +/* enable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_enable(void); +/* disable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_disable(void); + +/* set the IRC16M adjust value */ +void rcu_irc16m_adjust_value_set(uint32_t irc16m_adjval); +/* configure the spread spectrum modulation for the main PLL clock */ +void rcu_spread_spectrum_config(uint32_t spread_spectrum_type, uint32_t modstep, uint32_t modcnt); +/* enable the spread spectrum modulation for the main PLL clock */ +void rcu_spread_spectrum_enable(void); +/* disable the spread spectrum modulation for the main PLL clock */ +void rcu_spread_spectrum_disable(void); +/* unlock the voltage key */ +void rcu_voltage_key_unlock(void); +/* set the deep sleep mode voltage */ +void rcu_deepsleep_voltage_set(uint32_t dsvol); + +/* get the system clock, bus and peripheral clock frequency */ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock); + +#endif /* GD32F4XX_RCU_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h new file mode 100644 index 0000000000..27155a3076 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h @@ -0,0 +1,597 @@ +/*! + \file gd32f4xx_rtc.h + \brief definitions for the RTC +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_RTC_H +#define GD32F4XX_RTC_H + +#include "gd32f4xx.h" + +/* RTC definitions */ +#define RTC RTC_BASE + +/* registers definitions */ +#define RTC_TIME REG32((RTC) + 0x00U) /*!< RTC time of day register */ +#define RTC_DATE REG32((RTC) + 0x04U) /*!< RTC date register */ +#define RTC_CTL REG32((RTC) + 0x08U) /*!< RTC control register */ +#define RTC_STAT REG32((RTC) + 0x0CU) /*!< RTC status register */ +#define RTC_PSC REG32((RTC) + 0x10U) /*!< RTC time prescaler register */ +#define RTC_WUT REG32((RTC) + 0x14U) /*!< RTC wakeup timer regiser */ +#define RTC_COSC REG32((RTC) + 0x18U) /*!< RTC coarse calibration register */ +#define RTC_ALRM0TD REG32((RTC) + 0x1CU) /*!< RTC alarm 0 time and date register */ +#define RTC_ALRM1TD REG32((RTC) + 0x20U) /*!< RTC alarm 1 time and date register */ +#define RTC_WPK REG32((RTC) + 0x24U) /*!< RTC write protection key register */ +#define RTC_SS REG32((RTC) + 0x28U) /*!< RTC sub second register */ +#define RTC_SHIFTCTL REG32((RTC) + 0x2CU) /*!< RTC shift function control register */ +#define RTC_TTS REG32((RTC) + 0x30U) /*!< RTC time of timestamp register */ +#define RTC_DTS REG32((RTC) + 0x34U) /*!< RTC date of timestamp register */ +#define RTC_SSTS REG32((RTC) + 0x38U) /*!< RTC sub second of timestamp register */ +#define RTC_HRFC REG32((RTC) + 0x3CU) /*!< RTC high resolution frequency compensation registor */ +#define RTC_TAMP REG32((RTC) + 0x40U) /*!< RTC tamper register */ +#define RTC_ALRM0SS REG32((RTC) + 0x44U) /*!< RTC alarm 0 sub second register */ +#define RTC_ALRM1SS REG32((RTC) + 0x48U) /*!< RTC alarm 1 sub second register */ +#define RTC_BKP0 REG32((RTC) + 0x50U) /*!< RTC backup register */ +#define RTC_BKP1 REG32((RTC) + 0x54U) /*!< RTC backup register */ +#define RTC_BKP2 REG32((RTC) + 0x58U) /*!< RTC backup register */ +#define RTC_BKP3 REG32((RTC) + 0x5CU) /*!< RTC backup register */ +#define RTC_BKP4 REG32((RTC) + 0x60U) /*!< RTC backup register */ +#define RTC_BKP5 REG32((RTC) + 0x64U) /*!< RTC backup register */ +#define RTC_BKP6 REG32((RTC) + 0x68U) /*!< RTC backup register */ +#define RTC_BKP7 REG32((RTC) + 0x6CU) /*!< RTC backup register */ +#define RTC_BKP8 REG32((RTC) + 0x70U) /*!< RTC backup register */ +#define RTC_BKP9 REG32((RTC) + 0x74U) /*!< RTC backup register */ +#define RTC_BKP10 REG32((RTC) + 0x78U) /*!< RTC backup register */ +#define RTC_BKP11 REG32((RTC) + 0x7CU) /*!< RTC backup register */ +#define RTC_BKP12 REG32((RTC) + 0x80U) /*!< RTC backup register */ +#define RTC_BKP13 REG32((RTC) + 0x84U) /*!< RTC backup register */ +#define RTC_BKP14 REG32((RTC) + 0x88U) /*!< RTC backup register */ +#define RTC_BKP15 REG32((RTC) + 0x8CU) /*!< RTC backup register */ +#define RTC_BKP16 REG32((RTC) + 0x90U) /*!< RTC backup register */ +#define RTC_BKP17 REG32((RTC) + 0x94U) /*!< RTC backup register */ +#define RTC_BKP18 REG32((RTC) + 0x98U) /*!< RTC backup register */ +#define RTC_BKP19 REG32((RTC) + 0x9CU) /*!< RTC backup register */ + +/* bits definitions */ +/* RTC_TIME */ +#define RTC_TIME_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TIME_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_TIME_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TIME_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TIME_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TIME_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TIME_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DATE */ +#define RTC_DATE_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DATE_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DATE_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DATE_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DATE_DOW BITS(13,15) /*!< day of week units */ +#define RTC_DATE_YRU BITS(16,19) /*!< year units in BCD code */ +#define RTC_DATE_YRT BITS(20,23) /*!< year tens in BCD code */ + +/* RTC_CTL */ +#define RTC_CTL_WTCS BITS(0,2) /*!< auto wakeup timer clock selection */ +#define RTC_CTL_TSEG BIT(3) /*!< valid event edge of time-stamp */ +#define RTC_CTL_REFEN BIT(4) /*!< reference clock detection function enable */ +#define RTC_CTL_BPSHAD BIT(5) /*!< shadow registers bypass control */ +#define RTC_CTL_CS BIT(6) /*!< display format of clock system */ +#define RTC_CTL_CCEN BIT(7) /*!< coarse calibration function enable */ +#define RTC_CTL_ALRM0EN BIT(8) /*!< alarm0 function enable */ +#define RTC_CTL_ALRM1EN BIT(9) /*!< alarm1 function enable */ +#define RTC_CTL_WTEN BIT(10) /*!< auto wakeup timer function enable */ +#define RTC_CTL_TSEN BIT(11) /*!< time-stamp function enable */ +#define RTC_CTL_ALRM0IE BIT(12) /*!< RTC alarm0 interrupt enable */ +#define RTC_CTL_ALRM1IE BIT(13) /*!< RTC alarm1 interrupt enable */ +#define RTC_CTL_WTIE BIT(14) /*!< auto wakeup timer interrupt enable */ +#define RTC_CTL_TSIE BIT(15) /*!< time-stamp interrupt enable */ +#define RTC_CTL_A1H BIT(16) /*!< add 1 hour(summer time change) */ +#define RTC_CTL_S1H BIT(17) /*!< subtract 1 hour(winter time change) */ +#define RTC_CTL_DSM BIT(18) /*!< daylight saving mark */ +#define RTC_CTL_COS BIT(19) /*!< calibration output selection */ +#define RTC_CTL_OPOL BIT(20) /*!< output polarity */ +#define RTC_CTL_OS BITS(21,22) /*!< output selection */ +#define RTC_CTL_COEN BIT(23) /*!< calibration output enable */ + +/* RTC_STAT */ +#define RTC_STAT_ALRM0WF BIT(0) /*!< alarm0 configuration can be write flag */ +#define RTC_STAT_ALRM1WF BIT(1) /*!< alarm1 configuration can be write flag */ +#define RTC_STAT_WTWF BIT(2) /*!< wakeup timer can be write flag */ +#define RTC_STAT_SOPF BIT(3) /*!< shift function operation pending flag */ +#define RTC_STAT_YCM BIT(4) /*!< year configuration mark status flag */ +#define RTC_STAT_RSYNF BIT(5) /*!< register synchronization flag */ +#define RTC_STAT_INITF BIT(6) /*!< initialization state flag */ +#define RTC_STAT_INITM BIT(7) /*!< enter initialization mode */ +#define RTC_STAT_ALRM0F BIT(8) /*!< alarm0 occurs flag */ +#define RTC_STAT_ALRM1F BIT(9) /*!< alarm1 occurs flag */ +#define RTC_STAT_WTF BIT(10) /*!< wakeup timer occurs flag */ +#define RTC_STAT_TSF BIT(11) /*!< time-stamp flag */ +#define RTC_STAT_TSOVRF BIT(12) /*!< time-stamp overflow flag */ +#define RTC_STAT_TP0F BIT(13) /*!< RTC tamper 0 detected flag */ +#define RTC_STAT_TP1F BIT(14) /*!< RTC tamper 1 detected flag */ +#define RTC_STAT_SCPF BIT(16) /*!< smooth calibration pending flag */ + +/* RTC_PSC */ +#define RTC_PSC_FACTOR_S BITS(0,14) /*!< synchronous prescaler factor */ +#define RTC_PSC_FACTOR_A BITS(16,22) /*!< asynchronous prescaler factor */ + +/* RTC_WUT */ +#define RTC_WUT_WTRV BITS(0,15) /*!< auto wakeup timer reloads value */ + +/* RTC_COSC */ +#define RTC_COSC_COSS BITS(0,4) /*!< coarse calibration step */ +#define RTC_COSC_COSD BIT(7) /*!< coarse calibration direction */ + +/* RTC_ALRMxTD */ +#define RTC_ALRMXTD_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_ALRMXTD_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_ALRMXTD_MSKS BIT(7) /*!< alarm second mask bit */ +#define RTC_ALRMXTD_MNU BITS(8,11) /*!< minutes units in BCD code */ +#define RTC_ALRMXTD_MNT BITS(12,14) /*!< minutes tens in BCD code */ +#define RTC_ALRMXTD_MSKM BIT(15) /*!< alarm minutes mask bit */ +#define RTC_ALRMXTD_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_ALRMXTD_HRT BITS(20,21) /*!< hour units in BCD code */ +#define RTC_ALRMXTD_PM BIT(22) /*!< AM/PM flag */ +#define RTC_ALRMXTD_MSKH BIT(23) /*!< alarm hour mask bit */ +#define RTC_ALRMXTD_DAYU BITS(24,27) /*!< date units or week day in BCD code */ +#define RTC_ALRMXTD_DAYT BITS(28,29) /*!< date tens in BCD code */ +#define RTC_ALRMXTD_DOWS BIT(30) /*!< day of week selection */ +#define RTC_ALRMXTD_MSKD BIT(31) /*!< alarm date mask bit */ + +/* RTC_WPK */ +#define RTC_WPK_WPK BITS(0,7) /*!< key for write protection */ + +/* RTC_SS */ +#define RTC_SS_SSC BITS(0,15) /*!< sub second value */ + +/* RTC_SHIFTCTL */ +#define RTC_SHIFTCTL_SFS BITS(0,14) /*!< subtract a fraction of a second */ +#define RTC_SHIFTCTL_A1S BIT(31) /*!< one second add */ + +/* RTC_TTS */ +#define RTC_TTS_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TTS_SCT BITS(4,6) /*!< second units in BCD code */ +#define RTC_TTS_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TTS_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TTS_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TTS_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TTS_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DTS */ +#define RTC_DTS_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DTS_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DTS_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DTS_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DTS_DOW BITS(13,15) /*!< day of week units */ + +/* RTC_SSTS */ +#define RTC_SSTS_SSC BITS(0,15) /*!< timestamp sub second units */ + +/* RTC_HRFC */ +#define RTC_HRFC_CMSK BITS(0,8) /*!< calibration mask number */ +#define RTC_HRFC_CWND16 BIT(13) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_CWND8 BIT(14) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_FREQI BIT(15) /*!< increase RTC frequency by 488.5ppm */ + +/* RTC_TAMP */ +#define RTC_TAMP_TP0EN BIT(0) /*!< tamper 0 detection enable */ +#define RTC_TAMP_TP0EG BIT(1) /*!< tamper 0 event trigger edge for RTC tamp 0 input */ +#define RTC_TAMP_TPIE BIT(2) /*!< tamper detection interrupt enable */ +#define RTC_TAMP_TP1EN BIT(3) /*!< tamper 1 detection enable */ +#define RTC_TAMP_TP1EG BIT(4) /*!< Tamper 1 event trigger edge for RTC tamp 1 input */ +#define RTC_TAMP_TPTS BIT(7) /*!< make tamper function used for timestamp function */ +#define RTC_TAMP_FREQ BITS(8,10) /*!< sample frequency of tamper event detection */ +#define RTC_TAMP_FLT BITS(11,12) /*!< RTC tamp x filter count setting */ +#define RTC_TAMP_PRCH BITS(13,14) /*!< precharge duration time of RTC tamp x */ +#define RTC_TAMP_DISPU BIT(15) /*!< RTC tamp x pull up disable bit */ +#define RTC_TAMP_TP0SEL BIT(16) /*!< Tamper 0 function input mapping selection */ +#define RTC_TAMP_TSSEL BIT(17) /*!< Timestamp input mapping selection */ +#define RTC_TAMP_AOT BIT(18) /*!< RTC_ALARM output Type */ + +/* RTC_ALRM0SS */ +#define RTC_ALRM0SS_SSC BITS(0,14) /*!< alarm0 sub second value */ +#define RTC_ALRM0SS_MASKSSC BITS(24,27) /*!< mask control bit of SS */ + +/* RTC_ALRM1SS */ +#define RTC_ALRM1SS_SSC BITS(0,14) /*!< alarm1 sub second value */ +#define RTC_ALRM1SS_MASKSSC BITS(24,27) /*!< mask control bit of SS */ + +/* constants definitions */ +/* structure for initialization of the RTC */ +typedef struct +{ + uint8_t year; /*!< RTC year value: 0x0 - 0x99(BCD format) */ + uint8_t month; /*!< RTC month value */ + uint8_t date; /*!< RTC date value: 0x1 - 0x31(BCD format) */ + uint8_t day_of_week; /*!< RTC weekday value */ + uint8_t hour; /*!< RTC hour value */ + uint8_t minute; /*!< RTC minute value: 0x0 - 0x59(BCD format) */ + uint8_t second; /*!< RTC second value: 0x0 - 0x59(BCD format) */ + uint16_t factor_asyn; /*!< RTC asynchronous prescaler value: 0x0 - 0x7F */ + uint16_t factor_syn; /*!< RTC synchronous prescaler value: 0x0 - 0x7FFF */ + uint32_t am_pm; /*!< RTC AM/PM value */ + uint32_t display_format; /*!< RTC time notation */ +}rtc_parameter_struct; + +/* structure for RTC alarm configuration */ +typedef struct +{ + uint32_t alarm_mask; /*!< RTC alarm mask */ + uint32_t weekday_or_date; /*!< specify RTC alarm is on date or weekday */ + uint8_t alarm_day; /*!< RTC alarm date or weekday value*/ + uint8_t alarm_hour; /*!< RTC alarm hour value */ + uint8_t alarm_minute; /*!< RTC alarm minute value: 0x0 - 0x59(BCD format) */ + uint8_t alarm_second; /*!< RTC alarm second value: 0x0 - 0x59(BCD format) */ + uint32_t am_pm; /*!< RTC alarm AM/PM value */ +}rtc_alarm_struct; + +/* structure for RTC time-stamp configuration */ +typedef struct +{ + uint8_t timestamp_month; /*!< RTC time-stamp month value */ + uint8_t timestamp_date; /*!< RTC time-stamp date value: 0x1 - 0x31(BCD format) */ + uint8_t timestamp_day; /*!< RTC time-stamp weekday value */ + uint8_t timestamp_hour; /*!< RTC time-stamp hour value */ + uint8_t timestamp_minute; /*!< RTC time-stamp minute value: 0x0 - 0x59(BCD format) */ + uint8_t timestamp_second; /*!< RTC time-stamp second value: 0x0 - 0x59(BCD format) */ + uint32_t am_pm; /*!< RTC time-stamp AM/PM value */ +}rtc_timestamp_struct; + +/* structure for RTC tamper configuration */ +typedef struct +{ + uint32_t tamper_source; /*!< RTC tamper source */ + uint32_t tamper_trigger; /*!< RTC tamper trigger */ + uint32_t tamper_filter; /*!< RTC tamper consecutive samples needed during a voltage level detection */ + uint32_t tamper_sample_frequency; /*!< RTC tamper sampling frequency during a voltage level detection */ + ControlStatus tamper_precharge_enable; /*!< RTC tamper precharge feature during a voltage level detection */ + uint32_t tamper_precharge_time; /*!< RTC tamper precharge duration if precharge feature is enabled */ + ControlStatus tamper_with_timestamp; /*!< RTC tamper time-stamp feature */ +}rtc_tamper_struct; + +/* time register value */ +#define TIME_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_TIME_SC bit field */ +#define GET_TIME_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TIME_SC bit field */ + +#define TIME_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_TIME_MN bit field */ +#define GET_TIME_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TIME_MN bit field */ + +#define TIME_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_TIME_HR bit field */ +#define GET_TIME_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TIME_HR bit field */ + +#define RTC_AM ((uint32_t)0x00000000U) /*!< AM format */ +#define RTC_PM RTC_TIME_PM /*!< PM format */ + +/* date register value */ +#define DATE_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_DATE_DAY bit field */ +#define GET_DATE_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DATE_DAY bit field */ + +#define DATE_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_DATE_MON bit field */ +#define GET_DATE_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DATE_MON bit field */ +#define RTC_JAN ((uint8_t)0x01U) /*!< janurary */ +#define RTC_FEB ((uint8_t)0x02U) /*!< february */ +#define RTC_MAR ((uint8_t)0x03U) /*!< march */ +#define RTC_APR ((uint8_t)0x04U) /*!< april */ +#define RTC_MAY ((uint8_t)0x05U) /*!< may */ +#define RTC_JUN ((uint8_t)0x06U) /*!< june */ +#define RTC_JUL ((uint8_t)0x07U) /*!< july */ +#define RTC_AUG ((uint8_t)0x08U) /*!< august */ +#define RTC_SEP ((uint8_t)0x09U) /*!< september */ +#define RTC_OCT ((uint8_t)0x10U) /*!< october */ +#define RTC_NOV ((uint8_t)0x11U) /*!< november */ +#define RTC_DEC ((uint8_t)0x12U) /*!< december */ + +#define DATE_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< write value to RTC_DATE_DOW bit field */ +#define GET_DATE_DOW(regval) GET_BITS((uint32_t)(regval),13,15) /*!< get value of RTC_DATE_DOW bit field */ +#define RTC_MONDAY ((uint8_t)0x01) /*!< monday */ +#define RTC_TUESDAY ((uint8_t)0x02) /*!< tuesday */ +#define RTC_WEDSDAY ((uint8_t)0x03) /*!< wednesday */ +#define RTC_THURSDAY ((uint8_t)0x04) /*!< thursday */ +#define RTC_FRIDAY ((uint8_t)0x05) /*!< friday */ +#define RTC_SATURDAY ((uint8_t)0x06) /*!< saturday */ +#define RTC_SUNDAY ((uint8_t)0x07) /*!< sunday */ + +#define DATE_YR(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_DATE_YR bit field */ +#define GET_DATE_YR(regval) GET_BITS((regval),16,23) /*!< get value of RTC_DATE_YR bit field */ + +/* ctl register value */ +#define CTL_OS(regval) (BITS(21,22) & ((uint32_t)(regval) << 21)) /*!< write value to RTC_CTL_OS bit field */ +#define RTC_OS_DISABLE CTL_OS(0) /*!< disable output RTC_ALARM */ +#define RTC_OS_ALARM0 CTL_OS(1) /*!< enable alarm0 flag output */ +#define RTC_OS_ALARM1 CTL_OS(2) /*!< enable alarm1 flag output */ +#define RTC_OS_WAKEUP CTL_OS(3) /*!< enable wakeup flag output */ + +#define RTC_CALIBRATION_512HZ RTC_CTL_COEN /*!< calibration output of 512Hz is enable */ +#define RTC_CALIBRATION_1HZ (RTC_CTL_COEN | RTC_CTL_COS) /*!< calibration output of 1Hz is enable */ +#define RTC_ALARM0_HIGH RTC_OS_ALARM0 /*!< enable alarm0 flag output with high level */ +#define RTC_ALARM0_LOW (RTC_OS_ALARM0 | RTC_CTL_OPOL) /*!< enable alarm0 flag output with low level*/ +#define RTC_ALARM1_HIGH RTC_OS_ALARM1 /*!< enable alarm1 flag output with high level */ +#define RTC_ALARM1_LOW (RTC_OS_ALARM1 | RTC_CTL_OPOL) /*!< enable alarm1 flag output with low level*/ +#define RTC_WAKEUP_HIGH RTC_OS_WAKEUP /*!< enable wakeup flag output with high level */ +#define RTC_WAKEUP_LOW (RTC_OS_WAKEUP | RTC_CTL_OPOL) /*!< enable wakeup flag output with low level*/ + +#define RTC_24HOUR ((uint32_t)0x00000000U) /*!< 24-hour format */ +#define RTC_12HOUR RTC_CTL_CS /*!< 12-hour format */ + +#define RTC_TIMESTAMP_RISING_EDGE ((uint32_t)0x00000000U) /*!< rising edge is valid event edge for time-stamp event */ +#define RTC_TIMESTAMP_FALLING_EDGE RTC_CTL_TSEG /*!< falling edge is valid event edge for time-stamp event */ + +/* psc register value */ +#define PSC_FACTOR_S(regval) (BITS(0,14) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_PSC_FACTOR_S bit field */ +#define GET_PSC_FACTOR_S(regval) GET_BITS((regval),0,14) /*!< get value of RTC_PSC_FACTOR_S bit field */ + +#define PSC_FACTOR_A(regval) (BITS(16,22) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_PSC_FACTOR_A bit field */ +#define GET_PSC_FACTOR_A(regval) GET_BITS((regval),16,22) /*!< get value of RTC_PSC_FACTOR_A bit field */ + +/* alrmtd register value */ +#define ALRMTD_SC(regval) (BITS(0,6) & ((uint32_t)(regval)<< 0)) /*!< write value to RTC_ALRMTD_SC bit field */ +#define GET_ALRMTD_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_ALRMTD_SC bit field */ + +#define ALRMTD_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_ALRMTD_MN bit field */ +#define GET_ALRMTD_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_ALRMTD_MN bit field */ + +#define ALRMTD_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_ALRMTD_HR bit field */ +#define GET_ALRMTD_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_ALRMTD_HR bit field */ + +#define ALRMTD_DAY(regval) (BITS(24,29) & ((uint32_t)(regval) << 24)) /*!< write value to RTC_ALRMTD_DAY bit field */ +#define GET_ALRMTD_DAY(regval) GET_BITS((regval),24,29) /*!< get value of RTC_ALRMTD_DAY bit field */ + +#define RTC_ALARM_NONE_MASK ((uint32_t)0x00000000U) /*!< alarm none mask */ +#define RTC_ALARM_DATE_MASK RTC_ALRMXTD_MSKD /*!< alarm date mask */ +#define RTC_ALARM_HOUR_MASK RTC_ALRMXTD_MSKH /*!< alarm hour mask */ +#define RTC_ALARM_MINUTE_MASK RTC_ALRMXTD_MSKM /*!< alarm minute mask */ +#define RTC_ALARM_SECOND_MASK RTC_ALRMXTD_MSKS /*!< alarm second mask */ +#define RTC_ALARM_ALL_MASK (RTC_ALRMXTD_MSKD|RTC_ALRMXTD_MSKH|RTC_ALRMXTD_MSKM|RTC_ALRMXTD_MSKS) /*!< alarm all mask */ + +#define RTC_ALARM_DATE_SELECTED ((uint32_t)0x00000000U) /*!< alarm date format selected */ +#define RTC_ALARM_WEEKDAY_SELECTED RTC_ALRMXTD_DOWS /*!< alarm weekday format selected */ + +/* wpk register value */ +#define WPK_WPK(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_WPK_WPK bit field */ + +/* ss register value */ +#define SS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_SS_SSC bit field */ + +/* shiftctl register value */ +#define SHIFTCTL_SFS(regval) (BITS(0,14) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_SHIFTCTL_SFS bit field */ + +#define RTC_SHIFT_ADD1S_RESET ((uint32_t)0x00000000U) /*!< not add 1 second */ +#define RTC_SHIFT_ADD1S_SET RTC_SHIFTCTL_A1S /*!< add one second to the clock */ + +/* tts register value */ +#define TTS_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_TTS_SC bit field */ +#define GET_TTS_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TTS_SC bit field */ + +#define TTS_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_TTS_MN bit field */ +#define GET_TTS_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TTS_MN bit field */ + +#define TTS_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_TTS_HR bit field */ +#define GET_TTS_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TTS_HR bit field */ + +/* dts register value */ +#define DTS_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_DTS_DAY bit field */ +#define GET_DTS_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DTS_DAY bit field */ + +#define DTS_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_DTS_MON bit field */ +#define GET_DTS_MON(regval) GET_BITS((regval),8,11) /*!< get value of RTC_DTS_MON bit field */ + +#define DTS_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< write value to RTC_DTS_DOW bit field */ +#define GET_DTS_DOW(regval) GET_BITS((regval),13,15) /*!< get value of RTC_DTS_DOW bit field */ + +/* ssts register value */ +#define SSTS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_SSTS_SSC bit field */ + +/* hrfc register value */ +#define HRFC_CMSK(regval) (BITS(0,8) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_HRFC_CMSK bit field */ + +#define RTC_CALIBRATION_WINDOW_32S ((uint32_t)0x00000000U) /*!< 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_16S RTC_HRFC_CWND16 /*!< 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_8S RTC_HRFC_CWND8 /*!< 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz */ + +#define RTC_CALIBRATION_PLUS_SET RTC_HRFC_FREQI /*!< increase RTC frequency by 488.5ppm */ +#define RTC_CALIBRATION_PLUS_RESET ((uint32_t)0x00000000U) /*!< no effect */ + +/* tamp register value */ +#define TAMP_FREQ(regval) (BITS(8,10) & ((uint32_t)(regval) << 10)) /*!< write value to RTC_TAMP_FREQ bit field */ +#define RTC_FREQ_DIV32768 TAMP_FREQ(0) /*!< sample once every 32768 RTCCLK(1Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV16384 TAMP_FREQ(1) /*!< sample once every 16384 RTCCLK(2Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV8192 TAMP_FREQ(2) /*!< sample once every 8192 RTCCLK(4Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV4096 TAMP_FREQ(3) /*!< sample once every 4096 RTCCLK(8Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV2048 TAMP_FREQ(4) /*!< sample once every 2048 RTCCLK(16Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV1024 TAMP_FREQ(5) /*!< sample once every 1024 RTCCLK(32Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV512 TAMP_FREQ(6) /*!< sample once every 512 RTCCLK(64Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV256 TAMP_FREQ(7) /*!< sample once every 256 RTCCLK(128Hz if RTCCLK=32.768KHz) */ + +#define TAMP_FLT(regval) (BITS(11,12) & ((uint32_t)(regval) << 11)) /*!< write value to RTC_TAMP_FLT bit field */ +#define RTC_FLT_EDGE TAMP_FLT(0) /*!< detecting tamper event using edge mode. precharge duration is disabled automatically */ +#define RTC_FLT_2S TAMP_FLT(1) /*!< detecting tamper event using level mode.2 consecutive valid level samples will make a effective tamper event */ +#define RTC_FLT_4S TAMP_FLT(2) /*!< detecting tamper event using level mode.4 consecutive valid level samples will make an effective tamper event */ +#define RTC_FLT_8S TAMP_FLT(3) /*!< detecting tamper event using level mode.8 consecutive valid level samples will make a effective tamper event */ + +#define TAMP_PRCH(regval) (BITS(13,14) & ((uint32_t)(regval) << 13)) /*!< write value to RTC_TAMP_PRCH bit field */ +#define RTC_PRCH_1C TAMP_PRCH(0) /*!< 1 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_2C TAMP_PRCH(1) /*!< 2 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_4C TAMP_PRCH(2) /*!< 4 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_8C TAMP_PRCH(3) /*!< 8 RTC clock prechagre time before each sampling */ + +#define RTC_TAMPER0 RTC_TAMP_TP0EN /*!< tamper 0 detection enable */ +#define RTC_TAMPER1 RTC_TAMP_TP1EN /*!< tamper 1 detection enable */ + +#define RTC_TAMPER_TRIGGER_EDGE_RISING ((uint32_t)0x00000000U) /*!< tamper detection is in rising edge mode */ +#define RTC_TAMPER_TRIGGER_EDGE_FALLING RTC_TAMP_TP0EG /*!< tamper detection is in falling edge mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_LOW ((uint32_t)0x00000000U) /*!< tamper detection is in low level mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_HIGH RTC_TAMP_TP0EG /*!< tamper detection is in high level mode */ + +#define RTC_TAMPER_TRIGGER_POS ((uint32_t)0x00000001U) /* shift position of trigger relative to source */ + +#define RTC_ALARM_OUTPUT_OD ((uint32_t)0x00000000U) /*!< RTC alarm output open-drain mode */ +#define RTC_ALARM_OUTPUT_PP RTC_TAMP_AOT /*!< RTC alarm output push-pull mode */ + +/* ALRMXSS register value */ +#define ALRMXSS_SSC(regval) (BITS(0,14) & ((uint32_t)(regval)<< 0)) /*!< write value to RTC_ALRMXSS_SSC bit field */ + +#define ALRMXSS_MASKSSC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24)) /*!< write value to RTC_ALRMXSS_MASKSSC bit field */ +#define RTC_MASKSSC_0_14 ALRMXSS_MASKSSC(0) /*!< mask alarm subsecond configuration */ +#define RTC_MASKSSC_1_14 ALRMXSS_MASKSSC(1) /*!< mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared */ +#define RTC_MASKSSC_2_14 ALRMXSS_MASKSSC(2) /*!< mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared */ +#define RTC_MASKSSC_3_14 ALRMXSS_MASKSSC(3) /*!< mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared */ +#define RTC_MASKSSC_4_14 ALRMXSS_MASKSSC(4) /*!< mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared */ +#define RTC_MASKSSC_5_14 ALRMXSS_MASKSSC(5) /*!< mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared */ +#define RTC_MASKSSC_6_14 ALRMXSS_MASKSSC(6) /*!< mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared */ +#define RTC_MASKSSC_7_14 ALRMXSS_MASKSSC(7) /*!< mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared */ +#define RTC_MASKSSC_8_14 ALRMXSS_MASKSSC(8) /*!< mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared */ +#define RTC_MASKSSC_9_14 ALRMXSS_MASKSSC(9) /*!< mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared */ +#define RTC_MASKSSC_10_14 ALRMXSS_MASKSSC(10) /*!< mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared */ +#define RTC_MASKSSC_11_14 ALRMXSS_MASKSSC(11) /*!< mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared */ +#define RTC_MASKSSC_12_14 ALRMXSS_MASKSSC(12) /*!< mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared */ +#define RTC_MASKSSC_13_14 ALRMXSS_MASKSSC(13) /*!< mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared */ +#define RTC_MASKSSC_14 ALRMXSS_MASKSSC(14) /*!< mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared */ +#define RTC_MASKSSC_NONE ALRMXSS_MASKSSC(15) /*!< mask none, and RTC_ALRMXSS_SSC[14:0] is to be compared */ + +/* RTC interrupt source */ +#define RTC_INT_TIMESTAMP RTC_CTL_TSIE /*!< time-stamp interrupt enable */ +#define RTC_INT_ALARM0 RTC_CTL_ALRM0IE /*!< RTC alarm0 interrupt enable */ +#define RTC_INT_ALARM1 RTC_CTL_ALRM1IE /*!< RTC alarm1 interrupt enable */ +#define RTC_INT_TAMP RTC_TAMP_TPIE /*!< tamper detection interrupt enable */ +#define RTC_INT_WAKEUP RTC_CTL_WTIE /*!< RTC wakeup timer interrupt enable */ + +/* write protect key */ +#define RTC_UNLOCK_KEY1 ((uint8_t)0xCAU) /*!< RTC unlock key1 */ +#define RTC_UNLOCK_KEY2 ((uint8_t)0x53U) /*!< RTC unlock key2 */ +#define RTC_LOCK_KEY ((uint8_t)0xFFU) /*!< RTC lock key */ + +/* registers reset value */ +#define RTC_REGISTER_RESET ((uint32_t)0x00000000U) /*!< RTC common register reset value */ +#define RTC_DATE_RESET ((uint32_t)0x00002101U) /*!< RTC_DATE register reset value */ +#define RTC_STAT_RESET ((uint32_t)0x00000000U) /*!< RTC_STAT register reset value */ +#define RTC_PSC_RESET ((uint32_t)0x007F00FFU) /*!< RTC_PSC register reset value */ +#define RTC_WUT_RESET ((uint32_t)0x0000FFFFU) /*!< RTC_WUT register reset value */ + +/* RTC alarm */ +#define RTC_ALARM0 ((uint8_t)0x01U) /*!< RTC alarm 0 */ +#define RTC_ALARM1 ((uint8_t)0x02U) /*!< RTC alarm 1 */ + +/* RTC coarse calibration direction */ +#define CALIB_INCREASE ((uint8_t)0x01U) /*!< RTC coarse calibration increase */ +#define CALIB_DECREASE ((uint8_t)0x02U) /*!< RTC coarse calibration decrease */ + +/* RTC wakeup timer clock */ +#define CTL_WTCS(regval) (BITS(0,2) & ((regval)<< 0)) +#define WAKEUP_RTCCK_DIV16 CTL_WTCS(0) /*!< wakeup timer clock is RTC clock divided by 16 */ +#define WAKEUP_RTCCK_DIV8 CTL_WTCS(1) /*!< wakeup timer clock is RTC clock divided by 8 */ +#define WAKEUP_RTCCK_DIV4 CTL_WTCS(2) /*!< wakeup timer clock is RTC clock divided by 4 */ +#define WAKEUP_RTCCK_DIV2 CTL_WTCS(3) /*!< wakeup timer clock is RTC clock divided by 2 */ +#define WAKEUP_CKSPRE CTL_WTCS(4) /*!< wakeup timer clock is ckapre */ +#define WAKEUP_CKSPRE_2EXP16 CTL_WTCS(6) /*!< wakeup timer clock is ckapre and wakeup timer add 2exp16 */ + +/* RTC_AF pin */ +#define RTC_AF0_TIMESTAMP ((uint32_t)0x00000000) /*!< RTC_AF0 use for timestamp */ +#define RTC_AF1_TIMESTAMP RTC_TAMP_TSSEL /*!< RTC_AF1 use for timestamp */ +#define RTC_AF0_TAMPER0 ((uint32_t)0x00000000) /*!< RTC_AF0 use for tamper0 */ +#define RTC_AF1_TAMPER0 RTC_TAMP_TP0SEL /*!< RTC_AF1 use for tamper0 */ + +/* function declarations */ +/* reset most of the RTC registers */ +ErrStatus rtc_deinit(void); +/* initialize RTC registers */ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct); +/* enter RTC init mode */ +ErrStatus rtc_init_mode_enter(void); +/* exit RTC init mode */ +void rtc_init_mode_exit(void); +/* wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow registers are updated */ +ErrStatus rtc_register_sync_wait(void); + +/* get current time and date */ +void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct); +/* get current subsecond value */ +uint32_t rtc_subsecond_get(void); + +/* configure RTC alarm */ +void rtc_alarm_config(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time); +/* configure subsecond of RTC alarm */ +void rtc_alarm_subsecond_config(uint8_t rtc_alarm, uint32_t mask_subsecond, uint32_t subsecond); +/* get RTC alarm */ +void rtc_alarm_get(uint8_t rtc_alarm,rtc_alarm_struct* rtc_alarm_time); +/* get RTC alarm subsecond */ +uint32_t rtc_alarm_subsecond_get(uint8_t rtc_alarm); +/* enable RTC alarm */ +void rtc_alarm_enable(uint8_t rtc_alarm); +/* disable RTC alarm */ +ErrStatus rtc_alarm_disable(uint8_t rtc_alarm); + +/* enable RTC time-stamp */ +void rtc_timestamp_enable(uint32_t edge); +/* disable RTC time-stamp */ +void rtc_timestamp_disable(void); +/* get RTC timestamp time and date */ +void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp); +/* get RTC time-stamp subsecond */ +uint32_t rtc_timestamp_subsecond_get(void); +/* RTC time-stamp pin map */ +void rtc_timestamp_pin_map(uint32_t rtc_af); + +/* enable RTC tamper */ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper); +/* disable RTC tamper */ +void rtc_tamper_disable(uint32_t source); +/* RTC tamper0 pin map */ +void rtc_tamper0_pin_map(uint32_t rtc_af); + +/* enable specified RTC interrupt */ +void rtc_interrupt_enable(uint32_t interrupt); +/* disble specified RTC interrupt */ +void rtc_interrupt_disable(uint32_t interrupt); +/* check specified flag */ +FlagStatus rtc_flag_get(uint32_t flag); +/* clear specified flag */ +void rtc_flag_clear(uint32_t flag); + +/* configure RTC alarm output source */ +void rtc_alarm_output_config(uint32_t source, uint32_t mode); +/* configure RTC calibration output source */ +void rtc_calibration_output_config(uint32_t source); + +/* adjust the daylight saving time by adding or substracting one hour from the current time */ +void rtc_hour_adjust(uint32_t operation); +/* adjust RTC second or subsecond value of current time */ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus); + +/* enable RTC bypass shadow registers function */ +void rtc_bypass_shadow_enable(void); +/* disable RTC bypass shadow registers function */ +void rtc_bypass_shadow_disable(void); + +/* enable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_enable(void); +/* disable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_disable(void); + +/* enable RTC wakeup timer */ +void rtc_wakeup_enable(void); +/* disable RTC wakeup timer */ +ErrStatus rtc_wakeup_disable(void); +/* set auto wakeup timer clock */ +ErrStatus rtc_wakeup_clock_set(uint8_t wakeup_clock); +/* set auto wakeup timer value */ +ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer); +/* get auto wakeup timer value */ +uint16_t rtc_wakeup_timer_get(void); + +/* configure RTC smooth calibration */ +ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t minus); +/* enable RTC coarse calibration */ +ErrStatus rtc_coarse_calibration_enable(void); +/* disable RTC coarse calibration */ +ErrStatus rtc_coarse_calibration_disable(void); +/* configure RTC coarse calibration direction and step */ +ErrStatus rtc_coarse_calibration_config(uint8_t direction, uint8_t step); + +#endif /* GD32F4XX_RTC_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h new file mode 100644 index 0000000000..bd3b2c8fc6 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h @@ -0,0 +1,378 @@ +/*! + \file gd32f4xx_sdio.h + \brief definitions for the SDIO +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_SDIO_H +#define GD32F4XX_SDIO_H + +#include "gd32f4xx.h" + +/* SDIO definitions */ +#define SDIO SDIO_BASE + +/* registers definitions */ +#define SDIO_PWRCTL REG32(SDIO + 0x00U) /*!< SDIO power control register */ +#define SDIO_CLKCTL REG32(SDIO + 0x04U) /*!< SDIO clock control register */ +#define SDIO_CMDAGMT REG32(SDIO + 0x08U) /*!< SDIO command argument register */ +#define SDIO_CMDCTL REG32(SDIO + 0x0CU) /*!< SDIO command control register */ +#define SDIO_RSPCMDIDX REG32(SDIO + 0x10U) /*!< SDIO command index response register */ +#define SDIO_RESP0 REG32(SDIO + 0x14U) /*!< SDIO response register 0 */ +#define SDIO_RESP1 REG32(SDIO + 0x18U) /*!< SDIO response register 1 */ +#define SDIO_RESP2 REG32(SDIO + 0x1CU) /*!< SDIO response register 2 */ +#define SDIO_RESP3 REG32(SDIO + 0x20U) /*!< SDIO response register 3 */ +#define SDIO_DATATO REG32(SDIO + 0x24U) /*!< SDIO data timeout register */ +#define SDIO_DATALEN REG32(SDIO + 0x28U) /*!< SDIO data length register */ +#define SDIO_DATACTL REG32(SDIO + 0x2CU) /*!< SDIO data control register */ +#define SDIO_DATACNT REG32(SDIO + 0x30U) /*!< SDIO data counter register */ +#define SDIO_STAT REG32(SDIO + 0x34U) /*!< SDIO status register */ +#define SDIO_INTC REG32(SDIO + 0x38U) /*!< SDIO interrupt clear register */ +#define SDIO_INTEN REG32(SDIO + 0x3CU) /*!< SDIO interrupt enable register */ +#define SDIO_FIFOCNT REG32(SDIO + 0x48U) /*!< SDIO FIFO counter register */ +#define SDIO_FIFO REG32(SDIO + 0x80U) /*!< SDIO FIFO data register */ + +/* bits definitions */ +/* SDIO_PWRCTL */ +#define SDIO_PWRCTL_PWRCTL BITS(0,1) /*!< SDIO power control bits */ + +/* SDIO_CLKCTL */ +#define SDIO_CLKCTL_DIV BITS(0,7) /*!< clock division */ +#define SDIO_CLKCTL_CLKEN BIT(8) /*!< SDIO_CLK clock output enable bit */ +#define SDIO_CLKCTL_CLKPWRSAV BIT(9) /*!< SDIO_CLK clock dynamic switch on/off for power saving */ +#define SDIO_CLKCTL_CLKBYP BIT(10) /*!< clock bypass enable bit */ +#define SDIO_CLKCTL_BUSMODE BITS(11,12) /*!< SDIO card bus mode control bit */ +#define SDIO_CLKCTL_CLKEDGE BIT(13) /*!< SDIO_CLK clock edge selection bit */ +#define SDIO_CLKCTL_HWCLKEN BIT(14) /*!< hardware clock control enable bit */ +#define SDIO_CLKCTL_DIV8 BIT(31) /*!< MSB of clock division */ + +/* SDIO_CMDAGMT */ +#define SDIO_CMDAGMT_CMDAGMT BITS(0,31) /*!< SDIO card command argument */ + +/* SDIO_CMDCTL */ +#define SDIO_CMDCTL_CMDIDX BITS(0,5) /*!< command index */ +#define SDIO_CMDCTL_CMDRESP BITS(6,7) /*!< command response type bits */ +#define SDIO_CMDCTL_INTWAIT BIT(8) /*!< interrupt wait instead of timeout */ +#define SDIO_CMDCTL_WAITDEND BIT(9) /*!< wait for ends of data transfer */ +#define SDIO_CMDCTL_CSMEN BIT(10) /*!< command state machine(CSM) enable bit */ +#define SDIO_CMDCTL_SUSPEND BIT(11) /*!< SD I/O suspend command(SD I/O only) */ +#define SDIO_CMDCTL_ENCMDC BIT(12) /*!< CMD completion signal enabled (CE-ATA only) */ +#define SDIO_CMDCTL_NINTEN BIT(13) /*!< no CE-ATA interrupt (CE-ATA only) */ +#define SDIO_CMDCTL_ATAEN BIT(14) /*!< CE-ATA command enable(CE-ATA only) */ + +/* SDIO_DATATO */ +#define SDIO_DATATO_DATATO BITS(0,31) /*!< data timeout period */ + +/* SDIO_DATALEN */ +#define SDIO_DATALEN_DATALEN BITS(0,24) /*!< data transfer length */ + +/* SDIO_DATACTL */ +#define SDIO_DATACTL_DATAEN BIT(0) /*!< data transfer enabled bit */ +#define SDIO_DATACTL_DATADIR BIT(1) /*!< data transfer direction */ +#define SDIO_DATACTL_TRANSMOD BIT(2) /*!< data transfer mode */ +#define SDIO_DATACTL_DMAEN BIT(3) /*!< DMA enable bit */ +#define SDIO_DATACTL_BLKSZ BITS(4,7) /*!< data block size */ +#define SDIO_DATACTL_RWEN BIT(8) /*!< read wait mode enabled(SD I/O only) */ +#define SDIO_DATACTL_RWSTOP BIT(9) /*!< read wait stop(SD I/O only) */ +#define SDIO_DATACTL_RWTYPE BIT(10) /*!< read wait type(SD I/O only) */ +#define SDIO_DATACTL_IOEN BIT(11) /*!< SD I/O specific function enable(SD I/O only) */ + +/* SDIO_STAT */ +#define SDIO_STAT_CCRCERR BIT(0) /*!< command response received (CRC check failed) */ +#define SDIO_STAT_DTCRCERR BIT(1) /*!< data block sent/received (CRC check failed) */ +#define SDIO_STAT_CMDTMOUT BIT(2) /*!< command response timeout */ +#define SDIO_STAT_DTTMOUT BIT(3) /*!< data timeout */ +#define SDIO_STAT_TXURE BIT(4) /*!< transmit FIFO underrun error occurs */ +#define SDIO_STAT_RXORE BIT(5) /*!< received FIFO overrun error occurs */ +#define SDIO_STAT_CMDRECV BIT(6) /*!< command response received (CRC check passed) */ +#define SDIO_STAT_CMDSEND BIT(7) /*!< command sent (no response required) */ +#define SDIO_STAT_DTEND BIT(8) /*!< data end (data counter, SDIO_DATACNT, is zero) */ +#define SDIO_STAT_STBITE BIT(9) /*!< start bit error in the bus */ +#define SDIO_STAT_DTBLKEND BIT(10) /*!< data block sent/received (CRC check passed) */ +#define SDIO_STAT_CMDRUN BIT(11) /*!< command transmission in progress */ +#define SDIO_STAT_TXRUN BIT(12) /*!< data transmission in progress */ +#define SDIO_STAT_RXRUN BIT(13) /*!< data reception in progress */ +#define SDIO_STAT_TFH BIT(14) /*!< transmit FIFO is half empty: at least 8 words can be written into the FIFO */ +#define SDIO_STAT_RFH BIT(15) /*!< receive FIFO is half full: at least 8 words can be read in the FIFO */ +#define SDIO_STAT_TFF BIT(16) /*!< transmit FIFO is full */ +#define SDIO_STAT_RFF BIT(17) /*!< receive FIFO is full */ +#define SDIO_STAT_TFE BIT(18) /*!< transmit FIFO is empty */ +#define SDIO_STAT_RFE BIT(19) /*!< receive FIFO is empty */ +#define SDIO_STAT_TXDTVAL BIT(20) /*!< data is valid in transmit FIFO */ +#define SDIO_STAT_RXDTVAL BIT(21) /*!< data is valid in receive FIFO */ +#define SDIO_STAT_SDIOINT BIT(22) /*!< SD I/O interrupt received */ +#define SDIO_STAT_ATAEND BIT(23) /*!< CE-ATA command completion signal received (only for CMD61) */ + +/* SDIO_INTC */ +#define SDIO_INTC_CCRCERRC BIT(0) /*!< CCRCERR flag clear bit */ +#define SDIO_INTC_DTCRCERRC BIT(1) /*!< DTCRCERR flag clear bit */ +#define SDIO_INTC_CMDTMOUTC BIT(2) /*!< CMDTMOUT flag clear bit */ +#define SDIO_INTC_DTTMOUTC BIT(3) /*!< DTTMOUT flag clear bit */ +#define SDIO_INTC_TXUREC BIT(4) /*!< TXURE flag clear bit */ +#define SDIO_INTC_RXOREC BIT(5) /*!< RXORE flag clear bit */ +#define SDIO_INTC_CMDRECVC BIT(6) /*!< CMDRECV flag clear bit */ +#define SDIO_INTC_CMDSENDC BIT(7) /*!< CMDSEND flag clear bit */ +#define SDIO_INTC_DTENDC BIT(8) /*!< DTEND flag clear bit */ +#define SDIO_INTC_STBITEC BIT(9) /*!< STBITE flag clear bit */ +#define SDIO_INTC_DTBLKENDC BIT(10) /*!< DTBLKEND flag clear bit */ +#define SDIO_INTC_SDIOINTC BIT(22) /*!< SDIOINT flag clear bit */ +#define SDIO_INTC_ATAENDC BIT(23) /*!< ATAEND flag clear bit */ + +/* SDIO_INTEN */ +#define SDIO_INTEN_CCRCERRIE BIT(0) /*!< command response CRC fail interrupt enable */ +#define SDIO_INTEN_DTCRCERRIE BIT(1) /*!< data CRC fail interrupt enable */ +#define SDIO_INTEN_CMDTMOUTIE BIT(2) /*!< command response timeout interrupt enable */ +#define SDIO_INTEN_DTTMOUTIE BIT(3) /*!< data timeout interrupt enable */ +#define SDIO_INTEN_TXUREIE BIT(4) /*!< transmit FIFO underrun error interrupt enable */ +#define SDIO_INTEN_RXOREIE BIT(5) /*!< received FIFO overrun error interrupt enable */ +#define SDIO_INTEN_CMDRECVIE BIT(6) /*!< command response received interrupt enable */ +#define SDIO_INTEN_CMDSENDIE BIT(7) /*!< command sent interrupt enable */ +#define SDIO_INTEN_DTENDIE BIT(8) /*!< data end interrupt enable */ +#define SDIO_INTEN_STBITEIE BIT(9) /*!< start bit error interrupt enable */ +#define SDIO_INTEN_DTBLKENDIE BIT(10) /*!< data block end interrupt enable */ +#define SDIO_INTEN_CMDRUNIE BIT(11) /*!< command transmission interrupt enable */ +#define SDIO_INTEN_TXRUNIE BIT(12) /*!< data transmission interrupt enable */ +#define SDIO_INTEN_RXRUNIE BIT(13) /*!< data reception interrupt enable */ +#define SDIO_INTEN_TFHIE BIT(14) /*!< transmit FIFO half empty interrupt enable */ +#define SDIO_INTEN_RFHIE BIT(15) /*!< receive FIFO half full interrupt enable */ +#define SDIO_INTEN_TFFIE BIT(16) /*!< transmit FIFO full interrupt enable */ +#define SDIO_INTEN_RFFIE BIT(17) /*!< receive FIFO full interrupt enable */ +#define SDIO_INTEN_TFEIE BIT(18) /*!< transmit FIFO empty interrupt enable */ +#define SDIO_INTEN_RFEIE BIT(19) /*!< receive FIFO empty interrupt enable */ +#define SDIO_INTEN_TXDTVALIE BIT(20) /*!< data valid in transmit FIFO interrupt enable */ +#define SDIO_INTEN_RXDTVALIE BIT(21) /*!< data valid in receive FIFO interrupt enable */ +#define SDIO_INTEN_SDIOINTIE BIT(22) /*!< SD I/O interrupt received interrupt enable */ +#define SDIO_INTEN_ATAENDIE BIT(23) /*!< CE-ATA command completion signal received interrupt enable */ + +/* SDIO_FIFO */ +#define SDIO_FIFO_FIFODT BITS(0,31) /*!< receive FIFO data or transmit FIFO data */ + +/* constants definitions */ +/* SDIO flags */ +#define SDIO_FLAG_CCRCERR BIT(0) /*!< command response received (CRC check failed) flag */ +#define SDIO_FLAG_DTCRCERR BIT(1) /*!< data block sent/received (CRC check failed) flag */ +#define SDIO_FLAG_CMDTMOUT BIT(2) /*!< command response timeout flag */ +#define SDIO_FLAG_DTTMOUT BIT(3) /*!< data timeout flag */ +#define SDIO_FLAG_TXURE BIT(4) /*!< transmit FIFO underrun error occurs flag */ +#define SDIO_FLAG_RXORE BIT(5) /*!< received FIFO overrun error occurs flag */ +#define SDIO_FLAG_CMDRECV BIT(6) /*!< command response received (CRC check passed) flag */ +#define SDIO_FLAG_CMDSEND BIT(7) /*!< command sent (no response required) flag */ +#define SDIO_FLAG_DTEND BIT(8) /*!< data end (data counter, SDIO_DATACNT, is zero) flag */ +#define SDIO_FLAG_STBITE BIT(9) /*!< start bit error in the bus flag */ +#define SDIO_FLAG_DTBLKEND BIT(10) /*!< data block sent/received (CRC check passed) flag */ +#define SDIO_FLAG_CMDRUN BIT(11) /*!< command transmission in progress flag */ +#define SDIO_FLAG_TXRUN BIT(12) /*!< data transmission in progress flag */ +#define SDIO_FLAG_RXRUN BIT(13) /*!< data reception in progress flag */ +#define SDIO_FLAG_TFH BIT(14) /*!< transmit FIFO is half empty flag: at least 8 words can be written into the FIFO */ +#define SDIO_FLAG_RFH BIT(15) /*!< receive FIFO is half full flag: at least 8 words can be read in the FIFO */ +#define SDIO_FLAG_TFF BIT(16) /*!< transmit FIFO is full flag */ +#define SDIO_FLAG_RFF BIT(17) /*!< receive FIFO is full flag */ +#define SDIO_FLAG_TFE BIT(18) /*!< transmit FIFO is empty flag */ +#define SDIO_FLAG_RFE BIT(19) /*!< receive FIFO is empty flag */ +#define SDIO_FLAG_TXDTVAL BIT(20) /*!< data is valid in transmit FIFO flag */ +#define SDIO_FLAG_RXDTVAL BIT(21) /*!< data is valid in receive FIFO flag */ +#define SDIO_FLAG_SDIOINT BIT(22) /*!< SD I/O interrupt received flag */ +#define SDIO_FLAG_ATAEND BIT(23) /*!< CE-ATA command completion signal received (only for CMD61) flag */ + +/* SDIO interrupt flags */ +#define SDIO_INT_CCRCERR BIT(0) /*!< SDIO CCRCERR interrupt */ +#define SDIO_INT_DTCRCERR BIT(1) /*!< SDIO DTCRCERR interrupt */ +#define SDIO_INT_CMDTMOUT BIT(2) /*!< SDIO CMDTMOUT interrupt */ +#define SDIO_INT_DTTMOUT BIT(3) /*!< SDIO DTTMOUT interrupt */ +#define SDIO_INT_TXURE BIT(4) /*!< SDIO TXURE interrupt */ +#define SDIO_INT_RXORE BIT(5) /*!< SDIO RXORE interrupt */ +#define SDIO_INT_CMDRECV BIT(6) /*!< SDIO CMDRECV interrupt */ +#define SDIO_INT_CMDSEND BIT(7) /*!< SDIO CMDSEND interrupt */ +#define SDIO_INT_DTEND BIT(8) /*!< SDIO DTEND interrupt */ +#define SDIO_INT_STBITE BIT(9) /*!< SDIO STBITE interrupt */ +#define SDIO_INT_DTBLKEND BIT(10) /*!< SDIO DTBLKEND interrupt */ +#define SDIO_INT_CMDRUN BIT(11) /*!< SDIO CMDRUN interrupt */ +#define SDIO_INT_TXRUN BIT(12) /*!< SDIO TXRUN interrupt */ +#define SDIO_INT_RXRUN BIT(13) /*!< SDIO RXRUN interrupt */ +#define SDIO_INT_TFH BIT(14) /*!< SDIO TFH interrupt */ +#define SDIO_INT_RFH BIT(15) /*!< SDIO RFH interrupt */ +#define SDIO_INT_TFF BIT(16) /*!< SDIO TFF interrupt */ +#define SDIO_INT_RFF BIT(17) /*!< SDIO RFF interrupt */ +#define SDIO_INT_TFE BIT(18) /*!< SDIO TFE interrupt */ +#define SDIO_INT_RFE BIT(19) /*!< SDIO RFE interrupt */ +#define SDIO_INT_TXDTVAL BIT(20) /*!< SDIO TXDTVAL interrupt */ +#define SDIO_INT_RXDTVAL BIT(21) /*!< SDIO RXDTVAL interrupt */ +#define SDIO_INT_SDIOINT BIT(22) /*!< SDIO SDIOINT interrupt */ +#define SDIO_INT_ATAEND BIT(23) /*!< SDIO ATAEND interrupt */ + +/* SDIO power control */ +#define PWRCTL_PWRCTL(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define SDIO_POWER_OFF PWRCTL_PWRCTL(0) /*!< SDIO power off */ +#define SDIO_POWER_ON PWRCTL_PWRCTL(3) /*!< SDIO power on */ + +/* SDIO card bus mode control */ +#define CLKCTL_BUSMODE(regval) (BITS(11,12) & ((uint32_t)(regval) << 11)) +#define SDIO_BUSMODE_1BIT CLKCTL_BUSMODE(0) /*!< 1-bit SDIO card bus mode */ +#define SDIO_BUSMODE_4BIT CLKCTL_BUSMODE(1) /*!< 4-bit SDIO card bus mode */ +#define SDIO_BUSMODE_8BIT CLKCTL_BUSMODE(2) /*!< 8-bit SDIO card bus mode */ + +/* SDIO_CLK clock edge selection */ +#define SDIO_SDIOCLKEDGE_RISING (uint32_t)0x00000000U /*!< select the rising edge of the SDIOCLK to generate SDIO_CLK */ +#define SDIO_SDIOCLKEDGE_FALLING SDIO_CLKCTL_CLKEDGE /*!< select the falling edge of the SDIOCLK to generate SDIO_CLK */ + +/* clock bypass enable or disable */ +#define SDIO_CLOCKBYPASS_DISABLE (uint32_t)0x00000000U /*!< no bypass */ +#define SDIO_CLOCKBYPASS_ENABLE SDIO_CLKCTL_CLKBYP /*!< clock bypass */ + +/* SDIO_CLK clock dynamic switch on/off for power saving */ +#define SDIO_CLOCKPWRSAVE_DISABLE (uint32_t)0x00000000U /*!< SDIO_CLK clock is always on */ +#define SDIO_CLOCKPWRSAVE_ENABLE SDIO_CLKCTL_CLKPWRSAV /*!< SDIO_CLK closed when bus is idle */ + +/* SDIO command response type */ +#define CMDCTL_CMDRESP(regval) (BITS(6,7) & ((uint32_t)(regval) << 6)) +#define SDIO_RESPONSETYPE_NO CMDCTL_CMDRESP(0) /*!< no response */ +#define SDIO_RESPONSETYPE_SHORT CMDCTL_CMDRESP(1) /*!< short response */ +#define SDIO_RESPONSETYPE_LONG CMDCTL_CMDRESP(3) /*!< long response */ + +/* command state machine wait type */ +#define SDIO_WAITTYPE_NO (uint32_t)0x00000000U /*!< not wait interrupt */ +#define SDIO_WAITTYPE_INTERRUPT SDIO_CMDCTL_INTWAIT /*!< wait interrupt */ +#define SDIO_WAITTYPE_DATAEND SDIO_CMDCTL_WAITDEND /*!< wait the end of data transfer */ + +#define SDIO_RESPONSE0 (uint32_t)0x00000000U /*!< card response[31:0]/card response[127:96] */ +#define SDIO_RESPONSE1 (uint32_t)0x00000001U /*!< card response[95:64] */ +#define SDIO_RESPONSE2 (uint32_t)0x00000002U /*!< card response[63:32] */ +#define SDIO_RESPONSE3 (uint32_t)0x00000003U /*!< card response[31:1], plus bit 0 */ + +/* SDIO data block size */ +#define DATACTL_BLKSZ(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define SDIO_DATABLOCKSIZE_1BYTE DATACTL_BLKSZ(0) /*!< block size = 1 byte */ +#define SDIO_DATABLOCKSIZE_2BYTES DATACTL_BLKSZ(1) /*!< block size = 2 bytes */ +#define SDIO_DATABLOCKSIZE_4BYTES DATACTL_BLKSZ(2) /*!< block size = 4 bytes */ +#define SDIO_DATABLOCKSIZE_8BYTES DATACTL_BLKSZ(3) /*!< block size = 8 bytes */ +#define SDIO_DATABLOCKSIZE_16BYTES DATACTL_BLKSZ(4) /*!< block size = 16 bytes */ +#define SDIO_DATABLOCKSIZE_32BYTES DATACTL_BLKSZ(5) /*!< block size = 32 bytes */ +#define SDIO_DATABLOCKSIZE_64BYTES DATACTL_BLKSZ(6) /*!< block size = 64 bytes */ +#define SDIO_DATABLOCKSIZE_128BYTES DATACTL_BLKSZ(7) /*!< block size = 128 bytes */ +#define SDIO_DATABLOCKSIZE_256BYTES DATACTL_BLKSZ(8) /*!< block size = 256 bytes */ +#define SDIO_DATABLOCKSIZE_512BYTES DATACTL_BLKSZ(9) /*!< block size = 512 bytes */ +#define SDIO_DATABLOCKSIZE_1024BYTES DATACTL_BLKSZ(10) /*!< block size = 1024 bytes */ +#define SDIO_DATABLOCKSIZE_2048BYTES DATACTL_BLKSZ(11) /*!< block size = 2048 bytes */ +#define SDIO_DATABLOCKSIZE_4096BYTES DATACTL_BLKSZ(12) /*!< block size = 4096 bytes */ +#define SDIO_DATABLOCKSIZE_8192BYTES DATACTL_BLKSZ(13) /*!< block size = 8192 bytes */ +#define SDIO_DATABLOCKSIZE_16384BYTES DATACTL_BLKSZ(14) /*!< block size = 16384 bytes */ + +/* SDIO data transfer mode */ +#define SDIO_TRANSMODE_BLOCK (uint32_t)0x00000000U /*!< block transfer */ +#define SDIO_TRANSMODE_STREAM SDIO_DATACTL_TRANSMOD /*!< stream transfer or SDIO multibyte transfer */ + +/* SDIO data transfer direction */ +#define SDIO_TRANSDIRECTION_TOCARD (uint32_t)0x00000000U /*!< write data to card */ +#define SDIO_TRANSDIRECTION_TOSDIO SDIO_DATACTL_DATADIR /*!< read data from card */ + +/* SDIO read wait type */ +#define SDIO_READWAITTYPE_DAT2 (uint32_t)0x00000000U /*!< read wait control using SDIO_DAT[2] */ +#define SDIO_READWAITTYPE_CLK SDIO_DATACTL_RWTYPE /*!< read wait control by stopping SDIO_CLK */ + +/* function declarations */ +/* deinitialize the SDIO */ +void sdio_deinit(void); +/* configure the SDIO clock */ +void sdio_clock_config(uint32_t clock_edge, uint32_t clock_bypass, uint32_t clock_powersave, uint16_t clock_division); +/* enable hardware clock control */ +void sdio_hardware_clock_enable(void); +/* disable hardware clock control */ +void sdio_hardware_clock_disable(void); +/* set different SDIO card bus mode */ +void sdio_bus_mode_set(uint32_t bus_mode); +/* set the SDIO power state */ +void sdio_power_state_set(uint32_t power_state); +/* get the SDIO power state */ +uint32_t sdio_power_state_get(void); +/* enable SDIO_CLK clock output */ +void sdio_clock_enable(void); +/* disable SDIO_CLK clock output */ +void sdio_clock_disable(void); + +/* configure the command index, argument, response type, wait type and CSM to send command */ +/* configure the command and response */ +void sdio_command_response_config(uint32_t cmd_index, uint32_t cmd_argument, uint32_t response_type); +/* set the command state machine wait type */ +void sdio_wait_type_set(uint32_t wait_type); +/* enable the CSM(command state machine) */ +void sdio_csm_enable(void); +/* disable the CSM(command state machine) */ +void sdio_csm_disable(void); +/* get the last response command index */ +uint8_t sdio_command_index_get(void); +/* get the response for the last received command */ +uint32_t sdio_response_get(uint32_t sdio_responsex); + +/* configure the data timeout, length, block size, transfer mode, direction and DSM for data transfer */ +/* configure the data timeout, data length and data block size */ +void sdio_data_config(uint32_t data_timeout, uint32_t data_length, uint32_t data_blocksize); +/* configure the data transfer mode and direction */ +void sdio_data_transfer_config(uint32_t transfer_mode, uint32_t transfer_direction); +/* enable the DSM(data state machine) for data transfer */ +void sdio_dsm_enable(void); +/* disable the DSM(data state machine) */ +void sdio_dsm_disable(void); +/* write data(one word) to the transmit FIFO */ +void sdio_data_write(uint32_t data); +/* read data(one word) from the receive FIFO */ +uint32_t sdio_data_read(void); +/* get the number of remaining data bytes to be transferred to card */ +uint32_t sdio_data_counter_get(void); +/* get the number of words remaining to be written or read from FIFO */ +uint32_t sdio_fifo_counter_get(void); +/* enable the DMA request for SDIO */ +void sdio_dma_enable(void); +/* disable the DMA request for SDIO */ +void sdio_dma_disable(void); + +/* get the flags state of SDIO */ +FlagStatus sdio_flag_get(uint32_t flag); +/* clear the pending flags of SDIO */ +void sdio_flag_clear(uint32_t flag); +/* enable the SDIO interrupt */ +void sdio_interrupt_enable(uint32_t int_flag); +/* disable the SDIO interrupt */ +void sdio_interrupt_disable(uint32_t int_flag); +/* get the interrupt flags state of SDIO */ +FlagStatus sdio_interrupt_flag_get(uint32_t int_flag); +/* clear the interrupt pending flags of SDIO */ +void sdio_interrupt_flag_clear(uint32_t int_flag); + +/* enable the read wait mode(SD I/O only) */ +void sdio_readwait_enable(void); +/* disable the read wait mode(SD I/O only) */ +void sdio_readwait_disable(void); +/* enable the function that stop the read wait process(SD I/O only) */ +void sdio_stop_readwait_enable(void); +/* disable the function that stop the read wait process(SD I/O only) */ +void sdio_stop_readwait_disable(void); +/* set the read wait type(SD I/O only) */ +void sdio_readwait_type_set(uint32_t readwait_type); +/* enable the SD I/O mode specific operation(SD I/O only) */ +void sdio_operation_enable(void); +/* disable the SD I/O mode specific operation(SD I/O only) */ +void sdio_operation_disable(void); +/* enable the SD I/O suspend operation(SD I/O only) */ +void sdio_suspend_enable(void); +/* disable the SD I/O suspend operation(SD I/O only) */ +void sdio_suspend_disable(void); + +/* enable the CE-ATA command(CE-ATA only) */ +void sdio_ceata_command_enable(void); +/* disable the CE-ATA command(CE-ATA only) */ +void sdio_ceata_command_disable(void); +/* enable the CE-ATA interrupt(CE-ATA only) */ +void sdio_ceata_interrupt_enable(void); +/* disable the CE-ATA interrupt(CE-ATA only) */ +void sdio_ceata_interrupt_disable(void); +/* enable the CE-ATA command completion signal(CE-ATA only) */ +void sdio_ceata_command_completion_enable(void); +/* disable the CE-ATA command completion signal(CE-ATA only) */ +void sdio_ceata_command_completion_disable(void); + +#endif /* GD32F4XX_SDIO_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h new file mode 100644 index 0000000000..422df94a6f --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h @@ -0,0 +1,327 @@ +/*! + \file gd32f4xx_spi.h + \brief definitions for the SPI +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_SPI_H +#define GD32F4XX_SPI_H + +#include "gd32f4xx.h" + +/* SPIx(x=0,1,2,3,4,5) definitions */ +#define SPI0 (SPI_BASE + 0x0000F800U) +#define SPI1 SPI_BASE +#define SPI2 (SPI_BASE + 0x00000400U) +#define SPI3 (SPI_BASE + 0x0000FC00U) +#define SPI4 (SPI_BASE + 0x00011800U) +#define SPI5 (SPI_BASE + 0x00011C00U) + +/* I2Sx_ADD(x=1,2) definitions */ +#define I2S1_ADD I2S_ADD_BASE +#define I2S2_ADD (I2S_ADD_BASE + 0x00000C00U) + +/* SPI registers definitions */ +#define SPI_CTL0(spix) REG32((spix) + 0x00U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x04U) /*!< SPI control register 1*/ +#define SPI_STAT(spix) REG32((spix) + 0x08U) /*!< SPI status register */ +#define SPI_DATA(spix) REG32((spix) + 0x0CU) /*!< SPI data register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x10U) /*!< SPI CRC polynomial register */ +#define SPI_RCRC(spix) REG32((spix) + 0x14U) /*!< SPI receive CRC register */ +#define SPI_TCRC(spix) REG32((spix) + 0x18U) /*!< SPI transmit CRC register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x1CU) /*!< SPI I2S control register */ +#define SPI_I2SPSC(spix) REG32((spix) + 0x20U) /*!< SPI I2S clock prescaler register */ +#define SPI_QCTL(spix) REG32((spix) + 0x80U) /*!< SPI quad mode control register */ + +/* I2S_ADD registers definitions */ +#define I2S_ADD_CTL0(i2sx_add) REG32((i2sx_add) + 0x00U) /*!< I2S_ADD control register 0 */ +#define I2S_ADD_CTL1(i2sx_add) REG32((i2sx_add) + 0x04U) /*!< I2S_ADD control register 1*/ +#define I2S_ADD_STAT(i2sx_add) REG32((i2sx_add) + 0x08U) /*!< I2S_ADD status register */ +#define I2S_ADD_DATA(i2sx_add) REG32((i2sx_add) + 0x0CU) /*!< I2S_ADD data register */ +#define I2S_ADD_CRCPOLY(i2sx_add) REG32((i2sx_add) + 0x10U) /*!< I2S_ADD CRC polynomial register */ +#define I2S_ADD_RCRC(i2sx_add) REG32((i2sx_add) + 0x14U) /*!< I2S_ADD receive CRC register */ +#define I2S_ADD_TCRC(i2sx_add) REG32((i2sx_add) + 0x18U) /*!< I2S_ADD transmit CRC register */ +#define I2S_ADD_I2SCTL(i2sx_add) REG32((i2sx_add) + 0x1CU) /*!< I2S_ADD I2S control register */ +#define I2S_ADD_I2SPSC(i2sx_add) REG32((i2sx_add) + 0x20U) /*!< I2S_ADD I2S clock prescaler register */ + +/* bits definitions */ +/* SPIx_CTL0 */ +#define SPI_CTL0_CKPH BIT(0) /*!< clock phase selection*/ +#define SPI_CTL0_CKPL BIT(1) /*!< clock polarity selection */ +#define SPI_CTL0_MSTMOD BIT(2) /*!< master mode enable */ +#define SPI_CTL0_PSC BITS(3,5) /*!< master clock prescaler selection */ +#define SPI_CTL0_SPIEN BIT(6) /*!< SPI enable*/ +#define SPI_CTL0_LF BIT(7) /*!< lsb first mode */ +#define SPI_CTL0_SWNSS BIT(8) /*!< nss pin selection in nss software mode */ +#define SPI_CTL0_SWNSSEN BIT(9) /*!< nss software mode selection */ +#define SPI_CTL0_RO BIT(10) /*!< receive only */ +#define SPI_CTL0_FF16 BIT(11) /*!< data frame size */ +#define SPI_CTL0_CRCNT BIT(12) /*!< CRC next transfer */ +#define SPI_CTL0_CRCEN BIT(13) /*!< CRC calculation enable */ +#define SPI_CTL0_BDOEN BIT(14) /*!< bidirectional transmit output enable*/ +#define SPI_CTL0_BDEN BIT(15) /*!< bidirectional enable */ + +/* SPIx_CTL1 */ +#define SPI_CTL1_DMAREN BIT(0) /*!< receive buffer dma enable */ +#define SPI_CTL1_DMATEN BIT(1) /*!< transmit buffer dma enable */ +#define SPI_CTL1_NSSDRV BIT(2) /*!< drive nss output */ +#define SPI_CTL1_TMOD BIT(4) /*!< SPI TI mode enable */ +#define SPI_CTL1_ERRIE BIT(5) /*!< errors interrupt enable */ +#define SPI_CTL1_RBNEIE BIT(6) /*!< receive buffer not empty interrupt enable */ +#define SPI_CTL1_TBEIE BIT(7) /*!< transmit buffer empty interrupt enable */ + +/* SPIx_STAT */ +#define SPI_STAT_RBNE BIT(0) /*!< receive buffer not empty */ +#define SPI_STAT_TBE BIT(1) /*!< transmit buffer empty */ +#define SPI_STAT_I2SCH BIT(2) /*!< I2S channel side */ +#define SPI_STAT_TXURERR BIT(3) /*!< I2S transmission underrun error bit */ +#define SPI_STAT_CRCERR BIT(4) /*!< SPI CRC error bit */ +#define SPI_STAT_CONFERR BIT(5) /*!< SPI configuration error */ +#define SPI_STAT_RXORERR BIT(6) /*!< SPI reception overrun error Bit */ +#define SPI_STAT_TRANS BIT(7) /*!< transmitting on-going Bit */ +#define SPI_STAT_FERR BIT(8) /*!< format error */ + +/* 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 */ + +/* SPIx_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 */ + +/* SPIx_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 */ + +/* SPIx_SPI_QCTL(only SPI5) */ +#define SPI_QCTL_QMOD BIT(0) /*!< quad-SPI mode enable */ +#define SPI_QCTL_QRD BIT(1) /*!< quad-SPI mode read select */ +#define SPI_QCTL_IO23_DRV BIT(2) /*!< drive SPI_IO2 and SPI_IO3 enable */ + +/* constants definitions */ +/* SPI and I2S parameter struct definitions */ +typedef struct +{ + uint32_t device_mode; /*!< SPI master or slave */ + uint32_t trans_mode; /*!< SPI transtype */ + uint32_t frame_size; /*!< SPI frame size */ + uint32_t nss; /*!< SPI nss control by handware or software */ + uint32_t endian; /*!< SPI big endian or little endian */ + uint32_t clock_polarity_phase; /*!< SPI clock phase and polarity */ + uint32_t prescale; /*!< SPI prescale factor */ +}spi_parameter_struct; + +/* SPI struct parameter options */ +#define SPI_MASTER (SPI_CTL0_MSTMOD | SPI_CTL0_SWNSS) /*!< SPI as master */ +#define SPI_SLAVE ((uint32_t)0x00000000U) /*!< SPI as slave */ + +#define SPI_BIDIRECTIONAL_TEANSMIT SPI_CTL0_BDOEN /*!< SPI work in transmit-only mode */ +#define SPI_BIDIRECTIONAL_RECEIVE ~SPI_CTL0_BDOEN /*!< SPI work in receive-only mode */ + +#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*/ + +#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 */ + +#define SPI_NSS_SOFT SPI_CTL0_SWNSSEN /*!< SPI nss control by sofrware */ +#define SPI_NSS_HARD ((uint32_t)0x00000000U) /*!< SPI nss control by hardware */ + +#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 */ + +#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 */ + +#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 parameter options */ +#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 */ + +#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 */ + +#define I2S_MCKOUT_DISABLE ((uint32_t)0x00000000U) /*!< I2S master clock output disable */ +#define I2S_MCKOUT_ENABLE SPI_I2SPSC_MCKOEN /*!< I2S master clock output enable */ + +#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 */ + +#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 */ + +#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 DMA */ +#define SPI_DMA_RECEIVE ((uint8_t)0x01U) /*!< SPI receive data 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 interrupt 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_RXORERR ((uint8_t)0x02U) /*!< overrun interrupt */ +#define SPI_INT_CONFERR ((uint8_t)0x03U) /*!< config error interrupt */ +#define SPI_INT_CRCERR ((uint8_t)0x04U) /*!< CRC error interrupt */ +#define I2S_INT_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt */ +#define SPI_I2S_INT_ERR ((uint8_t)0x06U) /*!< error interrupt */ +#define SPI_I2S_INT_FERR ((uint8_t)0x07U) /*!< format error interrupt */ + +/* SPI 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 SPI_FLAG_FERR SPI_STAT_FERR /*!< format error interrupt 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 */ +#define I2S_FLAG_FERR SPI_STAT_FERR /*!< format error interrupt flag */ + +/* function declarations */ +/* SPI and I2S reset */ +void spi_i2s_deinit(uint32_t spi_periph); +/* SPI parameter initialization */ +void spi_init(uint32_t spi_periph,spi_parameter_struct* spi_struct); +/* SPI enable */ +void spi_enable(uint32_t spi_periph); +/* SPI disable */ +void spi_disable(uint32_t spi_periph); + +/* I2S parameter initialization */ +void i2s_init(uint32_t spi_periph,uint32_t i2s_mode,uint32_t i2s_standard,uint32_t i2s_ckpl); +/* I2S prescale configuration */ +void i2s_psc_config(uint32_t spi_periph,uint32_t i2s_audiosample,uint32_t i2s_frameformat,uint32_t i2s_mckout); +/* I2S enable */ +void i2s_enable(uint32_t spi_periph); +/* I2S disable */ +void i2s_disable(uint32_t spi_periph); + +/* SPI nss output enable */ +void spi_nss_output_enable(uint32_t spi_periph); +/* SPI nss output disable */ +void spi_nss_output_disable(uint32_t spi_periph); +/* SPI nss pin high level in software mode */ +void spi_nss_internal_high(uint32_t spi_periph); +/* SPI nss pin low level in software mode */ +void spi_nss_internal_low(uint32_t spi_periph); + +/* SPI dma enable */ +void spi_dma_enable(uint32_t spi_periph,uint8_t spi_dma); +/* SPI dma disable */ +void spi_dma_disable(uint32_t spi_periph,uint8_t spi_dma); + +/* configure SPI/I2S data frame format */ +void spi_i2s_data_frame_format_config(uint32_t spi_periph,uint16_t frame_format); +/* transmit data */ +void spi_i2s_data_transmit(uint32_t spi_periph,uint16_t data); +/* 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 interrupt */ +void spi_i2s_interrupt_enable(uint32_t spi_periph,uint8_t spi_i2s_int); +/* disable SPI interrupt */ +void spi_i2s_interrupt_disable(uint32_t spi_periph,uint8_t spi_i2s_int); +/* get SPI and I2S interrupt status*/ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph,uint8_t spi_i2s_int); +/* get SPI and I2S flag status */ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph,uint32_t spi_i2s_flag); +/* clear SPI CRC error flag status */ +void spi_crc_error_clear(uint32_t spi_periph); + +/* SPI CRC polynomial set */ +void spi_crc_polynomial_set(uint32_t spi_periph,uint16_t crc_poly); +/* SPI CRC polynomial get */ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph); +/* SPI CRC function turn on */ +void spi_crc_on(uint32_t spi_periph); +/* SPI CRC function turn off */ +void spi_crc_off(uint32_t spi_periph); +/* SPI next data is CRC value */ +void spi_crc_next(uint32_t spi_periph); +/* get SPI CRC send value or receive value */ +uint16_t spi_crc_get(uint32_t spi_periph,uint8_t spi_crc); + +/* SPI TI mode enable */ +void spi_ti_mode_enable(uint32_t spi_periph); +/* SPI TI mode disable */ +void spi_ti_mode_disable(uint32_t spi_periph); + +/* configure i2s full duplex mode */ +void i2s_full_duplex_mode_config(uint32_t i2s_add_periph,uint32_t i2s_mode,uint32_t i2s_standard,uint32_t i2s_ckpl,uint32_t i2s_frameformat); + +/* quad wire SPI enable */ +void qspi_enable(uint32_t spi_periph); +/* quad wire SPI disable */ +void qspi_disable(uint32_t spi_periph); +/* quad wire SPI write enable */ +void qspi_write_enable(uint32_t spi_periph); +/* quad wire SPI read enable */ +void qspi_read_enable(uint32_t spi_periph); +/* quad wire SPI_IO2 and SPI_IO3 pin output enable */ +void qspi_io23_output_enable(uint32_t spi_periph); +/* quad wire SPI_IO2 and SPI_IO3 pin output disable */ +void qspi_io23_output_disable(uint32_t spi_periph); + +#endif /* GD32F4XX_SPI_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h new file mode 100644 index 0000000000..42ae5599c7 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h @@ -0,0 +1,158 @@ +/*! + \file gd32f4xx_syscfg.h + \brief definitions for the SYSCFG +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_SYSCFG_H +#define GD32F4XX_SYSCFG_H + +#include "gd32f4xx.h" + +/* SYSCFG definitions */ +#define SYSCFG SYSCFG_BASE + +/* registers definitions */ +#define SYSCFG_CFG0 REG32(SYSCFG + 0x00U) /*!< system configuration register 0 */ +#define SYSCFG_CFG1 REG32(SYSCFG + 0x04U) /*!< system configuration register 1 */ +#define SYSCFG_EXTISS0 REG32(SYSCFG + 0x08U) /*!< EXTI sources selection register 0 */ +#define SYSCFG_EXTISS1 REG32(SYSCFG + 0x0CU) /*!< EXTI sources selection register 1 */ +#define SYSCFG_EXTISS2 REG32(SYSCFG + 0x10U) /*!< EXTI sources selection register 2 */ +#define SYSCFG_EXTISS3 REG32(SYSCFG + 0x14U) /*!< EXTI sources selection register 3 */ +#define SYSCFG_CPSCTL REG32(SYSCFG + 0x20U) /*!< system I/O compensation control register */ + +/* SYSCFG_CFG0 bits definitions */ +#define SYSCFG_CFG0_BOOT_MODE BITS(0,2) /*!< SYSCFG memory remap config */ +#define SYSCFG_CFG0_FMC_SWP BIT(8) /*!< FMC memory swap config */ +#define SYSCFG_CFG0_EXMC_SWP BITS(10,11) /*!< EXMC memory swap config */ + +/* SYSCFG_CFG1 bits definitions */ +#define SYSCFG_CFG1_ENET_PHY_SEL BIT(23) /*!< Ethernet PHY selection config */ + +/* SYSCFG_EXTISS0 bits definitions */ +#define SYSCFG_EXTISS0_EXTI0_SS BITS(0,3) /*!< EXTI 0 configuration */ +#define SYSCFG_EXTISS0_EXTI1_SS BITS(4,7) /*!< EXTI 1 configuration */ +#define SYSCFG_EXTISS0_EXTI2_SS BITS(8,11) /*!< EXTI 2 configuration */ +#define SYSCFG_EXTISS0_EXTI3_SS BITS(12,15) /*!< EXTI 3 configuration */ + +/* SYSCFG_EXTISS1 bits definitions */ +#define SYSCFG_EXTISS1_EXTI4_SS BITS(0,3) /*!< EXTI 4 configuration */ +#define SYSCFG_EXTISS1_EXTI5_SS BITS(4,7) /*!< EXTI 5 configuration */ +#define SYSCFG_EXTISS1_EXTI6_SS BITS(8,11) /*!< EXTI 6 configuration */ +#define SYSCFG_EXTISS1_EXTI7_SS BITS(12,15) /*!< EXTI 7 configuration */ + +/* SYSCFG_EXTISS2 bits definitions */ +#define SYSCFG_EXTISS2_EXTI8_SS BITS(0,3) /*!< EXTI 8 configuration */ +#define SYSCFG_EXTISS2_EXTI9_SS BITS(4,7) /*!< EXTI 9 configuration */ +#define SYSCFG_EXTISS2_EXTI10_SS BITS(8,11) /*!< EXTI 10 configuration */ +#define SYSCFG_EXTISS2_EXTI11_SS BITS(12,15) /*!< EXTI 11 configuration */ + +/* SYSCFG_EXTISS3 bits definitions */ +#define SYSCFG_EXTISS3_EXTI12_SS BITS(0,3) /*!< EXTI 12 configuration */ +#define SYSCFG_EXTISS3_EXTI13_SS BITS(4,7) /*!< EXTI 13 configuration */ +#define SYSCFG_EXTISS3_EXTI14_SS BITS(8,11) /*!< EXTI 14 configuration */ +#define SYSCFG_EXTISS3_EXTI15_SS BITS(12,15) /*!< EXTI 15 configuration */ + +/* SYSCFG_CPSCTL bits definitions */ +#define SYSCFG_CPSCTL_CPS_EN BIT(0) /*!< I/O compensation cell enable */ +#define SYSCFG_CPSCTL_CPS_RDY BIT(8) /*!< I/O compensation cell is ready or not */ + +/* constants definitions */ +/* boot mode definitions */ +#define SYSCFG_BOOTMODE_FLASH ((uint8_t)0x00U) /*!< main flash memory remap */ +#define SYSCFG_BOOTMODE_BOOTLOADER ((uint8_t)0x01U) /*!< boot loader remap */ +#define SYSCFG_BOOTMODE_EXMC_SRAM ((uint8_t)0x02U) /*!< SRAM/NOR 0 and 1 of EXMC remap */ +#define SYSCFG_BOOTMODE_SRAM ((uint8_t)0x03U) /*!< SRAM0 of on-chip SRAM remap */ +#define SYSCFG_BOOTMODE_EXMC_SDRAM ((uint8_t)0x04U) /*!< SDRAM bank0 of EXMC remap */ + +/* FMC swap definitions */ +#define SYSCFG_FMC_SWP_BANK0 ((uint32_t)0x00000000U) /*!< main flash Bank 0 is mapped at address 0x08000000 */ +#define SYSCFG_FMC_SWP_BANK1 ((uint32_t)0x00000100U) /*!< main flash Bank 1 is mapped at address 0x08000000 */ + +/* EXMC swap enable/disable */ +#define SYSCFG_EXMC_SWP_ENABLE ((uint32_t)0x00000400U) /*!< SDRAM bank 0 and bank 1 are swapped with NAND bank 1 and PC card */ +#define SYSCFG_EXMC_SWP_DISABLE ((uint32_t)0x00000000U) /*!< no memory mapping swap */ + +/* EXTI source select definition */ +#define EXTISS0 ((uint8_t)0x00U) /*!< EXTI source select GPIOx pin 0~3 */ +#define EXTISS1 ((uint8_t)0x01U) /*!< EXTI source select GPIOx pin 4~7 */ +#define EXTISS2 ((uint8_t)0x02U) /*!< EXTI source select GPIOx pin 8~11 */ +#define EXTISS3 ((uint8_t)0x03U) /*!< EXTI source select GPIOx pin 12~15 */ + +/* EXTI source select mask bits definition */ +#define EXTI_SS_MASK BITS(0,3) + +/* EXTI source select jumping step definition */ +#define EXTI_SS_JSTEP ((uint8_t)(0x04U)) + +/* EXTI source select moving step definition */ +#define EXTI_SS_MSTEP(pin) (EXTI_SS_JSTEP*((pin)%EXTI_SS_JSTEP)) + +/* EXTI source port definitions */ +#define EXTI_SOURCE_GPIOA ((uint8_t)0x00U) /*!< EXTI GPIOA configuration */ +#define EXTI_SOURCE_GPIOB ((uint8_t)0x01U) /*!< EXTI GPIOB configuration */ +#define EXTI_SOURCE_GPIOC ((uint8_t)0x02U) /*!< EXTI GPIOC configuration */ +#define EXTI_SOURCE_GPIOD ((uint8_t)0x03U) /*!< EXTI GPIOD configuration */ +#define EXTI_SOURCE_GPIOE ((uint8_t)0x04U) /*!< EXTI GPIOE configuration */ +#define EXTI_SOURCE_GPIOF ((uint8_t)0x05U) /*!< EXTI GPIOF configuration */ +#define EXTI_SOURCE_GPIOG ((uint8_t)0x06U) /*!< EXTI GPIOG configuration */ +#define EXTI_SOURCE_GPIOH ((uint8_t)0x07U) /*!< EXTI GPIOH configuration */ +#define EXTI_SOURCE_GPIOI ((uint8_t)0x08U) /*!< EXTI GPIOI configuration */ + +/* EXTI source pin definitions */ +#define EXTI_SOURCE_PIN0 ((uint8_t)0x00U) /*!< EXTI GPIO pin0 configuration */ +#define EXTI_SOURCE_PIN1 ((uint8_t)0x01U) /*!< EXTI GPIO pin1 configuration */ +#define EXTI_SOURCE_PIN2 ((uint8_t)0x02U) /*!< EXTI GPIO pin2 configuration */ +#define EXTI_SOURCE_PIN3 ((uint8_t)0x03U) /*!< EXTI GPIO pin3 configuration */ +#define EXTI_SOURCE_PIN4 ((uint8_t)0x04U) /*!< EXTI GPIO pin4 configuration */ +#define EXTI_SOURCE_PIN5 ((uint8_t)0x05U) /*!< EXTI GPIO pin5 configuration */ +#define EXTI_SOURCE_PIN6 ((uint8_t)0x06U) /*!< EXTI GPIO pin6 configuration */ +#define EXTI_SOURCE_PIN7 ((uint8_t)0x07U) /*!< EXTI GPIO pin7 configuration */ +#define EXTI_SOURCE_PIN8 ((uint8_t)0x08U) /*!< EXTI GPIO pin8 configuration */ +#define EXTI_SOURCE_PIN9 ((uint8_t)0x09U) /*!< EXTI GPIO pin9 configuration */ +#define EXTI_SOURCE_PIN10 ((uint8_t)0x0AU) /*!< EXTI GPIO pin10 configuration */ +#define EXTI_SOURCE_PIN11 ((uint8_t)0x0BU) /*!< EXTI GPIO pin11 configuration */ +#define EXTI_SOURCE_PIN12 ((uint8_t)0x0CU) /*!< EXTI GPIO pin12 configuration */ +#define EXTI_SOURCE_PIN13 ((uint8_t)0x0DU) /*!< EXTI GPIO pin13 configuration */ +#define EXTI_SOURCE_PIN14 ((uint8_t)0x0EU) /*!< EXTI GPIO pin14 configuration */ +#define EXTI_SOURCE_PIN15 ((uint8_t)0x0FU) /*!< EXTI GPIO pin15 configuration */ + +/* ethernet PHY selection */ +#define SYSCFG_ENET_PHY_MII ((uint32_t)0x00000000U) +#define SYSCFG_ENET_PHY_RMII ((uint32_t)0x00800000U) + +/* I/O compensation cell enable/disable */ +#define SYSCFG_COMPENSATION_ENABLE ((uint32_t)0x00000001U) +#define SYSCFG_COMPENSATION_DISABLE ((uint32_t)0x00000000U) + +/* function declarations */ +/* deinit syscfg module */ +void syscfg_deinit(void); + +/* configure the boot mode */ +void syscfg_bootmode_config(uint8_t syscfg_bootmode); + +/* FMC memory mapping swap */ +void syscfg_fmc_swap_config(uint32_t syscfg_fmc_swap); + +/* configure the EXMC swap */ +void syscfg_exmc_swap_config(uint32_t syscfg_exmc_swap); + +/* configure the GPIO pin as EXTI Line */ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin); + +/* configure the PHY interface for the ethernet MAC */ +void syscfg_enet_phy_interface_config(uint32_t syscfg_enet_phy_interface); + +/* configure the I/O compensation cell */ +void syscfg_compensation_config(uint32_t syscfg_compensation); + +/* check the I/O compensation cell is ready or not */ +FlagStatus syscfg_flag_get(void); + +#endif /* GD32F4XX_SYSCFG_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h new file mode 100644 index 0000000000..e856ec03ac --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h @@ -0,0 +1,735 @@ +/*! + \file gd32f4xx_timer.h + \brief definitions for the TIMER +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_TIMER_H +#define GD32F4XX_TIMER_H + +#include "gd32f4xx.h" + +/* TIMERx(x=0..13) definitions */ +#define TIMER0 (TIMER_BASE + 0x00010000U) +#define TIMER1 (TIMER_BASE + 0x00000000U) +#define TIMER2 (TIMER_BASE + 0x00000400U) +#define TIMER3 (TIMER_BASE + 0x00000800U) +#define TIMER4 (TIMER_BASE + 0x00000C00U) +#define TIMER5 (TIMER_BASE + 0x00001000U) +#define TIMER6 (TIMER_BASE + 0x00001400U) +#define TIMER7 (TIMER_BASE + 0x00010400U) +#define TIMER8 (TIMER_BASE + 0x00014000U) +#define TIMER9 (TIMER_BASE + 0x00014400U) +#define TIMER10 (TIMER_BASE + 0x00014800U) +#define TIMER11 (TIMER_BASE + 0x00001800U) +#define TIMER12 (TIMER_BASE + 0x00001C00U) +#define TIMER13 (TIMER_BASE + 0x00002000U) + +/* registers definitions */ +#define TIMER_CTL0(timerx) REG32((timerx) + 0x00U) /*!< TIMER control register 0 */ +#define TIMER_CTL1(timerx) REG32((timerx) + 0x04U) /*!< TIMER control register 1 */ +#define TIMER_SMCFG(timerx) REG32((timerx) + 0x08U) /*!< TIMER slave mode configuration register */ +#define TIMER_DMAINTEN(timerx) REG32((timerx) + 0x0CU) /*!< TIMER DMA and interrupt enable register */ +#define TIMER_INTF(timerx) REG32((timerx) + 0x10U) /*!< TIMER interrupt flag register */ +#define TIMER_SWEVG(timerx) REG32((timerx) + 0x14U) /*!< TIMER software event generation register */ +#define TIMER_CHCTL0(timerx) REG32((timerx) + 0x18U) /*!< TIMER channel control register 0 */ +#define TIMER_CHCTL1(timerx) REG32((timerx) + 0x1CU) /*!< TIMER channel control register 1 */ +#define TIMER_CHCTL2(timerx) REG32((timerx) + 0x20U) /*!< TIMER channel control register 2 */ +#define TIMER_CNT(timerx) REG32((timerx) + 0x24U) /*!< TIMER counter register */ +#define TIMER_PSC(timerx) REG32((timerx) + 0x28U) /*!< TIMER prescaler register */ +#define TIMER_CAR(timerx) REG32((timerx) + 0x2CU) /*!< TIMER counter auto reload register */ +#define TIMER_CREP(timerx) REG32((timerx) + 0x30U) /*!< TIMER counter repetition register */ +#define TIMER_CH0CV(timerx) REG32((timerx) + 0x34U) /*!< TIMER channel 0 capture/compare value register */ +#define TIMER_CH1CV(timerx) REG32((timerx) + 0x38U) /*!< TIMER channel 1 capture/compare value register */ +#define TIMER_CH2CV(timerx) REG32((timerx) + 0x3CU) /*!< TIMER channel 2 capture/compare value register */ +#define TIMER_CH3CV(timerx) REG32((timerx) + 0x40U) /*!< TIMER channel 3 capture/compare value register */ +#define TIMER_CCHP(timerx) REG32((timerx) + 0x44U) /*!< TIMER complementary channel protection register */ +#define TIMER_DMACFG(timerx) REG32((timerx) + 0x48U) /*!< TIMER DMA configuration register */ +#define TIMER_DMATB(timerx) REG32((timerx) + 0x4CU) /*!< TIMER DMA transfer buffer register */ +#define TIMER_IRMP(timerx) REG32((timerx) + 0x50U) /*!< TIMER channel input remap register */ +#define TIMER_CFG(timerx) REG32((timerx) + 0xFCU) /*!< TIMER configuration register */ + +/* bits definitions */ +/* TIMER_CTL0 */ +#define TIMER_CTL0_CEN BIT(0) /*!< TIMER counter enable */ +#define TIMER_CTL0_UPDIS BIT(1) /*!< update disable */ +#define TIMER_CTL0_UPS BIT(2) /*!< update source */ +#define TIMER_CTL0_SPM BIT(3) /*!< single pulse mode */ +#define TIMER_CTL0_DIR BIT(4) /*!< timer counter direction */ +#define TIMER_CTL0_CAM BITS(5,6) /*!< center-aligned mode selection */ +#define TIMER_CTL0_ARSE BIT(7) /*!< auto-reload shadow enable */ +#define TIMER_CTL0_CKDIV BITS(8,9) /*!< clock division */ + +/* TIMER_CTL1 */ +#define TIMER_CTL1_CCSE BIT(0) /*!< capture/compare control shadow register enable */ +#define TIMER_CTL1_CCUC BIT(2) /*!< capture/compare control shadow register update control */ +#define TIMER_CTL1_DMAS BIT(3) /*!< DMA request source selection */ +#define TIMER_CTL1_MMC BITS(4,6) /*!< master mode control */ +#define TIMER_CTL1_TI0S BIT(7) /*!< channel 0 trigger input selection(hall mode selection) */ +#define TIMER_CTL1_ISO0 BIT(8) /*!< idle state of channel 0 output */ +#define TIMER_CTL1_ISO0N BIT(9) /*!< idle state of channel 0 complementary output */ +#define TIMER_CTL1_ISO1 BIT(10) /*!< idle state of channel 1 output */ +#define TIMER_CTL1_ISO1N BIT(11) /*!< idle state of channel 1 complementary output */ +#define TIMER_CTL1_ISO2 BIT(12) /*!< idle state of channel 2 output */ +#define TIMER_CTL1_ISO2N BIT(13) /*!< idle state of channel 2 complementary output */ +#define TIMER_CTL1_ISO3 BIT(14) /*!< idle state of channel 3 output */ + +/* TIMER_SMCFG */ +#define TIMER_SMCFG_SMC BITS(0,2) /*!< slave mode control */ +#define TIMER_SMCFG_TRGS BITS(4,6) /*!< trigger selection */ +#define TIMER_SMCFG_MSM BIT(7) /*!< master-slave mode */ +#define TIMER_SMCFG_ETFC BITS(8,11) /*!< external trigger filter control */ +#define TIMER_SMCFG_ETPSC BITS(12,13) /*!< external trigger prescaler */ +#define TIMER_SMCFG_SMC1 BIT(14) /*!< part of SMC for enable external clock mode 1 */ +#define TIMER_SMCFG_ETP BIT(15) /*!< external trigger polarity */ + +/* TIMER_DMAINTEN */ +#define TIMER_DMAINTEN_UPIE BIT(0) /*!< update interrupt enable */ +#define TIMER_DMAINTEN_CH0IE BIT(1) /*!< channel 0 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(8) /*!< 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_CNT16 BITS(0,15) /*!< 16 bit timer counter */ +#define TIMER_CNT_CNT32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) timer counter */ + +/* TIMER_PSC */ +#define TIMER_PSC_PSC BITS(0,15) /*!< prescaler value of the counter clock */ + +/* TIMER_CAR */ +#define TIMER_CAR_CARL16 BITS(0,15) /*!< 16 bit counter auto reload value */ +#define TIMER_CAR_CARL32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) counter auto reload value */ + +/* TIMER_CREP */ +#define TIMER_CREP_CREP BITS(0,7) /*!< counter repetition value */ + +/* TIMER_CH0CV */ +#define TIMER_CH0CV_CH0VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 0 */ +#define TIMER_CH0CV_CH0VAL32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 0 */ + +/* TIMER_CH1CV */ +#define TIMER_CH1CV_CH0VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 1 */ +#define TIMER_CH1CV_CH0VAL32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 1 */ + +/* TIMER_CH2CV */ +#define TIMER_CH2CV_CH0VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 2 */ +#define TIMER_CH2CV_CH0VAL32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 2 */ + +/* TIMER_CH3CV */ +#define TIMER_CH3CV_CH0VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 3 */ +#define TIMER_CH3CV_CH0VAL32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 3 */ + +/* TIMER_CCHP */ +#define TIMER_CCHP_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_CCHP_PROT BITS(8,9) /*!< complementary register protect control */ +#define TIMER_CCHP_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_CCHP_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_CCHP_BRKEN BIT(12) /*!< break enable */ +#define TIMER_CCHP_BRKP BIT(13) /*!< break polarity */ +#define TIMER_CCHP_OAEN BIT(14) /*!< output automatic enable */ +#define TIMER_CCHP_POEN BIT(15) /*!< primary output enable */ + +/* TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA BITS(0,4) /*!< DMA transfer access start address */ +#define TIMER_DMACFG_DMATC BITS(8,12) /*!< DMA transfer count */ + +/* TIMER_DMATB */ +#define TIMER_DMATB_DMATB BITS(0,15) /*!< DMA transfer buffer address */ + +/* TIMER_IRMP */ +#define TIMER1_IRMP_ITI1_RMP BITS(10,11) /*!< TIMER1 internal trigger input 1 remap */ +#define TIMER4_IRMP_CI3_RMP BITS(6,7) /*!< TIMER4 channel 3 input remap */ +#define TIMER10_IRMP_ITI1_RMP BITS(0,1) /*!< TIMER10 internal trigger input 1 remap */ + +/* TIMER_CFG */ +#define TIMER_CFG_OUTSEL BIT(0) /*!< the output value selection */ +#define TIMER_CFG_CHVSEL BIT(1) /*!< write CHxVAL register selection */ + +/* constants definitions */ +/* TIMER init parameter struct definitions*/ +typedef struct +{ + uint16_t prescaler; /*!< prescaler value */ + uint16_t alignedmode; /*!< aligned mode */ + uint16_t counterdirection; /*!< counter direction */ + 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 */ + uint32_t ideloffstate; /*!< idle mode off-state */ + uint16_t deadtime; /*!< delay time between the switching off and on of the outputs */ + 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 +{ + uint32_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 source */ +#define TIMER_INT_UP ((uint32_t)0x00000001U) /*!< update interrupt */ +#define TIMER_INT_CH0 ((uint32_t)0x00000002U) /*!< channel 0 interrupt */ +#define TIMER_INT_CH1 ((uint32_t)0x00000004U) /*!< channel 1 interrupt */ +#define TIMER_INT_CH2 ((uint32_t)0x00000008U) /*!< channel 2 interrupt */ +#define TIMER_INT_CH3 ((uint32_t)0x00000010U) /*!< channel 3 interrupt */ +#define TIMER_INT_CMT ((uint32_t)0x00000020U) /*!< channel commutation interrupt flag */ +#define TIMER_INT_TRG ((uint32_t)0x00000040U) /*!< trigger interrupt */ +#define TIMER_INT_BRK ((uint32_t)0x00000080U) /*!< break interrupt */ + +/* TIMER flag */ +#define TIMER_FLAG_UP ((uint32_t)0x00000001U) /*!< update flag */ +#define TIMER_FLAG_CH0 ((uint32_t)0x00000002U) /*!< channel 0 flag */ +#define TIMER_FLAG_CH1 ((uint32_t)0x00000004U) /*!< channel 1 flag */ +#define TIMER_FLAG_CH2 ((uint32_t)0x00000008U) /*!< channel 2 flag */ +#define TIMER_FLAG_CH3 ((uint32_t)0x00000010U) /*!< channel 3 flag */ +#define TIMER_FLAG_CMT ((uint32_t)0x00000020U) /*!< channel control update flag */ +#define TIMER_FLAG_TRG ((uint32_t)0x00000040U) /*!< trigger flag */ +#define TIMER_FLAG_BRK ((uint32_t)0x00000080U) /*!< break flag */ +#define TIMER_FLAG_CH0OF ((uint32_t)0x00000200U) /*!< channel 0 overcapture flag */ +#define TIMER_FLAG_CH1OF ((uint32_t)0x00000400U) /*!< channel 1 overcapture flag */ +#define TIMER_FLAG_CH2OF ((uint32_t)0x00000800U) /*!< channel 2 overcapture flag */ +#define TIMER_FLAG_CH3OF ((uint32_t)0x00001000U) /*!< channel 3 overcapture 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 */ + +/* channel DMA request source selection */ +#define TIMER_DMAREQUEST_UPDATEEVENT ((uint8_t)0x00U) /*!< DMA request of channel y is sent when update event occurs */ +#define TIMER_DMAREQUEST_CHANNELEVENT ((uint8_t)0x01U) /*!< DMA request of channel y is sent when channel y event occurs */ + +/* DMA access base address */ +#define DMACFG_DMATA(regval) (BITS(0, 4) & ((uint32_t)(regval) << 0U)) +#define TIMER_DMACFG_DMATA_CTL0 DMACFG_DMATA(0) /*!< DMA transfer address is TIMER_CTL0 */ +#define TIMER_DMACFG_DMATA_CTL1 DMACFG_DMATA(1) /*!< DMA transfer address is TIMER_CTL1 */ +#define TIMER_DMACFG_DMATA_SMCFG DMACFG_DMATA(2) /*!< DMA transfer address is TIMER_SMCFG */ +#define TIMER_DMACFG_DMATA_DMAINTEN DMACFG_DMATA(3) /*!< DMA transfer address is TIMER_DMAINTEN */ +#define TIMER_DMACFG_DMATA_INTF DMACFG_DMATA(4) /*!< DMA transfer address is TIMER_INTF */ +#define TIMER_DMACFG_DMATA_SWEVG DMACFG_DMATA(5) /*!< DMA transfer address is TIMER_SWEVG */ +#define TIMER_DMACFG_DMATA_CHCTL0 DMACFG_DMATA(6) /*!< DMA transfer address is TIMER_CHCTL0 */ +#define TIMER_DMACFG_DMATA_CHCTL1 DMACFG_DMATA(7) /*!< DMA transfer address is TIMER_CHCTL1 */ +#define TIMER_DMACFG_DMATA_CHCTL2 DMACFG_DMATA(8) /*!< DMA transfer address is TIMER_CHCTL2 */ +#define TIMER_DMACFG_DMATA_CNT DMACFG_DMATA(9) /*!< DMA transfer address is TIMER_CNT */ +#define TIMER_DMACFG_DMATA_PSC DMACFG_DMATA(10) /*!< DMA transfer address is TIMER_PSC */ +#define TIMER_DMACFG_DMATA_CAR DMACFG_DMATA(11) /*!< DMA transfer address is TIMER_CAR */ +#define TIMER_DMACFG_DMATA_CREP DMACFG_DMATA(12) /*!< DMA transfer address is TIMER_CREP */ +#define TIMER_DMACFG_DMATA_CH0CV DMACFG_DMATA(13) /*!< DMA transfer address is TIMER_CH0CV */ +#define TIMER_DMACFG_DMATA_CH1CV DMACFG_DMATA(14) /*!< DMA transfer address is TIMER_CH1CV */ +#define TIMER_DMACFG_DMATA_CH2CV DMACFG_DMATA(15) /*!< DMA transfer address is TIMER_CH2CV */ +#define TIMER_DMACFG_DMATA_CH3CV DMACFG_DMATA(16) /*!< DMA transfer address is TIMER_CH3CV */ +#define TIMER_DMACFG_DMATA_CCHP DMACFG_DMATA(17) /*!< DMA transfer address is TIMER_CCHP */ +#define TIMER_DMACFG_DMATA_DMACFG DMACFG_DMATA(18) /*!< DMA transfer address is TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA_DMATB DMACFG_DMATA(19) /*!< DMA transfer address is TIMER_DMATB */ + +/* DMA access burst length */ +#define DMACFG_DMATC(regval) (BITS(8, 12) & ((uint32_t)(regval) << 8U)) +#define TIMER_DMACFG_DMATC_1TRANSFER DMACFG_DMATC(0) /*!< DMA transfer 1 time */ +#define TIMER_DMACFG_DMATC_2TRANSFER DMACFG_DMATC(1) /*!< DMA transfer 2 times */ +#define TIMER_DMACFG_DMATC_3TRANSFER DMACFG_DMATC(2) /*!< DMA transfer 3 times */ +#define TIMER_DMACFG_DMATC_4TRANSFER DMACFG_DMATC(3) /*!< DMA transfer 4 times */ +#define TIMER_DMACFG_DMATC_5TRANSFER DMACFG_DMATC(4) /*!< DMA transfer 5 times */ +#define TIMER_DMACFG_DMATC_6TRANSFER DMACFG_DMATC(5) /*!< DMA transfer 6 times */ +#define TIMER_DMACFG_DMATC_7TRANSFER DMACFG_DMATC(6) /*!< DMA transfer 7 times */ +#define TIMER_DMACFG_DMATC_8TRANSFER DMACFG_DMATC(7) /*!< DMA transfer 8 times */ +#define TIMER_DMACFG_DMATC_9TRANSFER DMACFG_DMATC(8) /*!< DMA transfer 9 times */ +#define TIMER_DMACFG_DMATC_10TRANSFER DMACFG_DMATC(9) /*!< DMA transfer 10 times */ +#define TIMER_DMACFG_DMATC_11TRANSFER DMACFG_DMATC(10) /*!< DMA transfer 11 times */ +#define TIMER_DMACFG_DMATC_12TRANSFER DMACFG_DMATC(11) /*!< DMA transfer 12 times */ +#define TIMER_DMACFG_DMATC_13TRANSFER DMACFG_DMATC(12) /*!< DMA transfer 13 times */ +#define TIMER_DMACFG_DMATC_14TRANSFER DMACFG_DMATC(13) /*!< DMA transfer 14 times */ +#define TIMER_DMACFG_DMATC_15TRANSFER DMACFG_DMATC(14) /*!< DMA transfer 15 times */ +#define TIMER_DMACFG_DMATC_16TRANSFER DMACFG_DMATC(15) /*!< DMA transfer 16 times */ +#define TIMER_DMACFG_DMATC_17TRANSFER DMACFG_DMATC(16) /*!< DMA transfer 17 times */ +#define TIMER_DMACFG_DMATC_18TRANSFER DMACFG_DMATC(17) /*!< DMA transfer 18 times */ + +/* TIMER software event generation source */ +#define TIMER_EVENT_SRC_UPG ((uint16_t)0x0001U) /*!< update event generation */ +#define TIMER_EVENT_SRC_CH0G ((uint16_t)0x0002U) /*!< channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH1G ((uint16_t)0x0004U) /*!< channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH2G ((uint16_t)0x0008U) /*!< channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH3G ((uint16_t)0x0010U) /*!< channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CMTG ((uint16_t)0x0020U) /*!< channel commutation event generation */ +#define TIMER_EVENT_SRC_TRGG ((uint16_t)0x0040U) /*!< trigger event generation */ +#define TIMER_EVENT_SRC_BRKG ((uint16_t)0x0080U) /*!< break event generation */ + +/* center-aligned mode selection */ +#define CTL0_CAM(regval) ((uint16_t)(BITS(5, 6) & ((uint32_t)(regval) << 5U))) +#define TIMER_COUNTER_EDGE CTL0_CAM(0) /*!< edge-aligned mode */ +#define TIMER_COUNTER_CENTER_DOWN CTL0_CAM(1) /*!< center-aligned and counting down assert mode */ +#define TIMER_COUNTER_CENTER_UP CTL0_CAM(2) /*!< center-aligned and counting up assert mode */ +#define TIMER_COUNTER_CENTER_BOTH CTL0_CAM(3) /*!< center-aligned and counting up/down assert mode */ + +/* TIMER prescaler reload mode */ +#define TIMER_PSC_RELOAD_NOW ((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 */ + +/* 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 ((uint32_t)0x00000800U) /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_ROS_STATE_DISABLE ((uint32_t)0x00000000U) /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are disabled */ + +/* idle mode off-state configure */ +#define TIMER_IOS_STATE_ENABLE ((uint16_t)0x0400U) /*!< when POEN bit is reset, he channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_IOS_STATE_DISABLE ((uint16_t)0x0000U) /*!< when POEN bit is reset, the channel output signals (CHx_O/CHx_ON) are disabled */ + +/* break input polarity */ +#define TIMER_BREAK_POLARITY_LOW ((uint16_t)0x0000U) /*!< break input polarity is low */ +#define TIMER_BREAK_POLARITY_HIGH ((uint16_t)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 channel 0(TIMERx(x=0..4,7..13)) */ +#define TIMER_CH_1 ((uint16_t)0x0001U) /*!< TIMER channel 1(TIMERx(x=0..4,7,8,11)) */ +#define TIMER_CH_2 ((uint16_t)0x0002U) /*!< TIMER channel 2(TIMERx(x=0..4,7)) */ +#define TIMER_CH_3 ((uint16_t)0x0003U) /*!< TIMER channel 3(TIMERx(x=0..4,7)) */ + +/* channel enable state*/ +#define TIMER_CCX_ENABLE ((uint32_t)0x00000001U) /*!< channel enable */ +#define TIMER_CCX_DISABLE ((uint32_t)0x00000000U) /*!< channel disable */ + +/* channel complementary output enable state*/ +#define TIMER_CCXN_ENABLE ((uint16_t)0x0004U) /*!< channel complementary enable */ +#define TIMER_CCXN_DISABLE ((uint16_t)0x0000U) /*!< channel complementary disable */ + +/* channel output polarity */ +#define TIMER_OC_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel output polarity is high */ +#define TIMER_OC_POLARITY_LOW ((uint16_t)0x0002U) /*!< channel output polarity is low */ + +/* channel complementary output polarity */ +#define TIMER_OCN_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel complementary output polarity is high */ +#define TIMER_OCN_POLARITY_LOW ((uint16_t)0x0008U) /*!< channel complementary output polarity is low */ + +/* idle state of channel output */ +#define TIMER_OC_IDLE_STATE_HIGH ((uint16_t)0x0100) /*!< idle state of channel output is high */ +#define TIMER_OC_IDLE_STATE_LOW ((uint16_t)0x0000) /*!< idle state of channel output is low */ + +/* idle state of channel complementary output */ +#define TIMER_OCN_IDLE_STATE_HIGH ((uint16_t)0x0200U) /*!< idle state of channel complementary output is high */ +#define TIMER_OCN_IDLE_STATE_LOW ((uint16_t)0x0000U) /*!< idle state of channel complementary output is low */ + +/* channel output compare mode */ +#define TIMER_OC_MODE_TIMING ((uint16_t)0x0000U) /*!< timing mode */ +#define TIMER_OC_MODE_ACTIVE ((uint16_t)0x0010U) /*!< active mode */ +#define TIMER_OC_MODE_INACTIVE ((uint16_t)0x0020U) /*!< inactive mode */ +#define TIMER_OC_MODE_TOGGLE ((uint16_t)0x0030U) /*!< toggle mode */ +#define TIMER_OC_MODE_LOW ((uint16_t)0x0040U) /*!< force low mode */ +#define TIMER_OC_MODE_HIGH ((uint16_t)0x0050U) /*!< force high mode */ +#define TIMER_OC_MODE_PWM0 ((uint16_t)0x0060U) /*!< PWM0 mode */ +#define TIMER_OC_MODE_PWM1 ((uint16_t)0x0070U) /*!< PWM1 mode*/ + +/* channel output compare shadow enable */ +#define TIMER_OC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< channel output shadow state enable */ +#define TIMER_OC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel output shadow state disable */ + +/* channel output compare fast enable */ +#define TIMER_OC_FAST_ENABLE ((uint16_t)0x0004) /*!< channel output fast function enable */ +#define TIMER_OC_FAST_DISABLE ((uint16_t)0x0000) /*!< channel output fast function disable */ + +/* channel output compare clear enable. */ +#define TIMER_OC_CLEAR_ENABLE ((uint16_t)0x0080U) /*!< channel output clear function enable */ +#define TIMER_OC_CLEAR_DISABLE ((uint16_t)0x0000U) /*!< channel output clear function disable */ + +/* channel control shadow register update control */ +#define TIMER_UPDATECTL_CCU ((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_CC0 CTL1_MMC(3) /*!< a capture or a compare match occurred in channal0 as trigger output TRGO */ +#define TIMER_TRI_OUT_SRC_O0CPRE CTL1_MMC(4) /*!< O0CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O1CPRE CTL1_MMC(5) /*!< O1CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O2CPRE CTL1_MMC(6) /*!< O2CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O3CPRE CTL1_MMC(7) /*!< O3CPRE as trigger output */ + +/* slave mode control */ +#define SMCFG_SMC(regval) (BITS(0, 2) & ((uint32_t)(regval) << 0U)) +#define TIMER_SLAVE_MODE_DISABLE SMCFG_SMC(0) /*!< slave mode disable */ +#define TIMER_ENCODER_MODE0 SMCFG_SMC(1) /*!< encoder mode 0 */ +#define TIMER_ENCODER_MODE1 SMCFG_SMC(2) /*!< encoder mode 1 */ +#define TIMER_ENCODER_MODE2 SMCFG_SMC(3) /*!< encoder mode 2 */ +#define TIMER_SLAVE_MODE_RESTART SMCFG_SMC(4) /*!< restart mode */ +#define TIMER_SLAVE_MODE_PAUSE SMCFG_SMC(5) /*!< pause mode */ +#define TIMER_SLAVE_MODE_EVENT SMCFG_SMC(6) /*!< event mode */ +#define TIMER_SLAVE_MODE_EXTERNAL0 SMCFG_SMC(7) /*!< external clock mode 0 */ + +/* master slave mode selection */ +#define TIMER_MASTER_SLAVE_MODE_ENABLE ((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 ((uint32_t)0x00000000U) /*!< 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 */ + +/* timer1 internal trigger input1 remap */ +#define TIMER1_IRMP(regval) (BITS(10, 11) & ((uint32_t)(regval) << 10U)) +#define TIMER1_ITI1_RMP_TIMER7_TRGO TIMER1_IRMP(0) /*!< timer1 internal trigger input 1 remap to TIMER7_TRGO */ +#define TIMER1_ITI1_RMP_ETHERNET_PTP TIMER1_IRMP(1) /*!< timer1 internal trigger input 1 remap to ethernet PTP */ +#define TIMER1_ITI1_RMP_USB_FS_SOF TIMER1_IRMP(2) /*!< timer1 internal trigger input 1 remap to USB FS SOF */ +#define TIMER1_ITI1_RMP_USB_HS_SOF TIMER1_IRMP(3) /*!< timer1 internal trigger input 1 remap to USB HS SOF */ + +/* timer4 channel 3 input remap */ +#define TIMER4_IRMP(regval) (BITS(6, 7) & ((uint32_t)(regval) << 6U)) +#define TIMER4_CI3_RMP_GPIO TIMER4_IRMP(0) /*!< timer4 channel 3 input remap to GPIO pin */ +#define TIMER4_CI3_RMP_IRC32K TIMER4_IRMP(1) /*!< timer4 channel 3 input remap to IRC32K */ +#define TIMER4_CI3_RMP_LXTAL TIMER4_IRMP(2) /*!< timer4 channel 3 input remap to LXTAL */ +#define TIMER4_CI3_RMP_RTC_WAKEUP_INT TIMER4_IRMP(3) /*!< timer4 channel 3 input remap to RTC wakeup interrupt */ + +/* timer10 internal trigger input1 remap */ +#define TIMER10_IRMP(regval) (BITS(0, 1) & ((uint32_t)(regval) << 0U)) +#define TIMER10_ITI1_RMP_GPIO TIMER10_IRMP(0) /*!< timer10 internal trigger input1 remap based on GPIO setting */ +#define TIMER10_ITI1_RMP_RTC_HXTAL_DIV TIMER10_IRMP(2) /*!< timer10 internal trigger input1 remap HXTAL _DIV(clock used for RTC which is HXTAL clock divided by RTCDIV bits in RCU_CFG0 register) */ + +/* timerx(x=0,1,2,13,14,15,16) write cc register selection */ +#define TIMER_CCSEL_DISABLE ((uint16_t)0x0000U) /*!< write CC register selection disable */ +#define TIMER_CCSEL_ENABLE ((uint16_t)0x0002U) /*!< write CC 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 */ + +/* 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* timer_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 timer_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 timer_prescaler,uint8_t timer_pscreload); +/* configure TIMER repetition register value */ +void timer_repetition_value_config(uint32_t timer_periph,uint16_t timer_repetition); +/* configure TIMER autoreload register value */ +void timer_autoreload_value_config(uint32_t timer_periph,uint32_t timer_autoreload); +/* configure TIMER counter register value */ +void timer_counter_value_config(uint32_t timer_periph , uint32_t timer_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 timer_spmode); +/* configure TIMER update source */ +void timer_update_source_config(uint32_t timer_periph,uint8_t timer_update); + +/* TIMER interrupt and flag*/ +/* enable the TIMER interrupt */ +void timer_interrupt_enable(uint32_t timer_periph,uint32_t timer_interrupt); +/* disable the TIMER interrupt */ +void timer_interrupt_disable(uint32_t timer_periph,uint32_t timer_interrupt); +/* get timer interrupt flag */ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph,uint32_t timer_interrupt); +/* clear TIMER interrupt flag */ +void timer_interrupt_flag_clear(uint32_t timer_periph,uint32_t timer_interrupt); +/* get TIMER flags */ +FlagStatus timer_flag_get(uint32_t timer_periph , uint32_t timer_flag); +/* clear TIMER flags */ +void timer_flag_clear(uint32_t timer_periph , uint32_t timer_flag); + +/* timer DMA and event*/ +/* enable the TIMER DMA */ +void timer_dma_enable(uint32_t timer_periph,uint16_t timer_dma); +/* disable the TIMER DMA */ +void timer_dma_disable(uint32_t timer_periph,uint16_t timer_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 timer_event); + +/* timer channel complementary protection */ +/* configure TIMER break function */ +void timer_break_config(uint32_t timer_periph,timer_break_parameter_struct* timer_bkdtpara); +/* 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 timer_ccuctl); + +/* TIMER channel output */ +/* configure TIMER channel output function */ +void timer_channel_output_config(uint32_t timer_periph,uint16_t timer_channel,timer_oc_parameter_struct* timer_ocpara); +/* configure TIMER channel output compare mode */ +void timer_channel_output_mode_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocmode); +/* configure TIMER channel output pulse value */ +void timer_channel_output_pulse_value_config(uint32_t timer_periph,uint16_t timer_channel,uint32_t timer_pluse); +/* configure TIMER channel output shadow function */ +void timer_channel_output_shadow_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocshadow); +/* configure TIMER channel output fast function */ +void timer_channel_output_fast_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocfast); +/* configure TIMER channel output clear function */ +void timer_channel_output_clear_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_occlear); +/* configure TIMER channel output polarity */ +void timer_channel_output_polarity_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocpolarity); +/* configure TIMER channel complementary output polarity */ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocnpolarity); +/* configure TIMER channel enable state */ +void timer_channel_output_state_config(uint32_t timer_periph,uint16_t timer_channel,uint32_t timer_state); +/* configure TIMER channel complementary output enable state */ +void timer_channel_complementary_output_state_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_ocnstate); + +/* TIMER channel input */ +/* configure TIMER input capture parameter */ +void timer_input_capture_config(uint32_t timer_periph,uint16_t timer_channel,timer_ic_parameter_struct* timer_icpara); +/* configure TIMER channel input capture prescaler value */ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph,uint16_t timer_channel,uint16_t timer_prescaler); +/* read TIMER channel capture compare register value */ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph,uint16_t timer_channel); +/* configure TIMER input pwm capture function */ +void timer_input_pwm_capture_config(uint32_t timer_periph,uint16_t timer_channel,timer_ic_parameter_struct* timer_icpwm); +/* configure TIMER hall sensor mode */ +void timer_hall_mode_config(uint32_t timer_periph,uint8_t timer_hallmode); + +/* TIMER master and slave */ +/* select TIMER input trigger source */ +void timer_input_trigger_source_select(uint32_t timer_periph,uint32_t timer_intrigger); +/* select TIMER master mode output trigger source */ +void timer_master_output_trigger_source_select(uint32_t timer_periph,uint32_t timer_outrigger); +/* select TIMER slave mode */ +void timer_slave_mode_select(uint32_t timer_periph,uint32_t timer_slavemode); +/* configure TIMER master slave mode */ +void timer_master_slave_mode_config(uint32_t timer_periph,uint8_t timer_masterslave); +/* configure TIMER external trigger input */ +void timer_external_trigger_config(uint32_t timer_periph,uint32_t timer_extprescaler,uint32_t timer_expolarity,uint32_t timer_extfilter); +/* configure TIMER quadrature decoder mode */ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph,uint32_t timer_decomode,uint16_t timer_ic0polarity,uint16_t timer_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 timer_intrigger); +/* configure TIMER the external trigger as external clock input */ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph,uint32_t timer_extrigger,uint16_t timer_expolarity,uint32_t timer_extfilter); +/* configure TIMER the external clock mode 0 */ +void timer_external_clock_mode0_config(uint32_t timer_periph,uint32_t timer_extprescaler,uint32_t timer_expolarity,uint32_t timer_extfilter); +/* configure TIMER the external clock mode 1 */ +void timer_external_clock_mode1_config(uint32_t timer_periph,uint32_t timer_extprescaler,uint32_t timer_expolarity,uint32_t timer_extfilter); +/* disable TIMER the external clock mode 1 */ +void timer_external_clock_mode1_disable(uint32_t timer_periph); +/* configure TIMER1 channel 0 remap function */ +void timer_channel_remap_config(uint32_t timer_periph,uint32_t timer_remap); + +/* TIMER configure */ +/* configure TIMER write CHxVAL register selection */ +void timer_write_cc_register_config(uint32_t timer_periph, uint16_t timer_ccsel); +/* configure TIMER output value selection */ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t timer_outsel); + +#endif /* GD32F4XX_TIMER_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h new file mode 100644 index 0000000000..f2f8f9d71e --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h @@ -0,0 +1,326 @@ +/*! + \file gd32f4xx_tli.h + \brief definitions for the TLI +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.1, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_TLI_H +#define GD32F4XX_TLI_H + +#include "gd32f4xx.h" + +/* TLI definitions */ +#define TLI TLI_BASE /*!< TLI base address */ +/* TLI layer definitions */ +#define LAYER0 TLI_BASE /*!< Layer0 base address */ +#define LAYER1 (TLI_BASE+0x80) /*!< Layer1 base address */ + +/* registers definitions */ +#define TLI_SPSZ REG32(TLI + 0x08U) /*!< TLI synchronous pulse size register */ +#define TLI_BPSZ REG32(TLI + 0x0CU) /*!< TLI back-porch size register */ +#define TLI_ASZ REG32(TLI + 0x10U) /*!< TLI active size register */ +#define TLI_TSZ REG32(TLI + 0x14U) /*!< TLI total size register */ +#define TLI_CTL REG32(TLI + 0x18U) /*!< TLI control register */ +#define TLI_RL REG32(TLI + 0x24U) /*!< TLI reload Layer register */ +#define TLI_BGC REG32(TLI + 0x2CU) /*!< TLI background color register */ +#define TLI_INTEN REG32(TLI + 0x34U) /*!< TLI interrupt enable register */ +#define TLI_INTF REG32(TLI + 0x38U) /*!< TLI interrupt flag register */ +#define TLI_INTC REG32(TLI + 0x3CU) /*!< TLI interrupt flag clear register */ +#define TLI_LM REG32(TLI + 0x40U) /*!< TLI line mark register */ +#define TLI_CPPOS REG32(TLI + 0x44U) /*!< TLI current pixel position register */ +#define TLI_STAT REG32(TLI + 0x48U) /*!< TLI status register */ +#define TLI_LxCTL(layerx) REG32((layerx) + 0x84U) /*!< TLI layer x control register */ +#define TLI_LxHPOS(layerx) REG32((layerx) + 0x88U) /*!< TLI layer x horizontal position parameters register */ +#define TLI_LxVPOS(layerx) REG32((layerx) + 0x8CU) /*!< TLI layer x vertical position parameters register */ +#define TLI_LxCKEY(layerx) REG32((layerx) + 0x90U) /*!< TLI layer x color key register */ +#define TLI_LxPPF(layerx) REG32((layerx) + 0x94U) /*!< TLI layer x packeted pixel format register */ +#define TLI_LxSA(layerx) REG32((layerx) + 0x98U) /*!< TLI layer x specified alpha register */ +#define TLI_LxDC(layerx) REG32((layerx) + 0x9CU) /*!< TLI layer x default color register */ +#define TLI_LxBLEND(layerx) REG32((layerx) + 0xA0U) /*!< TLI layer x blending register */ +#define TLI_LxFBADDR(layerx) REG32((layerx) + 0xACU) /*!< TLI layer x frame base address register */ +#define TLI_LxFLLEN(layerx) REG32((layerx) + 0xB0U) /*!< TLI layer x frame line length register */ +#define TLI_LxFTLN(layerx) REG32((layerx) + 0xB4U) /*!< TLI layer x frame total line number register */ +#define TLI_LxLUT(layerx) REG32((layerx) + 0xC4U) /*!< TLI ayer x Look Up Table register */ + + +/* bits definitions */ +/* TLI_SPSZ */ +#define TLI_SPSZ_VPSZ BITS(0,11) /*!< size of the vertical synchronous pulse */ +#define TLI_SPSZ_HPSZ BITS(16,27) /*!< size of the horizontal synchronous pulse */ + +/* TLI_BPSZ */ +#define TLI_BPSZ_VBPSZ BITS(0,11) /*!< size of the vertical back porch plus synchronous pulse */ +#define TLI_BPSZ_HBPSZ BITS(16,27) /*!< size of the horizontal back porch plus synchronous pulse */ + +/* TLI_ASZ */ +#define TLI_ASZ_VASZ BITS(0,11) /*!< size of the vertical active area width plus back porch and synchronous pulse */ +#define TLI_ASZ_HASZ BITS(16,27) /*!< size of the horizontal active area width plus back porch and synchronous pulse */ + +/* TLI_SPSZ */ +#define TLI_TSZ_VTSZ BITS(0,11) /*!< vertical total size of the display, including active area, back porch, synchronous pulse and front porch */ +#define TLI_TSZ_HTSZ BITS(16,27) /*!< horizontal total size of the display, including active area, back porch, synchronous pulse and front porch */ + +/* TLI_CTL */ +#define TLI_CTL_TLIEN BIT(0) /*!< TLI enable bit */ +#define TLI_CTL_BDB BITS(4,6) /*!< blue channel dither bits number */ +#define TLI_CTL_GDB BITS(8,10) /*!< green channel dither bits number */ +#define TLI_CTL_RDB BITS(12,14) /*!< red channel dither bits number */ +#define TLI_CTL_DFEN BIT(16) /*!< dither function enable */ +#define TLI_CTL_CLKPS BIT(28) /*!< pixel clock polarity selection */ +#define TLI_CTL_DEPS BIT(29) /*!< data enable polarity selection */ +#define TLI_CTL_VPPS BIT(30) /*!< vertical pulse polarity selection */ +#define TLI_CTL_HPPS BIT(31) /*!< horizontal pulse polarity selection */ + +/* TLI_RL */ +#define TLI_RL_RQR BIT(0) /*!< request reload */ +#define TLI_RL_FBR BIT(1) /*!< frame blank reload */ + +/* TLI_BGC */ +#define TLI_BGC_BVB BITS(0,7) /*!< background value blue */ +#define TLI_BGC_BVG BITS(8,15) /*!< background value green */ +#define TLI_BGC_BVR BITS(16,23) /*!< background value red */ + +/* TLI_INTEN */ +#define TLI_INTEN_LMIE BIT(0) /*!< line mark interrupt enable */ +#define TLI_INTEN_FEIE BIT(1) /*!< FIFO error interrupt enable */ +#define TLI_INTEN_TEIE BIT(2) /*!< transaction error interrupt enable */ +#define TLI_INTEN_LCRIE BIT(3) /*!< layer configuration reloaded interrupt enable */ + +/* TLI_INTF */ +#define TLI_INTF_LMF BIT(0) /*!< line mark flag */ +#define TLI_INTF_FEF BIT(1) /*!< FIFO error flag */ +#define TLI_INTF_TEF BIT(2) /*!< transaction error flag */ +#define TLI_INTF_LCRF BIT(3) /*!< layer configuration reloaded flag */ + +/* TLI_INTC */ +#define TLI_INTC_LMC BIT(0) /*!< line mark flag clear */ +#define TLI_INTC_FEC BIT(1) /*!< FIFO error flag clear */ +#define TLI_INTC_TEC BIT(2) /*!< transaction error flag clear */ +#define TLI_INTC_LCRC BIT(3) /*!< layer configuration reloaded flag clear */ + +/* TLI_LM */ +#define TLI_LM_LM BITS(0,10) /*!< line mark value */ + +/* TLI_CPPOS */ +#define TLI_CPPOS_VPOS BITS(0,15) /*!< vertical position */ +#define TLI_CPPOS_HPOS BITS(16,31) /*!< horizontal position */ + +/* TLI_STAT */ +#define TLI_STAT_VDE BIT(0) /*!< current VDE status */ +#define TLI_STAT_HDE BIT(1) /*!< current HDE status */ +#define TLI_STAT_VS BIT(2) /*!< current VS status of the TLI */ +#define TLI_STAT_HS BIT(3) /*!< current HS status of the TLI */ + +/* TLI_LxCTL */ +#define TLI_LxCTL_LEN BIT(0) /*!< layer enable */ +#define TLI_LxCTL_CKEYEN BIT(1) /*!< color keying enable */ +#define TLI_LxCTL_LUTEN BIT(4) /*!< LUT enable */ + +/* TLI_LxHPOS */ +#define TLI_LxHPOS_WLP BITS(0,11) /*!< window left position */ +#define TLI_LxHPOS_WRP BITS(16,27) /*!< window right position */ + +/* TLI_LxVPOS */ +#define TLI_LxVPOS_WTP BITS(0,11) /*!< window top position */ +#define TLI_LxVPOS_WBP BITS(16,27) /*!< window bottom position */ + +/* TLI_LxCKEY */ +#define TLI_LxCKEY_CKEYB BITS(0,7) /*!< color key blue */ +#define TLI_LxCKEY_CKEYG BITS(8,15) /*!< color key green */ +#define TLI_LxCKEY_CKEYR BITS(16,23) /*!< color key red */ + +/* TLI_LxPPF */ +#define TLI_LxPPF_PPF BITS(0,2) /*!< packeted pixel format */ + +/* TLI_LxSA */ +#define TLI_LxSA_SA BITS(0,7) /*!< specified alpha */ + +/* TLI_LxDC */ +#define TLI_LxDC_DCB BITS(0,7) /*!< the default color blue */ +#define TLI_LxDC_DCG BITS(8,15) /*!< the default color green */ +#define TLI_LxDC_DCR BITS(16,23) /*!< the default color red */ +#define TLI_LxDC_DCA BITS(24,31) /*!< the default color alpha */ + +/* TLI_LxBLEND */ +#define TLI_LxBLEND_ACF2 BITS(0,2) /*!< alpha calculation factor 2 of blending method */ +#define TLI_LxBLEND_ACF1 BITS(8,10) /*!< alpha calculation factor 1 of blending method */ + +/* TLI_LxFBADDR */ +#define TLI_LxFBADDR_FBADD BITS(0,31) /*!< frame buffer base address */ + +/* TLI_LxFLLEN */ +#define TLI_LxFLLEN_FLL BITS(0,12) /*!< frame line length */ +#define TLI_LxFLLEN_STDOFF BITS(16,28) /*!< frame buffer stride offset */ + +/* TLI_LxFTLN */ +#define TLI_LxFTLN_FTLN BITS(0,10) /*!< frame total line number */ + +/* TLI_LxLUT */ +#define TLI_LxLUT_TB BITS(0,7) /*!< blue channel of a LUT entry */ +#define TLI_LxLUT_TG BITS(8,15) /*!< green channel of a LUT entry */ +#define TLI_LxLUT_TR BITS(16,23) /*!< red channel of a LUT entry */ +#define TLI_LxLUT_TADD BITS(24,31) /*!< look up table write address */ + +/* constants definitions */ + +/* TLI parameter struct definitions */ +typedef struct +{ + uint32_t synpsz_vpsz; /*!< size of the vertical synchronous pulse */ + uint32_t synpsz_hpsz; /*!< size of the horizontal synchronous pulse */ + uint32_t backpsz_vbpsz; /*!< size of the vertical back porch plus synchronous pulse */ + uint32_t backpsz_hbpsz; /*!< size of the horizontal back porch plus synchronous pulse */ + uint32_t activesz_vasz; /*!< size of the vertical active area width plus back porch and synchronous pulse */ + uint32_t activesz_hasz; /*!< size of the horizontal active area width plus back porch and synchronous pulse */ + uint32_t totalsz_vtsz; /*!< vertical total size of the display */ + uint32_t totalsz_htsz; /*!< horizontal total size of the display */ + uint32_t backcolor_red; /*!< background value red */ + uint32_t backcolor_green; /*!< background value green */ + uint32_t backcolor_blue; /*!< background value blue */ + uint32_t signalpolarity_hs; /*!< horizontal pulse polarity selection */ + uint32_t signalpolarity_vs; /*!< vertical pulse polarity selection */ + uint32_t signalpolarity_de; /*!< data enable polarity selection */ + uint32_t signalpolarity_pixelck; /*!< pixel clock polarity selection */ +}tli_parameter_struct; + +/* TLI Layer parameter struct definitions */ +typedef struct +{ + uint32_t layer_window_rightpos; /*!< window right position */ + uint32_t layer_window_leftpos; /*!< window left position */ + uint32_t layer_window_bottompos; /*!< window bottom position */ + uint32_t layer_window_toppos; /*!< window top position */ + uint32_t layer_ppf; /*!< packeted pixel format */ + uint32_t layer_sa; /*!< specified alpha */ + uint32_t layer_default_alpha; /*!< the default color alpha */ + uint32_t layer_default_red; /*!< the default color red */ + uint32_t layer_default_green; /*!< the default color green */ + uint32_t layer_default_blue; /*!< the default color blue */ + uint32_t layer_acf1; /*!< alpha calculation factor 1 of blending method */ + uint32_t layer_acf2; /*!< alpha calculation factor 2 of blending method */ + uint32_t layer_frame_bufaddr; /*!< frame buffer base address */ + uint32_t layer_frame_buf_stride_offset; /*!< frame buffer stride offset */ + uint32_t layer_frame_line_length; /*!< frame line length */ + uint32_t layer_frame_total_line_number; /*!< frame total line number */ +}tli_layer_parameter_struct; + +/* TLI layer LUT parameter struct definitions */ +typedef struct +{ + uint32_t layer_table_addr; /*!< look up table write address */ + uint32_t layer_lut_channel_red; /*!< red channel of a LUT entry */ + uint32_t layer_lut_channel_green; /*!< green channel of a LUT entry */ + uint32_t layer_lut_channel_blue; /*!< blue channel of a LUT entry */ +}tli_layer_lut_parameter_struct; + +/* packeted pixel format */ +typedef enum +{ + LAYER_PPF_ARGB8888, /*!< layerx pixel format ARGB8888 */ + LAYER_PPF_RGB888, /*!< layerx pixel format RGB888 */ + LAYER_PPF_RGB565, /*!< layerx pixel format RGB565 */ + LAYER_PPF_ARGB1555, /*!< layerx pixel format ARGB1555 */ + LAYER_PPF_ARGB4444, /*!< layerx pixel format ARGB4444 */ + LAYER_PPF_L8, /*!< layerx pixel format L8 */ + LAYER_PPF_AL44, /*!< layerx pixel format AL44 */ + LAYER_PPF_AL88 /*!< layerx pixel format AL88 */ +} tli_layer_ppf_enum; + +/* layer reload configure */ +#define TLI_FRAME_BLANK_RELOAD_EN ((uint8_t)0x00U) /*!< the layer configuration will be reloaded at frame blank */ +#define TLI_REQUEST_RELOAD_EN ((uint8_t)0x01U) /*!< the layer configuration will be reloaded after this bit sets */ + +/* dither Function */ +#define TLI_DITHER_DISABLE ((uint8_t)0x00U) /*!< dither function disable */ +#define TLI_DITHER_ENABLE ((uint8_t)0x01U) /*!< dither function enable */ + +/* horizontal pulse polarity selection */ + +#define TLI_HSYN_ACTLIVE_LOW ((uint32_t)0x00000000U) /*!< horizontal synchronous pulse active low */ +#define TLI_HSYN_ACTLIVE_HIGHT TLI_CTL_HPPS /*!< horizontal synchronous pulse active high */ + + +/* vertical pulse polarity selection */ + +#define TLI_VSYN_ACTLIVE_LOW ((uint32_t)0x00000000U) /*!< vertical synchronous pulse active low */ +#define TLI_VSYN_ACTLIVE_HIGHT TLI_CTL_VPPS /*!< vertical synchronous pulse active high */ + + +/* pixel Clock Polarity Selection */ + +#define TLI_PIXEL_CLOCK_TLI ((uint32_t)0x00000000U) /*!< pixel clock is TLI clock */ +#define TLI_PIXEL_CLOCK_INVERTEDTLI TLI_CTL_CLKPS /*!< pixel clock is inverted TLI clock */ + + +/* data Enable Polarity Selection */ + +#define TLI_DE_ACTLIVE_LOW ((uint32_t)0x00000000U) /*!< data enable active low */ +#define TLI_DE_ACTLIVE_HIGHT TLI_CTL_DEPS /*!< data enable active high */ + +/* alpha calculation factor 1 of blending method */ +#define LxBLEND_ACF1(regval) (BITS(8,10) & ((regval)<<8)) +#define LAYER_ACF1_SA LxBLEND_ACF1(4) /*!< normalization specified alpha */ +#define LAYER_ACF1_PASA LxBLEND_ACF1(6) /*!< normalization pixel alpha * normalization specified alpha */ + +/* alpha calculation factor 2 of blending method*/ +#define LxBLEND_ACF2(regval) (BITS(0,2) & ((regval))) +#define LAYER_ACF2_SA LxBLEND_ACF2(5) /*!< normalization specified alpha */ +#define LAYER_ACF2_PASA LxBLEND_ACF2(7) /*!< normalization pixel alpha x normalization specified alpha */ +/* function declarations */ + +/* deinitialize TLI */ +void tli_deinit(void); +/* initialize TLI */ +void tli_init(tli_parameter_struct *tli_struct); +/* TLI dither function enable */ +void tli_dither_config(uint8_t ditherstat); +/* enable TLI */ +void tli_enable(void); +/* disable TLI */ +void tli_disable(void); +/* TLI reload mode config*/ +void tli_reload_config(uint8_t reloadmod); + +/* TLI interrupt enable */ +void tli_interrupt_enable(uint32_t inttype); +/* TLI interrupt disable */ +void tli_interrupt_disable(uint32_t inttype); +/* get TLI interrupt flag */ +FlagStatus tli_interrupt_flag_get(uint32_t intflag); +/* clear TLI interrupt flag */ +void tli_interrupt_flag_clear(uint32_t intflag); + +/* set line mark value */ +void tli_line_mark_set(uint32_t linenum); +/* get current displayed position */ +uint32_t tli_current_pos_get(void); +/* get TLI state */ +FlagStatus tli_flag_get(uint32_t state); + +/* TLI layer enable */ +void tli_layer_enable(uint32_t layerx); +/* TLI layer disable */ +void tli_layer_disable(uint32_t layerx); +/* TLI layer color keying enable */ +void tli_color_key_enable(uint32_t layerx); +/* TLI layer color keying disable */ +void tli_color_key_disable(uint32_t layerx); +/* TLI layer LUT enable */ +void tli_lut_enable(uint32_t layerx); +/* TLI layer LUT disable */ +void tli_lut_disable(uint32_t layerx); +/* TLI layer initialize */ +void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct); +/* TLI layer initialize */ +void tli_layer_window_offset_modify(uint32_t layerx,uint32_t offset_x,uint32_t offset_y); +/* TLI layer lut initialize */ +void tli_lut_init(uint32_t layerx,tli_layer_lut_parameter_struct *lut_struct); +/* TLI layer key initialize */ +void tli_ckey_init(uint32_t layerx,uint32_t redkey,uint32_t greenkey,uint32_t bluekey); + +#endif /* GD32F4XX_TLI_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h new file mode 100644 index 0000000000..7925b91af3 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h @@ -0,0 +1,78 @@ +/*! + \file gd32f4xx_trng.h + \brief definitions for the TRNG +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_TRNG_H +#define GD32F4XX_TRNG_H + +#include "gd32f4xx.h" + +/* EXTI definitions */ +#define TRNG TRNG_BASE + +/* registers definitions */ +#define TRNG_CTL REG32(TRNG + 0x00U) /*!< interrupt enable register */ +#define TRNG_STAT REG32(TRNG + 0x04U) /*!< event enable register */ +#define TRNG_DATA REG32(TRNG + 0x08U) /*!< rising edge trigger enable register */ + +/* bits definitions */ +/* TRNG_CTL */ +#define TRNG_CTL_TRNGEN BIT(2) /*!< TRNG enable bit */ +#define TRNG_CTL_IE BIT(3) /*!< interrupt enable bit */ + +/* TRNG_STAT */ +#define TRNG_STAT_DRDY BIT(0) /*!< random data ready status bit */ +#define TRNG_STAT_CECS BIT(1) /*!< clock error current status */ +#define TRNG_STAT_SECS BIT(2) /*!< seed error current status */ +#define TRNG_STAT_CEIF BIT(5) /*!< clock error interrupt flag */ +#define TRNG_STAT_SEIF BIT(6) /*!< seed error interrupt flag */ + +/* TRNG_DATA */ +#define TRNG_DATA_TRNDATA BITS(0,31) /*!< 32-Bit Random data */ + +/* constants definitions */ +/* trng status flag */ +typedef enum +{ + TRNG_FLAG_DRDY = TRNG_STAT_DRDY, /*!< random Data ready status */ + TRNG_FLAG_CECS = TRNG_STAT_CECS, /*!< clock error current status */ + TRNG_FLAG_SECS = TRNG_STAT_SECS /*!< seed error current status */ +}trng_flag_enum; + +/* trng inerrupt flag */ +typedef enum +{ + TRNG_INT_FLAG_CEIF = TRNG_STAT_CEIF, /*!< clock error interrupt flag */ + TRNG_INT_FLAG_SEIF = TRNG_STAT_SEIF /*!< seed error interrupt flag */ +}trng_int_flag_enum; + +/* function declarations */ +/* deinitialize the TRNG */ +void trng_deinit(void); +/* enable the TRNG interface */ +void trng_enable(void); +/* disable the TRNG interface */ +void trng_disable(void); +/* get the true random data */ +uint32_t trng_get_true_random_data(void); +/* get the trng status flags */ +FlagStatus trng_flag_get(trng_flag_enum flag); +/* clear the trng status flags */ +void trng_flag_clear(trng_flag_enum flag); +/* the trng interrupt enable */ +void trng_interrupt_enable(void); +/* the trng interrupt disable */ +void trng_interrupt_disable(void); +/* get the trng interrupt flags */ +FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag); +/* clear the trng interrupt flags */ +void trng_interrupt_flag_clear(trng_int_flag_enum int_flag); + +#endif /* GD32F4XX_TRNG_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h new file mode 100644 index 0000000000..5350f5e5b5 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h @@ -0,0 +1,467 @@ +/*! + \file gd32f4xx_usart.h + \brief definitions for the USART +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_USART_H +#define GD32F4XX_USART_H + +#include "gd32f4xx.h" + +/* USARTx(x=0,1) definitions */ +#define USART1 USART_BASE +#define USART2 (USART_BASE+0x00000400U) /*!< USART2 base address */ +#define UART3 (USART_BASE+0x00000800U) /*!< UART3 base address */ +#define UART4 (USART_BASE+0x00000C00U) /*!< UART4 base address */ +#define UART6 (USART_BASE+0x00003400U) /*!< UART6 base address */ +#define UART7 (USART_BASE+0x00003800U) /*!< UART7 base address */ +#define USART0 (USART_BASE+0x0000CC00U) /*!< USART0 base address */ +#define USART5 (USART_BASE+0x0000D000U) /*!< USART5 base address */ + +/* registers definitions */ +#define USART_STAT0(usartx) REG32((usartx) + 0x00U) /*!< USART status register 0 */ +#define USART_DATA(usartx) REG32((usartx) + 0x04U) /*!< USART data register */ +#define USART_BAUD(usartx) REG32((usartx) + 0x08U) /*!< USART baud rate register */ +#define USART_CTL0(usartx) REG32((usartx) + 0x0CU) /*!< USART control register 0 */ +#define USART_CTL1(usartx) REG32((usartx) + 0x10U) /*!< USART control register 1 */ +#define USART_CTL2(usartx) REG32((usartx) + 0x14U) /*!< USART control register 2 */ +#define USART_GP(usartx) REG32((usartx) + 0x18U) /*!< USART guard time and prescaler register */ +#define USART_CTL3(usartx) REG32((usartx) + 0x80U) /*!< USART control register 3 */ +#define USART_RT(usartx) REG32((usartx) + 0x84U) /*!< USART receiver timeout register */ +#define USART_STAT1(usartx) REG32((usartx) + 0x88U) /*!< USART status register 1 */ +#define USART_CHC(usartx) REG32((usartx) + 0xC0U) /*!< USART coherence control register */ + +/* bits definitions */ +/* USARTx_STAT0 */ +#define USART_STAT0_PERR BIT(0) /*!< parity error flag */ +#define USART_STAT0_FERR BIT(1) /*!< frame error flag */ +#define USART_STAT0_NERR BIT(2) /*!< noise error flag */ +#define USART_STAT0_ORERR BIT(3) /*!< overrun error */ +#define USART_STAT0_IDLEF BIT(4) /*!< IDLE frame detected flag */ +#define USART_STAT0_RBNE BIT(5) /*!< read data buffer not empty */ +#define USART_STAT0_TC BIT(6) /*!< transmission complete */ +#define USART_STAT0_TBE BIT(7) /*!< transmit data buffer empty */ +#define USART_STAT0_LBDF BIT(8) /*!< LIN break detected flag */ +#define USART_STAT0_CTSF BIT(9) /*!< CTS change flag */ + +/* USARTx_DATA */ +#define USART_DATA_DATA BITS(0,8) /*!< transmit or read data value */ + +/* USARTx_BAUD */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction part of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer part of baud-rate divider */ + +/* USARTx_CTL0 */ +#define USART_CTL0_SBKCMD BIT(0) /*!< send break command */ +#define USART_CTL0_RWU BIT(1) /*!< receiver wakeup from mute mode */ +#define USART_CTL0_REN BIT(2) /*!< receiver enable */ +#define USART_CTL0_TEN BIT(3) /*!< transmitter enable */ +#define USART_CTL0_IDLEIE BIT(4) /*!< idle line detected interrupt enable */ +#define USART_CTL0_RBNEIE BIT(5) /*!< read data buffer not empty interrupt and overrun error interrupt enable */ +#define USART_CTL0_TCIE BIT(6) /*!< transmission complete interrupt enable */ +#define USART_CTL0_TBEIE BIT(7) /*!< transmitter buffer empty interrupt enable */ +#define USART_CTL0_PERRIE BIT(8) /*!< parity error interrupt enable */ +#define USART_CTL0_PM BIT(9) /*!< parity mode */ +#define USART_CTL0_PCEN BIT(10) /*!< parity check function enable */ +#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL BIT(12) /*!< word length */ +#define USART_CTL0_UEN BIT(13) /*!< USART enable */ +#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ + +/* USARTx_CTL1 */ +#define USART_CTL1_ADDR BITS(0,3) /*!< address of USART */ +#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ +#define USART_CTL1_LBDIE BIT(6) /*!< LIN break detected interrupt eanble */ +#define USART_CTL1_CLEN BIT(8) /*!< CK length */ +#define USART_CTL1_CPH BIT(9) /*!< CK phase */ +#define USART_CTL1_CPL BIT(10) /*!< CK polarity */ +#define USART_CTL1_CKEN BIT(11) /*!< CK pin enable */ +#define USART_CTL1_STB BITS(12,13) /*!< STOP bits length */ +#define USART_CTL1_LMEN BIT(14) /*!< LIN mode enable */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< error interrupt enable */ +#define USART_CTL2_IREN BIT(1) /*!< IrDA mode enable */ +#define USART_CTL2_IRLP BIT(2) /*!< IrDA low-power */ +#define USART_CTL2_HDEN BIT(3) /*!< half-duplex enable */ +#define USART_CTL2_NKEN BIT(4) /*!< NACK enable in smartcard mode */ +#define USART_CTL2_SCEN BIT(5) /*!< smartcard mode enable */ +#define USART_CTL2_DENR BIT(6) /*!< DMA request enable for reception */ +#define USART_CTL2_DENT BIT(7) /*!< DMA request enable for transmission */ +#define USART_CTL2_RTSEN BIT(8) /*!< RTS enable */ +#define USART_CTL2_CTSEN BIT(9) /*!< CTS enable */ +#define USART_CTL2_CTSIE BIT(10) /*!< CTS interrupt enable */ +#define USART_CTL2_OSB BIT(11) /*!< one sample bit method */ + +/* USARTx_GP */ +#define USART_GP_PSC BITS(0,7) /*!< prescaler value for dividing the system clock */ +#define USART_GP_GUAT BITS(8,15) /*!< guard time value in smartcard mode */ + +/* USARTx_CTL3 */ +#define USART_CTL3_RTEN BIT(0) /*!< receiver timeout enable */ +#define USART_CTL3_SCRTNUM BITS(1,3) /*!< smartcard auto-retry number */ +#define USART_CTL3_RTIE BIT(4) /*!< interrupt enable bit of receive timeout event */ +#define USART_CTL3_EBIE BIT(5) /*!< interrupt enable bit of end of block event */ +#define USART_CTL3_RINV BIT(8) /*!< RX pin level inversion */ +#define USART_CTL3_TINV BIT(9) /*!< TX pin level inversion */ +#define USART_CTL3_DINV BIT(10) /*!< data bit level inversion */ +#define USART_CTL3_MSBF BIT(11) /*!< most significant bit first */ + +/* USARTx_RT */ +#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ +#define USART_RT_BL BITS(24,31) /*!< block length */ + +/* USARTx_STAT1 */ +#define USART_STAT1_RTF BIT(11) /*!< receiver timeout flag */ +#define USART_STAT1_EBF BIT(12) /*!< end of block flag */ +#define USART_STAT1_BSY BIT(16) /*!< busy flag */ + +/* USARTx_CHC */ +#define USART_CHC_HCM BIT(0) /*!< hardware flow control coherence mode */ +#define USART_CHC_PCM BIT(1) /*!< parity check coherence mode */ +#define USART_CHC_BCM BIT(2) /*!< break frame coherence mode */ +#define USART_CHC_EPERR BIT(8) /*!< early parity error flag */ + +/* constants definitions */ +/* define the USART bit position and its register index offset */ +#define USART_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define USART_REG_VAL(usartx, offset) (REG32((usartx) + ((uint32_t)(offset) >> 6))) +#define USART_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +/* register offset */ +#define STAT0_REG_OFFSET 0x00U /*!< STAT0 register offset */ +#define STAT1_REG_OFFSET 0x88U /*!< STAT1 register offset */ +#define CHC_REG_OFFSET 0xC0U /*!< CHC register offset */ +#define CTL0_REG_OFFSET 0x0CU /*!< CTL0 register offset */ +#define CTL1_REG_OFFSET 0x10U /*!< CTL1 register offset */ +#define CTL2_REG_OFFSET 0x14U /*!< CTL2 register offset */ +#define CTL3_REG_OFFSET 0x80U /*!< CTL2 register offset */ + +/* USART flags */ +typedef enum +{ + /* flags in STAT0 register */ + USART_FLAG_CTSF = USART_REGIDX_BIT(STAT0_REG_OFFSET, 9U), /*!< CTS change flag */ + USART_FLAG_LBDF = USART_REGIDX_BIT(STAT0_REG_OFFSET, 8U), /*!< LIN break detected flag */ + USART_FLAG_TBE = USART_REGIDX_BIT(STAT0_REG_OFFSET, 7U), /*!< transmit data buffer empty */ + USART_FLAG_TC = USART_REGIDX_BIT(STAT0_REG_OFFSET, 6U), /*!< transmission complete */ + USART_FLAG_RBNE = USART_REGIDX_BIT(STAT0_REG_OFFSET, 5U), /*!< read data buffer not empty */ + USART_FLAG_IDLEF = USART_REGIDX_BIT(STAT0_REG_OFFSET, 4U), /*!< IDLE frame detected flag */ + USART_FLAG_ORERR = USART_REGIDX_BIT(STAT0_REG_OFFSET, 3U), /*!< overrun error */ + USART_FLAG_NERR = USART_REGIDX_BIT(STAT0_REG_OFFSET, 2U), /*!< noise error flag */ + USART_FLAG_FERR = USART_REGIDX_BIT(STAT0_REG_OFFSET, 1U), /*!< frame error flag */ + USART_FLAG_PERR = USART_REGIDX_BIT(STAT0_REG_OFFSET, 0U), /*!< parity error flag */ + /* flags in STAT1 register */ + USART_FLAG_BSY = USART_REGIDX_BIT(STAT1_REG_OFFSET, 16U), /*!< busy flag */ + USART_FLAG_EBF = USART_REGIDX_BIT(STAT1_REG_OFFSET, 12U), /*!< end of block flag */ + USART_FLAG_RTF = USART_REGIDX_BIT(STAT1_REG_OFFSET, 11U), /*!< receiver timeout flag */ + /* flags in CHC register */ + USART_FLAG_EPERR = USART_REGIDX_BIT(CHC_REG_OFFSET, 8U), /*!< early parity error flag */ +}usart_flag_enum; + +/* USART interrupt flags */ +typedef enum +{ + /* interrupt flags in CTL0 register */ + USART_INT_PERRIE = USART_REGIDX_BIT(CTL0_REG_OFFSET, 8U), /*!< parity error interrupt */ + USART_INT_TBEIE = USART_REGIDX_BIT(CTL0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt */ + USART_INT_TCIE = USART_REGIDX_BIT(CTL0_REG_OFFSET, 6U), /*!< transmission complete interrupt */ + USART_INT_RBNEIE = USART_REGIDX_BIT(CTL0_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and overrun error interrupt */ + USART_INT_IDLEIE = USART_REGIDX_BIT(CTL0_REG_OFFSET, 4U), /*!< IDLE line detected interrupt */ + /* interrupt flags in CTL1 register */ + USART_INT_LBDIE = USART_REGIDX_BIT(CTL1_REG_OFFSET, 6U), /*!< LIN break detected interrupt */ + /* interrupt flags in CTL2 register */ + USART_INT_CTSIE = USART_REGIDX_BIT(CTL2_REG_OFFSET, 10U), /*!< CTS interrupt */ + USART_INT_ERRIE = USART_REGIDX_BIT(CTL2_REG_OFFSET, 0U), /*!< error interrupt */ + /* interrupt flags in CTL3 register */ + USART_INT_EBIE = USART_REGIDX_BIT(CTL3_REG_OFFSET, 5U), /*!< interrupt enable bit of end of block event */ + USART_INT_RTIE = USART_REGIDX_BIT(CTL3_REG_OFFSET, 4U), /*!< interrupt enable bit of receive timeout event */ +}usart_interrupt_flag_enum; + +/* USART invert configure */ +typedef enum +{ + /* data bit level inversion */ + USART_DINV_ENABLE, /*!< data bit level inversion */ + USART_DINV_DISABLE, /*!< data bit level not inversion */ + /* TX pin level inversion */ + USART_TXPIN_ENABLE, /*!< TX pin level inversion */ + USART_TXPIN_DISABLE, /*!< TX pin level not inversion */ + /* RX pin level inversion */ + USART_RXPIN_ENABLE, /*!< RX pin level inversion */ + USART_RXPIN_DISABLE, /*!< RX pin level not inversion */ +}usart_invert_enum; + +/* USART receiver configure */ +#define CTL0_REN(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_RECEIVE_ENABLE CTL0_REN(1) /*!< enable receiver */ +#define USART_RECEIVE_DISABLE CTL0_REN(0) /*!< disable receiver */ + +/* USART transmitter configure */ +#define CTL0_TEN(regval) (BIT(3) & ((uint32_t)(regval) << 3)) +#define USART_TRANSMIT_ENABLE CTL0_TEN(1) /*!< enable transmitter */ +#define USART_TRANSMIT_DISABLE CTL0_TEN(0) /*!< disable transmitter */ + +/* USART parity bits definitions */ +#define CTL0_PM(regval) (BITS(9,10) & ((uint32_t)(regval) << 9)) +#define USART_PM_NONE CTL0_PM(0) /*!< no parity */ +#define USART_PM_ODD CTL0_PM(2) /*!< odd parity */ +#define USART_PM_EVEN CTL0_PM(3) /*!< even parity */ + +/* USART wakeup method in mute mode */ +#define CTL0_WM(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_WM_IDLE CTL0_WM(0) /*!< idle Line */ +#define USART_WM_ADDR CTL0_WM(1) /*!< address mask */ + +/* USART word length definitions */ +#define CTL0_WL(regval) (BIT(12) & ((uint32_t)(regval) << 12)) +#define USART_WL_8BIT CTL0_WL(0) /*!< 8 bits */ +#define USART_WL_9BIT CTL0_WL(1) /*!< 9 bits */ + +/* USART oversampling mode definitions */ +#define CTL0_OVSMOD(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_OVSMOD_16 CTL0_OVSMOD(0) /*!< 16 bits */ +#define USART_OVSMOD_8 CTL0_OVSMOD(1) /*!< 8 bits */ + +/* USART stop bits definitions */ +#define CTL1_STB(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define USART_STB_1BIT CTL1_STB(0) /*!< 1 bit */ +#define USART_STB_0_5BIT CTL1_STB(1) /*!< 0.5 bit */ +#define USART_STB_2BIT CTL1_STB(2) /*!< 2 bits */ +#define USART_STB_1_5BIT CTL1_STB(3) /*!< 1.5 bits */ + +/* USART LIN break frame length */ +#define CTL1_LBLEN(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define USART_LBLEN_10B CTL1_LBLEN(0) /*!< 10 bits */ +#define USART_LBLEN_11B CTL1_LBLEN(1) /*!< 11 bits */ + +/* USART CK length */ +#define CTL1_CLEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_CLEN_NONE CTL1_CLEN(0) /*!< there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame */ +#define USART_CLEN_EN CTL1_CLEN(1) /*!< there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame */ + +/* USART clock phase */ +#define CTL1_CPH(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CPH_1CK CTL1_CPH(0) /*!< first clock transition is the first data capture edge */ +#define USART_CPH_2CK CTL1_CPH(1) /*!< second clock transition is the first data capture edge */ + +/* USART clock polarity */ +#define CTL1_CPL(regval) (BIT(10) & ((uint32_t)(regval) << 10)) +#define USART_CPL_LOW CTL1_CPL(0) /*!< steady low value on CK pin */ +#define USART_CPL_HIGH CTL1_CPL(1) /*!< steady high value on CK pin */ + +/* USART DMA request for receive configure */ +#define CLT2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define USART_DENR_ENABLE CLT2_DENR(1) /*!< DMA request enable for reception */ +#define USART_DENR_DISABLE CLT2_DENR(0) /*!< DMA request disable for reception */ + +/* USART DMA request for transmission configure */ +#define CLT2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_DENT_ENABLE CLT2_DENT(1) /*!< DMA request enable for transmission */ +#define USART_DENT_DISABLE CLT2_DENT(0) /*!< DMA request disable for transmission */ + +/* USART RTS configure */ +#define CLT2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CLT2_RTSEN(1) /*!< RTS enable */ +#define USART_RTS_DISABLE CLT2_RTSEN(0) /*!< RTS disable */ + +/* USART CTS configure */ +#define CLT2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CLT2_CTSEN(1) /*!< CTS enable */ +#define USART_CTS_DISABLE CLT2_CTSEN(0) /*!< CTS disable */ + +/* USART one sample bit method configure */ +#define CTL2_OSB(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_OSB_1bit CTL2_OSB(1) /*!< 1 bit */ +#define USART_OSB_3bit CTL2_OSB(0) /*!< 3 bits */ + +/* USART IrDA low-power enable */ +#define CTL2_IRLP(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_IRLP_LOW CTL2_IRLP(1) /*!< low-power */ +#define USART_IRLP_NORMAL CTL2_IRLP(0) /*!< normal */ + +/* USART data is transmitted/received with the LSB/MSB first */ +#define CTL3_MSBF(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_MSBF_LSB CTL3_MSBF(0) /*!< LSB first */ +#define USART_MSBF_MSB CTL3_MSBF(1) /*!< MSB first */ + +/* break frame coherence mode */ +#define CHC_BCM(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_BCM_NONE CHC_BCM(0) /*!< no parity error is detected */ +#define USART_BCM_EN CHC_BCM(1) /*!< parity error is detected */ + +/* USART parity check coherence mode */ +#define CHC_PCM(regval) (BIT(1) & ((uint32_t)(regval) << 1)) +#define USART_PCM_NONE CHC_PCM(0) /*!< not check parity */ +#define USART_PCM_EN CHC_PCM(1) /*!< check the parity */ + +/* USART hardware flow control coherence mode */ +#define CHC_HCM(regval) (BIT(0) & ((uint32_t)(regval) << 0)) +#define USART_HCM_NONE CHC_HCM(0) /*!< nRTS signal equals to the rxne status register */ +#define USART_HCM_EN CHC_HCM(1) /*!< nRTS signal is set when the last data bit has been sampled */ + +/* interrupt enable in USART_CTL0 */ +#define USART_INTEN_PERRIE ((uint32_t)0x10000100U) /*!< parity error interrupt */ +#define USART_INTEN_TBEIE ((uint32_t)0x10000080U) /*!< transmitter buffer empty interrupt */ +#define USART_INTEN_TCIE ((uint32_t)0x10000040U) /*!< transmission complete interrupt */ +#define USART_INTEN_RBNEIE ((uint32_t)0x10000020U) /*!< read data buffer not empty interrupt and overrun error interrupt */ +#define USART_INTEN_IDLEIE ((uint32_t)0x10000010U) /*!< IDLE line detected interrupt */ + +/* interrupt enable flag in USART_CTL1 */ +#define USART_INTEN_LBDIE ((uint32_t)0x20000040U) /*!< LIN break detected interrupt */ + +/* interrupt enable flag in USART_CTL2 */ +#define USART_INTEN_ERRIE ((uint32_t)0x40000001U) /*!< error interrupt */ +#define USART_INTEN_CTSIE ((uint32_t)0x40000400U) /*!< CTS interrupt*/ + +/* interrupt enable flag in USART_CTL3 */ +#define USART_INTEN_RTIE ((uint32_t)0x80000010U) /*!< interrupt enable bit of receive timeout event */ +#define USART_INTEN_EBIE ((uint32_t)0x80000020U) /*!< interrupt enable bit of end of block event */ + +#define USART_INTEN_MASK ((uint32_t)0x00000FFFU) /*!< USART interrupt mask */ +#define USART_INTS_CTL0 ((uint32_t)0x10000000U) /*!< interrupt in USART_CTL0 */ +#define USART_INTS_CTL1 ((uint32_t)0x20000000U) /*!< interrupt in USART_CTL1 */ +#define USART_INTS_CTL2 ((uint32_t)0x40000000U) /*!< interrupt in USART_CTL2 */ +#define USART_INTS_CTL3 ((uint32_t)0x80000000U) /*!< interrupt in USART_CTL3 */ + +/* 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); +/* data is transmitted/received with the LSB/MSB first */ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf); +/* configure USART inverted */ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara); +/* configure the USART oversample mode */ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp); +/* configure sample bit method */ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t obsm); +/* enable receiver timeout */ +void usart_receiver_timeout_enable(uint32_t usart_periph); +/* disable receiver timeout */ +void usart_receiver_timeout_disable(uint32_t usart_periph); +/* configure receiver timeout threshold */ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout); +/* USART transmit data function */ +void usart_data_transmit(uint32_t usart_periph, uint32_t data); +/* USART receive data function */ +uint16_t usart_data_receive(uint32_t usart_periph); + +/* multi-processor communication */ +/* configure address of the USART */ +void usart_address_config(uint32_t usart_periph, uint8_t addr); +/* enable mute mode */ +void usart_mute_mode_enable(uint32_t usart_periph); +/* disable mute mode */ +void usart_mute_mode_disable(uint32_t usart_periph); +/* configure wakeup method in mute mode */ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmehtod); + +/* LIN mode communication */ +/* 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); +/* send break frame */ +void usart_send_break(uint32_t usart_periph); + +/* 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_synchronous_clock_enable(uint32_t usart_periph); +/* clock disable */ +void usart_synchronous_clock_disable(uint32_t usart_periph); +/* configure usart synchronous mode parameters */ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl); + +/* smartcard communication */ +/* guard time value configure in smartcard mode */ +void usart_guard_time_config(uint32_t usart_periph,uint32_t gaut); +/* 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); +/* smartcard auto-retry number configure */ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum); +/* block length configure */ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl); + +/* IrDA communication */ +/* enable IrDA mode */ +void usart_irda_mode_enable(uint32_t usart_periph); +/* disable IrDA mode */ +void usart_irda_mode_disable(uint32_t usart_periph); +/* configure the peripheral clock prescaler */ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc); +/* configure IrDA low-power */ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp); + +/* hardware flow communication */ +/* configure hardware flow control RTS */ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig); +/* configure hardware flow control CTS */ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig); + +/* coherence control */ +/* configure break frame coherence mode */ +void usart_break_frame_coherence_config(uint32_t usart_periph, uint32_t bcm); +/* configure parity check coherence mode */ +void usart_parity_check_coherence_config(uint32_t usart_periph, uint32_t pcm); +/* configure hardware flow control coherence mode */ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm); + +/* configure USART DMA for reception */ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd); +/* configure USART DMA for transmission */ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd); + +/* flag functions */ +/* get flag in STAT0/STAT1/CHC register */ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag); +/* clear flag in STAT0/STAT1/CHC register */ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag); + +/* interrupt functions */ +/* enable USART interrupt */ +void usart_interrupt_enable(uint32_t usart_periph, uint32_t int_flag); +/* disable USART interrupt */ +void usart_interrupt_disable(uint32_t usart_periph, uint32_t int_flag); +/* get USART interrupt enable flag */ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag); + +#endif /* GD32F4XX_USART_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h new file mode 100644 index 0000000000..d76cbce32c --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h @@ -0,0 +1,63 @@ +/*! + \file gd32f4xx_wwdgt.h + \brief definitions for the WWDGT +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_WWDGT_H +#define GD32F4XX_WWDGT_H + +#include "gd32f4xx.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE + +/* registers definitions */ +#define WWDGT_CTL REG32((WWDGT) + 0x00U) /*!< WWDGT control register */ +#define WWDGT_CFG REG32((WWDGT) + 0x04U) /*!< WWDGT configuration register */ +#define WWDGT_STAT REG32((WWDGT) + 0x08U) /*!< WWDGT status register */ + +/* bits definitions */ +/* WWDGT_CTL */ +#define WWDGT_CTL_CNT BITS(0,6) /*!< WWDGT counter value */ +#define WWDGT_CTL_WDGTEN BIT(7) /*!< WWDGT counter enable */ + +/* WWDGT_CFG */ +#define WWDGT_CFG_WIN BITS(0,6) /*!< WWDGT counter window value */ +#define WWDGT_CFG_PSC BITS(7,8) /*!< WWDGT prescaler divider value */ +#define WWDGT_CFG_EWIE BIT(9) /*!< early wakeup interrupt enable */ + +/* WWDGT_STAT */ +#define WWDGT_STAT_EWIF BIT(0) /*!< early wakeup interrupt flag */ + +/* constants definitions */ +#define CFG_PSC(regval) (BITS(7,8) & ((uint32_t)(regval) << 7)) /*!< write value to WWDGT_CFG_PSC bit field */ +#define WWDGT_CFG_PSC_DIV1 CFG_PSC(0) /*!< the time base of WWDGT = (PCLK1/4096)/1 */ +#define WWDGT_CFG_PSC_DIV2 CFG_PSC(1) /*!< the time base of WWDGT = (PCLK1/4096)/2 */ +#define WWDGT_CFG_PSC_DIV4 CFG_PSC(2) /*!< the time base of WWDGT = (PCLK1/4096)/4 */ +#define WWDGT_CFG_PSC_DIV8 CFG_PSC(3) /*!< the time base of WWDGT = (PCLK1/4096)/8 */ + +/* function declarations */ +/* reset the window watchdog timer configuration */ +void wwdgt_deinit(void); +/* start the window watchdog timer counter */ +void wwdgt_enable(void); + +/* configure the window watchdog timer counter value */ +void wwdgt_counter_update(uint16_t counter_value); +/* configure counter value, window value, and prescaler divider value */ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler); + +/* enable early wakeup interrupt of WWDGT */ +void wwdgt_interrupt_enable(void); +/* check early wakeup interrupt state of WWDGT */ +FlagStatus wwdgt_flag_get(void); +/* clear early wakeup interrupt state of WWDGT */ +void wwdgt_flag_clear(void); + +#endif /* GD32F4XX_WWDGT_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c new file mode 100644 index 0000000000..73f89207ba --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c @@ -0,0 +1,1042 @@ +/*! + \file gd32f4xx_adc.c + \brief ADC driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_adc.h" + +#define REGULAR_CHANNEL_LENGTH_OFFSET ((uint32_t)20U) +#define INSERTED_CHANNEL_LENGTH_OFFSET ((uint32_t)20U) +#define REGULAR_DISCONTINUOUS_NUMBER ((uint32_t)13U) +#define REGULAR_TRIGGER_MODE ((uint32_t)28U) +#define INSERTED_TRIGGER_MODE ((uint32_t)20U) + +/*! + \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] adc_periph: ADCx,x=0,1,2 + \param[in] none + \param[out] none + \retval none +*/ +void adc_enable(uint32_t adc_periph) +{ + if(RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)){ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON; + } +} + +/*! + \brief disable ADC interface + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] none + \param[out] none + \retval none +*/ +void adc_disable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ADCON); +} + +/*! + \brief ADC data alignment config + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] inserted_channel : insert channel select + \arg ADC_DATAALIGN_RIGHT: LSB alignment + \arg ADC_DATAALIGN_LEFT: MSB alignment + \param[out] none + \retval none +*/ +void adc_data_alignment_config(uint32_t adc_periph , uint8_t data_alignment) +{ + if(data_alignment){ + ADC_CTL1(adc_periph) |= ADC_CTL1_DAL; + }else{ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL); + } +} + +/*! + \brief ADC resolution config + \param[in] adc_periph: ADCx,x=0,1,2 + \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 adc_periph , uint32_t resolution) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DRES); + ADC_CTL0(adc_periph) |= (uint32_t)resolution; +} + +/*! + \brief ADC calibration and reset calibration + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] none + \param[out] none + \retval none +*/ +void adc_calibration_enable(uint32_t adc_periph) +{ + /* reset the selected ADC1 calibration registers */ + ADC_CTL1(adc_periph) |= (uint32_t) ADC_CTL1_RSTCLB; + /* check the RSTCLB bit state */ + while((ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)){ + } + /* enable ADC calibration process */ + ADC_CTL1(adc_periph) |= ADC_CTL1_CLB; + /* check the CLB bit state */ + while((ADC_CTL1(adc_periph) & ADC_CTL1_CLB)){ + } +} + +/*! + \brief ADC discontinuous mode config + \param[in] adc_periph: ADCx,x=0,1,2 + \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] length: number of conversions in discontinuous mode,the number can be 1..8 + for regular channel ,the number is no effect for inserted channel + \param[out] none + \retval none +*/ +void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_channel_group , uint8_t length) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)( ADC_CTL0_DISRC | ADC_CTL0_DISIC )); + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* config the number of conversions in discontinuous mode */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM); + if((length <= 8U) && (length >= 1U)){ + ADC_CTL0(adc_periph) |= ((uint32_t)length - 1U) << REGULAR_DISCONTINUOUS_NUMBER; + } + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC; + break; + default: + break; + } +} + +/*! + \brief config end of conversion mode + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] end_selection: end of conversion mode + \arg ADC_EOC_SET_SEQUENCE: only at the end of a sequence of regular conversions, the EOC bit is set + \arg ADC_EOC_SET_CONVERSION: at the end of each regular conversion, the EOC bit is set. + \param[out] none + \retval none +*/ +void adc_end_of_conversion_config(uint32_t adc_periph , uint8_t end_selection) +{ + switch(end_selection){ + case ADC_EOC_SET_SEQUENCE: + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_EOCM); + break; + case ADC_EOC_SET_CONVERSION: + ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_EOCM); + break; + default: + break; + } +} + +/*! + \brief ADC special function enable or disable + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] function: select the function to config + \arg ADC_SCAN_MODE: scan mode select + \arg ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically + \arg ADC_CONTINUOUS_MODE: continuous mode select + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_special_function_config(uint32_t adc_periph , uint8_t function , ControlStatus newvalue) +{ + if(newvalue){ + switch(function){ + case ADC_SCAN_MODE: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_SM; + break; + case ADC_INSERTED_CHANNEL_AUTO: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_ICA; + break; + case ADC_CONTINUOUS_MODE: + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_CTN; + break; + default: + break; + } + }else{ + switch(function){ + case ADC_SCAN_MODE: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_SM); + break; + case ADC_INSERTED_CHANNEL_AUTO: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_ICA); + break; + case ADC_CONTINUOUS_MODE: + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_CTN); + break; + default: + break; + } + } +} + +/*! + \brief configure the ADC clock for all the ADCs + \param[in] prescaler: configure ADCs prescaler ratio + \arg ADC_ADCCK_PCLK2_DIV2: PCLK2 div2 + \arg ADC_ADCCK_PCLK2_DIV4: PCLK2 div4 + \arg ADC_ADCCK_PCLK2_DIV6: PCLK2 div6 + \arg ADC_ADCCK_PCLK2_DIV8: PCLK2 div8 + \arg ADC_ADCCK_HCLK_DIV5: HCLK div5 + \arg ADC_ADCCK_HCLK_DIV6: HCLK div6 + \arg ADC_ADCCK_HCLK_DIV10: HCLK div10 + \arg ADC_ADCCK_HCLK_DIV20: HCLK div20 + \param[out] none + \retval none +*/ +void adc_clock_config(uint32_t prescaler) +{ + ADC_SYNCCTL &= ~((uint32_t)ADC_SYNCCTL_ADCCK); + ADC_SYNCCTL |= (uint32_t) prescaler; +} + +/*! + \brief configure the ADC clock for all the ADCs + \param[in] function: temperature sensor and internal reference voltage channel or VBAT channel + \arg ADC_VBAT_CHANNEL_SWITCH: channel 18 (1/4 voltate of external battery) switch of ADC0 + \arg ADC_TEMP_VREF_CHANNEL_SWITCH: channel 16 (temperature sensor) and 17 (internal reference voltage) switch of ADC0 + \param[in] newvalue: ENABLE or DISABLE +\param[out] none + \retval none +*/ +void adc_channel_16_to_18(uint8_t function,ControlStatus newvalue) +{ + if(newvalue){ + switch(function){ + case ADC_VBAT_CHANNEL_SWITCH: + ADC_SYNCCTL |= (uint32_t)ADC_SYNCCTL_VBATEN; + break; + case ADC_TEMP_VREF_CHANNEL_SWITCH: + ADC_SYNCCTL |= (uint32_t)ADC_SYNCCTL_TSVREN; + break; + default: + break; + } + }else{ + switch(function){ + case ADC_VBAT_CHANNEL_SWITCH: + ADC_SYNCCTL &= ~((uint32_t)ADC_SYNCCTL_VBATEN); + break; + case ADC_TEMP_VREF_CHANNEL_SWITCH: + ADC_SYNCCTL &= ~((uint32_t)ADC_SYNCCTL_TSVREN); + break; + default: + break; + } + } +} + +/*! + \brief config the length of regular channel group or inserted channel group + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_channel_group: select the channel group + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] length: the length of the channel + regular channel 1-16 + inserted channel 1-4 + \param[out] none + \retval none +*/ +void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t length) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + if((length >= 1U) && (length <= 16U)){ + ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL); + ADC_RSQ0(adc_periph) |= (uint32_t)((length-1U) << REGULAR_CHANNEL_LENGTH_OFFSET); + } + break; + case ADC_INSERTED_CHANNEL: + if((length >= 1U) && (length <= 4U)){ + ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL); + ADC_ISQ(adc_periph) |= (uint32_t)((length-1U) << INSERTED_CHANNEL_LENGTH_OFFSET); + } + break; + default: + break; + } +} + +/*! + \brief ADC external trigger enable + \param[in] adc_periph: ADCx,x=0,1,2 + \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] trigger_mode: external trigger mode + \arg EXTERNAL_TRIGGER_DISABLE: external trigger disable + \arg EXTERNAL_TRIGGER_RISING: rising edge of external trigger + \arg EXTERNAL_TRIGGER_FALLING: falling edge of external trigger + \arg EXTERNAL_TRIGGER_RISING_FALLING: rising and falling edge of external trigger + \param[out] none + \retval none +*/ +void adc_external_trigger_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t trigger_mode) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMRC); + ADC_CTL1(adc_periph) |= (uint32_t) (trigger_mode << REGULAR_TRIGGER_MODE); + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMIC); + ADC_CTL1(adc_periph) |= (uint32_t) (trigger_mode << INSERTED_TRIGGER_MODE); + break; + default: + break; + } +} + +/*! + \brief ADC external trigger source config + \param[in] adc_periph: ADCx,x=0,1,2 + \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 CC0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T0_CH1: external trigger timer 0 CC1 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T0_CH2: external trigger timer 0 CC2 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T1_CH1: external trigger timer 1 CC1 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T1_CH2: external trigger timer 1 CC2 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T1_CH3: external trigger timer 1 CC3 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T1_TRGO: external trigger timer 1 TRGO event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T2_CH0 : external trigger timer 2 CC0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T2_TRGO : external trigger timer 2 TRGO event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T3_CH3: external trigger timer 3 CC3 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T4_CH0: external trigger timer 4 CC0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T4_CH1: external trigger timer 4 CC1 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T4_CH2: external trigger timer 4 CC2 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T7_CH0: external trigger timer 7 CC0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T7_TRGO: external trigger timer 7 TRGO event select for regular channel + \arg ADC_EXTTRIG_REGULAR_EXTI_11: external trigger extiline 11 select for regular channel + for inserted channel: + \arg ADC_EXTTRIG_INSERTED_T0_CH3: timer0 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_T0_TRGO: timer0 TRGO event + \arg ADC_EXTTRIG_INSERTED_T1_CH0: timer1 capture compare 0 + \arg ADC_EXTTRIG_INSERTED_T1_TRGO: timer1 TRGO event + \arg ADC_EXTTRIG_INSERTED_T2_CH1: timer2 capture compare 1 + \arg ADC_EXTTRIG_INSERTED_T2_CH3: timer2 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_T3_CH0: timer3 capture compare 0 + \arg ADC_EXTTRIG_INSERTED_T3_CH1: timer3 capture compare 1 + \arg ADC_EXTTRIG_INSERTED_T3_CH2: timer3 capture compare 2 + \arg ADC_EXTTRIG_INSERTED_T3_TRGO: timer3 capture compare TRGO + \arg ADC_EXTTRIG_INSERTED_T4_CH3: timer4 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_T4_TRGO: timer4 capture compare TRGO + \arg ADC_EXTTRIG_INSERTED_T7_CH1: timer7 capture compare 1 + \arg ADC_EXTTRIG_INSERTED_T7_CH2: timer7 capture compare 2 + \arg ADC_EXTTRIG_INSERTED_T7_CH3: timer7 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15 + \param[out] none + \retval none +*/ +void adc_external_trigger_source_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t external_trigger_source) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC); + ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC); + ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; + break; + default: + break; + } +} + +/*! + \brief ADC software trigger enable + \param[in] adc_periph: ADCx,x=0,1,2 + \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(uint32_t adc_periph , uint8_t adc_channel_group) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWRCST; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWICST; + break; + default: + break; + } +} + +/*! + \brief get the ADC flag bits + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_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 + \arg ADC_FLAG_ROVF: regular data register overflow flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_flag_get(uint32_t adc_periph , uint32_t adc_flag) +{ + if(ADC_STAT(adc_periph) & adc_flag){ + return SET; + } + return RESET; + +} + +/*! + \brief clear the ADC flag bits + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_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 + \arg ADC_FLAG_ROVF: regular data register overflow flag + \param[out] none + \retval none +*/ +void adc_flag_clear(uint32_t adc_periph , uint32_t adc_flag) +{ + ADC_STAT(adc_periph) &= ~((uint32_t)adc_flag); +} + +/*! + \brief get the ADC interrupt bits + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_interrupt: the adc interrupt bits + \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 + \arg ADC_INT_ROVF: regular data register overflow interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph , uint32_t adc_interrupt) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + /* check the interrupt bits */ + switch(adc_interrupt){ + case ADC_INT_WDE: + state = ADC_STAT(adc_periph) & ADC_STAT_WDE; + if((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_EOC: + state = ADC_STAT(adc_periph) & ADC_STAT_EOC; + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_EOIC: + state = ADC_STAT(adc_periph) & ADC_STAT_EOIC; + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_ROVF: + state = ADC_STAT(adc_periph) & ADC_STAT_ROVF; + if((ADC_CTL0(adc_periph) & ADC_CTL0_ROVFIE) && state){ + interrupt_flag = SET; + } + break; + default: + break; + } + return interrupt_flag; +} + +/*! + \brief clear the ADC flag + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_flag: the adc status flag + \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 + \arg ADC_INT_ROVF: regular data register overflow interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_flag_clear(uint32_t adc_periph , uint32_t adc_interrupt) +{ + ADC_STAT(adc_periph) &= ~((uint32_t)adc_interrupt); +} + +/*! + \brief ADC interrupt enable + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_flag: the adc interrupt flag + \arg ADC_INT_WDE: analog watchdog interrupt flag + \arg ADC_INT_EOC: end of group conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag + \arg ADC_INT_ROVF: regular data register overflow interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_enable(uint32_t adc_periph , uint32_t adc_interrupt) +{ + switch(adc_interrupt){ + case ADC_INT_WDE: + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDEIE; + break; + case ADC_INT_EOC: + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOCIE; + break; + case ADC_INT_EOIC: + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOICIE; + break; + case ADC_INT_ROVF: + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_ROVFIE; + break; + default: + break; + } +} + +/*! + \brief ADC interrupt disable + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_flag: the adc interrupt flag + \arg ADC_INT_WDE: analog watchdog interrupt flag + \arg ADC_INT_EOC: end of group conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag + \arg ADC_INT_ROVF: regular data register overflow interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_disable(uint32_t adc_periph , uint32_t adc_interrupt) +{ + switch(adc_interrupt){ + /* select the interrupt source */ + case ADC_INT_WDE: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDEIE); + break; + case ADC_INT_EOC: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_EOCIE); + break; + case ADC_INT_EOIC: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_EOICIE); + break; + case ADC_INT_ROVF: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_ROVFIE); + break; + default: + break; + } +} + +/*! + \brief ADC analog watchdog single channel disable + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none +*/ +void adc_watchdog_single_channel_disable(uint32_t adc_periph ) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDSC); +} + +/*! + \brief ADC analog watchdog single channel enable + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_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(uint32_t adc_periph , uint8_t adc_channel) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDCHSEL); + + ADC_CTL0(adc_periph) |= (uint32_t)adc_channel; + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDSC; +} + +/*! + \brief adc analog watchdog group channel config + \param[in] adc_periph: ADCx,x=0,1,2 + \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_enable(uint32_t adc_periph , uint8_t adc_channel_group) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC)); + /* select the group */ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_RWDEN; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_IWDEN; + break; + case ADC_REGULAR_INSERTED_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN); + break; + default: + break; + } +} + +/*! + \brief ADC analog watchdog disable + \param[in] adc_periph: ADCx,x=0,1,2 + \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_disable(uint32_t adc_periph , uint8_t adc_channel_group) +{ + /* select the group */ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_RWDEN); + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_IWDEN); + break; + case ADC_REGULAR_INSERTED_CHANNEL: + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN)); + break; + default: + break; + } +} + +/*! + \brief ADC analog watchdog threshold config + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] low_threshold: analog watchdog low threshold,0..4095 + \param[in] high_threshold: analog watchdog high threshold,0..4095 + \param[out] none + \retval none +*/ +void adc_watchdog_threshold_config(uint32_t adc_periph , uint16_t low_threshold , uint16_t high_threshold) +{ + ADC_WDLT(adc_periph) = (uint32_t)low_threshold; + ADC_WDHT(adc_periph) = (uint32_t)high_threshold; +} + +/*! + \brief ADC regular channel config + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] rank: the regular group sequencer rank,this parameter must be between 0 to 15 + \param[in] adc_channel: the selected ADC channel + \arg ADC_CHANNEL_x(x=0..18): ADC Channelx + \param[in] sample_time: the sample time value + \arg ADC_SAMPLETIME_3: 3 cycles + \arg ADC_SAMPLETIME_15: 15 cycles + \arg ADC_SAMPLETIME_28: 28 cycles + \arg ADC_SAMPLETIME_56: 56 cycles + \arg ADC_SAMPLETIME_84: 84 cycles + \arg ADC_SAMPLETIME_112: 112 cycles + \arg ADC_SAMPLETIME_144: 144 cycles + \arg ADC_SAMPLETIME_480: 480 cycles + \param[out] none + \retval none +*/ +void adc_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time) +{ + uint32_t rsq,sampt; + + /* ADC regular sequence config */ + if(rank < 6U){ + rsq = ADC_RSQ2(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank))); + rsq |= ((uint32_t)adc_channel << (5U*rank)); + ADC_RSQ2(adc_periph) = rsq; + }else if(rank < 12U){ + rsq = ADC_RSQ1(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U)))); + rsq |= ((uint32_t)adc_channel << (5U*(rank-6U))); + ADC_RSQ1(adc_periph) = rsq; + }else if(rank < 16U){ + rsq = ADC_RSQ0(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U)))); + rsq |= ((uint32_t)adc_channel << (5U*(rank-12U))); + ADC_RSQ0(adc_periph) = rsq; + }else{ + } + + /* ADC sampling time config */ + if(adc_channel < 10U){ + sampt = ADC_SAMPT1(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*adc_channel))); + sampt |= (uint32_t)(sample_time << (3U*adc_channel)); + ADC_SAMPT1(adc_periph) = sampt; + }else if(adc_channel < 19U){ + sampt = ADC_SAMPT0(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(adc_channel-10U)))); + sampt |= (uint32_t)(sample_time << (3U*(adc_channel-10U))); + ADC_SAMPT0(adc_periph) = sampt; + }else{ + } +} + +/*! + \brief ADC regular group data register read + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] none + \param[out] none + \retval the conversion value +*/ +uint16_t adc_regular_data_read(uint32_t adc_periph) +{ + return (uint16_t)(ADC_RDATA(adc_periph)); +} + +/*! + \brief ADC inserted channel config + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3 + \param[in] adc_channel: the selected ADC channel + \arg ADC_CHANNEL_x(x=0..18): ADC Channelx + \param[in] sample_time: The sample time value + \arg ADC_SAMPLETIME_3: 3 cycles + \arg ADC_SAMPLETIME_15: 15 cycles + \arg ADC_SAMPLETIME_28: 28 cycles + \arg ADC_SAMPLETIME_56: 56 cycles + \arg ADC_SAMPLETIME_84: 84 cycles + \arg ADC_SAMPLETIME_112: 112 cycles + \arg ADC_SAMPLETIME_144: 144 cycles + \arg ADC_SAMPLETIME_480: 480 cycles + \param[out] none + \retval none +*/ +void adc_inserted_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint8_t sample_time) +{ + uint8_t inserted_length; + uint32_t isq,sampt; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph) , 20U , 21U); + if(rank < 4U){ + isq = ADC_ISQ(adc_periph); + isq &= ~((uint32_t)(ADC_ISQ_ISQN << (15U-(inserted_length-rank)*5U))); + isq |= ((uint32_t)adc_channel << (15U-(inserted_length-rank)*5U)); + ADC_ISQ(adc_periph) = isq; + } + + if(adc_channel < 10U){ + sampt = ADC_SAMPT1(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*adc_channel))); + sampt |= (uint32_t) sample_time << (3U*adc_channel); + ADC_SAMPT1(adc_periph) = sampt; + }else if(adc_channel < 19U){ + sampt = ADC_SAMPT0(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(adc_channel-10U)))); + sampt |= ((uint32_t)sample_time << (3U*(adc_channel-10U))); + ADC_SAMPT0(adc_periph) = sampt; + }else{ + } +} + +/*! + \brief ADC inserted channel offset config + \param[in] adc_periph: ADCx,x=0,1,2 + \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(uint32_t adc_periph , uint8_t inserted_channel , uint16_t offset) +{ + /* config the offset of the selected channels */ + if(ADC_INSERTED_CHANNEL_0 == inserted_channel){ + ADC_IOFF0(adc_periph) = (uint32_t)offset; + }else if(ADC_INSERTED_CHANNEL_1 == inserted_channel){ + ADC_IOFF1(adc_periph) = (uint32_t)offset; + }else if(ADC_INSERTED_CHANNEL_2 == inserted_channel){ + ADC_IOFF2(adc_periph) = (uint32_t)offset; + }else if(ADC_INSERTED_CHANNEL_3 == inserted_channel){ + ADC_IOFF3(adc_periph) = (uint32_t)offset; + }else{ + } +} + +/*! + \brief ADC inserted group data register read + \param[in] adc_periph: ADCx,x=0,1,2 + \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(uint32_t adc_periph , uint8_t inserted_channel) +{ + uint32_t idata; + /* read the data of the selected channel */ + switch(inserted_channel){ + case ADC_INSERTED_CHANNEL_0: + idata = ADC_IDATA0(adc_periph); + break; + case ADC_INSERTED_CHANNEL_1: + idata = ADC_IDATA1(adc_periph); + break; + case ADC_INSERTED_CHANNEL_2: + idata = ADC_IDATA2(adc_periph); + break; + case ADC_INSERTED_CHANNEL_3: + idata = ADC_IDATA3(adc_periph); + break; + default: + idata = 0U; + break; + } + return (uint16_t)idata; +} + +/*! + \brief DMA request enable + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none +*/ +void adc_dma_mode_enable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DMA); +} + +/*! + \brief DMA request disable + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none +*/ +void adc_dma_mode_disable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DMA); +} + +/*! + \brief when DMA=1, the DMA engine issues a request at end of each regular conversion + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none +*/ +void adc_dma_request_after_last_enable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DDM); +} + +/*! + \brief the DMA engine is disabled after the end of transfer signal from DMA controller is detected + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none +*/ +void adc_dma_request_after_last_disable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DDM); +} + +/*! + \brief ADC oversample mode config + \param[in] adc_periph: ADCx,x=0,1,2 + \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 multiple 2 + \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4 + \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8 + \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16 + \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32 + \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64 + \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128 + \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256 + \param[out] none + \retval none +*/ +void adc_oversample_mode_config(uint32_t adc_periph , uint8_t mode , uint16_t shift , uint8_t ratio) +{ + if(ADC_OVERSAMPLING_ONE_CONVERT == mode){ + ADC_OVSAMPCTL(adc_periph) |= (uint32_t)ADC_OVSAMPCTL_TOVS; + }else{ + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_TOVS); + } + /* config the shift and ratio */ + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS)); + ADC_OVSAMPCTL(adc_periph) |= ((uint32_t)shift | (uint32_t)ratio); +} + +/*! + \brief ADC oversample mode enable + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none +*/ +void adc_oversample_mode_enable(uint32_t adc_periph) +{ + ADC_OVSAMPCTL(adc_periph) |= ADC_OVSAMPCTL_OVSEN; +} + +/*! + \brief ADC oversample mode disable + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none +*/ +void adc_oversample_mode_disable(uint32_t adc_periph) +{ + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN); +} + +/*! + \brief configure the ADC sync mode + \param[in] sync_mode: ADC sync mode + \arg ADC_SYNC_MODE_INDEPENDENT: all the ADCs work independently + \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined regular parallel & inserted parallel mode + \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined regular parallel & trigger rotation mode + \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode + \arg ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode + \arg ADC_DAUL_REGULAL_FOLLOW_UP: ADC0 and ADC1 work in follow-up mode + \arg ADC_DAUL_INSERTED_TRRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode + \arg ADC_ALL_REGULAL_PARALLEL_INSERTED_PARALLEL: all ADCs work in combined regular parallel & inserted parallel mode + \arg ADC_ALL_REGULAL_PARALLEL_INSERTED_ROTATION: all ADCs work in combined regular parallel & trigger rotation mode + \arg ADC_ALL_INSERTED_PARALLEL: all ADCs work in inserted parallel mode + \arg ADC_ALL_REGULAL_PARALLEL: all ADCs work in regular parallel mode + \arg ADC_ALL_REGULAL_FOLLOW_UP: all ADCs work in follow-up mode + \arg ADC_ALL_INSERTED_TRRIGGER_ROTATION: all ADCs work in trigger rotation mode + \param[out] none + \retval none +*/ +void adc_sync_mode_config(uint32_t sync_mode) +{ + ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCM); + ADC_SYNCCTL |= sync_mode; +} + +/*! + \brief configure the delay between 2 sampling phases in ADC sync modes + \param[in] sample_delay: the delay between 2 sampling phases in ADC sync modes + \arg ADC_SYNC_DELAY_xCYCLE: x=5..20,the delay between 2 sampling phases in ADC sync modes is x ADC clock cycles + \param[out] none + \retval none +*/ +void adc_sync_delay_config(uint32_t sample_delay) +{ + ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDLY); + ADC_SYNCCTL |= sample_delay; +} + +/*! + \brief configure ADC sync DMA mode selection + \param[in] dma_mode: ADC sync DMA mode + \arg ADC_SYNC_DMA_DISABLE: ADC sync DMA disabled + \arg ADC_SYNC_DMA_MODE0: ADC sync DMA disabled + \arg ADC_SYNC_DMA_MODE1: ADC sync DMA disabled + \param[out] none + \retval none +*/ +void adc_sync_dma_config(uint32_t dma_mode ) +{ + ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDMA); + ADC_SYNCCTL |= dma_mode; +} + +/*! + \brief configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected + \param[in] none + \param[out] none + \retval none +*/ +void adc_sync_dma_request_after_last_enable(void) +{ + ADC_SYNCCTL |= ADC_SYNCCTL_SYNCDDM; +} + +/*! + \brief configure ADC sync DMA engine issues requests according to the SYNCDMA bits + \param[in] none + \param[out] none + \retval none +*/ +void adc_sync_dma_request_after_last_disable(void) +{ + ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDDM); +} + +/*! + \brief ADC sync regular data register read + \param[in] none + \param[out] none + \retval sync regular data +*/ +uint32_t adc_sync_regular_data_read(void) +{ + return (uint32_t)ADC_SYNCDATA; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c new file mode 100644 index 0000000000..eb03822acf --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c @@ -0,0 +1,863 @@ +/*! + \file gd32f4xx_can.c + \brief CAN driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_can.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_struct: parameters for CAN initializtion + can_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE + can_sjw: CAN_BT_SJW_xTQ(x=1, 2, 3, 4) + can_bs1: CAN_BT_BS1_xTQ(1..16) + can_bs2: CAN_BT_BS2_xTQ(1..8) + can_ttc: ENABLE or DISABLE + can_abor: ENABLE or DISABLE + can_awu: ENABLE or DISABLE + can_ard: ENABLE or DISABLE + can_rfod: ENABLE or DISABLE + can_tfo: ENABLE or DISABLE + can_psc: 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_struct: struct for CAN filter initialization + can_filter_list_high: 0x0000 - 0xFFFF + can_filter_list_low: 0x0000 - 0xFFFF + can_filter_mask_high: 0x0000 - 0xFFFF + can_filter_mask_low: 0x0000 - 0xFFFF + can_filter_fifo_number: CAN_FIFO0, CAN_FIFO1 + can_filter_number: 0 - 27 + can_filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST + can_filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT + can_filter_enable: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init) +{ + uint32_t val = 0U; + + val = ((uint32_t)1) << (can_filter_parameter_init->filter_number); + /* filter lock disable */ + CAN_FCTL(CAN0) |= CAN_FCTL_FLD; + /* disable filter */ + CAN_FW(CAN0) &= ~(uint32_t)val; + + /* filter 16 bits */ + if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){ + /* set filter 16 bits */ + CAN_FSCFG(CAN0) &= ~(uint32_t)val; + /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */ + CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */ + CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS); + } + /* filter 32 bits */ + if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){ + /* set filter 32 bits */ + CAN_FSCFG(CAN0) |= (uint32_t)val; + /* 32 bits list or first 32 bits list */ + CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + /* 32 bits mask or second 32 bits list */ + CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS); + } + + /* filter mode */ + if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){ + /* mask mode */ + CAN_FMCFG(CAN0) &= ~(uint32_t)val; + }else{ + /* list mode */ + CAN_FMCFG(CAN0) |= (uint32_t)val; + } + + /* filter FIFO */ + if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){ + /* FIFO0 */ + CAN_FAFIFO(CAN0) &= ~(uint32_t)val; + } + + if(CAN_FIFO1 == can_filter_parameter_init->filter_fifo_number){ + /* FIFO1 */ + CAN_FAFIFO(CAN0) |= (uint32_t)val; + } + + /* filter working */ + if(ENABLE == can_filter_parameter_init->filter_enable){ + + CAN_FW(CAN0) |= (uint32_t)val; + } + + /* filter lock enable */ + CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; +} + +/*! + \brief set CAN1 fliter start bank number + \param[in] can1_start_bank_number + \arg (1..27) + \param[out] none + \retval none +*/ +void can1_filter_start_bank(uint8_t start_bank) +{ + /* filter lock disable */ + CAN_FCTL(CAN0) |= CAN_FCTL_FLD; + /* set CAN1 filter start number */ + CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F; + CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank); + /* filter lock enaable */ + CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; +} + +/*! + \brief enable CAN debug freeze + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_debug_freeze_enable(uint32_t can_periph) +{ + CAN_CTL(can_periph) |= CAN_CTL_DFZ; + if(CAN0 == can_periph){ + dbg_periph_enable(DBG_CAN0_HOLD); + }else{ + dbg_periph_enable(DBG_CAN1_HOLD); + } +} + +/*! + \brief disable CAN debug freeze + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_debug_freeze_disable(uint32_t can_periph) +{ + CAN_CTL(can_periph) &= ~CAN_CTL_DFZ; + if(CAN0 == can_periph){ + dbg_periph_disable(DBG_CAN0_HOLD); + }else{ + dbg_periph_disable(DBG_CAN0_HOLD); + } +} + +/*! + \brief enable CAN time trigger mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_trigger_mode_enable(uint32_t can_periph) +{ + uint8_t mailbox_number; + + /* enable the tcc mode */ + CAN_CTL(can_periph) |= CAN_CTL_TTC; + /* enable time stamp */ + for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){ + CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN; + } +} + +/*! + \brief disable CAN time trigger mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_trigger_mode_disable(uint32_t can_periph) +{ + uint8_t mailbox_number; + + /* disable the TCC mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_TTC; + /* reset TSEN bits */ + for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){ + CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN; + } +} + +/*! + \brief CAN transmit message + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_trasnmit_message_struct: struct for CAN transmit message + can_rx_sfid: 0x00000000 - 0x000007FF + can_rx_efid: 0x00000000 - 0x1FFFFFFF + can_rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED + can_rx_ft: CAN_FT_DATA, CAN_FT_REMOTE + can_rx_dlenc: 1 - 7 + can_rx_data[]: 0x00 - 0xFF + \param[out] none + \retval none +*/ +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 */ + transmit_message->tx_dlen &= (uint8_t)(CAN_TMP_DLENC); + CAN_TMP(can_periph, mailbox_number) &= ((uint32_t)~CAN_TMP_DLENC); + CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen; + /* set the data */ + CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \ + TMDATA0_DB2(transmit_message->tx_data[2]) | \ + TMDATA0_DB1(transmit_message->tx_data[1]) | \ + TMDATA0_DB0(transmit_message->tx_data[0]); + CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \ + TMDATA1_DB6(transmit_message->tx_data[6]) | \ + TMDATA1_DB5(transmit_message->tx_data[5]) | \ + TMDATA1_DB4(transmit_message->tx_data[4]); + /* enable transmission */ + CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN; + + return mailbox_number; +} + +/*! + \brief 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 failed */ + case (CAN_TSTAT_MTF0 | CAN_TSTAT_TME0): + state = CAN_TRANSMIT_FAILED; + break; + case (CAN_TSTAT_MTF1 | CAN_TSTAT_TME1): + state = CAN_TRANSMIT_FAILED; + break; + case (CAN_TSTAT_MTF2 | CAN_TSTAT_TME2): + state = CAN_TRANSMIT_FAILED; + break; + /* transmit succeeded */ + case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0): + state = CAN_TRANSMIT_OK; + break; + 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 CAN stop transmission + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] mailbox_number + \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 parameter*/ + } +} + +/*! + \brief CAN receive message + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + \arg CAN_FIFO0x(x=0,1) + \param[out] can_receive_message_struct: struct for CAN receive message + can_rx_sfid: 0x00000000 - 0x000007FF + can_rx_efid: 0x00000000 - 0x1FFFFFFF + can_rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED + can_rx_ft: CAN_FT_DATA, CAN_FT_REMOTE + can_rx_dlenc: 1 - 7 + can_rx_data[]: 0x00 - 0xFF + can_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) + \arg CAN_FIFO0x(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 parameter */ + } +} + +/*! + \brief CAN receive message length + \param[in] can_periph + \arg CANx(x=0,1) + \arg CAN_FIFO0x(x=0,1) + \param[out] none + \retval message length +*/ +uint8_t can_receive_message_length(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_RFIFO_RFL0_MASK); + }else if(CAN_FIFO0 == fifo_number){ + val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIFO_RFL0_MASK); + }else{ + /* illegal parameter */ + } + return val; +} + +/*! + \brief set CAN working mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_working_mode + \arg CAN_INITIALIZE_MODE + \arg CAN_NORMAL_MODE + \arg CAN_SLEEP_MODE + \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)) && (timeout != 0U)){ + 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))) && (timeout != 0U)){ + 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)) && (timeout != 0U)){ + 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)) && (timeout != 0x00U)){ + 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 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(uint32_t can_periph) +{ + uint8_t val; + + val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_RECNT) >> 24U); + return val; +} + +/*! + \brief 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(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_INTEN_TMEIE + \arg CAN_INTEN_RFNEIE0 + \arg CAN_INTEN_RFFIE0 + \arg CAN_INTEN_RFOIE0 + \arg CAN_INTEN_RFNEIE1 + \arg CAN_INTEN_RFFIE1 + \arg CAN_INTEN_RFOIE1 + \arg CAN_INTEN_WERRIE + \arg CAN_INTEN_PERRIE + \arg CAN_INTEN_BOIE + \arg CAN_INTEN_ERRNIE + \arg CAN_INTEN_ERRIE + \arg CAN_INTEN_WUIE + \arg CAN_INTEN_SLPWIE + \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_INTEN_TMEIE + \arg CAN_INTEN_RFNEIE0 + \arg CAN_INTEN_RFFIE0 + \arg CAN_INTEN_RFOIE0 + \arg CAN_INTEN_RFNEIE1 + \arg CAN_INTEN_RFFIE1 + \arg CAN_INTEN_RFOIE1 + \arg CAN_INTEN_WERRIE + \arg CAN_INTEN_PERRIE + \arg CAN_INTEN_BOIE + \arg CAN_INTEN_ERRNIE + \arg CAN_INTEN_ERRIE + \arg CAN_INTEN_WUIE + \arg CAN_INTEN_SLPWIE + \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 + \arg CAN_FLAG_MTE1 + \arg CAN_FLAG_MTE0 + \arg CAN_FLAG_MTF2 + \arg CAN_FLAG_MTF1 + \arg CAN_FLAG_MTF0 + \arg CAN_FLAG_RFO0 + \arg CAN_FLAG_RFF0 + \arg CAN_FLAG_RFO1 + \arg CAN_FLAG_RFF1 + \arg CAN_FLAG_BOERR + \arg CAN_FLAG_PERR + \arg CAN_FLAG_WERR + \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 + \arg CAN_FLAG_MTE1 + \arg CAN_FLAG_MTE0 + \arg CAN_FLAG_MTF2 + \arg CAN_FLAG_MTF1 + \arg CAN_FLAG_MTF0 + \arg CAN_FLAG_RFO0 + \arg CAN_FLAG_RFF0 + \arg CAN_FLAG_RFO1 + \arg CAN_FLAG_RFF1 + \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_SLPIF + \arg CAN_INT_WUIF + \arg CAN_INT_ERRIF + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag) +{ + FlagStatus inten = RESET; + FlagStatus temp = RESET; + FlagStatus status1 = RESET; + FlagStatus status2 = RESET; + + switch(flag){ + /* get the status of sleep working interrupt enable bit */ + case CAN_INT_SLPIF: + inten = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_SLPWIE); + break; + /* get the status of wakeup interrupt enable bit */ + case CAN_INT_WUIF: + inten = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_WUIE); + break; + /* get the status of error falgs and its enable bit */ + case CAN_INT_ERRIF: + /* check if the BOERR bit in CAN_ERR register and BOIE bit in CAN_INTEN register are set */ + status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_BOIE); + status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_BOERR); + if((RESET != status1) && (RESET != status2)){ + inten = SET; + } + /* check if the WERR bit in CAN_ERR register and WERRIE bit in CAN_INTEN register are set */ + status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_WERRIE); + status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_WERR); + if((RESET != status1) && (RESET != status2)){ + inten = SET; + } + /* check if the PERR bit in CAN_ERR register and PERRIE bit in CAN_INTEN register are set */ + status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_PERRIE); + status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_PERR); + if((RESET != status1) && (RESET != status2)){ + inten = SET; + } + /* check if the ERRN bit in CAN_ERR register and ERRNIE bit in CAN_INTEN register are set */ + status1 = (FlagStatus)(CAN_INTEN(can_periph) & CAN_INTEN_ERRNIE); + status2 = (FlagStatus)(CAN_ERR(can_periph) & CAN_ERR_ERRN); + if((RESET != status1) && (RESET != status2)){ + inten = SET; + } + break; + default: + break; + } + /* get the interrupt flag */ + temp = (FlagStatus)(CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag))); + /* check the interrupt enable bit and corresponding flag bit are set */ + if((RESET != inten) && (RESET != temp)){ + 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_SLPIF + \arg CAN_INT_WUIF + \arg CAN_INT_ERRIF + \param[out] none + \retval none +*/ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag) +{ + CAN_REG_VAL(can_periph, flag) |= BIT(CAN_BIT_POS(flag)); +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c new file mode 100644 index 0000000000..e51d8dc483 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c @@ -0,0 +1,101 @@ +/*! + \file gd32f4xx_crc.c + \brief CRC driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_crc.h" + +/*! + \brief deinit CRC calculation unit + \param[in] none + \param[out] none + \retval none +*/ +void crc_deinit(void) +{ + CRC_DATA = (uint32_t)0xFFFFFFFFU; + CRC_FDATA = (uint32_t)0x00000000U; + CRC_CTL = CRC_CTL_RST; +} + +/*! + \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 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/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c new file mode 100644 index 0000000000..34431164a3 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c @@ -0,0 +1,358 @@ +/*! + \file gd32f4xx_ctc.c + \brief CTC driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_ctc.h" + +#define CTC_FLAG_MASK ((uint32_t)0x00000700U) + +/*! + \brief reset CTC clock trim controller + \param[in] none + \param[out] none + \retval none +*/ +void ctc_deinit(void) +{ + /* reset CTC */ + rcu_periph_reset_enable(RCU_CTCRST); + rcu_periph_reset_disable(RCU_CTCRST); +} + +/*! + \brief configure the IRC48M trim value + \param[in] ctc_trim_value: 8-bit IRC48M trim value + \param[out] none + \retval none +*/ +void ctc_irc48m_trim_value_config(uint8_t ctc_trim_value) +{ + /* clear TRIMVALUE bits */ + CTC_CTL0 &= (~(uint32_t)CTC_CTL0_TRIMVALUE); + /* set TRIMVALUE bits */ + CTC_CTL0 |= ((uint32_t)ctc_trim_value << 8); +} + +/*! + \brief generate software reference source sync pulse + \param[in] none + \param[out] none + \retval none +*/ +void ctc_software_refsource_pulse_generate(void) +{ + CTC_CTL0 |= (uint32_t)CTC_CTL0_SWREFPUL; +} + +/*! + \brief configure hardware automatically trim mode + \param[in] ctc_hardmode: + \arg CTC_HARDWARE_TRIM_MODE_ENABLE: hardware automatically trim mode enable + \arg CTC_HARDWARE_TRIM_MODE_DISABLE: hardware automatically trim mode disable + \param[out] none + \retval none +*/ +void ctc_hardware_trim_mode_config(uint32_t ctc_hardmode) +{ + CTC_CTL0 &= (uint32_t)(~CTC_CTL0_AUTOTRIM); + CTC_CTL0 |= (uint32_t)ctc_hardmode; +} + +/*! + \brief enable CTC counter + \param[in] none + \param[out] none + \retval none +*/ +void ctc_counter_enable(void) +{ + CTC_CTL0 |= (uint32_t)CTC_CTL0_CNTEN; +} + +/*! + \brief disable CTC counter + \param[in] none + \param[out] none + \retval none +*/ +void ctc_counter_disable(void) +{ + CTC_CTL0 &= (uint32_t)(~CTC_CTL0_CNTEN); +} + +/*! + \brief configure reference signal source polarity + \param[in] ctc_polarity: + \arg CTC_REFSOURCE_POLARITY_FALLING: reference signal source polarity is falling edge + \arg CTC_REFSOURCE_POLARITY_RISING: reference signal source polarity is rising edge + \param[out] none + \retval none +*/ +void ctc_refsource_polarity_config(uint32_t ctc_polarity) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPOL); + CTC_CTL1 |= (uint32_t)ctc_polarity; +} + +/*! + \brief select USBFS or USBHS SOF signal + \param[in] ctc_usbsof: + \arg CTC_USBSOFSEL_USBHS: USBHS SOF signal is selected + \arg CTC_USBSOFSEL_USBFS: USBFS SOF signal is selected + \param[out] none + \retval none +*/ +void ctc_usbsof_signal_select(uint32_t ctc_usbsof) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_USBSOFSEL); + CTC_CTL1 |= (uint32_t)ctc_usbsof; +} + +/*! + \brief select reference signal source + \param[in] ctc_refs: + \arg CTC_REFSOURCE_GPIO: GPIO is selected + \arg CTC_REFSOURCE_LXTAL: LXTAL is clock selected + \arg CTC_REFSOURCE_USBSOF: USBSOF is selected + \param[out] none + \retval none +*/ +void ctc_refsource_signal_select(uint32_t ctc_refs) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFSEL); + CTC_CTL1 |= (uint32_t)ctc_refs; +} + +/*! + \brief configure reference signal source prescaler + \param[in] ctc_prescaler: + \arg CTC_REFSOURCE_PSC_OFF: reference signal not divided + \arg CTC_REFSOURCE_PSC_DIV2: reference signal divided by 2 + \arg CTC_REFSOURCE_PSC_DIV4: reference signal divided by 4 + \arg CTC_REFSOURCE_PSC_DIV8: reference signal divided by 8 + \arg CTC_REFSOURCE_PSC_DIV16: reference signal divided by 16 + \arg CTC_REFSOURCE_PSC_DIV32: reference signal divided by 32 + \arg CTC_REFSOURCE_PSC_DIV64: reference signal divided by 64 + \arg CTC_REFSOURCE_PSC_DIV128: reference signal divided by 128 + \param[out] none + \retval none +*/ +void ctc_refsource_prescaler_config(uint32_t ctc_prescaler) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPSC); + CTC_CTL1 |= (uint32_t)ctc_prescaler; +} + +/*! + \brief configure clock trim base limit value + \param[in] ctc_limit_value: 8-bit clock trim base limit value + \param[out] none + \retval none +*/ +void ctc_clock_limit_value_config(uint8_t ctc_limit_value) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_CKLIM); + CTC_CTL1 |= (uint32_t)((uint32_t)ctc_limit_value << 16); +} + +/*! + \brief configure CTC counter reload value + \param[in] ctc_reload_value: 16-bit CTC counter reload value + \param[out] none + \retval none +*/ +void ctc_counter_reload_value_config(uint16_t ctc_reload_value) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_RLVALUE); + CTC_CTL1 |= (uint32_t)ctc_reload_value; +} + +/*! + \brief read CTC counter capture value when reference sync pulse occurred + \param[in] none + \param[out] none + \retval the 16-bit CTC counter capture value +*/ +uint16_t ctc_counter_capture_value_read(void) +{ + uint16_t capture_value = 0U; + capture_value = (uint16_t)((CTC_STAT & CTC_STAT_REFCAP)>> 16); + return (capture_value); +} + +/*! + \brief read CTC trim counter direction when reference sync pulse occurred + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET + \arg SET: CTC trim counter direction is down-counting + \arg RESET: CTC trim counter direction is up-counting +*/ +FlagStatus ctc_counter_direction_read(void) +{ + if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief read CTC counter reload value + \param[in] none + \param[out] none + \retval the 16-bit CTC counter reload value +*/ +uint16_t ctc_counter_reload_value_read(void) +{ + uint16_t reload_value = 0U; + reload_value = (uint16_t)(CTC_CTL1 & CTC_CTL1_RLVALUE); + return (reload_value); +} + +/*! + \brief read the IRC48M trim value + \param[in] none + \param[out] none + \retval the 8-bit IRC48M trim value +*/ +uint8_t ctc_irc48m_trim_value_read(void) +{ + uint8_t trim_value = 0U; + trim_value = (uint8_t)((CTC_CTL0 & CTC_CTL0_TRIMVALUE) >> 8); + return (trim_value); +} + +/*! + \brief enable the CTC interrupt + \param[in] ctc_interrupt: CTC interrupt enable + \arg CTC_INT_CKOKIE: clock trim OK interrupt enable + \arg CTC_INT_CKWARNIE: clock trim warning interrupt enable + \arg CTC_INT_ERRIE: error interrupt enable + \arg CTC_INT_EREFIE: expect reference interrupt enable + \param[out] none + \retval none +*/ +void ctc_interrupt_enable(uint32_t ctc_interrupt) +{ + CTC_CTL0 |= (uint32_t)ctc_interrupt; +} + +/*! + \brief disable the CTC interrupt + \param[in] ctc_interrupt: CTC interrupt enable source + \arg CTC_INT_CKOKIE: clock trim OK interrupt enable + \arg CTC_INT_CKWARNIE: clock trim warning interrupt enable + \arg CTC_INT_ERRIE: error interrupt enable + \arg CTC_INT_EREFIE: expect reference interrupt enable + \param[out] none + \retval none +*/ +void ctc_interrupt_disable(uint32_t ctc_interrupt) +{ + CTC_CTL0 &= (uint32_t)(~ctc_interrupt); +} + +/*! + \brief get CTC interrupt flag + \param[in] ctc_interrupt: the CTC interrupt flag + \arg CTC_INT_CKOK: clock trim OK interrupt + \arg CTC_INT_CKWARN: clock trim warning interrupt + \arg CTC_INT_ERR: error interrupt + \arg CTC_INT_EREF: expect reference interrupt + \arg CTC_INT_CKERR: clock trim error bit interrupt + \arg CTC_INT_REFMISS: reference sync pulse miss interrupt + \arg CTC_INT_TRIMERR: trim value error interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ctc_interrupt_flag_get(uint32_t ctc_interrupt) +{ + uint32_t interrupt = 0U, intenable = 0U; + + if(ctc_interrupt & CTC_FLAG_MASK){ + intenable = CTC_CTL0 & CTC_INT_ERRIE; + }else{ + intenable = CTC_CTL0 & ctc_interrupt; + } + interrupt = CTC_STAT & ctc_interrupt; + + if(interrupt && intenable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CTC interrupt flag + \param[in] ctc_interrupt: the CTC interrupt flag + \arg CTC_INT_CKOK: clock trim OK interrupt + \arg CTC_INT_CKWARN: clock trim warning interrupt + \arg CTC_INT_ERR: error interrupt + \arg CTC_INT_EREF: expect reference interrupt + \arg CTC_INT_CKERR: clock trim error bit interrupt + \arg CTC_INT_REFMISS: reference sync pulse miss interrupt + \arg CTC_INT_TRIMERR: trim value error interrupt + \param[out] none + \retval none +*/ +void ctc_interrupt_flag_clear(uint32_t ctc_interrupt) +{ + if(ctc_interrupt & CTC_FLAG_MASK){ + CTC_INTC |= CTC_INTC_ERRIC; + }else{ + CTC_INTC |= ctc_interrupt; + } +} + +/*! + \brief get CTC flag + \param[in] ctc_flag: the CTC flag + \arg CTC_FLAG_CKOK: clock trim OK flag + \arg CTC_FLAG_CKWARN: clock trim warning flag + \arg CTC_FLAG_ERR: error flag + \arg CTC_FLAG_EREF: expect reference flag + \arg CTC_FLAG_CKERR: clock trim error bit + \arg CTC_FLAG_REFMISS: reference sync pulse miss + \arg CTC_FLAG_TRIMERR: trim value error bit + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ctc_flag_get(uint32_t ctc_flag) +{ + if(RESET != (CTC_STAT & ctc_flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CTC flag + \param[in] ctc_flag: the CTC flag + \arg CTC_FLAG_CKOK: clock trim OK flag + \arg CTC_FLAG_CKWARN: clock trim warning flag + \arg CTC_FLAG_ERR: error flag + \arg CTC_FLAG_EREF: expect reference flag + \arg CTC_FLAG_CKERR: clock trim error bit + \arg CTC_FLAG_REFMISS: reference sync pulse miss + \arg CTC_FLAG_TRIMERR: trim value error bit + \param[out] none + \retval none +*/ +void ctc_flag_clear(uint32_t ctc_flag) +{ + if(ctc_flag & CTC_FLAG_MASK){ + CTC_INTC |= CTC_INTC_ERRIC; + }else{ + CTC_INTC |= ctc_flag; + } +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c new file mode 100644 index 0000000000..2204d08c21 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c @@ -0,0 +1,650 @@ +/*! + \file gd32f4xx_dac.c + \brief DAC driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_dac.h" + +/*! + \brief deinitialize DAC + \param[in] none + \param[out] none + \retval none +*/ +void dac_deinit(void) +{ + rcu_periph_reset_enable(RCU_DACRST); + rcu_periph_reset_disable(RCU_DACRST); +} + +/*! + \brief enable DAC + \param[in] dac_periph + \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 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: TIMER1 TRGO + \arg DAC_TRIGGER_T3_TRGO: TIMER3 TRGO + \arg DAC_TRIGGER_T4_TRGO: TIMER4 TRGO + \arg DAC_TRIGGER_T5_TRGO: TIMER5 TRGO + \arg DAC_TRIGGER_T6_TRGO: TIMER6 TRGO + \arg DAC_TRIGGER_T7_TRGO: TIMER7 TRGO + \arg DAC_TRIGGER_EXTI_9: EXTI interrupt line9 event + \arg DAC_TRIGGER_SOFTWARE: software trigger + \param[out] none + \retval none +*/ +void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DTSEL0; + DAC_CTL |= triggersource; + }else{ + DAC_CTL &= ~DAC_CTL_DTSEL1; + DAC_CTL |= (triggersource << 16); + } +} + +/*! + \brief configure DAC wave mode + \param[in] dac_periph + \arg DACx(x=0,1) + \param[in] wave_mode + \arg DAC_WAVE_DISABLE: wave disable + \arg DAC_WAVE_MODE_LFSR: LFSR noise mode + \arg DAC_WAVE_MODE_TRIANGLE: triangle noise mode + \param[out] none + \retval none +*/ +void dac_wave_mode_config(uint32_t dac_periph, uint32_t wave_mode) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DWM0; + DAC_CTL |= wave_mode; + }else{ + DAC_CTL &= ~DAC_CTL_DWM1; + DAC_CTL |= wave_mode << 16; + } +} + +/*! + \brief configure DAC wave bit width + \param[in] dac_periph + \arg DACx(x=0,1) + \param[in] bit_width + \arg DAC_WAVE_BIT_WIDTH_1: bit width of the wave signal is 1 + \arg DAC_WAVE_BIT_WIDTH_2: bit width of the wave signal is 2 + \arg DAC_WAVE_BIT_WIDTH_3: bit width of the wave signal is 3 + \arg DAC_WAVE_BIT_WIDTH_4: bit width of the wave signal is 4 + \arg DAC_WAVE_BIT_WIDTH_5: bit width of the wave signal is 5 + \arg DAC_WAVE_BIT_WIDTH_6: bit width of the wave signal is 6 + \arg DAC_WAVE_BIT_WIDTH_7: bit width of the wave signal is 7 + \arg DAC_WAVE_BIT_WIDTH_8: bit width of the wave signal is 8 + \arg DAC_WAVE_BIT_WIDTH_9: bit width of the wave signal is 9 + \arg DAC_WAVE_BIT_WIDTH_10: bit width of the wave signal is 10 + \arg DAC_WAVE_BIT_WIDTH_11: bit width of the wave signal is 11 + \arg DAC_WAVE_BIT_WIDTH_12: bit width of the wave signal is 12 + \param[out] none + \retval none +*/ +void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DWBW0; + DAC_CTL |= bit_width; + }else{ + DAC_CTL &= ~DAC_CTL_DWBW1; + DAC_CTL |= bit_width << 16; + } +} + +/*! + \brief configure DAC LFSR noise mode + \param[in] dac_periph + \arg DACx(x=0,1) + \param[in] unmask_bits + \arg DAC_LFSR_BIT0: unmask the LFSR bit0 + \arg DAC_LFSR_BITS1_0: unmask the LFSR bits[1:0] + \arg DAC_LFSR_BITS2_0: unmask the LFSR bits[2:0] + \arg DAC_LFSR_BITS3_0: unmask the LFSR bits[3:0] + \arg DAC_LFSR_BITS4_0: unmask the LFSR bits[4:0] + \arg DAC_LFSR_BITS5_0: unmask the LFSR bits[5:0] + \arg DAC_LFSR_BITS6_0: unmask the LFSR bits[6:0] + \arg DAC_LFSR_BITS7_0: unmask the LFSR bits[7:0] + \arg DAC_LFSR_BITS8_0: unmask the LFSR bits[8:0] + \arg DAC_LFSR_BITS9_0: unmask the LFSR bits[9:0] + \arg DAC_LFSR_BITS10_0: unmask the LFSR bits[10:0] + \arg DAC_LFSR_BITS11_0: unmask the LFSR bits[11:0] + \param[out] none + \retval none +*/ +void dac_lfsr_noise_config(uint32_t dac_periph, uint32_t unmask_bits) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DWBW0; + DAC_CTL |= unmask_bits; + }else{ + DAC_CTL &= ~DAC_CTL_DWBW1; + DAC_CTL |= unmask_bits << 16; + } +} + +/*! + \brief configure DAC triangle noise mode + \param[in] dac_periph + \arg DACx(x=0,1) + \param[in] amplitude + \arg DAC_TRIANGLE_AMPLITUDE_1: triangle amplitude is 1 + \arg DAC_TRIANGLE_AMPLITUDE_3: triangle amplitude is 3 + \arg DAC_TRIANGLE_AMPLITUDE_7: triangle amplitude is 7 + \arg DAC_TRIANGLE_AMPLITUDE_15: triangle amplitude is 15 + \arg DAC_TRIANGLE_AMPLITUDE_31: triangle amplitude is 31 + \arg DAC_TRIANGLE_AMPLITUDE_63: triangle amplitude is 63 + \arg DAC_TRIANGLE_AMPLITUDE_127: triangle amplitude is 127 + \arg DAC_TRIANGLE_AMPLITUDE_255: triangle amplitude is 255 + \arg DAC_TRIANGLE_AMPLITUDE_511: triangle amplitude is 511 + \arg DAC_TRIANGLE_AMPLITUDE_1023: triangle amplitude is 1023 + \arg DAC_TRIANGLE_AMPLITUDE_2047: triangle amplitude is 2047 + \arg DAC_TRIANGLE_AMPLITUDE_4095: triangle amplitude is 4095 + \param[out] none + \retval none +*/ +void dac_triangle_noise_config(uint32_t dac_periph, uint32_t amplitude) +{ + if(DAC0 == dac_periph){ + DAC_CTL &= ~DAC_CTL_DWBW0; + DAC_CTL |= amplitude; + }else{ + DAC_CTL &= ~DAC_CTL_DWBW1; + DAC_CTL |= amplitude << 16; + } +} + +/*! + \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 concurrent mode + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1; + DAC_CTL |= (ctl); +} + +/*! + \brief disable DAC concurrent mode + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1; + DAC_CTL &= (~ctl); +} + +/*! + \brief enable DAC concurrent software trigger function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_enable(void) +{ + uint32_t swt = 0U; + swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; + DAC_SWT |= (swt); +} + +/*! + \brief disable DAC concurrent software trigger function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_disable(void) +{ + uint32_t swt = 0U; + swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; + DAC_SWT &= (~swt); +} + +/*! + \brief enable DAC concurrent buffer function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_output_buffer_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1; + DAC_CTL &= (~ctl); +} + +/*! + \brief disable DAC concurrent buffer function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_output_buffer_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1; + DAC_CTL |= (ctl); +} + +/*! + \brief enable DAC concurrent interrupt funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_interrupt_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DDUDRIE0 | DAC_CTL_DDUDRIE1; + DAC_CTL |= (ctl); +} + +/*! + \brief disable DAC concurrent interrupt funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_interrupt_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DDUDRIE0 | DAC_CTL_DDUDRIE1; + DAC_CTL &= (~ctl); +} + +/*! + \brief 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] data0: data to be loaded + \param[in] data1: data to be loaded + \param[out] none + \retval none +*/ +void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1) +{ + uint32_t data = 0U; + switch(dac_align){ + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + data = ((uint32_t)data1 << 16) | data0; + DACC_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + data = ((uint32_t)data1 << 16) | data0; + DACC_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + data = ((uint32_t)data1 << 8) | data0; + DACC_R8DH = data; + break; + default: + break; + } +} + +/*! + \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) +{ + FlagStatus temp_flag = RESET; + if(DAC0 == dac_periph){ + /* check the DMA underrun flag */ + if(RESET != (DAC_STAT & DAC_STAT_DDUDR0)){ + temp_flag = SET; + } + }else{ + /* check the DMA underrun flag */ + if(RESET != (DAC_STAT & DAC_STAT_DDUDR1)){ + temp_flag = SET; + } + } + return temp_flag; +} + +/*! + \brief clear the specified DAC flag(DAC DMA underrun flag) + \param[in] dac_periph + \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) +{ + FlagStatus temp_flag = RESET; + uint32_t ddudr_flag = 0U, ddudrie_flag = 0U; + if(DAC0 == dac_periph){ + /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ + ddudr_flag = DAC_STAT & DAC_STAT_DDUDR0; + ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE0; + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){ + temp_flag = SET; + } + }else{ + /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ + ddudr_flag = DAC_STAT & DAC_STAT_DDUDR1; + ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE1; + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){ + temp_flag = SET; + } + } + return temp_flag; +} + +/*! + \brief clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag) + \param[in] dac_periph + \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; + } +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c new file mode 100644 index 0000000000..a017c7e3e5 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c @@ -0,0 +1,122 @@ +/*! + \file gd32f4xx_dbg.c + \brief DBG driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_dbg.h" + +/*! + \brief read DBG_ID code register + \param[in] none + \param[out] none + \retval DBG_ID code +*/ +uint32_t dbg_id_get(void) +{ + return DBG_ID; +} + +/*! + \brief enable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + this parameter can be any combination of the following values: + \arg DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_enable(uint32_t dbg_low_power) +{ + DBG_CTL0 |= dbg_low_power; +} + +/*! + \brief disable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + this parameter can be any combination of the following values: + \arg DBG_LOW_POWER_SLEEP: donot keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: donot keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: donot keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_disable(uint32_t dbg_low_power) +{ + DBG_CTL0 &= ~dbg_low_power; +} + +/*! + \brief enable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: dbg_periph_enum + \param[out] none + \retval none +*/ +void dbg_periph_enable(dbg_periph_enum dbg_periph) +{ + if(RESET == ((uint32_t)dbg_periph & BIT(30))){ + DBG_CTL1 |= (uint32_t)dbg_periph; + }else{ + DBG_CTL2 |= ((uint32_t)dbg_periph & (~BIT(30))); + } + +} + +/*! + \brief disable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: dbg_periph_enum + \param[out] none + \retval none +*/ +void dbg_periph_disable(dbg_periph_enum dbg_periph) +{ + if(RESET == ((uint32_t)dbg_periph & BIT(30))){ + DBG_CTL1 &= ~(uint32_t)dbg_periph; + }else{ + DBG_CTL2 &= ~((uint32_t)dbg_periph & (~BIT(30))); + } +} + +/*! + \brief enable trace pin assignment + \param[in] none + \param[out] none + \retval none +*/ +void dbg_trace_pin_enable(void) +{ + DBG_CTL0 |= DBG_CTL0_TRACE_IOEN; +} + +/*! + \brief disable trace pin assignment + \param[in] none + \param[out] none + \retval none +*/ +void dbg_trace_pin_disable(void) +{ + DBG_CTL0 &= ~DBG_CTL0_TRACE_IOEN; +} + +/*! + \brief trace pin mode selection + \param[in] trace_mode: + \arg TRACE_MODE_ASYNC: trace pin used for async mode + \arg TRACE_MODE_SYNC_DATASIZE_1: trace pin used for sync mode and data size is 1 + \arg TRACE_MODE_SYNC_DATASIZE_2: trace pin used for sync mode and data size is 2 + \arg TRACE_MODE_SYNC_DATASIZE_4: trace pin used for sync mode and data size is 4 + \param[out] none + \retval none +*/ +void dbg_trace_pin_mode_set(uint32_t trace_mode) +{ + DBG_CTL0 &= ~DBG_CTL0_TRACE_MODE; + DBG_CTL0 |= trace_mode; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c new file mode 100644 index 0000000000..2984ff11f7 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c @@ -0,0 +1,341 @@ +/*! + \file gd32f4xx_dci.c + \brief DCI driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_dci.h" + +/*! + \brief DCI deinit + \param[in] none + \param[out] none + \retval none +*/ +void dci_deinit(void) +{ + rcu_periph_reset_enable(RCU_DCIRST); + rcu_periph_reset_disable(RCU_DCIRST); +} + +/*! + \brief initialize DCI registers + \param[in] dci_struct: DCI parameter initialization stuct + members of the structure and the member values are shown as below: + capture_mode : DCI_CAPTURE_MODE_CONTINUOUS, DCI_CAPTURE_MODE_SNAPSHOT + colck_polarity : DCI_CK_POLARITY_FALLING, DCI_CK_POLARITY_RISING + hsync_polarity : DCI_HSYNC_POLARITY_LOW, DCI_HSYNC_POLARITY_HIGH + vsync_polarity : DCI_VSYNC_POLARITY_LOW, DCI_VSYNC_POLARITY_HIGH + frame_rate : DCI_FRAME_RATE_ALL, DCI_FRAME_RATE_1_2, DCI_FRAME_RATE_1_4 + interface_format: DCI_INTERFACE_FORMAT_8BITS, DCI_INTERFACE_FORMAT_10BITS, + DCI_INTERFACE_FORMAT_12BITS, DCI_INTERFACE_FORMAT_14BITS + \param[out] none + \retval none +*/ +void dci_init(dci_parameter_struct* dci_struct) +{ + uint32_t reg =0U; + /* disable capture function and DCI */ + DCI_CTL &= ~(DCI_CTL_CAP | DCI_CTL_DCIEN); + /* config DCI parameter */ + reg |= dci_struct->capture_mode; + reg |= dci_struct->clock_polarity; + reg |= dci_struct->hsync_polarity; + reg |= dci_struct->vsync_polarity; + reg |= dci_struct->frame_rate; + reg |= dci_struct->interface_format; + + DCI_CTL = reg; +} + +/*! + \brief enable DCI function + \param[in] none + \param[out] none + \retval none +*/ +void dci_enable(void) +{ + DCI_CTL |= DCI_CTL_DCIEN; +} + +/*! + \brief disable DCI function + \param[in] none + \param[out] none + \retval none +*/ +void dci_disable(void) +{ + DCI_CTL &= ~DCI_CTL_DCIEN; +} + +/*! + \brief enable DCI capture + \param[in] none + \param[out] none + \retval none +*/ +void dci_capture_enable(void) +{ + DCI_CTL |= DCI_CTL_CAP; +} + +/*! + \brief disable DCI capture + \param[in] none + \param[out] none + \retval none +*/ +void dci_capture_disable(void) +{ + DCI_CTL &= ~DCI_CTL_CAP; +} + +/*! + \brief enable DCI jpeg mode + \param[in] none + \param[out] none + \retval none +*/ +void dci_jpeg_enable(void) +{ + DCI_CTL |= DCI_CTL_JM; +} + +/*! + \brief disable DCI jpeg mode + \param[in] none + \param[out] none + \retval none +*/ +void dci_jpeg_disable(void) +{ + DCI_CTL &= ~DCI_CTL_JM; +} + +/*! + \brief enable cropping window function + \param[in] none + \param[out] none + \retval none +*/ +void dci_crop_window_enable(void) +{ + DCI_CTL |= DCI_CTL_WDEN; +} + +/*! + \brief disable cropping window function + \param[in] none + \param[out] none + \retval none +*/ +void dci_crop_window_disable(void) +{ + DCI_CTL &= ~DCI_CTL_WDEN; +} + +/*! + \brief config DCI cropping window + \param[in] start_x: window horizontal start position + \param[in] start_y: window vertical start position + \param[in] size_height: window horizontal size + \param[in] size_width: window vertical size + \param[out] none + \retval none +*/ +void dci_crop_window_config(uint16_t start_x, uint16_t start_y, uint16_t size_width, uint16_t size_height) +{ + DCI_CWSPOS = ((uint32_t)start_x | ((uint32_t)start_y<<16)); + DCI_CWSZ = ((uint32_t)size_width | ((uint32_t)size_height<<16)); +} + +/*! + \brief enable sync codes function + \param[in] none + \param[out] none + \retval none +*/ +void dci_sync_codes_enable(void) +{ + DCI_CTL |= DCI_CTL_ESM; +} + +/*! + \brief disable sync codes function + \param[in] none + \param[out] none + \retval none +*/ +void dci_sync_codes_disable(void) +{ + DCI_CTL &= ~DCI_CTL_ESM; +} +/*! + \brief config sync codes + \param[in] frame_start: frame start code in embedded synchronous mode + \param[in] line_start: line start code in embedded synchronous mode + \param[in] line_end: line end code in embedded synchronous mode + \param[in] frame_end: frame end code in embedded synchronous mode + \param[out] none + \retval none +*/ +void dci_sync_codes_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end) +{ + DCI_SC = ((uint32_t)frame_start | ((uint32_t)line_start<<8) | ((uint32_t)line_end<<16) | ((uint32_t)frame_end<<24)); +} + +/*! + \brief config sync codes unmask + \param[in] frame_start: frame start code unmask bits in embedded synchronous mode + \param[in] line_start: line start code unmask bits in embedded synchronous mode + \param[in] line_end: line end code unmask bits in embedded synchronous mode + \param[in] frame_end: frame end code unmask bits in embedded synchronous mode + \param[out] none + \retval none +*/ +void dci_sync_codes_unmask_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end) +{ + DCI_SCUMSK = ((uint32_t)frame_start | ((uint32_t)line_start<<8) | ((uint32_t)line_end<<16) | ((uint32_t)frame_end<<24)); +} + +/*! + \brief read DCI data register + \param[in] none + \param[out] none + \retval data +*/ +uint32_t dci_data_read(void) +{ + return DCI_DATA; +} + +/*! + \brief enable specified DCI interrupt + \param[in] interrupt: + \arg DCI_INT_EF: end of frame interrupt + \arg DCI_INT_OVR: FIFO overrun interrupt + \arg DCI_INT_ESE: embedded synchronous error interrupt + \arg DCI_INT_VS: vsync interrupt + \arg DCI_INT_EL: end of line interrupt + \param[out] none + \retval none +*/ +void dci_interrupt_enable(uint32_t interrupt) +{ + DCI_INTEN |= interrupt; +} + +/*! + \brief disable specified DCI interrupt + \param[in] interrupt: + \arg DCI_INT_EF: end of frame interrupt + \arg DCI_INT_OVR: FIFO overrun interrupt + \arg DCI_INT_ESE: embedded synchronous error interrupt + \arg DCI_INT_VS: vsync interrupt + \arg DCI_INT_EL: end of line interrupt + \param[out] none + \retval none +*/ +void dci_interrupt_disable(uint32_t interrupt) +{ + DCI_INTEN &= ~interrupt; +} + +/*! + \brief clear specified interrupt + \param[in] interrupt: + \arg DCI_INT_EF: end of frame interrupt + \arg DCI_INT_OVR: FIFO overrun interrupt + \arg DCI_INT_ESE: embedded synchronous error interrupt + \arg DCI_INT_VS: vsync interrupt + \arg DCI_INT_EL: end of line interrupt + \param[out] none + \retval none +*/ +void dci_interrupt_clear(uint32_t interrupt) +{ + DCI_INTC |= interrupt; +} + +/*! + \brief get specified flag + \param[in] flag: + \arg DCI_FLAG_HS: HS line status + \arg DCI_FLAG_VS: VS line status + \arg DCI_FLAG_FV:FIFO valid + \arg DCI_FLAG_EFF: end of frame flag + \arg DCI_FLAG_OVRF: FIFO overrun flag + \arg DCI_FLAG_ESEF: embedded synchronous error flag + \arg DCI_FLAG_VSF: vsync flag + \arg DCI_FLAG_ELF: end of line flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dci_flag_get(uint32_t flag) +{ + uint32_t ret = 0U; + + switch(flag){ + /* get flag status from DCI_STAT0 register */ + case DCI_FLAG_HS: + ret = (DCI_STAT0 & DCI_STAT0_HS); + break; + case DCI_FLAG_VS: + ret = (DCI_STAT0 & DCI_STAT0_VS); + break; + case DCI_FLAG_FV: + ret = (DCI_STAT0 & DCI_STAT0_FV); + break; + /* get flag status from DCI_STAT1 register */ + case DCI_FLAG_EFF: + ret = (DCI_STAT1 & DCI_STAT1_EFF); + break; + case DCI_FLAG_OVRF: + ret = (DCI_STAT1 & DCI_STAT1_OVRF); + break; + case DCI_FLAG_ESEF: + ret = (DCI_STAT1 & DCI_STAT1_ESEF); + break; + case DCI_FLAG_VSF: + ret = (DCI_STAT1 & DCI_STAT1_VSF); + break; + case DCI_FLAG_ELF: + ret = (DCI_STAT1 & DCI_STAT1_ELF); + break; + default : + break; + } + + if(RESET == ret){ + return RESET; + }else{ + return SET; + } +} + +/*! + \brief get specified interrupt flag + \param[in] interrupt: + \arg DCI_INT_EF: end of frame interrupt + \arg DCI_INT_OVR: FIFO overrun interrupt + \arg DCI_INT_ESE: embedded synchronous error interrupt + \arg DCI_INT_VS: vsync interrupt + \arg DCI_INT_EL: end of line interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dci_interrupt_flag_get(uint32_t interrupt) +{ + if(RESET == (DCI_INTF & interrupt)){ + return RESET; + }else{ + return SET; + } +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c new file mode 100644 index 0000000000..c7f5ce9a70 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c @@ -0,0 +1,820 @@ +/*! + \file gd32f4xx_dma.c + \brief DMA driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_dma.h" + +/* DMA register bit offset */ +#define CHXCTL_PERIEN_OFFSET ((uint32_t)25U) + +/*! + \brief deinitialize DMA a channel registers + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is deinitialized + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_deinit(uint32_t dma_periph,dma_channel_enum channelx) +{ + /* disable DMA a channel */ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CHEN; + /* reset DMA channel registers */ + DMA_CHCTL(dma_periph,channelx) = DMA_CHCTL_RESET_VALUE; + DMA_CHCNT(dma_periph,channelx) = DMA_CHCNT_RESET_VALUE; + DMA_CHPADDR(dma_periph,channelx) = DMA_CHPADDR_RESET_VALUE; + DMA_CHM0ADDR(dma_periph,channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_CHM1ADDR(dma_periph,channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_CHFCTL(dma_periph,channelx) = DMA_CHFCTL_RESET_VALUE; + if(channelx < DMA_CH4){ + DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE,channelx); + }else{ + DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE,channelx); + } +} + +/*! + \brief initialize DMA single data mode + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is initialized + \arg DMA_CHx(x=0..7) + \param[in] init_struct: the data needed to initialize DMA single data mode + periph_addr: peripheral base address + periph_memory_width: DMA_PERIPH_WIDTH_8BIT,DMA_PERIPH_WIDTH_16BIT,DMA_PERIPH_WIDTH_32BIT + periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE,DMA_PERIPH_INCREASE_FIX + memory0_addr: memory base address + memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE + direction: DMA_PERIPH_TO_MEMORY,DMA_MEMORY_TO_PERIPH,DMA_MEMORY_TO_MEMORY + number: the number of remaining data to be transferred by the DMA + priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH + circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE + \param[out] none + \retval none +*/ +void dma_single_data_mode_init(uint32_t dma_periph,dma_channel_enum channelx,dma_single_data_parameter_struct init_struct) +{ + uint32_t ctl; + + /* select single data mode */ + DMA_CHFCTL(dma_periph,channelx) &= ~DMA_CHXFCTL_MDMEN; + + /* configure peripheral base address */ + DMA_CHPADDR(dma_periph,channelx) = init_struct.periph_addr; + + /* configure memory base address */ + DMA_CHM0ADDR(dma_periph,channelx) = init_struct.memory0_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(dma_periph,channelx) = init_struct.number; + + /* configure peripheral and memory transfer width,channel priotity,transfer mode */ + ctl = DMA_CHCTL(dma_periph,channelx); + ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM); + ctl |= (init_struct.periph_memory_width | (init_struct.periph_memory_width << 2) | init_struct.priority | init_struct.direction); + DMA_CHCTL(dma_periph,channelx) = ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct.periph_inc){ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA; + }else if(DMA_PERIPH_INCREASE_DISABLE == init_struct.periph_inc){ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_PNAGA; + }else{ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PAIF; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct.memory_inc){ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MNAGA; + }else{ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure DMA circular mode */ + if(DMA_CIRCULAR_MODE_ENABLE == init_struct.circular_mode){ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CMEN; + }else{ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CMEN; + } +} + +/*! + \brief initialize DMA multi data mode + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is initialized + \arg DMA_CHx(x=0..7) + \param[in] dma_multi_data_parameter_struct: the data needed to initialize DMA multi data mode + periph_addr: peripheral base address + periph_width: DMA_PERIPH_WIDTH_8BIT,DMA_PERIPH_WIDTH_16BIT,DMA_PERIPH_WIDTH_32BIT + periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE,DMA_PERIPH_INCREASE_FIX + memory0_addr: memory0 base address + memory_width: DMA_MEMORY_WIDTH_8BIT,DMA_MEMORY_WIDTH_16BIT,DMA_MEMORY_WIDTH_32BIT + memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE + direction: DMA_PERIPH_TO_MEMORY,DMA_MEMORY_TO_PERIPH,DMA_MEMORY_TO_MEMORY + number: the number of remaining data to be transferred by the DMA + priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH + circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE + memory_burst_width: DMA_MEMORY_BURST_SINGLE,DMA_MEMORY_BURST_4_BEAT,DMA_MEMORY_BURST_8_BEAT,DMA_MEMORY_BURST_16_BEAT + periph_burst_width: DMA_PERIPH_BURST_SINGLE,DMA_PERIPH_BURST_4_BEAT,DMA_PERIPH_BURST_8_BEAT,DMA_PERIPH_BURST_16_BEAT + critical_value: DMA_FIFO_1_WORD,DMA_FIFO_2_WORD,DMA_FIFO_3_WORD,DMA_FIFO_4_WORD + \param[out] none + \retval none +*/ +void dma_multi_data_mode_init(uint32_t dma_periph,dma_channel_enum channelx,dma_multi_data_parameter_struct init_struct) +{ + uint32_t ctl; + + /* select multi data mode and configure FIFO critical value */ + DMA_CHFCTL(dma_periph,channelx) |= (DMA_CHXFCTL_MDMEN | init_struct.critical_value); + + /* configure peripheral base address */ + DMA_CHPADDR(dma_periph,channelx) = init_struct.periph_addr; + + /* configure memory base address */ + DMA_CHM0ADDR(dma_periph,channelx) = init_struct.memory0_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(dma_periph,channelx) = init_struct.number; + + /* configure peripheral and memory transfer width,channel priotity,transfer mode,peripheral and memory burst transfer width */ + ctl = DMA_CHCTL(dma_periph,channelx); + ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM | DMA_CHXCTL_PBURST | DMA_CHXCTL_MBURST); + ctl |= (init_struct.periph_width | (init_struct.memory_width ) | init_struct.priority | init_struct.direction | init_struct.memory_burst_width | init_struct.periph_burst_width); + DMA_CHCTL(dma_periph,channelx) = ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct.periph_inc){ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA; + }else if(DMA_PERIPH_INCREASE_DISABLE == init_struct.periph_inc){ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_PNAGA; + }else{ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PAIF; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct.memory_inc){ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MNAGA; + }else{ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure DMA circular mode */ + if(DMA_CIRCULAR_MODE_ENABLE == init_struct.circular_mode){ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CMEN; + }else{ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CMEN; + } +} + +/*! + \brief get DMA flag is set or not + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get flag + \arg DMA_CHx(x=0..7) + \param[in] flag: specify get which flag + \arg DMA_INTF_FEEIF: FIFO error and exception flag + \arg DMA_INTF_SDEIF: single data mode exception flag + \arg DMA_INTF_TAEIF: transfer access error flag + \arg DMA_INTF_HTFIF: half transfer finish flag + \arg DMA_INTF_FTFIF: full transger finish flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_flag_get(uint32_t dma_periph,dma_channel_enum channelx,uint32_t flag) +{ + if(channelx < DMA_CH4){ + if(DMA_INTF0(dma_periph) & DMA_FLAG_ADD(flag,channelx)){ + return SET; + }else{ + return RESET; + } + }else{ + channelx -= (dma_channel_enum)4; + if(DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag,channelx)){ + return SET; + }else{ + return RESET; + } + } +} + +/*! + \brief clear DMA a channel flag + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get flag + \arg DMA_CHx(x=0..7) + \param[in] flag: specify get which flag + \arg DMA_INTF_FEEIF: FIFO error and exception flag + \arg DMA_INTF_SDEIF: single data mode exception flag + \arg DMA_INTF_TAEIF: transfer access error flag + \arg DMA_INTF_HTFIF: half transfer finish flag + \arg DMA_INTF_FTFIF: full transger finish flag + \param[out] none + \retval none +*/ +void dma_flag_clear(uint32_t dma_periph,dma_channel_enum channelx,uint32_t flag) +{ + if(channelx < DMA_CH4){ + DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(flag,channelx); + }else{ + channelx -= (dma_channel_enum)4; + DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(flag,channelx); + } +} + +/*! + \brief get DMA interrupt flag is set or not + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get interrupt flag + \arg DMA_CHx(x=0..7) + \param[in] interrupt: specify get which flag + \arg DMA_INTF_FEEIF: FIFO error and exception flag + \arg DMA_INTF_SDEIF: single data mode exception flag + \arg DMA_INTF_TAEIF: transfer access error flag + \arg DMA_INTF_HTFIF: half transfer finish flag + \arg DMA_INTF_FTFIF: full transger finish flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_interrupt_flag_get(uint32_t dma_periph,dma_channel_enum channelx,uint32_t interrupt) +{ + uint32_t interrupt_enable = 0U,interrupt_flag = 0U; + dma_channel_enum channel_flag_offset = channelx; + if(channelx < DMA_CH4){ + switch(interrupt){ + case DMA_INTF_FEEIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx); + interrupt_enable = DMA_CHFCTL(dma_periph,channelx) & DMA_CHXFCTL_FEEIE; + break; + case DMA_INTF_SDEIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx); + interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_SDEIE; + break; + case DMA_INTF_TAEIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx); + interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_TAEIE; + break; + case DMA_INTF_HTFIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx); + interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INTF_FTFIF: + interrupt_flag = (DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx)); + interrupt_enable = (DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_FTFIE); + break; + default: + break; + } + }else{ + channel_flag_offset -= (dma_channel_enum)4; + switch(interrupt){ + case DMA_INTF_FEEIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset); + interrupt_enable = DMA_CHFCTL(dma_periph,channelx) & DMA_CHXFCTL_FEEIE; + break; + case DMA_INTF_SDEIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_SDEIE; + break; + case DMA_INTF_TAEIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_TAEIE; + break; + case DMA_INTF_HTFIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INTF_FTFIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_FTFIE; + break; + default: + break; + } + } + + if(interrupt_flag && interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear DMA a channel interrupt flag + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to clear interrupt flag + \arg DMA_CHx(x=0..7) + \param[in] interrupt: specify get which flag + \arg DMA_INTC_FEEIFC: clear FIFO error and exception flag + \arg DMA_INTC_SDEIFC: clear single data mode exception flag + \arg DMA_INTC_TAEIFC: clear transfer access error flag + \arg DMA_INTC_HTFIFC: clear half transfer finish flag + \arg DMA_INTC_FTFIFC: clear full transger finish flag + \param[out] none + \retval none +*/ +void dma_interrupt_flag_clear(uint32_t dma_periph,dma_channel_enum channelx,uint32_t interrupt) +{ + if(channelx < DMA_CH4){ + DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(interrupt,channelx); + }else{ + channelx -= (dma_channel_enum)4; + DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(interrupt,channelx); + } +} + +/*! + \brief enable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] source: specify which interrupt to enbale + \arg DMA_CHXCTL_SDEIE: single data mode exception interrupt enable + \arg DMA_CHXCTL_TAEIE: tranfer access error interrupt enable + \arg DMA_CHXCTL_HTFIE: half transfer finish interrupt enable + \arg DMA_CHXCTL_FTFIE: full transfer finish interrupt enable + \arg DMA_CHXFCTL_FEEIE: FIFO exception interrupt enable + \param[out] none + \retval none +*/ +void dma_interrupt_enable(uint32_t dma_periph,dma_channel_enum channelx,uint32_t source) +{ + if(DMA_CHXFCTL_FEEIE != source){ + DMA_CHCTL(dma_periph,channelx) |= source; + }else{ + DMA_CHFCTL(dma_periph,channelx) |= source; + } +} + +/*! + \brief disable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] source: specify which interrupt to disbale + \arg DMA_CHXCTL_SDEIE: single data mode exception interrupt enable + \arg DMA_CHXCTL_TAEIE: tranfer access error interrupt enable + \arg DMA_CHXCTL_HTFIE: half transfer finish interrupt enable + \arg DMA_CHXCTL_FTFIE: full transfer finish interrupt enable + \arg DMA_CHXFCTL_FEEIE: FIFO exception interrupt enable + \param[out] none + \retval none +*/ +void dma_interrupt_disable(uint32_t dma_periph,dma_channel_enum channelx,uint32_t source) +{ + if(DMA_CHXFCTL_FEEIE != source){ + DMA_CHCTL(dma_periph,channelx) &= ~source; + }else{ + DMA_CHFCTL(dma_periph,channelx) &= ~source; + } +} + +/*! + \brief set DMA peripheral base address + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set peripheral base address + \arg DMA_CHx(x=0..7) + \param[in] address: peripheral base address + \param[out] none + \retval none +*/ +void dma_periph_address_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t address) +{ + DMA_CHPADDR(dma_periph,channelx) = address; +} + +/*! + \brief set DMA Memory0 base address + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set Memory base address + \arg DMA_CHx(x=0..7) + \param[in] memory_flag: DMA_MEMORY_x(x=0,1) + \param[in] address: Memory base address + \param[out] none + \retval none +*/ +void dma_memory_address_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t memory_flag,uint32_t address) +{ + if(memory_flag){ + DMA_CHM1ADDR(dma_periph,channelx) = address; + }else{ + DMA_CHM0ADDR(dma_periph,channelx) = address; + } +} + +/*! + \brief set the number of remaining data to be transferred by the DMA + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set number + \arg DMA_CHx(x=0..7) + \param[in] number: the number of remaining data to be transferred by the DMA + \param[out] none + \retval none +*/ +void dma_transfer_number_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t number) +{ + DMA_CHCNT(dma_periph,channelx) = number; +} + +/*! + \brief get the number of remaining data to be transferred by the DMA + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set number + \arg DMA_CHx(x=0..7) + \param[out] none + \retval uint32_t: the number of remaining data to be transferred by the DMA +*/ +uint32_t dma_transfer_number_get(uint32_t dma_periph,dma_channel_enum channelx) +{ + return (uint32_t)DMA_CHCNT(dma_periph,channelx); +} + +/*! + \brief configure priority level of DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] priority: priority Level of this channel + \arg DMA_PRIORITY_LOW: low priority + \arg DMA_PRIORITY_MEDIUM: medium priority + \arg DMA_PRIORITY_HIGH: high priority + \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority + \param[out] none + \retval none +*/ +void dma_priority_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t priority) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph,channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PRIO; + ctl |= priority; + DMA_CHCTL(dma_periph,channelx) = ctl; +} + +/*! + \brief configure transfer burst beats of memory + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] mbeat: transfer burst beats + \arg DMA_MEMORY_BURST_SINGLE: memory transfer single burst + \arg DMA_MEMORY_BURST_4_BEAT: memory transfer 4-beat burst + \arg DMA_MEMORY_BURST_8_BEAT: memory transfer 8-beat burst + \arg DMA_MEMORY_BURST_16_BEAT: memory transfer 16-beat burst + \param[out] none + \retval none +*/ +void dma_memory_burst_beats_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t mbeat) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph,channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MBURST; + ctl |= mbeat; + DMA_CHCTL(dma_periph,channelx) = ctl; +} + +/*! + \brief configure transfer burst beats of peripheral + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] pbeat: transfer burst beats + \arg DMA_PERIPH_BURST_SINGLE: peripheral transfer single burst + \arg DMA_PERIPH_BURST_4_BEAT: peripheral transfer 4-beat burst + \arg DMA_PERIPH_BURST_8_BEAT: peripheral transfer 8-beat burst + \arg DMA_PERIPH_BURST_16_BEAT: peripheral transfer 16-beat burst + \param[out] none + \retval none +*/ +void dma_periph_burst_beats_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t pbeat) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph,channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PBURST; + ctl |= pbeat; + DMA_CHCTL(dma_periph,channelx) = ctl; +} + +/*! + \brief configure transfer data size of memory + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] msize: transfer data size of memory + \arg DMA_MEMORY_WIDTH_8BIT: transfer data size of memory is 8-bit + \arg DMA_MEMORY_WIDTH_16BIT: transfer data size of memory is 16-bit + \arg DMA_MEMORY_WIDTH_32BIT: transfer data size of memory is 32-bit + \param[out] none + \retval none +*/ +void dma_memory_width_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t msize) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph,channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MWIDTH; + ctl |= msize; + DMA_CHCTL(dma_periph,channelx) = ctl; +} + +/*! + \brief configure transfer data size of peripheral + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] msize: transfer data size of peripheral + \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data size of peripheral is 8-bit + \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data size of peripheral is 16-bit + \arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data size of peripheral is 32-bit + \param[out] none + \retval none +*/ +void dma_periph_width_config (uint32_t dma_periph,dma_channel_enum channelx,uint32_t psize) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph,channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PWIDTH; + ctl |= psize; + DMA_CHCTL(dma_periph,channelx) = ctl; +} + +/*! + \brief configure memory address generation generation_algorithm + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] generation_algorithm: the address generation algorithm + \arg DMA_MEMORY_INCREASE_ENABLE: next address of memory is increasing address mode + \arg DMA_MEMORY_INCREASE_DISABLE: next address of memory is fixed address mode + \param[out] none + \retval none +*/ +void dma_memory_address_generation_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t generation_algorithm) +{ + if(DMA_MEMORY_INCREASE_ENABLE == generation_algorithm){ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MNAGA; + }else{ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MNAGA; + } +} + +/*! + \brief configure peripheral address generation generation_algorithm + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] generation_algorithm: the address generation algorithm + \arg DMA_PERIPH_INCREASE_ENABLE: next address of peripheral is increasing address mode + \arg DMA_PERIPH_INCREASE_DISABLE: next address of peripheral is fixed address mode + \arg DMA_PERIPH_INCREASE_FIX: increasing steps of peripheral address is fixed + \param[out] none + \retval none +*/ +void dma_peripheral_address_generation_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t generation_algorithm) +{ + if(DMA_PERIPH_INCREASE_ENABLE == generation_algorithm){ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA; + }else if(DMA_PERIPH_INCREASE_DISABLE == generation_algorithm){ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_PNAGA; + }else{ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA; + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PAIF; + } +} + +/*! + \brief enable DMA circulation mode + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_circulation_enable(uint32_t dma_periph,dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CMEN; +} + +/*! + \brief disable DMA circulation mode + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_circulation_disable(uint32_t dma_periph,dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CMEN; +} + +/*! + \brief configure the direction of data transfer on the channel + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] direction: specify the direction of data transfer + \arg DMA_PERIPH_TO_MEMORY: read from peripheral and write to memory + \arg DMA_MEMORY_TO_PERIPH: read from memory and write to peripheral + \arg DMA_MEMORY_TO_MEMORY: read from memory and write to memory + \param[out] none + \retval none +*/ +void dma_transfer_direction_config(uint32_t dma_periph,dma_channel_enum channelx,uint8_t direction) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph,channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_TM; + ctl |= direction; + + DMA_CHCTL(dma_periph,channelx) = ctl; +} + +/*! + \brief enable DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_channel_enable(uint32_t dma_periph,dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CHEN; +} + +/*! + \brief disable DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_channel_disable(uint32_t dma_periph,dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CHEN; +} + +/*! + \brief DMA channel peripheral select + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] sub_periph: specify DMA channel peripheral + \arg DMA_SUBPERIx(x=0..7) + \param[out] none + \retval none +*/ +void dma_channel_subperipheral_select(uint32_t dma_periph,dma_channel_enum channelx,dma_subperipheral_enum sub_periph) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph,channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PERIEN; + ctl |= ((uint32_t)sub_periph << CHXCTL_PERIEN_OFFSET); + + DMA_CHCTL(dma_periph,channelx) = ctl; +} + +/*! + \brief DMA switch buffer mode config + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] memory1_addr: memory1 base address + \param[in] memory_select: DMA_MEMORY_0 or DMA_MEMORY_1 + \param[out] none + \retval none +*/ +void dma_switch_buffer_mode_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t memory1_addr,uint32_t memory_select) +{ + /* configure memory1 base address */ + DMA_CHM1ADDR(dma_periph,channelx) = memory1_addr; + + if(DMA_MEMORY_0 == memory_select){ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MBS; + }else{ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MBS; + } +} + +/*! + \brief DMA switch buffer mode enable + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void dma_switch_buffer_mode_enable(uint32_t dma_periph,dma_channel_enum channelx,ControlStatus newvalue) +{ + if(ENABLE == newvalue){ + /* switch buffer mode enable */ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_SBMEN; + }else{ + /* switch buffer mode disable */ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_SBMEN; + } +} + +/*! + \brief DMA using memory get + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[out] none + \retval the using memory +*/ +uint32_t dma_using_memory_get(uint32_t dma_periph,dma_channel_enum channelx) +{ + if((DMA_CHCTL(dma_periph,channelx)) & DMA_CHXCTL_MBS){ + return DMA_MEMORY_1; + }else{ + return DMA_MEMORY_0; + } +} + +/*! + \brief DMA flow controller configure + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] controller: specify DMA flow controler + \arg DMA_FLOW_CONTROLLER_DMA: DMA is the flow controller + \arg DMA_FLOW_CONTROLLER_PERI: peripheral is the flow controller + \param[out] none + \retval none +*/ +void dma_flow_controller_config(uint32_t dma_periph,dma_channel_enum channelx,uint32_t controller) +{ + if(DMA_FLOW_CONTROLLER_DMA == controller){ + DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_TFCS; + }else{ + DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_TFCS; + } +} + +/*! + \brief DMA FIFO status get + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[out] none + \retval the using memory +*/ +uint32_t dma_fifo_status_get(uint32_t dma_periph,dma_channel_enum channelx) +{ + return (DMA_CHFCTL(dma_periph,channelx) & DMA_CHXFCTL_FCNT); +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c new file mode 100644 index 0000000000..efec047be7 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c @@ -0,0 +1,3449 @@ +/*! + \file gd32f4xx_enet.c + \brief ENET driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.1, firmware for GD32F4xx +*/ + +#include "gd32f4xx_enet.h" + +#if defined (__CC_ARM) /*!< ARM compiler */ +__align(4) +enet_descriptors_struct rxdesc_tab[ENET_RXBUF_NUM]; /*!< ENET RxDMA descriptor */ +__align(4) +enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM]; /*!< ENET TxDMA descriptor */ +__align(4) +uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE]; /*!< ENET receive buffer */ +__align(4) +uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE]; /*!< ENET transmit buffer */ + +#elif defined ( __ICCARM__ ) /*!< IAR compiler */ +#pragma data_alignment=4 +enet_descriptors_struct rxdesc_tab[ENET_RXBUF_NUM]; /*!< ENET RxDMA descriptor */ +#pragma data_alignment=4 +enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM]; /*!< ENET TxDMA descriptor */ +#pragma data_alignment=4 +uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE]; /*!< ENET receive buffer */ +#pragma data_alignment=4 +uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE]; /*!< ENET transmit buffer */ + +#endif /* __CC_ARM */ + +/* global transmit and receive descriptors pointers */ +enet_descriptors_struct *dma_current_txdesc; +enet_descriptors_struct *dma_current_rxdesc; + +/* structure pointer of ptp descriptor for normal mode */ +enet_descriptors_struct *dma_current_ptp_txdesc = NULL; +enet_descriptors_struct *dma_current_ptp_rxdesc = NULL; + +/* init structure parameters for ENET initialization */ +static enet_initpara_struct enet_initpara ={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +/* array of register offset for debug information get */ +static const uint16_t enet_reg_tab[] = { +0x0000, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, 0x0028, 0x002C, 0x0034, +0x0038, 0x003C, 0x0040, 0x0044, 0x0048, 0x004C, 0x0050, 0x0054, 0x0058, 0x005C, 0x1080, + +0x0100, 0x0104, 0x0108, 0x010C, 0x0110, 0x014C, 0x0150, 0x0168, 0x0194, 0x0198, 0x01C4, + +0x0700, 0x0704,0x0708, 0x070C, 0x0710, 0x0714, 0x0718, 0x071C, 0x0720, 0x0728, 0x072C, + +0x1000, 0x1004, 0x1008, 0x100C, 0x1010, 0x1014, 0x1018, 0x101C, 0x1020, 0x1024, 0x1048, +0x104C, 0x1050, 0x1054}; + + +/*! + \brief deinitialize the ENET, and reset structure parameters for ENET initialization + \param[in] none + \param[out] none + \retval none +*/ +void enet_deinit(void) +{ + rcu_periph_reset_enable(RCU_ENETRST); + rcu_periph_reset_disable(RCU_ENETRST); + enet_initpara_reset(); +} + +/*! + \brief configure the parameters which are usually less cared for initialization + note -- this function must be called before enet_init(), otherwise + configuration will be no effect + \param[in] option: different function option, which is related to several parameters, + only one parameter can be selected which is shown as below, refer to enet_option_enum + \arg FORWARD_OPTION: choose to configure the frame forward related parameters + \arg DMABUS_OPTION: choose to configure the DMA bus mode related parameters + \arg DMA_MAXBURST_OPTION: choose to configure the DMA max burst related parameters + \arg DMA_ARBITRATION_OPTION: choose to configure the DMA arbitration related parameters + \arg STORE_OPTION: choose to configure the store forward mode related parameters + \arg DMA_OPTION: choose to configure the DMA descriptor related parameters + \arg VLAN_OPTION: choose to configure vlan related parameters + \arg FLOWCTL_OPTION: choose to configure flow control related parameters + \arg HASHH_OPTION: choose to configure hash high + \arg HASHL_OPTION: choose to configure hash low + \arg FILTER_OPTION: choose to configure frame filter related parameters + \arg HALFDUPLEX_OPTION: choose to configure halfduplex mode related parameters + \arg TIMER_OPTION: choose to configure time counter related parameters + \arg INTERFRAMEGAP_OPTION: choose to configure the inter frame gap related parameters + \param[in] para: the related parameters according to the option + all the related parameters should be configured which are shown as below + FORWARD_OPTION related parameters: + - ENET_AUTO_PADCRC_DROP_ENABLE/ ENET_AUTO_PADCRC_DROP_DISABLE ; + - ENET_TYPEFRAME_CRC_DROP_ENABLE/ ENET_TYPEFRAME_CRC_DROP_DISABLE ; + - ENET_FORWARD_ERRFRAMES_ENABLE/ ENET_FORWARD_ERRFRAMES_DISABLE ; + - ENET_FORWARD_UNDERSZ_GOODFRAMES_ENABLE/ ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE . + DMABUS_OPTION related parameters: + - ENET_ADDRESS_ALIGN_ENABLE/ ENET_ADDRESS_ALIGN_DISABLE ; + - ENET_FIXED_BURST_ENABLE/ ENET_FIXED_BURST_DISABLE ; + - ENET_MIXED_BURST_ENABLE/ ENET_MIXED_BURST_DISABLE ; + DMA_MAXBURST_OPTION related parameters: + - ENET_RXDP_1BEAT/ ENET_RXDP_2BEAT/ ENET_RXDP_4BEAT/ + ENET_RXDP_8BEAT/ ENET_RXDP_16BEAT/ ENET_RXDP_32BEAT/ + ENET_RXDP_4xPGBL_4BEAT/ ENET_RXDP_4xPGBL_8BEAT/ + ENET_RXDP_4xPGBL_16BEAT/ ENET_RXDP_4xPGBL_32BEAT/ + ENET_RXDP_4xPGBL_64BEAT/ ENET_RXDP_4xPGBL_128BEAT ; + - ENET_PGBL_1BEAT/ ENET_PGBL_2BEAT/ ENET_PGBL_4BEAT/ + ENET_PGBL_8BEAT/ ENET_PGBL_16BEAT/ ENET_PGBL_32BEAT/ + ENET_PGBL_4xPGBL_4BEAT/ ENET_PGBL_4xPGBL_8BEAT/ + ENET_PGBL_4xPGBL_16BEAT/ ENET_PGBL_4xPGBL_32BEAT/ + ENET_PGBL_4xPGBL_64BEAT/ ENET_PGBL_4xPGBL_128BEAT ; + - ENET_RXTX_DIFFERENT_PGBL/ ENET_RXTX_SAME_PGBL ; + DMA_ARBITRATION_OPTION related parameters: + - ENET_ARBITRATION_RXPRIORTX + - ENET_ARBITRATION_RXTX_1_1/ ENET_ARBITRATION_RXTX_2_1/ + ENET_ARBITRATION_RXTX_3_1/ ENET_ARBITRATION_RXTX_4_1/. + STORE_OPTION related parameters: + - ENET_RX_MODE_STOREFORWARD/ ENET_RX_MODE_CUTTHROUGH ; + - ENET_TX_MODE_STOREFORWARD/ ENET_TX_MODE_CUTTHROUGH ; + - ENET_RX_THRESHOLD_64BYTES/ ENET_RX_THRESHOLD_32BYTES/ + ENET_RX_THRESHOLD_96BYTES/ ENET_RX_THRESHOLD_128BYTES ; + - ENET_TX_THRESHOLD_64BYTES/ ENET_TX_THRESHOLD_128BYTES/ + ENET_TX_THRESHOLD_192BYTES/ ENET_TX_THRESHOLD_256BYTES/ + ENET_TX_THRESHOLD_40BYTES/ ENET_TX_THRESHOLD_32BYTES/ + ENET_TX_THRESHOLD_24BYTES/ ENET_TX_THRESHOLD_16BYTES . + DMA_OPTION related parameters: + - ENET_FLUSH_RXFRAME_ENABLE/ ENET_FLUSH_RXFRAME_DISABLE ; + - ENET_SECONDFRAME_OPT_ENABLE/ ENET_SECONDFRAME_OPT_DISABLE ; + - ENET_ENHANCED_DESCRIPTOR/ ENET_NORMAL_DESCRIPTOR . + VLAN_OPTION related parameters: + - ENET_VLANTAGCOMPARISON_12BIT/ ENET_VLANTAGCOMPARISON_16BIT ; + - MAC_VLT_VLTI(regval) . + FLOWCTL_OPTION related parameters: + - MAC_FCTL_PTM(regval) ; + - ENET_ZERO_QUANTA_PAUSE_ENABLE/ ENET_ZERO_QUANTA_PAUSE_DISABLE ; + - ENET_PAUSETIME_MINUS4/ ENET_PAUSETIME_MINUS28/ + ENET_PAUSETIME_MINUS144/ENET_PAUSETIME_MINUS256 ; + - ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT/ ENET_UNIQUE_PAUSEDETECT ; + - ENET_RX_FLOWCONTROL_ENABLE/ ENET_RX_FLOWCONTROL_DISABLE ; + - ENET_TX_FLOWCONTROL_ENABLE/ ENET_TX_FLOWCONTROL_DISABLE . + HASHH_OPTION related parameters: + - 0x0~0xFFFF FFFFU + HASHL_OPTION related parameters: + - 0x0~0xFFFF FFFFU + FILTER_OPTION related parameters: + - ENET_SRC_FILTER_NORMAL_ENABLE/ ENET_SRC_FILTER_INVERSE_ENABLE/ + ENET_SRC_FILTER_DISABLE ; + - ENET_DEST_FILTER_INVERSE_ENABLE/ ENET_DEST_FILTER_INVERSE_DISABLE ; + - ENET_MULTICAST_FILTER_HASH_OR_PERFECT/ ENET_MULTICAST_FILTER_HASH/ + ENET_MULTICAST_FILTER_PERFECT/ ENET_MULTICAST_FILTER_NONE ; + - ENET_UNICAST_FILTER_EITHER/ ENET_UNICAST_FILTER_HASH/ + ENET_UNICAST_FILTER_PERFECT ; + - ENET_PCFRM_PREVENT_ALL/ ENET_PCFRM_PREVENT_PAUSEFRAME/ + ENET_PCFRM_FORWARD_ALL/ ENET_PCFRM_FORWARD_FILTERED . + HALFDUPLEX_OPTION related parameters: + - ENET_CARRIERSENSE_ENABLE/ ENET_CARRIERSENSE_DISABLE ; + - ENET_RECEIVEOWN_ENABLE/ ENET_RECEIVEOWN_DISABLE ; + - ENET_RETRYTRANSMISSION_ENABLE/ ENET_RETRYTRANSMISSION_DISABLE ; + - ENET_BACKOFFLIMIT_10/ ENET_BACKOFFLIMIT_8/ + ENET_BACKOFFLIMIT_4/ ENET_BACKOFFLIMIT_1 ; + - ENET_DEFERRALCHECK_ENABLE/ ENET_DEFERRALCHECK_DISABLE . + TIMER_OPTION related parameters: + - ENET_WATCHDOG_ENABLE/ ENET_WATCHDOG_DISABLE ; + - ENET_JABBER_ENABLE/ ENET_JABBER_DISABLE ; + INTERFRAMEGAP_OPTION related parameters: + - ENET_INTERFRAMEGAP_96BIT/ ENET_INTERFRAMEGAP_88BIT/ + ENET_INTERFRAMEGAP_80BIT/ ENET_INTERFRAMEGAP_72BIT/ + ENET_INTERFRAMEGAP_64BIT/ ENET_INTERFRAMEGAP_56BIT/ + ENET_INTERFRAMEGAP_48BIT/ ENET_INTERFRAMEGAP_40BIT . + \param[out] none + \retval none +*/ +void enet_initpara_config(enet_option_enum option, uint32_t para) +{ + switch(option){ + case FORWARD_OPTION: + /* choose to configure forward_frame, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)FORWARD_OPTION; + enet_initpara.forward_frame = para; + break; + case DMABUS_OPTION: + /* choose to configure dmabus_mode, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)DMABUS_OPTION; + enet_initpara.dmabus_mode = para; + break; + case DMA_MAXBURST_OPTION: + /* choose to configure dma_maxburst, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)DMA_MAXBURST_OPTION; + enet_initpara.dma_maxburst = para; + break; + case DMA_ARBITRATION_OPTION: + /* choose to configure dma_arbitration, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)DMA_ARBITRATION_OPTION; + enet_initpara.dma_arbitration = para; + break; + case STORE_OPTION: + /* choose to configure store_forward_mode, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)STORE_OPTION; + enet_initpara.store_forward_mode = para; + break; + case DMA_OPTION: + /* choose to configure dma_function, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)DMA_OPTION; + +#ifndef SELECT_DESCRIPTORS_ENHANCED_MODE + para &= ~ENET_ENHANCED_DESCRIPTOR; +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + + enet_initpara.dma_function = para; + break; + case VLAN_OPTION: + /* choose to configure vlan_config, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)VLAN_OPTION; + enet_initpara.vlan_config = para; + break; + case FLOWCTL_OPTION: + /* choose to configure flow_control, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)FLOWCTL_OPTION; + enet_initpara.flow_control = para; + break; + case HASHH_OPTION: + /* choose to configure hashtable_high, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)HASHH_OPTION; + enet_initpara.hashtable_high = para; + break; + case HASHL_OPTION: + /* choose to configure hashtable_low, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)HASHL_OPTION; + enet_initpara.hashtable_low = para; + break; + case FILTER_OPTION: + /* choose to configure framesfilter_mode, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)FILTER_OPTION; + enet_initpara.framesfilter_mode = para; + break; + case HALFDUPLEX_OPTION: + /* choose to configure halfduplex_param, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)HALFDUPLEX_OPTION; + enet_initpara.halfduplex_param = para; + break; + case TIMER_OPTION: + /* choose to configure timer_config, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)TIMER_OPTION; + enet_initpara.timer_config = para; + break; + case INTERFRAMEGAP_OPTION: + /* choose to configure interframegap, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)INTERFRAMEGAP_OPTION; + enet_initpara.interframegap = para; + break; + default: + break; + } +} + +/*! + \brief initialize ENET peripheral with generally concerned parameters and the less cared + parameters + \param[in] mediamode: PHY mode and mac loopback configurations, only one parameter can be selected + which is shown as below, refer to enet_mediamode_enum + \arg ENET_AUTO_NEGOTIATION: PHY auto negotiation + \arg ENET_100M_FULLDUPLEX: 100Mbit/s, full-duplex + \arg ENET_100M_HALFDUPLEX: 100Mbit/s, half-duplex + \arg ENET_10M_FULLDUPLEX: 10Mbit/s, full-duplex + \arg ENET_10M_HALFDUPLEX: 10Mbit/s, half-duplex + \arg ENET_LOOPBACKMODE: MAC in loopback mode at the MII + \param[in] checksum: IP frame checksum offload function, only one parameter can be selected + which is shown as below, refer to enet_mediamode_enum + \arg ENET_NO_AUTOCHECKSUM: disable IP frame checksum function + \arg ENET_AUTOCHECKSUM_DROP_FAILFRAMES: enable IP frame checksum function + \arg ENET_AUTOCHECKSUM_ACCEPT_FAILFRAMES: enable IP frame checksum function, and the received frame + with only payload error but no other errors will not be dropped + \param[in] recept: frame filter function, only one parameter can be selected + which is shown as below, refer to enet_frmrecept_enum + \arg ENET_PROMISCUOUS_MODE: promiscuous mode enabled + \arg ENET_RECEIVEALL: all received frame are forwarded to application + \arg ENET_BROADCAST_FRAMES_PASS: the address filters pass all received broadcast frames + \arg ENET_BROADCAST_FRAMES_DROP: the address filters filter all incoming broadcast frames + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus enet_init(enet_mediamode_enum mediamode, enet_chksumconf_enum checksum, enet_frmrecept_enum recept) +{ + uint32_t reg_value=0U, reg_temp = 0U, temp = 0U; + uint32_t media_temp = 0U; + uint32_t timeout = 0U; + uint16_t phy_value = 0U; + ErrStatus phy_state= ERROR, enet_state = ERROR; + + /* PHY interface configuration, configure SMI clock and reset PHY chip */ + if(ERROR == enet_phy_config()){ + _ENET_DELAY_(PHY_RESETDELAY); + if(ERROR == enet_phy_config()){ + return enet_state; + } + } + /* initialize ENET peripheral with generally concerned parameters */ + enet_default_init(); + + /* 1st, configure mediamode */ + media_temp = (uint32_t)mediamode; + /* if is PHY auto negotiation */ + if((uint32_t)ENET_AUTO_NEGOTIATION == media_temp){ + /* wait for PHY_LINKED_STATUS bit be set */ + do{ + enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); + phy_value &= PHY_LINKED_STATUS; + timeout++; + }while((RESET == phy_value) && (timeout < PHY_READ_TO)); + /* return ERROR due to timeout */ + if(PHY_READ_TO == timeout){ + return enet_state; + } + /* reset timeout counter */ + timeout = 0U; + + /* enable auto-negotiation */ + phy_value = PHY_AUTONEGOTIATION; + phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value); + if(!phy_state){ + /* return ERROR due to write timeout */ + return enet_state; + } + + /* wait for the PHY_AUTONEGO_COMPLETE bit be set */ + do{ + enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); + phy_value &= PHY_AUTONEGO_COMPLETE; + timeout++; + }while((RESET == phy_value) && (timeout < (uint32_t)PHY_READ_TO)); + /* return ERROR due to timeout */ + if(PHY_READ_TO == timeout){ + return enet_state; + } + /* reset timeout counter */ + timeout = 0U; + + /* read the result of the auto-negotiation */ + enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_SR, &phy_value); + /* configure the duplex mode of MAC following the auto-negotiation result */ + if((uint16_t)RESET != (phy_value & PHY_DUPLEX_STATUS)){ + media_temp = ENET_MODE_FULLDUPLEX; + }else{ + media_temp = ENET_MODE_HALFDUPLEX; + } + /* configure the communication speed of MAC following the auto-negotiation result */ + if((uint16_t)RESET !=(phy_value & PHY_SPEED_STATUS)){ + media_temp |= ENET_SPEEDMODE_10M; + }else{ + media_temp |= ENET_SPEEDMODE_100M; + } + }else{ + phy_value = (uint16_t)((media_temp & ENET_MAC_CFG_DPM) >> 3); + phy_value |= (uint16_t)((media_temp & ENET_MAC_CFG_SPD) >> 1); + phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value); + if(!phy_state){ + /* return ERROR due to write timeout */ + return enet_state; + } + /* PHY configuration need some time */ + _ENET_DELAY_(PHY_CONFIGDELAY); + } + /* after configuring the PHY, use mediamode to configure registers */ + reg_value = ENET_MAC_CFG; + /* configure ENET_MAC_CFG register */ + reg_value &= (~(ENET_MAC_CFG_SPD |ENET_MAC_CFG_DPM |ENET_MAC_CFG_LBM)); + reg_value |= media_temp; + ENET_MAC_CFG = reg_value; + + + /* 2st, configure checksum */ + if(RESET != ((uint32_t)checksum & ENET_CHECKSUMOFFLOAD_ENABLE)){ + ENET_MAC_CFG |= ENET_CHECKSUMOFFLOAD_ENABLE; + + reg_value = ENET_DMA_CTL; + /* configure ENET_DMA_CTL register */ + reg_value &= ~ENET_DMA_CTL_DTCERFD; + reg_value |= ((uint32_t)checksum & ENET_DMA_CTL_DTCERFD); + ENET_DMA_CTL = reg_value; + } + + /* 3rd, configure recept */ + ENET_MAC_FRMF |= (uint32_t)recept; + + /* 4th, configure different function options */ + /* configure forward_frame related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)FORWARD_OPTION)){ + reg_temp = enet_initpara.forward_frame; + + reg_value = ENET_MAC_CFG; + temp = reg_temp; + /* configure ENET_MAC_CFG register */ + reg_value &= (~(ENET_MAC_CFG_TFCD |ENET_MAC_CFG_APCD)); + temp &= (ENET_MAC_CFG_TFCD | ENET_MAC_CFG_APCD); + reg_value |= temp; + ENET_MAC_CFG = reg_value; + + reg_value = ENET_DMA_CTL; + temp = reg_temp; + /* configure ENET_DMA_CTL register */ + reg_value &= (~(ENET_DMA_CTL_FERF |ENET_DMA_CTL_FUF)); + temp &= ((ENET_DMA_CTL_FERF | ENET_DMA_CTL_FUF)<<2); + reg_value |= (temp >> 2); + ENET_DMA_CTL = reg_value; + } + + /* configure dmabus_mode related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMABUS_OPTION)){ + temp = enet_initpara.dmabus_mode; + + reg_value = ENET_DMA_BCTL; + /* configure ENET_DMA_BCTL register */ + reg_value &= ~(ENET_DMA_BCTL_AA | ENET_DMA_BCTL_FB \ + |ENET_DMA_BCTL_FPBL | ENET_DMA_BCTL_MB); + reg_value |= temp; + ENET_DMA_BCTL = reg_value; + } + + /* configure dma_maxburst related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_MAXBURST_OPTION)){ + temp = enet_initpara.dma_maxburst; + + reg_value = ENET_DMA_BCTL; + /* configure ENET_DMA_BCTL register */ + reg_value &= ~(ENET_DMA_BCTL_RXDP| ENET_DMA_BCTL_PGBL | ENET_DMA_BCTL_UIP); + reg_value |= temp; + ENET_DMA_BCTL = reg_value; + } + + /* configure dma_arbitration related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_ARBITRATION_OPTION)){ + temp = enet_initpara.dma_arbitration; + + reg_value = ENET_DMA_BCTL; + /* configure ENET_DMA_BCTL register */ + reg_value &= ~(ENET_DMA_BCTL_RTPR | ENET_DMA_BCTL_DAB); + reg_value |= temp; + ENET_DMA_BCTL = reg_value; + } + + /* configure store_forward_mode related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)STORE_OPTION)){ + temp = enet_initpara.store_forward_mode; + + reg_value = ENET_DMA_CTL; + /* configure ENET_DMA_CTL register */ + reg_value &= ~(ENET_DMA_CTL_RSFD | ENET_DMA_CTL_TSFD| ENET_DMA_CTL_RTHC| ENET_DMA_CTL_TTHC); + reg_value |= temp; + ENET_DMA_CTL = reg_value; + } + + /* configure dma_function related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_OPTION)){ + reg_temp = enet_initpara.dma_function; + + reg_value = ENET_DMA_CTL; + temp = reg_temp; + /* configure ENET_DMA_CTL register */ + reg_value &= (~(ENET_DMA_CTL_DAFRF |ENET_DMA_CTL_OSF)); + temp &= (ENET_DMA_CTL_DAFRF | ENET_DMA_CTL_OSF); + reg_value |= temp; + ENET_DMA_CTL = reg_value; + + reg_value = ENET_DMA_BCTL; + temp = reg_temp; + /* configure ENET_DMA_BCTL register */ + reg_value &= (~ENET_DMA_BCTL_DFM); + temp &= ENET_DMA_BCTL_DFM; + reg_value |= temp; + ENET_DMA_BCTL = reg_value; + } + + /* configure vlan_config related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)VLAN_OPTION)){ + reg_temp = enet_initpara.vlan_config; + + reg_value = ENET_MAC_VLT; + /* configure ENET_MAC_VLT register */ + reg_value &= ~(ENET_MAC_VLT_VLTI | ENET_MAC_VLT_VLTC); + reg_value |= reg_temp; + ENET_MAC_VLT = reg_value; + } + + /* configure flow_control related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)FLOWCTL_OPTION)){ + reg_temp = enet_initpara.flow_control; + + reg_value = ENET_MAC_FCTL; + temp = reg_temp; + /* configure ENET_MAC_FCTL register */ + reg_value &= ~(ENET_MAC_FCTL_PTM |ENET_MAC_FCTL_DZQP |ENET_MAC_FCTL_PLTS \ + | ENET_MAC_FCTL_UPFDT |ENET_MAC_FCTL_RFCEN |ENET_MAC_FCTL_TFCEN); + temp &= (ENET_MAC_FCTL_PTM |ENET_MAC_FCTL_DZQP |ENET_MAC_FCTL_PLTS \ + | ENET_MAC_FCTL_UPFDT |ENET_MAC_FCTL_RFCEN |ENET_MAC_FCTL_TFCEN); + reg_value |= temp; + ENET_MAC_FCTL = reg_value; + + reg_value = ENET_MAC_FCTH; + temp = reg_temp; + /* configure ENET_MAC_FCTH register */ + reg_value &= ~(ENET_MAC_FCTH_RFA |ENET_MAC_FCTH_RFD); + temp &= ((ENET_MAC_FCTH_RFA | ENET_MAC_FCTH_RFD )<<8); + reg_value |= (temp >> 8); + ENET_MAC_FCTH = reg_value; + } + + /* configure hashtable_high related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)HASHH_OPTION)){ + ENET_MAC_HLH = enet_initpara.hashtable_high; + } + + /* configure hashtable_low related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)HASHL_OPTION)){ + ENET_MAC_HLL = enet_initpara.hashtable_low; + } + + /* configure framesfilter_mode related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)FILTER_OPTION)){ + reg_temp = enet_initpara.framesfilter_mode; + + reg_value = ENET_MAC_FRMF; + /* configure ENET_MAC_FRMF register */ + reg_value &= ~(ENET_MAC_FRMF_SAFLT | ENET_MAC_FRMF_SAIFLT | ENET_MAC_FRMF_DAIFLT \ + | ENET_MAC_FRMF_HMF | ENET_MAC_FRMF_HPFLT | ENET_MAC_FRMF_MFD \ + | ENET_MAC_FRMF_HUF | ENET_MAC_FRMF_PCFRM); + reg_value |= reg_temp; + ENET_MAC_FRMF = reg_value; + } + + /* configure halfduplex_param related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)HALFDUPLEX_OPTION)){ + reg_temp = enet_initpara.halfduplex_param; + + reg_value = ENET_MAC_CFG; + /* configure ENET_MAC_CFG register */ + reg_value &= ~(ENET_MAC_CFG_CSD | ENET_MAC_CFG_ROD | ENET_MAC_CFG_RTD \ + | ENET_MAC_CFG_BOL | ENET_MAC_CFG_DFC); + reg_value |= reg_temp; + ENET_MAC_CFG = reg_value; + } + + /* configure timer_config related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)TIMER_OPTION)){ + reg_temp = enet_initpara.timer_config; + + reg_value = ENET_MAC_CFG; + /* configure ENET_MAC_CFG register */ + reg_value &= ~(ENET_MAC_CFG_WDD | ENET_MAC_CFG_JBD); + reg_value |= reg_temp; + ENET_MAC_CFG = reg_value; + } + + /* configure interframegap related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)INTERFRAMEGAP_OPTION)){ + reg_temp = enet_initpara.interframegap; + + reg_value = ENET_MAC_CFG; + /* configure ENET_MAC_CFG register */ + reg_value &= ~ENET_MAC_CFG_IGBS; + reg_value |= reg_temp; + ENET_MAC_CFG = reg_value; + } + + enet_state = SUCCESS; + return enet_state; +} + +/*! + \brief reset all core internal registers located in CLK_TX and CLK_RX + \param[in] none + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_software_reset(void) +{ + uint32_t timeout = 0U; + ErrStatus enet_state = ERROR; + uint32_t dma_flag; + + /* reset all core internal registers located in CLK_TX and CLK_RX */ + ENET_DMA_BCTL |= ENET_DMA_BCTL_SWR; + + /* wait for reset operation complete */ + do{ + dma_flag = (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR); + timeout++; + }while((RESET != dma_flag) && (ENET_DELAY_TO != timeout)); + + /* reset operation complete */ + if(RESET == (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR)){ + enet_state = SUCCESS; + } + + return enet_state; +} + +/*! + \brief check receive frame valid and return frame size + \param[in] none + \param[out] none + \retval size of received frame: 0x0 - 0x3FFF +*/ +uint32_t enet_rxframe_size_get(void) +{ + uint32_t size = 0U; + uint32_t status; + + /* get rdes0 information of current RxDMA descriptor */ + status = dma_current_rxdesc->status; + + /* if the desciptor is owned by DMA */ + if((uint32_t)RESET != (status & ENET_RDES0_DAV)){ + return 0U; + } + + /* if has any error, or the frame uses two or more descriptors */ + if((((uint32_t)RESET) != (status & ENET_RDES0_ERRS)) || + (((uint32_t)RESET) == (status & ENET_RDES0_LDES)) || + (((uint32_t)RESET) == (status & ENET_RDES0_FDES))){ + /* drop current receive frame */ + enet_rxframe_drop(); + + return 0U; + } +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE + /* if is an ethernet-type frame, and IP frame payload error occurred */ + if(((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_FRMT) && + ((uint32_t)RESET) != (dma_current_rxdesc->extended_status & ENET_RDES4_IPPLDERR)){ + /* drop current receive frame */ + enet_rxframe_drop(); + + return 0U; + } +#else + /* if is an ethernet-type frame, and IP frame payload error occurred */ + if((((uint32_t)RESET) != (status & ENET_RDES0_FRMT)) && + (((uint32_t)RESET) != (status & ENET_RDES0_PCERR))){ + /* drop current receive frame */ + enet_rxframe_drop(); + + return 0U; + } +#endif + /* if CPU owns current descriptor, no error occured, the frame uses only one descriptor */ + if((((uint32_t)RESET) == (status & ENET_RDES0_DAV)) && + (((uint32_t)RESET) == (status & ENET_RDES0_ERRS)) && + (((uint32_t)RESET) != (status & ENET_RDES0_LDES)) && + (((uint32_t)RESET) != (status & ENET_RDES0_FDES))){ + /* get the size of the received data including CRC */ + size = GET_RDES0_FRML(status); + /* substract the CRC size */ + size = size - 4U; + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (status & ENET_RDES0_FRMT))){ + size = size + 4U; + } + } + + /* return packet size */ + return size; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in chain mode + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[out] none + \retval none +*/ +void enet_descriptors_chain_init(enet_dmadirection_enum direction) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc, *desc_tab; + uint8_t *buf; + + /* if want to initialize DMA Tx descriptors */ + if (ENET_DMA_TX == direction){ + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* select chain mode */ + desc_status = ENET_TDES0_TCHM; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + }else{ + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* select receive chained mode and set buffer1 size */ + desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + } + dma_current_ptp_rxdesc = NULL; + dma_current_ptp_txdesc = NULL; + + /* configure each descriptor */ + for(num=0U; num < count; num++){ + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* if is not the last descriptor */ + if(num < (count - 1U)){ + /* configure the next descriptor address */ + desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U); + }else{ + /* when it is the last descriptor, the next descriptor address + equals to first descriptor address in descriptor table */ + desc->buffer2_next_desc_addr = (uint32_t) desc_tab; + } + } +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in ring mode + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[out] none + \retval none +*/ +void enet_descriptors_ring_init(enet_dmadirection_enum direction) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc; + enet_descriptors_struct *desc_tab; + uint8_t *buf; + + /* configure descriptor skip length */ + ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DPSL; + ENET_DMA_BCTL |= DMA_BCTL_DPSL(0); + + /* if want to initialize DMA Tx descriptors */ + if (ENET_DMA_TX == direction){ + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + }else{ + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* set buffer1 size */ + desc_bufsize = ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + } + dma_current_ptp_rxdesc = NULL; + dma_current_ptp_txdesc = NULL; + + /* configure each descriptor */ + for(num=0U; num < count; num++){ + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* when it is the last descriptor */ + if(num == (count - 1U)){ + if (ENET_DMA_TX == direction){ + /* configure transmit end of ring mode */ + desc->status |= ENET_TDES0_TERM; + }else{ + /* configure receive end of ring mode */ + desc->control_buffer_size |= ENET_RDES1_RERM; + } + } + } +} + +/*! + \brief handle current received frame data to application buffer + \param[in] bufsize: the size of buffer which is the parameter in function + \param[out] buffer: pointer to the received frame data + note -- if the input is NULL, user should copy data in application by himself + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_frame_receive(uint8_t *buffer, uint32_t bufsize) +{ + uint32_t offset = 0U, size = 0U; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)){ + return ERROR; + } + + + /* if buffer pointer is null, indicates that users has copied data in application */ + if(NULL != buffer){ + /* if no error occurs, and the frame uses only one descriptor */ + if((((uint32_t)RESET) == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && + (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && + (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_FDES))){ + /* get the frame length except CRC */ + size = GET_RDES0_FRML(dma_current_rxdesc->status); + size = size - 4U; + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))){ + size = size + 4U; + } + + /* to avoid situation that the frame size exceeds the buffer length */ + if(size > bufsize){ + return ERROR; + } + + /* copy data from Rx buffer to application buffer */ + for(offset = 0U; offsetbuffer1_addr) + offset)); + } + + }else{ + /* return ERROR */ + return ERROR; + } + } + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* check Rx buffer unavailable flag status */ + if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)){ + /* clear RBU flag */ + ENET_DMA_STAT = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN = 0U; + } + + /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ + /* chained mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){ + dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_rxdesc->buffer2_next_desc_addr); + }else{ + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){ + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR); + }else{ + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_rxdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL))); + } + } + + return SUCCESS; +} + +/*! + \brief handle application buffer data to transmit it + \param[in] buffer: pointer to the frame data to be transmitted, + note -- if the input is NULL, user should handle the data in application by himself + \param[in] length: the length of frame data to be transmitted + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_frame_transmit(uint8_t *buffer, uint32_t length) +{ + uint32_t offset = 0U; + uint32_t dma_tbu_flag, dma_tu_flag; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)){ + return ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE){ + return ERROR; + } + + /* if buffer pointer is null, indicates that users has handled data in application */ + if(NULL != buffer){ + /* copy frame data from application buffer to Tx buffer */ + for(offset = 0U; offset < length; offset++){ + (*(__IO uint8_t *) (uint32_t)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); + } + } + + /* set the frame length */ + dma_current_txdesc->control_buffer_size = length; + /* set the segment of frame, frame is transmitted in one descriptor */ + dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; + /* enable the DMA transmission */ + dma_current_txdesc->status |= ENET_TDES0_DAV; + + /* check Tx buffer unavailable flag status */ + dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); + dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); + + if ((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)){ + /* clear TBU and TU flag */ + ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN = 0U; + } + + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/ + /* chained mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){ + dma_current_txdesc = (enet_descriptors_struct*) (dma_current_txdesc->buffer2_next_desc_addr); + }else{ + /* ring mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){ + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR); + }else{ + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_txdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL))); + } + } + + return SUCCESS; +} + +/*! + \brief configure the transmit IP frame checksum offload calculation and insertion + \param[in] desc: the descriptor pointer which users want to configure + \param[in] checksum: IP frame checksum configuration + only one parameter can be selected which is shown as below + \arg ENET_CHECKSUM_DISABLE: checksum insertion disabled + \arg ENET_CHECKSUM_IPV4HEADER: only IP header checksum calculation and insertion are enabled + \arg ENET_CHECKSUM_TCPUDPICMP_SEGMENT: TCP/UDP/ICMP checksum insertion calculated but pseudo-header + \arg ENET_CHECKSUM_TCPUDPICMP_FULL: TCP/UDP/ICMP checksum insertion fully calculated + \param[out] none + \retval none +*/ +void enet_transmit_checksum_config(enet_descriptors_struct *desc, uint32_t checksum) +{ + desc->status &= ~ENET_TDES0_CM; + desc->status |= checksum; +} + +/*! + \brief ENET Tx and Rx function enable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_enable(void) +{ + enet_tx_enable(); + enet_rx_enable(); +} + +/*! + \brief ENET Tx and Rx function disable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_disable(void) +{ + enet_tx_disable(); + enet_rx_disable(); +} + +/*! + \brief configure MAC address + \param[in] mac_addr: select which MAC address will be set, + only one parameter can be selected which is shown as below + \arg ENET_MAC_ADDRESS0: set MAC address 0 filter + \arg ENET_MAC_ADDRESS1: set MAC address 1 filter + \arg ENET_MAC_ADDRESS2: set MAC address 2 filter + \arg ENET_MAC_ADDRESS3: set MAC address 3 filter + \param[in] paddr: the buffer pointer which stores the MAC address + (little-ending store, such as MAC address is aa:bb:cc:dd:ee:22, the buffer is {22, ee, dd, cc, bb, aa}) + \param[out] none + \retval none +*/ +void enet_mac_address_set(enet_macaddress_enum mac_addr, uint8_t paddr[]) +{ + REG32(ENET_ADDRH_BASE + (uint32_t)mac_addr) = ENET_SET_MACADDRH(paddr); + REG32(ENET_ADDRL_BASE + (uint32_t)mac_addr) = ENET_SET_MACADDRL(paddr); +} + +/*! + \brief get MAC address + \param[in] mac_addr: select which MAC address will be get, + only one parameter can be selected which is shown as below + \arg ENET_MAC_ADDRESS0: get MAC address 0 filter + \arg ENET_MAC_ADDRESS1: get MAC address 1 filter + \arg ENET_MAC_ADDRESS2: get MAC address 2 filter + \arg ENET_MAC_ADDRESS3: get MAC address 3 filter + \param[out] paddr: the buffer pointer which is stored the MAC address + (little-ending store, such as mac address is aa:bb:cc:dd:ee:22, the buffer is {22, ee, dd, cc, bb, aa}) + \retval none +*/ +void enet_mac_address_get(enet_macaddress_enum mac_addr, uint8_t paddr[]) +{ + paddr[0] = ENET_GET_MACADDR(mac_addr, 0U); + paddr[1] = ENET_GET_MACADDR(mac_addr, 1U); + paddr[2] = ENET_GET_MACADDR(mac_addr, 2U); + paddr[3] = ENET_GET_MACADDR(mac_addr, 3U); + paddr[4] = ENET_GET_MACADDR(mac_addr, 4U); + paddr[5] = ENET_GET_MACADDR(mac_addr, 5U); +} + +/*! + \brief get the ENET MAC/MSC/PTP/DMA status flag + \param[in] enet_flag: ENET status flag, refer to enet_flag_enum, + only one parameter can be selected which is shown as below + \arg ENET_MAC_FLAG_MPKR: magic packet received flag + \arg ENET_MAC_FLAG_WUFR: wakeup frame received flag + \arg ENET_MAC_FLAG_FLOWCONTROL: flow control status flag + \arg ENET_MAC_FLAG_WUM: WUM status flag + \arg ENET_MAC_FLAG_MSC: MSC status flag + \arg ENET_MAC_FLAG_MSCR: MSC receive status flag + \arg ENET_MAC_FLAG_MSCT: MSC transmit status flag + \arg ENET_MAC_FLAG_TMST: time stamp trigger status flag + \arg ENET_PTP_FLAG_TSSCO: timestamp second counter overflow flag + \arg ENET_PTP_FLAG_TTM: target time match flag + \arg ENET_MSC_FLAG_RFCE: received frames CRC error flag + \arg ENET_MSC_FLAG_RFAE: received frames alignment error flag + \arg ENET_MSC_FLAG_RGUF: received good unicast frames flag + \arg ENET_MSC_FLAG_TGFSC: transmitted good frames single collision flag + \arg ENET_MSC_FLAG_TGFMSC: transmitted good frames more single collision flag + \arg ENET_MSC_FLAG_TGF: transmitted good frames flag + \arg ENET_DMA_FLAG_TS: transmit status flag + \arg ENET_DMA_FLAG_TPS: transmit process stopped status flag + \arg ENET_DMA_FLAG_TBU: transmit buffer unavailable status flag + \arg ENET_DMA_FLAG_TJT: transmit jabber timeout status flag + \arg ENET_DMA_FLAG_RO: receive overflow status flag + \arg ENET_DMA_FLAG_TU: transmit underflow status flag + \arg ENET_DMA_FLAG_RS: receive status flag + \arg ENET_DMA_FLAG_RBU: receive buffer unavailable status flag + \arg ENET_DMA_FLAG_RPS: receive process stopped status flag + \arg ENET_DMA_FLAG_RWT: receive watchdog timeout status flag + \arg ENET_DMA_FLAG_ET: early transmit status flag + \arg ENET_DMA_FLAG_FBE: fatal bus error status flag + \arg ENET_DMA_FLAG_ER: early receive status flag + \arg ENET_DMA_FLAG_AI: abnormal interrupt summary flag + \arg ENET_DMA_FLAG_NI: normal interrupt summary flag + \arg ENET_DMA_FLAG_EB_DMA_ERROR: DMA error flag + \arg ENET_DMA_FLAG_EB_TRANSFER_ERROR: transfer error flag + \arg ENET_DMA_FLAG_EB_ACCESS_ERROR: access error flag + \arg ENET_DMA_FLAG_MSC: MSC status flag + \arg ENET_DMA_FLAG_WUM: WUM status flag + \arg ENET_DMA_FLAG_TST: timestamp trigger status flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus enet_flag_get(enet_flag_enum enet_flag) +{ + if(RESET != (ENET_REG_VAL(enet_flag) & BIT(ENET_BIT_POS(enet_flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the ENET DMA status flag + \param[in] enet_flag: ENET DMA flag clear, refer to enet_flag_clear_enum + only one parameter can be selected which is shown as below + \arg ENET_DMA_FLAG_TS_CLR: transmit status flag clear + \arg ENET_DMA_FLAG_TPS_CLR: transmit process stopped status flag clear + \arg ENET_DMA_FLAG_TBU_CLR: transmit buffer unavailable status flag clear + \arg ENET_DMA_FLAG_TJT_CLR: transmit jabber timeout status flag clear + \arg ENET_DMA_FLAG_RO_CLR: receive overflow status flag clear + \arg ENET_DMA_FLAG_TU_CLR: transmit underflow status flag clear + \arg ENET_DMA_FLAG_RS_CLR: receive status flag clear + \arg ENET_DMA_FLAG_RBU_CLR: receive buffer unavailable status flag clear + \arg ENET_DMA_FLAG_RPS_CLR: receive process stopped status flag clear + \arg ENET_DMA_FLAG_RWT_CLR: receive watchdog timeout status flag clear + \arg ENET_DMA_FLAG_ET_CLR: early transmit status flag clear + \arg ENET_DMA_FLAG_FBE_CLR: fatal bus error status flag clear + \arg ENET_DMA_FLAG_ER_CLR: early receive status flag clear + \arg ENET_DMA_FLAG_AI_CLR: abnormal interrupt summary flag clear + \arg ENET_DMA_FLAG_NI_CLR: normal interrupt summary flag clear + \param[out] none + \retval none +*/ +void enet_flag_clear(enet_flag_clear_enum enet_flag) +{ + /* write 1 to the corresponding bit in ENET_DMA_STAT, to clear it */ + ENET_REG_VAL(enet_flag) = BIT(ENET_BIT_POS(enet_flag)); +} + +/*! + \brief enable ENET MAC/MSC/DMA interrupt + \param[in] enet_int: ENET interrupt, + only one parameter can be selected which is shown as below + \arg ENET_MAC_INT_WUMIM: WUM interrupt mask + \arg ENET_MAC_INT_TMSTIM: timestamp trigger interrupt mask + \arg ENET_MSC_INT_RFCEIM: received frame CRC error interrupt mask + \arg ENET_MSC_INT_RFAEIM: received frames alignment error interrupt mask + \arg ENET_MSC_INT_RGUFIM: received good unicast frames interrupt mask + \arg ENET_MSC_INT_TGFSCIM: transmitted good frames single collision interrupt mask + \arg ENET_MSC_INT_TGFMSCIM: transmitted good frames more single collision interrupt mask + \arg ENET_MSC_INT_TGFIM: transmitted good frames interrupt mask + \arg ENET_DMA_INT_TIE: transmit interrupt enable + \arg ENET_DMA_INT_TPSIE: transmit process stopped interrupt enable + \arg ENET_DMA_INT_TBUIE: transmit buffer unavailable interrupt enable + \arg ENET_DMA_INT_TJTIE: transmit jabber timeout interrupt enable + \arg ENET_DMA_INT_ROIE: receive overflow interrupt enable + \arg ENET_DMA_INT_TUIE: transmit underflow interrupt enable + \arg ENET_DMA_INT_RIE: receive interrupt enable + \arg ENET_DMA_INT_RBUIE: receive buffer unavailable interrupt enable + \arg ENET_DMA_INT_RPSIE: receive process stopped interrupt enable + \arg ENET_DMA_INT_RWTIE: receive watchdog timeout interrupt enable + \arg ENET_DMA_INT_ETIE: early transmit interrupt enable + \arg ENET_DMA_INT_FBEIE: fatal bus error interrupt enable + \arg ENET_DMA_INT_ERIE: early receive interrupt enable + \arg ENET_DMA_INT_AIE: abnormal interrupt summary enable + \arg ENET_DMA_INT_NIE: normal interrupt summary enable + \param[out] none + \retval none +*/ +void enet_interrupt_enable(enet_int_enum enet_int) +{ + if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6)){ + /* ENET_DMA_INTEN register interrupt */ + ENET_REG_VAL(enet_int) |= BIT(ENET_BIT_POS(enet_int)); + }else{ + /* other INTMSK register interrupt */ + ENET_REG_VAL(enet_int) &= ~BIT(ENET_BIT_POS(enet_int)); + } +} + +/*! + \brief disable ENET MAC/MSC/DMA interrupt + \param[in] enet_int: ENET interrupt, + only one parameter can be selected which is shown as below + \arg ENET_MAC_INT_WUMIM: WUM interrupt mask + \arg ENET_MAC_INT_TMSTIM: timestamp trigger interrupt mask + \arg ENET_MSC_INT_RFCEIM: received frame CRC error interrupt mask + \arg ENET_MSC_INT_RFAEIM: received frames alignment error interrupt mask + \arg ENET_MSC_INT_RGUFIM: received good unicast frames interrupt mask + \arg ENET_MSC_INT_TGFSCIM: transmitted good frames single collision interrupt mask + \arg ENET_MSC_INT_TGFMSCIM: transmitted good frames more single collision interrupt mask + \arg ENET_MSC_INT_TGFIM: transmitted good frames interrupt mask + \arg ENET_DMA_INT_TIE: transmit interrupt enable + \arg ENET_DMA_INT_TPSIE: transmit process stopped interrupt enable + \arg ENET_DMA_INT_TBUIE: transmit buffer unavailable interrupt enable + \arg ENET_DMA_INT_TJTIE: transmit jabber timeout interrupt enable + \arg ENET_DMA_INT_ROIE: receive overflow interrupt enable + \arg ENET_DMA_INT_TUIE: transmit underflow interrupt enable + \arg ENET_DMA_INT_RIE: receive interrupt enable + \arg ENET_DMA_INT_RBUIE: receive buffer unavailable interrupt enable + \arg ENET_DMA_INT_RPSIE: receive process stopped interrupt enable + \arg ENET_DMA_INT_RWTIE: receive watchdog timeout interrupt enable + \arg ENET_DMA_INT_ETIE: early transmit interrupt enable + \arg ENET_DMA_INT_FBEIE: fatal bus error interrupt enable + \arg ENET_DMA_INT_ERIE: early receive interrupt enable + \arg ENET_DMA_INT_AIE: abnormal interrupt summary enable + \arg ENET_DMA_INT_NIE: normal interrupt summary enable + \param[out] none + \retval none +*/ +void enet_interrupt_disable(enet_int_enum enet_int) +{ + if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6)){ + /* ENET_DMA_INTEN register interrupt */ + ENET_REG_VAL(enet_int) &= ~BIT(ENET_BIT_POS(enet_int)); + }else{ + /* other INTMSK register interrupt */ + ENET_REG_VAL(enet_int) |= BIT(ENET_BIT_POS(enet_int)); + } +} + +/*! + \brief get ENET MAC/MSC/DMA interrupt flag + \param[in] int_flag: ENET interrupt flag, + only one parameter can be selected which is shown as below + \arg ENET_MAC_INT_FLAG_WUM: WUM status flag + \arg ENET_MAC_INT_FLAG_MSC: MSC status flag + \arg ENET_MAC_INT_FLAG_MSCR: MSC receive status flag + \arg ENET_MAC_INT_FLAG_MSCT: MSC transmit status flag + \arg ENET_MAC_INT_FLAG_TMST: time stamp trigger status flag + \arg ENET_MSC_INT_FLAG_RFCE: received frames CRC error flag + \arg ENET_MSC_INT_FLAG_RFAE: received frames alignment error flag + \arg ENET_MSC_INT_FLAG_RGUF: received good unicast frames flag + \arg ENET_MSC_INT_FLAG_TGFSC: transmitted good frames single collision flag + \arg ENET_MSC_INT_FLAG_TGFMSC: transmitted good frames more single collision flag + \arg ENET_MSC_INT_FLAG_TGF: transmitted good frames flag + \arg ENET_DMA_INT_FLAG_TS: transmit status flag + \arg ENET_DMA_INT_FLAG_TPS: transmit process stopped status flag + \arg ENET_DMA_INT_FLAG_TBU: transmit buffer unavailable status flag + \arg ENET_DMA_INT_FLAG_TJT: transmit jabber timeout status flag + \arg ENET_DMA_INT_FLAG_RO: receive overflow status flag + \arg ENET_DMA_INT_FLAG_TU: transmit underflow status flag + \arg ENET_DMA_INT_FLAG_RS: receive status flag + \arg ENET_DMA_INT_FLAG_RBU: receive buffer unavailable status flag + \arg ENET_DMA_INT_FLAG_RPS: receive process stopped status flag + \arg ENET_DMA_INT_FLAG_RWT: receive watchdog timeout status flag + \arg ENET_DMA_INT_FLAG_ET: early transmit status flag + \arg ENET_DMA_INT_FLAG_FBE: fatal bus error status flag + \arg ENET_DMA_INT_FLAG_ER: early receive status flag + \arg ENET_DMA_INT_FLAG_AI: abnormal interrupt summary flag + \arg ENET_DMA_INT_FLAG_NI: normal interrupt summary flag + \arg ENET_DMA_INT_FLAG_MSC: MSC status flag + \arg ENET_DMA_INT_FLAG_WUM: WUM status flag + \arg ENET_DMA_INT_FLAG_TST: timestamp trigger status flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus enet_interrupt_flag_get(enet_int_flag_enum int_flag) +{ + if(RESET != (ENET_REG_VAL(int_flag) & BIT(ENET_BIT_POS(int_flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear ENET DMA interrupt flag + \param[in] int_flag_clear: clear ENET interrupt flag, + only one parameter can be selected which is shown as below + \arg ENET_DMA_INT_FLAG_TS_CLR: transmit status flag + \arg ENET_DMA_INT_FLAG_TPS_CLR: transmit process stopped status flag + \arg ENET_DMA_INT_FLAG_TBU_CLR: transmit buffer unavailable status flag + \arg ENET_DMA_INT_FLAG_TJT_CLR: transmit jabber timeout status flag + \arg ENET_DMA_INT_FLAG_RO_CLR: receive overflow status flag + \arg ENET_DMA_INT_FLAG_TU_CLR: transmit underflow status flag + \arg ENET_DMA_INT_FLAG_RS_CLR: receive status flag + \arg ENET_DMA_INT_FLAG_RBU_CLR: receive buffer unavailable status flag + \arg ENET_DMA_INT_FLAG_RPS_CLR: receive process stopped status flag + \arg ENET_DMA_INT_FLAG_RWT_CLR: receive watchdog timeout status flag + \arg ENET_DMA_INT_FLAG_ET_CLR: early transmit status flag + \arg ENET_DMA_INT_FLAG_FBE_CLR: fatal bus error status flag + \arg ENET_DMA_INT_FLAG_ER_CLR: early receive status flag + \arg ENET_DMA_INT_FLAG_AI_CLR: abnormal interrupt summary flag + \arg ENET_DMA_INT_FLAG_NI_CLR: normal interrupt summary flag + \param[out] none + \retval none +*/ +void enet_interrupt_flag_clear(enet_int_flag_clear_enum int_flag_clear) +{ + /* write 1 to the corresponding bit in ENET_DMA_STAT, to clear it */ + ENET_REG_VAL(int_flag_clear) = BIT(ENET_BIT_POS(int_flag_clear)); +} + +/*! + \brief ENET Tx function enable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_tx_enable(void) +{ + ENET_MAC_CFG |= ENET_MAC_CFG_TEN; + enet_txfifo_flush(); + ENET_DMA_CTL |= ENET_DMA_CTL_STE; +} + +/*! + \brief ENET Tx function disable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_tx_disable(void) +{ + ENET_DMA_CTL &= ~ENET_DMA_CTL_STE; + enet_txfifo_flush(); + ENET_MAC_CFG &= ~ENET_MAC_CFG_TEN; +} + +/*! + \brief ENET Rx function enable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_rx_enable(void) +{ + ENET_MAC_CFG |= ENET_MAC_CFG_REN; + ENET_DMA_CTL |= ENET_DMA_CTL_SRE; +} + +/*! + \brief ENET Rx function disable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_rx_disable(void) +{ + ENET_DMA_CTL &= ~ENET_DMA_CTL_SRE; + ENET_MAC_CFG &= ~ENET_MAC_CFG_REN; +} + +/*! + \brief put registers value into the application buffer + \param[in] type: register type which will be get, refer to enet_registers_type_enum, + only one parameter can be selected which is shown as below + \arg ALL_MAC_REG: get the registers within the offset scope between ENET_MAC_CFG and ENET_MAC_FCTH + \arg ALL_MSC_REG: get the registers within the offset scope between ENET_MSC_CTL and ENET_MSC_RGUFCNT + \arg ALL_PTP_REG: get the registers within the offset scope between ENET_PTP_TSCTL and ENET_PTP_PPSCTL + \arg ALL_DMA_REG: get the registers within the offset scope between ENET_DMA_BCTL and ENET_DMA_CRBADDR + \param[in] num: the number of registers that the user want to get + \param[out] preg: the application buffer pointer for storing the register value + \retval none +*/ +void enet_registers_get(enet_registers_type_enum type, uint32_t *preg, uint32_t num) +{ + uint32_t offset = 0U, max = 0U, limit = 0U; + + offset = (uint32_t)type; + max = (uint32_t)type + num; + limit = sizeof(enet_reg_tab)/sizeof(uint16_t); + + /* prevent element in this array is out of range */ + if(max > limit){ + max = limit; + } + + for(; offset < max; offset++){ + /* get value of the corresponding register */ + *preg = REG32((ENET) + enet_reg_tab[offset]); + preg++; + } +} + +/*! + \brief get the enet debug status from the debug register + \param[in] mac_debug: enet debug status, + only one parameter can be selected which is shown as below + \arg ENET_MAC_RECEIVER_NOT_IDLE: MAC receiver is not in idle state + \arg ENET_RX_ASYNCHRONOUS_FIFO_STATE: Rx asynchronous FIFO status + \arg ENET_RXFIFO_NOT_WRITING: RxFIFO is not doing write operation + \arg ENET_RXFIFO_READ_STATUS: RxFIFO read operation status + \arg ENET_RXFIFO_STATE: RxFIFO state + \arg ENET_MAC_TRANSMITTER_NOT_IDLE: MAC transmitter is not in idle state + \arg ENET_MAC_TRANSMITTER_STATUS: status of MAC transmitter + \arg ENET_PAUSE_CONDITION_STATUS: pause condition status + \arg ENET_TXFIFO_READ_STATUS: TxFIFO read operation status + \arg ENET_TXFIFO_NOT_WRITING: TxFIFO is not doing write operation + \arg ENET_TXFIFO_NOT_EMPTY: TxFIFO is not empty + \arg ENET_TXFIFO_FULL: TxFIFO is full + \param[out] none + \retval value of the status users want to get +*/ +uint32_t enet_debug_status_get(uint32_t mac_debug) +{ + uint32_t temp_state = 0U; + + switch(mac_debug){ + case ENET_RX_ASYNCHRONOUS_FIFO_STATE: + temp_state = GET_MAC_DBG_RXAFS(ENET_MAC_DBG); + break; + case ENET_RXFIFO_READ_STATUS: + temp_state = GET_MAC_DBG_RXFRS(ENET_MAC_DBG); + break; + case ENET_RXFIFO_STATE: + temp_state = GET_MAC_DBG_RXFS(ENET_MAC_DBG); + break; + case ENET_MAC_TRANSMITTER_STATUS: + temp_state = GET_MAC_DBG_SOMT(ENET_MAC_DBG); + break; + case ENET_TXFIFO_READ_STATUS: + temp_state = GET_MAC_DBG_TXFRS(ENET_MAC_DBG); + break; + default: + if(RESET != (ENET_MAC_DBG & mac_debug)){ + temp_state = 0x1U; + } + break; + } + return temp_state; +} + +/*! + \brief enable the MAC address filter + \param[in] mac_addr: select which MAC address will be enable + \arg ENET_MAC_ADDRESS1: enable MAC address 1 filter + \arg ENET_MAC_ADDRESS2: enable MAC address 2 filter + \arg ENET_MAC_ADDRESS3: enable MAC address 3 filter + \param[out] none + \retval none +*/ +void enet_address_filter_enable(enet_macaddress_enum mac_addr) +{ + REG32(ENET_ADDRH_BASE + mac_addr) |= ENET_MAC_ADDR1H_AFE; +} + +/*! + \brief disable the MAC address filter + \param[in] mac_addr: select which MAC address will be disable, + only one parameter can be selected which is shown as below + \arg ENET_MAC_ADDRESS1: disable MAC address 1 filter + \arg ENET_MAC_ADDRESS2: disable MAC address 2 filter + \arg ENET_MAC_ADDRESS3: disable MAC address 3 filter + \param[out] none + \retval none +*/ +void enet_address_filter_disable(enet_macaddress_enum mac_addr) +{ + REG32(ENET_ADDRH_BASE + mac_addr) &= ~ENET_MAC_ADDR1H_AFE; +} + +/*! + \brief configure the MAC address filter + \param[in] mac_addr: select which MAC address will be configured, + only one parameter can be selected which is shown as below + \arg ENET_MAC_ADDRESS1: configure MAC address 1 filter + \arg ENET_MAC_ADDRESS2: configure MAC address 2 filter + \arg ENET_MAC_ADDRESS3: configure MAC address 3 filter + \param[in] addr_mask: select which MAC address bytes will be mask, + one or more parameters can be selected which are shown as below + \arg ENET_ADDRESS_MASK_BYTE0: mask ENET_MAC_ADDR1L[7:0] bits + \arg ENET_ADDRESS_MASK_BYTE1: mask ENET_MAC_ADDR1L[15:8] bits + \arg ENET_ADDRESS_MASK_BYTE2: mask ENET_MAC_ADDR1L[23:16] bits + \arg ENET_ADDRESS_MASK_BYTE3: mask ENET_MAC_ADDR1L [31:24] bits + \arg ENET_ADDRESS_MASK_BYTE4: mask ENET_MAC_ADDR1H [7:0] bits + \arg ENET_ADDRESS_MASK_BYTE5: mask ENET_MAC_ADDR1H [15:8] bits + \param[in] filter_type: select which MAC address filter type will be selected, + only one parameter can be selected which is shown as below + \arg ENET_ADDRESS_FILTER_SA: The MAC address is used to compared with the SA field of the received frame + \arg ENET_ADDRESS_FILTER_DA: The MAC address is used to compared with the DA field of the received frame + \param[out] none + \retval none +*/ +void enet_address_filter_config(enet_macaddress_enum mac_addr, uint32_t addr_mask, uint32_t filter_type) +{ + uint32_t reg; + + /* get the address filter register value which is to be configured */ + reg = REG32(ENET_ADDRH_BASE + mac_addr); + + /* clear and configure the address filter register */ + reg &= ~(ENET_MAC_ADDR1H_MB | ENET_MAC_ADDR1H_SAF); + reg |= (addr_mask | filter_type); + REG32(ENET_ADDRH_BASE + mac_addr) = reg; +} + +/*! + \brief PHY interface configuration (configure SMI clock and reset PHY chip) + \param[in] none + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_phy_config(void) +{ + uint32_t ahbclk; + uint32_t reg; + uint16_t phy_value; + ErrStatus enet_state = ERROR; + + /* clear the previous MDC clock */ + reg = ENET_MAC_PHY_CTL; + reg &= ~ENET_MAC_PHY_CTL_CLR; + + /* get the HCLK frequency */ + ahbclk = rcu_clock_freq_get(CK_AHB); + + /* configure MDC clock according to HCLK frequency range */ + if(ENET_RANGE(ahbclk, 20000000U, 35000000U)){ + reg |= ENET_MDC_HCLK_DIV16; + }else if(ENET_RANGE(ahbclk, 35000000U, 60000000U)){ + reg |= ENET_MDC_HCLK_DIV26; + }else if(ENET_RANGE(ahbclk, 60000000U, 100000000U)){ + reg |= ENET_MDC_HCLK_DIV42; + }else if(ENET_RANGE(ahbclk, 100000000U, 150000000U)){ + reg |= ENET_MDC_HCLK_DIV62; + }else if((ENET_RANGE(ahbclk, 150000000U, 200000000U))||(200000000U == ahbclk)){ + reg |= ENET_MDC_HCLK_DIV102; + }else{ + return enet_state; + } + ENET_MAC_PHY_CTL = reg; + + /* reset PHY */ + phy_value = PHY_RESET; + if(ERROR == (enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value))){ + return enet_state; + } + /* PHY reset need some time */ + _ENET_DELAY_(ENET_DELAY_TO); + + /* check whether PHY reset is complete */ + if(ERROR == (enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value))){ + return enet_state; + } + + /* PHY reset complete */ + if(RESET == (phy_value & PHY_RESET)){ + enet_state = SUCCESS; + } + + return enet_state; +} + +/*! + \brief write to / read from a PHY register + \param[in] direction: only one parameter can be selected which is shown as below + \arg ENET_PHY_WRITE: write data to phy register + \arg ENET_PHY_READ: read data from phy register + \param[in] phy_address: 0x0 - 0x1F + \param[in] phy_reg: 0x0 - 0x1F + \param[in] pvalue: the value will be written to the PHY register in ENET_PHY_WRITE direction + \param[out] pvalue: the value will be read from the PHY register in ENET_PHY_READ direction + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_phy_write_read(enet_phydirection_enum direction, uint16_t phy_address, uint16_t phy_reg, uint16_t *pvalue) +{ + uint32_t reg, phy_flag; + uint32_t timeout = 0U; + ErrStatus enet_state = ERROR; + + /* configure ENET_MAC_PHY_CTL with write/read operation */ + reg = ENET_MAC_PHY_CTL; + reg &= ~(ENET_MAC_PHY_CTL_PB | ENET_MAC_PHY_CTL_PW | ENET_MAC_PHY_CTL_PR | ENET_MAC_PHY_CTL_PA); + reg |= (direction | MAC_PHY_CTL_PR(phy_reg) | MAC_PHY_CTL_PA(phy_address) | ENET_MAC_PHY_CTL_PB); + + /* if do the write operation, write value to the register */ + if(ENET_PHY_WRITE == direction){ + ENET_MAC_PHY_DATA = *pvalue; + } + + /* do PHY write/read operation, and wait the operation complete */ + ENET_MAC_PHY_CTL = reg; + do{ + phy_flag = (ENET_MAC_PHY_CTL & ENET_MAC_PHY_CTL_PB); + timeout++; + } + while((RESET != phy_flag) && (ENET_DELAY_TO != timeout)); + + /* write/read operation complete */ + if(RESET == (ENET_MAC_PHY_CTL & ENET_MAC_PHY_CTL_PB)){ + enet_state = SUCCESS; + } + + /* if do the read operation, get value from the register */ + if(ENET_PHY_READ == direction){ + *pvalue = (uint16_t)ENET_MAC_PHY_DATA; + } + + return enet_state; +} + +/*! + \brief enable the loopback function of PHY chip + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus enet_phyloopback_enable(void) +{ + uint16_t temp_phy = 0U; + ErrStatus phy_state = ERROR; + + /* get the PHY configuration to update it */ + enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + + /* enable the PHY loopback mode */ + temp_phy |= PHY_LOOPBACK; + + /* update the PHY control register with the new configuration */ + phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + + return phy_state; +} + +/*! + \brief disable the loopback function of PHY chip + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus enet_phyloopback_disable(void) +{ + uint16_t temp_phy = 0U; + ErrStatus phy_state = ERROR; + + /* get the PHY configuration to update it */ + enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + + /* disable the PHY loopback mode */ + temp_phy &= (uint16_t)~PHY_LOOPBACK; + + /* update the PHY control register with the new configuration */ + phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + + return phy_state; +} + +/*! + \brief enable ENET forward feature + \param[in] feature: the feature of ENET forward mode, + one or more parameters can be selected which are shown as below + \arg ENET_AUTO_PADCRC_DROP: the function of the MAC strips the Pad/FCS field on received frames + \arg ENET_TYPEFRAME_CRC_DROP: the function that FCS field(last 4 bytes) of frame will be dropped before forwarding + \arg ENET_FORWARD_ERRFRAMES: the function that all frame received with error except runt error are forwarded to memory + \arg ENET_FORWARD_UNDERSZ_GOODFRAMES: the function that forwarding undersized good frames + \param[out] none + \retval none +*/ +void enet_forward_feature_enable(uint32_t feature) +{ + uint32_t mask; + + mask = (feature & (~(ENET_FORWARD_ERRFRAMES | ENET_FORWARD_UNDERSZ_GOODFRAMES))); + ENET_MAC_CFG |= mask; + + mask = (feature & (~(ENET_AUTO_PADCRC_DROP | ENET_TYPEFRAME_CRC_DROP))); + ENET_DMA_CTL |= (mask >> 2); +} + +/*! + \brief disable ENET forward feature + \param[in] feature: the feature of ENET forward mode, + one or more parameters can be selected which are shown as below + \arg ENET_AUTO_PADCRC_DROP: the automatic zero-quanta generation function + \arg ENET_TYPEFRAME_CRC_DROP: the flow control operation in the MAC + \arg ENET_FORWARD_ERRFRAMES: decoding function for the received pause frame and process it + \arg ENET_FORWARD_UNDERSZ_GOODFRAMES: back pressure operation in the MAC(only use in half-dulex mode) + \param[out] none + \retval none +*/ +void enet_forward_feature_disable(uint32_t feature) +{ + uint32_t mask; + + mask = (feature & (~(ENET_FORWARD_ERRFRAMES | ENET_FORWARD_UNDERSZ_GOODFRAMES))); + ENET_MAC_CFG &= ~mask; + + mask = (feature & (~(ENET_AUTO_PADCRC_DROP | ENET_TYPEFRAME_CRC_DROP))); + ENET_DMA_CTL &= ~(mask >> 2); +} + +/*! + \brief enable ENET fliter feature + \param[in] feature: the feature of ENET fliter mode, + one or more parameters can be selected which are shown as below + \arg ENET_SRC_FILTER: filter source address function + \arg ENET_SRC_FILTER_INVERSE: inverse source address filtering result function + \arg ENET_DEST_FILTER_INVERSE: inverse DA filtering result function + \arg ENET_MULTICAST_FILTER_PASS: pass all multicast frames function + \arg ENET_MULTICAST_FILTER_HASH_MODE: HASH multicast filter function + \arg ENET_UNICAST_FILTER_HASH_MODE: HASH unicast filter function + \arg ENET_FILTER_MODE_EITHER: HASH or perfect filter function + \param[out] none + \retval none +*/ +void enet_fliter_feature_enable(uint32_t feature) +{ + ENET_MAC_FRMF |= feature; +} + +/*! + \brief disable ENET fliter feature + \param[in] feature: the feature of ENET fliter mode, + one or more parameters can be selected which are shown as below + \arg ENET_SRC_FILTER: filter source address function + \arg ENET_SRC_FILTER_INVERSE: inverse source address filtering result function + \arg ENET_DEST_FILTER_INVERSE: inverse DA filtering result function + \arg ENET_MULTICAST_FILTER_PASS: pass all multicast frames function + \arg ENET_MULTICAST_FILTER_HASH_MODE: HASH multicast filter function + \arg ENET_UNICAST_FILTER_HASH_MODE: HASH unicast filter function + \arg ENET_FILTER_MODE_EITHER: HASH or perfect filter function + \param[out] none + \retval none +*/ +void enet_fliter_feature_disable(uint32_t feature) +{ + ENET_MAC_FRMF &= ~feature; +} + +/*! + \brief generate the pause frame, ENET will send pause frame after enable transmit flow control + this function only use in full-dulex mode + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus enet_pauseframe_generate(void) +{ + ErrStatus enet_state =ERROR; + uint32_t temp = 0U; + + /* in full-duplex mode, must make sure this bit is 0 before writing register */ + temp = ENET_MAC_FCTL & ENET_MAC_FCTL_FLCBBKPA; + if(RESET == temp){ + ENET_MAC_FCTL |= ENET_MAC_FCTL_FLCBBKPA; + enet_state = SUCCESS; + } + return enet_state; +} + +/*! + \brief configure the pause frame detect type + \param[in] detect: pause frame detect type, + only one parameter can be selected which is shown as below + \arg ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT: besides the unique multicast address, MAC can also + use the MAC0 address to detecting pause frame + \arg ENET_UNIQUE_PAUSEDETECT: only the unique multicast address for pause frame which is specified + in IEEE802.3 can be detected + \param[out] none + \retval none +*/ +void enet_pauseframe_detect_config(uint32_t detect) +{ + ENET_MAC_FCTL &= ~ENET_MAC_FCTL_UPFDT; + ENET_MAC_FCTL |= detect; +} + +/*! + \brief configure the pause frame parameters + \param[in] pausetime: pause time in transmit pause control frame + \param[in] pause_threshold: the threshold of the pause timer for retransmitting frames automatically, + this value must make sure to be less than configured pause time, only one parameter can be + selected which is shown as below + \arg ENET_PAUSETIME_MINUS4: pause time minus 4 slot times + \arg ENET_PAUSETIME_MINUS28: pause time minus 28 slot times + \arg ENET_PAUSETIME_MINUS144: pause time minus 144 slot times + \arg ENET_PAUSETIME_MINUS256: pause time minus 256 slot times + \param[out] none + \retval none +*/ +void enet_pauseframe_config(uint32_t pausetime, uint32_t pause_threshold) +{ + ENET_MAC_FCTL &= ~(ENET_MAC_FCTL_PTM | ENET_MAC_FCTL_PLTS); + ENET_MAC_FCTL |= (MAC_FCTL_PTM(pausetime) | pause_threshold); +} + +/*! + \brief configure the threshold of the flow control(deactive and active threshold) + \param[in] deactive: the threshold of the deactive flow control, this value + should always be less than active flow control value, only one + parameter can be selected which is shown as below + \arg ENET_DEACTIVE_THRESHOLD_256BYTES: threshold level is 256 bytes + \arg ENET_DEACTIVE_THRESHOLD_512BYTES: threshold level is 512 bytes + \arg ENET_DEACTIVE_THRESHOLD_768BYTES: threshold level is 768 bytes + \arg ENET_DEACTIVE_THRESHOLD_1024BYTES: threshold level is 1024 bytes + \arg ENET_DEACTIVE_THRESHOLD_1280BYTES: threshold level is 1280 bytes + \arg ENET_DEACTIVE_THRESHOLD_1536BYTES: threshold level is 1536 bytes + \arg ENET_DEACTIVE_THRESHOLD_1792BYTES: threshold level is 1792 bytes + \param[in] active: the threshold of the active flow control, only one parameter + can be selected which is shown as below + \arg ENET_ACTIVE_THRESHOLD_256BYTES: threshold level is 256 bytes + \arg ENET_ACTIVE_THRESHOLD_512BYTES: threshold level is 512 bytes + \arg ENET_ACTIVE_THRESHOLD_768BYTES: threshold level is 768 bytes + \arg ENET_ACTIVE_THRESHOLD_1024BYTES: threshold level is 1024 bytes + \arg ENET_ACTIVE_THRESHOLD_1280BYTES: threshold level is 1280 bytes + \arg ENET_ACTIVE_THRESHOLD_1536BYTES: threshold level is 1536 bytes + \arg ENET_ACTIVE_THRESHOLD_1792BYTES: threshold level is 1792 bytes + \param[out] none + \retval none +*/ +void enet_flowcontrol_threshold_config(uint32_t deactive, uint32_t active) +{ + ENET_MAC_FCTH = ((deactive | active) >> 8); +} + +/*! + \brief enable ENET flow control feature + \param[in] feature: the feature of ENET flow control mode + one or more parameters can be selected which are shown as below + \arg ENET_ZERO_QUANTA_PAUSE: the automatic zero-quanta generation function + \arg ENET_TX_FLOWCONTROL: the flow control operation in the MAC + \arg ENET_RX_FLOWCONTROL: decoding function for the received pause frame and process it + \arg ENET_BACK_PRESSURE: back pressure operation in the MAC(only use in half-dulex mode) + \param[out] none + \retval none +*/ +void enet_flowcontrol_feature_enable(uint32_t feature) +{ + if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)){ + ENET_MAC_FCTL &= ~ENET_ZERO_QUANTA_PAUSE; + } + feature &= ~ENET_ZERO_QUANTA_PAUSE; + ENET_MAC_FCTL |= feature; +} + +/*! + \brief disable ENET flow control feature + \param[in] feature: the feature of ENET flow control mode + one or more parameters can be selected which are shown as below + \arg ENET_ZERO_QUANTA_PAUSE: the automatic zero-quanta generation function + \arg ENET_TX_FLOWCONTROL: the flow control operation in the MAC + \arg ENET_RX_FLOWCONTROL: decoding function for the received pause frame and process it + \arg ENET_BACK_PRESSURE: back pressure operation in the MAC(only use in half-dulex mode) + \param[out] none + \retval none +*/ +void enet_flowcontrol_feature_disable(uint32_t feature) +{ + if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)){ + ENET_MAC_FCTL |= ENET_ZERO_QUANTA_PAUSE; + } + feature &= ~ENET_ZERO_QUANTA_PAUSE; + ENET_MAC_FCTL &= ~feature; +} + +/*! + \brief get the dma transmit/receive process state + \param[in] direction: choose the direction of dma process which users want to check, + refer to enet_dmadirection_enum, only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: dma transmit process + \arg ENET_DMA_RX: dma receive process + \param[out] none + \retval state of dma process, the value range shows below: + ENET_RX_STATE_STOPPED, ENET_RX_STATE_FETCHING, ENET_RX_STATE_WAITING, + ENET_RX_STATE_SUSPENDED, ENET_RX_STATE_CLOSING, ENET_RX_STATE_QUEUING, + ENET_TX_STATE_STOPPED, ENET_TX_STATE_FETCHING, ENET_TX_STATE_WAITING, + ENET_TX_STATE_READING, ENET_TX_STATE_SUSPENDED, ENET_TX_STATE_CLOSING +*/ +uint32_t enet_dmaprocess_state_get(enet_dmadirection_enum direction) +{ + uint32_t reval; + reval = (uint32_t)(ENET_DMA_STAT & (uint32_t)direction); + return reval; +} + +/*! + \brief poll the DMA transmission/reception enable by writing any value to the + ENET_DMA_TPEN/ENET_DMA_RPEN register, this will make the DMA to resume transmission/reception + \param[in] direction: choose the direction of DMA process which users want to resume, + refer to enet_dmadirection_enum, only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA transmit process + \arg ENET_DMA_RX: DMA receive process + \param[out] none + \retval none +*/ +void enet_dmaprocess_resume(enet_dmadirection_enum direction) +{ + if(ENET_DMA_TX == direction){ + ENET_DMA_TPEN = 0U; + }else{ + ENET_DMA_RPEN = 0U; + } +} + +/*! + \brief check and recover the Rx process + \param[in] none + \param[out] none + \retval none +*/ +void enet_rxprocess_check_recovery(void) +{ + uint32_t status; + + /* get DAV information of current RxDMA descriptor */ + status = dma_current_rxdesc->status; + status &= ENET_RDES0_DAV; + + /* if current descriptor is owned by DMA, but the descriptor address mismatches with + receive descriptor address pointer updated by RxDMA controller */ + if((ENET_DMA_CRDADDR != ((uint32_t)dma_current_rxdesc)) && + (ENET_RDES0_DAV == status)){ + dma_current_rxdesc = (enet_descriptors_struct*)ENET_DMA_CRDADDR; + } +} + +/*! + \brief flush the ENET transmit FIFO, and wait until the flush operation completes + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus enet_txfifo_flush(void) +{ + uint32_t flush_state; + uint32_t timeout = 0U; + ErrStatus enet_state = ERROR; + + /* set the FTF bit for flushing transmit FIFO */ + ENET_DMA_CTL |= ENET_DMA_CTL_FTF; + /* wait until the flush operation completes */ + do{ + flush_state = ENET_DMA_CTL & ENET_DMA_CTL_FTF; + timeout++; + }while((RESET != flush_state) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ + if(RESET == flush_state){ + enet_state = SUCCESS; + } + + return enet_state; +} + +/*! + \brief get the transmit/receive address of current descriptor, or current buffer, or descriptor table + \param[in] addr_get: choose the address which users want to get, refer to enet_desc_reg_enum, + only one parameter can be selected which is shown as below + \arg ENET_RX_DESC_TABLE: the start address of the receive descriptor table + \arg ENET_RX_CURRENT_DESC: the start descriptor address of the current receive descriptor read by + the RxDMA controller + \arg ENET_RX_CURRENT_BUFFER: the current receive buffer address being read by the RxDMA controller + \arg ENET_TX_DESC_TABLE: the start address of the transmit descriptor table + \arg ENET_TX_CURRENT_DESC: the start descriptor address of the current transmit descriptor read by + the TxDMA controller + \arg ENET_TX_CURRENT_BUFFER: the current transmit buffer address being read by the TxDMA controller + \param[out] none + \retval address value +*/ +uint32_t enet_current_desc_address_get(enet_desc_reg_enum addr_get) +{ + uint32_t reval = 0U; + + reval = REG32((ENET) +(uint32_t)addr_get); + return reval; +} + +/*! + \brief get the Tx or Rx descriptor information + \param[in] desc: the descriptor pointer which users want to get information + \param[in] info_get: the descriptor information type which is selected, + only one parameter can be selected which is shown as below + \arg RXDESC_BUFFER_1_SIZE: receive buffer 1 size + \arg RXDESC_BUFFER_2_SIZE: receive buffer 2 size + \arg RXDESC_FRAME_LENGTH: the byte length of the received frame that was transferred to the buffer + \arg TXDESC_COLLISION_COUNT: the number of collisions occurred before the frame was transmitted + \arg RXDESC_BUFFER_1_ADDR: the buffer1 address of the Rx frame + \arg TXDESC_BUFFER_1_ADDR: the buffer1 address of the Tx frame + \param[out] none + \retval descriptor information, if value is 0xFFFFFFFFU, means the false input parameter +*/ +uint32_t enet_desc_information_get(enet_descriptors_struct *desc, enet_descstate_enum info_get) +{ + uint32_t reval = 0xFFFFFFFFU; + + switch(info_get){ + case RXDESC_BUFFER_1_SIZE: + reval = GET_RDES1_RB1S(desc->control_buffer_size); + break; + case RXDESC_BUFFER_2_SIZE: + reval = GET_RDES1_RB2S(desc->control_buffer_size); + break; + case RXDESC_FRAME_LENGTH: + reval = GET_RDES0_FRML(desc->status); + reval = reval - 4U; + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (desc->status & ENET_RDES0_FRMT))){ + reval = reval + 4U; + } + break; + case RXDESC_BUFFER_1_ADDR: + reval = desc->buffer1_addr; + break; + case TXDESC_BUFFER_1_ADDR: + reval = desc->buffer1_addr; + break; + case TXDESC_COLLISION_COUNT: + reval = GET_TDES0_COCNT(desc->status); + break; + default: + break; + } + return reval; +} + +/*! + \brief get the number of missed frames during receiving + \param[in] none + \param[out] rxfifo_drop: pointer to the number of frames dropped by RxFIFO + \param[out] rxdma_drop: pointer to the number of frames missed by the RxDMA controller + \retval none +*/ +void enet_missed_frame_counter_get(uint32_t *rxfifo_drop, uint32_t *rxdma_drop) +{ + uint32_t temp_counter = 0U; + + temp_counter = ENET_DMA_MFBOCNT; + *rxfifo_drop = GET_DMA_MFBOCNT_MSFA(temp_counter); + *rxdma_drop = GET_DMA_MFBOCNT_MSFC(temp_counter); +} + +/*! + \brief get the bit flag of ENET DMA descriptor + \param[in] desc: the descriptor pointer which users want to get flag + \param[in] desc_flag: the bit flag of ENET DMA descriptor, + only one parameter can be selected which is shown as below + \arg ENET_TDES0_DB: deferred + \arg ENET_TDES0_UFE: underflow error + \arg ENET_TDES0_EXD: excessive deferral + \arg ENET_TDES0_VFRM: VLAN frame + \arg ENET_TDES0_ECO: excessive collision + \arg ENET_TDES0_LCO: late collision + \arg ENET_TDES0_NCA: no carrier + \arg ENET_TDES0_LCA: loss of carrier + \arg ENET_TDES0_IPPE: IP payload error + \arg ENET_TDES0_FRMF: frame flushed + \arg ENET_TDES0_JT: jabber timeout + \arg ENET_TDES0_ES: error summary + \arg ENET_TDES0_IPHE: IP header error + \arg ENET_TDES0_TTMSS: transmit timestamp status + \arg ENET_TDES0_TCHM: the second address chained mode + \arg ENET_TDES0_TERM: transmit end of ring mode + \arg ENET_TDES0_TTSEN: transmit timestamp function enable + \arg ENET_TDES0_DPAD: disable adding pad + \arg ENET_TDES0_DCRC: disable CRC + \arg ENET_TDES0_FSG: first segment + \arg ENET_TDES0_LSG: last segment + \arg ENET_TDES0_INTC: interrupt on completion + \arg ENET_TDES0_DAV: DAV bit + + \arg ENET_RDES0_PCERR: payload checksum error + \arg ENET_RDES0_EXSV: extended status valid + \arg ENET_RDES0_CERR: CRC error + \arg ENET_RDES0_DBERR: dribble bit error + \arg ENET_RDES0_RERR: receive error + \arg ENET_RDES0_RWDT: receive watchdog timeout + \arg ENET_RDES0_FRMT: frame type + \arg ENET_RDES0_LCO: late collision + \arg ENET_RDES0_IPHERR: IP frame header error + \arg ENET_RDES0_TSV: timestamp valid + \arg ENET_RDES0_LDES: last descriptor + \arg ENET_RDES0_FDES: first descriptor + \arg ENET_RDES0_VTAG: VLAN tag + \arg ENET_RDES0_OERR: overflow error + \arg ENET_RDES0_LERR: length error + \arg ENET_RDES0_SAFF: SA filter fail + \arg ENET_RDES0_DERR: descriptor error + \arg ENET_RDES0_ERRS: error summary + \arg ENET_RDES0_DAFF: destination address filter fail + \arg ENET_RDES0_DAV: descriptor available + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus enet_desc_flag_get(enet_descriptors_struct *desc, uint32_t desc_flag) +{ + FlagStatus enet_flag = RESET; + + if ((uint32_t)RESET != (desc->status & desc_flag)){ + enet_flag = SET; + } + + return enet_flag; +} + +/*! + \brief set the bit flag of ENET DMA descriptor + \param[in] desc: the descriptor pointer which users want to set flag + \param[in] desc_flag: the bit flag of ENET DMA descriptor, + only one parameter can be selected which is shown as below + \arg ENET_TDES0_VFRM: VLAN frame + \arg ENET_TDES0_FRMF: frame flushed + \arg ENET_TDES0_TCHM: the second address chained mode + \arg ENET_TDES0_TERM: transmit end of ring mode + \arg ENET_TDES0_TTSEN: transmit timestamp function enable + \arg ENET_TDES0_DPAD: disable adding pad + \arg ENET_TDES0_DCRC: disable CRC + \arg ENET_TDES0_FSG: first segment + \arg ENET_TDES0_LSG: last segment + \arg ENET_TDES0_INTC: interrupt on completion + \arg ENET_TDES0_DAV: DAV bit + \arg ENET_RDES0_DAV: descriptor available + \param[out] none + \retval none +*/ +void enet_desc_flag_set(enet_descriptors_struct *desc, uint32_t desc_flag) +{ + desc->status |= desc_flag; +} + +/*! + \brief clear the bit flag of ENET DMA descriptor + \param[in] desc: the descriptor pointer which users want to clear flag + \param[in] desc_flag: the bit flag of ENET DMA descriptor, + only one parameter can be selected which is shown as below + \arg ENET_TDES0_VFRM: VLAN frame + \arg ENET_TDES0_FRMF: frame flushed + \arg ENET_TDES0_TCHM: the second address chained mode + \arg ENET_TDES0_TERM: transmit end of ring mode + \arg ENET_TDES0_TTSEN: transmit timestamp function enable + \arg ENET_TDES0_DPAD: disable adding pad + \arg ENET_TDES0_DCRC: disable CRC + \arg ENET_TDES0_FSG: first segment + \arg ENET_TDES0_LSG: last segment + \arg ENET_TDES0_INTC: interrupt on completion + \arg ENET_TDES0_DAV: DAV bit + \arg ENET_RDES0_DAV: descriptor available + \param[out] none + \retval none +*/ +void enet_desc_flag_clear(enet_descriptors_struct *desc, uint32_t desc_flag) +{ + desc->status &= ~desc_flag; +} + +/*! + \brief when receiving completed, set RS bit in ENET_DMA_STAT register will immediately set + \param[in] desc: the descriptor pointer which users want to configure + \param[out] none + \retval none +*/ +void enet_rx_desc_immediate_receive_complete_interrupt(enet_descriptors_struct *desc) +{ + desc->control_buffer_size &= ~ENET_RDES1_DINTC; +} + +/*! + \brief when receiving completed, set RS bit in ENET_DMA_STAT register will is set after a configurable delay time + \param[in] desc: the descriptor pointer which users want to configure + \param[in] delay_time: delay a time of 256*delay_time HCLK, this value must be between 0 and 0xFF + \param[out] none + \retval none +*/ +void enet_rx_desc_delay_receive_complete_interrupt(enet_descriptors_struct *desc, uint32_t delay_time) +{ + desc->control_buffer_size |= ENET_RDES1_DINTC; + ENET_DMA_RSWDC = DMA_RSWDC_WDCFRS(delay_time); +} + +/*! + \brief drop current receive frame + \param[in] none + \param[out] none + \retval none +*/ +void enet_rxframe_drop(void) +{ + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* chained mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){ + if(NULL != dma_current_ptp_rxdesc){ + dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->buffer2_next_desc_addr); + /* if it is the last ptp descriptor */ + if(0U != dma_current_ptp_rxdesc->status){ + /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ + dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status); + }else{ + /* ponter to the next ptp descriptor */ + dma_current_ptp_rxdesc++; + } + }else{ + dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_rxdesc->buffer2_next_desc_addr); + } + + }else{ + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){ + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR); + if(NULL != dma_current_ptp_rxdesc){ + dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status); + } + }else{ + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_rxdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); + if(NULL != dma_current_ptp_rxdesc){ + dma_current_ptp_rxdesc++; + } + } + } +} + +/*! + \brief enable DMA feature + \param[in] feature: the feature of DMA mode, + one or more parameters can be selected which are shown as below + \arg ENET_FLUSH_RXFRAME: RxDMA flushes frames function + \arg ENET_SECONDFRAME_OPT: TxDMA controller operate on second frame function + \param[out] none + \retval none +*/ +void enet_dma_feature_enable(uint32_t feature) +{ + ENET_DMA_CTL |= feature; +} + +/*! + \brief disable DMA feature + \param[in] feature: the feature of DMA mode, + one or more parameters can be selected which are shown as below + \arg ENET_FLUSH_RXFRAME: RxDMA flushes frames function + \arg ENET_SECONDFRAME_OPT: TxDMA controller operate on second frame function + \param[out] none + \retval none +*/ +void enet_dma_feature_disable(uint32_t feature) +{ + ENET_DMA_CTL &= ~feature; +} + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE +/*! + \brief get the bit of extended status flag in ENET DMA descriptor + \param[in] desc: the descriptor pointer which users want to get the extended status flag + \param[in] desc_status: the extended status want to get, + only one parameter can be selected which is shown as below + \arg ENET_RDES4_IPPLDT: IP frame payload type + \arg ENET_RDES4_IPHERR: IP frame header error + \arg ENET_RDES4_IPPLDERR: IP frame payload error + \arg ENET_RDES4_IPCKSB: IP frame checksum bypassed + \arg ENET_RDES4_IPF4: IP frame in version 4 + \arg ENET_RDES4_IPF6: IP frame in version 6 + \arg ENET_RDES4_PTPMT: PTP message type + \arg ENET_RDES4_PTPOEF: PTP on ethernet frame + \arg ENET_RDES4_PTPVF: PTP version format + \param[out] none + \retval value of extended status +*/ +uint32_t enet_rx_desc_enhanced_status_get(enet_descriptors_struct *desc, uint32_t desc_status) +{ + uint32_t reval = 0xFFFFFFFFU; + + switch (desc_status){ + case ENET_RDES4_IPPLDT: + reval = GET_RDES4_IPPLDT(desc->extended_status); + break; + case ENET_RDES4_PTPMT: + reval = GET_RDES4_PTPMT(desc->extended_status); + break; + default: + if ((uint32_t)RESET != (desc->extended_status & desc_status)){ + reval = 1U; + }else{ + reval = 0U; + } + } + + return reval; +} + +/*! + \brief configure descriptor to work in enhanced mode + \param[in] none + \param[out] none + \retval none +*/ +void enet_desc_select_enhanced_mode(void) +{ + ENET_DMA_BCTL |= ENET_DMA_BCTL_DFM; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in enhanced chain mode with ptp function + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[out] none + \retval none +*/ +void enet_ptp_enhanced_descriptors_chain_init(enet_dmadirection_enum direction) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc, *desc_tab; + uint8_t *buf; + + /* if want to initialize DMA Tx descriptors */ + if (ENET_DMA_TX == direction){ + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* select chain mode, and enable transmit timestamp function */ + desc_status = ENET_TDES0_TCHM | ENET_TDES0_TTSEN; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + }else{ + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* select receive chained mode and set buffer1 size */ + desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + } + + /* configuration each descriptor */ + for(num = 0U; num < count; num++){ + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* if is not the last descriptor */ + if(num < (count - 1U)){ + /* configure the next descriptor address */ + desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U); + }else{ + /* when it is the last descriptor, the next descriptor address + equals to first descriptor address in descriptor table */ + desc->buffer2_next_desc_addr = (uint32_t)desc_tab; + } + } +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in enhanced ring mode with ptp function + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[out] none + \retval none +*/ +void enet_ptp_enhanced_descriptors_ring_init(enet_dmadirection_enum direction) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc; + enet_descriptors_struct *desc_tab; + uint8_t *buf; + + /* configure descriptor skip length */ + ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DPSL; + ENET_DMA_BCTL |= DMA_BCTL_DPSL(0); + + /* if want to initialize DMA Tx descriptors */ + if (ENET_DMA_TX == direction){ + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* select ring mode, and enable transmit timestamp function */ + desc_status = ENET_TDES0_TTSEN; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + }else{ + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* set buffer1 size */ + desc_bufsize = ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + } + + /* configure each descriptor */ + for(num=0U; num < count; num++){ + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* when it is the last descriptor */ + if(num == (count - 1U)){ + if (ENET_DMA_TX == direction){ + /* configure transmit end of ring mode */ + desc->status |= ENET_TDES0_TERM; + }else{ + /* configure receive end of ring mode */ + desc->control_buffer_size |= ENET_RDES1_RERM; + } + } + } +} + +/*! + \brief receive a packet data with timestamp values to application buffer, when the DMA is in enhanced mode + \param[in] bufsize: the size of buffer which is the parameter in function + \param[out] buffer: pointer to the application buffer + note -- if the input is NULL, user should copy data in application by himself + \param[out] timestamp: pointer to the table which stores the timestamp high and low + note -- if the input is NULL, timestamp is ignored + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_ptpframe_receive_enhanced_mode(uint8_t *buffer, uint32_t bufsize, uint32_t timestamp[]) +{ + uint32_t offset = 0U, size = 0U; + uint32_t timeout = 0U; + uint32_t rdes0_tsv_flag; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)){ + return ERROR; + } + + /* if buffer pointer is null, indicates that users has copied data in application */ + if(NULL != buffer){ + /* if no error occurs, and the frame uses only one descriptor */ + if(((uint32_t)RESET == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_FDES))){ + /* get the frame length except CRC */ + size = GET_RDES0_FRML(dma_current_rxdesc->status) - 4U; + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))){ + size = size + 4U; + } + + /* to avoid situation that the frame size exceeds the buffer length */ + if(size > bufsize){ + return ERROR; + } + + /* copy data from Rx buffer to application buffer */ + for(offset = 0; offset < size; offset++){ + (*(buffer + offset)) = (*(__IO uint8_t *)((dma_current_rxdesc->buffer1_addr) + offset)); + } + }else{ + return ERROR; + } + } + + /* if timestamp pointer is null, indicates that users don't care timestamp in application */ + if(NULL != timestamp){ + /* wait for ENET_RDES0_TSV flag to be set, the timestamp value is taken and + write to the RDES6 and RDES7 */ + do{ + rdes0_tsv_flag = (dma_current_rxdesc->status & ENET_RDES0_TSV); + timeout++; + }while ((RESET == rdes0_tsv_flag) && (timeout < ENET_DELAY_TO)); + + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + return ERROR; + } + + /* clear the ENET_RDES0_TSV flag */ + dma_current_rxdesc->status &= ~ENET_RDES0_TSV; + /* get the timestamp value of the received frame */ + timestamp[0] = dma_current_rxdesc->timestamp_low; + timestamp[1] = dma_current_rxdesc->timestamp_high; + } + + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* check Rx buffer unavailable flag status */ + if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)){ + /* Clear RBU flag */ + ENET_DMA_STAT = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN = 0; + } + + /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ + /* chained mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){ + dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_rxdesc->buffer2_next_desc_addr); + }else{ + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){ + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR); + }else{ + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_rxdesc = (enet_descriptors_struct*) ((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); + } + } + + return SUCCESS; +} + +/*! + \brief send data with timestamp values in application buffer as a transmit packet, when the DMA is in enhanced mode + \param[in] buffer: pointer on the application buffer + note -- if the input is NULL, user should copy data in application by himself + \param[in] length: the length of frame data to be transmitted + \param[out] timestamp: pointer to the table which stores the timestamp high and low + note -- if the input is NULL, timestamp is ignored + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_ptpframe_transmit_enhanced_mode(uint8_t *buffer, uint32_t length, uint32_t timestamp[]) +{ + uint32_t offset = 0; + uint32_t dma_tbu_flag, dma_tu_flag; + uint32_t tdes0_ttmss_flag; + uint32_t timeout = 0; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)){ + return ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE){ + return ERROR; + } + + /* if buffer pointer is null, indicates that users has handled data in application */ + if(NULL != buffer){ + /* copy frame data from application buffer to Tx buffer */ + for(offset = 0; offset < length; offset++){ + (*(__IO uint8_t *)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); + } + } + /* set the frame length */ + dma_current_txdesc->control_buffer_size = length; + /* set the segment of frame, frame is transmitted in one descriptor */ + dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; + /* enable the DMA transmission */ + dma_current_txdesc->status |= ENET_TDES0_DAV; + + /* check Tx buffer unavailable flag status */ + dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); + dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); + + if ((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)){ + /* Clear TBU and TU flag */ + ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN = 0; + } + + /* if timestamp pointer is null, indicates that users don't care timestamp in application */ + if(NULL != timestamp){ + /* wait for ENET_TDES0_TTMSS flag to be set, a timestamp was captured */ + do{ + tdes0_ttmss_flag = (dma_current_txdesc->status & ENET_TDES0_TTMSS); + timeout++; + }while((RESET == tdes0_ttmss_flag) && (timeout < ENET_DELAY_TO)); + + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + return ERROR; + } + + /* clear the ENET_TDES0_TTMSS flag */ + dma_current_txdesc->status &= ~ENET_TDES0_TTMSS; + /* get the timestamp value of the transmit frame */ + timestamp[0] = dma_current_txdesc->timestamp_low; + timestamp[1] = dma_current_txdesc->timestamp_high; + } + + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/ + /* chained mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){ + dma_current_txdesc = (enet_descriptors_struct*) (dma_current_txdesc->buffer2_next_desc_addr); + }else{ + /* ring mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){ + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR); + }else{ + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_txdesc = (enet_descriptors_struct*) ((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); + } + } + + return SUCCESS; +} + +#else + +/*! + \brief configure descriptor to work in normal mode + \param[in] none + \param[out] none + \retval none +*/ +void enet_desc_select_normal_mode(void) +{ + ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DFM; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in normal chain mode with PTP function + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[in] desc_ptptab: pointer to the first descriptor address of PTP Rx descriptor table + \param[out] none + \retval none +*/ +void enet_ptp_normal_descriptors_chain_init(enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc, *desc_tab; + uint8_t *buf; + + /* if want to initialize DMA Tx descriptors */ + if (ENET_DMA_TX == direction){ + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* select chain mode, and enable transmit timestamp function */ + desc_status = ENET_TDES0_TCHM | ENET_TDES0_TTSEN; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + dma_current_ptp_txdesc = desc_ptptab; + }else{ + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* select receive chained mode and set buffer1 size */ + desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + dma_current_ptp_rxdesc = desc_ptptab; + } + + /* configure each descriptor */ + for(num = 0U; num < count; num++){ + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* if is not the last descriptor */ + if(num < (count - 1U)){ + /* configure the next descriptor address */ + desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U); + }else{ + /* when it is the last descriptor, the next descriptor address + equals to first descriptor address in descriptor table */ + desc->buffer2_next_desc_addr = (uint32_t)desc_tab; + } + /* set desc_ptptab equal to desc_tab */ + (&desc_ptptab[num])->buffer1_addr = desc->buffer1_addr; + (&desc_ptptab[num])->buffer2_next_desc_addr = desc->buffer2_next_desc_addr; + } + /* when it is the last ptp descriptor, preserve the first descriptor + address of desc_ptptab in ptp descriptor status */ + (&desc_ptptab[num-1U])->status = (uint32_t)desc_ptptab; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in normal ring mode with PTP function + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[in] desc_ptptab: pointer to the first descriptor address of PTP Rx descriptor table + \param[out] none + \retval none +*/ +void enet_ptp_normal_descriptors_ring_init(enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc, *desc_tab; + uint8_t *buf; + + /* configure descriptor skip length */ + ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DPSL; + ENET_DMA_BCTL |= DMA_BCTL_DPSL(0); + + /* if want to initialize DMA Tx descriptors */ + if (ENET_DMA_TX == direction){ + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* select ring mode, and enable transmit timestamp function */ + desc_status = ENET_TDES0_TTSEN; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + dma_current_ptp_txdesc = desc_ptptab; + }else{ + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* select receive ring mode and set buffer1 size */ + desc_bufsize = (uint32_t)ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + dma_current_ptp_rxdesc = desc_ptptab; + } + + /* configure each descriptor */ + for(num = 0U; num < count; num++){ + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* when it is the last descriptor */ + if(num == (count - 1U)){ + if (ENET_DMA_TX == direction){ + /* configure transmit end of ring mode */ + desc->status |= ENET_TDES0_TERM; + }else{ + /* configure receive end of ring mode */ + desc->control_buffer_size |= ENET_RDES1_RERM; + } + } + /* set desc_ptptab equal to desc_tab */ + (&desc_ptptab[num])->buffer1_addr = desc->buffer1_addr; + (&desc_ptptab[num])->buffer2_next_desc_addr = desc->buffer2_next_desc_addr; + } + /* when it is the last ptp descriptor, preserve the first descriptor + address of desc_ptptab in ptp descriptor status */ + (&desc_ptptab[num-1U])->status = (uint32_t)desc_ptptab; +} + +/*! + \brief receive a packet data with timestamp values to application buffer, when the DMA is in normal mode + \param[in] bufsize: the size of buffer which is the parameter in function + \param[out] timestamp: pointer to the table which stores the timestamp high and low + \param[out] buffer: pointer to the application buffer + note -- if the input is NULL, user should copy data in application by himself + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_ptpframe_receive_normal_mode(uint8_t *buffer, uint32_t bufsize, uint32_t timestamp[]) +{ + uint32_t offset = 0U, size = 0U; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)){ + return ERROR; + } + + /* if buffer pointer is null, indicates that users has copied data in application */ + if(NULL != buffer){ + /* if no error occurs, and the frame uses only one descriptor */ + if(((uint32_t)RESET == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_FDES))){ + + /* get the frame length except CRC */ + size = GET_RDES0_FRML(dma_current_rxdesc->status) - 4U; + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))){ + size = size + 4U; + } + + /* to avoid situation that the frame size exceeds the buffer length */ + if(size > bufsize){ + return ERROR; + } + + /* copy data from Rx buffer to application buffer */ + for(offset = 0U; offset < size; offset++){ + (*(buffer + offset)) = (*(__IO uint8_t *)(uint32_t)((dma_current_ptp_rxdesc->buffer1_addr) + offset)); + } + + }else{ + return ERROR; + } + } + /* copy timestamp value from Rx descriptor to application array */ + timestamp[0] = dma_current_rxdesc->buffer1_addr; + timestamp[1] = dma_current_rxdesc->buffer2_next_desc_addr; + + dma_current_rxdesc->buffer1_addr = dma_current_ptp_rxdesc ->buffer1_addr ; + dma_current_rxdesc->buffer2_next_desc_addr = dma_current_ptp_rxdesc ->buffer2_next_desc_addr; + + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* check Rx buffer unavailable flag status */ + if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)){ + /* clear RBU flag */ + ENET_DMA_STAT = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN = 0U; + } + + + /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ + /* chained mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){ + dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->buffer2_next_desc_addr); + /* if it is the last ptp descriptor */ + if(0U != dma_current_ptp_rxdesc->status){ + /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ + dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status); + }else{ + /* ponter to the next ptp descriptor */ + dma_current_ptp_rxdesc++; + } + }else{ + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){ + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR); + /* RDES2 and RDES3 will not be covered by buffer address, so do not need to preserve a new table, + use the same table with RxDMA descriptor */ + dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status); + }else{ + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_rxdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); + dma_current_ptp_rxdesc ++; + } + } + + return SUCCESS; +} + +/*! + \brief send data with timestamp values in application buffer as a transmit packet, when the DMA is in normal mode + \param[in] buffer: pointer on the application buffer + note -- if the input is NULL, user should copy data in application by himself + \param[in] length: the length of frame data to be transmitted + \param[out] timestamp: pointer to the table which stores the timestamp high and low + note -- if the input is NULL, timestamp is ignored + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_ptpframe_transmit_normal_mode(uint8_t *buffer, uint32_t length, uint32_t timestamp[]) +{ + uint32_t offset = 0U, timeout = 0U; + uint32_t dma_tbu_flag, dma_tu_flag, tdes0_ttmss_flag; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)){ + return ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE){ + return ERROR; + } + + /* if buffer pointer is null, indicates that users has handled data in application */ + if(NULL != buffer){ + /* copy frame data from application buffer to Tx buffer */ + for(offset = 0U; offset < length; offset++){ + (*(__IO uint8_t *) (uint32_t)((dma_current_ptp_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); + } + } + /* set the frame length */ + dma_current_txdesc->control_buffer_size = (length & (uint32_t)0x1FFF); + /* set the segment of frame, frame is transmitted in one descriptor */ + dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; + /* enable the DMA transmission */ + dma_current_txdesc->status |= ENET_TDES0_DAV; + + /* check Tx buffer unavailable flag status */ + dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); + dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); + + if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)){ + /* clear TBU and TU flag */ + ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN = 0U; + } + + /* if timestamp pointer is null, indicates that users don't care timestamp in application */ + if(NULL != timestamp){ + /* wait for ENET_TDES0_TTMSS flag to be set, a timestamp was captured */ + do{ + tdes0_ttmss_flag = (dma_current_txdesc->status & ENET_TDES0_TTMSS); + timeout++; + }while((RESET == tdes0_ttmss_flag) && (timeout < ENET_DELAY_TO)); + + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + return ERROR; + } + + /* clear the ENET_TDES0_TTMSS flag */ + dma_current_txdesc->status &= ~ENET_TDES0_TTMSS; + /* get the timestamp value of the transmit frame */ + timestamp[0] = dma_current_txdesc->buffer1_addr; + timestamp[1] = dma_current_txdesc->buffer2_next_desc_addr; + } + dma_current_txdesc->buffer1_addr = dma_current_ptp_txdesc ->buffer1_addr ; + dma_current_txdesc->buffer2_next_desc_addr = dma_current_ptp_txdesc ->buffer2_next_desc_addr; + + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table */ + /* chained mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){ + dma_current_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->buffer2_next_desc_addr); + /* if it is the last ptp descriptor */ + if(0U != dma_current_ptp_txdesc->status){ + /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ + dma_current_ptp_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->status); + }else{ + /* ponter to the next ptp descriptor */ + dma_current_ptp_txdesc++; + } + }else{ + /* ring mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){ + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR); + /* TDES2 and TDES3 will not be covered by buffer address, so do not need to preserve a new table, + use the same table with TxDMA descriptor */ + dma_current_ptp_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->status); + }else{ + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_txdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); + dma_current_ptp_txdesc ++; + } + } + return SUCCESS; +} + +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/*! + \brief wakeup frame filter register pointer reset + \param[in] none + \param[out] none + \retval none +*/ +void enet_wum_filter_register_pointer_reset(void) +{ + ENET_MAC_WUM |= ENET_MAC_WUM_WUFFRPR; +} + +/*! + \brief set the remote wakeup frame registers + \param[in] pdata: pointer to buffer data which is written to remote wakeup frame registers (8 words total) + \param[out] none + \retval none +*/ +void enet_wum_filter_config(uint32_t pdata[]) +{ + uint32_t num = 0U; + + /* configure ENET_MAC_RWFF register */ + for(num = 0U; num < ETH_WAKEUP_REGISTER_LENGTH; num++){ + ENET_MAC_RWFF = pdata[num]; + } +} + +/*! + \brief enable wakeup management features + \param[in] feature: one or more parameters can be selected which are shown as below + \arg ENET_WUM_POWER_DOWN: power down mode + \arg ENET_WUM_MAGIC_PACKET_FRAME: enable a wakeup event due to magic packet reception + \arg ENET_WUM_WAKE_UP_FRAME: enable a wakeup event due to wakeup frame reception + \arg ENET_WUM_GLOBAL_UNICAST: any received unicast frame passed filter is considered to be a wakeup frame + \param[out] none + \retval none +*/ +void enet_wum_feature_enable(uint32_t feature) +{ + ENET_MAC_WUM |= feature; +} + +/*! + \brief disable wakeup management features + \param[in] feature: one or more parameters can be selected which are shown as below + \arg ENET_WUM_MAGIC_PACKET_FRAME: enable a wakeup event due to magic packet reception + \arg ENET_WUM_WAKE_UP_FRAME: enable a wakeup event due to wakeup frame reception + \arg ENET_WUM_GLOBAL_UNICAST: any received unicast frame passed filter is considered to be a wakeup frame + \param[out] none + \retval none +*/ +void enet_wum_feature_disable(uint32_t feature) +{ + ENET_MAC_WUM &= (~feature); +} + +/*! + \brief reset the MAC statistics counters + \param[in] none + \param[out] none + \retval none +*/ +void enet_msc_counters_reset(void) +{ + /* reset all counters */ + ENET_MSC_CTL |= ENET_MSC_CTL_CTR; +} + +/*! + \brief enable the MAC statistics counter features + \param[in] feature: one or more parameters can be selected which are shown as below + \arg ENET_MSC_COUNTER_STOP_ROLLOVER: counter stop rollover + \arg ENET_MSC_RESET_ON_READ: reset on read + \arg ENET_MSC_COUNTERS_FREEZE: MSC counter freeze + \param[out] none + \retval none +*/ +void enet_msc_feature_enable(uint32_t feature) +{ + ENET_MSC_CTL |= feature; +} + +/*! + \brief disable the MAC statistics counter features + \param[in] feature: one or more parameters can be selected which are shown as below + \arg ENET_MSC_COUNTER_STOP_ROLLOVER: counter stop rollover + \arg ENET_MSC_RESET_ON_READ: reset on read + \arg ENET_MSC_COUNTERS_FREEZE: MSC counter freeze + \param[out] none + \retval none +*/ +void enet_msc_feature_disable(uint32_t feature) +{ + ENET_MSC_CTL &= (~feature); +} + +/*! + \brief configure MAC statistics counters preset mode + \param[in] mode: MSC counters preset mode, refer to enet_msc_preset_enum, + only one parameter can be selected which is shown as below + \arg ENET_MSC_PRESET_NONE: do not preset MSC counter + \arg ENET_MSC_PRESET_HALF: preset all MSC counters to almost-half(0x7FFF FFF0) value + \arg ENET_MSC_PRESET_FULL: preset all MSC counters to almost-full(0xFFFF FFF0) value + \param[out] none + \retval none +*/ +void enet_msc_counters_preset_config(enet_msc_preset_enum mode) +{ + ENET_MSC_CTL &= ENET_MSC_PRESET_MASK; + ENET_MSC_CTL |= (uint32_t)mode; +} + +/*! + \brief get MAC statistics counter + \param[in] counter: MSC counters which is selected, refer to enet_msc_counter_enum, + only one parameter can be selected which is shown as below + \arg ENET_MSC_TX_SCCNT: MSC transmitted good frames after a single collision counter + \arg ENET_MSC_TX_MSCCNT: MSC transmitted good frames after more than a single collision counter + \arg ENET_MSC_TX_TGFCNT: MSC transmitted good frames counter + \arg ENET_MSC_RX_RFCECNT: MSC received frames with CRC error counter + \arg ENET_MSC_RX_RFAECNT: MSC received frames with alignment error counter + \arg ENET_MSC_RX_RGUFCNT: MSC received good unicast frames counter + \param[out] none + \retval the MSC counter value +*/ +uint32_t enet_msc_counters_get(enet_msc_counter_enum counter) +{ + uint32_t reval; + + reval = REG32((ENET + (uint32_t)counter)); + + return reval; +} + +/*! + \brief enable the PTP features + \param[in] feature: the feature of ENET PTP mode + one or more parameters can be selected which are shown as below + \arg ENET_RXTX_TIMESTAMP: timestamp function for transmit and receive frames + \arg ENET_PTP_TIMESTAMP_INT: timestamp interrupt trigger + \arg ENET_ALL_RX_TIMESTAMP: all received frames are taken snapshot + \arg ENET_NONTYPE_FRAME_SNAPSHOT: take snapshot when received non type frame + \arg ENET_IPV6_FRAME_SNAPSHOT: take snapshot for IPv6 frame + \arg ENET_IPV4_FRAME_SNAPSHOT: take snapshot for IPv4 frame + \arg ENET_PTP_FRAME_USE_MACADDRESS_FILTER: use MAC address1-3 to filter the PTP frame + \param[out] none + \retval none +*/ +void enet_ptp_feature_enable(uint32_t feature) +{ + ENET_PTP_TSCTL |= feature; +} + +/*! + \brief disable the PTP features + \param[in] feature: the feature of ENET PTP mode + one or more parameters can be selected which are shown as below + \arg ENET_RXTX_TIMESTAMP: timestamp function for transmit and receive frames + \arg ENET_PTP_TIMESTAMP_INT: timestamp interrupt trigger + \arg ENET_ALL_RX_TIMESTAMP: all received frames are taken snapshot + \arg ENET_NONTYPE_FRAME_SNAPSHOT: take snapshot when received non type frame + \arg ENET_IPV6_FRAME_SNAPSHOT: take snapshot for IPv6 frame + \arg ENET_IPV4_FRAME_SNAPSHOT: take snapshot for IPv4 frame + \arg ENET_PTP_FRAME_USE_MACADDRESS_FILTER: use MAC address1-3 to filter the PTP frame + \param[out] none + \retval none +*/ +void enet_ptp_feature_disable(uint32_t feature) +{ + ENET_PTP_TSCTL &= ~feature; +} + +/*! + \brief configure the PTP timestamp function + \param[in] func: only one parameter can be selected which is shown as below + \arg ENET_CKNT_ORDINARY: type of ordinary clock node type for timestamp + \arg ENET_CKNT_BOUNDARY: type of boundary clock node type for timestamp + \arg ENET_CKNT_END_TO_END: type of end-to-end transparent clock node type for timestamp + \arg ENET_CKNT_PEER_TO_PEER: type of peer-to-peer transparent clock node type for timestamp + \arg ENET_PTP_ADDEND_UPDATE: addend register update + \arg ENET_PTP_SYSTIME_UPDATE: timestamp update + \arg ENET_PTP_SYSTIME_INIT: timestamp initialize + \arg ENET_PTP_FINEMODE: the system timestamp uses the fine method for updating + \arg ENET_PTP_COARSEMODE: the system timestamp uses the coarse method for updating + \arg ENET_SUBSECOND_DIGITAL_ROLLOVER: digital rollover mode + \arg ENET_SUBSECOND_BINARY_ROLLOVER: binary rollover mode + \arg ENET_SNOOPING_PTP_VERSION_2: version 2 + \arg ENET_SNOOPING_PTP_VERSION_1: version 1 + \arg ENET_EVENT_TYPE_MESSAGES_SNAPSHOT: only event type messages are taken snapshot + \arg ENET_ALL_TYPE_MESSAGES_SNAPSHOT: all type messages are taken snapshot except announce, + management and signaling message + \arg ENET_MASTER_NODE_MESSAGE_SNAPSHOT: snapshot is only take for master node message + \arg ENET_SLAVE_NODE_MESSAGE_SNAPSHOT: snapshot is only taken for slave node message + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_ptp_timestamp_function_config(enet_ptp_function_enum func) +{ + uint32_t temp_config = 0U, temp_state = 0U; + uint32_t timeout = 0U; + ErrStatus enet_state = SUCCESS; + + switch(func){ + case ENET_CKNT_ORDINARY: + case ENET_CKNT_BOUNDARY: + case ENET_CKNT_END_TO_END: + case ENET_CKNT_PEER_TO_PEER: + ENET_PTP_TSCTL &= ~ENET_PTP_TSCTL_CKNT; + ENET_PTP_TSCTL |= (uint32_t)func; + break; + case ENET_PTP_ADDEND_UPDATE: + /* this bit must be read as zero before application set it */ + do{ + temp_state = ENET_PTP_TSCTL & ENET_PTP_TSCTL_TMSARU; + timeout++; + }while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + enet_state = ERROR; + }else{ + ENET_PTP_TSCTL |= ENET_PTP_TSCTL_TMSARU; + } + break; + case ENET_PTP_SYSTIME_UPDATE: + /* both the TMSSTU and TMSSTI bits must be read as zero before application set this bit */ + do{ + temp_state = ENET_PTP_TSCTL & (ENET_PTP_TSCTL_TMSSTU | ENET_PTP_TSCTL_TMSSTI); + timeout++; + }while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + enet_state = ERROR; + }else{ + ENET_PTP_TSCTL |= ENET_PTP_TSCTL_TMSSTU; + } + break; + case ENET_PTP_SYSTIME_INIT: + /* this bit must be read as zero before application set it */ + do{ + temp_state = ENET_PTP_TSCTL & ENET_PTP_TSCTL_TMSSTI; + timeout++; + }while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + enet_state = ERROR; + }else{ + ENET_PTP_TSCTL |= ENET_PTP_TSCTL_TMSSTI; + } + break; + default: + temp_config = (uint32_t)func & (~BIT(31)); + if(RESET != ((uint32_t)func & BIT(31))){ + ENET_PTP_TSCTL |= temp_config; + }else{ + ENET_PTP_TSCTL &= ~temp_config; + } + break; + } + + return enet_state; +} + +/*! + \brief configure system time subsecond increment value + \param[in] subsecond: the value will be added to the subsecond value of system time, + this value must be between 0 and 0xFF + \param[out] none + \retval none +*/ +void enet_ptp_subsecond_increment_config(uint32_t subsecond) +{ + ENET_PTP_SSINC = PTP_SSINC_STMSSI(subsecond); +} + +/*! + \brief adjusting the clock frequency only in fine update mode + \param[in] add: the value will be added to the accumulator register to achieve time synchronization + \param[out] none + \retval none +*/ +void enet_ptp_timestamp_addend_config(uint32_t add) +{ + ENET_PTP_TSADDEND = add; +} + +/*! + \brief initialize or add/subtract to second of the system time + \param[in] sign: timestamp update positive or negative sign, + only one parameter can be selected which is shown as below + \arg ENET_PTP_ADD_TO_TIME: timestamp update value is added to system time + \arg ENET_PTP_SUBSTRACT_FROM_TIME: timestamp update value is subtracted from system time + \param[in] second: initializing or adding/subtracting to second of the system time + \param[in] subsecond: the current subsecond of the system time + with 0.46 ns accuracy if required accuracy is 20 ns + \param[out] none + \retval none +*/ +void enet_ptp_timestamp_update_config(uint32_t sign, uint32_t second, uint32_t subsecond) +{ + ENET_PTP_TSUH = second; + ENET_PTP_TSUL = sign | PTP_TSUL_TMSUSS(subsecond); +} + +/*! + \brief configure the expected target time + \param[in] second: the expected target second time + \param[in] nanosecond: the expected target nanosecond time (signed) + \param[out] none + \retval none +*/ +void enet_ptp_expected_time_config(uint32_t second, uint32_t nanosecond) +{ + ENET_PTP_ETH = second; + ENET_PTP_ETL = nanosecond; +} + +/*! + \brief get the current system time + \param[in] none + \param[out] systime_struct: pointer to a enet_ptp_systime_struct structure which contains + parameters of PTP system time + members of the structure and the member values are shown as below: + second: 0x0 - 0xFFFF FFFF + subsecond: 0x0 - 0x7FFF FFFF + sign: ENET_PTP_TIME_POSITIVE, ENET_PTP_TIME_NEGATIVE + \retval none +*/ +void enet_ptp_system_time_get(enet_ptp_systime_struct *systime_struct) +{ + uint32_t temp_sec = 0U, temp_subs = 0U; + + /* get the value of sysytem time registers */ + temp_sec = (uint32_t)ENET_PTP_TSH; + temp_subs = (uint32_t)ENET_PTP_TSL; + + /* get sysytem time and construct the enet_ptp_systime_struct structure */ + systime_struct->second = temp_sec; + systime_struct->subsecond = GET_PTP_TSL_STMSS(temp_subs); + systime_struct->sign = GET_PTP_TSL_STS(temp_subs); +} + +/*! + \brief configure the PPS output frequency + \param[in] freq: PPS output frequency, + only one parameter can be selected which is shown as below + \arg ENET_PPSOFC_1HZ: PPS output 1Hz frequency + \arg ENET_PPSOFC_2HZ: PPS output 2Hz frequency + \arg ENET_PPSOFC_4HZ: PPS output 4Hz frequency + \arg ENET_PPSOFC_8HZ: PPS output 8Hz frequency + \arg ENET_PPSOFC_16HZ: PPS output 16Hz frequency + \arg ENET_PPSOFC_32HZ: PPS output 32Hz frequency + \arg ENET_PPSOFC_64HZ: PPS output 64Hz frequency + \arg ENET_PPSOFC_128HZ: PPS output 128Hz frequency + \arg ENET_PPSOFC_256HZ: PPS output 256Hz frequency + \arg ENET_PPSOFC_512HZ: PPS output 512Hz frequency + \arg ENET_PPSOFC_1024HZ: PPS output 1024Hz frequency + \arg ENET_PPSOFC_2048HZ: PPS output 2048Hz frequency + \arg ENET_PPSOFC_4096HZ: PPS output 4096Hz frequency + \arg ENET_PPSOFC_8192HZ: PPS output 8192Hz frequency + \arg ENET_PPSOFC_16384HZ: PPS output 16384Hz frequency + \arg ENET_PPSOFC_32768HZ: PPS output 32768Hz frequency + \param[out] none + \retval none +*/ +void enet_ptp_pps_output_frequency_config(uint32_t freq) +{ + ENET_PTP_PPSCTL = freq; +} + +/*! + \brief reset the ENET initpara struct, call it before using enet_initpara_config() + \param[in] none + \param[out] none + \retval none +*/ +void enet_initpara_reset(void) +{ + enet_initpara.option_enable = 0U; + enet_initpara.forward_frame = 0U; + enet_initpara.dmabus_mode = 0U; + enet_initpara.dma_maxburst = 0U; + enet_initpara.dma_arbitration = 0U; + enet_initpara.store_forward_mode = 0U; + enet_initpara.dma_function = 0U; + enet_initpara.vlan_config = 0U; + enet_initpara.flow_control = 0U; + enet_initpara.hashtable_high = 0U; + enet_initpara.hashtable_low = 0U; + enet_initpara.framesfilter_mode = 0U; + enet_initpara.halfduplex_param = 0U; + enet_initpara.timer_config = 0U; + enet_initpara.interframegap = 0U; +} + +/*! + \brief initialize ENET peripheral with generally concerned parameters, call it by enet_init() + \param[in] none + \param[out] none + \retval none +*/ +static void enet_default_init(void) +{ + uint32_t reg_value = 0U; + + /* MAC */ + /* configure ENET_MAC_CFG register */ + reg_value = ENET_MAC_CFG; + reg_value &= MAC_CFG_MASK; + reg_value |= ENET_WATCHDOG_ENABLE | ENET_JABBER_ENABLE | ENET_INTERFRAMEGAP_96BIT \ + | ENET_SPEEDMODE_10M |ENET_MODE_HALFDUPLEX | ENET_LOOPBACKMODE_DISABLE \ + | ENET_CARRIERSENSE_ENABLE | ENET_RECEIVEOWN_ENABLE \ + | ENET_RETRYTRANSMISSION_ENABLE | ENET_BACKOFFLIMIT_10 \ + | ENET_DEFERRALCHECK_DISABLE \ + | ENET_TYPEFRAME_CRC_DROP_DISABLE \ + | ENET_AUTO_PADCRC_DROP_DISABLE \ + | ENET_CHECKSUMOFFLOAD_DISABLE; + ENET_MAC_CFG = reg_value; + + /* configure ENET_MAC_FRMF register */ + ENET_MAC_FRMF = ENET_SRC_FILTER_DISABLE |ENET_DEST_FILTER_INVERSE_DISABLE \ + |ENET_MULTICAST_FILTER_PERFECT |ENET_UNICAST_FILTER_PERFECT \ + |ENET_PCFRM_PREVENT_ALL |ENET_BROADCASTFRAMES_ENABLE \ + |ENET_PROMISCUOUS_DISABLE |ENET_RX_FILTER_ENABLE; + + /* configure ENET_MAC_HLH, ENET_MAC_HLL register */ + ENET_MAC_HLH = 0x0U; + + ENET_MAC_HLL = 0x0U; + + /* configure ENET_MAC_FCTL, ENET_MAC_FCTH register */ + reg_value = ENET_MAC_FCTL; + reg_value &= MAC_FCTL_MASK; + reg_value |= MAC_FCTL_PTM(0) |ENET_ZERO_QUANTA_PAUSE_DISABLE \ + |ENET_PAUSETIME_MINUS4 |ENET_UNIQUE_PAUSEDETECT \ + |ENET_RX_FLOWCONTROL_DISABLE |ENET_TX_FLOWCONTROL_DISABLE; + ENET_MAC_FCTL = reg_value; + + ENET_MAC_FCTH = ENET_DEACTIVE_THRESHOLD_512BYTES |ENET_ACTIVE_THRESHOLD_1536BYTES; + + /* configure ENET_MAC_VLT register */ + ENET_MAC_VLT = ENET_VLANTAGCOMPARISON_16BIT |MAC_VLT_VLTI(0); + + /* DMA */ + /* configure ENET_DMA_CTL register */ + reg_value = ENET_DMA_CTL; + reg_value &= DMA_CTL_MASK; + reg_value |= ENET_TCPIP_CKSUMERROR_DROP |ENET_RX_MODE_STOREFORWARD \ + |ENET_FLUSH_RXFRAME_ENABLE |ENET_TX_MODE_STOREFORWARD \ + |ENET_TX_THRESHOLD_64BYTES |ENET_RX_THRESHOLD_64BYTES \ + |ENET_FORWARD_ERRFRAMES_DISABLE |ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE \ + |ENET_SECONDFRAME_OPT_DISABLE; + ENET_DMA_CTL = reg_value; + + /* configure ENET_DMA_BCTL register */ + reg_value = ENET_DMA_BCTL; + reg_value &= DMA_BCTL_MASK; + reg_value = ENET_ADDRESS_ALIGN_ENABLE |ENET_ARBITRATION_RXTX_2_1 \ + |ENET_RXDP_32BEAT |ENET_PGBL_32BEAT |ENET_RXTX_DIFFERENT_PGBL \ + |ENET_FIXED_BURST_ENABLE |ENET_MIXED_BURST_DISABLE \ + |ENET_NORMAL_DESCRIPTOR; + ENET_DMA_BCTL = reg_value; +} + +#ifndef USE_DELAY +/*! + \brief insert a delay time + \param[in] ncount: specifies the delay time length + \param[out] none + \param[out] none +*/ +static void enet_delay(uint32_t ncount) +{ + uint32_t delay_time = 0U; + + for(delay_time = ncount; delay_time != 0U; delay_time--){ + } +} +#endif /* USE_DELAY */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c new file mode 100644 index 0000000000..a3049a7448 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c @@ -0,0 +1,1138 @@ +/*! + \file gd32f4xx_exmc.c + \brief EXMC driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_exmc.h" + +/* EXMC bank0 register reset value */ +#define BANK0_SNCTL_REGION_RESET ((uint32_t)0x000030DAU) +#define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU) +#define BANK0_SNWTCFG_RESET ((uint32_t)0x0FFFFFFFU) + +/* EXMC bank1/2 register reset mask*/ +#define BANK1_2_NPCTL_RESET ((uint32_t)0x00000018U) +#define BANK1_2_NPINTEN_RESET ((uint32_t)0x00000040U) +#define BANK1_2_NPCTCFG_RESET ((uint32_t)0xFCFCFCFCU) +#define BANK1_2_NPATCFG_RESET ((uint32_t)0xFCFCFCFCU) + +/* EXMC bank3 register reset mask*/ +#define BANK3_NPCTL_RESET ((uint32_t)0x00000018U) +#define BANK3_NPINTEN_RESET ((uint32_t)0x00000000U) +#define BANK3_NPCTCFG_RESET ((uint32_t)0xFCFCFCFCU) +#define BANK3_NPATCFG_RESET ((uint32_t)0xFCFCFCFCU) +#define BANK3_PIOTCFG3_RESET ((uint32_t)0xFCFCFCFCU) + +/* EXMC SDRAM device register reset mask */ +#define SDRAM_DEVICE_SDCTL_RESET ((uint32_t)0x000002D0U) +#define SDRAM_DEVICE_SDTCFG_RESET ((uint32_t)0x0FFFFFFFU) +#define SDRAM_DEVICE_SDCMD_RESET ((uint32_t)0x00000000U) +#define SDRAM_DEVICE_SDARI_RESET ((uint32_t)0x00000000U) +#define SDRAM_DEVICE_SDSTAT_RESET ((uint32_t)0x00000000U) +#define SDRAM_DEVICE_SDRSCTL_RESET ((uint32_t)0x00000000U) + +/* EXMC bank0 SQPI-PSRAM register reset mask */ +#define BANK0_SQPI_SINIT_RESET ((uint32_t)0x18010000U) +#define BANK0_SQPI_SRCMD_RESET ((uint32_t)0x00000000U) +#define BANK0_SQPI_SWCMD_RESET ((uint32_t)0x00000000U) +#define BANK0_SQPI_SIDL_RESET ((uint32_t)0x00000000U) +#define BANK0_SQPI_SIDH_RESET ((uint32_t)0x00000000U) + +/* EXMC register bit offset */ +#define SNCTL_NRMUX_OFFSET ((uint32_t)1U) +#define SNCTL_SBRSTEN_OFFSET ((uint32_t)8U) +#define SNCTL_WRAPEN_OFFSET ((uint32_t)10U) +#define SNCTL_WREN_OFFSET ((uint32_t)12U) +#define SNCTL_NRWTEN_OFFSET ((uint32_t)13U) +#define SNCTL_EXMODEN_OFFSET ((uint32_t)14U) +#define SNCTL_ASYNCWAIT_OFFSET ((uint32_t)15U) + +#define SNTCFG_AHLD_OFFSET ((uint32_t)4U) +#define SNTCFG_DSET_OFFSET ((uint32_t)8U) +#define SNTCFG_BUSLAT_OFFSET ((uint32_t)16U) + +#define NPCTL_NDWTEN_OFFSET ((uint32_t)1U) +#define NPCTL_ECCEN_OFFSET ((uint32_t)6U) + +#define NPCTCFG_COMWAIT_OFFSET ((uint32_t)8U) +#define NPCTCFG_COMHLD_OFFSET ((uint32_t)16U) +#define NPCTCFG_COMHIZ_OFFSET ((uint32_t)24U) + +#define NPATCFG_COMWAIT_OFFSET ((uint32_t)8U) +#define NPATCFG_COMHLD_OFFSET ((uint32_t)16U) +#define NPATCFG_COMHIZ_OFFSET ((uint32_t)24U) + +#define PIOTCFG_COMWAIT_OFFSET ((uint32_t)8U) +#define PIOTCFG_COMHLD_OFFSET ((uint32_t)16U) +#define PIOTCFG_COMHIZ_OFFSET ((uint32_t)24U) + +#define SDCTL_WPEN_OFFSET ((uint32_t)9U) +#define SDCTL_BRSTRD_OFFSET ((uint32_t)12U) + +#define SDTCFG_XSRD_OFFSET ((uint32_t)4U) +#define SDTCFG_RASD_OFFSET ((uint32_t)8U) +#define SDTCFG_ARFD_OFFSET ((uint32_t)12U) +#define SDTCFG_WRD_OFFSET ((uint32_t)16U) +#define SDTCFG_RPD_OFFSET ((uint32_t)20U) +#define SDTCFG_RCD_OFFSET ((uint32_t)24U) + +#define SDCMD_NARF_OFFSET ((uint32_t)5U) +#define SDCMD_MRC_OFFSET ((uint32_t)9U) + +#define SDARI_ARINTV_OFFSET ((uint32_t)1U) + +#define SDRSCTL_SSCR_OFFSET ((uint32_t)1U) +#define SDRSCTL_SDSC_OFFSET ((uint32_t)4U) + +#define SDSTAT_STA0_OFFSET ((uint32_t)1U) +#define SDSTAT_STA1_OFFSET ((uint32_t)3U) + +#define SRCMD_RWAITCYCLE_OFFSET ((uint32_t)16U) +#define SWCMD_WWAITCYCLE_OFFSET ((uint32_t)16U) + +#define INTEN_INTEN_OFFSET ((uint32_t)3U) + +/*! + \brief deinitialize EXMC NOR/SRAM region + \param[in] exmc_norsram_region: select the region of bank0 + \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3) + \param[out] none + \retval none +*/ +void exmc_norsram_deinit(uint32_t exmc_norsram_region) +{ + /* reset the registers */ + EXMC_SNCTL(exmc_norsram_region) = BANK0_SNCTL_REGION_RESET; + EXMC_SNTCFG(exmc_norsram_region) = BANK0_SNTCFG_RESET; + EXMC_SNWTCFG(exmc_norsram_region) = BANK0_SNWTCFG_RESET; +} + +/*! + \brief initialize EXMC NOR/SRAM region + \param[in] exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter + norsram_region: EXMC_BANK0_NORSRAM_REGIONx,x=0..3 + write_mode: EXMC_ASYN_WRITE,EXMC_SYN_WRITE + extended_mode: ENABLE or DISABLE + asyn_wait: ENABLE or DISABLE + nwait_signal: ENABLE or DISABLE + memory_write: ENABLE or DISABLE + nwait_config: EXMC_NWAIT_CONFIG_BEFORE,EXMC_NWAIT_CONFIG_DURING + wrap_burst_mode: ENABLE or DISABLE + nwait_polarity: EXMC_NWAIT_POLARITY_LOW,EXMC_NWAIT_POLARITY_HIGH + burst_mode: ENABLE or DISABLE + databus_width: EXMC_NOR_DATABUS_WIDTH_8B,EXMC_NOR_DATABUS_WIDTH_16B + memory_type: EXMC_MEMORY_TYPE_SRAM,EXMC_MEMORY_TYPE_PSRAM,EXMC_MEMORY_TYPE_NOR + address_data_mux: ENABLE or DISABLE + read_write_timing: struct exmc_norsram_timing_parameter_struct set the time + write_timing: struct exmc_norsram_timing_parameter_struct set the time + \param[out] none + \retval none +*/ +void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct) +{ + uint32_t snctl = 0x00000000U,sntcfg = 0x00000000U,snwtcfg = 0x00000000U; + + /* get the register value */ + snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region); + + /* clear relative bits */ + snctl &= ((uint32_t)~(EXMC_SNCTL_EXMODEN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN | + EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG | EXMC_SNCTL_WREN | + EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT | EXMC_SNCTL_SYNCWR | + EXMC_SNCTL_NRBKEN)); + + snctl = (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) | + exmc_norsram_init_struct->memory_type | + exmc_norsram_init_struct->databus_width | + (exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) | + exmc_norsram_init_struct->nwait_polarity | + (exmc_norsram_init_struct->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) | + exmc_norsram_init_struct->nwait_config | + (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) | + (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) | + (exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) | + (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET) | + exmc_norsram_init_struct->write_mode; + + sntcfg = (uint32_t)exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime | + (exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) | + (exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) | + (exmc_norsram_init_struct->read_write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) | + exmc_norsram_init_struct->read_write_timing->syn_clk_division | + exmc_norsram_init_struct->read_write_timing->syn_data_latency | + exmc_norsram_init_struct->read_write_timing->asyn_access_mode; + + /* nor flash access enable */ + if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type) + { + snctl |= (uint32_t)EXMC_SNCTL_NREN; + } + + /* extended mode configure */ + if(ENABLE == exmc_norsram_init_struct->extended_mode) + { + snwtcfg = (uint32_t)exmc_norsram_init_struct->write_timing->asyn_address_setuptime | + (exmc_norsram_init_struct->write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET )| + (exmc_norsram_init_struct->write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) | + (exmc_norsram_init_struct->write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) | + exmc_norsram_init_struct->write_timing->asyn_access_mode; + } + else + { + snwtcfg = BANK0_SNWTCFG_RESET; + } + + /* configure the registers */ + EXMC_SNCTL(exmc_norsram_init_struct->norsram_region) = snctl; + EXMC_SNTCFG(exmc_norsram_init_struct->norsram_region) = sntcfg; + EXMC_SNWTCFG(exmc_norsram_init_struct->norsram_region) = snwtcfg; +} + +/*! + \brief initialize the struct exmc_norsram_parameter_struct + \param[in] none + \param[out] exmc_norsram_init_struct: the initialized struct exmc_norsram_parameter_struct pointer + \retval none +*/ +void exmc_norsram_parameter_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct) +{ + /* configure the structure with default value */ + exmc_norsram_init_struct->norsram_region = EXMC_BANK0_NORSRAM_REGION0; + exmc_norsram_init_struct->address_data_mux = ENABLE; + exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_SRAM; + exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_8B; + exmc_norsram_init_struct->burst_mode = DISABLE; + exmc_norsram_init_struct->nwait_polarity = EXMC_NWAIT_POLARITY_LOW; + exmc_norsram_init_struct->wrap_burst_mode = DISABLE; + exmc_norsram_init_struct->nwait_config = EXMC_NWAIT_CONFIG_BEFORE; + exmc_norsram_init_struct->memory_write = ENABLE; + exmc_norsram_init_struct->nwait_signal = ENABLE; + exmc_norsram_init_struct->extended_mode = DISABLE; + exmc_norsram_init_struct->asyn_wait = DISABLE; + exmc_norsram_init_struct->write_mode = EXMC_ASYN_WRITE; + + /* read/write timing configure */ + exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime = 0xFU; + exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime = 0xFU; + exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime = 0xFFU; + exmc_norsram_init_struct->read_write_timing->bus_latency = 0xFU; + exmc_norsram_init_struct->read_write_timing->syn_clk_division = EXMC_SYN_CLOCK_RATIO_16_CLK; + exmc_norsram_init_struct->read_write_timing->syn_data_latency = EXMC_DATALAT_17_CLK; + exmc_norsram_init_struct->read_write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A; + + /* write timing configure, when extended mode is used */ + exmc_norsram_init_struct->write_timing->asyn_address_setuptime = 0xFU; + exmc_norsram_init_struct->write_timing->asyn_address_holdtime = 0xFU; + exmc_norsram_init_struct->write_timing->asyn_data_setuptime = 0xFFU; + exmc_norsram_init_struct->write_timing->bus_latency = 0xFU; + exmc_norsram_init_struct->write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A; +} + +/*! + \brief consecutive clock configure + \param[in] clock_mode: specifie when the clock is generated + \arg EXMC_CLOCK_SYN_MODE: the clock is generated only during synchronous access + \arg EXMC_CLOCK_UNCONDITIONALLY: the clock is generated unconditionally + \param[out] none + \retval none +*/ +void exmc_norsram_consecutive_clock_config(uint32_t clock_mode) +{ + if (EXMC_CLOCK_UNCONDITIONALLY == clock_mode){ + EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= EXMC_CLOCK_UNCONDITIONALLY; + }else{ + EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_CLOCK_UNCONDITIONALLY; + } +} + +/*! + \brief CRAM page size configure + \param[in] page_size: CRAM page size + \arg EXMC_CRAM_AUTO_SPLIT: the clock is generated only during synchronous access + \arg EXMC_CRAM_PAGE_SIZE_128_BYTES: page size is 128 bytes + \arg EXMC_CRAM_PAGE_SIZE_256_BYTES: page size is 256 bytes + \arg EXMC_CRAM_PAGE_SIZE_512_BYTES: page size is 512 bytes + \arg EXMC_CRAM_PAGE_SIZE_1024_BYTES: page size is 1024 bytes + \param[out] none + \retval none +*/ +void exmc_norsram_page_size_config(uint32_t page_size) +{ + /* reset the bits */ + EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_SNCTL_CPS; + + /* set the CPS bits */ + EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= page_size; +} + +/*! + \brief enable EXMC NOR/PSRAM bank region + \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM bank + \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3) + \param[out] none + \retval none +*/ +void exmc_norsram_enable(uint32_t exmc_norsram_region) +{ + EXMC_SNCTL(exmc_norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN; +} + +/*! + \brief disable EXMC NOR/PSRAM bank region + \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM Bank + \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3) + \param[out] none + \retval none +*/ +void exmc_norsram_disable(uint32_t exmc_norsram_region) +{ + EXMC_SNCTL(exmc_norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN; +} + +/*! + \brief deinitialize EXMC NAND bank + \param[in] exmc_nand_bank: select the bank of NAND + \arg EXMC_BANKx_NAND(x=1..2) + \param[out] none + \retval none +*/ +void exmc_nand_deinit(uint32_t exmc_nand_bank) +{ + /* EXMC_BANK1_NAND or EXMC_BANK2_NAND */ + EXMC_NPCTL(exmc_nand_bank) = BANK1_2_NPCTL_RESET; + EXMC_NPINTEN(exmc_nand_bank) = BANK1_2_NPINTEN_RESET; + EXMC_NPCTCFG(exmc_nand_bank) = BANK1_2_NPCTCFG_RESET; + EXMC_NPATCFG(exmc_nand_bank) = BANK1_2_NPATCFG_RESET; +} + +/*! + \brief initialize EXMC NAND bank + \param[in] exmc_nand_parameter_struct: configure the EXMC NAND parameter + nand_bank: EXMC_BANK1_NAND,EXMC_BANK2_NAND + ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096 + atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16 + ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16 + ecc_logic: ENABLE or DISABLE + databus_width: EXMC_NAND_DATABUS_WIDTH_8B,EXMC_NAND_DATABUS_WIDTH_16B + wait_feature: ENABLE or DISABLE + common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time + attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time + \param[out] none + \retval none +*/ +void exmc_nand_init(exmc_nand_parameter_struct* exmc_nand_init_struct) +{ + uint32_t npctl = 0x00000000U, npctcfg = 0x00000000U, npatcfg = 0x00000000U; + + npctl = (uint32_t)(exmc_nand_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET)| + EXMC_NPCTL_NDTP | + exmc_nand_init_struct->databus_width | + (exmc_nand_init_struct->ecc_logic << NPCTL_ECCEN_OFFSET)| + exmc_nand_init_struct->ecc_size | + exmc_nand_init_struct->ctr_latency | + exmc_nand_init_struct->atr_latency; + + npctcfg = (uint32_t)(exmc_nand_init_struct->common_space_timing->setuptime - 1U) | + ((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) | + (exmc_nand_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET)| + ((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET); + + npatcfg = (uint32_t)(exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) | + ((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_COMWAIT_OFFSET) | + (exmc_nand_init_struct->attribute_space_timing->holdtime << NPATCFG_COMHLD_OFFSET)| + (exmc_nand_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_COMHIZ_OFFSET); + + /* EXMC_BANK1_NAND or EXMC_BANK2_NAND initialize */ + EXMC_NPCTL(exmc_nand_init_struct->nand_bank) = npctl; + EXMC_NPCTCFG(exmc_nand_init_struct->nand_bank) = npctcfg; + EXMC_NPATCFG(exmc_nand_init_struct->nand_bank) = npatcfg; +} + +/*! + \brief initialize the struct exmc_norsram_parameter_struct + \param[in] none + \param[out] the initialized struct exmc_norsram_parameter_struct pointer + \retval none +*/ +void exmc_nand_parameter_init(exmc_nand_parameter_struct* exmc_nand_init_struct) +{ + /* configure the structure with default value */ + exmc_nand_init_struct->nand_bank = EXMC_BANK1_NAND; + exmc_nand_init_struct->wait_feature = DISABLE; + exmc_nand_init_struct->databus_width = EXMC_NAND_DATABUS_WIDTH_8B; + exmc_nand_init_struct->ecc_logic = DISABLE; + exmc_nand_init_struct->ecc_size = EXMC_ECC_SIZE_256BYTES; + exmc_nand_init_struct->ctr_latency = 0x0U; + exmc_nand_init_struct->atr_latency = 0x0U; + exmc_nand_init_struct->common_space_timing->setuptime = 0xfcU; + exmc_nand_init_struct->common_space_timing->waittime = 0xfcU; + exmc_nand_init_struct->common_space_timing->holdtime = 0xfcU; + exmc_nand_init_struct->common_space_timing->databus_hiztime = 0xfcU; + exmc_nand_init_struct->attribute_space_timing->setuptime = 0xfcU; + exmc_nand_init_struct->attribute_space_timing->waittime = 0xfcU; + exmc_nand_init_struct->attribute_space_timing->holdtime = 0xfcU; + exmc_nand_init_struct->attribute_space_timing->databus_hiztime = 0xfcU; +} + +/*! + \brief enable NAND bank + \param[in] exmc_nand_bank: specifie the NAND bank + \arg EXMC_BANKx_NAND(x=1,2) + \param[out] none + \retval none +*/ +void exmc_nand_enable(uint32_t exmc_nand_bank) +{ + EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_NDBKEN; +} + +/*! + \brief disable NAND bank + \param[in] exmc_nand_bank: specifie the NAND bank + \arg EXMC_BANKx_NAND(x=1,2) + \param[out] none + \retval none +*/ +void exmc_nand_disable(uint32_t exmc_nand_bank) +{ + EXMC_NPCTL(exmc_nand_bank) &= ~EXMC_NPCTL_NDBKEN; +} + +/*! + \brief enable or disable the EXMC NAND ECC function + \param[in] exmc_nand_bank: specifie the NAND bank + \arg EXMC_BANKx_NAND(x=1,2) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void exmc_nand_ecc_config(uint32_t exmc_nand_bank, ControlStatus newvalue) +{ + if (ENABLE == newvalue) + { + /* enable the selected NAND bank ECC function */ + EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_ECCEN; + } + else + { + /* disable the selected NAND bank ECC function */ + EXMC_NPCTL(exmc_nand_bank) &= ~EXMC_NPCTL_ECCEN; + } +} + +/*! + \brief get the EXMC ECC value + \param[in] exmc_nand_bank: specifie the NAND bank + \arg EXMC_BANKx_NAND(x=1,2) + \param[out] none + \retval the error correction code(ECC) value +*/ +uint32_t exmc_ecc_get(uint32_t exmc_nand_bank) +{ + return(EXMC_NECC(exmc_nand_bank)); +} + +/*! + \brief deinitialize EXMC PC card bank + \param[in] none + \param[out] none + \retval none +*/ +void exmc_pccard_deinit(void) +{ + /* EXMC_BANK3_PCCARD */ + EXMC_NPCTL3 = BANK3_NPCTL_RESET; + EXMC_NPINTEN3 = BANK3_NPINTEN_RESET; + EXMC_NPCTCFG3 = BANK3_NPCTCFG_RESET; + EXMC_NPATCFG3 = BANK3_NPATCFG_RESET; + EXMC_PIOTCFG3 = BANK3_PIOTCFG3_RESET; +} + +/*! + \brief initialize EXMC PC card bank + \param[in] exmc_pccard_parameter_struct: configure the EXMC NAND parameter + atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16 + ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16 + wait_feature: ENABLE or DISABLE + common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time + attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time + io_space_timing: exmc_nand_pccard_timing_parameter_struct set the time + \param[out] none + \retval none +*/ +void exmc_pccard_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct) +{ + /* configure the EXMC bank3 PC card control register */ + EXMC_NPCTL3 = (uint32_t)(exmc_pccard_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) | + EXMC_NAND_DATABUS_WIDTH_16B | + exmc_pccard_init_struct->ctr_latency | + exmc_pccard_init_struct->atr_latency ; + + /* configure the EXMC bank3 PC card common space timing configuration register */ + EXMC_NPCTCFG3 = (uint32_t)(exmc_pccard_init_struct->common_space_timing->setuptime - 1U) | + ((exmc_pccard_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) | + (exmc_pccard_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET)| + ((exmc_pccard_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET); + + /* configure the EXMC bank3 PC card attribute space timing configuration register */ + EXMC_NPATCFG3 = (uint32_t)(exmc_pccard_init_struct->attribute_space_timing->setuptime - 1U) | + ((exmc_pccard_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_COMWAIT_OFFSET) | + (exmc_pccard_init_struct->attribute_space_timing->holdtime << NPATCFG_COMHLD_OFFSET)| + (exmc_pccard_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_COMHIZ_OFFSET); + + /* configure the EXMC bank3 PC card io space timing configuration register */ + EXMC_PIOTCFG3 = (uint32_t)(exmc_pccard_init_struct->io_space_timing->setuptime - 1U) | + ((exmc_pccard_init_struct->io_space_timing->waittime - 1U) << PIOTCFG_COMWAIT_OFFSET) | + (exmc_pccard_init_struct->io_space_timing->holdtime << PIOTCFG_COMHLD_OFFSET)| + (exmc_pccard_init_struct->io_space_timing->databus_hiztime << PIOTCFG_COMHIZ_OFFSET); +} + +/*! + \brief initialize the struct exmc_pccard_parameter_struct + \param[in] none + \param[out] the initialized struct exmc_pccard_parameter_struct pointer + \retval none +*/ +void exmc_pccard_parameter_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct) +{ + /* configure the structure with default value */ + exmc_pccard_init_struct->wait_feature = DISABLE; + exmc_pccard_init_struct->ctr_latency = 0x0U; + exmc_pccard_init_struct->atr_latency = 0x0U; + exmc_pccard_init_struct->common_space_timing->setuptime = 0xFCU; + exmc_pccard_init_struct->common_space_timing->waittime = 0xFCU; + exmc_pccard_init_struct->common_space_timing->holdtime = 0xFCU; + exmc_pccard_init_struct->common_space_timing->databus_hiztime = 0xFCU; + exmc_pccard_init_struct->attribute_space_timing->setuptime = 0xFCU; + exmc_pccard_init_struct->attribute_space_timing->waittime = 0xFCU; + exmc_pccard_init_struct->attribute_space_timing->holdtime = 0xFCU; + exmc_pccard_init_struct->attribute_space_timing->databus_hiztime = 0xFCU; + exmc_pccard_init_struct->io_space_timing->setuptime = 0xFCU; + exmc_pccard_init_struct->io_space_timing->waittime = 0xFCU; + exmc_pccard_init_struct->io_space_timing->holdtime = 0xFCU; + exmc_pccard_init_struct->io_space_timing->databus_hiztime = 0xFCU; +} + +/*! + \brief enable PC Card Bank + \param[in] none + \param[out] none + \retval none +*/ +void exmc_pccard_enable(void) +{ + EXMC_NPCTL3 |= EXMC_NPCTL_NDBKEN; +} + +/*! + \brief disable PC Card Bank + \param[in] none + \param[out] none + \retval none +*/ +void exmc_pccard_disable(void) +{ + EXMC_NPCTL3 &= ~EXMC_NPCTL_NDBKEN; +} + +/*! + \brief deinitialize EXMC SDRAM device + \param[in] none + \param[out] none + \retval none +*/ +void exmc_sdram_deinit(uint32_t exmc_sdram_device) +{ + /* reset SDRAM registers */ + EXMC_SDCTL(exmc_sdram_device) = SDRAM_DEVICE_SDCTL_RESET; + EXMC_SDTCFG(exmc_sdram_device) = SDRAM_DEVICE_SDTCFG_RESET; + EXMC_SDCMD = SDRAM_DEVICE_SDCMD_RESET; + EXMC_SDARI = SDRAM_DEVICE_SDARI_RESET; + EXMC_SDRSCTL = SDRAM_DEVICE_SDRSCTL_RESET; +} + +/*! + \brief initialize EXMC SDRAM device + \param[in] exmc_sdram_parameter_struct: configure the EXMC SDRAM parameter + sdram_device: EXMC_SDRAM_DEVICE0,EXMC_SDRAM_DEVICE1 + pipeline_read_delay: EXMC_PIPELINE_DELAY_x_HCLK,x=0..2 + brust_read_switch: ENABLE or DISABLE + sdclock_config: EXMC_SDCLK_DISABLE,EXMC_SDCLK_PERIODS_2_HCLK,EXMC_SDCLK_PERIODS_3_HCLK + write_protection: ENABLE or DISABLE + cas_latency: EXMC_CAS_LATENCY_x_SDCLK,x=1..3 + internal_bank_number: EXMC_SDRAM_2_INTER_BANK,EXMC_SDRAM_4_INTER_BANK + data_width: EXMC_SDRAM_DATABUS_WIDTH_8B,EXMC_SDRAM_DATABUS_WIDTH_16B,EXMC_SDRAM_DATABUS_WIDTH_32B + row_address_width: EXMC_SDRAM_ROW_ADDRESS_x,x=11..13 + column_address_width: EXMC_SDRAM_COW_ADDRESS_x,x=8..11 + timing: exmc_sdram_timing_parameter_struct set the time + \param[out] none + \retval none +*/ +void exmc_sdram_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct) +{ + uint32_t sdctl0, sdctl1, sdtcfg0, sdtcfg1; + + /* configuration EXMC_SDCTL0 or EXMC_SDCTL1 */ + if(EXMC_SDRAM_DEVICE0 == exmc_sdram_init_struct->sdram_device){ + /* configuration EXMC_SDCTL0 */ + EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = (uint32_t)exmc_sdram_init_struct->column_address_width | + exmc_sdram_init_struct->row_address_width | + exmc_sdram_init_struct->data_width | + exmc_sdram_init_struct->internal_bank_number | + exmc_sdram_init_struct->cas_latency | + (exmc_sdram_init_struct->write_protection << SDCTL_WPEN_OFFSET)| + exmc_sdram_init_struct->sdclock_config | + (exmc_sdram_init_struct->brust_read_switch << SDCTL_BRSTRD_OFFSET)| + exmc_sdram_init_struct->pipeline_read_delay; + + /* configuration EXMC_SDTCFG0 */ + EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay)-1U) | + (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay)-1U) << SDTCFG_XSRD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_address_select_delay)-1U) << SDTCFG_RASD_OFFSET) | + (((exmc_sdram_init_struct->timing->auto_refresh_delay)-1U) << SDTCFG_ARFD_OFFSET) | + (((exmc_sdram_init_struct->timing->write_recovery_delay)-1U) << SDTCFG_WRD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_precharge_delay)-1U) << SDTCFG_RPD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_to_column_delay)-1U) << SDTCFG_RCD_OFFSET); + }else{ + /* configuration EXMC_SDCTL0 and EXMC_SDCTL1 */ + /* some bits in the EXMC_SDCTL1 register are reserved */ + sdctl0 = EXMC_SDCTL(EXMC_SDRAM_DEVICE0) & (~( EXMC_SDCTL_PIPED | EXMC_SDCTL_BRSTRD | EXMC_SDCTL_SDCLK )); + + sdctl0 |= (uint32_t)exmc_sdram_init_struct->sdclock_config | + exmc_sdram_init_struct->brust_read_switch | + exmc_sdram_init_struct->pipeline_read_delay; + + sdctl1 = (uint32_t)exmc_sdram_init_struct->column_address_width | + exmc_sdram_init_struct->row_address_width | + exmc_sdram_init_struct->data_width | + exmc_sdram_init_struct->internal_bank_number | + exmc_sdram_init_struct->cas_latency | + exmc_sdram_init_struct->write_protection ; + + EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = sdctl0; + EXMC_SDCTL(EXMC_SDRAM_DEVICE1) = sdctl1; + + /* configuration EXMC_SDTCFG0 and EXMC_SDTCFG1 */ + /* some bits in the EXMC_SDTCFG1 register are reserved */ + sdtcfg0 = EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) & (~(EXMC_SDTCFG_RPD | EXMC_SDTCFG_WRD | EXMC_SDTCFG_ARFD)); + + sdtcfg0 |= (uint32_t)(((exmc_sdram_init_struct->timing->auto_refresh_delay)-1U) << SDTCFG_ARFD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_precharge_delay)-1U) << SDTCFG_RPD_OFFSET) | + (((exmc_sdram_init_struct->timing->write_recovery_delay)-1U) << SDTCFG_WRD_OFFSET); + + sdtcfg1 = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay)-1U) | + (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay)-1U) << SDTCFG_XSRD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_address_select_delay)-1U) << SDTCFG_RASD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_to_column_delay)-1U) << SDTCFG_RCD_OFFSET); + + EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = sdtcfg0; + EXMC_SDTCFG(EXMC_SDRAM_DEVICE1) = sdtcfg1; + } +} + +/*! + \brief initialize the struct exmc_pccard_parameter_struct + \param[in] none + \param[out] the initialized struct exmc_pccard_parameter_struct pointer + \retval none +*/ +void exmc_sdram_parameter_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct) +{ + /* configure the structure with default value */ + exmc_sdram_init_struct->sdram_device = EXMC_SDRAM_DEVICE0; + exmc_sdram_init_struct->column_address_width = EXMC_SDRAM_COW_ADDRESS_8; + exmc_sdram_init_struct->row_address_width = EXMC_SDRAM_ROW_ADDRESS_11; + exmc_sdram_init_struct->data_width = EXMC_SDRAM_DATABUS_WIDTH_16B; + exmc_sdram_init_struct->internal_bank_number = EXMC_SDRAM_4_INTER_BANK; + exmc_sdram_init_struct->cas_latency = EXMC_CAS_LATENCY_1_SDCLK; + exmc_sdram_init_struct->write_protection = ENABLE; + exmc_sdram_init_struct->sdclock_config = EXMC_SDCLK_DISABLE; + exmc_sdram_init_struct->brust_read_switch = DISABLE; + exmc_sdram_init_struct->pipeline_read_delay = EXMC_PIPELINE_DELAY_0_HCLK; + + exmc_sdram_init_struct->timing->load_mode_register_delay = 16U; + exmc_sdram_init_struct->timing->exit_selfrefresh_delay = 16U; + exmc_sdram_init_struct->timing->row_address_select_delay = 16U; + exmc_sdram_init_struct->timing->auto_refresh_delay = 16U; + exmc_sdram_init_struct->timing->write_recovery_delay = 16U; + exmc_sdram_init_struct->timing->row_precharge_delay = 16U; + exmc_sdram_init_struct->timing->row_to_column_delay = 16U; +} + +/*! + \brief configure the SDRAM memory command + \param[in] the struct exmc_sdram_command_parameter_struct pointer + \param[out] none + \retval none +*/ +void exmc_sdram_command_config(exmc_sdram_command_parameter_struct* exmc_sdram_command_init_struct) +{ + /* configure command register */ + EXMC_SDCMD = (uint32_t)((exmc_sdram_command_init_struct->command) | + (exmc_sdram_command_init_struct->bank_select) | + ((exmc_sdram_command_init_struct->auto_refresh_number)) | + ((exmc_sdram_command_init_struct->mode_register_content)<> SDSTAT_STA0_OFFSET); + } + else + { + sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA1) >> SDSTAT_STA1_OFFSET); + } + + return sdstat; +} + +/*! + \brief configure the delayed sample clock of read data + \param[in] delay_cell: SDRAM the delayed sample clock of read data + \arg EXMC_SDRAM_x_DELAY_CELL(x=0..15) + \param[in] extra_hclk: sample cycle of read data + \arg EXMC_SDRAM_READSAMPLE_x_EXTRAHCLK(x=0,1) + \param[out] none + \retval none +*/ +void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_hclk) +{ + uint32_t sdrsctl = 0U; + + sdrsctl = EXMC_SDRSCTL & (~(EXMC_SDRSCTL_SDSC | EXMC_SDRSCTL_SSCR)); + sdrsctl |= (uint32_t)(delay_cell & EXMC_SDRSCTL_SDSC) | + ((extra_hclk << SDRSCTL_SSCR_OFFSET) & EXMC_SDRSCTL_SSCR); + EXMC_SDRSCTL = sdrsctl; +} + +/*! + \brief enable or disable read sample + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void exmc_sdram_readsample_enable(ControlStatus newvalue) +{ + if (ENABLE == newvalue){ + EXMC_SDRSCTL |= EXMC_SDRSCTL_RSEN; + }else{ + EXMC_SDRSCTL &= (uint32_t)(~EXMC_SDRSCTL_RSEN); + } +} + +/*! + \brief deinitialize exmc SQPIPSRAM + \param[in] none + \param[out] none + \retval none +*/ +void exmc_sqpipsram_deinit(void) +{ + /* reset the registers */ + EXMC_SINIT = BANK0_SQPI_SINIT_RESET; + EXMC_SRCMD = BANK0_SQPI_SRCMD_RESET; + EXMC_SWCMD = BANK0_SQPI_SWCMD_RESET; + EXMC_SIDL = BANK0_SQPI_SIDL_RESET; + EXMC_SIDH = BANK0_SQPI_SIDH_RESET; +} + +/*! + \brief initialize EXMC SQPIPSRAM + \param[in] exmc_sqpipsram_parameter_struct: configure the EXMC SQPIPSRAM parameter + sample_polarity: EXMC_SDRAM_SAMPLE_RISING_EDGE,EXMC_SDRAM_SAMPLE_FALLING_EDGE + id_length: EXMC_SQPIPSRAM_ID_LENGTH_xB,x=8,16,32,64 + address_bits: EXMC_SQPIPSRAM_ADDR_LENGTH_xB,x=1..26 + command_bits: EXMC_SQPIPSRAM_COMMAND_LENGTH_xB,x=4,8,16 + \param[out] none + \retval none +*/ +void exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct) +{ + /* initialize SQPI controller */ + EXMC_SINIT = (uint32_t)exmc_sqpipsram_init_struct->sample_polarity | + exmc_sqpipsram_init_struct->id_length | + exmc_sqpipsram_init_struct->address_bits | + exmc_sqpipsram_init_struct->command_bits; +} + +/*! + \brief initialize the struct exmc_sqpipsram_parameter_struct + \param[in] the struct exmc_sqpipsram_parameter_struct pointer + \param[out] none + \retval none +*/ +void exmc_sqpipsram_parameter_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct) +{ + /* configure the structure with default value */ + exmc_sqpipsram_init_struct->sample_polarity = EXMC_SDRAM_SAMPLE_RISING_EDGE; + exmc_sqpipsram_init_struct->id_length = EXMC_SQPIPSRAM_ID_LENGTH_64B; + exmc_sqpipsram_init_struct->address_bits = EXMC_SQPIPSRAM_ADDR_LENGTH_24B; + exmc_sqpipsram_init_struct->command_bits = EXMC_SQPIPSRAM_COMMAND_LENGTH_8B; +} + +/*! + \brief set the read command + \param[in] read_command_mode: configure SPI PSRAM read command mode + \arg EXMC_SQPIPSRAM_READ_MODE_DISABLE: not SPI mode + \arg EXMC_SQPIPSRAM_READ_MODE_SPI: SPI mode + \arg EXMC_SQPIPSRAM_READ_MODE_SQPI: SQPI mode + \arg EXMC_SQPIPSRAM_READ_MODE_QPI: QPI mode + \param[in] read_wait_cycle: wait cycle number after address phase,0..15 + \param[in] read_command_code: read command for AHB read transfer + \param[out] none + \retval none +*/ +void exmc_sqpipsram_read_command_set(uint32_t read_command_mode,uint32_t read_wait_cycle,uint32_t read_command_code) +{ + uint32_t srcmd; + + srcmd = (uint32_t) read_command_mode | + ((read_wait_cycle << SRCMD_RWAITCYCLE_OFFSET) & EXMC_SRCMD_RWAITCYCLE) | + ((read_command_code & EXMC_SRCMD_RCMD)); + EXMC_SRCMD = srcmd; +} + +/*! + \brief set the write command + \param[in] write_command_mode: configure SPI PSRAM write command mode + \arg EXMC_SQPIPSRAM_WRITE_MODE_DISABLE: not SPI mode + \arg EXMC_SQPIPSRAM_WRITE_MODE_SPI: SPI mode + \arg EXMC_SQPIPSRAM_WRITE_MODE_SQPI: SQPI mode + \arg EXMC_SQPIPSRAM_WRITE_MODE_QPI: QPI mode + \param[in] write_wait_cycle: wait cycle number after address phase,0..15 + \param[in] write_command_code: read command for AHB read transfer + \param[out] none + \retval none +*/ +void exmc_sqpipsram_write_command_set(uint32_t write_command_mode,uint32_t write_wait_cycle,uint32_t write_command_code) +{ + uint32_t swcmd; + + swcmd = (uint32_t) write_command_mode | + ((write_wait_cycle << SWCMD_WWAITCYCLE_OFFSET) & EXMC_SWCMD_WWAITCYCLE) | + ((write_command_code & EXMC_SWCMD_WCMD)); + EXMC_SWCMD = swcmd; +} + +/*! + \brief send SPI read ID command + \param[in] none + \param[out] none + \retval none +*/ +void exmc_sqpipsram_read_id_command_send(void) +{ + EXMC_SRCMD |= EXMC_SRCMD_RDID; +} + +/*! + \brief send SPI special command which does not have address and data phase + \param[in] none + \param[out] none + \retval none +*/ +void exmc_sqpipsram_write_cmd_send(void) +{ + EXMC_SWCMD |= EXMC_SWCMD_SC; +} + +/*! + \brief get the EXMC SPI ID low data + \param[in] none + \param[out] none + \retval the ID low data +*/ +uint32_t exmc_sqpipsram_low_id_get(void) +{ + return (EXMC_SIDL); +} + +/*! + \brief get the EXMC SPI ID high data + \param[in] none + \param[out] none + \retval the ID high data +*/ +uint32_t exmc_sqpipsram_high_id_get(void) +{ + return (EXMC_SIDH); +} + +/*! + \brief get the bit value of EXMC send write command bit or read ID command + \param[in] send_command_flag: the send command flag + \arg EXMC_SEND_COMMAND_FLAG_RDID: EXMC_SRCMD_RDID flag bit + \arg EXMC_SEND_COMMAND_FLAG_SC: EXMC_SWCMD_SC flag bit + \param[out] none + \retval the new value of send command flag +*/ +FlagStatus exmc_sqpipsram_send_command_state_get(uint32_t send_command_flag) +{ + uint32_t flag = 0x00000000U; + + if(EXMC_SEND_COMMAND_FLAG_RDID == send_command_flag){ + flag = EXMC_SRCMD; + }else if(EXMC_SEND_COMMAND_FLAG_SC == send_command_flag){ + flag = EXMC_SWCMD; + }else{ + } + + if (flag & send_command_flag){ + /* flag is set */ + return SET; + }else{ + /* flag is reset */ + return RESET; + } +} + +/*! + \brief check EXMC flag is set or not + \param[in] exmc_bank: specifies the NAND bank , PC card bank or SDRAM device + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC Card bank + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] flag: specify get which flag + \arg EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status + \arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status + \arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status + \arg EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag + \arg EXMC_SDRAM_FLAG_REFRESH: refresh error interrupt flag + \arg EXMC_SDRAM_FLAG_NREADY: not ready status + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus exmc_flag_get(uint32_t exmc_bank,uint32_t flag) +{ + uint32_t status = 0x00000000U; + + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + /* NAND bank1,bank2 or PC card bank3 */ + status = EXMC_NPINTEN(exmc_bank); + }else{ + /* SDRAM device0 or device1 */ + status = EXMC_SDSTAT; + } + + if ((status & flag) != (uint32_t)flag ){ + /* flag is reset */ + return RESET; + }else{ + /* flag is set */ + return SET; + } +} + +/*! + \brief clear EXMC a channel flag + \param[in] exmc_bank: specifie the NAND bank , PCCARD bank or SDRAM device + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC card bank + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] flag: specify get which flag + \arg EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status + \arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status + \arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status + \arg EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag + \arg EXMC_SDRAM_FLAG_REFRESH: refresh error interrupt flag + \arg EXMC_SDRAM_FLAG_NREADY: not ready status + \param[out] none + \retval none +*/ +void exmc_flag_clear(uint32_t exmc_bank,uint32_t flag) +{ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + /* NAND bank1,bank2 or PC card bank3 */ + EXMC_NPINTEN(exmc_bank) &= ~flag; + }else{ + /* SDRAM device0 or device1 */ + EXMC_SDSTAT &= ~flag; + } +} + +/*! + \brief check EXMC interrupt flag is set or not + \param[in] exmc_bank: specifies the NAND bank , PC card bank or SDRAM device + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC card bank + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] interrupt_source: specify get which interrupt flag + \arg EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge + \arg EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level + \arg EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge + \arg EXMC_SDRAM_INT_REFRESH: interrupt source of refresh error + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank,uint32_t interrupt_source) +{ + uint32_t status = 0x00000000U,interrupt_enable = 0x00000000U,interrupt_state = 0x00000000U; + + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + /* NAND bank1,bank2 or PC card bank3 */ + status = EXMC_NPINTEN(exmc_bank); + interrupt_enable = (status & (interrupt_source >> INTEN_INTEN_OFFSET)); + }else{ + /* SDRAM device0 or device1 */ + status = EXMC_SDARI; + interrupt_enable = (EXMC_SDSTAT & EXMC_SDSDAT_REIF); + } + + interrupt_state = (status & interrupt_source); + + if ((interrupt_enable) && (interrupt_state)){ + /* interrupt flag is set */ + return SET; + }else{ + /* interrupt flag is reset */ + return RESET; + } +} + +/*! + \brief clear EXMC one channel interrupt flag + \param[in] exmc_bank: specifies the NAND bank , PC card bank or SDRAM device + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC card bank + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] interrupt_source: specify get which interrupt flag + \arg EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge + \arg EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level + \arg EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge + \arg EXMC_SDRAM_INT_REFRESH: interrupt source of refresh error + \param[out] none + \retval none +*/ +void exmc_interrupt_flag_clear(uint32_t exmc_bank,uint32_t interrupt_source) +{ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + /* NAND bank1,bank2 or PC card bank3 */ + EXMC_NPINTEN(exmc_bank) &= ~(interrupt_source >> INTEN_INTEN_OFFSET); + }else{ + /* SDRAM device0 or device1 */ + EXMC_SDARI |= EXMC_SDARI_REC; + } +} + +/*! + \brief enable EXMC interrupt + \param[in] exmc_bank: specifies the NAND bank,PC card bank or SDRAM device + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC card bank + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] interrupt_source: specify get which interrupt flag + \arg EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge + \arg EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level + \arg EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge + \arg EXMC_SDRAM_INT_REFRESH: interrupt source of refresh error + \param[out] none + \retval none +*/ +void exmc_interrupt_enable(uint32_t exmc_bank,uint32_t interrupt_source) +{ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + /* NAND bank1,bank2 or PC card bank3 */ + EXMC_NPINTEN(exmc_bank) |= interrupt_source; + }else{ + /* SDRAM device0 or device1 */ + EXMC_SDARI |= EXMC_SDARI_REIE; + } +} + +/*! + \brief disable EXMC interrupt + \param[in] exmc_bank: specifies the NAND bank , PC card bank or SDRAM device + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC card bank + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] interrupt_source: specify get which interrupt flag + \arg EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge + \arg EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level + \arg EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge + \arg EXMC_SDRAM_INT_REFRESH: interrupt source of refresh error + \param[out] none + \retval none +*/ +void exmc_interrupt_disable(uint32_t exmc_bank,uint32_t interrupt_source) +{ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + /* NAND bank1,bank2 or PC card bank3 */ + EXMC_NPINTEN(exmc_bank) &= ~interrupt_source; + }else{ + /* SDRAM device0 or device1 */ + EXMC_SDARI &= ~EXMC_SDARI_REIE; + } +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c new file mode 100644 index 0000000000..24bffea316 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c @@ -0,0 +1,229 @@ +/*! + \file gd32f4xx_exti.c + \brief EXTI driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_exti.h" + +/*! + \brief deinitialize the EXTI + \param[in] none + \param[out] none + \retval none +*/ +void exti_deinit(void) +{ + /* reset the value of all the EXTI registers */ + EXTI_INTEN = (uint32_t)0x00000000U; + EXTI_EVEN = (uint32_t)0x00000000U; + EXTI_RTEN = (uint32_t)0x00000000U; + EXTI_FTEN = (uint32_t)0x00000000U; + EXTI_SWIEV = (uint32_t)0x00000000U; +} + +/*! + \brief initialize the EXTI + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..22): EXTI line x + \param[in] mode: interrupt or event mode, refer to exti_mode_enum + only one parameter can be selected which is shown as below: + \arg EXTI_INTERRUPT: interrupt mode + \arg EXTI_EVENT: event mode + \param[in] trig_type: interrupt trigger type, refer to exti_trig_type_enum + only one parameter can be selected which is shown as below: + \arg EXTI_TRIG_RISING: rising edge trigger + \arg EXTI_TRIG_FALLING: falling trigger + \arg EXTI_TRIG_BOTH: rising and falling trigger + \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..22): EXTI line x + \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..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_enable(exti_line_enum linex) +{ + EXTI_EVEN |= (uint32_t)linex; +} + +/*! + \brief disable the interrupt from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_disable(exti_line_enum linex) +{ + EXTI_INTEN &= ~(uint32_t)linex; +} + +/*! + \brief disable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_disable(exti_line_enum linex) +{ + EXTI_EVEN &= ~(uint32_t)linex; +} + +/*! + \brief get EXTI lines flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..22): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_flag_get(exti_line_enum linex) +{ + if(RESET != (EXTI_PD & (uint32_t)linex)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)linex; +} + +/*! + \brief get EXTI lines flag when the interrupt flag is set + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..22): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex) +{ + uint32_t flag_left, flag_right; + + flag_left = EXTI_PD & (uint32_t)linex; + flag_right = EXTI_INTEN & (uint32_t)linex; + + if((RESET != flag_left) && (RESET != flag_right)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)linex; +} + +/*! + \brief enable EXTI software interrupt event + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_enable(exti_line_enum linex) +{ + EXTI_SWIEV |= (uint32_t)linex; +} + +/*! + \brief disable EXTI software interrupt event + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_disable(exti_line_enum linex) +{ + EXTI_SWIEV &= ~(uint32_t)linex; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c new file mode 100644 index 0000000000..2bfc2f1caa --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c @@ -0,0 +1,824 @@ +/*! + \file gd32f4xx_fmc.c + \brief FMC driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_fmc.h" + +/*! + \brief set the wait state counter value + \param[in] wscntwait state counter value + \arg WS_WSCNT_0: FMC 0 wait + \arg WS_WSCNT_1: FMC 1 wait + \arg WS_WSCNT_2: FMC 2 wait + \arg WS_WSCNT_3: FMC 3 wait + \arg WS_WSCNT_4: FMC 4 wait + \arg WS_WSCNT_5: FMC 5 wait + \arg WS_WSCNT_6: FMC 6 wait + \arg WS_WSCNT_7: FMC 7 wait + \arg WS_WSCNT_8: FMC 8 wait + \arg WS_WSCNT_9: FMC 9 wait + \arg WS_WSCNT_10: FMC 10 wait + \arg WS_WSCNT_11: FMC 11 wait + \arg WS_WSCNT_12: FMC 12 wait + \arg WS_WSCNT_13: FMC 13 wait + \arg WS_WSCNT_14: FMC 14 wait + \arg WS_WSCNT_15: FMC 15 wait + \param[out] none + \retval none +*/ +void fmc_wscnt_set(uint32_t wscnt) +{ + uint32_t reg; + + reg = FMC_WS; + /* set the wait state counter value */ + reg &= ~FMC_WC_WSCNT; + FMC_WS = (reg | wscnt); +} + +/*! + \brief unlock the main FMC operation + \param[in] none + \param[out] none + \retval none +*/ +void fmc_unlock(void) +{ + if((RESET != (FMC_CTL & FMC_CTL_LK))){ + /* write the FMC key */ + FMC_KEY = UNLOCK_KEY0; + FMC_KEY = UNLOCK_KEY1; + } +} + +/*! + \brief lock the main FMC operation + \param[in] none + \param[out] none + \retval none +*/ +void fmc_lock(void) +{ + /* set the LK bit*/ + FMC_CTL |= FMC_CTL_LK; +} + +/*! + \brief erase sector + \param[in] fmc_sector: select the sector to erase + \arg CTL_SECTOR_NUMBER_0: sector 0 + \arg CTL_SECTOR_NUMBER_1: sector 1 + \arg CTL_SECTOR_NUMBER_2: sector 2 + \arg CTL_SECTOR_NUMBER_3: sector 3 + \arg CTL_SECTOR_NUMBER_4: sector 4 + \arg CTL_SECTOR_NUMBER_5: sector 5 + \arg CTL_SECTOR_NUMBER_6: sector 6 + \arg CTL_SECTOR_NUMBER_7: sector 7 + \arg CTL_SECTOR_NUMBER_8: sector 8 + \arg CTL_SECTOR_NUMBER_9: sector 9 + \arg CTL_SECTOR_NUMBER_10: sector 10 + \arg CTL_SECTOR_NUMBER_11: sector 11 + \arg CTL_SECTOR_NUMBER_12: sector 12 + \arg CTL_SECTOR_NUMBER_13: sector 13 + \arg CTL_SECTOR_NUMBER_14: sector 14 + \arg CTL_SECTOR_NUMBER_15: sector 15 + \arg CTL_SECTOR_NUMBER_16: sector 16 + \arg CTL_SECTOR_NUMBER_17: sector 17 + \arg CTL_SECTOR_NUMBER_18: sector 18 + \arg CTL_SECTOR_NUMBER_19: sector 19 + \arg CTL_SECTOR_NUMBER_20: sector 20 + \arg CTL_SECTOR_NUMBER_21: sector 21 + \arg CTL_SECTOR_NUMBER_22: sector 22 + \arg CTL_SECTOR_NUMBER_23: sector 23 + \arg CTL_SECTOR_NUMBER_24: sector 24 + \arg CTL_SECTOR_NUMBER_25: sector 25 + \arg CTL_SECTOR_NUMBER_26: sector 26 + \arg CTL_SECTOR_NUMBER_27: sector 27 + \arg CTL_SECTOR_NUMBER_28: sector 28 + \arg CTL_SECTOR_NUMBER_29: sector 29 + \arg CTL_SECTOR_NUMBER_30: sector 30 + \param[out] none + \retval fmc_state_enum +*/ +fmc_state_enum fmc_sector_erase(uint32_t fmc_sector) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start sector erase */ + FMC_CTL &= ~FMC_CTL_SN; + FMC_CTL |= (FMC_CTL_SER | fmc_sector); + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the SER bit */ + FMC_CTL &= (~FMC_CTL_SER); + FMC_CTL &= ~FMC_CTL_SN; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief erase whole chip + \param[in] none + \param[out] none + \retval fmc_state_enum +*/ +fmc_state_enum fmc_mass_erase(void) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start whole chip erase */ + FMC_CTL |= (FMC_CTL_MER0 | FMC_CTL_MER1); + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER bits */ + FMC_CTL &= ~(FMC_CTL_MER0 | FMC_CTL_MER1); + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief erase all FMC sectors in bank0 + \param[in] none + \param[out] none + \retval fmc_state_enum +*/ +fmc_state_enum fmc_bank0_erase(void) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start FMC bank0 erase */ + FMC_CTL |= FMC_CTL_MER0; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER0 bit */ + FMC_CTL &= (~FMC_CTL_MER0); + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief erase all FMC sectors in bank1 + \param[in] none + \param[out] none + \retval fmc_state_enum +*/ +fmc_state_enum fmc_bank1_erase(void) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start FMC bank1 erase */ + FMC_CTL |= FMC_CTL_MER1; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER1 bit */ + FMC_CTL &= (~FMC_CTL_MER1); + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief program a word at the corresponding address + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval fmc_state_enum +*/ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL &= ~FMC_CTL_PSZ; + FMC_CTL |= CTL_PSZ_WORD; + FMC_CTL |= FMC_CTL_PG; + + REG32(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program a half word at the corresponding address + \param[in] address: address to program + \param[in] data: halfword to program + \param[out] none + \retval fmc_state_enum +*/ +fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL &= ~FMC_CTL_PSZ; + FMC_CTL |= CTL_PSZ_HALF_WORD; + FMC_CTL |= FMC_CTL_PG; + + REG16(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program a byte at the corresponding address + \param[in] address: address to program + \param[in] data: byte to program + \param[out] none + \retval fmc_state_enum +*/ +fmc_state_enum fmc_byte_program(uint32_t address, uint8_t data) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL &= ~FMC_CTL_PSZ; + FMC_CTL |= CTL_PSZ_BYTE; + FMC_CTL |= FMC_CTL_PG; + + REG8(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief unlock the option byte operation + \param[in] none + \param[out] none + \retval none +*/ +void ob_unlock(void) +{ + if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_OB_LK)){ + /* write the FMC key */ + FMC_OBKEY = OB_UNLOCK_KEY0; + FMC_OBKEY = OB_UNLOCK_KEY1; + } +} + +/*! + \brief lock the option byte operation + \param[in] none + \param[out] none + \retval none +*/ +void ob_lock(void) +{ + /* reset the OB_LK bit */ + FMC_OBCTL0 &= ~FMC_OBCTL0_OB_LK; +} + +/*! + \brief send option byte change command + \param[in] none + \param[out] none + \retval none +*/ +void ob_start(void) +{ + /* set the OB_START bit in OBCTL0 register */ + FMC_OBCTL0 |= FMC_OBCTL0_OB_START; +} + +/*! + \brief enable write protection + \param[in] ob_wp: specify sector to be write protected + \arg OB_WPx(x=0..11): write protect specify sector + \arg OB_WP_ALL: write protect all sector + \param[out] none + \retval none +*/ +void ob_write_protection0_enable(uint32_t ob_wp) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + FMC_OBCTL0 &= (~((uint32_t)ob_wp << 16)); + } +} + +/*! + \brief disable write protection + \param[in] ob_wp: specify sector to be write protected + \arg OB_WPx(x=0..11): write protect specify sector + \arg OB_WP_ALL: write protect all sector + \param[out] none + \retval none +*/ +void ob_write_protection0_disable(uint32_t ob_wp) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + FMC_OBCTL0 |= ((uint32_t)ob_wp << 16); + } +} + +/*! + \brief enable write protection + \param[in] ob_wp: specify sector to be write protected + \arg OB_WPx(x=12..30): write protect specify sector + \arg OB_WP_ALL: write protect all sector + \param[out] none + \retval none +*/ +void ob_write_protection1_enable(uint32_t ob_wp) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + FMC_OBCTL1 &= (~((uint32_t)ob_wp << 16)); + } +} + +/*! + \brief disable write protection + \param[in] ob_wp: specify sector to be write protected + \arg OB_WPx(x=12..30): write protect specify sector + \arg OB_WP_ALL: write protect all sector + \param[out] none + \retval none +*/ +void ob_write_protection1_disable(uint32_t ob_wp) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + FMC_OBCTL1 |= ((uint32_t)ob_wp << 16); + } +} +/*! + \brief configure the protection mode + \param[in] ob_drp: configure the protection mode of WPx bits + \arg OB_DRP_DISABLE: the WPx bits used as erase/program protection of each sector + \arg OB_DRP_ENABLE: the WPx bits used as erase/program protection and D-bus read protection of each sector + \param[out] none + \retval none +*/ +void ob_drp_config(uint32_t ob_drp) +{ + FMC_OBCTL0 &= ~FMC_OBCTL0_DRP; + FMC_OBCTL0 |= ob_drp; +} + +/*! + \brief enable erase/program protection and D-bus read protection + \param[in] ob_drp: enable the WPx bits used as erase/program protection and D-bus read protection of each sector + \arg OB_DRPx(x=0..11): erase/program protection and D-bus read protection of specify sector + \arg OB_DRP_ALL: erase/program protection and D-bus read protection of all sector + \param[out] none + \retval none +*/ +void ob_drp0_enable(uint32_t ob_drp) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + FMC_OBCTL0 |= ((uint32_t)ob_drp << 16); + } +} + +/*! + \brief disable erase/program protection and D-bus read protection + \param[in] ob_drp: disable the WPx bits used as erase/program protection and D-bus read protection of each sector + \arg OB_DRPx(x=0..11): erase/program protection and D-bus read protection of specify sector + \arg OB_DRP_ALL: erase/program protection and D-bus read protection of all sector + \param[out] none + \retval none +*/ +void ob_drp0_disable(uint32_t ob_drp) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + FMC_OBCTL0 &= (~((uint32_t)ob_drp << 16)); + } +} + +/*! + \brief enable erase/program protection and D-bus read protection + \param[in] ob_drp: enable the WPx bits used as erase/program protection and D-bus read protection of each sector + \arg OB_DRPx(x=12..30): erase/program protection and D-bus read protection of specify sector + \arg OB_DRP_ALL: erase/program protection and D-bus read protection of all sector + \param[out] none + \retval none +*/ +void ob_drp1_enable(uint32_t ob_drp) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + FMC_OBCTL1 |= ((uint32_t)ob_drp << 16); + } +} + +/*! + \brief disable erase/program protection and D-bus read protection + \param[in] ob_drp: disable the WPx bits used as erase/program protection and D-bus read protection of each sector + \arg OB_DRPx(x=12..30): erase/program protection and D-bus read protection of specify sector + \arg OB_DRP_ALL: erase/program protection and D-bus read protection of all sector + \param[out] none + \retval none +*/ +void ob_drp1_disable(uint32_t ob_drp) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + FMC_OBCTL1 &= (~((uint32_t)ob_drp << 16)); + } +} + +/*! + \brief configure security protection level + \param[in] ob_spc: specify security protection level + \arg FMC_NSPC: no security protection + \arg FMC_LSPC: low security protection + \arg FMC_HSPC: high security protection + \param[out] none + \retval none +*/ +void ob_security_protection_config(uint8_t ob_spc) +{ + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + uint32_t reg; + + reg = FMC_OBCTL0; + /* reset the OBCTL0_SPC, set according to ob_spc */ + reg &= ~FMC_OBCTL0_SPC; + FMC_OBCTL0 |= ((uint32_t)ob_spc << 8); + } +} + +/*! + \brief program the FMC user option byte + \param[in] ob_fwdgt: option byte watchdog value + \arg OB_FWDGT_SW: software free watchdog + \arg OB_FWDGT_HW: hardware free watchdog + \param[in] ob_deepsleep: option byte deepsleep reset value + \arg OB_DEEPSLEEP_NRST: no reset when entering deepsleep mode + \arg OB_DEEPSLEEP_RST: generate a reset instead of entering deepsleep mode + \param[in] ob_stdby:option byte standby reset value + \arg OB_STDBY_NRST: no reset when entering standby mode + \arg OB_STDBY_RST: generate a reset instead of entering standby mode + \param[out] none + \retval none +*/ +void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby) +{ + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + uint32_t reg; + + reg = FMC_OBCTL0; + /* reset the OB_FWDGT, OB_DEEPSLEEP and OB_STDBY, set according to ob_fwdgt ,ob_deepsleep and ob_stdby */ + reg &= ~(FMC_OBCTL0_NWDG_HW | FMC_OBCTL0_NRST_DPSLP | FMC_OBCTL0_NRST_STDBY); + FMC_OBCTL0 = (reg | ob_fwdgt | ob_deepsleep | ob_stdby); + } +} + +/*! + \brief program the option byte BOR threshold value + \param[in] ob_bor_th: user option byte + \arg OB_BOR_TH_VALUE3: BOR threshold value 3 + \arg OB_BOR_TH_VALUE2: BOR threshold value 2 + \arg OB_BOR_TH_VALUE1: BOR threshold value 1 + \arg OB_BOR_TH_OFF: no BOR function. + \param[out] none + \retval none +*/ +void ob_user_bor_threshold(uint32_t ob_bor_th) +{ + uint32_t reg; + + reg = FMC_OBCTL0; + /* set the BOR level */ + reg &= ~FMC_OBCTL0_BOR_TH; + FMC_OBCTL0 = (reg | ob_bor_th); +} + +/*! + \brief configure the option byte boot bank value + \param[in] boot_mode: specifies the option byte boot bank value + \arg OB_BB_DISABLE: boot from bank0 + \arg OB_BB_ENABLE: boot from bank1 or bank0 if bank1 is void + \param[out] none + \retval none +*/ +void ob_boot_mode_config(uint32_t boot_mode) +{ + uint32_t reg; + + reg = FMC_OBCTL0; + /* set option byte boot bank value */ + reg &= ~FMC_OBCTL0_BB; + FMC_OBCTL0 = (reg | boot_mode); +} + +/*! + \brief get the FMC user option byte + \param[in] none + \param[out] none + \retval the FMC user option byte values: ob_fwdgt(Bit0), ob_deepsleep(Bit1), ob_stdby(Bit2). +*/ +uint8_t ob_user_get(void) +{ + return (uint8_t)((uint8_t)(FMC_OBCTL0 >> 5) & (uint8_t)0x07); +} + +/*! + \brief get the FMC option byte write protection + \param[in] none + \param[out] none + \retval the FMC write protection option byte value +*/ +uint16_t ob_write_protection0_get(void) +{ + /* return the FMC write protection option byte value */ + return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16)) & (uint16_t)0x0FFF); +} + +/*! + \brief get the FMC option byte write protection + \param[in] none + \param[out] none + \retval the FMC write protection option byte value +*/ +uint16_t ob_write_protection1_get(void) +{ + /* return the the FMC write protection option byte value */ + return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16)) & (uint16_t)0x0FFF); +} + +/*! + \brief get the FMC D-bus read protection protection + \param[in] none + \param[out] none + \retval the FMC erase/program protection and D-bus read protection option bytes value +*/ +uint16_t ob_drp0_get(void) +{ + /* return the FMC erase/program protection and D-bus read protection option bytes value */ + return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16)) & (uint16_t)0x0FFF); +} + +/*! + \brief get the FMC D-bus read protection protection + \param[in] none + \param[out] none + \retval the FMC erase/program protection and D-bus read protection option bytes value +*/ +uint16_t ob_drp1_get(void) +{ + /* return the FMC erase/program protection and D-bus read protection option bytes value */ + return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16)) & (uint16_t)0x0FFF); +} + +/*! + \brief get the FMC option byte security protection + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ob_spc_get(void) +{ + FlagStatus spc_state = RESET; + + if (((uint8_t)(FMC_OBCTL0 >> 8)) != (uint8_t)FMC_NSPC){ + spc_state = SET; + }else{ + spc_state = RESET; + } + return spc_state; +} + +/*! + \brief get the FMC option byte BOR threshold value + \param[in] none + \param[out] none + \retval the FMC BOR threshold value:OB_BOR_TH_OFF,OB_BOR_TH_VALUE1,OB_BOR_TH_VALUE2,OB_BOR_TH_VALUE3 +*/ +uint8_t ob_user_bor_threshold_get(void) +{ + /* return the FMC BOR threshold value */ + return (uint8_t)((uint8_t)FMC_OBCTL0 & (uint8_t)0x0C); +} + +/*! + \brief enable FMC interrupt + \param[in] the FMC interrupt source + \arg FMC_INTEN_END: enable FMC end of program interrupt + \arg FMC_INTEN_ERR: enable FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_enable(uint32_t fmc_int) +{ + FMC_CTL |= fmc_int; +} + +/*! + \brief disable FMC interrupt + \param[in] the FMC interrupt source + \arg FMC_INTEN_END: disable FMC end of program interrupt + \arg FMC_INTEN_ERR: disable FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_disable(uint32_t fmc_int) +{ + FMC_CTL &= ~(uint32_t)fmc_int; +} + +/*! + \brief get flag set or reset + \param[in] fmc_flag: check FMC flag + \arg FMC_FLAG_BUSY: FMC busy flag + \arg FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit + \arg FMC_FLAG_PGSERR: FMC program sequence error flag bit + \arg FMC_FLAG_PGMERR: FMC program size not match error flag bit + \arg FMC_FLAG_WPERR: FMC Erase/Program protection error flag bit + \arg FMC_FLAG_OPERR: FMC operation error flag bit + \arg FMC_FLAG_END: FMC end of operation flag bit + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flag_get(uint32_t fmc_flag) +{ + if(FMC_STAT & fmc_flag){ + return SET; + } + /* return the state of corresponding FMC flag */ + return RESET; +} + +/*! + \brief clear the FMC pending flag + \param[in] FMC_flag: clear FMC flag + \arg FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit + \arg FMC_FLAG_PGSERR: FMC program sequence error flag bit + \arg FMC_FLAG_PGMERR: FMC program size not match error flag bit + \arg FMC_FLAG_WPERR: FMC erase/program protection error flag bit + \arg FMC_FLAG_OPERR: FMC operation error flag bit + \arg FMC_FLAG_END: FMC end of operation flag bit + \param[out] none + \retval none +*/ +void fmc_flag_clear(uint32_t fmc_flag) +{ + /* clear the flags */ + FMC_STAT = fmc_flag; +} + +/*! + \brief get the FMC state + \param[in] none + \param[out] none + \retval fmc_state_enum +*/ +fmc_state_enum fmc_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((FMC_STAT & FMC_FLAG_BUSY) == FMC_FLAG_BUSY){ + fmc_state = FMC_BUSY; + }else{ + if((FMC_STAT & FMC_FLAG_WPERR) != (uint32_t)0x00){ + fmc_state = FMC_WPERR; + }else{ + if((FMC_STAT & FMC_FLAG_RDDERR) != (uint32_t)0x00){ + fmc_state = FMC_RDDERR; + }else{ + if((FMC_STAT & (uint32_t)0xEF) != (uint32_t)0x00){ + fmc_state = FMC_PGERR; + }else{ + if((FMC_STAT & FMC_FLAG_OPERR) != (uint32_t)0x00){ + fmc_state = FMC_OPERR; + }else{ + fmc_state = FMC_READY; + } + } + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC is ready or not + \param[in] count: FMC_TIMEOUT_COUNT + \param[out] none + \retval fmc_state_enum +*/ +fmc_state_enum fmc_ready_wait(uint32_t count) +{ + fmc_state_enum fmc_state = FMC_BUSY; + + /* wait for FMC ready */ + do{ + /* get FMC state */ + fmc_state = fmc_state_get(); + count--; + }while((FMC_BUSY == fmc_state) && ((uint32_t)RESET != count)); + + if(FMC_BUSY == fmc_state){ + fmc_state = FMC_TOERR; + } + /* return the FMC state */ + return fmc_state; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c new file mode 100644 index 0000000000..4762344417 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c @@ -0,0 +1,120 @@ +/*! + \file gd32f4xx_fwdgt.c + \brief FWDGT driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_fwdgt.h" + +/* write value to FWDGT_CTL_CMD bit field */ +#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) +/* write value to FWDGT_RLD_RLD bit field */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +/*! + \brief disable write access to FWDGT_PSC and FWDGT_RLD + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_disable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE; +} + +/*! + \brief 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 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_STAT_PUD: a write operation to FWDGT_PSC register is on going + \arg FWDGT_STAT_RUD: a write operation to FWDGT_RLD register is on going + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fwdgt_flag_get(uint16_t flag) +{ + if(FWDGT_STAT & flag){ + return SET; + } + + return RESET; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c new file mode 100644 index 0000000000..ccce538926 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c @@ -0,0 +1,357 @@ +/*! + \file gd32f4xx_gpio.c + \brief GPIO driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_gpio.h" + +/*! + \brief reset GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) + \param[out] none + \retval none +*/ +void gpio_deinit(uint32_t gpio_periph) +{ + switch(gpio_periph){ + case GPIOA: + /* reset GPIOA */ + rcu_periph_reset_enable(RCU_GPIOARST); + rcu_periph_reset_disable(RCU_GPIOARST); + break; + case GPIOB: + /* reset GPIOB */ + rcu_periph_reset_enable(RCU_GPIOBRST); + rcu_periph_reset_disable(RCU_GPIOBRST); + break; + case GPIOC: + /* reset GPIOC */ + rcu_periph_reset_enable(RCU_GPIOCRST); + rcu_periph_reset_disable(RCU_GPIOCRST); + break; + case GPIOD: + /* reset GPIOD */ + rcu_periph_reset_enable(RCU_GPIODRST); + rcu_periph_reset_disable(RCU_GPIODRST); + break; + case GPIOE: + /* reset GPIOE */ + rcu_periph_reset_enable(RCU_GPIOERST); + rcu_periph_reset_disable(RCU_GPIOERST); + break; + case GPIOF: + /* reset GPIOF */ + rcu_periph_reset_enable(RCU_GPIOFRST); + rcu_periph_reset_disable(RCU_GPIOFRST); + break; + case GPIOG: + /* reset GPIOG */ + rcu_periph_reset_enable(RCU_GPIOGRST); + rcu_periph_reset_disable(RCU_GPIOGRST); + break; + case GPIOH: + /* reset GPIOH */ + rcu_periph_reset_enable(RCU_GPIOHRST); + rcu_periph_reset_disable(RCU_GPIOHRST); + break; + case GPIOI: + /* reset GPIOI */ + rcu_periph_reset_enable(RCU_GPIOIRST); + rcu_periph_reset_disable(RCU_GPIOIRST); + break; + default: + break; + } +} + +/*! + \brief set GPIO output mode + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) + \param[in] mode: gpio pin mode + \arg GPIO_MODE_INPUT: input mode + \arg GPIO_MODE_OUTPUT: output mode + \arg GPIO_MODE_AF: alternate function mode + \arg GPIO_MODE_ANALOG: analog mode + \param[in] pull_up_down: gpio pin with pull-up or pull-down resistor + \arg GPIO_PUPD_NONE: 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,E,F,G,H,I) + \param[in] otype: gpio pin output mode + \arg GPIO_OTYPE_PP: push pull mode + \arg GPIO_OTYPE_OD: open drain mode + \param[in] speed: gpio pin output max speed + \arg GPIO_OSPEED_2MHZ: output max speed 2M + \arg GPIO_OSPEED_25MHZ: output max speed 25M + \arg GPIO_OSPEED_50MHZ: output max speed 50M + \arg GPIO_OSPEED_200MHZ: output max speed 200M + \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,E,F,G,H,I) + \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,E,F,G,H,I) + \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,E,F,G,H,I) + \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[in] bitvalue: 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,E,F,G,H,I) + \param[in] data: specify the value to be written to the port output data register + \param[out] none + \retval none +*/ +void gpio_port_write(uint32_t gpio_periph,uint16_t data) +{ + GPIO_OCTL(gpio_periph) = (uint32_t)data; +} + +/*! + \brief get GPIO pin input status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) + \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,E,F,G,H,I) + \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,E,F,G,H,I) + \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,E,F,G,H,I) + \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,E,F,G,H,I) + \param[in] alt_func_num: gpio pin af function + \arg GPIO_AF_0: SYSTEM + \arg GPIO_AF_1: TIMER0, TIMER1 + \arg GPIO_AF_2: TIMER2, TIMER3, TIMER4 + \arg GPIO_AF_3: TIMER7, TIMER8, TIMER9, TIMER10 + \arg GPIO_AF_4: I2C0, I2C1, I2C2 + \arg GPIO_AF_5: SPI0, SPI1, SPI2, SPI3, SPI4, SPI5 + \arg GPIO_AF_6: SPI1, SPI2, SAI0 + \arg GPIO_AF_7: USART0, USART1, USART2 + \arg GPIO_AF_8: UART3, UART4, USART5, UART6, UART7 + \arg GPIO_AF_9: CAN0,CAN1, TLI, TIMER11, TIMER12, TIMER13 + \arg GPIO_AF_10: USB_FS, USB_HS + \arg GPIO_AF_11: ENET + \arg GPIO_AF_12: FMC, SDIO, USB_HS + \arg GPIO_AF_13: DCI + \arg GPIO_AF_14: TLI + \arg GPIO_AF_15: EVENTOUT + \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,C,D,E,F,G,H,I) + \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); +} + +/*! + \brief toggle GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,I) + \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,E,F,G,H,I) + \param[out] none + \retval none +*/ +void gpio_port_toggle(uint32_t gpio_periph) +{ + GPIO_TG(gpio_periph) = 0x0000FFFFU; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c new file mode 100644 index 0000000000..79480b63e5 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c @@ -0,0 +1,730 @@ +/*! + \file gd32f4xx_i2c.c + \brief I2C driver + +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_i2c.h" + +#define I2CCLK_MAX 0x3fU /*!< i2cclk max value */ +#define I2C_STATE_MASK 0x0000FFFFU /*!< i2c state 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: + rcu_periph_reset_enable(RCU_I2C0RST); + rcu_periph_reset_disable(RCU_I2C0RST); + break; + case I2C1: + rcu_periph_reset_enable(RCU_I2C1RST); + rcu_periph_reset_disable(RCU_I2C1RST); + break; + case I2C2: + rcu_periph_reset_enable(RCU_I2C2RST); + rcu_periph_reset_disable(RCU_I2C2RST); + break; + default: + break; + + } +} + +/*! + \brief I2C clock configure + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] clkspeed: i2c clock speed + \param[in] dutycyc: duty cycle in fast mode + \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,i2cclk,risetime; + pclk1 = rcu_clock_freq_get(CK_APB1); + /* I2C Peripheral clock frequency */ + i2cclk=((pclk1)/(uint32_t)(1000000)); + if(i2cclk >= I2CCLK_MAX){ + i2cclk = I2CCLK_MAX; + } + + I2C_CTL1(i2c_periph) |= (I2C_CTL1_I2CCLK & i2cclk) ; + + if(100000U >= clkspeed){ + /* standard mode the maximum SCL rise time in standard mode is 1000ns */ + risetime = (uint32_t)((pclk1/1000000U)+1U); + if(risetime >= I2CCLK_MAX){ + I2C_RT(i2c_periph) |= I2CCLK_MAX; + }else{ + I2C_RT(i2c_periph) |= (uint32_t)((pclk1/1000000U)+1U); + } + 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{ + /* fast mode the maximum SCL rise time in standard mode is 300ns */ + I2C_RT(i2c_periph) |= (uint16_t)(((i2cclk*(uint16_t)300)/(uint16_t)1000)+(uint16_t)1); + if(I2C_DTCY_2 == dutycyc){ + /* I2C_DutyCycle == 2 */ + clkc = (uint16_t)(pclk1/(clkspeed*3U)); + } else{ + /* I2C_DutyCycle == 16/9 */ + clkc = (uint16_t)(pclk1/(clkspeed*25U)); + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY; + } + if((clkc & I2C_CKCFG_CLKC) == 0U){ + /* The CLKC in standard mode minmum value is 1*/ + clkc |= (uint16_t)0x0001; + } + I2C_CKCFG(i2c_periph) |= clkc; + } +} + +/*! + \brief I2C address configure + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] i2cmod: + \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 i2cmod,uint32_t addformat,uint32_t addr) +{ + /* SMBus/I2C mode selected */ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SMBEN); + ctl |= i2cmod; + 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,uint8_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_ACK_ENABLE: ACK will be sent + \arg I2C_ACK_DISABLE: ACK will not be sent + \param[out] none + \retval none +*/ +void i2c_ackpos_config(uint32_t i2c_periph,uint8_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,uint8_t addr,uint32_t trandirection) +{ + if(I2C_TRANSMITTER==trandirection){ + addr = (uint8_t)((uint32_t)addr & I2C_TRANSMITTER); + }else{ + addr = (uint8_t)((uint32_t)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: dual-address mode disabled + \arg I2C_DUADEN_ENABLE: dual-address mode enabled + \param[out] none + \retval none +*/ +void i2c_dualaddr_enable(uint32_t i2c_periph,uint8_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_transmit_data(uint32_t i2c_periph,uint8_t data) +{ + I2C_DATA(i2c_periph) = 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_receive_data(uint32_t i2c_periph) +{ + return (uint8_t)I2C_DATA(i2c_periph); +} + +/*! + \brief I2C DMA mode enable + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dmastste: + \arg I2C_DMA_ON: DMA mode enabled + \arg I2C_DMA_OFF: DMA mode disabled + \param[out] none + \retval none +*/ +void i2c_dma_enable(uint32_t i2c_periph,uint32_t dmastste) +{ + /* configure i2c DMA function */ + uint32_t ctl = 0U; + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMAON); + ctl |= dmastste; + I2C_CTL1(i2c_periph) = ctl; + +} + +/*! + \brief flag indicating DMA last transfer + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dmastste: + \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 Cal + \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 state + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] state: + \arg I2C_SBSEND: start condition send out + \arg I2C_ADDSEND: address is sent in master mode or received and matches in slave mode + \arg I2C_BTC: byte transmission finishes + \arg I2C_ADD10SEND: header of 10-bit address is sent in master mode + \arg I2C_STPDET: etop condition detected in slave mode + \arg I2C_RBNE: I2C_DATA is not Empty during receiving + \arg I2C_TBE: I2C_DATA is empty during transmitting + \arg I2C_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus + \arg I2C_LOSTARB: arbitration lost in master mode + \arg I2C_AERR: acknowledge error + \arg I2C_OUERR: over-run or under-run situation occurs in slave mode + \arg I2C_PECERR: PEC error when receiving data + \arg I2C_SMBTO: timeout signal in SMBus mode + \arg I2C_SMBALT: SMBus alert status + \arg I2C_MASTER: a flag indicating whether I2C block is in master or slave mode + \arg I2C_I2CBSY: busy flag + \arg I2C_TRS: whether the I2C is a transmitter or a receiver + \arg I2C_RXGC: general call address (00h) received + \arg I2C_DEFSMB: default address of SMBus device + \arg I2C_HSTSMB: SMBus host header detected in slave mode + \arg I2C_DUMODF: dual flag in slave mode indicating which address is matched in dual-address mode + \param[out] none + \retval state of i2c +*/ +FlagStatus i2c_flag_get(uint32_t i2c_periph,uint32_t state ) +{ + uint32_t reg = 0U; + FlagStatus regstate = RESET; + /* get the state in which register */ + reg = (BIT(31) & state); + if((BIT(31) == reg)){ + if((I2C_STAT1(i2c_periph)&(state & I2C_STATE_MASK))){ + regstate = SET; + }else{ + regstate = RESET; + } + }else{ + if((I2C_STAT0(i2c_periph)&(state & I2C_STATE_MASK))){ + regstate = SET; + }else{ + regstate = RESET; + } + } + /* return the state */ + return regstate; +} + +/*! + \brief clear i2c state + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] state: state type + \@arg I2C_STAT0_SMBALT: SMBus Alert status + \@arg I2C_STAT0_SMBTO: timeout signal in SMBus mode + \@arg I2C_STAT0_PECERR: PEC error when receiving data + \@arg I2C_STAT0_OUERR: over-run or under-run situation occurs in slave mode + \@arg I2C_STAT0_AERR: acknowledge error + \@arg I2C_STAT0_LOSTARB: arbitration lost in master mode + \@arg I2C_STAT0_BERR: a bus error + \@arg I2C_STAT0_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 state) +{ + if(I2C_STAT0_ADDSEND == state){ + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + }else{ + I2C_STAT0(i2c_periph) &= ~(state); + } +} + +/*! + \brief enable i2c interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] inttype: interrupt type + \arg I2C_CTL1_ERRIE: error interrupt enable + \arg I2C_CTL1_EVIE: event interrupt enable + \arg I2C_CTL1_BUFIE: 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_CTL1_ERRIE: error interrupt enable + \arg I2C_CTL1_EVIE: event interrupt enable + \arg I2C_CTL1_BUFIE: 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 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 packet error checking value + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval PEC value +*/ +uint8_t i2c_pec_value(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_alert_issue(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 I2C ARP protocol in SMBus switch enable or disable + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] smbuspara: + \arg I2C_ARP_ENABLE: ARP is enabled + \arg I2C_ARP_DISABLE: ARP is disabled + \param[out] none + \retval none +*/ +void i2c_smbus_arp_enable(uint32_t i2c_periph,uint32_t arpstate) +{ + /* enable or disable I2C ARP protocol*/ + uint32_t ctl = 0U; + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_ARPEN); + ctl |= arpstate; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief analog noise filter disable + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph) +{ + I2C_FCTL(i2c_periph) |= I2C_FCTL_AFD; +} + +/*! + \brief analog noise filter enable + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph) +{ + I2C_FCTL(i2c_periph) &= ~(I2C_FCTL_AFD); +} + +/*! + \brief digital noise filter configuration + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dfilterpara: refer to enum i2c_gcall_config_enum + \param[out] none + \retval none +*/ +void i2c_digital_noise_filter_config(uint32_t i2c_periph,i2c_digital_filter_enum dfilterpara) +{ + I2C_FCTL(i2c_periph) |= dfilterpara; +} + +/*! + \brief enable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN; +} + +/*! + \brief disable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN); +} + +/*! + \brief enable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN; +} + +/*! + \brief disable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN); +} + +/*! + \brief 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) +{ + FlagStatus reg = RESET; + if(I2C_SAMCS(i2c_periph)&samstate){ + reg =SET; + }else{ + reg =RESET; + } + return reg; +} + +/*! + \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); + +} + diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c new file mode 100644 index 0000000000..d50b473ab9 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c @@ -0,0 +1,409 @@ +/*! + \file gd32f4xx_ipa.c + \brief IPA driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_ipa.h" + +/*! + \brief deinitialize IPA registers + \param[in] none + \param[out] none + \retval none +*/ +void ipa_deinit(void) +{ + rcu_periph_reset_enable(RCU_IPAENRST); + rcu_periph_reset_disable(RCU_IPAENRST); +} + +/*! + \brief IPA transfer enable + \param[in] none + \param[out] none + \retval none +*/ +void ipa_transfer_enable(void) +{ + IPA_CTL |= IPA_CTL_TEN; +} + +/*! + \brief IPA transfer hang up enable + \param[in] none. + \param[out] none + \retval none +*/ +void ipa_transfer_hangup_enable(void) +{ + IPA_CTL |= IPA_CTL_THU; +} + +/*! + \brief IPA transfer hang up disable + \param[in] none. + \param[out] none + \retval none +*/ +void ipa_transfer_hangup_disable(void) +{ + IPA_CTL &= ~(IPA_CTL_THU); +} + +/*! + \brief IPA transfer stop enable + \param[in] none. + \param[out] none + \retval none +*/ +void ipa_transfer_stop_enable(void) +{ + IPA_CTL |= IPA_CTL_TST; +} + +/*! + \brief IPA transfer stop disable + \param[in] none. + \param[out] none + \retval none +*/ +void ipa_transfer_stop_disable(void) +{ + IPA_CTL &= ~(IPA_CTL_TST); +} +/*! + \brief IPA foreground LUT loading enable + \param[in] none. + \param[out] none + \retval none +*/ +void ipa_foreground_lut_loading_enable(void) +{ + IPA_FPCTL |= IPA_FPCTL_FLLEN; +} + +/*! + \brief IPA background LUT loading enable + \param[in] none. + \param[out] none + \retval none +*/ +void ipa_background_lut_loading_enable(void) +{ + IPA_BPCTL |= IPA_BPCTL_BLLEN; +} + +/*! + \brief Pixel format convert mode + \param[in] pfcm: + \arg IPA_FGTODE: foreground memory to destination memory without pixel format convert + \arg IPA_FGTODE_PF_CONVERT: foreground memory to destination memory with pixel format convert + \arg IPA_FGBGTODE: blending foreground and background memory to destination memory + \arg IPA_FILL_UP_DE: fill up destination memory with specific color + \param[out] none + \retval none +*/ +void ipa_pixel_format_convert_mod(uint32_t pfcm) +{ + IPA_CTL |= pfcm; +} + +/*! + \brief initialize foreground parameters + \param[in] foreground_struct: the data needed to initialize fore. + foreground_memaddr: foreground memory base address + foreground_lineoff: foreground line offset + foreground_prealpha: foreground pre-defined alpha value + foreground_alpha_algorithm: IPA_FG_ALPHA_MODE_0,IPA_FG_ALPHA_MODE_1,IPA_FG_ALPHA_MODE_2 + foreground_pf: foreground pixel format + foreground_prered: foreground pre-defined red value + foreground_pregreen: foreground pre-defined green value + foreground_preblue: foreground pre-defined blue value + \param[out] none + \retval none +*/ +void ipa_foreground_init(ipa_foreground_parameter_struct* foreground_struct) +{ + /* foreground memory base address configuration */ + IPA_FMADDR &= ~(IPA_FMADDR_FMADDR); + IPA_FMADDR = foreground_struct->foreground_memaddr; + /* foreground line offset configuration */ + IPA_FLOFF &= ~(IPA_FLOFF_FLOFF); + IPA_FLOFF = foreground_struct->foreground_lineoff; + /* foreground pixel format pre-defined alpha, alpha calculation algorithm configuration */ + IPA_FPCTL &= ~(IPA_FPCTL_FAVCA|IPA_FPCTL_FAVCA|IPA_FPCTL_FPF); + IPA_FPCTL |= (foreground_struct->foreground_prealpha<<24U); + IPA_FPCTL |= foreground_struct->foreground_alpha_algorithm; + IPA_FPCTL |= foreground_struct->foreground_pf; + /* foreground pre-defined red green blue configuration */ + IPA_FPV &= ~(IPA_FPV_FPDRV|IPA_FPV_FPDGV|IPA_FPV_FPDBV); + IPA_FPV |= ((foreground_struct->foreground_prered<<16U)|(foreground_struct->foreground_pregreen<<8U)|(foreground_struct->foreground_preblue)); +} + +/*! + \brief initialize background parameters + \param[in] background_struct: the data needed to initialize fore. + background_memaddr: background memory base address + background_lineoff: background line offset + background_prealpha: background pre-defined alpha value + background_alpha_algorithm: IPA_BG_ALPHA_MODE_0,IPA_FG_ALPHA_MODE_1,IPA_FG_ALPHA_MODE_2 + background_pf: background pixel format + background_prered: background pre-defined red value + background_pregreen: background pre-defined green value + background_preblue: background pre-defined blue value + \param[out] none + \retval none +*/ +void ipa_background_init(ipa_background_parameter_struct* background_struct) +{ + /* background memory base address configuration */ + IPA_BMADDR &= ~(IPA_BMADDR_BMADDR); + IPA_BMADDR = background_struct->background_memaddr; + /* background line offset configuration */ + IPA_BLOFF &= ~(IPA_BLOFF_BLOFF); + IPA_BLOFF =background_struct->background_lineoff; + /* background pixel format pre-defined alpha, alpha calculation algorithm configuration */ + IPA_BPCTL &= ~(IPA_BPCTL_BAVCA|IPA_BPCTL_BAVCA|IPA_BPCTL_BPF); + IPA_BPCTL |= (background_struct->background_prealpha<<24U); + IPA_BPCTL |= background_struct->background_alpha_algorithm; + IPA_BPCTL |= background_struct->background_pf; + /* background pre-defined red green blue configuration */ + IPA_BPV &= ~(IPA_BPV_BPDRV|IPA_BPV_BPDGV|IPA_BPV_BPDBV); + IPA_BPV |= ((background_struct->background_prered<<16U)|(background_struct->background_pregreen<<8U)|(background_struct->background_preblue)); +} + +/*! + \brief initialize destination parameters + \param[in] destination_struct: the data needed to initialize tli. + destination_pf: refer to ipa_dpf_enum + destination_lineoff: destination line offset + destination_prealpha: destination pre-defined alpha value + destination_prered: destination pre-defined red value + destination_pregreen: destination pre-defined green value + destination_preblue: destination pre-defined blue value + destination_memaddr: destination memory base address + image_width: width of the image to be processed + image_height: height of the image to be processed + \param[out] none + \retval none +*/ +void ipa_destination_init(ipa_destination_parameter_struct* destination_struct) +{ + uint32_t destination_pixelformat; + /* destination pixel format configuration */ + IPA_DPCTL &= ~(IPA_DPCTL_DPF); + IPA_DPCTL = destination_struct->destination_pf; + destination_pixelformat = destination_struct->destination_pf; + /* destination pixel format ARGB8888 */ + switch(destination_pixelformat){ + case IPA_DPF_ARGB8888: + IPA_DPV &= ~(IPA_DPV_DPDBV_0|(IPA_DPV_DPDGV_0)|(IPA_DPV_DPDRV_0)|(IPA_DPV_DPDAV_0)); + IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<8U) + |(destination_struct->destination_prered<<16U) + |(destination_struct->destination_prealpha<<24U)); + break; + /* destination pixel format RGB888 */ + case IPA_DPF_RGB888: + IPA_DPV &= ~(IPA_DPV_DPDBV_1|(IPA_DPV_DPDGV_1)|(IPA_DPV_DPDRV_1)); + IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<8U) + |(destination_struct->destination_prered<<16U)); + break; + /* destination pixel format RGB565 */ + case IPA_DPF_RGB565: + IPA_DPV &= ~(IPA_DPV_DPDBV_2|(IPA_DPV_DPDGV_2)|(IPA_DPV_DPDRV_2)); + IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<5U) + |(destination_struct->destination_prered<<11U)); + break; + /* destination pixel format ARGB1555 */ + case IPA_DPF_ARGB1555: + IPA_DPV &= ~(IPA_DPV_DPDBV_3|(IPA_DPV_DPDGV_3)|(IPA_DPV_DPDRV_3)|(IPA_DPV_DPDAV_3)); + IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<5U) + |(destination_struct->destination_prered<<10U) + |(destination_struct->destination_prealpha<<15U)); + break; + /* destination pixel format ARGB4444 */ + case IPA_DPF_ARGB4444: + IPA_DPV &= ~(IPA_DPV_DPDBV_4|(IPA_DPV_DPDGV_4)|(IPA_DPV_DPDRV_4)|(IPA_DPV_DPDAV_4)); + IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<5U) + |(destination_struct->destination_prered<<10U) + |(destination_struct->destination_prealpha<<15U)); + break; + default: + break; + } + /* destination memory base address configuration */ + IPA_DMADDR &= ~(IPA_DMADDR_DMADDR); + IPA_DMADDR =destination_struct->destination_memaddr; + /* destination line offset configuration */ + IPA_DLOFF &= ~(IPA_DLOFF_DLOFF); + IPA_DLOFF =destination_struct->destination_lineoff; + /* image size configuration */ + IPA_IMS &= ~(IPA_IMS_HEIGHT|IPA_IMS_WIDTH); + IPA_IMS |= ((destination_struct->image_width<<16)|(destination_struct->image_height)); +} + +/*! + \brief initialize IPA foreground LUT parameters + \param[in] fg_lut_num: foreground LUT number of pixel. + \param[in] fg_lut_pf: foreground LUT pixel format,IPA_LUT_PF_ARGB8888,IPA_LUT_PF_RGB888. + \param[in] fg_lut_addr: foreground LUT memory base address. + \param[out] none + \retval none +*/ +void ipa_foreground_lut_init(uint32_t fg_lut_num,uint8_t fg_lut_pf, uint32_t fg_lut_addr) +{ + /* foreground LUT number of pixel configuration */ + IPA_FPCTL |= (fg_lut_num<<8U); + /* foreground LUT pixel format configuration */ + if(IPA_LUT_PF_RGB888 == fg_lut_pf){ + IPA_FPCTL |= IPA_FPCTL_FLPF; + }else{ + IPA_FPCTL &= ~(IPA_FPCTL_FLPF); + } + /* foreground LUT memory base address configuration */ + IPA_FLMADDR &= ~(IPA_FLMADDR_FLMADDR); + IPA_FLMADDR = fg_lut_addr; +} + +/*! + \brief initialize IPA background LUT parameters + \param[in] bg_lut_num: background LUT number of pixel. + \param[in] bg_lut_pf: background LUT pixel format, IPA_LUT_PF_ARGB8888,IPA_LUT_PF_RGB888. + \param[in] bg_lut_addr: background LUT memory base address. + \param[out] none + \retval none +*/ +void ipa_background_lut_init(uint32_t bg_lut_num,uint8_t bg_lut_pf, uint32_t bg_lut_addr) +{ + /* background LUT number of pixel configuration */ + IPA_BPCTL|=(bg_lut_num<<8U); + /* background LUT pixel format configuration */ + if(IPA_LUT_PF_RGB888 == bg_lut_pf){ + IPA_BPCTL |= IPA_BPCTL_BLPF; + }else{ + IPA_BPCTL &= ~(IPA_BPCTL_BLPF); + } + /* background LUT memory base address configuration */ + IPA_BLMADDR &= ~(IPA_BLMADDR_BLMADDR); + IPA_BLMADDR = bg_lut_addr; +} + +/*! + \brief configure line mark + \param[in] linenum: line number. + \param[out] none + \retval none +*/ +void ipa_line_mark_config(uint32_t linenum) +{ + IPA_LM &= ~(IPA_LM_LM); + IPA_LM = linenum; +} + +/*! + \brief Inter-timer enable or disable + \param[in] timercfg: IPA_INTER_TIMER_ENABLE,IPA_INTER_TIMER_DISABLE + \param[out] none + \retval none +*/ +void ipa_inter_timer_config(uint8_t timercfg) +{ + if(IPA_INTER_TIMER_ENABLE == timercfg){ + IPA_ITCTL |= IPA_ITCTL_ITEN; + }else{ + IPA_ITCTL &= ~(IPA_ITCTL_ITEN); + } +} + +/*! + \brief number of clock cycles interval set + \param[in] clk_num: the number of clock cycles. + \param[out] none + \retval none +*/ +void ipa_interval_clock_num_config(uint32_t clk_num ) +{ + IPA_ITCTL &= ~(IPA_ITCTL_NCCI); + IPA_ITCTL |= (clk_num<<8U); +} + +/*! + \brief IPA interrupt enable + \param[in] inttype: IPA interrupt bits. + \arg IPA_CTL_TAEIE: transfer access error interrupt + \arg IPA_CTL_FTFIE: full transfer finish interrupt + \arg IPA_CTL_TLMIE: transfer line mark interrupt + \arg IPA_CTL_LACIE: LUT access conflict interrupt + \arg IPA_CTL_LLFIE: LUT loading finish interrupt + \arg IPA_CTL_WCFIE: wrong configuration interrupt + \param[out] none + \retval none +*/ +void ipa_interrupt_enable(uint32_t inttype) +{ + IPA_CTL |= (inttype); +} + +/*! + \brief IPA interrupt disable + \param[in] inttype: IPA interrupt bits. + \arg IPA_CTL_TAEIE: transfer access error interrupt + \arg IPA_CTL_FTFIE: full transfer finish interrupt + \arg IPA_CTL_TLMIE: transfer line mark interrupt + \arg IPA_CTL_LACIE: LUT access conflict interrupt + \arg IPA_CTL_LLFIE: LUT loading finish interrupt + \arg IPA_CTL_WCFIE: wrong configuration interrupt + \param[out] none + \retval none +*/ +void ipa_interrupt_disable(uint32_t inttype) +{ + IPA_CTL &= ~(inttype); +} + +/*! + \brief get IPA interrupt flag + \param[in] intflag: tli interrupt flag bits. + \arg IPA_INTF_TAEIF: transfer access error interrupt flag + \arg IPA_INTF_FTFIF: full transfer finish interrupt flag + \arg IPA_INTF_TLMIF: transfer line mark interrupt flag + \arg IPA_INTF_LACIF: LUT access conflict interrupt flag + \arg IPA_INTF_LLFIF: LUT loading finish interrupt flag + \arg IPA_INTF_WCFIF: wrong configuration interrupt flag + \param[out] none + \retval none +*/ +FlagStatus ipa_interrupt_flag_get(uint32_t intflag) +{ + uint32_t state; + state = IPA_INTF; + if(state & intflag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear IPA interrupt flag + \param[in] intflag: tli interrupt flag bits. + \arg IPA_INTC_TAEIFC: transfer access error interrupt flag + \arg IPA_INTC_FTFIFC: full transfer finish interrupt flag + \arg IPA_INTC_TLMIFC: transfer line mark interrupt flag + \arg IPA_INTC_LACIFC: LUT access conflict interrupt flag + \arg IPA_INTC_LLFIFC: LUT loading finish interrupt flag + \arg IPA_INTC_WCFIFC: wrong configuration interrupt flag + \param[out] none + \retval none +*/ +void ipa_interrupt_flag_clear(uint32_t intflag) +{ + IPA_INTC |= (intflag); +} + diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c new file mode 100644 index 0000000000..237fc2ee75 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c @@ -0,0 +1,101 @@ +/*! + \file gd32f4xx_iref.c + \brief IREF driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_iref.h" + +/*! + \brief deinit IREF + \param[in] none + \param[out] none + \retval none +*/ +void iref_deinit(void) +{ + rcu_periph_reset_enable(RCU_IREFRST); + rcu_periph_reset_disable(RCU_IREFRST); +} + +/*! + \brief enable IREF + \param[in] none + \param[out] none + \retval none +*/ +void iref_enable(void) +{ + IREF_CTL |= IREF_CTL_CREN; +} + +/*! + \brief disable IREF + \param[in] none + \param[out] none + \retval none +*/ +void iref_disable(void) +{ + IREF_CTL &= ~IREF_CTL_CREN; +} + +/*! + \brief set IREF mode + \param[in] step + \arg IREF_MODE_LOW_POWER: 1uA step + \arg IREF_MODE_HIGH_CURRENT: 8uA step + \param[out] none + \retval none +*/ +void iref_mode_set(uint32_t step) +{ + IREF_CTL &= ~IREF_CTL_SSEL; + IREF_CTL |= step; +} + +/*! + \brief set IREF precision_trim_value + \param[in] precisiontrim + \arg IREF_CUR_PRECISION_TRIM_X(x=0..31): (-15+ x)% + \param[out] none + \retval none +*/ +void iref_precision_trim_value_set(uint32_t precisiontrim) +{ + IREF_CTL &= ~IREF_CTL_CPT; + IREF_CTL |= precisiontrim; +} + +/*! + \brief set IREF sink mode + \param[in] sinkmode + \arg IREF_SOURCE_CURRENT : source current. + \arg IREF_SINK_CURRENT: sink current + \param[out] none + \retval none +*/ +void iref_sink_set(uint32_t sinkmode) +{ + IREF_CTL &= ~IREF_CTL_SCMOD; + IREF_CTL |= sinkmode; +} + +/*! + \brief set IREF step data + \param[in] stepdata + \arg IREF_CUR_STEP_DATA_X:(x=0..63): step*x + \param[out] none + \retval none +*/ + +void iref_step_data_config(uint32_t stepdata) +{ + IREF_CTL &= ~IREF_CTL_CSDT; + IREF_CTL |= stepdata; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c new file mode 100644 index 0000000000..1649929a4b --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c @@ -0,0 +1,146 @@ +/*! + \file gd32f4xx_misc.c + \brief MISC driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_misc.h" + +/*! + \brief set the priority group + \param[in] nvic_prigroup: the NVIC priority group + \arg NVIC_PRIGROUP_PRE0_SUB4:0 bits for pre-emption priority 4 bits for subpriority + \arg NVIC_PRIGROUP_PRE1_SUB3:1 bits for pre-emption priority 3 bits for subpriority + \arg NVIC_PRIGROUP_PRE2_SUB2:2 bits for pre-emption priority 2 bits for subpriority + \arg NVIC_PRIGROUP_PRE3_SUB1:3 bits for pre-emption priority 1 bits for subpriority + \arg NVIC_PRIGROUP_PRE4_SUB0:4 bits for pre-emption priority 0 bits for subpriority + \param[out] none + \retval none +*/ +void nvic_priority_group_set(uint32_t nvic_prigroup) +{ + /* set the priority group value */ + SCB->AIRCR = NVIC_AIRCR_VECTKEY_MASK | nvic_prigroup; +} + +/*! + \brief enable NVIC request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[in] nvic_irq_pre_priority: the pre-emption priority needed to set + \param[in] nvic_irq_sub_priority: the subpriority needed to set + \param[out] none + \retval none +*/ +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, + uint8_t nvic_irq_sub_priority) +{ + uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U; + /* use the priority group value to get the temp_pre and the temp_sub */ + if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE0_SUB4){ + temp_pre=0U; + temp_sub=0x4U; + }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE1_SUB3){ + temp_pre=1U; + temp_sub=0x3U; + }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE2_SUB2){ + temp_pre=2U; + temp_sub=0x2U; + }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE3_SUB1){ + temp_pre=3U; + temp_sub=0x1U; + }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE4_SUB0){ + temp_pre=4U; + temp_sub=0x0U; + }else{ + } + /* get the temp_priority to fill the NVIC->IP register */ + temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre); + temp_priority |= nvic_irq_sub_priority &(0x0FU >> (0x4U - temp_sub)); + temp_priority = temp_priority << 0x04U; + NVIC->IP[nvic_irq] = (uint8_t)temp_priority; + /* enable the selected IRQ */ + NVIC->ISER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU); +} + +/*! + \brief disable NVIC request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[out] none + \retval none +*/ +void nvic_irq_disable(uint8_t nvic_irq) +{ + /* disable the selected IRQ.*/ + NVIC->ICER[nvic_irq >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F); +} + +/*! + \brief set the NVIC vector table base address + \param[in] nvic_vict_tab: the RAM or FLASH base address + \arg NVIC_VECTTAB_RAM: RAM base address + \are NVIC_VECTTAB_FLASH: Flash base address + \param[in] offset: Vector Table offset + \param[out] none + \retval none +*/ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset) +{ + SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK); +} + +/*! + \brief set the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up + by all the enable and disable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_set(uint8_t lowpower_mode) +{ + SCB->SCR |= (uint32_t)lowpower_mode; +} + +/*! + \brief reset the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be + woke up by the enable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_reset(uint8_t lowpower_mode) +{ + SCB->SCR &= (~(uint32_t)lowpower_mode); +} + +/*! + \brief set the systick clock source + \param[in] systick_clksource: the systick clock source needed to choose + \arg SYSTICK_CLKSOURCE_HCLK: systick clock source is from HCLK + \arg SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8 + \param[out] none + \retval none +*/ + +void systick_clksource_set(uint32_t systick_clksource) +{ + if(SYSTICK_CLKSOURCE_HCLK == systick_clksource ){ + /* set the systick clock source from HCLK */ + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + }else{ + /* set the systick clock source from HCLK/8 */ + SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8; + } +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c new file mode 100644 index 0000000000..267e4c32fd --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c @@ -0,0 +1,348 @@ +/*! + \file gd32f4xx_pmu.c + \brief PMU driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_pmu.h" +#include "core_cm4.h" +/*! + \brief reset PMU register + \param[in] none + \param[out] none + \retval none +*/ +void pmu_deinit(void) +{ + /* reset PMU */ + rcu_periph_reset_enable(RCU_PMURST); + rcu_periph_reset_disable(RCU_PMURST); +} + +/*! + \brief select low voltage detector threshold + \param[in] pmu_lvdt_n: + \arg PMU_LVDT_0: voltage threshold is 2.2V + \arg PMU_LVDT_1: voltage threshold is 2.3V + \arg PMU_LVDT_2: voltage threshold is 2.4V + \arg PMU_LVDT_3: voltage threshold is 2.5V + \arg PMU_LVDT_4: voltage threshold is 2.6V + \arg PMU_LVDT_5: voltage threshold is 2.7V + \arg PMU_LVDT_6: voltage threshold is 2.8V + \arg PMU_LVDT_7: voltage threshold is 2.9V + \param[out] none + \retval none +*/ +void pmu_lvd_select(uint32_t pmu_lvdt_n) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; + /* clear LVDT bits */ + PMU_CTL &= ~PMU_CTL_LVDT; + /* set LVDT bits according to pmu_lvdt_n */ + PMU_CTL |= pmu_lvdt_n; + /* enable LVD */ + PMU_CTL |= PMU_CTL_LVDEN; +} + +/*! + \brief LDO output voltage select + this bit set by software when the main PLL closed, before closing PLL, change the system clock to IRC16M or HXTAL + \param[in] ldo_output: + \arg PMU_LDOVS_LOW: low-driver mode enable in deep-sleep mode + \arg PMU_LDOVS_MID: low-driver mode disable in deep-sleep mode + \arg PMU_LDOVS_HIGH: low-driver mode disable in deep-sleep mode + \param[out] none + \retval none +*/ +void pmu_ldo_output_select(uint32_t ldo_output) +{ + PMU_CTL &= ~PMU_CTL_LDOVS; + PMU_CTL |= ldo_output; +} + +/*! + \brief low-driver mode enable in deep-sleep mode + \param[in] lowdr_mode: + \arg PMU_LOWDRIVER_ENABLE: low-driver mode enable in deep-sleep mode + \arg PMU_LOWDRIVER_DISABLE: low-driver mode disable in deep-sleep mode + \param[out] none + \retval none +*/ +void pmu_low_driver_mode_enable(uint32_t lowdr_mode) +{ + PMU_CTL &= ~PMU_CTL_LDEN; + PMU_CTL |= lowdr_mode; +} + +/*! + \brief high-driver mode switch + this bit set by software only when IRC16M or HXTAL used as system clock + \param[in] highdr_switch: + \arg PMU_HIGHDR_SWITCH_NONE: no high-driver mode switch + \arg PMU_HIGHDR_SWITCH_EN: high-driver mode switch + \param[out] none + \retval none +*/ +void pmu_highdriver_switch_select(uint32_t highdr_switch) +{ + /* wait for HDRF flag set */ + while(SET != pmu_flag_get(PMU_FLAG_HDRF)){ + } + PMU_CTL &= ~PMU_CTL_HDS; + PMU_CTL |= highdr_switch; +} + +/*! + \brief enable high-driver mode + this bit set by software only when IRC16M or HXTAL used as system clock + \param[in] none + \param[out] none + \retval none +*/ +void pmu_highdriver_mode_enable(void) +{ + PMU_CTL |= PMU_CTL_HDEN; +} + +/*! + \brief disable high-driver mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_highdriver_mode_disable(void) +{ + PMU_CTL &= ~PMU_CTL_HDEN; +} + +/*! + \brief disable PMU lvd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; +} + +/*! + \brief low-driver mode when use low power LDO + \param[in] mode: + \arg PMU_NORMALDR_LOWPWR: normal driver when use low power LDO + \arg PMU_LOWDR_LOWPWR: low-driver mode enabled when LDEN is 11 and use low power LDO + \param[out] none + \retval none +*/ +void pmu_lowdriver_lowpower_config(uint32_t mode) +{ + PMU_CTL &= ~PMU_CTL_LDLP; + PMU_CTL |= mode; +} + +/*! + \brief low-driver mode when use normal power LDO + \param[in] mode: + \arg PMU_NORMALDR_NORMALPWR: normal driver when use low power LDO + \arg PMU_LOWDR_NORMALPWR: low-driver mode enabled when LDEN is 11 and use low power LDO + \param[out] none + \retval none +*/ +void pmu_lowdriver_normalpower_config(uint32_t mode) +{ + PMU_CTL &= ~PMU_CTL_LDNP; + PMU_CTL |= mode; +} + +/*! + \brief PMU work at sleep mode + \param[in] sleepmodecmd: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_sleepmode(uint8_t sleepmodecmd) +{ + /* clear sleepdeep bit of Cortex-M4 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + + /* select WFI or WFE command to enter sleep mode */ + if(WFI_CMD == sleepmodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \brief PMU work at deepsleep mode + \param[in] pmu_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 pmu_ldo,uint8_t deepsleepmodecmd) +{ + /* clear stbmod and ldolp bits */ + PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP)); + + /* set ldolp bit according to pmu_ldo */ + PMU_CTL |= pmu_ldo; + + /* set sleepdeep bit of Cortex-M4 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* select WFI or WFE command to enter deepsleep mode */ + if(WFI_CMD == deepsleepmodecmd){ + __WFI(); + }else{ + __SEV(); + __WFE(); + __WFE(); + } + /* reset sleepdeep bit of Cortex-M4 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); +} + +/*! + \brief pmu work at standby mode + \param[in] standbymodecmd: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_standbymode(uint8_t standbymodecmd) +{ + /* set sleepdeep bit of Cortex-M4 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* set stbmod bit */ + PMU_CTL |= PMU_CTL_STBMOD; + + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + + /* select WFI or WFE command to enter standby mode */ + if(WFI_CMD == standbymodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \brief backup SRAM LDO on + \param[in] bkp_ldo: + \arg PMU_BLDOON_OFF: backup SRAM LDO closed + \arg PMU_BLDOON_ON: open the backup SRAM LDO + \param[out] none + \retval none +*/ +void pmu_backup_ldo_config(uint32_t bkp_ldo) +{ + PMU_CS &= ~PMU_CS_BLDOON; + PMU_CS |= bkp_ldo; +} + +/*! + \brief reset flag bit + \param[in] flag_reset: + \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag + \arg PMU_FLAG_RESET_STANDBY: reset standby flag + \param[out] none + \retval none +*/ +void pmu_flag_reset(uint32_t flag_reset) +{ + switch(flag_reset){ + case PMU_FLAG_RESET_WAKEUP: + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + break; + case PMU_FLAG_RESET_STANDBY: + /* reset standby flag */ + PMU_CTL |= PMU_CTL_STBRST; + break; + default : + break; + } +} + +/*! + \brief get flag status + \param[in] pmu_flag: + \arg PMU_FLAG_WAKEUP: wakeup flag status + \arg PMU_FLAG_STANDBY: standby flag status + \arg PMU_FLAG_LVD: lvd flag status + \arg PMU_FLAG_BLDORF: backup SRAM LDO ready flag + \arg PMU_FLAG_LDOVSRF: LDO voltage select ready flag + \arg PMU_FLAG_HDRF: high-driver ready flag + \arg PMU_FLAG_HDSRF: high-driver switch ready flag + \arg PMU_FLAG_LDRF: low-driver mode ready flag + \param[out] none + \retval FlagStatus SET or RESET +*/ +FlagStatus pmu_flag_get(uint32_t pmu_flag ) +{ + if(PMU_CS & pmu_flag){ + return SET; + } + return RESET; +} + +/*! + \brief enable backup domain write + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL |= PMU_CTL_BKPWEN; +} + +/*! + \brief disable backup domain write + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL &= ~PMU_CTL_BKPWEN; +} + +/*! + \brief enable wakeup pin + \param[in] none + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(void) +{ + PMU_CS |= PMU_CS_WUPEN; +} + +/*! + \brief disable wakeup pin + \param[in] none + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(void) +{ + PMU_CS &= ~PMU_CS_WUPEN; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c new file mode 100644 index 0000000000..e37b9f9808 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c @@ -0,0 +1,1281 @@ +/*! + \file gd32f4xx_rcu.c + \brief RCU driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.1, firmware for GD32F4xx +*/ + +#include "gd32f4xx_rcu.h" + +#define SEL_IRC16M 0U +#define SEL_HXTAL 1U +#define SEL_PLLP 2U +#define OSC_STARTUP_TIMEOUT ((uint16_t)0xfffffU) +#define LXTAL_STARTUP_TIMEOUT ((uint16_t)0x3ffffffU) + +/*! + \brief deinitialize the RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_deinit(void) +{ + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + rcu_osci_stab_wait(RCU_IRC16M); + /* reset CFG0 register */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | + RCU_CFG0_RTCDIV | RCU_CFG0_CKOUT0SEL | RCU_CFG0_I2SSEL | RCU_CFG0_CKOUT0DIV | + RCU_CFG0_CKOUT1DIV | RCU_CFG0_CKOUT1SEL); + /* reset CTL register */ + RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN | RCU_CTL_PLLI2SEN | + RCU_CTL_PLLSAIEN | RCU_CTL_HXTALBPS); + /* reset PLL register */ + RCU_PLL = 0x24003010U; + /* reset PLLI2S register */ + RCU_PLLI2S = 0x24003000U; + /* reset PLLSAI register */ + RCU_PLLSAI = 0x24003010U; + /* reset INT register */ + RCU_INT = 0x00000000U; + /* reset CFG1 register */ + RCU_CFG1 &= ~(RCU_CFG1_PLLSAIRDIV | RCU_CFG1_TIMERSEL); +} + +/*! + \brief enable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOx (x=A,B,C,D,E,F,G,H,I): GPIO ports clock + \arg RCU_CRC: CRC clock + \arg RCU_BKPSRAM: BKPSRAM clock + \arg RCU_TCMSRAM: TCMSRAM clock + \arg RCU_DMAx (x=0,1): DMA clock + \arg RCU_IPA: IPA clock + \arg RCU_ENET: ENET clock + \arg RCU_ENETTX: ENETTX clock + \arg RCU_ENETRX: ENETRX clock + \arg RCU_ENETPTP: ENETPTP clock + \arg RCU_USBHS: USBHS clock + \arg RCU_USBHSULPI: USBHSULPI clock + \arg RCU_DCI: DCI clock + \arg RCU_TRNG: TRNG clock + \arg RCU_USBFS: USBFS clock + \arg RCU_EXMC: EXMC clock + \arg RCU_TIMERx (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_SPIx (x=0,1,2,3,4,5): SPI clock + \arg RCU_USARTx (x=0,1,2,5): USART clock + \arg RCU_UARTx (x=3,4,6,7): UART clock + \arg RCU_I2Cx (x=0,1,2): I2C clock + \arg RCU_CANx (x=0,1): CAN clock + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC clock + \arg RCU_RTC: RTC clock + \arg RCU_ADCx (x=0,1,2): ADC clock + \arg RCU_SDIO: SDIO clock + \arg RCU_SYSCFG: SYSCFG clock + \arg RCU_TLI: TLI clock + \arg RCU_CTC: CTC clock + \arg RCU_IREF: IREF clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_enable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief disable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOx (x=A,B,C,D,E,F,G,H,I): GPIO ports clock + \arg RCU_CRC: CRC clock + \arg RCU_BKPSRAM: BKPSRAM clock + \arg RCU_TCMSRAM: TCMSRAM clock + \arg RCU_DMAx (x=0,1): DMA clock + \arg RCU_IPA: IPA clock + \arg RCU_ENET: ENET clock + \arg RCU_ENETTX: ENETTX clock + \arg RCU_ENETRX: ENETRX clock + \arg RCU_ENETPTP: ENETPTP clock + \arg RCU_USBHS: USBHS clock + \arg RCU_USBHSULPI: USBHSULPI clock + \arg RCU_DCI: DCI clock + \arg RCU_TRNG: TRNG clock + \arg RCU_USBFS: USBFS clock + \arg RCU_EXMC: EXMC clock + \arg RCU_TIMERx (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_SPIx (x=0,1,2,3,4,5): SPI clock + \arg RCU_USARTx (x=0,1,2,5): USART clock + \arg RCU_UARTx (x=3,4,6,7): UART clock + \arg RCU_I2Cx (x=0,1,2): I2C clock + \arg RCU_CANx (x=0,1): CAN clock + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC clock + \arg RCU_RTC: RTC clock + \arg RCU_ADCx (x=0,1,2): ADC clock + \arg RCU_SDIO: SDIO clock + \arg RCU_SYSCFG: SYSCFG clock + \arg RCU_TLI: TLI clock + \arg RCU_CTC: CTC clock + \arg RCU_IREF: IREF clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_disable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief enable the peripherals clock when sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOx_SLP (x=A,B,C,D,E,F,G,H,I): GPIO ports clock + \arg RCU_CRC_SLP: CRC clock + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM0_SLP: SRAM0 clock + \arg RCU_SRAM1_SLP: SRAM1 clock + \arg RCU_BKPSRAM: BKPSRAM clock + \arg RCU_SRAM2_SLP: SRAM2 clock + \arg RCU_DMAx_SLP (x=0,1): DMA clock + \arg RCU_IPA_SLP: IPA clock + \arg RCU_ENET_SLP: ENET clock + \arg RCU_ENETTX_SLP: ENETTX clock + \arg RCU_ENETRX_SLP: ENETRX clock + \arg RCU_ENETPTP_SLP: ENETPTP clock + \arg RCU_USBHS_SLP: USBHS clock + \arg RCU_USBHSULPI_SLP: USBHSULPI clock + \arg RCU_DCI_SLP: DCI clock + \arg RCU_TRNG_SLP: TRNG clock + \arg RCU_USBFS_SLP: USBFS clock + \arg RCU_EXMC_SLP: EXMC clock + \arg RCU_TIMERx_SLP (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock + \arg RCU_WWDGT_SLP: WWDGT clock + \arg RCU_SPIx_SLP (x=0,1,2,3,4,5): SPI clock + \arg RCU_USARTx_SLP (x=0,1,2,5): USART clock + \arg RCU_UARTx_SLP (x=3,4,6,7): UART clock + \arg RCU_I2Cx_SLP (x=0,1,2): I2C clock + \arg RCU_CANx_SLP (x=0,1): CAN clock + \arg RCU_PMU_SLP: PMU clock + \arg RCU_DAC_SLP: DAC clock + \arg RCU_RTC_SLP: RTC clock + \arg RCU_ADCx_SLP (x=0,1,2): ADC clock + \arg RCU_SDIO_SLP: SDIO clock + \arg RCU_SYSCFG_SLP: SYSCFG clock + \arg RCU_TLI_SLP: TLI clock + \arg RCU_CTC_SLP: CTC clock + \arg RCU_IREF_SLP: IREF clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph) +{ + RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief disable the peripherals clock when sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOx_SLP (x=A,B,C,D,E,F,G,H,I): GPIO ports clock + \arg RCU_CRC_SLP: CRC clock + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM0_SLP: SRAM0 clock + \arg RCU_SRAM1_SLP: SRAM1 clock + \arg RCU_BKPSRAM: BKPSRAM clock + \arg RCU_SRAM2_SLP: SRAM2 clock + \arg RCU_DMAx_SLP (x=0,1): DMA clock + \arg RCU_IPA_SLP: IPA clock + \arg RCU_ENET_SLP: ENET clock + \arg RCU_ENETTX_SLP: ENETTX clock + \arg RCU_ENETRX_SLP: ENETRX clock + \arg RCU_ENETPTP_SLP: ENETPTP clock + \arg RCU_USBHS_SLP: USBHS clock + \arg RCU_USBHSULPI_SLP: USBHSULPI clock + \arg RCU_DCI_SLP: DCI clock + \arg RCU_TRNG_SLP: TRNG clock + \arg RCU_USBFS_SLP: USBFS clock + \arg RCU_EXMC_SLP: EXMC clock + \arg RCU_TIMERx_SLP (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock + \arg RCU_WWDGT_SLP: WWDGT clock + \arg RCU_SPIx_SLP (x=0,1,2,3,4,5): SPI clock + \arg RCU_USARTx_SLP (x=0,1,2,5): USART clock + \arg RCU_UARTx_SLP (x=3,4,6,7): UART clock + \arg RCU_I2Cx_SLP (x=0,1,2): I2C clock + \arg RCU_CANx_SLP (x=0,1): CAN clock + \arg RCU_PMU_SLP: PMU clock + \arg RCU_DAC_SLP: DAC clock + \arg RCU_RTC_SLP: RTC clock + \arg RCU_ADCx_SLP (x=0,1,2): ADC clock + \arg RCU_SDIO_SLP: SDIO clock + \arg RCU_SYSCFG_SLP: SYSCFG clock + \arg RCU_TLI_SLP: TLI clock + \arg RCU_CTC_SLP: CTC clock + \arg RCU_IREF_SLP: IREF clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief reset the peripherals + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOxRST (x=A,B,C,D,E,F,G,H,I): reset GPIO ports + \arg RCU_CRCRST: reset CRC + \arg RCU_DMAxRST (x=0,1): reset DMA + \arg RCU_IPAENRST: reset IPA + \arg RCU_ENETRST: reset ENET + \arg RCU_USBHSRST: reset USBHS + \arg RCU_DCIRST: reset DCI + \arg RCU_TRNGRST: reset TRNG + \arg RCU_USBFSRST: reset USBFS + \arg RCU_EXMCRST: reset EXMC + \arg RCU_TIMERxRST (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): reset TIMER + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_SPIxRST (x=0,1,2,3,4,5): reset SPI + \arg RCU_USARTxRST (x=0,1,2,5): reset USART + \arg RCU_UARTxRST (x=3,4,6,7): reset UART + \arg RCU_I2CxRST (x=0,1,2): reset I2C + \arg RCU_CANxRST (x=0,1): reset CAN + \arg RCU_PMURST: reset PMU + \arg RCU_DACRST: reset DAC + \arg RCU_ADCRST (x=0,1,2): reset ADC + \arg RCU_SDIORST: reset SDIO + \arg RCU_SYSCFGRST: reset SYSCFG + \arg RCU_TLIRST: reset TLI + \arg RCU_CTCRST: reset CTC + \arg RCU_IREFRST: reset IREF + \param[out] none + \retval none +*/ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) |= BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief disable reset the peripheral + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOxRST (x=A,B,C,D,E,F,G,H,I): reset GPIO ports + \arg RCU_CRCRST: reset CRC + \arg RCU_DMAxRST (x=0,1): reset DMA + \arg RCU_IPAENRST: reset IPA + \arg RCU_ENETRST: reset ENET + \arg RCU_USBHSRST: reset USBHS + \arg RCU_DCIRST: reset DCI + \arg RCU_TRNGRST: reset TRNG + \arg RCU_USBFSRST: reset USBFS + \arg RCU_EXMCRST: reset EXMC + \arg RCU_TIMERxRST (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): reset TIMER + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_SPIxRST (x=0,1,2,3,4,5): reset SPI + \arg RCU_USARTxRST (x=0,1,2,5): reset USART + \arg RCU_UARTxRST (x=3,4,6,7): reset UART + \arg RCU_I2CxRST (x=0,1,2): reset I2C + \arg RCU_CANxRST (x=0,1): reset CAN + \arg RCU_PMURST: reset PMU + \arg RCU_DACRST: reset DAC + \arg RCU_ADCRST (x=0,1,2): reset ADC + \arg RCU_SDIORST: reset SDIO + \arg RCU_SYSCFGRST: reset SYSCFG + \arg RCU_TLIRST: reset TLI + \arg RCU_CTCRST: reset CTC + \arg RCU_IREFRST: reset IREF + \param[out] none + \retval none +*/ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) &= ~BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief reset the BKP + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_enable(void) +{ + RCU_BDCTL |= RCU_BDCTL_BKPRST; +} + +/*! + \brief disable the BKP reset + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_disable(void) +{ + RCU_BDCTL &= ~RCU_BDCTL_BKPRST; +} + +/*! + \brief configure the system clock source + \param[in] ck_sys: system clock source select + only one parameter can be selected which is shown as below: + \arg RCU_CKSYSSRC_IRC16M: select CK_IRC16M as the CK_SYS source + \arg RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_CKSYSSRC_PLLP: select CK_PLLP as the CK_SYS source + \param[out] none + \retval none +*/ +void rcu_system_clock_source_config(uint32_t ck_sys) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the SCS bits and set according to ck_sys */ + reg &= ~RCU_CFG0_SCS; + RCU_CFG0 = (reg | ck_sys); +} + +/*! + \brief get the system clock source + \param[in] none + \param[out] none + \retval which clock is selected as CK_SYS source + \arg RCU_SCSS_IRC16M: CK_IRC16M is selected as the CK_SYS source + \arg RCU_SCSS_HXTAL: CK_HXTAL is selected as the CK_SYS source + \arg RCU_SCSS_PLLP: CK_PLLP is selected as the CK_SYS source +*/ +uint32_t rcu_system_clock_source_get(void) +{ + return (RCU_CFG0 & RCU_CFG0_SCSS); +} + +/*! + \brief configure the AHB clock prescaler selection + \param[in] ck_ahb: AHB clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_AHB_CKSYS_DIVx, x=1, 2, 4, 8, 16, 64, 128, 256, 512 + \param[out] none + \retval none +*/ +void rcu_ahb_clock_config(uint32_t ck_ahb) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the AHBPS bits and set according to ck_ahb */ + reg &= ~RCU_CFG0_AHBPSC; + RCU_CFG0 = (reg | ck_ahb); +} + +/*! + \brief configure the APB1 clock prescaler selection + \param[in] ck_apb1: APB1 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB1_CKAHB_DIV1: select CK_AHB as CK_APB1 + \arg RCU_APB1_CKAHB_DIV2: select CK_AHB/2 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV4: select CK_AHB/4 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV8: select CK_AHB/8 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV16: select CK_AHB/16 as CK_APB1 + \param[out] none + \retval none +*/ +void rcu_apb1_clock_config(uint32_t ck_apb1) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the APB1PS and set according to ck_apb1 */ + reg &= ~RCU_CFG0_APB1PSC; + RCU_CFG0 = (reg | ck_apb1); +} + +/*! + \brief configure the APB2 clock prescaler selection + \param[in] ck_apb2: APB2 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB2_CKAHB_DIV1: select CK_AHB as CK_APB2 + \arg RCU_APB2_CKAHB_DIV2: select CK_AHB/2 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV4: select CK_AHB/4 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV8: select CK_AHB/8 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV16: select CK_AHB/16 as CK_APB2 + \param[out] none + \retval none +*/ +void rcu_apb2_clock_config(uint32_t ck_apb2) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the APB2PS and set according to ck_apb2 */ + reg &= ~RCU_CFG0_APB2PSC; + RCU_CFG0 = (reg | ck_apb2); +} + +/*! + \brief configure the CK_OUT0 clock source and divider + \param[in] ckout0_src: CK_OUT0 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CKOUT0SRC_IRC16M: IRC16M selected + \arg RCU_CKOUT0SRC_LXTAL: LXTAL selected + \arg RCU_CKOUT0SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT0SRC_PLLP: PLLP selected + \param[in] ckout0_div: CK_OUT0 divider + \arg RCU_CKOUT0_DIVx(x=1,2,3,4,5): CK_OUT0 is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the CKOUT0SRC, CKOUT0DIV and set according to ckout0_src and ckout0_div */ + reg &= ~(RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV ); + RCU_CFG0 = (reg | ckout0_src | ckout0_div); +} + +/*! + \brief configure the CK_OUT1 clock source and divider + \param[in] ckout1_src: CK_OUT1 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CKOUT1SRC_SYSTEMCLOCK: system clock selected + \arg RCU_CKOUT1SRC_PLLI2SR: PLLI2SR selected + \arg RCU_CKOUT1SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT1SRC_PLLP: PLLP selected + \param[in] ckout1_div: CK_OUT1 divider + \arg RCU_CKOUT1_DIVx(x=1,2,3,4,5): CK_OUT1 is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the CKOUT1SRC, CKOUT1DIV and set according to ckout1_src and ckout1_div */ + reg &= ~(RCU_CFG0_CKOUT1SEL | RCU_CFG0_CKOUT1DIV); + RCU_CFG0 = (reg | ckout1_src | ckout1_div); +} + +/*! + \brief configure the main PLL clock + \param[in] pll_src: PLL clock source selection + \arg RCU_PLLSRC_IRC16M: select IRC16M as PLL source clock + \arg RCU_PLLSRC_HXTAL: select HXTAL as PLL source clock + \param[in] pll_psc: the PLL VCO source clock prescaler + \arg this parameter should be selected between 2 and 63 + \param[in] pll_n: the PLL VCO clock multi factor + \arg this parameter should be selected between 64 and 500 + \param[in] pll_p: the PLLP output frequency division factor from PLL VCO clock + \arg this parameter should be selected 2,4,6,8 + \param[in] pll_q: the PLL Q output frequency division factor from PLL VCO clock + \arg this parameter should be selected between 2 and 15 + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_pll_config(uint32_t pll_src, uint32_t pll_psc, uint32_t pll_n, uint32_t pll_p, uint32_t pll_q) +{ + uint32_t ss_modulation_inc; + uint32_t ss_modulation_reg; + + ss_modulation_inc = 0U; + ss_modulation_reg = RCU_PLLSSCTL; + + /* calculate the minimum factor of PLLN */ + if((ss_modulation_reg & RCU_PLLSSCTL_SSCGON) == RCU_PLLSSCTL_SSCGON){ + if((ss_modulation_reg & RCU_SS_TYPE_DOWN) == RCU_SS_TYPE_DOWN){ + ss_modulation_inc += RCU_SS_MODULATION_DOWN_INC; + }else{ + ss_modulation_inc += RCU_SS_MODULATION_CENTER_INC; + } + } + + /* check the function parameter */ + if(CHECK_PLL_PSC_VALID(pll_psc) && CHECK_PLL_N_VALID(pll_n,ss_modulation_inc) && + CHECK_PLL_P_VALID(pll_p) && CHECK_PLL_Q_VALID(pll_q)){ + RCU_PLL = pll_psc | (pll_n << 6) | (((pll_p >> 1) - 1U) << 16) | + (pll_src) | (pll_q << 24); + }else{ + /* return status */ + return ERROR; + } + + /* return status */ + return SUCCESS; +} + +/*! + \brief configure the PLLI2S clock + \param[in] plli2s_n: the PLLI2S VCO clock multi factor + \arg this parameter should be selected between 50 and 500 + \param[in] plli2s_q: the PLLI2S Q output frequency division factor from PLLI2S VCO clock + \arg this parameter should be selected between 2 and 15 + \param[in] plli2s_r: the PLLI2S R output frequency division factor from PLLI2S VCO clock + \arg this parameter should be selected between 2 and 7 + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_plli2s_config(uint32_t plli2s_n, uint32_t plli2s_q, uint32_t plli2s_r) +{ + /* check the function parameter */ + if(CHECK_PLLI2S_N_VALID(plli2s_n) && CHECK_PLLI2S_Q_VALID(plli2s_q) && CHECK_PLLI2S_R_VALID(plli2s_r)){ + RCU_PLLI2S = (plli2s_n << 6) | (plli2s_q << 24) | (plli2s_r << 28); + }else{ + /* return status */ + return ERROR; + } + + /* return status */ + return SUCCESS; +} + +/*! + \brief configure the PLLSAI clock + \param[in] pllsai_n: the PLLSAI VCO clock multi factor + \arg this parameter should be selected between 50 and 500 + \param[in] pllsai_p: the PLLSAI P output frequency division factor from PLL VCO clock + \arg this parameter should be selected 2,4,6,8 + \param[in] pllsai_q: the PLLSAI Q output frequency division factor from PLL VCO clock + \arg this parameter should be selected between 2 and 15 + \param[in] pllsai_r: the PLLSAI R output frequency division factor from PLL VCO clock + \arg this parameter should be selected between 2 and 7 + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_pllsai_config(uint32_t pllsai_n, uint32_t pllsai_p, uint32_t pllsai_q, uint32_t pllsai_r) +{ + /* check the function parameter */ + if(CHECK_PLLSAI_N_VALID(pllsai_n) && CHECK_PLLSAI_P_VALID(pllsai_p) && + CHECK_PLLSAI_Q_VALID(pllsai_q) && CHECK_PLLSAI_R_VALID(pllsai_r)){ + RCU_PLLSAI = (pllsai_n << 6U) | (((pllsai_p >> 1U) - 1U) << 16U) | (pllsai_q << 24U) | (pllsai_r << 28U); + }else{ + /* return status */ + return ERROR; + } + + /* return status */ + return SUCCESS; +} + +/*! + \brief configure the RTC clock source selection + \param[in] rtc_clock_source: RTC clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_RTCSRC_NONE: no clock selected + \arg RCU_RTCSRC_LXTAL: CK_LXTAL selected as RTC source clock + \arg RCU_RTCSRC_IRC32K: CK_IRC32K selected as RTC source clock + \arg RCU_RTCSRC_HXTAL_DIV_RTCDIV: CK_HXTAL/RTCDIV selected as RTC source clock + \param[out] none + \retval none +*/ +void rcu_rtc_clock_config(uint32_t rtc_clock_source) +{ + uint32_t reg; + + reg = RCU_BDCTL; + /* reset the RTCSRC bits and set according to rtc_clock_source */ + reg &= ~RCU_BDCTL_RTCSRC; + RCU_BDCTL = (reg | rtc_clock_source); +} + +/*! + \brief configure the I2S clock source selection + \param[in] i2s_clock_source: I2S clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_I2SSRC_PLLI2S: CK_PLLI2S selected as I2S source clock + \arg RCU_I2SSRC_I2S_CKIN: external i2s_ckin pin selected as I2S source clock + \param[out] none + \retval none +*/ +void rcu_i2s_clock_config(uint32_t i2s_clock_source) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the I2SSEL bit and set according to i2s_clock_source */ + reg &= ~RCU_CFG0_I2SSEL; + RCU_CFG0 = (reg | i2s_clock_source); +} + +/*! + \brief configure the CK48M clock source selection + \param[in] ck48m_clock_source: CK48M clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CK48MSRC_PLL48M: CK_PLL48M selected as CK48M source clock + \arg RCU_CK48MSRC_IRC48M: CK_IRC48M selected as CK48M source clock + \param[out] none + \retval none +*/ +void rcu_ck48m_clock_config(uint32_t ck48m_clock_source) +{ + uint32_t reg; + + reg = RCU_ADDCTL; + /* reset the I2SSEL bit and set according to i2s_clock_source */ + reg &= ~RCU_ADDCTL_CK48MSEL; + RCU_ADDCTL = (reg | ck48m_clock_source); +} + +/*! + \brief configure the PLL48M clock source selection + \param[in] pll48m_clock_source: PLL48M clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_PLL48MSRC_PLLQ: CK_PLLQ selected as PLL48M source clock + \arg RCU_PLL48MSRC_PLLSAIP: CK_PLLSAIP selected as PLL48M source clock + \param[out] none + \retval none +*/ +void rcu_pll48m_clock_config(uint32_t pll48m_clock_source) +{ + uint32_t reg; + + reg = RCU_ADDCTL; + /* reset the PLL48MSEL bit and set according to pll48m_clock_source */ + reg &= ~RCU_ADDCTL_PLL48MSEL; + RCU_ADDCTL = (reg | pll48m_clock_source); +} + +/*! + \brief configure the TIMER clock prescaler selection + \param[in] timer_clock_prescaler: TIMER clock selection + only one parameter can be selected which is shown as below: + \arg RCU_TIMER_PSC_MUL2: if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB) + or 0b100(CK_APBx = CK_AHB/2), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). + or else, the TIMER clock is twice the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 2 x CK_APB1; + TIMER in APB2 domain: CK_TIMERx = 2 x CK_APB2) + \arg RCU_TIMER_PSC_MUL4: if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB), + 0b100(CK_APBx = CK_AHB/2), or 0b101(CK_APBx = CK_AHB/4), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). + or else, the TIMER clock is four timers the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 4 x CK_APB1; + TIMER in APB2 domain: CK_TIMERx = 4 x CK_APB2) + \param[out] none + \retval none +*/ +void rcu_timer_clock_prescaler_config(uint32_t timer_clock_prescaler) +{ + /* configure the TIMERSEL bit and select the TIMER clock prescaler */ + if(timer_clock_prescaler == RCU_TIMER_PSC_MUL2){ + RCU_CFG1 &= timer_clock_prescaler; + }else{ + RCU_CFG1 |= timer_clock_prescaler; + } +} + +/*! + \brief configure the PLLSAIR divider used as input of TLI + \param[in] pllsai_r_div: PLLSAIR divider used as input of TLI + only one parameter can be selected which is shown as below: + \arg RCU_PLLSAIR_DIVx(x=2,4,8,16): PLLSAIR divided x used as input of TLI + \param[out] none + \retval none +*/ +void rcu_tli_clock_div_config(uint32_t pllsai_r_div) +{ + uint32_t reg; + + reg = RCU_CFG1; + /* reset the PLLSAIRDIV bit and set according to pllsai_r_div */ + reg &= ~RCU_CFG1_PLLSAIRDIV; + RCU_CFG1 = (reg | pllsai_r_div); +} + +/*! + \brief get the clock stabilization and periphral reset flags + \param[in] flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_FLAG_IRC16MSTB: IRC16M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_PLLSTB: PLL stabilization flag + \arg RCU_FLAG_PLLI2SSTB: PLLI2S stabilization flag + \arg RCU_FLAG_PLLSAISTB: PLLSAI stabilization flag + \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag + \arg RCU_FLAG_IRC32KSTB: IRC32K stabilization flag + \arg RCU_FLAG_IRC48MSTB: IRC48M stabilization flag + \arg RCU_FLAG_BORRST: BOR reset flags + \arg RCU_FLAG_EPRST: external PIN reset flag + \arg RCU_FLAG_PORRST: Power reset flag + \arg RCU_FLAG_SWRST: software reset flag + \arg RCU_FLAG_FWDGTRST: free watchdog timer reset flag + \arg RCU_FLAG_WWDGTRST: window watchdog timer reset flag + \arg RCU_FLAG_LPRST: low-power reset flag + \param[out] none + \retval none +*/ +FlagStatus rcu_flag_get(rcu_flag_enum flag) +{ + /* get the rcu flag */ + if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear all the reset flag + \param[in] none + \param[out] none + \retval none +*/ +void rcu_all_reset_flag_clear(void) +{ + RCU_RSTSCK |= RCU_RSTSCK_RSTFC; +} + +/*! + \brief get the clock stabilization interrupt and ckm flags + \param[in] int_flag: interrupt and ckm flags, refer to rcu_int_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC32KSTB: 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_PLLI2SSTB: PLLI2S stabilization interrupt flag + \arg RCU_INT_FLAG_PLLSAISTB: PLLSAI stabilization interrupt flag + \arg RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag + \arg RCU_INT_FLAG_IRC48MSTB: IRC48M stabilization interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag) +{ + /* get the rcu interrupt flag */ + if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the interrupt flags + \param[in] int_flag_clear: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC32KSTB_CLR: IRC32K stabilization interrupt flag clear + \arg RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_IRC16MSTB_CLR: IRC16M stabilization interrupt flag clear + \arg RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLSTB_CLR: PLL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLI2SSTB_CLR: PLLI2S stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLSAISTB_CLR: PLLSAI stabilization interrupt flag clear + \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear + \arg RCU_INT_FLAG_IRC48MSTB_CLR: IRC48M stabilization interrupt flag clear + \param[out] none + \retval none +*/ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear) +{ + RCU_REG_VAL(int_flag_clear) |= BIT(RCU_BIT_POS(int_flag_clear)); +} + +/*! + \brief enable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + Only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC32KSTB: IRC32K stabilization interrupt enable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable + \arg RCU_INT_IRC16MSTB: IRC16M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable + \arg RCU_INT_PLLI2SSTB: PLLI2S stabilization interrupt enable + \arg RCU_INT_PLLSAISTB: PLLSAI stabilization interrupt enable + \arg RCU_INT_IRC48MSTB: IRC48M stabilization interrupt enable + \param[out] none + \retval none +*/ +void rcu_interrupt_enable(rcu_int_enum stab_int) +{ + RCU_REG_VAL(stab_int) |= BIT(RCU_BIT_POS(stab_int)); +} + + +/*! + \brief disable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC32KSTB: IRC32K stabilization interrupt disable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt disable + \arg RCU_INT_IRC16MSTB: IRC16M stabilization interrupt disable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt disable + \arg RCU_INT_PLLI2SSTB: PLLI2S stabilization interrupt disable + \arg RCU_INT_PLLSAISTB: PLLSAI stabilization interrupt disable + \arg RCU_INT_IRC48MSTB: IRC48M stabilization interrupt disable + \param[out] none + \retval none +*/ +void rcu_interrupt_disable(rcu_int_enum stab_int) +{ + RCU_REG_VAL(stab_int) &= ~BIT(RCU_BIT_POS(stab_int)); +} + +/*! + \brief configure the LXTAL drive capability + \param[in] lxtal_dricap: drive capability of LXTAL + only one parameter can be selected which is shown as below: + \arg RCU_LXTALDRI_LOWER_DRIVE: lower driving capability + \arg RCU_LXTALDRI_HIGHER_DRIVE: higher driving capability + \param[out] none + \retval none +*/ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap) +{ + uint32_t reg; + + reg = RCU_BDCTL; + + /* reset the LXTALDRI bits and set according to lxtal_dricap */ + reg &= ~RCU_BDCTL_LXTALDRI; + RCU_BDCTL = (reg | lxtal_dricap); +} + +/*! + \brief wait for oscillator stabilization flags is SET or oscillator startup is timeout + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC16M: IRC16M + \arg RCU_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \arg RCU_PLL_CK: PLL + \arg RCU_PLLI2S_CK: PLLI2S + \arg RCU_PLLSAI_CK: PLLSAI + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci) +{ + uint32_t stb_cnt = 0U; + ErrStatus reval = ERROR; + FlagStatus osci_stat = RESET; + + switch(osci){ + /* wait HXTAL stable */ + case RCU_HXTAL: + while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_HXTALSTB)){ + reval = SUCCESS; + } + break; + /* wait LXTAL stable */ + case RCU_LXTAL: + while((RESET == osci_stat) && (LXTAL_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_LXTALSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)){ + reval = SUCCESS; + } + break; + /* wait IRC16M stable */ + case RCU_IRC16M: + while((RESET == osci_stat) && (IRC16M_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC16MSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC16MSTB)){ + reval = SUCCESS; + } + break; + /* wait IRC48M stable */ + case RCU_IRC48M: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC48MSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if (RESET != rcu_flag_get(RCU_FLAG_IRC48MSTB)){ + reval = SUCCESS; + } + break; + /* wait IRC32K stable */ + case RCU_IRC32K: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC32KSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC32KSTB)){ + reval = SUCCESS; + } + break; + /* wait PLL stable */ + case RCU_PLL_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_PLLSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLSTB)){ + reval = SUCCESS; + } + break; + /* wait PLLI2S stable */ + case RCU_PLLI2S_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_PLLI2SSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLI2SSTB)){ + reval = SUCCESS; + } + break; + /* wait PLLSAI stable */ + case RCU_PLLSAI_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_PLLSAISTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLSAISTB)){ + reval = SUCCESS; + } + break; + + default: + break; + } + + /* return value */ + return reval; +} + +/*! + \brief turn on the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC16M: IRC16M + \arg RCU_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \arg RCU_PLL_CK: PLL + \arg RCU_PLLI2S_CK: PLLI2S + \arg RCU_PLLSAI_CK: PLLSAI + \param[out] none + \retval none +*/ +void rcu_osci_on(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) |= BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief turn off the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC16M: IRC16M + \arg RCU_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \arg RCU_PLL_CK: PLL + \arg RCU_PLLI2S_CK: PLLI2S + \arg RCU_PLLSAI_CK: PLLSAI + \param[out] none + \retval none +*/ +void rcu_osci_off(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) &= ~BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: 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){ + /* enable HXTAL to bypass mode */ + case RCU_HXTAL: + reg = RCU_CTL; + RCU_CTL &= ~RCU_CTL_HXTALEN; + RCU_CTL = (reg | RCU_CTL_HXTALBPS); + break; + /* enable LXTAL to bypass mode */ + case RCU_LXTAL: + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg | RCU_BDCTL_LXTALBPS); + break; + case RCU_IRC16M: + case RCU_IRC48M: + case RCU_IRC32K: + case RCU_PLL_CK: + case RCU_PLLI2S_CK: + case RCU_PLLSAI_CK: + break; + default: + break; + } +} + +/*! + \brief disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: 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){ + /* disable HXTAL to bypass mode */ + case RCU_HXTAL: + reg = RCU_CTL; + RCU_CTL &= ~RCU_CTL_HXTALEN; + RCU_CTL = (reg & ~RCU_CTL_HXTALBPS); + break; + /* disable LXTAL to bypass mode */ + case RCU_LXTAL: + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg & ~RCU_BDCTL_LXTALBPS); + break; + case RCU_IRC16M: + case RCU_IRC48M: + case RCU_IRC32K: + case RCU_PLL_CK: + case RCU_PLLI2S_CK: + case RCU_PLLSAI_CK: + break; + default: + break; + } +} + +/*! + \brief enable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ + +void rcu_hxtal_clock_monitor_enable(void) +{ + RCU_CTL |= RCU_CTL_CKMEN; +} + +/*! + \brief disable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_disable(void) +{ + RCU_CTL &= ~RCU_CTL_CKMEN; +} + +/*! + \brief set the IRC16M adjust value + \param[in] irc16m_adjval: IRC16M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc16m_adjust_value_set(uint32_t irc16m_adjval) +{ + uint32_t reg; + + reg = RCU_CTL; + /* reset the IRC16MADJ bits and set according to irc16m_adjval */ + reg &= ~RCU_CTL_IRC16MADJ; + RCU_CTL = (reg | ((irc16m_adjval & 0x1FU) << 3)); +} + +/*! + \brief unlock the voltage key + \param[in] none + \param[out] none + \retval none +*/ +void rcu_voltage_key_unlock(void) +{ + RCU_VKEY = RCU_VKEY_UNLOCK; +} + +/*! + \brief deep-sleep mode voltage select + \param[in] dsvol: deep sleep mode voltage + only one parameter can be selected which is shown as below: + \arg RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V + \arg RCU_DEEPSLEEP_V_1_1: the core voltage is 1.1V + \arg RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V + \arg RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V + \param[out] none + \retval none +*/ +void rcu_deepsleep_voltage_set(uint32_t dsvol) +{ + dsvol &= RCU_DSV_DSLPVS; + RCU_DSV = dsvol; +} + +/*! + \brief configure the spread spectrum modulation for the main PLL clock + \param[in] spread_spectrum_type: PLL spread spectrum modulation type select + \arg RCU_SS_TYPE_CENTER: center spread type is selected + \arg RCU_SS_TYPE_DOWN: down spread type is selected + \param[in] modstep: configure PLL spread spectrum modulation profile amplitude and frequency + \arg This parameter should be selected between 0 and 7FFF.The following criteria must be met: MODSTEP*MODCNT=215-1 + \param[in] modcnt: configure PLL spread spectrum modulation profile amplitude and frequency + \arg This parameter should be selected between 0 and 1FFF.The following criteria must be met: MODSTEP*MODCNT=215-1 + \param[out] none + \retval none +*/ +void rcu_spread_spectrum_config(uint32_t spread_spectrum_type, uint32_t modstep, uint32_t modcnt) +{ + uint32_t reg; + + reg = RCU_PLLSSCTL; + /* reset the RCU_PLLSSCTL register bits */ + reg &= ~(RCU_PLLSSCTL_MODCNT | RCU_PLLSSCTL_MODSTEP | RCU_PLLSSCTL_SS_TYPE); + RCU_PLLSSCTL = (reg | spread_spectrum_type | modstep << 13 | modcnt); +} + +/*! + \brief enable the PLL spread spectrum modulation + \param[in] none + \param[out] none + \retval none +*/ +void rcu_spread_spectrum_enable(void) +{ + RCU_PLLSSCTL |= RCU_PLLSSCTL_SSCGON; +} + +/*! + \brief disable the PLL spread spectrum modulation + \param[in] none + \param[out] none + \retval none +*/ +void rcu_spread_spectrum_disable(void) +{ + RCU_PLLSSCTL &= ~RCU_PLLSSCTL_SSCGON; +} + +/*! + \brief get the system clock, bus and peripheral clock frequency + \param[in] clock: the clock frequency which to get + only one parameter can be selected which is shown as below: + \arg CK_SYS: system clock frequency + \arg CK_AHB: AHB clock frequency + \arg CK_APB1: APB1 clock frequency + \arg CK_APB2: APB2 clock frequency + \param[out] none + \retval clock frequency of system, AHB, APB1, APB2 +*/ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) +{ + uint32_t sws, ck_freq = 0U; + uint32_t cksys_freq, ahb_freq, apb1_freq, apb2_freq; + uint32_t pllpsc, plln, pllsel, pllp, ck_src, idx, clk_exp; + + /* exponent of AHB, APB1 and APB2 clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + const uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + const uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC16M is selected as CK_SYS */ + case SEL_IRC16M: + cksys_freq = IRC16M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + cksys_freq = HXTAL_VALUE; + break; + /* PLLP is selected as CK_SYS */ + case SEL_PLLP: + /* get the value of PLLPSC[5:0] */ + pllpsc = GET_BITS(RCU_PLL, 0U, 5U); + plln = GET_BITS(RCU_PLL, 6U, 14U); + pllp = (GET_BITS(RCU_PLL, 16U, 17U) + 1U) * 2U; + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = (RCU_PLL & RCU_PLL_PLLSEL); + if (RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else { + ck_src = IRC16M_VALUE; + } + cksys_freq = ((ck_src / pllpsc) * plln)/pllp; + break; + /* IRC16M is selected as CK_SYS */ + default: + cksys_freq = IRC16M_VALUE; + break; + } + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + ahb_freq = cksys_freq >> clk_exp; + + /* calculate APB1 clock frequency */ + idx = GET_BITS(RCU_CFG0, 10, 12); + clk_exp = apb1_exp[idx]; + apb1_freq = ahb_freq >> clk_exp; + + /* calculate APB2 clock frequency */ + idx = GET_BITS(RCU_CFG0, 13, 15); + clk_exp = apb2_exp[idx]; + apb2_freq = ahb_freq >> clk_exp; + + /* return the clocks frequency */ + switch(clock){ + case CK_SYS: + ck_freq = cksys_freq; + break; + case CK_AHB: + ck_freq = ahb_freq; + break; + case CK_APB1: + ck_freq = apb1_freq; + break; + case CK_APB2: + ck_freq = apb2_freq; + break; + default: + break; + } + return ck_freq; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c new file mode 100644 index 0000000000..8e2713ceb1 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c @@ -0,0 +1,1257 @@ +/*! + \file gd32f4xx_rtc.c + \brief RTC driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_rtc.h" + +/* RTC timeout value */ +#define RTC_WTWF_TIMEOUT ((uint32_t)0x00004000U) /*!< wakeup timer can be write flag timeout */ +#define RTC_INITM_TIMEOUT ((uint32_t)0x00004000U) /*!< initialization state flag timeout */ +#define RTC_RSYNF_TIMEOUT ((uint32_t)0x00008000U) /*!< register synchronization flag timeout */ +#define RTC_HRFC_TIMEOUT ((uint32_t)0x20000000U) /*!< recalibration pending flag timeout */ +#define RTC_SHIFTCTL_TIMEOUT ((uint32_t)0x00001000U) /*!< shift function operation pending flag timeout */ +#define RTC_ALRMXWF_TIMEOUT ((uint32_t)0x00008000U) /*!< alarm configuration can be write flag timeout */ + + +/*! + \brief reset most of the RTC registers + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_deinit(void) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + /* RTC_TAMP register is not under write protection */ + RTC_TAMP = RTC_REGISTER_RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + /* reset RTC_CTL register, but RTC_CTL[20] */ + RTC_CTL &= (RTC_REGISTER_RESET | RTC_CTL_WTCS); + /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition. + in order to read calendar from shadow register, not the real registers being reset */ + RTC_TIME = RTC_REGISTER_RESET; + RTC_DATE = RTC_DATE_RESET; + + RTC_PSC = RTC_PSC_RESET; + /* only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[20] */ + /* wait until the WTWF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_WTWF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET == flag_status){ + error_status = ERROR; + }else{ + RTC_CTL &= RTC_REGISTER_RESET; + RTC_WUT = RTC_WUT_RESET; + RTC_COSC = RTC_REGISTER_RESET; + /* to write RTC_ALRMxSS register, ALRMxEN bit in RTC_CTL register should be reset as the condition */ + RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM1TD = RTC_REGISTER_RESET; + RTC_ALRM0SS = RTC_REGISTER_RESET; + RTC_ALRM1SS = RTC_REGISTER_RESET; + /* reset RTC_STAT register, also exit init mode. + at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */ + RTC_STAT = RTC_STAT_RESET; + /* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */ + RTC_SHIFTCTL = RTC_REGISTER_RESET; + RTC_HRFC = RTC_REGISTER_RESET; + error_status = rtc_register_sync_wait(); + } + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief initialize RTC registers + \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + year: 0x0 - 0x99(BCD format) + month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + date: 0x1 - 0x31(BCD format) + day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose + minute: 0x0 - 0x59(BCD format) + second: 0x0 - 0x59(BCD format) + factor_asyn: 0x0 - 0x7F + factor_syn: 0x0 - 0x7FFF + am_pm: RTC_AM, RTC_PM + display_format: RTC_24HOUR, RTC_12HOUR + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct) +{ + ErrStatus error_status = ERROR; + uint32_t reg_time = 0U, reg_date = 0U; + + reg_date = (DATE_YR(rtc_initpara_struct->year) | \ + DATE_DOW(rtc_initpara_struct->day_of_week) | \ + DATE_MON(rtc_initpara_struct->month) | \ + DATE_DAY(rtc_initpara_struct->date)); + + reg_time = (rtc_initpara_struct->am_pm| \ + TIME_HR(rtc_initpara_struct->hour) | \ + TIME_MN(rtc_initpara_struct->minute) | \ + TIME_SC(rtc_initpara_struct->second)); + + /* 1st: disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* 2nd: enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->factor_asyn)| \ + PSC_FACTOR_S(rtc_initpara_struct->factor_syn)); + + RTC_TIME = (uint32_t)reg_time; + RTC_DATE = (uint32_t)reg_date; + + RTC_CTL &= (uint32_t)(~RTC_CTL_CS); + RTC_CTL |= rtc_initpara_struct->display_format; + + /* 3rd: exit init mode */ + rtc_init_mode_exit(); + + /* 4th: wait the RSYNF flag to set */ + error_status = rtc_register_sync_wait(); + } + + /* 5th: enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enter RTC init mode + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init_mode_enter(void) +{ + volatile uint32_t time_index = RTC_INITM_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + /* check whether it has been in init mode */ + if ((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){ + RTC_STAT |= RTC_STAT_INITM; + + /* wait until the INITF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_INITF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + }else{ + error_status = SUCCESS; + } + return error_status; +} + +/*! + \brief exit RTC init mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_init_mode_exit(void) +{ + RTC_STAT &= (uint32_t)(~RTC_STAT_INITM); +} + +/*! + \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow + registers are updated + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_register_sync_wait(void) +{ + volatile uint32_t time_index = RTC_RSYNF_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + if ((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* firstly clear RSYNF flag */ + RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF); + + /* wait until RSYNF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_RSYNF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + }else{ + error_status = SUCCESS; + } + + return error_status; +} + +/*! + \brief get current time and date + \param[in] none + \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + year: 0x0 - 0x99(BCD format) + month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + date: 0x1 - 0x31(BCD format) + day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose + minute: 0x0 - 0x59(BCD format) + second: 0x0 - 0x59(BCD format) + factor_asyn: 0x0 - 0x7F + factor_syn: 0x0 - 0x7FFF + am_pm: RTC_AM, RTC_PM + display_format: RTC_24HOUR, RTC_12HOUR + \retval none +*/ +void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct) +{ + uint32_t temp_tr = 0U, temp_dr = 0U, temp_pscr = 0U, temp_ctlr = 0U; + + temp_tr = (uint32_t)RTC_TIME; + temp_dr = (uint32_t)RTC_DATE; + temp_pscr = (uint32_t)RTC_PSC; + temp_ctlr = (uint32_t)RTC_CTL; + + /* get current time and construct rtc_parameter_struct structure */ + rtc_initpara_struct->year = (uint8_t)GET_DATE_YR(temp_dr); + rtc_initpara_struct->month = (uint8_t)GET_DATE_MON(temp_dr); + rtc_initpara_struct->date = (uint8_t)GET_DATE_DAY(temp_dr); + rtc_initpara_struct->day_of_week = (uint8_t)GET_DATE_DOW(temp_dr); + rtc_initpara_struct->hour = (uint8_t)GET_TIME_HR(temp_tr); + rtc_initpara_struct->minute = (uint8_t)GET_TIME_MN(temp_tr); + rtc_initpara_struct->second = (uint8_t)GET_TIME_SC(temp_tr); + rtc_initpara_struct->factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr); + rtc_initpara_struct->factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr); + rtc_initpara_struct->am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM); + rtc_initpara_struct->display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS); +} + +/*! + \brief get current subsecond value + \param[in] none + \param[out] none + \retval current subsecond value +*/ +uint32_t rtc_subsecond_get(void) +{ + uint32_t reg = 0U; + /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */ + reg = (uint32_t)RTC_SS; + /* read RTC_DATE to unlock the 3 shadow registers */ + (void) (RTC_DATE); + + return reg; +} + +/*! + \brief configure RTC alarm + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + alarm_minute: 0x0 - 0x59(BCD format) + alarm_second: 0x0 - 0x59(BCD format) + am_pm: RTC_AM, RTC_PM + \param[out] none + \retval none +*/ +void rtc_alarm_config(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time) +{ + uint32_t reg_alrmtd = 0U; + + reg_alrmtd =(rtc_alarm_time->alarm_mask | \ + rtc_alarm_time->weekday_or_date | \ + rtc_alarm_time->am_pm | \ + ALRMTD_DAY(rtc_alarm_time->alarm_day) | \ + ALRMTD_HR(rtc_alarm_time->alarm_hour) | \ + ALRMTD_MN(rtc_alarm_time->alarm_minute) | \ + ALRMTD_SC(rtc_alarm_time->alarm_second)); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + if(RTC_ALARM0 == rtc_alarm){ + RTC_ALRM0TD = (uint32_t)reg_alrmtd; + + }else{ + RTC_ALRM1TD = (uint32_t)reg_alrmtd; + } + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure subsecond of RTC alarm + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[in] mask_subsecond: alarm subsecond mask + \arg RTC_MASKSSC_0_14: mask alarm subsecond configuration + \arg RTC_MASKSSC_1_14: mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared + \arg RTC_MASKSSC_2_14: mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared + \arg RTC_MASKSSC_3_14: mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared + \arg RTC_MASKSSC_4_14: mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared + \arg RTC_MASKSSC_5_14: mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared + \arg RTC_MASKSSC_6_14: mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared + \arg RTC_MASKSSC_7_14: mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared + \arg RTC_MASKSSC_8_14: mask RTC_ALRMXSS_SSC[14:8], and RTC_ALRMXSS_SSC[7:0] is to be compared + \arg RTC_MASKSSC_9_14: mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared + \arg RTC_MASKSSC_10_14: mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared + \arg RTC_MASKSSC_11_14: mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared + \arg RTC_MASKSSC_12_14: mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared + \arg RTC_MASKSSC_13_14: mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared + \arg RTC_MASKSSC_14: mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared + \arg RTC_MASKSSC_NONE: mask none, and RTC_ALRMXSS_SSC[14:0] is to be compared + \param[in] subsecond: alarm subsecond value(0x000 - 0x7FFF) + \param[out] none + \retval none +*/ +void rtc_alarm_subsecond_config(uint8_t rtc_alarm, uint32_t mask_subsecond, uint32_t subsecond) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + if(RTC_ALARM0 == rtc_alarm){ + RTC_ALRM0SS = mask_subsecond | subsecond; + }else{ + RTC_ALRM1SS = mask_subsecond | subsecond; + } + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief get RTC alarm + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + alarm_minute: 0x0 - 0x59(BCD format) + alarm_second: 0x0 - 0x59(BCD format) + am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_alarm_get(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time) +{ + uint32_t reg_alrmtd = 0U; + + /* get the value of RTC_ALRM0TD register */ + if(RTC_ALARM0 == rtc_alarm){ + reg_alrmtd = RTC_ALRM0TD; + }else{ + reg_alrmtd = RTC_ALRM1TD; + } + /* get alarm parameters and construct the rtc_alarm_struct structure */ + rtc_alarm_time->alarm_mask = reg_alrmtd & RTC_ALARM_ALL_MASK; + rtc_alarm_time->am_pm = (uint32_t)(reg_alrmtd & RTC_ALRMXTD_PM); + rtc_alarm_time->weekday_or_date = (uint32_t)(reg_alrmtd & RTC_ALRMXTD_DOWS); + rtc_alarm_time->alarm_day = (uint8_t)GET_ALRMTD_DAY(reg_alrmtd); + rtc_alarm_time->alarm_hour = (uint8_t)GET_ALRMTD_HR(reg_alrmtd); + rtc_alarm_time->alarm_minute = (uint8_t)GET_ALRMTD_MN(reg_alrmtd); + rtc_alarm_time->alarm_second = (uint8_t)GET_ALRMTD_SC(reg_alrmtd); +} + +/*! + \brief get RTC alarm subsecond + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[out] none + \retval RTC alarm subsecond value +*/ +uint32_t rtc_alarm_subsecond_get(uint8_t rtc_alarm) +{ + if(RTC_ALARM0 == rtc_alarm){ + return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC)); + }else{ + return ((uint32_t)(RTC_ALRM1SS & RTC_ALRM1SS_SSC)); + } +} + +/*! + \brief enable RTC alarm + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[out] none + \retval none +*/ +void rtc_alarm_enable(uint8_t rtc_alarm) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + if(RTC_ALARM0 == rtc_alarm){ + RTC_CTL |= RTC_CTL_ALRM0EN; + }else{ + RTC_CTL |= RTC_CTL_ALRM1EN; + } + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC alarm + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_alarm_disable(uint8_t rtc_alarm) +{ + volatile uint32_t time_index = RTC_ALRMXWF_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the state of alarm */ + if(RTC_ALARM0 == rtc_alarm){ + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN); + /* wait until ALRM0WF flag to be set after the alarm is disabled */ + do{ + flag_status = RTC_STAT & RTC_STAT_ALRM0WF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + }else{ + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM1EN); + /* wait until ALRM1WF flag to be set after the alarm is disabled */ + do{ + flag_status = RTC_STAT & RTC_STAT_ALRM1WF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + } + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC time-stamp + \param[in] edge: specify which edge to detect of time-stamp + \arg RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event + \arg RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event + \param[out] none + \retval none +*/ +void rtc_timestamp_enable(uint32_t edge) +{ + uint32_t reg_ctl = 0U; + + /* clear the bits to be configured in RTC_CTL */ + reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN))); + + /* new configuration */ + reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL = (uint32_t)reg_ctl; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC time-stamp + \param[in] none + \param[out] none + \retval none +*/ +void rtc_timestamp_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the TSEN bit */ + RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief get RTC timestamp time and date + \param[in] none + \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains + parameters for RTC time-stamp configuration + members of the structure and the member values are shown as below: + timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + timestamp_date: 0x1 - 0x31(BCD format) + timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + timestamp_minute: 0x0 - 0x59(BCD format) + timestamp_second: 0x0 - 0x59(BCD format) + am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp) +{ + uint32_t temp_tts = 0U, temp_dts = 0U; + + /* get the value of time_stamp registers */ + temp_tts = (uint32_t)RTC_TTS; + temp_dts = (uint32_t)RTC_DTS; + + /* get timestamp time and construct the rtc_timestamp_struct structure */ + rtc_timestamp->am_pm = (uint32_t)(temp_tts & RTC_TTS_PM); + rtc_timestamp->timestamp_month = (uint8_t)GET_DTS_MON(temp_dts); + rtc_timestamp->timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts); + rtc_timestamp->timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts); + rtc_timestamp->timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts); + rtc_timestamp->timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts); + rtc_timestamp->timestamp_second = (uint8_t)GET_TTS_SC(temp_tts); +} + +/*! + \brief get RTC time-stamp subsecond + \param[in] none + \param[out] none + \retval RTC time-stamp subsecond value +*/ +uint32_t rtc_timestamp_subsecond_get(void) +{ + return ((uint32_t)RTC_SSTS); +} + +/*! + \brief RTC time-stamp mapping + \param[in] rtc_af: + \arg RTC_AF0_TIMESTAMP: RTC_AF0 use for timestamp + \arg RTC_AF1_TIMESTAMP: RTC_AF1 use for timestamp + \param[out] none + \retval none +*/ +void rtc_timestamp_pin_map(uint32_t rtc_af) +{ + RTC_TAMP &= ~RTC_TAMP_TSSEL; + RTC_TAMP |= rtc_af; +} + +/*! + \brief enable RTC tamper + \param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains + parameters for RTC tamper configuration + members of the structure and the member values are shown as below: + tamper_source: RTC_TAMPER0, RTC_TAMPER1 + tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING + RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH + tamper_filter: RTC_FLT_EDGE, RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S + tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192, + RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024, + RTC_FREQ_DIV512, RTC_FREQ_DIV256 + tamper_precharge_enable: DISABLE, ENABLE + tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C + tamper_with_timestamp: DISABLE, ENABLE + \param[out] none + \retval none +*/ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~(rtc_tamper->tamper_source); + + /* tamper filter must be used when the tamper source is voltage level detection */ + RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT; + + /* the tamper source is voltage level detection */ + if((uint32_t)(rtc_tamper->tamper_filter) != RTC_FLT_EDGE ){ + RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT); + + /* check if the tamper pin need precharge, if need, then configure the precharge time */ + if(DISABLE == rtc_tamper->tamper_precharge_enable){ + RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU; + }else{ + RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_precharge_time); + } + + RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_sample_frequency); + RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_filter); + } + + RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS; + + if(DISABLE != rtc_tamper->tamper_with_timestamp){ + /* the tamper event also cause a time-stamp event */ + RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS; + } + + /* configure the tamper trigger */ + RTC_TAMP &= ((uint32_t)~((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS)); + if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->tamper_trigger){ + RTC_TAMP |= (uint32_t)((rtc_tamper->tamper_source)<< RTC_TAMPER_TRIGGER_POS); + } + /* enable tamper */ + RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_source); +} + +/*! + \brief disable RTC tamper + \param[in] source: specify which tamper source to be disabled + \arg RTC_TAMPER0 + \arg RTC_TAMPER1 + \param[out] none + \retval none +*/ +void rtc_tamper_disable(uint32_t source) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~source; + +} + +/*! + \brief RTC tamper0 mapping + \param[in] rtc_af: + \arg RTC_AF0_TAMPER0: RTC_AF0 use for tamper0 + \arg RTC_AF1_TAMPER0: RTC_AF1 use for tamper0 + \param[out] none + \retval none +*/ +void rtc_tamper0_pin_map(uint32_t rtc_af) +{ + RTC_TAMP &= ~(RTC_TAMP_TP0EN | RTC_TAMP_TP0SEL); + RTC_TAMP |= rtc_af; +} +/*! + \brief enable specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be enabled + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM0: alarm0 interrupt + \arg RTC_INT_ALARM1: alarm1 interrupt + \arg RTC_INT_TAMP: tamp interrupt + \arg RTC_INT_WAKEUP: wakeup timer interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_enable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enable the interrupts in RTC_CTL register */ + RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE); + /* enable the interrupts in RTC_TAMP register */ + RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disble specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be disabled + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM0: alarm interrupt + \arg RTC_INT_ALARM1: alarm interrupt + \arg RTC_INT_TAMP: tamp interrupt + \arg RTC_INT_WAKEUP: wakeup timer interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_disable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* disable the interrupts in RTC_CTL register */ + RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE); + /* disable the interrupts in RTC_TAMP register */ + RTC_TAMP &= (uint32_t)~(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief check specified flag + \param[in] flag: specify which flag to check + \arg RTC_STAT_RECPF: recalibration pending flag + \arg RTC_STAT_TP1F: tamper 1 event flag + \arg RTC_STAT_TP0F: tamper 0 event flag + \arg RTC_STAT_TSOVRF: time-stamp overflow event flag + \arg RTC_STAT_TSF: time-stamp event flag + \arg RTC_STAT_ALRM0F: alarm0 event flag + \arg RTC_STAT_ALRM1F: alarm1 event flag + \arg RTC_STAT_WTF: wakeup timer event flag + \arg RTC_STAT_INITF: init mode event flag + \arg RTC_STAT_RSYNF: time and date registers synchronized event flag + \arg RTC_STAT_YCM: year parameter configured event flag + \arg RTC_STAT_SOPF: shift operation pending flag + \arg RTC_STAT_ALRM0WF: alarm0 writen available flag + \arg RTC_STAT_ALRM1WF: alarm1 writen available flag + \arg RTC_STAT_WTWF: wakeup timer 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_STAT_TP1F: tamper 1 event flag + \arg RTC_STAT_TP0F: tamper 0 event flag + \arg RTC_STAT_TSOVRF: time-stamp overflow event flag + \arg RTC_STAT_TSF: time-stamp event flag + \arg RTC_STAT_WTF: time-stamp event flag + \arg RTC_STAT_ALRM0F: alarm0 event flag + \arg RTC_STAT_ALRM1F: alarm1 event flag + \arg RTC_STAT_RSYNF: 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 alarm output source + \param[in] source: specify signal to output + \arg RTC_ALARM0_HIGH: when the alarm0 flag is set, the output pin is high + \arg RTC_ALARM0_LOW: when the alarm0 flag is set, the output pin is low + \arg RTC_ALARM1_HIGH: when the alarm1 flag is set, the output pin is high + \arg RTC_ALARM1_LOW: when the alarm1 flag is set, the output pin is low + \arg RTC_WAKEUP_HIGH: when the wakeup flag is set, the output pin is high + \arg RTC_WAKEUP_LOW: when the wakeup flag is set, the output pin is low + \param[in] mode: specify the output pin mode when output alarm signal + \arg RTC_ALARM_OUTPUT_OD: open drain mode + \arg RTC_ALARM_OUTPUT_PP: push pull mode + \param[out] none + \retval none +*/ +void rtc_alarm_output_config(uint32_t source, uint32_t mode) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= ~(RTC_CTL_OS | RTC_CTL_OPOL); + RTC_TAMP &= ~RTC_TAMP_AOT; + + RTC_CTL |= (uint32_t)(source); + /* alarm output */ + RTC_TAMP |= (uint32_t)(mode); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure rtc calibration output source + \param[in] source: specify signal to output + \arg RTC_CALIBRATION_512HZ: when the LSE freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \arg RTC_CALIBRATION_1HZ: when the LSE freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \param[out] none + \retval none +*/ +void rtc_calibration_output_config(uint32_t source) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_COS); + + RTC_CTL |= (uint32_t)(source); + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + + +/*! + \brief adjust the daylight saving time by adding or substracting one hour from the current time + \param[in] operation: hour adjustment operation + \arg RTC_CTL_A1H: add one hour + \arg RTC_CTL_S1H: substract one hour + \param[out] none + \retval none +*/ +void rtc_hour_adjust(uint32_t operation) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint32_t)(operation); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief adjust RTC second or subsecond value of current time + \param[in] add: add 1s to current time or not + \arg RTC_SHIFT_ADD1S_RESET: no effect + \arg RTC_SHIFT_ADD1S_SET: add 1s to current time + \param[in] minus: number of subsecond to minus from current time(0x0 - 0x7FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus) +{ + volatile uint32_t time_index = RTC_SHIFTCTL_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + uint32_t temp=0U; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a shift operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SOPF; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + /* check if the function of reference clock detection is disabled */ + temp = RTC_CTL & RTC_CTL_REFEN; + if((RESET == flag_status) && (RESET == temp)){ + RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus)); + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= ~RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_enable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL |= (uint32_t)RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief disable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_disable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL &= (uint32_t)~RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC auto wakeup function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_wakeup_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= RTC_CTL_WTEN; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC auto wakeup function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_wakeup_disable(void) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + RTC_CTL &= ~RTC_CTL_WTEN; + /* wait until the WTWF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_WTWF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET == flag_status){ + error_status = ERROR; + }else{ + error_status = SUCCESS; + } + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + return error_status; +} + +/*! + \brief set RTC auto wakeup timer clock + \param[in] wakeup_clock: + \arg WAKEUP_RTCCK_DIV16: RTC auto wakeup timer clock is RTC clock divided by 16 + \arg WAKEUP_RTCCK_DIV8: RTC auto wakeup timer clock is RTC clock divided by 8 + \arg WAKEUP_RTCCK_DIV4: RTC auto wakeup timer clock is RTC clock divided by 4 + \arg WAKEUP_RTCCK_DIV2: RTC auto wakeup timer clock is RTC clock divided by 2 + \arg WAKEUP_CKSPRE: RTC auto wakeup timer clock is ckspre + \arg WAKEUP_CKSPRE_2EXP16: RTC auto wakeup timer clock is ckspre and wakeup timer add 2exp16 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_wakeup_clock_set(uint8_t wakeup_clock) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + /* only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[20] */ + /* wait until the WTWF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_WTWF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET == flag_status){ + error_status = ERROR; + }else{ + RTC_CTL &= (uint32_t)~ RTC_CTL_WTCS; + RTC_CTL |= (uint32_t)wakeup_clock; + error_status = SUCCESS; + } + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief set wakeup timer value + \param[in] wakeup_timer: 0x0000-0xffff + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + /* wait until the WTWF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_WTWF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET == flag_status){ + error_status = ERROR; + }else{ + RTC_WUT = (uint32_t)wakeup_timer; + error_status = SUCCESS; + } + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + return error_status; +} + +/*! + \brief get wakeup timer value + \param[in] none + \param[out] none + \retval wakeup timer value +*/ + uint16_t rtc_wakeup_timer_get(void) +{ + return (uint16_t)RTC_WUT; +} + +/*! + \brief configure RTC smooth calibration + \param[in] window: select calibration window + \arg RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz + \param[in] plus: add RTC clock or not + \arg RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock + \arg RTC_CALIBRATION_PLUS_RESET: no effect + \param[in] minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t minus) +{ + volatile uint32_t time_index = RTC_HRFC_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a smooth calibration operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SCPF; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + if((uint32_t)RESET == flag_status){ + RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus)); + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC coarse calibration + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_coarse_calibration_enable(void) +{ + ErrStatus error_status = ERROR; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL |= (uint32_t)RTC_CTL_CCEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + return error_status; +} + +/*! + \brief disable RTC coarse calibration + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_coarse_calibration_disable(void) +{ + ErrStatus error_status = ERROR; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL &= (uint32_t)~RTC_CTL_CCEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + return error_status; +} + +/*! + \brief config coarse calibration direction and step + \param[in] direction: CALIB_INCREASE or CALIB_DECREASE + \param[in] step: 0x00-0x1F + COSD=0: + 0x00:+0 PPM + 0x01:+4 PPM + 0x02:+8 PPM + .... + 0x1F:+126 PPM + COSD=1: + 0x00:-0 PPM + 0x01:-2 PPM + 0x02:-4 PPM + .... + 0x1F:-63 PPM + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_coarse_calibration_config(uint8_t direction, uint8_t step) +{ + ErrStatus error_status = ERROR; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + if(CALIB_DECREASE == direction){ + RTC_COSC |= (uint32_t)RTC_COSC_COSD; + }else{ + RTC_COSC &= (uint32_t)~RTC_COSC_COSD; + } + RTC_COSC &= ~RTC_COSC_COSS; + RTC_COSC |= (uint32_t)((uint32_t)step & 0x1FU); + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c new file mode 100644 index 0000000000..f7b26358b5 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c @@ -0,0 +1,759 @@ +/*! + \file gd32f4xx_sdio.c + \brief SDIO driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_sdio.h" + +/*! + \brief deinitialize the SDIO + \param[in] none + \param[out] none + \retval none +*/ +void sdio_deinit(void) +{ + rcu_periph_reset_enable(RCU_SDIORST); + rcu_periph_reset_disable(RCU_SDIORST); +} + +/*! + \brief configure the SDIO clock + \param[in] clock_edge: SDIO_CLK clock edge + \arg SDIO_SDIOCLKEDGE_RISING: select the rising edge of the SDIOCLK to generate SDIO_CLK + \arg SDIO_SDIOCLKEDGE_FALLING: select the falling edge of the SDIOCLK to generate SDIO_CLK + \param[in] clock_bypass: clock bypass + \arg SDIO_CLOCKBYPASS_ENABLE: clock bypass + \arg SDIO_CLOCKBYPASS_DISABLE: no bypass + \param[in] clock_powersave: SDIO_CLK clock dynamic switch on/off for power saving + \arg SDIO_CLOCKPWRSAVE_ENABLE: SDIO_CLK closed when bus is idle + \arg SDIO_CLOCKPWRSAVE_DISABLE: SDIO_CLK clock is always on + \param[in] clock_division: clock division, less than 512 + \param[out] none + \retval none +*/ +void sdio_clock_config(uint32_t clock_edge, uint32_t clock_bypass, uint32_t clock_powersave, uint16_t clock_division) +{ + uint32_t clock_config = 0U; + clock_config = SDIO_CLKCTL; + /* reset the CLKEDGE, CLKBYP, CLKPWRSAV, DIV */ + clock_config &= ~(SDIO_CLKCTL_CLKEDGE | SDIO_CLKCTL_CLKBYP | SDIO_CLKCTL_CLKPWRSAV | SDIO_CLKCTL_DIV8 | SDIO_CLKCTL_DIV); + /* if the clock division is greater or equal to 256, set the DIV[8] */ + if(clock_division >= 256U){ + clock_config |= SDIO_CLKCTL_DIV8; + clock_division -= 256U; + } + /* configure the SDIO_CLKCTL according to the parameters */ + clock_config |= (clock_edge | clock_bypass | clock_powersave | clock_division); + SDIO_CLKCTL = clock_config; +} + +/*! + \brief enable hardware clock control + \param[in] none + \param[out] none + \retval none +*/ +void sdio_hardware_clock_enable(void) +{ + SDIO_CLKCTL |= SDIO_CLKCTL_HWCLKEN; +} + +/*! + \brief disable hardware clock control + \param[in] none + \param[out] none + \retval none +*/ +void sdio_hardware_clock_disable(void) +{ + SDIO_CLKCTL &= ~SDIO_CLKCTL_HWCLKEN; +} + +/*! + \brief set different SDIO card bus mode + \param[in] bus_mode: SDIO card bus mode + \arg SDIO_BUSMODE_1BIT: 1-bit SDIO card bus mode + \arg SDIO_BUSMODE_4BIT: 4-bit SDIO card bus mode + \arg SDIO_BUSMODE_8BIT: 8-bit SDIO card bus mode + \param[out] none + \retval none +*/ +void sdio_bus_mode_set(uint32_t bus_mode) +{ + /* reset the SDIO card bus mode bits and set according to bus_mode */ + SDIO_CLKCTL &= ~SDIO_CLKCTL_BUSMODE; + SDIO_CLKCTL |= bus_mode; +} + +/*! + \brief set the SDIO power state + \param[in] power_state: SDIO power state + \arg SDIO_POWER_ON: SDIO power on + \arg SDIO_POWER_OFF: SDIO power off + \param[out] none + \retval none +*/ +void sdio_power_state_set(uint32_t power_state) +{ + SDIO_PWRCTL = power_state; +} + +/* get the SDIO power state */ +/*! + \brief get the SDIO power state + \param[in] none + \param[out] none + \retval SDIO power state + \arg SDIO_POWER_ON: SDIO power on + \arg SDIO_POWER_OFF: SDIO power off +*/ +uint32_t sdio_power_state_get(void) +{ + return SDIO_PWRCTL; +} + +/*! + \brief enable SDIO_CLK clock output + \param[in] none + \param[out] none + \retval none +*/ +void sdio_clock_enable(void) +{ + SDIO_CLKCTL |= SDIO_CLKCTL_CLKEN; +} + +/*! + \brief disable SDIO_CLK clock output + \param[in] none + \param[out] none + \retval none +*/ +void sdio_clock_disable(void) +{ + SDIO_CLKCTL &= ~SDIO_CLKCTL_CLKEN; +} + +/*! + \brief configure the command and response + \param[in] cmd_index: command index, refer to the related specifications + \param[in] cmd_argument: command argument, refer to the related specifications + \param[in] response_type: response type + \arg SDIO_RESPONSETYPE_NO: no response + \arg SDIO_RESPONSETYPE_SHORT: short response + \arg SDIO_RESPONSETYPE_LONG: long response + \param[out] none + \retval none +*/ +void sdio_command_response_config(uint32_t cmd_index, uint32_t cmd_argument, uint32_t response_type) +{ + uint32_t cmd_config = 0U; + /* reset the command index, command argument and response type */ + SDIO_CMDAGMT &= ~SDIO_CMDAGMT_CMDAGMT; + SDIO_CMDAGMT = cmd_argument; + cmd_config = SDIO_CMDCTL; + cmd_config &= ~(SDIO_CMDCTL_CMDIDX | SDIO_CMDCTL_CMDRESP); + /* configure SDIO_CMDCTL and SDIO_CMDAGMT according to the parameters */ + cmd_config |= (cmd_index | response_type); + SDIO_CMDCTL = cmd_config; +} + +/*! + \brief set the command state machine wait type + \param[in] wait_type: wait type + \arg SDIO_WAITTYPE_NO: not wait interrupt + \arg SDIO_WAITTYPE_INTERRUPT: wait interrupt + \arg SDIO_WAITTYPE_DATAEND: wait the end of data transfer + \param[out] none + \retval none +*/ +void sdio_wait_type_set(uint32_t wait_type) +{ + /* reset INTWAIT and WAITDEND */ + SDIO_CMDCTL &= ~(SDIO_CMDCTL_INTWAIT | SDIO_CMDCTL_WAITDEND); + /* set the wait type according to wait_type */ + SDIO_CMDCTL |= wait_type; +} + +/*! + \brief enable the CSM(command state machine) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_csm_enable(void) +{ + SDIO_CMDCTL |= SDIO_CMDCTL_CSMEN; +} + +/*! + \brief disable the CSM(command state machine) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_csm_disable(void) +{ + SDIO_CMDCTL &= ~SDIO_CMDCTL_CSMEN; +} + +/*! + \brief get the last response command index + \param[in] none + \param[out] none + \retval last response command index +*/ +uint8_t sdio_command_index_get(void) +{ + return (uint8_t)SDIO_RSPCMDIDX; +} + +/*! + \brief get the response for the last received command + \param[in] sdio_responsex: SDIO response + \arg SDIO_RESPONSE0: card response[31:0]/card response[127:96] + \arg SDIO_RESPONSE1: card response[95:64] + \arg SDIO_RESPONSE2: card response[63:32] + \arg SDIO_RESPONSE3: card response[31:1], plus bit 0 + \param[out] none + \retval response for the last received command +*/ +uint32_t sdio_response_get(uint32_t sdio_responsex) +{ + uint32_t resp_content = 0U; + switch(sdio_responsex){ + case SDIO_RESPONSE0: + resp_content = SDIO_RESP0; + break; + case SDIO_RESPONSE1: + resp_content = SDIO_RESP1; + break; + case SDIO_RESPONSE2: + resp_content = SDIO_RESP2; + break; + case SDIO_RESPONSE3: + resp_content = SDIO_RESP3; + break; + default: + break; + } + return resp_content; +} + +/*! + \brief configure the data timeout, data length and data block size + \param[in] data_timeout: data timeout period in card bus clock periods + \param[in] data_length: number of data bytes to be transferred + \param[in] data_blocksize: size of data block for block transfer + \arg SDIO_DATABLOCKSIZE_1BYTE: block size = 1 byte + \arg SDIO_DATABLOCKSIZE_2BYTES: block size = 2 bytes + \arg SDIO_DATABLOCKSIZE_4BYTES: block size = 4 bytes + \arg SDIO_DATABLOCKSIZE_8BYTES: block size = 8 bytes + \arg SDIO_DATABLOCKSIZE_16BYTES: block size = 16 bytes + \arg SDIO_DATABLOCKSIZE_32BYTES: block size = 32 bytes + \arg SDIO_DATABLOCKSIZE_64BYTES: block size = 64 bytes + \arg SDIO_DATABLOCKSIZE_128BYTES: block size = 128 bytes + \arg SDIO_DATABLOCKSIZE_256BYTES: block size = 256 bytes + \arg SDIO_DATABLOCKSIZE_512BYTES: block size = 512 bytes + \arg SDIO_DATABLOCKSIZE_1024BYTES: block size = 1024 bytes + \arg SDIO_DATABLOCKSIZE_2048BYTES: block size = 2048 bytes + \arg SDIO_DATABLOCKSIZE_4096BYTES: block size = 4096 bytes + \arg SDIO_DATABLOCKSIZE_8192BYTES: block size = 8192 bytes + \arg SDIO_DATABLOCKSIZE_16384BYTES: block size = 16384 bytes + \param[out] none + \retval none +*/ +void sdio_data_config(uint32_t data_timeout, uint32_t data_length, uint32_t data_blocksize) +{ + /* reset data timeout, data length and data block size */ + SDIO_DATATO &= ~SDIO_DATATO_DATATO; + SDIO_DATALEN &= ~SDIO_DATALEN_DATALEN; + SDIO_DATACTL &= ~SDIO_DATACTL_BLKSZ; + /* configure the related parameters of data */ + SDIO_DATATO = data_timeout; + SDIO_DATALEN = data_length; + SDIO_DATACTL |= data_blocksize; +} + +/*! + \brief configure the data transfer mode and direction + \param[in] transfer_mode: mode of data transfer + \arg SDIO_TRANSMODE_BLOCK: block transfer + \arg SDIO_TRANSMODE_STREAM: stream transfer or SDIO multibyte transfer + \param[in] transfer_direction: data transfer direction, read or write + \arg SDIO_TRANSDIRECTION_TOCARD: write data to card + \arg SDIO_TRANSDIRECTION_TOSDIO: read data from card + \param[out] none + \retval none +*/ +void sdio_data_transfer_config(uint32_t transfer_mode, uint32_t transfer_direction) +{ + uint32_t data_trans = 0U; + /* reset the data transfer mode, transfer direction and set according to the parameters */ + data_trans = SDIO_DATACTL; + data_trans &= ~(SDIO_DATACTL_TRANSMOD | SDIO_DATACTL_DATADIR); + data_trans |= (transfer_mode | transfer_direction); + SDIO_DATACTL = data_trans; +} + +/*! + \brief enable the DSM(data state machine) for data transfer + \param[in] none + \param[out] none + \retval none +*/ +void sdio_dsm_enable(void) +{ + SDIO_DATACTL |= SDIO_DATACTL_DATAEN; +} + +/*! + \brief disable the DSM(data state machine) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_dsm_disable(void) +{ + SDIO_DATACTL &= ~SDIO_DATACTL_DATAEN; +} + +/*! + \brief write data(one word) to the transmit FIFO + \param[in] data: 32-bit data write to card + \param[out] none + \retval none +*/ +void sdio_data_write(uint32_t data) +{ + SDIO_FIFO = data; +} + +/*! + \brief read data(one word) from the receive FIFO + \param[in] none + \param[out] none + \retval received data +*/ +uint32_t sdio_data_read(void) +{ + return SDIO_FIFO; +} + +/*! + \brief get the number of remaining data bytes to be transferred to card + \param[in] none + \param[out] none + \retval number of remaining data bytes to be transferred +*/ +uint32_t sdio_data_counter_get(void) +{ + return SDIO_DATACNT; +} + +/*! + \brief get the number of words remaining to be written or read from FIFO + \param[in] none + \param[out] none + \retval remaining number of words +*/ +uint32_t sdio_fifo_counter_get(void) +{ + return SDIO_FIFOCNT; +} + +/*! + \brief enable the DMA request for SDIO + \param[in] none + \param[out] none + \retval none +*/ +void sdio_dma_enable(void) +{ + SDIO_DATACTL |= SDIO_DATACTL_DMAEN; +} + +/*! + \brief disable the DMA request for SDIO + \param[in] none + \param[out] none + \retval none +*/ +void sdio_dma_disable(void) +{ + SDIO_DATACTL &= ~SDIO_DATACTL_DMAEN; +} + +/*! + \brief get the flags state of SDIO + \param[in] flag: flags state of SDIO + \arg SDIO_FLAG_CCRCERR: command response received (CRC check failed) flag + \arg SDIO_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag + \arg SDIO_FLAG_CMDTMOUT: command response timeout flag + \arg SDIO_FLAG_DTTMOUT: data timeout flag + \arg SDIO_FLAG_TXURE: transmit FIFO underrun error occurs flag + \arg SDIO_FLAG_RXORE: received FIFO overrun error occurs flag + \arg SDIO_FLAG_CMDRECV: command response received (CRC check passed) flag + \arg SDIO_FLAG_CMDSEND: command sent (no response required) flag + \arg SDIO_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag + \arg SDIO_FLAG_STBITE: start bit error in the bus flag + \arg SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag + \arg SDIO_FLAG_CMDRUN: command transmission in progress flag + \arg SDIO_FLAG_TXRUN: data transmission in progress flag + \arg SDIO_FLAG_RXRUN: data reception in progress flag + \arg SDIO_FLAG_TFH: transmit FIFO is half empty flag: at least 8 words can be written into the FIFO + \arg SDIO_FLAG_RFH: receive FIFO is half full flag: at least 8 words can be read in the FIFO + \arg SDIO_FLAG_TFF: transmit FIFO is full flag + \arg SDIO_FLAG_RFF: receive FIFO is full flag + \arg SDIO_FLAG_TFE: transmit FIFO is empty flag + \arg SDIO_FLAG_RFE: receive FIFO is empty flag + \arg SDIO_FLAG_TXDTVAL: data is valid in transmit FIFO flag + \arg SDIO_FLAG_RXDTVAL: data is valid in receive FIFO flag + \arg SDIO_FLAG_SDIOINT: SD I/O interrupt received flag + \arg SDIO_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus sdio_flag_get(uint32_t flag) +{ + FlagStatus temp_flag = RESET; + if(RESET != (SDIO_STAT & flag)){ + temp_flag = SET; + } + return temp_flag; +} + +/*! + \brief clear the pending flags of SDIO + \param[in] flag: flags state of SDIO + \arg SDIO_FLAG_CCRCERR: command response received (CRC check failed) flag + \arg SDIO_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag + \arg SDIO_FLAG_CMDTMOUT: command response timeout flag + \arg SDIO_FLAG_DTTMOUT: data timeout flag + \arg SDIO_FLAG_TXURE: transmit FIFO underrun error occurs flag + \arg SDIO_FLAG_RXORE: received FIFO overrun error occurs flag + \arg SDIO_FLAG_CMDRECV: command response received (CRC check passed) flag + \arg SDIO_FLAG_CMDSEND: command sent (no response required) flag + \arg SDIO_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag + \arg SDIO_FLAG_STBITE: start bit error in the bus flag + \arg SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag + \arg SDIO_FLAG_SDIOINT: SD I/O interrupt received flag + \arg SDIO_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag + \param[out] none + \retval none +*/ +void sdio_flag_clear(uint32_t flag) +{ + SDIO_INTC = flag; +} + +/*! + \brief enable the SDIO interrupt + \param[in] int_flag: interrupt flags state of SDIO + \arg SDIO_INT_CCRCERR: SDIO CCRCERR interrupt + \arg SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt + \arg SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt + \arg SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt + \arg SDIO_INT_TXURE: SDIO TXURE interrupt + \arg SDIO_INT_RXORE: SDIO RXORE interrupt + \arg SDIO_INT_CMDRECV: SDIO CMDRECV interrupt + \arg SDIO_INT_CMDSEND: SDIO CMDSEND interrupt + \arg SDIO_INT_DTEND: SDIO DTEND interrupt + \arg SDIO_INT_STBITE: SDIO STBITE interrupt + \arg SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt + \arg SDIO_INT_CMDRUN: SDIO CMDRUN interrupt + \arg SDIO_INT_TXRUN: SDIO TXRUN interrupt + \arg SDIO_INT_RXRUN: SDIO RXRUN interrupt + \arg SDIO_INT_TFH: SDIO TFH interrupt + \arg SDIO_INT_RFH: SDIO RFH interrupt + \arg SDIO_INT_TFF: SDIO TFF interrupt + \arg SDIO_INT_RFF: SDIO RFF interrupt + \arg SDIO_INT_TFE: SDIO TFE interrupt + \arg SDIO_INT_RFE: SDIO RFE interrupt + \arg SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt + \arg SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt + \arg SDIO_INT_SDIOINT: SDIO SDIOINT interrupt + \arg SDIO_INT_ATAEND: SDIO ATAEND interrupt + \param[out] none + \retval none +*/ +void sdio_interrupt_enable(uint32_t int_flag) +{ + SDIO_INTEN |= int_flag; +} + +/*! + \brief disable the SDIO interrupt + \param[in] int_flag: interrupt flags state of SDIO + \arg SDIO_INT_CCRCERR: SDIO CCRCERR interrupt + \arg SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt + \arg SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt + \arg SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt + \arg SDIO_INT_TXURE: SDIO TXURE interrupt + \arg SDIO_INT_RXORE: SDIO RXORE interrupt + \arg SDIO_INT_CMDRECV: SDIO CMDRECV interrupt + \arg SDIO_INT_CMDSEND: SDIO CMDSEND interrupt + \arg SDIO_INT_DTEND: SDIO DTEND interrupt + \arg SDIO_INT_STBITE: SDIO STBITE interrupt + \arg SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt + \arg SDIO_INT_CMDRUN: SDIO CMDRUN interrupt + \arg SDIO_INT_TXRUN: SDIO TXRUN interrupt + \arg SDIO_INT_RXRUN: SDIO RXRUN interrupt + \arg SDIO_INT_TFH: SDIO TFH interrupt + \arg SDIO_INT_RFH: SDIO RFH interrupt + \arg SDIO_INT_TFF: SDIO TFF interrupt + \arg SDIO_INT_RFF: SDIO RFF interrupt + \arg SDIO_INT_TFE: SDIO TFE interrupt + \arg SDIO_INT_RFE: SDIO RFE interrupt + \arg SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt + \arg SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt + \arg SDIO_INT_SDIOINT: SDIO SDIOINT interrupt + \arg SDIO_INT_ATAEND: SDIO ATAEND interrupt + \param[out] none + \retval none +*/ +void sdio_interrupt_disable(uint32_t int_flag) +{ + SDIO_INTEN &= ~int_flag; +} + +/*! + \brief get the interrupt flags state of SDIO + \param[in] int_flag: interrupt flags state of SDIO + \arg SDIO_INT_CCRCERR: SDIO CCRCERR interrupt + \arg SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt + \arg SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt + \arg SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt + \arg SDIO_INT_TXURE: SDIO TXURE interrupt + \arg SDIO_INT_RXORE: SDIO RXORE interrupt + \arg SDIO_INT_CMDRECV: SDIO CMDRECV interrupt + \arg SDIO_INT_CMDSEND: SDIO CMDSEND interrupt + \arg SDIO_INT_DTEND: SDIO DTEND interrupt + \arg SDIO_INT_STBITE: SDIO STBITE interrupt + \arg SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt + \arg SDIO_INT_CMDRUN: SDIO CMDRUN interrupt + \arg SDIO_INT_TXRUN: SDIO TXRUN interrupt + \arg SDIO_INT_RXRUN: SDIO RXRUN interrupt + \arg SDIO_INT_TFH: SDIO TFH interrupt + \arg SDIO_INT_RFH: SDIO RFH interrupt + \arg SDIO_INT_TFF: SDIO TFF interrupt + \arg SDIO_INT_RFF: SDIO RFF interrupt + \arg SDIO_INT_TFE: SDIO TFE interrupt + \arg SDIO_INT_RFE: SDIO RFE interrupt + \arg SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt + \arg SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt + \arg SDIO_INT_SDIOINT: SDIO SDIOINT interrupt + \arg SDIO_INT_ATAEND: SDIO ATAEND interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus sdio_interrupt_flag_get(uint32_t int_flag) +{ + FlagStatus temp_flag = RESET; + if(RESET != (SDIO_STAT & int_flag)){ + temp_flag = SET; + } + return temp_flag; +} + +/*! + \brief clear the interrupt pending flags of SDIO + \param[in] int_flag: interrupt flags state of SDIO + \arg SDIO_INT_CCRCERR: command response received (CRC check failed) flag + \arg SDIO_INT_DTCRCERR: data block sent/received (CRC check failed) flag + \arg SDIO_INT_CMDTMOUT: command response timeout flag + \arg SDIO_INT_DTTMOUT: data timeout flag + \arg SDIO_INT_TXURE: transmit FIFO underrun error occurs flag + \arg SDIO_INT_RXORE: received FIFO overrun error occurs flag + \arg SDIO_INT_CMDRECV: command response received (CRC check passed) flag + \arg SDIO_INT_CMDSEND: command sent (no response required) flag + \arg SDIO_INT_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag + \arg SDIO_INT_STBITE: start bit error in the bus flag + \arg SDIO_INT_DTBLKEND: data block sent/received (CRC check passed) flag + \arg SDIO_INT_SDIOINT: SD I/O interrupt received flag + \arg SDIO_INT_ATAEND: CE-ATA command completion signal received (only for CMD61) flag + \param[out] none + \retval none +*/ +void sdio_interrupt_flag_clear(uint32_t int_flag) +{ + SDIO_INTC = int_flag; +} + +/*! + \brief enable the read wait mode(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_readwait_enable(void) +{ + SDIO_DATACTL |= SDIO_DATACTL_RWEN; +} + +/*! + \brief disable the read wait mode(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_readwait_disable(void) +{ + SDIO_DATACTL &= ~SDIO_DATACTL_RWEN; +} + +/*! + \brief enable the function that stop the read wait process(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_stop_readwait_enable(void) +{ + SDIO_DATACTL |= SDIO_DATACTL_RWSTOP; +} + +/*! + \brief disable the function that stop the read wait process(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_stop_readwait_disable(void) +{ + SDIO_DATACTL &= ~SDIO_DATACTL_RWSTOP; +} + +/*! + \brief set the read wait type(SD I/O only) + \param[in] readwait_type: SD I/O read wait type + \arg SDIO_READWAITTYPE_CLK: read wait control by stopping SDIO_CLK + \arg SDIO_READWAITTYPE_DAT2: read wait control using SDIO_DAT[2] + \param[out] none + \retval none +*/ +void sdio_readwait_type_set(uint32_t readwait_type) +{ + if(SDIO_READWAITTYPE_CLK == readwait_type){ + SDIO_DATACTL |= SDIO_DATACTL_RWTYPE; + }else{ + SDIO_DATACTL &= ~SDIO_DATACTL_RWTYPE; + } +} + +/*! + \brief enable the SD I/O mode specific operation(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_operation_enable(void) +{ + SDIO_DATACTL |= SDIO_DATACTL_IOEN; +} + +/*! + \brief disable the SD I/O mode specific operation(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_operation_disable(void) +{ + SDIO_DATACTL &= ~SDIO_DATACTL_IOEN; +} + +/*! + \brief enable the SD I/O suspend operation(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_suspend_enable(void) +{ + SDIO_CMDCTL |= SDIO_CMDCTL_SUSPEND; +} + +/*! + \brief disable the SD I/O suspend operation(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_suspend_disable(void) +{ + SDIO_CMDCTL &= ~SDIO_CMDCTL_SUSPEND; +} + +/*! + \brief enable the CE-ATA command(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_command_enable(void) +{ + SDIO_CMDCTL |= SDIO_CMDCTL_ATAEN; +} + +/*! + \brief disable the CE-ATA command(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_command_disable(void) +{ + SDIO_CMDCTL &= ~SDIO_CMDCTL_ATAEN; +} + +/*! + \brief enable the CE-ATA interrupt(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_interrupt_enable(void) +{ + SDIO_CMDCTL &= ~SDIO_CMDCTL_NINTEN; +} + +/*! + \brief disable the CE-ATA interrupt(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_interrupt_disable(void) +{ + SDIO_CMDCTL |= SDIO_CMDCTL_NINTEN; +} + +/*! + \brief enable the CE-ATA command completion signal(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_command_completion_enable(void) +{ + SDIO_CMDCTL |= SDIO_CMDCTL_ENCMDC; +} + +/*! + \brief disable the CE-ATA command completion signal(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_command_completion_disable(void) +{ + SDIO_CMDCTL &= ~SDIO_CMDCTL_ENCMDC; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c new file mode 100644 index 0000000000..c5947cf174 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c @@ -0,0 +1,811 @@ +/*! + \file gd32f4xx_spi.c + \brief SPI driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.1, firmware for GD32F4xx +*/ + +#include "gd32f4xx_spi.h" +#include "gd32f4xx_rcu.h" + +#define SPI_INIT_MASK ((uint32_t)0x00003040U) +#define I2S_INIT_MASK ((uint32_t)0x0000F047U) +#define I2S_FULL_DUPLEX_MASK ((uint32_t)0x0000F040U) + +/*! + \brief SPI and I2S reset + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5),include I2S1_ADD and I2S2_ADD + \param[out] none + \retval none +*/ +void spi_i2s_deinit(uint32_t spi_periph) +{ + switch(spi_periph){ + case SPI0: + /* reset SPI0 and I2S0 */ + rcu_periph_reset_enable(RCU_SPI0RST); + rcu_periph_reset_disable(RCU_SPI0RST); + break; + case SPI1: + /* reset SPI1,I2S1 and I2S1_ADD */ + rcu_periph_reset_enable(RCU_SPI1RST); + rcu_periph_reset_disable(RCU_SPI1RST); + break; + case SPI2: + /* reset SPI2,I2S2 and I2S2_ADD */ + rcu_periph_reset_enable(RCU_SPI2RST); + rcu_periph_reset_disable(RCU_SPI2RST); + break; + case SPI3: + /* reset SPI3 and I2S3 */ + rcu_periph_reset_enable(RCU_SPI3RST); + rcu_periph_reset_disable(RCU_SPI3RST); + break; + case SPI4: + /* reset SPI4 and I2S4 */ + rcu_periph_reset_enable(RCU_SPI4RST); + rcu_periph_reset_disable(RCU_SPI4RST); + break; + case SPI5: + /* reset SPI5 */ + rcu_periph_reset_enable(RCU_SPI5RST); + rcu_periph_reset_disable(RCU_SPI5RST); + break; + default : + break; + } +} + +/*! + \brief SPI parameter initialization + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_struct: SPI parameter initialization stuct + members of the structure and the member values are shown as below: + device_mode : SPI_MASTER, SPI_SLAVE. + trans_mode : SPI_TRANSMODE_FULLDUPLEX, SPI_TRANSMODE_RECEIVEONLY, + SPI_TRANSMODE_BDRECEIVE, SPI_TRANSMODE_BDTRANSMIT + frame_size : SPI_FRAMESIZE_16BIT, SPI_FRAMESIZE_8BIT + nss: : SPI_NSS_SOFT, SPI_NSS_HARD + endian : SPI_ENDIAN_MSB, SPI_ENDIAN_LSB + clock_polarity_phase : SPI_CK_PL_LOW_PH_1EDGE, SPI_CK_PL_HIGH_PH_1EDGE + SPI_CK_PL_LOW_PH_2EDGE, SPI_CK_PL_HIGH_PH_2EDGE + prescale : SPI_PSC_n (n=2,4,8,16,32,64,128,256) + \param[out] none + \retval none +*/ +void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct) +{ + uint32_t reg = 0U; + reg = SPI_CTL0(spi_periph); + reg &= SPI_INIT_MASK; + + /* (1) select SPI as master or slave */ + reg |= spi_struct->device_mode; + /* (2) select SPI transfer mode */ + reg |= spi_struct->trans_mode; + /* (3) select SPI frame size */ + reg |= spi_struct->frame_size; + /* (4) select SPI nss use hardware or software */ + reg |= spi_struct->nss; + /* (5) select SPI LSB or MSB */ + reg |= spi_struct->endian; + /* (6) select SPI polarity and phase */ + reg |= spi_struct->clock_polarity_phase; + /* (7) select SPI prescale to adjust transmit speed */ + reg |= spi_struct->prescale; + + /* write to SPI_CTL0 register */ + SPI_CTL0(spi_periph) = (uint32_t)reg; + + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL); +} + +/*! + \brief SPI enable + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_enable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN; +} + +/*! + \brief SPI disable + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_disable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN); +} + +/*! + \brief I2S prescale config + \param[in] spi_periph: SPIx(x=0,1,2,3,4) + \param[in] audiosample: + \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: + \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: + \arg I2S_MCKOUT_ENABLE: I2S master clock output enable + \arg I2S_MCKOUT_DISABLE: I2S master clock output disable + \param[out] none + \retval none +*/ +void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_frameformat, uint32_t i2s_mckout) +{ + uint32_t temp_div = 2U, temp_of = 0U; + uint32_t temp = 0U; + uint32_t i2sclock = 0U; + +#ifndef I2S_EXTERNAL_CLOCK_IN + uint32_t plli2sm = 0U, plli2sn = 0U, plli2sr = 0U; +#endif /* I2S_EXTERNAL_CLOCK_IN */ + + /* deinit SPI_I2SPSC register */ + SPI_I2SPSC(spi_periph) = 0x0002U; + +#ifdef I2S_EXTERNAL_CLOCK_IN + rcu_i2s_clock_config(RCU_I2SSRC_I2S_CKIN); + + /* set the I2S clock to the external clock input value */ + i2sclock = I2S_EXTERNAL_CLOCK_IN; +#else + + /* turn on the oscillator HXTAL */ + rcu_osci_on(RCU_HXTAL); + /* wait for oscillator stabilization flags is SET */ + rcu_osci_stab_wait(RCU_HXTAL); + /* turn on the PLLI2S */ + rcu_osci_on(RCU_PLLI2S_CK); + /* wait for PLLI2S flags is SET */ + rcu_osci_stab_wait(RCU_PLLI2S_CK); + /* configure the I2S clock source selection */ + rcu_i2s_clock_config(RCU_I2SSRC_PLLI2S); + + /* get the RCU_PLL_PLLPSC value */ + plli2sm = (uint32_t)(RCU_PLL & RCU_PLL_PLLPSC); + /* get the RCU_PLLI2S_PLLI2SN value */ + plli2sn = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SN) >> 6); + /* get the RCU_PLLI2S_PLLI2SR value */ + plli2sr = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SR) >> 28); + + if((RCU_PLL & RCU_PLL_PLLSEL) == RCU_PLLSRC_HXTAL) + { + /* get the I2S source clock value */ + i2sclock = (uint32_t)(((HXTAL_VALUE / plli2sm) * plli2sn) / plli2sr); + } + else + { /* get the I2S source clock value */ + i2sclock = (uint32_t)(((IRC16M_VALUE / plli2sm) * plli2sn) / plli2sr); + } +#endif /* I2S_EXTERNAL_CLOCK_IN */ + + /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */ + if(I2S_MCKOUT_ENABLE == i2s_mckout){ + temp = (uint32_t)(((i2sclock / 256U) * 10U) / i2s_audiosample); + }else{ + if(I2S_FRAMEFORMAT_DT16B_CH16B == i2s_frameformat){ + temp = (uint32_t)(((i2sclock / 32U) *10U ) / i2s_audiosample); + }else{ + temp = (uint32_t)(((i2sclock / 64U) *10U ) / i2s_audiosample); + } + } + /* remove the floating point */ + temp = (temp + 5U) / 10U; + temp_of = (temp & 0x00000001U); + temp_div = ((temp - temp_of) / 2U); + temp_of = (temp_of << 8); + + /* set the default values */ + if((temp_div< 2U) || (temp_div > 255U)){ + temp_div = 2U; + temp_of = 0U; + } + + /* configure SPI_I2SPSC */ + SPI_I2SPSC(spi_periph) = (uint32_t)(temp_div | temp_of | i2s_mckout); + + /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN|SPI_I2SCTL_CHLEN)); + /* configure data frame format */ + SPI_I2SCTL(spi_periph) |= (uint32_t)i2s_frameformat; +} + +/*! + \brief I2S parameter configuration + \param[in] spi_periph: SPIx(x=0,1,2,3,4) + \param[in] i2s_mode: + \arg I2S_MODE_SLAVETX : I2S slave transmit mode + \arg I2S_MODE_SLAVERX : I2S slave receive mode + \arg I2S_MODE_MASTERTX : I2S master transmit mode + \arg I2S_MODE_MASTERRX : I2S master receive mode + \param[in] i2s_std: + \arg I2S_STD_PHILLIPS : I2S phillips standard + \arg I2S_STD_MSB : I2S MSB standard + \arg I2S_STD_LSB : I2S LSB standard + \arg I2S_STD_PCMSHORT : I2S PCM short standard + \arg I2S_STD_PCMLONG : I2S PCM long standard + \param[in] i2s_ckpl: + \arg I2S_CKPL_LOW : I2S clock polarity low level + \arg I2S_CKPL_HIGH : I2S clock polarity high level + \param[out] none + \retval none +*/ +void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl) +{ + uint32_t reg= 0U; + reg = SPI_I2SCTL(spi_periph); + reg &= I2S_INIT_MASK; + + /* enable I2S mode */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)i2s_mode; + /* select I2S standard */ + reg |= (uint32_t)i2s_standard; + /* select I2S polarity */ + reg |= (uint32_t)i2s_ckpl; + + /* write to SPI_I2SCTL register */ + SPI_I2SCTL(spi_periph) = (uint32_t)reg; +} + +/*! + \brief I2S enable + \param[in] spi_periph: SPIx(x=0,1,2,3,4) + \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,1,2,3,4) + \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,3,4,5) + \param[out] none + \retval none +*/ +void spi_nss_output_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV; +} + +/*! + \brief SPI nss output disable + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_nss_output_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV); +} + +/*! + \brief SPI nss pin high level in software mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_nss_internal_high(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS; +} + +/*! + \brief SPI nss pin low level in software mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_nss_internal_low(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS); +} + +/*! + \brief SPI dma send or receive enable + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_dma: + \arg SPI_DMA_TRANSMIT: enable DMA transmit + \arg SPI_DMA_RECEIVE: enable DMA receive + \param[out] none + \retval none +*/ +void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma) +{ + if(SPI_DMA_TRANSMIT == spi_dma){ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN; + }else{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN; + } +} + +/*! + \brief SPI dma send or receive diable + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_dma: + \arg SPI_DMA_TRANSMIT: disable DMA transmit + \arg SPI_DMA_RECEIVE: disable DMA receive + \param[out] none + \retval none +*/ +void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma) +{ + if(SPI_DMA_TRANSMIT == spi_dma){ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN); + }else{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN); + } +} + +/*! + \brief configure SPI/I2S data frame format + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] frame_format: + \arg SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits + \arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits + \param[out] none + \retval none +*/ +void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format) +{ + /* clear SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16); + /* confige SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) |= (uint32_t)frame_format; +} + +/*! + \brief SPI transmit data + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] data: 16-bit data + \param[out] none + \retval none +*/ +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data) +{ + SPI_DATA(spi_periph) = (uint32_t)data; +} + +/*! + \brief receive data + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval 16-bit data +*/ +uint16_t spi_i2s_data_receive(uint32_t spi_periph) +{ + return ((uint16_t)SPI_DATA(spi_periph)); +} + +/*! + \brief configure SPI bidirectional transfer direction + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] transfer_direction: + \arg SPI_BIDIRECTIONAL_TEANSMIT: 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_TEANSMIT == transfer_direction){ + /* set the transmit only mode */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TEANSMIT; + }else{ + /* set the receive only mode */ + SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE; + } +} + +/*! + \brief SPI and I2S interrupt enable + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_i2s_int: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error, + transmission underrun error and format error interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t spi_i2s_int) +{ + switch(spi_i2s_int){ + case SPI_I2S_INT_TBE: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE; + break; + case SPI_I2S_INT_RBNE: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE; + break; + case SPI_I2S_INT_ERR: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE; + break; + default: + break; + } +} + +/*! + \brief SPI and I2S interrupt disable + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_i2s_int: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error, + transmission underrun error and format error interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t spi_i2s_int) +{ + switch(spi_i2s_int){ + case SPI_I2S_INT_TBE : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE); + break; + case SPI_I2S_INT_RBNE : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE); + break; + case SPI_I2S_INT_ERR : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE); + break; + default : + break; + } +} + +/*! + \brief get interrupt flag status + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_i2s_int: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_RXORERR: overrun interrupt + \arg SPI_INT_CONFERR: config error interrupt + \arg SPI_INT_CRCERR: CRC error interrupt + \arg I2S_INT_TXURERR: underrun error interrupt + \arg SPI_I2S_INT_FERR: format error interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t spi_i2s_int) +{ + uint32_t reg1 = SPI_STAT(spi_periph); + uint32_t reg2 = SPI_CTL1(spi_periph); + + uint32_t temp1 = 0U; + uint32_t temp2 = 0U; + + switch(spi_i2s_int){ + case SPI_I2S_INT_TBE : + temp1 = reg1 & SPI_STAT_TBE; + temp2 = reg2 & SPI_CTL1_TBEIE; + break; + case SPI_I2S_INT_RBNE : + temp1 = reg1 & SPI_STAT_RBNE; + temp2 = reg2 & SPI_CTL1_RBNEIE; + break; + case SPI_I2S_INT_RXORERR : + temp1 = reg1 & SPI_STAT_RXORERR; + temp2 = reg2 & SPI_CTL1_ERRIE; + break; + case SPI_INT_CONFERR : + temp1 = reg1 & SPI_STAT_CONFERR; + temp2 = reg2 & SPI_CTL1_ERRIE; + break; + case SPI_INT_CRCERR : + temp1 = reg1 & SPI_STAT_CRCERR; + temp2 = reg2 & SPI_CTL1_ERRIE; + break; + case I2S_INT_TXURERR : + temp1 = reg1 & SPI_STAT_TXURERR; + temp2 = reg2 & SPI_CTL1_ERRIE; + break; + case SPI_I2S_INT_FERR : + temp1 = reg1 & SPI_STAT_FERR; + temp2 = reg2 & SPI_CTL1_ERRIE; + break; + default : + break; + } + + if(temp1 && temp2){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get flag status + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_i2s_flag: + \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 flag + \arg SPI_FLAG_CONFERR: mode config error flag + \arg SPI_FLAG_CRCERR: CRC error flag + \arg SPI_FLAG_FERR: format error interrupt 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 flag + \arg I2S_FLAG_TXURERR: underrun error flag + \arg I2S_FLAG_CH: channel side flag + \arg I2S_FLAG_FERR: format error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t spi_i2s_flag) +{ + if(SPI_STAT(spi_periph) & spi_i2s_flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear SPI CRC error flag status + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_error_clear(uint32_t spi_periph) +{ + SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR); +} + +/*! + \brief CRC function turn on + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_on(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; +} + +/*! + \brief CRC function turn off + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_off(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN); +} + +/*! + \brief CRC polynomial set + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] crc_poly: CRC polynomial value + \param[out] none + \retval none +*/ +void spi_crc_polynomial_set(uint32_t spi_periph,uint16_t crc_poly) +{ + /* enable SPI CRC */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; + + /* set SPI CRC polynomial */ + SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly; +} + +/*! + \brief get SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval 16-bit CRC polynomial +*/ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph) +{ + return ((uint16_t)SPI_CRCPOLY(spi_periph)); +} + +/*! + \brief SPI next data is CRC value + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_next(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT; +} + +/*! + \brief get SPI CRC send value or receive value + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_crc: + \arg SPI_CRC_TX: get transmit crc value + \arg SPI_CRC_RX: get receive crc value + \param[out] none + \retval 16-bit CRC value +*/ +uint16_t spi_crc_get(uint32_t spi_periph,uint8_t spi_crc) +{ + if(SPI_CRC_TX == spi_crc){ + return ((uint16_t)(SPI_TCRC(spi_periph))); + }else{ + return ((uint16_t)(SPI_RCRC(spi_periph))); + } +} + +/*! + \brief enable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_ti_mode_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD; +} + +/*! + \brief disable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_ti_mode_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD); +} + +/*! + \brief configure i2s full duplex mode + \param[in] i2s_add_periph: I2Sx_ADD(x=1,2) + \param[in] i2s_mode: + \arg I2S_MODE_SLAVETX : I2S slave transmit mode + \arg I2S_MODE_SLAVERX : I2S slave receive mode + \arg I2S_MODE_MASTERTX : I2S master transmit mode + \arg I2S_MODE_MASTERRX : I2S master receive mode + \param[in] i2s_standard: + \arg I2S_STD_PHILLIPS : I2S phillips standard + \arg I2S_STD_MSB : I2S MSB standard + \arg I2S_STD_LSB : I2S LSB standard + \arg I2S_STD_PCMSHORT : I2S PCM short standard + \arg I2S_STD_PCMLONG : I2S PCM long standard + \param[in] i2s_ckpl: + \arg I2S_CKPL_LOW : I2S clock polarity low level + \arg I2S_CKPL_HIGH : I2S clock polarity high level + \param[in] i2s_frameformat: + \arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit + \arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit + \param[out] none + \retval none +*/ +void i2s_full_duplex_mode_config(uint32_t i2s_add_periph, uint32_t i2s_mode, uint32_t i2s_standard, + uint32_t i2s_ckpl, uint32_t i2s_frameformat) +{ + uint32_t reg = 0U, tmp = 0U; + + reg = I2S_ADD_I2SCTL(i2s_add_periph); + reg &= I2S_FULL_DUPLEX_MASK; + + /* get the mode of the extra I2S module I2Sx_ADD */ + if((I2S_MODE_MASTERTX == i2s_mode) || (I2S_MODE_SLAVETX == i2s_mode)){ + tmp = I2S_MODE_SLAVERX; + }else{ + tmp = I2S_MODE_SLAVETX; + } + + /* enable I2S mode */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)tmp; + /* select I2S standard */ + reg |= (uint32_t)i2s_standard; + /* select I2S polarity */ + reg |= (uint32_t)i2s_ckpl; + /* configure data frame format */ + reg |= (uint32_t)i2s_frameformat; + + /* write to SPI_I2SCTL register */ + I2S_ADD_I2SCTL(i2s_add_periph) = (uint32_t)reg; +} + +/*! + \brief quad wire SPI enable + \param[in] spi_periph: SPIx(only x=5) + \param[out] none + \retval none +*/ +void qspi_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD; +} + +/*! + \brief quad wire SPI disable + \param[in] spi_periph: SPIx(only x=5) + \param[out] none + \retval none +*/ +void qspi_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD); +} + +/*! + \brief quad wire SPI write enable + \param[in] spi_periph: SPIx(only x=5) + \param[out] none + \retval none +*/ +void qspi_write_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD); +} + +/*! + \brief quad wire SPI read enable + \param[in] spi_periph: SPIx(only x=5) + \param[out] none + \retval none +*/ +void qspi_read_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD; +} + +/*! + \brief SPI_IO2 and SPI_IO3 pin output enable + \param[in] spi_periph: SPIx(only x=5) + \param[out] none + \retval none +*/ +void qspi_io23_output_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV; +} + + /*! + \brief SPI_IO2 and SPI_IO3 pin output disable + \param[in] spi_periph: SPIx(only x=5) + \param[out] none + \retval none +*/ + void qspi_io23_output_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV); +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c new file mode 100644 index 0000000000..d834462aba --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c @@ -0,0 +1,172 @@ +/*! + \file gd32f4xx_syscfg.c + \brief SYSCFG driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_syscfg.h" + +/*! + \brief reset the SYSCFG registers + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_deinit(void) +{ + rcu_periph_reset_enable(RCU_SYSCFGRST); + rcu_periph_reset_disable(RCU_SYSCFGRST); +} + +/*! + \brief configure the boot mode + \param[in] syscfg_bootmode: selects the memory remapping + \arg SYSCFG_BOOTMODE_FLASH: main flash memory (0x08000000~0x083BFFFF) is mapped at address 0x00000000 + \arg SYSCFG_BOOTMODE_BOOTLOADER: boot loader (0x1FFF0000 - 0x1FFF77FF) is mapped at address 0x00000000 + \arg SYSCFG_BOOTMODE_EXMC_SRAM: SRAM/NOR 0 and 1 of EXMC (0x60000000~0x67FFFFFF) is mapped at address 0x00000000 + \arg SYSCFG_BOOTMODE_SRAM: SRAM0 of on-chip SRAM (0x20000000~0x2001BFFF) is mapped at address 0x00000000 + \arg SYSCFG_BOOTMODE_EXMC_SDRAM: SDRAM bank0 of EXMC (0xC0000000~0xC7FFFFFF) is mapped at address 0x00000000 + \param[out] none + \retval none +*/ +void syscfg_bootmode_config(uint8_t syscfg_bootmode) +{ + /* reset the SYSCFG_CFG0_BOOT_MODE bit and set according to syscfg_bootmode */ + SYSCFG_CFG0 &= ~SYSCFG_CFG0_BOOT_MODE; + SYSCFG_CFG0 |= (uint32_t)syscfg_bootmode; +} + +/*! + \brief FMC memory mapping swap + \param[in] syscfg_fmc_swap: selects the interal flash bank swapping + \arg SYSCFG_FMC_SWP_BANK0: bank 0 is mapped at address 0x08000000 and bank 1 is mapped at address 0x08100000 + \arg SYSCFG_FMC_SWP_BANK1: bank 1 is mapped at address 0x08000000 and bank 0 is mapped at address 0x08100000 + \param[out] none + \retval none +*/ +void syscfg_fmc_swap_config(uint32_t syscfg_fmc_swap) +{ + uint32_t reg; + reg = SYSCFG_CFG0; + /* reset the FMC_SWP bit and set according to syscfg_fmc_swap */ + reg &= ~SYSCFG_CFG0_FMC_SWP; + SYSCFG_CFG0 = (reg | syscfg_fmc_swap); +} + +/*! + \brief EXMC memory mapping swap + \param[in] syscfg_exmc_swap: selects the memories in EXMC swapping + \arg SYSCFG_EXMC_SWP_ENABLE: SDRAM bank 0 and bank 1 are swapped with NAND bank 1 and PC card + \arg SYSCFG_EXMC_SWP_DISABLE: no memory mapping swap + \param[out] none + \retval none +*/ +void syscfg_exmc_swap_config(uint32_t syscfg_exmc_swap) +{ + uint32_t reg; + + reg = SYSCFG_CFG0; + /* reset the SYSCFG_CFG0_EXMC_SWP bits and set according to syscfg_exmc_swap */ + reg &= ~SYSCFG_CFG0_EXMC_SWP; + SYSCFG_CFG0 = (reg | syscfg_exmc_swap); +} + +/*! + \brief configure the GPIO pin as EXTI Line + \param[in] exti_port: specify the GPIO port used in EXTI + \arg EXTI_SOURCE_GPIOx(x = A,B,C,D,E,F,G,H,I): EXTI GPIO port + \param[in] exti_pin: specify the EXTI line + \arg EXTI_SOURCE_PINx(x = 0..15): EXTI GPIO pin + \param[out] none + \retval none +*/ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin) +{ + uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin))); + uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin)); + + switch(exti_pin/EXTI_SS_JSTEP){ + case EXTISS0: + /* clear EXTI source line(0..3) */ + SYSCFG_EXTISS0 &= clear_exti_mask; + /* configure EXTI soure line(0..3) */ + SYSCFG_EXTISS0 |= config_exti_mask; + break; + case EXTISS1: + /* clear EXTI soure line(4..7) */ + SYSCFG_EXTISS1 &= clear_exti_mask; + /* configure EXTI soure line(4..7) */ + SYSCFG_EXTISS1 |= config_exti_mask; + break; + case EXTISS2: + /* clear EXTI soure line(8..11) */ + SYSCFG_EXTISS2 &= clear_exti_mask; + /* configure EXTI soure line(8..11) */ + SYSCFG_EXTISS2 |= config_exti_mask; + break; + case EXTISS3: + /* clear EXTI soure line(12..15) */ + SYSCFG_EXTISS3 &= clear_exti_mask; + /* configure EXTI soure line(12..15) */ + SYSCFG_EXTISS3 |= config_exti_mask; + break; + default: + break; + } +} + +/*! + \brief configure the PHY interface for the ethernet MAC + \param[in] syscfg_enet_phy_interface: specifies the media interface mode. + \arg SYSCFG_ENET_PHY_MII: MII mode is selected + \arg SYSCFG_ENET_PHY_RMII: RMII mode is selected + \param[out] none + \retval none +*/ +void syscfg_enet_phy_interface_config(uint32_t syscfg_enet_phy_interface) +{ + uint32_t reg; + + reg = SYSCFG_CFG1; + /* reset the ENET_PHY_SEL bit and set according to syscfg_enet_phy_interface */ + reg &= ~SYSCFG_CFG1_ENET_PHY_SEL; + SYSCFG_CFG1 = (reg | syscfg_enet_phy_interface); +} + +/*! + \brief configure the I/O compensation cell + \param[in] syscfg_compensation: specifies the I/O compensation cell mode + \arg SYSCFG_COMPENSATION_ENABLE: I/O compensation cell is enabled + \arg SYSCFG_COMPENSATION_DISABLE: I/O compensation cell is disabled + \param[out] none + \retval none +*/ +void syscfg_compensation_config(uint32_t syscfg_compensation) +{ + uint32_t reg; + + reg = SYSCFG_CPSCTL; + /* reset the SYSCFG_CPSCTL_CPS_EN bit and set according to syscfg_compensation */ + reg &= ~SYSCFG_CPSCTL_CPS_EN; + SYSCFG_CPSCTL = (reg | syscfg_compensation); +} + +/*! + \brief checks whether the I/O compensation cell ready flag is set or not + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET + */ +FlagStatus syscfg_flag_get(void) +{ + if(((uint32_t)RESET) != (SYSCFG_CPSCTL & SYSCFG_CPSCTL_CPS_RDY)){ + return SET; + }else{ + return RESET; + } +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c new file mode 100644 index 0000000000..04c8fab0d3 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c @@ -0,0 +1,1892 @@ +/*! + \file gd32f4xx_timer.c + \brief TIMER driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_timer.h" + +/*! + \brief deinit a TIMER + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval none +*/ +void timer_deinit(uint32_t timer_periph) +{ + switch(timer_periph){ + case TIMER0: + /* reset TIMER0 */ + rcu_periph_reset_enable(RCU_TIMER0RST); + rcu_periph_reset_disable(RCU_TIMER0RST); + break; + case TIMER1: + /* reset TIMER1 */ + rcu_periph_reset_enable(RCU_TIMER1RST); + rcu_periph_reset_disable(RCU_TIMER1RST); + break; + case TIMER2: + /* reset TIMER2 */ + rcu_periph_reset_enable(RCU_TIMER2RST); + rcu_periph_reset_disable(RCU_TIMER2RST); + break; + case TIMER3: + /* reset TIMER3 */ + rcu_periph_reset_enable(RCU_TIMER3RST); + rcu_periph_reset_disable(RCU_TIMER3RST); + break; + case TIMER4: + /* reset TIMER4 */ + rcu_periph_reset_enable(RCU_TIMER4RST); + rcu_periph_reset_disable(RCU_TIMER4RST); + break; + case TIMER5: + /* reset TIMER5 */ + rcu_periph_reset_enable(RCU_TIMER5RST); + rcu_periph_reset_disable(RCU_TIMER5RST); + break; + case TIMER6: + /* reset TIMER6 */ + rcu_periph_reset_enable(RCU_TIMER6RST); + rcu_periph_reset_disable(RCU_TIMER6RST); + break; + case TIMER7: + /* reset TIMER7 */ + rcu_periph_reset_enable(RCU_TIMER7RST); + rcu_periph_reset_disable(RCU_TIMER7RST); + break; + case TIMER8: + /* reset TIMER8 */ + rcu_periph_reset_enable(RCU_TIMER8RST); + rcu_periph_reset_disable(RCU_TIMER8RST); + break; + case TIMER9: + /* reset TIMER9 */ + rcu_periph_reset_enable(RCU_TIMER9RST); + rcu_periph_reset_disable(RCU_TIMER9RST); + break; + case TIMER10: + /* reset TIMER10 */ + rcu_periph_reset_enable(RCU_TIMER10RST); + rcu_periph_reset_disable(RCU_TIMER10RST); + break; + case TIMER11: + /* reset TIMER11 */ + rcu_periph_reset_enable(RCU_TIMER11RST); + rcu_periph_reset_disable(RCU_TIMER11RST); + break; + case TIMER12: + /* reset TIMER12 */ + rcu_periph_reset_enable(RCU_TIMER12RST); + rcu_periph_reset_disable(RCU_TIMER12RST); + break; + case TIMER13: + /* reset TIMER13 */ + rcu_periph_reset_enable(RCU_TIMER13RST); + rcu_periph_reset_disable(RCU_TIMER13RST); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER counter + \param[in] timer_periph: TIMERx(x=0..13) + \param[in] timer_initpara: init parameter struct + prescaler: prescaler value of the counter clock,0~65535 + alignedmode: TIMER_COUNTER_EDGE,TIMER_COUNTER_CENTER_DOWN,TIMER_COUNTER_CENTER_UP,TIMER_COUNTER_CENTER_BOTH + counterdirection: TIMER_COUNTER_UP,TIMER_COUNTER_DOWN + period: counter auto reload value,(TIMER1,TIMER4,32 bit) + clockdivision: TIMER_CKDIV_DIV1,TIMER_CKDIV_DIV2,TIMER_CKDIV_DIV4 + repetitioncounter: counter repetition value,0~255 + \param[out] none + \retval none +*/ +void timer_init(uint32_t timer_periph, timer_parameter_struct* timer_initpara) +{ + /* configure the counter prescaler value */ + TIMER_PSC(timer_periph) = (uint16_t)timer_initpara->prescaler; + + /* configure the counter direction and aligned mode */ + if((TIMER0 == timer_periph) || (TIMER1 == timer_periph) || (TIMER2 == timer_periph) + || (TIMER3 == timer_periph) || (TIMER4 == timer_periph) || (TIMER7 == timer_periph)){ + TIMER_CTL0(timer_periph) &= ~(uint32_t)(TIMER_CTL0_DIR|TIMER_CTL0_CAM); + TIMER_CTL0(timer_periph) |= (uint32_t)timer_initpara->alignedmode; + TIMER_CTL0(timer_periph) |= (uint32_t)timer_initpara->counterdirection; + } + + /* configure the autoreload value */ + TIMER_CAR(timer_periph) = (uint32_t)timer_initpara->period; + + if((TIMER5 != timer_periph) && (TIMER6 != timer_periph)){ + /* reset the CKDIV bit */ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CKDIV; + TIMER_CTL0(timer_periph) |= (uint32_t)timer_initpara->clockdivision; + } + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){ + /* configure the repetition counter value */ + TIMER_CREP(timer_periph) = (uint32_t)timer_initpara->repetitioncounter; + } + + /* generate an update event */ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; +} + +/*! + \brief enable a TIMER + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval none +*/ +void timer_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief disable a TIMER + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval none +*/ +void timer_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief enable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief disable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief enable the update event + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval none +*/ +void timer_update_event_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPDIS; +} + +/*! + \brief disable the update event + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval none +*/ +void timer_update_event_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_CTL0_UPDIS; +} + +/*! + \brief set TIMER counter alignment mode + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[in] timer_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 timer_aligned) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CAM; + TIMER_CTL0(timer_periph) |= (uint32_t)timer_aligned; +} + +/*! + \brief set TIMER counter up direction + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_counter_up_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief set TIMER counter down direction + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_counter_down_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief configure TIMER prescaler + \param[in] timer_periph: TIMERx(x=0..13) + \param[in] timer_prescaler: prescaler value + \param[in] timer_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 timer_prescaler,uint8_t timer_pscreload) +{ + TIMER_PSC(timer_periph) = (uint32_t)timer_prescaler; + + if(TIMER_PSC_RELOAD_NOW == timer_pscreload){ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; + } +} + +/*! + \brief configure TIMER repetition register value + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] timer_repetition: the counter repetition value,0~255 + \param[out] none + \retval none +*/ +void timer_repetition_value_config(uint32_t timer_periph,uint16_t timer_repetition) +{ + TIMER_CREP(timer_periph) = (uint32_t)timer_repetition; +} + +/*! + \brief configure TIMER autoreload register value + \param[in] timer_periph: TIMERx(x=0..13) + \param[in] timer_autoreload: the counter auto-reload value + \param[out] none + \retval none +*/ +void timer_autoreload_value_config(uint32_t timer_periph,uint32_t timer_autoreload) +{ + TIMER_CAR(timer_periph) = (uint32_t)timer_autoreload; +} + +/*! + \brief configure TIMER counter register value + \param[in] timer_periph: TIMERx(x=0..13) + \param[in] timer_counter: the counter value + \param[out] none + \retval none +*/ +void timer_counter_value_config(uint32_t timer_periph , uint32_t timer_counter) +{ + TIMER_CNT(timer_periph) = (uint32_t)timer_counter; +} + +/*! + \brief read TIMER counter value + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval counter value +*/ +uint32_t timer_counter_read(uint32_t timer_periph) +{ + uint32_t count_value = 0U; + count_value = TIMER_CNT(timer_periph); + return (count_value); +} + +/*! + \brief read TIMER prescaler value + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval prescaler register value +*/ +uint16_t timer_prescaler_read(uint32_t timer_periph) +{ + uint16_t prescaler_value = 0U; + prescaler_value = (uint16_t)(TIMER_CAR(timer_periph)); + return (prescaler_value); +} + +/*! + \brief configure TIMER single pulse mode + \param[in] timer_periph: TIMERx(x=0..8,11) + \param[in] timer_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 timer_spmode) +{ + if(TIMER_SP_MODE_SINGLE == timer_spmode){ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_SPM; + }else if(TIMER_SP_MODE_REPETITIVE == timer_spmode){ + TIMER_CTL0(timer_periph) &= ~((uint32_t)TIMER_CTL0_SPM); + }else{ + } +} + +/*! + \brief configure TIMER update source + \param[in] timer_periph: TIMERx(x=0..13) + \param[in] timer_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 timer_update) +{ + if(TIMER_UPDATE_SRC_REGULAR == timer_update){ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS; + }else if(timer_update == TIMER_UPDATE_SRC_GLOBAL){ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS; + }else{ + } +} + +/*! + \brief enable the TIMER interrupt + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_interrupt: timer interrupt enable source + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0..13) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4,7..13) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4,7) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4,7) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,7) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_interrupt_enable(uint32_t timer_periph,uint32_t timer_interrupt) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) timer_interrupt; +} + +/*! + \brief disable the TIMER interrupt + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_interrupt: timer interrupt source enable + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0..13) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4,7..13) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4,7) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4,7) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,7) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_interrupt_disable(uint32_t timer_periph,uint32_t timer_interrupt) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)timer_interrupt); +} + +/*! + \brief get timer interrupt flag + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_interrupt: the timer interrupt bits + \arg TIMER_INT_UP: update interrupt flag,TIMERx(x=0..13) + \arg TIMER_INT_CH0: channel 0 interrupt flag,TIMERx(x=0..4,7..13) + \arg TIMER_INT_CH1: channel 1 interrupt flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_CH2: channel 2 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_CH3: channel 3 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_CMT: channel commutation interrupt flag,TIMERx(x=0,7) + \arg TIMER_INT_TRG: trigger interrupt flag,TIMERx(x=0,7,8,11) + \arg TIMER_INT_BRK: break interrupt flag,TIMERx(x=0,7) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph,uint32_t timer_interrupt) +{ + uint32_t val; + val = (TIMER_DMAINTEN(timer_periph) & timer_interrupt); + if((RESET != (TIMER_INTF(timer_periph) & timer_interrupt) ) && (RESET != val)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER interrupt flag + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_interrupt: the timer interrupt bits + \arg TIMER_INT_UP: update interrupt flag,TIMERx(x=0..13) + \arg TIMER_INT_CH0: channel 0 interrupt flag,TIMERx(x=0..4,7..13) + \arg TIMER_INT_CH1: channel 1 interrupt flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_CH2: channel 2 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_CH3: channel 3 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_CMT: channel commutation interrupt flag,TIMERx(x=0,7) + \arg TIMER_INT_TRG: trigger interrupt flag,TIMERx(x=0,7,8,11) + \arg TIMER_INT_BRK: break interrupt flag,TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph,uint32_t timer_interrupt) +{ + TIMER_INTF(timer_periph) &= (~(uint32_t)timer_interrupt); +} + +/*! + \brief get TIMER flags + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_flag: the timer interrupt flags + \arg TIMER_FLAG_UP: update flag,TIMERx(x=0..13) + \arg TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0..4,7..13) + \arg TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CMT: channel control update flag,TIMERx(x=0,7) + \arg TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,7,8,11) + \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,7) + \arg TIMER_FLAG_CH0OF: channel 0 overcapture flag,TIMERx(x=0..4,7..11) + \arg TIMER_FLAG_CH1OF: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2OF: channel 2 overcapture flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3OF: channel 3 overcapture flag,TIMERx(x=0..4,7) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_flag_get(uint32_t timer_periph , uint32_t timer_flag) +{ + if(RESET != (TIMER_INTF(timer_periph) & timer_flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER flags + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_flag: the timer interrupt flags + \arg TIMER_FLAG_UP: update flag,TIMERx(x=0..13) + \arg TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0..4,7..13) + \arg TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CMT: channel control update flag,TIMERx(x=0,7) + \arg TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,7,8,11) + \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,7) + \arg TIMER_FLAG_CH0OF: channel 0 overcapture flag,TIMERx(x=0..4,7..11) + \arg TIMER_FLAG_CH1OF: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2OF: channel 2 overcapture flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3OF: channel 3 overcapture flag,TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_flag_clear(uint32_t timer_periph , uint32_t timer_flag) +{ + TIMER_INTF(timer_periph) &= (~(uint32_t)timer_flag); +} + +/*! + \brief enable the TIMER DMA + \param[in] timer_periph: TIMERx(x=0,1,2,5,14,15,16) + \param[in] timer_dma: timer DMA source enable + \arg TIMER_DMA_UPD: update DMA enable,TIMERx(x=0..7) + \arg TIMER_DMA_CH0D: channel 0 DMA enable,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH1D: channel 1 DMA enable,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH2D: channel 2 DMA enable,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH3D: channel 3 DMA enable,TIMERx(x=0..4,7) + \arg TIMER_DMA_CMTD: commutation DMA request enable,TIMERx(x=0,7) + \arg TIMER_DMA_TRGD: trigger DMA enable,TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_dma_enable(uint32_t timer_periph,uint16_t timer_dma) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) timer_dma; +} + +/*! + \brief disable the TIMER DMA + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_dma: timer DMA source enable + \arg TIMER_DMA_UPD: update DMA enable,TIMERx(x=0..7) + \arg TIMER_DMA_CH0D: channel 0 DMA enable,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH1D: channel 1 DMA enable,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH2D: channel 2 DMA enable,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH3D: channel 3 DMA enable,TIMERx(x=0..4,7) + \arg TIMER_DMA_CMTD: commutation DMA request enable,TIMERx(x=0,7) + \arg TIMER_DMA_TRGD: trigger DMA enable,TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_dma_disable(uint32_t timer_periph,uint16_t timer_dma) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(timer_dma)); +} + +/*! + \brief channel DMA request source selection + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[in] dma_request: channel DMA request source selection + \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: please refer to the following parameters + \param[in] dma_baseaddr: + \arg TIMER_DMACFG_DMATA_CTL0: DMA transfer address is TIMER_CTL0,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP,TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP,TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_DMACFG: DMA transfer address is TIMER_DMACFG,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_DMATB: DMA transfer address is TIMER_DMATB,TIMERx(x=0..4,7) + \param[in] dma_lenth: + \arg TIMER_DMACFG_DMATC_xTRANSFER(x=1..18): DMA transfer x time + \param[out] none + \retval none +*/ +void timer_dma_transfer_config(uint32_t timer_periph,uint32_t dma_baseaddr,uint32_t dma_lenth) +{ + TIMER_DMACFG(timer_periph) &= (~(uint32_t)(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC)); + TIMER_DMACFG(timer_periph) |= (uint32_t)(dma_baseaddr | dma_lenth); +} + +/*! + \brief software generate events + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_event: the timer software event generation sources + \arg TIMER_EVENT_SRC_UPG: update event,TIMERx(x=0..13) + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation,TIMERx(x=0..4,7..13) + \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation,TIMERx(x=0..4,7,8,11) + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation,TIMERx(x=0..4,7) + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation,TIMERx(x=0..4,7) + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation,TIMERx(x=0,7) + \arg TIMER_EVENT_SRC_TRGG: trigger event generation,TIMERx(x=0..4,7,8,11) + \arg TIMER_EVENT_SRC_BRKG: break event generation,TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_event_software_generate(uint32_t timer_periph,uint16_t timer_event) +{ + TIMER_SWEVG(timer_periph) |= (uint32_t)timer_event; +} + +/*! + \brief configure TIMER break function + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] timer_bkdtpara: 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* timer_bkdtpara) +{ + TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(timer_bkdtpara->runoffstate))| + ((uint32_t)(timer_bkdtpara->ideloffstate))| + ((uint32_t)(timer_bkdtpara->deadtime))| + ((uint32_t)(timer_bkdtpara->breakpolarity))| + ((uint32_t)(timer_bkdtpara->outputautostate)) | + ((uint32_t)(timer_bkdtpara->protectmode))| + ((uint32_t)(timer_bkdtpara->breakstate))) ; +} + +/*! + \brief enable TIMER break function + \param[in] timer_periph: TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_break_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief disable TIMER break function + \param[in] timer_periph: TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_break_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief enable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_automatic_output_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief disable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_automatic_output_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief configure TIMER primary output function + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_primary_output_config(uint32_t timer_periph,ControlStatus newvalue) +{ + if(ENABLE == newvalue){ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_POEN; + }else{ + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_POEN); + } +} + +/*! + \brief channel capture/compare control shadow register enable + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_config(uint32_t timer_periph,ControlStatus newvalue) +{ + if(ENABLE == newvalue){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCSE; + }else{ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCSE); + } +} + +/*! + \brief configure TIMER channel control shadow register update control + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] timer_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 timer_ccuctl) +{ + if(TIMER_UPDATECTL_CCU == timer_ccuctl){ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC); + }else if(TIMER_UPDATECTL_CCUTRI == timer_ccuctl){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC; + }else{ + } +} + +/*! + \brief configure TIMER channel output function + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4,7)) + \param[in] timer_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 timer_channel,timer_oc_parameter_struct* timer_ocpara) +{ + switch(timer_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)timer_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)timer_ocpara->ocpolarity; + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){ + /* reset the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); + /* set the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_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)timer_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)timer_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)timer_ocpara->ocnidlestate; + } + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH0MS; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(timer_ocpara->outputstate<< 4U); + /* reset the CH1P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + /* set the CH1P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocpolarity)<< 4U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){ + /* reset the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); + /* set the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->outputnstate)<< 4U); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocnpolarity)<< 4U); + /* reset the ISO1 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1); + /* set the ISO1 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocidlestate)<< 2U); + /* reset the ISO1N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1N); + /* set the ISO1N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocnidlestate)<< 2U); + } + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH1MS; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(timer_ocpara->outputstate<< 8U); + /* reset the CH2P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + /* set the CH2P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocpolarity)<< 8U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){ + /* reset the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); + /* set the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->outputnstate)<< 8U); + /* reset the CH2NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP); + /* set the CH2NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocnpolarity)<< 8U); + /* reset the ISO2 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2); + /* set the ISO2 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocidlestate)<< 4U); + /* reset the ISO2N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2N); + /* set the ISO2N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocnidlestate)<< 4U); + } + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH2MS; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &=(~(uint32_t)TIMER_CHCTL2_CH3EN); + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(timer_ocpara->outputstate<< 12U); + /* reset the CH3P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + /* set the CH3P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocpolarity)<< 12U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){ + /* reset the ISO3 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3); + /* set the ISO3 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_ocpara->ocidlestate)<< 6U); + } + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH3MS; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output compare mode + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] timer_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 timer_channel,uint16_t timer_ocmode) +{ + switch(timer_channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_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)(timer_ocmode)<< 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)timer_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)(timer_ocmode)<< 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output pulse value + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] timer_pluse: channel output pulse value + \param[out] none + \retval none +*/ +void timer_channel_output_pulse_value_config(uint32_t timer_periph,uint16_t timer_channel,uint32_t timer_pluse) +{ + switch(timer_channel){ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = (uint32_t)timer_pluse; + break; + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = (uint32_t)timer_pluse; + break; + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = (uint32_t)timer_pluse; + break; + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = (uint32_t)timer_pluse; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output shadow function + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] timer_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 timer_channel,uint16_t timer_ocshadow) +{ + switch(timer_channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_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)(timer_ocshadow) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)timer_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)(timer_ocshadow) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output fast function + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] timer_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 timer_channel,uint16_t timer_ocfast) +{ + switch(timer_channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_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)timer_ocfast << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)timer_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)timer_ocfast << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output clear function + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0 + \arg TIMER_CH_1: TIMER channel1 + \arg TIMER_CH_2: TIMER channel2 + \arg TIMER_CH_3: TIMER channel3 + \param[in] timer_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 timer_channel,uint16_t timer_occlear) +{ + switch(timer_channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_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)timer_occlear << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)timer_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)timer_occlear << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output polarity + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] timer_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 timer_channel,uint16_t timer_ocpolarity) +{ + switch(timer_channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_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)timer_ocpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocpolarity << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocpolarity << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output polarity + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \param[in] timer_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 timer_channel,uint16_t timer_ocnpolarity) +{ + switch(timer_channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_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)timer_ocnpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocnpolarity << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel enable state + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] timer_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 timer_channel,uint32_t timer_state) +{ + switch(timer_channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_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)timer_state << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_state << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_state << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output enable state + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0 + \arg TIMER_CH_1: TIMER channel1 + \arg TIMER_CH_2: TIMER channel2 + \param[in] timer_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 timer_channel,uint16_t timer_ocnstate) +{ + switch(timer_channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)timer_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)timer_ocnstate << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)timer_ocnstate << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER input capture parameter + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] timer_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 timer_channel,timer_ic_parameter_struct* timer_icpara) +{ + switch(timer_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)(timer_icpara->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(timer_icpara->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icfilter) << 4U); + + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + break; + + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icpolarity)<< 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icselection)<< 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icfilter)<< 12U); + + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + + /* reset the CH2P and CH2NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P|TIMER_CHCTL2_CH2NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icpolarity)<< 8U); + + /* reset the CH2MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icselection)); + + /* reset the CH2CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icfilter)<< 4U); + + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + + /* reset the CH3P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH3P)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icpolarity)<< 12U); + + /* reset the CH3MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icselection)<< 8U); + + /* reset the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(timer_icpara->icfilter)<< 12U); + + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN; + break; + default: + break; + } + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph,timer_channel,(uint16_t)(timer_icpara->icprescaler)); +} + +/*! + \brief configure TIMER channel input capture prescaler value + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] timer_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 timer_channel,uint16_t timer_prescaler) +{ + switch(timer_channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC); + TIMER_CHCTL0(timer_periph) |= (uint32_t)timer_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)timer_prescaler << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPPSC); + TIMER_CHCTL1(timer_periph) |= (uint32_t)timer_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)timer_prescaler << 8U); + break; + default: + break; + } +} + +/*! + \brief read TIMER channel capture compare register value + \param[in] timer_periph: please refer to the following parameters + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[out] none + \retval channel capture compare register value +*/ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph,uint16_t timer_channel) +{ + uint32_t count_value = 0U; + + switch(timer_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..4,7,8,11) + \param[in] timer_channel: + \arg TIMER_CH_0: TIMER channel0 + \arg TIMER_CH_1: TIMER channel1 + \param[in] timer_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 timer_channel,timer_ic_parameter_struct* timer_icpwm) +{ + uint16_t icpolarity = 0x0U; + uint16_t icselection = 0x0U; + + if(TIMER_IC_POLARITY_RISING == timer_icpwm->icpolarity){ + icpolarity = TIMER_IC_POLARITY_FALLING; + }else{ + icpolarity = TIMER_IC_POLARITY_RISING; + } + + if(TIMER_IC_SELECTION_DIRECTTI == timer_icpwm->icselection){ + icselection = TIMER_IC_SELECTION_INDIRECTTI; + }else{ + icselection = TIMER_IC_SELECTION_DIRECTTI; + } + + if(TIMER_CH_0 == timer_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)(timer_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)(timer_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)(timer_icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_0,(uint16_t)(timer_icpwm->icprescaler)); + + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpolarity<< 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icselection<< 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpwm->icfilter)<< 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_1,(uint16_t)(timer_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)(timer_icpwm->icpolarity)<< 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpwm->icselection)<< 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(timer_icpwm->icfilter)<< 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_1,(uint16_t)(timer_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)(timer_icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_0,(uint16_t)(timer_icpwm->icprescaler)); + } +} + +/*! + \brief configure TIMER hall sensor mode + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[in] timer_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 timer_hallmode) +{ + if(TIMER_HALLINTERFACE_ENABLE == timer_hallmode){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_TI0S; + }else if(TIMER_HALLINTERFACE_DISABLE == timer_hallmode){ + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_TI0S; + }else{ + } +} + +/*! + \brief select TIMER input trigger source + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] timer_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 timer_intrigger) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_TRGS); + TIMER_SMCFG(timer_periph) |= (uint32_t)timer_intrigger; +} + +/*! + \brief select TIMER master mode output trigger source + \param[in] timer_periph: TIMERx(x=0..7) + \param[in] timer_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_CC0: 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 timer_outrigger) +{ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_MMC); + TIMER_CTL1(timer_periph) |= (uint32_t)timer_outrigger; +} + +/*! + \brief select TIMER slave mode + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] timer_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 timer_slavemode) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + + TIMER_SMCFG(timer_periph) |= (uint32_t)timer_slavemode; +} + +/*! + \brief configure TIMER master slave mode + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] timer_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 timer_masterslave) +{ + if(TIMER_MASTER_SLAVE_MODE_ENABLE == timer_masterslave){ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_MSM; + }else if(TIMER_MASTER_SLAVE_MODE_DISABLE == timer_masterslave){ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_MSM; + }else{ + } +} + +/*! + \brief configure TIMER external trigger input + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[in] timer_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] timer_expolarity: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] timer_extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_config(uint32_t timer_periph,uint32_t timer_extprescaler, + uint32_t timer_expolarity,uint32_t timer_extfilter) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_ETP|TIMER_SMCFG_ETPSC|TIMER_SMCFG_ETFC)); + TIMER_SMCFG(timer_periph) |= (uint32_t)(timer_extprescaler|timer_expolarity); + TIMER_SMCFG(timer_periph) |= (uint32_t)(timer_extfilter<< 8U); +} + +/*! + \brief configure TIMER quadrature decoder mode + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] timer_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] timer_ic0polarity: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[in] timer_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 timer_decomode, + uint16_t timer_ic0polarity,uint16_t timer_ic1polarity) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + TIMER_SMCFG(timer_periph) |= (uint32_t)timer_decomode; + + TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS))&((~(uint32_t)TIMER_CHCTL0_CH1MS))); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI|((uint32_t)TIMER_IC_SELECTION_DIRECTTI<< 8U)); + + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)timer_ic0polarity|((uint32_t)timer_ic1polarity<< 4U)); +} + +/*! + \brief configure TIMER internal clock mode + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[out] none + \retval none +*/ +void timer_internal_clock_config(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; +} + +/*! + \brief configure TIMER the internal trigger as external clock input + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] timer_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 timer_intrigger) +{ + timer_input_trigger_source_select(timer_periph,timer_intrigger); + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external trigger as external clock input + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] timer_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] timer_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] timer_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 timer_extrigger, + uint16_t timer_expolarity,uint32_t timer_extfilter) +{ + if(TIMER_SMCFG_TRGSEL_CI1FE1 == timer_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)timer_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)(timer_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)timer_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)timer_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,timer_extrigger); + /* reset the SMC bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + /* set the SMC bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external clock mode0 + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] timer_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] timer_expolarity: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] timer_extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode0_config(uint32_t timer_periph,uint32_t timer_extprescaler, + uint32_t timer_expolarity,uint32_t timer_extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph,timer_extprescaler,timer_expolarity,timer_extfilter); + + /* reset the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_SMC | TIMER_SMCFG_TRGS)); + /* set the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)(TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_ETIFP); +} + +/*! + \brief configure TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[in] timer_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] timer_expolarity: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] timer_extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_config(uint32_t timer_periph,uint32_t timer_extprescaler, + uint32_t timer_expolarity,uint32_t timer_extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph,timer_extprescaler,timer_expolarity,timer_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 TIMER1 channel0 remap function + \param[in] timer_periph: TIMERx(x=1,4,10) + \param[in] timer_remap: + \arg TIMER1_ITI1_RMP_TIMER7_TRGO: timer1 internal trigger input1 remap to TIMER7_TRGO + \arg TIMER1_ITI1_RMP_ETHERNET_PTP: timer1 internal trigger input1 remap to ethernet PTP + \arg TIMER1_ITI1_RMP_USB_FS_SOF: timer1 internal trigger input1 remap to USB FS SOF + \arg TIMER1_ITI1_RMP_USB_HS_SOF: timer1 internal trigger input1 remap to USB HS SOF + \arg TIMER4_CI3_RMP_GPIO: timer4 channel 3 input remap to GPIO pin + \arg TIMER4_CI3_RMP_IRC32K: timer4 channel 3 input remap to IRC32K + \arg TIMER4_CI3_RMP_LXTAL: timer4 channel 3 input remap to LXTAL + \arg TIMER4_CI3_RMP_RTC_WAKEUP_INT: timer4 channel 3 input remap to RTC wakeup interrupt + \arg TIMER10_ITI1_RMP_GPIO: timer10 internal trigger input1 remap based on GPIO setting + \arg TIMER10_ITI1_RMP_RTC_HXTAL_DIV: timer10 internal trigger input1 remap HXTAL _DIV(clock used for RTC which is HXTAL clock divided by RTCDIV bits in RCU_CFG0 register) + \param[out] none + \retval none +*/ +void timer_channel_remap_config(uint32_t timer_periph,uint32_t timer_remap) +{ + TIMER_IRMP(timer_periph) = (uint32_t)timer_remap; +} + +/*! + \brief configure TIMER write CHxVAL register selection + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] timer_ccsel: + \arg TIMER_CCSEL_DISABLE: no effect + \arg TIMER_CCSEL_ENABLE: if write the CHxVAL register, the write value is same as the CHxVAL value, the write access ignored + \param[out] none + \retval none +*/ +void timer_write_cc_register_config(uint32_t timer_periph, uint16_t timer_ccsel) +{ + if(TIMER_CCSEL_ENABLE == timer_ccsel){ + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CHVSEL; + }else if(TIMER_CCSEL_DISABLE == timer_ccsel){ + TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_CHVSEL; + }else{ + } +} + +/*! + \brief configure TIMER output value selection + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] timer_outsel: + \arg TIMER_OUTSEL_DISABLE: no effect + \arg TIMER_OUTSEL_ENABLE: if POEN and IOS is 0, the output disabled + \param[out] none + \retval none +*/ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t timer_outsel) +{ + if(TIMER_OUTSEL_ENABLE == timer_outsel){ + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_OUTSEL; + }else if(TIMER_OUTSEL_DISABLE == timer_outsel){ + TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_OUTSEL; + }else{ + } +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c new file mode 100644 index 0000000000..dfa65744ba --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c @@ -0,0 +1,443 @@ +/*! + \file gd32f4xx_tli.c + \brief TLI driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.1, firmware for GD32F4xx +*/ + +#include "gd32f4xx_tli.h" + +/*! + \brief deinitialize TLI registers + \param[in] none + \param[out] none + \retval none +*/ +void tli_deinit(void) +{ + rcu_periph_reset_enable(RCU_TLIRST); + rcu_periph_reset_disable(RCU_TLIRST); +} + +/*! + \brief initialize TLI display timing parameters + \param[in] tli_struct: the data needed to initialize tli. + synpsz_vpsz: size of the vertical synchronous pulse + synpsz_hpsz: size of the horizontal synchronous pulse + backpsz_vbpsz: size of the vertical back porch plus synchronous pulse + backpsz_hbpsz: size of the horizontal back porch plus synchronous pulse + activesz_vasz: size of the vertical active area width plus back porch and synchronous pulse + activesz_hasz: size of the horizontal active area width plus back porch and synchronous pulse + totalsz_vtsz: vertical total size of the display, including active area, back porch, synchronous + totalsz_htsz: vorizontal total size of the display, including active area, back porch, synchronous + backcolor_red: background value red + backcolor_green: background value green + backcolor_blue: background value blue + signalpolarity_hs: TLI_HSYN_ACTLIVE_LOW,TLI_HSYN_ACTLIVE_HIGHT + signalpolarity_vs: TLI_VSYN_ACTLIVE_LOW,TLI_VSYN_ACTLIVE_HIGHT + signalpolarity_de: TLI_DE_ACTLIVE_LOW,TLI_DE_ACTLIVE_HIGHT + signalpolarity_pixelck: TLI_PIXEL_CLOCK_TLI,TLI_PIXEL_CLOCK_INVERTEDTLI + \param[out] none + \retval none +*/ +void tli_init(tli_parameter_struct *tli_struct) +{ + /* synchronous pulse size configuration */ + TLI_SPSZ &= ~(TLI_SPSZ_VPSZ|TLI_SPSZ_HPSZ); + TLI_SPSZ = (tli_struct->synpsz_vpsz|(tli_struct->synpsz_hpsz<<16U)); + /* back-porch size configuration */ + TLI_BPSZ &= ~(TLI_BPSZ_VBPSZ|TLI_BPSZ_HBPSZ); + TLI_BPSZ = (tli_struct->backpsz_vbpsz|(tli_struct->backpsz_hbpsz<<16U)); + /* active size configuration */ + TLI_ASZ &= ~(TLI_ASZ_VASZ|TLI_ASZ_HASZ); + TLI_ASZ = (tli_struct->activesz_vasz|(tli_struct->activesz_hasz<<16U)); + /* total size configuration */ + TLI_TSZ &= ~(TLI_TSZ_VTSZ|TLI_TSZ_HTSZ); + TLI_TSZ = (tli_struct->totalsz_vtsz|(tli_struct->totalsz_htsz<<16U)); + /* background color configuration */ + TLI_BGC &= ~(TLI_BGC_BVB|(TLI_BGC_BVG)|(TLI_BGC_BVR)); + TLI_BGC = (tli_struct->backcolor_blue|(tli_struct->backcolor_green<<8U)|(tli_struct->backcolor_red<<16U)); + TLI_CTL &= ~(TLI_CTL_HPPS|TLI_CTL_VPPS|TLI_CTL_DEPS|TLI_CTL_CLKPS); + TLI_CTL |= (tli_struct->signalpolarity_hs|tli_struct->signalpolarity_vs|\ + tli_struct->signalpolarity_de|tli_struct->signalpolarity_pixelck); + +} + +/*! + \brief dither function configure + \param[in] ditherstat: TLI_DITHER_ENABLE,TLI_DITHER_DISABLE + \param[out] none + \retval none +*/ +void tli_dither_config(uint8_t ditherstat) +{ + if(TLI_DITHER_ENABLE == ditherstat){ + TLI_CTL |= TLI_CTL_DFEN; + }else{ + TLI_CTL &= ~(TLI_CTL_DFEN); + } +} + +/*! + \brief TLI enable + \param[in] none. + \param[out] none + \retval none +*/ +void tli_enable(void) +{ + TLI_CTL |= TLI_CTL_TLIEN; +} + +/*! + \brief TLI disable + \param[in] none. + \param[out] none + \retval none +*/ +void tli_disable(void) +{ + TLI_CTL &= ~(TLI_CTL_DFEN); +} + +/*! + \brief TLI reload layer configure + \param[in] reloadmod: TLI_FRAME_BLANK_RELOAD_EN,TLI_REQUEST_RELOAD_EN + \param[out] none + \retval none +*/ +void tli_reload_config(uint8_t reloadmod) +{ + if(TLI_FRAME_BLANK_RELOAD_EN == reloadmod){ + TLI_RL |= TLI_RL_FBR; + }else{ + TLI_RL |= TLI_RL_RQR; + } +} + +/*! + \brief TLI interrupt enable + \param[in] inttype: TLI interrupt bits. + \arg TLI_INTEN_LMIE: line mark interrupt + \arg TLI_INTEN_FEIE: FIFO error interrupt + \arg TLI_INTEN_TEIE: transaction error interrupt + \arg TLI_INTEN_LCRIE: layer configuration reloaded interrupt + \param[out] none + \retval none +*/ +void tli_interrupt_enable(uint32_t inttype) +{ + TLI_INTEN |= (inttype); +} + +/*! + \brief TLI interrupt disable + \param[in] inttype: TLI interrupt bits. + \arg TLI_INTEN_LMIE: line mark interrupt + \arg TLI_INTEN_FEIE: FIFO error interrupt + \arg TLI_INTEN_TEIE: transaction error interrupt + \arg TLI_INTEN_LCRIE: layer configuration reloaded interrupt + \param[out] none + \retval none +*/ +void tli_interrupt_disable(uint32_t inttype) +{ + TLI_INTEN &= ~(inttype); +} + +/*! + \brief get TLI interrupt flag + \param[in] intflag: TLI interrupt flag bits. + \arg TLI_INTF_LMF: line mark flag + \arg TLI_INTF_FEF: FIFO error flag + \arg TLI_INTF_TEF: transaction error flag + \arg TLI_INTF_LCRF: layer configuration reloaded flag + \param[out] none + \retval none +*/ +FlagStatus tli_interrupt_flag_get(uint32_t intflag) +{ + uint32_t state; + state = TLI_INTF; + if(state & intflag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TLI interrupt flag + \param[in] intflag: TLI interrupt flag bits. + \arg TLI_INTC_LMC: line mark flag + \arg TLI_INTC_FEC: FIFO error flag + \arg TLI_INTC_TEC: transaction error flag + \arg TLI_INTC_LCRC: layer configuration reloaded flag + \param[out] none + \retval none +*/ +void tli_interrupt_flag_clear(uint32_t intflag) +{ + TLI_INTC |= (intflag); +} + +/*! + \brief set line mark value + \param[in] linenum: line number. + \param[out] none + \retval none +*/ +void tli_line_mark_set(uint32_t linenum) +{ + TLI_LM &= ~(TLI_LM_LM); + TLI_LM = linenum; +} + +/*! + \brief get current displayed position + \param[in] none + \param[out] none + \retval none +*/ +uint32_t tli_current_pos_get(void) +{ + return TLI_CPPOS; +} + + +/*! + \brief get TLI state + \param[in] state: TLI state. + \arg TLI_STAT_VDE: current VDE state + \arg TLI_STAT_HDE: current HDE state + \arg TLI_STAT_VS: current vs state + \arg TLI_STAT_HS: current hs state + \param[out] none + \retval none +*/ +FlagStatus tli_flag_get(uint32_t state) +{ + uint32_t stat; + stat = TLI_STAT; + if(state & stat){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief TLI layer enable + \param[in] layerx: LAYERx(x=0,1). + \param[out] none + \retval none +*/ +void tli_layer_enable(uint32_t layerx) +{ + TLI_LxCTL(layerx) |= TLI_LxCTL_LEN; +} + +/*! + \brief TLI layer disable + \param[in] layerx: LAYERx(x=0,1). + \param[out] none + \retval none +*/ +void tli_layer_disable(uint32_t layerx) +{ + TLI_LxCTL(layerx) &= ~(TLI_LxCTL_LEN); +} + +/*! + \brief TLI layer color keying enable + \param[in] layerx: LAYERx(x=0,1). + \param[out] none + \retval none +*/ +void tli_color_key_enable(uint32_t layerx) +{ + TLI_LxCTL(layerx) |= TLI_LxCTL_CKEYEN; +} + +/*! + \brief TLI layer color keying disable + \param[in] layerx: LAYERx(x=0,1). + \param[out] none + \retval none +*/ +void tli_color_key_disable(uint32_t layerx) +{ + TLI_LxCTL(layerx) &= ~(TLI_LxCTL_CKEYEN); +} + +/*! + \brief TLI layer LUT enable + \param[in] layerx: LAYERx(x=0,1). + \param[out] none + \retval none +*/ +void tli_lut_enable(uint32_t layerx) +{ + TLI_LxCTL(layerx) |= TLI_LxCTL_LUTEN; +} + +/*! + \brief TLI layer LUT disable + \param[in] layerx: LAYERx(x=0,1). + \param[out] none + \retval none +*/ +void tli_lut_disable(uint32_t layerx) +{ + TLI_LxCTL(layerx) &= ~(TLI_LxCTL_LUTEN); +} + +/*! + \brief TLI layer initialize + \param[in] layerx: LAYERx(x=0,1) + \param[in] layer_struct: TLI Layer parameter struct + layer_window_rightpos: window right position + layer_window_leftpos: window left position + layer_window_bottompos: window bottom position + layer_window_toppos: window top position + layer_ppf: LAYER_PPF_ARGB8888,LAYER_PPF_RGB888,LAYER_PPF_RGB565, + LAYER_PPF_ARG1555,LAYER_PPF_ARGB4444,LAYER_PPF_L8, + LAYER_PPF_AL44,LAYER_PPF_AL88 + layer_sa: specified alpha + layer_default_alpha: the default color alpha + layer_default_red: the default color red + layer_default_green: the default color green + layer_default_blue: the default color blue + layer_acf1: LAYER_ACF1_SA,LAYER_ACF1_PASA + layer_acf2: LAYER_ACF2_SA,LAYER_ACF2_PASA + layer_frame_bufaddr: frame buffer base address + layer_frame_buf_stride_offset: frame buffer stride offset + layer_frame_line_length: frame line length + layer_frame_total_line_number: frame total line number + \param[out] none + \retval none +*/ +void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct) +{ + /* configure layer window horizontal position */ + TLI_LxHPOS(layerx) &= ~(TLI_LxHPOS_WLP|(TLI_LxHPOS_WRP)); + TLI_LxHPOS(layerx) = (layer_struct->layer_window_leftpos | (layer_struct->layer_window_rightpos<<16U)); + /* configure layer window vertical position */ + TLI_LxVPOS(layerx) &= ~(TLI_LxVPOS_WTP|(TLI_LxVPOS_WBP)); + TLI_LxVPOS(layerx) = (layer_struct->layer_window_toppos |(layer_struct->layer_window_bottompos<<16U)); + /* configure layer packeted pixel format */ + TLI_LxPPF(layerx) &= ~(TLI_LxPPF_PPF); + TLI_LxPPF(layerx) = layer_struct->layer_ppf; + /* configure layer specified alpha */ + TLI_LxSA(layerx) &= ~(TLI_LxSA_SA); + TLI_LxSA(layerx) = layer_struct->layer_sa; + /* configure layer default color */ + TLI_LxDC(layerx) &= ~(TLI_LxDC_DCB|(TLI_LxDC_DCG)|(TLI_LxDC_DCR)|(TLI_LxDC_DCA)); + TLI_LxDC(layerx) = (layer_struct->layer_default_blue |(layer_struct->layer_default_green<<8U) + |(layer_struct->layer_default_red<<16U) + |(layer_struct->layer_default_alpha<<24U)); + + /* configure layer alpha calculation factors */ + TLI_LxBLEND(layerx) &= ~(TLI_LxBLEND_ACF2|(TLI_LxBLEND_ACF1)); + TLI_LxBLEND(layerx) = ((layer_struct->layer_acf2)|(layer_struct->layer_acf1)); + /* configure layer frame buffer base address */ + TLI_LxFBADDR(layerx) &= ~(TLI_LxFBADDR_FBADD); + TLI_LxFBADDR(layerx) = (layer_struct->layer_frame_bufaddr); + /* configure layer frame line length */ + TLI_LxFLLEN(layerx) &= ~(TLI_LxFLLEN_FLL|(TLI_LxFLLEN_STDOFF)); + TLI_LxFLLEN(layerx) = (layer_struct->layer_frame_line_length|(layer_struct->layer_frame_buf_stride_offset<<16U)); + /* configure layer frame buffer base address */ + TLI_LxFBADDR(layerx) &= ~(TLI_LxFBADDR_FBADD); + TLI_LxFBADDR(layerx) = (layer_struct->layer_frame_bufaddr); + /* configure layer frame total line number */ + TLI_LxFTLN(layerx) &= ~(TLI_LxFTLN_FTLN); + TLI_LxFTLN(layerx) = (layer_struct->layer_frame_total_line_number); + +} + +/*! + \brief reconfigure window position + \param[in] layerx: LAYERx(x=0,1). + \param[in] offset_x: new horizontal offset . + \param[in] offset_y: new vertical offset. + \param[out] none + \retval none +*/ +void tli_layer_window_offset_modify(uint32_t layerx,uint32_t offset_x,uint32_t offset_y) +{ + /* configure window start position */ + uint32_t layer_ppf,line_length,line_num,hstart,vstart; + TLI_LxHPOS(layerx) &= ~(TLI_LxHPOS_WLP|(TLI_LxHPOS_WRP)); + TLI_LxVPOS(layerx) &= ~(TLI_LxVPOS_WTP|(TLI_LxVPOS_WBP)); + hstart = offset_x+(((TLI_BPSZ & TLI_BPSZ_HBPSZ)>>16U)+1U); + vstart = offset_y+((TLI_BPSZ & TLI_BPSZ_VBPSZ)+1U); + line_num = (TLI_LxFTLN(layerx) & TLI_LxFTLN_FTLN); + layer_ppf = (TLI_LxPPF(layerx) & TLI_LxPPF_PPF); + /* the bytes of a line equal TLI_LxFLLEN_FLL bits value minus 3 */ + switch(layer_ppf){ + case LAYER_PPF_ARGB8888: + /* each pixel includes 4bytes,when pixel format is ARGB8888 */ + line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)/4U); + break; + case LAYER_PPF_RGB888: + /* each pixel includes 3bytes,when pixel format is RGB888 */ + line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)/3U); + break; + case LAYER_PPF_RGB565: + case LAYER_PPF_ARGB1555: + case LAYER_PPF_ARGB4444: + case LAYER_PPF_AL88: + /* each pixel includes 2bytes,when pixel format is RGB565,ARG1555,ARGB4444 or AL88 */ + line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)/2U); + break; + case LAYER_PPF_L8: + case LAYER_PPF_AL44: + /* each pixel includes 1byte,when pixel format is L8 or AL44 */ + line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)); + break; + default: + break; + } + /* reconfigure window position */ + TLI_LxHPOS(layerx) = (hstart|((hstart+line_length-1U)<<16U)); + TLI_LxVPOS(layerx) = (vstart|((vstart+line_num-1U)<<16U)); + + +} + +/*! + \brief TLI layer lut initialize + \param[in] layerx: LAYERx(x=0,1) + \param[in] lut_struct: TLI layer LUT parameter struct + layer_table_addr: window right position + layer_lut_channel_red: window left position + layer_window_bottompos: window bottom position + layer_window_toppos: window top position + \param[out] none + \retval none +*/ +void tli_lut_init(uint32_t layerx,tli_layer_lut_parameter_struct *lut_struct) +{ + TLI_LxLUT(layerx) &= ~(TLI_LxLUT_TB|TLI_LxLUT_TG|TLI_LxLUT_TR|TLI_LxLUT_TADD); + TLI_LxLUT(layerx) = ((lut_struct->layer_lut_channel_blue)|(lut_struct->layer_lut_channel_green<<8) + |(lut_struct->layer_lut_channel_red<<16 + |(lut_struct->layer_table_addr<<24))); +} + +/*! + \brief TLI layer key initialize + \param[in] layerx: LAYERx(x=0,1). + \param[in] redkey: color key red. + \param[in] greenkey: color key green + \param[in] bluekey: color key blue. + \param[out] none + \retval none +*/ +void tli_ckey_init(uint32_t layerx,uint32_t redkey,uint32_t greenkey,uint32_t bluekey) +{ + TLI_LxCKEY(layerx) = ((bluekey)|(greenkey<<8U)|(redkey<<16U)); +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c new file mode 100644 index 0000000000..f0defdcd51 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c @@ -0,0 +1,144 @@ +/*! + \file gd32f4xx_trng.c + \brief TRNG driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_trng.h" + +/*! + \brief deinitialize the TRNG + \param[in] none + \param[out] none + \retval none +*/ +void trng_deinit(void) +{ + rcu_periph_reset_enable(RCU_TRNGRST); + rcu_periph_reset_disable(RCU_TRNGRST); +} + +/*! + \brief enable the TRNG interface + \param[in] none + \param[out] none + \retval none +*/ +void trng_enable(void) +{ + TRNG_CTL |= TRNG_CTL_TRNGEN; +} + +/*! + \brief disable the TRNG interface + \param[in] none + \param[out] none + \retval none +*/ +void trng_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_TRNGEN; +} + +/*! + \brief get the true random data + \param[in] none + \param[out] none + \retval the generated random data +*/ +uint32_t trng_get_true_random_data(void) +{ + return (TRNG_DATA); +} + +/*! + \brief get the trng status flags + \param[in] flag: trng status flag, refer to trng_flag_enum + only one parameter can be selected which is shown as below: + \arg TRNG_FLAG_DRDY: Random Data ready status + \arg TRNG_FLAG_CECS: Clock error current status + \arg TRNG_FLAG_SECS: Seed error current status + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus trng_flag_get(trng_flag_enum flag) +{ + if(RESET != (TRNG_STAT & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the trng status flags + \param[in] flag: the special status flag + only one parameter can be selected which is shown as below: + \arg TRNG_FLAG_CECS: Clock error current status + \arg TRNG_FLAG_SECS: Seed error current status + \param[out] none + \retval none +*/ +void trng_flag_clear(trng_flag_enum flag) +{ + TRNG_STAT &= ~(uint32_t)flag; +} + +/*! + \brief enable the TRNG interrupt + \param[in] none + \param[out] none + \retval none +*/ +void trng_interrupt_enable(void) +{ + TRNG_CTL |= TRNG_CTL_IE; +} + +/*! + \brief disable the TRNG interrupt + \param[in] none + \param[out] none + \retval none +*/ +void trng_interrupt_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_IE; +} + +/*! + \brief get the trng interrupt flags + \param[in] int_flag: trng interrupt flag, refer to trng_int_flag_enum + only one parameter can be selected which is shown as below: + \arg TRNG_INT_FLAG_CEIF: clock error interrupt flag + \arg TRNG_INT_FLAG_SEIF: Seed error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag) +{ + if(RESET != (TRNG_STAT & int_flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the trng interrupt flags + \param[in] int_flag: trng interrupt flag, refer to trng_int_flag_enum + only one parameter can be selected which is shown as below: + \arg TRNG_INT_FLAG_CEIF: clock error interrupt flag + \arg TRNG_INT_FLAG_SEIF: Seed error interrupt flag + \param[out] none + \retval none +*/ +void trng_interrupt_flag_clear(trng_int_flag_enum int_flag) +{ + TRNG_STAT &= ~(uint32_t)int_flag; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c new file mode 100644 index 0000000000..945e60bc73 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c @@ -0,0 +1,952 @@ +/*! + \file gd32f4xx_usart.c + \brief USART driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_usart.h" + +/*! + \brief reset USART/UART + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_deinit(uint32_t usart_periph) +{ + switch(usart_periph){ + case USART0: + rcu_periph_reset_enable(RCU_USART0RST); + rcu_periph_reset_disable(RCU_USART0RST); + break; + case USART1: + rcu_periph_reset_enable(RCU_USART1RST); + rcu_periph_reset_disable(RCU_USART1RST); + break; + case USART2: + rcu_periph_reset_enable(RCU_USART2RST); + rcu_periph_reset_disable(RCU_USART2RST); + break; + case USART5: + rcu_periph_reset_enable(RCU_USART5RST); + rcu_periph_reset_disable(RCU_USART5RST); + break; + case UART3: + rcu_periph_reset_enable(RCU_UART3RST); + rcu_periph_reset_disable(RCU_UART3RST); + break; + case UART4: + rcu_periph_reset_enable(RCU_UART4RST); + rcu_periph_reset_disable(RCU_UART4RST); + break; + case UART6: + rcu_periph_reset_enable(RCU_UART6RST); + rcu_periph_reset_disable(RCU_UART6RST); + break; + case UART7: + rcu_periph_reset_enable(RCU_UART7RST); + rcu_periph_reset_disable(RCU_UART7RST); + break; + default: + break; + } +} + +/*! + \brief configure USART baud rate value + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] baudval: baud rate value + \param[out] none + \retval none +*/ +void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval) +{ + uint32_t uclk=0U, intdiv=0U, fradiv=0U, udiv=0U; + switch(usart_periph){ + /* get clock frequency */ + case USART0: + uclk=rcu_clock_freq_get(CK_APB2); + break; + case USART5: + uclk=rcu_clock_freq_get(CK_APB2); + break; + case USART1: + uclk=rcu_clock_freq_get(CK_APB1); + break; + case USART2: + uclk=rcu_clock_freq_get(CK_APB1); + break; + case UART3: + uclk=rcu_clock_freq_get(CK_APB1); + break; + case UART4: + uclk=rcu_clock_freq_get(CK_APB1); + break; + case UART6: + uclk=rcu_clock_freq_get(CK_APB1); + break; + case UART7: + uclk=rcu_clock_freq_get(CK_APB1); + break; + default: + break; + } + if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD){ + /* when oversampling by 8, configure the value of USART_BAUD */ + udiv = ((2U*uclk) + baudval/2U)/baudval; + intdiv = udiv & 0xfff0U; + fradiv = udiv & 0x7U; + USART_BAUD(usart_periph) |= ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + }else{ + /* when oversampling by 16, configure the value of USART_BAUD */ + udiv = (uclk+baudval/2U)/baudval; + intdiv = udiv & 0xfff0U; + fradiv = udiv & 0xfU; + USART_BAUD(usart_periph) |= ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } +} + +/*! + \brief configure USART parity function + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] paritycfg: configure USART parity + \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) +{ + /* clear USART_CTL0 PM,PCEN Bits */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN); + /* configure USART parity mode */ + USART_CTL0(usart_periph) |= paritycfg ; +} + +/*! + \brief configure USART word length + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] wlen: USART word length configure + \arg USART_WL_8BIT: 8 bits + \arg USART_WL_9BIT: 9 bits + \param[out] none + \retval none +*/ +void usart_word_length_set(uint32_t usart_periph, uint32_t wlen) +{ + /* clear USART_CTL0 WL bit */ + USART_CTL0(usart_periph) &= ~USART_CTL0_WL; + /* configure USART word length */ + USART_CTL0(usart_periph) |= wlen; +} + +/*! + \brief configure USART stop bit length + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] stblen: USART stop bit configure + \arg USART_STB_1BIT: 1 bit + \arg USART_STB_0_5BIT: 0.5 bit + \arg USART_STB_2BIT: 2 bits + \arg USART_STB_1_5BIT: 1.5 bits + \param[out] none + \retval none +*/ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen) +{ + /* clear USART_CTL1 STB bits */ + USART_CTL1(usart_periph) &= ~USART_CTL1_STB; + /* configure USART stop bits */ + USART_CTL1(usart_periph) |= stblen; +} +/*! + \brief enable USART + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UEN; +} + +/*! + \brief disable USART + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); +} + +/*! + \brief configure USART transmitter + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] rtconfig: 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) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL0(usart_periph); + ctl &= ~USART_CTL0_TEN; + ctl |= txconfig; + /* configure transfer mode */ + USART_CTL0(usart_periph) = ctl; +} + +/*! + \brief configure USART receiver + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] rtconfig: 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) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL0(usart_periph); + ctl &= ~USART_CTL0_REN; + ctl |= rxconfig; + /* configure transfer mode */ + USART_CTL0(usart_periph) = ctl; +} + +/*! + \brief data is transmitted/received with the LSB/MSB first + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] msbf: LSB/MSB + \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_CTL3(usart_periph) &= ~(USART_CTL3_MSBF); + USART_CTL3(usart_periph) |= msbf; +} + +/*! + \brief configure USART inversion + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] invertpara: refer to enum USART_INVERT_CONFIG + \arg USART_DINV_ENABLE: data bit level inversion + \arg USART_DINV_DISABLE: data bit level not inversion + \arg USART_TXPIN_ENABLE: TX pin level inversion + \arg USART_TXPIN_DISABLE: TX pin level not inversion + \arg USART_RXPIN_ENABLE: RX pin level inversion + \arg USART_RXPIN_DISABLE: RX pin level not inversion + \param[out] none + \retval none +*/ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara) +{ + /* inverted or not the specified siginal */ + switch(invertpara){ + case USART_DINV_ENABLE: + USART_CTL3(usart_periph) |= USART_CTL3_DINV; + break; + case USART_TXPIN_ENABLE: + USART_CTL3(usart_periph) |= USART_CTL3_TINV; + break; + case USART_RXPIN_ENABLE: + USART_CTL3(usart_periph) |= USART_CTL3_RINV; + break; + case USART_DINV_DISABLE: + USART_CTL3(usart_periph) &= ~(USART_CTL3_DINV); + break; + case USART_TXPIN_DISABLE: + USART_CTL3(usart_periph) &= ~(USART_CTL3_TINV); + break; + case USART_RXPIN_DISABLE: + USART_CTL3(usart_periph) &= ~(USART_CTL3_RINV); + break; + default: + break; + } +} + +/*! + \brief configure the USART oversample mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] oversamp: oversample value + \arg USART_OVSMOD_8: 8 bits + \arg USART_OVSMOD_16: 16 bits + \param[out] none + \retval none +*/ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp) +{ + /* clear OVSMOD bit */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_OVSMOD); + USART_CTL0(usart_periph) |= oversamp; +} + +/*! + \brief configure sample bit method + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] obsm: sample bit + \arg USART_OSB_1bit: 1 bit + \arg USART_OSB_3bit: 3 bits + \param[out] none + \retval none +*/ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t obsm) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB); + USART_CTL2(usart_periph) |= obsm; +} + +/*! + \brief enable receiver timeout of USART + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_enable(uint32_t usart_periph) +{ + USART_CTL3(usart_periph) |= USART_CTL3_RTEN; +} + +/*! + \brief disable receiver timeout of USART + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_disable(uint32_t usart_periph) +{ + USART_CTL3(usart_periph) &= ~(USART_CTL3_RTEN); +} + +/*! + \brief set the receiver timeout threshold of USART + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] rtimeout: 0-0x00FFFFFF + \param[out] none + \retval none +*/ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout) +{ + USART_RT(usart_periph) &= ~(USART_RT_RT); + USART_RT(usart_periph) |= rtimeout; +} + +/*! + \brief USART transmit data function + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void usart_data_transmit(uint32_t usart_periph, uint32_t data) +{ + USART_DATA(usart_periph) = ((uint16_t)USART_DATA_DATA & data); +} + +/*! + \brief USART receive data function + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval data of received +*/ +uint16_t usart_data_receive(uint32_t usart_periph) +{ + return (uint16_t)(USART_DATA(usart_periph) & (uint16_t)USART_DATA_DATA); +} + +/*! + \brief configure the address of the USART in wake up by address match mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] addr: address of USART/UART + \param[out] none + \retval none +*/ +void usart_address_config(uint32_t usart_periph, uint8_t addr) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & addr); +} + +/*! + \brief receiver in mute mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_mute_mode_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_RWU; +} + +/*! + \brief receiver in active mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_mute_mode_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_RWU); +} + +/*! + \brief configure wakeup method in mute mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] wmehtod: two method be used to enter or exit the mute mode + \arg USART_WM_IDLE: idle line + \arg USART_WM_ADDR: address mask + \param[out] none + \retval none +*/ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmehtod) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_WM); + USART_CTL0(usart_periph) |= wmehtod; +} + +/*! + \brief enable LIN mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_lin_mode_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_LMEN; +} + +/*! + \brief disable LIN mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_lin_mode_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); +} + +/*! + \brief configure lin break frame length + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] lblen: lin break frame length + \arg USART_LBLEN_10B: 10 bits + \arg USART_LBLEN_11B: 11 bits + \param[out] none + \retval none +*/ +void usart_lin_break_dection_length_config(uint32_t usart_periph, uint32_t lblen) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN); + USART_CTL1(usart_periph) |= (USART_CTL1_LBLEN & lblen); +} + +/*! + \brief send break frame + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_send_break(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_SBKCMD; +} + +/*! + \brief enable half duplex mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_halfduplex_enable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) |= USART_CTL2_HDEN; +} + +/*! + \brief disable half duplex mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_halfduplex_disable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN); +} + +/*! + \brief enable CK pin in synchronous mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_synchronous_clock_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_CKEN; +} + +/*! + \brief disable CK pin in synchronous mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_synchronous_clock_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN); +} + +/*! + \brief configure USART synchronous mode parameters + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] clen: CK length + \arg USART_CLEN_NONE: there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame + \arg USART_CLEN_EN: there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame + \param[in] cph: clock phase + \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) +{ + uint32_t ctl = 0U; + + /* read USART_CTL1 register */ + ctl = USART_CTL1(usart_periph); + /* set CK length, CK phase, CK polarity */ + ctl |= (USART_CTL1_CLEN & clen) | (USART_CTL1_CPH & cph) | (USART_CTL1_CPL & cpl); + + USART_CTL1(usart_periph) |= ctl; +} + +/*! + \brief configure guard time value in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] gaut: guard time value + \param[out] none + \retval none +*/ +void usart_guard_time_config(uint32_t usart_periph,uint32_t gaut) +{ + USART_GP(usart_periph) &= ~(USART_GP_GUAT); + USART_GP(usart_periph) |= (USART_GP_GUAT & ((gaut)<<8)); +} + +/*! + \brief enable smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_enable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) |= USART_CTL2_SCEN; +} + +/*! + \brief disable smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_disable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN); +} + +/*! + \brief enable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) |= USART_CTL2_NKEN; +} + +/*! + \brief disable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN); +} + +/*! + \brief configure smartcard auto-retry number + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] scrtnum: smartcard auto-retry number + \param[out] none + \retval none +*/ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum) +{ + USART_CTL3(usart_periph) &= ~(USART_CTL3_SCRTNUM); + USART_CTL3(usart_periph) |= (USART_CTL3_SCRTNUM & ((scrtnum)<<1)); +} + +/*! + \brief configure block length in Smartcard T=1 reception + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] bl: block length + \param[out] none + \retval none +*/ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl) +{ + USART_RT(usart_periph) &= ~(USART_RT_BL); + USART_RT(usart_periph) |= (USART_RT_BL & ((bl)<<24)); +} + +/*! + \brief enable IrDA mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_irda_mode_enable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) |= USART_CTL2_IREN; +} + +/*! + \brief disable IrDA mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_irda_mode_disable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN); +} + +/*! + \brief configure the peripheral clock prescaler in USART IrDA low-power mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] psc: 0-0x00FFFFFF + \param[out] none + \retval none +*/ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc) +{ + USART_GP(usart_periph) &= ~(USART_GP_PSC); + USART_GP(usart_periph) |= psc; +} + +/*! + \brief configure IrDA low-power + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \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) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP); + USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp); +} + +/*! + \brief configure hardware flow control RTS + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] hardwareflow: 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) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL2(usart_periph); + ctl &= ~USART_CTL2_RTSEN; + ctl |= rtsconfig; + /* configure RTS */ + USART_CTL2(usart_periph) = ctl; +} + +/*! + \brief configure hardware flow control CTS + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] hardwareflow: 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) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL2(usart_periph); + ctl &= ~USART_CTL2_CTSEN; + ctl |= ctsconfig; + /* configure CTS */ + USART_CTL2(usart_periph) = ctl; +} + +/*! + \brief configure break frame coherence mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] bcm: + \arg USART_BCM_NONE: no parity error is detected + \arg USART_BCM_EN: parity error is detected + \param[out] none + \retval none +*/ +void usart_break_frame_coherence_config(uint32_t usart_periph, uint32_t bcm) +{ + USART_CHC(usart_periph) &= ~(USART_CHC_BCM); + USART_CHC(usart_periph) |= (USART_CHC_BCM & bcm); +} + +/*! + \brief configure parity check coherence mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] pcm: + \arg USART_PCM_NONE: not check parity + \arg USART_PCM_EN: check the parity + \param[out] none + \retval none +*/ +void usart_parity_check_coherence_config(uint32_t usart_periph, uint32_t pcm) +{ + USART_CHC(usart_periph) &= ~(USART_CHC_PCM); + USART_CHC(usart_periph) |= (USART_CHC_PCM & pcm); +} + +/*! + \brief configure hardware flow control coherence mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] hcm: + \arg USART_HCM_NONE: nRTS signal equals to the rxne status register + \arg USART_HCM_EN: nRTS signal is set when the last data bit has been sampled + \param[out] none + \retval none +*/ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm) +{ + USART_CHC(usart_periph) &= ~(USART_CHC_HCM); + USART_CHC(usart_periph) |= (USART_CHC_HCM & hcm); +} + +/*! + \brief configure USART DMA reception + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] dmacmd: enable or disable DMA for reception + \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) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL2(usart_periph); + ctl &= ~USART_CTL2_DENR; + ctl |= dmacmd; + /* configure DMA reception */ + USART_CTL2(usart_periph) = ctl; +} + +/*! + \brief configure USART DMA transmission + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] dmacmd: enable or disable DMA for transmission + \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) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL2(usart_periph); + ctl &= ~USART_CTL2_DENT; + ctl |= dmacmd; + /* configure DMA transmission */ + USART_CTL2(usart_periph) = ctl; +} + +/*! + \brief get flag in STAT0/STAT1/CHC register + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] flag: USART flags, refer to usart_flag_enum + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_LBDF: LIN break detected flag + \arg USART_FLAG_TBE: transmit data buffer empty + \arg USART_FLAG_TC: transmission complete + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_IDLEF: IDLE frame detected flag + \arg USART_FLAG_ORERR: overrun error + \arg USART_FLAG_NERR: noise error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_BSY: busy flag + \arg USART_FLAG_EBF: end of block flag + \arg USART_FLAG_RTF: receiver timeout flag + \arg USART_FLAG_EPERR: early parity error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag) +{ + if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear flag in STAT0/STAT1/CHC register + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] flag: USART flags, refer to usart_flag_enum + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_LBDF: LIN break detected flag + \arg USART_FLAG_TC: transmission complete + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_EBF: end of block flag + \arg USART_FLAG_RTF: receiver timeout flag + \arg USART_FLAG_EPERR: early parity error flag + \param[out] none + \retval none +*/ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) +{ + USART_REG_VAL(usart_periph, flag) &= ~BIT(USART_BIT_POS(flag)); +} + +/*! + \brief enable USART interrupt + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] int_flag + \arg USART_INTEN_PERRIE: parity error interrupt + \arg USART_INTEN_TBEIE: transmitter buffer empty interrupt + \arg USART_INTEN_TCIE: transmission complete interrupt + \arg USART_INTEN_RBNEIE: read data buffer not empty interrupt and overrun error interrupt + \arg USART_INTEN_IDLEIE: IDLE line detected interrupt + \arg USART_INTEN_LBDIE: LIN break detected interrupt + \arg USART_INTEN_ERRIE: error interrupt + \arg USART_INTEN_CTSIE: CTS interrupt + \arg USART_INTEN_RTIE: interrupt enable bit of receive timeout event + \arg USART_INTEN_EBIE: interrupt enable bit of end of block event + \param[out] none +*/ +void usart_interrupt_enable(uint32_t usart_periph, uint32_t int_flag) +{ + uint32_t usart_reg = 0U; + + usart_reg = int_flag & (~(uint32_t)USART_INTEN_MASK); + int_flag &= USART_INTEN_MASK; + /* flags in USART_CTL0 */ + if(USART_INTS_CTL0 == usart_reg){ + USART_CTL0(usart_periph) |= int_flag; + /* flags in USART_CTL1 */ + }else if(USART_INTS_CTL1 == usart_reg){ + USART_CTL1(usart_periph) |= int_flag; + /* flags in USART_CTL2 */ + }else if(USART_INTS_CTL2 == usart_reg){ + USART_CTL2(usart_periph) |= int_flag; + /* flags in USART_CTL3 */ + }else if(USART_INTS_CTL3 == usart_reg){ + USART_CTL3(usart_periph) |= int_flag; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief disable USART interrupt + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] int_flag + \arg USART_INTEN_PERRIE: parity error interrupt + \arg USART_INTEN_TBEIE: transmitter buffer empty interrupt + \arg USART_INTEN_TCIE: transmission complete interrupt + \arg USART_INTEN_RBNEIE: read data buffer not empty interrupt and overrun error interrupt + \arg USART_INTEN_IDLEIE: IDLE line detected interrupt + \arg USART_INTEN_LBDIE: LIN break detected interrupt + \arg USART_INTEN_ERRIE: error interrupt + \arg USART_INTEN_CTSIE: CTS interrupt + \arg USART_INTEN_RTIE: interrupt enable bit of receive timeout event + \arg USART_INTEN_EBIE: interrupt enable bit of end of block event + \param[out] none +*/ +void usart_interrupt_disable(uint32_t usart_periph, uint32_t int_flag) +{ + uint32_t usart_reg = 0U; + + usart_reg = int_flag & (~(uint32_t)USART_INTEN_MASK); + int_flag &= USART_INTEN_MASK; + /* flags in USART_CTL0 */ + if(USART_INTS_CTL0 == usart_reg){ + USART_CTL0(usart_periph) &= ~(int_flag); + /* flags in USART_CTL1 */ + }else if(USART_INTS_CTL1 == usart_reg){ + USART_CTL1(usart_periph) &= ~(int_flag); + /* flags in USART_CTL2 */ + }else if(USART_INTS_CTL2 == usart_reg){ + USART_CTL2(usart_periph) &= ~(int_flag); + /* flags in USART_CTL3 */ + }else if(USART_INTS_CTL3 == usart_reg){ + USART_CTL3(usart_periph) &= ~(int_flag); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief get USART interrupt enable flag + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] int_flag + \arg USART_INT_PERRIE: parity error interrupt + \arg USART_INT_TBEIE: transmitter buffer empty interrupt + \arg USART_INT_TCIE: transmission complete interrupt + \arg USART_INT_RBNEIE: read data buffer not empty interrupt and overrun error interrupt + \arg USART_INT_IDLEIE: IDLE line detected interrupt + \arg USART_INT_LBDIE: LIN break detected interrupt + \arg USART_INT_CTSIE: CTS interrupt + \arg USART_INT_ERRIE: error interrupt + \arg USART_INT_EBIE: interrupt enable bit of end of block event + \arg USART_INT_RTIE: interrupt enable bit of receive timeout event + \param[out] none + \retval FlagStatus +*/ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag) +{ + if(RESET != (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag)))){ + return SET; + }else{ + return RESET; + } +} + diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_wwdgt.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_wwdgt.c new file mode 100644 index 0000000000..94a50ac996 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_standard_peripheral/Source/gd32f4xx_wwdgt.c @@ -0,0 +1,122 @@ +/*! + \file gd32f4xx_wwdgt.c + \brief WWDGT driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "gd32f4xx_wwdgt.h" + +/* write value to WWDGT_CTL_CNT bit field */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) +/* write value to WWDGT_CFG_WIN bit field */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) + +/*! + \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 |= CTL_CNT(counter_value); + + WWDGT_CTL = 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 &(~WWDGT_CTL_CNT)); + + /* configure WIN and PSC bits, configure CNT bit */ + reg_cfg |= CFG_WIN(window); + reg_cfg |= prescaler; + reg_ctl |= CTL_CNT(counter); + + WWDGT_CTL = reg_ctl; + WWDGT_CFG = reg_cfg; +} + +/*! + \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 &= (~WWDGT_STAT_EWIF); +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_core.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_core.h new file mode 100644 index 0000000000..2891e0219c --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_core.h @@ -0,0 +1,287 @@ +/*! + \file usb_core.h + \brief USB core driver header file +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef USB_CORE_H +#define USB_CORE_H + +#include "usb_conf.h" +#include "usb_regs.h" +#include "usb_defines.h" + +#define USB_MAX_EP0_SIZE 64U /* endpoint 0 max packet size */ +#define RX_MAX_DATA_LENGTH 512U /* host rx buffer max data length */ +#define HC_MAX_PACKET_COUNT 140U /* host channel max packet count */ + +#ifdef USE_USBFS + #define USB_MAX_DEV_EPCOUNT USBFS_MAX_DEV_EPCOUNT + #define USB_MAX_FIFOS (USBFS_MAX_HOST_CHANNELCOUNT * 2U - 1U) +#elif defined(USE_USBHS) + #define USB_MAX_DEV_EPCOUNT USBHS_MAX_DEV_EPCOUNT + #define USB_MAX_FIFOS (USBHS_MAX_HOST_CHANNELCOUNT * 2U - 1U) +#endif /* USE_USBFS */ + +/* USB core status */ +typedef enum +{ + USB_OK = 0, /* USB core OK status */ + USB_FAIL /* USB core fail status */ +}usb_status_enum; + +/* USB host channel status */ +typedef enum +{ + HC_IDLE = 0, /* USB host channel idle status */ + HC_XF, /* USB host channel transfer status */ + HC_HALTED, /* USB host channel halted status */ + HC_NAK, /* USB host channel nak status */ + HC_NYET, /* USB host channel nyet status */ + HC_STALL, /* USB host channel stall status */ + HC_TRACERR, /* USB host channel tracerr status */ + HC_BBERR, /* USB host channel bberr status */ + HC_DTGERR, /* USB host channel dtgerr status */ +}hc_status_enum; + +/* USB URB(USB request block) state */ +typedef enum +{ + URB_IDLE = 0, /* USB URB idle status */ + URB_DONE, /* USB URB done status */ + URB_NOTREADY, /* USB URB notready status */ + URB_ERROR, /* USB URB error status */ + URB_STALL, /* USB URB stall status */ + URB_PING /* USB URB ping status */ +}urb_state_enum; + +/* USB core configuration */ +typedef struct +{ + uint8_t core_id; /* USB core id */ + uint8_t core_speed; /* USB core speed */ + uint8_t phy_interface; /* USB PHY interface */ + uint8_t host_channel_num; /* USB host channel number */ + uint8_t dev_endp_num; /* USB device endpoint number */ + uint8_t dma_enable; /* USBHS can use DMA */ + uint8_t sof_output; /* USB SOF output */ + uint8_t low_power; /* USB low power */ + uint16_t max_packet_size; /* USB max packet size */ + uint16_t max_fifo_size; /* USB fifo size */ +}usb_core_cfgs_struct; + +typedef enum +{ + USBD_OK = 0, /* USB device ok status */ + USBD_BUSY, /* USB device busy status */ + USBD_FAIL, /* USB device fail stauts */ +}usbd_status_enum; + +/* USB control transfer state */ +typedef enum +{ + USB_CTRL_IDLE = 0, /* USB control transfer idle state */ + USB_CTRL_SETUP, /* USB control transfer setup state */ + USB_CTRL_DATA_IN, /* USB control transfer data in state */ + USB_CTRL_DATA_OUT, /* USB control transfer data out state */ + USB_CTRL_STATUS_IN, /* USB control transfer status in state*/ + USB_CTRL_STATUS_OUT, /* USB control transfer status out state */ + USB_CTRL_STALL /* USB control transfer stall state */ +}usbd_control_state_enum; + +/* USB transfer direction */ +typedef enum +{ + USBD_RX = 0, /* receive direction type value */ + USBD_TX /* transmit direction type value */ +}usbd_dir_enum; + +/* USB endpoint in device mode */ +typedef struct +{ + uint8_t endp_type; /* USB endpoint type */ + uint8_t endp_frame; /* USB endpoint frame */ + uint32_t endp_mps; /* USB endpoint max packet size */ + + /* Transaction level variables */ + uint8_t *xfer_buff; /* USB transfer buffer */ + uint32_t xfer_len; /* USB transfer length */ + uint32_t xfer_count; /* USB transfer count */ + + uint32_t dma_addr; /* USBHS can use DMA */ +}usb_ep_struct; + +/* USB device standard request */ +typedef struct +{ + uint8_t bmRequestType; /* USB device request type */ + uint8_t bRequest; /* USB device request */ + uint16_t wValue; /* USB device request value */ + uint16_t wIndex; /* USB device request index */ + uint16_t wLength; /* USB device request length */ +}usb_device_req_struct; + +/* USB core device driver */ +typedef struct +{ + uint8_t config_num; /* USB configuration number */ + uint8_t status; /* USB status */ + uint8_t ctl_status; /* USB control status */ + uint8_t prev_status; /* USB previous status */ + uint8_t connection_status; /* USB connection status */ + uint32_t remote_wakeup; /* USB remote wakeup */ + + /* transfer level variables */ + uint32_t remain_len; /* USB remain length */ + uint32_t sum_len; /* USB sum length */ + uint32_t ctl_len; /* USB control length */ + uint8_t setup_packet[8 * 3]; /* USB setup packet */ + + usb_ep_struct in_ep[USB_MAX_DEV_EPCOUNT]; /* USB IN endpoint */ + usb_ep_struct out_ep[USB_MAX_DEV_EPCOUNT]; /* USB OUT endpoint */ + + uint8_t *dev_desc; /* device descriptor */ + uint8_t *config_desc; /* configuration descriptor */ + uint8_t* *strings; /* configuration strings */ + + /* device class handler */ + uint8_t (*class_init) (void *pudev, uint8_t config_index); /* device class initialize */ + uint8_t (*class_deinit) (void *pudev, uint8_t config_index); /* device class deinitialize */ + uint8_t (*class_req_handler) (void *pudev, usb_device_req_struct *req); /* device request handler */ + uint8_t (*class_data_handler) (void *pudev, usbd_dir_enum rx_tx, uint8_t ep_id); /* device data handler */ +}dcd_dev_struct; + +/* USB core host mode channel */ +typedef struct +{ + uint8_t dev_addr; /* device address */ + uint8_t dev_speed; /* device speed */ + uint8_t DPID; /* endpoint transfer data pid */ + uint8_t endp_id; /* endpoint id */ + uint8_t endp_in; /* endpoint in */ + uint8_t endp_type; /* endpoint type */ + uint16_t endp_mps; /* endpoint max pactet size */ + uint16_t info; /* channel information */ + + uint8_t do_ping; /* USBHS ping */ + + uint8_t *xfer_buff; /* transfer buffer */ + uint32_t xfer_len; /* transfer length */ + uint32_t xfer_count; /* trasnfer count */ + + uint32_t err_count; /* USB transfer error count */ + uint32_t dma_addr; /* USBHS can use DMA */ + + hc_status_enum status; /* channel status */ + urb_state_enum urb_state; /* URB state */ + + uint8_t data_tg_in; /* data in toggle */ + uint8_t data_tg_out; /* data out toggle */ +}usb_hostchannel_struct; + +/* USB core host driver */ +typedef struct +{ + uint8_t rx_buffer[RX_MAX_DATA_LENGTH]; /* rx buffer */ + uint8_t connect_status; /* device connect status */ + usb_hostchannel_struct host_channel[USB_MAX_FIFOS]; /* host channel */ + void (*vbus_drive) (void *pudev, uint8_t state); /* the vbus driver function */ +}hcd_dev_struct; + +#ifdef USE_OTG_MODE + +/* USB core OTG-mode driver */ +typedef struct +{ + uint8_t OTG_State; /* OTG state */ + uint8_t OTG_PrevState; /* OTG previous state */ + uint8_t OTG_Mode; /* OTG mode */ +}otg_dev_struct; + +#endif /* USE_OTG_MODE */ + +/* USB core driver */ +typedef struct +{ + usb_core_cfgs_struct cfg; + +#ifdef USE_DEVICE_MODE + dcd_dev_struct dev; +#endif /* USE_DEVICE_MODE */ + +#ifdef USE_HOST_MODE + hcd_dev_struct host; +#endif /* USE_HOST_MODE */ + +#ifdef USE_OTG_MODE + otg_dev_struct otg; +#endif /* USE_OTG_MODE */ + + void (*udelay) (const uint32_t usec); + void (*mdelay) (const uint32_t msec); +}usb_core_handle_struct; + +/* function declarations */ + +/* global APIs */ +/* initializes the USB controller registers and prepares the core device mode or host mode operation */ +usb_status_enum usb_core_init (usb_core_handle_struct *pudev); +/* initialize core parameters */ +usb_status_enum usb_core_select (usb_core_handle_struct *pudev, usb_core_id_enum core_id); +/* read a packet from the Rx FIFO associated with the endpoint */ +void* usb_fifo_read (uint8_t *dest, uint16_t len); +/* write a packet into the Tx FIFO associated with the endpoint */ +usb_status_enum usb_fifo_write (uint8_t *src, uint8_t ep_id, uint16_t len); +/* flush a Tx FIFO or all Tx FIFOs */ +usb_status_enum usb_txfifo_flush (usb_core_handle_struct *pudev, uint8_t fifo_num); +/* flush the entire Rx FIFO */ +usb_status_enum usb_rxfifo_flush (usb_core_handle_struct *pudev); +/* set operation mode (host or device) */ +usb_status_enum usb_mode_set (usb_core_handle_struct *pudev, uint8_t mode); + +/* host APIs */ +#ifdef USE_HOST_MODE + +/* initializes USB core for host mode */ +usb_status_enum usb_hostcore_init (usb_core_handle_struct *pudev); +/* enables the host mode interrupts */ +usb_status_enum usb_hostint_enable (usb_core_handle_struct *pudev); +/* initialize host channel */ +usb_status_enum usb_hostchannel_init (usb_core_handle_struct *pudev, uint8_t hc_num); +/* halt channel */ +usb_status_enum usb_hostchannel_halt (usb_core_handle_struct *pudev, uint8_t hc_num); +/* prepare host channel for transferring packets */ +usb_status_enum usb_hostchannel_startxfer (usb_core_handle_struct *pudev, uint8_t hc_num); +/* issue a ping token */ +usb_status_enum usb_hostchannel_ping (usb_core_handle_struct *pudev, uint8_t hc_num); +/* reset host port */ +uint32_t usb_port_reset (usb_core_handle_struct *pudev); +/* control the VBUS to power */ +void usb_vbus_drive (usb_core_handle_struct *pudev, uint8_t state); +/* stop the USB host and clean up fifos */ +void usb_host_stop (usb_core_handle_struct *pudev); + +#endif /* USE_HOST_MODE */ + +/* device APIs */ +#ifdef USE_DEVICE_MODE + +/* initialize USB core registers for device mode */ +usb_status_enum usb_devcore_init (usb_core_handle_struct *pudev); +/* configures endpoint 0 to receive SETUP packets */ +void usb_ep0_startout (usb_core_handle_struct *pudev); +/* active remote wakeup signalling */ +void usb_remotewakeup_active (usb_core_handle_struct *pudev); +/* active USB core clock */ +void usb_clock_ungate (usb_core_handle_struct *pudev); +/* stop the device and clean up fifos */ +void usb_device_stop (usb_core_handle_struct *pudev); + +#endif /* USE_DEVICE_MODE */ + +#endif /* USB_CORE_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_defines.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_defines.h new file mode 100644 index 0000000000..309e23f32f --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_defines.h @@ -0,0 +1,100 @@ +/*! + \file usb_defines.h + \brief USB core defines +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef USB_DEFINES_H +#define USB_DEFINES_H + +#include "usb_conf.h" + +#ifndef NULL + #define NULL (void *)0 /*!< USB null marco value*/ +#endif /* NULL */ + +#define USB_CORE_SPEED_HIGH 0U /* USB core speed is high-speed */ +#define USB_CORE_SPEED_FULL 1U /* USB core speed is full-speed */ + +#define USBFS_MAX_PACKET_SIZE 64U /* USBFS max packet size */ +#define USBFS_MAX_HOST_CHANNELCOUNT 8U /* USBFS host channel count */ +#define USBFS_MAX_DEV_EPCOUNT 4U /* USBFS device endpoint count */ +#define USBFS_MAX_FIFO_WORDLEN 320U /* USBFS max fifo size in words */ + +#define USBHS_MAX_PACKET_SIZE 512U /* USBHS max packet size */ +#define USBHS_MAX_HOST_CHANNELCOUNT 12U /* USBHS host channel count */ +#define USBHS_MAX_DEV_EPCOUNT 6U /* USBHS device endpoint count */ +#define USBHS_MAX_FIFO_WORDLEN 1280U /* USBHS max fifo size in words */ + +#define USB_CORE_ULPI_PHY 1U /* USB core use external ULPI PHY */ +#define USB_CORE_EMBEDDED_PHY 2U /* USB core use embedded PHY */ + +#define DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0U /* USB enumerate speed use high-speed PHY clock in 30MHz or 60MHz */ +#define DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1U /* USB enumerate speed use full-speed PHY clock in 30MHz or 60MHz */ +#define DSTAT_ENUMSPD_LS_PHY_6MHZ 2U /* USB enumerate speed use low-speed PHY clock in 6MHz */ +#define DSTAT_ENUMSPD_FS_PHY_48MHZ 3U /* USB enumerate speed use full-speed PHY clock in 48MHz */ + +#define GRSTATR_RPCKST_IN 2U /* IN data packet received */ +#define GRSTATR_RPCKST_IN_XFER_COMP 3U /* IN transfer completed (generates an interrupt if poped) */ +#define GRSTATR_RPCKST_DATA_TOGGLE_ERR 5U /* Data toggle error (generates an interrupt if poped) */ +#define GRSTATR_RPCKST_CH_HALTED 7U /* Channel halted (generates an interrupt if poped) */ + +#define DEVICE_MODE 0U /* USB core in device mode */ +#define HOST_MODE 1U /* USB core in host mode */ +#define OTG_MODE 2U /* USB core in OTG mode */ + +#define USB_EPTYPE_CTRL 0U /* USB control endpoint type */ +#define USB_EPTYPE_ISOC 1U /* USB synchronous endpoint type */ +#define USB_EPTYPE_BULK 2U /* USB bulk endpoint type */ +#define USB_EPTYPE_INTR 3U /* USB interrupt endpoint type */ +#define USB_EPTYPE_MASK 3U /* USB endpoint type mask */ + +#define RXSTAT_GOUT_NAK 1U /* global OUT NAK (triggers an interrupt) */ +#define RXSTAT_DATA_UPDT 2U /* OUT data packet received */ +#define RXSTAT_XFER_COMP 3U /* OUT transfer completed (triggers an interrupt) */ +#define RXSTAT_SETUP_COMP 4U /* SETUP transaction completed (triggers an interrupt) */ +#define RXSTAT_SETUP_UPDT 6U /* SETUP data packet received */ + +#define DPID_DATA0 0U /* device endpoint data PID is DATA0 */ +#define DPID_DATA1 2U /* device endpoint data PID is DATA1 */ +#define DPID_DATA2 1U /* device endpoint data PID is DATA2 */ +#define DPID_MDATA 3U /* device endpoint data PID is MDATA */ + +#define HC_PID_DATA0 0U /* host channel data PID is DATA0 */ +#define HC_PID_DATA2 1U /* host channel data PID is DATA2 */ +#define HC_PID_DATA1 2U /* host channel data PID is DATA1 */ +#define HC_PID_SETUP 3U /* host channel data PID is SETUP */ + +#define HPRT_PRTSPD_HIGH_SPEED 0U /* host port speed use high speed */ +#define HPRT_PRTSPD_FULL_SPEED 1U /* host port speed use full speed */ +#define HPRT_PRTSPD_LOW_SPEED 2U /* host port speed use low speed */ + +#define HCTLR_30_60_MHZ 0U /* USB PHY(ULPI) clock is 60MHz */ +#define HCTLR_48_MHZ 1U /* USB PHY(embedded full-speed) clock is 48MHz */ +#define HCTLR_6_MHZ 2U /* USB PHY(embedded low-speed) clock is 6MHz */ + +#define HCCHAR_CTRL 0U /* control channel type */ +#define HCCHAR_ISOC 1U /* synchronous channel type */ +#define HCCHAR_BULK 2U /* bulk channel type */ +#define HCCHAR_INTR 3U /* interrupt channel type */ + +typedef enum +{ + USB_HS_CORE_ID = 0, + USB_FS_CORE_ID = 1 +}usb_core_id_enum; + +typedef enum +{ + USB_SPEED_UNKNOWN = 0, + USB_SPEED_LOW, + USB_SPEED_FULL, + USB_SPEED_HIGH +}usb_speed_enum; + +#endif /* USB_DEFINES_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_regs.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_regs.h new file mode 100644 index 0000000000..db05aa25ff --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_regs.h @@ -0,0 +1,676 @@ +/*! + \file usb_regs.h + \brief USB FS&HS cell registers definition and handle macros +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef USB_REGS_H +#define USB_REGS_H + +#include "usb_conf.h" + +#define USBFS USBFS_BASE /*!< base address of USBFS registers */ +#define USBHS USBHS_BASE /*!< base address of USBHS registers */ + +#ifdef USE_USBFS + #define USBX USBFS /*!< USB full speed mode */ +#endif /* USE_USBFS */ + +#ifdef USE_USBHS + #define USBX USBHS /*!< USB high speed mode */ +#endif /* USE_USBHS */ + +/* registers location definitions */ +#define LOCATE_DIEPTFLEN(x) (0x104U + 4U * ((x) - 1U)) /*!< locate device IN endpoint-x transfer length registers */ +#define LOCATE_HCHCTL(x) (0x500U + 0x20U * (x)) /*!< locate host channel-x control registers */ +#define LOCATE_HCHSTCTL(x) (0x504U + 0x20U * (x)) /*!< locate host channel-x split transaction control registers */ +#define LOCATE_HCHINTF(x) (0x508U + 0x20U * (x)) /*!< locate host channel-x interrupt flag registers */ +#define LOCATE_HCHINTEN(x) (0x50CU + 0x20U * (x)) /*!< locate host channel-x interrupt enable registers */ +#define LOCATE_HCHLEN(x) (0x510U + 0x20U * (x)) /*!< locate host channel-x transfer length registers */ +#define LOCATE_HCHDMAADDR(x) (0x514U + 0x20U * (x)) /*!< locate host channel-x DMA address registers */ +#define LOCATE_DIEPCTL(x) (0x900U + 0x20U * (x)) /*!< locate device IN endpoint-x control registers */ +#define LOCATE_DOEPCTL(x) (0xB00U + 0x20U * (x)) /*!< locate device OUT endpoint-x control registers */ +#define LOCATE_DIEPINTF(x) (0x908U + 0x20U * (x)) /*!< locate device IN endpoint-x interrupt flag registers */ +#define LOCATE_DOEPINTF(x) (0xB08U + 0x20U * (x)) /*!< locate device OUT endpoint-x interrupt flag registers */ +#define LOCATE_DIEPLEN(x) (0x910U + 0x20U * (x)) /*!< locate device IN endpoint-x transfer length registers */ +#define LOCATE_DOEPLEN(x) (0xB10U + 0x20U * (x)) /*!< locate device OUT endpoint-x transfer length registers */ +#define LOCATE_DIEPxDMAADDR(x) (0x914U + 0x20U * (x)) /*!< locate device IN endpoint-x DMA address registers */ +#define LOCATE_DOEPxDMAADDR(x) (0xB14U + 0x20U * (x)) /*!< locate device OUT endpoint-x DMA address registers */ +#define LOCATE_DIEPxTFSTAT(x) (0x918U + 0x20U * (x)) /*!< locate Device IN endpoint-x transmit FIFO status register */ +#define LOCATE_FIFO(x) (((x) + 1U) << 12U) /*!< locate FIFO-x memory */ + +/* registers definitions */ +#define USB_GOTGCS REG32(((USBX) + 0x0000U)) /*!< global OTG control and status register */ +#define USB_GOTGINTF REG32(((USBX) + 0x0004U)) /*!< global OTG interrupt flag register */ +#define USB_GAHBCS REG32(((USBX) + 0x0008U)) /*!< global AHB control and status register */ +#define USB_GUSBCS REG32(((USBX) + 0x000CU)) /*!< global USB control and status register */ +#define USB_GRSTCTL REG32(((USBX) + 0x0010U)) /*!< global reset control register */ +#define USB_GINTF REG32(((USBX) + 0x0014U)) /*!< global interrupt flag register */ +#define USB_GINTEN REG32(((USBX) + 0x0018U)) /*!< global interrupt enable register */ +#define USB_GRSTATR REG32(((USBX) + 0x001CU)) /*!< global receive status read register */ +#define USB_GRSTATP REG32(((USBX) + 0x0020U)) /*!< global receive status read and pop register */ +#define USB_GRFLEN REG32(((USBX) + 0x0024U)) /*!< global receive FIFO length register */ +#define USB_HNPTFLEN REG32(((USBX) + 0x0028U)) /*!< host non-periodic transmit FIFO length register */ +#define USB_DIEP0TFLEN REG32(((USBX) + 0x0028U)) /*!< device IN endpoint 0 transmit FIFO length register */ +#define USB_HNPTFQSTAT REG32(((USBX) + 0x002CU)) /*!< host non-periodic transmint FIFO/queue status register */ +#define USB_GCCFG REG32(((USBX) + 0x0038U)) /*!< global core configuration register */ +#define USB_CID REG32(((USBX) + 0x003CU)) /*!< core id register */ +#define USB_HPTFLEN REG32(((USBX) + 0x0100U)) /*!< host periodic transmit FIFO length register */ +#define USB_DIEPxTFLEN(x) REG32(((USBX) + LOCATE_DIEPTFLEN(x))) /*!< device IN endpoint transmit FIFO length register */ + +#define USB_HCTL REG32(((USBX) + 0x0400U)) /*!< host control register */ +#define USB_HFT REG32(((USBX) + 0x0404U)) /*!< host frame interval register */ +#define USB_HFINFR REG32(((USBX) + 0x0408U)) /*!< host frame information remaining register */ +#define USB_HPTFQSTAT REG32(((USBX) + 0x0410U)) /*!< host periodic transmit FIFO/queue status register */ +#define USB_HACHINT REG32(((USBX) + 0x0414U)) /*!< host all channels interrupt register */ +#define USB_HACHINTEN REG32(((USBX) + 0x0418U)) /*!< host all channels interrupt enable register */ +#define USB_HPCS REG32(((USBX) + 0x0440U)) /*!< host port control and status register */ +#define USB_HCHxCTL(x) REG32(((USBX) + LOCATE_HCHCTL(x))) /*!< host channel-x control register */ +#define USB_HCHxSTCTL(x) REG32(((USBX) + LOCATE_HCHSTCTL(x))) /*!< host channel-x split transaction control register */ +#define USB_HCHxINTF(x) REG32(((USBX) + LOCATE_HCHINTF(x))) /*!< host channel-x interrupt flag register */ +#define USB_HCHxINTEN(x) REG32(((USBX) + LOCATE_HCHINTEN(x))) /*!< host channel-x interrupt enable register */ +#define USB_HCHxLEN(x) REG32(((USBX) + LOCATE_HCHLEN(x))) /*!< host channel-x tranfer length register */ +#define USB_HCHxDMAADDR(x) REG32(((USBX) + LOCATE_HCHDMAADDR(x))) /*!< host channel-x DMA address register */ + +#define USB_DCFG REG32(((USBX) + 0x0800U)) /*!< device configuration register */ +#define USB_DCTL REG32(((USBX) + 0x0804U)) /*!< device control register */ +#define USB_DSTAT REG32(((USBX) + 0x0808U)) /*!< device status register */ +#define USB_DIEPINTEN REG32(((USBX) + 0x0810U)) /*!< device IN endpoint common interrupt enable register */ +#define USB_DOEPINTEN REG32(((USBX) + 0x0814U)) /*!< device OUT endpoint common interrupt enable register */ +#define USB_DAEPINT REG32(((USBX) + 0x0818U)) /*!< device all endpoints interrupt register */ +#define USB_DAEPINTEN REG32(((USBX) + 0x081CU)) /*!< device all endpoints interrupt enable register */ +#define USB_DVBUSDT REG32(((USBX) + 0x0828U)) /*!< device vbus discharge time register */ +#define USB_DVBUSPT REG32(((USBX) + 0x082CU)) /*!< device vbus pulsing time register */ +#define USB_DIEPFEINTEN REG32(((USBX) + 0x0834U)) /*!< device IN endpoint FIFO empty interrupt enable register */ +#define USB_DEP1INT REG32(((USBX) + 0x0838U)) /*!< device endpoint 1 interrupt register */ +#define USB_DEP1INTEN REG32(((USBX) + 0x083CU)) /*!< device endpoint 1 interrupt enable register */ +#define USB_DIEP1INTEN REG32(((USBX) + 0x0844U)) /*!< device IN endpoint 1 interrupt enable register */ +#define USB_DOEP1INTEN REG32(((USBX) + 0x0884U)) /*!< device OUT endpoint 1 interrupt enable register */ +#define USB_DIEP0CTL REG32(((USBX) + 0x0900U)) /*!< device IN endpoint 0 control register */ +#define USB_DIEP0LEN REG32(((USBX) + 0x0910U)) /*!< device IN endpoint 0 transfer length register */ +#define USB_DOEP0CTL REG32(((USBX) + 0x0B00U)) /*!< device OUT endpoint 0 control register */ +#define USB_DOEP0LEN REG32(((USBX) + 0x0B10U)) /*!< device OUT endpoint 0 transfer length register */ +#define USB_DIEPxCTL(x) REG32(((USBX) + LOCATE_DIEPCTL(x))) /*!< device IN endpoint-x control register */ +#define USB_DOEPxCTL(x) REG32(((USBX) + LOCATE_DOEPCTL(x))) /*!< device OUT endpoint-x control register */ +#define USB_DIEPxINTF(x) REG32(((USBX) + LOCATE_DIEPINTF(x))) /*!< device IN endpoint-x interrupt flag register */ +#define USB_DOEPxINTF(x) REG32(((USBX) + LOCATE_DOEPINTF(x))) /*!< device OUT endpoint-x interrupt flag register */ +#define USB_DIEPxLEN(x) REG32(((USBX) + LOCATE_DIEPLEN(x))) /*!< device IN endpoint-x transfer length register */ +#define USB_DOEPxLEN(x) REG32(((USBX) + LOCATE_DOEPLEN(x))) /*!< device OUT endpoint-x transfer length register */ +#define USB_DIEPxDMAADDR(x) REG32(((USBX) + LOCATE_DIEPxDMAADDR(x)))/*!< device IN endpoint-x DMA address register */ +#define USB_DOEPxDMAADDR(x) REG32(((USBX) + LOCATE_DOEPxDMAADDR(x)))/*!< device OUT endpoint-x DMA address register */ +#define USB_DIEPxTFSTAT(x) REG32(((USBX) + LOCATE_DIEPxTFSTAT(x))) /*!< device IN endpoint-x transmit FIFO status register */ + +#define USB_PWRCLKCTL REG32(((USBX) + 0x0E00U)) /*!< power and clock register */ + +#define USB_FIFO(x) (®32(((USBX) + LOCATE_FIFO(x)))) /*!< FIFO memory */ + +/* global OTG control and status register bits definitions */ +#define GOTGCS_BSV BIT(19) /*!< B-Session Valid */ +#define GOTGCS_ASV BIT(18) /*!< A-session valid */ +#define GOTGCS_DI BIT(17) /*!< debounce interval */ +#define GOTGCS_CIDPS BIT(16) /*!< id pin status */ +#define GOTGCS_DHNPEN BIT(11) /*!< device HNP enable */ +#define GOTGCS_HHNPEN BIT(10) /*!< host HNP enable */ +#define GOTGCS_HNPREQ BIT(9) /*!< HNP request */ +#define GOTGCS_HNPS BIT(8) /*!< HNP successes */ +#define GOTGCS_SRPREQ BIT(1) /*!< SRP request */ +#define GOTGCS_SRPS BIT(0) /*!< SRP successes */ + +/* global OTG interrupt flag register bits definitions */ +#define GOTGINTF_DF BIT(19) /*!< debounce finish */ +#define GOTGINTF_ADTO BIT(18) /*!< A-device timeout */ +#define GOTGINTF_HNPDET BIT(17) /*!< host negotiation request detected */ +#define GOTGINTF_HNPEND BIT(9) /*!< HNP end */ +#define GOTGINTF_SRPEND BIT(8) /*!< SRP end */ +#define GOTGINTF_SESEND BIT(2) /*!< session end */ + +/* global AHB control and status register bits definitions */ +#define GAHBCS_PTXFTH BIT(8) /*!< periodic Tx FIFO threshold */ +#define GAHBCS_TXFTH BIT(7) /*!< tx FIFO threshold */ +#define GAHBCS_DMAEN BIT(5) /*!< DMA function Enable */ +#define GAHBCS_BURST BITS(1, 4) /*!< the AHB burst type used by DMA */ +#define GAHBCS_GINTEN BIT(0) /*!< global interrupt enable */ + +/* global USB control and status register bits definitions */ +#define GUSBCS_FDM BIT(30) /*!< force device mode */ +#define GUSBCS_FHM BIT(29) /*!< force host mode */ +#define GUSBCS_ULPIEOI BIT(21) /*!< ULPI external over-current indicator */ +#define GUSBCS_ULPIEVD BIT(20) /*!< ULPI external VBUS driver */ +#define GUSBCS_UTT BITS(10, 13) /*!< USB turnaround time */ +#define GUSBCS_HNPCEN BIT(9) /*!< HNP capability enable */ +#define GUSBCS_SRPCEN BIT(8) /*!< SRP capability enable */ +#define GUSBCS_EMBPHY BIT(6) /*!< embedded PHY selected */ +#define GUSBCS_TOC BITS(0, 2) /*!< timeout calibration */ + +/* global reset control register bits definitions */ +#define GRSTCTL_DMAIDL BIT(31) /*!< DMA idle state */ +#define GRSTCTL_DMABSY BIT(30) /*!< DMA busy */ +#define GRSTCTL_TXFNUM BITS(6, 10) /*!< tx FIFO number */ +#define GRSTCTL_TXFF BIT(5) /*!< tx FIFO flush */ +#define GRSTCTL_RXFF BIT(4) /*!< rx FIFO flush */ +#define GRSTCTL_HFCRST BIT(2) /*!< host frame counter reset */ +#define GRSTCTL_HCSRST BIT(1) /*!< HCLK soft reset */ +#define GRSTCTL_CSRST BIT(0) /*!< core soft reset */ + +/* global interrupt flag register bits definitions */ +#define GINTF_WKUPIF BIT(31) /*!< wakeup interrupt flag */ +#define GINTF_SESIF BIT(30) /*!< session interrupt flag */ +#define GINTF_DISCIF BIT(29) /*!< disconnect interrupt flag */ +#define GINTF_IDPSC BIT(28) /*!< id pin status change */ +#define GINTF_PTXFEIF BIT(26) /*!< periodic tx FIFO empty interrupt flag */ +#define GINTF_HCIF BIT(25) /*!< host channels interrupt flag */ +#define GINTF_HPIF BIT(24) /*!< host port interrupt flag */ +#define GINTF_PXNCIF BIT(21) /*!< periodic transfer not complete interrupt flag */ +#define GINTF_ISOONCIF BIT(21) /*!< isochronous OUT transfer not complete interrupt flag */ +#define GINTF_ISOINCIF BIT(20) /*!< isochronous IN transfer not complete interrupt flag */ +#define GINTF_OEPIF BIT(19) /*!< OUT endpoint interrupt flag */ +#define GINTF_IEPIF BIT(18) /*!< IN endpoint interrupt flag */ +#define GINTF_EOPFIF BIT(15) /*!< end of periodic frame interrupt flag */ +#define GINTF_ISOOPDIF BIT(14) /*!< isochronous OUT packet dropped interrupt flag */ +#define GINTF_ENUMFIF BIT(13) /*!< enumeration finished */ +#define GINTF_RST BIT(12) /*!< USB reset */ +#define GINTF_SP BIT(11) /*!< USB suspend */ +#define GINTF_ESP BIT(10) /*!< early suspend */ +#define GINTF_GONAK BIT(7) /*!< global OUT NAK effective */ +#define GINTF_GNPINAK BIT(6) /*!< global IN non-periodic NAK effective */ +#define GINTF_NPTXFEIF BIT(5) /*!< non-periodic tx FIFO empty interrupt flag */ +#define GINTF_RXFNEIF BIT(4) /*!< rx FIFO non-empty interrupt flag */ +#define GINTF_SOF BIT(3) /*!< start of frame */ +#define GINTF_OTGIF BIT(2) /*!< OTG interrupt flag */ +#define GINTF_MFIF BIT(1) /*!< mode fault interrupt flag */ +#define GINTF_COPM BIT(0) /*!< current operation mode */ + +/* global interrupt enable register bits definitions */ +#define GINTEN_WKUPIE BIT(31) /*!< wakeup interrupt enable */ +#define GINTEN_SESIE BIT(30) /*!< session interrupt enable */ +#define GINTEN_DISCIE BIT(29) /*!< disconnect interrupt enable */ +#define GINTEN_IDPSCIE BIT(28) /*!< id pin status change interrupt enable */ +#define GINTEN_PTXFEIE BIT(26) /*!< periodic tx FIFO empty interrupt enable */ +#define GINTEN_HCIE BIT(25) /*!< host channels interrupt enable */ +#define GINTEN_HPIE BIT(24) /*!< host port interrupt enable */ +#define GINTEN_IPXIE BIT(21) /*!< periodic transfer not complete interrupt enable */ +#define GINTEN_ISOONCIE BIT(21) /*!< isochronous OUT transfer not complete interrupt enable */ +#define GINTEN_ISOINCIE BIT(20) /*!< isochronous IN transfer not complete interrupt enable */ +#define GINTEN_OEPIE BIT(19) /*!< OUT endpoints interrupt enable */ +#define GINTEN_IEPIE BIT(18) /*!< IN endpoints interrupt enable */ +#define GINTEN_EOPFIE BIT(15) /*!< end of periodic frame interrupt enable */ +#define GINTEN_ISOOPDIE BIT(14) /*!< isochronous OUT packet dropped interrupt enable */ +#define GINTEN_ENUMFIE BIT(13) /*!< enumeration finish enable */ +#define GINTEN_RSTIE BIT(12) /*!< USB reset interrupt enable */ +#define GINTEN_SPIE BIT(11) /*!< USB suspend interrupt enable */ +#define GINTEN_ESPIE BIT(10) /*!< early suspend interrupt enable */ +#define GINTEN_GONAKIE BIT(7) /*!< global OUT NAK effective interrupt enable */ +#define GINTEN_GNPINAKIE BIT(6) /*!< global non-periodic IN NAK effective interrupt enable */ +#define GINTEN_NPTXFEIE BIT(5) /*!< non-periodic Tx FIFO empty interrupt enable */ +#define GINTEN_RXFNEIE BIT(4) /*!< receive FIFO non-empty interrupt enable */ +#define GINTEN_SOFIE BIT(3) /*!< start of frame interrupt enable */ +#define GINTEN_OTGIE BIT(2) /*!< OTG interrupt enable */ +#define GINTEN_MFIE BIT(1) /*!< mode fault interrupt enable */ + +/* global receive status debug read register bits definitions */ +#define GRSTATR_RPCKST BITS(17, 20) /*!< received packet status */ +#define GRSTATR_DPID BITS(15, 16) /*!< data PID */ +#define GRSTATR_BCOUNT BITS(4, 14) /*!< byte count */ +#define GRSTATR_CNUM BITS(0, 3) /*!< channel number */ + +/* global status read and pop register bits definitions */ +#define GRSTATP_RPCKST BITS(17, 20) /*!< received packet status */ +#define GRSTATP_DPID BITS(15, 16) /*!< data PID */ +#define GRSTATP_BCOUNT BITS(4, 14) /*!< byte count */ +#define GRSTATP_EPNUM BITS(0, 3) /*!< endpoint number */ + +/* global receive FIFO length register bits definitions */ +#define GRFLEN_RXFD BITS(0, 15) /*!< rx FIFO depth */ + +/* host non-periodic transmit FIFO length register bits definitions */ +#define HNPTFLEN_HNPTXFD BITS(16, 31) /*!< non-periodic Tx FIFO depth */ +#define HNPTFLEN_HNPTXRSAR BITS(0, 15) /*!< non-periodic Tx RAM start address */ + +/* IN endpoint 0 transmit FIFO length register bits definitions */ +#define DIEP0TFLEN_IEP0TXFD BITS(16, 31) /*!< IN Endpoint 0 Tx FIFO depth */ +#define DIEP0TFLEN_IEP0TXRSAR BITS(0, 15) /*!< IN Endpoint 0 TX RAM start address */ + +/* host non-periodic transmit FIFO/queue status register bits definitions */ +#define HNPTFQSTAT_NPTXRQTOP BITS(24, 30) /*!< top entry of the non-periodic Tx request queue */ +#define HNPTFQSTAT_NPTXRQS BITS(16, 23) /*!< non-periodic Tx request queue space */ +#define HNPTFQSTAT_NPTXFS BITS(0, 15) /*!< non-periodic Tx FIFO space */ +#define HNPTFQSTAT_CNUM BITS(27, 30) /*!< channel number*/ +#define HNPTFQSTAT_EPNUM BITS(27, 30) /*!< endpoint number */ +#define HNPTFQSTAT_TYPE BITS(25, 26) /*!< token type */ +#define HNPTFQSTAT_TMF BIT(24) /*!< terminate flag */ + +/* global core configuration register bits definitions */ +#define GCCFG_VBUSIG BIT(21) /*!< vbus ignored */ +#define GCCFG_SOFOEN BIT(20) /*!< SOF output enable */ +#define GCCFG_VBUSBCEN BIT(19) /*!< the VBUS B-device comparer enable */ +#define GCCFG_VBUSACEN BIT(18) /*!< the VBUS A-device comparer enable */ +#define GCCFG_PWRON BIT(16) /*!< power on */ + +/* core ID register bits definitions */ +#define CID_CID BITS(0, 31) /*!< core ID */ + +/* host periodic transmit FIFO length register bits definitions */ +#define HPTFLEN_HPTXFD BITS(16, 31) /*!< host periodic Tx FIFO depth */ +#define HPTFLEN_HPTXFSAR BITS(0, 15) /*!< host periodic Tx RAM start address */ + +/* device IN endpoint transmit FIFO length register bits definitions */ +#define DIEPTFLEN_IEPTXFD BITS(16, 31) /*!< IN endpoint Tx FIFO x depth */ +#define DIEPTFLEN_IEPTXRSAR BITS(0, 15) /*!< IN endpoint FIFOx Tx x RAM start address */ + +/* host control register bits definitions */ +#define HCTL_SPDFSLS BIT(2) /*!< speed limited to FS and LS */ +#define HCTL_CLKSEL BITS(0, 1) /*!< clock select for USB clock */ + +/* host frame interval register bits definitions */ +#define HFT_FRI BITS(0, 15) /*!< frame interval */ + +/* host frame information remaining register bits definitions */ +#define HFINFR_FRT BITS(16, 31) /*!< frame remaining time */ +#define HFINFR_FRNUM BITS(0, 15) /*!< frame number */ + +/* host periodic transmit FIFO/queue status register bits definitions */ +#define HPTFQSTAT_PTXREQT BITS(24, 31) /*!< top entry of the periodic Tx request queue */ +#define HPTFQSTAT_PTXREQS BITS(16, 23) /*!< periodic Tx request queue space */ +#define HPTFQSTAT_PTXFS BITS(0, 15) /*!< periodic Tx FIFO space */ +#define HPTFQSTAT_OEFRM BIT(31) /*!< odd/eveb frame */ +#define HPTFQSTAT_CNUM BITS(27, 30) /*!< channel number */ +#define HPTFQSTAT_EPNUM BITS(27, 30) /*!< endpoint number */ +#define HPTFQSTAT_TYPE BITS(25, 26) /*!< token type */ +#define HPTFQSTAT_TMF BIT(24) /*!< terminate flag */ + +/* host all channels interrupt register bits definitions */ +#define HACHINT_HACHINT BITS(0, 11) /*!< host all channel interrupts */ + +/* host all channels interrupt enable register bits definitions */ +#define HACHINTEN_CINTEN BITS(0, 11) /*!< channel interrupt enable */ + +/* host port control and status register bits definitions */ +#define HPCS_PS BITS(17, 18) /*!< port speed */ +#define HPCS_PP BIT(12) /*!< port power */ +#define HPCS_PLST BITS(10, 11) /*!< port line status */ +#define HPCS_PRST BIT(8) /*!< port reset */ +#define HPCS_PSP BIT(7) /*!< port suspend */ +#define HPCS_PREM BIT(6) /*!< port resume */ +#define HPCS_PEDC BIT(3) /*!< port enable/disable change */ +#define HPCS_PE BIT(2) /*!< port enable */ +#define HPCS_PCD BIT(1) /*!< port connect detected */ +#define HPCS_PCST BIT(0) /*!< port connect status */ + +/* host channel-x control register bits definitions */ +#define HCHCTL_CEN BIT(31) /*!< channel enable */ +#define HCHCTL_CDIS BIT(30) /*!< channel disable */ +#define HCHCTL_ODDFRM BIT(29) /*!< odd frame */ +#define HCHCTL_DAR BITS(22, 28) /*!< device address */ +#define HCHCTL_MPC BITS(20, 21) /*!< multiple packet count */ +#define HCHCTL_EPTYPE BITS(18, 19) /*!< endpoint type */ +#define HCHCTL_LSD BIT(17) /*!< low-speed device */ +#define HCHCTL_EPDIR BIT(15) /*!< endpoint direction */ +#define HCHCTL_EPNUM BITS(11, 14) /*!< endpoint number */ +#define HCHCTL_MPL BITS(0, 10) /*!< maximum packet length */ + +/* host channel-x split transaction register bits definitions */ +#define HCHSTCTL_SPLEN BIT(31) /*!< enable high-speed split transaction */ +#define HCHSTCTL_CSPLT BIT(16) /*!< complete-split enable */ +#define HCHSTCTL_ISOPCE BITS(14, 15) /*!< isochronous OUT payload continuation encoding */ +#define HCHSTCTL_HADDR BITS(7, 13) /*!< HUB address */ +#define HCHSTCTL_PADDR BITS(0, 6) /*!< port address */ + +/* host channel-x interrupt flag register bits definitions */ +#define HCHINTF_DTER BIT(10) /*!< data toggle error */ +#define HCHINTF_REQOVR BIT(9) /*!< request queue overrun */ +#define HCHINTF_BBER BIT(8) /*!< babble error */ +#define HCHINTF_USBER BIT(7) /*!< USB bus Error */ +#define HCHINTF_NYET BIT(6) /*!< NYET */ +#define HCHINTF_ACK BIT(5) /*!< ACK */ +#define HCHINTF_NAK BIT(4) /*!< NAK */ +#define HCHINTF_STALL BIT(3) /*!< STALL */ +#define HCHINTF_DMAER BIT(2) /*!< DMA error */ +#define HCHINTF_CH BIT(1) /*!< channel halted */ +#define HCHINTF_TF BIT(0) /*!< transfer finished */ + +/* host channel-x interrupt enable register bits definitions */ +#define HCHINTEN_DTERIE BIT(10) /*!< data toggle error interrupt enable */ +#define HCHINTEN_REQOVRIE BIT(9) /*!< request queue overrun interrupt enable */ +#define HCHINTEN_BBERIE BIT(8) /*!< babble error interrupt enable */ +#define HCHINTEN_USBERIE BIT(7) /*!< USB bus error interrupt enable */ +#define HCHINTEN_NYETIE BIT(6) /*!< NYET interrupt enable */ +#define HCHINTEN_ACKIE BIT(5) /*!< ACK interrupt enable */ +#define HCHINTEN_NAKIE BIT(4) /*!< NAK interrupt enable */ +#define HCHINTEN_STALLIE BIT(3) /*!< STALL interrupt enable */ +#define HCHINTEN_DMAERIE BIT(2) /*!< DMA error interrupt enable */ +#define HCHINTEN_CHIE BIT(1) /*!< channel halted interrupt enable */ +#define HCHINTEN_TFIE BIT(0) /*!< transfer finished interrupt enable */ + +/* host channel-x transfer length register bits definitions */ +#define HCHLEN_PING BIT(31) /*!< PING token request */ +#define HCHLEN_DPID BITS(29, 30) /*!< data PID */ +#define HCHLEN_PCNT BITS(19, 28) /*!< packet count */ +#define HCHLEN_TLEN BITS(0, 18) /*!< transfer length */ + +/* host channel-x DMA address register bits definitions */ +#define HCHDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */ + +/* device control and status registers */ +/* device configuration registers bits definitions */ +#define DCFG_EOPFT BITS(11, 12) /*!< end of periodic frame time */ +#define DCFG_DAR BITS(4, 10) /*!< device address */ +#define DCFG_NZLSOH BIT(2) /*!< non-zero-length status OUT handshake */ +#define DCFG_DS BITS(0, 1) /*!< device speed */ + +/* device control registers bits definitions */ +#define DCTL_POIF BIT(11) /*!< power-on initialization finished */ +#define DCTL_CGONAK BIT(10) /*!< clear global OUT NAK */ +#define DCTL_SGONAK BIT(9) /*!< set global OUT NAK */ +#define DCTL_CGINAK BIT(8) /*!< clear global IN NAK */ +#define DCTL_SGINAK BIT(7) /*!< set global IN NAK */ +#define DCTL_GONS BIT(3) /*!< global OUT NAK status */ +#define DCTL_GINS BIT(2) /*!< global IN NAK status */ +#define DCTL_SD BIT(1) /*!< soft disconnect */ +#define DCTL_RWKUP BIT(0) /*!< remote wakeup */ + +/* device status registers bits definitions */ +#define DSTAT_FNRSOF BITS(8, 21) /*!< the frame number of the received SOF. */ +#define DSTAT_ES BITS(1, 2) /*!< enumerated speed */ +#define DSTAT_SPST BIT(0) /*!< suspend status */ + +/* device IN endpoint common interrupt enable registers bits definitions */ +#define DIEPINTEN_NAKEN BIT(13) /*!< NAK handshake sent by USBHS interrupt enable bit */ +#define DIEPINTEN_TXFEEN BIT(7) /*!< transmit FIFO empty interrupt enable bit */ +#define DIEPINTEN_IEPNEEN BIT(6) /*!< IN endpoint NAK effective interrupt enable bit */ +#define DIEPINTEN_EPTXFUDEN BIT(4) /*!< endpoint Tx FIFO underrun interrupt enable bit */ +#define DIEPINTEN_CITOEN BIT(3) /*!< control In Timeout interrupt enable bit */ +#define DIEPINTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */ +#define DIEPINTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */ + +/* device OUT endpoint common interrupt enable registers bits definitions */ +#define DOEPINTEN_NYETEN BIT(14) /*!< NYET handshake is sent interrupt enable bit */ +#define DOEPINTEN_BTBSTPEN BIT(6) /*!< back-to-back SETUP packets interrupt enable bit */ +#define DOEPINTEN_EPRXFOVREN BIT(4) /*!< endpoint Rx FIFO overrun interrupt enable bit */ +#define DOEPINTEN_STPFEN BIT(3) /*!< SETUP phase finished interrupt enable bit */ +#define DOEPINTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */ +#define DOEPINTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */ + +/* device all endpoints interrupt registers bits definitions */ +#define DAEPINT_OEPITB BITS(16, 21) /*!< device all OUT endpoint interrupt bits */ +#define DAEPINT_IEPITB BITS(0, 5) /*!< device all IN endpoint interrupt bits */ + +/* device all endpoints interrupt enable registers bits definitions */ +#define DAEPINTEN_OEPIE BITS(16, 21) /*!< OUT endpoint interrupt enable */ +#define DAEPINTEN_IEPIE BITS(0, 3) /*!< IN endpoint interrupt enable */ + +/* device Vbus discharge time registers bits definitions */ +#define DVBUSDT_DVBUSDT BITS(0, 15) /*!< device VBUS discharge time */ + +/* device Vbus pulsing time registers bits definitions */ +#define DVBUSPT_DVBUSPT BITS(0, 11) /*!< device VBUS pulsing time */ + +/* device IN endpoint FIFO empty interrupt enable register bits definitions */ +#define DIEPFEINTEN_IEPTXFEIE BITS(0, 5) /*!< IN endpoint Tx FIFO empty interrupt enable bits */ + +/* device endpoint 1 interrupt register bits definitions */ +#define DEP1INT_OEP1INT BIT(17) /*!< OUT Endpoint 1 interrupt */ +#define DEP1INT_IEP1INT BIT(1) /*!< IN Endpoint 1 interrupt */ + +/* device endpoint 1 interrupt register enable bits definitions */ +#define DEP1INTEN_OEP1INTEN BIT(17) /*!< OUT Endpoint 1 interrupt enable */ +#define DEP1INTEN_IEP1INTEN BIT(1) /*!< IN Endpoint 1 interrupt enable */ + +/* device IN endpoint 1 interrupt enable register bits definitions */ +#define DIEP1INTEN_NAKEN BIT(13) /*!< NAK handshake sent by USBHS interrupt enable bit */ +#define DIEP1INTEN_IEPNEEN BIT(6) /*!< IN endpoint NAK effective interrupt enable bit */ +#define DIEP1INTEN_EPTXFUDEN BIT(4) /*!< endpoint Tx FIFO underrun interrupt enable bit */ +#define DIEP1INTEN_CITOEN BIT(3) /*!< control In Timeout interrupt enable bit */ +#define DIEP1INTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */ +#define DIEP1INTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */ + +/* device OUT endpoint 1 interrupt enable register bits definitions */ +#define DOEP1INTEN_NYETEN BIT(14) /*!< NYET handshake is sent interrupt enable bit */ +#define DOEP1INTEN_BTBSTPEN BIT(6) /*!< back-to-back SETUP packets interrupt enable bit */ +#define DOEP1INTEN_EPRXOVREN BIT(4) /*!< endpoint Rx FIFO over run interrupt enable bit */ +#define DOEP1INTEN_STPFEN BIT(3) /*!< SETUP phase finished interrupt enable bit */ +#define DOEP1INTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */ +#define DOEP1INTEN_TFEN BIT(0) /*!< back-to-back SETUP packets interrupt enable bit */ + +/* device IN endpoint 0 control register bits definitions */ +#define DIEP0CTL_EPEN BIT(31) /*!< endpoint enable */ +#define DIEP0CTL_EPD BIT(30) /*!< endpoint disable */ +#define DIEP0CTL_SNAK BIT(27) /*!< set NAK */ +#define DIEP0CTL_CNAK BIT(26) /*!< clear NAK */ +#define DIEP0CTL_TXFNUM BITS(22, 25) /*!< tx FIFO number */ +#define DIEP0CTL_STALL BIT(21) /*!< STALL handshake */ +#define DIEP0CTL_EPTYPE BITS(18, 19) /*!< endpoint type */ +#define DIEP0CTL_NAKS BIT(17) /*!< NAK status */ +#define DIEP0CTL_EPACT BIT(15) /*!< endpoint active */ +#define DIEP0CTL_MPL BITS(0, 1) /*!< maximum packet length */ + +/* device IN endpoint x control register bits definitions */ +#define DIEPCTL_EPEN BIT(31) /*!< endpoint enable */ +#define DIEPCTL_EPD BIT(30) /*!< endpoint disable */ +#define DIEPCTL_SODDFRM BIT(29) /*!< set odd frame */ +#define DIEPCTL_SD1PID BIT(29) /*!< set DATA1 PID */ +#define DIEPCTL_SEVNFRM BIT(28) /*!< set even frame */ +#define DIEPCTL_SD0PID BIT(28) /*!< set DATA0 PID */ +#define DIEPCTL_SNAK BIT(27) /*!< set NAK */ +#define DIEPCTL_CNAK BIT(26) /*!< clear NAK */ +#define DIEPCTL_TXFNUM BITS(22, 25) /*!< tx FIFO number */ +#define DIEPCTL_STALL BIT(21) /*!< STALL handshake */ +#define DIEPCTL_EPTYPE BITS(18, 19) /*!< endpoint type */ +#define DIEPCTL_NAKS BIT(17) /*!< NAK status */ +#define DIEPCTL_EOFRM BIT(16) /*!< even/odd frame */ +#define DIEPCTL_DPID BIT(16) /*!< endpoint data PID */ +#define DIEPCTL_EPACT BIT(15) /*!< endpoint active */ +#define DIEPCTL_MPL BITS(0, 10) /*!< maximum packet length */ + +/* device OUT endpoint 0 control register bits definitions */ +#define DOEP0CTL_EPEN BIT(31) /*!< endpoint enable */ +#define DOEP0CTL_EPD BIT(30) /*!< endpoint disable */ +#define DOEP0CTL_SNAK BIT(27) /*!< set NAK */ +#define DOEP0CTL_CNAK BIT(26) /*!< clear NAK */ +#define DOEP0CTL_STALL BIT(21) /*!< STALL handshake */ +#define DOEP0CTL_SNOOP BIT(20) /*!< snoop mode */ +#define DOEP0CTL_EPTYPE BITS(18, 19) /*!< endpoint type */ +#define DOEP0CTL_NAKS BIT(17) /*!< NAK status */ +#define DOEP0CTL_EPACT BIT(15) /*!< endpoint active */ +#define DOEP0CTL_MPL BITS(0, 1) /*!< maximum packet length */ + +/* device OUT endpoint-x control register bits definitions */ +#define DOEPCTL_EPEN BIT(31) /*!< endpoint enable */ +#define DOEPCTL_EPD BIT(30) /*!< endpoint disable */ +#define DOEPCTL_SODDFRM BIT(29) /*!< set odd frame */ +#define DOEPCTL_SD1PID BIT(29) /*!< set DATA1 PID */ +#define DOEPCTL_SEVNFRM BIT(28) /*!< set even frame */ +#define DOEPCTL_SD0PID BIT(28) /*!< set DATA0 PID */ +#define DOEPCTL_SNAK BIT(27) /*!< set NAK */ +#define DOEPCTL_CNAK BIT(26) /*!< clear NAK */ +#define DOEPCTL_STALL BIT(21) /*!< STALL handshake */ +#define DOEPCTL_SNOOP BIT(20) /*!< snoop mode */ +#define DOEPCTL_EPTYPE BITS(18, 19) /*!< endpoint type */ +#define DOEPCTL_NAKS BIT(17) /*!< NAK status */ +#define DOEPCTL_EOFRM BIT(16) /*!< even/odd frame */ +#define DOEPCTL_DPID BIT(16) /*!< endpoint data PID */ +#define DOEPCTL_EPACT BIT(15) /*!< endpoint active */ +#define DOEPCTL_MPL BITS(0, 10) /*!< maximum packet length */ + +/* device IN endpoint-x interrupt flag register bits definitions */ +#define DIEPINTF_NAK BIT(13) /*!< NAK handshake sent by USBHS */ +#define DIEPINTF_TXFE BIT(7) /*!< transmit FIFO empty */ +#define DIEPINTF_IEPNE BIT(6) /*!< IN endpoint NAK effective */ +#define DIEPINTF_EPTXFUD BIT(4) /*!< endpoint Tx FIFO underrun */ +#define DIEPINTF_CITO BIT(3) /*!< control In Timeout interrupt */ +#define DIEPINTF_EPDIS BIT(1) /*!< endpoint disabled */ +#define DIEPINTF_TF BIT(0) /*!< transfer finished */ + +/* device OUT endpoint-x interrupt flag register bits definitions */ +#define DOEPINTF_NYET BIT(14) /*!< NYET handshake is sent */ +#define DOEPINTF_BTBSTP BIT(6) /*!< back-to-back SETUP packets */ +#define DOEPINTF_EPRXFOVR BIT(4) /*!< endpoint Rx FIFO overrun */ +#define DOEPINTF_STPF BIT(3) /*!< SETUP phase finished */ +#define DOEPINTF_EPDIS BIT(1) /*!< endpoint disabled */ +#define DOEPINTF_TF BIT(0) /*!< transfer finished */ + +/* device IN endpoint 0 transfer length register bits definitions */ +#define DIEP0LEN_PCNT BITS(19, 20) /*!< packet count */ +#define DIEP0LEN_TLEN BITS(0, 6) /*!< transfer length */ + +/* device OUT endpoint 0 transfer length register bits definitions */ +#define DOEP0LEN_STPCNT BITS(29, 30) /*!< SETUP packet count */ +#define DOEP0LEN_PCNT BIT(19) /*!< packet count */ +#define DOEP0LEN_TLEN BITS(0, 6) /*!< transfer length */ + +/* device IN endpoint-x transfer length register bits definitions */ +#define DIEPLEN_MCNT BITS(29, 30) /*!< multi count */ +#define DIEPLEN_PCNT BITS(19, 28) /*!< packet count */ +#define DIEPLEN_TLEN BITS(0, 18) /*!< transfer length */ + +/* device OUT endpoint-x transfer length register bits definitions */ +#define DOEPLEN_RXDPID BITS(29, 30) /*!< received data PID */ +#define DOEPLEN_STPCNT BITS(29, 30) /*!< SETUP packet count */ +#define DOEPLEN_PCNT BITS(19, 28) /*!< packet count */ +#define DOEPLEN_TLEN BITS(0, 18) /*!< transfer length */ + +/* device IN endpoint-x DMA address register bits definitions */ +#define DIEPDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */ + +/* device OUT endpoint-x DMA address register bits definitions */ +#define DOEPDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */ + +/* device IN endpoint-x transmit FIFO status register bits definitions */ +#define DIEPTFSTAT_IEPTFS BITS(0, 15) /*!< IN endpoints Tx FIFO space remaining */ + +/* USB power and clock registers bits definition */ +#define PWRCLKCTL_SHCLK BIT(1) /*!< stop HCLK */ +#define PWRCLKCTL_SUCLK BIT(0) /*!< stop the USB clock */ + +/* register options defines */ +#define DCFG_DEVSPEED(regval) (DCFG_DS & ((regval) << 0U)) /*!< device speed configuration */ + +#define USB_SPEED_EXP_HIGH DCFG_DEVSPEED(0U) /*!< device external PHY high speed */ +#define USB_SPEED_EXP_FULL DCFG_DEVSPEED(1U) /*!< device external PHY full speed */ +#define USB_SPEED_INP_FULL DCFG_DEVSPEED(3U) /*!< device internal PHY full speed */ + +#define GAHBCS_TFEL(regval) (GAHBCS_TXFTH & ((regval) << 7U)) /*!< device speed configuration */ + +#define TXFIFO_EMPTY_HALF GAHBCS_TFEL(0U) /*!< Tx FIFO half empty */ +#define TXFIFO_EMPTY GAHBCS_TFEL(1U) /*!< Tx FIFO completely empty */ + +#define GAHBCS_DMAINCR(regval) (GAHBCS_BURST & ((regval) << 1U)) /*!< AHB burst type used by DMA*/ + +#define DMA_INCR0 GAHBCS_DMAINCR(0U) /*!< single burst type used by DMA*/ +#define DMA_INCR1 GAHBCS_DMAINCR(1U) /*!< 4-beat incrementing burst type used by DMA*/ +#define DMA_INCR4 GAHBCS_DMAINCR(3U) /*!< 8-beat incrementing burst type used by DMA*/ +#define DMA_INCR8 GAHBCS_DMAINCR(5U) /*!< 16-beat incrementing burst type used by DMA*/ +#define DMA_INCR16 GAHBCS_DMAINCR(7U) /*!< 32-beat incrementing burst type used by DMA*/ + +#define DCFG_PFRI(regval) (DCFG_EOPFT & ((regval) << 11U)) /*!< end of periodic frame time configuration */ + +#define FRAME_INTERVAL_80 DCFG_PFRI(0U) /*!< 80% of the frame time */ +#define FRAME_INTERVAL_85 DCFG_PFRI(1U) /*!< 85% of the frame time */ +#define FRAME_INTERVAL_90 DCFG_PFRI(2U) /*!< 90% of the frame time */ +#define FRAME_INTERVAL_95 DCFG_PFRI(3U) /*!< 95% of the frame time */ + +#define DEP0CTL_MPL(regval) (DOEP0CTL_MPL & ((regval) << 0U)) /*!< maximum packet length configuration */ + +#define EP0MPL_64 DEP0CTL_MPL(0U) /*!< maximum packet length 64 bytes */ +#define EP0MPL_32 DEP0CTL_MPL(1U) /*!< maximum packet length 32 bytes */ +#define EP0MPL_16 DEP0CTL_MPL(2U) /*!< maximum packet length 16 bytes */ +#define EP0MPL_8 DEP0CTL_MPL(3U) /*!< maximum packet length 8 bytes */ + +/* endpoints address */ + +/* first bit is direction(0 for Rx and 1 for Tx) */ +#define EP0_OUT ((uint8_t)0x00U) /*!< endpoint out 0 */ +#define EP0_IN ((uint8_t)0x80U) /*!< endpoint in 0 */ +#define EP1_OUT ((uint8_t)0x01U) /*!< endpoint out 1 */ +#define EP1_IN ((uint8_t)0x81U) /*!< endpoint in 1 */ +#define EP2_OUT ((uint8_t)0x02U) /*!< endpoint out 2 */ +#define EP2_IN ((uint8_t)0x82U) /*!< endpoint in 2 */ +#define EP3_OUT ((uint8_t)0x03U) /*!< endpoint out 3 */ +#define EP3_IN ((uint8_t)0x83U) /*!< endpoint in 3 */ + +/* enable global interrupt */ +#define USB_GLOBAL_INT_ENABLE() (USB_GAHBCS |= GAHBCS_GINTEN) + +/* disable global interrupt */ +#define USB_GLOBAL_INT_DISABLE() (USB_GAHBCS &= ~GAHBCS_GINTEN) + +/* get current operation mode */ +#define USB_CURRENT_MODE_GET() (USB_GINTF & GINTF_COPM) + +/* read global interrupt flag */ +#define USB_CORE_INTR_READ(x) \ +do { \ + uint32_t global_intf = USB_GINTF; \ + (x) = global_intf & USB_GINTEN; \ +} while(0) + +/* read global interrupt flag */ +#define USB_DAOEP_INTR_READ(x) \ +do { \ + uint32_t dev_all_ep_inten = USB_DAEPINTEN; \ + uint32_t dev_all_ep_int = USB_DAEPINT; \ + uint32_t out_ep_intb = DAEPINT_OEPITB; \ + (x) = (dev_all_ep_inten & dev_all_ep_int & out_ep_intb) >> 16; \ +} while(0) + +/* read out endpoint-x interrupt flag */ +#define USB_DOEP_INTR_READ(x, EpID) \ +do { \ + uint32_t out_epintf = USB_DOEPxINTF(EpID); \ + (x) = out_epintf & USB_DOEPINTEN; \ +} while(0) + +/* read all in endpoint interrupt flag */ +#define USB_DAIEP_INTR_READ(x) \ +do { \ + uint32_t dev_all_ep_inten = USB_DAEPINTEN; \ + uint32_t dev_all_ep_int = USB_DAEPINT; \ + uint32_t in_ep_intb = DAEPINT_IEPITB; \ + (x) = dev_all_ep_inten & dev_all_ep_int & in_ep_intb; \ +} while(0) + + +/* read in endpoint-x interrupt flag */ +#define USB_DIEP_INTR_READ(x, EpID) \ +do { \ + uint32_t dev_ep_intf = USB_DIEPxINTF(EpID); \ + uint32_t dev_ep_fifoempty_intf = (((USB_DIEPFEINTEN >> (EpID)) & 0x1U) << 7U); \ + uint32_t dev_inep_inten = USB_DIEPINTEN; \ + (x) = dev_ep_intf & (dev_ep_fifoempty_intf | dev_inep_inten); \ +} while(0) + +/* generate remote wakup signal */ +#define USB_REMOTE_WAKEUP_SET() (USB_DCTL |= DCTL_RWKUP) + +/* no remote wakup signal generate */ +#define USB_REMOTE_WAKEUP_RESET() (USB_DCTL &= ~DCTL_RWKUP) + +/* generate soft disconnect */ +#define USB_SOFT_DISCONNECT_ENABLE() (USB_DCTL |= DCTL_SD) + +/* no soft disconnect generate */ +#define USB_SOFT_DISCONNECT_DISABLE() (USB_DCTL &= ~DCTL_SD) + +/* set device address */ +#define USB_SET_DEVADDR(DevAddr) (USB_DCFG |= (DevAddr) << 4U) + +/* check whether frame is even */ +#define USB_EVEN_FRAME() (!(USB_HFINFR & 0x01U)) + +/* read port status */ +#define USB_PORT_READ() (USB_HPCS & (~HPCS_PE) & (~HPCS_PCD) & (~HPCS_PEDC)) + +/* usb clock initialize */ +#define USB_FSLSCLOCK_INIT(ClockFreq) (USB_HCTL &= ~HCTL_CLKSEL | (ClockFreq)) + +/* get usb current speed */ +#define USB_CURRENT_SPEED_GET() ((USB_HPCS & HPCS_PS) >> 17) + +/* get usb current frame */ +#define USB_CURRENT_FRAME_GET() (USB_HFINFR & 0xFFFFU) + +#endif /* USB_REGS_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_std.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_std.h new file mode 100644 index 0000000000..b7fa5d8e9a --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usb_std.h @@ -0,0 +1,188 @@ +/*! + \file usb_std.h + \brief USB 2.0 standard defines +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef USB_STD_H +#define USB_STD_H + +#include "usb_conf.h" + +#define USB_DEV_QUALIFIER_DESC_LEN 0x0AU /*!< USB device qualifier descriptor length */ +#define USB_DEV_DESC_LEN 0x12U /*!< USB device descriptor length */ +#define USB_CFG_DESC_LEN 0x09U /*!< USB device configuration descriptor length */ +#define USB_IF_DESC_LEN 0x09U /*!< USB device interface descriptor length */ +#define USB_EP_DESC_LEN 0x07U /*!< USB device endpoint descriptor length */ +#define USB_OTG_DESC_LEN 0x03U /*!< USB device OTG descriptor length */ + +/* bit 7 of bmRequestType: data phase transfer direction */ +#define USB_DIR_MASK 0x80U /*!< USB transfer direction mask */ +#define USB_DIR_OUT 0x00U /*!< USB transfer OUT direction */ +#define USB_DIR_IN 0x80U /*!< USB transfer IN direction */ + +/* bit 6..5 of bmRequestType: request type */ +#define USB_STANDARD_REQ 0x00U /*!< USB standard request */ +#define USB_CLASS_REQ 0x20U /*!< USB class request */ +#define USB_VENDOR_REQ 0x40U /*!< USB vebdor request */ +#define USB_REQ_MASK 0x60U /*!< USB request mask */ + +/* bit 4..0 of bmRequestType: recipient type */ +#define USB_REQTYPE_DEVICE 0x00U /*!< USB device request type */ +#define USB_REQTYPE_INTERFACE 0x01U /*!< USB interface request type*/ +#define USB_REQTYPE_ENDPOINT 0x02U /*!< USB endpoint request type*/ +#define USB_REQTYPE_MASK 0x03U /*!< USB request type mask*/ + +/* bRequest value */ +#define USBREQ_GET_STATUS 0x00U /*!< USB get status request*/ +#define USBREQ_CLEAR_FEATURE 0x01U /*!< USB clear feature request*/ +#define USBREQ_SET_FEATURE 0x03U /*!< USB set feature request*/ +#define USBREQ_SET_ADDRESS 0x05U /*!< USB set address request*/ +#define USBREQ_GET_DESCRIPTOR 0x06U /*!< USB get descriptor request*/ +#define USBREQ_SET_DESCRIPTOR 0x07U /*!< USB set descriptor request*/ +#define USBREQ_GET_CONFIGURATION 0x08U /*!< USB get configuration request*/ +#define USBREQ_SET_CONFIGURATION 0x09U /*!< USB set configuration request*/ +#define USBREQ_GET_INTERFACE 0x0AU /*!< USB get interface request*/ +#define USBREQ_SET_INTERFACE 0x0BU /*!< USB set interface request*/ +#define USBREQ_SYNCH_FRAME 0x0CU /*!< USB synchronize frame request*/ + +/* descriptor types of usb specifications */ +#define USB_DESCTYPE_DEVICE 0x01U /*!< USB device descriptor type*/ +#define USB_DESCTYPE_CONFIGURATION 0x02U /*!< USB configuration descriptor type*/ +#define USB_DESCTYPE_STRING 0x03U /*!< USB string descriptor type*/ +#define USB_DESCTYPE_INTERFACE 0x04U /*!< USB interface descriptor type*/ +#define USB_DESCTYPE_ENDPOINT 0x05U /*!< USB endpoint descriptor type*/ +#define USB_DESCTYPE_DEVICE_QUALIFIER 0x06U /*!< USB device qualtfier descriptor type*/ +#define USB_DESCTYPE_OTHER_SPEED_CONFIGURATION 0x07U /*!< USB other speed configuration descriptor type*/ +#define USB_DESCTYPE_INTERFACE_POWER 0x08U /*!< USB interface power descriptor type*/ + +#define USB_DESCTYPE_HID 0x21U /*!< USB HID descriptor type*/ +#define USB_DESCTYPE_HID_REPORT 0x22U /*!< USB HID report descriptor type*/ + +#define USB_DEVDESC_SIZE 18U /*!< USB device descriptor size*/ +#define USB_CFGDESC_SIZE 9U /*!< USB configure descriptor size*/ +#define USB_INTDESC_SIZE 9U /*!< USB interface descriptor size*/ +#define USB_EPDESC_SIZE 7U /*!< USB endpoint descriptor size*/ + +/* descriptor type and descriptor index */ +/* use the following values when USB host need to get descriptor */ +#define USB_DEVDESC ((USB_DESCTYPE_DEVICE << 8U) & 0xFF00U) /*!< USB device operation marco */ +#define USB_CFGDESC ((USB_DESCTYPE_CONFIGURATION << 8U) & 0xFF00U) /*!< USB configuration operation marco */ +#define USB_STRDESC ((USB_DESCTYPE_STRING << 8U) & 0xFF00U) /*!< USB string operation marco */ +#define USB_INTDESC ((USB_DESCTYPE_INTERFACE << 8U) & 0xFF00U) /*!< USB interface operation marco */ +#define USB_EPDESC ((USB_DESCTYPE_INTERFACE << 8U) & 0xFF00U) /*!< USB endpoint operation marco */ +#define USB_DEVQUADESC ((USB_DESCTYPE_DEVICE_QUALIFIER << 8U) & 0xFF00U) /*!< USB device qualifier operation marco */ +#define USB_OSPCFGDESC ((USB_DESCTYPE_OTHER_SPEED_CONFIGURATION << 8U) & 0xFF00U) /*!< USB other speed configuration operation marco */ +#define USB_INTPWRDESC ((USB_DESCTYPE_INTERFACE_POWER << 8U) & 0xFF00U) /*!< USB interface power operation marco */ +#define USB_HIDREPDESC ((USB_DESCTYPE_HID_REPORT << 8U) & 0xFF00U) /*!< USB HID report operation marco */ +#define USB_HIDDESC ((USB_DESCTYPE_HID << 8U) & 0xFF00U) /*!< USB HID operation marco */ + +#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ + (uint16_t)(((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U)) + +/* supported classes */ +#define USB_MSC_CLASS 0x08U /*!< USB MSC class*/ +#define USB_HID_CLASS 0x03U /*!< USB HID class*/ + +/* interface descriptor field values for hid boot protocol */ +#define HID_BOOT_CODE 0x01U /*!< USB HID boot code*/ +#define HID_KEYBRD_BOOT_CODE 0x01U /*!< USB HID keyboard boot code*/ +#define HID_MOUSE_BOOT_CODE 0x02U /*!< USB HID mouse boot code*/ + +/* as per usb specs 9.2.6.4 :standard request with data request timeout: 5sec + standard request with no data stage timeout : 50ms */ +#define DATA_STAGE_TIMEOUT 5000U /*!< USB data stage timeout*/ +#define NODATA_STAGE_TIMEOUT 50U /*!< USB no data stage timeout*/ + +#define USBH_CFG_DESC_SET_SIZE (USB_CFGDESC_SIZE + USB_INTDESC_SIZE \ + + (USBH_MAX_EP_NUM * USB_EPDESC_SIZE)) /*!< USB host set configuration descriptor size */ + +#pragma pack(1) + +typedef union +{ + uint8_t data[8]; + + struct _setup_packet_struct + { + uint8_t bmRequestType; /*!< type of request */ + uint8_t bRequest; /*!< request of setup packet */ + uint16_t wValue; /*!< value of setup packet */ + uint16_t wIndex; /*!< index of setup packet */ + uint16_t wLength; /*!< length of setup packet */ + } b; +}usb_setup_union; + +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; + +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; + +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; + +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() + +#endif /* USB_STD_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_core.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_core.h new file mode 100644 index 0000000000..8b79c2ed5a --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_core.h @@ -0,0 +1,54 @@ +/*! + \file usbd_core.h + \brief USB device-mode core driver header file +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + + +#ifndef USBD_CORE_H +#define USBD_CORE_H + +#include "usbd_conf.h" +#include "usb_core.h" +#include "usbd_std.h" + +/* device status */ +#define USB_STATUS_DEFAULT 1U /* default status */ +#define USB_STATUS_ADDRESSED 2U /* addressed status */ +#define USB_STATUS_CONFIGURED 3U /* configured status */ +#define USB_STATUS_SUSPENDED 4U /* suspended status */ + +/* function declarations */ +/* initailizes the USB device-mode handler stack */ +void usbd_init (usb_core_handle_struct *pudev, usb_core_id_enum core_id); +/* endpoint initialization */ +void usbd_ep_init (usb_core_handle_struct *pudev, const usb_descriptor_endpoint_struct *pep_desc); +/* endpoint deinitialize */ +void usbd_ep_deinit (usb_core_handle_struct *pudev, uint8_t ep_addr); +/* endpoint prepare to receive data */ +void usbd_ep_rx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len); +/* endpoint prepare to transmit data */ +void usbd_ep_tx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len); +/* transmit data on the control channel */ +usbd_status_enum usbd_ctltx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len); +/* receive data on the control channel */ +usbd_status_enum usbd_ctlrx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len); +/* transmit status on the control channel */ +usbd_status_enum usbd_ctlstatus_tx (usb_core_handle_struct *pudev); +/* receive status on the control channel */ +usbd_status_enum usbd_ctlstatus_rx (usb_core_handle_struct *pudev); +/* set an endpoint to STALL status */ +void usbd_ep_stall (usb_core_handle_struct *pudev, uint8_t ep_addr); +/* clear endpoint stalled status */ +void usbd_ep_clear_stall (usb_core_handle_struct *pudev, uint8_t ep_addr); +/* flushes the FIFOs */ +void usbd_ep_fifo_flush (usb_core_handle_struct *pudev, uint8_t ep_addr); +/* get the received data length */ +uint16_t usbd_rxcount_get (usb_core_handle_struct *pudev, uint8_t ep_id); + +#endif /* USBD_CORE_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_int.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_int.h new file mode 100644 index 0000000000..3247853be5 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_int.h @@ -0,0 +1,31 @@ +/*! + \file usbd_int.h + \brief USB device-mode interrupt handler header file +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef USBD_INT_H +#define USBD_INT_H + +#include "usbd_core.h" + +/* function declarations */ +/* USB device-mode interrupts global service routine handler */ +uint32_t usbd_isr (usb_core_handle_struct *pudev); + +#ifdef USBHS_DEDICATED_EP1_ENABLED + +/* USB dedicated OUT endpoint 1 interrupt service routine handler */ +uint32_t USBD_EP1OUT_ISR_Handler (usb_core_handle_struct *pudev); +/* USB dedicated IN endpoint 1 interrupt service routine handler */ +uint32_t USBD_EP1IN_ISR_Handler (usb_core_handle_struct *pudev); + +#endif /* USBHS_DEDICATED_EP1_ENABLED */ + +#endif /* USBD_INT_H */ + diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_std.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_std.h new file mode 100644 index 0000000000..494f0ec3aa --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbd_std.h @@ -0,0 +1,70 @@ +/*! + \file usbd_std.h + \brief USB 2.0 standard driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-06-30, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef USBD_STD_H +#define USBD_STD_H + +#include "usb_std.h" +#include "usbd_core.h" +#include "usbd_conf.h" +#include + +#define USBD_LANGID_STR_IDX 0x00U /*!< USB language ID string index*/ +#define USBD_MFC_STR_IDX 0x01U /*!< USB manufacturer string index*/ +#define USBD_PRODUCT_STR_IDX 0x02U /*!< USB product string index*/ +#define USBD_SERIAL_STR_IDX 0x03U /*!< USB serial string index*/ +#define USBD_CONFIG_STR_IDX 0x04U /*!< USB configuration string index*/ +#define USBD_INTERFACE_STR_IDX 0x05U /*!< USB interface string index*/ + +#define USB_STATUS_REMOTE_WAKEUP 0x02U /*!< USB remote wakeup status*/ +#define USB_STATUS_SELF_POWERED 0x01U /*!< USB self power status*/ + +#define USB_FEATURE_ENDP_HALT 0x00U /*!< USB halt endpoint feature*/ +#define USB_FEATURE_REMOTE_WAKEUP 0x01U /*!< USB remote wakeup feature*/ +#define USB_FEATURE_TEST_MODE 0x02U /*!< USB test mode feature*/ + +#define ENG_LANGID 0x0409U /*!< USB english language id*/ +#define CHN_LANGID 0x0804U /*!< USB chinese language id*/ + +#define USB_DEVICE_DESC_SIZE 0x12U /*!< USB device descriptor size*/ + +#define LOWBYTE(x) ((uint8_t)((x) & 0x00FFU)) /*!< USB lowbyte operation marco*/ +#define HIGHBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) /*!< USB highbyte operation marco*/ + +#define USB_MIN(a, b) (((a) < (b)) ? (a) : (b)) /*!< USB minimum operation marco*/ + +#define WIDE_STRING(string) _WIDE_STRING(string) +#define _WIDE_STRING(string) L##string + +#define USBD_STRING_DESC(string) \ + (uint8_t *)&(struct { \ + uint8_t _len; \ + uint8_t _type; \ + wchar_t _data[sizeof(string)]; \ + }) { \ + sizeof(WIDE_STRING(string)) + 2U - 2U, \ + USB_DESCTYPE_STRING, \ + WIDE_STRING(string) \ + } + +#define IS_NOT_EP0(ep_addr) (((ep_addr) != 0x00U) && ((ep_addr) != 0x80U)) + +/* function declarations */ +/* USB device setup transaction*/ +usbd_status_enum usbd_setup_transaction (usb_core_handle_struct *pudev); +/* USB device out transaction*/ +usbd_status_enum usbd_out_transaction (usb_core_handle_struct *pudev, uint8_t endp_num); +/* USB device in transaction*/ +usbd_status_enum usbd_in_transaction (usb_core_handle_struct *pudev, uint8_t endp_num); +/* USB device enum error handle*/ +void usbd_enum_error (usb_core_handle_struct *pudev, usb_device_req_struct *req); + +#endif /* USBD_STD_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_core.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_core.h new file mode 100644 index 0000000000..f4e8739687 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_core.h @@ -0,0 +1,283 @@ +/*! + \file usbh_core.h + \brief header file for usbh_core.c +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.1, firmware for GD32F4xx +*/ + +#ifndef USBH_CORE_H +#define USBH_CORE_H + +#include "usbh_conf.h" +#include "usb_std.h" +#include "usb_core.h" + +#define MSC_CLASS 0x08 /*!< the MSC class define */ +#define HID_CLASS 0x03 /*!< the HID class define */ +#define MSC_PROTOCOL 0x50 /*!< the MSC protocal define */ +#define CBI_PROTOCOL 0x01 /*!< the CBI protocal define */ + +#define USBH_DEVICE_ADDRESS_DEFAULT 0U /*!< the default device address define */ +#define USBH_DEVICE_ADDRESS 1U /*!< the device address define */ +#define USBH_MAX_ERROR_COUNT 2U /*!< the max error count define */ + +#define HOST_USER_SELECT_CONFIGURATION 1U /*!< the user select configuration define */ +#define HOST_USER_CLASS_ACTIVE 2U /*!< the user class active define */ +#define HOST_USER_CLASS_SELECTED 3U /*!< the user class selected define */ +#define HOST_USER_CONNECTION 4U /*!< the user connecttion define */ +#define HOST_USER_DISCONNECTION 5U /*!< the user disconnection define */ +#define HOST_USER_UNRECOVERED_ERROR 6U /*!< the user unrecovered error define */ + +#define MAX_USBH_STATE_STACK_DEEP 4 /*!< the max state stack deep define */ +#define MAX_USBH_STATE_TABLE_NUM 10U /*!< the max state table number */ + +#define HOST_FSM_ID 0U /*!< the host state table id */ +#define ENUM_FSM_ID 1U /*!< the enum state table id */ +#define CMD_FSM_ID 2U /*!< the cmd state table id */ +#define CTRL_FSM_ID 3U /*!< the ctrl state table id */ +#define CLASS_REQ_FSM_ID 4U /*!< the class req state table id */ +#define CLASS_FSM_ID 5U /*!< the class state table id */ + +#define UP_STATE 100U /*!< up state define */ +#define GO_TO_UP_STATE_EVENT 100U /*!< go to up state event define */ + +#define HOST_HANDLE_TABLE_SIZE 9U /*!< the host handle table size define */ + +/* the enum of host state */ +typedef enum +{ + HOST_IDLE = 0, /* the host idle state definition */ + HOST_DEV_ATTACHED, /* the host device attached state definition */ + HOST_DEV_DETACHED, /* the host device detached state definition */ + HOST_DETECT_DEV_SPEED, /* the host detect device speed state definition */ + HOST_ENUMERATION, /* the host enumeration state definition */ + HOST_CLASS_REQUEST, /* the host class request state definition */ + HOST_CLASS, /* the host class state definition */ + HOST_USER_INPUT, /* the host user input state definition */ + HOST_SUSPENDED, /* the host suspended state definition */ + HOST_ERROR /* the host error state definition */ +}host_state_enum; + +/* the enum of host event */ +typedef enum +{ + HOST_EVENT_ATTACHED = 0, /* the host attached event */ + HOST_EVENT_ENUM, /* the host enum event */ + HOST_EVENT_USER_INPUT, /* the host user input event */ + HOST_EVENT_CLASS_REQ, /* the host class request event */ + HOST_EVENT_CLASS, /* the host class event */ + HOST_EVENT_ERROR, /* the host error event */ + HOST_EVENT_DEV_DETACHED, /* the host device detached event */ + HOST_EVENT_IDLE /* the host idle event */ +}host_event_enum; + +/* the enum of enum state */ +typedef enum +{ + ENUM_IDLE = 0, /* the enum idle state definition */ + ENUM_SET_ADDR, /* the enum set address state definition */ + ENUM_GET_FULL_DEV_DESC, /* the enum get full device descripter state definition */ + ENUM_GET_CFG_DESC, /* the enum get configuration descripter state definition */ + ENUM_GET_FULL_CFG_DESC, /* the enum get full configuration descripter state definition */ + ENUM_GET_MFC_STRING_DESC, /* the enum get MFC string descripter state definition */ + ENUM_GET_PRODUCT_STRING_DESC, /* the enum get product string descripter state definition */ + ENUM_GET_SERIALNUM_STRING_DESC, /* the enum get serialnum string descripter state definition */ + ENUM_SET_CONFIGURATION, /* the enum set congiguration state definition */ + ENUM_DEV_CONFIGURED /* the enum device configuration state definition */ +}enum_state_enum; + +/* the enum of ctrl state */ +typedef enum +{ + CTRL_IDLE = 0, /* the ctrl idle state definition */ + CTRL_SETUP, /* the ctrl setup state definition */ + CTRL_DATA, /* the ctrl data state definition */ + CTRL_STATUS, /* the ctrl status state definition */ + CTRL_ERROR, /* the ctrl error state definition */ + CTRL_STALLED, /* the ctrl stalled state definition */ + CTRL_COMPLETE /* the ctrl complete state definition */ +}ctrl_state_enum; + +/* the enum of host status */ +typedef enum +{ + USBH_OK = 0, /* the usbh ok status definition */ + USBH_BUSY, /* the usbh busy status definition */ + USBH_FAIL, /* the usbh fail status definition */ + USBH_NOT_SUPPORTED, /* the usbh not supported status definition */ + USBH_UNRECOVERED_ERROR, /* the usbh unrecovered error status definition */ + USBH_SPEED_UNKNOWN_ERROR, /* the usbh speed unknown error status definition */ + USBH_APPLY_DEINIT /* the usbh apply deinit status definition */ +}usbh_status_enum; + +/* the state of user action */ +typedef enum +{ + USBH_USER_NO_RESP = 0, /* the user no response */ + USBH_USER_RESP_OK = 1, /* the user response ok */ +}usbh_user_status_enum; + +/* control transfer information */ +typedef struct +{ + uint8_t hc_in_num; /* the host in channel number */ + uint8_t hc_out_num; /* the host out channel number */ + uint8_t ep0_size; /* the endpoint 0 max packet size */ + uint8_t error_count; /* the error count */ + uint16_t length; /* the length */ + uint16_t timer; /* the timer */ + uint8_t *buff; /* the buffer */ + usb_setup_union setup; /* the setup packet */ +}usbh_ctrl_struct; + +/* device property */ +typedef struct +{ + uint8_t address; /* the device address */ + uint8_t speed; /* the device speed */ + usb_descriptor_device_struct dev_desc; /* the device descripter */ + usb_descriptor_configuration_struct cfg_desc; /* the configuration descripter */ + usb_descriptor_interface_struct itf_desc[USBH_MAX_INTERFACES_NUM]; /* the interface descripter */ + usb_descriptor_endpoint_struct ep_desc[USBH_MAX_INTERFACES_NUM][USBH_MAX_EP_NUM]; /* the endpoint descripter */ +}usbh_device_struct; + +/* user callbacks */ +typedef struct +{ + void (*init) (void); /* the user callback init function */ + void (*deinit) (void); /* the user callback deinit function */ + void (*device_connected) (void); /* the user callback device connected function */ + void (*device_reset) (void); /* the user callback device reset function */ + void (*device_disconnected) (void); /* the user callback device disconnected function */ + void (*over_current_detected) (void); /* the user callback over current detected function */ + void (*device_speed_detected) (uint8_t device_speed); /* the user callback device speed detected function */ + void (*device_desc_available) (void *devDesc); /* the user callback device descrpiter available function */ + void (*device_address_set) (void); /* the user callback set device address function */ + + void (*configuration_desc_available)(usb_descriptor_configuration_struct *cfg_desc, + usb_descriptor_interface_struct *itf_desc, + usb_descriptor_endpoint_struct *ep_desc); + /* the configuration descripter available function */ + + void (*manufacturer_string) (void *mfc_string); /* the user callback manufacturer string function */ + void (*product_string) (void *prod_string); /* the user callback product string function */ + void (*serial_num_string) (void *serial_string); /* the user callback serial number string function */ + void (*enumeration_finish) (void); /* the user callback enumeration finish function */ + usbh_user_status_enum (*user_input) (void); /* the user callback user input function */ + int (*user_application) (usb_core_handle_struct *pudev, uint8_t id); + /* the user callback user appliction function */ + void (*device_not_supported) (void); /* the user callback device not supported function */ + void (*unrecovered_error) (void); /* the user callback unrecovered error function */ +}usbh_user_callback_struct; + +/* the backup state struct */ +typedef struct +{ + host_state_enum host_backup_state; /* the host backup state */ + enum_state_enum enum_backup_state; /* the enum backup state */ + ctrl_state_enum ctrl_backup_state; /* the ctrl backup state */ + uint8_t class_req_backup_state;/* the class request backup state */ + uint8_t class_backup_state; /* the class backup state */ +} backup_state_struct; + +/* host information */ +typedef struct +{ + backup_state_struct usbh_backup_state; /* the usbh backup state variable */ + usbh_ctrl_struct control; /* the control struct variable */ + usbh_device_struct device; /* the device struct variable */ + usbh_user_callback_struct *usr_cb; /* the user callback function */ + usbh_status_enum (*class_init) (usb_core_handle_struct *pudev, void *phost); /* the class init function */ + void (*class_deinit) (usb_core_handle_struct *pudev, void *phost); /* the class deinit function */ +}usbh_host_struct; + +/* the action function definition */ +typedef usbh_status_enum (*ACT_FUN) (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void* pustate); + +/* the state table struct */ +typedef struct +{ + uint8_t cur_state; /* the current state */ + uint8_t cur_event; /* the current event */ + uint8_t next_state; /* the next state */ + ACT_FUN event_action_fun; /* the event action function entry */ +} state_table_struct; + +/* the state stack struct */ +typedef struct +{ + uint8_t state; /* the state in state stack */ + state_table_struct* table; /* the table in state stack */ + uint8_t table_size; /* the table size in state stack */ +} usbh_state_stack_struct; + +/* the state regist table struct */ +typedef struct +{ + uint8_t id; /* the id of the state table */ + state_table_struct* table; /* the table entry to regist */ + uint8_t table_size; /* the table size to regist */ +} usbh_state_regist_table_struct; + +/* the state handle struct */ +typedef struct +{ + uint8_t usbh_current_state; /* current state */ + uint8_t usbh_current_state_table_size; /* current state table size */ + state_table_struct* usbh_current_state_table; /* current state table */ + + usbh_state_stack_struct stack[MAX_USBH_STATE_STACK_DEEP]; /* the stack of state table */ + int8_t usbh_current_state_stack_top; /* the current state top */ + + usbh_state_regist_table_struct usbh_regist_state_table[MAX_USBH_STATE_TABLE_NUM]; /* the array of regist state table */ + uint8_t usbh_regist_state_table_num; /* the number of regist state table */ +} usbh_state_handle_struct; + +/* function declarations */ +/* the host core driver function */ +usbh_status_enum host_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate); +/* initialize the host portion of the driver */ +uint32_t hcd_init (usb_core_handle_struct *pudev, usb_core_id_enum core_id); +/* check if the device is connected */ +uint32_t hcd_is_device_connected (usb_core_handle_struct *pudev); +/* this function returns the last URBstate */ +urb_state_enum hcd_urb_state_get (usb_core_handle_struct *pudev, uint8_t channel_num); +/* this function returns the last URBstate */ +uint32_t hcd_xfer_count_get (usb_core_handle_struct *pudev, uint8_t channel_num); +/* de-initialize host */ +usbh_status_enum usbh_deinit (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct* pustate); + +/* the state core driver function */ +/* state core driver init */ +void scd_init (usbh_state_handle_struct* pustate); +/* state core driver table regist */ +void scd_table_regist (usbh_state_handle_struct* pustate, + state_table_struct* pstate_table, + uint8_t table_id, + uint8_t current_table_size); +/* state core driver begin */ +void scd_begin (usbh_state_handle_struct* pustate, uint8_t table_id); +/* state core driver move state */ +void scd_state_move (usbh_state_handle_struct* pustate, uint8_t state); +/* state core driver event handle */ +usbh_status_enum scd_event_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct* pustate, + uint8_t event, + uint8_t state); +/* state core driver table push */ +void scd_table_push (usbh_state_handle_struct* pustate); +/* state core driver table pop */ +void scd_table_pop (usbh_state_handle_struct* pustate); +/* the function is only used to state move */ +usbh_status_enum only_state_move (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate); +/* the function to the up state */ +usbh_status_enum goto_up_state_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate); + +#endif /* USBH_CORE_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_ctrl.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_ctrl.h new file mode 100644 index 0000000000..4b30c64d1a --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_ctrl.h @@ -0,0 +1,45 @@ +/*! + \file usbh_ctrl.h + \brief header file for usbh_ctrl.c +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef USBH_CTRL_H +#define USBH_CTRL_H + +#include "usbh_core.h" +#include "usbh_usr.h" + +#define CTRL_HANDLE_TABLE_SIZE 13U /*!< the ctrl handle table size define */ + +extern state_table_struct ctrl_handle_table[CTRL_HANDLE_TABLE_SIZE]; +extern uint8_t ctrl_polling_handle_flag; + +/* the enum of CTRL event */ +typedef enum +{ + CTRL_EVENT_IDLE = 0, /* the ctrl idle event */ + CTRL_EVENT_SETUP, /* the ctrl setup event */ + CTRL_EVENT_DATA, /* the ctrl data event */ + CTRL_EVENT_STATUS, /* the ctrl status event */ + CTRL_EVENT_COMPLETE, /* the ctrl complete event */ + CTRL_EVENT_ERROR, /* the ctrl error event */ + CTRL_EVENT_STALLED, /* the ctrl stalled event */ +}ctrl_event_enum; + +/* function declarations */ +/* the polling function of control transfer state handle */ +usbh_status_enum ctrl_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate); +/* send datas from the host channel */ +usbh_status_enum usbh_xfer (usb_core_handle_struct *pudev, uint8_t *buf, uint8_t hc_num, uint16_t len); +/* send the setup packet to the device */ +usbh_status_enum usbh_ctltx_setup (usb_core_handle_struct *pudev, uint8_t *buf, uint8_t hc_num); +/* this function prepare a hc and start a transfer */ +uint32_t hcd_submit_request (usb_core_handle_struct *pudev, uint8_t channel_num); + +#endif /* USBH_CTRL_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_hcs.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_hcs.h new file mode 100644 index 0000000000..34bdff55b7 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_hcs.h @@ -0,0 +1,46 @@ +/*! + \file usbh_hcs.h + \brief header file for usbh_hcs.c +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef USBH_HCS_H +#define USBH_HCS_H + +#include "usbh_core.h" + +#define HC_MAX 8U + +#define HC_OK 0x0000U +#define HC_USED 0x8000U +#define HC_ERROR 0xFFFFU +#define HC_USED_MASK 0x7FFFU + +/* function declarations */ +/* allocate a new channel for the pipe */ +uint8_t usbh_channel_alloc (usb_core_handle_struct *pudev, uint8_t ep_addr); +/* free all usb host channel */ +uint8_t usbh_allchannel_dealloc (usb_core_handle_struct *pudev); +/* free the usb host channel */ +uint8_t usbh_channel_free (usb_core_handle_struct *pudev, uint8_t index); +/* open a channel */ +uint8_t usbh_channel_open (usb_core_handle_struct *pudev, + uint8_t channel_num, + uint8_t dev_addr, + uint8_t dev_speed, + uint8_t ep_type, + uint16_t ep_mps); +/* modify a channel */ +uint8_t usbh_channel_modify (usb_core_handle_struct *pudev, + uint8_t channel_num, + uint8_t dev_addr, + uint8_t dev_speed, + uint8_t ep_type, + uint16_t ep_mps); + +#endif /* USBH_HCS_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_int.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_int.h new file mode 100644 index 0000000000..9fac257295 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_int.h @@ -0,0 +1,30 @@ +/*! + \file usbh_int.h + \brief USB host mode interrupt handler header file +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.1, firmware for GD32F4xx +*/ + +#ifndef USBH_INT_H +#define USBH_INT_H + +#include "usb_core.h" + +typedef struct +{ + uint8_t (*sof) (usb_core_handle_struct *pudev); + uint8_t (*device_connected) (usb_core_handle_struct *pudev); + uint8_t (*device_disconnected) (usb_core_handle_struct *pudev); +}usbh_hcd_int_cb_struct; + +extern usbh_hcd_int_cb_struct *usbh_hcd_int_fops; + +/* function declarations */ +/* handle global host interrupt */ +uint32_t usbh_isr (usb_core_handle_struct *pudev); + +#endif /* USBH_INT_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_std.h b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_std.h new file mode 100644 index 0000000000..2dbc45ee30 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Include/usbh_std.h @@ -0,0 +1,74 @@ +/*! + \file usbh_std.h + \brief header file for usbh_std.c +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef USBH_STD_H +#define USBH_STD_H + +#include "usbh_core.h" +#include "usbh_usr.h" + +/* standard feature selector for clear feature command */ +#define FEATURE_SELECTOR_ENDPOINT 0x00U +#define FEATURE_SELECTOR_DEVICE 0x01U + +#define USBH_SETUP_PACKET_SIZE 8U /* setup packet size */ +#define ENUM_HANDLE_TABLE_SIZE 10U /* enumerate handle table size */ + +extern uint8_t usbh_cfg_desc[512]; +extern uint8_t enum_polling_handle_flag; +extern state_table_struct enum_handle_table[ENUM_HANDLE_TABLE_SIZE]; + +typedef enum +{ + ENUN_EVENT_IDLE = 0, /* the enum idle event */ + ENUM_EVENT_SET_ADDR, /* the enum set address event */ + ENUN_EVENT_GET_FULL_DEV_DESC, /* the enum get full device descripter event */ + ENUN_EVENT_GET_CFG_DESC, /* the enum get congiguration descripter event */ + ENUN_EVENT_GET_FULL_CFG_DESC, /* the enum get full configuration descripter event */ + ENUN_EVENT_GET_MFC_STRING_DESC, /* the enum get MFC string descripter event */ + ENUN_EVENT_GET_PRODUCT_STRING_DESC, /* the enum get product string event */ + ENUN_EVENT_GET_SERIALNUM_STRING_DESC, /* the enum get serialnum string event */ + ENUN_EVENT_SET_CONFIGURATION, /* the enum set configuration event */ + ENUN_EVENT_DEV_CONFIGURED /* the enum device configured event */ +}enum_event_enum; + +/* function declarations */ +/* the polling function of enumeration state */ +usbh_status_enum enum_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate); +/* get descriptor in usb host enumeration stage */ +void usbh_enum_desc_get (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + uint8_t *buf, + uint8_t req_type, + uint16_t value_idx, + uint16_t len); +/* set address in usb host enumeration stage */ +void usbh_enum_addr_set (usb_core_handle_struct *pudev, usbh_host_struct *puhost, uint8_t device_address); +/* set configuration in usb host enumeration stage */ +void usbh_enum_cfg_set (usb_core_handle_struct *pudev, usbh_host_struct *puhost, uint16_t cfg_idx); +/* parse the device descriptor */ +void usbh_device_desc_parse (usb_descriptor_device_struct *dev_desc, uint8_t *buf, uint16_t len); +/* parse the configuration descriptor */ +void usbh_cfg_desc_parse (usb_descriptor_configuration_struct *cfg_desc, + usb_descriptor_interface_struct *itf_desc, + usb_descriptor_endpoint_struct ep_desc[][USBH_MAX_EP_NUM], + uint8_t *buf, + uint16_t len); +/* parse the interface descriptor */ +void usbh_interface_desc_parse (usb_descriptor_interface_struct *itf_desc, uint8_t *buf); +/* parse the endpoint descriptor */ +void usbh_endpoint_desc_parse (usb_descriptor_endpoint_struct *ep_desc, uint8_t *buf); +/* parse the string descriptor */ +void usbh_string_desc_parse (uint8_t *psrc, uint8_t *pdest, uint16_t len); +/* get the next descriptor header */ +usb_descriptor_header_struct *usbh_next_desc_get (uint8_t *pbuf, uint16_t *ptr); + +#endif /* USBH_STD_H */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usb_core.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usb_core.c new file mode 100644 index 0000000000..18834acd9e --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usb_core.c @@ -0,0 +1,1132 @@ +/*! + \file usb_core.c + \brief USB core driver which can operate in host-mode and device-mode +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "usb_core.h" + +static void usb_commonint_enable (usb_core_handle_struct *pudev); +static usb_status_enum usb_core_reset (usb_core_handle_struct *pudev); + +/*! + \brief enable the commmon interrupts which are used in both device and host modes + \param[in] pudev: pointer to selected usb device + \param[out] none + \retval none +*/ +static void usb_commonint_enable (usb_core_handle_struct *pudev) +{ +#ifndef USE_OTG_MODE + + /* clear any pending USB interrupts */ + USB_GOTGINTF = 0xFFFFFFFFU; + +#endif /* USE_OTG_MODE */ + + /* enable the usb wakeup and suspend interrupts */ + USB_GINTEN = GINTEN_WKUPIE | GINTEN_SPIE; + +#ifdef USE_OTG_MODE + + /* enable the OTG interrupts, session interrrupts and connector ID pin interrupt */ + USB_GINTEN |= GINTEN_OTGIE | GINTEN_SESIE | GINTEN_CIDPSCIE; + +#endif /* USE_OTG_MODE */ +} + +/*! + \brief soft reset of the OTG_FS core + \param[in] pudev: pointer to usb device + \param[out] none + \retval operation status +*/ +static usb_status_enum usb_core_reset (usb_core_handle_struct *pudev) +{ + uint32_t count = 0U; + + /* enable core soft reset */ + USB_GRSTCTL |= GRSTCTL_CSRST; + + /* wait for the core to be soft reset */ + do { + if (++count > 200000U) { + break; + } + } while (1U == (USB_GRSTCTL & GRSTCTL_CSRST)); + + /* wait for addtional 3 PHY clocks */ + if (NULL != pudev->udelay) { + pudev->udelay(3U); + } + + return USB_OK; +} + +/*! + \brief write a packet into the Tx FIFO associated with the endpoint + \param[in] src: pointer to source buffer + \param[in] ep_id: endpoint identifier which is in (0..3) + \param[in] len: packet length + \param[out] none + \retval operation status +*/ +usb_status_enum usb_fifo_write (uint8_t *src, uint8_t ep_id, uint16_t len) +{ + uint32_t count32b = 0U, i = 0U; + __IO uint32_t *fifo = USB_FIFO(ep_id); + + count32b = (len + 3U) / 4U; + + for (i = 0U; i < count32b; i++) { + *fifo = *((__packed uint32_t *)src); + + src += 4U; + } + + return USB_OK; +} + +/*! + \brief read a packet from the Rx FIFO associated with the endpoint + \param[in] dest: pointer to destination buffer + \param[in] len: packet length + \param[out] none + \retval void type pointer +*/ +void *usb_fifo_read (uint8_t *dest, uint16_t len) +{ + uint32_t i = 0U; + uint32_t count32b = (len + 3U) / 4U; + + __IO uint32_t *fifo = USB_FIFO(0U); + + for (i = 0U; i < count32b; i++) { + *(__packed uint32_t *)dest = *fifo; + + dest += 4U; + } + + return ((void *)dest); +} + +/*! + \brief initialize core parameters + \param[in] pudev: pointer to usb device + \param[in] core_id: USB core id + \param[out] none + \retval operation status +*/ +usb_status_enum usb_core_select (usb_core_handle_struct *pudev, usb_core_id_enum core_id) +{ + /* at startup the core is in FS mode */ + pudev->cfg.core_speed = USB_CORE_SPEED_FULL; + pudev->cfg.max_packet_size = USBFS_MAX_PACKET_SIZE; + + pudev->cfg.dma_enable = 0U; + + /* initialize the core parameters */ + if (USB_FS_CORE_ID == core_id) { + pudev->cfg.core_id = USB_FS_CORE_ID; + + /* set the host channel numbers */ + pudev->cfg.host_channel_num = USBFS_MAX_HOST_CHANNELCOUNT; + + /* set the device endpoint numbers */ + pudev->cfg.dev_endp_num = USBFS_MAX_DEV_EPCOUNT; + + /* fifo size is in terms of DWORD */ + pudev->cfg.max_fifo_size = USBFS_MAX_FIFO_WORDLEN; + + /* OTG_FS core use embedded physical layer */ + pudev->cfg.phy_interface = USB_CORE_EMBEDDED_PHY; + +#ifdef USBFS_SOF_OUTPUT_ENABLED + pudev->cfg.sof_output = 1U; +#endif /* USBFS_SOF_OUTPUT_ENABLED */ + +#ifdef USBFS_LOW_PWR_MGMT_SUPPORT + pudev->cfg.low_power = 1U; +#endif /* USBFS_LOW_PWR_MGMT_SUPPORT */ + + } else if (USB_HS_CORE_ID == core_id) { + pudev->cfg.core_id = USB_HS_CORE_ID; + + /* set the host channel numbers */ + pudev->cfg.host_channel_num = USBHS_MAX_HOST_CHANNELCOUNT; + + /* set the device endpoint numbers */ + pudev->cfg.dev_endp_num = USBHS_MAX_DEV_EPCOUNT; + + /* fifo size is in terms of DWORD */ + pudev->cfg.max_fifo_size = USBHS_MAX_FIFO_WORDLEN; + +#ifdef USB_ULPI_PHY_ENABLED + pudev->cfg.phy_interface = USB_CORE_ULPI_PHY; +#elif defined(USB_EMBEDDED_PHY_ENABLED) + pudev->cfg.phy_interface = USB_CORE_EMBEDDED_PHY; +#endif /* USB_ULPI_PHY_ENABLED */ + +#ifdef USBHS_INTERNAL_DMA_ENABLED + pudev->cfg.dma_enable = 1U; +#endif /* USBHS_INTERNAL_DMA_ENABLED */ + +#ifdef USBHS_SOF_OUTPUT_ENABLED + pudev->cfg.sof_output = 1U; +#endif /* USBHS_SOF_OUTPUT_ENABLED */ + +#ifdef USBHS_LOW_PWR_MGMT_SUPPORT + pudev->cfg.low_power = 1U; +#endif /* USBHS_LOW_PWR_MGMT_SUPPORT */ + } else { + /* no operation */ + } + + return USB_OK; +} + +/*! + \brief initializes the USB controller registers and + prepares the core device mode or host mode operation + \param[in] pudev: pointer to usb device + \param[out] none + \retval operation status +*/ +usb_status_enum usb_core_init (usb_core_handle_struct *pudev) +{ + if (USB_CORE_ULPI_PHY == pudev->cfg.phy_interface) { + USB_GCCFG &= ~GCCFG_PWRON; + + if (pudev->cfg.sof_output) { + USB_GCCFG |= GCCFG_SOFOEN; + } + + /* use high-speed interface */ + USB_GUSBCS &= ~GUSBCS_EMBPHY; + + /* use internal over-current indicator */ + USB_GUSBCS &= ~GUSBCS_ULPIEOI; + +#ifdef USBHS_EXTERNAL_VBUS_ENABLED + /* use external VBUS driver */ + USB_GUSBCS |= GUSBCS_ULPIEVD; +#else + /* use internal VBUS driver */ + USB_GUSBCS &= ~GUSBCS_ULPIEVD; +#endif + + /* soft reset the core */ + usb_core_reset(pudev); + } else if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) { + if (USB_HS_CORE_ID == pudev->cfg.core_id) { + USB_GUSBCS |= GUSBCS_EMBPHY; + } + + /* soft reset the core */ + usb_core_reset(pudev); + + /* active the transceiver and enable vbus sensing */ + USB_GCCFG |= GCCFG_PWRON | GCCFG_VBUSACEN | GCCFG_VBUSBCEN; + + /* set Tx FIFO empty level to half empty mode */ + USB_GAHBCS &= ~GAHBCS_TXFTH | TXFIFO_EMPTY_HALF; + +#ifndef VBUS_SENSING_ENABLED + USB_GCCFG |= GCCFG_VBUSIG; +#endif /* VBUS_SENSING_ENABLED */ + + if(pudev->cfg.sof_output){ + USB_GCCFG |= GCCFG_SOFOEN; + } + + if (NULL != pudev->mdelay) { + pudev->mdelay(20U); + } + } else { + /* no operation */ + } + + if (1U == pudev->cfg.dma_enable) { + USB_GAHBCS = DMA_INCR8 | GAHBCS_DMAEN; + } + +#ifdef USE_OTG_MODE + /* enable OTG features */ + USB_GUSBCS |= GUSBCS_HNPCAP | GUSBCS_SRPCAP; + USB_OTG_EnableCommonInt(pudev); + +#endif /* USE_OTG_MODE */ + + return USB_OK; +} + +/*! + \brief flush a Tx FIFO or all Tx FIFOs + \param[in] pudev: pointer to usb device + \param[in] fifo_num: FIFO number which is in (0..3) + \param[out] none + \retval operation status +*/ +usb_status_enum usb_txfifo_flush (usb_core_handle_struct *pudev, uint8_t fifo_num) +{ + uint32_t count = 0U; + + USB_GRSTCTL = ((uint32_t)fifo_num << 6U) | GRSTCTL_TXFF; + + /* wait for Tx FIFO flush bit is set */ + do { + if (++count > 200000U) { + break; + } + } while (USB_GRSTCTL & GRSTCTL_TXFF); + + /* wait for 3 PHY clocks */ + if (NULL != pudev->udelay) { + pudev->udelay(3U); + } + + return USB_OK; +} + +/*! + \brief flush the entire Rx FIFO + \param[in] pudev: pointer to usb device + \param[out] none + \retval operation status +*/ +usb_status_enum usb_rxfifo_flush (usb_core_handle_struct *pudev) +{ + uint32_t count = 0U; + + USB_GRSTCTL = GRSTCTL_RXFF; + + /* wait for Rx FIFO flush bit is set */ + do { + if (++count > 200000U) { + break; + } + } while (USB_GRSTCTL & GRSTCTL_RXFF); + + /* wait for 3 PHY clocks */ + if (NULL != pudev->udelay) { + pudev->udelay(3U); + } + + return USB_OK; +} + +/*! + \brief set operation mode (host or device) + \param[in] pudev: pointer to usb device + \param[in] mode: operation mode which need to set + \arg HOST_MODE + \arg DEVICE_MODE + \param[out] none + \retval operation status +*/ +usb_status_enum usb_mode_set (usb_core_handle_struct *pudev, uint8_t mode) +{ + if (HOST_MODE == mode) { + USB_GUSBCS &= ~GUSBCS_FDM; + USB_GUSBCS |= GUSBCS_FHM; + } else if (DEVICE_MODE == mode) { + USB_GUSBCS &= ~GUSBCS_FHM; + USB_GUSBCS |= GUSBCS_FDM; + } else { + /* no operation */ + } + + if (NULL != pudev->mdelay) { + pudev->mdelay(50U); + } + + return USB_OK; +} + +#ifdef USE_HOST_MODE + +/*! + \brief initializes USB core for host mode + \param[in] pudev: pointer to selected usb host + \param[out] none + \retval operation status +*/ +usb_status_enum usb_hostcore_init (usb_core_handle_struct *pudev) +{ + uint32_t i = 0U; + __IO uint32_t host_nptxfifo_size = 0U; + __IO uint32_t host_ptxfifo_size = 0U; + +#ifdef USE_OTG_MODE + __IO uint32_t OtgCtrl = 0; +#endif /* USE_OTG_MODE */ + + /* restart the PHY clock */ + USB_PWRCLKCTL = 0U; + + /* initialize host configuration register */ + if (USB_CORE_ULPI_PHY == pudev->cfg.phy_interface) { + USB_FSLSCLOCK_INIT(HCTLR_30_60_MHZ); + } else { + USB_FSLSCLOCK_INIT(HCTLR_48_MHZ); + } + + /* configure data FIFO sizes */ +#ifdef USBFS_CORE + if (USB_FS_CORE_ID == pudev->cfg.core_id) { + /* set Rx FIFO size */ + USB_GRFLEN = USBFS_RX_FIFO_SIZE; + + /* set non-periodic Tx FIFO size and address */ + host_nptxfifo_size &= ~HNPTFLEN_HNPTXRSAR; + host_nptxfifo_size |= USBFS_RX_FIFO_SIZE; + host_nptxfifo_size &= ~HNPTFLEN_HNPTXFD; + host_nptxfifo_size |= USBFS_HTX_NPFIFO_SIZE << 16; + USB_HNPTFLEN = host_nptxfifo_size; + + /* set periodic Tx FIFO size and address */ + host_ptxfifo_size &= ~HPTFLEN_HPTXFSAR; + host_ptxfifo_size |= USBFS_RX_FIFO_SIZE + USBFS_HTX_PFIFO_SIZE; + host_ptxfifo_size &= ~HPTFLEN_HPTXFD; + host_ptxfifo_size |= USBFS_HTX_PFIFO_SIZE << 16; + USB_HPTFLEN = host_ptxfifo_size; + } +#endif /* USBFS_CORE */ + +#ifdef USBHS_CORE + if (USB_HS_CORE_ID == pudev->cfg.core_id) { + /* set Rx FIFO size */ + USB_GRFLEN = USBHS_RX_FIFO_SIZE; + + /* set non-periodic Tx FIFO size and address */ + host_nptxfifo_size &= ~HNPTFLEN_HNPTXRSAR; + host_nptxfifo_size |= USBHS_RX_FIFO_SIZE; + host_nptxfifo_size &= ~HNPTFLEN_HNPTXFD; + host_nptxfifo_size |= USBHS_HTX_NPFIFO_SIZE << 16; + USB_HNPTFLEN = host_nptxfifo_size; + + /* set periodic Tx FIFO size and address */ + host_ptxfifo_size &= ~HPTFLEN_HPTXFSAR; + host_ptxfifo_size |= USBHS_RX_FIFO_SIZE + USBHS_HTX_PFIFO_SIZE; + host_ptxfifo_size &= ~HPTFLEN_HPTXFD; + host_ptxfifo_size |= USBHS_HTX_PFIFO_SIZE << 16; + USB_HPTFLEN = host_ptxfifo_size; + } +#endif /* USBHS_CORE */ + +#ifdef USE_OTG_MODE + + /* clear Host Set HNP Enable bit in the USB OTG Control Register */ + OtgCtrl |= GOTGCS_HHNPEN; + USB_GOTGCS &= ~OtgCtrl; + USB_GOTGCS |= 0; + +#endif /* USE_OTG_MODE */ + + /* make sure the FIFOs are flushed */ + + /* flush all Tx FIFOs in device or host mode */ + usb_txfifo_flush(pudev, 0x10U); + + /* flush the entire Rx FIFO */ + usb_rxfifo_flush(pudev); + + /* clear all pending host channel interrupts */ + USB_HACHINTEN &= ~HACHINTEN_CINTEN; + + for (i = 0U; i < pudev->cfg.host_channel_num; i++) { + USB_HCHxINTEN(i) = 0U; + USB_HCHxINTF(i) = 0xFFFFFFFFU; + } + +#ifndef USE_OTG_MODE + usb_vbus_drive(pudev, 1U); +#endif /* USE_OTG_MODE */ + + usb_hostint_enable(pudev); + + return USB_OK; +} + +/*! + \brief control the VBUS to power + \param[in] pudev: pointer to selected usb host + \param[in] state: VBUS state + \param[out] none + \retval none +*/ +void usb_vbus_drive (usb_core_handle_struct *pudev, uint8_t state) +{ + __IO uint32_t host_port = 0U; + + /* enable or disable the external charge pump */ + if ((void *)0 != pudev->host.vbus_drive) { + pudev->host.vbus_drive(pudev, state); + } + + /* turn on the host port power. */ + host_port = USB_PORT_READ(); + + if ((0U == (host_port & HPCS_PP)) && (1U == state)) { + host_port |= HPCS_PP; + } else if ((1U == (host_port & HPCS_PP)) && (0U == state)) { + host_port &= ~HPCS_PP; + } else { + /* no operation */ + } + + USB_HPCS = host_port; + + if (NULL != pudev->mdelay) { + pudev->mdelay(200U); + } +} + +/*! + \brief enables the host mode interrupts + \param[in] pudev: pointer to selected usb host + \param[out] none + \retval operation status +*/ +usb_status_enum usb_hostint_enable (usb_core_handle_struct *pudev) +{ + uint32_t global_int_flag = 0U; + + /* disable all interrupts */ + USB_GINTEN = 0U; + + /* clear any pending interrupts */ + USB_GINTF = 0xFFFFFFFFU; + + /* enable the common interrupts */ + usb_commonint_enable(pudev); + + if (0U == pudev->cfg.dma_enable) { + global_int_flag |= GINTF_RXFNEIF; + } + + /* enable host_mode-related interrupts */ + global_int_flag |= GINTF_HPIF | GINTF_HCIF | GINTF_DISCIF \ + | GINTF_SOF | GINTF_ISOONCIF; + + USB_GINTEN &= ~global_int_flag; + USB_GINTEN |= global_int_flag; + + return USB_OK; +} + +/*! + \brief reset host port + \param[in] pudev: pointer to usb device + \param[out] none + \retval operation status +*/ +uint32_t usb_port_reset (usb_core_handle_struct *pudev) +{ + USB_HPCS = USB_PORT_READ() | HPCS_PRST; + + if (NULL != pudev->mdelay) { + pudev->mdelay(10U); + } + + USB_HPCS &= ~HPCS_PRST; + + if (NULL != pudev->mdelay) { + pudev->mdelay(20U); + } + + return USB_OK; +} + +/*! + \brief initialize host channel + \param[in] pudev: pointer to usb device + \param[in] hc_num: host channel number which is in (0..7) + \param[out] none + \retval operation status +*/ +usb_status_enum usb_hostchannel_init(usb_core_handle_struct *pudev, uint8_t hc_num) +{ + usb_status_enum status = USB_OK; + uint8_t is_low_speed = 0U; + __IO uint32_t host_channel_inten = 0U; + __IO uint32_t host_channel_ctlr = 0U; + + usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num]; + + /* clear old interrupt conditions for this host channel */ + USB_HCHxINTF((uint16_t)hc_num) = 0xFFFFFFFFU; + + if (1U == pudev->cfg.dma_enable) { + host_channel_inten |= HCHINTEN_DMAERIE; + } + + /* enable channel interrupts required for this transfer */ + switch (puhc->endp_type) { + case USB_EPTYPE_CTRL: + case USB_EPTYPE_BULK: + host_channel_inten |= HCHINTEN_TFIE | HCHINTEN_STALLIE | HCHINTEN_USBERIE \ + | HCHINTEN_DTERIE | HCHINTEN_NAKIE; + + if (puhc->endp_in) { + host_channel_inten |= HCHINTEN_BBERIE; + } else { + host_channel_inten |= HCHINTEN_NYETIE; + + if (puhc->do_ping) { + host_channel_inten |= HCHINTEN_ACKIE; + } + } + break; + + case USB_EPTYPE_INTR: + host_channel_inten |= HCHINTEN_TFIE | HCHINTEN_STALLIE | HCHINTEN_USBERIE | HCHINTEN_DTERIE \ + | HCHINTEN_NAKIE | HCHINTEN_REQOVRIE; + + if (puhc->endp_in) { + host_channel_inten |= HCHINTEN_BBERIE; + } + break; + + case USB_EPTYPE_ISOC: + host_channel_inten |= HCHINTEN_TFIE | HCHINTEN_REQOVRIE | HCHINTEN_ACKIE; + + if (puhc->endp_in) { + host_channel_inten |= HCHINTEN_USBERIE | HCHINTEN_BBERIE; + } + break; + + default: + break; + } + + USB_HCHxINTEN((uint16_t)hc_num) = host_channel_inten; + + /* enable the top level host channel interrupt */ + USB_HACHINTEN |= 1U << hc_num; + + /* make sure host channel interrupts are enabled */ + USB_GINTEN |= GINTEN_HCIE; + + /* program the hcctlr register */ + host_channel_ctlr = 0U; + + if (HPRT_PRTSPD_LOW_SPEED == puhc->dev_speed) { + is_low_speed = 1U; + } + + host_channel_ctlr |= (uint32_t)puhc->dev_addr << 22U; + host_channel_ctlr |= (uint32_t)puhc->endp_type << 18U; + host_channel_ctlr |= (uint32_t)puhc->endp_id << 11U; + host_channel_ctlr |= (uint32_t)puhc->endp_in << 15U; + host_channel_ctlr |= (uint32_t)is_low_speed << 17U; + host_channel_ctlr |= puhc->endp_mps; + + if (HCCHAR_INTR == puhc->endp_type) { + host_channel_ctlr |= HCHCTL_ODDFRM; + } + + USB_HCHxCTL((uint16_t)hc_num) = host_channel_ctlr; + + return status; +} + +/*! + \brief prepare host channel for transferring packets + \param[in] pudev: pointer to usb device + \param[in] hc_num: host channel number which is in (0..7) + \param[out] none + \retval operation status +*/ +usb_status_enum usb_hostchannel_startxfer(usb_core_handle_struct *pudev, uint8_t hc_num) +{ + usb_status_enum status = USB_OK; + + uint16_t dword_len = 0U; + uint16_t packet_num = 0U; + + __IO uint32_t host_channel_xlen = 0U; + __IO uint32_t host_channel_ctlr = 0U; + + usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num]; + + /* compute the expected number of packets associated to the transfer */ + if (puhc->xfer_len > 0U) { + packet_num = ((uint16_t)puhc->xfer_len + puhc->endp_mps - 1U) / puhc->endp_mps; + + if (packet_num > HC_MAX_PACKET_COUNT) { + packet_num = HC_MAX_PACKET_COUNT; + puhc->xfer_len = (uint32_t)(packet_num) * (uint32_t)(puhc->endp_mps); + } + } else { + packet_num = 1U; + } + + if (puhc->endp_in) { + puhc->xfer_len = (uint32_t)(packet_num) * (uint32_t)(puhc->endp_mps); + } + + /* initialize the host channel length register */ + host_channel_xlen &= ~HCHLEN_TLEN; + host_channel_xlen |= puhc->xfer_len; + host_channel_xlen &= ~HCHLEN_PCNT; + host_channel_xlen |= (uint32_t)packet_num << 19U; + host_channel_xlen &= ~HCHLEN_DPID; + host_channel_xlen |= (uint32_t)(puhc->DPID) << 29U; + USB_HCHxLEN((uint16_t)hc_num) = (uint32_t)host_channel_xlen; + + if (1U == pudev->cfg.dma_enable) { + USB_HCHxDMAADDR((uint16_t)hc_num) = (uint32_t)puhc->xfer_buff; + } + + /* set host channel enable */ + host_channel_ctlr = USB_HCHxCTL((uint16_t)hc_num); + + if (1U == USB_EVEN_FRAME()) { + host_channel_ctlr |= HCHCTL_ODDFRM; + } else { + host_channel_ctlr &= ~HCHCTL_ODDFRM; + } + + host_channel_ctlr |= HCHCTL_CEN; + host_channel_ctlr &= ~HCHCTL_CDIS; + USB_HCHxCTL((uint16_t)hc_num) = host_channel_ctlr; + + if (0U == pudev->cfg.dma_enable) { + if ((0U == puhc->endp_in) && (puhc->xfer_len > 0U)) { + dword_len = (uint16_t)(puhc->xfer_len + 3U) / 4U; + + switch (puhc->endp_type) { + /* non-periodic transfer */ + case USB_EPTYPE_CTRL: + case USB_EPTYPE_BULK: + /* check if there is enough space in fifo space */ + if (dword_len > (USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS)) { + /* need to process data in non-periodic transfer fifo empty interrupt */ + USB_GINTEN |= GINTEN_NPTXFEIE; + } + break; + + /* periodic transfer */ + case USB_EPTYPE_INTR: + case USB_EPTYPE_ISOC: + /* check if there is enough space in FIFO space */ + if (dword_len > (USB_HPTFQSTAT & HPTFQSTAT_PTXFS)) { + /* need to process data in periodic transfer fifo empty interrupt */ + USB_GINTEN |= GINTEN_PTXFEIE; + } + break; + + default: + break; + } + + /* write packet into the Tx FIFO. */ + usb_fifo_write(puhc->xfer_buff, hc_num, (uint16_t)puhc->xfer_len); + } + } + + return status; +} + +/*! + \brief halt channel + \param[in] pudev: pointer to usb device + \param[in] hc_num: host channel number which is in (0..7) + \param[out] none + \retval operation status +*/ +usb_status_enum usb_hostchannel_halt(usb_core_handle_struct *pudev, uint8_t hc_num) +{ + uint8_t endp_type = 0U; + __IO uint32_t host_channel_ctrl = USB_HCHxCTL((uint16_t)hc_num); + + host_channel_ctrl |= HCHCTL_CEN | HCHCTL_CDIS; + + endp_type = (uint8_t)((host_channel_ctrl & HCHCTL_EPTYPE) >> 18U); + + /* check for space in the request queue to issue the halt. */ + if ((HCCHAR_CTRL == endp_type) || (HCCHAR_BULK == endp_type)) { + if (0U == (USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS)) { + host_channel_ctrl |= HCHCTL_CDIS; + } + } else { + if (0U == (USB_HPTFQSTAT & HPTFQSTAT_PTXFS)) { + host_channel_ctrl |= HCHCTL_CEN; + } + } + + USB_HCHxCTL((uint16_t)hc_num) = host_channel_ctrl; + + return USB_OK; +} + +/*! + \brief issue a ping token + \param[in] pudev: pointer to usb device + \param[in] hc_num: host channel number which is in (0..7) + \param[out] none + \retval operation status +*/ +usb_status_enum usb_hostchannel_ping(usb_core_handle_struct *pudev, uint8_t hc_num) +{ + uint32_t host_channel_ctrl = 0U; + + USB_HCHxLEN((uint16_t)hc_num) = HCHLEN_PING | (HCHLEN_PCNT & (1U << 19U)); + + host_channel_ctrl = USB_HCHxCTL((uint16_t)hc_num); + host_channel_ctrl |= HCHCTL_CEN; + host_channel_ctrl &= ~HCHCTL_CDIS; + + USB_HCHxCTL((uint16_t)hc_num) = host_channel_ctrl; + + return USB_OK; +} + +/*! + \brief stop the USB host and clean up fifos + \param[in] none + \param[out] none + \retval none +*/ +void usb_host_stop(usb_core_handle_struct *pudev) +{ + uint32_t i; + + /* disable all host channel interrupt */ + USB_HACHINTEN = 0U; + USB_HACHINT = 0xFFFFFFFFU; + + /* flush out any leftover queued requests */ + for (i = 0U; i < pudev->cfg.host_channel_num; i++) { + USB_HCHxCTL(i) |= HCHCTL_CEN | HCHCTL_CDIS | HCHCTL_EPDIR; + } + + /* flush the FIFO */ + usb_rxfifo_flush(pudev); + usb_txfifo_flush(pudev, 0x10U); +} + +#endif /* USE_HOST_MODE */ + + +#ifdef USE_DEVICE_MODE + +#ifdef USBFS_CORE + +/* USB endpoint Tx FIFO size */ +static uint16_t USBFS_TX_FIFO_SIZE[USBFS_MAX_DEV_EPCOUNT] = +{ + (uint16_t)TX0_FIFO_FS_SIZE, + (uint16_t)TX1_FIFO_FS_SIZE, + (uint16_t)TX2_FIFO_FS_SIZE, + (uint16_t)TX3_FIFO_FS_SIZE +}; + +#elif defined(USBHS_CORE) + +uint16_t USBHS_TX_FIFO_SIZE[USBHS_MAX_DEV_EPCOUNT] = +{ + (uint16_t)TX0_FIFO_HS_SIZE, + (uint16_t)TX1_FIFO_HS_SIZE, + (uint16_t)TX2_FIFO_HS_SIZE, + (uint16_t)TX3_FIFO_HS_SIZE, + (uint16_t)TX4_FIFO_HS_SIZE, + (uint16_t)TX5_FIFO_HS_SIZE +}; + +#endif /* USBFS_CORE */ + +static usb_status_enum usb_devint_enable(usb_core_handle_struct *pudev); + +/*! + \brief initialize USB core registers for device mode + \param[in] pudev: pointer to usb device + \param[out] none + \retval operation status +*/ +usb_status_enum usb_devcore_init (usb_core_handle_struct *pudev) +{ + uint32_t i, ram_address = 0U; + __IO uint32_t dev_in_ep0_inf = USB_DIEP0TFLEN; + __IO uint32_t dev_in_ep_inf = 0U; + + /* restart the Phy Clock (Maybe don't need to...) */ + USB_PWRCLKCTL = 0U; + + /* config periodic frmae interval to default */ + USB_DCFG &= ~DCFG_EOPFT; + USB_DCFG |= FRAME_INTERVAL_80; + +#ifdef USBFS_CORE + if (USB_FS_CORE_ID == pudev->cfg.core_id) { + /* set full speed PHY */ + USB_DCFG &= ~DCFG_DS; + USB_DCFG |= USB_SPEED_INP_FULL; + + /* set Rx FIFO size */ + USB_GRFLEN &= ~GRFLEN_RXFD; + USB_GRFLEN |= RX_FIFO_FS_SIZE; + + /* set endpoint 0 Tx FIFO length and RAM address */ + dev_in_ep0_inf &= ~DIEP0TFLEN_IEP0TXFD; + dev_in_ep0_inf |= TX0_FIFO_FS_SIZE << 16; + dev_in_ep0_inf &= ~DIEP0TFLEN_IEP0TXRSAR; + dev_in_ep0_inf |= RX_FIFO_FS_SIZE; + + USB_DIEP0TFLEN = dev_in_ep0_inf; + + ram_address = RX_FIFO_FS_SIZE; + + /* set endpoint 1 to 3's Tx FIFO length and RAM address */ + for (i = 1U; i < USBFS_MAX_DEV_EPCOUNT; i++) { + ram_address += USBFS_TX_FIFO_SIZE[i - 1U]; + + dev_in_ep_inf &= ~DIEPTFLEN_IEPTXFD; + dev_in_ep_inf |= (uint32_t)USBFS_TX_FIFO_SIZE[i] << 16U; + dev_in_ep_inf &= ~DIEPTFLEN_IEPTXRSAR; + dev_in_ep_inf |= ram_address; + + USB_DIEPxTFLEN(i) = dev_in_ep_inf; + } + } +#endif /* USBFS_CORE */ + +#ifdef USBHS_CORE + if (USB_HS_CORE_ID == pudev->cfg.core_id) { + USB_DCFG &= ~DCFG_DS; + + if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) { + /* set full speed PHY in USB high speed core */ + USB_DCFG |= USB_SPEED_INP_FULL; + } else if (USB_CORE_ULPI_PHY == pudev->cfg.phy_interface) { + USB_DCFG |= USB_SPEED_EXP_HIGH; + } + + /* set Rx FIFO size */ + USB_GRFLEN &= ~GRFLEN_RXFD; + USB_GRFLEN |= RX_FIFO_HS_SIZE; + + /* set endpoint 0 Tx FIFO length and RAM address */ + dev_in_ep0_inf &= ~DIEP0TFLEN_IEP0TXFD; + dev_in_ep0_inf |= TX0_FIFO_HS_SIZE << 16; + dev_in_ep0_inf &= ~DIEP0TFLEN_IEP0TXRSAR; + dev_in_ep0_inf |= RX_FIFO_HS_SIZE; + + USB_DIEP0TFLEN = dev_in_ep0_inf; + + ram_address = RX_FIFO_HS_SIZE; + + /* set endpoint 1 to 3's Tx FIFO length and RAM address */ + for (i = 1; i < USBHS_MAX_DEV_EPCOUNT; i++) { + ram_address += USBHS_TX_FIFO_SIZE[i - 1]; + + dev_in_ep_inf &= ~DIEPTFLEN_IEPTXFD; + dev_in_ep_inf |= USBHS_TX_FIFO_SIZE[i] << 16; + dev_in_ep_inf &= ~DIEPTFLEN_IEPTXRSAR; + dev_in_ep_inf |= ram_address; + + USB_DIEPxTFLEN(i) = dev_in_ep_inf; + } + } +#endif /* USBHS_CORE */ + + /* make sure all FIFOs are flushed */ + + /* flush all Tx FIFOs */ + usb_txfifo_flush(pudev, 0x10U); + + /* flush entire Rx FIFO */ + usb_rxfifo_flush(pudev); + + /* clear all pending device interrupts */ + USB_DIEPINTEN = 0U; + USB_DOEPINTEN = 0U; + USB_DAEPINT = 0xFFFFFFFF; + USB_DAEPINTEN = 0U; + + /* configure all IN/OUT endpoints */ + for (i = 0U; i < pudev->cfg.dev_endp_num; i++) { + if (USB_DIEPxCTL(i) & DIEPCTL_EPEN) { + USB_DIEPxCTL(i) |= DIEPCTL_EPD | DIEPCTL_SNAK; + } else { + USB_DIEPxCTL(i) = 0U; + } + + if (USB_DOEPxCTL(i) & DOEPCTL_EPEN) { + USB_DOEPxCTL(i) |= DOEPCTL_EPD | DOEPCTL_SNAK; + } else { + USB_DOEPxCTL(i) = 0U; + } + + /* set IN/OUT endpoint transfer length to 0 */ + USB_DIEPxLEN(i) = 0U; + USB_DOEPxLEN(i) = 0U; + + /* clear all pending IN/OUT endpoints interrupts */ + USB_DIEPxINTF(i) = 0xFFU; + USB_DOEPxINTF(i) = 0xFFU; + } + + USB_DIEPINTEN |= DIEPINTEN_EPTXFUDEN; + usb_devint_enable(pudev); + + return USB_OK; +} + +/*! + \brief enable the device mode interrupts + \param[in] pudev: pointer to usb device + \param[out] none + \retval status +*/ +static usb_status_enum usb_devint_enable(usb_core_handle_struct *pudev) +{ + uint32_t int_mask = 0U; + + /* disable all interrupts */ + USB_GINTEN = 0U; + + /* clear any pending interrupts */ + USB_GINTF = 0xBFFFFFFFU; + + /* enable the common interrupts */ + usb_commonint_enable(pudev); + + if (0U == pudev->cfg.dma_enable) { + int_mask = GINTEN_RXFNEIE; + } + + /* enable device_mode-related interrupts */ + int_mask |= GINTEN_SPIE | GINTEN_RSTIE | GINTEN_ENUMFIE \ + | GINTEN_IEPIE | GINTEN_OEPIE | GINTEN_SOFIE | GINTEN_ISOONCIE \ + | GINTEN_ISOINCIE; + +#ifdef VBUS_SENSING_ENABLED + int_mask |= GINTEN_SESIE | GINTEN_OTGIE; +#endif /* VBUS_SENSING_ENABLED */ + + USB_GINTEN &= ~int_mask; + USB_GINTEN |= int_mask; + + return USB_OK; +} + +/*! + \brief configures endpoint 0 to receive SETUP packets + \param[in] pudev: pointer to usb device + \param[out] none + \retval none +*/ +void usb_ep0_startout(usb_core_handle_struct *pudev) +{ + __IO uint32_t ep0_xlen = 0U; + + /* set OUT endpoint 0 receive length to 24 bytes */ + ep0_xlen &= ~DOEP0LEN_TLEN; + ep0_xlen |= 8U * 3U; + + /* set OUT endpoint 0 receive length to 1 packet */ + ep0_xlen &= ~DOEP0LEN_PCNT; + ep0_xlen |= 1U << 19; + + /* set SETUP packet count to 3 */ + ep0_xlen &= ~DOEP0LEN_STPCNT; + ep0_xlen |= 3U << 29; + + USB_DOEPxLEN(0U) = ep0_xlen; + + if (1U == pudev->cfg.dma_enable) { + USB_DOEPxDMAADDR(0U) = (uint32_t)&pudev->dev.setup_packet; + + USB_DOEPxCTL(0U) = DOEPCTL_EPEN | DOEPCTL_EPACT; + } +} + +/*! + \brief active remote wakeup signalling + \param[in] pudev: pointer to usb device + \param[out] none + \retval none +*/ +void usb_remotewakeup_active(usb_core_handle_struct *pudev) +{ + __IO uint32_t power_clock; + + if (pudev->dev.remote_wakeup) { + if (1U == (USB_DSTAT & DSTAT_SPST)) { + if (pudev->cfg.low_power) { + /* ungate USB core clock */ + power_clock = USB_PWRCLKCTL; + power_clock &= ~PWRCLKCTL_SHCLK; + power_clock &= ~PWRCLKCTL_SUCLK; + + USB_PWRCLKCTL = power_clock; + } + + /* active remote wakeup signaling */ + USB_DCTL |= DCTL_RWKUP; + + if (pudev->mdelay != (void *)0) { + pudev->mdelay(5U); + } + + USB_DCTL &= ~DCTL_RWKUP; + } + } +} + +/*! + \brief active USB core clock + \param[in] pudev: pointer to usb device + \param[out] none + \retval none +*/ +void usb_clock_ungate(usb_core_handle_struct *pudev) +{ + if (pudev->cfg.low_power) { + __IO uint32_t power_clock; + + if (1U == (USB_DSTAT & DSTAT_SPST)) { + /* un-gate USB core clock */ + power_clock = USB_PWRCLKCTL; + power_clock &= ~PWRCLKCTL_SHCLK; + power_clock &= ~PWRCLKCTL_SUCLK; + + USB_PWRCLKCTL = power_clock; + } + } +} + +/*! + \brief stop the device and clean up fifos + \param[in] pudev: pointer to usb device + \param[out] none + \retval none +*/ +void usb_device_stop (usb_core_handle_struct *pudev) +{ + uint32_t i; + + pudev->dev.status = 1U; + + for (i = 0U; i < pudev->cfg.dev_endp_num; i++) { + USB_DIEPxINTF(i) = 0xFFU; + USB_DOEPxINTF(i) = 0xFFU; + } + + USB_DIEPINTEN = 0U; + USB_DOEPINTEN = 0U; + USB_DAEPINTEN = 0U; + USB_DAEPINT = 0xFFFFFFFFU; + + /* flush the FIFO */ + usb_rxfifo_flush(pudev); + usb_txfifo_flush(pudev, 0x10U); +} +#endif /* USE_DEVICE_MODE */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_core.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_core.c new file mode 100644 index 0000000000..0d15a7950f --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_core.c @@ -0,0 +1,520 @@ +/*! + \file usbd_core.c + \brief USB device-mode core driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "usbd_core.h" +#include "usbd_std.h" + +/*! + \brief initailizes the USB device-mode handler stack + \param[in] pudev: pointer to usb device instance + \param[in] core_id: USB core ID + \param[out] none + \retval none +*/ +void usbd_init (usb_core_handle_struct *pudev, usb_core_id_enum core_id) +{ + /* select USB core */ + usb_core_select (pudev, core_id); + + pudev->dev.status = USB_STATUS_DEFAULT; + + /* disable USB global interrupt */ + USB_GLOBAL_INT_DISABLE(); + + /* init the core (common init.) */ + usb_core_init(pudev); + + /* force device mode*/ + usb_mode_set(pudev, DEVICE_MODE); + + /* set device disconnect */ + USB_SOFT_DISCONNECT_ENABLE(); + + if ((void *)0 != pudev->mdelay) { + pudev->mdelay(3U); + } + + /* init device */ + usb_devcore_init(pudev); + + /* set device Connect */ + USB_SOFT_DISCONNECT_DISABLE(); + + if ((void *)0 != pudev->mdelay) { + pudev->mdelay(3U); + } + + /* enable USB global interrupt */ + USB_GLOBAL_INT_ENABLE(); +} + +/*! + \brief endpoint initialization + \param[in] pudev: pointer to usb device instance + \param[in] pep_desc: pointer to usb endpoint descriptor + \param[out] none + \retval none +*/ +void usbd_ep_init (usb_core_handle_struct *pudev, const usb_descriptor_endpoint_struct *pep_desc) +{ + usb_ep_struct *ep; + + uint32_t dev_all_ep_int_en = 0U; + uint32_t dev_ep_ctlr = 0U; + + uint8_t ep_id = pep_desc->bEndpointAddress & 0x7FU; + uint8_t ep_type = pep_desc->bmAttributes & USB_EPTYPE_MASK; + uint16_t ep_mps = pep_desc->wMaxPacketSize; + + if (pep_desc->bEndpointAddress >> 7) { + ep = &pudev->dev.in_ep[ep_id]; + + dev_all_ep_int_en |= 1U << ep_id; + dev_ep_ctlr = USB_DIEPxCTL((uint16_t)ep_id); + + /* if the endpoint is not active, need change the endpoint control register */ + if (!(dev_ep_ctlr & DIEPCTL_EPACT)) { + if (0U == ep_id) { + dev_ep_ctlr &= ~DIEP0CTL_MPL; + } else { + dev_ep_ctlr &= ~DIEPCTL_MPL; + } + dev_ep_ctlr |= ep_mps; + + dev_ep_ctlr &= ~DIEPCTL_EPTYPE; + dev_ep_ctlr |= (uint32_t)ep_type << 18; + + dev_ep_ctlr &= ~DIEPCTL_TXFNUM; + dev_ep_ctlr |= (uint32_t)ep_id << 22; + + if (0U != ep_id) { + dev_ep_ctlr |= DIEPCTL_SD0PID; + dev_ep_ctlr |= DIEPCTL_EPACT; + } + + USB_DIEPxCTL((uint16_t)ep_id) = dev_ep_ctlr; + } + } else { + ep = &pudev->dev.out_ep[ep_id]; + + dev_all_ep_int_en |= (1U << ep_id) << 16; + dev_ep_ctlr = USB_DOEPxCTL((uint16_t)ep_id); + + /* if the endpoint is not active, need change the endpoint control register */ + if (!(dev_ep_ctlr & DOEPCTL_EPACT)) { + if (0U == ep_id) { + dev_ep_ctlr &= ~DOEP0CTL_MPL; + } else { + dev_ep_ctlr &= ~DOEPCTL_MPL; + } + dev_ep_ctlr |= ep_mps; + + dev_ep_ctlr &= ~DOEPCTL_EPTYPE; + dev_ep_ctlr |= (uint32_t)ep_type << 18; + + if (0U != ep_id) { + dev_ep_ctlr |= DOEPCTL_SD0PID; + dev_ep_ctlr |= DOEPCTL_EPACT; + } + + USB_DOEPxCTL((uint16_t)ep_id) = dev_ep_ctlr; + } + } + + ep->endp_mps = ep_mps; + ep->endp_type = ep_type; + + /* enable the interrupts for this endpoint */ +#ifdef USBHS_DEDICATED_EP1_ENABLED + if ((1 == ep_id) && (USB_HS_CORE_ID == pudev->cfg.core_id)) { + USB_DEP1INTEN |= dev_all_ep_int_en; + } else +#endif /* USBHS_DEDICATED_EP1_ENABLED */ + { + USB_DAEPINTEN |= dev_all_ep_int_en; + } +} + +/*! + \brief endpoint deinitialize + \param[in] pudev: pointer to usb device instance + \param[in] ep_addr: endpoint address + \param[out] none + \retval none +*/ +void usbd_ep_deinit (usb_core_handle_struct *pudev, uint8_t ep_addr) +{ + uint32_t dev_all_ep_int_en = 0U; + uint8_t ep_id = ep_addr & 0x7FU; + + if (ep_addr >> 7) { + dev_all_ep_int_en |= 1U << ep_id; + + USB_DIEPxCTL((uint16_t)ep_id) &= ~DIEPCTL_EPACT; + } else { + dev_all_ep_int_en |= (1U << ep_id) << 16U; + + USB_DOEPxCTL((uint16_t)ep_id) &= ~DOEPCTL_EPACT; + } + + /* disable the interrupts for this endpoint */ +#ifdef USBHS_DEDICATED_EP1_ENABLED + if ((1U == ep_id) && (USB_HS_CORE_ID == pudev->cfg.core_id)) { + USB_DEP1INTEN &= ~dev_all_ep_int_en; + } else +#endif /* USBHS_DEDICATED_EP1_ENABLED */ + { + USB_DAEPINTEN &= ~dev_all_ep_int_en; + } +} + +/*! + \brief endpoint prepare to receive data + \param[in] pudev: pointer to usb device instance + \param[in] ep_addr: endpoint address + \param[in] pbuf: pointer to buffer + \param[in] buf_len: buffer length + \param[out] none + \retval none +*/ +void usbd_ep_rx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len) +{ + usb_ep_struct *ep; + uint8_t ep_id = ep_addr & 0x7FU; + uint32_t dev_ep_ctlr = 0U, dev_ep_xlen = 0U; + + ep = &pudev->dev.out_ep[ep_id]; + + /* setup and start the Xfer */ + ep->xfer_buff = pbuf; + ep->xfer_len = buf_len; + ep->xfer_count = 0U; + + if (1U == pudev->cfg.dma_enable) { + ep->dma_addr = (uint32_t)pbuf; + } + + dev_ep_ctlr = USB_DOEPxCTL((uint16_t)ep_id); + dev_ep_xlen = USB_DOEPxLEN((uint16_t)ep_id); + + dev_ep_xlen &= ~DOEPLEN_TLEN; + dev_ep_xlen &= ~DOEPLEN_PCNT; + + /* zero length packet */ + if (0U == ep->xfer_len) { + /* set the transfer length to max packet size */ + dev_ep_xlen |= ep->endp_mps; + + /* set the transfer packet count to 1 */ + dev_ep_xlen |= 1U << 19U; + } else { + if (0U == ep_id) { + /* set the transfer length to max packet size */ + dev_ep_xlen |= ep->endp_mps; + + /* set the transfer packet count to 1 */ + dev_ep_xlen |= 1U << 19U; + } else { + /* configure the transfer size and packet count as follows: + * pktcnt = N + * xfersize = N * maxpacket + */ + dev_ep_xlen |= ((ep->xfer_len + ep->endp_mps - 1U) / ep->endp_mps) << 19U; + dev_ep_xlen |= ((dev_ep_xlen & DOEPLEN_PCNT) >> 19U) * ep->endp_mps; + } + } + + USB_DOEPxLEN((uint16_t)ep_id) = dev_ep_xlen; + + if (1U == pudev->cfg.dma_enable) { + USB_DOEPxDMAADDR((uint16_t)ep_id) = ep->dma_addr; + } + + if (USB_EPTYPE_ISOC == ep->endp_type) { + if (ep->endp_frame) { + dev_ep_ctlr |= DOEPCTL_SODDFRM; + } else { + dev_ep_ctlr |= DOEPCTL_SEVNFRM; + } + } + + /* enable the endpoint and clear the NAK */ + dev_ep_ctlr |= DOEPCTL_EPEN | DOEPCTL_CNAK; + + USB_DOEPxCTL((uint16_t)ep_id) = dev_ep_ctlr; +} + +/*! + \brief endpoint prepare to transmit data + \param[in] pudev: pointer to usb device instance + \param[in] ep_addr: endpoint address + \param[in] pbuf: pointer to buffer + \param[in] len: buffer length + \param[out] none + \retval none +*/ +void usbd_ep_tx (usb_core_handle_struct *pudev, uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len) +{ + usb_ep_struct *ep; + uint8_t ep_id = ep_addr & 0x7FU; + __IO uint32_t dev_ep_ctlr = 0U; + __IO uint32_t dev_ep_xlen = 0U; + + ep = &pudev->dev.in_ep[ep_id]; + + /* setup and start the transfer */ + ep->xfer_buff = pbuf; + ep->xfer_len = buf_len; + ep->xfer_count = 0U; + + if (1U == pudev->cfg.dma_enable) { + ep->dma_addr = (uint32_t)pbuf; + } + + dev_ep_ctlr = USB_DIEPxCTL((uint16_t)ep_id); + dev_ep_xlen = USB_DIEPxLEN((uint16_t)ep_id); + + /* clear transfer length to 0 */ + dev_ep_xlen &= ~DIEPLEN_TLEN; + + /* clear transfer packet to 0 */ + dev_ep_xlen &= ~DIEPLEN_PCNT; + + /* zero length packet */ + if (0U == ep->xfer_len) { + /* set transfer packet count to 1 */ + dev_ep_xlen |= 1U << 19U; + } else { + if (0U == ep_id) { + if (ep->xfer_len > ep->endp_mps) { + ep->xfer_len = ep->endp_mps; + } + + dev_ep_xlen |= 1U << 19U; + } else { + dev_ep_xlen |= ((ep->xfer_len - 1U + ep->endp_mps) / ep->endp_mps) << 19U; + } + + /* configure the transfer size and packet count as follows: + * xfersize = N * maxpacket + short_packet + * pktcnt = N + (short_packet exist ? 1 : 0) + */ + dev_ep_xlen |= ep->xfer_len; + + if (USB_EPTYPE_ISOC == ep->endp_type) { + dev_ep_xlen |= DIEPLEN_MCNT & (1U << 29U); + } + } + + USB_DIEPxLEN((uint16_t)ep_id) = dev_ep_xlen; + + if (USB_EPTYPE_ISOC == ep->endp_type) { + if (0U == (((USB_DSTAT & DSTAT_FNRSOF) >> 8U) & 0x1U)) { + dev_ep_ctlr |= DIEPCTL_SODDFRM; + } else { + dev_ep_ctlr |= DIEPCTL_SEVNFRM; + } + } + + if (1U == pudev->cfg.dma_enable) { + USB_DIEPxDMAADDR((uint16_t)ep_id) = ep->dma_addr; + } + + /* enable the endpoint and clear the NAK */ + dev_ep_ctlr |= DIEPCTL_EPEN | DIEPCTL_CNAK; + + USB_DIEPxCTL((uint16_t)ep_id) = dev_ep_ctlr; + + if (0U == pudev->cfg.dma_enable) { + if (USB_EPTYPE_ISOC != ep->endp_type) { + /* enable the Tx FIFO empty interrupt for this endpoint */ + if (ep->xfer_len > 0U) { + USB_DIEPFEINTEN |= 1U << ep_id; + } + } else { + usb_fifo_write(ep->xfer_buff, ep_id, (uint16_t)ep->xfer_len); + } + } +} + +/*! + \brief transmit data on the control channel + \param[in] pudev: pointer to usb device instance + \param[in] pbuf: pointer to buffer + \param[in] len: buffer length + \param[out] none + \retval usb device operation status +*/ +usbd_status_enum usbd_ctltx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len) +{ + usbd_status_enum ret = USBD_OK; + + pudev->dev.sum_len = len; + pudev->dev.remain_len = len; + pudev->dev.ctl_status = USB_CTRL_DATA_IN; + + usbd_ep_tx (pudev, 0U, pbuf, (uint32_t)len); + + return ret; +} + +/*! + \brief receive data on the control channel + \param[in] pudev: pointer to usb device instance + \param[in] pbuf: pointer to buffer + \param[in] len: buffer length + \param[out] none + \retval usb device operation status +*/ +usbd_status_enum usbd_ctlrx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len) +{ + pudev->dev.sum_len = len; + pudev->dev.remain_len = len; + pudev->dev.ctl_status = USB_CTRL_DATA_OUT; + + usbd_ep_rx (pudev, 0U, pbuf, len); + + return USBD_OK; +} + +/*! + \brief transmit status on the control channel + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval usb device operation status +*/ +usbd_status_enum usbd_ctlstatus_tx (usb_core_handle_struct *pudev) +{ + pudev->dev.ctl_status = USB_CTRL_STATUS_IN; + + usbd_ep_tx (pudev, 0U, NULL, 0U); + + usb_ep0_startout(pudev); + + return USBD_OK; +} + +/*! + \brief receive status on the control channel + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval usb device operation status +*/ +usbd_status_enum usbd_ctlstatus_rx (usb_core_handle_struct *pudev) +{ + pudev->dev.ctl_status = USB_CTRL_STATUS_OUT; + + usbd_ep_rx (pudev, 0U, NULL, 0U); + + usb_ep0_startout(pudev); + + return USBD_OK; +} + +/*! + \brief set an endpoint to STALL status + \param[in] pudev: pointer to usb device instance + \param[in] ep_addr: endpoint address + \param[out] none + \retval none +*/ +void usbd_ep_stall (usb_core_handle_struct *pudev, uint8_t ep_addr) +{ + uint8_t ep_id = ep_addr & 0x7FU; + __IO uint32_t dev_ep_ctlr = 0U; + + if (ep_addr >> 7U) { + dev_ep_ctlr = USB_DIEPxCTL((uint16_t)ep_id); + + /* set the endpoint disable bit */ + if (dev_ep_ctlr & DIEPCTL_EPEN) { + dev_ep_ctlr |= DIEPCTL_EPD; + } + + /* set the endpoint stall bit */ + dev_ep_ctlr |= DIEPCTL_STALL; + + USB_DIEPxCTL((uint16_t)ep_id) = dev_ep_ctlr; + } else { + /* set the endpoint stall bit */ + USB_DOEPxCTL((uint16_t)ep_id) |= DOEPCTL_STALL; + } +} + +/*! + \brief clear endpoint stalled status + \param[in] pudev: pointer to usb device instance + \param[in] ep_addr: endpoint address + \param[out] none + \retval none +*/ +void usbd_ep_clear_stall (usb_core_handle_struct *pudev, uint8_t ep_addr) +{ + usb_ep_struct *ep; + uint8_t ep_id = ep_addr & 0x7FU; + __IO uint32_t dev_ep_ctlr = 0U; + + if(ep_addr >> 7){ + ep = &pudev->dev.in_ep[ep_id]; + + dev_ep_ctlr = USB_DIEPxCTL((uint16_t)ep_id); + + /* clear the IN endpoint stall bits */ + dev_ep_ctlr &= ~DIEPCTL_STALL; + + if ((USB_EPTYPE_INTR == ep->endp_type) || (USB_EPTYPE_BULK == ep->endp_type)) { + dev_ep_ctlr |= DIEPCTL_SEVNFRM; + } + + USB_DIEPxCTL((uint16_t)ep_id) = dev_ep_ctlr; + } else { + ep = &pudev->dev.out_ep[ep_id]; + + dev_ep_ctlr = USB_DOEPxCTL((uint16_t)ep_id); + + /* clear the OUT endpoint stall bits */ + dev_ep_ctlr &= ~DOEPCTL_STALL; + + if ((USB_EPTYPE_INTR == ep->endp_type) || (USB_EPTYPE_BULK == ep->endp_type)) { + dev_ep_ctlr |= DOEPCTL_SEVNFRM; + } + + USB_DOEPxCTL((uint16_t)ep_id) = dev_ep_ctlr; + } +} + +/*! + \brief flushes the FIFOs + \param[in] pudev: pointer to usb device instance + \param[in] ep_addr: endpoint address + \param[out] none + \retval none +*/ +void usbd_ep_fifo_flush (usb_core_handle_struct *pudev, uint8_t ep_addr) +{ + if (ep_addr >> 7) { + usb_txfifo_flush(pudev, ep_addr & 0x7FU); + } else { + usb_rxfifo_flush(pudev); + } +} + +/*! + \brief get the received data length + \param[in] pudev: pointer to usb device instance + \param[in] ep_id: endpoint identifier which is in (0..3) + \param[out] none + \retval received data length +*/ +uint16_t usbd_rxcount_get (usb_core_handle_struct *pudev, uint8_t ep_id) +{ + return (uint16_t)pudev->dev.out_ep[ep_id].xfer_count; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_int.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_int.c new file mode 100644 index 0000000000..01338e2e9b --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_int.c @@ -0,0 +1,758 @@ +/*! + \file usbd_int.c + \brief USB device mode interrupt routines +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "usbd_int.h" +#include "usbd_std.h" + +/* interrupt handlers */ +static uint32_t usbd_intf_outep (usb_core_handle_struct *pudev); +static uint32_t usbd_intf_inep (usb_core_handle_struct *pudev); +static uint32_t usbd_intf_earlysuspend (usb_core_handle_struct *pudev); +static uint32_t usbd_intf_suspend (usb_core_handle_struct *pudev); +static uint32_t usbd_intf_resume (usb_core_handle_struct *pudev); +static uint32_t usbd_intf_sof (usb_core_handle_struct *pudev); +static uint32_t usbd_intf_rxfifo (usb_core_handle_struct *pudev); +static uint32_t usbd_intf_reset (usb_core_handle_struct *pudev); +static uint32_t usbd_intf_enumfinish (usb_core_handle_struct *pudev); +static uint32_t usbd_intf_isoinincomplete (usb_core_handle_struct *pudev); +static uint32_t usbd_intf_isooutincomplete (usb_core_handle_struct *pudev); + +static uint32_t usbd_emptytxfifo_write (usb_core_handle_struct *pudev, uint8_t ep_num); + +#ifdef VBUS_SENSING_ENABLED + + static uint32_t usbd_intf_otg (usb_core_handle_struct *pudev); + static uint32_t usbd_intf_sessionrequest (usb_core_handle_struct *pudev); + +#endif + +static usb_speed_enum USB_SPEED[4] = { + [DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ] = USB_SPEED_HIGH, + [DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ] = USB_SPEED_FULL, + [DSTAT_ENUMSPD_FS_PHY_48MHZ] = USB_SPEED_FULL, + [DSTAT_ENUMSPD_LS_PHY_6MHZ] = USB_SPEED_LOW +}; + +static const uint8_t EP0_MAXLEN[4] = { + [DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ] = EP0MPL_64, + [DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ] = EP0MPL_64, + [DSTAT_ENUMSPD_FS_PHY_48MHZ] = EP0MPL_64, + [DSTAT_ENUMSPD_LS_PHY_6MHZ] = EP0MPL_8 +}; + +#ifdef USBHS_DEDICATED_EP1_ENABLED + +/*! + \brief USB dedicated OUT endpoint 1 interrupt service routine handler + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +uint32_t USBD_EP1OUT_ISR_Handler (usb_core_handle_struct *pudev) +{ + uint32_t out_endp_int = 0; + uint32_t out_endp_size = 0; + + out_endp_int = USB_DOEPxINTF(1); + out_endp_int &= USB_DOEP1INTEN; + + /* transfer complete */ + if (out_endp_int & DOEPINTF_TF) { + /* clear the interrupt bit */ + USB_DOEPxINTF(1) = DOEPINTF_TF; + + if (1U == pudev->cfg.dma_enable) { + out_endp_size = USB_DOEPxLEN(1); + + /* handle more than one single MPS size packet */ + pudev->dev.out_ep[1].xfer_count = pudev->dev.out_ep[1].endp_mps - \ + (out_endp_size & DOEPLEN_TLEN); + } + + /* inform upper layer: data ready */ + + /* receive complete */ + usbd_out_transaction(pudev, 1); + } + + /* endpoint disable interrupt */ + if (out_endp_int & DOEPINTF_EPDIS) { + /* clear the interrupt bit */ + USB_DOEPxINTF(1) = DOEPINTF_EPDIS; + } + + return 1; +} + +/*! + \brief USB dedicated IN endpoint 1 interrupt service routine handler + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +uint32_t USBD_EP1IN_ISR_Handler (usb_core_handle_struct *pudev) +{ + uint32_t fifoemptymask = 0, mask = 0; + uint32_t in_endp_int = 0; + + mask = USB_DIEP1INTEN; + mask |= ((USB_DIEPFEINTEN >> 1) & 0x01) << 7; + in_endp_int = USB_DIEPxINTF(1) & mask; + + if (in_endp_int & DIEPINTF_TF) { + fifoemptymask = 0x01 << 1; + USB_DIEPFEINTEN &= ~fifoemptymask; + + USB_DIEPxINTF(1) = DIEPINTF_TF; + + /* transmit complete */ + usbd_in_transaction(pudev , 1); + } + + if (in_endp_int & DIEPINTF_EPDIS) { + USB_DIEPxINTF(1) = DIEPINTF_EPDIS; + } + + if (in_endp_int & DIEPINTF_CITO) { + USB_DIEPxINTF(1) = DIEPINTF_CITO; + } + + if (in_endp_int & DIEPINTF_EPTXFUD) { + USB_DIEPxINTF(1) = DIEPINTF_EPTXFUD; + } + + if (in_endp_int & DIEPINTF_IEPNE) { + USB_DIEPxINTF(1) = DIEPINTF_IEPNE; + } + + if (in_endp_int & DIEPINTF_TXFE) { + usbd_emptytxfifo_write(pudev, 1); + + USB_DIEPxINTF(1) = DIEPINTF_IEPNE; + } + + return 1; +} + +#endif + + +/*! + \brief USB device-mode interrupts global service routine handler + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +uint32_t usbd_isr (usb_core_handle_struct *pudev) +{ + uint32_t retval = 0U; + uint32_t int_status = 0U, gintf = USB_GINTF, ginten = USB_GINTEN; + + /* ensure the core is in device mode */ + if (DEVICE_MODE == USB_CURRENT_MODE_GET()) { + int_status = gintf & ginten; + + /* there are no interrupts, avoid spurious interrupt */ + if (!int_status) { + return 0U; + } + + /* OUT endpoints interrupts */ + if (int_status & GINTF_OEPIF) { + retval |= usbd_intf_outep(pudev); + } + + /* IN endpoints interrupts */ + if (int_status & GINTF_IEPIF) { + retval |= usbd_intf_inep(pudev); + } + + /* mode mismatch interrupt */ + if (int_status & GINTF_MFIF) { + /* clear interrupt */ + USB_GINTF = GINTF_MFIF; + } + + /* early suspend interrupt */ + if (int_status & GINTF_ESP) { + retval |= usbd_intf_earlysuspend(pudev); + } + + /* suspend interrupt */ + if (int_status & GINTF_SP) { + retval |= usbd_intf_suspend(pudev); + } + + /* wakeup interrupt */ + if (int_status & GINTF_WKUPIF) { + retval |= usbd_intf_resume(pudev); + } + + /* start of frame interrupt */ + if (int_status & GINTF_SOF) { + retval |= usbd_intf_sof(pudev); + } + + /* reveive fifo not empty interrupt */ + if (int_status & GINTF_RXFNEIF) { + retval |= usbd_intf_rxfifo(pudev); + } + + /* USB reset interrupt */ + if (int_status & GINTF_RST) { + retval |= usbd_intf_reset(pudev); + } + + /* enumeration has been finished interrupt */ + if (int_status & GINTF_ENUMFIF) { + retval |= usbd_intf_enumfinish(pudev); + } + + /* incomplete synchronization in transfer interrupt*/ + if (int_status & GINTF_ISOINCIF) { + retval |= usbd_intf_isoinincomplete(pudev); + } + + /* incomplete synchronization out transfer interrupt*/ + if (int_status & GINTF_ISOONCIF) { + retval |= usbd_intf_isooutincomplete(pudev); + } + +#ifdef VBUS_SENSING_ENABLED + + /* session request interrupt */ + if (int_status & GINTF_SESIF) { + retval |= usbd_intf_sessionrequest(pudev); + } + + /* OTG mode interrupt */ + if (int_status & GINTF_OTGIF) { + retval |= usbd_intf_otg(pudev); + } +#endif /* VBUS_SENSING_ENABLED */ + } + + return retval; +} + +/*! + \brief indicates that an OUT endpoint has a pending interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_intf_outep (usb_core_handle_struct *pudev) +{ + uint8_t endp_num = 0U; + uint32_t endp_intr = 0U; + + __IO uint32_t out_endp_intr = 0U; + + /* read in the device interrupt bits */ + USB_DAOEP_INTR_READ(endp_intr); + + while (endp_intr) { + if (endp_intr & 0x1U) { + USB_DOEP_INTR_READ(out_endp_intr, (uint16_t)endp_num); + + /* transfer complete interrupt */ + if (out_endp_intr & DOEPINTF_TF) { + USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_TF; + + if (1U == pudev->cfg.dma_enable) { + uint32_t xfer_size = USB_DOEPxLEN((uint16_t)endp_num) & DOEPLEN_TLEN; + + pudev->dev.out_ep[endp_num].xfer_count = pudev->dev.out_ep[endp_num].endp_mps - \ + xfer_size; + } + + /* data receive is completed */ + usbd_out_transaction(pudev, endp_num); + + if (1U == pudev->cfg.dma_enable) { + if ((0U == endp_num) && (USB_CTRL_STATUS_OUT == pudev->dev.ctl_status)) { + /* prepare to receive more setup packets */ + usb_ep0_startout(pudev); + } + } + } + + /* endpoint disable interrupt */ + if (out_endp_intr & DOEPINTF_EPDIS) { + USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_EPDIS; + } + + /* setup phase finished interrupt (just for control endpoints) */ + if (out_endp_intr & DOEPINTF_STPF) { + /* setup phase is completed */ + usbd_setup_transaction(pudev); + + USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_STPF; + } + + /* back to back setup packets received */ + if (out_endp_intr & DOEPINTF_BTBSTP) { + USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_BTBSTP; + } + } + + endp_num ++; + endp_intr >>= 1; + } + + return 1U; +} + +/*! + \brief indicates that an IN endpoint has a pending interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_intf_inep(usb_core_handle_struct *pudev) +{ + uint8_t endp_num = 0U; + uint32_t endp_intr = 0U; + + __IO uint32_t in_endp_intr = 0U; + + /* get all in endpoints which have interrupts */ + USB_DAIEP_INTR_READ(endp_intr); + + while (endp_intr) { + if (endp_intr & 0x1U) { + USB_DIEP_INTR_READ(in_endp_intr, (uint16_t)endp_num); + + if (in_endp_intr & DIEPINTF_TF) { + /* disable the fifo empty interrupt for the endpoint */ + USB_DIEPFEINTEN &= ~(0x1U << endp_num); + + USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_TF; + + /* data transmittion is completed */ + usbd_in_transaction(pudev, endp_num); + + if (1U == pudev->cfg.dma_enable) { + if ((0U == endp_num) && (USB_CTRL_STATUS_IN == pudev->dev.ctl_status)) { + /* prepare to receive more setup packets */ + usb_ep0_startout(pudev); + } + } + } + + if (in_endp_intr & DIEPINTF_CITO) { + USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_CITO; + } + + if (in_endp_intr & DIEPINTF_IEPNE) { + USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_IEPNE; + } + + if (in_endp_intr & DIEPINTF_EPDIS) { + USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_EPDIS; + } + + if (in_endp_intr & DIEPINTF_TXFE) { + usbd_emptytxfifo_write(pudev, endp_num); + USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_TXFE; + } + } + + endp_num ++; + endp_intr >>= 1; + } + + return 1U; +} + +/*! + \brief indicates that early SUSPEND state has been detected on the USB + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_intf_earlysuspend (usb_core_handle_struct *pudev) +{ + USB_GINTEN &= ~GINTEN_ESPIE; + USB_GINTF = GINTF_ESP; + + return 1U; +} + +/*! + \brief indicates that SUSPEND state has been detected on the USB + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_intf_suspend(usb_core_handle_struct *pudev) +{ + __IO uint8_t low_power = pudev->cfg.low_power; + __IO uint8_t suspend = (uint8_t)(USB_DSTAT & DSTAT_SPST); + __IO uint8_t is_configured = (pudev->dev.status == USB_STATUS_CONFIGURED)? 1U : 0U; + + pudev->dev.prev_status = pudev->dev.status; + pudev->dev.status = USB_STATUS_SUSPENDED; + + if (low_power && suspend && is_configured) { + /* switch-off the otg clocks */ + USB_PWRCLKCTL |= PWRCLKCTL_SUCLK | PWRCLKCTL_SHCLK; + + /* enter DEEP_SLEEP mode with LDO in low power mode */ + pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD); + } + + /* clear interrupt */ + USB_GINTF = GINTF_SP; + + return 1U; +} + +/*! + \brief indicates that the USB controller has detected a resume or remote Wake-up sequence + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_intf_resume (usb_core_handle_struct *pudev) +{ + pudev->dev.status = pudev->dev.prev_status; + pudev->dev.status = USB_STATUS_CONFIGURED; + + /* clear interrupt */ + USB_GINTF = GINTF_WKUPIF; + + return 1U; +} + +/*! + \brief handle the SOF interrupts + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_intf_sof(usb_core_handle_struct *pudev) +{ +// USBD_DCD_INT_fops->SOF(pudev); + + USB_GINTF = GINTF_SOF; + + return 1U; +} + +/*! + \brief handle the Rx status queue level interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_intf_rxfifo (usb_core_handle_struct *pudev) +{ + usb_ep_struct *ep; + uint8_t data_pid = 0U, endp_num = 0U; + uint32_t bcount = 0U; + + /* get the status from the top of the fifo (must be read to a variable) */ + __IO uint32_t rx_status = USB_GRSTATP; + + /* disable the rx fifo non-empty interrupt */ + USB_GINTEN &= ~GINTEN_RXFNEIE; + + endp_num = (uint8_t)(rx_status & GRSTATP_EPNUM); + bcount = (rx_status & GRSTATP_BCOUNT) >> 4U; + data_pid = (uint8_t)((rx_status & GRSTATP_DPID) >> 15U); + + if ((endp_num == 1) && ((*(uint32_t *)0x40040B30 & 0x1FF80000) == 0)) { + *(uint32_t *)0x40040B20 = ((*(uint32_t *)0x40040B20 | 0x08000000) & 0x3FFFFFFF); + } + + ep = &pudev->dev.out_ep[endp_num]; + + switch ((rx_status & GRSTATP_RPCKST) >> 17U) { + case RXSTAT_GOUT_NAK: + if(0U != bcount) { + return 0U; + } + break; + case RXSTAT_DATA_UPDT: + if (bcount > 0U) { + usb_fifo_read(ep->xfer_buff, (uint16_t)bcount); + ep->xfer_buff += bcount; + ep->xfer_count += bcount; + } + break; + case RXSTAT_XFER_COMP: + if (0U != bcount) { + return 0U; + } + break; + case RXSTAT_SETUP_COMP: + if(0U != bcount) { + return 0U; + } + break; + case RXSTAT_SETUP_UPDT: + if ((0U == endp_num) && (8U == bcount) && (DPID_DATA0 == data_pid)) { + /* copy the setup packet received in fifo into the setup buffer in ram */ + usb_fifo_read(pudev->dev.setup_packet, 8U); + + ep->xfer_count += bcount; + } + break; + default: + break; + } + + /* enable the Rx fifo non-empty interrupt */ + USB_GINTEN |= GINTEN_RXFNEIE; + + return 1U; +} + +/*! + \brief handle USB reset interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval status +*/ +static uint32_t usbd_intf_reset(usb_core_handle_struct *pudev) +{ + uint8_t i = 0U; + usb_ep_struct *ep; + + /* clear the remote wakeup signaling */ + USB_DCTL &= ~DCTL_RWKUP; + + /* flush the tx fifo */ + usb_txfifo_flush(pudev, 0U); + + for (i = 0U; i < pudev->cfg.dev_endp_num; i++) { + USB_DIEPxINTF((uint16_t)i) = 0xFFU; + USB_DOEPxINTF((uint16_t)i) = 0xFFU; + } + + /* clear all pending device endpoint interrupts */ + USB_DAEPINT = 0xFFFFFFFF; + + /* enable endpoint 0 interrupts */ + USB_DAEPINTEN &= ~DAEPINTEN_OEPIE; + USB_DAEPINTEN &= ~DAEPINTEN_IEPIE; + USB_DAEPINTEN = (1U << 16) | 1U; + + /* enable out endpoint interrupts */ + USB_DOEPINTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN | DOEPINTEN_EPDISEN; + +#ifdef USBHS_DEDICATED_EP1_ENABLED + USB_DOEP1INTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN | DOEPINTEN_EPDISEN; +#endif + + /* enable in endpoint interrupts */ + USB_DIEPINTEN = DIEPINTEN_TFEN | DIEPINTEN_CITOEN | DIEPINTEN_EPDISEN; + +#ifdef USBHS_DEDICATED_EP1_ENABLED + USB_DIEP1INTEN = DIEPINTEN_TFEN | DIEPINTEN_CITOEN | DIEPINTEN_EPDISEN; +#endif + + /* reset device address */ + USB_DCFG &= ~DCFG_DAR; + USB_DCFG |= 0U << 4U; + + /* configure endpoint 0 to receive setup packets */ + usb_ep0_startout(pudev); + + /* clear usb reset interrupt */ + USB_GINTF = GINTF_RST; + + /* open EP0 IN */ + ep = &pudev->dev.in_ep[0]; + + USB_DIEPxCTL(0U) &= ~DIEP0CTL_MPL; + USB_DIEPxCTL(0U) &= ~DIEPCTL_EPTYPE; + USB_DIEPxCTL(0U) &= ~DIEPCTL_TXFNUM; + + if (!(USB_DIEPxCTL(0U) & DIEPCTL_EPACT)) { + USB_DIEPxCTL(0U) |= USB_MAX_EP0_SIZE; + USB_DIEPxCTL(0U) |= (USB_EPTYPE_CTRL << 18U); + USB_DIEPxCTL(0U) |= DIEP0CTL_EPACT; + } + + ep->endp_mps = USB_MAX_EP0_SIZE; + ep->endp_type = USB_EPTYPE_CTRL; + + /* open EP0 OUT */ + ep = &pudev->dev.out_ep[0]; + + USB_DOEPxCTL(0U) &= ~DOEP0CTL_MPL; + USB_DOEPxCTL(0U) &= ~DOEPCTL_EPTYPE; + + if (!(USB_DOEPxCTL(0U) & DOEPCTL_EPACT)) { + USB_DOEPxCTL(0U) |= USB_MAX_EP0_SIZE; + USB_DOEPxCTL(0U) |= (USB_EPTYPE_CTRL << 18U); + USB_DOEPxCTL(0U) |= DOEP0CTL_EPACT; + } + + ep->endp_mps = USB_MAX_EP0_SIZE; + ep->endp_type = USB_EPTYPE_CTRL; + + pudev->dev.status = USB_STATUS_DEFAULT; + + return 1U; +} + +/*! + \brief handle enumeration finish interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval status +*/ +static uint32_t usbd_intf_enumfinish(usb_core_handle_struct *pudev) +{ + uint8_t enum_speed = (uint8_t)((USB_DSTAT & DSTAT_ES) >> 1U); + + /* set the max packet size of devie in endpoint based on the enumeration speed */ + USB_DIEPxCTL(0U) |= EP0_MAXLEN[enum_speed]; + + /* clear global IN NAK */ + USB_DCTL &= ~DCTL_CGINAK; + USB_DCTL |= DCTL_CGINAK; + + /* set USB turn-around time based on device speed and PHY interface */ + if (USB_SPEED_HIGH == USB_SPEED[enum_speed]) { + pudev->cfg.core_speed = USB_CORE_SPEED_HIGH; + pudev->cfg.max_packet_size = USBHS_MAX_PACKET_SIZE; + + USB_GUSBCS &= ~GUSBCS_UTT; + USB_GUSBCS |= 0x09U << 10; + } else { + pudev->cfg.core_speed = USB_CORE_SPEED_FULL; + pudev->cfg.max_packet_size = USBFS_MAX_PACKET_SIZE; + + USB_GUSBCS &= ~GUSBCS_UTT; + USB_GUSBCS |= 0x05U << 10; + } + + /* clear interrupt */ + USB_GINTF = GINTF_ENUMFIF; + + return 1U; +} + +/*! + \brief handle the ISO IN incomplete interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval status +*/ +static uint32_t usbd_intf_isoinincomplete(usb_core_handle_struct *pudev) +{ +// USBD_DCD_INT_fops->IsoINIncomplete (pudev); + + /* clear interrupt */ + USB_GINTF = GINTF_ISOINCIF; + + return 1U; +} + +/*! + \brief handle the ISO OUT incomplete interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval status +*/ +static uint32_t usbd_intf_isooutincomplete(usb_core_handle_struct *pudev) +{ +// USBD_DCD_INT_fops->IsoOUTIncomplete (pudev); + + /* clear interrupt */ + USB_GINTF = GINTF_ISOONCIF; + + return 1U; +} + +/*! + \brief check FIFO for the next packet to be loaded + \param[in] pudev: pointer to usb device instance + \param[in] ep_id: endpoint identifier which is in (0..3) + \param[out] none + \retval status +*/ +static uint32_t usbd_emptytxfifo_write(usb_core_handle_struct *pudev, uint8_t ep_num) +{ + uint32_t len = 0U, word_len = 0U; + usb_ep_struct *ep; + + ep = &pudev->dev.in_ep[ep_num]; + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->endp_mps) { + len = ep->endp_mps; + } + + word_len = (len + 3U) / 4U; + + while (((USB_DIEPxTFSTAT((uint16_t)ep_num) & DIEPTFSTAT_IEPTFS) > word_len) && + (ep->xfer_count < ep->xfer_len)) { + /* write the FIFO */ + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->endp_mps) { + len = ep->endp_mps; + } + + word_len = (len + 3U) / 4U; + + usb_fifo_write (ep->xfer_buff, ep_num, (uint16_t)len); + + ep->xfer_buff += len; + ep->xfer_count += len; + } + + return 1U; +} + +#ifdef VBUS_SENSING_ENABLED + +/*! + \brief indicates that the USB_OTG controller has detected a connection + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval status +*/ +static uint32_t usbd_intf_sessionrequest(usb_core_handle_struct *pudev) +{ + pudev->dev.connection_status = 1U; + + /* clear the interrupt bit */ + USB_GINTF = GINTF_SESIF; + + return 1; +} + +/*! + \brief indicates that the USB_OTG controller has detected an OTG event + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval status +*/ +static uint32_t usbd_intf_otg(usb_core_handle_struct *pudev) +{ + if (USB_GOTGINTF & GOTGINTF_SESEND) { + pudev->dev.class_deinit(pudev, 0); + pudev->dev.connection_status = 0; + } + + /* clear OTG interrupt */ + USB_GOTGINTF |= GOTGINTF_SESEND; + + return 1; +} + +#endif /* VBUS_SENSING_ENABLED */ diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_std.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_std.c new file mode 100644 index 0000000000..0ae93e4472 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbd_std.c @@ -0,0 +1,699 @@ +/*! + \file usbd_std.c + \brief USB 2.0 standard handler driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "usbd_std.h" +#include "usb_core.h" + +static usbd_status_enum usbd_standard_request (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static usbd_status_enum usbd_device_class_request (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static usbd_status_enum usbd_vendor_request (usb_core_handle_struct *pudev, usb_device_req_struct *req); + +static void usbd_setup_request_parse(usb_core_handle_struct *pudev, usb_device_req_struct *req); + +static void usbd_getdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_setaddress (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_setconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_getconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_getstatus (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_setfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_clrfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_reserved (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_setdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_getinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_setinterface (usb_core_handle_struct *pudev, usb_device_req_struct *req); +static void usbd_synchframe (usb_core_handle_struct *pudev, usb_device_req_struct *req); + +static uint8_t* usbd_device_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen); +static uint8_t* usbd_configuration_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen); +static uint8_t* usbd_string_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen); + +static void (*StandardDeviceRequest[])(usb_core_handle_struct *pudev, usb_device_req_struct *req) = +{ + usbd_getstatus, + usbd_clrfeature, + usbd_reserved, + usbd_setfeature, + usbd_reserved, + usbd_setaddress, + usbd_getdescriptor, + usbd_setdescriptor, + usbd_getconfig, + usbd_setconfig, + usbd_getinterface, + usbd_setinterface, + usbd_synchframe, +}; + +/* get standard descriptor handler */ +static uint8_t* (*standard_descriptor_get[])(usb_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 +*/ +usbd_status_enum usbd_setup_transaction(usb_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, req.bmRequestType & 0x80U); + break; + } + + return USBD_OK; +} + +/*! + \brief data out stage processing + \param[in] pudev: pointer to USB device instance + \param[in] ep_id: endpoint identifier(0..7) + \param[out] none + \retval USB device operation status +*/ +usbd_status_enum usbd_out_transaction (usb_core_handle_struct *pudev, uint8_t endp_num) +{ + usb_ep_struct *ep; + + if (0U == endp_num) { + ep = &pudev->dev.out_ep[0]; + + if (USB_CTRL_DATA_OUT == pudev->dev.ctl_status) { + if (pudev->dev.remain_len > ep->endp_mps) { + pudev->dev.remain_len -= ep->endp_mps; + + if (1U == pudev->cfg.dma_enable) { + /* update buffer location */ + ep->xfer_buff += ep->endp_mps; + } + + usbd_ep_rx (pudev, + 0U, + ep->xfer_buff, + (uint16_t)USB_MIN(pudev->dev.remain_len, ep->endp_mps)); + } else { + if (USB_STATUS_CONFIGURED == pudev->dev.status) { + pudev->dev.class_data_handler(pudev, USBD_RX, 0U); + } + + usbd_ctlstatus_tx(pudev); + } + } + } else if (USB_STATUS_CONFIGURED == pudev->dev.status) { + pudev->dev.class_data_handler(pudev, USBD_RX, endp_num); + } else { + /* no operation */ + } + + return USBD_OK; +} + +/*! + \brief data in stage processing + \param[in] pudev: pointer to USB device instance + \param[in] ep_id: endpoint identifier(0..7) + \param[out] none + \retval USB device operation status +*/ +usbd_status_enum usbd_in_transaction (usb_core_handle_struct *pudev, uint8_t endp_num) +{ + usb_ep_struct *ep; + + if (0U == endp_num) { + ep = &pudev->dev.in_ep[0]; + + if (USB_CTRL_DATA_IN == pudev->dev.ctl_status) { + if (pudev->dev.remain_len > ep->endp_mps) { + pudev->dev.remain_len -= ep->endp_mps; + + if (1U == pudev->cfg.dma_enable) { + /* update buffer location */ + ep->xfer_buff += ep->endp_mps; + } + + usbd_ep_tx (pudev, 0U, ep->xfer_buff, pudev->dev.remain_len); + } else { + /* last packet is MPS multiple, so send ZLP packet */ + if ((pudev->dev.sum_len % ep->endp_mps == 0U) && + (pudev->dev.sum_len >= ep->endp_mps) && + (pudev->dev.sum_len < pudev->dev.ctl_len)) { + usbd_ep_tx (pudev, 0U, NULL, 0U); + pudev->dev.ctl_len = 0U; + } else { + if (USB_STATUS_CONFIGURED == pudev->dev.status) { + pudev->dev.class_data_handler(pudev, USBD_TX, 0U); + } + + usbd_ctlstatus_rx(pudev); + } + } + } + } else if (USB_STATUS_CONFIGURED == pudev->dev.status) { + pudev->dev.class_data_handler(pudev, USBD_TX, endp_num); + } else { + /* no operation */ + } + + 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 +*/ +static usbd_status_enum usbd_standard_request (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + /* call device request handle function */ + (*StandardDeviceRequest[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 +*/ +static usbd_status_enum usbd_device_class_request (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + usbd_status_enum ret = USBD_OK; + + switch (pudev->dev.status) { + case USB_STATUS_CONFIGURED: + if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) { + ret = (usbd_status_enum)(pudev->dev.class_req_handler(pudev, req)); + + if ((0U == req->wLength) && (USBD_OK == ret)) { + /* no data stage */ + usbd_ctlstatus_tx(pudev); + } + } else { + usbd_enum_error(pudev, req); + } + break; + + default: + usbd_enum_error(pudev, req); + break; + } + + return ret; +} + +/*! + \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 +*/ +static usbd_status_enum usbd_vendor_request (usb_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 (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + /* no operation... */ +} + +/*! + \brief get the device descriptor + \brief[in] index: no use + \param[in] none + \param[out] pLen: data length pointer + \retval descriptor buffer pointer +*/ +static uint8_t* usbd_device_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) +{ + *pLen = pudev->dev.dev_desc[0]; + + return pudev->dev.dev_desc; +} + +/*! + \brief get the configuration descriptor + \brief[in] index: no use + \param[in] none + \param[out] pLen: data length pointer + \retval descriptor buffer pointer +*/ +static uint8_t* usbd_configuration_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) +{ + *pLen = pudev->dev.config_desc[2]; + + return pudev->dev.config_desc; +} + +/*! + \brief get string descriptor + \param[in] index: string descriptor index + \param[in] pLen: pointer to string length + \param[out] none + \retval none +*/ +static uint8_t* usbd_string_descriptor_get (usb_core_handle_struct *pudev, uint8_t index, uint16_t *pLen) +{ + uint8_t *desc = pudev->dev.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 (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ +} + +/*! + \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_clrfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + uint8_t ep_addr = 0U; + + switch (req->bmRequestType & USB_REQTYPE_MASK) { + case USB_REQTYPE_DEVICE: + switch (pudev->dev.status) { + case USB_STATUS_ADDRESSED: + case USB_STATUS_CONFIGURED: + if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) { + pudev->dev.remote_wakeup = 0U; + pudev->dev.class_req_handler(pudev, req); + + usbd_ctlstatus_tx(pudev); + } + break; + + default: + usbd_enum_error(pudev, req); + break; + } + break; + case USB_REQTYPE_INTERFACE: + switch (pudev->dev.status) { + case USB_STATUS_ADDRESSED: + usbd_enum_error(pudev, req); + break; + case USB_STATUS_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: + ep_addr = LOWBYTE(req->wIndex); + + switch (pudev->dev.status) { + case USB_STATUS_ADDRESSED: + if (IS_NOT_EP0(ep_addr)) { + usbd_ep_stall(pudev, ep_addr); + } + break; + case USB_STATUS_CONFIGURED: + if (USB_FEATURE_ENDP_HALT == req->wValue) { + if (IS_NOT_EP0(ep_addr)) { + usbd_ep_clear_stall(pudev, ep_addr); + + pudev->dev.class_req_handler(pudev, req); + } + } + usbd_ctlstatus_tx(pudev); + 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 (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + uint8_t ep_addr = 0U; + __IO uint32_t DctlrStatus; + + switch (req->bmRequestType & USB_REQ_MASK) { + case USB_REQTYPE_DEVICE: + switch (pudev->dev.status) { + case USB_STATUS_ADDRESSED: + case USB_STATUS_CONFIGURED: + if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) { + pudev->dev.remote_wakeup = 1U; + pudev->dev.class_req_handler(pudev, req); + + usbd_ctlstatus_tx(pudev); + } else if ((req->wValue == USB_FEATURE_TEST_MODE) && + (0U == (req->wIndex & 0xFFU))) { + DctlrStatus = USB_DCTL; + + usbd_ctlstatus_tx(pudev); + } else { + /* no operation */ + } + break; + default: + break; + } + break; + case USB_REQTYPE_INTERFACE: + switch (pudev->dev.status) { + case USB_STATUS_ADDRESSED: + usbd_enum_error(pudev, req); + break; + case USB_STATUS_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: + switch (pudev->dev.status) { + case USB_STATUS_ADDRESSED: + if (IS_NOT_EP0(ep_addr)) { + usbd_ep_stall(pudev, ep_addr); + } + break; + case USB_STATUS_CONFIGURED: + if (USB_FEATURE_ENDP_HALT == req->wValue) { + if (IS_NOT_EP0(ep_addr)) { + usbd_ep_stall(pudev, ep_addr); + } + } + pudev->dev.class_req_handler(pudev, req); + + usbd_ctlstatus_tx(pudev); + 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 (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + uint8_t DevAddr; + + if ((0U == req->wIndex) && (0U == req->wLength)) { + DevAddr = (uint8_t)(req->wValue) & 0x7FU; + + if (USB_STATUS_CONFIGURED == pudev->dev.status) { + usbd_enum_error(pudev, req); + } else { + USB_SET_DEVADDR((uint32_t)DevAddr); + + usbd_ctlstatus_tx(pudev); + + if (0U != DevAddr) { + pudev->dev.status = USB_STATUS_ADDRESSED; + } else { + pudev->dev.status = USB_STATUS_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 (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + if (USB_REQTYPE_DEVICE == (req->bmRequestType & USB_REQTYPE_MASK)) { + uint8_t desc_index = (uint8_t)(req->wValue >> 8U); + + if (desc_index <= 0x03U) { + uint16_t len; + uint8_t *pbuf; + + /* call corresponding descriptor get function */ + pbuf = standard_descriptor_get[desc_index - 1U](pudev, (uint8_t)(req->wValue) & 0xFFU, &len); + + if ((0U != len) && (0U != req->wLength)) { + len = USB_MIN(len, req->wLength); + + if ((1U == desc_index) && (64U == req->wLength)) { + len = 8U; + } + + usbd_ctltx(pudev, pbuf, len); + } + } else { + usbd_enum_error(pudev, req); + } + } else if (USB_REQTYPE_INTERFACE == (req->bmRequestType & USB_REQTYPE_MASK)) { + pudev->dev.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 (usb_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_getconfig (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + uint32_t USBD_default_config = 0U; + + if (1U != req->wLength) { + usbd_enum_error(pudev, req); + } else { + switch (pudev->dev.status) { + case USB_STATUS_ADDRESSED: + usbd_ctltx(pudev, (uint8_t *)&USBD_default_config, 1U); + break; + case USB_STATUS_CONFIGURED: + usbd_ctltx(pudev, &pudev->dev.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_setconfig (usb_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->dev.status) { + case USB_STATUS_ADDRESSED: + if (cfgidx) { + pudev->dev.config_num = cfgidx; + pudev->dev.status = USB_STATUS_CONFIGURED; + pudev->dev.class_init(pudev, cfgidx); + } + + usbd_ctlstatus_tx(pudev); + break; + case USB_STATUS_CONFIGURED: + if (0U == cfgidx) { + pudev->dev.status = USB_STATUS_ADDRESSED; + pudev->dev.config_num = cfgidx; + pudev->dev.class_deinit(pudev, cfgidx); + } else if (cfgidx != pudev->dev.config_num) { + /* clear old configuration */ + pudev->dev.class_deinit(pudev, pudev->dev.config_num); + + /* set new configuration */ + pudev->dev.config_num = cfgidx; + pudev->dev.class_init(pudev, cfgidx); + } else { + /* no operation */ + } + + usbd_ctlstatus_tx(pudev); + break; + default: + usbd_enum_error(pudev, req); + 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 (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + pudev->dev.class_req_handler(pudev, req); +} + +/*! + \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 (usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + pudev->dev.class_req_handler(pudev, req); +} + +/*! + \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 (usb_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 +*/ +static void usbd_setup_request_parse(usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + uint8_t *psetup = pudev->dev.setup_packet; + + req->bmRequestType = *psetup; + req->bRequest = *(uint8_t *)(psetup + 1U); + req->wValue = SWAPBYTE (psetup + 2U); + req->wIndex = SWAPBYTE (psetup + 4U); + req->wLength = SWAPBYTE (psetup + 6U); + + pudev->dev.ctl_len = req->wLength; +} + +/*! + \brief handle USB low level 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(usb_core_handle_struct *pudev, usb_device_req_struct *req) +{ + usbd_ep_stall(pudev, 0x80U); + usbd_ep_stall(pudev, 0x00U); + usb_ep0_startout(pudev); +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_core.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_core.c new file mode 100644 index 0000000000..1c90b55187 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_core.c @@ -0,0 +1,710 @@ +/*! + \file usbh_core.c + \brief this file implements the functions for the core state machine process +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "usbh_hcs.h" +#include "usbh_core.h" +#include "usbh_int.h" +#include "stdio.h" +#include "usbh_std.h" +#include "usbh_ctrl.h" +#include "usb_core.h" + +extern class_polling_fun_cb_struct class_polling_cb; + +uint8_t usbh_sof (usb_core_handle_struct *pudev); +uint8_t usbh_connected (usb_core_handle_struct *pudev); +uint8_t usbh_disconnected (usb_core_handle_struct *pudev); + +usbh_hcd_int_cb_struct usbh_hcd_int_cb = +{ + usbh_sof, + usbh_connected, + usbh_disconnected, +}; + +usbh_hcd_int_cb_struct *usbh_hcd_int_fops = &usbh_hcd_int_cb; +extern usbh_state_handle_struct usbh_state_core; + +static void host_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void host_dev_attached_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void host_dev_detached_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void host_detect_dev_speed_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void host_enum_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void host_class_request_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void host_class_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void host_user_input_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void host_suspended_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void host_error_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); + +static usbh_status_enum class_req_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate); +static usbh_status_enum class_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate); + +/* the host state handle function array */ +void (*host_state_handle[]) (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate) = +{ + host_idle_handle, + host_dev_attached_handle, + host_dev_detached_handle, + host_detect_dev_speed_handle, + host_enum_handle, + host_class_request_handle, + host_class_handle, + host_user_input_handle, + host_suspended_handle, + host_error_handle, +}; + +/* the host state handle table */ +state_table_struct host_handle_table[HOST_HANDLE_TABLE_SIZE] = +{ + /* the current state the current event the next state the event function */ + {HOST_IDLE, HOST_EVENT_ATTACHED, HOST_DEV_ATTACHED, only_state_move }, + {HOST_DEV_ATTACHED, HOST_EVENT_ENUM, HOST_ENUMERATION, only_state_move }, + {HOST_ENUMERATION, HOST_EVENT_USER_INPUT, HOST_USER_INPUT, only_state_move }, + {HOST_USER_INPUT, HOST_EVENT_CLASS_REQ, HOST_CLASS_REQUEST, only_state_move }, + {HOST_CLASS_REQUEST, HOST_EVENT_CLASS, HOST_CLASS, only_state_move }, + {HOST_CLASS, HOST_EVENT_ERROR, HOST_ERROR, only_state_move }, + {HOST_ERROR, HOST_EVENT_IDLE, HOST_IDLE, only_state_move }, + {HOST_DEV_DETACHED, HOST_EVENT_IDLE, HOST_IDLE, only_state_move }, + {HOST_CLASS_REQUEST, HOST_EVENT_ERROR, HOST_ERROR, only_state_move }, +}; + +/*! + \brief the polling function of HOST state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +usbh_status_enum host_state_polling_fun (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + void *pustate) +{ + usbh_state_handle_struct *p_state = (usbh_state_handle_struct *)pustate; + + scd_begin(p_state, HOST_FSM_ID); + + if (-1 == p_state->usbh_current_state_stack_top) { + uint8_t cur_state = p_state->usbh_current_state; + + if ((0U == hcd_is_device_connected(pudev)) && (HOST_IDLE != cur_state)) { + if (HOST_DEV_DETACHED != cur_state) { + p_state->usbh_current_state = HOST_DEV_DETACHED; + cur_state = HOST_DEV_DETACHED; + } + } + + host_state_handle[cur_state](pudev, puhost, p_state); + } else { + uint8_t stack0_state = p_state->stack[0].state; + + if ((0U == hcd_is_device_connected(pudev)) && (HOST_IDLE != stack0_state)) { + if (HOST_DEV_DETACHED != stack0_state) { + p_state->stack[0].state = HOST_DEV_DETACHED; + stack0_state = HOST_DEV_DETACHED; + p_state->usbh_current_state = HOST_DEV_DETACHED; + } + } + + host_state_handle[stack0_state](pudev, puhost, p_state); + } + + return USBH_OK; +} + +/*! + \brief the handle function of HOST_IDLE state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void host_idle_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + if (hcd_is_device_connected(pudev)) { + scd_event_handle(pudev, puhost, pustate, HOST_EVENT_ATTACHED, pustate->usbh_current_state); + + if ((void *)0 != pudev->mdelay) { + pudev->mdelay(100U); + } + } +} + +/*! + \brief the handle function of HOST_DEV_ATTACHED state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void host_dev_attached_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usr_cb->device_connected(); + puhost->control.hc_out_num = usbh_channel_alloc(pudev, 0x00U); + puhost->control.hc_in_num = usbh_channel_alloc(pudev, 0x80U); + + /* reset usb device */ + if (0U == usb_port_reset(pudev)) { + puhost->usr_cb->device_reset(); + + /* wait for USB USBH_ISR_PrtEnDisableChange() + * host is now ready to start the enumeration + */ + puhost->device.speed = (uint8_t)USB_CURRENT_SPEED_GET(); + puhost->usr_cb->device_speed_detected(puhost->device.speed); + + /* open IN control pipes */ + usbh_channel_open (pudev, + puhost->control.hc_in_num, + puhost->device.address, + puhost->device.speed, + USB_EPTYPE_CTRL, + (uint16_t)puhost->control.ep0_size); + + /* open OUT control pipes */ + usbh_channel_open (pudev, + puhost->control.hc_out_num, + puhost->device.address, + puhost->device.speed, + USB_EPTYPE_CTRL, + (uint16_t)puhost->control.ep0_size); + + scd_event_handle(pudev, puhost, pustate, HOST_EVENT_ENUM, pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of HOST_ENUMERATION state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void host_enum_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + if (USBH_OK == enum_state_polling_fun(pudev, puhost, pustate)) { + puhost->usr_cb->enumeration_finish(); + scd_event_handle(pudev, + puhost, + pustate, + HOST_EVENT_USER_INPUT, + pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of HOST_USER_INPUT state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void host_user_input_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + if (USBH_USER_RESP_OK == puhost->usr_cb->user_input()) { + if (USBH_OK == (puhost->class_init(pudev, puhost))) { + scd_event_handle(pudev, + puhost, + pustate, + HOST_EVENT_CLASS_REQ, + pustate->usbh_current_state); + } + } +} + +/*! + \brief the handle function of HOST_CLASS_REQUEST state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void host_class_request_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + if (USBH_OK == class_req_state_polling_fun(pudev, puhost, pustate)) { + scd_event_handle(pudev, puhost, pustate, HOST_EVENT_CLASS, pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of HOST_CLASS state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void host_class_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + class_state_polling_fun(pudev, puhost, pustate); +} + +/*! + \brief the handle function of HOST_SUSPENDED state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void host_suspended_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + /* no operation */ +} + +/*! + \brief the handle function of HOST_ERROR state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void host_error_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + /* re-initilaize host for new enumeration */ + usbh_deinit (pudev, puhost,&usbh_state_core); + puhost->usr_cb->deinit(); + puhost->class_deinit(pudev, &puhost->device); + scd_event_handle(pudev, puhost, pustate, HOST_EVENT_IDLE, pustate->usbh_current_state); +} + +/*! + \brief the handle function of HOST_DEV_DETACHED state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void host_dev_detached_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + /* manage user disconnect operations*/ + puhost->usr_cb->device_disconnected(); + + /* re-initilaize host for new enumeration */ + usbh_deinit(pudev, puhost,&usbh_state_core); + puhost->usr_cb->deinit(); + puhost->class_deinit(pudev, &puhost->device); + usbh_allchannel_dealloc(pudev); + scd_event_handle(pudev, puhost, pustate, HOST_EVENT_IDLE, pustate->usbh_current_state); +} + +/*! + \brief the handle function of HOST_DETECT_DEV_SPEED state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void host_detect_dev_speed_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + /* no operation */ +} + +/*! + \brief usb connect callback function from the interrupt. + \param[in] pudev: pointer to usb device + \param[out] none + \retval operation status +*/ +uint8_t usbh_connected (usb_core_handle_struct *pudev) +{ + pudev->host.connect_status = 1U; + + return 0U; +} + +/*! + \brief usb disconnect callback function from the interrupt. + \param[in] pudev: pointer to usb device + \param[out] none + \retval operation status +*/ +uint8_t usbh_disconnected (usb_core_handle_struct *pudev) +{ + pudev->host.connect_status = 0U; + + return 0U; +} + +/*! + \brief usb sof callback function from the interrupt. + \param[in] pudev: pointer to usb device + \param[out] none + \retval operation status +*/ +uint8_t usbh_sof (usb_core_handle_struct *pudev) +{ + /* this callback could be used to implement a scheduler process */ + return 0U; +} + +/*! + \brief initialize the host portion of the driver. + \param[in] pudev: pointer to usb device + \param[in] core_id: usb otg core identifier(high-speed or full-speed) + \param[out] none + \retval operation status +*/ +uint32_t hcd_init(usb_core_handle_struct *pudev, usb_core_id_enum core_id) +{ + pudev->host.connect_status = 0U; + + pudev->host.host_channel[0].endp_mps = 8U; + + usb_core_select(pudev, core_id); + +#ifndef DUAL_ROLE_MODE_ENABLED + + USB_GLOBAL_INT_DISABLE(); + + usb_core_init(pudev); + + /* force host mode*/ + usb_mode_set(pudev, HOST_MODE); + + usb_hostcore_init(pudev); + + USB_GLOBAL_INT_ENABLE(); + +#endif + + return 0U; +} + +/*! + \brief check if the device is connected. + \param[in] pudev: pointer to usb device + \param[out] none + \retval device connection status. 1 -> connected and 0 -> disconnected +*/ +uint32_t hcd_is_device_connected(usb_core_handle_struct *pudev) +{ + return (uint32_t)(pudev->host.connect_status); +} + +/*! + \brief this function returns the last URBstate + \param[in] pudev: pointer to usb device + \param[in] channel_num: host channel number which is in (0..7) + \param[out] none + \retval urb_state_enum +*/ +urb_state_enum hcd_urb_state_get (usb_core_handle_struct *pudev, uint8_t channel_num) +{ + return pudev->host.host_channel[channel_num].urb_state; +} + +/*! + \brief this function returns the last URBstate + \param[in] pudev: pointer to usb device + \param[in] channel_num: host channel number which is in (0..7) + \param[out] none + \retval No. of data bytes transferred +*/ +uint32_t hcd_xfer_count_get (usb_core_handle_struct *pudev, uint8_t channel_num) +{ + return pudev->host.host_channel[channel_num].xfer_count; +} + +/*! + \brief de-initialize host + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[out] none + \retval host status +*/ +usbh_status_enum usbh_deinit(usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct* pustate) +{ + /* software init */ + + puhost->control.ep0_size = USB_MAX_EP0_SIZE; + + puhost->device.address = USBH_DEVICE_ADDRESS_DEFAULT; + puhost->device.speed = HPRT_PRTSPD_FULL_SPEED; + + usbh_channel_free(pudev, puhost->control.hc_in_num); + usbh_channel_free(pudev, puhost->control.hc_out_num); + + scd_init(pustate); + scd_table_regist(pustate, host_handle_table, HOST_FSM_ID, HOST_HANDLE_TABLE_SIZE); + scd_table_regist(pustate, enum_handle_table, ENUM_FSM_ID, ENUM_HANDLE_TABLE_SIZE); + scd_table_regist(pustate, ctrl_handle_table, CTRL_FSM_ID, CTRL_HANDLE_TABLE_SIZE); + + scd_begin(pustate,HOST_FSM_ID); + scd_state_move(pustate, HOST_IDLE); + + return USBH_OK; +} + +/*! + \brief state core driver init + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +void scd_init(usbh_state_handle_struct* pustate) +{ + /* init the state core */ + pustate->usbh_current_state = 0U; + pustate->usbh_current_state_table = NULL; + pustate->usbh_current_state_table_size = 0U; + + pustate->usbh_current_state_stack_top = -1; + pustate->stack->state = 0U; + pustate->stack->table_size = 0U; + pustate->stack->table = NULL; + + pustate->usbh_regist_state_table_num = 0U; + pustate->usbh_regist_state_table->table = NULL; + pustate->usbh_regist_state_table->table_size = 0U; + pustate->usbh_regist_state_table->id = 0U; + + /* init the control and the enumeration polling handle flag */ + ctrl_polling_handle_flag = 0U; + enum_polling_handle_flag = 0U; +} + +/*! + \brief state core driver table regist + \param[in] pustate: pointer to usb state driver + \param[in] pstate_table: pointer to the table to regist + \param[in] table_id: the id of the table to regist + \param[in] current_table_size: the size of the current table to regist + \param[out] none + \retval none +*/ +void scd_table_regist (usbh_state_handle_struct* pustate, + state_table_struct* pstate_table, + uint8_t table_id, + uint8_t current_table_size) +{ + usbh_state_regist_table_struct *cur_state_reg_table; + + cur_state_reg_table = &pustate->usbh_regist_state_table[pustate->usbh_regist_state_table_num]; + + cur_state_reg_table->id = table_id; + cur_state_reg_table->table = pstate_table; + cur_state_reg_table->table_size = current_table_size; + + pustate->usbh_regist_state_table_num++; +} + +/*! + \brief state core driver begin + \param[in] pustate: pointer to usb state driver + \param[in] table_id: the id of the table to begin + \param[out] none + \retval none +*/ +void scd_begin(usbh_state_handle_struct* pustate, uint8_t table_id) +{ + uint8_t i = 0, table_num = pustate->usbh_regist_state_table_num; + usbh_state_regist_table_struct *cur_state_reg_table; + + for (i = 0; i < table_num; i++) { + cur_state_reg_table = &pustate->usbh_regist_state_table[i]; + + if (table_id == cur_state_reg_table->id) { + pustate->usbh_current_state_table = cur_state_reg_table->table; + pustate->usbh_current_state_table_size = cur_state_reg_table->table_size; + break; + } + } +} + +/*! + \brief state core driver move state + \param[in] pustate: pointer to usb state driver + \param[in] state: the state to move + \param[out] none + \retval none +*/ +void scd_state_move(usbh_state_handle_struct* pustate, uint8_t state) +{ + pustate->usbh_current_state = state; +} + +/*! + \brief state core driver event handle + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[in] event: the current event + \param[in] state: the current state + \param[out] none + \retval host status +*/ +usbh_status_enum scd_event_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct* pustate, + uint8_t event, + uint8_t state) +{ + uint8_t i = 0; + ACT_FUN event_act_fun = NULL; + state_table_struct *backup_state_t = pustate->usbh_current_state_table; + state_table_struct *executive_state_table = pustate->usbh_current_state_table; + + /* look up the table to find the action function */ + for (i = 0; i < pustate->usbh_current_state_table_size; i++) { + if (state == executive_state_table->cur_state) { + if (event == executive_state_table->cur_event) { + state = executive_state_table->next_state; + event_act_fun = executive_state_table->event_action_fun; + break; + } else { + executive_state_table++; + } + } else { + executive_state_table++; + } + } + + pustate->usbh_current_state_table = backup_state_t; + + /* if the action function is not NULL, execute the action function */ + if (event_act_fun) { + if (event_act_fun == &only_state_move) { + pustate->usbh_current_state = state; + } else { + return event_act_fun(pudev, puhost, pustate); + } + } + + return USBH_BUSY; +} + +/*! + \brief state core driver table push + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +void scd_table_push(usbh_state_handle_struct* pustate) +{ + usbh_state_stack_struct *top_state_element; + + if (pustate->usbh_current_state_stack_top < MAX_USBH_STATE_STACK_DEEP) { + pustate->usbh_current_state_stack_top++; + + top_state_element = &pustate->stack[pustate->usbh_current_state_stack_top]; + + /* put the current state table into the state stack */ + top_state_element->state = pustate->usbh_current_state; + top_state_element->table = pustate->usbh_current_state_table; + top_state_element->table_size = pustate->usbh_current_state_table_size; + } +} + +/*! + \brief state core driver table pop + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +void scd_table_pop (usbh_state_handle_struct* pustate) +{ + usbh_state_stack_struct *top_state_element; + + top_state_element = &pustate->stack[pustate->usbh_current_state_stack_top]; + + if (pustate->usbh_current_state_stack_top > -1) { + /* get the current state table from the state stack */ + pustate->usbh_current_state = top_state_element->state; + pustate->usbh_current_state_table = top_state_element->table; + pustate->usbh_current_state_table_size = top_state_element->table_size; + pustate->usbh_current_state_stack_top--; + } +} +/*! + \brief the polling function of class req state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval host status +*/ +static usbh_status_enum class_req_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate) +{ + return class_polling_cb.class_req_polling(pudev, puhost, pustate); +} + +/*! + \brief the polling function of class state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval host status +*/ +static usbh_status_enum class_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate) +{ + return class_polling_cb.class_polling(pudev, puhost, pustate); +} + +/*! + \brief the function is only used to state move + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +usbh_status_enum only_state_move (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate) +{ + return USBH_OK; +} + +/*! + \brief the function to the up state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +usbh_status_enum goto_up_state_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate) +{ + scd_table_pop((usbh_state_handle_struct *)pustate); + + return USBH_OK; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_ctrl.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_ctrl.c new file mode 100644 index 0000000000..b61484053e --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_ctrl.c @@ -0,0 +1,620 @@ +/*! + \file usbh_ctrl.c + \brief this file implements the functions for the control transmit process +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ +#include "usbh_core.h" +#include "usbh_std.h" +#include "usbh_ctrl.h" + +uint8_t ctrl_polling_handle_flag = 0U; +uint8_t ctrl_setup_wait_flag = 0U; +uint8_t ctrl_data_wait_flag = 0U; +uint8_t ctrl_status_wait_flag = 0U; + +static uint16_t timeout = 0U; + +static void ctrl_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void ctrl_setup_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void ctrl_data_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void ctrl_status_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void ctrl_error_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void ctrl_stalled_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void ctrl_complete_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); + +/* the ctrl state handle function array */ +void (*ctrl_state_handle[]) (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) = +{ + ctrl_idle_handle, + ctrl_setup_handle, + ctrl_data_handle, + ctrl_status_handle, + ctrl_error_handle, + ctrl_stalled_handle, + ctrl_complete_handle, +}; + +/* the ctrl state handle table */ +state_table_struct ctrl_handle_table[CTRL_HANDLE_TABLE_SIZE] = +{ + /* the current state the current event the next state the event function */ + {CTRL_IDLE, CTRL_EVENT_SETUP, CTRL_SETUP, only_state_move }, + {CTRL_SETUP, CTRL_EVENT_DATA, CTRL_DATA, only_state_move }, + {CTRL_SETUP, CTRL_EVENT_STATUS, CTRL_STATUS, only_state_move }, + {CTRL_SETUP, CTRL_EVENT_ERROR, CTRL_ERROR, only_state_move }, + {CTRL_DATA, CTRL_EVENT_STATUS, CTRL_STATUS, only_state_move }, + {CTRL_DATA, CTRL_EVENT_ERROR, CTRL_ERROR, only_state_move }, + {CTRL_DATA, CTRL_EVENT_STALLED, CTRL_STALLED, only_state_move }, + {CTRL_STATUS, CTRL_EVENT_COMPLETE, CTRL_COMPLETE, only_state_move }, + {CTRL_STATUS, CTRL_EVENT_ERROR, CTRL_ERROR, only_state_move }, + {CTRL_STATUS, CTRL_EVENT_STALLED, CTRL_STALLED, only_state_move }, + {CTRL_ERROR, GO_TO_UP_STATE_EVENT, UP_STATE, goto_up_state_fun }, + {CTRL_STALLED, GO_TO_UP_STATE_EVENT, UP_STATE, goto_up_state_fun }, + {CTRL_COMPLETE, GO_TO_UP_STATE_EVENT, UP_STATE, goto_up_state_fun }, +}; + +/*! + \brief the polling function of CTRL state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +usbh_status_enum ctrl_state_polling_fun (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + void *pustate) +{ + usbh_status_enum exe_state = USBH_BUSY; + usbh_state_handle_struct *p_state; + + p_state = (usbh_state_handle_struct *)pustate; + + /* if first enter this function, begin the ctrl state */ + if (0U == ctrl_polling_handle_flag) { + ctrl_polling_handle_flag = 1U; + scd_table_push(p_state); + scd_state_move(p_state, CTRL_IDLE); + } + + /* base on the current state to handle the ctrl state */ + scd_begin(p_state, CTRL_FSM_ID); + ctrl_state_handle[p_state->usbh_current_state](pudev, puhost, p_state); + + /* determine the control transfer whether to complete */ + switch (puhost->usbh_backup_state.ctrl_backup_state) { + case CTRL_COMPLETE: + ctrl_polling_handle_flag = 0U; + puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE; + exe_state = USBH_OK; + break; + case CTRL_STALLED: + ctrl_polling_handle_flag = 0U; + puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE; + exe_state = USBH_NOT_SUPPORTED; + break; + case CTRL_ERROR: + ctrl_polling_handle_flag = 0U; + puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE; + exe_state = USBH_FAIL; + break; + default: + exe_state = USBH_BUSY; + break; + } + + return exe_state; +} + +/*! + \brief the handle function of CTRL_IDLE state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void ctrl_idle_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.ctrl_backup_state = CTRL_IDLE; + scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_SETUP, pustate->usbh_current_state); +} + +/*! + \brief the handle function of CTRL_SETUP state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void ctrl_setup_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + urb_state_enum urb_status = URB_IDLE; + puhost->usbh_backup_state.ctrl_backup_state = CTRL_SETUP; + + if (0U == ctrl_setup_wait_flag) { + ctrl_setup_wait_flag = 1U; + + /* send a setup packet */ + usbh_ctltx_setup (pudev, + puhost->control.setup.data, + puhost->control.hc_out_num); + } else { + urb_status = hcd_urb_state_get(pudev, puhost->control.hc_out_num); + + /* case setup packet sent successfully */ + if (URB_DONE == urb_status) { + /* check if there is a data stage */ + if (0U != puhost->control.setup.b.wLength) { + ctrl_setup_wait_flag = 0U; + timeout = DATA_STAGE_TIMEOUT; + scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_DATA, pustate->usbh_current_state); + /* no data stage */ + } else { + timeout = NODATA_STAGE_TIMEOUT; + ctrl_setup_wait_flag = 0U; + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_STATUS, + pustate->usbh_current_state); + } + + /* set the delay timer to enable timeout for data stage completion */ + puhost->control.timer = (uint16_t)USB_CURRENT_FRAME_GET(); + } else if (URB_ERROR == urb_status) { + ctrl_setup_wait_flag = 0U; + scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_ERROR, pustate->usbh_current_state); + } else { + /* no operation */ + } + } +} + +/*! + \brief the handle function of CTRL_DATA state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void ctrl_data_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + uint8_t direction; + urb_state_enum urb_status = URB_IDLE; + puhost->usbh_backup_state.ctrl_backup_state = CTRL_DATA; + + direction = (puhost->control.setup.b.bmRequestType & USB_DIR_MASK); + + if (USB_DIR_IN == direction) { + if (0U == ctrl_data_wait_flag) { + ctrl_data_wait_flag = 1U; + + /* issue an IN token */ + usbh_xfer(pudev, + puhost->control.buff, + puhost->control.hc_in_num, + puhost->control.length); + } else { + urb_status = hcd_urb_state_get(pudev, puhost->control.hc_in_num); + + /* check is data packet transfered successfully */ + switch (urb_status) { + case URB_DONE: + ctrl_data_wait_flag = 0U; + + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_STATUS, + pustate->usbh_current_state); + break; + case URB_STALL: + ctrl_data_wait_flag = 0U; + + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_STALLED, + pustate->usbh_current_state); + break; + case URB_ERROR: + ctrl_data_wait_flag = 0U; + + /* device error */ + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_ERROR, + pustate->usbh_current_state); + break; + default: + if (((uint16_t)USB_CURRENT_FRAME_GET() - puhost->control.timer) > timeout) { + ctrl_data_wait_flag = 0U; + + /* timeout for IN transfer */ + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_ERROR, + pustate->usbh_current_state); + } + break; + } + } + } else { + if (0U == ctrl_data_wait_flag) { + ctrl_data_wait_flag = 1U; + + /* start DATA out transfer (only one DATA packet)*/ + pudev->host.host_channel[puhost->control.hc_out_num].data_tg_out = 1U; + + usbh_xfer(pudev, + puhost->control.buff, + puhost->control.hc_out_num, + puhost->control.length); + } else { + urb_status = hcd_urb_state_get(pudev, puhost->control.hc_out_num); + + switch (urb_status) { + case URB_DONE: + ctrl_data_wait_flag = 0U; + + /* if the setup pkt is sent successful, then change the state */ + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_STATUS, + pustate->usbh_current_state); + break; + case URB_STALL: + ctrl_data_wait_flag = 0U; + + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_STALLED, + pustate->usbh_current_state); + break; + case URB_NOTREADY: + /* nack received from device */ + ctrl_data_wait_flag = 0U; + break; + case URB_ERROR: + ctrl_data_wait_flag = 0U; + + /* device error */ + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_ERROR, + pustate->usbh_current_state); + break; + default: + break; + } + } + } +} + +/*! + \brief the handle function of CTRL_STATUS state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void ctrl_status_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + uint8_t direction; + urb_state_enum urb_status = URB_IDLE; + + puhost->usbh_backup_state.ctrl_backup_state = CTRL_STATUS; + + /* get the transfer direction in the data state, but the transfer direction in the status state is opposite */ + direction = (puhost->control.setup.b.bmRequestType & USB_DIR_MASK); + + if (USB_DIR_OUT == direction) { + /* handle status in */ + if (0U == ctrl_status_wait_flag) { + ctrl_status_wait_flag = 1U; + usbh_xfer (pudev, 0U, puhost->control.hc_in_num, 0U); + } else { + urb_status = hcd_urb_state_get(pudev, puhost->control.hc_in_num); + + switch (urb_status) { + case URB_DONE: + ctrl_status_wait_flag = 0U; + + /* handle URB_DONE status */ + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_COMPLETE, + pustate->usbh_current_state); + break; + case URB_ERROR: + ctrl_status_wait_flag = 0U; + + /* handle URB_STALL status*/ + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_ERROR, + pustate->usbh_current_state); + break; + case URB_STALL: + ctrl_status_wait_flag = 0U; + + /* handle URB_STALL status */ + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_STALLED, + pustate->usbh_current_state); + break; + default: + if (((uint16_t)USB_CURRENT_FRAME_GET() - puhost->control.timer) > timeout) { + ctrl_status_wait_flag = 0U; + + /* handle timeout */ + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_ERROR, + pustate->usbh_current_state); + } + break; + } + } + } else { + /* handle status out */ + if (0U == ctrl_status_wait_flag) { + ctrl_status_wait_flag = 1U; + pudev->host.host_channel[puhost->control.hc_out_num].data_tg_out ^= 1U; + usbh_xfer (pudev, 0U, puhost->control.hc_out_num, 0U); + + { + uint32_t host_ctlr = 0; + + host_ctlr = USB_HCHxLEN(puhost->control.hc_out_num); + USB_HCHxLEN(puhost->control.hc_out_num) = host_ctlr | 1; + host_ctlr = USB_HCHxCTL(puhost->control.hc_out_num); + USB_HCHxCTL(puhost->control.hc_out_num) = (host_ctlr & 0x3FFFFFFF) | 0x80000000; + } + } else { + urb_status = hcd_urb_state_get(pudev, puhost->control.hc_out_num); + + switch (urb_status) { + case URB_DONE: + ctrl_status_wait_flag = 0U; + + /* handle URB_DONE status */ + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_COMPLETE, + pustate->usbh_current_state); + break; + case URB_NOTREADY: + /* handle URB_NOTREADY status */ + ctrl_status_wait_flag = 0U; + break; + case URB_ERROR: + ctrl_status_wait_flag = 0U; + + /* handle URB_ERROR status */ + scd_event_handle(pudev, + puhost, + pustate, + CTRL_EVENT_ERROR, + pustate->usbh_current_state); + break; + default: + break; + } + } + } +} + +/*! + \brief the handle function of CTRL_ERROR state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void ctrl_error_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.ctrl_backup_state = CTRL_ERROR; + + if (++puhost->control.error_count <= USBH_MAX_ERROR_COUNT) { + /* do the transmission again, starting from SETUP Packet */ + scd_event_handle(pudev, puhost, pustate, CTRL_EVENT_SETUP, pustate->usbh_current_state); + } else { + scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of CTRL_STALLED state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void ctrl_stalled_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.ctrl_backup_state = CTRL_STALLED; + scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state); +} + +/*! + \brief the handle function of CTRL_COMPLETE state + \param[in] pudev: pointer to usb device + \param[in] puhost: pointer to usb host + \param[in] pustate: pointer to usb state driver + \param[out] none + \retval none +*/ +static void ctrl_complete_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.ctrl_backup_state = CTRL_COMPLETE; + scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state); +} + +/*! + \brief send datas from the host channel + \param[in] pudev: pointer to usb device + \param[in] buf: data buffer address to send datas + \param[in] hc_num: the number of the host channel + \param[in] len: length of the send data + \param[out] none + \retval host operation status +*/ +usbh_status_enum usbh_xfer (usb_core_handle_struct *pudev, + uint8_t *buf, + uint8_t hc_num, + uint16_t len) +{ + usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num]; + + puhc->xfer_buff = buf; + puhc->xfer_len = len; + + switch (puhc->endp_type) { + case USB_EPTYPE_CTRL: + if (0U == puhc->endp_in) { + if (0U == len) { + /* for status out stage, length = 0, status out pid = 1 */ + puhc->data_tg_out = 1U; + } + + /* set the data toggle bit as per the flag */ + if (0U == puhc->data_tg_out) { + /* put the pid 0 */ + puhc->DPID = HC_PID_DATA0; + } else { + /* put the pid 1 */ + puhc->DPID = HC_PID_DATA1; + } + } else { + puhc->DPID = HC_PID_DATA1; + } + break; + + case USB_EPTYPE_ISOC: + puhc->DPID = HC_PID_DATA0; + break; + + case USB_EPTYPE_BULK: + if (0U == puhc->endp_in) { + /* set the data toggle bit as per the flag */ + if (0U == puhc->data_tg_out) { + /* put the pid 0 */ + puhc->DPID = HC_PID_DATA0; + } else { + /* put the pid 1 */ + puhc->DPID = HC_PID_DATA1; + } + } else { + if (0U == puhc->data_tg_in) { + puhc->DPID = HC_PID_DATA0; + } else { + puhc->DPID = HC_PID_DATA1; + } + } + break; + + case USB_EPTYPE_INTR: + if (0U == puhc->endp_in) { + if (0U == puhc->data_tg_out) { + puhc->DPID = HC_PID_DATA0; + } else { + puhc->DPID = HC_PID_DATA1; + } + + /* toggle data pid */ + puhc->data_tg_out ^= 1U; + } else { + if (0U == puhc->data_tg_in) { + puhc->DPID = HC_PID_DATA0; + } else { + puhc->DPID = HC_PID_DATA1; + } + + /* toggle data pid */ + puhc->data_tg_in ^= 1U; + } + break; + + default: + break; + } + + hcd_submit_request (pudev, hc_num); + + return USBH_OK; +} + +/*! + \brief send the setup packet to the device + \param[in] pudev: pointer to usb device + \param[in] buf: buffer pointer from which the data will be send to device + \param[in] hc_num: host channel number + \param[out] none + \retval host operation status +*/ +usbh_status_enum usbh_ctltx_setup (usb_core_handle_struct *pudev, uint8_t *buf, uint8_t hc_num) +{ + usb_hostchannel_struct *puhc = &pudev->host.host_channel[hc_num]; + + puhc->DPID = HC_PID_SETUP; + puhc->xfer_buff = buf; + puhc->xfer_len = USBH_SETUP_PACKET_SIZE; + + return (usbh_status_enum)hcd_submit_request (pudev, hc_num); +} + +/*! + \brief this function prepare a hc and start a transfer + \param[in] pudev: pointer to usb device + \param[in] channel_num: host channel number which is in (0..7) + \param[out] none + \retval host operation status +*/ +uint32_t hcd_submit_request (usb_core_handle_struct *pudev, uint8_t channel_num) +{ + usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num]; + + puhc->urb_state = URB_IDLE; + puhc->xfer_count = 0U; + + return (uint32_t)usb_hostchannel_startxfer(pudev, channel_num); +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_hcs.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_hcs.c new file mode 100644 index 0000000000..035459d195 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_hcs.c @@ -0,0 +1,162 @@ +/*! + \file usbh_hcs.c + \brief this file implements functions for opening and closing host channels +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.0, firmware for GD32F4xx +*/ + +#include "usbh_hcs.h" + +static uint16_t usbh_freechannel_get (usb_core_handle_struct *pudev); + +/*! + \brief open a channel + \param[in] pudev: pointer to usb device + \param[in] channel_num: host channel number which is in (0..7) + \param[in] dev_addr: USB device address allocated to attached device + \param[in] dev_speed: USB device speed (Full speed/Low speed) + \param[in] ep_type: endpoint type (bulk/int/ctl) + \param[in] ep_mps: max packet size + \param[out] none + \retval operation status +*/ +uint8_t usbh_channel_open (usb_core_handle_struct *pudev, + uint8_t channel_num, + uint8_t dev_addr, + uint8_t dev_speed, + uint8_t ep_type, + uint16_t ep_mps) +{ + usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num]; + uint16_t channel_info = puhc->info; + + puhc->endp_id = (uint8_t)channel_info & 0x7FU; + puhc->endp_in = (uint8_t)(channel_info & 0x80U) >> 7; + puhc->endp_type = ep_type; + puhc->endp_mps = ep_mps; + puhc->dev_addr = dev_addr; + puhc->dev_speed = dev_speed; + + puhc->data_tg_in = 0U; + puhc->data_tg_out = 0U; + + if (HPRT_PRTSPD_HIGH_SPEED == dev_speed) { + puhc->do_ping = 1U; + } + + usb_hostchannel_init(pudev, channel_num); + + return (uint8_t)HC_OK; +} + +/*! + \brief modify a channel + \param[in] pudev: pointer to usb device + \param[in] channel_num: host channel number which is in (0..7) + \param[in] dev_addr: USB Device address allocated to attached device + \param[in] dev_speed: USB device speed (Full speed/Low speed) + \param[in] ep_type: endpoint type (bulk/int/ctl) + \param[in] ep_mps: max packet size + \param[out] none + \retval operation status +*/ +uint8_t usbh_channel_modify (usb_core_handle_struct *pudev, + uint8_t channel_num, + uint8_t dev_addr, + uint8_t dev_speed, + uint8_t ep_type, + uint16_t ep_mps) +{ + usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num]; + + if (0U != dev_addr) { + puhc->dev_addr = dev_addr; + } + + if ((puhc->endp_mps != ep_mps) && (0U != ep_mps)) { + puhc->endp_mps = ep_mps; + } + + if ((puhc->dev_speed != dev_speed) && (0U != dev_speed)) { + puhc->dev_speed = dev_speed; + } + + usb_hostchannel_init(pudev, channel_num); + + return (uint8_t)HC_OK; +} + +/*! + \brief allocate a new channel for the pipe + \param[in] pudev: pointer to usb device + \param[in] ep_addr: endpoint for which the channel to be allocated + \param[out] none + \retval host channel number +*/ +uint8_t usbh_channel_alloc (usb_core_handle_struct *pudev, uint8_t ep_addr) +{ + uint16_t hc_num = usbh_freechannel_get(pudev); + + if ((uint16_t)HC_ERROR != hc_num) { + pudev->host.host_channel[hc_num].info = HC_USED | ep_addr; + } + + return (uint8_t)hc_num; +} + +/*! + \brief free the usb host channel + \param[in] pudev: pointer to usb device + \param[in] index: channel number to be freed which is in (0..7) + \param[out] none + \retval host operation status +*/ +uint8_t usbh_channel_free (usb_core_handle_struct *pudev, uint8_t index) +{ + if (index < HC_MAX) { + pudev->host.host_channel[index].info &= HC_USED_MASK; + } + + return USBH_OK; +} + +/*! + \brief free all usb host channel + \param[in] pudev: pointer to usb device + \param[out] none + \retval host operation status +*/ +uint8_t usbh_allchannel_dealloc (usb_core_handle_struct *pudev) +{ + uint8_t index; + + for (index = 2U; index < HC_MAX; index ++) { + pudev->host.host_channel[index].info = 0U; + } + + return USBH_OK; +} + +/*! + \brief get a free channel number for allocation to a device endpoint + \param[in] pudev: pointer to usb device + \param[out] none + \retval free channel number +*/ +static uint16_t usbh_freechannel_get (usb_core_handle_struct *pudev) +{ + uint8_t index = 0U; + + for (index = 0U; index < HC_MAX; index++) { + if (0U == (pudev->host.host_channel[index].info & HC_USED)) { + return (uint16_t)index; + } + } + + return HC_ERROR; +} + diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_int.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_int.c new file mode 100644 index 0000000000..a386d185ed --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_int.c @@ -0,0 +1,591 @@ +/*! + \file usbh_int.c + \brief USB host mode interrupt handler file +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.1, firmware for GD32F4xx +*/ + +#include "usb_core.h" +#include "usb_defines.h" +#include "usbh_int.h" + +static uint32_t usbh_intf_sof (usb_core_handle_struct *pudev); +static uint32_t usbh_intf_port (usb_core_handle_struct *pudev); +static uint32_t usbh_intf_hc (usb_core_handle_struct *pudev); +static uint32_t usbh_intf_hc_in (usb_core_handle_struct *pudev, uint8_t channel_num); +static uint32_t usbh_intf_hc_out (usb_core_handle_struct *pudev, uint8_t channel_num); +static uint32_t usbh_intf_rxfifo_noempty (usb_core_handle_struct *pudev); +static uint32_t usbh_intf_nptxfifo_empty (usb_core_handle_struct *pudev); +static uint32_t usbh_intf_ptxfifo_empty (usb_core_handle_struct *pudev); +static uint32_t usbh_intf_disconnect (usb_core_handle_struct *pudev); +static uint32_t usbh_intf_iso_incomplete_xfer (usb_core_handle_struct *pudev); + +/*! + \brief handle global host interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +uint32_t usbh_isr (usb_core_handle_struct *pudev) +{ + uint32_t retval = 0U; + uint32_t int_flag = 0U; + + /* check if host mode */ + if (USB_CURRENT_MODE_GET() == HOST_MODE) { + USB_CORE_INTR_READ(int_flag); + + if (!int_flag) { + return 0U; + } + + /* start of frame interrupt handle */ + if (int_flag & GINTF_SOF) { + retval |= usbh_intf_sof (pudev); + } + + /* Rx FIFO non-empty interrupt handle */ + if (int_flag & GINTF_RXFNEIF) { + retval |= usbh_intf_rxfifo_noempty (pudev); + } + + /* Non-Periodic Tx FIFO empty interrupt hanlde */ + if (int_flag & GINTF_NPTXFEIF) { + retval |= usbh_intf_nptxfifo_empty (pudev); + } + + /* periodic Tx FIFO empty interrupt handle */ + if (int_flag & GINTF_PTXFEIF) { + retval |= usbh_intf_ptxfifo_empty (pudev); + } + + /* host channels interrupt handle */ + if (int_flag & GINTF_HCIF) { + retval |= usbh_intf_hc (pudev); + } + + /* host port interrupt handle */ + if (int_flag & GINTF_HPIF) { + retval |= usbh_intf_port (pudev); + } + + /* disconnect interrupt handle */ + if (int_flag & GINTF_DISCIF) { + retval |= usbh_intf_disconnect (pudev); + } + + /* isochronous IN transfer not complete interrupt handle */ + if (int_flag & GINTF_ISOONCIF) { + retval |= usbh_intf_iso_incomplete_xfer (pudev); + } + } + + return retval; +} + +/*! + \brief handle the start-of-frame interrupt in host mode + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbh_intf_sof (usb_core_handle_struct *pudev) +{ + usbh_hcd_int_fops->sof(pudev); + + /* clear interrupt */ + USB_GINTF = GINTF_SOF; + + return 1U; +} + +/*! + \brief handle all host channels interrupt in host mode + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbh_intf_hc (usb_core_handle_struct *pudev) +{ + uint8_t i = 0U; + uint32_t retval = 0U; + + for (i = 0U; i < pudev->cfg.host_channel_num; i++) { + if ((USB_HACHINT & HACHINT_HACHINT) & ((uint32_t)1U << i)) { + if ((USB_HCHxCTL((uint16_t)i) & HCHCTL_EPDIR) >> 15U) { + retval |= usbh_intf_hc_in (pudev, i); + } else { + retval |= usbh_intf_hc_out (pudev, i); + } + } + } + + return retval; +} + +/*! + \brief handle the disconnect interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbh_intf_disconnect (usb_core_handle_struct *pudev) +{ + usbh_hcd_int_fops->device_disconnected(pudev); + + /* clear interrupt */ + USB_GINTF = GINTF_DISCIF; + + return 1U; +} + +/*! + \brief handle the non-periodic tx fifo empty interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbh_intf_nptxfifo_empty (usb_core_handle_struct *pudev) +{ + uint8_t channel_num = 0U; + uint32_t dword_len = 0U, len = 0U; + usb_hostchannel_struct *puhc; + + channel_num = (uint8_t)((USB_HNPTFQSTAT & HNPTFQSTAT_CNUM) >> 27U); + puhc = &pudev->host.host_channel[channel_num]; + dword_len = (puhc->xfer_len + 3U) / 4U; + + while (((USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS) > dword_len) && (0U != puhc->xfer_len)) { + len = (USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS) * 4U; + + if (len > puhc->xfer_len) { + /* last packet */ + len = (uint16_t)puhc->xfer_len; + + USB_GINTEN &= ~GINTF_NPTXFEIF; + + } + + dword_len = (puhc->xfer_len + 3U) / 4U; + usb_fifo_write (puhc->xfer_buff, channel_num, (uint16_t)len); + + puhc->xfer_buff += len; + puhc->xfer_len -= len; + puhc->xfer_count += len; + } + + return 1U; +} + +/*! + \brief handle the periodic tx fifo empty interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbh_intf_ptxfifo_empty (usb_core_handle_struct *pudev) +{ + uint8_t channel_num = 0U; + uint32_t dword_len = 0U, len = 0U; + usb_hostchannel_struct *puhc; + + channel_num = (uint8_t)((USB_HPTFQSTAT & HPTFQSTAT_CNUM) >> 27U); + puhc = &pudev->host.host_channel[channel_num]; + dword_len = (puhc->xfer_len + 3U) / 4U; + + while (((USB_HPTFQSTAT & HPTFQSTAT_PTXFS) > dword_len) && (0U != puhc->xfer_len)) { + len = (USB_HPTFQSTAT & HPTFQSTAT_PTXFS) * 4U; + + if (len > puhc->xfer_len) { + len = puhc->xfer_len; + + /* last packet */ + USB_GINTEN &= ~GINTF_PTXFEIF; + } + + dword_len = (puhc->xfer_len + 3U) / 4U; + usb_fifo_write (puhc->xfer_buff, channel_num, (uint16_t)len); + + puhc->xfer_buff += len; + puhc->xfer_len -= len; + puhc->xfer_count += len; + } + + return 1U; +} + +/*! + \brief handle the host port interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbh_intf_port (usb_core_handle_struct *pudev) +{ + uint8_t port_speed = 0U; + uint8_t port_reset = 0U; + uint32_t retval = 0U; + __IO uint32_t hostportdup = USB_HPCS; + + /* clear the interrupt bits in gintsts */ + hostportdup &= ~HPCS_PE; + hostportdup &= ~HPCS_PCD; + hostportdup &= ~HPCS_PEDC; + + /* port connect detected */ + if (USB_HPCS & HPCS_PCD) { + hostportdup |= HPCS_PCD; + usbh_hcd_int_fops->device_connected(pudev); + retval |= 1U; + } + + /* port enable changed */ + if (USB_HPCS & HPCS_PEDC) { + hostportdup |= HPCS_PEDC; + + if (USB_HPCS & HPCS_PE) { + port_speed = (uint8_t)((USB_HPCS & HPCS_PS) >> 17U); + + if (HPRT_PRTSPD_LOW_SPEED == port_speed) { + USB_HFT = 6000U; + + if (HCTLR_6_MHZ != (USB_HCTL & HCTL_CLKSEL)) { + if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) { + USB_FSLSCLOCK_INIT(HCTLR_6_MHZ); + } + port_reset = 1U; + } + } else if(HPRT_PRTSPD_FULL_SPEED == port_speed) { + USB_HFT = 48000U; + + if (HCTLR_48_MHZ != (USB_HCTL & HCTL_CLKSEL)) { + if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) { + USB_FSLSCLOCK_INIT(HCTLR_48_MHZ); + } + port_reset = 1U; + } + } else { + /* for high speed device and others */ + port_reset = 1U; + } + + + } + } + + if (port_reset) { + usb_port_reset(pudev); + } + + /* clear port interrupts */ + USB_HPCS = hostportdup; + + return retval; +} + +/*! + \brief handle the OUT channel interrupt + \param[in] pudev: pointer to usb device instance + \param[in] channel_num: host channel number which is in (0..7) + \param[out] none + \retval operation status +*/ +static uint32_t usbh_intf_hc_out (usb_core_handle_struct *pudev, uint8_t channel_num) +{ + uint32_t channel_intr = USB_HCHxINTF((uint16_t)channel_num); + usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num]; + + channel_intr &= USB_HCHxINTEN((uint16_t)channel_num); + + if (channel_intr & HCHINTF_ACK) { + if (URB_PING == puhc->urb_state) { + puhc->err_count = 0U; + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + usb_hostchannel_halt(pudev, channel_num); + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF; + puhc->status = HC_XF; + } + + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_ACK; + } else if (channel_intr & HCHINTF_REQOVR) { + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + usb_hostchannel_halt(pudev, channel_num); + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_REQOVR; + } else if (channel_intr & HCHINTF_TF) { + puhc->err_count = 0U; + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + usb_hostchannel_halt(pudev, channel_num); + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF; + puhc->status = HC_XF; + } else if (channel_intr & HCHINTF_STALL) { + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_STALL; + usb_hostchannel_halt(pudev, channel_num); + puhc->status = HC_STALL; + } else if (channel_intr & HCHINTF_NAK) { + puhc->err_count = 0U; + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + usb_hostchannel_halt(pudev, channel_num); + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK; + puhc->status = HC_NAK; + } else if (channel_intr & HCHINTF_USBER) { + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + usb_hostchannel_halt(pudev, channel_num); + puhc->err_count ++; + puhc->status = HC_TRACERR; + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_USBER; + } else if (channel_intr & HCHINTF_NYET) { + puhc->err_count = 0U; + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + puhc->status = HC_NYET; + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NYET; + } else if (channel_intr & HCHINTF_DTER) { + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + usb_hostchannel_halt(pudev, channel_num); + puhc->status= HC_DTGERR; + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_DTER; + } else if (channel_intr & HCHINTF_CH) { + USB_HCHxINTEN((uint16_t)channel_num) &= ~HCHINTEN_CHIE; + + switch (puhc->status) { + case HC_XF: + puhc->urb_state = URB_DONE; + + if (USB_EPTYPE_BULK == ((USB_HCHxCTL((uint16_t)channel_num) & HCHCTL_EPTYPE) >> 18)) { + puhc->data_tg_out ^= 1U; + } + break; + case HC_NAK: + if (URB_PING == puhc->urb_state) { + usb_hostchannel_ping(pudev, channel_num); + } else { + puhc->urb_state = URB_NOTREADY; + } + break; + case HC_NYET: + if (1U == puhc->do_ping) { + usb_hostchannel_ping(pudev, channel_num); + puhc->urb_state = URB_PING; + } + break; + case HC_STALL: + puhc->urb_state = URB_STALL; + break; + case HC_TRACERR: + if (3U == puhc->err_count) { + puhc->urb_state = URB_ERROR; + puhc->err_count = 0U; + } + break; + default: + break; + } + + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_CH; + } else { + /* no operation */ + } + + return 1U; +} + +/*! + \brief handle the IN channel interrupt + \param[in] pudev: pointer to usb device instance + \param[in] channel_num: host channel number which is in (0..7) + \param[out] none + \retval operation status +*/ +static uint32_t usbh_intf_hc_in (usb_core_handle_struct *pudev, uint8_t channel_num) +{ + uint8_t endp_type = 0U; + usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num]; + + uint32_t channle_intf = USB_HCHxINTF((uint16_t)channel_num); + __IO uint32_t channel_ctrl = USB_HCHxCTL((uint16_t)channel_num); + + channle_intf &= USB_HCHxINTEN((uint16_t)channel_num); + + endp_type = (uint8_t)((channel_ctrl & HCHCTL_EPTYPE) >> 18U); + + if (channle_intf & HCHINTF_ACK) { + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_ACK; + } else if (channle_intf & HCHINTF_STALL) { + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + puhc->status = HC_STALL; + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK; + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_STALL; + + /* NOTE: When there is a 'stall', reset also nak, + else, the pudev->host.status = HC_STALL + will be overwritten by 'nak' in code below */ + channle_intf &= ~HCHINTF_NAK; + + usb_hostchannel_halt(pudev, channel_num); + } else if (channle_intf & HCHINTF_DTER) { + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + usb_hostchannel_halt(pudev, channel_num); + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK; + puhc->status = HC_DTGERR; + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_DTER; + } else { + /* no operation */ + } + + if (channle_intf & HCHINTF_REQOVR) { + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + usb_hostchannel_halt(pudev, channel_num); + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_REQOVR; + } else if (channle_intf & HCHINTF_TF) { + if (pudev->cfg.dma_enable == 1U) { + uint32_t xfer_size = USB_HCHxLEN((uint16_t)channel_num) & HCHLEN_TLEN; + puhc->xfer_count = puhc->xfer_len - xfer_size; + } + + puhc->status = HC_XF; + puhc->err_count = 0U; + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF; + + if ((USB_EPTYPE_CTRL == endp_type) || (USB_EPTYPE_BULK == endp_type)) { + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + usb_hostchannel_halt(pudev, channel_num); + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK; + puhc->data_tg_in ^= 1U; + } else if (USB_EPTYPE_INTR == endp_type) { + channel_ctrl |= HCHCTL_ODDFRM; + USB_HCHxCTL((uint16_t)channel_num) = channel_ctrl; + puhc->urb_state = URB_DONE; + } else { + /* no operation */ + } + } else if (channle_intf & HCHINTF_CH) { + USB_HCHxINTEN((uint16_t)channel_num) &= ~HCHINTEN_CHIE; + + switch (puhc->status) { + case HC_XF: + puhc->urb_state = URB_DONE; + break; + case HC_TRACERR: + case HC_DTGERR: + puhc->err_count = 0U; + puhc->urb_state = URB_ERROR; + break; + case HC_STALL: + puhc->urb_state = URB_STALL; + break; + default: + if (USB_EPTYPE_INTR == endp_type) { + puhc->data_tg_in ^= 1U; + } + break; + } + + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_CH; + } else if (channle_intf & HCHINTF_USBER) { + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + (puhc->err_count)++; + puhc->status = HC_TRACERR; + usb_hostchannel_halt(pudev, channel_num); + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_USBER; + } else if (channle_intf & HCHINTF_NAK) { + if (USB_EPTYPE_INTR == endp_type) { + USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE; + usb_hostchannel_halt(pudev, channel_num); + } else if ((USB_EPTYPE_CTRL == endp_type) || (USB_EPTYPE_BULK == endp_type)) { + /* re-activate the channel */ + channel_ctrl |= HCHCTL_CEN; + channel_ctrl &= ~HCHCTL_CDIS; + USB_HCHxCTL((uint16_t)channel_num) = channel_ctrl; + } else { + /* no operation */ + } + + puhc->status = HC_NAK; + USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK; + } else { + /* no operation */ + } + + return 1U; +} + +/*! + \brief handle the rx fifo non-empty interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbh_intf_rxfifo_noempty (usb_core_handle_struct *pudev) +{ + uint32_t count = 0U; + __IO uint8_t channel_num = 0U; + __IO uint32_t rx_status = 0U; + uint32_t usbh_ch_ctl_reg = 0U; + usb_hostchannel_struct *puhc; + + /* disable the Rx status queue level interrupt */ + USB_GINTEN &= ~GINTF_RXFNEIF; + + rx_status = USB_GRSTATP; + channel_num = (uint8_t)(rx_status & GRSTATR_CNUM); + puhc = &pudev->host.host_channel[channel_num]; + + switch ((rx_status & GRSTATR_RPCKST) >> 17) { + case GRSTATR_RPCKST_IN: + count = (rx_status & GRSTATR_BCOUNT) >> 4; + + /* read the data into the host buffer. */ + if ((count > 0U) && (puhc->xfer_buff != (void *)0)) { + usb_fifo_read(puhc->xfer_buff, (uint16_t)count); + + /* manage multiple Xfer */ + puhc->xfer_buff += count; + puhc->xfer_count += count; + + if (USB_HCHxLEN((uint16_t)channel_num) & HCHLEN_PCNT) { + /* re-activate the channel when more packets are expected */ + usbh_ch_ctl_reg = USB_HCHxCTL((uint16_t)channel_num); + usbh_ch_ctl_reg |= HCHCTL_CEN; + usbh_ch_ctl_reg &= ~HCHCTL_CDIS; + USB_HCHxCTL((uint16_t)channel_num) = usbh_ch_ctl_reg; + } + } + break; + case GRSTATR_RPCKST_IN_XFER_COMP: + case GRSTATR_RPCKST_DATA_TOGGLE_ERR: + case GRSTATR_RPCKST_CH_HALTED: + default: + break; + } + + /* enable the Rx status queue level interrupt */ + USB_GINTEN |= GINTF_RXFNEIF; + + return 1U; +} + +/*! + \brief handle the incomplete periodic transfer interrupt + \param[in] pudev: pointer to usb device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbh_intf_iso_incomplete_xfer (usb_core_handle_struct *pudev) +{ + __IO uint32_t gint_flag = 0U; + + gint_flag = USB_HCHxCTL(0U); + USB_HCHxCTL(0U) = 0U; + + gint_flag = 0U; + + /* clear interrupt */ + gint_flag |= GINTF_ISOONCIF; + USB_GINTF = gint_flag; + + return 1U; +} diff --git a/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_std.c b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_std.c new file mode 100644 index 0000000000..57f9e996a4 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/GD32F4xx_usb_driver/Source/usbh_std.c @@ -0,0 +1,808 @@ +/*! + \file usbh_std.c + \brief USB 2.0 standard function definition +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-08-15, V1.0.1, firmware for GD32F4xx +*/ + +#include "usbh_core.h" +#include "usbh_usr.h" +#include "usbh_std.h" +#include "usbh_ctrl.h" + +uint8_t local_buffer[64]; +uint8_t usbh_cfg_desc[512]; +uint8_t enum_polling_handle_flag = 0U; + +static void enum_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void enum_get_full_dev_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void enum_set_addr_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void enum_get_cfg_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void enum_get_full_cfg_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void enum_get_mfc_string_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void enum_get_product_string_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void enum_get_serialnum_string_desc_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void enum_set_configuration_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); +static void enum_dev_configured_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate); + +/* the enumeration state handle function array */ +void (*enum_state_handle[]) (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate) = +{ + enum_idle_handle, + enum_set_addr_handle, + enum_get_full_dev_desc_handle, + enum_get_cfg_desc_handle, + enum_get_full_cfg_desc_handle, + enum_get_mfc_string_desc_handle, + enum_get_product_string_desc_handle, + enum_get_serialnum_string_desc_handle, + enum_set_configuration_handle, + enum_dev_configured_handle, +}; + +/* the enumeration state handle table */ +state_table_struct enum_handle_table[ENUM_HANDLE_TABLE_SIZE] = +{ + /* the current state the current event the next state the event function */ + {ENUM_IDLE, ENUM_EVENT_SET_ADDR, ENUM_SET_ADDR, only_state_move }, + {ENUM_SET_ADDR, ENUN_EVENT_GET_FULL_DEV_DESC, ENUM_GET_FULL_DEV_DESC, only_state_move }, + {ENUM_GET_FULL_DEV_DESC, ENUN_EVENT_GET_CFG_DESC, ENUM_GET_CFG_DESC, only_state_move }, + {ENUM_GET_CFG_DESC, ENUN_EVENT_GET_FULL_CFG_DESC, ENUM_GET_FULL_CFG_DESC, only_state_move }, + {ENUM_GET_FULL_CFG_DESC, ENUN_EVENT_GET_MFC_STRING_DESC, ENUM_GET_MFC_STRING_DESC, only_state_move }, + {ENUM_GET_MFC_STRING_DESC, ENUN_EVENT_GET_PRODUCT_STRING_DESC, ENUM_GET_PRODUCT_STRING_DESC, only_state_move }, + {ENUM_GET_PRODUCT_STRING_DESC, ENUN_EVENT_GET_SERIALNUM_STRING_DESC, ENUM_GET_SERIALNUM_STRING_DESC, only_state_move }, + {ENUM_GET_SERIALNUM_STRING_DESC, ENUN_EVENT_SET_CONFIGURATION, ENUM_SET_CONFIGURATION, only_state_move }, + {ENUM_SET_CONFIGURATION, ENUN_EVENT_DEV_CONFIGURED, ENUM_DEV_CONFIGURED, only_state_move }, + {ENUM_DEV_CONFIGURED, GO_TO_UP_STATE_EVENT, UP_STATE, goto_up_state_fun }, +}; + +/*! + \brief the polling function of enumeration state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval usb host status +*/ +usbh_status_enum enum_state_polling_fun (usb_core_handle_struct *pudev, usbh_host_struct *puhost, void *pustate) +{ + usbh_status_enum exe_state = USBH_BUSY; + usbh_state_handle_struct *p_state; + p_state = (usbh_state_handle_struct *)pustate; + + if (0U == enum_polling_handle_flag) { + enum_polling_handle_flag = 1U; + scd_table_push(p_state); + scd_state_move(p_state, ENUM_IDLE); + } + + /* start the enumeration state handle */ + scd_begin(p_state,ENUM_FSM_ID); + + if (0U == p_state->usbh_current_state_stack_top) { + enum_state_handle[p_state->usbh_current_state](pudev, puhost, p_state); + } else { + enum_state_handle[p_state->stack[1].state](pudev, puhost, p_state); + } + + /* determine the enumeration whether to complete */ + if (ENUM_DEV_CONFIGURED == puhost->usbh_backup_state.enum_backup_state) { + puhost->usbh_backup_state.enum_backup_state = ENUM_IDLE; + enum_polling_handle_flag = 0U; + exe_state = USBH_OK; + } + + return exe_state; +} + +/*! + \brief the handle function of ENUM_IDLE state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval none +*/ +static void enum_idle_handle (usb_core_handle_struct *pudev, usbh_host_struct *puhost, usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.enum_backup_state = ENUM_IDLE; + + if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) { + usbh_enum_desc_get(pudev, + puhost, + pudev->host.rx_buffer, + USB_REQTYPE_DEVICE | USB_STANDARD_REQ, + USB_DEVDESC, + 8U); + if ((void *)0 != pudev->mdelay) { + pudev->mdelay(100U); + } + } + + if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) { + usbh_device_desc_parse(&puhost->device.dev_desc, pudev->host.rx_buffer, 8U); + puhost->control.ep0_size = puhost->device.dev_desc.bMaxPacketSize0; + + /* issue reset */ + usb_port_reset(pudev); + + /* modify control channels configuration for maxpacket size */ + usbh_channel_modify (pudev, + puhost->control.hc_out_num, + 0U, + 0U, + 0U, + (uint16_t)puhost->control.ep0_size); + + usbh_channel_modify (pudev, + puhost->control.hc_in_num, + 0U, + 0U, + 0U, + (uint16_t)puhost->control.ep0_size); + + scd_event_handle(pudev, + puhost, + pustate, + ENUM_EVENT_SET_ADDR, + pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of ENUM_GET_FULL_DEV_DESC state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval none +*/ +static void enum_get_full_dev_desc_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.enum_backup_state = ENUM_GET_FULL_DEV_DESC; + + if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) { + usbh_enum_desc_get(pudev, + puhost, + pudev->host.rx_buffer, + USB_REQTYPE_DEVICE | USB_STANDARD_REQ, + USB_DEVDESC, + USB_DEVDESC_SIZE); + } + + if(USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)){ + usbh_device_desc_parse(&puhost->device.dev_desc, pudev->host.rx_buffer, USB_DEVDESC_SIZE); + puhost->usr_cb->device_desc_available(&puhost->device.dev_desc); + + scd_event_handle(pudev, + puhost, + pustate, + ENUN_EVENT_GET_CFG_DESC, + pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of ENUM_SET_ADDR state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval none +*/ +static void enum_set_addr_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.enum_backup_state = ENUM_SET_ADDR; + + if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) { + usbh_enum_addr_set(pudev, puhost,USBH_DEVICE_ADDRESS); + if ((void *)0 != pudev->mdelay) { + pudev->mdelay(100U); + } + } + + if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) { + if ((void *)0 != pudev->mdelay) { + pudev->mdelay(2U); + } + puhost->device.address = USBH_DEVICE_ADDRESS; + + /* user callback for device address assigned */ + puhost->usr_cb->device_address_set(); + + /* modify control channels to update device address */ + usbh_channel_modify (pudev, + puhost->control.hc_in_num, + puhost->device.address, + 0U, + 0U, + 0U); + + usbh_channel_modify (pudev, + puhost->control.hc_out_num, + puhost->device.address, + 0U, + 0U, + 0U); + + scd_event_handle(pudev, + puhost, + pustate, + ENUN_EVENT_GET_FULL_DEV_DESC, + pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of ENUM_GET_CFG_DESC state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval none +*/ +static void enum_get_cfg_desc_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + uint16_t index = 0U; + + puhost->usbh_backup_state.enum_backup_state = ENUM_GET_CFG_DESC; + + if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) { + usbh_enum_desc_get(pudev, + puhost, + pudev->host.rx_buffer, + USB_REQTYPE_DEVICE | USB_STANDARD_REQ, + USB_CFGDESC, + USB_CFGDESC_SIZE); + } + + if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) { + /* save configuration descriptor for class parsing usage */ + for (; index < USB_CFGDESC_SIZE; index ++) { + usbh_cfg_desc[index] = pudev->host.rx_buffer[index]; + } + + /* commands successfully sent and response received */ + usbh_cfg_desc_parse (&puhost->device.cfg_desc, + puhost->device.itf_desc, + puhost->device.ep_desc, + pudev->host.rx_buffer, + USB_CFGDESC_SIZE); + + scd_event_handle(pudev, + puhost, + pustate, + ENUN_EVENT_GET_FULL_CFG_DESC, + pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of ENUM_GET_FULL_CFG_DESC state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval none +*/ +static void enum_get_full_cfg_desc_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + + uint16_t index = 0U; + + puhost->usbh_backup_state.enum_backup_state = ENUM_GET_FULL_CFG_DESC; + + if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) { + usbh_enum_desc_get (pudev, puhost, pudev->host.rx_buffer, + USB_REQTYPE_DEVICE | USB_STANDARD_REQ, + USB_CFGDESC, puhost->device.cfg_desc.wTotalLength); + } + + + if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) { + /* save configuration descriptor for class parsing usage */ + for (; index < puhost->device.cfg_desc.wTotalLength; index ++) { + usbh_cfg_desc[index] = pudev->host.rx_buffer[index]; + } + + /* commands successfully sent and response received */ + usbh_cfg_desc_parse (&puhost->device.cfg_desc, + puhost->device.itf_desc, + puhost->device.ep_desc, + pudev->host.rx_buffer, + puhost->device.cfg_desc.wTotalLength); + + /* User callback for configuration descriptors available */ + puhost->usr_cb->configuration_desc_available(&puhost->device.cfg_desc, + puhost->device.itf_desc, + puhost->device.ep_desc[0]); + + scd_event_handle(pudev, + puhost, + pustate, + ENUN_EVENT_GET_MFC_STRING_DESC, + pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of ENUM_GET_MFC_STRING_DESC state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval none +*/ +static void enum_get_mfc_string_desc_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.enum_backup_state = ENUM_GET_MFC_STRING_DESC; + + if (0U != puhost->device.dev_desc.iManufacturer) { + if(CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) { + usbh_enum_desc_get(pudev, + puhost, + pudev->host.rx_buffer, + USB_REQTYPE_DEVICE | USB_STANDARD_REQ, + USB_STRDESC | puhost->device.dev_desc.iManufacturer, + 0xffU); + } + + if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) { + usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU); + puhost->usr_cb->manufacturer_string(local_buffer); + + scd_event_handle(pudev, + puhost, + pustate, + ENUN_EVENT_GET_PRODUCT_STRING_DESC, + pustate->usbh_current_state); + } + } else { + puhost->usr_cb->manufacturer_string("N/A"); + scd_state_move((usbh_state_handle_struct *)pustate, ENUM_GET_PRODUCT_STRING_DESC); + } +} + +/*! + \brief the handle function of ENUM_GET_PRODUCT_STRING_DESC state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval none +*/ +static void enum_get_product_string_desc_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.enum_backup_state = ENUM_GET_PRODUCT_STRING_DESC; + + if (0U != puhost->device.dev_desc.iProduct) { + if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) { + usbh_enum_desc_get(pudev, + puhost, + pudev->host.rx_buffer, + USB_REQTYPE_DEVICE | USB_STANDARD_REQ, + USB_STRDESC | puhost->device.dev_desc.iProduct, + 0xffU); + } + + if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) { + usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU); + + /* User callback for Product string */ + puhost->usr_cb->product_string(local_buffer); + + scd_event_handle(pudev, + puhost, + pustate, + ENUN_EVENT_GET_SERIALNUM_STRING_DESC, + pustate->usbh_current_state); + } + + } else { + puhost->usr_cb->product_string("N/A"); + scd_event_handle(pudev, + puhost, + pustate, + ENUN_EVENT_GET_SERIALNUM_STRING_DESC, + pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of ENUM_GET_SERIALNUM_STRING_DESC state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval none +*/ +static void enum_get_serialnum_string_desc_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.enum_backup_state = ENUM_GET_SERIALNUM_STRING_DESC; + + if (0U != puhost->device.dev_desc.iSerialNumber) { + if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state) { + usbh_enum_desc_get(pudev, + puhost, + pudev->host.rx_buffer, + USB_REQTYPE_DEVICE | USB_STANDARD_REQ, + USB_STRDESC | puhost->device.dev_desc.iSerialNumber, + 0xffU); + } + + if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)){ + usbh_string_desc_parse(pudev->host.rx_buffer, local_buffer, 0xffU); + + /* user callback for product string */ + puhost->usr_cb->serial_num_string(local_buffer); + scd_event_handle(pudev, + puhost, + pustate, + ENUN_EVENT_SET_CONFIGURATION, + pustate->usbh_current_state); + } + } else { + puhost->usr_cb->serial_num_string("N/A"); + scd_event_handle(pudev, + puhost, + pustate, + ENUN_EVENT_SET_CONFIGURATION, + pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of ENUM_SET_CONFIGURATION state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval none +*/ +static void enum_set_configuration_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.enum_backup_state = ENUM_SET_CONFIGURATION; + + if (CTRL_IDLE == puhost->usbh_backup_state.ctrl_backup_state ) { + usbh_enum_cfg_set(pudev, puhost, (uint16_t)puhost->device.cfg_desc.bConfigurationValue); + } + + if (USBH_OK == ctrl_state_polling_fun(pudev, puhost, pustate)) { + scd_event_handle(pudev, + puhost, + pustate, + ENUN_EVENT_DEV_CONFIGURED, + pustate->usbh_current_state); + } +} + +/*! + \brief the handle function of ENUM_DEV_CONFIGURED state + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] pustate: pointer to USB state driver + \param[out] none + \retval none +*/ +static void enum_dev_configured_handle (usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + usbh_state_handle_struct *pustate) +{ + puhost->usbh_backup_state.enum_backup_state = ENUM_DEV_CONFIGURED; + scd_event_handle(pudev, puhost, pustate, GO_TO_UP_STATE_EVENT, pustate->usbh_current_state); +} + +/*! + \brief get descriptor in usb host enumeration stage + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] buf: buffer to store the descriptor + \param[in] ReqType: descriptor type + \param[in] ValueIdx: wValue for the GetDescriptr request + \param[in] Len: length of the descriptor + \param[out] none + \retval none +*/ +void usbh_enum_desc_get(usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + uint8_t *buf, + uint8_t req_type, + uint16_t value_idx, + uint16_t len) +{ + usb_setup_union *pSetup = &(puhost->control.setup); + + pSetup->b.bmRequestType = USB_DIR_IN | req_type; + pSetup->b.bRequest = USBREQ_GET_DESCRIPTOR; + pSetup->b.wValue = value_idx; + + if (USB_STRDESC == (value_idx & 0xff00U)){ + pSetup->b.wIndex = 0x0409U; + } else { + pSetup->b.wIndex = 0U; + } + + pSetup->b.wLength = len; + + puhost->control.buff = buf; + puhost->control.length = len; + +} + +/*! + \brief set address in usb host enumeration stage + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] device_address: the device address + \param[out] none + \retval none +*/ +void usbh_enum_addr_set(usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + uint8_t device_address) +{ + usb_setup_union *p_setup = &(puhost->control.setup); + + p_setup->b.bmRequestType = USB_DIR_OUT | USB_REQTYPE_DEVICE | USB_STANDARD_REQ; + p_setup->b.bRequest = USBREQ_SET_ADDRESS; + p_setup->b.wValue = (uint16_t)device_address; + p_setup->b.wIndex = 0U; + p_setup->b.wLength = 0U; + puhost->control.buff = 0U; + puhost->control.length = 0U; +} + +/*! + \brief set configuration in usb host enumeration stage + \param[in] pudev: pointer to USB device + \param[in] puhost: pointer to USB host + \param[in] cfg_idx: the index of the configuration + \param[out] none + \retval none +*/ +void usbh_enum_cfg_set(usb_core_handle_struct *pudev, + usbh_host_struct *puhost, + uint16_t cfg_idx) +{ + usb_setup_union *p_setup = &(puhost->control.setup); + + p_setup->b.bmRequestType = USB_DIR_OUT | USB_REQTYPE_DEVICE | USB_STANDARD_REQ; + p_setup->b.bRequest = USBREQ_SET_CONFIGURATION; + p_setup->b.wValue = cfg_idx; + p_setup->b.wIndex = 0U; + p_setup->b.wLength = 0U; + puhost->control.buff = 0; + puhost->control.length = 0U; +} + +/*! + \brief parse the device descriptor + \param[in] dev_desc: device_descriptor destinaton address + \param[in] buf: buffer where the source descriptor is available + \param[in] len: length of the descriptor + \param[out] none + \retval none +*/ +void usbh_device_desc_parse (usb_descriptor_device_struct *dev_desc, uint8_t *buf, uint16_t len) +{ + dev_desc->Header.bLength = *(uint8_t *)(buf + 0); + dev_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1); + dev_desc->bcdUSB = SWAPBYTE(buf + 2); + dev_desc->bDeviceClass = *(uint8_t *)(buf + 4); + dev_desc->bDeviceSubClass = *(uint8_t *)(buf + 5); + dev_desc->bDeviceProtocol = *(uint8_t *)(buf + 6); + dev_desc->bMaxPacketSize0 = *(uint8_t *)(buf + 7); + + if (len > 8U){ + /* for 1st time after device connection, host may issue only 8 bytes for device descriptor length */ + dev_desc->idVendor = SWAPBYTE(buf + 8); + dev_desc->idProduct = SWAPBYTE(buf + 10); + dev_desc->bcdDevice = SWAPBYTE(buf + 12); + dev_desc->iManufacturer = *(uint8_t *)(buf + 14); + dev_desc->iProduct = *(uint8_t *)(buf + 15); + dev_desc->iSerialNumber = *(uint8_t *)(buf + 16); + dev_desc->bNumberConfigurations = *(uint8_t *)(buf + 17); + } +} + +/*! + \brief parse the configuration descriptor + \param[in] cfg_desc: configuration descriptor address + \param[in] itf_desc: interface descriptor address + \param[in] ep_desc: endpoint descriptor address + \param[in] buf: buffer where the source descriptor is available + \param[in] len: length of the descriptor + \param[out] none + \retval none +*/ +void usbh_cfg_desc_parse (usb_descriptor_configuration_struct *cfg_desc, + usb_descriptor_interface_struct *itf_desc, + usb_descriptor_endpoint_struct ep_desc[][USBH_MAX_EP_NUM], + uint8_t *buf, + uint16_t len) +{ + usb_descriptor_interface_struct *pitf = NULL; + usb_descriptor_interface_struct temp_pitf; + usb_descriptor_endpoint_struct *pep = NULL; + usb_descriptor_header_struct *pdesc = (usb_descriptor_header_struct *)buf; + + uint8_t itf_ix = 0U; + uint8_t ep_ix = 0U; + uint16_t ptr = 0U; + static uint8_t prev_itf = 0U; + static uint16_t prev_ep_size = 0U; + + /* parse configuration descriptor */ + cfg_desc->Header.bLength = *(uint8_t *)(buf + 0); + cfg_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1); + cfg_desc->wTotalLength = SWAPBYTE(buf + 2); + cfg_desc->bNumInterfaces = *(uint8_t *)(buf + 4); + cfg_desc->bConfigurationValue = *(uint8_t *)(buf + 5); + cfg_desc->iConfiguration = *(uint8_t *)(buf + 6); + cfg_desc->bmAttributes = *(uint8_t *)(buf + 7); + cfg_desc->bMaxPower = *(uint8_t *)(buf + 8); + + if (len > USB_CFGDESC_SIZE) { + ptr = USB_CFG_DESC_LEN; + + if (cfg_desc->bNumInterfaces <= USBH_MAX_INTERFACES_NUM) { + pitf = (usb_descriptor_interface_struct *)0; + + for (; ptr < cfg_desc->wTotalLength; ) { + pdesc = usbh_next_desc_get((uint8_t *)pdesc, &ptr); + + if (USB_DESCTYPE_INTERFACE == pdesc->bDescriptorType) { + itf_ix = *((uint8_t *)pdesc + 2U); + pitf = &itf_desc[itf_ix]; + + if (*((uint8_t *)pdesc + 3U) < 3U) { + usbh_interface_desc_parse (&temp_pitf, (uint8_t *)pdesc); + + /* parse endpoint descriptors relative to the current interface */ + if (temp_pitf.bNumEndpoints <= USBH_MAX_EP_NUM) { + for (ep_ix = 0U; ep_ix < temp_pitf.bNumEndpoints;) { + pdesc = usbh_next_desc_get((void* )pdesc, &ptr); + + if (USB_DESCTYPE_ENDPOINT == pdesc->bDescriptorType) { + pep = &ep_desc[itf_ix][ep_ix]; + + if (prev_itf != itf_ix) { + prev_itf = itf_ix; + usbh_interface_desc_parse (pitf, (uint8_t *)&temp_pitf); + } else { + if (prev_ep_size > SWAPBYTE((uint8_t *)pdesc + 4)) { + break; + } else { + usbh_interface_desc_parse (pitf, (uint8_t *)&temp_pitf); + } + } + + usbh_endpoint_desc_parse (pep, (uint8_t *)pdesc); + prev_ep_size = SWAPBYTE((uint8_t *)pdesc + 4); + ep_ix++; + } + } + } + } + } + } + } + + prev_ep_size = 0U; + prev_itf = 0U; + } +} + +/*! + \brief parse the interface descriptor + \param[in] itf_desc: interface descriptor destination + \param[in] buf: buffer where the descriptor data is available + \param[out] none + \retval none +*/ +void usbh_interface_desc_parse (usb_descriptor_interface_struct *itf_desc, uint8_t *buf) +{ + itf_desc->Header.bLength = *(uint8_t *)(buf + 0); + itf_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1); + itf_desc->bInterfaceNumber = *(uint8_t *)(buf + 2); + itf_desc->bAlternateSetting = *(uint8_t *)(buf + 3); + itf_desc->bNumEndpoints = *(uint8_t *)(buf + 4); + itf_desc->bInterfaceClass = *(uint8_t *)(buf + 5); + itf_desc->bInterfaceSubClass = *(uint8_t *)(buf + 6); + itf_desc->bInterfaceProtocol = *(uint8_t *)(buf + 7); + itf_desc->iInterface = *(uint8_t *)(buf + 8); +} + +/*! + \brief parse the endpoint descriptor + \param[in] ep_desc: endpoint descriptor destination address + \param[in] buf: buffer where the parsed descriptor stored + \param[out] none + \retval none +*/ +void usbh_endpoint_desc_parse (usb_descriptor_endpoint_struct *ep_desc, uint8_t *buf) +{ + ep_desc->Header.bLength = *(uint8_t *)(buf + 0); + ep_desc->Header.bDescriptorType = *(uint8_t *)(buf + 1); + ep_desc->bEndpointAddress = *(uint8_t *)(buf + 2); + ep_desc->bmAttributes = *(uint8_t *)(buf + 3); + ep_desc->wMaxPacketSize = SWAPBYTE(buf + 4); + ep_desc->bInterval = *(uint8_t *)(buf + 6); +} + +/*! + \brief parse the string descriptor + \param[in] psrc: source pointer containing the descriptor data + \param[in] pdest: destination address pointer + \param[in] len: length of the descriptor + \param[out] none + \retval none +*/ +void usbh_string_desc_parse (uint8_t* psrc, uint8_t* pdest, uint16_t len) +{ + uint16_t strlength; + uint16_t idx; + + /* the unicode string descriptor is not null-terminated. the string length is + computed by substracting two from the value of the first byte of the descriptor. + */ + + /* check which is lower size, the size of string or the length of bytes read from the device */ + + if (USB_DESCTYPE_STRING == psrc[1]){ + /* make sure the descriptor is string type */ + + /* psrc[0] contains size of descriptor, subtract 2 to get the length of string */ + strlength = ((((uint16_t)psrc[0] - 2U) <= len) ? ((uint16_t)psrc[0] - 2U) : len); + psrc += 2; /* adjust the offset ignoring the string len and descriptor type */ + + for (idx = 0U; idx < strlength; idx += 2U) { + /* copy only the string and ignore the unicode id, hence add the src */ + *pdest = psrc[idx]; + pdest++; + } + + *pdest = 0U; /* mark end of string */ + } +} + +/*! + \brief get the next descriptor header + \param[in] pbuf: pointer to buffer where the cfg descriptor is available + \param[in] ptr: data popinter inside the configuration descriptor + \param[out] none + \retval next descriptor header +*/ +usb_descriptor_header_struct *usbh_next_desc_get (uint8_t *pbuf, uint16_t *ptr) +{ + uint8_t len = ((usb_descriptor_header_struct *)pbuf)->bLength; + + usb_descriptor_header_struct *pnext; + + *ptr += len; + + pnext = (usb_descriptor_header_struct *)((uint8_t *)pbuf + len); + + return(pnext); +} + diff --git a/bsp/gd32450z-eval/Libraries/SConscript b/bsp/gd32450z-eval/Libraries/SConscript new file mode 100644 index 0000000000..e4a83cde55 --- /dev/null +++ b/bsp/gd32450z-eval/Libraries/SConscript @@ -0,0 +1,36 @@ +import rtconfig +from building import * + +# get current directory +cwd = GetCurrentDir() + +# The set of source files associated with this SConscript file. + +src = Glob('GD32F4xx_standard_peripheral/Source/*.c') +src += [cwd + '/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c'] + +#add for startup script +if rtconfig.CROSS_TOOL == 'gcc': + print '=================================================' + print 'Not support gcc yet!' + print '=================================================' + exit(0) +elif rtconfig.CROSS_TOOL == 'keil': + src += [cwd + '/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s'] +elif rtconfig.CROSS_TOOL == 'iar': + src += [cwd + '/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s'] + +path = [ + cwd + '/CMSIS/GD/GD32F4xx/Include', + cwd + '/CMSIS', + cwd + '/GD32F4xx_standard_peripheral/Include',] + +if GetDepend(['RT_USING_BSP_USB']): + path += [cwd + '/GD32F4xx_usb_driver/Include'] + src += [cwd + '/GD32F4xx_usb_driver/Source'] + +CPPDEFINES = ['USE_STDPERIPH_DRIVER', 'GD32F4XX'] + +group = DefineGroup('GD32_Lib', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/gd32450z-eval/SConscript b/bsp/gd32450z-eval/SConscript new file mode 100644 index 0000000000..fe0ae941ae --- /dev/null +++ b/bsp/gd32450z-eval/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +Import('RTT_ROOT') + +cwd = str(Dir('#')) +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/gd32450z-eval/SConstruct b/bsp/gd32450z-eval/SConstruct new file mode 100644 index 0000000000..42ae8c9646 --- /dev/null +++ b/bsp/gd32450z-eval/SConstruct @@ -0,0 +1,39 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +try: + from building import * +except: + print 'Cannot found RT-Thread root directory, please check RTT_ROOT' + print RTT_ROOT + exit(-1) + +TARGET = 'rtthread-gd32f4xx.' + rtconfig.TARGET_EXT + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +if rtconfig.PLATFORM == 'iar': + env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(ARFLAGS = ['']) + env.Replace(LINKCOM = ['$LINK $SOURCES $LINKFLAGS -o $TARGET --map project.map']) + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/gd32450z-eval/applications/SConscript b/bsp/gd32450z-eval/applications/SConscript new file mode 100644 index 0000000000..01eb940dfb --- /dev/null +++ b/bsp/gd32450z-eval/applications/SConscript @@ -0,0 +1,11 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'applications') +src = Glob('*.c') +CPPPATH = [cwd, str(Dir('#'))] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/gd32450z-eval/applications/application.c b/bsp/gd32450z-eval/applications/application.c new file mode 100644 index 0000000000..d4e2b8ced1 --- /dev/null +++ b/bsp/gd32450z-eval/applications/application.c @@ -0,0 +1,83 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard the first version + * 2014-04-27 Bernard make code cleanup. + */ + +#include +#include +#include + +#ifdef RT_USING_GUIENGINE +#include "rtgui_demo.h" +#include +#endif + +#ifdef RT_USING_DFS +/* dfs init */ +#include +/* dfs filesystem:ELM filesystem init */ +#include +/* dfs Filesystem APIs */ +#include +#include +#endif + +#include + +void rt_init_thread_entry(void* parameter) +{ + /* initialization RT-Thread Components */ +#ifdef RT_USING_COMPONENTS_INIT + rt_components_init(); +#endif + +#ifdef RT_USING_GUIENGINE + { + rt_device_t device; + + device = rt_device_find("lcd"); + /* re-set graphic device */ + rtgui_graphic_set_device(device); + + rt_gui_demo_init(); + } +#endif + +#ifdef RT_USING_DFS + #ifdef RT_USING_DFS_ELMFAT + /* mount sd card fat partition 0 as root directory */ + if (dfs_mount("gd25q16", "/", "elm", 0, 0) == 0) + { + rt_kprintf("spi flash mount to / !\n"); + } + else + { + rt_kprintf("spi flash mount to / failed!\n"); + } + #endif /* RT_USING_DFS_ELMFAT */ + +#endif /* DFS */ +} +int rt_application_init() +{ + rt_thread_t tid; + + tid = rt_thread_create("init", + rt_init_thread_entry, RT_NULL, + 2048, RT_THREAD_PRIORITY_MAX/3, 20); + + if (tid != RT_NULL) + rt_thread_startup(tid); + + return 0; +} diff --git a/bsp/gd32450z-eval/applications/rtgui_demo.c b/bsp/gd32450z-eval/applications/rtgui_demo.c new file mode 100644 index 0000000000..f8f3636a85 --- /dev/null +++ b/bsp/gd32450z-eval/applications/rtgui_demo.c @@ -0,0 +1,127 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + */ + +#include +#include +#include "rtgui_demo.h" + +#define DEBUG + +#ifdef DEBUG +#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +#ifdef RT_USING_GUIENGINE + +#include +#include +#include + +#include +#include +#include + +struct rtgui_win *main_win; +rt_bool_t dc_event_handler(struct rtgui_object *object, rtgui_event_t *event); + +static void rt_gui_demo_entry(void *parameter) +{ + struct rtgui_app *app; + //struct rtgui_dc *dc; + + DEBUG_PRINTF("gui demo entry\n"); + + /* create gui app */ + app = rtgui_app_create("gui_demo"); + if (app == RT_NULL) + { + DEBUG_PRINTF("rtgui_app_create faild\n"); + return; + } + + /* create main window */ + main_win = rtgui_mainwin_create(RT_NULL, + "UiWindow", RTGUI_WIN_STYLE_NO_TITLE | RTGUI_WIN_STYLE_NO_BORDER); + if (main_win == RT_NULL) + { + DEBUG_PRINTF("main_win is null\n"); + rtgui_app_destroy(app); + return; + } + + rtgui_object_set_event_handler(RTGUI_OBJECT(main_win), dc_event_handler); + + DEBUG_PRINTF("rtgui_win_show\n"); + rtgui_win_show(main_win, RT_FALSE); + + DEBUG_PRINTF("rtgui_app_run\n"); + rtgui_app_run(app); + + DEBUG_PRINTF("rtgui_win_destroy\n"); + rtgui_win_destroy(main_win); + + DEBUG_PRINTF("rtgui_app_destroy\n"); + rtgui_app_destroy(app); +} + +rt_bool_t dc_event_handler(struct rtgui_object *object, rtgui_event_t *event) +{ + struct rtgui_widget *widget = RTGUI_WIDGET(object); + + if (event->type == RTGUI_EVENT_PAINT) + { + struct rtgui_dc *dc; + rtgui_rect_t rect; + + rt_kprintf("\r\n RTGUI_EVENT_PAINT \r\n"); + rtgui_win_event_handler(RTGUI_OBJECT(widget), event); + + rtgui_widget_get_rect(widget, &rect); + DEBUG_PRINTF("widget react x1: %d, y1: %d, x2: %d, y2: %d\r\n", + rect.x1, rect.y1, rect.x2, rect.y2); + + dc = rtgui_dc_begin_drawing(widget); + if(dc == RT_NULL) + { + DEBUG_PRINTF("\r\n dc is null \r\n"); + return RT_FALSE; + } + + rtgui_dc_draw_line(dc, rect.x1, rect.y1, rect.x2, rect.y2); + rtgui_dc_draw_line(dc, rect.x1, rect.y2, rect.x2, rect.y1); + + rect.x1 += (rect.x2 - rect.x1) / 2; + rect.y1 += (rect.y2 - rect.y1) / 2; + rtgui_dc_draw_text_stroke(dc, __DATE__"--"__TIME__, &rect, HIGH_LIGHT, BLUE); + + + rtgui_dc_end_drawing(dc); + } + return RT_FALSE; +} + +int rt_gui_demo_init(void) +{ + rt_thread_t tid; + tid = rt_thread_create("mygui", + rt_gui_demo_entry, RT_NULL, + 2048, 25, 10); + + if (tid != RT_NULL) + rt_thread_startup(tid); + + return 0; +} +#endif /* RT_USING_GUIENGINE */ diff --git a/bsp/gd32450z-eval/applications/rtgui_demo.h b/bsp/gd32450z-eval/applications/rtgui_demo.h new file mode 100644 index 0000000000..e27f7b5609 --- /dev/null +++ b/bsp/gd32450z-eval/applications/rtgui_demo.h @@ -0,0 +1,20 @@ +/* + * File : dc.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-06-02 tanek first version + */ +#ifndef __APP_GUI_DEMO_H__ +#define __APP_GUI_DEMO_H__ + +extern int rt_gui_demo_init(void); + +#endif + diff --git a/bsp/gd32450z-eval/applications/startup.c b/bsp/gd32450z-eval/applications/startup.c new file mode 100644 index 0000000000..eb34167091 --- /dev/null +++ b/bsp/gd32450z-eval/applications/startup.c @@ -0,0 +1,107 @@ +/* + * File : startup.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2006-08-31 Bernard first implementation + */ + +#include +#include + +#include +#include "board.h" + +/** + * @addtogroup GD32F4xx + */ + +/*@{*/ + +extern int rt_application_init(void); + +#ifdef RT_USING_FINSH +extern int finsh_system_init(void); +extern void finsh_set_device(const char* device); +#endif + +/******************************************************************************* +* Function Name : assert_failed +* Description : Reports the name of the source file and the source line number +* where the assert error has occurred. +* Input : - file: pointer to the source file name +* - line: assert error line source number +* Output : None +* Return : None +*******************************************************************************/ +void assert_failed(uint8_t* file, uint32_t line) +{ + rt_kprintf("\n\r Wrong parameter value detected on\r\n"); + rt_kprintf(" file %s\r\n", file); + rt_kprintf(" line %d\r\n", line); + + while (1) ; +} + +/** + * This function will startup RT-Thread RTOS. + */ +void rtthread_startup(void) +{ + /* init board */ + rt_hw_board_init(); + + /* show version */ + rt_show_version(); + + /* init tick */ + rt_system_tick_init(); + + /* init kernel object */ + rt_system_object_init(); + + /* init timer system */ + rt_system_timer_init(); + +#ifdef RT_USING_EXT_SDRAM + rt_system_heap_init((void*)EXT_SDRAM_BEGIN, (void*)EXT_SDRAM_END); +#else + rt_system_heap_init((void*)HEAP_BEGIN, (void*)HEAP_END); +#endif + + /* init scheduler system */ + rt_system_scheduler_init(); + + /* init application */ + rt_application_init(); + + /* init timer thread */ + rt_system_timer_thread_init(); + + /* init idle thread */ + rt_thread_idle_init(); + + /* start scheduler */ + rt_system_scheduler_start(); + + /* never reach here */ + return ; +} + +int main(void) +{ + /* disable interrupt first */ + rt_hw_interrupt_disable(); + + /* startup RT-Thread RTOS */ + rtthread_startup(); + return 0; +} + +/*@}*/ diff --git a/bsp/gd32450z-eval/drivers/SConscript b/bsp/gd32450z-eval/drivers/SConscript new file mode 100644 index 0000000000..40107508d7 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/SConscript @@ -0,0 +1,33 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'drivers') + +# add the general drivers. +src = Split(""" +board.c +drv_exmc_sdram.c +drv_usart.c +""") + +CPPPATH = [cwd] + +# add Ethernet drivers. +if GetDepend('RT_USING_LWIP'): + src += ['drv_enet.c', 'synopsys_emac.c'] + +# add lcd drivers. +if GetDepend('RT_USING_GUIENGINE'): + src += ['drv_lcd.c', 'gd32f450z_lcd_eval.c'] + +# add spi flash drivers. +if GetDepend('RT_USING_SFUD'): + src += ['drv_spi_flash.c', 'drv_spi.c'] +elif GetDepend('RT_USING_SPI'): + src += ['drv_spi.c'] + + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/gd32450z-eval/drivers/board.c b/bsp/gd32450z-eval/drivers/board.c new file mode 100644 index 0000000000..43280a2b50 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/board.c @@ -0,0 +1,87 @@ +/* + * File : board.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard first implementation + */ +#include +#include +#include + +#include +#include +#include + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler */ + /* User can add his own implementation to report the HAL error return state */ + while(1) + { + } + /* USER CODE END Error_Handler */ +} + +/** System Clock Configuration +*/ +void SystemClock_Config(void) +{ + SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); + NVIC_SetPriority(SysTick_IRQn, 0); +} + +/** + * This is the timer interrupt service routine. + * + */ +void SysTick_Handler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); +} + + +/** + * This function will initial GD32 board. + */ +void rt_hw_board_init() +{ + /* NVIC Configuration */ +#define NVIC_VTOR_MASK 0x3FFFFF80 +#ifdef VECT_TAB_RAM + /* Set the Vector Table base location at 0x10000000 */ + SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK); +#else /* VECT_TAB_FLASH */ + /* Set the Vector Table base location at 0x08000000 */ + SCB->VTOR = (0x08000000 & NVIC_VTOR_MASK); +#endif + + SystemClock_Config(); + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + +#ifdef RT_USING_CONSOLE + rt_console_set_device(CONSOLE_DEVICE); +#endif +} + +/*@}*/ diff --git a/bsp/gd32450z-eval/drivers/board.h b/bsp/gd32450z-eval/drivers/board.h new file mode 100644 index 0000000000..c91005d026 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/board.h @@ -0,0 +1,84 @@ +/* + * File : board.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-09-22 Bernard add board.h to this bsp + */ + +// <<< Use Configuration Wizard in Context Menu >>> +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include + + +#define EXT_SDRAM_BEGIN (0xC0000000U) /* the begining address of external SDRAM */ +#define EXT_SDRAM_END (EXT_SDRAM_BEGIN + (32U * 1024 * 1024)) /* the end address of external SDRAM */ + +// Internal SRAM memory size[Kbytes] <8-64> +// Default: 64 +#ifdef __ICCARM__ +// Use *.icf ram symbal, to avoid hardcode. +extern char __ICFEDIT_region_RAM_end__; +#define GD32_SRAM_END &__ICFEDIT_region_RAM_end__ +#else +#define GD32_SRAM_SIZE 128 +#define GD32_SRAM_END (0x20000000 + GD32_SRAM_SIZE * 1024) +#endif + +#ifdef __CC_ARM +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="HEAP" +#define HEAP_BEGIN (__segment_end("HEAP")) +#else +extern int __bss_end; +#define HEAP_BEGIN (&__bss_end) +#endif + +#define HEAP_END GD32_SRAM_END + +// Console on USART: +// <127=> no console +// <0=>USART 0 <1=>USART 1 <2=>USART 2 <3=> USART 3 +// <4=>USART 4 <5=>USART 5 <6=>USART 6 <7=> USART 7 +// Default: 1 +#define GD32_CONSOLE_USART 0 + +void rt_hw_board_init(void); + +#if GD32_CONSOLE_USART == 127 + #define CONSOLE_DEVICE "no" +#elif GD32_CONSOLE_USART == 0 + #define CONSOLE_DEVICE "uart0" +#elif GD32_CONSOLE_USART == 1 + #define CONSOLE_DEVICE "uart1" +#elif GD32_CONSOLE_USART == 2 + #define CONSOLE_DEVICE "uart2" +#elif GD32_CONSOLE_USART == 3 + #define CONSOLE_DEVICE "uart3" +#elif GD32_CONSOLE_USART == 4 + #define CONSOLE_DEVICE "uart4" +#elif GD32_CONSOLE_USART == 5 + #define CONSOLE_DEVICE "uart5" +#elif GD32_CONSOLE_USART == 6 + #define CONSOLE_DEVICE "uart6" +#elif GD32_CONSOLE_USART == 7 + #define CONSOLE_DEVICE "uart7" +#endif + +#define FINSH_DEVICE_NAME CONSOLE_DEVICE + +void Error_Handler(void); + +#endif + +//*** <<< end of configuration section >>> *** diff --git a/bsp/gd32450z-eval/drivers/drv_enet.c b/bsp/gd32450z-eval/drivers/drv_enet.c new file mode 100644 index 0000000000..bbc28f2f5d --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_enet.c @@ -0,0 +1,658 @@ +/* + * File : eth_driver.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-11-30 aozima the first version. + * 2011-12-10 aozima support dual ethernet. + * 2011-12-21 aozima cleanup code. + * 2012-07-13 aozima mask all GMAC MMC Interrupt. + * 2012-07-20 aozima fixed mask all GMAC MMC Interrupt,and read clear. + * 2012-07-20 aozima use memcpy replace byte copy. + */ + +#include +#include + +#include "lwipopts.h" +#include +#include +#include + +#include "gd32f4xx.h" +#include "synopsys_emac.h" + +#define ETHERNET_MAC0 ((struct rt_synopsys_eth *)(0x40020000U + 0x00008000U)) + +//#define EMAC_DEBUG +//#define EMAC_RX_DUMP +//#define EMAC_TX_DUMP + +#ifdef EMAC_DEBUG +#define EMAC_TRACE rt_kprintf +#else +#define EMAC_TRACE(...) +#endif + +#define EMAC_RXBUFNB 4 +#define EMAC_TXBUFNB 2 + +#define EMAC_PHY_AUTO 0 +#define EMAC_PHY_10MBIT 1 +#define EMAC_PHY_100MBIT 2 + +#define MAX_ADDR_LEN 6 +struct gd32_emac +{ + /* inherit from Ethernet device */ + struct eth_device parent; + + rt_uint8_t phy_mode; + /* interface address info. */ + rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ + + struct rt_synopsys_eth * ETHERNET_MAC; + IRQn_Type ETHER_MAC_IRQ; + + EMAC_DMADESCTypeDef *DMATxDescToSet; + EMAC_DMADESCTypeDef *DMARxDescToGet; + +#pragma pack(4) + EMAC_DMADESCTypeDef DMARxDscrTab[EMAC_RXBUFNB]; +#pragma pack(4) + EMAC_DMADESCTypeDef DMATxDscrTab[EMAC_TXBUFNB]; +#pragma pack(4) + rt_uint8_t Rx_Buff[EMAC_RXBUFNB][EMAC_MAX_PACKET_SIZE]; +#pragma pack(4) + rt_uint8_t Tx_Buff[EMAC_TXBUFNB][EMAC_MAX_PACKET_SIZE]; + + struct rt_semaphore tx_buf_free; +}; + +static struct gd32_emac gd32_emac_device0; + +/** + * Initializes the DMA Tx descriptors in chain mode. + */ +static void EMAC_DMA_tx_desc_init(EMAC_DMADESCTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount) +{ + uint32_t i = 0; + EMAC_DMADESCTypeDef *DMATxDesc; + + /* Fill each DMATxDesc descriptor with the right values */ + for(i=0; i < TxBuffCount; i++) + { + /* Get the pointer on the ith member of the Tx Desc list */ + DMATxDesc = DMATxDescTab + i; + /* Set Second Address Chained bit */ + DMATxDesc->Status = EMAC_DMATxDesc_TCH; + + /* Set Buffer1 address pointer */ + DMATxDesc->Buffer1Addr = (uint32_t)(&TxBuff[i*EMAC_MAX_PACKET_SIZE]); + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + if(i < (TxBuffCount-1)) + { + /* Set next descriptor address register with next descriptor base address */ + DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab+i+1); + } + else + { + /* For last descriptor, set next descriptor address register equal to the first descriptor base address */ + DMATxDesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab; + } + } +} + +/** + * Initializes the DMA Rx descriptors in chain mode. + */ +static void EMAC_DMA_rx_desc_init(EMAC_DMADESCTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount) +{ + uint32_t i = 0; + EMAC_DMADESCTypeDef *DMARxDesc; + + /* Fill each DMARxDesc descriptor with the right values */ + for(i=0; i < RxBuffCount; i++) + { + /* Get the pointer on the ith member of the Rx Desc list */ + DMARxDesc = DMARxDescTab+i; + /* Set Own bit of the Rx descriptor Status */ + DMARxDesc->Status = EMAC_DMARxDesc_OWN; + + /* Set Buffer1 size and Second Address Chained bit */ + DMARxDesc->ControlBufferSize = EMAC_DMARxDesc_RCH | (uint32_t)EMAC_MAX_PACKET_SIZE; + /* Set Buffer1 address pointer */ + DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i*EMAC_MAX_PACKET_SIZE]); + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + if(i < (RxBuffCount-1)) + { + /* Set next descriptor address register with next descriptor base address */ + DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab+i+1); + } + else + { + /* For last descriptor, set next descriptor address register equal to the first descriptor base address */ + DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab); + } + } +} + +static rt_err_t gd32_emac_init(rt_device_t dev) +{ + struct gd32_emac * gd32_emac_device; + struct rt_synopsys_eth * ETHERNET_MAC; + + gd32_emac_device = (struct gd32_emac *)dev; + ETHERNET_MAC = gd32_emac_device->ETHERNET_MAC; + + /* Software reset */ + ETHERNET_MAC->BMR |= (1<<0); /* [bit0]SWR (Software Reset) */ + + /* Wait for software reset */ + while(ETHERNET_MAC->BMR & (1<<0)); + + /* Configure ETHERNET */ + EMAC_init(ETHERNET_MAC, SystemCoreClock); + + /* mask all GMAC MMC Interrupt.*/ + ETHERNET_MAC->mmc_cntl = (1<<3) | (1<<0); /* MMC Counter Freeze and reset. */ + ETHERNET_MAC->mmc_intr_mask_rx = 0xFFFFFFFF; + ETHERNET_MAC->mmc_intr_mask_tx = 0xFFFFFFFF; + ETHERNET_MAC->mmc_ipc_intr_mask_rx = 0xFFFFFFFF; + + /* Enable DMA Receive interrupt (need to enable in this case Normal interrupt) */ + EMAC_INT_config(ETHERNET_MAC, EMAC_DMA_INT_NIS | EMAC_DMA_INT_R | EMAC_DMA_INT_T , ENABLE); + + /* Initialize Tx Descriptors list: Chain Mode */ + EMAC_DMA_tx_desc_init(gd32_emac_device->DMATxDscrTab, &gd32_emac_device->Tx_Buff[0][0], EMAC_TXBUFNB); + gd32_emac_device->DMATxDescToSet = gd32_emac_device->DMATxDscrTab; + /* Set Transmit Descriptor List Address Register */ + ETHERNET_MAC->TDLAR = (uint32_t) gd32_emac_device->DMATxDescToSet; + + /* Initialize Rx Descriptors list: Chain Mode */ + EMAC_DMA_rx_desc_init(gd32_emac_device->DMARxDscrTab, &gd32_emac_device->Rx_Buff[0][0], EMAC_RXBUFNB); + gd32_emac_device->DMARxDescToGet = gd32_emac_device->DMARxDscrTab; + /* Set Receive Descriptor List Address Register */ + ETHERNET_MAC->RDLAR = (uint32_t) gd32_emac_device->DMARxDescToGet; + + /* MAC address configuration */ + EMAC_MAC_Addr_config(ETHERNET_MAC, EMAC_MAC_Address0, (uint8_t*)&gd32_emac_device->dev_addr[0]); + + NVIC_EnableIRQ( gd32_emac_device->ETHER_MAC_IRQ ); + + /* Enable MAC and DMA transmission and reception */ + EMAC_start(ETHERNET_MAC); + + return RT_EOK; +} + +static rt_err_t gd32_emac_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t gd32_emac_close(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_size_t gd32_emac_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_size_t gd32_emac_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_err_t gd32_emac_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + struct gd32_emac * gd32_emac_device = (struct gd32_emac *)dev; + + switch (cmd) + { + case NIOCTL_GADDR: + /* get mac address */ + if (args) memcpy(args, &gd32_emac_device->dev_addr[0], MAX_ADDR_LEN); + else return -RT_ERROR; + break; + + default : + break; + } + + return RT_EOK; +} + +static void EMAC_IRQHandler(struct gd32_emac * gd32_emac_device) +{ + rt_uint32_t status, ier; + struct rt_synopsys_eth * ETHERNET_MAC; + + ETHERNET_MAC = gd32_emac_device->ETHERNET_MAC; + + /* get DMA IT status */ + status = ETHERNET_MAC->SR; + ier = ETHERNET_MAC->IER; + + /* GMAC MMC Interrupt. */ + if(status & EMAC_DMA_INT_GMI) + { + volatile rt_uint32_t dummy; + volatile rt_uint32_t * reg; + + EMAC_TRACE("EMAC_DMA_INT_GMI\r\n"); + + /* read clear all MMC interrupt. */ + reg = ÐERNET_MAC->mmc_cntl; + while((uint32_t)reg < (uint32_t)ÐERNET_MAC->rxicmp_err_octets) + { + dummy = *reg++; + } + } + + /* Normal interrupt summary. */ + if(status & EMAC_DMA_INT_NIS) + { + rt_uint32_t nis_clear = EMAC_DMA_INT_NIS; + + /* [0]:Transmit Interrupt. */ + if((status & ier) & EMAC_DMA_INT_T) /* packet transmission */ + { + rt_sem_release(&gd32_emac_device->tx_buf_free); + + nis_clear |= EMAC_DMA_INT_T; + } + + /* [2]:Transmit Buffer Unavailable. */ + + /* [6]:Receive Interrupt. */ + if((status & ier) & EMAC_DMA_INT_R) /* packet reception */ + { + /* a frame has been received */ + eth_device_ready(&(gd32_emac_device->parent)); + + nis_clear |= EMAC_DMA_INT_R; + } + + /* [14]:Early Receive Interrupt. */ + + EMAC_clear_pending(ETHERNET_MAC, nis_clear); + } + + /* Abnormal interrupt summary. */ + if( status & EMAC_DMA_INT_AIS) + { + rt_uint32_t ais_clear = EMAC_DMA_INT_AIS; + + /* [1]:Transmit Process Stopped. */ + /* [3]:Transmit Jabber Timeout. */ + /* [4]: Receive FIFO Overflow. */ + /* [5]: Transmit Underflow. */ + /* [7]: Receive Buffer Unavailable. */ + /* [8]: Receive Process Stopped. */ + /* [9]: Receive Watchdog Timeout. */ + /* [10]: Early Transmit Interrupt. */ + /* [13]: Fatal Bus Error. */ + + EMAC_clear_pending(ETHERNET_MAC, ais_clear); + } +} + +void ENET_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + EMAC_IRQHandler(&gd32_emac_device0); + + /* leave interrupt */ + rt_interrupt_leave(); +} + + +/* EtherNet Device Interface */ +rt_err_t gd32_emac_tx( rt_device_t dev, struct pbuf* p) +{ + struct pbuf* q; + char * to; + struct gd32_emac * gd32_emac_device; + struct rt_synopsys_eth * ETHERNET_MAC; + + gd32_emac_device = (struct gd32_emac *)dev; + ETHERNET_MAC = gd32_emac_device->ETHERNET_MAC; + + /* get free tx buffer */ + { + rt_err_t result; + result = rt_sem_take(&gd32_emac_device->tx_buf_free, RT_TICK_PER_SECOND/10); + if (result != RT_EOK) return -RT_ERROR; + } + + to = (char *)gd32_emac_device->DMATxDescToSet->Buffer1Addr; + + for (q = p; q != NULL; q = q->next) + { + /* Copy the frame to be sent into memory pointed by the current ETHERNET DMA Tx descriptor */ + memcpy(to, q->payload, q->len); + to += q->len; + } + +#ifdef EMAC_TX_DUMP + { + rt_uint32_t i; + rt_uint8_t *ptr = (rt_uint8_t*)(gd32_emac_device->DMATxDescToSet->Buffer1Addr); + + EMAC_TRACE("\r\n%c%c tx_dump:", gd32_emac_device->parent.netif->name[0], gd32_emac_device->parent.netif->name[1]); + for(i=0; itot_len; i++) + { + if( (i%8) == 0 ) + { + EMAC_TRACE(" "); + } + if( (i%16) == 0 ) + { + EMAC_TRACE("\r\n"); + } + EMAC_TRACE("%02x ",*ptr); + ptr++; + } + EMAC_TRACE("\r\ndump done!\r\n"); + } +#endif + + /* Setting the Frame Length: bits[12:0] */ + gd32_emac_device->DMATxDescToSet->ControlBufferSize = (p->tot_len & EMAC_DMATxDesc_TBS1); + /* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */ + gd32_emac_device->DMATxDescToSet->Status |= EMAC_DMATxDesc_LS | EMAC_DMATxDesc_FS; + /* Enable TX Completion Interrupt */ + gd32_emac_device->DMATxDescToSet->Status |= EMAC_DMATxDesc_IC; +#ifdef CHECKSUM_BY_HARDWARE + gd32_emac_device->DMATxDescToSet->Status |= EMAC_DMATxDesc_ChecksumTCPUDPICMPFull; + /* clean ICMP checksum */ + { + struct eth_hdr *ethhdr = (struct eth_hdr *)(gd32_emac_device->DMATxDescToSet->Buffer1Addr); + /* is IP ? */ + if( ethhdr->type == htons(ETHTYPE_IP) ) + { + struct ip_hdr *iphdr = (struct ip_hdr *)(gd32_emac_device->DMATxDescToSet->Buffer1Addr + SIZEOF_ETH_HDR); + /* is ICMP ? */ + if( IPH_PROTO(iphdr) == IP_PROTO_ICMP ) + { + struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)(gd32_emac_device->DMATxDescToSet->Buffer1Addr + SIZEOF_ETH_HDR + sizeof(struct ip_hdr) ); + iecho->chksum = 0; + } + } + } +#endif + /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ + gd32_emac_device->DMATxDescToSet->Status |= EMAC_DMATxDesc_OWN; + /* When Tx Buffer unavailable flag is set: clear it and resume transmission */ + if ((ETHERNET_MAC->SR & EMAC_DMASR_TBUS) != (uint32_t)RESET) + { + /* Clear TBUS ETHERNET DMA flag */ + ETHERNET_MAC->SR = EMAC_DMASR_TBUS; + /* Transmit Poll Demand to resume DMA transmission*/ + ETHERNET_MAC->TPDR = 0; + } + + /* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */ + /* Chained Mode */ + /* Selects the next DMA Tx descriptor list for next buffer to send */ + gd32_emac_device->DMATxDescToSet = (EMAC_DMADESCTypeDef*) (gd32_emac_device->DMATxDescToSet->Buffer2NextDescAddr); + + /* Return SUCCESS */ + return RT_EOK; +} + +/* reception a Ethernet packet. */ +struct pbuf * gd32_emac_rx(rt_device_t dev) +{ + struct pbuf* p; + rt_uint32_t framelength = 0; + struct gd32_emac * gd32_emac_device; + struct rt_synopsys_eth * ETHERNET_MAC; + + gd32_emac_device = (struct gd32_emac *)dev; + ETHERNET_MAC = gd32_emac_device->ETHERNET_MAC; + + /* init p pointer */ + p = RT_NULL; + + /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */ + if(((gd32_emac_device->DMARxDescToGet->Status & EMAC_DMARxDesc_OWN) != (uint32_t)RESET)) + { + return p; + } + + if (((gd32_emac_device->DMARxDescToGet->Status & EMAC_DMARxDesc_ES) == (uint32_t)RESET) && + ((gd32_emac_device->DMARxDescToGet->Status & EMAC_DMARxDesc_LS) != (uint32_t)RESET) && + ((gd32_emac_device->DMARxDescToGet->Status & EMAC_DMARxDesc_FS) != (uint32_t)RESET)) + { + /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ + framelength = ((gd32_emac_device->DMARxDescToGet->Status & EMAC_DMARxDesc_FL) + >> EMAC_DMARXDESC_FRAME_LENGTHSHIFT) - 4; + + /* allocate buffer */ + p = pbuf_alloc(PBUF_LINK, framelength, PBUF_RAM); + if (p != RT_NULL) + { + const char * from; + struct pbuf* q; + + from = (const char *)gd32_emac_device->DMARxDescToGet->Buffer1Addr; + + for (q = p; q != RT_NULL; q= q->next) + { + /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */ + memcpy(q->payload, from, q->len); + from += q->len; + } +#ifdef EMAC_RX_DUMP + { + rt_uint32_t i; + rt_uint8_t *ptr = (rt_uint8_t*)(gd32_emac_device->DMARxDescToGet->Buffer1Addr); + + EMAC_TRACE("\r\n%c%c rx_dump:", gd32_emac_device->parent.netif->name[0], gd32_emac_device->parent.netif->name[1]); + for(i=0; itot_len; i++) + { + if( (i%8) == 0 ) + { + EMAC_TRACE(" "); + } + if( (i%16) == 0 ) + { + EMAC_TRACE("\r\n"); + } + EMAC_TRACE("%02x ",*ptr); + ptr++; + } + EMAC_TRACE("\r\ndump done!\r\n"); + } +#endif + } + } + + /* Set Own bit of the Rx descriptor Status: gives the buffer back to ETHERNET DMA */ + gd32_emac_device->DMARxDescToGet->Status = EMAC_DMARxDesc_OWN; + + /* When Rx Buffer unavailable flag is set: clear it and resume reception */ + if ((ETHERNET_MAC->SR & EMAC_DMASR_RBUS) != (uint32_t)RESET) + { + /* Clear RBUS ETHERNET DMA flag */ + ETHERNET_MAC->SR = EMAC_DMASR_RBUS; + /* Resume DMA reception */ + ETHERNET_MAC->RPDR = 0; + } + + /* Update the ETHERNET DMA global Rx descriptor with next Rx decriptor */ + /* Chained Mode */ + if((gd32_emac_device->DMARxDescToGet->ControlBufferSize & EMAC_DMARxDesc_RCH) != (uint32_t)RESET) + { + /* Selects the next DMA Rx descriptor list for next buffer to read */ + gd32_emac_device->DMARxDescToGet = (EMAC_DMADESCTypeDef*) (gd32_emac_device->DMARxDescToGet->Buffer2NextDescAddr); + } + else /* Ring Mode */ + { + if((gd32_emac_device->DMARxDescToGet->ControlBufferSize & EMAC_DMARxDesc_RER) != (uint32_t)RESET) + { + /* Selects the first DMA Rx descriptor for next buffer to read: last Rx descriptor was used */ + gd32_emac_device->DMARxDescToGet = (EMAC_DMADESCTypeDef*) (ETHERNET_MAC->RDLAR); + } + else + { + /* Selects the next DMA Rx descriptor list for next buffer to read */ + gd32_emac_device->DMARxDescToGet = (EMAC_DMADESCTypeDef*) ((uint32_t)gd32_emac_device->DMARxDescToGet + 0x10 + ((ETHERNET_MAC->BMR & EMAC_DMABMR_DSL) >> 2)); + } + } + + return p; +} + +/*! + \brief configures the nested vectored interrupt controller + \param[in] none + \param[out] none + \retval none +*/ +static void nvic_configuration(void) +{ + nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x0); + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + nvic_irq_enable(ENET_IRQn, 0, 0); +} + +/*! + \brief configures the different GPIO ports + \param[in] none + \param[out] none + \retval none +*/ +static void enet_gpio_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_GPIOD); + rcu_periph_clock_enable(RCU_GPIOG); + rcu_periph_clock_enable(RCU_GPIOH); + rcu_periph_clock_enable(RCU_GPIOI); + + gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_8); + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_8); + + /* enable SYSCFG clock */ + rcu_periph_clock_enable(RCU_SYSCFG); + + /* choose DIV2 to get 50MHz from 200MHz on CKOUT0 pin (PA8) to clock the PHY */ + rcu_ckout0_config(RCU_CKOUT0SRC_PLLP, RCU_CKOUT0_DIV4); + syscfg_enet_phy_interface_config(SYSCFG_ENET_PHY_RMII); + + /* PA1: ETH_RMII_REF_CLK */ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_1); + + /* PA2: ETH_MDIO */ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_2); + + /* PA7: ETH_RMII_CRS_DV */ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_7); + + gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_1); + gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_2); + gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_7); + + /* PB11: ETH_RMII_TX_EN */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_11); + + /* PB12: ETH_RMII_TXD0 */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_12); + + /* PB13: ETH_RMII_TXD1 */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_13); + + gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_11); + gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_12); + gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_13); + + /* PC1: ETH_MDC */ + gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); + gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_1); + + /* PC4: ETH_RMII_RXD0 */ + gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4); + gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_4); + + /* PC5: ETH_RMII_RXD1 */ + gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); + gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_5); + + gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_1); + gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_4); + gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_5); +} + + +int rt_hw_gd32_eth_init(void) +{ + rt_kprintf("rt_gd32_eth_init...\n"); + + /* enable ethernet clock */ + rcu_periph_clock_enable(RCU_ENET); + rcu_periph_clock_enable(RCU_ENETTX); + rcu_periph_clock_enable(RCU_ENETRX); + + nvic_configuration(); + + /* configure the GPIO ports for ethernet pins */ + enet_gpio_config(); + + /* set autonegotiation mode */ + gd32_emac_device0.phy_mode = EMAC_PHY_AUTO; + gd32_emac_device0.ETHERNET_MAC = ETHERNET_MAC0; + gd32_emac_device0.ETHER_MAC_IRQ = ENET_IRQn; + + // OUI 00-00-0E FUJITSU LIMITED + gd32_emac_device0.dev_addr[0] = 0x00; + gd32_emac_device0.dev_addr[1] = 0x00; + gd32_emac_device0.dev_addr[2] = 0x0E; + /* set mac address: (only for test) */ + gd32_emac_device0.dev_addr[3] = 0x12; + gd32_emac_device0.dev_addr[4] = 0x34; + gd32_emac_device0.dev_addr[5] = 0x56; + + gd32_emac_device0.parent.parent.init = gd32_emac_init; + gd32_emac_device0.parent.parent.open = gd32_emac_open; + gd32_emac_device0.parent.parent.close = gd32_emac_close; + gd32_emac_device0.parent.parent.read = gd32_emac_read; + gd32_emac_device0.parent.parent.write = gd32_emac_write; + gd32_emac_device0.parent.parent.control = gd32_emac_control; + gd32_emac_device0.parent.parent.user_data = RT_NULL; + + gd32_emac_device0.parent.eth_rx = gd32_emac_rx; + gd32_emac_device0.parent.eth_tx = gd32_emac_tx; + + /* init tx buffer free semaphore */ + rt_sem_init(&gd32_emac_device0.tx_buf_free, "tx_buf0", EMAC_TXBUFNB, RT_IPC_FLAG_FIFO); + eth_device_init(&(gd32_emac_device0.parent), "e0"); + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_gd32_eth_init); diff --git a/bsp/gd32450z-eval/drivers/drv_exmc_sdram.c b/bsp/gd32450z-eval/drivers/drv_exmc_sdram.c new file mode 100644 index 0000000000..41355987b5 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_exmc_sdram.c @@ -0,0 +1,315 @@ +/*! + \file main.c + \brief exmc sdram(MICRON 48LC16M16A2) driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, demo for GD32F4xx +*/ + +#include "gd32f4xx.h" +#include "drv_exmc_sdram.h" +#include + +/* define mode register content */ +/* burst length */ +#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) +#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) +#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0003) + +/* burst type */ +#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) + +/* CAS latency */ +#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) +#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) + +/* write mode */ +#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) + +#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) + +#define SDRAM_TIMEOUT ((uint32_t)0x0000FFFF) + +static void delay_1ms(volatile uint32_t count) +{ + count *= 1000; + while (count--) + { + count = count; + } +} + +/*! + \brief sdram peripheral initialize + \param[in] sdram_device: specifie the SDRAM device + \param[out] none + \retval none +*/ +void exmc_synchronous_dynamic_ram_init(uint32_t sdram_device) +{ + exmc_sdram_parameter_struct sdram_init_struct; + exmc_sdram_timing_parameter_struct sdram_timing_init_struct; + exmc_sdram_command_parameter_struct sdram_command_init_struct; + + uint32_t command_content = 0, bank_select; + uint32_t timeout = SDRAM_TIMEOUT; + + /* enable EXMC clock*/ + rcu_periph_clock_enable(RCU_EXMC); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_GPIOD); + rcu_periph_clock_enable(RCU_GPIOE); + rcu_periph_clock_enable(RCU_GPIOF); + rcu_periph_clock_enable(RCU_GPIOG); + rcu_periph_clock_enable(RCU_GPIOH); + + /* common GPIO configuration */ + /* SDNWE(PC0),SDNE0(PC2),SDCKE0(PC3) pin configuration */ + gpio_af_set(GPIOC, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3); + gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3); + gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3); + + /* D2(PD0),D3(PD1),D13(PD8),D14(PD9),D15(PD10),D0(PD14),D1(PD15) pin configuration */ + gpio_af_set(GPIOD, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | + GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15); + gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | + GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15); + gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | + GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15); + + /* NBL0(PE0),NBL1(PE1),D4(PE7),D5(PE8),D6(PE9),D7(PE10),D8(PE11),D9(PE12),D10(PE13),D11(PE14),D12(PE15) pin configuration */ + gpio_af_set(GPIOE, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 | GPIO_PIN_8 | + GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); + gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 | GPIO_PIN_8 | + GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); + gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 | GPIO_PIN_8 | + GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); + + /* A0(PF0),A1(PF1),A2(PF2),A3(PF3),A4(PF4),A5(PF5),NRAS(PF11),A6(PF12),A7(PF13),A8(PF14),A9(PF15) pin configuration */ + gpio_af_set(GPIOF, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | + GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); + gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | + GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); + gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | + GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | + GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15); + + /* A10(PG0),A11(PG1),A12(PG2),A14(PG4),A15(PG5),SDCLK(PG8),NCAS(PG15) pin configuration */ + gpio_af_set(GPIOG, GPIO_AF_12, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | + GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15); + gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | + GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15); + gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | + GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15); + + /* specify which SDRAM to read and write */ + if(EXMC_SDRAM_DEVICE0 == sdram_device){ + bank_select = EXMC_SDRAM_DEVICE0_SELECT; + }else{ + bank_select = EXMC_SDRAM_DEVICE1_SELECT; + } + + /* EXMC SDRAM device initialization sequence --------------------------------*/ + /* Step 1 : configure SDRAM timing registers --------------------------------*/ + /* LMRD: 2 clock cycles */ + sdram_timing_init_struct.load_mode_register_delay = 2; + /* XSRD: min = 67ns */ + sdram_timing_init_struct.exit_selfrefresh_delay = 7; + /* RASD: min=42ns , max=120k (ns) */ + sdram_timing_init_struct.row_address_select_delay = 5; + /* ARFD: min=60ns */ + sdram_timing_init_struct.auto_refresh_delay = 6; + /* WRD: min=1 Clock cycles +6ns */ + sdram_timing_init_struct.write_recovery_delay = 2; + /* RPD: min=18ns */ + sdram_timing_init_struct.row_precharge_delay = 2; + /* RCD: min=18ns */ + sdram_timing_init_struct.row_to_column_delay = 2; + + /* step 2 : configure SDRAM control registers ---------------------------------*/ + sdram_init_struct.sdram_device = sdram_device; + sdram_init_struct.column_address_width = EXMC_SDRAM_COW_ADDRESS_9; + sdram_init_struct.row_address_width = EXMC_SDRAM_ROW_ADDRESS_13; + sdram_init_struct.data_width = EXMC_SDRAM_DATABUS_WIDTH_16B; + sdram_init_struct.internal_bank_number = EXMC_SDRAM_4_INTER_BANK; + sdram_init_struct.cas_latency = EXMC_CAS_LATENCY_3_SDCLK; + sdram_init_struct.write_protection = DISABLE; + sdram_init_struct.sdclock_config = EXMC_SDCLK_PERIODS_2_HCLK; + sdram_init_struct.brust_read_switch = ENABLE; + sdram_init_struct.pipeline_read_delay = EXMC_PIPELINE_DELAY_1_HCLK; + sdram_init_struct.timing = &sdram_timing_init_struct; + /* EXMC SDRAM bank initialization */ + exmc_sdram_init(&sdram_init_struct); + + /* step 3 : configure CKE high command---------------------------------------*/ + sdram_command_init_struct.command = EXMC_SDRAM_CLOCK_ENABLE; + sdram_command_init_struct.bank_select = bank_select; + sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_1_SDCLK; + sdram_command_init_struct.mode_register_content = 0; + /* wait until the SDRAM controller is ready */ + while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)){ + timeout--; + } + /* send the command */ + exmc_sdram_command_config(&sdram_command_init_struct); + + /* step 4 : insert 10ms delay----------------------------------------------*/ + delay_1ms(10); + + /* step 5 : configure precharge all command----------------------------------*/ + sdram_command_init_struct.command = EXMC_SDRAM_PRECHARGE_ALL; + sdram_command_init_struct.bank_select = bank_select; + sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_1_SDCLK; + sdram_command_init_struct.mode_register_content = 0; + /* wait until the SDRAM controller is ready */ + timeout = SDRAM_TIMEOUT; + while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)){ + timeout--; + } + /* send the command */ + exmc_sdram_command_config(&sdram_command_init_struct); + + /* step 6 : configure Auto-Refresh command-----------------------------------*/ + sdram_command_init_struct.command = EXMC_SDRAM_AUTO_REFRESH; + sdram_command_init_struct.bank_select = bank_select; + sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_8_SDCLK; + sdram_command_init_struct.mode_register_content = 0; + /* wait until the SDRAM controller is ready */ + timeout = SDRAM_TIMEOUT; + while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)){ + timeout--; + } + /* send the command */ + exmc_sdram_command_config(&sdram_command_init_struct); + + /* step 7 : configure load mode register command-----------------------------*/ + /* program mode register */ + command_content = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | + SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | + SDRAM_MODEREG_CAS_LATENCY_3 | + SDRAM_MODEREG_OPERATING_MODE_STANDARD | + SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; + + sdram_command_init_struct.command = EXMC_SDRAM_LOAD_MODE_REGISTER; + sdram_command_init_struct.bank_select = bank_select; + sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_1_SDCLK; + sdram_command_init_struct.mode_register_content = command_content; + + /* wait until the SDRAM controller is ready */ + timeout = SDRAM_TIMEOUT; + while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)){ + timeout--; + } + /* send the command */ + exmc_sdram_command_config(&sdram_command_init_struct); + + /* step 8 : set the auto-refresh rate counter--------------------------------*/ + /* 64ms, 8192-cycle refresh, 64ms/8192=7.81us */ + /* SDCLK_Freq = SYS_Freq/2 */ + /* (7.81 us * SDCLK_Freq) - 20 */ + exmc_sdram_refresh_count_set(761); + + /* wait until the SDRAM controller is ready */ + timeout = SDRAM_TIMEOUT; + while((exmc_flag_get(sdram_device, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)){ + timeout--; + } +} + +/*! + \brief fill the buffer with specified value + \param[in] pbuffer: pointer on the buffer to fill + \param[in] buffersize: size of the buffer to fill + \param[in] value: value to fill on the buffer + \param[out] none + \retval none +*/ +void fill_buffer(uint8_t *pbuffer, uint16_t buffer_lengh, uint16_t offset) +{ + uint16_t index = 0; + + /* put in global buffer same values */ + for (index = 0; index < buffer_lengh; index++ ){ + pbuffer[index] = index + offset; + } +} + +/*! + \brief write a byte buffer(data is 8 bits) to the EXMC SDRAM memory + \param[in] sdram_device: specify which a SDRAM memory block is written + \param[in] pbuffer: pointer to buffer + \param[in] writeaddr: SDRAM memory internal address from which the data will be written + \param[in] numbytetowrite: number of bytes to write + \param[out] none + \retval none +*/ +void sdram_writebuffer_8(uint32_t sdram_device,uint8_t* pbuffer, uint32_t writeaddr, uint32_t numbytetowrite) +{ + uint32_t temp_addr; + + /* Select the base address according to EXMC_Bank */ + if(sdram_device == EXMC_SDRAM_DEVICE0){ + temp_addr = SDRAM_DEVICE0_ADDR; + }else{ + temp_addr = SDRAM_DEVICE1_ADDR; + } + + /* While there is data to write */ + for(; numbytetowrite != 0; numbytetowrite--) { + /* Transfer data to the memory */ + *(uint8_t *) (temp_addr + writeaddr) = *pbuffer++; + + /* Increment the address*/ + writeaddr += 1; + } +} + +/*! + \brief read a block of 8-bit data from the EXMC SDRAM memory + \param[in] sdram_device: specify which a SDRAM memory block is written + \param[in] pbuffer: pointer to buffer + \param[in] readaddr: SDRAM memory internal address to read from + \param[in] numbytetoread: number of bytes to read + \param[out] none + \retval none +*/ +void sdram_readbuffer_8(uint32_t sdram_device,uint8_t* pbuffer, uint32_t readaddr, uint32_t numbytetoread) +{ + uint32_t temp_addr; + + /* select the base address according to EXMC_Bank */ + if(sdram_device == EXMC_SDRAM_DEVICE0){ + temp_addr = SDRAM_DEVICE0_ADDR; + }else{ + temp_addr = SDRAM_DEVICE1_ADDR; + } + + /* while there is data to read */ + for(; numbytetoread != 0; numbytetoread--){ + /* read a byte from the memory */ + *pbuffer++ = *(uint8_t*) (temp_addr + readaddr); + + /* increment the address */ + readaddr += 1; + } +} + +int rt_hw_sdram_init(void) +{ + exmc_synchronous_dynamic_ram_init(EXMC_SDRAM_DEVICE0); + return 0; +} +INIT_BOARD_EXPORT(rt_hw_sdram_init); + diff --git a/bsp/gd32450z-eval/drivers/drv_exmc_sdram.h b/bsp/gd32450z-eval/drivers/drv_exmc_sdram.h new file mode 100644 index 0000000000..b859d36226 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_exmc_sdram.h @@ -0,0 +1,32 @@ +/*! + \file exmc_nandflash.h + \brief the header file of sdram(MICRON 48LC16M16A2) driver +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, demo for GD32F4xx +*/ + +#ifndef EXMC_SDRAM_H +#define EXMC_SDRAM_H + +#include "gd32f4xx.h" + +/* sdram peripheral initialize */ +void exmc_synchronous_dynamic_ram_init(uint32_t sdram_device); + +/* fill the buffer with specified value */ +void fill_buffer(uint8_t *pbuffer, uint16_t buffer_lengh, uint16_t offset); + +/* write a byte buffer(data is 8 bits) to the EXMC SDRAM memory */ +void sdram_writebuffer_8(uint32_t sdram_device,uint8_t* pbuffer, uint32_t writeaddr, uint32_t numbytetowrite); + +/* read a block of 8-bit data from the EXMC SDRAM memory */ +void sdram_readbuffer_8(uint32_t sdram_device,uint8_t* pbuffer, uint32_t readaddr, uint32_t numbytetoread); + +#define SDRAM_DEVICE0_ADDR ((uint32_t)0xC0000000) +#define SDRAM_DEVICE1_ADDR ((uint32_t)0xD0000000) + +#endif /* EXMC_SDRAM_H */ diff --git a/bsp/gd32450z-eval/drivers/drv_lcd.c b/bsp/gd32450z-eval/drivers/drv_lcd.c new file mode 100644 index 0000000000..fd7880f73a --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_lcd.c @@ -0,0 +1,268 @@ +/* + * File : usart.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-08-23 Tanek the first version + */ + +#include "gd32f450z_lcd_eval.h" +#include +#include +#include +#include + +#ifdef RT_USING_GUIENGINE + + +#define RT_HW_LCD_WIDTH ((uint16_t)320) /* LCD PIXEL WIDTH */ +#define RT_HW_LCD_HEIGHT ((uint16_t)480) /* LCD PIXEL HEIGHT */ + +#define LCD_480_320_HSYNC ((uint32_t)10) /* Horizontal synchronization */ +#define LCD_480_320_HBP ((uint32_t)20) /* Horizontal back porch */ +#define LCD_480_320_HFP ((uint32_t)40) /* Horizontal front porch */ +#define LCD_480_320_VSYNC ((uint32_t)2) /* Vertical synchronization */ +#define LCD_480_320_VBP ((uint32_t)1) /* Vertical back porch */ +#define LCD_480_320_VFP ((uint32_t)4) /* Vertical front porch */ + +#define LCD_BITS_PER_PIXEL 16 + + +static rt_uint16_t *lcd_framebuffer = RT_NULL; +static rt_uint16_t *_rt_framebuffer = RT_NULL; + +static struct rt_device_graphic_info _lcd_info; +static struct rt_device lcd; + +/*! + \brief configure TLI GPIO + \param[in] none + \param[out] none + \retval none +*/ +static void tli_gpio_config(void) +{ + /* enable the periphral clock */ + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_GPIOD); + rcu_periph_clock_enable(RCU_GPIOF); + rcu_periph_clock_enable(RCU_GPIOG); + + /* configure HSYNC(PC6), VSYNC(PA4), PCLK(PG7), DE(PF10) */ + /* configure LCD_R7(PG6), LCD_R6(PA8), LCD_R5(PA12), LCD_R4(PA11), LCD_R3(PB0), + LCD_G7(PD3), LCD_G6(PC7), LCD_G5(PB11), LCD_G4(PB10), LCD_G3(PG10), LCD_G2(PA6), + LCD_B7(PB9), LCD_B6(PB8), LCD_B5(PA3), LCD_B4(PG12), LCD_B3(PG11) */ + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_3); + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_4); + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_6); + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_12); + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_11); + gpio_af_set(GPIOA,GPIO_AF_14,GPIO_PIN_8); + + gpio_af_set(GPIOB,GPIO_AF_9,GPIO_PIN_0); + gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_10); + //gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_11); + gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_8); + gpio_af_set(GPIOB,GPIO_AF_14,GPIO_PIN_9); + + gpio_af_set(GPIOC,GPIO_AF_14,GPIO_PIN_6); + gpio_af_set(GPIOC,GPIO_AF_14,GPIO_PIN_7); + + gpio_af_set(GPIOD,GPIO_AF_14,GPIO_PIN_3); + + gpio_af_set(GPIOF,GPIO_AF_14,GPIO_PIN_10); + + gpio_af_set(GPIOG,GPIO_AF_14,GPIO_PIN_6); + gpio_af_set(GPIOG,GPIO_AF_14,GPIO_PIN_7); + gpio_af_set(GPIOG,GPIO_AF_9,GPIO_PIN_10); + gpio_af_set(GPIOG,GPIO_AF_14,GPIO_PIN_11); + gpio_af_set(GPIOG,GPIO_AF_9,GPIO_PIN_12); + + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_6 + |GPIO_PIN_8|GPIO_PIN_11|GPIO_PIN_12); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4|GPIO_PIN_3 + |GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_11|GPIO_PIN_12); + + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 + /*|GPIO_PIN_11*/); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 + /*|GPIO_PIN_11*/); + + gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6|GPIO_PIN_7); + gpio_output_options_set(GPIOC, GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ, GPIO_PIN_6|GPIO_PIN_7); + + gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3); + gpio_output_options_set(GPIOD, GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ, GPIO_PIN_3); + + gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10); + gpio_output_options_set(GPIOF, GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ, GPIO_PIN_10); + + gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_11 + |GPIO_PIN_12); + gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_11 + |GPIO_PIN_12); +} + +/*! + \brief LCD Configuration + \param[in] none + \param[out] none + \retval none +*/ +static void lcd_config(void) +{ + /* configure the LCD control line */ + lcd_ctrl_line_config(); + lcd_disable(); + lcd_enable(); + + /* configure the GPIO of TLI */ + tli_gpio_config(); + /* configure the LCD_SPI */ + lcd_spi_config(); + + /* power on the LCD */ + //lcd_power_on(); + lcd_power_on3(); //New Version 3.5" TFT RGB Hardware needs use this initilize funtion ---By xufei 2016.10.21 +} + +/*! + \brief configure TLI peripheral + \param[in] none + \param[out] none + \retval none +*/ +static void tli_config(void) +{ + tli_parameter_struct tli_init_struct; + tli_layer_parameter_struct tli_layer_init_struct; + + rcu_periph_clock_enable(RCU_TLI); + + /* configure the PLLSAI clock to generate lcd clock */ + if(ERROR == rcu_pllsai_config(192, 2, 3, 3)){ + while(1); + } + rcu_tli_clock_div_config(RCU_PLLSAIR_DIV8); + rcu_osci_on(RCU_PLLSAI_CK); + if(ERROR == rcu_osci_stab_wait(RCU_PLLSAI_CK)){ + while(1); + } + + /* TLI initialization */ + tli_init_struct.signalpolarity_hs = TLI_HSYN_ACTLIVE_LOW; + tli_init_struct.signalpolarity_vs = TLI_VSYN_ACTLIVE_LOW; + tli_init_struct.signalpolarity_de = TLI_DE_ACTLIVE_LOW; + tli_init_struct.signalpolarity_pixelck = TLI_PIXEL_CLOCK_TLI; + + /* LCD display timing configuration */ + tli_init_struct.synpsz_hpsz = LCD_480_320_HSYNC; + tli_init_struct.synpsz_vpsz = LCD_480_320_VSYNC; + tli_init_struct.backpsz_hbpsz = LCD_480_320_HSYNC + LCD_480_320_HBP; + tli_init_struct.backpsz_vbpsz = LCD_480_320_VSYNC + LCD_480_320_VBP; + tli_init_struct.activesz_hasz = RT_HW_LCD_WIDTH + LCD_480_320_HSYNC + LCD_480_320_HBP; + tli_init_struct.activesz_vasz = RT_HW_LCD_HEIGHT + LCD_480_320_VSYNC + LCD_480_320_VBP; + tli_init_struct.totalsz_htsz = RT_HW_LCD_WIDTH + LCD_480_320_HSYNC + LCD_480_320_HBP + LCD_480_320_HFP; + tli_init_struct.totalsz_vtsz = RT_HW_LCD_HEIGHT + LCD_480_320_VSYNC + LCD_480_320_VBP + LCD_480_320_VFP; + + /* LCD background color configure*/ + tli_init_struct.backcolor_red = 0x00; + tli_init_struct.backcolor_green = 0x00; + tli_init_struct.backcolor_blue = 0x00; + tli_init(&tli_init_struct); + + lcd_framebuffer = rt_malloc(sizeof(rt_uint16_t) * RT_HW_LCD_HEIGHT * RT_HW_LCD_WIDTH); + RT_ASSERT(lcd_framebuffer != NULL); + rt_memset(lcd_framebuffer, 0, sizeof(rt_uint16_t) * RT_HW_LCD_WIDTH * RT_HW_LCD_HEIGHT); + + /* TLI layer0 configuration */ + tli_layer_init_struct.layer_window_leftpos = tli_init_struct.backpsz_hbpsz + 1; + tli_layer_init_struct.layer_window_rightpos = tli_init_struct.backpsz_hbpsz + RT_HW_LCD_WIDTH; + tli_layer_init_struct.layer_window_toppos = tli_init_struct.backpsz_vbpsz + 1; + tli_layer_init_struct.layer_window_bottompos = tli_init_struct.backpsz_vbpsz + RT_HW_LCD_HEIGHT; + + tli_layer_init_struct.layer_ppf = LAYER_PPF_RGB565; + tli_layer_init_struct.layer_sa = 0xFF; + tli_layer_init_struct.layer_default_blue = 0x00; + tli_layer_init_struct.layer_default_green = 0x00; + tli_layer_init_struct.layer_default_red = 0x00; + tli_layer_init_struct.layer_default_alpha = 0x00; + tli_layer_init_struct.layer_acf1 = LAYER_ACF1_PASA; + tli_layer_init_struct.layer_acf2 = LAYER_ACF2_PASA; + tli_layer_init_struct.layer_frame_bufaddr = (uint32_t)lcd_framebuffer; + tli_layer_init_struct.layer_frame_line_length = ((RT_HW_LCD_WIDTH * 2) + 3); + tli_layer_init_struct.layer_frame_buf_stride_offset = (RT_HW_LCD_WIDTH * 2); + tli_layer_init_struct.layer_frame_total_line_number = RT_HW_LCD_HEIGHT; + + tli_layer_init(LAYER0, &tli_layer_init_struct); +} + +static rt_err_t rt_lcd_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + switch (cmd) + { + case RTGRAPHIC_CTRL_RECT_UPDATE: + { + memcpy((void *)lcd_framebuffer, _rt_framebuffer, sizeof(rt_uint16_t)*RT_HW_LCD_HEIGHT * RT_HW_LCD_WIDTH); + } + break; + + case RTGRAPHIC_CTRL_POWERON: + break; + + case RTGRAPHIC_CTRL_POWEROFF: + break; + + case RTGRAPHIC_CTRL_GET_INFO: + memcpy(args, &_lcd_info, sizeof(_lcd_info)); + break; + + case RTGRAPHIC_CTRL_SET_MODE: + break; + } + + return RT_EOK; +} + +int gd32_hw_lcd_init(void) +{ + _rt_framebuffer = rt_malloc_align(sizeof(rt_uint16_t) * RT_HW_LCD_WIDTH * RT_HW_LCD_HEIGHT, 32); + if (_rt_framebuffer == RT_NULL) + return -1; /* no memory yet */ + + lcd_config(); + tli_config(); + tli_layer_enable(LAYER0); + tli_reload_config(TLI_FRAME_BLANK_RELOAD_EN); + tli_enable(); + + _lcd_info.bits_per_pixel = LCD_BITS_PER_PIXEL; + _lcd_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565; + _lcd_info.framebuffer = (void *)_rt_framebuffer; + _lcd_info.width = RT_HW_LCD_WIDTH; + _lcd_info.height = RT_HW_LCD_HEIGHT; + + lcd.type = RT_Device_Class_Graphic; + lcd.init = NULL; + lcd.open = NULL; + lcd.close = NULL; + lcd.read = NULL; + lcd.write = NULL; + lcd.control = rt_lcd_control; + lcd.user_data = (void *)&_lcd_info; + + /* register lcd device to RT-Thread */ + rt_device_register(&lcd, "lcd", RT_DEVICE_FLAG_RDWR); + + return 0; +} +INIT_DEVICE_EXPORT(gd32_hw_lcd_init); +#endif diff --git a/bsp/gd32450z-eval/drivers/drv_spi.c b/bsp/gd32450z-eval/drivers/drv_spi.c new file mode 100644 index 0000000000..4f116d7d68 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_spi.c @@ -0,0 +1,329 @@ +/* + * File : drv_spi.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-06-05 tanek first implementation. + */ + +#include "drv_spi.h" + +#include +#include + +#ifdef RT_USING_SPI + +#if !defined(RT_USING_SPI0) && !defined(RT_USING_SPI1) && \ + !defined(RT_USING_SPI2) && !defined(RT_USING_SPI3) && \ + !defined(RT_USING_SPI4) && !defined(RT_USING_SPI5) +#error "Please define at least one SPIx" +#endif + +//#define DEBUG + +#define ARR_LEN(__N) (sizeof(__N) / sizeof(__N[0])) + +#ifdef DEBUG +#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +/* private rt-thread spi ops function */ +static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration); +static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message); + +static struct rt_spi_ops gd32_spi_ops = +{ + configure, + xfer +}; + +static rt_err_t configure(struct rt_spi_device* device, + struct rt_spi_configuration* configuration) +{ + struct rt_spi_bus * spi_bus = (struct rt_spi_bus *)device->bus; + struct gd32f4_spi *f4_spi = (struct gd32f4_spi *)spi_bus->parent.user_data; + + spi_parameter_struct spi_init_struct; + + uint32_t spi_periph = f4_spi->spi_periph; + + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(configuration != RT_NULL); + + /* data_width */ + if(configuration->data_width <= 8) + { + spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; + } + else if(configuration->data_width <= 16) + { + spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT; + } + else + { + return RT_EIO; + } + + /* baudrate */ + { + rcu_clock_freq_enum spi_src; + uint32_t spi_apb_clock; + uint32_t max_hz; + + max_hz = configuration->max_hz; + + DEBUG_PRINTF("sys freq: %d\n", HAL_RCC_GetSysClockFreq()); + DEBUG_PRINTF("pclk2 freq: %d\n", HAL_RCC_GetPCLK2Freq()); + DEBUG_PRINTF("max freq: %d\n", max_hz); + + if (spi_periph == SPI1 || spi_periph == SPI2) + { + spi_src = CK_APB1; + } + else + { + spi_src = CK_APB2; + } + spi_apb_clock = rcu_clock_freq_get(spi_src); + + if(max_hz >= spi_apb_clock/2) + { + spi_init_struct.prescale = SPI_PSC_2; + } + else if (max_hz >= spi_apb_clock/4) + { + spi_init_struct.prescale = SPI_PSC_4; + } + else if (max_hz >= spi_apb_clock/8) + { + spi_init_struct.prescale = SPI_PSC_8; + } + else if (max_hz >= spi_apb_clock/16) + { + spi_init_struct.prescale = SPI_PSC_16; + } + else if (max_hz >= spi_apb_clock/32) + { + spi_init_struct.prescale = SPI_PSC_32; + } + else if (max_hz >= spi_apb_clock/64) + { + spi_init_struct.prescale = SPI_PSC_64; + } + else if (max_hz >= spi_apb_clock/128) + { + spi_init_struct.prescale = SPI_PSC_128; + } + else + { + /* min prescaler 256 */ + spi_init_struct.prescale = SPI_PSC_256; + } + } /* baudrate */ + + switch(configuration->mode) + { + case RT_SPI_MODE_0: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; + break; + case RT_SPI_MODE_1: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE; + break; + case RT_SPI_MODE_2: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE; + break; + case RT_SPI_MODE_3: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; + break; + } + + /* MSB or LSB */ + if(configuration->mode & RT_SPI_MSB) + { + spi_init_struct.endian = SPI_ENDIAN_MSB; + } + else + { + spi_init_struct.endian = SPI_ENDIAN_LSB; + } + + spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_init_struct.device_mode = SPI_MASTER; + spi_init_struct.nss = SPI_NSS_SOFT; + + spi_crc_off(spi_periph); + + /* init SPI */ + spi_init(spi_periph, &spi_init_struct); + /* Enable SPI_MASTER */ + spi_enable(spi_periph); + + return RT_EOK; +}; + +static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message) +{ + struct rt_spi_bus * gd32_spi_bus = (struct rt_spi_bus *)device->bus; + struct gd32f4_spi *f4_spi = (struct gd32f4_spi *)gd32_spi_bus->parent.user_data; + struct rt_spi_configuration * config = &device->config; + struct gd32_spi_cs * gd32_spi_cs = device->parent.user_data; + uint32_t spi_periph = f4_spi->spi_periph; + + RT_ASSERT(device != NULL); + RT_ASSERT(message != NULL); + + /* take CS */ + if(message->cs_take) + { + gpio_bit_reset(gd32_spi_cs->GPIOx, gd32_spi_cs->GPIO_Pin); + DEBUG_PRINTF("spi take cs\n"); + } + + { + if(config->data_width <= 8) + { + const rt_uint8_t * send_ptr = message->send_buf; + rt_uint8_t * recv_ptr = message->recv_buf; + rt_uint32_t size = message->length; + + DEBUG_PRINTF("spi poll transfer start: %d\n", size); + + while(size--) + { + rt_uint8_t data = 0xFF; + + if(send_ptr != RT_NULL) + { + data = *send_ptr++; + } + + // Todo: replace register read/write by gd32f4 lib + //Wait until the transmit buffer is empty + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)); + // Send the byte + spi_i2s_data_transmit(spi_periph, data); + + //Wait until a data is received + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)); + // Get the received data + data = spi_i2s_data_receive(spi_periph); + + if(recv_ptr != RT_NULL) + { + *recv_ptr++ = data; + } + } + DEBUG_PRINTF("spi poll transfer finsh\n"); + } + else if(config->data_width <= 16) + { + const rt_uint16_t * send_ptr = message->send_buf; + rt_uint16_t * recv_ptr = message->recv_buf; + rt_uint32_t size = message->length; + + while(size--) + { + rt_uint16_t data = 0xFF; + + if(send_ptr != RT_NULL) + { + data = *send_ptr++; + } + + //Wait until the transmit buffer is empty + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)); + // Send the byte + spi_i2s_data_transmit(spi_periph, data); + + //Wait until a data is received + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)); + // Get the received data + data = spi_i2s_data_receive(spi_periph); + + if(recv_ptr != RT_NULL) + { + *recv_ptr++ = data; + } + } + } + } + + /* release CS */ + if(message->cs_release) + { + gpio_bit_set(gd32_spi_cs->GPIOx, gd32_spi_cs->GPIO_Pin); + DEBUG_PRINTF("spi release cs\n"); + } + + return message->length; +}; + + +static struct rt_spi_bus spi_bus[]; + +static const struct gd32f4_spi spis[] = { +#ifdef RT_USING_SPI0 + {SPI0, RCU_SPI0, &spi_bus[0]}, +#endif + +#ifdef RT_USING_SPI1 + {SPI1, RCU_SPI1, &spi_bus[1]}, +#endif + +#ifdef RT_USING_SPI2 + {SPI2, RCU_SPI2, &spi_bus[2]}, +#endif + +#ifdef RT_USING_SPI3 + {SPI3, RCU_SPI3, &spi_bus[3]}, +#endif + +#ifdef RT_USING_SPI4 + {SPI4, RCU_SPI4, &spi_bus[4]}, +#endif + +#ifdef RT_USING_SPI5 + {SPI5, RCU_SPI5, &spi_bus[5]}, +#endif +}; + +static struct rt_spi_bus spi_bus[ARR_LEN(spis)]; + +/** \brief init and register gd32 spi bus. + * + * \param SPI: gd32 SPI, e.g: SPI1,SPI2,SPI3. + * \param spi_bus_name: spi bus name, e.g: "spi1" + * \return + * + */ +rt_err_t gd32_spi_bus_register(uint32_t spi_periph, + //struct gd32_spi_bus * gd32_spi, + const char * spi_bus_name) +{ + int i; + + RT_ASSERT(spi_bus_name != RT_NULL); + + for (i = 0; i < ARR_LEN(spis); i++) + { + if (spi_periph == spis[i].spi_periph) + { + rcu_periph_clock_enable(spis[i].spi_clk); + spis[i].spi_bus->parent.user_data = (void *)&spis[i]; + rt_spi_bus_register(spis[i].spi_bus, spi_bus_name, &gd32_spi_ops); + return RT_EOK; + } + } + + return RT_ERROR; +} +#endif diff --git a/bsp/gd32450z-eval/drivers/drv_spi.h b/bsp/gd32450z-eval/drivers/drv_spi.h new file mode 100644 index 0000000000..c97cbba880 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_spi.h @@ -0,0 +1,42 @@ +/* + * File : gd32f20x_40x_spi.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 20012-01-01 aozima first implementation. + */ + +#ifndef gd32F20X_40X_SPI_H_INCLUDED +#define gd32F20X_40X_SPI_H_INCLUDED + +#include +#include + +#include "gd32f4xx.h" + +struct gd32f4_spi +{ + uint32_t spi_periph; + rcu_periph_enum spi_clk; + struct rt_spi_bus *spi_bus; +}; + + +struct gd32_spi_cs +{ + uint32_t GPIOx; + uint32_t GPIO_Pin; +}; + +/* public function */ +rt_err_t gd32_spi_bus_register(uint32_t spi_periph, + //struct gd32_spi_bus * gd32_spi, + const char * spi_bus_name); + +#endif // gd32F20X_40X_SPI_H_INCLUDED diff --git a/bsp/gd32450z-eval/drivers/drv_spi_flash.c b/bsp/gd32450z-eval/drivers/drv_spi_flash.c new file mode 100644 index 0000000000..b55bb9d8ce --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_spi_flash.c @@ -0,0 +1,105 @@ +/* + * File : gd32f20x_40x_spi.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-01-01 aozima first implementation. + * 2012-07-27 aozima fixed variable uninitialized. + */ +#include +#include "drv_spi.h" +#include "spi_flash.h" + +#ifdef RT_USING_SFUD +#include "spi_flash_sfud.h" +#endif + +#ifdef RT_USING_W25QXX +#include "spi_flash_w25qxx.h" +#endif + +#include +#include + +#if defined(RT_USING_SFUD) && defined(RT_USING_W25QXX) +#error "RT_USING_SFUD and RT_USING_W25QXX only need one" +#endif + +#define SPI_PERIPH SPI5 +#define SPI_BUS_NAME "spi5" +#define SPI_FLASH_DEVICE_NAME "spi50" +#define SPI_FLASH_CHIP "gd25q16" + +static int rt_hw_spi5_init(void) +{ + /* register spi bus */ + { + rt_err_t result; + + rcu_periph_clock_enable(RCU_GPIOG); + rcu_periph_clock_enable(RCU_SPI5); + + /* SPI5_CLK(PG13), SPI5_MISO(PG12), SPI5_MOSI(PG14),SPI5_IO2(PG10) and SPI5_IO3(PG11) GPIO pin configuration */ + gpio_af_set(GPIOG, GPIO_AF_5, GPIO_PIN_10|GPIO_PIN_11| GPIO_PIN_12|GPIO_PIN_13| GPIO_PIN_14); + gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10|GPIO_PIN_11| GPIO_PIN_12|GPIO_PIN_13| GPIO_PIN_14); + gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ, GPIO_PIN_10|GPIO_PIN_11| GPIO_PIN_12|GPIO_PIN_13| GPIO_PIN_14); + + result = gd32_spi_bus_register(SPI5, SPI_BUS_NAME); + if (result != RT_EOK) + { + return result; + } + } + + /* attach cs */ + { + static struct rt_spi_device spi_device; + static struct gd32_spi_cs spi_cs; + rt_err_t result; + + spi_cs.GPIOx = GPIOG; + spi_cs.GPIO_Pin = GPIO_PIN_9; + + /* SPI5_CS(PG9) GPIO pin configuration */ + gpio_mode_set(GPIOG, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_9); + gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); + + gpio_bit_set(GPIOG,GPIO_PIN_9); + + result = rt_spi_bus_attach_device(&spi_device, SPI_FLASH_DEVICE_NAME, SPI_BUS_NAME, (void*)&spi_cs); + if (result != RT_EOK) + { + return result; + } + } + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_spi5_init); + +#ifdef RT_USING_SFUD +static int rt_hw_spi_flash_with_sfud_init(void) +{ + if (RT_NULL == rt_sfud_flash_probe(SPI_FLASH_CHIP, SPI_FLASH_DEVICE_NAME)) + { + return RT_ERROR; + }; + + return RT_EOK; +} +INIT_COMPONENT_EXPORT(rt_hw_spi_flash_with_sfud_init) +#endif + +#ifdef RT_USING_W25QXX +static int rt_hw_spi_flash_init(void) +{ + return w25qxx_init(SPI_FLASH_CHIP, SPI_FLASH_DEVICE_NAME); +} +INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init) +#endif diff --git a/bsp/gd32450z-eval/drivers/drv_usart.c b/bsp/gd32450z-eval/drivers/drv_usart.c new file mode 100644 index 0000000000..01ea3ccdfb --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_usart.c @@ -0,0 +1,475 @@ +/* + * File : usart.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard the first version + * 2010-03-29 Bernard remove interrupt Tx and DMA Rx mode + * 2012-02-08 aozima update for F4. + * 2012-07-28 aozima update for ART board. + * 2016-05-28 armink add DMA Rx mode + */ + +#include +#include +#include + +#ifdef RT_USING_SERIAL + +#if !defined(RT_USING_USART0) && !defined(RT_USING_USART1) && \ + !defined(RT_USING_USART2) && !defined(RT_USING_UART3) && \ + !defined(RT_USING_UART4) && !defined(RT_USING_USART5) && \ + !defined(RT_USING_UART6) && !defined(RT_USING_UART7) +#error "Please define at least one UARTx" + +#endif + +#include + +/* GD32 uart driver */ +// Todo: compress uart info +struct gd32_uart +{ + uint32_t uart_periph; //Todo: 3bits + IRQn_Type irqn; //Todo: 7bits + rcu_periph_enum per_clk; //Todo: 5bits + rcu_periph_enum tx_gpio_clk; //Todo: 5bits + rcu_periph_enum rx_gpio_clk; //Todo: 5bits + uint32_t tx_port; //Todo: 4bits + uint16_t tx_af; //Todo: 4bits + uint16_t tx_pin; //Todo: 4bits + uint32_t rx_port; //Todo: 4bits + uint16_t rx_af; //Todo: 4bits + uint16_t rx_pin; //Todo: 4bits + + struct rt_serial_device * serial; + char *device_name; +}; + +static void uart_isr(struct rt_serial_device *serial); + +#if defined(RT_USING_USART0) +struct rt_serial_device serial0; + +void USART0_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial0); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_USART0 */ + +#if defined(RT_USING_USART1) +struct rt_serial_device serial1; + +void USART1_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial1); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_UART1 */ + +#if defined(RT_USING_USART2) +struct rt_serial_device serial2; + +void USART2_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial2); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_UART2 */ + +#if defined(RT_USING_UART3) +struct rt_serial_device serial3; + +void UART3_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial3); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_UART3 */ + +#if defined(RT_USING_UART4) +struct rt_serial_device serial4; + +void UART4_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial4); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* RT_USING_UART4 */ + +#if defined(RT_USING_USART5) +struct rt_serial_device serial5; + +void USART5_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial5); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_UART5 */ + +#if defined(RT_USING_UART6) +struct rt_serial_device serial6; + +void UART6_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial6); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_UART6 */ + +#if defined(RT_USING_UART7) +struct rt_serial_device serial7; + +void UART7_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial7); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_UART7 */ + +static const struct gd32_uart uarts[] = { + #ifdef RT_USING_USART0 + { + USART0, // uart peripheral index + USART0_IRQn, // uart iqrn + RCU_USART0, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock + GPIOA, GPIO_AF_7, GPIO_PIN_9, // tx port, tx alternate, tx pin + GPIOA, GPIO_AF_7, GPIO_PIN_10, // rx port, rx alternate, rx pin + &serial0, + "uart0", + }, + #endif + + #ifdef RT_USING_USART1 + { + USART1, // uart peripheral index + USART1_IRQn, // uart iqrn + RCU_USART1, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock + GPIOA, GPIO_AF_7, GPIO_PIN_2, // tx port, tx alternate, tx pin + GPIOA, GPIO_AF_7, GPIO_PIN_3, // rx port, rx alternate, rx pin + &serial1, + "uart1", + }, + #endif + + #ifdef RT_USING_USART2 + { + USART2, // uart peripheral index + USART2_IRQn, // uart iqrn + RCU_USART2, RCU_GPIOB, RCU_GPIOB, // periph clock, tx gpio clock, rt gpio clock + GPIOB, GPIO_AF_7, GPIO_PIN_10, // tx port, tx alternate, tx pin + GPIOB, GPIO_AF_7, GPIO_PIN_11, // rx port, rx alternate, rx pin + &serial2, + "uart2", + }, + #endif + + #ifdef RT_USING_UART3 + { + UART3, // uart peripheral index + UART3_IRQn, // uart iqrn + RCU_UART3, RCU_GPIOC, RCU_GPIOC, // periph clock, tx gpio clock, rt gpio clock + GPIOC, GPIO_AF_8, GPIO_PIN_10, // tx port, tx alternate, tx pin + GPIOC, GPIO_AF_8, GPIO_PIN_11, // rx port, rx alternate, rx pin + &serial3, + "uart3", + }, + #endif + + #ifdef RT_USING_UART4 + { + UART4, // uart peripheral index + UART4_IRQn, // uart iqrn + RCU_UART4, RCU_GPIOC, RCU_GPIOD, // periph clock, tx gpio clock, rt gpio clock + GPIOC, GPIO_AF_8, GPIO_PIN_12, // tx port, tx alternate, tx pin + GPIOD, GPIO_AF_8, GPIO_PIN_2, // rx port, rx alternate, rx pin + &serial4, + "uart4", + }, + #endif + + #ifdef RT_USING_USART5 + { + USART5, // uart peripheral index + USART5_IRQn, // uart iqrn + RCU_USART5, RCU_GPIOC, RCU_GPIOC, // periph clock, tx gpio clock, rt gpio clock + GPIOC, GPIO_AF_8, GPIO_PIN_6, // tx port, tx alternate, tx pin + GPIOC, GPIO_AF_8, GPIO_PIN_7, // rx port, rx alternate, rx pin + &serial5, + "uart5", + }, + #endif + + #ifdef RT_USING_UART6 + { + UART6, // uart peripheral index + UART6_IRQn, // uart iqrn + RCU_UART6, RCU_GPIOE, RCU_GPIOE, // periph clock, tx gpio clock, rt gpio clock + GPIOE, GPIO_AF_8, GPIO_PIN_7, // tx port, tx alternate, tx pin + GPIOE, GPIO_AF_8, GPIO_PIN_8, // rx port, rx alternate, rx pin + &serial6, + "uart6", + }, + #endif + + #ifdef RT_USING_UART7 + { + UART7, // uart peripheral index + UART7_IRQn, // uart iqrn + RCU_UART7, RCU_GPIOE, RCU_GPIOE, // periph clock, tx gpio clock, rt gpio clock + GPIOE, GPIO_AF_8, GPIO_PIN_0, // tx port, tx alternate, tx pin + GPIOE, GPIO_AF_8, GPIO_PIN_1, // rx port, rx alternate, rx pin + &serial7, + "uart7", + }, + #endif +}; + + +/** +* @brief UART MSP Initialization +* This function configures the hardware resources used in this example: +* - Peripheral's clock enable +* - Peripheral's GPIO Configuration +* - NVIC configuration for UART interrupt request enable +* @param huart: UART handle pointer +* @retval None +*/ +void gd32_uart_gpio_init(struct gd32_uart *uart) +{ + /* enable USART clock */ + rcu_periph_clock_enable(uart->tx_gpio_clk); + rcu_periph_clock_enable(uart->rx_gpio_clk); + rcu_periph_clock_enable(uart->per_clk); + + /* connect port to USARTx_Tx */ + gpio_af_set(uart->tx_port, uart->tx_af, uart->tx_pin); + + /* connect port to USARTx_Rx */ + gpio_af_set(uart->rx_port, uart->rx_af, uart->rx_pin); + + /* configure USART Tx as alternate function push-pull */ + gpio_mode_set(uart->tx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, uart->tx_pin); + gpio_output_options_set(uart->tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, uart->tx_pin); + + /* configure USART Rx as alternate function push-pull */ + gpio_mode_set(uart->rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, uart->rx_pin); + gpio_output_options_set(uart->rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, uart->rx_pin); + + NVIC_SetPriority(uart->irqn, 0); + NVIC_EnableIRQ(uart->irqn); +} + +static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + uart = (struct gd32_uart *)serial->parent.user_data; + + gd32_uart_gpio_init(uart); + + usart_baudrate_set(uart->uart_periph, cfg->baud_rate); + + switch (cfg->data_bits) + { + case DATA_BITS_9: + usart_word_length_set(uart->uart_periph, USART_WL_9BIT); + break; + + default: + usart_word_length_set(uart->uart_periph, USART_WL_8BIT); + break; + } + + switch (cfg->stop_bits) + { + case STOP_BITS_2: + usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT); + break; + default: + usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT); + break; + } + + switch (cfg->parity) + { + case PARITY_ODD: + usart_parity_config(uart->uart_periph, USART_PM_ODD); + break; + case PARITY_EVEN: + usart_parity_config(uart->uart_periph, USART_PM_EVEN); + break; + default: + usart_parity_config(uart->uart_periph, USART_PM_NONE); + break; + } + + usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE); + usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE); + usart_enable(uart->uart_periph); + + return RT_EOK; +} + +static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + NVIC_DisableIRQ(uart->irqn); + /* disable interrupt */ + usart_interrupt_disable(uart->uart_periph, USART_INTEN_RBNEIE); + + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + NVIC_EnableIRQ(uart->irqn); + /* enable interrupt */ + usart_interrupt_enable(uart->uart_periph, USART_INTEN_RBNEIE); + break; + } + + return RT_EOK; +} + +static int gd32_putc(struct rt_serial_device *serial, char ch) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + usart_data_transmit(uart->uart_periph, ch); + while((usart_flag_get(uart->uart_periph, USART_FLAG_TC) == RESET)); + + return 1; +} + +static int gd32_getc(struct rt_serial_device *serial) +{ + int ch; + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + ch = -1; + if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET) + ch = usart_data_receive(uart->uart_periph); + return ch; +} + +/** + * Uart common interrupt process. This need add to uart ISR. + * + * @param serial serial device + */ +static void uart_isr(struct rt_serial_device *serial) +{ + struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + /* UART in mode Receiver -------------------------------------------------*/ + if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_RBNEIE) != RESET) && + (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + /* Clear RXNE interrupt flag */ + usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE); + } +} + +static const struct rt_uart_ops gd32_uart_ops = +{ + gd32_configure, + gd32_control, + gd32_putc, + gd32_getc, +}; + +int gd32_hw_usart_init(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + int i; + + + for (i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++) + { + uarts[i].serial->ops = &gd32_uart_ops; + uarts[i].serial->config = config; + + /* register UART1 device */ + rt_hw_serial_register(uarts[i].serial, + uarts[i].device_name, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + (void *)&uarts[i]); + } + + return 0; +} +INIT_BOARD_EXPORT(gd32_hw_usart_init); +#endif diff --git a/bsp/gd32450z-eval/drivers/drv_usart.h b/bsp/gd32450z-eval/drivers/drv_usart.h new file mode 100644 index 0000000000..79c7ed6d90 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/drv_usart.h @@ -0,0 +1,26 @@ +/* + * File : usart.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard the first version + */ + +#ifndef __USART_H__ +#define __USART_H__ + +#include +#include + +#define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n)) +#define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n)) + +int gd32_hw_usart_init(void); + +#endif diff --git a/bsp/gd32450z-eval/drivers/gd32f450z_eval.h b/bsp/gd32450z-eval/drivers/gd32f450z_eval.h new file mode 100644 index 0000000000..73ea9baaa4 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/gd32f450z_eval.h @@ -0,0 +1,118 @@ +/*! + \file gd32f450z_eval.h + \brief definitions for GD32F450_EVAL's leds, keys and COM ports hardware resources +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, firmware for GD32F450Z +*/ + +#ifndef GD32F450Z_EVAL_H +#define GD32F450Z_EVAL_H + +#ifdef cplusplus + extern "C" { +#endif + +#include "gd32f4xx.h" + +/* exported types */ +typedef enum +{ + LED1 = 0, + LED2 = 1, + LED3 = 2 +} led_typedef_enum; + +typedef enum +{ + KEY_WAKEUP = 0, + KEY_TAMPER = 1, + KEY_USER = 2 +} key_typedef_enum; + +typedef enum +{ + KEY_MODE_GPIO = 0, + KEY_MODE_EXTI = 1 +} keymode_typedef_enum; + +/* eval board low layer led */ +#define LEDn 3U + +#define LED1_PIN GPIO_PIN_4 +#define LED1_GPIO_PORT GPIOD +#define LED1_GPIO_CLK RCU_GPIOD + +#define LED2_PIN GPIO_PIN_5 +#define LED2_GPIO_PORT GPIOD +#define LED2_GPIO_CLK RCU_GPIOD + +#define LED3_PIN GPIO_PIN_3 +#define LED3_GPIO_PORT GPIOG +#define LED3_GPIO_CLK RCU_GPIOG + +#define COMn 1U +#define EVAL_COM1 USART0 +#define EVAL_COM1_CLK RCU_USART0 + +#define EVAL_COM1_TX_PIN GPIO_PIN_9 +#define EVAL_COM1_RX_PIN GPIO_PIN_10 + +#define EVAL_COM_GPIO_PORT GPIOA +#define EVAL_COM_GPIO_CLK RCU_GPIOA +#define EVAL_COM_AF GPIO_AF_7 + +#define KEYn 3U + +/* tamper push-button */ +#define TAMPER_KEY_PIN GPIO_PIN_13 +#define TAMPER_KEY_GPIO_PORT GPIOC +#define TAMPER_KEY_GPIO_CLK RCU_GPIOC +#define TAMPER_KEY_EXTI_LINE EXTI_13 +#define TAMPER_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOC +#define TAMPER_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN13 +#define TAMPER_KEY_EXTI_IRQn EXTI10_15_IRQn + +/* wakeup push-button */ +#define WAKEUP_KEY_PIN GPIO_PIN_0 +#define WAKEUP_KEY_GPIO_PORT GPIOA +#define WAKEUP_KEY_GPIO_CLK RCU_GPIOA +#define WAKEUP_KEY_EXTI_LINE EXTI_0 +#define WAKEUP_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOA +#define WAKEUP_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN0 +#define WAKEUP_KEY_EXTI_IRQn EXTI0_IRQn + +/* user push-button */ +#define USER_KEY_PIN GPIO_PIN_14 +#define USER_KEY_GPIO_PORT GPIOB +#define USER_KEY_GPIO_CLK RCU_GPIOB +#define USER_KEY_EXTI_LINE EXTI_14 +#define USER_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOB +#define USER_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN14 +#define USER_KEY_EXTI_IRQn EXTI10_15_IRQn + +/* function declarations */ +/* configures led GPIO */ +void gd_eval_led_init(led_typedef_enum lednum); +/* turn on selected led */ +void gd_eval_led_on(led_typedef_enum lednum); +/* turn off selected led */ +void gd_eval_led_off(led_typedef_enum lednum); +/* toggle the selected led */ +void gd_eval_led_toggle(led_typedef_enum lednum); +/* configure key */ +void gd_eval_key_init(key_typedef_enum key_num, keymode_typedef_enum key_mode); +/* return the selected button state */ +uint8_t gd_eval_key_state_get(key_typedef_enum button); +/* configure COM port */ +void gd_eval_com_init(uint32_t com); + + +#ifdef cplusplus +} +#endif + +#endif /* GD32F450Z_EVAL_H */ diff --git a/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.c b/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.c new file mode 100644 index 0000000000..8a309a1a75 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.c @@ -0,0 +1,316 @@ +/*! + \file gd32f450z_lcd_eval.c + \brief firmware functions to manage LCD +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, firmware for GD32F450Z +*/ + +#include "gd32f450z_lcd_eval.h" + +static void delay(uint32_t time); + +/*! + \brief enable the LCD + \param[in] none + \param[out] none + \retval none +*/ +void lcd_enable(void) +{ + gpio_bit_set(LCD_CS_GPIO_PORT, LCD_CS_PIN); +} + +/*! + \brief disable the LCD + \param[in] none + \param[out] none + \retval none +*/ +void lcd_disable(void) +{ + gpio_bit_reset(LCD_CS_GPIO_PORT, LCD_CS_PIN); +} + +/*! + \brief configure the LCD control line + \param[in] none + \param[out] none + \retval none +*/ +void lcd_ctrl_line_config(void) +{ + /* enable GPIOs clock*/ + rcu_periph_clock_enable(LCD_CS_GPIO_CLK); + rcu_periph_clock_enable(LCD_RS_GPIO_CLK); + + /* configure LCD_CS_GPIO_PORT(PD11) and LCD_RS_GPIO_PORT(PE3) */ + gpio_mode_set(LCD_CS_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LCD_CS_PIN); + gpio_output_options_set(LCD_CS_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,LCD_CS_PIN); + + gpio_mode_set(LCD_RS_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LCD_RS_PIN); + gpio_output_options_set(LCD_RS_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,LCD_RS_PIN); + + /* set the chip select pin */ + lcd_ctrl_line_set(LCD_CS_GPIO_PORT, LCD_CS_PIN); +} + +/*! + \brief set the LCD control line + \param[in] gpiox: control line GPIO + \arg LCD_CS_GPIO_PORT: LCD chip select GPIO + \arg LCD_RS_GPIO_PORT: LCD register/RAM selection GPIO + \param[in] gpiopin: control line pin + \arg LCD_CS_PIN: LCD chip select pin + \arg LCD_RS_PIN: LCD register/RAM selection pin + \param[out] none + \retval none +*/ +void lcd_ctrl_line_set(uint32_t gpiox, uint16_t gpiopin) +{ + gpio_bit_set(gpiox, gpiopin); +} + +/*! + \brief reset the LCD control line + \param[in] gpiox: control line GPIO + \arg LCD_CS_GPIO_PORT: LCD chip select GPIO + \arg LCD_RS_GPIO_PORT: LCD register/RAM selection GPIO + \param[in] gpiopin: control line pin + \arg LCD_CS_PIN: LCD chip select pin + \arg LCD_RS_PIN: LCD register/RAM selection pin + \param[out] none + \retval none +*/ +void lcd_ctrl_line_reset(uint32_t gpiox, uint16_t gpiopin) +{ + gpio_bit_reset(gpiox, gpiopin); +} + +/*! + \brief configure the LCD SPI and it's GPIOs + \param[in] none + \param[out] none + \retval none +*/ +void lcd_spi_config(void) +{ + spi_parameter_struct spi_init_struct; + rcu_periph_clock_enable(RCU_GPIOG); + rcu_periph_clock_enable(RCU_SPI5); + + /* configure SPI5_SCK(PG13) and SPI5_MOSI(PG14) */ + gpio_af_set(GPIOG,GPIO_AF_5,GPIO_PIN_13); + gpio_af_set(GPIOG,GPIO_AF_5,GPIO_PIN_14); + gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13|GPIO_PIN_14); + gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13|GPIO_PIN_14); + spi_i2s_deinit(SPI5); + + if(0 == (SPI_CTL0(LCD_SPI) & SPI_CTL0_SPIEN)){ + 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_LOW_PH_1EDGE; + spi_init_struct.nss = SPI_NSS_SOFT; + spi_init_struct.prescale = SPI_PSC_16; + spi_init_struct.endian = SPI_ENDIAN_MSB; + spi_init(LCD_SPI, &spi_init_struct); + spi_enable(LCD_SPI); + } +} + +/*! + \brief write command to select LCD register + \param[in] lcd_register: the address of the selected register + \param[out] none + \retval none +*/ +void lcd_command_write(uint8_t lcd_register) +{ + /* reset LCD_RS to send command */ + lcd_ctrl_line_reset(LCD_RS_GPIO_PORT, LCD_RS_PIN); + + /* reset LCD control line and send command */ + lcd_disable(); + while(RESET == spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TBE)) ; + spi_i2s_data_transmit(LCD_SPI, lcd_register); + + /* wait until a data is sent */ + while(RESET != spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TRANS)); + + lcd_enable(); +} + +/*! + \brief write data to select LCD register + \param[in] value: the value that will be written to the selected register + \param[out] none + \retval none +*/ +void lcd_data_write(uint8_t value) +{ + /* set LCD_RS to send data */ + lcd_ctrl_line_set(LCD_RS_GPIO_PORT, LCD_RS_PIN); + + /* reset LCD control line and send data */ + lcd_disable(); + while(RESET == spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TBE)) ; + + spi_i2s_data_transmit(LCD_SPI, value); + + /* wait until a data is sent */ + while(RESET != spi_i2s_flag_get(LCD_SPI, SPI_FLAG_TRANS)) ; + + lcd_enable(); +} + +/*! + \brief configure the LCD based on the power on sequence + \param[in] none + \param[out] none + \retval none +*/ +void lcd_power_on(void) +{ + lcd_command_write(0x11); + delay(120); + lcd_command_write(0x36); + lcd_data_write(0x48); + lcd_command_write(0x3A); + lcd_data_write(0x55); + lcd_command_write(0xB4); + lcd_data_write(0x11); + lcd_command_write(0xB3); + lcd_data_write(0x00); + lcd_data_write(0x00); + lcd_data_write(0x00); + lcd_data_write(0x20); + lcd_command_write(0xC0); + lcd_data_write(0x10); + lcd_data_write(0x3B); + lcd_data_write(0x00); + lcd_data_write(0x12); + lcd_data_write(0x01); + lcd_command_write(0xC5); + lcd_data_write(0x07); + lcd_command_write(0xC8); + lcd_data_write(0x01 ); + lcd_data_write(0x36); + lcd_data_write(0x00); + lcd_data_write(0x02); + lcd_data_write(0x00); + lcd_data_write(0x1C); + lcd_data_write(0x77); + lcd_data_write(0x14); + lcd_data_write(0x67); + lcd_data_write(0x20); + lcd_data_write(0x0E); + lcd_data_write(0x00); + lcd_command_write(0xD0); + lcd_data_write(0x44); + lcd_data_write(0x41 ); + lcd_data_write(0x08); + lcd_data_write(0xC2); + lcd_command_write(0xD1); + lcd_data_write(0x50); + lcd_data_write(0x11); + lcd_command_write(0xD2); + lcd_data_write(0x05); + lcd_data_write(0x12); + + lcd_command_write(0xC6); + lcd_data_write(0x83); + lcd_command_write(0x29); + delay(5); +} +/** + * @brief New Version 3.5" TFT RGB Hardware needs add this initilize funtion ---By xufei 2016.10.21 + Modified by GAO HAIYANG, test pass, 17, Nov, 2016 + * @param None + * @retval None + */ +void lcd_power_on3(void) +{ + lcd_command_write(0xC0);//power control1 command/w/ + lcd_data_write(0x0A); // P-Gamma level//4.1875v + lcd_data_write(0x0A); // N-Gamma level + lcd_command_write(0xC1); // BT & VC Setting//power contrl2 command/w/ + lcd_data_write(0x41); + lcd_data_write(0x07); // VCI1 = 2.5V + lcd_command_write(0xC2); // DC1.DC0 Setting//power control3 for normal mode + lcd_data_write(0x33); + lcd_command_write(0xC5);//VCOM control + lcd_data_write(0x00); //NV memory is not programmed + lcd_data_write(0x42); // VCM Setting + lcd_data_write(0x80); // VCM Register Enable + lcd_command_write(0xB0); //interface mode control //Polarity Setting + lcd_data_write(0x02); + lcd_command_write(0xB1);//frame rate control for normal mode + lcd_data_write(0xB0); // Frame Rate Setting//70 frame per second//no division for internal clocks + lcd_data_write(0x11);//17 clocks per line period for idle mode at cpu interface + lcd_command_write(0xB4);//dispaly inversion control + lcd_data_write(0x00); // disable Z-inversion , column inversion + lcd_command_write(0xB6); //display function control// RM.DM Setting + lcd_data_write(0x70);////0xF0 + lcd_data_write(0x02);//direction of gate scan: G1->G480 one by one, source scan: S1->S960, scan cycle if interval scan in non-display area + lcd_data_write(0x3B); // number of lines to drive LCD: 8*(0x3C) = 480 + lcd_command_write(0xB7); // Entry Mode + lcd_data_write(0x07); // disable low voltage detection, normal display, + lcd_command_write(0xF0); // Enter ENG , must be set before gamma setting + lcd_data_write(0x36); + lcd_data_write(0xA5); + lcd_data_write(0xD3); + lcd_command_write(0xE5); // Open gamma function , must be set before gamma setting + lcd_data_write(0x80); + lcd_command_write(0xE5); // Page 1 + lcd_data_write(0x01); + lcd_command_write(0XB3); // WEMODE=0(Page 1) , pixels over window setting will be ignored.//frame rate control in partial mode/full colors + lcd_data_write(0x00); + lcd_command_write(0xE5); // Page 0 + lcd_data_write(0x00); + lcd_command_write(0xF0); // Exit ENG , must be set before gamma setting + lcd_data_write(0x36); + lcd_data_write(0xA5); + lcd_data_write(0x53); + lcd_command_write(0xE0); // Gamma setting + //y fine adjustment register for positive polarity + lcd_data_write(0x00); + lcd_data_write(0x35); + lcd_data_write(0x33); + //y gradient adjustment register for positive polarity + lcd_data_write(0x00); + //y amplitude adjustment register for positive polarity + lcd_data_write(0x00); + lcd_data_write(0x00); + //y fine adjustment register for negative polarity + lcd_data_write(0x00); + lcd_data_write(0x35); + lcd_data_write(0x33); + //y gradient adjustment register for negative polarity + lcd_data_write(0x00); + //y amplitude adjustment register for negative polarity + lcd_data_write(0x00); + lcd_data_write(0x00); + lcd_command_write(0x36); // memory data access control // + lcd_data_write(0x48);// + lcd_command_write(0x3A); // interface pixel format setting + lcd_data_write(0x55);//16-bits + lcd_command_write(0x11); // Exit sleep mode + lcd_command_write(0x29); // Display on + + delay(10); +} +/*! + \brief insert a delay time + \param[in] time: delay time length + \param[out] none + \retval none +*/ +static void delay(uint32_t time) +{ + uint32_t timecount = time; + while(0 != timecount--); +} diff --git a/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.h b/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.h new file mode 100644 index 0000000000..815925a170 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/gd32f450z_lcd_eval.h @@ -0,0 +1,55 @@ +/*! + \file gd32f450z_lcd_eval.h + \brief definitions for GD32F450Z_EVAL's LCD +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, firmware for GD32F450Z +*/ + +#ifndef GD32F450Z_LCD_EVAL_H +#define GD32F450Z_LCD_EVAL_H + +#include "gd32f450z_eval.h" + +#define LCD_CS_PIN GPIO_PIN_11 +#define LCD_CS_GPIO_PORT GPIOD +#define LCD_CS_GPIO_CLK RCU_GPIOD + +#define LCD_RS_PIN GPIO_PIN_3 +#define LCD_RS_GPIO_PORT GPIOE +#define LCD_RS_GPIO_CLK RCU_GPIOE + +#define LCD_SPI_SCK_PIN GPIO_PIN_13 +#define LCD_SPI_SCK_GPIO_PORT GPIOG +#define LCD_SPI_SCK_GPIO_CLK RCU_GPIOG + +#define LCD_SPI_MOSI_PIN GPIO_PIN_14 +#define LCD_SPI_MOSI_GPIO_PORT GPIOG +#define LCD_SPI_MOSI_GPIO_CLK RCU_GPIOG + +#define LCD_SPI SPI5 +#define LCD_SPI_CLK RCU_SPI5 + +/* enable the LCD */ +void lcd_enable(void); +/* disable the LCD */ +void lcd_disable(void); +/* configure the LCD control line */ +void lcd_ctrl_line_config(void); +/* set the LCD control line */ +void lcd_ctrl_line_set(uint32_t gpiox, uint16_t gpiopin); +/* reset the LCD control line */ +void lcd_ctrl_line_reset(uint32_t gpiox, uint16_t gpiopin); +/* configure the LCD SPI and it's GPIOs */ +void lcd_spi_config(void); +/* write command to select LCD register */ +void lcd_command_write(uint8_t lcd_register); +/* write data to select LCD register */ +void lcd_data_write(uint8_t value); +/* configure the LCD based on the power on sequence */ +void lcd_power_on(void); +void lcd_power_on3(void); +#endif /* GD32F450Z_LCD_EVAL_H */ diff --git a/bsp/gd32450z-eval/drivers/gd32f4xx_libopt.h b/bsp/gd32450z-eval/drivers/gd32f4xx_libopt.h new file mode 100644 index 0000000000..d26e3d15ec --- /dev/null +++ b/bsp/gd32450z-eval/drivers/gd32f4xx_libopt.h @@ -0,0 +1,45 @@ +/*! + \file gd32f4xx_libopt.h + \brief library optional for gd32f4xx +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_LIBOPT_H +#define GD32F4XX_LIBOPT_H +#include "gd32f4xx_rcu.h" +#include "gd32f4xx_adc.h" +#include "gd32f4xx_can.h" +#include "gd32f4xx_crc.h" +#include "gd32f4xx_ctc.h" +#include "gd32f4xx_dac.h" +#include "gd32f4xx_dbg.h" +#include "gd32f4xx_dci.h" +#include "gd32f4xx_dma.h" +//#include "gd32f4xx_enet.h" +#include "gd32f4xx_exmc.h" +#include "gd32f4xx_exti.h" +#include "gd32f4xx_fmc.h" +#include "gd32f4xx_fwdgt.h" +#include "gd32f4xx_gpio.h" +#include "gd32f4xx_syscfg.h" +#include "gd32f4xx_i2c.h" +#include "gd32f4xx_ipa.h" +#include "gd32f4xx_iref.h" +#include "gd32f4xx_pmu.h" +#include "gd32f4xx_rcu.h" +#include "gd32f4xx_rtc.h" +#include "gd32f4xx_sdio.h" +#include "gd32f4xx_spi.h" +#include "gd32f4xx_timer.h" +#include "gd32f4xx_tli.h" +#include "gd32f4xx_trng.h" +#include "gd32f4xx_usart.h" +#include "gd32f4xx_wwdgt.h" +#include "gd32f4xx_misc.h" + +#endif /* GD32F4XX_LIBOPT_H */ diff --git a/bsp/gd32450z-eval/drivers/synopsys_emac.c b/bsp/gd32450z-eval/drivers/synopsys_emac.c new file mode 100644 index 0000000000..bf58b3a008 --- /dev/null +++ b/bsp/gd32450z-eval/drivers/synopsys_emac.c @@ -0,0 +1,401 @@ +/* + * File : rthw.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "synopsys_emac.h" + +/* Global pointers on Tx and Rx descriptor used to track transmit and receive descriptors */ +extern EMAC_DMADESCTypeDef *DMATxDescToSet; +extern EMAC_DMADESCTypeDef *DMARxDescToGet; + + +/** + * Initializes the ETHERNET peripheral according to the specified + */ +rt_uint32_t EMAC_init(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t SystemCoreClock) +{ + rt_uint32_t value = 0; + + /*-------------------------------- MAC Config ------------------------------*/ + /*---------------------- ETHERNET MACMIIAR Configuration -------------------*/ + /* Get the ETHERNET MACMIIAR value */ + value = ETHERNET_MAC->GAR; + /* Clear CSR Clock Range CR[2:0] bits */ + value &= MACMIIAR_CR_MASK; + + /* Get hclk frequency value */ + /* Set CR bits depending on hclk value */ + if((SystemCoreClock >= 20000000)&&(SystemCoreClock < 35000000)) + { + /* CSR Clock Range between 20-35 MHz */ + value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div16; + } + else if((SystemCoreClock >= 35000000)&&(SystemCoreClock < 60000000)) + { + /* CSR Clock Range between 35-60 MHz */ + value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div26; + } + else if((SystemCoreClock >= 60000000)&&(SystemCoreClock <= 100000000)) + { + /* CSR Clock Range between 60-100 MHz */ + value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div42; + } + else if((SystemCoreClock >= 100000000)&&(SystemCoreClock <= 150000000)) + { + /* CSR Clock Range between 100-150 MHz */ + value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div62; + } + else if((SystemCoreClock >= 150000000)&&(SystemCoreClock <= 250000000)) + { + /* CSR Clock Range between 150-250 MHz */ + value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div102; + } + else /* if((SystemCoreClock >= 250000000)&&(SystemCoreClock <= 300000000)) */ + { + /* CSR Clock Range between 250-300 MHz */ + value |= (rt_uint32_t)EMAC_MACMIIAR_CR_Div122; + } + /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */ + ETHERNET_MAC->GAR = (rt_uint32_t)value; + + /*------------------------ ETHERNET MACCR Configuration --------------------*/ + /* Get the ETHERNET MACCR value */ + value = ETHERNET_MAC->MCR; + /* Clear WD, PCE, PS, TE and RE bits */ + value &= MACCR_CLEAR_MASK; + + value |= (rt_uint32_t)(EMAC_Watchdog_Enable | + EMAC_Jabber_Enable | + EMAC_InterFrameGap_96Bit | + EMAC_CarrierSense_Enable | + EMAC_Speed_100M | + EMAC_ReceiveOwn_Enable | + EMAC_LoopbackMode_Disable | + EMAC_Mode_FullDuplex | + EMAC_ChecksumOffload_Enable | + EMAC_RetryTransmission_Disable | + EMAC_AutomaticPadCRCStrip_Disable | + EMAC_BackOffLimit_10 | + EMAC_DeferralCheck_Disable); + + /* Write to ETHERNET MACCR */ + value |= (1<<15); + value &= ~(1<<25); + value &= ~(1<<24); + ETHERNET_MAC->MCR = (rt_uint32_t)value; + + /*----------------------- ETHERNET MACFFR Configuration --------------------*/ + /* Write to ETHERNET MACFFR */ + ETHERNET_MAC->MFFR = (rt_uint32_t)(EMAC_ReceiveAll_Enable | + EMAC_SourceAddrFilter_Disable | + EMAC_PassControlFrames_BlockAll | + EMAC_BroadcastFramesReception_Disable | + EMAC_DestinationAddrFilter_Normal | + EMAC_PromiscuousMode_Disable | + EMAC_MulticastFramesFilter_Perfect | + EMAC_UnicastFramesFilter_Perfect); + + /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/ + /* Write to ETHERNET MACHTHR */ + ETHERNET_MAC->MHTRH = 0; + /* Write to ETHERNET MACHTLR */ + ETHERNET_MAC->MHTRL = 0; + /*----------------------- ETHERNET MACFCR Configuration --------------------*/ + /* Get the ETHERNET MACFCR value */ + value = ETHERNET_MAC->FCR; + /* Clear xx bits */ + value &= MACFCR_CLEAR_MASK; + + value |= (rt_uint32_t)((0 << 16) | + EMAC_ZeroQuantaPause_Disable | + EMAC_PauseLowThreshold_Minus4 | + EMAC_UnicastPauseFrameDetect_Disable | + EMAC_ReceiveFlowControl_Disable | + EMAC_TransmitFlowControl_Disable); + + /* Write to ETHERNET MACFCR */ + ETHERNET_MAC->FCR = (rt_uint32_t)value; + /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/ + ETHERNET_MAC->VTR = (rt_uint32_t)(EMAC_VLANTagComparison_16Bit | + 0); + + /*-------------------------------- DMA Config ------------------------------*/ + /*----------------------- ETHERNET DMAOMR Configuration --------------------*/ + /* Get the ETHERNET DMAOMR value */ + value = ETHERNET_MAC->OMR; + /* Clear xx bits */ + value &= DMAOMR_CLEAR_MASK; + + value |= (rt_uint32_t)(EMAC_DropTCPIPChecksumErrorFrame_Disable | + EMAC_ReceiveStoreForward_Enable | + EMAC_FlushReceivedFrame_Enable | + EMAC_TransmitStoreForward_Enable | + EMAC_TransmitThresholdControl_64Bytes | + EMAC_ForwardErrorFrames_Disable | + EMAC_ForwardUndersizedGoodFrames_Disable | + EMAC_ReceiveThresholdControl_64Bytes | + EMAC_SecondFrameOperate_Disable); + + /* Write to ETHERNET DMAOMR */ + ETHERNET_MAC->OMR = (rt_uint32_t)value; + + /*----------------------- ETHERNET DMABMR Configuration --------------------*/ + ETHERNET_MAC->BMR = (rt_uint32_t)(EMAC_AddressAlignedBeats_Enable | + EMAC_FixedBurst_Enable | + EMAC_RxDMABurstLength_32Beat | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */ + EMAC_TxDMABurstLength_32Beat | + (0 << 2) | + EMAC_DMAArbitration_RoundRobin_RxTx_2_1 | + EMAC_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */ + + /* Return Ethernet configuration success */ + return EMAC_SUCCESS; +} + +/** + * Enables or disables the specified ETHERNET DMA interrupts. + */ +void EMAC_INT_config(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t EMAC_DMA_IT, rt_bool_t NewState) +{ + if (NewState) + { + /* Enable the selected ETHERNET DMA interrupts */ + ETHERNET_MAC->IER |= EMAC_DMA_IT; + } + else + { + /* Disable the selected ETHERNET DMA interrupts */ + ETHERNET_MAC->IER &=(~(rt_uint32_t)EMAC_DMA_IT); + } +} + +/** + * Configures the selected MAC address. + */ +void EMAC_MAC_Addr_config(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t MacAddr, rt_uint8_t *Addr) +{ + rt_uint32_t value; + + /* Calculate the selectecd MAC address high register */ + value = ((rt_uint32_t)Addr[5] << 8) | (rt_uint32_t)Addr[4]; + /* Load the selectecd MAC address high register */ + //(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_HBASE + MacAddr)) = value; + ETHERNET_MAC->MARs[MacAddr].MARH = value; + /* Calculate the selectecd MAC address low register */ + value = ((rt_uint32_t)Addr[3] << 24) | ((rt_uint32_t)Addr[2] << 16) | ((rt_uint32_t)Addr[1] << 8) | Addr[0]; + + /* Load the selectecd MAC address low register */ + //(*(volatile rt_uint32_t *) (EMAC_MAC_ADDR_LBASE + MacAddr)) = value; + ETHERNET_MAC->MARs[MacAddr].MARL = value; +} + +/** + * Enables or disables the MAC transmission. + */ +void EMAC_MACTransmissionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState) +{ + if (NewState) + { + /* Enable the MAC transmission */ + ETHERNET_MAC->MCR |= EMAC_MACCR_TE; + } + else + { + /* Disable the MAC transmission */ + ETHERNET_MAC->MCR &= ~EMAC_MACCR_TE; + } +} + +/** + * Clears the ETHERNET transmit FIFO. + */ +void EMAC_FlushTransmitFIFO(struct rt_synopsys_eth * ETHERNET_MAC) +{ + /* Set the Flush Transmit FIFO bit */ + ETHERNET_MAC->OMR |= EMAC_DMAOMR_FTF; +} + +/** + * Enables or disables the MAC reception. + */ +void EMAC_MACReceptionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState) +{ + if (NewState) + { + /* Enable the MAC reception */ + ETHERNET_MAC->MCR |= EMAC_MACCR_RE; + } + else + { + /* Disable the MAC reception */ + ETHERNET_MAC->MCR &= ~EMAC_MACCR_RE; + } +} + +/** + * Enables or disables the DMA transmission. + */ +void EMAC_DMATransmissionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState) +{ + if (NewState) + { + /* Enable the DMA transmission */ + ETHERNET_MAC->OMR |= EMAC_DMAOMR_ST; + } + else + { + /* Disable the DMA transmission */ + ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_ST; + } +} + +/** + * Enables or disables the DMA reception. + */ +void EMAC_DMAReceptionCmd(struct rt_synopsys_eth * ETHERNET_MAC, rt_bool_t NewState) +{ + if (NewState) + { + /* Enable the DMA reception */ + ETHERNET_MAC->OMR |= EMAC_DMAOMR_SR; + } + else + { + /* Disable the DMA reception */ + ETHERNET_MAC->OMR &= ~EMAC_DMAOMR_SR; + } +} + +/** + * Enables ENET MAC and DMA reception/transmission + */ +void EMAC_start(struct rt_synopsys_eth * ETHERNET_MAC) +{ + /* Enable transmit state machine of the MAC for transmission on the MII */ + EMAC_MACTransmissionCmd(ETHERNET_MAC, RT_TRUE); + /* Flush Transmit FIFO */ + EMAC_FlushTransmitFIFO(ETHERNET_MAC); + /* Enable receive state machine of the MAC for reception from the MII */ + EMAC_MACReceptionCmd(ETHERNET_MAC, RT_TRUE); + + /* Start DMA transmission */ + EMAC_DMATransmissionCmd(ETHERNET_MAC, RT_TRUE); + /* Start DMA reception */ + EMAC_DMAReceptionCmd(ETHERNET_MAC, RT_TRUE); +} + +/** + * Clears the ETHERNET's DMA interrupt pending bit. + */ +void EMAC_clear_pending(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t pending) +{ + /* Clear the selected ETHERNET DMA IT */ + ETHERNET_MAC->SR = (rt_uint32_t) pending; +} + +/** + * Resumes the DMA Transmission by writing to the DmaRxPollDemand register + * (the data written could be anything). This forces the DMA to resume reception. + */ +void EMAC_resume_reception(struct rt_synopsys_eth * ETHERNET_MAC) +{ + ETHERNET_MAC->RPDR = 0; +} + +/** + * Resumes the DMA Transmission by writing to the DmaTxPollDemand register + * (the data written could be anything). This forces the DMA to resume transmission. + */ +void EMAC_resume_transmission(struct rt_synopsys_eth * ETHERNET_MAC) +{ + ETHERNET_MAC->TPDR = 0; +} + +/** + * Read a PHY register + */ +rt_uint16_t EMAC_PHY_read(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg) +{ + rt_uint32_t value = 0; + volatile rt_uint32_t timeout = 0; + + /* Get the ETHERNET MACMIIAR value */ + value = ETHERNET_MAC->GAR; + /* Keep only the CSR Clock Range CR[2:0] bits value */ + value &= ~MACMIIAR_CR_MASK; + /* Prepare the MII address register value */ + value |=(((rt_uint32_t)PHYAddress<<11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */ + value |=(((rt_uint32_t)PHYReg<<6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */ + value &= ~EMAC_MACMIIAR_MW; /* Set the read mode */ + value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */ + /* Write the result value into the MII Address register */ + ETHERNET_MAC->GAR = value; + /* Check for the Busy flag */ + do + { + timeout++; + value = ETHERNET_MAC->GAR; + } + while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_READ_TO)); + /* Return ERROR in case of timeout */ + if(timeout == PHY_READ_TO) + { + return (rt_uint16_t)EMAC_ERROR; + } + + /* Return data register value */ + return (rt_uint16_t)(ETHERNET_MAC->GDR); +} + +/** + * Write to a PHY register + */ +rt_uint32_t EMAC_PHY_write(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg, rt_uint16_t PHYValue) +{ + rt_uint32_t value = 0; + volatile rt_uint32_t timeout = 0; + + /* Get the ETHERNET MACMIIAR value */ + value = ETHERNET_MAC->GAR; + /* Keep only the CSR Clock Range CR[2:0] bits value */ + value &= ~MACMIIAR_CR_MASK; + /* Prepare the MII register address value */ + value |=(((rt_uint32_t)PHYAddress<<11) & EMAC_MACMIIAR_PA); /* Set the PHY device address */ + value |=(((rt_uint32_t)PHYReg<<6) & EMAC_MACMIIAR_MR); /* Set the PHY register address */ + value |= EMAC_MACMIIAR_MW; /* Set the write mode */ + value |= EMAC_MACMIIAR_MB; /* Set the MII Busy bit */ + /* Give the value to the MII data register */ + ETHERNET_MAC->GDR = PHYValue; + /* Write the result value into the MII Address register */ + ETHERNET_MAC->GAR = value; + /* Check for the Busy flag */ + do + { + timeout++; + value = ETHERNET_MAC->GAR; + } + while ((value & EMAC_MACMIIAR_MB) && (timeout < (rt_uint32_t)PHY_WRITE_TO)); + /* Return ERROR in case of timeout */ + if(timeout == PHY_WRITE_TO) + { + return EMAC_ERROR; + } + + /* Return SUCCESS */ + return EMAC_SUCCESS; +} diff --git a/bsp/gd32450z-eval/drivers/synopsys_emac.h b/bsp/gd32450z-eval/drivers/synopsys_emac.h new file mode 100644 index 0000000000..cb0d62122f --- /dev/null +++ b/bsp/gd32450z-eval/drivers/synopsys_emac.h @@ -0,0 +1,1291 @@ +/* + * File : rtdef.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __SYNOPSYS_EMAC_H__ +#define __SYNOPSYS_EMAC_H__ + +#include + + +/******************************************************************************/ +/* Ethernet MAC Registers bits definitions */ +/******************************************************************************/ +/* Bit definition for Ethernet MAC Control Register register */ +#define EMAC_MACCR_WD ((rt_uint32_t)0x00800000) /* Watchdog disable */ +#define EMAC_MACCR_JD ((rt_uint32_t)0x00400000) /* Jabber disable */ +#define EMAC_MACCR_IFG ((rt_uint32_t)0x000E0000) /* Inter-frame gap */ +#define EMAC_MACCR_IFG_96Bit ((rt_uint32_t)0x00000000) /* Minimum IFG between frames during transmission is 96Bit */ +#define EMAC_MACCR_IFG_88Bit ((rt_uint32_t)0x00020000) /* Minimum IFG between frames during transmission is 88Bit */ +#define EMAC_MACCR_IFG_80Bit ((rt_uint32_t)0x00040000) /* Minimum IFG between frames during transmission is 80Bit */ +#define EMAC_MACCR_IFG_72Bit ((rt_uint32_t)0x00060000) /* Minimum IFG between frames during transmission is 72Bit */ +#define EMAC_MACCR_IFG_64Bit ((rt_uint32_t)0x00080000) /* Minimum IFG between frames during transmission is 64Bit */ +#define EMAC_MACCR_IFG_56Bit ((rt_uint32_t)0x000A0000) /* Minimum IFG between frames during transmission is 56Bit */ +#define EMAC_MACCR_IFG_48Bit ((rt_uint32_t)0x000C0000) /* Minimum IFG between frames during transmission is 48Bit */ +#define EMAC_MACCR_IFG_40Bit ((rt_uint32_t)0x000E0000) /* Minimum IFG between frames during transmission is 40Bit */ +#define EMAC_MACCR_CSD ((rt_uint32_t)0x00010000) /* Carrier sense disable (during transmission) */ +#define EMAC_MACCR_FES ((rt_uint32_t)0x00004000) /* Fast ethernet speed */ +#define EMAC_MACCR_ROD ((rt_uint32_t)0x00002000) /* Receive own disable */ +#define EMAC_MACCR_LM ((rt_uint32_t)0x00001000) /* loopback mode */ +#define EMAC_MACCR_DM ((rt_uint32_t)0x00000800) /* Duplex mode */ +#define EMAC_MACCR_IPCO ((rt_uint32_t)0x00000400) /* IP Checksum offload */ +#define EMAC_MACCR_RD ((rt_uint32_t)0x00000200) /* Retry disable */ +#define EMAC_MACCR_APCS ((rt_uint32_t)0x00000080) /* Automatic Pad/CRC stripping */ +#define EMAC_MACCR_BL ((rt_uint32_t)0x00000060) /* Back-off limit: random integer number (r) of slot time delays before rescheduling + a transmission attempt during retries after a collision: 0 =< r <2^k */ +#define EMAC_MACCR_BL_10 ((rt_uint32_t)0x00000000) /* k = min (n, 10) */ +#define EMAC_MACCR_BL_8 ((rt_uint32_t)0x00000020) /* k = min (n, 8) */ +#define EMAC_MACCR_BL_4 ((rt_uint32_t)0x00000040) /* k = min (n, 4) */ +#define EMAC_MACCR_BL_1 ((rt_uint32_t)0x00000060) /* k = min (n, 1) */ +#define EMAC_MACCR_DC ((rt_uint32_t)0x00000010) /* Defferal check */ +#define EMAC_MACCR_TE ((rt_uint32_t)0x00000008) /* Transmitter enable */ +#define EMAC_MACCR_RE ((rt_uint32_t)0x00000004) /* Receiver enable */ + +/* Bit definition for Ethernet MAC Frame Filter Register */ +#define EMAC_MACFFR_RA ((rt_uint32_t)0x80000000) /* Receive all */ +#define EMAC_MACFFR_HPF ((rt_uint32_t)0x00000400) /* Hash or perfect filter */ +#define EMAC_MACFFR_SAF ((rt_uint32_t)0x00000200) /* Source address filter enable */ +#define EMAC_MACFFR_SAIF ((rt_uint32_t)0x00000100) /* SA inverse filtering */ +#define EMAC_MACFFR_PCF ((rt_uint32_t)0x000000C0) /* Pass control frames: 3 cases */ +#define EMAC_MACFFR_PCF_BlockAll ((rt_uint32_t)0x00000040) /* MAC filters all control frames from reaching the application */ +#define EMAC_MACFFR_PCF_ForwardAll ((rt_uint32_t)0x00000080) /* MAC forwards all control frames to application even if they fail the Address Filter */ +#define EMAC_MACFFR_PCF_ForwardPassedAddrFilter ((rt_uint32_t)0x000000C0) /* MAC forwards control frames that pass the Address Filter. */ +#define EMAC_MACFFR_BFD ((rt_uint32_t)0x00000020) /* Broadcast frame disable */ +#define EMAC_MACFFR_PAM ((rt_uint32_t)0x00000010) /* Pass all mutlicast */ +#define EMAC_MACFFR_DAIF ((rt_uint32_t)0x00000008) /* DA Inverse filtering */ +#define EMAC_MACFFR_HM ((rt_uint32_t)0x00000004) /* Hash multicast */ +#define EMAC_MACFFR_HU ((rt_uint32_t)0x00000002) /* Hash unicast */ +#define EMAC_MACFFR_PM ((rt_uint32_t)0x00000001) /* Promiscuous mode */ + +/* Bit definition for Ethernet MAC Hash Table High Register */ +#define EMAC_MACHTHR_HTH ((rt_uint32_t)0xFFFFFFFF) /* Hash table high */ + +/* Bit definition for Ethernet MAC Hash Table Low Register */ +#define EMAC_MACHTLR_HTL ((rt_uint32_t)0xFFFFFFFF) /* Hash table low */ + +/* Bit definition for Ethernet MAC MII Address Register */ +#define EMAC_MACMIIAR_PA ((rt_uint32_t)0x0000F800) /* Physical layer address */ +#define EMAC_MACMIIAR_MR ((rt_uint32_t)0x000007C0) /* MII register in the selected PHY */ +#define EMAC_MACMIIAR_CR ((rt_uint32_t)0x0000001C) /* CR clock range: 6 cases */ +#define EMAC_MACMIIAR_CR_Div42 ((rt_uint32_t)0x00000000) /* HCLK:60-100 MHz; MDC clock= HCLK/42 */ +#define EMAC_MACMIIAR_CR_Div62 ((rt_uint32_t)0x00000004) /* HCLK:100-150 MHz; MDC clock= HCLK/62 */ +#define EMAC_MACMIIAR_CR_Div16 ((rt_uint32_t)0x00000008) /* HCLK:20-35 MHz; MDC clock= HCLK/16 */ +#define EMAC_MACMIIAR_CR_Div26 ((rt_uint32_t)0x0000000C) /* HCLK:35-60 MHz; MDC clock= HCLK/26 */ +#define EMAC_MACMIIAR_CR_Div102 ((rt_uint32_t)0x00000010) /* HCLK:150-250 MHz; MDC clock= HCLK/102 */ +#define EMAC_MACMIIAR_CR_Div122 ((rt_uint32_t)0x00000014) /* HCLK:250-300 MHz; MDC clock= HCLK/122*/ +#define EMAC_MACMIIAR_MW ((rt_uint32_t)0x00000002) /* MII write */ +#define EMAC_MACMIIAR_MB ((rt_uint32_t)0x00000001) /* MII busy */ + +/* Bit definition for Ethernet MAC MII Data Register */ +#define EMAC_MACMIIDR_MD ((rt_uint32_t)0x0000FFFF) /* MII data: read/write data from/to PHY */ + +/* Bit definition for Ethernet MAC Flow Control Register */ +#define EMAC_MACFCR_PT ((rt_uint32_t)0xFFFF0000) /* Pause time */ +#define EMAC_MACFCR_ZQPD ((rt_uint32_t)0x00000080) /* Zero-quanta pause disable */ +#define EMAC_MACFCR_PLT ((rt_uint32_t)0x00000030) /* Pause low threshold: 4 cases */ +#define EMAC_MACFCR_PLT_Minus4 ((rt_uint32_t)0x00000000) /* Pause time minus 4 slot times */ +#define EMAC_MACFCR_PLT_Minus28 ((rt_uint32_t)0x00000010) /* Pause time minus 28 slot times */ +#define EMAC_MACFCR_PLT_Minus144 ((rt_uint32_t)0x00000020) /* Pause time minus 144 slot times */ +#define EMAC_MACFCR_PLT_Minus256 ((rt_uint32_t)0x00000030) /* Pause time minus 256 slot times */ +#define EMAC_MACFCR_UPFD ((rt_uint32_t)0x00000008) /* Unicast pause frame detect */ +#define EMAC_MACFCR_RFCE ((rt_uint32_t)0x00000004) /* Receive flow control enable */ +#define EMAC_MACFCR_TFCE ((rt_uint32_t)0x00000002) /* Transmit flow control enable */ +#define EMAC_MACFCR_FCBBPA ((rt_uint32_t)0x00000001) /* Flow control busy/backpressure activate */ + +/* Bit definition for Ethernet MAC VLAN Tag Register */ +#define EMAC_MACVLANTR_VLANTC ((rt_uint32_t)0x00010000) /* 12-bit VLAN tag comparison */ +#define EMAC_MACVLANTR_VLANTI ((rt_uint32_t)0x0000FFFF) /* VLAN tag identifier (for receive frames) */ + +/* Bit definition for Ethernet MAC Remote Wake-UpFrame Filter Register */ +#define EMAC_MACRWUFFR_D ((rt_uint32_t)0xFFFFFFFF) /* Wake-up frame filter register data */ +/* Eight sequential Writes to this address (offset 0x28) will write all Wake-UpFrame Filter Registers. + Eight sequential Reads from this address (offset 0x28) will read all Wake-UpFrame Filter Registers. */ +/* Wake-UpFrame Filter Reg0 : Filter 0 Byte Mask + Wake-UpFrame Filter Reg1 : Filter 1 Byte Mask + Wake-UpFrame Filter Reg2 : Filter 2 Byte Mask + Wake-UpFrame Filter Reg3 : Filter 3 Byte Mask + Wake-UpFrame Filter Reg4 : RSVD - Filter3 Command - RSVD - Filter2 Command - + RSVD - Filter1 Command - RSVD - Filter0 Command + Wake-UpFrame Filter Re5 : Filter3 Offset - Filter2 Offset - Filter1 Offset - Filter0 Offset + Wake-UpFrame Filter Re6 : Filter1 CRC16 - Filter0 CRC16 + Wake-UpFrame Filter Re7 : Filter3 CRC16 - Filter2 CRC16 */ + +/* Bit definition for Ethernet MAC PMT Control and Status Register */ +#define EMAC_MACPMTCSR_WFFRPR ((rt_uint32_t)0x80000000) /* Wake-Up Frame Filter Register Pointer Reset */ +#define EMAC_MACPMTCSR_GU ((rt_uint32_t)0x00000200) /* Global Unicast */ +#define EMAC_MACPMTCSR_WFR ((rt_uint32_t)0x00000040) /* Wake-Up Frame Received */ +#define EMAC_MACPMTCSR_MPR ((rt_uint32_t)0x00000020) /* Magic Packet Received */ +#define EMAC_MACPMTCSR_WFE ((rt_uint32_t)0x00000004) /* Wake-Up Frame Enable */ +#define EMAC_MACPMTCSR_MPE ((rt_uint32_t)0x00000002) /* Magic Packet Enable */ +#define EMAC_MACPMTCSR_PD ((rt_uint32_t)0x00000001) /* Power Down */ + +/* Bit definition for Ethernet MAC Status Register */ +#define EMAC_MACSR_TSTS ((rt_uint32_t)0x00000200) /* Time stamp trigger status */ +#define EMAC_MACSR_MMCTS ((rt_uint32_t)0x00000040) /* MMC transmit status */ +#define EMAC_MACSR_MMMCRS ((rt_uint32_t)0x00000020) /* MMC receive status */ +#define EMAC_MACSR_MMCS ((rt_uint32_t)0x00000010) /* MMC status */ +#define EMAC_MACSR_PMTS ((rt_uint32_t)0x00000008) /* PMT status */ + +/* Bit definition for Ethernet MAC Interrupt Mask Register */ +#define EMAC_MACIMR_TSTIM ((rt_uint32_t)0x00000200) /* Time stamp trigger interrupt mask */ +#define EMAC_MACIMR_PMTIM ((rt_uint32_t)0x00000008) /* PMT interrupt mask */ + +/* Bit definition for Ethernet MAC Address0 High Register */ +#define EMAC_MACA0HR_MACA0H ((rt_uint32_t)0x0000FFFF) /* MAC address0 high */ + +/* Bit definition for Ethernet MAC Address0 Low Register */ +#define EMAC_MACA0LR_MACA0L ((rt_uint32_t)0xFFFFFFFF) /* MAC address0 low */ + +/* Bit definition for Ethernet MAC Address1 High Register */ +#define EMAC_MACA1HR_AE ((rt_uint32_t)0x80000000) /* Address enable */ +#define EMAC_MACA1HR_SA ((rt_uint32_t)0x40000000) /* Source address */ +#define EMAC_MACA1HR_MBC ((rt_uint32_t)0x3F000000) /* Mask byte control: bits to mask for comparison of the MAC Address bytes */ +#define EMAC_MACA1HR_MBC_HBits15_8 ((rt_uint32_t)0x20000000) /* Mask MAC Address high reg bits [15:8] */ +#define EMAC_MACA1HR_MBC_HBits7_0 ((rt_uint32_t)0x10000000) /* Mask MAC Address high reg bits [7:0] */ +#define EMAC_MACA1HR_MBC_LBits31_24 ((rt_uint32_t)0x08000000) /* Mask MAC Address low reg bits [31:24] */ +#define EMAC_MACA1HR_MBC_LBits23_16 ((rt_uint32_t)0x04000000) /* Mask MAC Address low reg bits [23:16] */ +#define EMAC_MACA1HR_MBC_LBits15_8 ((rt_uint32_t)0x02000000) /* Mask MAC Address low reg bits [15:8] */ +#define EMAC_MACA1HR_MBC_LBits7_0 ((rt_uint32_t)0x01000000) /* Mask MAC Address low reg bits [7:0] */ +#define EMAC_MACA1HR_MACA1H ((rt_uint32_t)0x0000FFFF) /* MAC address1 high */ + +/* Bit definition for Ethernet MAC Address1 Low Register */ +#define EMAC_MACA1LR_MACA1L ((rt_uint32_t)0xFFFFFFFF) /* MAC address1 low */ + +/* Bit definition for Ethernet MAC Address2 High Register */ +#define EMAC_MACA2HR_AE ((rt_uint32_t)0x80000000) /* Address enable */ +#define EMAC_MACA2HR_SA ((rt_uint32_t)0x40000000) /* Source address */ +#define EMAC_MACA2HR_MBC ((rt_uint32_t)0x3F000000) /* Mask byte control */ +#define EMAC_MACA2HR_MBC_HBits15_8 ((rt_uint32_t)0x20000000) /* Mask MAC Address high reg bits [15:8] */ +#define EMAC_MACA2HR_MBC_HBits7_0 ((rt_uint32_t)0x10000000) /* Mask MAC Address high reg bits [7:0] */ +#define EMAC_MACA2HR_MBC_LBits31_24 ((rt_uint32_t)0x08000000) /* Mask MAC Address low reg bits [31:24] */ +#define EMAC_MACA2HR_MBC_LBits23_16 ((rt_uint32_t)0x04000000) /* Mask MAC Address low reg bits [23:16] */ +#define EMAC_MACA2HR_MBC_LBits15_8 ((rt_uint32_t)0x02000000) /* Mask MAC Address low reg bits [15:8] */ +#define EMAC_MACA2HR_MBC_LBits7_0 ((rt_uint32_t)0x01000000) /* Mask MAC Address low reg bits [70] */ +#define EMAC_MACA2HR_MACA2H ((rt_uint32_t)0x0000FFFF) /* MAC address1 high */ + +/* Bit definition for Ethernet MAC Address2 Low Register */ +#define EMAC_MACA2LR_MACA2L ((rt_uint32_t)0xFFFFFFFF) /* MAC address2 low */ + +/* Bit definition for Ethernet MAC Address3 High Register */ +#define EMAC_MACA3HR_AE ((rt_uint32_t)0x80000000) /* Address enable */ +#define EMAC_MACA3HR_SA ((rt_uint32_t)0x40000000) /* Source address */ +#define EMAC_MACA3HR_MBC ((rt_uint32_t)0x3F000000) /* Mask byte control */ +#define EMAC_MACA3HR_MBC_HBits15_8 ((rt_uint32_t)0x20000000) /* Mask MAC Address high reg bits [15:8] */ +#define EMAC_MACA3HR_MBC_HBits7_0 ((rt_uint32_t)0x10000000) /* Mask MAC Address high reg bits [7:0] */ +#define EMAC_MACA3HR_MBC_LBits31_24 ((rt_uint32_t)0x08000000) /* Mask MAC Address low reg bits [31:24] */ +#define EMAC_MACA3HR_MBC_LBits23_16 ((rt_uint32_t)0x04000000) /* Mask MAC Address low reg bits [23:16] */ +#define EMAC_MACA3HR_MBC_LBits15_8 ((rt_uint32_t)0x02000000) /* Mask MAC Address low reg bits [15:8] */ +#define EMAC_MACA3HR_MBC_LBits7_0 ((rt_uint32_t)0x01000000) /* Mask MAC Address low reg bits [70] */ +#define EMAC_MACA3HR_MACA3H ((rt_uint32_t)0x0000FFFF) /* MAC address3 high */ + +/* Bit definition for Ethernet MAC Address3 Low Register */ +#define EMAC_MACA3LR_MACA3L ((rt_uint32_t)0xFFFFFFFF) /* MAC address3 low */ + +/******************************************************************************/ +/* Ethernet MMC Registers bits definition */ +/******************************************************************************/ + +/* Bit definition for Ethernet MMC Contol Register */ +#define EMAC_MMCCR_MCF ((rt_uint32_t)0x00000008) /* MMC Counter Freeze */ +#define EMAC_MMCCR_ROR ((rt_uint32_t)0x00000004) /* Reset on Read */ +#define EMAC_MMCCR_CSR ((rt_uint32_t)0x00000002) /* Counter Stop Rollover */ +#define EMAC_MMCCR_CR ((rt_uint32_t)0x00000001) /* Counters Reset */ + +/* Bit definition for Ethernet MMC Receive Interrupt Register */ +#define EMAC_MMCRIR_RGUFS ((rt_uint32_t)0x00020000) /* Set when Rx good unicast frames counter reaches half the maximum value */ +#define EMAC_MMCRIR_RFAES ((rt_uint32_t)0x00000040) /* Set when Rx alignment error counter reaches half the maximum value */ +#define EMAC_MMCRIR_RFCES ((rt_uint32_t)0x00000020) /* Set when Rx crc error counter reaches half the maximum value */ + +/* Bit definition for Ethernet MMC Transmit Interrupt Register */ +#define EMAC_MMCTIR_TGFS ((rt_uint32_t)0x00200000) /* Set when Tx good frame count counter reaches half the maximum value */ +#define EMAC_MMCTIR_TGFMSCS ((rt_uint32_t)0x00008000) /* Set when Tx good multi col counter reaches half the maximum value */ +#define EMAC_MMCTIR_TGFSCS ((rt_uint32_t)0x00004000) /* Set when Tx good single col counter reaches half the maximum value */ + +/* Bit definition for Ethernet MMC Receive Interrupt Mask Register */ +#define EMAC_MMCRIMR_RGUFM ((rt_uint32_t)0x00020000) /* Mask the interrupt when Rx good unicast frames counter reaches half the maximum value */ +#define EMAC_MMCRIMR_RFAEM ((rt_uint32_t)0x00000040) /* Mask the interrupt when when Rx alignment error counter reaches half the maximum value */ +#define EMAC_MMCRIMR_RFCEM ((rt_uint32_t)0x00000020) /* Mask the interrupt when Rx crc error counter reaches half the maximum value */ + +/* Bit definition for Ethernet MMC Transmit Interrupt Mask Register */ +#define EMAC_MMCTIMR_TGFM ((rt_uint32_t)0x00200000) /* Mask the interrupt when Tx good frame count counter reaches half the maximum value */ +#define EMAC_MMCTIMR_TGFMSCM ((rt_uint32_t)0x00008000) /* Mask the interrupt when Tx good multi col counter reaches half the maximum value */ +#define EMAC_MMCTIMR_TGFSCM ((rt_uint32_t)0x00004000) /* Mask the interrupt when Tx good single col counter reaches half the maximum value */ + +/* Bit definition for Ethernet MMC Transmitted Good Frames after Single Collision Counter Register */ +#define EMAC_MMCTGFSCCR_TGFSCC ((rt_uint32_t)0xFFFFFFFF) /* Number of successfully transmitted frames after a single collision in Half-duplex mode. */ + +/* Bit definition for Ethernet MMC Transmitted Good Frames after More than a Single Collision Counter Register */ +#define EMAC_MMCTGFMSCCR_TGFMSCC ((rt_uint32_t)0xFFFFFFFF) /* Number of successfully transmitted frames after more than a single collision in Half-duplex mode. */ + +/* Bit definition for Ethernet MMC Transmitted Good Frames Counter Register */ +#define EMAC_MMCTGFCR_TGFC ((rt_uint32_t)0xFFFFFFFF) /* Number of good frames transmitted. */ + +/* Bit definition for Ethernet MMC Received Frames with CRC Error Counter Register */ +#define EMAC_MMCRFCECR_RFCEC ((rt_uint32_t)0xFFFFFFFF) /* Number of frames received with CRC error. */ + +/* Bit definition for Ethernet MMC Received Frames with Alignment Error Counter Register */ +#define EMAC_MMCRFAECR_RFAEC ((rt_uint32_t)0xFFFFFFFF) /* Number of frames received with alignment (dribble) error */ + +/* Bit definition for Ethernet MMC Received Good Unicast Frames Counter Register */ +#define EMAC_MMCRGUFCR_RGUFC ((rt_uint32_t)0xFFFFFFFF) /* Number of good unicast frames received. */ + +/******************************************************************************/ +/* Ethernet PTP Registers bits definition */ +/******************************************************************************/ + +/* Bit definition for Ethernet PTP Time Stamp Control Register */ +#define EMAC_PTPTSCR_TSARU ((rt_uint32_t)0x00000020) /* Addend register update */ +#define EMAC_PTPTSCR_TSITE ((rt_uint32_t)0x00000010) /* Time stamp interrupt trigger enable */ +#define EMAC_PTPTSCR_TSSTU ((rt_uint32_t)0x00000008) /* Time stamp update */ +#define EMAC_PTPTSCR_TSSTI ((rt_uint32_t)0x00000004) /* Time stamp initialize */ +#define EMAC_PTPTSCR_TSFCU ((rt_uint32_t)0x00000002) /* Time stamp fine or coarse update */ +#define EMAC_PTPTSCR_TSE ((rt_uint32_t)0x00000001) /* Time stamp enable */ + +/* Bit definition for Ethernet PTP Sub-Second Increment Register */ +#define EMAC_PTPSSIR_STSSI ((rt_uint32_t)0x000000FF) /* System time Sub-second increment value */ + +/* Bit definition for Ethernet PTP Time Stamp High Register */ +#define EMAC_PTPTSHR_STS ((rt_uint32_t)0xFFFFFFFF) /* System Time second */ + +/* Bit definition for Ethernet PTP Time Stamp Low Register */ +#define EMAC_PTPTSLR_STPNS ((rt_uint32_t)0x80000000) /* System Time Positive or negative time */ +#define EMAC_PTPTSLR_STSS ((rt_uint32_t)0x7FFFFFFF) /* System Time sub-seconds */ + +/* Bit definition for Ethernet PTP Time Stamp High Update Register */ +#define EMAC_PTPTSHUR_TSUS ((rt_uint32_t)0xFFFFFFFF) /* Time stamp update seconds */ + +/* Bit definition for Ethernet PTP Time Stamp Low Update Register */ +#define EMAC_PTPTSLUR_TSUPNS ((rt_uint32_t)0x80000000) /* Time stamp update Positive or negative time */ +#define EMAC_PTPTSLUR_TSUSS ((rt_uint32_t)0x7FFFFFFF) /* Time stamp update sub-seconds */ + +/* Bit definition for Ethernet PTP Time Stamp Addend Register */ +#define EMAC_PTPTSAR_TSA ((rt_uint32_t)0xFFFFFFFF) /* Time stamp addend */ + +/* Bit definition for Ethernet PTP Target Time High Register */ +#define EMAC_PTPTTHR_TTSH ((rt_uint32_t)0xFFFFFFFF) /* Target time stamp high */ + +/* Bit definition for Ethernet PTP Target Time Low Register */ +#define EMAC_PTPTTLR_TTSL ((rt_uint32_t)0xFFFFFFFF) /* Target time stamp low */ + +/******************************************************************************/ +/* Ethernet DMA Registers bits definition */ +/******************************************************************************/ + +/* Bit definition for Ethernet DMA Bus Mode Register */ +#define EMAC_DMABMR_AAB ((rt_uint32_t)0x02000000) /* Address-Aligned beats */ +#define EMAC_DMABMR_FPM ((rt_uint32_t)0x01000000) /* 4xPBL mode */ +#define EMAC_DMABMR_USP ((rt_uint32_t)0x00800000) /* Use separate PBL */ +#define EMAC_DMABMR_RDP ((rt_uint32_t)0x007E0000) /* RxDMA PBL */ +#define EMAC_DMABMR_RDP_1Beat ((rt_uint32_t)0x00020000) /* maximum number of beats to be transferred in one RxDMA transaction is 1 */ +#define EMAC_DMABMR_RDP_2Beat ((rt_uint32_t)0x00040000) /* maximum number of beats to be transferred in one RxDMA transaction is 2 */ +#define EMAC_DMABMR_RDP_4Beat ((rt_uint32_t)0x00080000) /* maximum number of beats to be transferred in one RxDMA transaction is 4 */ +#define EMAC_DMABMR_RDP_8Beat ((rt_uint32_t)0x00100000) /* maximum number of beats to be transferred in one RxDMA transaction is 8 */ +#define EMAC_DMABMR_RDP_16Beat ((rt_uint32_t)0x00200000) /* maximum number of beats to be transferred in one RxDMA transaction is 16 */ +#define EMAC_DMABMR_RDP_32Beat ((rt_uint32_t)0x00400000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */ +#define EMAC_DMABMR_RDP_4xPBL_4Beat ((rt_uint32_t)0x01020000) /* maximum number of beats to be transferred in one RxDMA transaction is 4 */ +#define EMAC_DMABMR_RDP_4xPBL_8Beat ((rt_uint32_t)0x01040000) /* maximum number of beats to be transferred in one RxDMA transaction is 8 */ +#define EMAC_DMABMR_RDP_4xPBL_16Beat ((rt_uint32_t)0x01080000) /* maximum number of beats to be transferred in one RxDMA transaction is 16 */ +#define EMAC_DMABMR_RDP_4xPBL_32Beat ((rt_uint32_t)0x01100000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */ +#define EMAC_DMABMR_RDP_4xPBL_64Beat ((rt_uint32_t)0x01200000) /* maximum number of beats to be transferred in one RxDMA transaction is 64 */ +#define EMAC_DMABMR_RDP_4xPBL_128Beat ((rt_uint32_t)0x01400000) /* maximum number of beats to be transferred in one RxDMA transaction is 128 */ +#define EMAC_DMABMR_FB ((rt_uint32_t)0x00010000) /* Fixed Burst */ +#define EMAC_DMABMR_RTPR ((rt_uint32_t)0x0000C000) /* Rx Tx priority ratio */ +#define EMAC_DMABMR_RTPR_1_1 ((rt_uint32_t)0x00000000) /* Rx Tx priority ratio */ +#define EMAC_DMABMR_RTPR_2_1 ((rt_uint32_t)0x00004000) /* Rx Tx priority ratio */ +#define EMAC_DMABMR_RTPR_3_1 ((rt_uint32_t)0x00008000) /* Rx Tx priority ratio */ +#define EMAC_DMABMR_RTPR_4_1 ((rt_uint32_t)0x0000C000) /* Rx Tx priority ratio */ +#define EMAC_DMABMR_PBL ((rt_uint32_t)0x00003F00) /* Programmable burst length */ +#define EMAC_DMABMR_PBL_1Beat ((rt_uint32_t)0x00000100) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */ +#define EMAC_DMABMR_PBL_2Beat ((rt_uint32_t)0x00000200) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */ +#define EMAC_DMABMR_PBL_4Beat ((rt_uint32_t)0x00000400) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */ +#define EMAC_DMABMR_PBL_8Beat ((rt_uint32_t)0x00000800) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */ +#define EMAC_DMABMR_PBL_16Beat ((rt_uint32_t)0x00001000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */ +#define EMAC_DMABMR_PBL_32Beat ((rt_uint32_t)0x00002000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */ +#define EMAC_DMABMR_PBL_4xPBL_4Beat ((rt_uint32_t)0x01000100) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */ +#define EMAC_DMABMR_PBL_4xPBL_8Beat ((rt_uint32_t)0x01000200) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */ +#define EMAC_DMABMR_PBL_4xPBL_16Beat ((rt_uint32_t)0x01000400) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */ +#define EMAC_DMABMR_PBL_4xPBL_32Beat ((rt_uint32_t)0x01000800) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */ +#define EMAC_DMABMR_PBL_4xPBL_64Beat ((rt_uint32_t)0x01001000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 64 */ +#define EMAC_DMABMR_PBL_4xPBL_128Beat ((rt_uint32_t)0x01002000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 128 */ +#define EMAC_DMABMR_EDE ((rt_uint32_t)0x00000080) /* Enhanced Descriptor Enable */ +#define EMAC_DMABMR_DSL ((rt_uint32_t)0x0000007C) /* Descriptor Skip Length */ +#define EMAC_DMABMR_DA ((rt_uint32_t)0x00000002) /* DMA arbitration scheme */ +#define EMAC_DMABMR_SR ((rt_uint32_t)0x00000001) /* Software reset */ + +/* Bit definition for Ethernet DMA Transmit Poll Demand Register */ +#define EMAC_DMATPDR_TPD ((rt_uint32_t)0xFFFFFFFF) /* Transmit poll demand */ + +/* Bit definition for Ethernet DMA Receive Poll Demand Register */ +#define EMAC_DMARPDR_RPD ((rt_uint32_t)0xFFFFFFFF) /* Receive poll demand */ + +/* Bit definition for Ethernet DMA Receive Descriptor List Address Register */ +#define EMAC_DMARDLAR_SRL ((rt_uint32_t)0xFFFFFFFF) /* Start of receive list */ + +/* Bit definition for Ethernet DMA Transmit Descriptor List Address Register */ +#define EMAC_DMATDLAR_STL ((rt_uint32_t)0xFFFFFFFF) /* Start of transmit list */ + +/* Bit definition for Ethernet DMA Status Register */ +#define EMAC_DMASR_TSTS ((rt_uint32_t)0x20000000) /* Time-stamp trigger status */ +#define EMAC_DMASR_PMTS ((rt_uint32_t)0x10000000) /* PMT status */ +#define EMAC_DMASR_MMCS ((rt_uint32_t)0x08000000) /* MMC status */ +#define EMAC_DMASR_EBS ((rt_uint32_t)0x03800000) /* Error bits status */ +/* combination with EBS[2:0] for GetFlagStatus function */ +#define EMAC_DMASR_EBS_DescAccess ((rt_uint32_t)0x02000000) /* Error bits 0-data buffer, 1-desc. access */ +#define EMAC_DMASR_EBS_ReadTransf ((rt_uint32_t)0x01000000) /* Error bits 0-write transfer, 1-read transfer */ +#define EMAC_DMASR_EBS_DataTransfTx ((rt_uint32_t)0x00800000) /* Error bits 0-Rx DMA, 1-Tx DMA */ +#define EMAC_DMASR_TPS ((rt_uint32_t)0x00700000) /* Transmit process state */ +#define EMAC_DMASR_TPS_Stopped ((rt_uint32_t)0x00000000) /* Stopped - Reset or Stop Tx Command issued */ +#define EMAC_DMASR_TPS_Fetching ((rt_uint32_t)0x00100000) /* Running - fetching the Tx descriptor */ +#define EMAC_DMASR_TPS_Waiting ((rt_uint32_t)0x00200000) /* Running - waiting for status */ +#define EMAC_DMASR_TPS_Reading ((rt_uint32_t)0x00300000) /* Running - reading the data from host memory */ +#define EMAC_DMASR_TPS_Suspended ((rt_uint32_t)0x00600000) /* Suspended - Tx Descriptor unavailable */ +#define EMAC_DMASR_TPS_Closing ((rt_uint32_t)0x00700000) /* Running - closing Rx descriptor */ +#define EMAC_DMASR_RPS ((rt_uint32_t)0x000E0000) /* Receive process state */ +#define EMAC_DMASR_RPS_Stopped ((rt_uint32_t)0x00000000) /* Stopped - Reset or Stop Rx Command issued */ +#define EMAC_DMASR_RPS_Fetching ((rt_uint32_t)0x00020000) /* Running - fetching the Rx descriptor */ +#define EMAC_DMASR_RPS_Waiting ((rt_uint32_t)0x00060000) /* Running - waiting for packet */ +#define EMAC_DMASR_RPS_Suspended ((rt_uint32_t)0x00080000) /* Suspended - Rx Descriptor unavailable */ +#define EMAC_DMASR_RPS_Closing ((rt_uint32_t)0x000A0000) /* Running - closing descriptor */ +#define EMAC_DMASR_RPS_Queuing ((rt_uint32_t)0x000E0000) /* Running - queuing the receive frame into host memory */ +#define EMAC_DMASR_NIS ((rt_uint32_t)0x00010000) /* Normal interrupt summary */ +#define EMAC_DMASR_AIS ((rt_uint32_t)0x00008000) /* Abnormal interrupt summary */ +#define EMAC_DMASR_ERS ((rt_uint32_t)0x00004000) /* Early receive status */ +#define EMAC_DMASR_FBES ((rt_uint32_t)0x00002000) /* Fatal bus error status */ +#define EMAC_DMASR_ETS ((rt_uint32_t)0x00000400) /* Early transmit status */ +#define EMAC_DMASR_RWTS ((rt_uint32_t)0x00000200) /* Receive watchdog timeout status */ +#define EMAC_DMASR_RPSS ((rt_uint32_t)0x00000100) /* Receive process stopped status */ +#define EMAC_DMASR_RBUS ((rt_uint32_t)0x00000080) /* Receive buffer unavailable status */ +#define EMAC_DMASR_RS ((rt_uint32_t)0x00000040) /* Receive status */ +#define EMAC_DMASR_TUS ((rt_uint32_t)0x00000020) /* Transmit underflow status */ +#define EMAC_DMASR_ROS ((rt_uint32_t)0x00000010) /* Receive overflow status */ +#define EMAC_DMASR_TJTS ((rt_uint32_t)0x00000008) /* Transmit jabber timeout status */ +#define EMAC_DMASR_TBUS ((rt_uint32_t)0x00000004) /* Transmit buffer unavailable status */ +#define EMAC_DMASR_TPSS ((rt_uint32_t)0x00000002) /* Transmit process stopped status */ +#define EMAC_DMASR_TS ((rt_uint32_t)0x00000001) /* Transmit status */ + +/* Bit definition for Ethernet DMA Operation Mode Register */ +#define EMAC_DMAOMR_DTCEFD ((rt_uint32_t)0x04000000) /* Disable Dropping of TCP/IP checksum error frames */ +#define EMAC_DMAOMR_RSF ((rt_uint32_t)0x02000000) /* Receive store and forward */ +#define EMAC_DMAOMR_DFRF ((rt_uint32_t)0x01000000) /* Disable flushing of received frames */ +#define EMAC_DMAOMR_TSF ((rt_uint32_t)0x00200000) /* Transmit store and forward */ +#define EMAC_DMAOMR_FTF ((rt_uint32_t)0x00100000) /* Flush transmit FIFO */ +#define EMAC_DMAOMR_TTC ((rt_uint32_t)0x0001C000) /* Transmit threshold control */ +#define EMAC_DMAOMR_TTC_64Bytes ((rt_uint32_t)0x00000000) /* threshold level of the MTL Transmit FIFO is 64 Bytes */ +#define EMAC_DMAOMR_TTC_128Bytes ((rt_uint32_t)0x00004000) /* threshold level of the MTL Transmit FIFO is 128 Bytes */ +#define EMAC_DMAOMR_TTC_192Bytes ((rt_uint32_t)0x00008000) /* threshold level of the MTL Transmit FIFO is 192 Bytes */ +#define EMAC_DMAOMR_TTC_256Bytes ((rt_uint32_t)0x0000C000) /* threshold level of the MTL Transmit FIFO is 256 Bytes */ +#define EMAC_DMAOMR_TTC_40Bytes ((rt_uint32_t)0x00010000) /* threshold level of the MTL Transmit FIFO is 40 Bytes */ +#define EMAC_DMAOMR_TTC_32Bytes ((rt_uint32_t)0x00014000) /* threshold level of the MTL Transmit FIFO is 32 Bytes */ +#define EMAC_DMAOMR_TTC_24Bytes ((rt_uint32_t)0x00018000) /* threshold level of the MTL Transmit FIFO is 24 Bytes */ +#define EMAC_DMAOMR_TTC_16Bytes ((rt_uint32_t)0x0001C000) /* threshold level of the MTL Transmit FIFO is 16 Bytes */ +#define EMAC_DMAOMR_ST ((rt_uint32_t)0x00002000) /* Start/stop transmission command */ +#define EMAC_DMAOMR_FEF ((rt_uint32_t)0x00000080) /* Forward error frames */ +#define EMAC_DMAOMR_FUGF ((rt_uint32_t)0x00000040) /* Forward undersized good frames */ +#define EMAC_DMAOMR_RTC ((rt_uint32_t)0x00000018) /* receive threshold control */ +#define EMAC_DMAOMR_RTC_64Bytes ((rt_uint32_t)0x00000000) /* threshold level of the MTL Receive FIFO is 64 Bytes */ +#define EMAC_DMAOMR_RTC_32Bytes ((rt_uint32_t)0x00000008) /* threshold level of the MTL Receive FIFO is 32 Bytes */ +#define EMAC_DMAOMR_RTC_96Bytes ((rt_uint32_t)0x00000010) /* threshold level of the MTL Receive FIFO is 96 Bytes */ +#define EMAC_DMAOMR_RTC_128Bytes ((rt_uint32_t)0x00000018) /* threshold level of the MTL Receive FIFO is 128 Bytes */ +#define EMAC_DMAOMR_OSF ((rt_uint32_t)0x00000004) /* operate on second frame */ +#define EMAC_DMAOMR_SR ((rt_uint32_t)0x00000002) /* Start/stop receive */ + +/* Bit definition for Ethernet DMA Interrupt Enable Register */ +#define EMAC_DMAIER_NISE ((rt_uint32_t)0x00010000) /* Normal interrupt summary enable */ +#define EMAC_DMAIER_AISE ((rt_uint32_t)0x00008000) /* Abnormal interrupt summary enable */ +#define EMAC_DMAIER_ERIE ((rt_uint32_t)0x00004000) /* Early receive interrupt enable */ +#define EMAC_DMAIER_FBEIE ((rt_uint32_t)0x00002000) /* Fatal bus error interrupt enable */ +#define EMAC_DMAIER_ETIE ((rt_uint32_t)0x00000400) /* Early transmit interrupt enable */ +#define EMAC_DMAIER_RWTIE ((rt_uint32_t)0x00000200) /* Receive watchdog timeout interrupt enable */ +#define EMAC_DMAIER_RPSIE ((rt_uint32_t)0x00000100) /* Receive process stopped interrupt enable */ +#define EMAC_DMAIER_RBUIE ((rt_uint32_t)0x00000080) /* Receive buffer unavailable interrupt enable */ +#define EMAC_DMAIER_RIE ((rt_uint32_t)0x00000040) /* Receive interrupt enable */ +#define EMAC_DMAIER_TUIE ((rt_uint32_t)0x00000020) /* Transmit Underflow interrupt enable */ +#define EMAC_DMAIER_ROIE ((rt_uint32_t)0x00000010) /* Receive Overflow interrupt enable */ +#define EMAC_DMAIER_TJTIE ((rt_uint32_t)0x00000008) /* Transmit jabber timeout interrupt enable */ +#define EMAC_DMAIER_TBUIE ((rt_uint32_t)0x00000004) /* Transmit buffer unavailable interrupt enable */ +#define EMAC_DMAIER_TPSIE ((rt_uint32_t)0x00000002) /* Transmit process stopped interrupt enable */ +#define EMAC_DMAIER_TIE ((rt_uint32_t)0x00000001) /* Transmit interrupt enable */ + +/* Bit definition for Ethernet DMA Missed Frame and Buffer Overflow Counter Register */ +#define EMAC_DMAMFBOCR_OFOC ((rt_uint32_t)0x10000000) /* Overflow bit for FIFO overflow counter */ +#define EMAC_DMAMFBOCR_MFA ((rt_uint32_t)0x0FFE0000) /* Number of frames missed by the application */ +#define EMAC_DMAMFBOCR_OMFC ((rt_uint32_t)0x00010000) /* Overflow bit for missed frame counter */ +#define EMAC_DMAMFBOCR_MFC ((rt_uint32_t)0x0000FFFF) /* Number of frames missed by the controller */ + +/* Bit definition for Ethernet DMA Current Host Transmit Descriptor Register */ +#define EMAC_DMACHTDR_HTDAP ((rt_uint32_t)0xFFFFFFFF) /* Host transmit descriptor address pointer */ + +/* Bit definition for Ethernet DMA Current Host Receive Descriptor Register */ +#define EMAC_DMACHRDR_HRDAP ((rt_uint32_t)0xFFFFFFFF) /* Host receive descriptor address pointer */ + +/* Bit definition for Ethernet DMA Current Host Transmit Buffer Address Register */ +#define EMAC_DMACHTBAR_HTBAP ((rt_uint32_t)0xFFFFFFFF) /* Host transmit buffer address pointer */ + +/* Bit definition for Ethernet DMA Current Host Receive Buffer Address Register */ +#define EMAC_DMACHRBAR_HRBAP ((rt_uint32_t)0xFFFFFFFF) /* Host receive buffer address pointer */ + +//typedef enum { +// RESET = 0, SET = !RESET +//} FlagStatus, ITStatus; +//typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; + +/** + * ETH MAC Init structure definition + */ +typedef struct +{ + /** + * MAC + */ + rt_uint32_t EMAC_AutoNegotiation; /* Selects or not the AutoNegotiation mode for the external PHY + The AutoNegotiation allows an automatic setting of the Speed (10/100Mbps) + and the mode (half/full-duplex). + This parameter can be a value of @ref EMAC_AutoNegotiation */ + + rt_uint32_t EMAC_Watchdog; /* Selects or not the Watchdog timer + When enabled, the MAC allows no more then 2048 bytes to be received. + When disabled, the MAC can receive up to 16384 bytes. + This parameter can be a value of @ref EMAC_watchdog */ + + rt_uint32_t EMAC_Jabber; /* Selects or not Jabber timer + When enabled, the MAC allows no more then 2048 bytes to be sent. + When disabled, the MAC can send up to 16384 bytes. + This parameter can be a value of @ref EMAC_Jabber */ + + rt_uint32_t EMAC_InterFrameGap; /* Selects the minimum IFG between frames during transmission + This parameter can be a value of @ref EMAC_Inter_Frame_Gap */ + + rt_uint32_t EMAC_CarrierSense; /* Selects or not the Carrier Sense + This parameter can be a value of @ref EMAC_Carrier_Sense */ + + rt_uint32_t EMAC_Speed; /* Sets the Ethernet speed: 10/100 Mbps + This parameter can be a value of @ref EMAC_Speed */ + + rt_uint32_t EMAC_ReceiveOwn; /* Selects or not the ReceiveOwn + ReceiveOwn allows the reception of frames when the TX_EN signal is asserted + in Half-Duplex mode + This parameter can be a value of @ref EMAC_Receive_Own */ + + rt_uint32_t EMAC_LoopbackMode; /* Selects or not the internal MAC MII Loopback mode + This parameter can be a value of @ref EMAC_Loop_Back_Mode */ + + rt_uint32_t EMAC_Mode; /* Selects the MAC duplex mode: Half-Duplex or Full-Duplex mode + This parameter can be a value of @ref EMAC_Duplex_Mode */ + + rt_uint32_t EMAC_ChecksumOffload; /* Selects or not the IPv4 checksum checking for received frame payloads' TCP/UDP/ICMP headers. + This parameter can be a value of @ref EMAC_Checksum_Offload */ + + rt_uint32_t EMAC_RetryTransmission; /* Selects or not the MAC attempt retries transmission, based on the settings of BL, + when a colision occurs (Half-Duplex mode) + This parameter can be a value of @ref EMAC_Retry_Transmission */ + + rt_uint32_t EMAC_AutomaticPadCRCStrip; /* Selects or not the Automatic MAC Pad/CRC Stripping + This parameter can be a value of @ref EMAC_Automatic_Pad_CRC_Strip */ + + rt_uint32_t EMAC_BackOffLimit; /* Selects the BackOff limit value + This parameter can be a value of @ref EMAC_Back_Off_Limit */ + + rt_uint32_t EMAC_DeferralCheck; /* Selects or not the deferral check function (Half-Duplex mode) + This parameter can be a value of @ref EMAC_Deferral_Check */ + + rt_uint32_t EMAC_ReceiveAll; /* Selects or not all frames reception by the MAC (No fitering) + This parameter can be a value of @ref EMAC_Receive_All */ + + rt_uint32_t EMAC_SourceAddrFilter; /* Selects the Source Address Filter mode + This parameter can be a value of @ref EMAC_Source_Addr_Filter */ + + rt_uint32_t EMAC_PassControlFrames; /* Sets the forwarding mode of the control frames (including unicast and multicast PAUSE frames) + This parameter can be a value of @ref EMAC_Pass_Control_Frames */ + + rt_uint32_t EMAC_BroadcastFramesReception; /* Selects or not the reception of Broadcast Frames + This parameter can be a value of @ref EMAC_Broadcast_Frames_Reception */ + + rt_uint32_t EMAC_DestinationAddrFilter; /* Sets the destination filter mode for both unicast and multicast frames + This parameter can be a value of @ref EMAC_Destination_Addr_Filter */ + + rt_uint32_t EMAC_PromiscuousMode; /* Selects or not the Promiscuous Mode + This parameter can be a value of @ref EMAC_Promiscuous_Mode */ + + rt_uint32_t EMAC_MulticastFramesFilter; /* Selects the Multicast Frames filter mode: None/HashTableFilter/PerfectFilter/PerfectHashTableFilter + This parameter can be a value of @ref EMAC_Multicast_Frames_Filter */ + + rt_uint32_t EMAC_UnicastFramesFilter; /* Selects the Unicast Frames filter mode: HashTableFilter/PerfectFilter/PerfectHashTableFilter + This parameter can be a value of @ref EMAC_Unicast_Frames_Filter */ + + rt_uint32_t EMAC_HashTableHigh; /* This field holds the higher 32 bits of Hash table. */ + + rt_uint32_t EMAC_HashTableLow; /* This field holds the lower 32 bits of Hash table. */ + + rt_uint32_t EMAC_PauseTime; /* This field holds the value to be used in the Pause Time field in the + transmit control frame */ + + rt_uint32_t EMAC_ZeroQuantaPause; /* Selects or not the automatic generation of Zero-Quanta Pause Control frames + This parameter can be a value of @ref EMAC_Zero_Quanta_Pause */ + + rt_uint32_t EMAC_PauseLowThreshold; /* This field configures the threshold of the PAUSE to be checked for + automatic retransmission of PAUSE Frame + This parameter can be a value of @ref EMAC_Pause_Low_Threshold */ + + rt_uint32_t EMAC_UnicastPauseFrameDetect; /* Selects or not the MAC detection of the Pause frames (with MAC Address0 + unicast address and unique multicast address) + This parameter can be a value of @ref EMAC_Unicast_Pause_Frame_Detect */ + + rt_uint32_t EMAC_ReceiveFlowControl; /* Enables or disables the MAC to decode the received Pause frame and + disable its transmitter for a specified time (Pause Time) + This parameter can be a value of @ref EMAC_Receive_Flow_Control */ + + rt_uint32_t EMAC_TransmitFlowControl; /* Enables or disables the MAC to transmit Pause frames (Full-Duplex mode) + or the MAC back-pressure operation (Half-Duplex mode) + This parameter can be a value of @ref EMAC_Transmit_Flow_Control */ + + rt_uint32_t EMAC_VLANTagComparison; /* Selects the 12-bit VLAN identifier or the complete 16-bit VLAN tag for + comparison and filtering + This parameter can be a value of @ref EMAC_VLAN_Tag_Comparison */ + + rt_uint32_t EMAC_VLANTagIdentifier; /* Holds the VLAN tag identifier for receive frames */ + + /** + * DMA + */ + + rt_uint32_t EMAC_DropTCPIPChecksumErrorFrame; /* Selects or not the Dropping of TCP/IP Checksum Error Frames + This parameter can be a value of @ref EMAC_Drop_TCP_IP_Checksum_Error_Frame */ + + rt_uint32_t EMAC_ReceiveStoreForward; /* Enables or disables the Receive store and forward mode + This parameter can be a value of @ref EMAC_Receive_Store_Forward */ + + rt_uint32_t EMAC_FlushReceivedFrame; /* Enables or disables the flushing of received frames + This parameter can be a value of @ref EMAC_Flush_Received_Frame */ + + rt_uint32_t EMAC_TransmitStoreForward; /* Enables or disables Transmit store and forward mode + This parameter can be a value of @ref EMAC_Transmit_Store_Forward */ + + rt_uint32_t EMAC_TransmitThresholdControl; /* Selects or not the Transmit Threshold Control + This parameter can be a value of @ref EMAC_Transmit_Threshold_Control */ + + rt_uint32_t EMAC_ForwardErrorFrames; /* Selects or not the forward to the DMA of erroneous frames + This parameter can be a value of @ref EMAC_Forward_Error_Frames */ + + rt_uint32_t EMAC_ForwardUndersizedGoodFrames; /* Enables or disables the Rx FIFO to forward Undersized frames (frames with no Error + and length less than 64 bytes) including pad-bytes and CRC) + This parameter can be a value of @ref EMAC_Forward_Undersized_Good_Frames */ + + rt_uint32_t EMAC_ReceiveThresholdControl; /* Selects the threshold level of the Receive FIFO + This parameter can be a value of @ref EMAC_Receive_Threshold_Control */ + + rt_uint32_t EMAC_SecondFrameOperate; /* Selects or not the Operate on second frame mode, which allows the DMA to process a second + frame of Transmit data even before obtaining the status for the first frame. + This parameter can be a value of @ref EMAC_Second_Frame_Operate */ + + rt_uint32_t EMAC_AddressAlignedBeats; /* Enables or disables the Address Aligned Beats + This parameter can be a value of @ref EMAC_Address_Aligned_Beats */ + + rt_uint32_t EMAC_FixedBurst; /* Enables or disables the AHB Master interface fixed burst transfers + This parameter can be a value of @ref EMAC_Fixed_Burst */ + + rt_uint32_t EMAC_RxDMABurstLength; /* Indicates the maximum number of beats to be transferred in one Rx DMA transaction + This parameter can be a value of @ref EMAC_Rx_DMA_Burst_Length */ + + rt_uint32_t EMAC_TxDMABurstLength; /* Indicates sthe maximum number of beats to be transferred in one Tx DMA transaction + This parameter can be a value of @ref EMAC_Tx_DMA_Burst_Length */ + + rt_uint32_t EMAC_DescriptorSkipLength; /* Specifies the number of word to skip between two unchained int (Ring mode) */ + + rt_uint32_t EMAC_DMAArbitration; /* Selects the DMA Tx/Rx arbitration + This parameter can be a value of @ref EMAC_DMA_Arbitration */ +} EMAC_InitTypeDef; + +/**--------------------------------------------------------------------------**/ +/** + * DMA int types + */ +/**--------------------------------------------------------------------------**/ + +/** + * ETH DMA Descriptors data structure definition + */ +typedef struct +{ + rt_uint32_t Status; /* Status */ + rt_uint32_t ControlBufferSize; /* Control and Buffer1, Buffer2 lengths */ + rt_uint32_t Buffer1Addr; /* Buffer1 address pointer */ + rt_uint32_t Buffer2NextDescAddr; /* Buffer2 or next descriptor address pointer */ +} EMAC_DMADESCTypeDef; + +/**--------------------------------------------------------------------------**/ +/** + * ETH Frames defines + */ +/**--------------------------------------------------------------------------**/ + +#define EMAC_MAX_PACKET_SIZE 1520 /* EMAC_HEADER + EMAC_EXTRA + MAX_EMAC_PAYLOAD + EMAC_CRC */ +#define EMAC_HEADER 14 /* 6 byte Dest addr, 6 byte Src addr, 2 byte length/type */ +#define EMAC_CRC 4 /* Ethernet CRC */ +#define EMAC_EXTRA 2 /* Extra bytes in some cases */ +#define VLAN_TAG 4 /* optional 802.1q VLAN Tag */ +#define MIN_EMAC_PAYLOAD 46 /* Minimum Ethernet payload size */ +#define MAX_EMAC_PAYLOAD 1500 /* Maximum Ethernet payload size */ +#define JUMBO_FRAME_PAYLOAD 9000 /* Jumbo frame payload size */ + +/**--------------------------------------------------------------------------**/ +/** + * Ethernet DMA int registers bits definition + */ +/**--------------------------------------------------------------------------**/ + +#define EMAC_DMATxDesc_OWN ((rt_uint32_t)0x80000000) /* OWN bit: descriptor is owned by DMA engine */ +#define EMAC_DMATxDesc_IC ((rt_uint32_t)0x40000000) /* Interrupt on Completion */ +#define EMAC_DMATxDesc_LS ((rt_uint32_t)0x20000000) /* Last Segment */ +#define EMAC_DMATxDesc_FS ((rt_uint32_t)0x10000000) /* First Segment */ +#define EMAC_DMATxDesc_DC ((rt_uint32_t)0x08000000) /* Disable CRC */ +#define EMAC_DMATxDesc_DP ((rt_uint32_t)0x04000000) /* Disable Padding */ +#define EMAC_DMATxDesc_TTSE ((rt_uint32_t)0x02000000) /* Transmit Time Stamp Enable */ +#define EMAC_DMATxDesc_CIC ((rt_uint32_t)0x00C00000) /* Checksum Insertion Control: 4 cases */ +#define EMAC_DMATxDesc_CIC_ByPass ((rt_uint32_t)0x00000000) /* Do Nothing: Checksum Engine is bypassed */ +#define EMAC_DMATxDesc_CIC_IPV4Header ((rt_uint32_t)0x00400000) /* IPV4 header Checksum Insertion */ +#define EMAC_DMATxDesc_CIC_TCPUDPICMP_Segment ((rt_uint32_t)0x00800000) /* TCP/UDP/ICMP Checksum Insertion calculated over segment only */ +#define EMAC_DMATxDesc_CIC_TCPUDPICMP_Full ((rt_uint32_t)0x00C00000) /* TCP/UDP/ICMP Checksum Insertion fully calculated */ +#define EMAC_DMATxDesc_TER ((rt_uint32_t)0x00200000) /* Transmit End of Ring */ +#define EMAC_DMATxDesc_TCH ((rt_uint32_t)0x00100000) /* Second Address Chained */ +#define EMAC_DMATxDesc_TTSS ((rt_uint32_t)0x00020000) /* Tx Time Stamp Status */ +#define EMAC_DMATxDesc_IHE ((rt_uint32_t)0x00010000) /* IP Header Error */ +#define EMAC_DMATxDesc_ES ((rt_uint32_t)0x00008000) /* Error summary: OR of the following bits: UE || ED || EC || LCO || NC || LCA || FF || JT */ +#define EMAC_DMATxDesc_JT ((rt_uint32_t)0x00004000) /* Jabber Timeout */ +#define EMAC_DMATxDesc_FF ((rt_uint32_t)0x00002000) /* Frame Flushed: DMA/MTL flushed the frame due to SW flush */ +#define EMAC_DMATxDesc_PCE ((rt_uint32_t)0x00001000) /* Payload Checksum Error */ +#define EMAC_DMATxDesc_LCA ((rt_uint32_t)0x00000800) /* Loss of Carrier: carrier lost during transmission */ +#define EMAC_DMATxDesc_NC ((rt_uint32_t)0x00000400) /* No Carrier: no carrier signal from the transceiver */ +#define EMAC_DMATxDesc_LCO ((rt_uint32_t)0x00000200) /* Late Collision: transmission aborted due to collision */ +#define EMAC_DMATxDesc_EC ((rt_uint32_t)0x00000100) /* Excessive Collision: transmission aborted after 16 collisions */ +#define EMAC_DMATxDesc_VF ((rt_uint32_t)0x00000080) /* VLAN Frame */ +#define EMAC_DMATxDesc_CC ((rt_uint32_t)0x00000078) /* Collision Count */ +#define EMAC_DMATxDesc_ED ((rt_uint32_t)0x00000004) /* Excessive Deferral */ +#define EMAC_DMATxDesc_UF ((rt_uint32_t)0x00000002) /* Underflow Error: late data arrival from the memory */ +#define EMAC_DMATxDesc_DB ((rt_uint32_t)0x00000001) /* Deferred Bit */ + +#define EMAC_DMATxDesc_TBS2 ((rt_uint32_t)0x1FFF0000) /* Transmit Buffer2 Size */ +#define EMAC_DMATxDesc_TBS1 ((rt_uint32_t)0x00001FFF) /* Transmit Buffer1 Size */ + +#define EMAC_DMATxDesc_B1AP ((rt_uint32_t)0xFFFFFFFF) /* Buffer1 Address Pointer */ + +#define EMAC_DMATxDesc_B2AP ((rt_uint32_t)0xFFFFFFFF) /* Buffer2 Address Pointer */ + +#define EMAC_DMARxDesc_OWN ((rt_uint32_t)0x80000000) /* OWN bit: descriptor is owned by DMA engine */ +#define EMAC_DMARxDesc_AFM ((rt_uint32_t)0x40000000) /* DA Filter Fail for the rx frame */ +#define EMAC_DMARxDesc_FL ((rt_uint32_t)0x3FFF0000) /* Receive descriptor frame length */ +#define EMAC_DMARxDesc_ES ((rt_uint32_t)0x00008000) /* Error summary: OR of the following bits: DE || OE || IPC || LC || RWT || RE || CE */ +#define EMAC_DMARxDesc_DE ((rt_uint32_t)0x00004000) /* Descriptor error: no more int for receive frame */ +#define EMAC_DMARxDesc_SAF ((rt_uint32_t)0x00002000) /* SA Filter Fail for the received frame */ +#define EMAC_DMARxDesc_LE ((rt_uint32_t)0x00001000) /* Frame size not matching with length field */ +#define EMAC_DMARxDesc_OE ((rt_uint32_t)0x00000800) /* Overflow Error: Frame was damaged due to buffer overflow */ +#define EMAC_DMARxDesc_VLAN ((rt_uint32_t)0x00000400) /* VLAN Tag: received frame is a VLAN frame */ +#define EMAC_DMARxDesc_FS ((rt_uint32_t)0x00000200) /* First descriptor of the frame */ +#define EMAC_DMARxDesc_LS ((rt_uint32_t)0x00000100) /* Last descriptor of the frame */ +#define EMAC_DMARxDesc_IPV4HCE ((rt_uint32_t)0x00000080) /* IPC Checksum Error: Rx Ipv4 header checksum error */ +#define EMAC_DMARxDesc_LC ((rt_uint32_t)0x00000040) /* Late collision occurred during reception */ +#define EMAC_DMARxDesc_FT ((rt_uint32_t)0x00000020) /* Frame type - Ethernet, otherwise 802.3 */ +#define EMAC_DMARxDesc_RWT ((rt_uint32_t)0x00000010) /* Receive Watchdog Timeout: watchdog timer expired during reception */ +#define EMAC_DMARxDesc_RE ((rt_uint32_t)0x00000008) /* Receive error: error reported by MII interface */ +#define EMAC_DMARxDesc_DBE ((rt_uint32_t)0x00000004) /* Dribble bit error: frame contains non int multiple of 8 bits */ +#define EMAC_DMARxDesc_CE ((rt_uint32_t)0x00000002) /* CRC error */ +#define EMAC_DMARxDesc_MAMPCE ((rt_uint32_t)0x00000001) /* Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */ + +#define EMAC_DMARxDesc_DIC ((rt_uint32_t)0x80000000) /* Disable Interrupt on Completion */ +#define EMAC_DMARxDesc_RBS2 ((rt_uint32_t)0x1FFF0000) /* Receive Buffer2 Size */ +#define EMAC_DMARxDesc_RER ((rt_uint32_t)0x00008000) /* Receive End of Ring */ +#define EMAC_DMARxDesc_RCH ((rt_uint32_t)0x00004000) /* Second Address Chained */ +#define EMAC_DMARxDesc_RBS1 ((rt_uint32_t)0x00001FFF) /* Receive Buffer1 Size */ + +#define EMAC_DMARxDesc_B1AP ((rt_uint32_t)0xFFFFFFFF) /* Buffer1 Address Pointer */ + +#define EMAC_DMARxDesc_B2AP ((rt_uint32_t)0xFFFFFFFF) /* Buffer2 Address Pointer */ + +#define PHY_READ_TO ((rt_uint32_t)0x0004FFFF) +#define PHY_WRITE_TO ((rt_uint32_t)0x0004FFFF) + +#define PHY_ResetDelay ((rt_uint32_t)0x000FFFFF) + +#define PHY_ConfigDelay ((rt_uint32_t)0x00FFFFFF) + +#define PHY_BCR 0 /* Tranceiver Basic Control Register */ +#define PHY_BSR 1 /* Tranceiver Basic Status Register */ + +#define PHY_Reset ((rt_uint16_t)0x8000) /* PHY Reset */ +//#define PHY_Loopback ((rt_uint16_t)0x4000) /* Select loop-back mode */ +//#define PHY_FULLDUPLEX_100M ((rt_uint16_t)0x2100) /* Set the full-duplex mode at 100 Mb/s */ +//#define PHY_HALFDUPLEX_100M ((rt_uint16_t)0x2000) /* Set the half-duplex mode at 100 Mb/s */ +//#define PHY_FULLDUPLEX_10M ((rt_uint16_t)0x0100) /* Set the full-duplex mode at 10 Mb/s */ +//#define PHY_HALFDUPLEX_10M ((rt_uint16_t)0x0000) /* Set the half-duplex mode at 10 Mb/s */ +//#define PHY_AutoNegotiation ((rt_uint16_t)0x1000) /* Enable auto-negotiation function */ +//#define PHY_Restart_AutoNegotiation ((rt_uint16_t)0x0200) /* Restart auto-negotiation function */ +//#define PHY_Powerdown ((rt_uint16_t)0x0800) /* Select the power down mode */ +//#define PHY_Isolate ((rt_uint16_t)0x0400) /* Isolate PHY from MII */ +// +//#define PHY_AutoNego_Complete ((rt_uint16_t)0x0020) /* Auto-Negotiation process completed */ +//#define PHY_Linked_Status ((rt_uint16_t)0x0004) /* Valid link established */ +//#define PHY_Jabber_detection ((rt_uint16_t)0x0002) /* Jabber condition detected */ +// +//#define PHY_SR 16 /* Transceiver Status Register */ +// +//#define PHY_Speed_Status ((rt_uint16_t)0x0002) /* Configured information of Speed: 10Mbps */ +//#define PHY_Duplex_Status ((rt_uint16_t)0x0004) /* Configured information of Duplex: Full-duplex */ + +#define EMAC_AutoNegotiation_Enable ((rt_uint32_t)0x00000001) +#define EMAC_AutoNegotiation_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_Watchdog_Enable ((rt_uint32_t)0x00000000) +#define EMAC_Watchdog_Disable ((rt_uint32_t)0x00800000) + +#define EMAC_Jabber_Enable ((rt_uint32_t)0x00000000) +#define EMAC_Jabber_Disable ((rt_uint32_t)0x00400000) + +#define EMAC_InterFrameGap_96Bit ((rt_uint32_t)0x00000000) /* minimum IFG between frames during transmission is 96Bit */ +#define EMAC_InterFrameGap_88Bit ((rt_uint32_t)0x00020000) /* minimum IFG between frames during transmission is 88Bit */ +#define EMAC_InterFrameGap_80Bit ((rt_uint32_t)0x00040000) /* minimum IFG between frames during transmission is 80Bit */ +#define EMAC_InterFrameGap_72Bit ((rt_uint32_t)0x00060000) /* minimum IFG between frames during transmission is 72Bit */ +#define EMAC_InterFrameGap_64Bit ((rt_uint32_t)0x00080000) /* minimum IFG between frames during transmission is 64Bit */ +#define EMAC_InterFrameGap_56Bit ((rt_uint32_t)0x000A0000) /* minimum IFG between frames during transmission is 56Bit */ +#define EMAC_InterFrameGap_48Bit ((rt_uint32_t)0x000C0000) /* minimum IFG between frames during transmission is 48Bit */ +#define EMAC_InterFrameGap_40Bit ((rt_uint32_t)0x000E0000) /* minimum IFG between frames during transmission is 40Bit */ + +#define EMAC_CarrierSense_Enable ((rt_uint32_t)0x00000000) +#define EMAC_CarrierSense_Disable ((rt_uint32_t)0x00010000) + +#define EMAC_Speed_10M ((rt_uint32_t)0x00000000) +#define EMAC_Speed_100M ((rt_uint32_t)0x00004000) + +#define EMAC_ReceiveOwn_Enable ((rt_uint32_t)0x00000000) +#define EMAC_ReceiveOwn_Disable ((rt_uint32_t)0x00002000) + +#define EMAC_LoopbackMode_Enable ((rt_uint32_t)0x00001000) +#define EMAC_LoopbackMode_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_Mode_FullDuplex ((rt_uint32_t)0x00000800) +#define EMAC_Mode_HalfDuplex ((rt_uint32_t)0x00000000) + +#define EMAC_ChecksumOffload_Enable ((rt_uint32_t)0x00000400) +#define EMAC_ChecksumOffload_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_RetryTransmission_Enable ((rt_uint32_t)0x00000000) +#define EMAC_RetryTransmission_Disable ((rt_uint32_t)0x00000200) + +#define EMAC_AutomaticPadCRCStrip_Enable ((rt_uint32_t)0x00000080) +#define EMAC_AutomaticPadCRCStrip_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_BackOffLimit_10 ((rt_uint32_t)0x00000000) +#define EMAC_BackOffLimit_8 ((rt_uint32_t)0x00000020) +#define EMAC_BackOffLimit_4 ((rt_uint32_t)0x00000040) +#define EMAC_BackOffLimit_1 ((rt_uint32_t)0x00000060) + +#define EMAC_DeferralCheck_Enable ((rt_uint32_t)0x00000010) +#define EMAC_DeferralCheck_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_ReceiveAll_Enable ((rt_uint32_t)0x80000000) +#define EMAC_ReceiveAll_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_SourceAddrFilter_Normal_Enable ((rt_uint32_t)0x00000200) +#define EMAC_SourceAddrFilter_Inverse_Enable ((rt_uint32_t)0x00000300) +#define EMAC_SourceAddrFilter_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_PassControlFrames_BlockAll ((rt_uint32_t)0x00000040) /* MAC filters all control frames from reaching the application */ +#define EMAC_PassControlFrames_ForwardAll ((rt_uint32_t)0x00000080) /* MAC forwards all control frames to application even if they fail the Address Filter */ +#define EMAC_PassControlFrames_ForwardPassedAddrFilter ((rt_uint32_t)0x000000C0) /* MAC forwards control frames that pass the Address Filter. */ + +#define EMAC_BroadcastFramesReception_Enable ((rt_uint32_t)0x00000000) +#define EMAC_BroadcastFramesReception_Disable ((rt_uint32_t)0x00000020) + +#define EMAC_DestinationAddrFilter_Normal ((rt_uint32_t)0x00000000) +#define EMAC_DestinationAddrFilter_Inverse ((rt_uint32_t)0x00000008) + +#define EMAC_PromiscuousMode_Enable ((rt_uint32_t)0x00000001) +#define EMAC_PromiscuousMode_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_MulticastFramesFilter_PerfectHashTable ((rt_uint32_t)0x00000404) +#define EMAC_MulticastFramesFilter_HashTable ((rt_uint32_t)0x00000004) +#define EMAC_MulticastFramesFilter_Perfect ((rt_uint32_t)0x00000000) +#define EMAC_MulticastFramesFilter_None ((rt_uint32_t)0x00000010) + +#define EMAC_UnicastFramesFilter_PerfectHashTable ((rt_uint32_t)0x00000402) +#define EMAC_UnicastFramesFilter_HashTable ((rt_uint32_t)0x00000002) +#define EMAC_UnicastFramesFilter_Perfect ((rt_uint32_t)0x00000000) + +#define EMAC_ZeroQuantaPause_Enable ((rt_uint32_t)0x00000000) +#define EMAC_ZeroQuantaPause_Disable ((rt_uint32_t)0x00000080) + +#define EMAC_PauseLowThreshold_Minus4 ((rt_uint32_t)0x00000000) /* Pause time minus 4 slot times */ +#define EMAC_PauseLowThreshold_Minus28 ((rt_uint32_t)0x00000010) /* Pause time minus 28 slot times */ +#define EMAC_PauseLowThreshold_Minus144 ((rt_uint32_t)0x00000020) /* Pause time minus 144 slot times */ +#define EMAC_PauseLowThreshold_Minus256 ((rt_uint32_t)0x00000030) /* Pause time minus 256 slot times */ + +#define EMAC_UnicastPauseFrameDetect_Enable ((rt_uint32_t)0x00000008) +#define EMAC_UnicastPauseFrameDetect_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_ReceiveFlowControl_Enable ((rt_uint32_t)0x00000004) +#define EMAC_ReceiveFlowControl_Disable ((rt_uint32_t)0x00000000) +#define EMAC_TransmitFlowControl_Enable ((rt_uint32_t)0x00000002) +#define EMAC_TransmitFlowControl_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_VLANTagComparison_12Bit ((rt_uint32_t)0x00010000) +#define EMAC_VLANTagComparison_16Bit ((rt_uint32_t)0x00000000) + +#define EMAC_MAC_FLAG_TST ((rt_uint32_t)0x00000200) /* Time stamp trigger flag (on MAC) */ +#define EMAC_MAC_FLAG_MMCT ((rt_uint32_t)0x00000040) /* MMC transmit flag */ +#define EMAC_MAC_FLAG_MMCR ((rt_uint32_t)0x00000020) /* MMC receive flag */ +#define EMAC_MAC_FLAG_MMC ((rt_uint32_t)0x00000010) /* MMC flag (on MAC) */ +#define EMAC_MAC_FLAG_PMT ((rt_uint32_t)0x00000008) /* PMT flag (on MAC) */ + +#define EMAC_MAC_IT_TST ((rt_uint32_t)0x00000200) /* Time stamp trigger interrupt (on MAC) */ +#define EMAC_MAC_IT_MMCT ((rt_uint32_t)0x00000040) /* MMC transmit interrupt */ +#define EMAC_MAC_IT_MMCR ((rt_uint32_t)0x00000020) /* MMC receive interrupt */ +#define EMAC_MAC_IT_MMC ((rt_uint32_t)0x00000010) /* MMC interrupt (on MAC) */ +#define EMAC_MAC_IT_PMT ((rt_uint32_t)0x00000008) /* PMT interrupt (on MAC) */ + +#define EMAC_MAC_Address0 ((rt_uint32_t)0x00000000) +#define EMAC_MAC_Address1 ((rt_uint32_t)0x00000008) +#define EMAC_MAC_Address2 ((rt_uint32_t)0x00000010) +#define EMAC_MAC_Address3 ((rt_uint32_t)0x00000018) + +#define EMAC_MAC_AddressFilter_SA ((rt_uint32_t)0x00000000) +#define EMAC_MAC_AddressFilter_DA ((rt_uint32_t)0x00000008) + +#define EMAC_MAC_AddressMask_Byte6 ((rt_uint32_t)0x20000000) /* Mask MAC Address high reg bits [15:8] */ +#define EMAC_MAC_AddressMask_Byte5 ((rt_uint32_t)0x10000000) /* Mask MAC Address high reg bits [7:0] */ +#define EMAC_MAC_AddressMask_Byte4 ((rt_uint32_t)0x08000000) /* Mask MAC Address low reg bits [31:24] */ +#define EMAC_MAC_AddressMask_Byte3 ((rt_uint32_t)0x04000000) /* Mask MAC Address low reg bits [23:16] */ +#define EMAC_MAC_AddressMask_Byte2 ((rt_uint32_t)0x02000000) /* Mask MAC Address low reg bits [15:8] */ +#define EMAC_MAC_AddressMask_Byte1 ((rt_uint32_t)0x01000000) /* Mask MAC Address low reg bits [70] */ + +#define EMAC_DMATxDesc_LastSegment ((rt_uint32_t)0x40000000) /* Last Segment */ +#define EMAC_DMATxDesc_FirstSegment ((rt_uint32_t)0x20000000) /* First Segment */ + +#define EMAC_DMATxDesc_ChecksumByPass ((rt_uint32_t)0x00000000) /* Checksum engine bypass */ +#define EMAC_DMATxDesc_ChecksumIPV4Header ((rt_uint32_t)0x00400000) /* IPv4 header checksum insertion */ +#define EMAC_DMATxDesc_ChecksumTCPUDPICMPSegment ((rt_uint32_t)0x00800000) /* TCP/UDP/ICMP checksum insertion. Pseudo header checksum is assumed to be present */ +#define EMAC_DMATxDesc_ChecksumTCPUDPICMPFull ((rt_uint32_t)0x00C00000) /* TCP/UDP/ICMP checksum fully in hardware including pseudo header */ + +#define EMAC_DMARxDesc_Buffer1 ((rt_uint32_t)0x00000000) /* DMA Rx Desc Buffer1 */ +#define EMAC_DMARxDesc_Buffer2 ((rt_uint32_t)0x00000001) /* DMA Rx Desc Buffer2 */ + +#define EMAC_DropTCPIPChecksumErrorFrame_Enable ((rt_uint32_t)0x00000000) +#define EMAC_DropTCPIPChecksumErrorFrame_Disable ((rt_uint32_t)0x04000000) + +#define EMAC_ReceiveStoreForward_Enable ((rt_uint32_t)0x02000000) +#define EMAC_ReceiveStoreForward_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_FlushReceivedFrame_Enable ((rt_uint32_t)0x00000000) +#define EMAC_FlushReceivedFrame_Disable ((rt_uint32_t)0x01000000) + +#define EMAC_TransmitStoreForward_Enable ((rt_uint32_t)0x00200000) +#define EMAC_TransmitStoreForward_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_TransmitThresholdControl_64Bytes ((rt_uint32_t)0x00000000) /* threshold level of the MTL Transmit FIFO is 64 Bytes */ +#define EMAC_TransmitThresholdControl_128Bytes ((rt_uint32_t)0x00004000) /* threshold level of the MTL Transmit FIFO is 128 Bytes */ +#define EMAC_TransmitThresholdControl_192Bytes ((rt_uint32_t)0x00008000) /* threshold level of the MTL Transmit FIFO is 192 Bytes */ +#define EMAC_TransmitThresholdControl_256Bytes ((rt_uint32_t)0x0000C000) /* threshold level of the MTL Transmit FIFO is 256 Bytes */ +#define EMAC_TransmitThresholdControl_40Bytes ((rt_uint32_t)0x00010000) /* threshold level of the MTL Transmit FIFO is 40 Bytes */ +#define EMAC_TransmitThresholdControl_32Bytes ((rt_uint32_t)0x00014000) /* threshold level of the MTL Transmit FIFO is 32 Bytes */ +#define EMAC_TransmitThresholdControl_24Bytes ((rt_uint32_t)0x00018000) /* threshold level of the MTL Transmit FIFO is 24 Bytes */ +#define EMAC_TransmitThresholdControl_16Bytes ((rt_uint32_t)0x0001C000) /* threshold level of the MTL Transmit FIFO is 16 Bytes */ + +#define EMAC_ForwardErrorFrames_Enable ((rt_uint32_t)0x00000080) +#define EMAC_ForwardErrorFrames_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_ForwardUndersizedGoodFrames_Enable ((rt_uint32_t)0x00000040) +#define EMAC_ForwardUndersizedGoodFrames_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_ReceiveThresholdControl_64Bytes ((rt_uint32_t)0x00000000) /* threshold level of the MTL Receive FIFO is 64 Bytes */ +#define EMAC_ReceiveThresholdControl_32Bytes ((rt_uint32_t)0x00000008) /* threshold level of the MTL Receive FIFO is 32 Bytes */ +#define EMAC_ReceiveThresholdControl_96Bytes ((rt_uint32_t)0x00000010) /* threshold level of the MTL Receive FIFO is 96 Bytes */ +#define EMAC_ReceiveThresholdControl_128Bytes ((rt_uint32_t)0x00000018) /* threshold level of the MTL Receive FIFO is 128 Bytes */ + +#define EMAC_SecondFrameOperate_Enable ((rt_uint32_t)0x00000004) +#define EMAC_SecondFrameOperate_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_AddressAlignedBeats_Enable ((rt_uint32_t)0x02000000) +#define EMAC_AddressAlignedBeats_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_FixedBurst_Enable ((rt_uint32_t)0x00010000) +#define EMAC_FixedBurst_Disable ((rt_uint32_t)0x00000000) + +#define EMAC_RxDMABurstLength_1Beat ((rt_uint32_t)0x00020000) /* maximum number of beats to be transferred in one RxDMA transaction is 1 */ +#define EMAC_RxDMABurstLength_2Beat ((rt_uint32_t)0x00040000) /* maximum number of beats to be transferred in one RxDMA transaction is 2 */ +#define EMAC_RxDMABurstLength_4Beat ((rt_uint32_t)0x00080000) /* maximum number of beats to be transferred in one RxDMA transaction is 4 */ +#define EMAC_RxDMABurstLength_8Beat ((rt_uint32_t)0x00100000) /* maximum number of beats to be transferred in one RxDMA transaction is 8 */ +#define EMAC_RxDMABurstLength_16Beat ((rt_uint32_t)0x00200000) /* maximum number of beats to be transferred in one RxDMA transaction is 16 */ +#define EMAC_RxDMABurstLength_32Beat ((rt_uint32_t)0x00400000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */ +#define EMAC_RxDMABurstLength_4xPBL_4Beat ((rt_uint32_t)0x01020000) /* maximum number of beats to be transferred in one RxDMA transaction is 4 */ +#define EMAC_RxDMABurstLength_4xPBL_8Beat ((rt_uint32_t)0x01040000) /* maximum number of beats to be transferred in one RxDMA transaction is 8 */ +#define EMAC_RxDMABurstLength_4xPBL_16Beat ((rt_uint32_t)0x01080000) /* maximum number of beats to be transferred in one RxDMA transaction is 16 */ +#define EMAC_RxDMABurstLength_4xPBL_32Beat ((rt_uint32_t)0x01100000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */ +#define EMAC_RxDMABurstLength_4xPBL_64Beat ((rt_uint32_t)0x01200000) /* maximum number of beats to be transferred in one RxDMA transaction is 64 */ +#define EMAC_RxDMABurstLength_4xPBL_128Beat ((rt_uint32_t)0x01400000) /* maximum number of beats to be transferred in one RxDMA transaction is 128 */ + +#define EMAC_TxDMABurstLength_1Beat ((rt_uint32_t)0x00000100) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */ +#define EMAC_TxDMABurstLength_2Beat ((rt_uint32_t)0x00000200) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */ +#define EMAC_TxDMABurstLength_4Beat ((rt_uint32_t)0x00000400) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */ +#define EMAC_TxDMABurstLength_8Beat ((rt_uint32_t)0x00000800) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */ +#define EMAC_TxDMABurstLength_16Beat ((rt_uint32_t)0x00001000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */ +#define EMAC_TxDMABurstLength_32Beat ((rt_uint32_t)0x00002000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */ +#define EMAC_TxDMABurstLength_4xPBL_4Beat ((rt_uint32_t)0x01000100) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */ +#define EMAC_TxDMABurstLength_4xPBL_8Beat ((rt_uint32_t)0x01000200) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */ +#define EMAC_TxDMABurstLength_4xPBL_16Beat ((rt_uint32_t)0x01000400) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */ +#define EMAC_TxDMABurstLength_4xPBL_32Beat ((rt_uint32_t)0x01000800) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */ +#define EMAC_TxDMABurstLength_4xPBL_64Beat ((rt_uint32_t)0x01001000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 64 */ +#define EMAC_TxDMABurstLength_4xPBL_128Beat ((rt_uint32_t)0x01002000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 128 */ + +#define EMAC_DMAArbitration_RoundRobin_RxTx_1_1 ((rt_uint32_t)0x00000000) +#define EMAC_DMAArbitration_RoundRobin_RxTx_2_1 ((rt_uint32_t)0x00004000) +#define EMAC_DMAArbitration_RoundRobin_RxTx_3_1 ((rt_uint32_t)0x00008000) +#define EMAC_DMAArbitration_RoundRobin_RxTx_4_1 ((rt_uint32_t)0x0000C000) +#define EMAC_DMAArbitration_RxPriorTx ((rt_uint32_t)0x00000002) + +#define EMAC_DMA_FLAG_TST ((rt_uint32_t)0x20000000) /* Time-stamp trigger interrupt (on DMA) */ +#define EMAC_DMA_FLAG_PMT ((rt_uint32_t)0x10000000) /* PMT interrupt (on DMA) */ +#define EMAC_DMA_FLAG_MMC ((rt_uint32_t)0x08000000) /* MMC interrupt (on DMA) */ +#define EMAC_DMA_FLAG_DataTransferError ((rt_uint32_t)0x00800000) /* Error bits 0-Rx DMA, 1-Tx DMA */ +#define EMAC_DMA_FLAG_ReadWriteError ((rt_uint32_t)0x01000000) /* Error bits 0-write transfer, 1-read transfer */ +#define EMAC_DMA_FLAG_AccessError ((rt_uint32_t)0x02000000) /* Error bits 0-data buffer, 1-desc. access */ +#define EMAC_DMA_FLAG_NIS ((rt_uint32_t)0x00010000) /* Normal interrupt summary flag */ +#define EMAC_DMA_FLAG_AIS ((rt_uint32_t)0x00008000) /* Abnormal interrupt summary flag */ +#define EMAC_DMA_FLAG_ER ((rt_uint32_t)0x00004000) /* Early receive flag */ +#define EMAC_DMA_FLAG_FBE ((rt_uint32_t)0x00002000) /* Fatal bus error flag */ +#define EMAC_DMA_FLAG_ET ((rt_uint32_t)0x00000400) /* Early transmit flag */ +#define EMAC_DMA_FLAG_RWT ((rt_uint32_t)0x00000200) /* Receive watchdog timeout flag */ +#define EMAC_DMA_FLAG_RPS ((rt_uint32_t)0x00000100) /* Receive process stopped flag */ +#define EMAC_DMA_FLAG_RBU ((rt_uint32_t)0x00000080) /* Receive buffer unavailable flag */ +#define EMAC_DMA_FLAG_R ((rt_uint32_t)0x00000040) /* Receive flag */ +#define EMAC_DMA_FLAG_TU ((rt_uint32_t)0x00000020) /* Underflow flag */ +#define EMAC_DMA_FLAG_RO ((rt_uint32_t)0x00000010) /* Overflow flag */ +#define EMAC_DMA_FLAG_TJT ((rt_uint32_t)0x00000008) /* Transmit jabber timeout flag */ +#define EMAC_DMA_FLAG_TBU ((rt_uint32_t)0x00000004) /* Transmit buffer unavailable flag */ +#define EMAC_DMA_FLAG_TPS ((rt_uint32_t)0x00000002) /* Transmit process stopped flag */ +#define EMAC_DMA_FLAG_T ((rt_uint32_t)0x00000001) /* Transmit flag */ + +#define EMAC_DMA_INT_GLPII ((rt_uint32_t)(1UL<<30)) /* GMAC LPI Interrupt. */ +#define EMAC_DMA_INT_TTI ((rt_uint32_t)(1UL<<29)) /* Time-Stamp Trigger Interrupt. */ +#define EMAC_DMA_INT_GPI ((rt_uint32_t)(1UL<<28)) /* GMAC PMT Interrupt. */ +#define EMAC_DMA_INT_GMI ((rt_uint32_t)(1UL<<27)) /* GMAC MMC Interrupt. */ +#define EMAC_DMA_INT_GLI ((rt_uint32_t)(1UL<<26)) /* GMAC Line interface Interrupt. */ +#define EMAC_DMA_INT_NIS ((rt_uint32_t)(1UL<<16)) /* Normal interrupt summary. */ +#define EMAC_DMA_INT_AIS ((rt_uint32_t)(1UL<<15)) /* Abnormal interrupt summary. */ +#define EMAC_DMA_INT_ER ((rt_uint32_t)0x00004000) /* Early receive interrupt */ +#define EMAC_DMA_INT_FBE ((rt_uint32_t)0x00002000) /* Fatal bus error interrupt */ +#define EMAC_DMA_INT_ET ((rt_uint32_t)0x00000400) /* Early transmit interrupt */ +#define EMAC_DMA_INT_RWT ((rt_uint32_t)0x00000200) /* Receive watchdog timeout interrupt */ +#define EMAC_DMA_INT_RPS ((rt_uint32_t)0x00000100) /* Receive process stopped interrupt */ +#define EMAC_DMA_INT_RBU ((rt_uint32_t)0x00000080) /* Receive buffer unavailable interrupt */ +#define EMAC_DMA_INT_R ((rt_uint32_t)0x00000040) /* Receive interrupt */ +#define EMAC_DMA_INT_TU ((rt_uint32_t)0x00000020) /* Underflow interrupt */ +#define EMAC_DMA_INT_RO ((rt_uint32_t)0x00000010) /* Overflow interrupt */ +#define EMAC_DMA_INT_TJT ((rt_uint32_t)0x00000008) /* Transmit jabber timeout interrupt */ +#define EMAC_DMA_INT_TBU ((rt_uint32_t)0x00000004) /* Transmit buffer unavailable interrupt */ +#define EMAC_DMA_INT_TPS ((rt_uint32_t)0x00000002) /* Transmit process stopped interrupt */ +#define EMAC_DMA_INT_T ((rt_uint32_t)0x00000001) /* Transmit interrupt */ + +#define EMAC_DMA_TransmitProcess_Stopped ((rt_uint32_t)0x00000000) /* Stopped - Reset or Stop Tx Command issued */ +#define EMAC_DMA_TransmitProcess_Fetching ((rt_uint32_t)0x00100000) /* Running - fetching the Tx descriptor */ +#define EMAC_DMA_TransmitProcess_Waiting ((rt_uint32_t)0x00200000) /* Running - waiting for status */ +#define EMAC_DMA_TransmitProcess_Reading ((rt_uint32_t)0x00300000) /* Running - reading the data from host memory */ +#define EMAC_DMA_TransmitProcess_Suspended ((rt_uint32_t)0x00600000) /* Suspended - Tx Descriptor unavailable */ +#define EMAC_DMA_TransmitProcess_Closing ((rt_uint32_t)0x00700000) /* Running - closing Rx descriptor */ + +#define EMAC_DMA_ReceiveProcess_Stopped ((rt_uint32_t)0x00000000) /* Stopped - Reset or Stop Rx Command issued */ +#define EMAC_DMA_ReceiveProcess_Fetching ((rt_uint32_t)0x00020000) /* Running - fetching the Rx descriptor */ +#define EMAC_DMA_ReceiveProcess_Waiting ((rt_uint32_t)0x00060000) /* Running - waiting for packet */ +#define EMAC_DMA_ReceiveProcess_Suspended ((rt_uint32_t)0x00080000) /* Suspended - Rx Descriptor unavailable */ +#define EMAC_DMA_ReceiveProcess_Closing ((rt_uint32_t)0x000A0000) /* Running - closing descriptor */ +#define EMAC_DMA_ReceiveProcess_Queuing ((rt_uint32_t)0x000E0000) /* Running - queuing the receive frame into host memory */ + +#define EMAC_DMA_Overflow_RxFIFOCounter ((rt_uint32_t)0x10000000) /* Overflow bit for FIFO overflow counter */ +#define EMAC_DMA_Overflow_MissedFrameCounter ((rt_uint32_t)0x00010000) /* Overflow bit for missed frame counter */ + +#define EMAC_PMT_FLAG_WUFFRPR ((rt_uint32_t)0x80000000) /* Wake-Up Frame Filter Register Pointer Reset */ +#define EMAC_PMT_FLAG_WUFR ((rt_uint32_t)0x00000040) /* Wake-Up Frame Received */ +#define EMAC_PMT_FLAG_MPR ((rt_uint32_t)0x00000020) /* Magic Packet Received */ + +#define EMAC_MMC_IT_TGF ((rt_uint32_t)0x00200000) /* When Tx good frame counter reaches half the maximum value */ +#define EMAC_MMC_IT_TGFMSC ((rt_uint32_t)0x00008000) /* When Tx good multi col counter reaches half the maximum value */ +#define EMAC_MMC_IT_TGFSC ((rt_uint32_t)0x00004000) /* When Tx good single col counter reaches half the maximum value */ +#define EMAC_MMC_IT_RGUF ((rt_uint32_t)0x10020000) /* When Rx good unicast frames counter reaches half the maximum value */ +#define EMAC_MMC_IT_RFAE ((rt_uint32_t)0x10000040) /* When Rx alignment error counter reaches half the maximum value */ +#define EMAC_MMC_IT_RFCE ((rt_uint32_t)0x10000020) /* When Rx crc error counter reaches half the maximum value */ + +#define EMAC_MMCCR ((rt_uint32_t)0x00000100) /* MMC CR register */ +#define EMAC_MMCRIR ((rt_uint32_t)0x00000104) /* MMC RIR register */ +#define EMAC_MMCTIR ((rt_uint32_t)0x00000108) /* MMC TIR register */ +#define EMAC_MMCRIMR ((rt_uint32_t)0x0000010C) /* MMC RIMR register */ +#define EMAC_MMCTIMR ((rt_uint32_t)0x00000110) /* MMC TIMR register */ +#define EMAC_MMCTGFSCCR ((rt_uint32_t)0x0000014C) /* MMC TGFSCCR register */ +#define EMAC_MMCTGFMSCCR ((rt_uint32_t)0x00000150) /* MMC TGFMSCCR register */ +#define EMAC_MMCTGFCR ((rt_uint32_t)0x00000168) /* MMC TGFCR register */ +#define EMAC_MMCRFCECR ((rt_uint32_t)0x00000194) /* MMC RFCECR register */ +#define EMAC_MMCRFAECR ((rt_uint32_t)0x00000198) /* MMC RFAECR register */ +#define EMAC_MMCRGUFCR ((rt_uint32_t)0x000001C4) /* MMC RGUFCR register */ + +#define EMAC_PTP_FineUpdate ((rt_uint32_t)0x00000001) /* Fine Update method */ +#define EMAC_PTP_CoarseUpdate ((rt_uint32_t)0x00000000) /* Coarse Update method */ + +#define EMAC_PTP_FLAG_TSARU ((rt_uint32_t)0x00000020) /* Addend Register Update */ +#define EMAC_PTP_FLAG_TSITE ((rt_uint32_t)0x00000010) /* Time Stamp Interrupt Trigger */ +#define EMAC_PTP_FLAG_TSSTU ((rt_uint32_t)0x00000008) /* Time Stamp Update */ +#define EMAC_PTP_FLAG_TSSTI ((rt_uint32_t)0x00000004) /* Time Stamp Initialize */ + +#define EMAC_PTP_PositiveTime ((rt_uint32_t)0x00000000) /* Positive time value */ +#define EMAC_PTP_NegativeTime ((rt_uint32_t)0x80000000) /* Negative time value */ + +#define EMAC_PTPTSCR ((rt_uint32_t)0x00000700) /* PTP TSCR register */ +#define EMAC_PTPSSIR ((rt_uint32_t)0x00000704) /* PTP SSIR register */ +#define EMAC_PTPTSHR ((rt_uint32_t)0x00000708) /* PTP TSHR register */ +#define EMAC_PTPTSLR ((rt_uint32_t)0x0000070C) /* PTP TSLR register */ +#define EMAC_PTPTSHUR ((rt_uint32_t)0x00000710) /* PTP TSHUR register */ +#define EMAC_PTPTSLUR ((rt_uint32_t)0x00000714) /* PTP TSLUR register */ +#define EMAC_PTPTSAR ((rt_uint32_t)0x00000718) /* PTP TSAR register */ +#define EMAC_PTPTTHR ((rt_uint32_t)0x0000071C) /* PTP TTHR register */ +#define EMAC_PTPTTLR ((rt_uint32_t)0x00000720) /* PTP TTLR register */ + +/* ETHERNET MAC address offsets */ +#define EMAC_MAC_ADDR_HBASE (ETHERNET_MAC0_BASE + 0x40) /* ETHERNET MAC address high offset */ +#define EMAC_MAC_ADDR_LBASE (ETHERNET_MAC0_BASE + 0x44) /* ETHERNET MAC address low offset */ + +/* ETHERNET MACMIIAR register Mask */ +#define MACMIIAR_CR_MASK ((rt_uint32_t)0xFFFFFFE3) + +/* ETHERNET MACCR register Mask */ +#define MACCR_CLEAR_MASK ((rt_uint32_t)0xFF20810F) + +/* ETHERNET MACFCR register Mask */ +#define MACFCR_CLEAR_MASK ((rt_uint32_t)0x0000FF41) + +/* ETHERNET DMAOMR register Mask */ +#define DMAOMR_CLEAR_MASK ((rt_uint32_t)0xF8DE3F23) + +/* ETHERNET errors */ +#define EMAC_ERROR ((rt_uint32_t)0) +#define EMAC_SUCCESS ((rt_uint32_t)1) + +/* ETHERNET DMA Rx descriptors Frame Length Shift */ +#define EMAC_DMARXDESC_FRAME_LENGTHSHIFT 16 + + + + +/* ETHERNET-MAC registers */ +/* ETHERNET-MAC registers */ +struct rt_synopsys_eth +{ + volatile rt_uint32_t MCR; + volatile rt_uint32_t MFFR; + volatile rt_uint32_t MHTRH; + volatile rt_uint32_t MHTRL; + volatile rt_uint32_t GAR; + volatile rt_uint32_t GDR; + volatile rt_uint32_t FCR; + volatile rt_uint32_t VTR; + rt_uint8_t RESERVED0[8]; + + volatile rt_uint32_t RWFFR; + volatile rt_uint32_t PMTR; + volatile rt_uint32_t LPICSR; + volatile rt_uint32_t LPITCR; + volatile rt_uint32_t ISR; + volatile rt_uint32_t IMR; + + struct MARS + { + volatile rt_uint32_t MARH; + volatile rt_uint32_t MARL; + } MARs[16]; + + rt_uint8_t RESERVED1[24]; + volatile rt_uint32_t RGSR; + rt_uint8_t RESERVED2[36]; + volatile rt_uint32_t mmc_cntl; + volatile rt_uint32_t mmc_intr_rx; + volatile rt_uint32_t mmc_intr_tx; + volatile rt_uint32_t mmc_intr_mask_rx; + volatile rt_uint32_t mmc_intr_mask_tx; + volatile rt_uint32_t txoctetcount_gb; + volatile rt_uint32_t txframecount_gb; + volatile rt_uint32_t txbroadcastframes_g; + volatile rt_uint32_t txmulticastframes_g; + volatile rt_uint32_t tx64octets_gb; + volatile rt_uint32_t tx65to127octets_gb; + volatile rt_uint32_t tx128to255octets_gb; + volatile rt_uint32_t tx256to511octets_gb; + volatile rt_uint32_t tx512to1023octets_gb; + volatile rt_uint32_t tx1024tomaxoctets_gb; + volatile rt_uint32_t txunicastframes_gb; + volatile rt_uint32_t txmulticastframes_gb; + volatile rt_uint32_t txbroadcastframes_gb; + volatile rt_uint32_t txunderflowerror; + volatile rt_uint32_t txsinglecol_g; + volatile rt_uint32_t txmulticol_g; + volatile rt_uint32_t txdeferred; + volatile rt_uint32_t txlatecol; + volatile rt_uint32_t txexesscol; + volatile rt_uint32_t txcarriererror; + volatile rt_uint32_t txoctetcount_g; + volatile rt_uint32_t txframecount_g; + volatile rt_uint32_t txexecessdef_g; + volatile rt_uint32_t txpauseframes; + volatile rt_uint32_t txvlanframes_g; + rt_uint8_t RESERVED3[8]; + volatile rt_uint32_t rxframecount_gb; + volatile rt_uint32_t rxoctetcount_gb; + volatile rt_uint32_t rxoctetcount_g; + volatile rt_uint32_t rxbroadcastframes_g; + volatile rt_uint32_t rxmulticastframes_g; + volatile rt_uint32_t rxcrcerror; + volatile rt_uint32_t rxallignmenterror; + volatile rt_uint32_t rxrunterror; + volatile rt_uint32_t rxjabbererror; + volatile rt_uint32_t rxundersize_g; + volatile rt_uint32_t rxoversize_g; + volatile rt_uint32_t rx64octets_gb; + volatile rt_uint32_t rx65to127octets_gb; + volatile rt_uint32_t rx128to255octets_gb; + volatile rt_uint32_t rx256to511octets_gb; + volatile rt_uint32_t rx512to1023octets_gb; + volatile rt_uint32_t rx1024tomaxoctets_gb; + volatile rt_uint32_t rxunicastframes_g; + volatile rt_uint32_t rxlengtherror; + volatile rt_uint32_t rxoutofrangetype; + volatile rt_uint32_t rxpauseframes; + volatile rt_uint32_t rxfifooverflow; + volatile rt_uint32_t rxvlanframes_gb; + volatile rt_uint32_t rxwatchdogerror; + rt_uint8_t RESERVED4[32]; + volatile rt_uint32_t mmc_ipc_intr_mask_rx; + rt_uint8_t RESERVED5[4]; + volatile rt_uint32_t mmc_ipc_intr_rx; + rt_uint8_t RESERVED6[4]; + volatile rt_uint32_t rxipv4_gd_frms; + volatile rt_uint32_t rxipv4_hdrerr_frms; + volatile rt_uint32_t rxipv4_nopay_frms; + volatile rt_uint32_t rxipv4_frag_frms; + volatile rt_uint32_t rxipv4_udsbl_frms; + volatile rt_uint32_t rxipv6_gd_frms; + volatile rt_uint32_t rxipv6_hdrerr_frms; + volatile rt_uint32_t rxipv6_nopay_frms; + volatile rt_uint32_t rxudp_gd_frms; + volatile rt_uint32_t rxudp_err_frms; + volatile rt_uint32_t rxtcp_gd_frms; + volatile rt_uint32_t rxtcp_err_frms; + volatile rt_uint32_t rxicmp_gd_frms; + volatile rt_uint32_t rxicmp_err_frms; + rt_uint8_t RESERVED7[8]; + volatile rt_uint32_t rxipv4_gd_octets; + volatile rt_uint32_t rxipv4_hdrerr_octets; + volatile rt_uint32_t rxipv4_nopay_octets; + volatile rt_uint32_t rxipv4_frag_octets; + volatile rt_uint32_t rxipv4_udsbl_octets; + volatile rt_uint32_t rxipv6_gd_octets; + volatile rt_uint32_t rxipv6_hdrerr_octets; + volatile rt_uint32_t rxipv6_nopay_octets; + volatile rt_uint32_t rxudp_gd_octets; + volatile rt_uint32_t rxudp_err_octets; + volatile rt_uint32_t rxtcp_gd_octets; + volatile rt_uint32_t rxtcp_err_octets; + volatile rt_uint32_t rxicmp_gd_octets; + volatile rt_uint32_t rxicmp_err_octets; + rt_uint8_t RESERVED8[1144]; + volatile rt_uint32_t TSCR; + volatile rt_uint32_t SSIR; + volatile rt_uint32_t STSR; + volatile rt_uint32_t STNR; + volatile rt_uint32_t STSUR; + volatile rt_uint32_t STNUR; + volatile rt_uint32_t TSAR; + volatile rt_uint32_t TTSR; + volatile rt_uint32_t TTNR; + volatile rt_uint32_t STHWSR; + volatile rt_uint32_t TSR; + volatile rt_uint32_t PPSCR; + volatile rt_uint32_t ATNR; + volatile rt_uint32_t ATSR; + rt_uint8_t RESERVED9[200]; + volatile rt_uint32_t MAR16H; + volatile rt_uint32_t MAR16L; + volatile rt_uint32_t MAR17H; + volatile rt_uint32_t MAR17L; + volatile rt_uint32_t MAR18H; + volatile rt_uint32_t MAR18L; + volatile rt_uint32_t MAR19H; + volatile rt_uint32_t MAR19L; + volatile rt_uint32_t MAR20H; + volatile rt_uint32_t MAR20L; + volatile rt_uint32_t MAR21H; + volatile rt_uint32_t MAR21L; + volatile rt_uint32_t MAR22H; + volatile rt_uint32_t MAR22L; + volatile rt_uint32_t MAR23H; + volatile rt_uint32_t MAR23L; + volatile rt_uint32_t MAR24H; + volatile rt_uint32_t MAR24L; + volatile rt_uint32_t MAR25H; + volatile rt_uint32_t MAR25L; + volatile rt_uint32_t MAR26H; + volatile rt_uint32_t MAR26L; + volatile rt_uint32_t MAR27H; + volatile rt_uint32_t MAR27L; + volatile rt_uint32_t MAR28H; + volatile rt_uint32_t MAR28L; + volatile rt_uint32_t MAR29H; + volatile rt_uint32_t MAR29L; + volatile rt_uint32_t MAR30H; + volatile rt_uint32_t MAR30L; + volatile rt_uint32_t MAR31H; + volatile rt_uint32_t MAR31L; + rt_uint8_t RESERVED10[1920]; + volatile rt_uint32_t BMR; + volatile rt_uint32_t TPDR; + volatile rt_uint32_t RPDR; + volatile rt_uint32_t RDLAR; + volatile rt_uint32_t TDLAR; + volatile rt_uint32_t SR; + volatile rt_uint32_t OMR; + volatile rt_uint32_t IER; + volatile rt_uint32_t MFBOCR; + volatile rt_uint32_t RIWTR; + rt_uint8_t RESERVED11[4]; + volatile rt_uint32_t AHBSR; + rt_uint8_t RESERVED12[24]; + volatile rt_uint32_t CHTDR; + volatile rt_uint32_t CHRDR; + volatile rt_uint32_t CHTBAR; + volatile rt_uint32_t CHRBAR; +}; +typedef struct rt_synopsys_eth rt_synopsys_eth; + + +rt_uint32_t EMAC_init(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t SystemCoreClock); + +void EMAC_start(struct rt_synopsys_eth * ETHERNET_MAC); + +rt_uint16_t EMAC_PHY_read(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg); +rt_uint32_t EMAC_PHY_write(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint16_t PHYAddress, rt_uint16_t PHYReg, rt_uint16_t PHYValue); + +void EMAC_MAC_Addr_config(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t MacAddr, rt_uint8_t *Addr); +void EMAC_clear_pending(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t EMAC_DMA_IT); + +void EMAC_INT_config(struct rt_synopsys_eth * ETHERNET_MAC, rt_uint32_t EMAC_DMA_IT, rt_bool_t NewState); +void EMAC_resume_transmission(struct rt_synopsys_eth * ETHERNET_MAC); +void EMAC_resume_reception(struct rt_synopsys_eth * ETHERNET_MAC); + +#endif diff --git a/bsp/gd32450z-eval/gd32_rom.icf b/bsp/gd32450z-eval/gd32_rom.icf new file mode 100644 index 0000000000..1741be6a71 --- /dev/null +++ b/bsp/gd32450z-eval/gd32_rom.icf @@ -0,0 +1,40 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x082FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x2000; +define symbol __ICFEDIT_size_heap__ = 0x2000; +/**** End of ICF editor section. ###ICF###*/ + +export symbol __ICFEDIT_region_RAM_end__; + +define symbol __region_RAM1_start__ = 0x10000000; +define symbol __region_RAM1_end__ = 0x1000FFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region RAM1_region = mem:[from __region_RAM1_start__ to __region_RAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +keep { section FSymTab }; +keep { section VSymTab }; +keep { section .rti_fn* }; +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; +place in RAM1_region { section .sram }; \ No newline at end of file diff --git a/bsp/gd32450z-eval/gd32_rom.ld b/bsp/gd32450z-eval/gd32_rom.ld new file mode 100644 index 0000000000..ec1c65c34e --- /dev/null +++ b/bsp/gd32450z-eval/gd32_rom.ld @@ -0,0 +1,142 @@ +/* + * linker script for GD32F4xx with GNU ld + * bernard.xiong 2009-10-14 + */ + +/* Program Entry, set to mark it as "used" and avoid gc */ +MEMORY +{ + CODE (rx) : ORIGIN = 0x08000000, LENGTH = 3072k /* 3072KB flash */ + DATA (rw) : ORIGIN = 0x20000000, LENGTH = 192k /* 192KB sram */ +} +ENTRY(Reset_Handler) +_system_stack_size = 0x200; + +SECTIONS +{ + .text : + { + . = ALIGN(4); + _stext = .; + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + /* section information for initial. */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + . = ALIGN(4); + _etext = .; + } > CODE = 0 + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > CODE + __exidx_end = .; + + /* .data section which is used for initialized data */ + + .data : AT (_sidata) + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _sdata = . ; + + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _edata = . ; + } >DATA + + .stack : + { + . = . + _system_stack_size; + . = ALIGN(4); + _estack = .; + } >DATA + + __bss_start = .; + .bss : + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; + + *(.bss) + *(.bss.*) + *(COMMON) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _ebss = . ; + + *(.bss.init) + } > DATA + __bss_end = .; + + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/bsp/gd32450z-eval/gd32_rom.sct b/bsp/gd32450z-eval/gd32_rom.sct new file mode 100644 index 0000000000..f8a5eaf1e2 --- /dev/null +++ b/bsp/gd32450z-eval/gd32_rom.sct @@ -0,0 +1,15 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x08000000 0x00300000 { ; load region size_region + ER_IROM1 0x08000000 0x00300000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM1 0x20000000 0x00030000 { ; RW data + .ANY (+RW +ZI) + } +} + diff --git a/bsp/gd32450z-eval/project.ewp b/bsp/gd32450z-eval/project.ewp new file mode 100644 index 0000000000..2245e82dbb --- /dev/null +++ b/bsp/gd32450z-eval/project.ewp @@ -0,0 +1,2631 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 20 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 29 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 20 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + Applications + + $PROJ_DIR$\applications\application.c + + + $PROJ_DIR$\applications\rtgui_demo.c + + + $PROJ_DIR$\applications\startup.c + + + + CORTEX-M4 + + $PROJ_DIR$\..\..\..\git\rt-thread\libcpu\arm\common\backtrace.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\libcpu\arm\cortex-m4\context_iar.S + + + $PROJ_DIR$\..\..\..\git\rt-thread\libcpu\arm\cortex-m4\cpuport.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\libcpu\arm\common\div0.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\libcpu\arm\common\showmem.c + + + + DeviceDrivers + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\src\completion.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\src\dataqueue.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\i2c\i2c-bit-ops.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\i2c\i2c_core.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\i2c\i2c_dev.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\src\pipe.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\src\portal.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\src\ringbuffer.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\rtc\rtc.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\serial\serial.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\spi\sfud\src\sfud.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\spi\spi_core.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\spi\spi_dev.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\spi\spi_flash_sfud.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\drivers\src\workqueue.c + + + + Drivers + + $PROJ_DIR$\drivers\board.c + + + $PROJ_DIR$\drivers\drv_enet.c + + + $PROJ_DIR$\drivers\drv_exmc_sdram.c + + + $PROJ_DIR$\drivers\drv_lcd.c + + + $PROJ_DIR$\drivers\drv_spi.c + + + $PROJ_DIR$\drivers\drv_spi_flash.c + + + $PROJ_DIR$\drivers\drv_usart.c + + + $PROJ_DIR$\drivers\gd32f450z_lcd_eval.c + + + $PROJ_DIR$\drivers\synopsys_emac.c + + + + Filesystem + + $PROJ_DIR$\..\..\..\git\rt-thread\components\dfs\filesystems\devfs\console.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\dfs\filesystems\devfs\devfs.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\dfs\src\dfs.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\dfs\filesystems\elmfat\dfs_elm.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\dfs\src\dfs_file.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\dfs\src\dfs_fs.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\dfs\src\dfs_posix.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\dfs\filesystems\elmfat\ff.c + + + + finsh + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\cmd.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\finsh_compiler.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\finsh_error.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\finsh_heap.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\finsh_init.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\finsh_node.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\finsh_ops.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\finsh_parser.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\finsh_token.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\finsh_var.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\finsh_vm.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\shell.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\finsh\symbol.c + + + + GD32_Lib + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_adc.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_can.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_crc.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_ctc.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dac.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dbg.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dci.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dma.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_enet.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_exmc.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_exti.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_fmc.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_fwdgt.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_gpio.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_i2c.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_ipa.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_iref.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_misc.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_pmu.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_rcu.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_rtc.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_sdio.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_spi.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_syscfg.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_timer.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_tli.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_trng.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_usart.c + + + $PROJ_DIR$\Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_wwdgt.c + + + $PROJ_DIR$\Libraries\CMSIS\GD\GD32F4xx\Source\IAR\startup_gd32f4xx.s + + + $PROJ_DIR$\Libraries\CMSIS\GD\GD32F4xx\Source\system_gd32f4xx.c + + + + GUIEngine + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\asc12font.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\asc16font.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\blit.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\box.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\color.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\container.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\dc.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\dc_blend.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\dc_buffer.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\dc_client.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\dc_hw.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\dc_rotozoom.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\dc_trans.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\filerw.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\font.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\font_bmp.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\font_fnt.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\font_freetype.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\font_hz_bmp.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\font_hz_file.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\hz12font.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\hz16font.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\image.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\image_bmp.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\image_hdc.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\image_jpg.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\image_png.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\image_xpm.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\matrix.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\mouse.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\region.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\rtgui_app.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\rtgui_driver.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\rtgui_object.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\rtgui_system.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\server.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\title.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\topwin.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\widget.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\gui\src\window.c + + + + Kernel + + $PROJ_DIR$\..\..\..\git\rt-thread\src\clock.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\components.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\device.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\idle.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\ipc.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\irq.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\kservice.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\mem.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\memheap.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\mempool.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\module.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\object.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\scheduler.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\thread.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\src\timer.c + + + + LwIP + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\api_lib.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\api_msg.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\autoip.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\def.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\dhcp.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\dns.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\err.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\netif\etharp.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\netif\ethernetif.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\icmp.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\igmp.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\inet.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\inet_chksum.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\init.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\ip.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\ip_addr.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\ip_frag.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\memp.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\netbuf.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\netdb.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\netif.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\netifapi.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\pbuf.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\raw.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\netif\slipif.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\sockets.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\stats.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\sys.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\arch\sys_arch.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\tcp.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\tcp_in.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\tcp_out.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\tcpip.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\timers.c + + + $PROJ_DIR$\..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\udp.c + + + diff --git a/bsp/gd32450z-eval/project.uvproj b/bsp/gd32450z-eval/project.uvproj new file mode 100644 index 0000000000..69cd18f7ae --- /dev/null +++ b/bsp/gd32450z-eval/project.uvproj @@ -0,0 +1,1354 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32f4xx + 0x4 + ARM-ADS + + + GD32F450ZK + GigaDevice + IRAM(0x20000000-0x2002FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x08000000-0x082FFFFF) CLOCK(16000000) CPUTYPE("Cortex-M4") FPU2 + + "Startup\GD\GD32F4xx\startup_gd32f4xx.s" ("GD32F4xx Startup Code") + UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0GD32F4xx_3MB -FS08000000 -FL0300000) + 0 + gd32f4xx0.h + + + + + + + + + + SFD\GD\GD32F4xx\GD32F4xx.SFR + 0 + 0 + + + + GD\GD32F4xx\ + GD\GD32F4xx\ + + 0 + 0 + 0 + 0 + 1 + + .\output\ + rtthread-gd32f4xx + 1 + 0 + 1 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP + DCM.DLL + -pCM3 + SARMCM3.DLL + + TCM.DLL + -pCM3 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 0 + + 0 + 6 + + + + + + + + + + + + + + Segger\JL2CM3.dll + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 1 + 0 + 8 + 1 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 1 + 0x8000000 + 0x300000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x300000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 0 + 0x10000000 + 0x10000 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + + + GD32F4XX, USE_STDPERIPH_DRIVER + + applications;.;drivers;Libraries\CMSIS\GD\GD32F4xx\Include;Libraries\CMSIS;Libraries\GD32F4xx_standard_peripheral\Include;..\..\..\git\rt-thread\include;..\..\..\git\rt-thread\libcpu\arm\cortex-m4;..\..\..\git\rt-thread\libcpu\arm\common;..\..\..\git\rt-thread\components\dfs\include;..\..\..\git\rt-thread\components\dfs\filesystems\devfs;..\..\..\git\rt-thread\components\dfs\filesystems\elmfat;..\..\..\git\rt-thread\components\drivers\include;..\..\..\git\rt-thread\components\drivers\include;..\..\..\git\rt-thread\components\drivers\include;..\..\..\git\rt-thread\components\drivers\spi;..\..\..\git\rt-thread\components\drivers\include;..\..\..\git\rt-thread\components\drivers\spi\sfud\inc;..\..\..\git\rt-thread\components\drivers\include;..\..\..\git\rt-thread\components\finsh;..\..\..\git\rt-thread\components\gui\include;..\..\..\git\rt-thread\components\net\lwip-1.4.1\src;..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\include;..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\include\ipv4;..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\arch\include;..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\include\netif;..\..\..\git\rt-thread\components\trace;..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\Config;..\..\..\git\rt-thread\components\trace;..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\SEGGER + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + --keep *.o(RTMSymTab) --keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab) + + + + + + + + Applications + + + application.c + 1 + applications\application.c + + + rtgui_demo.c + 1 + applications\rtgui_demo.c + + + startup.c + 1 + applications\startup.c + + + + + Drivers + + + board.c + 1 + drivers\board.c + + + drv_exmc_sdram.c + 1 + drivers\drv_exmc_sdram.c + + + drv_usart.c + 1 + drivers\drv_usart.c + + + drv_enet.c + 1 + drivers\drv_enet.c + + + synopsys_emac.c + 1 + drivers\synopsys_emac.c + + + drv_lcd.c + 1 + drivers\drv_lcd.c + + + gd32f450z_lcd_eval.c + 1 + drivers\gd32f450z_lcd_eval.c + + + drv_spi_flash.c + 1 + drivers\drv_spi_flash.c + + + drv_spi.c + 1 + drivers\drv_spi.c + + + + + GD32_Lib + + + gd32f4xx_adc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_adc.c + + + gd32f4xx_can.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_can.c + + + gd32f4xx_crc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_crc.c + + + gd32f4xx_ctc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_ctc.c + + + gd32f4xx_dac.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dac.c + + + gd32f4xx_dbg.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dbg.c + + + gd32f4xx_dci.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dci.c + + + gd32f4xx_dma.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dma.c + + + gd32f4xx_enet.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_enet.c + + + gd32f4xx_exmc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_exmc.c + + + gd32f4xx_exti.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_exti.c + + + gd32f4xx_fmc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_fmc.c + + + gd32f4xx_fwdgt.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_fwdgt.c + + + gd32f4xx_gpio.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_gpio.c + + + gd32f4xx_i2c.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_i2c.c + + + gd32f4xx_ipa.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_ipa.c + + + gd32f4xx_iref.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_iref.c + + + gd32f4xx_misc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_misc.c + + + gd32f4xx_pmu.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_pmu.c + + + gd32f4xx_rcu.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_rcu.c + + + gd32f4xx_rtc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_rtc.c + + + gd32f4xx_sdio.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_sdio.c + + + gd32f4xx_spi.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_spi.c + + + gd32f4xx_syscfg.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_syscfg.c + + + gd32f4xx_timer.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_timer.c + + + gd32f4xx_tli.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_tli.c + + + gd32f4xx_trng.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_trng.c + + + gd32f4xx_usart.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_usart.c + + + gd32f4xx_wwdgt.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_wwdgt.c + + + system_gd32f4xx.c + 1 + Libraries\CMSIS\GD\GD32F4xx\Source\system_gd32f4xx.c + + + startup_gd32f4xx.s + 2 + Libraries\CMSIS\GD\GD32F4xx\Source\ARM\startup_gd32f4xx.s + + + + + Kernel + + + clock.c + 1 + ..\..\..\git\rt-thread\src\clock.c + + + components.c + 1 + ..\..\..\git\rt-thread\src\components.c + + + device.c + 1 + ..\..\..\git\rt-thread\src\device.c + + + idle.c + 1 + ..\..\..\git\rt-thread\src\idle.c + + + ipc.c + 1 + ..\..\..\git\rt-thread\src\ipc.c + + + irq.c + 1 + ..\..\..\git\rt-thread\src\irq.c + + + kservice.c + 1 + ..\..\..\git\rt-thread\src\kservice.c + + + mem.c + 1 + ..\..\..\git\rt-thread\src\mem.c + + + memheap.c + 1 + ..\..\..\git\rt-thread\src\memheap.c + + + mempool.c + 1 + ..\..\..\git\rt-thread\src\mempool.c + + + module.c + 1 + ..\..\..\git\rt-thread\src\module.c + + + object.c + 1 + ..\..\..\git\rt-thread\src\object.c + + + scheduler.c + 1 + ..\..\..\git\rt-thread\src\scheduler.c + + + thread.c + 1 + ..\..\..\git\rt-thread\src\thread.c + + + timer.c + 1 + ..\..\..\git\rt-thread\src\timer.c + + + + + CORTEX-M4 + + + cpuport.c + 1 + ..\..\..\git\rt-thread\libcpu\arm\cortex-m4\cpuport.c + + + context_rvds.S + 2 + ..\..\..\git\rt-thread\libcpu\arm\cortex-m4\context_rvds.S + + + backtrace.c + 1 + ..\..\..\git\rt-thread\libcpu\arm\common\backtrace.c + + + div0.c + 1 + ..\..\..\git\rt-thread\libcpu\arm\common\div0.c + + + showmem.c + 1 + ..\..\..\git\rt-thread\libcpu\arm\common\showmem.c + + + + + Filesystem + + + dfs.c + 1 + ..\..\..\git\rt-thread\components\dfs\src\dfs.c + + + dfs_file.c + 1 + ..\..\..\git\rt-thread\components\dfs\src\dfs_file.c + + + dfs_fs.c + 1 + ..\..\..\git\rt-thread\components\dfs\src\dfs_fs.c + + + dfs_posix.c + 1 + ..\..\..\git\rt-thread\components\dfs\src\dfs_posix.c + + + console.c + 1 + ..\..\..\git\rt-thread\components\dfs\filesystems\devfs\console.c + + + devfs.c + 1 + ..\..\..\git\rt-thread\components\dfs\filesystems\devfs\devfs.c + + + dfs_elm.c + 1 + ..\..\..\git\rt-thread\components\dfs\filesystems\elmfat\dfs_elm.c + + + ff.c + 1 + ..\..\..\git\rt-thread\components\dfs\filesystems\elmfat\ff.c + + + + + DeviceDrivers + + + i2c_core.c + 1 + ..\..\..\git\rt-thread\components\drivers\i2c\i2c_core.c + + + i2c_dev.c + 1 + ..\..\..\git\rt-thread\components\drivers\i2c\i2c_dev.c + + + i2c-bit-ops.c + 1 + ..\..\..\git\rt-thread\components\drivers\i2c\i2c-bit-ops.c + + + rtc.c + 1 + ..\..\..\git\rt-thread\components\drivers\rtc\rtc.c + + + serial.c + 1 + ..\..\..\git\rt-thread\components\drivers\serial\serial.c + + + spi_core.c + 1 + ..\..\..\git\rt-thread\components\drivers\spi\spi_core.c + + + spi_dev.c + 1 + ..\..\..\git\rt-thread\components\drivers\spi\spi_dev.c + + + spi_flash_sfud.c + 1 + ..\..\..\git\rt-thread\components\drivers\spi\spi_flash_sfud.c + + + sfud.c + 1 + ..\..\..\git\rt-thread\components\drivers\spi\sfud\src\sfud.c + + + completion.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\completion.c + + + dataqueue.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\dataqueue.c + + + pipe.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\pipe.c + + + portal.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\portal.c + + + ringbuffer.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\ringbuffer.c + + + workqueue.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\workqueue.c + + + + + finsh + + + shell.c + 1 + ..\..\..\git\rt-thread\components\finsh\shell.c + + + symbol.c + 1 + ..\..\..\git\rt-thread\components\finsh\symbol.c + + + cmd.c + 1 + ..\..\..\git\rt-thread\components\finsh\cmd.c + + + finsh_compiler.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_compiler.c + + + finsh_error.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_error.c + + + finsh_heap.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_heap.c + + + finsh_init.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_init.c + + + finsh_node.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_node.c + + + finsh_ops.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_ops.c + + + finsh_parser.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_parser.c + + + finsh_var.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_var.c + + + finsh_vm.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_vm.c + + + finsh_token.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_token.c + + + + + GUIEngine + + + asc12font.c + 1 + ..\..\..\git\rt-thread\components\gui\src\asc12font.c + + + asc16font.c + 1 + ..\..\..\git\rt-thread\components\gui\src\asc16font.c + + + blit.c + 1 + ..\..\..\git\rt-thread\components\gui\src\blit.c + + + box.c + 1 + ..\..\..\git\rt-thread\components\gui\src\box.c + + + color.c + 1 + ..\..\..\git\rt-thread\components\gui\src\color.c + + + container.c + 1 + ..\..\..\git\rt-thread\components\gui\src\container.c + + + dc.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc.c + + + dc_blend.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_blend.c + + + dc_buffer.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_buffer.c + + + dc_client.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_client.c + + + dc_hw.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_hw.c + + + dc_rotozoom.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_rotozoom.c + + + dc_trans.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_trans.c + + + filerw.c + 1 + ..\..\..\git\rt-thread\components\gui\src\filerw.c + + + font.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font.c + + + font_bmp.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font_bmp.c + + + font_fnt.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font_fnt.c + + + font_freetype.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font_freetype.c + + + font_hz_bmp.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font_hz_bmp.c + + + font_hz_file.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font_hz_file.c + + + hz12font.c + 1 + ..\..\..\git\rt-thread\components\gui\src\hz12font.c + + + hz16font.c + 1 + ..\..\..\git\rt-thread\components\gui\src\hz16font.c + + + image.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image.c + + + image_bmp.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image_bmp.c + + + image_hdc.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image_hdc.c + + + image_jpg.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image_jpg.c + + + image_png.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image_png.c + + + image_xpm.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image_xpm.c + + + matrix.c + 1 + ..\..\..\git\rt-thread\components\gui\src\matrix.c + + + mouse.c + 1 + ..\..\..\git\rt-thread\components\gui\src\mouse.c + + + region.c + 1 + ..\..\..\git\rt-thread\components\gui\src\region.c + + + rtgui_app.c + 1 + ..\..\..\git\rt-thread\components\gui\src\rtgui_app.c + + + rtgui_driver.c + 1 + ..\..\..\git\rt-thread\components\gui\src\rtgui_driver.c + + + rtgui_object.c + 1 + ..\..\..\git\rt-thread\components\gui\src\rtgui_object.c + + + rtgui_system.c + 1 + ..\..\..\git\rt-thread\components\gui\src\rtgui_system.c + + + server.c + 1 + ..\..\..\git\rt-thread\components\gui\src\server.c + + + title.c + 1 + ..\..\..\git\rt-thread\components\gui\src\title.c + + + topwin.c + 1 + ..\..\..\git\rt-thread\components\gui\src\topwin.c + + + widget.c + 1 + ..\..\..\git\rt-thread\components\gui\src\widget.c + + + window.c + 1 + ..\..\..\git\rt-thread\components\gui\src\window.c + + + + + LwIP + + + api_lib.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\api_lib.c + + + api_msg.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\api_msg.c + + + err.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\err.c + + + netbuf.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\netbuf.c + + + netdb.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\netdb.c + + + netifapi.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\netifapi.c + + + sockets.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\sockets.c + + + tcpip.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\tcpip.c + + + sys_arch.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\arch\sys_arch.c + + + def.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\def.c + + + dhcp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\dhcp.c + + + dns.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\dns.c + + + init.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\init.c + + + memp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\memp.c + + + netif.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\netif.c + + + pbuf.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\pbuf.c + + + raw.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\raw.c + + + stats.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\stats.c + + + sys.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\sys.c + + + tcp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\tcp.c + + + tcp_in.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\tcp_in.c + + + tcp_out.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\tcp_out.c + + + timers.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\timers.c + + + udp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\udp.c + + + autoip.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\autoip.c + + + icmp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\icmp.c + + + igmp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\igmp.c + + + inet.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\inet.c + + + inet_chksum.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\inet_chksum.c + + + ip.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\ip.c + + + ip_addr.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\ip_addr.c + + + ip_frag.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\ip_frag.c + + + etharp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\netif\etharp.c + + + ethernetif.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\netif\ethernetif.c + + + slipif.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\netif\slipif.c + + + + + trace + + + SEGGER_SYSVIEW_Config_RTThread.c + 1 + ..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\Config\SEGGER_SYSVIEW_Config_RTThread.c + + + SEGGER_SYSVIEW_RTThread.c + 1 + ..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\Config\SEGGER_SYSVIEW_RTThread.c + + + SEGGER_RTT.c + 1 + ..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\SEGGER\SEGGER_RTT.c + + + SEGGER_SYSVIEW.c + 1 + ..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\SEGGER\SEGGER_SYSVIEW.c + + + + + + + +
diff --git a/bsp/gd32450z-eval/project.uvprojx b/bsp/gd32450z-eval/project.uvprojx new file mode 100644 index 0000000000..6ccda76c67 --- /dev/null +++ b/bsp/gd32450z-eval/project.uvprojx @@ -0,0 +1,1344 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32f4xx + 0x4 + ARM-ADS + 5060422::V5.06 update 4 (build 422)::ARMCC + + + GD32F450ZK + GigaDevice + GigaDevice.GD32F4xx_DFP.1.0.1 + http://gd32mcu.21ic.com/data/documents/yingyongruanjian/GD32F4 + IRAM(0x20000000,0x030000) IRAM2(0x10000000,0x010000) IROM(0x08000000,0x0300000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F4xx_3MB -FS08000000 -FL0300000 -FP0($$Device:GD32F450ZK$Flash\GD32F4xx_3MB.FLM)) + 0 + $$Device:GD32F450ZK$Device\Include\gd32f4xx.h + + + + + + + + + + $$Device:GD32F450ZK$SVD\GD32F4xx.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-gd32f4xx + 1 + 0 + 0 + 1 + 0 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 1 + 0x8000000 + 0x300000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x300000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 0 + 0x10000000 + 0x10000 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + GD32F4XX, USE_STDPERIPH_DRIVER + + applications;.;drivers;Libraries\CMSIS\GD\GD32F4xx\Include;Libraries\CMSIS;Libraries\GD32F4xx_standard_peripheral\Include;..\..\..\git\rt-thread\include;..\..\..\git\rt-thread\libcpu\arm\cortex-m4;..\..\..\git\rt-thread\libcpu\arm\common;..\..\..\git\rt-thread\components\dfs\include;..\..\..\git\rt-thread\components\dfs\filesystems\devfs;..\..\..\git\rt-thread\components\dfs\filesystems\elmfat;..\..\..\git\rt-thread\components\drivers\include;..\..\..\git\rt-thread\components\drivers\include;..\..\..\git\rt-thread\components\drivers\include;..\..\..\git\rt-thread\components\drivers\spi;..\..\..\git\rt-thread\components\drivers\include;..\..\..\git\rt-thread\components\drivers\spi\sfud\inc;..\..\..\git\rt-thread\components\drivers\include;..\..\..\git\rt-thread\components\finsh;..\..\..\git\rt-thread\components\gui\include;..\..\..\git\rt-thread\components\net\lwip-1.4.1\src;..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\include;..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\include\ipv4;..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\arch\include;..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\include\netif;..\..\..\git\rt-thread\components\trace;..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\Config;..\..\..\git\rt-thread\components\trace;..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\SEGGER + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + .\gd32_rom.ld + + + --keep *.o(RTMSymTab) --keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab) + + + + + + + + Applications + + + application.c + 1 + applications\application.c + + + rtgui_demo.c + 1 + applications\rtgui_demo.c + + + startup.c + 1 + applications\startup.c + + + + + Drivers + + + board.c + 1 + drivers\board.c + + + drv_exmc_sdram.c + 1 + drivers\drv_exmc_sdram.c + + + drv_usart.c + 1 + drivers\drv_usart.c + + + drv_enet.c + 1 + drivers\drv_enet.c + + + synopsys_emac.c + 1 + drivers\synopsys_emac.c + + + drv_lcd.c + 1 + drivers\drv_lcd.c + + + gd32f450z_lcd_eval.c + 1 + drivers\gd32f450z_lcd_eval.c + + + drv_spi_flash.c + 1 + drivers\drv_spi_flash.c + + + drv_spi.c + 1 + drivers\drv_spi.c + + + + + GD32_Lib + + + gd32f4xx_adc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_adc.c + + + gd32f4xx_can.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_can.c + + + gd32f4xx_crc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_crc.c + + + gd32f4xx_ctc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_ctc.c + + + gd32f4xx_dac.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dac.c + + + gd32f4xx_dbg.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dbg.c + + + gd32f4xx_dci.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dci.c + + + gd32f4xx_dma.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dma.c + + + gd32f4xx_enet.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_enet.c + + + gd32f4xx_exmc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_exmc.c + + + gd32f4xx_exti.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_exti.c + + + gd32f4xx_fmc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_fmc.c + + + gd32f4xx_fwdgt.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_fwdgt.c + + + gd32f4xx_gpio.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_gpio.c + + + gd32f4xx_i2c.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_i2c.c + + + gd32f4xx_ipa.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_ipa.c + + + gd32f4xx_iref.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_iref.c + + + gd32f4xx_misc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_misc.c + + + gd32f4xx_pmu.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_pmu.c + + + gd32f4xx_rcu.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_rcu.c + + + gd32f4xx_rtc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_rtc.c + + + gd32f4xx_sdio.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_sdio.c + + + gd32f4xx_spi.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_spi.c + + + gd32f4xx_syscfg.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_syscfg.c + + + gd32f4xx_timer.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_timer.c + + + gd32f4xx_tli.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_tli.c + + + gd32f4xx_trng.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_trng.c + + + gd32f4xx_usart.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_usart.c + + + gd32f4xx_wwdgt.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_wwdgt.c + + + system_gd32f4xx.c + 1 + Libraries\CMSIS\GD\GD32F4xx\Source\system_gd32f4xx.c + + + startup_gd32f4xx.s + 2 + Libraries\CMSIS\GD\GD32F4xx\Source\ARM\startup_gd32f4xx.s + + + + + Kernel + + + clock.c + 1 + ..\..\..\git\rt-thread\src\clock.c + + + components.c + 1 + ..\..\..\git\rt-thread\src\components.c + + + device.c + 1 + ..\..\..\git\rt-thread\src\device.c + + + idle.c + 1 + ..\..\..\git\rt-thread\src\idle.c + + + ipc.c + 1 + ..\..\..\git\rt-thread\src\ipc.c + + + irq.c + 1 + ..\..\..\git\rt-thread\src\irq.c + + + kservice.c + 1 + ..\..\..\git\rt-thread\src\kservice.c + + + mem.c + 1 + ..\..\..\git\rt-thread\src\mem.c + + + memheap.c + 1 + ..\..\..\git\rt-thread\src\memheap.c + + + mempool.c + 1 + ..\..\..\git\rt-thread\src\mempool.c + + + module.c + 1 + ..\..\..\git\rt-thread\src\module.c + + + object.c + 1 + ..\..\..\git\rt-thread\src\object.c + + + scheduler.c + 1 + ..\..\..\git\rt-thread\src\scheduler.c + + + thread.c + 1 + ..\..\..\git\rt-thread\src\thread.c + + + timer.c + 1 + ..\..\..\git\rt-thread\src\timer.c + + + + + CORTEX-M4 + + + cpuport.c + 1 + ..\..\..\git\rt-thread\libcpu\arm\cortex-m4\cpuport.c + + + context_rvds.S + 2 + ..\..\..\git\rt-thread\libcpu\arm\cortex-m4\context_rvds.S + + + backtrace.c + 1 + ..\..\..\git\rt-thread\libcpu\arm\common\backtrace.c + + + div0.c + 1 + ..\..\..\git\rt-thread\libcpu\arm\common\div0.c + + + showmem.c + 1 + ..\..\..\git\rt-thread\libcpu\arm\common\showmem.c + + + + + Filesystem + + + dfs.c + 1 + ..\..\..\git\rt-thread\components\dfs\src\dfs.c + + + dfs_file.c + 1 + ..\..\..\git\rt-thread\components\dfs\src\dfs_file.c + + + dfs_fs.c + 1 + ..\..\..\git\rt-thread\components\dfs\src\dfs_fs.c + + + dfs_posix.c + 1 + ..\..\..\git\rt-thread\components\dfs\src\dfs_posix.c + + + console.c + 1 + ..\..\..\git\rt-thread\components\dfs\filesystems\devfs\console.c + + + devfs.c + 1 + ..\..\..\git\rt-thread\components\dfs\filesystems\devfs\devfs.c + + + dfs_elm.c + 1 + ..\..\..\git\rt-thread\components\dfs\filesystems\elmfat\dfs_elm.c + + + ff.c + 1 + ..\..\..\git\rt-thread\components\dfs\filesystems\elmfat\ff.c + + + + + DeviceDrivers + + + i2c_core.c + 1 + ..\..\..\git\rt-thread\components\drivers\i2c\i2c_core.c + + + i2c_dev.c + 1 + ..\..\..\git\rt-thread\components\drivers\i2c\i2c_dev.c + + + i2c-bit-ops.c + 1 + ..\..\..\git\rt-thread\components\drivers\i2c\i2c-bit-ops.c + + + rtc.c + 1 + ..\..\..\git\rt-thread\components\drivers\rtc\rtc.c + + + serial.c + 1 + ..\..\..\git\rt-thread\components\drivers\serial\serial.c + + + spi_core.c + 1 + ..\..\..\git\rt-thread\components\drivers\spi\spi_core.c + + + spi_dev.c + 1 + ..\..\..\git\rt-thread\components\drivers\spi\spi_dev.c + + + spi_flash_sfud.c + 1 + ..\..\..\git\rt-thread\components\drivers\spi\spi_flash_sfud.c + + + sfud.c + 1 + ..\..\..\git\rt-thread\components\drivers\spi\sfud\src\sfud.c + + + completion.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\completion.c + + + dataqueue.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\dataqueue.c + + + pipe.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\pipe.c + + + portal.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\portal.c + + + ringbuffer.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\ringbuffer.c + + + workqueue.c + 1 + ..\..\..\git\rt-thread\components\drivers\src\workqueue.c + + + + + finsh + + + shell.c + 1 + ..\..\..\git\rt-thread\components\finsh\shell.c + + + symbol.c + 1 + ..\..\..\git\rt-thread\components\finsh\symbol.c + + + cmd.c + 1 + ..\..\..\git\rt-thread\components\finsh\cmd.c + + + finsh_compiler.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_compiler.c + + + finsh_error.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_error.c + + + finsh_heap.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_heap.c + + + finsh_init.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_init.c + + + finsh_node.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_node.c + + + finsh_ops.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_ops.c + + + finsh_parser.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_parser.c + + + finsh_var.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_var.c + + + finsh_vm.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_vm.c + + + finsh_token.c + 1 + ..\..\..\git\rt-thread\components\finsh\finsh_token.c + + + + + GUIEngine + + + asc12font.c + 1 + ..\..\..\git\rt-thread\components\gui\src\asc12font.c + + + asc16font.c + 1 + ..\..\..\git\rt-thread\components\gui\src\asc16font.c + + + blit.c + 1 + ..\..\..\git\rt-thread\components\gui\src\blit.c + + + box.c + 1 + ..\..\..\git\rt-thread\components\gui\src\box.c + + + color.c + 1 + ..\..\..\git\rt-thread\components\gui\src\color.c + + + container.c + 1 + ..\..\..\git\rt-thread\components\gui\src\container.c + + + dc.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc.c + + + dc_blend.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_blend.c + + + dc_buffer.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_buffer.c + + + dc_client.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_client.c + + + dc_hw.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_hw.c + + + dc_rotozoom.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_rotozoom.c + + + dc_trans.c + 1 + ..\..\..\git\rt-thread\components\gui\src\dc_trans.c + + + filerw.c + 1 + ..\..\..\git\rt-thread\components\gui\src\filerw.c + + + font.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font.c + + + font_bmp.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font_bmp.c + + + font_fnt.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font_fnt.c + + + font_freetype.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font_freetype.c + + + font_hz_bmp.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font_hz_bmp.c + + + font_hz_file.c + 1 + ..\..\..\git\rt-thread\components\gui\src\font_hz_file.c + + + hz12font.c + 1 + ..\..\..\git\rt-thread\components\gui\src\hz12font.c + + + hz16font.c + 1 + ..\..\..\git\rt-thread\components\gui\src\hz16font.c + + + image.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image.c + + + image_bmp.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image_bmp.c + + + image_hdc.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image_hdc.c + + + image_jpg.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image_jpg.c + + + image_png.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image_png.c + + + image_xpm.c + 1 + ..\..\..\git\rt-thread\components\gui\src\image_xpm.c + + + matrix.c + 1 + ..\..\..\git\rt-thread\components\gui\src\matrix.c + + + mouse.c + 1 + ..\..\..\git\rt-thread\components\gui\src\mouse.c + + + region.c + 1 + ..\..\..\git\rt-thread\components\gui\src\region.c + + + rtgui_app.c + 1 + ..\..\..\git\rt-thread\components\gui\src\rtgui_app.c + + + rtgui_driver.c + 1 + ..\..\..\git\rt-thread\components\gui\src\rtgui_driver.c + + + rtgui_object.c + 1 + ..\..\..\git\rt-thread\components\gui\src\rtgui_object.c + + + rtgui_system.c + 1 + ..\..\..\git\rt-thread\components\gui\src\rtgui_system.c + + + server.c + 1 + ..\..\..\git\rt-thread\components\gui\src\server.c + + + title.c + 1 + ..\..\..\git\rt-thread\components\gui\src\title.c + + + topwin.c + 1 + ..\..\..\git\rt-thread\components\gui\src\topwin.c + + + widget.c + 1 + ..\..\..\git\rt-thread\components\gui\src\widget.c + + + window.c + 1 + ..\..\..\git\rt-thread\components\gui\src\window.c + + + + + LwIP + + + api_lib.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\api_lib.c + + + api_msg.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\api_msg.c + + + err.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\err.c + + + netbuf.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\netbuf.c + + + netdb.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\netdb.c + + + netifapi.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\netifapi.c + + + sockets.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\sockets.c + + + tcpip.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\api\tcpip.c + + + sys_arch.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\arch\sys_arch.c + + + def.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\def.c + + + dhcp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\dhcp.c + + + dns.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\dns.c + + + init.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\init.c + + + memp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\memp.c + + + netif.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\netif.c + + + pbuf.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\pbuf.c + + + raw.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\raw.c + + + stats.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\stats.c + + + sys.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\sys.c + + + tcp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\tcp.c + + + tcp_in.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\tcp_in.c + + + tcp_out.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\tcp_out.c + + + timers.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\timers.c + + + udp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\udp.c + + + autoip.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\autoip.c + + + icmp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\icmp.c + + + igmp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\igmp.c + + + inet.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\inet.c + + + inet_chksum.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\inet_chksum.c + + + ip.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\ip.c + + + ip_addr.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\ip_addr.c + + + ip_frag.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\core\ipv4\ip_frag.c + + + etharp.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\netif\etharp.c + + + ethernetif.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\netif\ethernetif.c + + + slipif.c + 1 + ..\..\..\git\rt-thread\components\net\lwip-1.4.1\src\netif\slipif.c + + + + + trace + + + SEGGER_SYSVIEW_Config_RTThread.c + 1 + ..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\Config\SEGGER_SYSVIEW_Config_RTThread.c + + + SEGGER_SYSVIEW_RTThread.c + 1 + ..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\Config\SEGGER_SYSVIEW_RTThread.c + + + SEGGER_RTT.c + 1 + ..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\SEGGER\SEGGER_RTT.c + + + SEGGER_SYSVIEW.c + 1 + ..\..\..\git\rt-thread\components\trace\SystemView_Src_V240\SEGGER\SEGGER_SYSVIEW.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/bsp/gd32450z-eval/rtconfig.h b/bsp/gd32450z-eval/rtconfig.h new file mode 100644 index 0000000000..30614c9375 --- /dev/null +++ b/bsp/gd32450z-eval/rtconfig.h @@ -0,0 +1,241 @@ +/* RT-Thread config file */ +#ifndef __RTTHREAD_CFG_H__ +#define __RTTHREAD_CFG_H__ + +/* RT_NAME_MAX*/ +#define RT_NAME_MAX 8 + +/* RT_ALIGN_SIZE*/ +#define RT_ALIGN_SIZE 4 + +/* PRIORITY_MAX */ +#define RT_THREAD_PRIORITY_MAX 32 + +/* Tick per Second */ +#define RT_TICK_PER_SECOND 1000 + +/* SECTION: RT_DEBUG */ +/* Thread Debug */ +#define RT_DEBUG +#define RT_DEBUG_INIT 1 +#define RT_USING_OVERFLOW_CHECK + +/* Using Hook */ +#define RT_USING_HOOK +//#define RT_USING_TRACE + +#define IDLE_THREAD_STACK_SIZE 1024 + +/* Using Software Timer */ +/* #define RT_USING_TIMER_SOFT */ +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 512 +// +#define RT_USING_MODULE +/* SECTION: IPC */ +/* Using Semaphore*/ +#define RT_USING_SEMAPHORE + +/* Using Mutex */ +#define RT_USING_MUTEX + +/* Using Event */ +#define RT_USING_EVENT + +/* Using MailBox */ +#define RT_USING_MAILBOX + +/* Using Message Queue */ +#define RT_USING_MESSAGEQUEUE + +/* SECTION: Memory Management */ +/* Using Memory Pool Management*/ +#define RT_USING_MEMPOOL + +/* Using Dynamic Heap Management */ +#define RT_USING_HEAP +#define RT_USING_MEMHEAP +/* Using Small MM */ +#define RT_USING_SMALL_MEM + +#define RT_USING_COMPONENTS_INIT + +/* SECTION: Device System */ +/* Using Device System */ +#define RT_USING_DEVICE +#define RT_USING_DEVICE_IPC + +/* SECTION: RTGUI support */ +/* using RTGUI support */ +#define RT_USING_GUIENGINE + +/* name length of RTGUI object */ +#define RTGUI_NAME_MAX 16 +/* support 16 weight font */ +#define RTGUI_USING_FONT16 +/* support 16 weight font */ +#define RTGUI_USING_FONT12 +/* support Chinese font */ +#define RTGUI_USING_FONTHZ +/* use DFS as file interface */ +#define RTGUI_USING_DFS_FILERW +/* use font file as Chinese font */ +/* #define RTGUI_USING_HZ_FILE */ +/* use Chinese bitmap font */ +#define RTGUI_USING_HZ_BMP +/* use small size in RTGUI */ +/* #define RTGUI_USING_SMALL_SIZE */ +/* use mouse cursor */ +/* #define RTGUI_USING_MOUSE_CURSOR */ + +/* Using serial framework */ +#define RT_USING_SERIAL + +#define RT_USING_USART0 +#define RT_USING_USART1 +#define RT_USING_USART2 +#define RT_USING_UART3 +#define RT_USING_UART4 +#define RT_USING_USART5 +#define RT_USING_UART6 +#define RT_USING_UART7 + +/* Using GPIO pin framework */ +//#define RT_USING_PIN + +/* Using Hardware Timer framework */ +//#define RT_USING_HWTIMER + +#define RT_USING_EXT_SDRAM + +/* SECTION: Console options */ +#define RT_USING_CONSOLE +/* the buffer size of console*/ +#define RT_CONSOLEBUF_SIZE 128 + +/* SECTION: finsh, a C-Express shell */ +#define RT_USING_FINSH +/* Using symbol table */ +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +//#define FINSH_USING_MSH + +#define RT_USING_RTC +#ifdef RT_USING_RTC +#define RT_RTC_NAME "rtc" +#endif + +//
+// +//#define RT_USING_LIBC + +/* SECTION: device filesystem */ +/* Using Device file system */ +#define RT_USING_DFS /**/ +// +#define RT_USING_DFS_DEVFS +//// +//#define DFS_FILESYSTEM_TYPES_MAX 2 +/* the max number of mounted filesystem */ +#define DFS_FILESYSTEMS_MAX 2 +/* the max number of opened files */ +#define DFS_FD_MAX 4 +//#define DFS_USING_WORKDIR + +/* Using ELM FATFS */ +#define RT_USING_DFS_ELMFAT +////#define RT_DFS_ELM_WORD_ACCESS +///* Reentrancy (thread safe) of the FatFs module. */ +//#define RT_DFS_ELM_REENTRANT +///* Number of volumes (logical drives) to be used. */ +#define RT_DFS_ELM_DRIVES 2 +//#define RT_DFS_ELM_USE_LFN 3 /* */ +#define RT_DFS_ELM_MAX_LFN 255 +///* Maximum sector size to be handled. */ +#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 + +/* SECTION: lwip, a lighwight TCP/IP protocol stack */ +#define RT_USING_LWIP +/* LwIP uses RT-Thread Memory Management */ +#define RT_LWIP_USING_RT_MEM +/* Enable ICMP protocol*/ +#define RT_LWIP_ICMP +/* Enable UDP protocol*/ +#define RT_LWIP_UDP +/* Enable TCP protocol*/ +#define RT_LWIP_TCP +/* Enable DNS */ +#define RT_LWIP_DNS +/* Enable DHCP */ +#define RT_LWIP_DHCP +/* Enable DEBUG */ +#define RT_LWIP_DEBUG + +/* the number of simulatenously active TCP connections*/ +#define RT_LWIP_TCP_PCB_NUM 5 + +/* ip address of target*/ +#define RT_LWIP_IPADDR0 192 +#define RT_LWIP_IPADDR1 168 +#define RT_LWIP_IPADDR2 10 +#define RT_LWIP_IPADDR3 241 + +/* gateway address of target*/ +#define RT_LWIP_GWADDR0 192 +#define RT_LWIP_GWADDR1 168 +#define RT_LWIP_GWADDR2 10 +#define RT_LWIP_GWADDR3 1 + +/* mask address of target*/ +#define RT_LWIP_MSKADDR0 255 +#define RT_LWIP_MSKADDR1 255 +#define RT_LWIP_MSKADDR2 255 +#define RT_LWIP_MSKADDR3 0 + +/* tcp thread options */ +#define RT_LWIP_TCPTHREAD_PRIORITY 12 +#define RT_LWIP_TCPTHREAD_MBOX_SIZE 4 +#define RT_LWIP_TCPTHREAD_STACKSIZE 1024 + +/* ethernet if thread options */ +#define RT_LWIP_ETHTHREAD_PRIORITY 15 +#define RT_LWIP_ETHTHREAD_MBOX_SIZE 4 +#define RT_LWIP_ETHTHREAD_STACKSIZE 512 + +/* TCP sender buffer space */ +#define RT_LWIP_TCP_SND_BUF 8192 +/* TCP receive window. */ +#define RT_LWIP_TCP_WND 8192 + +#define CHECKSUM_CHECK_TCP 0 +#define CHECKSUM_CHECK_IP 0 +#define CHECKSUM_CHECK_UDP 0 + +//#define CHECKSUM_GEN_TCP 0 +//#define CHECKSUM_GEN_IP 0 +//#define CHECKSUM_GEN_UDP 0 + +/* RT_GDB_STUB */ +//#define RT_USING_GDB + +/* spi driver */ +#define RT_USING_SPI +#define RT_USING_SPI0 +#define RT_USING_SPI1 +#define RT_USING_SPI2 +#define RT_USING_SPI3 +#define RT_USING_SPI4 +#define RT_USING_SPI5 +//#define RT_USING_W25QXX +//#define FLASH_DEBUG + +#define RT_USING_SFUD +//#define RT_SFUD_USING_SFDP +#define RT_SFUD_USING_FLASH_INFO_TABLE + +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS + +//#define RT_USING_CPU_FFS + +#endif diff --git a/bsp/gd32450z-eval/rtconfig.py b/bsp/gd32450z-eval/rtconfig.py new file mode 100644 index 0000000000..3d9ffaab8d --- /dev/null +++ b/bsp/gd32450z-eval/rtconfig.py @@ -0,0 +1,103 @@ +import os + +# toolchains options +ARCH='arm' +CPU='cortex-m4' +CROSS_TOOL='iar' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR +if CROSS_TOOL == 'gcc': + print '================ERROR============================' + print 'Not support iar yet!' + print '=================================================' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = r'C:/Keil_v5' +elif CROSS_TOOL == 'iar': + PLATFORM = 'iar' + EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.0' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + exit(0) + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --cpu=cortex-m4.fp' + CFLAGS = DEVICE + ' --apcs=interwork --cpu Cortex-M4.fp' + AFLAGS = DEVICE + LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-gd32.map --scatter gd32_rom.sct' + + CFLAGS += ' -I' + EXEC_PATH + '/ARM/RV31/INC' + LFLAGS += ' --libpath ' + EXEC_PATH + '/ARM/RV31/LIB' + + EXEC_PATH += '/arm/bin40/' + + CFLAGS += ' --c99' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'iar': + # toolchains + CC = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + DEVICE = ' -D USE_STDPERIPH_DRIVER' + ' -D GD32F450xK' + + CFLAGS = DEVICE + CFLAGS += ' --diag_suppress Pa050' + CFLAGS += ' --no_cse' + CFLAGS += ' --no_unroll' + CFLAGS += ' --no_inline' + CFLAGS += ' --no_code_motion' + CFLAGS += ' --no_tbaa' + CFLAGS += ' --no_clustering' + CFLAGS += ' --no_scheduling' + CFLAGS += ' --debug' + CFLAGS += ' --endian=little' + CFLAGS += ' --cpu=Cortex-M4' + CFLAGS += ' -e' + CFLAGS += ' --fpu=None' + CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' -Ol' + CFLAGS += ' --use_c++_inline' + + AFLAGS = '' + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --cpu Cortex-M4' + AFLAGS += ' --fpu None' + + LFLAGS = ' --config gd32_rom.icf' + LFLAGS += ' --redirect _Printf=_PrintfTiny' + LFLAGS += ' --redirect _Scanf=_ScanfSmall' + LFLAGS += ' --entry __iar_program_start' + + EXEC_PATH += '/arm/bin/' + POST_ACTION = '' diff --git a/bsp/gd32450z-eval/startcmd.bat b/bsp/gd32450z-eval/startcmd.bat new file mode 100644 index 0000000000..a03f9d44c3 --- /dev/null +++ b/bsp/gd32450z-eval/startcmd.bat @@ -0,0 +1 @@ +start cmd.exe \ No newline at end of file diff --git a/bsp/gd32450z-eval/template.ewp b/bsp/gd32450z-eval/template.ewp new file mode 100644 index 0000000000..0aaf7642be --- /dev/null +++ b/bsp/gd32450z-eval/template.ewp @@ -0,0 +1,1892 @@ + + + + 2 + + Debug + + ARM + + 1 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 22 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 31 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + + diff --git a/bsp/gd32450z-eval/template.uvproj b/bsp/gd32450z-eval/template.uvproj new file mode 100644 index 0000000000..fbd08b87f3 --- /dev/null +++ b/bsp/gd32450z-eval/template.uvproj @@ -0,0 +1,614 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32f4xx + 0x4 + ARM-ADS + + + GD32F450ZK + GigaDevice + IRAM(0x20000000-0x2002FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x08000000-0x082FFFFF) CLOCK(16000000) CPUTYPE("Cortex-M4") FPU2 + + "Startup\GD\GD32F4xx\startup_gd32f4xx.s" ("GD32F4xx Startup Code") + UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0GD32F4xx_3MB -FS08000000 -FL0300000) + 0 + gd32f4xx0.h + + + + + + + + + + SFD\GD\GD32F4xx\GD32F4xx.SFR + 0 + 0 + + + + GD\GD32F4xx\ + GD\GD32F4xx\ + + 0 + 0 + 0 + 0 + 1 + + .\output\ + rtthread-gd32f4xx + 1 + 0 + 1 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP + DCM.DLL + -pCM3 + SARMCM3.DLL + + TCM.DLL + -pCM3 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 0 + + 0 + 12 + + + + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 1 + 0 + 8 + 1 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 1 + 0x8000000 + 0x300000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x300000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 0 + 0x10000000 + 0x10000 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + + + + + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Include;..\..\..\Library\Firmware\CMSIS\GD\GD32F4xx\Include;..\..\..\Library\Utilities;..\ + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + + + + + + + + + Application + + + main.c + 1 + ..\main.c + + + gd32f4xx_it.c + 1 + ..\gd32f4xx_it.c + + + + + CMSIS + + + system_gd32f4xx.c + 1 + ..\..\..\Library\Firmware\CMSIS\GD\GD32F4xx\Source\system_gd32f4xx.c + + + + + GD32F4xx_Peripherals + + + gd32f4xx_adc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_adc.c + + + gd32f4xx_can.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_can.c + + + gd32f4xx_crc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_crc.c + + + gd32f4xx_ctc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_ctc.c + + + gd32f4xx_dac.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_dac.c + + + gd32f4xx_dbg.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_dbg.c + + + gd32f4xx_dci.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_dci.c + + + gd32f4xx_dma.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_dma.c + + + gd32f4xx_enet.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_enet.c + + + gd32f4xx_exmc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_exmc.c + + + gd32f4xx_exti.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_exti.c + + + gd32f4xx_fmc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_fmc.c + + + gd32f4xx_fwdgt.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_fwdgt.c + + + gd32f4xx_gpio.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_gpio.c + + + gd32f4xx_i2c.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_i2c.c + + + gd32f4xx_ipa.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_ipa.c + + + gd32f4xx_iref.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_iref.c + + + gd32f4xx_misc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_misc.c + + + gd32f4xx_pmu.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_pmu.c + + + gd32f4xx_rcu.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_rcu.c + + + gd32f4xx_rtc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_rtc.c + + + gd32f4xx_sdio.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_sdio.c + + + gd32f4xx_spi.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_spi.c + + + gd32f4xx_syscfg.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_syscfg.c + + + gd32f4xx_timer.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_timer.c + + + gd32f4xx_tli.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_tli.c + + + gd32f4xx_trng.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_trng.c + + + gd32f4xx_usart.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_usart.c + + + gd32f4xx_wwdgt.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_wwdgt.c + + + + + GD32F4xx_EVAL + + + gd32f450z_eval.c + 1 + ..\..\..\Library\Utilities\gd32f450z_eval.c + + + + + Startup + + + startup_gd32f4xx.s + 2 + ..\..\..\Library\Firmware\CMSIS\GD\GD32F4xx\Source\ARM\startup_gd32f4xx.s + + + + + Doc + + + readme.txt + 5 + ..\readme.txt + + + + + + + +
diff --git a/bsp/gd32450z-eval/template.uvprojx b/bsp/gd32450z-eval/template.uvprojx new file mode 100644 index 0000000000..d9e889bb99 --- /dev/null +++ b/bsp/gd32450z-eval/template.uvprojx @@ -0,0 +1,398 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32f4xx + 0x4 + ARM-ADS + + + GD32F450ZK + GigaDevice + GigaDevice.GD32F4xx_DFP.1.0.1 + http://gd32mcu.21ic.com/data/documents/yingyongruanjian/GD32F4 + IRAM(0x20000000,0x030000) IRAM2(0x10000000,0x010000) IROM(0x08000000,0x0300000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F4xx_3MB -FS08000000 -FL0300000 -FP0($$Device:GD32F450ZK$Flash\GD32F4xx_3MB.FLM)) + 0 + $$Device:GD32F450ZK$Device\Include\gd32f4xx.h + + + + + + + + + + $$Device:GD32F450ZK$SVD\GD32F4xx.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-gd32f4xx + 1 + 0 + 0 + 1 + 0 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 1 + 0x8000000 + 0x300000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x300000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 0 + 0x10000000 + 0x10000 + + + + + + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + .\gd32_rom.ld + + + + + + + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/bsp/hifive1/rtconfig.py b/bsp/hifive1/rtconfig.py index 7db1fd0b90..6ace0388d8 100644 --- a/bsp/hifive1/rtconfig.py +++ b/bsp/hifive1/rtconfig.py @@ -10,14 +10,7 @@ if os.getenv('RTT_CC'): if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' - # EXEC_PATH = 'D:/ArdaArmTools/Sourcery_Lite/bin' EXEC_PATH = '/home/zj/risc-v/riscv64-unknown-elf-gcc-20170612-x86_64-linux-centos6/bin' -elif CROSS_TOOL == 'keil': - PLATFORM = 'armcc' - EXEC_PATH = 'C:/Keil_v5' -elif CROSS_TOOL == 'iar': - PLATFORM = 'iar' - IAR_PATH = 'C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.0' if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') @@ -33,8 +26,7 @@ TARGET_NAME = 'rtthread.bin' #------- GCC settings ---------------------------------------------------------- if PLATFORM == 'gcc': # toolchains - PREFIX = '/home/zj/risc-v/riscv64-unknown-elf-gcc-20170612-x86_64-linux-centos6/bin/riscv64-unknown-elf-' - #PREFIX = 'arm-none-linux-gnueabi-' + PREFIX = 'riscv64-unknown-elf-' CC = PREFIX + 'gcc' AS = PREFIX + 'gcc' AR = PREFIX + 'ar' @@ -45,9 +37,7 @@ if PLATFORM == 'gcc': OBJCPY = PREFIX + 'objcopy' DEVICE = ' -march=rv32imac -mabi=ilp32 -DUSE_PLIC -DUSE_M_TIME -mcmodel=medany -msmall-data-limit=8 -g -L. -nostartfiles -lc ' -# DEVICE += '-Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=open -Wl,--wrap=lseek -Wl,--wrap=read -Wl,--wrap=write -Wl,--wrap=fstat -Wl,--wrap=stat -Wl,--wrap=close -Wl,--wrap=link -Wl,--wrap=unlink -Wl,--wrap=execve -Wl,--wrap=fork -Wl,--wrap=getpid -Wl,--wrap=kill -Wl,--wrap=wait -Wl,--wrap=isatty -Wl,--wrap=times -Wl,--wrap=sbrk -Wl,--wrap=_exit' CFLAGS = DEVICE -# CFLAGS += ' -I ./mx28_registers/' CFLAGS += '' AFLAGS = '-c'+ DEVICE + ' -x assembler-with-cpp' AFLAGS += ' -Iplatform' @@ -66,77 +56,3 @@ if PLATFORM == 'gcc': POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n' POST_ACTION += SIZE + ' $TARGET\n' -#------- Keil settings --------------------------------------------------------- -elif PLATFORM == 'armcc': - # toolchains - CC = 'armcc' - AS = 'armasm' - AR = 'armar' - LINK = 'armlink' - TARGET_EXT = 'axf' - EXEC_PATH += '/arm/armcc/bin/' - - DEVICE = ' --cpu=' + CORE - CFLAGS = DEVICE + ' --apcs=interwork --diag_suppress=870' - AFLAGS = DEVICE + ' -Iplatform' - LFLAGS = DEVICE + ' --strict' - LFLAGS += ' --info sizes --info totals --info unused --info veneers' - LFLAGS += ' --list ' + MAP_FILE - LFLAGS += ' --scatter ' + LINK_FILE + '.scat' - - if BUILD == 'debug': - CFLAGS += ' -g -O0' - AFLAGS += ' -g' - else: - CFLAGS += ' -O2' - - POST_ACTION = 'fromelf --bin $TARGET --output ' + TARGET_NAME + ' \n' - POST_ACTION += 'fromelf -z $TARGET\n' -#------- IAR settings ---------------------------------------------------------- -elif PLATFORM == 'iar': - # toolchains - CC = 'iccarm' - AS = 'iasmarm' - AR = 'iarchive' - LINK = 'ilinkarm' - TARGET_EXT = 'axf' - - DEVICE = CORE - - CFLAGS = '--cpu=' + DEVICE - CFLAGS += ' --diag_suppress Pa050' - CFLAGS += ' --no_cse' - CFLAGS += ' --no_unroll' - CFLAGS += ' --no_inline' - CFLAGS += ' --no_code_motion' - CFLAGS += ' --no_tbaa' - CFLAGS += ' --no_clustering' - CFLAGS += ' --no_scheduling' - - CFLAGS += ' --endian=little' - CFLAGS += ' -e' - CFLAGS += ' --fpu=none' - CFLAGS += ' --dlib_config "' + IAR_PATH + '/arm/INC/c/DLib_Config_Normal.h"' - CFLAGS += ' --silent' - - AFLAGS = '--cpu '+ DEVICE - AFLAGS += ' -s+' - AFLAGS += ' -w+' - AFLAGS += ' -r' - AFLAGS += ' --fpu none' - AFLAGS += ' -S' - AFLAGS += ' -Iplatform' - - if BUILD == 'debug': - CFLAGS += ' --debug' - CFLAGS += ' -On' - else: - CFLAGS += ' -Oh' - - LFLAGS = '--config ' + LINK_FILE +'.icf' - LFLAGS += ' --entry __iar_program_start' - LFLAGS += ' --map ' + MAP_FILE - LFLAGS += ' --silent' - - EXEC_PATH = IAR_PATH + '/arm/bin/' - POST_ACTION = 'ielftool --silent --bin $TARGET ' + TARGET_NAME diff --git a/bsp/ls1cdev/applications/application.c b/bsp/ls1cdev/applications/application.c index 6690da528a..61672edfca 100644 --- a/bsp/ls1cdev/applications/application.c +++ b/bsp/ls1cdev/applications/application.c @@ -16,11 +16,16 @@ #include #include +#include "net/synopGMAC.h" +#include void rt_init_thread_entry(void *parameter) { /* initialization RT-Thread Components */ rt_components_init(); + + // EMACʼ + rt_hw_eth_init(); } int rt_application_init(void) diff --git a/bsp/ls1cdev/drivers/SConscript b/bsp/ls1cdev/drivers/SConscript index 6c6d2c7adb..3e76809efb 100644 --- a/bsp/ls1cdev/drivers/SConscript +++ b/bsp/ls1cdev/drivers/SConscript @@ -7,4 +7,14 @@ CPPPATH = [cwd] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +group = group + objs + Return('group') diff --git a/bsp/ls1cdev/drivers/net/SConscript b/bsp/ls1cdev/drivers/net/SConscript new file mode 100644 index 0000000000..1eea3171de --- /dev/null +++ b/bsp/ls1cdev/drivers/net/SConscript @@ -0,0 +1,11 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + +CPPPATH = [cwd] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + + +Return('group') diff --git a/bsp/ls1cdev/drivers/net/mii.c b/bsp/ls1cdev/drivers/net/mii.c new file mode 100644 index 0000000000..b53592f87e --- /dev/null +++ b/bsp/ls1cdev/drivers/net/mii.c @@ -0,0 +1,150 @@ +/* + * File : mii.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + +#include "mii.h" + + +static inline unsigned int mii_nway_result (unsigned int negotiated) +{ + unsigned int ret; + + if (negotiated & LPA_100FULL) + ret = LPA_100FULL; + else if (negotiated & LPA_100BASE4) + ret = LPA_100BASE4; + else if (negotiated & LPA_100HALF) + ret = LPA_100HALF; + else if (negotiated & LPA_10FULL) + ret = LPA_10FULL; + else + ret = LPA_10HALF; + + return ret; +} + +static int mii_check_gmii_support(struct mii_if_info *mii) +{ + int reg; + + reg = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); + if (reg & BMSR_ESTATEN) { + reg = mii->mdio_read(mii->dev, mii->phy_id, MII_ESTATUS); + if (reg & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) + return 1; + } + + return 0; +} + +static int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) +{ + struct synopGMACNetworkAdapter * dev = mii->dev; + u32 advert, bmcr, lpa, nego; + u32 advert2 = 0, bmcr2 = 0, lpa2 = 0; + + ecmd->supported = + (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII); + if (mii->supports_gmii) + ecmd->supported |= SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full; + + /* only supports twisted-pair */ + ecmd->port = PORT_MII; + + /* only supports internal transceiver */ + ecmd->transceiver = XCVR_INTERNAL; + + /* this isn't fully supported at higher layers */ + ecmd->phy_address = mii->phy_id; + + ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII; + advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE); + if (mii->supports_gmii) + advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); + + if (advert & ADVERTISE_10HALF) + ecmd->advertising |= ADVERTISED_10baseT_Half; + if (advert & ADVERTISE_10FULL) + ecmd->advertising |= ADVERTISED_10baseT_Full; + if (advert & ADVERTISE_100HALF) + ecmd->advertising |= ADVERTISED_100baseT_Half; + if (advert & ADVERTISE_100FULL) + ecmd->advertising |= ADVERTISED_100baseT_Full; + if (advert2 & ADVERTISE_1000HALF) + ecmd->advertising |= ADVERTISED_1000baseT_Half; + if (advert2 & ADVERTISE_1000FULL) + ecmd->advertising |= ADVERTISED_1000baseT_Full; + + bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); + lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA); + if (mii->supports_gmii) { + bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); + lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000); + } + if (bmcr & BMCR_ANENABLE) { + ecmd->advertising |= ADVERTISED_Autoneg; + ecmd->autoneg = AUTONEG_ENABLE; + + nego = mii_nway_result(advert & lpa); + if ((bmcr2 & (ADVERTISE_1000HALF | ADVERTISE_1000FULL)) & + (lpa2 >> 2)) + ecmd->speed = SPEED_1000; + else if (nego == LPA_100FULL || nego == LPA_100HALF) + ecmd->speed = SPEED_100; + else + ecmd->speed = SPEED_10; + if ((lpa2 & LPA_1000FULL) || nego == LPA_100FULL || + nego == LPA_10FULL) { + ecmd->duplex = DUPLEX_FULL; + mii->full_duplex = 1; + } else { + ecmd->duplex = DUPLEX_HALF; + mii->full_duplex = 0; + } + } else { + ecmd->autoneg = AUTONEG_DISABLE; + + ecmd->speed = ((bmcr & BMCR_SPEED1000 && + (bmcr & BMCR_SPEED100) == 0) ? SPEED_1000 : + (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10); + ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; + } + + /* ignore maxtxpkt, maxrxpkt for now */ + + return 0; +} + +static int mii_link_ok (struct mii_if_info *mii) +{ + /* first, a dummy read, needed to latch some MII phys */ + mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); + if (mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_LSTATUS) + return 1; + return 0; +} + diff --git a/bsp/ls1cdev/drivers/net/mii.h b/bsp/ls1cdev/drivers/net/mii.h new file mode 100644 index 0000000000..cbdd3d5cef --- /dev/null +++ b/bsp/ls1cdev/drivers/net/mii.h @@ -0,0 +1,245 @@ +/* + * File : mii.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + +#ifndef __MII_H__ +#define __MII_H__ +/* Generic MII registers. */ + +#include "synopGMAC_types.h" + +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +#define MII_CTRL1000 0x09 /* 1000BASE-T control */ +#define MII_STAT1000 0x0a /* 1000BASE-T status */ +#define MII_ESTATUS 0x0f /* Extended Status */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_RESV1 0x17 /* Reserved... */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESV2 0x1a /* Reserved... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control register. */ +#define BMCR_RESV 0x003f /* Unused... */ +#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x00c0 /* Unused... */ +#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ +#define BMSR_100FULL2 0x0200 /* Can do 100BASE-T2 HDX */ +#define BMSR_100HALF2 0x0400 /* Can do 100BASE-T2 FDX */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +/* Advertisement control register. */ +#define ADVERTISE_SLCT 0x001f /* Selector bits */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */ +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ +#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ +#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */ +#define ADVERTISE_RESV 0x1000 /* Unused... */ +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ + +#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \ + ADVERTISE_CSMA) +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL) + +/* Indicates what features are advertised by the interface. */ +#define ADVERTISED_10baseT_Half (1 << 0) +#define ADVERTISED_10baseT_Full (1 << 1) +#define ADVERTISED_100baseT_Half (1 << 2) +#define ADVERTISED_100baseT_Full (1 << 3) +#define ADVERTISED_1000baseT_Half (1 << 4) +#define ADVERTISED_1000baseT_Full (1 << 5) +#define ADVERTISED_Autoneg (1 << 6) +#define ADVERTISED_TP (1 << 7) +#define ADVERTISED_AUI (1 << 8) +#define ADVERTISED_MII (1 << 9) +#define ADVERTISED_FIBRE (1 << 10) +#define ADVERTISED_BNC (1 << 11) +#define ADVERTISED_10000baseT_Full (1 << 12) +#define ADVERTISED_Pause (1 << 13) +#define ADVERTISED_Asym_Pause (1 << 14) + +/* Link partner ability register. */ +#define LPA_SLCT 0x001f /* Same as advertise selector */ +#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ +#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */ +#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ +#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */ +#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ +#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */ +#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ +#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/ +#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */ +#define LPA_PAUSE_CAP 0x0400 /* Can pause */ +#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */ +#define LPA_RESV 0x1000 /* Unused... */ +#define LPA_RFAULT 0x2000 /* Link partner faulted */ +#define LPA_LPACK 0x4000 /* Link partner acked us */ +#define LPA_NPAGE 0x8000 /* Next page bit */ + +#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) +#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) + +/* Expansion register for auto-negotiation. */ +#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */ +#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */ +#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */ +#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */ +#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */ +#define EXPANSION_RESV 0xffe0 /* Unused... */ + +#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */ +#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */ + +/* N-way test register. */ +#define NWAYTEST_RESV1 0x00ff /* Unused... */ +#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ +#define NWAYTEST_RESV2 0xfe00 /* Unused... */ + +/* 1000BASE-T Control register */ +#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ +#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ + +/* 1000BASE-T Status register */ +#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ +#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */ +#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ + +#define SUPPORTED_10baseT_Half (1 << 0) +#define SUPPORTED_10baseT_Full (1 << 1) +#define SUPPORTED_100baseT_Half (1 << 2) +#define SUPPORTED_100baseT_Full (1 << 3) +#define SUPPORTED_1000baseT_Half (1 << 4) +#define SUPPORTED_1000baseT_Full (1 << 5) +#define SUPPORTED_Autoneg (1 << 6) +#define SUPPORTED_TP (1 << 7) +#define SUPPORTED_AUI (1 << 8) +#define SUPPORTED_MII (1 << 9) +#define SUPPORTED_FIBRE (1 << 10) +#define SUPPORTED_BNC (1 << 11) +#define SUPPORTED_10000baseT_Full (1 << 12) +#define SUPPORTED_Pause (1 << 13) +#define SUPPORTED_Asym_Pause (1 << 14) + + +/* Which connector port. */ +#define PORT_TP 0x00 +#define PORT_AUI 0x01 +#define PORT_MII 0x02 +#define PORT_FIBRE 0x03 +#define PORT_BNC 0x04 + +/* Which transceiver to use. */ +#define XCVR_INTERNAL 0x00 +#define XCVR_EXTERNAL 0x01 +#define XCVR_DUMMY1 0x02 +#define XCVR_DUMMY2 0x03 +#define XCVR_DUMMY3 0x04 + +#define AUTONEG_DISABLE 0x00 +#define AUTONEG_ENABLE 0x01 + + +#define SPEED_10 10 +#define SPEED_100 100 +#define SPEED_1000 1000 +#define SPEED_2500 2500 +#define SPEED_10000 10000 + +#define DUPLEX_HALF 0x00 +#define DUPLEX_FULL 0x01 + +struct ethtool_cmd { + u32 cmd; + u32 supported; /* Features this interface supports */ + u32 advertising; /* Features this interface advertises */ + u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */ + u8 duplex; /* Duplex, half or full */ + u8 port; /* Which connector port */ + u8 phy_address; + u8 transceiver; /* Which transceiver to use */ + u8 autoneg; /* Enable or disable autonegotiation */ + u32 maxtxpkt; /* Tx pkts before generating tx int */ + u32 maxrxpkt; /* Rx pkts before generating rx int */ + u32 reserved[4]; +}; + +struct mii_if_info { + int phy_id; + int advertising; + int phy_id_mask; + int reg_num_mask; + + unsigned int full_duplex : 1; /* is full duplex? */ + unsigned int force_media : 1; /* is autoneg. disabled? */ + unsigned int supports_gmii : 1; /* are GMII registers supported? */ + + struct synopGMACNetworkAdapter *dev; + int (*mdio_read) (struct synopGMACNetworkAdapter *dev, int phy_id, int location); + void (*mdio_write) (struct synopGMACNetworkAdapter *dev, int phy_id, int location, int val); +}; + +#endif diff --git a/bsp/ls1cdev/drivers/net/synopGMAC.c b/bsp/ls1cdev/drivers/net/synopGMAC.c new file mode 100644 index 0000000000..a092fe66a6 --- /dev/null +++ b/bsp/ls1cdev/drivers/net/synopGMAC.c @@ -0,0 +1,929 @@ +/* + * File : synopGMAC.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + +#include +#include +#include +//#include + +#include "synopGMAC.h" +#include "mii.c" +#include "synopGMAC_debug.h" +#include +#define RMII + +#define Gmac_base 0xbfe10000 +#define Buffer_Size 2048 +#define MAX_ADDR_LEN 6 +#define NAMESIZE 16 + +#define LS1B_GMAC0_IRQ 34 +#define BUS_SIZE_ALIGN(x) ((x+15)&~15) + +#define DEFAULT_MAC_ADDRESS {0x00, 0x55, 0x7B, 0xB5, 0x7D, 0xF7} + +u32 regbase = 0xbfe10000; +static u32 GMAC_Power_down; +extern void *plat_alloc_consistent_dmaable_memory(synopGMACdevice *pcidev, u32 size, u32 *addr) ; +extern s32 synopGMAC_check_phy_init (synopGMACPciNetworkAdapter *adapter) ; +extern int init_phy(synopGMACdevice *gmacdev); +dma_addr_t plat_dma_map_single(void *hwdev, void *ptr,u32 size); + +void eth_rx_irq(int irqno,void *param); +static char Rx_Buffer[Buffer_Size]; +static char Tx_Buffer[Buffer_Size]; + +struct rt_eth_dev +{ + struct eth_device parent; + rt_uint8_t dev_addr[MAX_ADDR_LEN]; + char *name; + int iobase; + int state; + int index; + struct rt_timer link_timer; + struct rt_timer rx_poll_timer; + void *priv; +}; +static struct rt_eth_dev eth_dev; +static struct rt_semaphore sem_ack, sem_lock; + +/** + * This sets up the transmit Descriptor queue in ring or chain mode. + * This function is tightly coupled to the platform and operating system + * Device is interested only after the descriptors are setup. Therefore this function + * is not included in the device driver API. This function should be treated as an + * example code to design the descriptor structures for ring mode or chain mode. + * This function depends on the pcidev structure for allocation consistent dma-able memory in case + * of linux. + * This limitation is due to the fact that linux uses pci structure to allocate a dmable memory + * - Allocates the memory for the descriptors. + * - Initialize the Busy and Next descriptors indices to 0(Indicating first descriptor). + * - Initialize the Busy and Next descriptors to first descriptor address. + * - Initialize the last descriptor with the endof ring in case of ring mode. + * - Initialize the descriptors in chain mode. + * @param[in] pointer to synopGMACdevice. + * @param[in] pointer to pci_device structure. + * @param[in] number of descriptor expected in tx descriptor queue. + * @param[in] whether descriptors to be created in RING mode or CHAIN mode. + * \return 0 upon success. Error code upon failure. + * \note This function fails if allocation fails for required number of descriptors in Ring mode, + * but in chain mode + * function returns -ESYNOPGMACNOMEM in the process of descriptor chain creation. once returned from + * this function + * user should for gmacdev->TxDescCount to see how many descriptors are there in the chain. Should + * continue further + * only if the number of descriptors in the chain meets the requirements + */ +s32 synopGMAC_setup_tx_desc_queue(synopGMACdevice * gmacdev,u32 no_of_desc, u32 desc_mode) +{ + s32 i; + DmaDesc * bf1; + + DmaDesc *first_desc = NULL; + + dma_addr_t dma_addr; + gmacdev->TxDescCount = 0; + + first_desc = (DmaDesc *)plat_alloc_consistent_dmaable_memory (gmacdev, sizeof(DmaDesc) * no_of_desc,&dma_addr); + if(first_desc == NULL){ + rt_kprintf("Error in Tx Descriptors memory allocation\n"); + return -ESYNOPGMACNOMEM; + } + + DEBUG_MES("tx_first_desc_addr = %p\n", first_desc); + DEBUG_MES("dmaadr = %p\n", dma_addr); + gmacdev->TxDescCount = no_of_desc; + gmacdev->TxDesc = first_desc; + gmacdev->TxDescDma = dma_addr; + + for(i =0; i < gmacdev->TxDescCount; i++){ + synopGMAC_tx_desc_init_ring(gmacdev->TxDesc + i, i == gmacdev->TxDescCount-1); +#if SYNOP_TOP_DEBUG + rt_kprintf("\n%02d %08x \n",i,(unsigned int)(gmacdev->TxDesc + i)); + rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i))->status); + rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->length)); + rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->buffer1)); + rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->buffer2)); + rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->data1)); + rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->data2)); + rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->dummy1)); + rt_kprintf("%08x ",(unsigned int)((gmacdev->TxDesc + i)->dummy2)); +#endif + } + + gmacdev->TxNext = 0; + gmacdev->TxBusy = 0; + gmacdev->TxNextDesc = gmacdev->TxDesc; + gmacdev->TxBusyDesc = gmacdev->TxDesc; + gmacdev->BusyTxDesc = 0; + + return -ESYNOPGMACNOERR; +} + +/** + * This sets up the receive Descriptor queue in ring or chain mode. + * This function is tightly coupled to the platform and operating system + * Device is interested only after the descriptors are setup. Therefore this function + * is not included in the device driver API. This function should be treated as an + * example code to design the descriptor structures in ring mode or chain mode. + * This function depends on the pcidev structure for allocation of consistent dma-able memory in + * case of linux. + * This limitation is due to the fact that linux uses pci structure to allocate a dmable memory + * - Allocates the memory for the descriptors. + * - Initialize the Busy and Next descriptors indices to 0(Indicating first descriptor). + * - Initialize the Busy and Next descriptors to first descriptor address. + * - Initialize the last descriptor with the endof ring in case of ring mode. + * - Initialize the descriptors in chain mode. + * @param[in] pointer to synopGMACdevice. + * @param[in] pointer to pci_device structure. + * @param[in] number of descriptor expected in rx descriptor queue. + * @param[in] whether descriptors to be created in RING mode or CHAIN mode. + * \return 0 upon success. Error code upon failure. + * \note This function fails if allocation fails for required number of descriptors in Ring mode, + * but in chain mode + * function returns -ESYNOPGMACNOMEM in the process of descriptor chain creation. once returned from + * this function + * user should for gmacdev->RxDescCount to see how many descriptors are there in the chain. Should + * continue further + * only if the number of descriptors in the chain meets the requirements + */ +s32 synopGMAC_setup_rx_desc_queue(synopGMACdevice * gmacdev,u32 no_of_desc, u32 desc_mode) +{ + s32 i; + DmaDesc * bf1; + DmaDesc *first_desc = NULL; + + dma_addr_t dma_addr; + + gmacdev->RxDescCount = 0; + first_desc =(DmaDesc *)plat_alloc_consistent_dmaable_memory (gmacdev, sizeof(DmaDesc) * no_of_desc, &dma_addr); + if(first_desc == NULL){ + rt_kprintf("Error in Rx Descriptor Memory allocation in Ring mode\n"); + return -ESYNOPGMACNOMEM; + } + + DEBUG_MES("rx_first_desc_addr = %p\n", first_desc); + DEBUG_MES("dmaadr = %p\n", dma_addr); + gmacdev->RxDescCount = no_of_desc; + gmacdev->RxDesc = (DmaDesc *)first_desc; + gmacdev->RxDescDma = dma_addr; + + for(i =0; i < gmacdev->RxDescCount; i++){ + synopGMAC_rx_desc_init_ring(gmacdev->RxDesc + i, i == gmacdev->RxDescCount-1); + + } + + gmacdev->RxNext = 0; + gmacdev->RxBusy = 0; + gmacdev->RxNextDesc = gmacdev->RxDesc; + gmacdev->RxBusyDesc = gmacdev->RxDesc; + + gmacdev->BusyRxDesc = 0; + + return -ESYNOPGMACNOERR; +} + +void synopGMAC_linux_cable_unplug_function(void *adaptr) +{ + s32 data; + synopGMACPciNetworkAdapter *adapter = (synopGMACPciNetworkAdapter *)adaptr; + synopGMACdevice *gmacdev = adapter->synopGMACdev; + struct ethtool_cmd cmd; + + //rt_kprintf("%s\n",__FUNCTION__); + if(!mii_link_ok(&adapter->mii)){ + if(gmacdev->LinkState) + rt_kprintf("\r\nNo Link\r\n"); + gmacdev->DuplexMode = 0; + gmacdev->Speed = 0; + gmacdev->LoopBackMode = 0; + gmacdev->LinkState = 0; + } + else{ + data = synopGMAC_check_phy_init(adapter); + + if(gmacdev->LinkState != data){ + gmacdev->LinkState = data; + synopGMAC_mac_init(gmacdev); + rt_kprintf("Link is up in %s mode\n",(gmacdev->DuplexMode == FULLDUPLEX) ? "FULL DUPLEX": "HALF DUPLEX"); + if(gmacdev->Speed == SPEED1000) + rt_kprintf("Link is with 1000M Speed \r\n"); + if(gmacdev->Speed == SPEED100) + rt_kprintf("Link is with 100M Speed \n"); + if(gmacdev->Speed == SPEED10) + rt_kprintf("Link is with 10M Speed \n"); + } + } +} + +s32 synopGMAC_check_phy_init (synopGMACPciNetworkAdapter *adapter) +{ + struct ethtool_cmd cmd; + synopGMACdevice *gmacdev = adapter->synopGMACdev; + + if(!mii_link_ok(&adapter->mii)) + { + gmacdev->DuplexMode = FULLDUPLEX; + gmacdev->Speed = SPEED100; + + return 0; + } + else + { + mii_ethtool_gset(&adapter->mii, &cmd); + + gmacdev->DuplexMode = (cmd.duplex == DUPLEX_FULL) ? FULLDUPLEX: HALFDUPLEX ; + if(cmd.speed == SPEED_1000) + gmacdev->Speed = SPEED1000; + else if(cmd.speed == SPEED_100) + gmacdev->Speed = SPEED100; + else + gmacdev->Speed = SPEED10; + } + + return gmacdev->Speed|(gmacdev->DuplexMode<<4); +} + + +static int Mac_change_check(u8 *macaddr0, u8 *macaddr1) +{ + int i; + for(i = 0; i < 6; i++){ + if(macaddr0[i] != macaddr1[i]) + return 1; + } + return 0; +} + +static rt_err_t eth_init(rt_device_t device ) +{ + struct eth_device *eth_device = (struct eth_device *)device; + RT_ASSERT(eth_device != RT_NULL); + + s32 ijk; + s32 status = 0; + u64 dma_addr; + u32 Mac_changed = 0; + struct pbuf *pbuf; + u8 macaddr[6] = DEFAULT_MAC_ADDRESS; + struct rt_eth_dev *dev = ð_dev; + struct synopGMACNetworkAdapter *adapter = dev->priv; + synopGMACdevice * gmacdev = (synopGMACdevice *)adapter->synopGMACdev; + + synopGMAC_reset(gmacdev); + synopGMAC_attach(gmacdev,(regbase + MACBASE),(regbase + DMABASE), DEFAULT_PHY_BASE, macaddr); + + synopGMAC_read_version(gmacdev); + + synopGMAC_set_mdc_clk_div(gmacdev,GmiiCsrClk3); + gmacdev->ClockDivMdc = synopGMAC_get_mdc_clk_div(gmacdev); + + init_phy(adapter->synopGMACdev); + + rt_kprintf("tx desc_queue\n"); + synopGMAC_setup_tx_desc_queue(gmacdev,TRANSMIT_DESC_SIZE, RINGMODE); + synopGMAC_init_tx_desc_base(gmacdev); + + rt_kprintf("rx desc_queue\n"); + synopGMAC_setup_rx_desc_queue(gmacdev,RECEIVE_DESC_SIZE, RINGMODE); + synopGMAC_init_rx_desc_base(gmacdev); + DEBUG_MES("DmaRxBaseAddr = %08x\n",synopGMACReadReg(gmacdev->DmaBase,DmaRxBaseAddr)); + +// u32 dmaRx_Base_addr = synopGMACReadReg(gmacdev->DmaBase,DmaRxBaseAddr); +// rt_kprintf("first_desc_addr = 0x%x\n", dmaRx_Base_addr); + +#ifdef ENH_DESC_8W + synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength32 | DmaDescriptorSkip2 | DmaDescriptor8Words ); +#else + //synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength4 | DmaDescriptorSkip1); + synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength4 | DmaDescriptorSkip2); +#endif + synopGMAC_dma_control_init(gmacdev,DmaStoreAndForward |DmaTxSecondFrame|DmaRxThreshCtrl128); + + status = synopGMAC_check_phy_init(adapter); + synopGMAC_mac_init(gmacdev); + + synopGMAC_pause_control(gmacdev); + +#ifdef IPC_OFFLOAD + synopGMAC_enable_rx_chksum_offload(gmacdev); + synopGMAC_rx_tcpip_chksum_drop_enable(gmacdev); +#endif + + u32 skb; + do{ + skb = (u32)plat_alloc_memory(RX_BUF_SIZE); //should skb aligned here? + if(skb == RT_NULL){ + rt_kprintf("ERROR in skb buffer allocation\n"); + break; + } + + dma_addr = plat_dma_map_single(gmacdev,(void *)skb,RX_BUF_SIZE); //获取 skb 的 dma 地址 + + status = synopGMAC_set_rx_qptr(gmacdev,dma_addr,RX_BUF_SIZE,(u32)skb,0,0,0); + if(status < 0) + { + rt_kprintf("status < 0!!\n"); + plat_free_memory((void *)skb); + } + }while(status >= 0 && (status < (RECEIVE_DESC_SIZE - 1))); + + synopGMAC_clear_interrupt(gmacdev); + + synopGMAC_disable_mmc_tx_interrupt(gmacdev, 0xFFFFFFFF); + synopGMAC_disable_mmc_rx_interrupt(gmacdev, 0xFFFFFFFF); + synopGMAC_disable_mmc_ipc_rx_interrupt(gmacdev, 0xFFFFFFFF); + +// synopGMAC_disable_interrupt_all(gmacdev); + synopGMAC_enable_interrupt(gmacdev, DmaIntEnable); + synopGMAC_enable_dma_rx(gmacdev); + synopGMAC_enable_dma_tx(gmacdev); + + plat_delay(DEFAULT_LOOP_VARIABLE); + synopGMAC_check_phy_init(adapter); + synopGMAC_mac_init(gmacdev); + + rt_timer_init(&dev->link_timer, "link_timer", + synopGMAC_linux_cable_unplug_function, + (void *)adapter, + RT_TICK_PER_SECOND, + RT_TIMER_FLAG_PERIODIC); + + rt_timer_start(&dev->link_timer); +#ifdef RT_USING_GMAC_INT_MODE + /* installl isr */ + DEBUG_MES("%s\n", __FUNCTION__); + rt_hw_interrupt_install(LS1C_MAC_IRQ, eth_rx_irq, RT_NULL, "e0_isr"); + rt_hw_interrupt_umask(LS1C_MAC_IRQ); +#else + rt_timer_init(&dev->rx_poll_timer, "rx_poll_timer", + eth_rx_irq, + (void *)adapter, + 1, + RT_TIMER_FLAG_PERIODIC); + + rt_timer_start(&dev->rx_poll_timer); +#endif /*RT_USING_GMAC_INT_MODE*/ + + rt_kprintf("eth_inited!\n"); + + return RT_EOK; +} + +static rt_err_t eth_open(rt_device_t dev, rt_uint16_t oflag) +{ + rt_kprintf("eth_open!!\n"); + + return RT_EOK; +} + +static rt_err_t eth_close(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_size_t eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_size_t eth_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_err_t eth_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + switch (cmd) + { + case NIOCTL_GADDR: + if(args) rt_memcpy(args, eth_dev.dev_addr, 6); + else return -RT_ERROR; + break; + + default : + break; + } + return RT_EOK; +} + +rt_err_t rt_eth_tx(rt_device_t device, struct pbuf* p) +{ + /* lock eth device */ + rt_sem_take(&sem_lock, RT_WAITING_FOREVER); + + DEBUG_MES("in %s\n", __FUNCTION__); + + s32 status; + u32 pbuf; + u64 dma_addr; + u32 offload_needed = 0; + u32 index; + DmaDesc * dpr; + struct rt_eth_dev *dev = (struct rt_eth_dev *) device; + struct synopGMACNetworkAdapter *adapter; + synopGMACdevice * gmacdev; + adapter = (struct synopGMACNetworkAdapter *) dev->priv; + if(adapter == NULL) + return -1; + + gmacdev = (synopGMACdevice *) adapter->synopGMACdev; + if(gmacdev == NULL) + return -1; + + if(!synopGMAC_is_desc_owned_by_dma(gmacdev->TxNextDesc)) + { + + pbuf = (u32)plat_alloc_memory(p->len); + //pbuf = (u32)pbuf_alloc(PBUF_LINK, p->len, PBUF_RAM); + if(pbuf == 0) + { + rt_kprintf("===error in alloc bf1\n"); + return -1; + } + + DEBUG_MES("p->len = %d\n", p->len); + memcpy((void *)pbuf, p->payload, p->len); + dma_addr = plat_dma_map_single(gmacdev,(void*)pbuf,p->len); + + status = synopGMAC_set_tx_qptr(gmacdev,dma_addr,p->len,pbuf,0,0,0,offload_needed,&index,dpr); + if(status < 0){ + rt_kprintf("%s No More Free Tx Descriptors\n",__FUNCTION__); + + plat_free_memory((void *)pbuf); + return -16; + } + } + synopGMAC_resume_dma_tx(gmacdev); + + s32 desc_index; + u32 data1, data2; + u32 dma_addr1, dma_addr2; + u32 length1, length2; +#ifdef ENH_DESC_8W + u32 ext_status; + u16 time_stamp_higher; + u32 time_stamp_high; + u32 time_stamp_low; +#endif + do { +#ifdef ENH_DESC_8W + desc_index = synopGMAC_get_tx_qptr(gmacdev, &status, &dma_addr1, &length1, &data1, &dma_addr2, &length2, &data2,&ext_status,&time_stamp_high,&time_stamp_low); + synopGMAC_TS_read_timestamp_higher_val(gmacdev, &time_stamp_higher); +#else + desc_index = synopGMAC_get_tx_qptr(gmacdev, &status, &dma_addr1, &length1, &data1, &dma_addr2, &length2, &data2); +#endif + if(desc_index >= 0 && data1 != 0){ +#ifdef IPC_OFFLOAD + if(synopGMAC_is_tx_ipv4header_checksum_error(gmacdev, status)){ + rt_kprintf("Harware Failed to Insert IPV4 Header Checksum\n"); + } + if(synopGMAC_is_tx_payload_checksum_error(gmacdev, status)){ + rt_kprintf("Harware Failed to Insert Payload Checksum\n"); + } +#endif + + plat_free_memory((void *)(data1)); //sw: data1 = buffer1 + + if(synopGMAC_is_desc_valid(status)){ + adapter->synopGMACNetStats.tx_bytes += length1; + adapter->synopGMACNetStats.tx_packets++; + } + else { + adapter->synopGMACNetStats.tx_errors++; + adapter->synopGMACNetStats.tx_aborted_errors += synopGMAC_is_tx_aborted(status); + adapter->synopGMACNetStats.tx_carrier_errors += synopGMAC_is_tx_carrier_error(status); + } + } adapter->synopGMACNetStats.collisions += synopGMAC_get_tx_collision_count(status); + } while(desc_index >= 0); + + /* unlock eth device */ + rt_sem_release(&sem_lock); +// rt_kprintf("output %d bytes\n", p->len); + u32 test_data; + test_data = synopGMACReadReg(gmacdev->DmaBase, DmaStatus); + return RT_EOK; +} + +struct pbuf *rt_eth_rx(rt_device_t device) +{ + DEBUG_MES("%s : \n", __FUNCTION__); + struct rt_eth_dev *dev = ð_dev; + struct synopGMACNetworkAdapter *adapter; + synopGMACdevice * gmacdev; +// struct PmonInet * pinetdev; + s32 desc_index; + int i; + char * ptr; + u32 bf1; + u32 data1; + u32 data2; + u32 len; + u32 status; + u32 dma_addr1; + u32 dma_addr2; + struct pbuf *pbuf = RT_NULL; + rt_sem_take(&sem_lock, RT_WAITING_FOREVER); + + adapter = (struct synopGMACNetworkAdapter *) dev->priv; + if(adapter == NULL){ + rt_kprintf("%S : Unknown Device !!\n", __FUNCTION__); + return NULL; + } + + gmacdev = (synopGMACdevice *) adapter->synopGMACdev; + if(gmacdev == NULL){ + rt_kprintf("%s : GMAC device structure is missing\n", __FUNCTION__); + return NULL; + } + + /*Handle the Receive Descriptors*/ + // do{ + desc_index = synopGMAC_get_rx_qptr(gmacdev, &status,&dma_addr1,NULL, &data1,&dma_addr2,NULL,&data2); + + if(desc_index >= 0 && data1 != 0){ + DEBUG_MES("Received Data at Rx Descriptor %d for skb 0x%08x whose status is %08x\n",desc_index,dma_addr1,status); + + if(synopGMAC_is_rx_desc_valid(status)||SYNOP_PHY_LOOPBACK) + { + pbuf = pbuf_alloc(PBUF_LINK, MAX_ETHERNET_PAYLOAD, PBUF_RAM); + if(pbuf == 0) rt_kprintf("===error in pbuf_alloc\n"); + + + dma_addr1 = plat_dma_map_single(gmacdev,(void*)data1,RX_BUF_SIZE); + len = synopGMAC_get_rx_desc_frame_length(status); //Not interested in Ethernet CRC bytes + rt_memcpy( pbuf->payload, (char *)data1, len); + DEBUG_MES("==get pkg len: %d\n",len); + } + else + { + rt_kprintf("s: %08x\n",status); + adapter->synopGMACNetStats.rx_errors++; + adapter->synopGMACNetStats.collisions += synopGMAC_is_rx_frame_collision(status); + adapter->synopGMACNetStats.rx_crc_errors += synopGMAC_is_rx_crc(status); + adapter->synopGMACNetStats.rx_frame_errors += synopGMAC_is_frame_dribbling_errors(status); + adapter->synopGMACNetStats.rx_length_errors += synopGMAC_is_rx_frame_length_errors(status); + } + + desc_index = synopGMAC_set_rx_qptr(gmacdev,dma_addr1, RX_BUF_SIZE, (u32)data1,0,0,0); + + if(desc_index < 0){ +#if SYNOP_RX_DEBUG + rt_kprintf("Cannot set Rx Descriptor for data1 %08x\n",(u32)data1); +#endif + plat_free_memory((void *)data1); + } + + } + + // }while(desc_index >= 0); + rt_sem_release(&sem_lock); + DEBUG_MES("%s : before return \n", __FUNCTION__); + return pbuf; +} + +static int rtl88e1111_config_init(synopGMACdevice *gmacdev) +{ + int retval, err; + u16 data; + + DEBUG_MES("in %s\n", __FUNCTION__); + synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x14,&data); + data = data | 0x82; + err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x14,data); + synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x00,&data); + data = data | 0x8000; + err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x00,data); +#if SYNOP_PHY_LOOPBACK + synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x14,&data); + data = data | 0x70; + data = data & 0xffdf; + err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x14,data); + data = 0x8000; + err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x00,data); + data = 0x5140; + err = synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x00,data); +#endif + if (err < 0) + return err; + return 0; +} + +int init_phy(synopGMACdevice *gmacdev) +{ + u16 data; + + synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,2,&data); + /*set 88e1111 clock phase delay*/ + if(data == 0x141) + rtl88e1111_config_init(gmacdev); +#if defined (RMII) + else if(data == 0x8201) + { + //RTL8201 + data = 0x400; // set RMII mode + synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x19,data); + synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x19,&data); + TR("phy reg25 is %0x \n",data); + + data = 0x3100; //set 100M speed + synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x0,data); + } + else if(data == 0x0180 || data == 0x0181) + { + //DM9161 + synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x10,&data); + data |= (1 << 8); //set RMII mode + synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x10,data); //set RMII mode + synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x10,&data); + TR("phy reg16 is 0x%0x \n",data); + + // synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x0,&data); + // data &= ~(1<<10); + data = 0x3100; //set auto- + //data = 0x0100; //set 10M speed + synopGMAC_write_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x0,data); + } +#endif + + return 0; +} + +u32 synopGMAC_wakeup_filter_config3[] = { + 0x00000000, + 0x000000FF, + 0x00000000, + 0x00000000, + 0x00000100, + 0x00003200, + 0x7eED0000, + 0x00000000 +}; + +static void synopGMAC_linux_powerdown_mac(synopGMACdevice *gmacdev) +{ + rt_kprintf("Put the GMAC to power down mode..\n"); + + GMAC_Power_down = 1; + + synopGMAC_disable_dma_tx(gmacdev); + plat_delay(10000); + + synopGMAC_tx_disable(gmacdev); + synopGMAC_rx_disable(gmacdev); + plat_delay(10000); + + synopGMAC_disable_dma_rx(gmacdev); + + synopGMAC_magic_packet_enable(gmacdev); + synopGMAC_write_wakeup_frame_register(gmacdev, synopGMAC_wakeup_filter_config3); + + synopGMAC_wakeup_frame_enable(gmacdev); + + synopGMAC_rx_enable(gmacdev); + + synopGMAC_pmt_int_enable(gmacdev); + + synopGMAC_power_down_enable(gmacdev); + return; +} + +static void synopGMAC_linux_powerup_mac(synopGMACdevice *gmacdev) +{ + GMAC_Power_down = 0; + if( synopGMAC_is_magic_packet_received(gmacdev)) + rt_kprintf("GMAC wokeup due to Magic Pkt Received\n"); + if(synopGMAC_is_wakeup_frame_received(gmacdev)) + rt_kprintf("GMAC wokeup due to Wakeup Frame Received\n"); + + synopGMAC_pmt_int_disable(gmacdev); + + synopGMAC_rx_enable(gmacdev); + synopGMAC_enable_dma_rx(gmacdev); + + synopGMAC_tx_enable(gmacdev); + synopGMAC_enable_dma_tx(gmacdev); + return; +} + + +static int mdio_read(synopGMACPciNetworkAdapter *adapter, int addr, int reg) +{ + synopGMACdevice * gmacdev; + u16 data; + gmacdev = adapter->synopGMACdev; + + synopGMAC_read_phy_reg(gmacdev->MacBase,addr,reg, &data); + return data; +} + +static void mdio_write(synopGMACPciNetworkAdapter *adapter, int addr, int reg, int data) +{ + synopGMACdevice * gmacdev; + gmacdev = adapter->synopGMACdev; + synopGMAC_write_phy_reg(gmacdev->MacBase,addr,reg,data); +} + +void eth_rx_irq(int irqno,void *param) +{ + struct rt_eth_dev *dev = ð_dev; + struct synopGMACNetworkAdapter *adapter = dev->priv; + //DEBUG_MES("in irq!!\n"); +#ifdef RT_USING_GMAC_INT_MODE + int i ; + for(i = 0; i < 7200; i++) + ; +#endif /*RT_USING_GMAC_INT_MODE*/ + synopGMACdevice * gmacdev = (synopGMACdevice *)adapter->synopGMACdev; + + u32 interrupt,dma_status_reg; + s32 status; + u32 dma_addr; + + //rt_kprintf("irq i = %d\n", i++); + dma_status_reg = synopGMACReadReg(gmacdev->DmaBase, DmaStatus); + if(dma_status_reg == 0) + { + rt_kprintf("dma_status ==0 \n"); + return; + } + + //rt_kprintf("dma_status_reg is 0x%x\n", dma_status_reg); + u32 gmacstatus; + synopGMAC_disable_interrupt_all(gmacdev); + gmacstatus = synopGMACReadReg(gmacdev->MacBase,GmacStatus); + + if(dma_status_reg & GmacPmtIntr){ + rt_kprintf("%s:: Interrupt due to PMT module\n",__FUNCTION__); + //synopGMAC_linux_powerup_mac(gmacdev); + } + if(dma_status_reg & GmacMmcIntr){ + rt_kprintf("%s:: Interrupt due to MMC module\n",__FUNCTION__); + DEBUG_MES("%s:: synopGMAC_rx_int_status = %08x\n",__FUNCTION__,synopGMAC_read_mmc_rx_int_status(gmacdev)); + DEBUG_MES("%s:: synopGMAC_tx_int_status = %08x\n",__FUNCTION__,synopGMAC_read_mmc_tx_int_status(gmacdev)); + } + + if(dma_status_reg & GmacLineIntfIntr){ + rt_kprintf("%s:: Interrupt due to GMAC LINE module\n",__FUNCTION__); + } + + interrupt = synopGMAC_get_interrupt_type(gmacdev); + //rt_kprintf("%s:Interrupts to be handled: 0x%08x\n",__FUNCTION__,interrupt); + if(interrupt & synopGMACDmaError){ + u8 mac_addr0[6]; + rt_kprintf("%s::Fatal Bus Error Inetrrupt Seen\n",__FUNCTION__); + + memcpy(mac_addr0,dev->dev_addr,6); + synopGMAC_disable_dma_tx(gmacdev); + synopGMAC_disable_dma_rx(gmacdev); + + synopGMAC_take_desc_ownership_tx(gmacdev); + synopGMAC_take_desc_ownership_rx(gmacdev); + + synopGMAC_init_tx_rx_desc_queue(gmacdev); + + synopGMAC_reset(gmacdev); + + synopGMAC_set_mac_addr(gmacdev,GmacAddr0High,GmacAddr0Low, mac_addr0); + synopGMAC_dma_bus_mode_init(gmacdev,DmaFixedBurstEnable| DmaBurstLength8 | DmaDescriptorSkip2 ); + synopGMAC_dma_control_init(gmacdev,DmaStoreAndForward); + synopGMAC_init_rx_desc_base(gmacdev); + synopGMAC_init_tx_desc_base(gmacdev); + synopGMAC_mac_init(gmacdev); + synopGMAC_enable_dma_rx(gmacdev); + synopGMAC_enable_dma_tx(gmacdev); + + } + if(interrupt & synopGMACDmaRxNormal){ + //DEBUG_MES("%s:: Rx Normal \n", __FUNCTION__); + //synop_handle_received_data(netdev); + eth_device_ready(ð_dev.parent); + } + if(interrupt & synopGMACDmaRxAbnormal){ + //rt_kprintf("%s::Abnormal Rx Interrupt Seen\n",__FUNCTION__); + if(GMAC_Power_down == 0){ + adapter->synopGMACNetStats.rx_over_errors++; + synopGMACWriteReg(gmacdev->DmaBase, DmaStatus ,0x80); + synopGMAC_resume_dma_rx(gmacdev); + } + } + if(interrupt & synopGMACDmaRxStopped){ + rt_kprintf("%s::Receiver stopped seeing Rx interrupts\n",__FUNCTION__); //Receiver gone in to stopped state + } + + if(interrupt & synopGMACDmaTxNormal){ + DEBUG_MES("%s::Finished Normal Transmission \n",__FUNCTION__); + // synop_handle_transmit_over(netdev); + } + + if(interrupt & synopGMACDmaTxAbnormal){ + rt_kprintf("%s::Abnormal Tx Interrupt Seen\n",__FUNCTION__); + } + if(interrupt & synopGMACDmaTxStopped){ + TR("%s::Transmitter stopped sending the packets\n",__FUNCTION__); + if(GMAC_Power_down == 0){ // If Mac is not in powerdown + synopGMAC_disable_dma_tx(gmacdev); + synopGMAC_take_desc_ownership_tx(gmacdev); + + synopGMAC_enable_dma_tx(gmacdev); + // netif_wake_queue(netdev); + TR("%s::Transmission Resumed\n",__FUNCTION__); + } + } + /* Enable the interrrupt before returning from ISR*/ + synopGMAC_enable_interrupt(gmacdev,DmaIntEnable); + + return; +} + +void rt_hw_eth_init(void) +{ + u64 base_addr = Gmac_base; + struct synopGMACNetworkAdapter * synopGMACadapter; + static u8 mac_addr0[6] = DEFAULT_MAC_ADDRESS; + + rt_sem_init(&sem_ack, "tx_ack", 1, RT_IPC_FLAG_FIFO); + rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO); + + + memset(ð_dev, 0, sizeof(eth_dev)); + synopGMACadapter = (struct synopGMACNetworkAdapter * )plat_alloc_memory(sizeof (struct synopGMACNetworkAdapter)); + if(!synopGMACadapter){ + rt_kprintf("Error in Memory Allocataion, Founction : %s \n", __FUNCTION__); + } + memset((char *)synopGMACadapter ,0, sizeof (struct synopGMACNetworkAdapter)); + + synopGMACadapter->synopGMACdev = NULL; + + synopGMACadapter->synopGMACdev = (synopGMACdevice *) plat_alloc_memory(sizeof (synopGMACdevice)); + if(!synopGMACadapter->synopGMACdev){ + rt_kprintf("Error in Memory Allocataion, Founction : %s \n", __FUNCTION__); + } + memset((char *)synopGMACadapter->synopGMACdev ,0, sizeof (synopGMACdevice)); + /* + * Attach the device to MAC struct This will configure all the required base addresses + * such as Mac base, configuration base, phy base address(out of 32 possible phys) + * */ + synopGMAC_attach(synopGMACadapter->synopGMACdev,(regbase + MACBASE), regbase + DMABASE, DEFAULT_PHY_BASE, mac_addr0); + + init_phy(synopGMACadapter->synopGMACdev); + synopGMAC_reset(synopGMACadapter->synopGMACdev); + + /* MII setup */ + synopGMACadapter->mii.phy_id_mask = 0x1F; + synopGMACadapter->mii.reg_num_mask = 0x1F; + synopGMACadapter->mii.dev = synopGMACadapter; + synopGMACadapter->mii.mdio_read = mdio_read; + synopGMACadapter->mii.mdio_write = mdio_write; + synopGMACadapter->mii.phy_id = synopGMACadapter->synopGMACdev->PhyBase; + synopGMACadapter->mii.supports_gmii = mii_check_gmii_support(&synopGMACadapter->mii); + + eth_dev.iobase = base_addr; + eth_dev.name = "e0"; + eth_dev.priv = synopGMACadapter; + eth_dev.dev_addr[0] = mac_addr0[0]; + eth_dev.dev_addr[1] = mac_addr0[1]; + eth_dev.dev_addr[2] = mac_addr0[2]; + eth_dev.dev_addr[3] = mac_addr0[3]; + eth_dev.dev_addr[4] = mac_addr0[4]; + eth_dev.dev_addr[5] = mac_addr0[5]; + + eth_dev.parent.parent.type = RT_Device_Class_NetIf; + eth_dev.parent.parent.init = eth_init; + eth_dev.parent.parent.open = eth_open; + eth_dev.parent.parent.close = eth_close; + eth_dev.parent.parent.read = eth_read; + eth_dev.parent.parent.write = eth_write; + eth_dev.parent.parent.control = eth_control; + eth_dev.parent.parent.user_data = RT_NULL; + + eth_dev.parent.eth_tx = rt_eth_tx; + eth_dev.parent.eth_rx = rt_eth_rx; + + eth_device_init(&(eth_dev.parent), "e0"); +} diff --git a/bsp/ls1cdev/drivers/net/synopGMAC.h b/bsp/ls1cdev/drivers/net/synopGMAC.h new file mode 100644 index 0000000000..2988d5c4ba --- /dev/null +++ b/bsp/ls1cdev/drivers/net/synopGMAC.h @@ -0,0 +1,37 @@ +/* + * File : synopGMAC.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + +#ifndef __SYNOPGMAC__H +#define __SYNOPGMAC__H + +#include "synopGMAC_network_interface.h" +#include "synopGMAC_Host.h" +#include "synopGMAC_Dev.h" +#include "synopGMAC_plat.h" +#include "mii.h" +#include "synopGMAC_types.h" + +void rt_hw_eth_init(void); + +#endif /*__SYNOPGMAC__H*/ diff --git a/bsp/ls1cdev/drivers/net/synopGMAC_Dev.c b/bsp/ls1cdev/drivers/net/synopGMAC_Dev.c new file mode 100644 index 0000000000..6c5b4a2cde --- /dev/null +++ b/bsp/ls1cdev/drivers/net/synopGMAC_Dev.c @@ -0,0 +1,3705 @@ +/** \file + * This file defines the synopsys GMAC device dependent functions. + * Most of the operations on the GMAC device are available in this file. + * Functions for initiliasing and accessing MAC/DMA/PHY registers and the DMA descriptors + * are encapsulated in this file. The functions are platform/host/OS independent. + * These functions in turn use the low level device dependent (HAL) functions to + * access the register space. + * \internal + * ------------------------REVISION HISTORY--------------------------------- + * Synopsys 01/Aug/2007 Created + */ + +/* + * File : synopGMAC_Dev.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + +#include "synopGMAC_Dev.h" +#include +#include + +#define UNUSED 1 + +/** + * Function to set the MDC clock for mdio transactiona + * + * @param[in] pointer to device structure. + * @param[in] clk divider value. + * \return Reuturns 0 on success else return the error value. + */ +s32 synopGMAC_set_mdc_clk_div(synopGMACdevice *gmacdev,u32 clk_div_val) +{ + u32 orig_data; + orig_data = synopGMACReadReg(gmacdev->MacBase,GmacGmiiAddr); //set the mdc clock to the user defined value + orig_data &= (~ GmiiCsrClkMask); + orig_data |= clk_div_val; + synopGMACWriteReg(gmacdev->MacBase, GmacGmiiAddr ,orig_data); + return 0; +} + +/** + * Returns the current MDC divider value programmed in the ip. + * + * @param[in] pointer to device structure. + * @param[in] clk divider value. + * \return Returns the MDC divider value read. + */ +u32 synopGMAC_get_mdc_clk_div(synopGMACdevice *gmacdev) +{ + u32 data; + data = synopGMACReadReg(gmacdev->MacBase,GmacGmiiAddr); + data &= GmiiCsrClkMask; + return data; +} + + +/** + * Function to read the Phy register. The access to phy register + * is a slow process as the data is moved accross MDI/MDO interface + * @param[in] pointer to Register Base (It is the mac base in our case) . + * @param[in] PhyBase register is the index of one of supported 32 PHY devices. + * @param[in] Register offset is the index of one of the 32 phy register. + * @param[out] u16 data read from the respective phy register (only valid iff return value is 0). + * \return Returns 0 on success else return the error status. + */ +s32 synopGMAC_read_phy_reg(u32 RegBase,u32 PhyBase, u32 RegOffset, u16 * data ) +{ + u32 addr; + u32 loop_variable; + addr = ((PhyBase << GmiiDevShift) & GmiiDevMask) | ((RegOffset << GmiiRegShift) & GmiiRegMask) + | GmiiCsrClk3; //sw: add GmiiCsrClk + addr = addr | GmiiBusy ; //Gmii busy bit + + synopGMACWriteReg(RegBase,GmacGmiiAddr,addr); + //write the address from where the data to be read in GmiiGmiiAddr register of synopGMAC ip + + for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ + //Wait till the busy bit gets cleared within a certain amount of time + if (!(synopGMACReadReg(RegBase,GmacGmiiAddr) & GmiiBusy)){ + break; + } + plat_delay(DEFAULT_DELAY_VARIABLE); + } + if(loop_variable < DEFAULT_LOOP_VARIABLE) + * data = (u16)(synopGMACReadReg(RegBase,GmacGmiiData) & 0xFFFF); + else{ + TR("Error::: PHY not responding Busy bit didnot get cleared !!!!!!\n"); + return -ESYNOPGMACPHYERR; + } + //sw +#if SYNOP_REG_DEBUG + printf("read phy reg: offset = 0x%x\tdata = 0x%x\n",RegOffset,*data); +#endif + + return -ESYNOPGMACNOERR; +} + +/** + * Function to write to the Phy register. The access to phy register + * is a slow process as the data is moved accross MDI/MDO interface + * @param[in] pointer to Register Base (It is the mac base in our case) . + * @param[in] PhyBase register is the index of one of supported 32 PHY devices. + * @param[in] Register offset is the index of one of the 32 phy register. + * @param[in] data to be written to the respective phy register. + * \return Returns 0 on success else return the error status. + */ +s32 synopGMAC_write_phy_reg(u32 RegBase, u32 PhyBase, u32 RegOffset, u16 data) +{ + u32 addr; + u32 loop_variable; + + synopGMACWriteReg(RegBase,GmacGmiiData,data); // write the data in to GmacGmiiData register of synopGMAC ip + + addr = ((PhyBase << GmiiDevShift) & GmiiDevMask) | ((RegOffset << GmiiRegShift) & GmiiRegMask) | GmiiWrite | GmiiCsrClk3; //sw: add GmiiCsrclk + + addr = addr | GmiiBusy ; //set Gmii clk to 20-35 Mhz and Gmii busy bit + + synopGMACWriteReg(RegBase,GmacGmiiAddr,addr); + for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ + if (!(synopGMACReadReg(RegBase,GmacGmiiAddr) & GmiiBusy)){ + break; + } + plat_delay(DEFAULT_DELAY_VARIABLE); + } + + if(loop_variable < DEFAULT_LOOP_VARIABLE){ + return -ESYNOPGMACNOERR; + } + else{ + TR("Error::: PHY not responding Busy bit didnot get cleared !!!!!!\n"); + return -ESYNOPGMACPHYERR; + } +#if SYNOP_REG_DEBUG + printf("write phy reg: offset = 0x%x\tdata = 0x%x",RegOffset,data); +#endif +} + +/** + * Function to configure the phy in loopback mode. + * + * @param[in] pointer to synopGMACdevice. + * @param[in] enable or disable the loopback. + * \return 0 on success else return the error status. + * \note Don't get confused with mac loop-back synopGMAC_loopback_on(synopGMACdevice *) + * and synopGMAC_loopback_off(synopGMACdevice *) functions. + */ +#if UNUSED +s32 synopGMAC_phy_loopback(synopGMACdevice *gmacdev, bool loopback) +{ +s32 status = -ESYNOPGMACNOERR; +u16 *temp; + status = synopGMAC_read_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, PHY_CONTROL_REG,temp); +if(loopback) + *temp |= 0x4000; +else + *temp = *temp; + + status = synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, PHY_CONTROL_REG, *temp); +return status; +} + +#endif + + +/** + * Function to read the GMAC IP Version and populates the same in device data structure. + * @param[in] pointer to synopGMACdevice. + * \return Always return 0. + */ + +s32 synopGMAC_read_version (synopGMACdevice * gmacdev) +{ + u32 data = 0; + data = synopGMACReadReg(gmacdev->MacBase, GmacVersion ); + gmacdev->Version = data; + return 0; +} + + +/** + * Function to reset the GMAC core. + * This reests the DMA and GMAC core. After reset all the registers holds their respective reset value + * @param[in] pointer to synopGMACdevice. + * \return 0 on success else return the error status. + */ +s32 synopGMAC_reset (synopGMACdevice * gmacdev) +{ + u32 data = 0; + synopGMACWriteReg(gmacdev->DmaBase, DmaBusMode ,DmaResetOn); + plat_delay(DEFAULT_LOOP_VARIABLE); + data = synopGMACReadReg(gmacdev->DmaBase, DmaBusMode); + TR("DATA after Reset = %08x\n",data); + + return 0; +} + + +/** + * Function to program DMA bus mode register. + * + * The Bus Mode register is programmed with the value given. The bits to be set are + * bit wise or'ed and sent as the second argument to this function. + * @param[in] pointer to synopGMACdevice. + * @param[in] the data to be programmed. + * \return 0 on success else return the error status. + */ +s32 synopGMAC_dma_bus_mode_init(synopGMACdevice * gmacdev, u32 init_value ) +{ + synopGMACWriteReg(gmacdev->DmaBase, DmaBusMode ,init_value ); + return 0; + +} + +/** + * Function to program DMA Control register. + * + * The Dma Control register is programmed with the value given. The bits to be set are + * bit wise or'ed and sent as the second argument to this function. + * @param[in] pointer to synopGMACdevice. + * @param[in] the data to be programmed. + * \return 0 on success else return the error status. + */ +s32 synopGMAC_dma_control_init(synopGMACdevice * gmacdev, u32 init_value ) +{ + synopGMACWriteReg(gmacdev->DmaBase, DmaControl, init_value); + return 0; +} + + +/*Gmac configuration functions*/ + +/** + * Enable the watchdog timer on the receiver. + * When enabled, Gmac enables Watchdog timer, and GMAC allows no more than + * 2048 bytes of data (10,240 if Jumbo frame enabled). + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_wd_enable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacWatchdog); + return; +} +/** + * Disable the watchdog timer on the receiver. + * When disabled, Gmac disabled watchdog timer, and can receive frames up to + * 16,384 bytes. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ + +void synopGMAC_wd_disable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacWatchdog); + return; +} + +/** + * Enables the Jabber frame support. + * When enabled, GMAC disabled the jabber timer, and can transfer 16,384 byte frames. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_jab_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacJabber); + return; +} +/** + * Disables the Jabber frame support. + * When disabled, GMAC enables jabber timer. It cuts of transmitter if application + * sends more than 2048 bytes of data (10240 if Jumbo frame enabled). + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_jab_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacJabber); + return; +} +#endif + +/** + * Enables Frame bursting (Only in Half Duplex Mode). + * When enabled, GMAC allows frame bursting in GMII Half Duplex mode. + * Reserved in 10/100 and Full-Duplex configurations. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_frame_burst_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacFrameBurst); + return; +} +/** + * Disables Frame bursting. + * When Disabled, frame bursting is not supported. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_frame_burst_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacFrameBurst); + return; +} +#endif + +/** + * Enable Jumbo frame support. + * When Enabled GMAC supports jumbo frames of 9018/9022(VLAN tagged). + * Giant frame error is not reported in receive frame status. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_jumbo_frame_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacJumboFrame); + return; +} +#endif +/** + * Disable Jumbo frame support. + * When Disabled GMAC does not supports jumbo frames. + * Giant frame error is reported in receive frame status. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_jumbo_frame_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacJumboFrame); + return; +} + +/** + * Disable Carrier sense. + * When Disabled GMAC ignores CRS signal during frame transmission + * in half duplex mode. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ + +#if UNUSED +void synopGMAC_disable_crs(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacDisableCrs); + return; +} +#endif + + + +/** + * Selects the GMII port. + * When called GMII (1000Mbps) port is selected (programmable only in 10/100/1000 Mbps configuration). + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_select_gmii(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacMiiGmii); + return; +} +/** + * Selects the MII port. + * When called MII (10/100Mbps) port is selected (programmable only in 10/100/1000 Mbps configuration). + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_select_mii(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacMiiGmii); + return; +} + +/** + * Enables Receive Own bit (Only in Half Duplex Mode). + * When enaled GMAC receives all the packets given by phy while transmitting. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_rx_own_enable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacRxOwn); + return; +} +/** + * Disables Receive Own bit (Only in Half Duplex Mode). + * When enaled GMAC disables the reception of frames when gmii_txen_o is asserted. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_rx_own_disable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacRxOwn); + return; +} +#endif + +/** + * Sets the GMAC in loopback mode. + * When on GMAC operates in loop-back mode at GMII/MII. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + * \note (G)MII Receive clock is required for loopback to work properly, as transmit clock is + * not looped back internally. + */ +void synopGMAC_loopback_on(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacLoopback); + return; +} +/** + * Sets the GMAC in Normal mode. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_loopback_off(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacLoopback); + return; +} + +/** + * Sets the GMAC core in Full-Duplex mode. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_set_full_duplex(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacDuplex); + return; +} +/** + * Sets the GMAC core in Half-Duplex mode. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_set_half_duplex(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacDuplex); + return; +} + +/** + * GMAC tries retransmission (Only in Half Duplex mode). + * If collision occurs on the GMII/MII, GMAC attempt retries based on the + * back off limit configured. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + * \note This function is tightly coupled with synopGMAC_back_off_limit(synopGMACdev *, u32). + */ +void synopGMAC_retry_enable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacRetry); + return; +} +/** + * GMAC tries only one transmission (Only in Half Duplex mode). + * If collision occurs on the GMII/MII, GMAC will ignore the current frami + * transmission and report a frame abort with excessive collision in tranmit frame status. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_retry_disable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacRetry); + return; +} +#endif + +/** + * GMAC strips the Pad/FCS field of incoming frames. + * This is true only if the length field value is less than or equal to + * 1500 bytes. All received frames with length field greater than or equal to + * 1501 bytes are passed to the application without stripping the Pad/FCS field. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_pad_crc_strip_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacPadCrcStrip); + return; +} +#endif +/** + * GMAC doesnot strips the Pad/FCS field of incoming frames. + * GMAC will pass all the incoming frames to Host unmodified. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_pad_crc_strip_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacPadCrcStrip); + u32 status = synopGMACReadReg(gmacdev->MacBase, GmacConfig); + DEBUG_MES("strips status : %u\n", status & GmacPadCrcStrip); + return; +} +/** + * GMAC programmed with the back off limit value. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + * \note This function is tightly coupled with synopGMAC_retry_enable(synopGMACdevice * gmacdev) + */ +void synopGMAC_back_off_limit(synopGMACdevice * gmacdev, u32 value) +{ + u32 data; + data = synopGMACReadReg(gmacdev->MacBase, GmacConfig); + data &= (~GmacBackoffLimit); + data |= value; + synopGMACWriteReg(gmacdev->MacBase, GmacConfig,data); + return; +} + +/** + * Enables the Deferral check in GMAC (Only in Half Duplex mode) + * GMAC issues a Frame Abort Status, along with the excessive deferral error bit set in the + * transmit frame status when transmit state machine is deferred for more than + * - 24,288 bit times in 10/100Mbps mode + * - 155,680 bit times in 1000Mbps mode or Jumbo frame mode in 10/100Mbps operation. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + * \note Deferral begins when transmitter is ready to transmit, but is prevented because of + * an active CRS (carrier sense) + */ +#if UNUSED +void synopGMAC_deferral_check_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacDeferralCheck); + return; +} +#endif +/** + * Disables the Deferral check in GMAC (Only in Half Duplex mode). + * GMAC defers until the CRS signal goes inactive. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_deferral_check_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacDeferralCheck); + return; +} +/** + * Enable the reception of frames on GMII/MII. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_rx_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacRx); + return; +} +/** + * Disable the reception of frames on GMII/MII. + * GMAC receive state machine is disabled after completion of reception of current frame. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_rx_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacRx); + return; +} +#endif +/** + * Enable the transmission of frames on GMII/MII. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_tx_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacTx); + return; +} +/** + * Disable the transmission of frames on GMII/MII. + * GMAC transmit state machine is disabled after completion of transmission of current frame. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_tx_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacConfig, GmacTx); + return; +} +#endif + + +/*Receive frame filter configuration functions*/ + +/** + * Enables reception of all the frames to application. + * GMAC passes all the frames received to application irrespective of whether they + * pass SA/DA address filtering or not. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_frame_filter_enable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFrameFilter, GmacFilter); + return; +} +/** + * Disables reception of all the frames to application. + * GMAC passes only those received frames to application which + * pass SA/DA address filtering. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_frame_filter_disable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacFilter); + return; +} + +/** + * Populates the Hash High register with the data supplied. + * This function is called when the Hash filtering is to be enabled. + * @param[in] pointer to synopGMACdevice. + * @param[in] data to be written to hash table high register. + * \return void. + */ +#if UNUSED +void synopGMAC_write_hash_table_high(synopGMACdevice * gmacdev, u32 data) +{ + synopGMACWriteReg(gmacdev->MacBase,GmacHashHigh,data); + return; +} +#endif + +/** + * Populates the Hash Low register with the data supplied. + * This function is called when the Hash filtering is to be enabled. + * @param[in] pointer to synopGMACdevice. + * @param[in] data to be written to hash table low register. + * \return void. + */ +#if UNUSED +void synopGMAC_write_hash_table_low(synopGMACdevice * gmacdev, u32 data) +{ + synopGMACWriteReg(gmacdev->MacBase,GmacHashLow,data); + return; +} +#endif + +/** + * Enables Hash or Perfect filter (only if Hash filter is enabled in H/W). + * Only frames matching either perfect filtering or Hash Filtering as per HMC and HUC + * configuration are sent to application. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_hash_perfect_filter_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacHashPerfectFilter); + return; +} +#endif + +/** + * Enables only Hash(only if Hash filter is enabled in H/W). + * Only frames matching Hash Filtering as per HMC and HUC + * configuration are sent to application. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_Hash_filter_only_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacHashPerfectFilter); + return; +} +#endif + +/** + * Enables Source address filtering. + * When enabled source address filtering is performed. Only frames matching SA filtering are passed to application with + * SAMatch bit of RxStatus is set. GMAC drops failed frames. + * @param[in] pointer to synopGMACdevice. + * \return void. + * \note This function is overriden by synopGMAC_frame_filter_disable(synopGMACdevice *) + */ +#if UNUSED +void synopGMAC_src_addr_filter_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacSrcAddrFilter); + return; +} +#endif +/** + * Disables Source address filtering. + * When disabled GMAC forwards the received frames with updated SAMatch bit in RxStatus. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_src_addr_filter_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFrameFilter, GmacSrcAddrFilter); + return; +} +/** + * Enables Inverse Destination address filtering. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_dst_addr_filter_inverse(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacDestAddrFilterNor); + return; +} +#endif +/** + * Enables the normal Destination address filtering. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_dst_addr_filter_normal(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFrameFilter, GmacDestAddrFilterNor); + return; +} + +/** + * Enables forwarding of control frames. + * When set forwards all the control frames (incl. unicast and multicast PAUSE frames). + * @param[in] pointer to synopGMACdevice. + * \return void. + * \note Depends on RFE of FlowControlRegister[2] + */ +void synopGMAC_set_pass_control(synopGMACdevice * gmacdev,u32 passcontrol) +{ + u32 data; + data = synopGMACReadReg(gmacdev->MacBase, GmacFrameFilter); + data &= (~GmacPassControl); + data |= passcontrol; + synopGMACWriteReg(gmacdev->MacBase,GmacFrameFilter,data); + return; +} + +/** + * Enables Broadcast frames. + * When enabled Address filtering module passes all incoming broadcast frames. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_broadcast_enable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFrameFilter, GmacBroadcast ); + return; +} +/** + * Disable Broadcast frames. + * When disabled Address filtering module filters all incoming broadcast frames. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_broadcast_disable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacBroadcast); + return; +} +#endif + +/** + * Enables Multicast frames. + * When enabled all multicast frames are passed. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_multicast_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacMulticastFilter); + return; +} +#endif +/** + * Disable Multicast frames. + * When disabled multicast frame filtering depends on HMC bit. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_multicast_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFrameFilter, GmacMulticastFilter); + return; +} + +/** + * Enables multicast hash filtering. + * When enabled GMAC performs teh destination address filtering according to the hash table. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_multicast_hash_filter_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacMcastHashFilter); + return; +} +#endif +/** + * Disables multicast hash filtering. + * When disabled GMAC performs perfect destination address filtering for multicast frames, it compares + * DA field with the value programmed in DA register. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_multicast_hash_filter_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFrameFilter, GmacMcastHashFilter); + return; +} + +/** + * Enables promiscous mode. + * When enabled Address filter modules pass all incoming frames regardless of their Destination + * and source addresses. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_promisc_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacPromiscuousMode); + return; +} +#endif +/** + * Clears promiscous mode. + * When called the GMAC falls back to normal operation from promiscous mode. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_promisc_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFrameFilter, GmacPromiscuousMode); + return; +} + + +/** + * Enables unicast hash filtering. + * When enabled GMAC performs the destination address filtering of unicast frames according to the hash table. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_unicast_hash_filter_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacUcastHashFilter); + return; +} +#endif +/** + * Disables multicast hash filtering. + * When disabled GMAC performs perfect destination address filtering for unicast frames, it compares + * DA field with the value programmed in DA register. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_unicast_hash_filter_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFrameFilter, GmacUcastHashFilter); + return; +} + +/*Flow control configuration functions*/ + +/** + * Enables detection of pause frames with stations unicast address. + * When enabled GMAC detects the pause frames with stations unicast address in addition to the + * detection of pause frames with unique multicast address. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_unicast_pause_frame_detect_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFlowControl, GmacUnicastPauseFrame); + return; +} +#endif +/** + * Disables detection of pause frames with stations unicast address. + * When disabled GMAC only detects with the unique multicast address (802.3x). + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_unicast_pause_frame_detect_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFlowControl, GmacUnicastPauseFrame); + return; +} +/** + * Rx flow control enable. + * When Enabled GMAC will decode the rx pause frame and disable the tx for a specified time. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_rx_flow_control_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFlowControl, GmacRxFlowControl); + return; +} +/** + * Rx flow control disable. + * When disabled GMAC will not decode pause frame. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_rx_flow_control_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFlowControl, GmacRxFlowControl); + return; +} +/** + * Tx flow control enable. + * When Enabled + * - In full duplex GMAC enables flow control operation to transmit pause frames. + * - In Half duplex GMAC enables the back pressure operation + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_tx_flow_control_enable(synopGMACdevice * gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase, GmacFlowControl, GmacTxFlowControl); + return; +} + +/** + * Tx flow control disable. + * When Disabled + * - In full duplex GMAC will not transmit any pause frames. + * - In Half duplex GMAC disables the back pressure feature. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_tx_flow_control_disable(synopGMACdevice * gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase, GmacFlowControl, GmacTxFlowControl); + return; +} + +/** + * Initiate Flowcontrol operation. + * When Set + * - In full duplex GMAC initiates pause control frame. + * - In Half duplex GMAC initiates back pressure function. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_tx_activate_flow_control(synopGMACdevice * gmacdev) +{ + //In case of full duplex check for this bit to b'0. if it is read as b'1 indicates that + //control frame transmission is in progress. + if(gmacdev->Speed == FULLDUPLEX){ + if(!synopGMACCheckBits(gmacdev->MacBase, GmacFlowControl, GmacFlowControlBackPressure)) + synopGMACSetBits(gmacdev->MacBase, GmacFlowControl, GmacFlowControlBackPressure); + } + else{ //if half duplex mode + + synopGMACSetBits(gmacdev->MacBase, GmacFlowControl, GmacFlowControlBackPressure); + } + + return; +} +#endif + +/** + * stops Flowcontrol operation. + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +#if UNUSED +void synopGMAC_tx_deactivate_flow_control(synopGMACdevice * gmacdev) +{ + //In full duplex this bit is automatically cleared after transmitting a pause control frame. + if(gmacdev->Speed == HALFDUPLEX){ + synopGMACSetBits(gmacdev->MacBase, GmacFlowControl, GmacFlowControlBackPressure); + } + return; +} +#endif + +/** + * This enables the pause frame generation after programming the appropriate registers. + * presently activation is set at 3k and deactivation set at 4k. These may have to tweaked + * if found any issues + * @param[in] pointer to synopGMACdevice. + * \return void. + */ +void synopGMAC_pause_control(synopGMACdevice *gmacdev) +{ + u32 omr_reg; + u32 mac_flow_control_reg; + omr_reg = synopGMACReadReg(gmacdev->DmaBase,DmaControl); + omr_reg |= DmaRxFlowCtrlAct4K | DmaRxFlowCtrlDeact5K |DmaEnHwFlowCtrl; + synopGMACWriteReg(gmacdev->DmaBase, DmaControl, omr_reg); + + mac_flow_control_reg = synopGMACReadReg(gmacdev->MacBase,GmacFlowControl); + mac_flow_control_reg |= GmacRxFlowControl | GmacTxFlowControl | 0xFFFF0000; + synopGMACWriteReg(gmacdev->MacBase,GmacFlowControl,mac_flow_control_reg); + + return; + +} + +/** + * Example mac initialization sequence. + * This function calls the initialization routines to initialize the GMAC register. + * One can change the functions invoked here to have different configuration as per the requirement + * @param[in] pointer to synopGMACdevice. + * \return Returns 0 on success. + */ +s32 synopGMAC_mac_init(synopGMACdevice * gmacdev) +{ + u32 PHYreg; + + if(gmacdev->DuplexMode == FULLDUPLEX){ + TR("\n===phy FULLDUPLEX MODE\n"); //sw: debug + synopGMAC_wd_enable(gmacdev); + synopGMAC_jab_enable(gmacdev); + synopGMAC_frame_burst_enable(gmacdev); + synopGMAC_jumbo_frame_disable(gmacdev); + synopGMAC_rx_own_enable(gmacdev); +#if SYNOP_LOOPBACK_MODE + synopGMAC_loopback_on(gmacdev); +#else + synopGMAC_loopback_off(gmacdev); +#endif + synopGMAC_set_full_duplex(gmacdev); //1 + synopGMAC_retry_enable(gmacdev); + synopGMAC_pad_crc_strip_disable(gmacdev); + synopGMAC_back_off_limit(gmacdev,GmacBackoffLimit0); + synopGMAC_deferral_check_disable(gmacdev); + + synopGMAC_tx_enable(gmacdev); //according to Tang Dan's commitment + synopGMAC_rx_enable(gmacdev); + + synopGMACSetBits(gmacdev->DmaBase,DmaControl, DmaStoreAndForward );//3 + synopGMACSetBits(gmacdev->DmaBase,DmaControl, DmaFwdErrorFrames ); + if(gmacdev->Speed == SPEED1000) + synopGMAC_select_gmii(gmacdev); + else{ + synopGMAC_select_mii(gmacdev); + if(gmacdev->Speed == SPEED100) + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacFESpeed100); + else + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacFESpeed10); + } + + + /*Frame Filter Configuration*/ + synopGMAC_frame_filter_enable(gmacdev); //2 + //synopGMAC_frame_filter_disable(gmacdev); //2 + synopGMAC_set_pass_control(gmacdev,GmacPassControl0); + synopGMAC_broadcast_enable(gmacdev); + synopGMAC_src_addr_filter_disable(gmacdev); + synopGMAC_multicast_disable(gmacdev); + //synopGMAC_dst_addr_filter_normal(gmacdev); //scl + synopGMAC_dst_addr_filter_inverse(gmacdev); + synopGMAC_multicast_hash_filter_disable(gmacdev); + synopGMAC_promisc_disable(gmacdev); + synopGMAC_unicast_hash_filter_disable(gmacdev); + + /*Flow Control Configuration*/ + synopGMAC_unicast_pause_frame_detect_disable(gmacdev); + synopGMAC_rx_flow_control_enable(gmacdev); + synopGMAC_tx_flow_control_enable(gmacdev); + } + else{//for Half Duplex configuration + + TR("\n===phy HALFDUPLEX MODE\n"); //sw: debug + synopGMAC_wd_enable(gmacdev ); + synopGMAC_jab_enable(gmacdev); + synopGMAC_frame_burst_enable(gmacdev); + synopGMAC_jumbo_frame_disable(gmacdev); + synopGMAC_rx_own_enable(gmacdev); +#if SYNOP_LOOPBACK_MODE + synopGMAC_loopback_on(gmacdev); +#else + synopGMAC_loopback_off(gmacdev); +#endif + synopGMAC_set_half_duplex(gmacdev); + synopGMAC_retry_enable(gmacdev); + synopGMAC_pad_crc_strip_disable(gmacdev); + synopGMAC_back_off_limit(gmacdev,GmacBackoffLimit0); + synopGMAC_deferral_check_disable(gmacdev); + +//sw: set efe & tsf + synopGMACSetBits(gmacdev->DmaBase,DmaControl, DmaStoreAndForward ); + synopGMACSetBits(gmacdev->DmaBase,DmaControl, DmaFwdErrorFrames ); +//sw: put it in the end + synopGMAC_tx_enable(gmacdev); + synopGMAC_rx_enable(gmacdev); + + + if(gmacdev->Speed == SPEED1000) + synopGMAC_select_gmii(gmacdev); + else{ + synopGMAC_select_mii(gmacdev ); + if(gmacdev->Speed == SPEED100) + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacFESpeed100 ); + else + synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacFESpeed10 ); + } + +// synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacDisableCrs); +// synopGMAC_select_gmii(gmacdev); + + /*Frame Filter Configuration*/ + synopGMAC_frame_filter_enable(gmacdev); +// synopGMAC_frame_filter_disable(gmacdev); + + synopGMAC_set_pass_control(gmacdev,GmacPassControl0); + synopGMAC_broadcast_enable(gmacdev); + synopGMAC_src_addr_filter_disable(gmacdev); + synopGMAC_multicast_disable(gmacdev); + synopGMAC_dst_addr_filter_normal(gmacdev); + synopGMAC_multicast_hash_filter_disable(gmacdev); + + synopGMAC_promisc_disable(gmacdev); +// synopGMAC_promisc_enable(gmacdev); + synopGMAC_unicast_hash_filter_disable(gmacdev); + +//sw: loopback mode +// synopGMAC_loopback_on(gmacdev); + + /*Flow Control Configuration*/ + synopGMAC_unicast_pause_frame_detect_disable(gmacdev); + synopGMAC_rx_flow_control_disable(gmacdev); + synopGMAC_tx_flow_control_disable(gmacdev); + + /*To set PHY register to enable CRS on Transmit*/ + } + return 0; +} + + +/** + * Sets the Mac address in to GMAC register. + * This function sets the MAC address to the MAC register in question. + * @param[in] pointer to synopGMACdevice to populate mac dma and phy addresses. + * @param[in] Register offset for Mac address high + * @param[in] Register offset for Mac address low + * @param[in] buffer containing mac address to be programmed. + * \return 0 upon success. Error code upon failure. + */ +s32 synopGMAC_set_mac_addr(synopGMACdevice *gmacdev, u32 MacHigh, u32 MacLow, u8 *MacAddr) +{ + u32 data; + + data = (MacAddr[5] << 8) | MacAddr[4]; + synopGMACWriteReg(gmacdev->MacBase,MacHigh,data); + data = (MacAddr[3] << 24) | (MacAddr[2] << 16) | (MacAddr[1] << 8) | MacAddr[0] ; + synopGMACWriteReg(gmacdev->MacBase,MacLow,data); + + return 0; +} + + +/** + * Get the Mac address in to the address specified. + * The mac register contents are read and written to buffer passed. + * @param[in] pointer to synopGMACdevice to populate mac dma and phy addresses. + * @param[in] Register offset for Mac address high + * @param[in] Register offset for Mac address low + * @param[out] buffer containing the device mac address. + * \return 0 upon success. Error code upon failure. + */ +s32 synopGMAC_get_mac_addr(synopGMACdevice *gmacdev, u32 MacHigh, u32 MacLow, u8 *MacAddr) +{ + u32 data; + + data = synopGMACReadReg(gmacdev->MacBase,MacHigh); + MacAddr[5] = (data >> 8) & 0xff; + MacAddr[4] = (data) & 0xff; + + data = synopGMACReadReg(gmacdev->MacBase,MacLow); + MacAddr[3] = (data >> 24) & 0xff; + MacAddr[2] = (data >> 16) & 0xff; + MacAddr[1] = (data >> 8 ) & 0xff; + MacAddr[0] = (data ) & 0xff; + +// rt_kprintf("MacAddr = 0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\n",MacAddr[0],MacAddr[1],MacAddr[2],MacAddr[3],MacAddr[4],MacAddr[5]); + + return 0; +} + + +/** + * Attaches the synopGMAC device structure to the hardware. + * Device structure is populated with MAC/DMA and PHY base addresses. + * @param[in] pointer to synopGMACdevice to populate mac dma and phy addresses. + * @param[in] GMAC IP mac base address. + * @param[in] GMAC IP dma base address. + * @param[in] GMAC IP phy base address. + * \return 0 upon success. Error code upon failure. + * \note This is important function. No kernel api provided by Synopsys + */ + +s32 synopGMAC_attach (synopGMACdevice * gmacdev, u32 macBase, u32 dmaBase, u32 phyBase,u8 *mac_addr) +{ + /*Make sure the Device data strucure is cleared before we proceed further*/ + rt_memset((void *) gmacdev,0,sizeof(synopGMACdevice)); + /*Populate the mac and dma base addresses*/ + gmacdev->MacBase = macBase; + gmacdev->DmaBase = dmaBase; + gmacdev->PhyBase = phyBase; +// rt_kprintf("gmacdev->DmaBase = 0x%x\n", gmacdev->DmaBase); +// rt_kprintf("dmaBase = 0x%x\n", dmaBase); + { + int i,j; + u16 data; + for (i = phyBase,j=0;j<32;i=(i+1)&0x1f,j++) + { + synopGMAC_read_phy_reg(gmacdev->MacBase,i,2,&data); + if(data != 0 && data != 0xffff) break; + synopGMAC_read_phy_reg(gmacdev->MacBase,i,3,&data); + if(data != 0 && data != 0xffff) break; + } + + if(j==32) { + rt_kprintf("phy_detect: can't find PHY!\n"); + } + gmacdev->PhyBase = i; + } + +// synopGMAC_get_mac_addr(gmacdev, GmacAddr0High, GmacAddr0Low, mac_addr); + + /* Program/flash in the station/IP's Mac address */ + synopGMAC_set_mac_addr(gmacdev,GmacAddr0High,GmacAddr0Low, mac_addr); + + return 0; +} + + + + +/** + * Initialize the rx descriptors for ring or chain mode operation. + * - Status field is initialized to 0. + * - EndOfRing set for the last descriptor. + * - buffer1 and buffer2 set to 0 for ring mode of operation. (note) + * - data1 and data2 set to 0. (note) + * @param[in] pointer to DmaDesc structure. + * @param[in] whether end of ring + * \return void. + * \note Initialization of the buffer1, buffer2, data1,data2 and status are not done here. This only initializes whether one wants to use this descriptor + * in chain mode or ring mode. For chain mode of operation the buffer2 and data2 are programmed before calling this function. + */ +void synopGMAC_rx_desc_init_ring(DmaDesc *desc, bool last_ring_desc) +{ + desc->status = 0; + desc->length = last_ring_desc ? RxDescEndOfRing : 0; + desc->buffer1 = 0; + desc->buffer2 = 0; + desc->data1 = 0; + desc->data2 = 0; + desc->dummy1 = 0; + desc->dummy2 = 0; + + return; +} +void synopGMAC_rx_desc_recycle(DmaDesc *desc, bool last_ring_desc) +{ + desc->status = DescOwnByDma; + desc->length = last_ring_desc ? RxDescEndOfRing : 0; + //desc->buffer1 = 0; + //desc->buffer2 = 0; + //desc->data1 = 0; + //desc->data2 = 0; + desc->dummy1 = 0; + desc->dummy2 = 0; + + return; +} +/** + * Initialize the tx descriptors for ring or chain mode operation. + * - Status field is initialized to 0. + * - EndOfRing set for the last descriptor. + * - buffer1 and buffer2 set to 0 for ring mode of operation. (note) + * - data1 and data2 set to 0. (note) + * @param[in] pointer to DmaDesc structure. + * @param[in] whether end of ring + * \return void. + * \note Initialization of the buffer1, buffer2, data1,data2 and status are not done here. This only initializes whether one wants to use this descriptor + * in chain mode or ring mode. For chain mode of operation the buffer2 and data2 are programmed before calling this function. + */ +void synopGMAC_tx_desc_init_ring(DmaDesc *desc, bool last_ring_desc) +{ + #ifdef ENH_DESC + desc->status = last_ring_desc? TxDescEndOfRing : 0; + desc->length = 0; + #else + desc->length = last_ring_desc? TxDescEndOfRing : 0; + #endif +//sw + desc->status = 0; + + desc->buffer1 = 0; + desc->buffer2 = 0; + desc->data1 = 0; + desc->data2 = 0; + desc->dummy1 = 0; + desc->dummy2 = 0; + return; +} + + + +/** + * Initialize the rx descriptors for chain mode of operation. + * - Status field is initialized to 0. + * - EndOfRing set for the last descriptor. + * - buffer1 and buffer2 set to 0. + * - data1 and data2 set to 0. + * @param[in] pointer to DmaDesc structure. + * @param[in] whether end of ring + * \return void. + */ + +void synopGMAC_rx_desc_init_chain(DmaDesc * desc) +{ + desc->status = 0; + desc->length = RxDescChain; + desc->buffer1 = 0; + desc->data1 = 0; + return; +} +/** + * Initialize the rx descriptors for chain mode of operation. + * - Status field is initialized to 0. + * - EndOfRing set for the last descriptor. + * - buffer1 and buffer2 set to 0. + * - data1 and data2 set to 0. + * @param[in] pointer to DmaDesc structure. + * @param[in] whether end of ring + * \return void. + */ +void synopGMAC_tx_desc_init_chain(DmaDesc * desc) +{ + #ifdef ENH_DESC + desc->status = TxDescChain; + desc->length = 0; + #else + desc->length = TxDescChain; + #endif + desc->buffer1 = 0; + desc->data1 = 0; + return; +} + + +s32 synopGMAC_init_tx_rx_desc_queue(synopGMACdevice *gmacdev) +{ + s32 i; + for(i =0; i < gmacdev -> TxDescCount; i++){ + synopGMAC_tx_desc_init_ring(gmacdev->TxDesc + i, i == gmacdev->TxDescCount-1); + } + TR("At line %d\n",__LINE__); + for(i =0; i < gmacdev -> RxDescCount; i++){ + synopGMAC_rx_desc_init_ring(gmacdev->RxDesc + i, i == gmacdev->RxDescCount-1); + } + + gmacdev->TxNext = 0; + gmacdev->TxBusy = 0; + gmacdev->RxNext = 0; + gmacdev->RxBusy = 0; + + return -ESYNOPGMACNOERR; +} +/** + * Programs the DmaRxBaseAddress with the Rx descriptor base address. + * Rx Descriptor's base address is available in the gmacdev structure. This function progrms the + * Dma Rx Base address with the starting address of the descriptor ring or chain. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_init_rx_desc_base(synopGMACdevice *gmacdev) +{ + DEBUG_MES("gmacdev->RxDescDma = %08x\n", gmacdev->RxDescDma); + synopGMACWriteReg(gmacdev->DmaBase,DmaRxBaseAddr,(u32)gmacdev->RxDescDma ); + return; +} + +/** + * Programs the DmaTxBaseAddress with the Tx descriptor base address. + * Tx Descriptor's base address is available in the gmacdev structure. This function progrms the + * Dma Tx Base address with the starting address of the descriptor ring or chain. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_init_tx_desc_base(synopGMACdevice *gmacdev) +{ + synopGMACWriteReg(gmacdev->DmaBase,DmaTxBaseAddr,(u32)gmacdev->TxDescDma); + return; +} + + +/** + * Makes the Dma as owner for this descriptor. + * This function sets the own bit of status field of the DMA descriptor, + * indicating the DMA is the owner for this descriptor. + * @param[in] pointer to DmaDesc structure. + * \return returns void. + */ +void synopGMAC_set_owner_dma(DmaDesc *desc) +{ +desc->status |= DescOwnByDma; +} + +/** + * set tx descriptor to indicate SOF. + * This Descriptor contains the start of ethernet frame. + * @param[in] pointer to DmaDesc structure. + * \return returns void. + */ +void synopGMAC_set_desc_sof(DmaDesc *desc) +{ +#ifdef ENH_DESC +desc->status |= DescTxFirst;//ENH_DESC +#else +desc->length |= DescTxFirst; +#endif + +} + +/** + * set tx descriptor to indicate EOF. + * This descriptor contains the End of ethernet frame. + * @param[in] pointer to DmaDesc structure. + * \return returns void. + */ +void synopGMAC_set_desc_eof(DmaDesc *desc) +{ +#ifdef ENH_DESC +desc->status |= DescTxLast;//ENH_DESC +#else +desc->length |= DescTxLast; +#endif +} + + +/** + * checks whether this descriptor contains start of frame. + * This function is to check whether the descriptor's data buffer + * contains a fresh ethernet frame? + * @param[in] pointer to DmaDesc structure. + * \return returns true if SOF in current descriptor, else returns fail. + */ +bool synopGMAC_is_sof_in_rx_desc(DmaDesc *desc) +{ +return ((desc->status & DescRxFirst) == DescRxFirst); +} + +/** + * checks whether this descriptor contains end of frame. + * This function is to check whether the descriptor's data buffer + * contains end of ethernet frame? + * @param[in] pointer to DmaDesc structure. + * \return returns true if SOF in current descriptor, else returns fail. + */ +bool synopGMAC_is_eof_in_rx_desc(DmaDesc *desc) +{ +return ((desc->status & DescRxLast) == DescRxLast); +} + +/** + * checks whether destination address filter failed in the rx frame. + * @param[in] pointer to DmaDesc structure. + * \return returns true if Failed, false if not. + */ +bool synopGMAC_is_da_filter_failed(DmaDesc *desc) +{ +return ((desc->status & DescDAFilterFail) == DescDAFilterFail); +} + +/** + * checks whether source address filter failed in the rx frame. + * @param[in] pointer to DmaDesc structure. + * \return returns true if Failed, false if not. + */ +bool synopGMAC_is_sa_filter_failed(DmaDesc *desc) +{ +return ((desc->status & DescSAFilterFail) == DescSAFilterFail); +} + +/** + * Checks whether the descriptor is owned by DMA. + * If descriptor is owned by DMA then the OWN bit is set to 1. This API is same for both ring and chain mode. + * @param[in] pointer to DmaDesc structure. + * \return returns true if Dma owns descriptor and false if not. + */ +bool synopGMAC_is_desc_owned_by_dma(DmaDesc *desc) +{ +return ((desc->status & DescOwnByDma) == DescOwnByDma ); +} + +/** + * returns the byte length of received frame including CRC. + * This returns the no of bytes received in the received ethernet frame including CRC(FCS). + * @param[in] pointer to DmaDesc structure. + * \return returns the length of received frame lengths in bytes. + */ +u32 synopGMAC_get_rx_desc_frame_length(u32 status) +{ + return ((status & DescFrameLengthMask) >> DescFrameLengthShift); +} + +/** + * Checks whether the descriptor is valid + * if no errors such as CRC/Receive Error/Watchdog Timeout/Late collision/Giant Frame/Overflow/Descriptor + * error the descritpor is said to be a valid descriptor. + * @param[in] pointer to DmaDesc structure. + * \return True if desc valid. false if error. + */ +bool synopGMAC_is_desc_valid(u32 status) +{ + return ((status & DescError) == 0); +} + +/** + * Checks whether the descriptor is empty. + * If the buffer1 and buffer2 lengths are zero in ring mode descriptor is empty. + * In chain mode buffer2 length is 0 but buffer2 itself contains the next descriptor address. + * @param[in] pointer to DmaDesc structure. + * \return returns true if descriptor is empty, false if not empty. + */ +bool synopGMAC_is_desc_empty(DmaDesc *desc) +{ + //if both the buffer1 length and buffer2 length are zero desc is empty + return(((desc->length & DescSize1Mask) == 0) && ((desc->length & DescSize2Mask) == 0) ); +} + + +/** + * Checks whether the rx descriptor is valid. + * if rx descripor is not in error and complete frame is available in the same descriptor + * @param[in] pointer to DmaDesc structure. + * \return returns true if no error and first and last desc bits are set, otherwise it returns false. + */ +bool synopGMAC_is_rx_desc_valid(u32 status) +{ + return ((status & DescError) == 0) && ((status & DescRxFirst) == DescRxFirst) && ((status & DescRxLast) == DescRxLast); +} + +/** + * Checks whether the tx is aborted due to collisions. + * @param[in] pointer to DmaDesc structure. + * \return returns true if collisions, else returns false. + */ +bool synopGMAC_is_tx_aborted(u32 status) +{ + return (((status & DescTxLateCollision) == DescTxLateCollision) | ((status & DescTxExcCollisions) == DescTxExcCollisions)); + +} + +/** + * Checks whether the tx carrier error. + * @param[in] pointer to DmaDesc structure. + * \return returns true if carrier error occured, else returns falser. + */ +bool synopGMAC_is_tx_carrier_error(u32 status) +{ + return (((status & DescTxLostCarrier) == DescTxLostCarrier) | ((status & DescTxNoCarrier) == DescTxNoCarrier)); +} + + +/** + * Gives the transmission collision count. + * returns the transmission collision count indicating number of collisions occured before the frame was transmitted. + * Make sure to check excessive collision didnot happen to ensure the count is valid. + * @param[in] pointer to DmaDesc structure. + * \return returns the count value of collision. + */ +u32 synopGMAC_get_tx_collision_count(u32 status) +{ + return ((status & DescTxCollMask) >> DescTxCollShift); +} +u32 synopGMAC_is_exc_tx_collisions(u32 status) +{ + return ((status & DescTxExcCollisions) == DescTxExcCollisions); +} + + +/** + * Check for damaged frame due to overflow or collision. + * Retruns true if rx frame was damaged due to buffer overflow in MTL or late collision in half duplex mode. + * @param[in] pointer to DmaDesc structure. + * \return returns true if error else returns false. + */ +bool synopGMAC_is_rx_frame_damaged(u32 status) +{ +//bool synopGMAC_dma_rx_collisions(u32 status) + return (((status & DescRxDamaged) == DescRxDamaged) | ((status & DescRxCollision) == DescRxCollision)); +} + +/** + * Check for damaged frame due to collision. + * Retruns true if rx frame was damaged due to late collision in half duplex mode. + * @param[in] pointer to DmaDesc structure. + * \return returns true if error else returns false. + */ +bool synopGMAC_is_rx_frame_collision(u32 status) +{ +//bool synopGMAC_dma_rx_collisions(u32 status) + return ((status & DescRxCollision) == DescRxCollision); +} + +/** + * Check for receive CRC error. + * Retruns true if rx frame CRC error occured. + * @param[in] pointer to DmaDesc structure. + * \return returns true if error else returns false. + */ +bool synopGMAC_is_rx_crc(u32 status) +{ +//u32 synopGMAC_dma_rx_crc(u32 status) + return ((status & DescRxCrc) == DescRxCrc); +} + +/** + * Indicates rx frame has non integer multiple of bytes. (odd nibbles). + * Retruns true if dribbling error in rx frame. + * @param[in] pointer to DmaDesc structure. + * \return returns true if error else returns false. + */ +bool synopGMAC_is_frame_dribbling_errors(u32 status) +{ +//u32 synopGMAC_dma_rx_frame_errors(u32 status) + return ((status & DescRxDribbling) == DescRxDribbling); +} + +/** + * Indicates error in rx frame length. + * Retruns true if received frame length doesnot match with the length field + * @param[in] pointer to DmaDesc structure. + * \return returns true if error else returns false. + */ +bool synopGMAC_is_rx_frame_length_errors(u32 status) +{ +//u32 synopGMAC_dma_rx_length_errors(u32 status) + return((status & DescRxLengthError) == DescRxLengthError); +} + +/** + * Checks whether this rx descriptor is last rx descriptor. + * This returns true if it is last descriptor either in ring mode or in chain mode. + * @param[in] pointer to devic structure. + * @param[in] pointer to DmaDesc structure. + * \return returns true if it is last descriptor, false if not. + * \note This function should not be called before initializing the descriptor using synopGMAC_desc_init(). + */ +bool synopGMAC_is_last_rx_desc(synopGMACdevice * gmacdev,DmaDesc *desc) +{ +//bool synopGMAC_is_last_desc(DmaDesc *desc) +return (((desc->length & RxDescEndOfRing) == RxDescEndOfRing) || ((u32)gmacdev->RxDesc == desc->data2)); +} + +/** + * Checks whether this tx descriptor is last tx descriptor. + * This returns true if it is last descriptor either in ring mode or in chain mode. + * @param[in] pointer to devic structure. + * @param[in] pointer to DmaDesc structure. + * \return returns true if it is last descriptor, false if not. + * \note This function should not be called before initializing the descriptor using synopGMAC_desc_init(). + */ +bool synopGMAC_is_last_tx_desc(synopGMACdevice * gmacdev,DmaDesc *desc) +{ +//bool synopGMAC_is_last_desc(DmaDesc *desc) +#ifdef ENH_DESC + return (((desc->status & TxDescEndOfRing) == TxDescEndOfRing) || ((u32)gmacdev->TxDesc == desc->data2)); +#else + return (((desc->length & TxDescEndOfRing) == TxDescEndOfRing) || ((u32)gmacdev->TxDesc == desc->data2)); +#endif +} + +/** + * Checks whether this rx descriptor is in chain mode. + * This returns true if it is this descriptor is in chain mode. + * @param[in] pointer to DmaDesc structure. + * \return returns true if chain mode is set, false if not. + */ +bool synopGMAC_is_rx_desc_chained(DmaDesc * desc) +{ + return((desc->length & RxDescChain) == RxDescChain); +} + +/** + * Checks whether this tx descriptor is in chain mode. + * This returns true if it is this descriptor is in chain mode. + * @param[in] pointer to DmaDesc structure. + * \return returns true if chain mode is set, false if not. + */ +bool synopGMAC_is_tx_desc_chained(DmaDesc * desc) +{ +#ifdef ENH_DESC + return((desc->status & TxDescChain) == TxDescChain); +#else + return((desc->length & TxDescChain) == TxDescChain); +#endif +} + +/** + * Driver Api to get the descriptor field information. + * This returns the status, dma-able address of buffer1, the length of buffer1, virtual address of buffer1 + * dma-able address of buffer2, length of buffer2, virtural adddress of buffer2. + * @param[in] pointer to DmaDesc structure. + * @param[out] pointer to status field fo descriptor. + * @param[out] dma-able address of buffer1. + * @param[out] length of buffer1. + * @param[out] virtual address of buffer1. + * @param[out] dma-able address of buffer2. + * @param[out] length of buffer2. + * @param[out] virtual address of buffer2. + * \return returns void. + */ +void synopGMAC_get_desc_data(DmaDesc * desc, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Buffer2, u32 * Length2, u32 * Data2) +{ + + if(Status != 0) + *Status = desc->status; + + if(Buffer1 != 0) + *Buffer1 = desc->buffer1; + if(Length1 != 0) + *Length1 = (desc->length & DescSize1Mask) >> DescSize1Shift; + if(Data1 != 0) + *Data1 = desc->data1; + + if(Buffer2 != 0) + *Buffer2 = desc->buffer2; + if(Length2 != 0) + *Length2 = (desc->length & DescSize2Mask) >> DescSize2Shift; + if(Data1 != 0) + *Data2 = desc->data2; + + return; + +} + +#ifdef ENH_DESC_8W +/** + * This function is defined two times. Once when the code is compiled for ENHANCED DESCRIPTOR SUPPORT and Once for Normal descriptor + * Get the index and address of Tx desc. + * This api is same for both ring mode and chain mode. + * This function tracks the tx descriptor the DMA just closed after the transmission of data from this descriptor is + * over. This returns the descriptor fields to the caller. + * @param[in] pointer to synopGMACdevice. + * @param[out] status field of the descriptor. + * @param[out] Dma-able buffer1 pointer. + * @param[out] length of buffer1 (Max is 2048). + * @param[out] virtual pointer for buffer1. + * @param[out] Dma-able buffer2 pointer. + * @param[out] length of buffer2 (Max is 2048). + * @param[out] virtual pointer for buffer2. + * @param[out] u32 data indicating whether the descriptor is in ring mode or chain mode. + * \return returns present tx descriptor index on success. Negative value if error. + */ +s32 synopGMAC_get_tx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Buffer2, u32 * Length2, u32 * Data2, + u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_Low) +{ + u32 txover = gmacdev->TxBusy; + DmaDesc * txdesc = gmacdev->TxBusyDesc; + + if(synopGMAC_is_desc_owned_by_dma(txdesc)) + return -1; + if(synopGMAC_is_desc_empty(txdesc)) + return -1; + + (gmacdev->BusyTxDesc)--; //busy tx descriptor is reduced by one as it will be handed over to Processor now + + if(Status != 0) + *Status = txdesc->status; + + if(Ext_Status != 0) + *Ext_Status = txdesc->extstatus; + if(Time_Stamp_High != 0) + *Time_Stamp_High = txdesc->timestamphigh; + if(Time_Stamp_Low != 0) + *Time_Stamp_High = txdesc->timestamplow; + + if(Buffer1 != 0) + *Buffer1 = txdesc->buffer1; + if(Length1 != 0) + *Length1 = (txdesc->length & DescSize1Mask) >> DescSize1Shift; + if(Data1 != 0) + *Data1 = txdesc->data1; + + if(Buffer2 != 0) + *Buffer2 = txdesc->buffer2; + if(Length2 != 0) + *Length2 = (txdesc->length & DescSize2Mask) >> DescSize2Shift; + if(Data1 != 0) + *Data2 = txdesc->data2; + + gmacdev->TxBusy = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? 0 : txover + 1; + + if(synopGMAC_is_tx_desc_chained(txdesc)){ + gmacdev->TxBusyDesc = (DmaDesc *)txdesc->data2; + synopGMAC_tx_desc_init_chain(txdesc); + } + else{ + gmacdev->TxBusyDesc = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? gmacdev->TxDesc : (txdesc + 1); + synopGMAC_tx_desc_init_ring(txdesc, synopGMAC_is_last_tx_desc(gmacdev,txdesc)); + } + TR("%02d %08x %08x %08x %08x %08x %08x %08x\n",txover,(u32)txdesc,txdesc->status,txdesc->length,txdesc->buffer1,txdesc->buffer2,txdesc->data1,txdesc->data2); + + return txover; +} +#else + +/** + * Get the index and address of Tx desc. + * This api is same for both ring mode and chain mode. + * This function tracks the tx descriptor the DMA just closed after the transmission of data from this descriptor is + * over. This returns the descriptor fields to the caller. + * @param[in] pointer to synopGMACdevice. + * @param[out] status field of the descriptor. + * @param[out] Dma-able buffer1 pointer. + * @param[out] length of buffer1 (Max is 2048). + * @param[out] virtual pointer for buffer1. + * @param[out] Dma-able buffer2 pointer. + * @param[out] length of buffer2 (Max is 2048). + * @param[out] virtual pointer for buffer2. + * @param[out] u32 data indicating whether the descriptor is in ring mode or chain mode. + * \return returns present tx descriptor index on success. Negative value if error. + */ +s32 synopGMAC_get_tx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Buffer2, u32 * Length2, u32 * Data2 ) +{ + u32 txover = gmacdev->TxBusy; + DmaDesc * txdesc = gmacdev->TxBusyDesc; + int i; + +//sw: dbg + + + //pci_sync_cache(0, (vm_offset_t)txdesc, 64, SYNC_R); + //pci_sync_cache(0, (vm_offset_t)txdesc, 64, SYNC_W); +#if SYNOP_TX_DEBUG + printf("Cache sync before get a used tx dma desc!\n"); + printf("\n==%02d %08x %08x %08x %08x %08x %08x %08x\n",txover,(u32)txdesc,txdesc->status,txdesc->length,txdesc->buffer1,txdesc->buffer2,txdesc->data1,txdesc->data2); +#endif + if(synopGMAC_is_desc_owned_by_dma(txdesc)) + { + return -1; + } +// gmacdev->TxBusy = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? 0 : txover + 1; +// gmacdev->TxBusyDesc = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? gmacdev->TxDesc : (txdesc + 1); + if(synopGMAC_is_desc_empty(txdesc)) + { + return -1; + } + (gmacdev->BusyTxDesc)--; //busy tx descriptor is reduced by one as it will be handed over to Processor now + + if(Status != 0) + *Status = txdesc->status; + + if(Buffer1 != 0) + *Buffer1 = txdesc->buffer1; + if(Length1 != 0) + *Length1 = (txdesc->length & DescSize1Mask) >> DescSize1Shift; + if(Data1 != 0) + *Data1 = txdesc->data1; + + if(Buffer2 != 0) + *Buffer2 = txdesc->buffer2; + if(Length2 != 0) + *Length2 = (txdesc->length & DescSize2Mask) >> DescSize2Shift; + if(Data1 != 0) + *Data2 = txdesc->data2; + + gmacdev->TxBusy = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? 0 : txover + 1; + + if(synopGMAC_is_tx_desc_chained(txdesc)){ + gmacdev->TxBusyDesc = (DmaDesc *)txdesc->data2; + synopGMAC_tx_desc_init_chain(txdesc); + } + else{ + gmacdev->TxBusyDesc = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? gmacdev->TxDesc : (txdesc + 1); + synopGMAC_tx_desc_init_ring(txdesc, synopGMAC_is_last_tx_desc(gmacdev,txdesc)); + } + //printf("%02d %08x %08x %08x %08x %08x %08x %08x\n",txover,(u32)txdesc,txdesc->status,txdesc->length,txdesc->buffer1,txdesc->buffer2,txdesc->data1,txdesc->data2); + //pci_sync_cache(0, (vm_offset_t)txdesc, 64, SYNC_W); +#if SYNOP_TX_DEBUG + printf("Cache sync after re-init a tx dma desc!\n"); +#endif + + return txover; +} + +#endif +/** + * Populate the tx desc structure with the buffer address. + * Once the driver has a packet ready to be transmitted, this function is called with the + * valid dma-able buffer addresses and their lengths. This function populates the descriptor + * and make the DMA the owner for the descriptor. This function also controls whetther Checksum + * offloading to be done in hardware or not. + * This api is same for both ring mode and chain mode. + * @param[in] pointer to synopGMACdevice. + * @param[in] Dma-able buffer1 pointer. + * @param[in] length of buffer1 (Max is 2048). + * @param[in] virtual pointer for buffer1. + * @param[in] Dma-able buffer2 pointer. + * @param[in] length of buffer2 (Max is 2048). + * @param[in] virtual pointer for buffer2. + * @param[in] u32 data indicating whether the descriptor is in ring mode or chain mode. + * @param[in] u32 indicating whether the checksum offloading in HW/SW. + * \return returns present tx descriptor index on success. Negative value if error. + */ +u32 len; +s32 synopGMAC_set_tx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u32 Data1, u32 Buffer2, u32 Length2, u32 Data2,u32 offload_needed,u32 * index, DmaDesc * Dpr) +{ + u32 txnext = gmacdev->TxNext; + DmaDesc * txdesc = gmacdev->TxNextDesc; + + *index = txnext; + Dpr = txdesc; + + if(!synopGMAC_is_desc_empty(txdesc)) + { + TR("set tx qptr: desc empty!\n"); + return -1; + } + + (gmacdev->BusyTxDesc)++; //busy tx descriptor is reduced by one as it will be handed over to Processor now + + if(synopGMAC_is_tx_desc_chained(txdesc)){ + txdesc->length |= ((Length1 <status |= (DescTxFirst | DescTxLast | DescTxIntEnable); //ENH_DESC + #else + txdesc->length |= (DescTxFirst | DescTxLast | DescTxIntEnable); //Its always assumed that complete data will fit in to one descriptor + #endif + + txdesc->buffer1 = Buffer1; + txdesc->data1 = Data1; + + if(offload_needed){ + /* + Make sure that the OS you are running supports the IP and TCP checkusm offloaidng, + before calling any of the functions given below. + */ + synopGMAC_tx_checksum_offload_ipv4hdr(gmacdev, txdesc); + synopGMAC_tx_checksum_offload_tcponly(gmacdev, txdesc); +// synopGMAC_tx_checksum_offload_tcp_pseudo(gmacdev, txdesc); + } + #ifdef ENH_DESC + txdesc->status |= DescOwnByDma;//ENH_DESC + #else + txdesc->status = DescOwnByDma; + #endif + + gmacdev->TxNext = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? 0 : txnext + 1; + gmacdev->TxNextDesc = (DmaDesc *)txdesc->data2; + } + else{ +// printf("synopGMAC_set_tx_qptr:in ring mode\n"); + txdesc->length |= (((Length1 <status |= (DescTxFirst | DescTxLast | DescTxIntEnable); //ENH_DESC + #else + txdesc->length |= (DescTxFirst | DescTxLast | DescTxIntEnable); //Its always assumed that complete data will fit in to one descriptor + #endif + + txdesc->buffer1 = Buffer1; + txdesc->data1 = Data1; + + txdesc->buffer2 = Buffer2; + txdesc->data2 = Data2; + + if(offload_needed){ + /* + Make sure that the OS you are running supports the IP and TCP checkusm offloaidng, + before calling any of the functions given below. + */ +//sw: i am not sure about the checksum.so i omit it in the outside + synopGMAC_tx_checksum_offload_ipv4hdr(gmacdev, txdesc); + synopGMAC_tx_checksum_offload_tcponly(gmacdev, txdesc); +// synopGMAC_tx_checksum_offload_tcp_pseudo(gmacdev, txdesc); + } + #ifdef ENH_DESC + txdesc->status |= DescOwnByDma;//ENH_DESC + #else +// printf("synopGMAC_set_tx_qptr:give the tx descroptor to dma\n"); + txdesc->status = DescOwnByDma; + #endif + + gmacdev->TxNext = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? 0 : txnext + 1; + gmacdev->TxNextDesc = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? gmacdev->TxDesc : (txdesc + 1); + } + + +#if SYNOP_TX_DEBUG + printf("%02d %08x %08x %08x %08x %08x %08x %08x\n",txnext,(u32)txdesc,txdesc->status,txdesc->length,txdesc->buffer1,txdesc->buffer2,txdesc->data1,txdesc->data2); +#endif + //pci_sync_cache(0, (vm_offset_t)txdesc, 64, SYNC_W); +#if SYNOP_TX_DEBUG + printf("Cache sync to set a tx desc!\n"); +#endif + //pci_sync_cache(0, (vm_offset_t)(txdesc->data1), 32, SYNC_W); +#if SYNOP_TX_DEBUG + //printf("Cache sync for data in the buf of the tx desc!\n"); +#endif + return txnext; +} +#ifdef ENH_DESC_8W +/** + * Prepares the descriptor to receive packets. + * The descriptor is allocated with the valid buffer addresses (sk_buff address) and the length fields + * and handed over to DMA by setting the ownership. After successful return from this function the + * descriptor is added to the receive descriptor pool/queue. + * This api is same for both ring mode and chain mode. + * @param[in] pointer to synopGMACdevice. + * @param[in] Dma-able buffer1 pointer. + * @param[in] length of buffer1 (Max is 2048). + * @param[in] Dma-able buffer2 pointer. + * @param[in] length of buffer2 (Max is 2048). + * @param[in] u32 data indicating whether the descriptor is in ring mode or chain mode. + * \return returns present rx descriptor index on success. Negative value if error. + */ +// dma_addr RX_BUF_SIZE skb +s32 synopGMAC_set_rx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u32 Data1, u32 Buffer2, u32 Length2, u32 Data2) +{ + u32 rxnext = gmacdev->RxNext; + DmaDesc * rxdesc = gmacdev->RxNextDesc; + + if(!synopGMAC_is_desc_empty(rxdesc)) + return -1; + + if(synopGMAC_is_rx_desc_chained(rxdesc)){ + rxdesc->length |= ((Length1 <buffer1 = Buffer1; + rxdesc->data1 = Data1; + + rxdesc->extstatus = 0; + rxdesc->reserved1 = 0; + rxdesc->timestamplow = 0; + rxdesc->timestamphigh = 0; + + if((rxnext % MODULO_INTERRUPT) !=0) + rxdesc->length |= RxDisIntCompl; + + rxdesc->status = DescOwnByDma; + + gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1; + gmacdev->RxNextDesc = (DmaDesc *)rxdesc->data2; + } + else{ + rxdesc->length |= (((Length1 <buffer1 = Buffer1; + rxdesc->data1 = Data1; + + rxdesc->extstatus = 0; + rxdesc->reserved1 = 0; + rxdesc->timestamplow = 0; + rxdesc->timestamphigh = 0; + + rxdesc->buffer2 = Buffer2; + rxdesc->data2 = Data2; + + if((rxnext % MODULO_INTERRUPT) !=0) + rxdesc->length |= RxDisIntCompl; + + rxdesc->status = DescOwnByDma; + gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1; + gmacdev->RxNextDesc = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? gmacdev->RxDesc : (rxdesc + 1); + } +#if SYNOP_RX_DEBUG + TR("%02d %08x %08x %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2,rxdesc->dummy1,rxdesc->dummy2); +#endif + + (gmacdev->BusyRxDesc)++; //One descriptor will be given to Hardware. So busy count incremented by one + //pci_sync_cache(0, (vm_offset_t)rxdesc,64, SYNC_W); + return rxnext; +} + +#else +/** + * Prepares the descriptor to receive packets. + * The descriptor is allocated with the valid buffer addresses (sk_buff address) and the length fields + * and handed over to DMA by setting the ownership. After successful return from this function the + * descriptor is added to the receive descriptor pool/queue. + * This api is same for both ring mode and chain mode. + * @param[in] pointer to synopGMACdevice. + * @param[in] Dma-able buffer1 pointer. + * @param[in] length of buffer1 (Max is 2048). + * @param[in] Dma-able buffer2 pointer. + * @param[in] length of buffer2 (Max is 2048). + * @param[in] u32 data indicating whether the descriptor is in ring mode or chain mode. + * \return returns present rx descriptor index on success. Negative value if error. + */ +s32 synopGMAC_set_rx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u32 Data1, u32 Buffer2, u32 Length2, u32 Data2) +{ + u32 rxnext = gmacdev->RxNext; + DmaDesc * rxdesc = gmacdev->RxNextDesc; + + if(!synopGMAC_is_desc_empty(rxdesc)) + return -1; + + if(synopGMAC_is_rx_desc_chained(rxdesc)){ + rxdesc->length |= ((Length1 <buffer1 = Buffer1; + rxdesc->data1 = Data1; + + if((rxnext % MODULO_INTERRUPT) !=0) + rxdesc->length |= RxDisIntCompl; + + rxdesc->status = DescOwnByDma; + + gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1; + gmacdev->RxNextDesc = (DmaDesc *)rxdesc->data2; + } + else{ + rxdesc->length |= (((Length1 <buffer1 = Buffer1; + rxdesc->data1 = Data1; + + rxdesc->buffer2 = Buffer2; + rxdesc->data2 = Data2; + + if((rxnext % MODULO_INTERRUPT) !=0) + rxdesc->length |= RxDisIntCompl; + + rxdesc->status = DescOwnByDma; + + gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1; + gmacdev->RxNextDesc = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? gmacdev->RxDesc : (rxdesc + 1); + } +#if SYNOP_RX_DEBUG + TR("%02d %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2); +#endif + (gmacdev->BusyRxDesc)++; //One descriptor will be given to Hardware. So busy count incremented by one + + return rxnext; +} + +s32 synopGMAC_set_rx_qptr_init(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u32 Data1, u32 Buffer2, u32 Length2, u32 Data2) +{ + u32 rxnext = gmacdev->RxNext; + DmaDesc * rxdesc = gmacdev->RxNextDesc; + +/* sw + if(synopGMAC_is_desc_owned_by_dma(rxdesc)) + return -1; +*/ + + if(!synopGMAC_is_desc_empty(rxdesc)) + return -1; + + if(synopGMAC_is_rx_desc_chained(rxdesc)){ + rxdesc->length |= ((Length1 <buffer1 = Buffer1; + rxdesc->data1 = Data1; + + if((rxnext % MODULO_INTERRUPT) !=0) + rxdesc->length |= RxDisIntCompl; + + rxdesc->status = DescOwnByDma; + rxdesc->status = 0; + + gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1; + gmacdev->RxNextDesc = (DmaDesc *)rxdesc->data2; + } + else{ + rxdesc->length |= (((Length1 <buffer1 = Buffer1; + rxdesc->data1 = Data1; + + rxdesc->buffer2 = Buffer2; + rxdesc->data2 = Data2; + + if((rxnext % MODULO_INTERRUPT) !=0) + rxdesc->length |= RxDisIntCompl; + + rxdesc->status = DescOwnByDma; + rxdesc->status = 0; + + gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1; + gmacdev->RxNextDesc = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? gmacdev->RxDesc : (rxdesc + 1); + } + TR("%02d %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2); + (gmacdev->BusyRxDesc)++; //One descriptor will be given to Hardware. So busy count incremented by one + return rxnext; +} +#endif +#ifdef ENH_DESC_8W +/** + * This function is defined two times. Once when the code is compiled for ENHANCED DESCRIPTOR SUPPORT and Once for Normal descriptor + * Get back the descriptor from DMA after data has been received. + * When the DMA indicates that the data is received (interrupt is generated), this function should be + * called to get the descriptor and hence the data buffers received. With successful return from this + * function caller gets the descriptor fields for processing. check the parameters to understand the + * fields returned.` + * @param[in] pointer to synopGMACdevice. + * @param[out] pointer to hold the status of DMA. + * @param[out] Dma-able buffer1 pointer. + * @param[out] pointer to hold length of buffer1 (Max is 2048). + * @param[out] virtual pointer for buffer1. + * @param[out] Dma-able buffer2 pointer. + * @param[out] pointer to hold length of buffer2 (Max is 2048). + * @param[out] virtual pointer for buffer2. + * \return returns present rx descriptor index on success. Negative value if error. + */ +s32 synopGMAC_get_rx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Buffer2, u32 * Length2, u32 * Data2, + u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_Low) +{ + u32 rxnext = gmacdev->RxBusy; // index of descriptor the DMA just completed. May be useful when data + //is spread over multiple buffers/descriptors + DmaDesc * rxdesc = gmacdev->RxBusyDesc; + if(synopGMAC_is_desc_owned_by_dma(rxdesc)) + return -1; + if(synopGMAC_is_desc_empty(rxdesc)) + return -1; + + + if(Status != 0) + *Status = rxdesc->status;// send the status of this descriptor + + if(Ext_Status != 0) + *Ext_Status = rxdesc->extstatus; + if(Time_Stamp_High != 0) + *Time_Stamp_High = rxdesc->timestamphigh; + if(Time_Stamp_Low != 0) + *Time_Stamp_Low = rxdesc->timestamplow; + + if(Length1 != 0) + *Length1 = (rxdesc->length & DescSize1Mask) >> DescSize1Shift; + if(Buffer1 != 0) + *Buffer1 = rxdesc->buffer1; + if(Data1 != 0) + *Data1 = rxdesc->data1; + + if(Length2 != 0) + *Length2 = (rxdesc->length & DescSize2Mask) >> DescSize2Shift; + if(Buffer2 != 0) + *Buffer2 = rxdesc->buffer2; + if(Data1 != 0) + *Data2 = rxdesc->data2; + + gmacdev->RxBusy = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1; + + if(synopGMAC_is_rx_desc_chained(rxdesc)){ + gmacdev->RxBusyDesc = (DmaDesc *)rxdesc->data2; + synopGMAC_rx_desc_init_chain(rxdesc); + //synopGMAC_desc_init_chain(rxdesc, synopGMAC_is_last_rx_desc(gmacdev,rxdesc),0,0); + } + else{ + gmacdev->RxBusyDesc = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? gmacdev->RxDesc : (rxdesc + 1); + synopGMAC_rx_desc_init_ring(rxdesc, synopGMAC_is_last_rx_desc(gmacdev,rxdesc)); + } + TR("%02d %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2); + (gmacdev->BusyRxDesc)--; //busy tx descriptor is reduced by one as it will be handed over to Processor now + return(rxnext); + +} +#else + +/** + * Get back the descriptor from DMA after data has been received. + * When the DMA indicates that the data is received (interrupt is generated), this function should be + * called to get the descriptor and hence the data buffers received. With successful return from this + * function caller gets the descriptor fields for processing. check the parameters to understand the + * fields returned.` + * @param[in] pointer to synopGMACdevice. + * @param[out] pointer to hold the status of DMA. + * @param[out] Dma-able buffer1 pointer. + * @param[out] pointer to hold length of buffer1 (Max is 2048). + * @param[out] virtual pointer for buffer1. + * @param[out] Dma-able buffer2 pointer. + * @param[out] pointer to hold length of buffer2 (Max is 2048). + * @param[out] virtual pointer for buffer2. + * \return returns present rx descriptor index on success. Negative value if error. + */ +s32 synopGMAC_get_rx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Buffer2, u32 * Length2, u32 * Data2) +{ + u32 rxnext = gmacdev->RxBusy; // index of descriptor the DMA just completed. May be useful when data + //is spread over multiple buffers/descriptors + DmaDesc * rxdesc = gmacdev->RxBusyDesc; + + u32 len; + if(synopGMAC_is_desc_owned_by_dma(rxdesc)) + { + DEBUG_MES("synopGMAC_get_rx_qptr:DMA descriptor is owned by GMAC!\n"); + return -1; + } + + if(synopGMAC_is_desc_empty(rxdesc)) + { + DEBUG_MES("synopGMAC_get_rx_qptr:rx desc is empty!\n"); + return -1; + } + + if(Status != 0) + *Status = rxdesc->status;// send the status of this descriptor + + if(Length1 != 0) + *Length1 = (rxdesc->length & DescSize1Mask) >> DescSize1Shift; + if(Buffer1 != 0) + *Buffer1 = rxdesc->buffer1; + if(Data1 != 0) + *Data1 = rxdesc->data1; + if(Length2 != 0) + *Length2 = (rxdesc->length & DescSize2Mask) >> DescSize2Shift; + if(Buffer2 != 0) + *Buffer2 = rxdesc->buffer2; + if(Data1 != 0) + *Data2 = rxdesc->data2; + + len = synopGMAC_get_rx_desc_frame_length(*Status); + DEBUG_MES("Cache sync for data buffer in rx dma desc: length = 0x%x\n",len); + gmacdev->RxBusy = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1; + if(synopGMAC_is_rx_desc_chained(rxdesc)){ + gmacdev->RxBusyDesc = (DmaDesc *)rxdesc->data2; + synopGMAC_rx_desc_init_chain(rxdesc); + } + else{ + gmacdev->RxBusyDesc = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? gmacdev->RxDesc : (rxdesc + 1); +//sw: raw data +#if SYNOP_RX_DEBUG + DEBUG_MES("%02d %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2); +#endif + synopGMAC_rx_desc_init_ring(rxdesc, synopGMAC_is_last_rx_desc(gmacdev,rxdesc)); + } +#if SYNOP_RX_DEBUG + DEBUG_MES("%02d %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2); +#endif + + (gmacdev->BusyRxDesc)--; //This returns one descriptor to processor. So busy count will be decremented by one + return(rxnext); + +} + +#endif + +/** + * Clears all the pending interrupts. + * If the Dma status register is read then all the interrupts gets cleared + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_clear_interrupt(synopGMACdevice *gmacdev) +{ + u32 data; + data = synopGMACReadReg(gmacdev->DmaBase, DmaStatus); + TR("DMA status reg = 0x%x before cleared!\n",data); + synopGMACWriteReg(gmacdev->DmaBase, DmaStatus ,data); + // plat_delay(DEFAULT_LOOP_VARIABLE); +// data = synopGMACReadReg(gmacdev->DmaBase, DmaStatus); + TR("DMA status reg = 0x%x after cleared!\n",data); +} + +/** + * Returns the all unmasked interrupt status after reading the DmaStatus register. + * @param[in] pointer to synopGMACdevice. + * \return 0 upon success. Error code upon failure. + */ +u32 synopGMAC_get_interrupt_type(synopGMACdevice *gmacdev) +{ + u32 data; + u32 interrupts = 0; + data = synopGMACReadReg(gmacdev->DmaBase, DmaStatus); + + //data = data & ~0x84; //sw: some bits shoud not be cleaned + synopGMACWriteReg(gmacdev->DmaBase, DmaStatus ,data); //manju: I think this is the appropriate location to clear the interrupts + plat_delay(DEFAULT_LOOP_VARIABLE); + if(data & DmaIntErrorMask) interrupts |= synopGMACDmaError; + if(data & DmaIntRxNormMask) interrupts |= synopGMACDmaRxNormal; + if(data & DmaIntRxAbnMask) interrupts |= synopGMACDmaRxAbnormal; + if(data & DmaIntRxStoppedMask) interrupts |= synopGMACDmaRxStopped; + if(data & DmaIntTxNormMask) interrupts |= synopGMACDmaTxNormal; + if(data & DmaIntTxAbnMask) interrupts |= synopGMACDmaTxAbnormal; + if(data & DmaIntTxStoppedMask) interrupts |= synopGMACDmaTxStopped; + + return interrupts; +} + +/** + * Returns the interrupt mask. + * @param[in] pointer to synopGMACdevice. + * \return 0 upon success. Error code upon failure. + */ +#if UNUSED +u32 synopGMAC_get_interrupt_mask(synopGMACdevice *gmacdev) +{ + return(synopGMACReadReg(gmacdev->DmaBase, DmaInterrupt)); +} +#endif + +/** + * Enable all the interrupts. + * Enables the DMA interrupt as specified by the bit mask. + * @param[in] pointer to synopGMACdevice. + * @param[in] bit mask of interrupts to be enabled. + * \return returns void. + */ +#if UNUSED +void synopGMAC_enable_interrupt(synopGMACdevice *gmacdev, u32 interrupts) +{ + synopGMACWriteReg(gmacdev->DmaBase, DmaInterrupt, interrupts); + return; +} +#endif + + +/** + * Disable all the interrupts. + * Disables all DMA interrupts. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + * \note This function disabled all the interrupts, if you want to disable a particular interrupt then + * use synopGMAC_disable_interrupt(). + */ +void synopGMAC_disable_interrupt_all(synopGMACdevice *gmacdev) +{ +// rt_kprintf("dmabase = 0x%x\n",gmacdev->DmaBase); + synopGMACWriteReg(gmacdev->DmaBase, DmaInterrupt, DmaIntDisable); +// synopGMACReadReg(gmacdev->DmaBase, DmaInterrupt); + return; +} + +/** + * Disable interrupt according to the bitfield supplied. + * Disables only those interrupts specified in the bit mask in second argument. + * @param[in] pointer to synopGMACdevice. + * @param[in] bit mask for interrupts to be disabled. + * \return returns void. + */ +#if UNUSED +void synopGMAC_disable_interrupt(synopGMACdevice *gmacdev, u32 interrupts) +{ + synopGMACClearBits(gmacdev->DmaBase, DmaInterrupt, interrupts); + return; +} +#endif +/** + * Enable the DMA Reception. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_enable_dma_rx(synopGMACdevice * gmacdev) +{ +// synopGMACSetBits(gmacdev->DmaBase, DmaControl, DmaRxStart); + u32 data; + data = synopGMACReadReg(gmacdev->DmaBase, DmaControl); + data |= DmaRxStart; + TR0(" ===33334\n"); + synopGMACWriteReg(gmacdev->DmaBase, DmaControl ,data); + TR0(" ===33344\n"); +} + +/** + * Enable the DMA Transmission. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_enable_dma_tx(synopGMACdevice * gmacdev) +{ +// synopGMACSetBits(gmacdev->DmaBase, DmaControl, DmaTxStart); + u32 data; + data = synopGMACReadReg(gmacdev->DmaBase, DmaControl); + data |= DmaTxStart; + synopGMACWriteReg(gmacdev->DmaBase, DmaControl ,data); + +} + +/** + * Resumes the DMA Transmission. + * the DmaTxPollDemand is written. (the data writeen could be anything). + * This forces the DMA to resume transmission. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_resume_dma_tx(synopGMACdevice * gmacdev) +{ + synopGMACWriteReg(gmacdev->DmaBase, DmaTxPollDemand, 1); + +} +/** + * Resumes the DMA Reception. + * the DmaRxPollDemand is written. (the data writeen could be anything). + * This forces the DMA to resume reception. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_resume_dma_rx(synopGMACdevice * gmacdev) +{ + synopGMACWriteReg(gmacdev->DmaBase, DmaRxPollDemand, 0); + +} +/** + * Take ownership of this Descriptor. + * The function is same for both the ring mode and the chain mode DMA structures. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_take_desc_ownership(DmaDesc * desc) +{ + if(desc){ + desc->status &= ~DescOwnByDma; //Clear the DMA own bit +// desc->status |= DescError; // Set the error to indicate this descriptor is bad + } +} + +/** + * Take ownership of all the rx Descriptors. + * This function is called when there is fatal error in DMA transmission. + * When called it takes the ownership of all the rx descriptor in rx descriptor pool/queue from DMA. + * The function is same for both the ring mode and the chain mode DMA structures. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + * \note Make sure to disable the transmission before calling this function, otherwise may result in racing situation. + */ +void synopGMAC_take_desc_ownership_rx(synopGMACdevice * gmacdev) +{ + s32 i; + DmaDesc *desc; + desc = gmacdev->RxDesc; + for(i = 0; i < gmacdev->RxDescCount; i++){ + if(synopGMAC_is_rx_desc_chained(desc)){ //This descriptor is in chain mode + + synopGMAC_take_desc_ownership(desc); + desc = (DmaDesc *)desc->data2; + } + else{ + synopGMAC_take_desc_ownership(desc + i); + } + } +} + +/** + * Take ownership of all the rx Descriptors. + * This function is called when there is fatal error in DMA transmission. + * When called it takes the ownership of all the tx descriptor in tx descriptor pool/queue from DMA. + * The function is same for both the ring mode and the chain mode DMA structures. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + * \note Make sure to disable the transmission before calling this function, otherwise may result in racing situation. + */ +void synopGMAC_take_desc_ownership_tx(synopGMACdevice * gmacdev) +{ + s32 i; + DmaDesc *desc; + desc = gmacdev->TxDesc; + for(i = 0; i < gmacdev->TxDescCount; i++){ + if(synopGMAC_is_tx_desc_chained(desc)){ //This descriptor is in chain mode + synopGMAC_take_desc_ownership(desc); + desc = (DmaDesc *)desc->data2; + } + else{ + synopGMAC_take_desc_ownership(desc + i); + } + } + +} + +/** + * Disable the DMA for Transmission. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ + +void synopGMAC_disable_dma_tx(synopGMACdevice * gmacdev) +{ +// synopGMACClearBits(gmacdev->DmaBase, DmaControl, DmaTxStart); + u32 data; + data = synopGMACReadReg(gmacdev->DmaBase, DmaControl); + data &= (~DmaTxStart); + synopGMACWriteReg(gmacdev->DmaBase, DmaControl ,data); +} +/** + * Disable the DMA for Reception. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_disable_dma_rx(synopGMACdevice * gmacdev) +{ +// synopGMACClearBits(gmacdev->DmaBase, DmaControl, DmaRxStart); + u32 data; + data = synopGMACReadReg(gmacdev->DmaBase, DmaControl); + data &= (~DmaRxStart); + synopGMACWriteReg(gmacdev->DmaBase, DmaControl ,data); +} + + + +/*******************PMT APIs***************************************/ + + + + +/** + * Enables the assertion of PMT interrupt. + * This enables the assertion of PMT interrupt due to Magic Pkt or Wakeup frame + * reception. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_pmt_int_enable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask); + return; +} +#endif +/** + * Disables the assertion of PMT interrupt. + * This disables the assertion of PMT interrupt due to Magic Pkt or Wakeup frame + * reception. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_pmt_int_disable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask); + return; +} +/** + * Enables the power down mode of GMAC. + * This function puts the Gmac in power down mode. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_power_down_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtPowerDown); + return; +} +#endif +/** + * Disables the powerd down setting of GMAC. + * If the driver wants to bring up the GMAC from powerdown mode, even though the magic packet or the + * wake up frames received from the network, this function should be called. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_power_down_disable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtPowerDown); + return; +} +#endif +/** + * Enables the pmt interrupt generation in powerdown mode. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_enable_pmt_interrupt(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask); +} +#endif +/** + * Disables the pmt interrupt generation in powerdown mode. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_disable_pmt_interrupt(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask); +} +#endif +/** + * Enables GMAC to look for Magic packet. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_magic_packet_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtMagicPktEnable); + return; +} +#endif + +/** + * Enables GMAC to look for wake up frame. + * Wake up frame is defined by the user. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_wakeup_frame_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtWakeupFrameEnable); + return; +} +#endif + +/** + * Enables wake-up frame filter to handle unicast packets. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_pmt_unicast_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtGlobalUnicast); + return; +} +#endif +/** + * Checks whether the packet received is a magic packet?. + * @param[in] pointer to synopGMACdevice. + * \return returns True if magic packet received else returns false. + */ +bool synopGMAC_is_magic_packet_received(synopGMACdevice *gmacdev) +{ + u32 data; + data = synopGMACReadReg(gmacdev->MacBase,GmacPmtCtrlStatus); + return((data & GmacPmtMagicPktReceived) == GmacPmtMagicPktReceived); +} +/** + * Checks whether the packet received is a wakeup frame?. + * @param[in] pointer to synopGMACdevice. + * \return returns true if wakeup frame received else returns false. + */ +bool synopGMAC_is_wakeup_frame_received(synopGMACdevice *gmacdev) +{ + u32 data; + data = synopGMACReadReg(gmacdev->MacBase,GmacPmtCtrlStatus); + return((data & GmacPmtWakeupFrameReceived) == GmacPmtWakeupFrameReceived); +} + +/** + * Populates the remote wakeup frame registers. + * Consecutive 8 writes to GmacWakeupAddr writes the wakeup frame filter registers. + * Before commensing a new write, frame filter pointer is reset to 0x0000. + * A small delay is introduced to allow frame filter pointer reset operation. + * @param[in] pointer to synopGMACdevice. + * @param[in] pointer to frame filter contents array. + * \return returns void. + */ +#if UNUSED +void synopGMAC_write_wakeup_frame_register(synopGMACdevice *gmacdev, u32 * filter_contents) +{ + s32 i; + synopGMACSetBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtFrmFilterPtrReset); + plat_delay(10); + for(i =0; iMacBase, GmacWakeupAddr, *(filter_contents + i)); + return; + +} +#endif +/*******************PMT APIs***************************************/ +/*******************MMC APIs***************************************/ + +/** + * Freezes the MMC counters. + * This function call freezes the MMC counters. None of the MMC counters are updated + * due to any tx or rx frames until synopGMAC_mmc_counters_resume is called. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_mmc_counters_stop(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterFreeze); + return; +} +#endif +/** + * Resumes the MMC counter updation. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_mmc_counters_resume(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterFreeze); + return; +} +#endif +/** + * Configures the MMC in Self clearing mode. + * Programs MMC interface so that counters are cleared when the counters are read. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_mmc_counters_set_selfclear(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterResetOnRead); + return; +} +#endif +/** + * Configures the MMC in non-Self clearing mode. + * Programs MMC interface so that counters are cleared when the counters are read. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_mmc_counters_reset_selfclear(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterResetOnRead); + return; +} +#endif +/** + * Configures the MMC to stop rollover. + * Programs MMC interface so that counters will not rollover after reaching maximum value. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_mmc_counters_disable_rollover(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterStopRollover); + return; +} +/** + * Configures the MMC to rollover. + * Programs MMC interface so that counters will rollover after reaching maximum value. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_mmc_counters_enable_rollover(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterStopRollover); + return; +} + +/** + * Read the MMC Counter. + * @param[in] pointer to synopGMACdevice. + * @param[in] the counter to be read. + * \return returns the read count value. + */ +u32 synopGMAC_read_mmc_counter(synopGMACdevice *gmacdev, u32 counter) +{ + return( synopGMACReadReg(gmacdev->MacBase,counter)); +} +#endif +/** + * Read the MMC Rx interrupt status. + * @param[in] pointer to synopGMACdevice. + * \return returns the Rx interrupt status. + */ +u32 synopGMAC_read_mmc_rx_int_status(synopGMACdevice *gmacdev) +{ + return( synopGMACReadReg(gmacdev->MacBase,GmacMmcIntrRx)); +} +/** + * Read the MMC Tx interrupt status. + * @param[in] pointer to synopGMACdevice. + * \return returns the Tx interrupt status. + */ +u32 synopGMAC_read_mmc_tx_int_status(synopGMACdevice *gmacdev) +{ + return( synopGMACReadReg(gmacdev->MacBase,GmacMmcIntrTx)); +} +/** + * Disable the MMC Tx interrupt. + * The MMC tx interrupts are masked out as per the mask specified. + * @param[in] pointer to synopGMACdevice. + * @param[in] tx interrupt bit mask for which interrupts needs to be disabled. + * \return returns void. + */ +void synopGMAC_disable_mmc_tx_interrupt(synopGMACdevice *gmacdev, u32 mask) +{ + synopGMACSetBits(gmacdev->MacBase,GmacMmcIntrMaskTx,mask); + return; +} +/** + * Enable the MMC Tx interrupt. + * The MMC tx interrupts are enabled as per the mask specified. + * @param[in] pointer to synopGMACdevice. + * @param[in] tx interrupt bit mask for which interrupts needs to be enabled. + * \return returns void. + */ +#if UNUSED +void synopGMAC_enable_mmc_tx_interrupt(synopGMACdevice *gmacdev, u32 mask) +{ + synopGMACClearBits(gmacdev->MacBase,GmacMmcIntrMaskTx,mask); +} +#endif +/** + * Disable the MMC Rx interrupt. + * The MMC rx interrupts are masked out as per the mask specified. + * @param[in] pointer to synopGMACdevice. + * @param[in] rx interrupt bit mask for which interrupts needs to be disabled. + * \return returns void. + */ +void synopGMAC_disable_mmc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask) +{ + synopGMACSetBits(gmacdev->MacBase,GmacMmcIntrMaskRx,mask); + return; +} +/** + * Enable the MMC Rx interrupt. + * The MMC rx interrupts are enabled as per the mask specified. + * @param[in] pointer to synopGMACdevice. + * @param[in] rx interrupt bit mask for which interrupts needs to be enabled. + * \return returns void. + */ +#if UNUSED +void synopGMAC_enable_mmc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask) +{ + synopGMACClearBits(gmacdev->MacBase,GmacMmcIntrMaskRx,mask); + return; +} +#endif +/** + * Disable the MMC ipc rx checksum offload interrupt. + * The MMC ipc rx checksum offload interrupts are masked out as per the mask specified. + * @param[in] pointer to synopGMACdevice. + * @param[in] rx interrupt bit mask for which interrupts needs to be disabled. + * \return returns void. + */ +void synopGMAC_disable_mmc_ipc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask) +{ + synopGMACSetBits(gmacdev->MacBase,GmacMmcRxIpcIntrMask,mask); + return; +} +/** + * Enable the MMC ipc rx checksum offload interrupt. + * The MMC ipc rx checksum offload interrupts are enabled as per the mask specified. + * @param[in] pointer to synopGMACdevice. + * @param[in] rx interrupt bit mask for which interrupts needs to be enabled. + * \return returns void. + */ +#if UNUSED +void synopGMAC_enable_mmc_ipc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask) +{ + synopGMACClearBits(gmacdev->MacBase,GmacMmcRxIpcIntrMask,mask); + return; +} +#endif +/*******************MMC APIs***************************************/ +/*******************Ip checksum offloading APIs***************************************/ + +/** + * Enables the ip checksum offloading in receive path. + * When set GMAC calculates 16 bit 1's complement of all received ethernet frame payload. + * It also checks IPv4 Header checksum is correct. GMAC core appends the 16 bit checksum calculated + * for payload of IP datagram and appends it to Ethernet frame transferred to the application. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +#if UNUSED +void synopGMAC_enable_rx_chksum_offload(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacConfig,GmacRxIpcOffload); + return; +} +/** + * Disable the ip checksum offloading in receive path. + * Ip checksum offloading is disabled in the receive path. + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_disable_rx_Ipchecksum_offload(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacConfig,GmacRxIpcOffload); +} +/** + * Instruct the DMA to drop the packets fails tcp ip checksum. + * This is to instruct the receive DMA engine to drop the recevied packet if they + * fails the tcp/ip checksum in hardware. Valid only when full checksum offloading is enabled(type-2). + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_rx_tcpip_chksum_drop_enable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->DmaBase,DmaControl,DmaDisableDropTcpCs); + return; +} +/** + * Instruct the DMA not to drop the packets even if it fails tcp ip checksum. + * This is to instruct the receive DMA engine to allow the packets even if recevied packet + * fails the tcp/ip checksum in hardware. Valid only when full checksum offloading is enabled(type-2). + * @param[in] pointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_rx_tcpip_chksum_drop_disable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->DmaBase,DmaControl,DmaDisableDropTcpCs); + return; +} +#endif + +/** + * When the Enhanced Descriptor is enabled then the bit 0 of RDES0 indicates whether the + * Extended Status is available (RDES4). Time Stamp feature and the Checksum Offload Engine2 + * makes use of this extended status to provide the status of the received packet. + * @param[in] pointer to synopGMACdevice + * \return returns TRUE or FALSE + */ +#ifdef ENH_DESC_8W + +/** + * This function indicates whether extended status is available in the RDES0. + * Any function which accesses the fields of extended status register must ensure a check on this has been made + * This is valid only for Enhanced Descriptor. + * @param[in] pointer to synopGMACdevice. + * @param[in] u32 status field of the corresponding descriptor. + * \return returns TRUE or FALSE. + */ +bool synopGMAC_is_ext_status(synopGMACdevice *gmacdev,u32 status) // extended status present indicates that the RDES4 need to be probed +{ + return((status & DescRxEXTsts ) != 0 ); // if extstatus set then it returns 1 +} +/** + * This function returns true if the IP header checksum bit is set in the extended status. + * Valid only when enhaced status available is set in RDES0 bit 0. + * This is valid only for Enhanced Descriptor. + * @param[in] pointer to synopGMACdevice. + * @param[in] u32 status field of the corresponding descriptor. + * \return returns TRUE or FALSE. + */ +bool synopGMAC_ES_is_IP_header_error(synopGMACdevice *gmacdev,u32 ext_status) // IP header (IPV4) checksum error +{ + return((ext_status & DescRxIpHeaderError) != 0 ); // if IPV4 header error return 1 +} +/** + * This function returns true if the Checksum is bypassed in the hardware. + * Valid only when enhaced status available is set in RDES0 bit 0. + * This is valid only for Enhanced Descriptor. + * @param[in] pointer to synopGMACdevice. + * @param[in] u32 status field of the corresponding descriptor. + * \return returns TRUE or FALSE. + */ +bool synopGMAC_ES_is_rx_checksum_bypassed(synopGMACdevice *gmacdev,u32 ext_status) // Hardware engine bypassed the checksum computation/checking +{ + return((ext_status & DescRxChkSumBypass ) != 0 ); // if checksum offloading bypassed return 1 +} +/** + * This function returns true if payload checksum error is set in the extended status. + * Valid only when enhaced status available is set in RDES0 bit 0. + * This is valid only for Enhanced Descriptor. + * @param[in] pointer to synopGMACdevice. + * @param[in] u32 status field of the corresponding descriptor. + * \return returns TRUE or FALSE. + */ +bool synopGMAC_ES_is_IP_payload_error(synopGMACdevice *gmacdev,u32 ext_status) // IP payload checksum is in error (UDP/TCP/ICMP checksum error) +{ + return((ext_status & DescRxIpPayloadError) != 0 ); // if IP payload error return 1 +} +#endif + + + +/** + * Decodes the Rx Descriptor status to various checksum error conditions. + * @param[in] pointer to synopGMACdevice. + * @param[in] u32 status field of the corresponding descriptor. + * \return returns decoded enum (u32) indicating the status. + */ +u32 synopGMAC_is_rx_checksum_error(synopGMACdevice *gmacdev, u32 status) +{ + if (((status & DescRxChkBit5) == 0) && ((status & DescRxChkBit7) == 0) && ((status & DescRxChkBit0) == 0)) + return RxLenLT600; + else if(((status & DescRxChkBit5) == 0) && ((status & DescRxChkBit7) == 0) && ((status & DescRxChkBit0) != 0)) + return RxIpHdrPayLoadChkBypass; + else if(((status & DescRxChkBit5) == 0) && ((status & DescRxChkBit7) != 0) && ((status & DescRxChkBit0) != 0)) + return RxChkBypass; + else if(((status & DescRxChkBit5) != 0) && ((status & DescRxChkBit7) == 0) && ((status & DescRxChkBit0) == 0)) + return RxNoChkError; + else if(((status & DescRxChkBit5) != 0) && ((status & DescRxChkBit7) == 0) && ((status & DescRxChkBit0) != 0)) + return RxPayLoadChkError; + else if(((status & DescRxChkBit5) != 0) && ((status & DescRxChkBit7) != 0) && ((status & DescRxChkBit0) == 0)) + return RxIpHdrChkError; + else if(((status & DescRxChkBit5) != 0) && ((status & DescRxChkBit7) != 0) && ((status & DescRxChkBit0) != 0)) + return RxIpHdrPayLoadChkError; + else + return RxIpHdrPayLoadRes; +} +/** + * Checks if any Ipv4 header checksum error in the frame just transmitted. + * This serves as indication that error occureed in the IPv4 header checksum insertion. + * The sent out frame doesnot carry any ipv4 header checksum inserted by the hardware. + * @param[in] pointer to synopGMACdevice. + * @param[in] u32 status field of the corresponding descriptor. + * \return returns true if error in ipv4 header checksum, else returns false. + */ +bool synopGMAC_is_tx_ipv4header_checksum_error(synopGMACdevice *gmacdev, u32 status) +{ + return((status & DescTxIpv4ChkError) == DescTxIpv4ChkError); +} + + +/** + * Checks if any payload checksum error in the frame just transmitted. + * This serves as indication that error occureed in the payload checksum insertion. + * The sent out frame doesnot carry any payload checksum inserted by the hardware. + * @param[in] pointer to synopGMACdevice. + * @param[in] u32 status field of the corresponding descriptor. + * \return returns true if error in ipv4 header checksum, else returns false. + */ +bool synopGMAC_is_tx_payload_checksum_error(synopGMACdevice *gmacdev, u32 status) +{ + return((status & DescTxPayChkError) == DescTxPayChkError); +} +/** + * The check summ offload engine is bypassed in the tx path. + * Checksum is not computed in the Hardware. + * @param[in] pointer to synopGMACdevice. + * @param[in] Pointer to tx descriptor for which ointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_tx_checksum_offload_bypass(synopGMACdevice *gmacdev, DmaDesc *desc) +{ + #ifdef ENH_DESC + desc->status = (desc->length & (~DescTxCisMask));//ENH_DESC + #else + desc->length = (desc->length & (~DescTxCisMask)); + #endif + +} +/** + * The check summ offload engine is enabled to do only IPV4 header checksum. + * IPV4 header Checksum is computed in the Hardware. + * @param[in] pointer to synopGMACdevice. + * @param[in] Pointer to tx descriptor for which ointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_tx_checksum_offload_ipv4hdr(synopGMACdevice *gmacdev, DmaDesc *desc) +{ + #ifdef ENH_DESC + desc->status = ((desc->status & (~DescTxCisMask)) | DescTxCisIpv4HdrCs);//ENH_DESC + #else + desc->length = ((desc->length & (~DescTxCisMask)) | DescTxCisIpv4HdrCs); + #endif + +} + +/** + * The check summ offload engine is enabled to do TCPIP checsum assuming Pseudo header is available. + * Hardware computes the tcp ip checksum assuming pseudo header checksum is computed in software. + * Ipv4 header checksum is also inserted. + * @param[in] pointer to synopGMACdevice. + * @param[in] Pointer to tx descriptor for which ointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_tx_checksum_offload_tcponly(synopGMACdevice *gmacdev, DmaDesc *desc) +{ + #ifdef ENH_DESC + desc->status = ((desc->status & (~DescTxCisMask)) | DescTxCisTcpOnlyCs);//ENH_DESC + #else + desc->length = ((desc->length & (~DescTxCisMask)) | DescTxCisTcpOnlyCs); + #endif + +} +/** + * The check summ offload engine is enabled to do complete checksum computation. + * Hardware computes the tcp ip checksum including the pseudo header checksum. + * Here the tcp payload checksum field should be set to 0000. + * Ipv4 header checksum is also inserted. + * @param[in] pointer to synopGMACdevice. + * @param[in] Pointer to tx descriptor for which ointer to synopGMACdevice. + * \return returns void. + */ +void synopGMAC_tx_checksum_offload_tcp_pseudo(synopGMACdevice *gmacdev, DmaDesc *desc) +{ + #ifdef ENH_DESC + desc->status = ((desc->length & (~DescTxCisMask)) | DescTxCisTcpPseudoCs); + #else + desc->length = ((desc->length & (~DescTxCisMask)) | DescTxCisTcpPseudoCs); + #endif + +} +/*******************Ip checksum offloading APIs***************************************/ + + + + + +/*******************IEEE 1588 Timestamping API***************************************/ + + +/* + * At this time the driver supports the IEEE time stamping feature when the Enhanced Descriptors are enabled. + * For normal descriptor and the IEEE time stamp (version 1), driver support is not proviced + * Please make sure you have enabled the Advanced timestamp feature in the hardware and the driver should + * be compiled with the ADV_TME_STAMP feature. + * Some of the APIs provided here may not be valid for all configurations. Please make sure you call the + * API with due care. + */ + +/** + * This function enables the timestamping. This enables the timestamping for transmit and receive frames. + * When disabled timestamp is not added to tx and receive frames and timestamp generator is suspended. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +#if UNUSED +void synopGMAC_TS_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSENA); + return; +} +/** + * This function disables the timestamping. + * When disabled timestamp is not added to tx and receive frames and timestamp generator is suspended. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_disable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacInterruptMask, GmacTSIntMask); + return; +} + + +/** + * Enable the interrupt to get timestamping interrupt. + * This enables the host to get the interrupt when (1) system time is greater or equal to the + * target time high and low register or (2) there is a overflow in th esecond register. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_int_enable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask); + return; +} + +/** + * Disable the interrupt to get timestamping interrupt. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_int_disable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask); + return; +} + +/** + * Enable MAC address for PTP frame filtering. + * When enabled, uses MAC address (apart from MAC address 0) to filter the PTP frames when + * PTP is sent directly over Ethernet. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_mac_addr_filt_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSENMACADDR); + return; +} + +/** + * Disables MAC address for PTP frame filtering. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_mac_addr_filt_disable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSENMACADDR); + return; +} + + +/** + * Selet the type of clock mode for PTP. + * Please note to use one of the follwoing as the clk_type argument. + * GmacTSOrdClk = 0x00000000, 00=> Ordinary clock + * GmacTSBouClk = 0x00010000, 01=> Boundary clock + * GmacTSEtoEClk = 0x00020000, 10=> End-to-End transparent clock + * GmacTSPtoPClk = 0x00030000, 11=> P-to-P transparent clock + * @param[in] pointer to synopGMACdevice + * @param[in] u32 value representing one of the above clk value + * \return returns void + */ +void synopGMAC_TS_set_clk_type(synopGMACdevice *gmacdev, u32 clk_type) +{ + u32 clkval; + clkval = synopGMACReadReg(gmacdev->MacBase,GmacTSControl); //set the mdc clock to the user defined value + clkval = clkval | clk_type; + synopGMACWriteReg(gmacdev->MacBase,GmacTSControl,clkval); + return; +} + +/** + * Enable Snapshot for messages relevant to Master. + * When enabled, snapshot is taken for messages relevant to master mode only, else snapshot is taken for messages relevant + * to slave node. + * Valid only for Ordinary clock and Boundary clock + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_master_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSMSTRENA); + return; +} +/** + * Disable Snapshot for messages relevant to Master. + * When disabled, snapshot is taken for messages relevant + * to slave node. + * Valid only for Ordinary clock and Boundary clock + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_master_disable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSMSTRENA); + return; +} +/** + * Enable Snapshot for Event messages. + * When enabled, snapshot is taken for event messages only (SYNC, Delay_Req, Pdelay_Req or Pdelay_Resp) + * When disabled, snapshot is taken for all messages except Announce, Management and Signaling. + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_event_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSEVNTENA); + return; +} +/** + * Disable Snapshot for Event messages. + * When disabled, snapshot is taken for all messages except Announce, Management and Signaling. + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_event_disable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSEVNTENA); + return; +} + +/** + * Enable time stamp snapshot for IPV4 frames. + * When enabled, time stamp snapshot is taken for IPV4 frames + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_IPV4_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSIPV4ENA); + return; +} +/** + * Disable time stamp snapshot for IPV4 frames. + * When disabled, time stamp snapshot is not taken for IPV4 frames + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_IPV4_disable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSIPV4ENA); + return; +} // Only for "Advanced Time Stamp" +/** + * Enable time stamp snapshot for IPV6 frames. + * When enabled, time stamp snapshot is taken for IPV6 frames + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_IPV6_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSIPV6ENA); + return; +} +/** + * Disable time stamp snapshot for IPV6 frames. + * When disabled, time stamp snapshot is not taken for IPV6 frames + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_IPV6_disable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSIPV6ENA); + return; +} + +/** + * Enable time stamp snapshot for PTP over Ethernet frames. + * When enabled, time stamp snapshot is taken for PTP over Ethernet frames + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_ptp_over_ethernet_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSIPENA); + return; +} +/** + * Disable time stamp snapshot for PTP over Ethernet frames. + * When disabled, time stamp snapshot is not taken for PTP over Ethernet frames + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_ptp_over_ethernet_disable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSIPENA); + return; +} + + +/** + * Snoop PTP packet for version 2 format + * When set the PTP packets are snooped using the version 2 format. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_pkt_snoop_ver2(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSVER2ENA); + return; +} +/** + * Snoop PTP packet for version 2 format + * When set the PTP packets are snooped using the version 2 format. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_pkt_snoop_ver1(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSVER2ENA); + return; +} + +/** + * Timestamp digital rollover + * When set the timestamp low register rolls over after 0x3B9A_C9FF value. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_digital_rollover_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSCTRLSSR); + return; +} +/** + * Timestamp binary rollover + * When set the timestamp low register rolls over after 0x7FFF_FFFF value. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_binary_rollover_enable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSCTRLSSR); + return; +} +/** + * Enable Time Stamp for All frames + * When set the timestamp snap shot is enabled for all frames received by the core. + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_all_frames_enable(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSENALL); + return; +} +/** + * Disable Time Stamp for All frames + * When reset the timestamp snap shot is not enabled for all frames received by the core. + * Reserved when "Advanced Time Stamp" is not selected + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_all_frames_disable(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSENALL); + return; +} +/** + * Addend Register Update + * This function loads the contents of Time stamp addend register with the supplied 32 value. + * This is reserved function when only coarse correction option is selected + * @param[in] pointer to synopGMACdevice + * @param[in] 32 bit addend value + * \return returns 0 for Success or else Failure + */ +s32 synopGMAC_TS_addend_update(synopGMACdevice *gmacdev, u32 addend_value) +{ + u32 loop_variable; + synopGMACWriteReg(gmacdev->MacBase,GmacTSAddend,addend_value);// Load the addend_value in to Addend register + for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ //Wait till the busy bit gets cleared with in a certain amount of time + if(!((synopGMACReadReg(gmacdev->MacBase,GmacTSControl)) & GmacTSADDREG)){ // if it is cleared then break + break; + } + plat_delay(DEFAULT_DELAY_VARIABLE); + } + if(loop_variable < DEFAULT_LOOP_VARIABLE) + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSADDREG); + else{ + TR("Error::: The TSADDREG bit is not getting cleared !!!!!!\n"); + return -ESYNOPGMACPHYERR; + } +return -ESYNOPGMACNOERR; + +} +/** + * time stamp Update + * This function updates (adds/subtracts) with the value specified in the Timestamp High Update and + * Timestamp Low Update register. + * @param[in] pointer to synopGMACdevice + * @param[in] Timestamp High Update value + * @param[in] Timestamp Low Update value + * \return returns 0 for Success or else Failure + */ +s32 synopGMAC_TS_timestamp_update(synopGMACdevice *gmacdev, u32 high_value, u32 low_value) +{ + u32 loop_variable; + synopGMACWriteReg(gmacdev->MacBase,GmacTSHighUpdate,high_value);// Load the high value to Timestamp High register + synopGMACWriteReg(gmacdev->MacBase,GmacTSLowUpdate,low_value);// Load the high value to Timestamp High register + for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ //Wait till the busy bit gets cleared with in a certain amount of time + if(!((synopGMACReadReg(gmacdev->MacBase,GmacTSControl)) & GmacTSUPDT)){ // if it is cleared then break + break; + } + plat_delay(DEFAULT_DELAY_VARIABLE); + } + if(loop_variable < DEFAULT_LOOP_VARIABLE) + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSUPDT); + else{ + TR("Error::: The TSADDREG bit is not getting cleared !!!!!!\n"); + return -ESYNOPGMACPHYERR; + } +return -ESYNOPGMACNOERR; +} + +/** + * time stamp Initialize + * This function Loads/Initializes h the value specified in the Timestamp High Update and + * Timestamp Low Update register. + * @param[in] pointer to synopGMACdevice + * @param[in] Timestamp High Load value + * @param[in] Timestamp Low Load value + * \return returns 0 for Success or else Failure + */ +s32 synopGMAC_TS_timestamp_init(synopGMACdevice *gmacdev, u32 high_value, u32 low_value) +{ + u32 loop_variable; + synopGMACWriteReg(gmacdev->MacBase,GmacTSHighUpdate,high_value);// Load the high value to Timestamp High register + synopGMACWriteReg(gmacdev->MacBase,GmacTSLowUpdate,low_value);// Load the high value to Timestamp High register + for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ //Wait till the busy bit gets cleared with in a certain amount of time + if(!((synopGMACReadReg(gmacdev->MacBase,GmacTSControl)) & GmacTSINT)){ // if it is cleared then break + break; + } + plat_delay(DEFAULT_DELAY_VARIABLE); + } + if(loop_variable < DEFAULT_LOOP_VARIABLE) + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSINT); + else{ + TR("Error::: The TSADDREG bit is not getting cleared !!!!!!\n"); + return -ESYNOPGMACPHYERR; + } +return -ESYNOPGMACNOERR; +} + +/** + * Time Stamp Update Coarse + * When reset the timestamp update is done using coarse method. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_coarse_update(synopGMACdevice *gmacdev) +{ + synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSCFUPDT); + return; +} +/** + * Time Stamp Update Fine + * When reset the timestamp update is done using Fine method. + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_fine_update(synopGMACdevice *gmacdev) +{ + synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSCFUPDT); + return; +} + +/** + * Load the Sub Second Increment value in to Sub Second increment register + * @param[in] pointer to synopGMACdevice + * \return returns void + */ +void synopGMAC_TS_subsecond_init(synopGMACdevice *gmacdev, u32 sub_sec_inc_value) +{ + synopGMACWriteReg(gmacdev->MacBase,GmacTSSubSecIncr,(sub_sec_inc_value & GmacSSINCMsk)); + return; +} +/** + * Reads the time stamp contents in to the respective pointers + * These registers are readonly. + * This function returns the 48 bit time stamp assuming Version 2 timestamp with higher word is selected. + * @param[in] pointer to synopGMACdevice + * @param[in] pointer to hold 16 higher bit second register contents + * @param[in] pointer to hold 32 bit second register contents + * @param[in] pointer to hold 32 bit subnanosecond register contents + * \return returns void + * \note Please note that since the atomic access to the timestamp registers is not possible, + * the contents read may be different from the actual time stamp. + */ +void synopGMAC_TS_read_timestamp(synopGMACdevice *gmacdev, u16 * higher_sec_val, u32 * sec_val, u32 * sub_sec_val) +{ + * higher_sec_val = (u16)(synopGMACReadReg(gmacdev->MacBase,GmacTSHighWord) & GmacTSHighWordMask); + * sec_val = synopGMACReadReg(gmacdev->MacBase,GmacTSHigh); + * sub_sec_val = synopGMACReadReg(gmacdev->MacBase,GmacTSLow); + return; +} +/** + * Loads the time stamp higher sec value from the value supplied + * @param[in] pointer to synopGMACdevice + * @param[in] 16 higher bit second register contents passed as 32 bit value + * \return returns void + */ +void synopGMAC_TS_load_timestamp_higher_val(synopGMACdevice *gmacdev, u32 higher_sec_val) +{ + synopGMACWriteReg(gmacdev->MacBase,GmacTSHighWord, (higher_sec_val & GmacTSHighWordMask)); + return; +} +/** + * Reads the time stamp higher sec value to respective pointers + * @param[in] pointer to synopGMACdevice + * @param[in] pointer to hold 16 higher bit second register contents + * \return returns void + */ +void synopGMAC_TS_read_timestamp_higher_val(synopGMACdevice *gmacdev, u16 * higher_sec_val) +{ + * higher_sec_val = (u16)(synopGMACReadReg(gmacdev->MacBase,GmacTSHighWord) & GmacTSHighWordMask); + return; +} +/** + * Load the Target time stamp registers + * This function Loads the target time stamp registers with the values proviced + * @param[in] pointer to synopGMACdevice + * @param[in] target Timestamp High value + * @param[in] target Timestamp Low value + * \return returns 0 for Success or else Failure + */ +void synopGMAC_TS_load_target_timestamp(synopGMACdevice *gmacdev, u32 sec_val, u32 sub_sec_val) +{ + synopGMACWriteReg(gmacdev->MacBase,GmacTSTargetTimeHigh,sec_val); + synopGMACWriteReg(gmacdev->MacBase,GmacTSTargetTimeLow,sub_sec_val); + return; +} +/** + * Reads the Target time stamp registers + * This function Loads the target time stamp registers with the values proviced + * @param[in] pointer to synopGMACdevice + * @param[in] pointer to hold target Timestamp High value + * @param[in] pointer to hold target Timestamp Low value + * \return returns 0 for Success or else Failure + */ +void synopGMAC_TS_read_target_timestamp(synopGMACdevice *gmacdev, u32 * sec_val, u32 * sub_sec_val) +{ + * sec_val = synopGMACReadReg(gmacdev->MacBase,GmacTSTargetTimeHigh); + * sub_sec_val = synopGMACReadReg(gmacdev->MacBase,GmacTSTargetTimeLow); + return; +} +#endif diff --git a/bsp/ls1cdev/drivers/net/synopGMAC_Dev.h b/bsp/ls1cdev/drivers/net/synopGMAC_Dev.h new file mode 100644 index 0000000000..25c7814a16 --- /dev/null +++ b/bsp/ls1cdev/drivers/net/synopGMAC_Dev.h @@ -0,0 +1,1772 @@ +/**\file + * This file defines the function prototypes for the Synopsys GMAC device and the + * Marvell 88E1011/88E1011S integrated 10/100/1000 Gigabit Ethernet Transceiver. + * Since the phy register mapping are standardised, the phy register map and the + * bit definitions remain the same for other phy as well. + * This also defines some of the Ethernet related parmeters. + * \internal + * -----------------------------REVISION HISTORY------------------------------------ + * Synopsys 01/Aug/2007 Created + */ + +/* + * File : synopGMAC_Dev.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + +#define UNUSED 1 + +#ifndef SYNOP_GMAC_DEV_H +#define SYNOP_GMAC_DEV_H 1 + +/*******************************************************************/ +#define SYNOP_LOOPBACK_MODE 0 +#define SYNOP_LOOPBACK_DEBUG 0 +#define SYNOP_PHY_LOOPBACK 0 + +#define SYNOP_TX_TEST 0 +#define SYNOP_RX_TEST 0 + +#define SYNOP_TOP_DEBUG 0 +#define SYNOP_REG_DEBUG 0 +#define SYNOP_RX_DEBUG 0 +#define SYNOP_TX_DEBUG 0 +/*******************************************************************/ + +#include "synopGMAC_plat.h" +#include "synopGMAC_types.h" + +//sw: typedef are included in synopGMAC_plat.h +// it is strange that we should add it here again!! + +/*SynopGMAC can support up to 32 phys*/ +#define GMAC_PHY_BASE 1 +#ifdef GMAC_PHY_BASE +#define DEFAULT_PHY_BASE GMAC_PHY_BASE +#else +#define DEFAULT_PHY_BASE PHY16 //We use First Phy +#endif +#define MACBASE 0x0000 // The Mac Base address offset is 0x0000 +#define DMABASE 0x1000 // Dma base address starts with an offset 0x1000 + + +enum GMACPhyBase +{ + PHY0 = 0, //The device can support 32 phys, but we use first phy only + PHY1 = 1, + PHY16 = 16, + PHY31 = 31, +}; + + +//#define TRANSMIT_DESC_SIZE 256 //Tx Descriptors needed in the Descriptor pool/queue +//#define RECEIVE_DESC_SIZE 256 //Rx Descriptors needed in the Descriptor pool/queue +//#define TRANSMIT_DESC_SIZE 13//256 //Tx Descriptors needed in the Descriptor pool/queue +#define TRANSMIT_DESC_SIZE 36 //48 //Tx Descriptors needed in the Descriptor pool/queue +#define RECEIVE_DESC_SIZE 72 //96 //Rx Descriptors needed in the Descriptor pool/queue + +#define ETHERNET_HEADER 14 //6 byte Dest addr, 6 byte Src addr, 2 byte length/type +#define ETHERNET_CRC 4 //Ethernet CRC +#define ETHERNET_EXTRA 2 //Only God knows about this????? +#define ETHERNET_PACKET_COPY 250 // Maximum length when received data is copied on to a new skb +#define ETHERNET_PACKET_EXTRA 18 // Preallocated length for the rx packets is MTU + ETHERNET_PACKET_EXTRA +#define VLAN_TAG 4 //optional 802.1q VLAN Tag +#define MIN_ETHERNET_PAYLOAD 46 //Minimum Ethernet payload size +#define MAX_ETHERNET_PAYLOAD 1500 //Maximum Ethernet payload size +#define JUMBO_FRAME_PAYLOAD 9000 //Jumbo frame payload size + +#define TX_BUF_SIZE ETHERNET_HEADER + ETHERNET_CRC + MAX_ETHERNET_PAYLOAD + VLAN_TAG +#define RX_BUF_SIZE ETHERNET_HEADER + ETHERNET_CRC + MAX_ETHERNET_PAYLOAD + VLAN_TAG + + +// This is the IP's phy address. This is unique address for every MAC in the universe +#define DEFAULT_MAC_ADDRESS {0x00, 0x55, 0x7B, 0xB5, 0x7D, 0xF7} + +/* +DMA Descriptor Structure +The structure is common for both receive and transmit descriptors +The descriptor is of 4 words, but our structrue contains 6 words where +last two words are to hold the virtual address of the network buffer pointers +for driver's use +From the GMAC core release 3.50a onwards, the Enhanced Descriptor structure got changed. +The descriptor (both transmit and receive) are of 8 words each rather the 4 words of normal +descriptor structure. +Whenever IEEE 1588 Timestamping is enabled TX/RX DESC6 provides the lower 32 bits of Timestamp value and + TX/RX DESC7 provides the upper 32 bits of Timestamp value +In addition to this whenever extended status bit is set (RX DESC0 bit 0), RX DESC4 contains the extended status information +*/ + +#define MODULO_INTERRUPT 1 // if it is set to 1, interrupt is available for all the descriptors or else interrupt is available only for + // descriptor whose index%MODULO_INTERRUPT is zero +#ifdef ENH_DESC_8W +typedef struct DmaDescStruct +{ + u32 status; /* Status */ + u32 length; /* Buffer 1 and Buffer 2 length */ + u32 buffer1; /* Network Buffer 1 pointer (Dma-able) */ + u32 buffer2; /* Network Buffer 2 pointer or next descriptor pointer (Dma-able)in chain structure */ + /* This data below is used only by driver */ + u32 extstatus; /* Extended status of a Rx Descriptor */ + u32 reserved1; /* Reserved word */ + u32 timestamplow; /* Lower 32 bits of the 64 bit timestamp value */ + u32 timestamphigh; /* Higher 32 bits of the 64 bit timestamp value */ + u32 data1; /* This holds virtual address of buffer1, not used by DMA */ + u32 data2; /* This holds virtual address of buffer2, not used by DMA */ +} DmaDesc; +#else +typedef struct DmaDescStruct +{ + u32 status; /* Status */ + u32 length; /* Buffer 1 and Buffer 2 length */ + u32 buffer1; /* Network Buffer 1 pointer (Dma-able) */ + u32 buffer2; /* Network Buffer 2 pointer or next descriptor pointer (Dma-able)in chain structure */ + /* This data below is used only by driver */ + u32 data1; /* This holds virtual address of buffer1, not used by DMA */ + u32 data2; /* This holds virtual address of buffer2, not used by DMA */ + + u32 dummy1; //sw: for addr align + u32 dummy2; // + +} DmaDesc; +#endif + +enum DescMode +{ + RINGMODE = 0x00000001, + CHAINMODE = 0x00000002, +}; + +enum BufferMode +{ + SINGLEBUF = 0x00000001, + DUALBUF = 0x00000002, +}; + +/* synopGMAC device data */ + +typedef struct synopGMACDeviceStruct +{ + u32 MacBase; /* base address of MAC registers */ + u32 DmaBase; /* base address of DMA registers */ + u32 PhyBase; /* PHY device address on MII interface */ + u32 Version; /* Gmac Revision version */ + + + dma_addr_t TxDescDma; /* Dma-able address of first tx descriptor either in ring or chain mode, this is used by the GMAC device*/ + dma_addr_t RxDescDma; /* Dma-albe address of first rx descriptor either in ring or chain mode, this is used by the GMAC device*/ + DmaDesc *TxDesc; /* start address of TX descriptors ring or chain, this is used by the driver */ + DmaDesc *RxDesc; /* start address of RX descriptors ring or chain, this is used by the driver */ + + u32 BusyTxDesc; /* Number of Tx Descriptors owned by DMA at any given time*/ + u32 BusyRxDesc; /* Number of Rx Descriptors owned by DMA at any given time*/ + + u32 RxDescCount; /* number of rx descriptors in the tx descriptor queue/pool */ + u32 TxDescCount; /* number of tx descriptors in the rx descriptor queue/pool */ + + u32 TxBusy; /* index of the tx descriptor owned by DMA, is obtained by synopGMAC_get_tx_qptr() */ + u32 TxNext; /* index of the tx descriptor next available with driver, given to DMA by synopGMAC_set_tx_qptr() */ + u32 RxBusy; /* index of the rx descriptor owned by DMA, obtained by synopGMAC_get_rx_qptr() */ + u32 RxNext; /* index of the rx descriptor next available with driver, given to DMA by synopGMAC_set_rx_qptr() */ + + DmaDesc * TxBusyDesc; /* Tx Descriptor address corresponding to the index TxBusy */ + DmaDesc * TxNextDesc; /* Tx Descriptor address corresponding to the index TxNext */ + DmaDesc * RxBusyDesc; /* Rx Descriptor address corresponding to the index TxBusy */ + DmaDesc * RxNextDesc; /* Rx Descriptor address corresponding to the index RxNext */ + + /*Phy related stuff*/ + u32 ClockDivMdc; /* Clock divider value programmed in the hardware */ + /* The status of the link */ + u32 LinkState0; /* Link status as reported by the Marvel Phy */ + u32 LinkState; /* Link status as reported by the Marvel Phy */ + u32 DuplexMode; /* Duplex mode of the Phy */ + u32 Speed; /* Speed of the Phy */ + u32 LoopBackMode; /* Loopback status of the Phy */ + +// void * FirstTxDesc; +// void * FirstRxDesc; +// u32 skb_array[RECEIVE_DESC_SIZE]; +} synopGMACdevice; + + + +/* Below is "88E1011/88E1011S Integrated 10/100/1000 Gigabit Ethernet Transceiver" + * Register and their layouts. This Phy has been used in the Dot Aster GMAC Phy daughter. + * Since the Phy register map is standard, this map hardly changes to a different Ppy + */ + +enum MiiRegisters +{ + PHY_CONTROL_REG = 0x0000, /*Control Register*/ + PHY_STATUS_REG = 0x0001, /*Status Register */ + PHY_ID_HI_REG = 0x0002, /*PHY Identifier High Register*/ + PHY_ID_LOW_REG = 0x0003, /*PHY Identifier High Register*/ + PHY_AN_ADV_REG = 0x0004, /*Auto-Negotiation Advertisement Register*/ + PHY_LNK_PART_ABl_REG = 0x0005, /*Link Partner Ability Register (Base Page)*/ + PHY_AN_EXP_REG = 0x0006, /*Auto-Negotiation Expansion Register*/ + PHY_AN_NXT_PAGE_TX_REG = 0x0007, /*Next Page Transmit Register*/ + PHY_LNK_PART_NXT_PAGE_REG = 0x0008, /*Link Partner Next Page Register*/ + PHY_1000BT_CTRL_REG = 0x0009, /*1000BASE-T Control Register*/ + PHY_1000BT_STATUS_REG = 0x000a, /*1000BASE-T Status Register*/ + PHY_SPECIFIC_CTRL_REG = 0x0010, /*Phy specific control register*/ + PHY_SPECIFIC_STATUS_REG = 0x0011, /*Phy specific status register*/ + PHY_INTERRUPT_ENABLE_REG = 0x0012, /*Phy interrupt enable register*/ + PHY_INTERRUPT_STATUS_REG = 0x0013, /*Phy interrupt status register*/ + PHY_EXT_PHY_SPC_CTRL = 0x0014, /*Extended Phy specific control*/ + PHY_RX_ERR_COUNTER = 0x0015, /*Receive Error Counter*/ + PHY_EXT_ADDR_CBL_DIAG = 0x0016, /*Extended address for cable diagnostic register*/ + PHY_LED_CONTROL = 0x0018, /*LED Control*/ + PHY_MAN_LED_OVERIDE = 0x0019, /*Manual LED override register*/ + PHY_EXT_PHY_SPC_CTRL2 = 0x001a, /*Extended Phy specific control 2*/ + PHY_EXT_PHY_SPC_STATUS = 0x001b, /*Extended Phy specific status*/ + PHY_CBL_DIAG_REG = 0x001c, /*Cable diagnostic registers*/ +}; + + +/* This is Control register layout. Control register is of 16 bit wide. +*/ + +enum Mii_GEN_CTRL +{ /* Description bits R/W default value */ + Mii_reset = 0x8000, + Mii_Speed_10 = 0x0000, /* 10 Mbps 6:13 RW */ + Mii_Speed_100 = 0x2000, /* 100 Mbps 6:13 RW */ + Mii_Speed_1000 = 0x0040, /* 1000 Mbit/s 6:13 RW */ + + Mii_Duplex = 0x0100, /* Full Duplex mode 8 RW */ + + Mii_Manual_Master_Config = 0x0800, /* Manual Master Config 11 RW */ + + Mii_Loopback = 0x4000, /* Enable Loop back 14 RW */ + Mii_NoLoopback = 0x0000, /* Enable Loop back 14 RW */ +}; + +enum Mii_Phy_Status +{ + Mii_phy_status_speed_10 = 0x0000, + Mii_phy_status_speed_100 = 0x4000, + Mii_phy_status_speed_1000 = 0x8000, + + Mii_phy_status_full_duplex = 0x2000, + Mii_phy_status_half_duplex = 0x0000, + + Mii_phy_status_link_up = 0x0400, //lyf:rtl 8211 phy +// Mii_phy_status_link_up = 0x0100, //sw: broadcom BCM5461 PHY +}; +/* This is Status register layout. Status register is of 16 bit wide. +*/ +enum Mii_GEN_STATUS +{ + Mii_AutoNegCmplt = 0x0020, /* Autonegotiation completed 5 RW */ + Mii_Link = 0x0004, /* Link status 2 RW */ +}; + +enum Mii_Link_Status +{ + LINKDOWN = 0, + LINKUP = 1, +}; + +enum Mii_Duplex_Mode +{ + HALFDUPLEX = 1, + FULLDUPLEX = 2, +}; +enum Mii_Link_Speed +{ + SPEED10 = 1, + SPEED100 = 2, + SPEED1000 = 3, +}; + +enum Mii_Loop_Back +{ + NOLOOPBACK = 0, + LOOPBACK = 1, +}; + + + +/********************************************************** + * GMAC registers Map + * For Pci based system address is BARx + GmacRegisterBase + * For any other system translation is done accordingly + **********************************************************/ +enum GmacRegisters +{ + GmacConfig = 0x0000, /* Mac config Register */ + GmacFrameFilter = 0x0004, /* Mac frame filtering controls */ + GmacHashHigh = 0x0008, /* Multi-cast hash table high */ + GmacHashLow = 0x000C, /* Multi-cast hash table low */ + GmacGmiiAddr = 0x0010, /* GMII address Register(ext. Phy) */ + GmacGmiiData = 0x0014, /* GMII data Register(ext. Phy) */ + GmacFlowControl = 0x0018, /* Flow control Register */ + GmacVlan = 0x001C, /* VLAN tag Register (IEEE 802.1Q) */ + + GmacVersion = 0x0020, /* GMAC Core Version Register */ + GmacWakeupAddr = 0x0028, /* GMAC wake-up frame filter adrress reg */ + GmacPmtCtrlStatus = 0x002C, /* PMT control and status register */ + + GmacInterruptStatus = 0x0038, /* Mac Interrupt ststus register */ + GmacInterruptMask = 0x003C, /* Mac Interrupt Mask register */ + + GmacAddr0High = 0x0040, /* Mac address0 high Register */ + GmacAddr0Low = 0x0044, /* Mac address0 low Register */ + GmacAddr1High = 0x0048, /* Mac address1 high Register */ + GmacAddr1Low = 0x004C, /* Mac address1 low Register */ + GmacAddr2High = 0x0050, /* Mac address2 high Register */ + GmacAddr2Low = 0x0054, /* Mac address2 low Register */ + GmacAddr3High = 0x0058, /* Mac address3 high Register */ + GmacAddr3Low = 0x005C, /* Mac address3 low Register */ + GmacAddr4High = 0x0060, /* Mac address4 high Register */ + GmacAddr4Low = 0x0064, /* Mac address4 low Register */ + GmacAddr5High = 0x0068, /* Mac address5 high Register */ + GmacAddr5Low = 0x006C, /* Mac address5 low Register */ + GmacAddr6High = 0x0070, /* Mac address6 high Register */ + GmacAddr6Low = 0x0074, /* Mac address6 low Register */ + GmacAddr7High = 0x0078, /* Mac address7 high Register */ + GmacAddr7Low = 0x007C, /* Mac address7 low Register */ + GmacAddr8High = 0x0080, /* Mac address8 high Register */ + GmacAddr8Low = 0x0084, /* Mac address8 low Register */ + GmacAddr9High = 0x0088, /* Mac address9 high Register */ + GmacAddr9Low = 0x008C, /* Mac address9 low Register */ + GmacAddr10High = 0x0090, /* Mac address10 high Register */ + GmacAddr10Low = 0x0094, /* Mac address10 low Register */ + GmacAddr11High = 0x0098, /* Mac address11 high Register */ + GmacAddr11Low = 0x009C, /* Mac address11 low Register */ + GmacAddr12High = 0x00A0, /* Mac address12 high Register */ + GmacAddr12Low = 0x00A4, /* Mac address12 low Register */ + GmacAddr13High = 0x00A8, /* Mac address13 high Register */ + GmacAddr13Low = 0x00AC, /* Mac address13 low Register */ + GmacAddr14High = 0x00B0, /* Mac address14 high Register */ + GmacAddr14Low = 0x00B4, /* Mac address14 low Register */ + GmacAddr15High = 0x00B8, /* Mac address15 high Register */ + GmacAddr15Low = 0x00BC, /* Mac address15 low Register */ + GmacStatus = 0x00d8, /*MAC status*/ + + /*Time Stamp Register Map*/ + GmacTSControl = 0x0700, /* Controls the Timestamp update logic : only when IEEE 1588 time stamping is enabled in corekit */ + + GmacTSSubSecIncr = 0x0704, /* 8 bit value by which sub second register is incremented : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSHigh = 0x0708, /* 32 bit seconds(MS) : only when IEEE 1588 time stamping without external timestamp input */ + GmacTSLow = 0x070C, /* 32 bit nano seconds(MS) : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSHighUpdate = 0x0710, /* 32 bit seconds(MS) to be written/added/subtracted : only when IEEE 1588 time stamping without external timestamp input */ + GmacTSLowUpdate = 0x0714, /* 32 bit nano seconds(MS) to be writeen/added/subtracted : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSAddend = 0x0718, /* Used by Software to readjust the clock frequency linearly : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSTargetTimeHigh = 0x071C, /* 32 bit seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */ + GmacTSTargetTimeLow = 0x0720, /* 32 bit nano seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSHighWord = 0x0724, /* Time Stamp Higher Word Register (Version 2 only); only lower 16 bits are valid */ + //GmacTSHighWordUpdate = 0x072C, /* Time Stamp Higher Word Update Register (Version 2 only); only lower 16 bits are valid */ + + GmacTSStatus = 0x0728, /* Time Stamp Status Register */ +}; + +/********************************************************** + * GMAC Network interface registers + * This explains the Register's Layout + + * FES is Read only by default and is enabled only when Tx + * Config Parameter is enabled for RGMII/SGMII interface + * during CoreKit Config. + + * DM is Read only with value 1'b1 in Full duplex only Config + **********************************************************/ + +/* GmacConfig = 0x0000, Mac config Register Layout */ +enum GmacConfigReg +{ + /* Bit description Bits R/W Reset value */ + GmacWatchdog = 0x00800000, + GmacWatchdogDisable = 0x00800000, /* (WD)Disable watchdog timer on Rx 23 RW */ + GmacWatchdogEnable = 0x00000000, /* Enable watchdog timer 0 */ + + GmacJabber = 0x00400000, + GmacJabberDisable = 0x00400000, /* (JD)Disable jabber timer on Tx 22 RW */ + GmacJabberEnable = 0x00000000, /* Enable jabber timer 0 */ + + GmacFrameBurst = 0x00200000, + GmacFrameBurstEnable = 0x00200000, /* (BE)Enable frame bursting during Tx 21 RW */ + GmacFrameBurstDisable = 0x00000000, /* Disable frame bursting 0 */ + + GmacJumboFrame = 0x00100000, + GmacJumboFrameEnable = 0x00100000, /* (JE)Enable jumbo frame for Tx 20 RW */ + GmacJumboFrameDisable = 0x00000000, /* Disable jumbo frame 0 */ + + GmacInterFrameGap7 = 0x000E0000, /* (IFG) Config7 - 40 bit times 19:17 RW */ + GmacInterFrameGap6 = 0x000C0000, /* (IFG) Config6 - 48 bit times */ + GmacInterFrameGap5 = 0x000A0000, /* (IFG) Config5 - 56 bit times */ + GmacInterFrameGap4 = 0x00080000, /* (IFG) Config4 - 64 bit times */ + GmacInterFrameGap3 = 0x00040000, /* (IFG) Config3 - 72 bit times */ + GmacInterFrameGap2 = 0x00020000, /* (IFG) Config2 - 80 bit times */ + GmacInterFrameGap1 = 0x00010000, /* (IFG) Config1 - 88 bit times */ + GmacInterFrameGap0 = 0x00000000, /* (IFG) Config0 - 96 bit times 000 */ + + GmacDisableCrs = 0x00010000, + GmacMiiGmii = 0x00008000, + GmacSelectMii = 0x00008000, /* (PS)Port Select-MII mode 15 RW */ + GmacSelectGmii = 0x00000000, /* GMII mode 0 */ + + GmacFESpeed100 = 0x00004000, /*(FES)Fast Ethernet speed 100Mbps 14 RW */ + GmacFESpeed10 = 0x00000000, /* 10Mbps 0 */ + + GmacRxOwn = 0x00002000, + GmacDisableRxOwn = 0x00002000, /* (DO)Disable receive own packets 13 RW */ + GmacEnableRxOwn = 0x00000000, /* Enable receive own packets 0 */ + + GmacLoopback = 0x00001000, + GmacLoopbackOn = 0x00001000, /* (LM)Loopback mode for GMII/MII 12 RW */ + GmacLoopbackOff = 0x00000000, /* Normal mode 0 */ + + GmacDuplex = 0x00000800, + GmacFullDuplex = 0x00000800, /* (DM)Full duplex mode 11 RW */ + GmacHalfDuplex = 0x00000000, /* Half duplex mode 0 */ + + GmacRxIpcOffload = 0x00000400, /*IPC checksum offload 10 RW 0 */ + + GmacRetry = 0x00000200, + GmacRetryDisable = 0x00000200, /* (DR)Disable Retry 9 RW */ + GmacRetryEnable = 0x00000000, /* Enable retransmission as per BL 0 */ + + GmacLinkUp = 0x00000100, /* (LUD)Link UP 8 RW */ + GmacLinkDown = 0x00000100, /* Link Down 0 */ + + GmacPadCrcStrip = 0x00000080, + GmacPadCrcStripEnable = 0x00000080, /* (ACS) Automatic Pad/Crc strip enable 7 RW */ + GmacPadCrcStripDisable = 0x00000000, /* Automatic Pad/Crc stripping disable 0 */ + + GmacBackoffLimit = 0x00000060, + GmacBackoffLimit3 = 0x00000060, /* (BL)Back-off limit in HD mode 6:5 RW */ + GmacBackoffLimit2 = 0x00000040, /* */ + GmacBackoffLimit1 = 0x00000020, /* */ + GmacBackoffLimit0 = 0x00000000, /* 00 */ + + GmacDeferralCheck = 0x00000010, + GmacDeferralCheckEnable = 0x00000010, /* (DC)Deferral check enable in HD mode 4 RW */ + GmacDeferralCheckDisable = 0x00000000, /* Deferral check disable 0 */ + + GmacTx = 0x00000008, + GmacTxEnable = 0x00000008, /* (TE)Transmitter enable 3 RW */ + GmacTxDisable = 0x00000000, /* Transmitter disable 0 */ + + GmacRx = 0x00000004, + GmacRxEnable = 0x00000004, /* (RE)Receiver enable 2 RW */ + GmacRxDisable = 0x00000000, /* Receiver disable 0 */ +}; + +/* GmacFrameFilter = 0x0004, Mac frame filtering controls Register Layout*/ +enum GmacFrameFilterReg +{ + GmacFilter = 0x80000000, + GmacFilterOff = 0x80000000, /* (RA)Receive all incoming packets 31 RW */ + GmacFilterOn = 0x00000000, /* Receive filtered packets only 0 */ + + GmacHashPerfectFilter = 0x00000400, /*Hash or Perfect Filter enable 10 RW 0 */ + + GmacSrcAddrFilter = 0x00000200, + GmacSrcAddrFilterEnable = 0x00000200, /* (SAF)Source Address Filter enable 9 RW */ + GmacSrcAddrFilterDisable = 0x00000000, /* 0 */ + + GmacSrcInvaAddrFilter = 0x00000100, + GmacSrcInvAddrFilterEn = 0x00000100, /* (SAIF)Inv Src Addr Filter enable 8 RW */ + GmacSrcInvAddrFilterDis = 0x00000000, /* 0 */ + + GmacPassControl = 0x000000C0, + GmacPassControl3 = 0x000000C0, /* (PCS)Forwards ctrl frms that pass AF 7:6 RW */ + GmacPassControl2 = 0x00000080, /* Forwards all control frames */ + GmacPassControl1 = 0x00000040, /* Does not pass control frames */ + GmacPassControl0 = 0x00000000, /* Does not pass control frames 00 */ + + GmacBroadcast = 0x00000020, + GmacBroadcastDisable = 0x00000020, /* (DBF)Disable Rx of broadcast frames 5 RW */ + GmacBroadcastEnable = 0x00000000, /* Enable broadcast frames 0 */ + + GmacMulticastFilter = 0x00000010, + GmacMulticastFilterOff = 0x00000010, /* (PM) Pass all multicast packets 4 RW */ + GmacMulticastFilterOn = 0x00000000, /* Pass filtered multicast packets 0 */ + + GmacDestAddrFilter = 0x00000008, + GmacDestAddrFilterInv = 0x00000008, /* (DAIF)Inverse filtering for DA 3 RW */ + GmacDestAddrFilterNor = 0x00000000, /* Normal filtering for DA 0 */ + + GmacMcastHashFilter = 0x00000004, + GmacMcastHashFilterOn = 0x00000004, /* (HMC)perfom multicast hash filtering 2 RW */ + GmacMcastHashFilterOff = 0x00000000, /* perfect filtering only 0 */ + + GmacUcastHashFilter = 0x00000002, + GmacUcastHashFilterOn = 0x00000002, /* (HUC)Unicast Hash filtering only 1 RW */ + GmacUcastHashFilterOff = 0x00000000, /* perfect filtering only 0 */ + + GmacPromiscuousMode = 0x00000001, + GmacPromiscuousModeOn = 0x00000001, /* Receive all frames 0 RW */ + GmacPromiscuousModeOff = 0x00000000, /* Receive filtered packets only 0 */ +}; + + +/*GmacGmiiAddr = 0x0010, GMII address Register(ext. Phy) Layout */ +enum GmacGmiiAddrReg +{ + GmiiDevMask = 0x0000F800, /* (PA)GMII device address 15:11 RW 0x00 */ + GmiiDevShift = 11, + + GmiiRegMask = 0x000007C0, /* (GR)GMII register in selected Phy 10:6 RW 0x00 */ + GmiiRegShift = 6, + + GmiiCsrClkMask = 0x0000001C, /*CSR Clock bit Mask 4:2 */ + GmiiCsrClk5 = 0x00000014, /* (CR)CSR Clock Range 250-300 MHz 4:2 RW 000 */ + GmiiCsrClk4 = 0x00000010, /* 150-250 MHz */ + GmiiCsrClk3 = 0x0000000C, /* 35-60 MHz */ + GmiiCsrClk2 = 0x00000008, /* 20-35 MHz */ + GmiiCsrClk1 = 0x00000004, /* 100-150 MHz */ + GmiiCsrClk0 = 0x00000000, /* 60-100 MHz */ + + GmiiWrite = 0x00000002, /* (GW)Write to register 1 RW */ + GmiiRead = 0x00000000, /* Read from register 0 */ + + GmiiBusy = 0x00000001, /* (GB)GMII interface is busy 0 RW 0 */ +}; + +/* GmacGmiiData = 0x0014, GMII data Register(ext. Phy) Layout */ +enum GmacGmiiDataReg +{ + GmiiDataMask = 0x0000FFFF, /* (GD)GMII Data 15:0 RW 0x0000 */ +}; + + +/*GmacFlowControl = 0x0018, Flow control Register Layout */ +enum GmacFlowControlReg +{ + GmacPauseTimeMask = 0xFFFF0000, /* (PT) PAUSE TIME field in the control frame 31:16 RW 0x0000 */ + GmacPauseTimeShift = 16, + + GmacPauseLowThresh = 0x00000030, + GmacPauseLowThresh3 = 0x00000030, /* (PLT)thresh for pause tmr 256 slot time 5:4 RW */ + GmacPauseLowThresh2 = 0x00000020, /* 144 slot time */ + GmacPauseLowThresh1 = 0x00000010, /* 28 slot time */ + GmacPauseLowThresh0 = 0x00000000, /* 4 slot time 000 */ + + GmacUnicastPauseFrame = 0x00000008, + GmacUnicastPauseFrameOn = 0x00000008, /* (UP)Detect pause frame with unicast addr. 3 RW */ + GmacUnicastPauseFrameOff = 0x00000000, /* Detect only pause frame with multicast addr. 0 */ + + GmacRxFlowControl = 0x00000004, + GmacRxFlowControlEnable = 0x00000004, /* (RFE)Enable Rx flow control 2 RW */ + GmacRxFlowControlDisable = 0x00000000, /* Disable Rx flow control 0 */ + + GmacTxFlowControl = 0x00000002, + GmacTxFlowControlEnable = 0x00000002, /* (TFE)Enable Tx flow control 1 RW */ + GmacTxFlowControlDisable = 0x00000000, /* Disable flow control 0 */ + + GmacFlowControlBackPressure= 0x00000001, + GmacSendPauseFrame = 0x00000001, /* (FCB/PBA)send pause frm/Apply back pressure 0 RW 0 */ +}; + +/* GmacInterruptStatus = 0x0038, Mac Interrupt ststus register */ +enum GmacInterruptStatusBitDefinition +{ + GmacTSIntSts = 0x00000200, /* set if int generated due to TS (Read Time Stamp Status Register to know details)*/ + GmacMmcRxChksumOffload = 0x00000080, /* set if int generated in MMC RX CHECKSUM OFFLOAD int register */ + GmacMmcTxIntSts = 0x00000040, /* set if int generated in MMC TX Int register */ + GmacMmcRxIntSts = 0x00000020, /* set if int generated in MMC RX Int register */ + GmacMmcIntSts = 0x00000010, /* set if any of the above bit [7:5] is set */ + GmacPmtIntSts = 0x00000008, /* set whenver magic pkt/wake-on-lan frame is received */ + GmacPcsAnComplete = 0x00000004, /* set when AN is complete in TBI/RTBI/SGMIII phy interface */ + GmacPcsLnkStsChange = 0x00000002, /* set if any lnk status change in TBI/RTBI/SGMII interface */ + GmacRgmiiIntSts = 0x00000001, /* set if any change in lnk status of RGMII interface */ + +}; + +/* GmacInterruptMask = 0x003C, Mac Interrupt Mask register */ +enum GmacInterruptMaskBitDefinition +{ + GmacTSIntMask = 0x00000200, /* when set disables the time stamp interrupt generation */ + GmacPmtIntMask = 0x00000008, /* when set Disables the assertion of PMT interrupt */ + GmacPcsAnIntMask = 0x00000004, /* When set disables the assertion of PCS AN complete interrupt */ + GmacPcsLnkStsIntMask = 0x00000002, /* when set disables the assertion of PCS lnk status change interrupt */ + GmacRgmiiIntMask = 0x00000001, /* when set disables the assertion of RGMII int */ +}; + +/********************************************************** + * GMAC DMA registers + * For Pci based system address is BARx + GmaDmaBase + * For any other system translation is done accordingly + **********************************************************/ + +enum DmaRegisters +{ + DmaBusMode = 0x0000, /* CSR0 - Bus Mode Register */ + DmaTxPollDemand = 0x0004, /* CSR1 - Transmit Poll Demand Register */ + DmaRxPollDemand = 0x0008, /* CSR2 - Receive Poll Demand Register */ + DmaRxBaseAddr = 0x000C, /* CSR3 - Receive Descriptor list base address */ + DmaTxBaseAddr = 0x0010, /* CSR4 - Transmit Descriptor list base address */ + DmaStatus = 0x0014, /* CSR5 - Dma status Register */ + DmaControl = 0x0018, /* CSR6 - Dma Operation Mode Register */ + DmaInterrupt = 0x001C, /* CSR7 - Interrupt enable */ + DmaMissedFr = 0x0020, /* CSR8 - Missed Frame & Buffer overflow Counter */ + DmaTxCurrDesc = 0x0048, /* - Current host Tx Desc Register */ + DmaRxCurrDesc = 0x004C, /* - Current host Rx Desc Register */ + DmaTxCurrAddr = 0x0050, /* CSR20 - Current host transmit buffer address */ + DmaRxCurrAddr = 0x0054, /* CSR21 - Current host receive buffer address */ +}; + +/********************************************************** + * DMA Engine registers Layout + **********************************************************/ + +/*DmaBusMode = 0x0000, CSR0 - Bus Mode */ +enum DmaBusModeReg +{ /* Bit description Bits R/W Reset value */ + DmaFixedBurstEnable = 0x00010000, /* (FB)Fixed Burst SINGLE, INCR4, INCR8 or INCR16 16 RW */ + DmaFixedBurstDisable = 0x00000000, /* SINGLE, INCR 0 */ + + DmaTxPriorityRatio11 = 0x00000000, /* (PR)TX:RX DMA priority ratio 1:1 15:14 RW 00 */ + DmaTxPriorityRatio21 = 0x00004000, /* (PR)TX:RX DMA priority ratio 2:1 */ + DmaTxPriorityRatio31 = 0x00008000, /* (PR)TX:RX DMA priority ratio 3:1 */ + DmaTxPriorityRatio41 = 0x0000C000, /* (PR)TX:RX DMA priority ratio 4:1 */ + + DmaBurstLengthx8 = 0x01000000, /* When set mutiplies the PBL by 8 24 RW 0 */ + + DmaBurstLength256 = 0x01002000, /*(DmaBurstLengthx8 | DmaBurstLength32) = 256 [24]:13:8 */ + DmaBurstLength128 = 0x01001000, /*(DmaBurstLengthx8 | DmaBurstLength16) = 128 [24]:13:8 */ + DmaBurstLength64 = 0x01000800, /*(DmaBurstLengthx8 | DmaBurstLength8) = 64 [24]:13:8 */ + DmaBurstLength32 = 0x00002000, /* (PBL) programmable Dma burst length = 32 13:8 RW */ + DmaBurstLength16 = 0x00001000, /* Dma burst length = 16 */ + DmaBurstLength8 = 0x00000800, /* Dma burst length = 8 */ + DmaBurstLength4 = 0x00000400, /* Dma burst length = 4 */ + DmaBurstLength2 = 0x00000200, /* Dma burst length = 2 */ + DmaBurstLength1 = 0x00000100, /* Dma burst length = 1 */ + DmaBurstLength0 = 0x00000000, /* Dma burst length = 0 0x00 */ + + DmaDescriptor8Words = 0x00000080, /* Enh Descriptor works 1=> 8 word descriptor 7 0 */ + DmaDescriptor4Words = 0x00000000, /* Enh Descriptor works 0=> 4 word descriptor 7 0 */ + + DmaDescriptorSkip16 = 0x00000040, /* (DSL)Descriptor skip length (no.of dwords) 6:2 RW */ + DmaDescriptorSkip8 = 0x00000020, /* between two unchained descriptors */ + DmaDescriptorSkip4 = 0x00000010, /* */ + DmaDescriptorSkip2 = 0x00000008, /* */ + DmaDescriptorSkip1 = 0x00000004, /* */ + DmaDescriptorSkip0 = 0x00000000, /* 0x00 */ + + DmaArbitRr = 0x00000000, /* (DA) DMA RR arbitration 1 RW 0 */ + DmaArbitPr = 0x00000002, /* Rx has priority over Tx */ + + DmaResetOn = 0x00000001, /* (SWR)Software Reset DMA engine 0 RW */ + DmaResetOff = 0x00000000, /* 0 */ +}; + + +/*DmaStatus = 0x0014, CSR5 - Dma status Register */ +enum DmaStatusReg +{ + /*Bit 28 27 and 26 indicate whether the interrupt due to PMT GMACMMC or GMAC LINE Remaining bits are DMA interrupts*/ + GmacPmtIntr = 0x10000000, /* (GPI)Gmac subsystem interrupt 28 RO 0 */ + GmacMmcIntr = 0x08000000, /* (GMI)Gmac MMC subsystem interrupt 27 RO 0 */ + GmacLineIntfIntr = 0x04000000, /* Line interface interrupt 26 RO 0 */ + + DmaErrorBit2 = 0x02000000, /* (EB)Error bits 0-data buffer, 1-desc. access 25 RO 0 */ + DmaErrorBit1 = 0x01000000, /* (EB)Error bits 0-write trnsf, 1-read transfr 24 RO 0 */ + DmaErrorBit0 = 0x00800000, /* (EB)Error bits 0-Rx DMA, 1-Tx DMA 23 RO 0 */ + + DmaTxState = 0x00700000, /* (TS)Transmit process state 22:20 RO */ + DmaTxStopped = 0x00000000, /* Stopped - Reset or Stop Tx Command issued 000 */ + DmaTxFetching = 0x00100000, /* Running - fetching the Tx descriptor */ + DmaTxWaiting = 0x00200000, /* Running - waiting for status */ + DmaTxReading = 0x00300000, /* Running - reading the data from host memory */ + DmaTxSuspended = 0x00600000, /* Suspended - Tx Descriptor unavailabe */ + DmaTxClosing = 0x00700000, /* Running - closing Rx descriptor */ + + DmaRxState = 0x000E0000, /* (RS)Receive process state 19:17 RO */ + DmaRxStopped = 0x00000000, /* Stopped - Reset or Stop Rx Command issued 000 */ + DmaRxFetching = 0x00020000, /* Running - fetching the Rx descriptor */ + DmaRxWaiting = 0x00060000, /* Running - waiting for packet */ + DmaRxSuspended = 0x00080000, /* Suspended - Rx Descriptor unavailable */ + DmaRxClosing = 0x000A0000, /* Running - closing descriptor */ + DmaRxQueuing = 0x000E0000, /* Running - queuing the recieve frame into host memory */ + + DmaIntNormal = 0x00010000, /* (NIS)Normal interrupt summary 16 RW 0 */ + DmaIntAbnormal = 0x00008000, /* (AIS)Abnormal interrupt summary 15 RW 0 */ + + DmaIntEarlyRx = 0x00004000, /* Early receive interrupt (Normal) RW 0 */ + DmaIntBusError = 0x00002000, /* Fatal bus error (Abnormal) RW 0 */ + DmaIntEarlyTx = 0x00000400, /* Early transmit interrupt (Abnormal) RW 0 */ + DmaIntRxWdogTO = 0x00000200, /* Receive Watchdog Timeout (Abnormal) RW 0 */ + DmaIntRxStopped = 0x00000100, /* Receive process stopped (Abnormal) RW 0 */ + DmaIntRxNoBuffer = 0x00000080, /* Receive buffer unavailable (Abnormal) RW 0 */ + DmaIntRxCompleted = 0x00000040, /* Completion of frame reception (Normal) RW 0 */ + DmaIntTxUnderflow = 0x00000020, /* Transmit underflow (Abnormal) RW 0 */ + DmaIntRcvOverflow = 0x00000010, /* Receive Buffer overflow interrupt RW 0 */ + DmaIntTxJabberTO = 0x00000008, /* Transmit Jabber Timeout (Abnormal) RW 0 */ + DmaIntTxNoBuffer = 0x00000004, /* Transmit buffer unavailable (Normal) RW 0 */ + DmaIntTxStopped = 0x00000002, /* Transmit process stopped (Abnormal) RW 0 */ + DmaIntTxCompleted = 0x00000001, /* Transmit completed (Normal) RW 0 */ +}; + +/*DmaControl = 0x0018, CSR6 - Dma Operation Mode Register */ +enum DmaControlReg +{ + DmaDisableDropTcpCs = 0x04000000, /* (DT) Dis. drop. of tcp/ip CS error frames 26 RW 0 */ + + DmaStoreAndForward = 0x02200000, /* (SF)Store and forward 21 RW 0 */ + DmaFlushTxFifo = 0x00100000, /* (FTF)Tx FIFO controller is reset to default 20 RW 0 */ + + DmaTxThreshCtrl = 0x0001C000, /* (TTC)Controls thre Threh of MTL tx Fifo 16:14 RW */ + DmaTxThreshCtrl16 = 0x0001C000, /* (TTC)Controls thre Threh of MTL tx Fifo 16 16:14 RW */ + DmaTxThreshCtrl24 = 0x00018000, /* (TTC)Controls thre Threh of MTL tx Fifo 24 16:14 RW */ + DmaTxThreshCtrl32 = 0x00014000, /* (TTC)Controls thre Threh of MTL tx Fifo 32 16:14 RW */ + DmaTxThreshCtrl40 = 0x00010000, /* (TTC)Controls thre Threh of MTL tx Fifo 40 16:14 RW */ + DmaTxThreshCtrl256 = 0x0000c000, /* (TTC)Controls thre Threh of MTL tx Fifo 256 16:14 RW */ + DmaTxThreshCtrl192 = 0x00008000, /* (TTC)Controls thre Threh of MTL tx Fifo 192 16:14 RW */ + DmaTxThreshCtrl128 = 0x00004000, /* (TTC)Controls thre Threh of MTL tx Fifo 128 16:14 RW */ + DmaTxThreshCtrl64 = 0x00000000, /* (TTC)Controls thre Threh of MTL tx Fifo 64 16:14 RW 000 */ + + DmaTxStart = 0x00002000, /* (ST)Start/Stop transmission 13 RW 0 */ + + DmaRxFlowCtrlDeact = 0x00401800, /* (RFD)Rx flow control deact. threhold [22]:12:11 RW */ + DmaRxFlowCtrlDeact1K = 0x00000000, /* (RFD)Rx flow control deact. threhold (1kbytes) [22]:12:11 RW 00 */ + DmaRxFlowCtrlDeact2K = 0x00000800, /* (RFD)Rx flow control deact. threhold (2kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact3K = 0x00001000, /* (RFD)Rx flow control deact. threhold (3kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact4K = 0x00001800, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact5K = 0x00400000, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact6K = 0x00400800, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact7K = 0x00401000, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + + DmaRxFlowCtrlAct = 0x00800600, /* (RFA)Rx flow control Act. threhold [23]:10:09 RW */ + DmaRxFlowCtrlAct1K = 0x00000000, /* (RFA)Rx flow control Act. threhold (1kbytes) [23]:10:09 RW 00 */ + DmaRxFlowCtrlAct2K = 0x00000200, /* (RFA)Rx flow control Act. threhold (2kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct3K = 0x00000400, /* (RFA)Rx flow control Act. threhold (3kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct4K = 0x00000300, /* (RFA)Rx flow control Act. threhold (4kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct5K = 0x00800000, /* (RFA)Rx flow control Act. threhold (5kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct6K = 0x00800200, /* (RFA)Rx flow control Act. threhold (6kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct7K = 0x00800400, /* (RFA)Rx flow control Act. threhold (7kbytes) [23]:10:09 RW */ + + DmaRxThreshCtrl = 0x00000018, /* (RTC)Controls thre Threh of MTL rx Fifo 4:3 RW */ + DmaRxThreshCtrl64 = 0x00000000, /* (RTC)Controls thre Threh of MTL tx Fifo 64 4:3 RW */ + DmaRxThreshCtrl32 = 0x00000008, /* (RTC)Controls thre Threh of MTL tx Fifo 32 4:3 RW */ + DmaRxThreshCtrl96 = 0x00000010, /* (RTC)Controls thre Threh of MTL tx Fifo 96 4:3 RW */ + DmaRxThreshCtrl128 = 0x00000018, /* (RTC)Controls thre Threh of MTL tx Fifo 128 4:3 RW */ + + DmaEnHwFlowCtrl = 0x00000100, /* (EFC)Enable HW flow control 8 RW */ + DmaDisHwFlowCtrl = 0x00000000, /* Disable HW flow control 0 */ + + DmaFwdErrorFrames = 0x00000080, /* (FEF)Forward error frames 7 RW 0 */ + DmaFwdUnderSzFrames = 0x00000040, /* (FUF)Forward undersize frames 6 RW 0 */ + DmaTxSecondFrame = 0x00000004, /* (OSF)Operate on second frame 4 RW 0 */ + DmaRxStart = 0x00000002, /* (SR)Start/Stop reception 1 RW 0 */ +}; + + +/*DmaInterrupt = 0x001C, CSR7 - Interrupt enable Register Layout */ +enum DmaInterruptReg +{ + DmaIeNormal = DmaIntNormal , /* Normal interrupt enable RW 0 */ + DmaIeAbnormal = DmaIntAbnormal , /* Abnormal interrupt enable RW 0 */ + + DmaIeEarlyRx = DmaIntEarlyRx , /* Early receive interrupt enable RW 0 */ + DmaIeBusError = DmaIntBusError , /* Fatal bus error enable RW 0 */ + DmaIeEarlyTx = DmaIntEarlyTx , /* Early transmit interrupt enable RW 0 */ + DmaIeRxWdogTO = DmaIntRxWdogTO , /* Receive Watchdog Timeout enable RW 0 */ + DmaIeRxStopped = DmaIntRxStopped , /* Receive process stopped enable RW 0 */ + DmaIeRxNoBuffer = DmaIntRxNoBuffer , /* Receive buffer unavailable enable RW 0 */ + DmaIeRxCompleted = DmaIntRxCompleted, /* Completion of frame reception enable RW 0 */ + DmaIeTxUnderflow = DmaIntTxUnderflow, /* Transmit underflow enable RW 0 */ + + DmaIeRxOverflow = DmaIntRcvOverflow, /* Receive Buffer overflow interrupt RW 0 */ + DmaIeTxJabberTO = DmaIntTxJabberTO , /* Transmit Jabber Timeout enable RW 0 */ + DmaIeTxNoBuffer = DmaIntTxNoBuffer , /* Transmit buffer unavailable enable RW 0 */ + DmaIeTxStopped = DmaIntTxStopped , /* Transmit process stopped enable RW 0 */ + DmaIeTxCompleted = DmaIntTxCompleted, /* Transmit completed enable RW 0 */ +}; + + + +/********************************************************** + * DMA Engine descriptors + **********************************************************/ +#ifdef ENH_DESC +/* +**********Enhanced Descritpor structure to support 8K buffer per buffer **************************** + +DmaRxBaseAddr = 0x000C, CSR3 - Receive Descriptor list base address +DmaRxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a +32 bit Data bus is as shown below + +Similarly +DmaTxBaseAddr = 0x0010, CSR4 - Transmit Descriptor list base address +DmaTxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a +32 bit Data bus is as shown below + -------------------------------------------------------------------------- + RDES0 |OWN (31)| Status | + -------------------------------------------------------------------------- + RDES1 | Ctrl | Res | Byte Count Buffer 2 | Ctrl | Res | Byte Count Buffer 1 | + -------------------------------------------------------------------------- + RDES2 | Buffer 1 Address | + -------------------------------------------------------------------------- + RDES3 | Buffer 2 Address / Next Descriptor Address | + -------------------------------------------------------------------------- + + -------------------------------------------------------------------------- + TDES0 |OWN (31)| Ctrl | Res | Ctrl | Res | Status | + -------------------------------------------------------------------------- + TDES1 | Res | Byte Count Buffer 2 | Res | Byte Count Buffer 1 | + -------------------------------------------------------------------------- + TDES2 | Buffer 1 Address | + -------------------------------------------------------------------------- + TDES3 | Buffer 2 Address / Next Descriptor Address | + -------------------------------------------------------------------------- + +*/ + +enum DmaDescriptorStatus /* status word of DMA descriptor */ +{ + DescOwnByDma = 0x80000000, /* (OWN)Descriptor is owned by DMA engine 31 RW */ + + DescDAFilterFail = 0x40000000, /* (AFM)Rx - DA Filter Fail for the rx frame 30 */ + + DescFrameLengthMask = 0x3FFF0000, /* (FL)Receive descriptor frame length 29:16 */ + DescFrameLengthShift = 16, + + DescError = 0x00008000, /* (ES)Error summary bit - OR of the follo. bits: 15 */ + /* DE || OE || IPC || LC || RWT || RE || CE */ + DescRxTruncated = 0x00004000, /* (DE)Rx - no more descriptors for receive frame 14 */ + DescSAFilterFail = 0x00002000, /* (SAF)Rx - SA Filter Fail for the received frame 13 */ + DescRxLengthError = 0x00001000, /* (LE)Rx - frm size not matching with len field 12 */ + DescRxDamaged = 0x00000800, /* (OE)Rx - frm was damaged due to buffer overflow 11 */ + DescRxVLANTag = 0x00000400, /* (VLAN)Rx - received frame is a VLAN frame 10 */ + DescRxFirst = 0x00000200, /* (FS)Rx - first descriptor of the frame 9 */ + DescRxLast = 0x00000100, /* (LS)Rx - last descriptor of the frame 8 */ + DescRxLongFrame = 0x00000080, /* (Giant Frame)Rx - frame is longer than 1518/1522 7 */ + DescRxCollision = 0x00000040, /* (LC)Rx - late collision occurred during reception 6 */ + DescRxFrameEther = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + DescRxWatchdog = 0x00000010, /* (RWT)Rx - watchdog timer expired during reception 4 */ + DescRxMiiError = 0x00000008, /* (RE)Rx - error reported by MII interface 3 */ + DescRxDribbling = 0x00000004, /* (DE)Rx - frame contains non int multiple of 8 bits 2 */ + DescRxCrc = 0x00000002, /* (CE)Rx - CRC error 1 */ +// DescRxMacMatch = 0x00000001, /* (RX MAC Address) Rx mac address reg(1 to 15)match 0 */ + + DescRxEXTsts = 0x00000001, /* Extended Status Available (RDES4) 0 */ + + DescTxIntEnable = 0x40000000, /* (IC)Tx - interrupt on completion 30 */ + DescTxLast = 0x20000000, /* (LS)Tx - Last segment of the frame 29 */ + DescTxFirst = 0x10000000, /* (FS)Tx - First segment of the frame 28 */ + DescTxDisableCrc = 0x08000000, /* (DC)Tx - Add CRC disabled (first segment only) 27 */ + DescTxDisablePadd = 0x04000000, /* (DP)disable padding, added by - reyaz 26 */ + + DescTxCisMask = 0x00c00000, /* Tx checksum offloading control mask 23:22 */ + DescTxCisBypass = 0x00000000, /* Checksum bypass */ + DescTxCisIpv4HdrCs = 0x00400000, /* IPv4 header checksum */ + DescTxCisTcpOnlyCs = 0x00800000, /* TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present */ + DescTxCisTcpPseudoCs = 0x00c00000, /* TCP/UDP/ICMP checksum fully in hardware including pseudo header */ + + TxDescEndOfRing = 0x00200000, /* (TER)End of descriptors ring 21 */ + TxDescChain = 0x00100000, /* (TCH)Second buffer address is chain address 20 */ + + DescRxChkBit0 = 0x00000001, /*() Rx - Rx Payload Checksum Error 0 */ + DescRxChkBit7 = 0x00000080, /* (IPC CS ERROR)Rx - Ipv4 header checksum error 7 */ + DescRxChkBit5 = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + + DescRxTSavail = 0x00000080, /* Time stamp available 7 */ + DescRxFrameType = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + + DescTxIpv4ChkError = 0x00010000, /* (IHE) Tx Ip header error 16 */ + DescTxTimeout = 0x00004000, /* (JT)Tx - Transmit jabber timeout 14 */ + DescTxFrameFlushed = 0x00002000, /* (FF)Tx - DMA/MTL flushed the frame due to SW flush 13 */ + DescTxPayChkError = 0x00001000, /* (PCE) Tx Payload checksum Error 12 */ + DescTxLostCarrier = 0x00000800, /* (LC)Tx - carrier lost during tramsmission 11 */ + DescTxNoCarrier = 0x00000400, /* (NC)Tx - no carrier signal from the tranceiver 10 */ + DescTxLateCollision = 0x00000200, /* (LC)Tx - transmission aborted due to collision 9 */ + DescTxExcCollisions = 0x00000100, /* (EC)Tx - transmission aborted after 16 collisions 8 */ + DescTxVLANFrame = 0x00000080, /* (VF)Tx - VLAN-type frame 7 */ + + DescTxCollMask = 0x00000078, /* (CC)Tx - Collision count 6:3 */ + DescTxCollShift = 3, + + DescTxExcDeferral = 0x00000004, /* (ED)Tx - excessive deferral 2 */ + DescTxUnderflow = 0x00000002, /* (UF)Tx - late data arrival from the memory 1 */ + DescTxDeferred = 0x00000001, /* (DB)Tx - frame transmision deferred 0 */ + + /* + This explains the RDES1/TDES1 bits layout + -------------------------------------------------------------------- + RDES1/TDES1 | Control Bits | Byte Count Buffer 2 | Byte Count Buffer 1 | + -------------------------------------------------------------------- + + */ +// DmaDescriptorLength length word of DMA descriptor + + + RxDisIntCompl = 0x80000000, /* (Disable Rx int on completion) 31 */ + RxDescEndOfRing = 0x00008000, /* (TER)End of descriptors ring 15 */ + RxDescChain = 0x00004000, /* (TCH)Second buffer address is chain address 14 */ + + + DescSize2Mask = 0x1FFF0000, /* (TBS2) Buffer 2 size 28:16 */ + DescSize2Shift = 16, + DescSize1Mask = 0x00001FFF, /* (TBS1) Buffer 1 size 12:0 */ + DescSize1Shift = 0, + + + /* + This explains the RDES4 Extended Status bits layout + -------------------------------------------------------------------- + RDES4 | Extended Status | + -------------------------------------------------------------------- + */ + DescRxPtpAvail = 0x00004000, /* PTP snapshot available 14 */ + DescRxPtpVer = 0x00002000, /* When set indicates IEEE1584 Version 2 (else Ver1) 13 */ + DescRxPtpFrameType = 0x00001000, /* PTP frame type Indicates PTP sent over ethernet 12 */ + DescRxPtpMessageType = 0x00000F00, /* Message Type 11:8 */ + DescRxPtpNo = 0x00000000, /* 0000 => No PTP message received */ + DescRxPtpSync = 0x00000100, /* 0001 => Sync (all clock types) received */ + DescRxPtpFollowUp = 0x00000200, /* 0010 => Follow_Up (all clock types) received */ + DescRxPtpDelayReq = 0x00000300, /* 0011 => Delay_Req (all clock types) received */ + DescRxPtpDelayResp = 0x00000400, /* 0100 => Delay_Resp (all clock types) received */ + DescRxPtpPdelayReq = 0x00000500, /* 0101 => Pdelay_Req (in P to P tras clk) or Announce in Ord and Bound clk */ + DescRxPtpPdelayResp = 0x00000600, /* 0110 => Pdealy_Resp(in P to P trans clk) or Management in Ord and Bound clk */ + DescRxPtpPdelayRespFP = 0x00000700, /* 0111 => Pdealy_Resp_Follow_Up (in P to P trans clk) or Signaling in Ord and Bound clk */ + DescRxPtpIPV6 = 0x00000080, /* Received Packet is in IPV6 Packet 7 */ + DescRxPtpIPV4 = 0x00000040, /* Received Packet is in IPV4 Packet 6 */ + + DescRxChkSumBypass = 0x00000020, /* When set indicates checksum offload engine 5 + is bypassed */ + DescRxIpPayloadError = 0x00000010, /* When set indicates 16bit IP payload CS is in error 4 */ + DescRxIpHeaderError = 0x00000008, /* When set indicates 16bit IPV4 header CS is in 3 + error or IP datagram version is not consistent + with Ethernet type value */ + DescRxIpPayloadType = 0x00000007, /* Indicate the type of payload encapsulated 2:0 + in IPdatagram processed by COE (Rx) */ + DescRxIpPayloadUnknown= 0x00000000, /* Unknown or didnot process IP payload */ + DescRxIpPayloadUDP = 0x00000001, /* UDP */ + DescRxIpPayloadTCP = 0x00000002, /* TCP */ + DescRxIpPayloadICMP = 0x00000003, /* ICMP */ + +}; + +#else +/* + +********** Default Descritpor structure **************************** +DmaRxBaseAddr = 0x000C, CSR3 - Receive Descriptor list base address +DmaRxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a +32 bit Data bus is as shown below + +Similarly +DmaTxBaseAddr = 0x0010, CSR4 - Transmit Descriptor list base address +DmaTxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a +32 bit Data bus is as shown below + -------------------------------------------------------------------- + RDES0/TDES0 |OWN (31)| Status | + -------------------------------------------------------------------- + RDES1/TDES1 | Control Bits | Byte Count Buffer 2 | Byte Count Buffer 1 | + -------------------------------------------------------------------- + RDES2/TDES2 | Buffer 1 Address | + -------------------------------------------------------------------- + RDES3/TDES3 | Buffer 2 Address / Next Descriptor Address | + -------------------------------------------------------------------- +*/ +enum DmaDescriptorStatus /* status word of DMA descriptor */ +{ + DescOwnByDma = 0x80000000, /* (OWN)Descriptor is owned by DMA engine 31 RW */ + + DescDAFilterFail = 0x40000000, /* (AFM)Rx - DA Filter Fail for the rx frame 30 */ + + DescFrameLengthMask = 0x3FFF0000, /* (FL)Receive descriptor frame length 29:16 */ + DescFrameLengthShift = 16, + + DescError = 0x00008000, /* (ES)Error summary bit - OR of the follo. bits: 15 */ + /* DE || OE || IPC || LC || RWT || RE || CE */ + DescRxTruncated = 0x00004000, /* (DE)Rx - no more descriptors for receive frame 14 */ + DescSAFilterFail = 0x00002000, /* (SAF)Rx - SA Filter Fail for the received frame 13 */ + DescRxLengthError = 0x00001000, /* (LE)Rx - frm size not matching with len field 12 */ + DescRxDamaged = 0x00000800, /* (OE)Rx - frm was damaged due to buffer overflow 11 */ + DescRxVLANTag = 0x00000400, /* (VLAN)Rx - received frame is a VLAN frame 10 */ + DescRxFirst = 0x00000200, /* (FS)Rx - first descriptor of the frame 9 */ + DescRxLast = 0x00000100, /* (LS)Rx - last descriptor of the frame 8 */ + DescRxLongFrame = 0x00000080, /* (Giant Frame)Rx - frame is longer than 1518/1522 7 */ + DescRxCollision = 0x00000040, /* (LC)Rx - late collision occurred during reception 6 */ + DescRxFrameEther = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + DescRxWatchdog = 0x00000010, /* (RWT)Rx - watchdog timer expired during reception 4 */ + DescRxMiiError = 0x00000008, /* (RE)Rx - error reported by MII interface 3 */ + DescRxDribbling = 0x00000004, /* (DE)Rx - frame contains non int multiple of 8 bits 2 */ + DescRxCrc = 0x00000002, /* (CE)Rx - CRC error 1 */ + DescRxMacMatch = 0x00000001, /* (RX MAC Address) Rx mac address reg(1 to 15)match 0 */ + + //Rx Descriptor Checksum Offload engine (type 2) encoding + //DescRxPayChkError = 0x00000001, /* () Rx - Rx Payload Checksum Error 0 */ + //DescRxIpv4ChkError = 0x00000080, /* (IPC CS ERROR)Rx - Ipv4 header checksum error 7 */ + + DescRxChkBit0 = 0x00000001, /*() Rx - Rx Payload Checksum Error 0 */ + DescRxChkBit7 = 0x00000080, /* (IPC CS ERROR)Rx - Ipv4 header checksum error 7 */ + DescRxChkBit5 = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + + DescTxIpv4ChkError = 0x00010000, /* (IHE) Tx Ip header error 16 */ + DescTxTimeout = 0x00004000, /* (JT)Tx - Transmit jabber timeout 14 */ + DescTxFrameFlushed = 0x00002000, /* (FF)Tx - DMA/MTL flushed the frame due to SW flush 13 */ + DescTxPayChkError = 0x00001000, /* (PCE) Tx Payload checksum Error 12 */ + DescTxLostCarrier = 0x00000800, /* (LC)Tx - carrier lost during tramsmission 11 */ + DescTxNoCarrier = 0x00000400, /* (NC)Tx - no carrier signal from the tranceiver 10 */ + DescTxLateCollision = 0x00000200, /* (LC)Tx - transmission aborted due to collision 9 */ + DescTxExcCollisions = 0x00000100, /* (EC)Tx - transmission aborted after 16 collisions 8 */ + DescTxVLANFrame = 0x00000080, /* (VF)Tx - VLAN-type frame 7 */ + + DescTxCollMask = 0x00000078, /* (CC)Tx - Collision count 6:3 */ + DescTxCollShift = 3, + + DescTxExcDeferral = 0x00000004, /* (ED)Tx - excessive deferral 2 */ + DescTxUnderflow = 0x00000002, /* (UF)Tx - late data arrival from the memory 1 */ + DescTxDeferred = 0x00000001, /* (DB)Tx - frame transmision deferred 0 */ + + /* + This explains the RDES1/TDES1 bits layout + -------------------------------------------------------------------- + RDES1/TDES1 | Control Bits | Byte Count Buffer 2 | Byte Count Buffer 1 | + -------------------------------------------------------------------- + + */ +//DmaDescriptorLength length word of DMA descriptor + + DescTxIntEnable = 0x80000000, /* (IC)Tx - interrupt on completion 31 */ + DescTxLast = 0x40000000, /* (LS)Tx - Last segment of the frame 30 */ + DescTxFirst = 0x20000000, /* (FS)Tx - First segment of the frame 29 */ + DescTxDisableCrc = 0x04000000, /* (DC)Tx - Add CRC disabled (first segment only) 26 */ + + RxDisIntCompl = 0x80000000, /* (Disable Rx int on completion) 31 */ + RxDescEndOfRing = 0x02000000, /* (TER)End of descriptors ring */ + RxDescChain = 0x01000000, /* (TCH)Second buffer address is chain address 24 */ + + DescTxDisablePadd = 0x00800000, /* (DP)disable padding, added by - reyaz 23 */ + + TxDescEndOfRing = 0x02000000, /* (TER)End of descriptors ring */ + TxDescChain = 0x01000000, /* (TCH)Second buffer address is chain address 24 */ + + DescSize2Mask = 0x003FF800, /* (TBS2) Buffer 2 size 21:11 */ + DescSize2Shift = 11, + DescSize1Mask = 0x000007FF, /* (TBS1) Buffer 1 size 10:0 */ + DescSize1Shift = 0, + + + DescTxCisMask = 0x18000000, /* Tx checksum offloading control mask 28:27 */ + DescTxCisBypass = 0x00000000, /* Checksum bypass */ + DescTxCisIpv4HdrCs = 0x08000000, /* IPv4 header checksum */ + DescTxCisTcpOnlyCs = 0x10000000, /* TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present */ + DescTxCisTcpPseudoCs = 0x18000000, /* TCP/UDP/ICMP checksum fully in hardware including pseudo header */ +}; +#endif + +// Rx Descriptor COE type2 encoding +enum RxDescCOEEncode +{ + RxLenLT600 = 0, /* Bit(5:7:0)=>0 IEEE 802.3 type frame Length field is Lessthan 0x0600 */ + RxIpHdrPayLoadChkBypass = 1, /* Bit(5:7:0)=>1 Payload & Ip header checksum bypassed (unsuppported payload) */ + RxIpHdrPayLoadRes = 2, /* Bit(5:7:0)=>2 Reserved */ + RxChkBypass = 3, /* Bit(5:7:0)=>3 Neither IPv4 nor IPV6. So checksum bypassed */ + RxNoChkError = 4, /* Bit(5:7:0)=>4 No IPv4/IPv6 Checksum error detected */ + RxPayLoadChkError = 5, /* Bit(5:7:0)=>5 Payload checksum error detected for Ipv4/Ipv6 frames */ + RxIpHdrChkError = 6, /* Bit(5:7:0)=>6 Ip header checksum error detected for Ipv4 frames */ + RxIpHdrPayLoadChkError = 7, /* Bit(5:7:0)=>7 Payload & Ip header checksum error detected for Ipv4/Ipv6 frames */ +}; + +/********************************************************** + * DMA engine interrupt handling functions + **********************************************************/ + + enum synopGMACDmaIntEnum /* Intrerrupt types */ +{ + synopGMACDmaRxNormal = 0x01, /* normal receiver interrupt */ + synopGMACDmaRxAbnormal = 0x02, /* abnormal receiver interrupt */ + synopGMACDmaRxStopped = 0x04, /* receiver stopped */ + synopGMACDmaTxNormal = 0x08, /* normal transmitter interrupt */ + synopGMACDmaTxAbnormal = 0x10, /* abnormal transmitter interrupt */ + synopGMACDmaTxStopped = 0x20, /* transmitter stopped */ + synopGMACDmaError = 0x80, /* Dma engine error */ +}; + + +/********************************************************** + * Initial register values + **********************************************************/ +enum InitialRegisters +{ + /* Full-duplex mode with perfect filter on */ + GmacConfigInitFdx1000 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectGmii | GmacEnableRxOwn | GmacLoopbackOff + | GmacFullDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Full-duplex mode with perfect filter on */ + GmacConfigInitFdx110 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectMii | GmacEnableRxOwn | GmacLoopbackOff + | GmacFullDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Full-duplex mode */ + // CHANGED: Pass control config, dest addr filter normal, added source address filter, multicast & unicast + // Hash filter. + /* = GmacFilterOff | GmacPassControlOff | GmacBroadcastEnable */ + GmacFrameFilterInitFdx = GmacFilterOn | GmacPassControl0 | GmacBroadcastEnable | GmacSrcAddrFilterDisable + | GmacMulticastFilterOn | GmacDestAddrFilterNor | GmacMcastHashFilterOff + | GmacPromiscuousModeOff | GmacUcastHashFilterOff, + + /* Full-duplex mode */ + GmacFlowControlInitFdx = GmacUnicastPauseFrameOff | GmacRxFlowControlEnable | GmacTxFlowControlEnable, + + /* Full-duplex mode */ + GmacGmiiAddrInitFdx = GmiiCsrClk2, + + + /* Half-duplex mode with perfect filter on */ + // CHANGED: Removed Endian configuration, added single bit config for PAD/CRC strip, + /*| GmacSelectMii | GmacLittleEndian | GmacDisableRxOwn | GmacLoopbackOff*/ + GmacConfigInitHdx1000 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectGmii | GmacDisableRxOwn | GmacLoopbackOff + | GmacHalfDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Half-duplex mode with perfect filter on */ + GmacConfigInitHdx110 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectMii | GmacDisableRxOwn | GmacLoopbackOff + | GmacHalfDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Half-duplex mode */ + GmacFrameFilterInitHdx = GmacFilterOn | GmacPassControl0 | GmacBroadcastEnable | GmacSrcAddrFilterDisable + | GmacMulticastFilterOn | GmacDestAddrFilterNor | GmacMcastHashFilterOff + | GmacUcastHashFilterOff| GmacPromiscuousModeOff, + + /* Half-duplex mode */ + GmacFlowControlInitHdx = GmacUnicastPauseFrameOff | GmacRxFlowControlDisable | GmacTxFlowControlDisable, + + /* Half-duplex mode */ + GmacGmiiAddrInitHdx = GmiiCsrClk2, + + + + /********************************************** + *DMA configurations + **********************************************/ + + DmaBusModeInit = DmaFixedBurstEnable | DmaBurstLength8 | DmaDescriptorSkip2 | DmaResetOff, +// DmaBusModeInit = DmaFixedBurstEnable | DmaBurstLength8 | DmaDescriptorSkip4 | DmaResetOff, + + /* 1000 Mb/s mode */ + DmaControlInit1000 = DmaStoreAndForward,// | DmaTxSecondFrame , + + /* 100 Mb/s mode */ + DmaControlInit100 = DmaStoreAndForward, + + /* 10 Mb/s mode */ + DmaControlInit10 = DmaStoreAndForward, + + /* Interrupt groups */ + DmaIntErrorMask = DmaIntBusError, /* Error */ + DmaIntRxAbnMask = DmaIntRxNoBuffer, /* receiver abnormal interrupt */ + DmaIntRxNormMask = DmaIntRxCompleted, /* receiver normal interrupt */ + DmaIntRxStoppedMask = DmaIntRxStopped, /* receiver stopped */ + DmaIntTxAbnMask = DmaIntTxUnderflow, /* transmitter abnormal interrupt */ + DmaIntTxNormMask = DmaIntTxCompleted, /* transmitter normal interrupt */ + DmaIntTxStoppedMask = DmaIntTxStopped, /* transmitter stopped */ + + DmaIntEnable = DmaIeNormal | DmaIeAbnormal | DmaIntErrorMask +//DmaIntEnable = DmaIeNormal | DmaIntErrorMask + | DmaIntRxAbnMask | DmaIntRxNormMask | DmaIntRxStoppedMask +// | DmaIntRxNormMask | DmaIntRxStoppedMask + | DmaIntTxAbnMask | DmaIntTxNormMask | DmaIntTxStoppedMask, + DmaIntDisable = 0, +}; + + +/********************************************************** + * Mac Management Counters (MMC) + **********************************************************/ + +enum MMC_ENABLE +{ + GmacMmcCntrl = 0x0100, /* mmc control for operating mode of MMC */ + GmacMmcIntrRx = 0x0104, /* maintains interrupts generated by rx counters */ + GmacMmcIntrTx = 0x0108, /* maintains interrupts generated by tx counters */ + GmacMmcIntrMaskRx = 0x010C, /* mask for interrupts generated from rx counters */ + GmacMmcIntrMaskTx = 0x0110, /* mask for interrupts generated from tx counters */ +}; +enum MMC_TX +{ + GmacMmcTxOctetCountGb = 0x0114, /*Bytes Tx excl. of preamble and retried bytes (Good or Bad) */ + GmacMmcTxFrameCountGb = 0x0118, /*Frames Tx excl. of retried frames (Good or Bad) */ + GmacMmcTxBcFramesG = 0x011C, /*Broadcast Frames Tx (Good) */ + GmacMmcTxMcFramesG = 0x0120, /*Multicast Frames Tx (Good) */ + + GmacMmcTx64OctetsGb = 0x0124, /*Tx with len 64 bytes excl. of pre and retried (Good or Bad) */ + GmacMmcTx65To127OctetsGb = 0x0128, /*Tx with len >64 bytes <=127 excl. of pre and retried (Good or Bad) */ + GmacMmcTx128To255OctetsGb = 0x012C, /*Tx with len >128 bytes <=255 excl. of pre and retried (Good or Bad) */ + GmacMmcTx256To511OctetsGb = 0x0130, /*Tx with len >256 bytes <=511 excl. of pre and retried (Good or Bad) */ + GmacMmcTx512To1023OctetsGb = 0x0134, /*Tx with len >512 bytes <=1023 excl. of pre and retried (Good or Bad) */ + GmacMmcTx1024ToMaxOctetsGb = 0x0138, /*Tx with len >1024 bytes <=MaxSize excl. of pre and retried (Good or Bad) */ + + GmacMmcTxUcFramesGb = 0x013C, /*Unicast Frames Tx (Good or Bad) */ + GmacMmcTxMcFramesGb = 0x0140, /*Multicast Frames Tx (Good and Bad) */ + GmacMmcTxBcFramesGb = 0x0144, /*Broadcast Frames Tx (Good and Bad) */ + GmacMmcTxUnderFlowError = 0x0148, /*Frames aborted due to Underflow error */ + GmacMmcTxSingleColG = 0x014C, /*Successfully Tx Frames after singel collision in Half duplex mode */ + GmacMmcTxMultiColG = 0x0150, /*Successfully Tx Frames after more than singel collision in Half duplex mode */ + GmacMmcTxDeferred = 0x0154, /*Successfully Tx Frames after a deferral in Half duplex mode */ + GmacMmcTxLateCol = 0x0158, /*Frames aborted due to late collision error */ + GmacMmcTxExessCol = 0x015C, /*Frames aborted due to excessive (16) collision errors */ + GmacMmcTxCarrierError = 0x0160, /*Frames aborted due to carrier sense error (No carrier or Loss of carrier) */ + GmacMmcTxOctetCountG = 0x0164, /*Bytes Tx excl. of preamble and retried bytes (Good) */ + GmacMmcTxFrameCountG = 0x0168, /*Frames Tx (Good) */ + GmacMmcTxExessDef = 0x016C, /*Frames aborted due to excessive deferral errors (deferred for more than 2 max-sized frame times)*/ + + GmacMmcTxPauseFrames = 0x0170, /*Number of good pause frames Tx. */ + GmacMmcTxVlanFramesG = 0x0174, /*Number of good Vlan frames Tx excl. retried frames */ +}; +enum MMC_RX +{ + GmacMmcRxFrameCountGb = 0x0180, /*Frames Rx (Good or Bad) */ + GmacMmcRxOctetCountGb = 0x0184, /*Bytes Rx excl. of preamble and retried bytes (Good or Bad) */ + GmacMmcRxOctetCountG = 0x0188, /*Bytes Rx excl. of preamble and retried bytes (Good) */ + GmacMmcRxBcFramesG = 0x018C, /*Broadcast Frames Rx (Good) */ + GmacMmcRxMcFramesG = 0x0190, /*Multicast Frames Rx (Good) */ + + GmacMmcRxCrcError = 0x0194, /*Number of frames received with CRC error */ + GmacMmcRxAlignError = 0x0198, /*Number of frames received with alignment (dribble) error. Only in 10/100mode */ + GmacMmcRxRuntError = 0x019C, /*Number of frames received with runt (<64 bytes and CRC error) error */ + GmacMmcRxJabberError = 0x01A0, /*Number of frames rx with jabber (>1518/1522 or >9018/9022 and CRC) */ + GmacMmcRxUnderSizeG = 0x01A4, /*Number of frames received with <64 bytes without any error */ + GmacMmcRxOverSizeG = 0x01A8, /*Number of frames received with >1518/1522 bytes without any error */ + + GmacMmcRx64OctetsGb = 0x01AC, /*Rx with len 64 bytes excl. of pre and retried (Good or Bad) */ + GmacMmcRx65To127OctetsGb = 0x01B0, /*Rx with len >64 bytes <=127 excl. of pre and retried (Good or Bad) */ + GmacMmcRx128To255OctetsGb = 0x01B4, /*Rx with len >128 bytes <=255 excl. of pre and retried (Good or Bad) */ + GmacMmcRx256To511OctetsGb = 0x01B8, /*Rx with len >256 bytes <=511 excl. of pre and retried (Good or Bad) */ + GmacMmcRx512To1023OctetsGb = 0x01BC, /*Rx with len >512 bytes <=1023 excl. of pre and retried (Good or Bad) */ + GmacMmcRx1024ToMaxOctetsGb = 0x01C0, /*Rx with len >1024 bytes <=MaxSize excl. of pre and retried (Good or Bad) */ + + GmacMmcRxUcFramesG = 0x01C4, /*Unicast Frames Rx (Good) */ + GmacMmcRxLengthError = 0x01C8, /*Number of frames received with Length type field != frame size */ + GmacMmcRxOutOfRangeType = 0x01CC, /*Number of frames received with length field != valid frame size */ + + GmacMmcRxPauseFrames = 0x01D0, /*Number of good pause frames Rx. */ + GmacMmcRxFifoOverFlow = 0x01D4, /*Number of missed rx frames due to FIFO overflow */ + GmacMmcRxVlanFramesGb = 0x01D8, /*Number of good Vlan frames Rx */ + + GmacMmcRxWatchdobError = 0x01DC, /*Number of frames rx with error due to watchdog timeout error */ +}; +enum MMC_IP_RELATED +{ + GmacMmcRxIpcIntrMask = 0x0200, /*Maintains the mask for interrupt generated from rx IPC statistic counters */ + GmacMmcRxIpcIntr = 0x0208, /*Maintains the interrupt that rx IPC statistic counters generate */ + + GmacMmcRxIpV4FramesG = 0x0210, /*Good IPV4 datagrams received */ + GmacMmcRxIpV4HdrErrFrames = 0x0214, /*Number of IPV4 datagrams received with header errors */ + GmacMmcRxIpV4NoPayFrames = 0x0218, /*Number of IPV4 datagrams received which didnot have TCP/UDP/ICMP payload */ + GmacMmcRxIpV4FragFrames = 0x021C, /*Number of IPV4 datagrams received with fragmentation */ + GmacMmcRxIpV4UdpChkDsblFrames = 0x0220, /*Number of IPV4 datagrams received that had a UDP payload checksum disabled */ + + GmacMmcRxIpV6FramesG = 0x0224, /*Good IPV6 datagrams received */ + GmacMmcRxIpV6HdrErrFrames = 0x0228, /*Number of IPV6 datagrams received with header errors */ + GmacMmcRxIpV6NoPayFrames = 0x022C, /*Number of IPV6 datagrams received which didnot have TCP/UDP/ICMP payload */ + + GmacMmcRxUdpFramesG = 0x0230, /*Number of good IP datagrams with good UDP payload */ + GmacMmcRxUdpErrorFrames = 0x0234, /*Number of good IP datagrams with UDP payload having checksum error */ + + GmacMmcRxTcpFramesG = 0x0238, /*Number of good IP datagrams with good TDP payload */ + GmacMmcRxTcpErrorFrames = 0x023C, /*Number of good IP datagrams with TCP payload having checksum error */ + + GmacMmcRxIcmpFramesG = 0x0240, /*Number of good IP datagrams with good Icmp payload */ + GmacMmcRxIcmpErrorFrames = 0x0244, /*Number of good IP datagrams with Icmp payload having checksum error */ + + GmacMmcRxIpV4OctetsG = 0x0250, /*Good IPV4 datagrams received excl. Ethernet hdr,FCS,Pad,Ip Pad bytes */ + GmacMmcRxIpV4HdrErrorOctets = 0x0254, /*Number of bytes in IPV4 datagram with header errors */ + GmacMmcRxIpV4NoPayOctets = 0x0258, /*Number of bytes in IPV4 datagram with no TCP/UDP/ICMP payload */ + GmacMmcRxIpV4FragOctets = 0x025C, /*Number of bytes received in fragmented IPV4 datagrams */ + GmacMmcRxIpV4UdpChkDsblOctets = 0x0260, /*Number of bytes received in UDP segment that had UDP checksum disabled */ + + GmacMmcRxIpV6OctetsG = 0x0264, /*Good IPV6 datagrams received excl. Ethernet hdr,FCS,Pad,Ip Pad bytes */ + GmacMmcRxIpV6HdrErrorOctets = 0x0268, /*Number of bytes in IPV6 datagram with header errors */ + GmacMmcRxIpV6NoPayOctets = 0x026C, /*Number of bytes in IPV6 datagram with no TCP/UDP/ICMP payload */ + + GmacMmcRxUdpOctetsG = 0x0270, /*Number of bytes in IP datagrams with good UDP payload */ + GmacMmcRxUdpErrorOctets = 0x0274, /*Number of bytes in IP datagrams with UDP payload having checksum error */ + + GmacMmcRxTcpOctetsG = 0x0278, /*Number of bytes in IP datagrams with good TDP payload */ + GmacMmcRxTcpErrorOctets = 0x027C, /*Number of bytes in IP datagrams with TCP payload having checksum error */ + + GmacMmcRxIcmpOctetsG = 0x0280, /*Number of bytes in IP datagrams with good Icmp payload */ + GmacMmcRxIcmpErrorOctets = 0x0284, /*Number of bytes in IP datagrams with Icmp payload having checksum error */ +}; + + +enum MMC_CNTRL_REG_BIT_DESCRIPTIONS +{ + GmacMmcCounterFreeze = 0x00000008, /* when set MMC counters freeze to current value */ + GmacMmcCounterResetOnRead = 0x00000004, /* when set MMC counters will be reset to 0 after read */ + GmacMmcCounterStopRollover = 0x00000002, /* when set counters will not rollover after max value */ + GmacMmcCounterReset = 0x00000001, /* when set all counters wil be reset (automatically cleared after 1 clk) */ + +}; + +enum MMC_RX_INTR_MASK_AND_STATUS_BIT_DESCRIPTIONS +{ + GmacMmcRxWDInt = 0x00800000, /* set when rxwatchdog error reaches half of max value */ + GmacMmcRxVlanInt = 0x00400000, /* set when GmacMmcRxVlanFramesGb counter reaches half of max value */ + GmacMmcRxFifoOverFlowInt = 0x00200000, /* set when GmacMmcRxFifoOverFlow counter reaches half of max value */ + GmacMmcRxPauseFrameInt = 0x00100000, /* set when GmacMmcRxPauseFrames counter reaches half of max value */ + GmacMmcRxOutOfRangeInt = 0x00080000, /* set when GmacMmcRxOutOfRangeType counter reaches half of max value */ + GmacMmcRxLengthErrorInt = 0x00040000, /* set when GmacMmcRxLengthError counter reaches half of max value */ + GmacMmcRxUcFramesInt = 0x00020000, /* set when GmacMmcRxUcFramesG counter reaches half of max value */ + GmacMmcRx1024OctInt = 0x00010000, /* set when GmacMmcRx1024ToMaxOctetsGb counter reaches half of max value */ + GmacMmcRx512OctInt = 0x00008000, /* set when GmacMmcRx512To1023OctetsGb counter reaches half of max value */ + GmacMmcRx256OctInt = 0x00004000, /* set when GmacMmcRx256To511OctetsGb counter reaches half of max value */ + GmacMmcRx128OctInt = 0x00002000, /* set when GmacMmcRx128To255OctetsGb counter reaches half of max value */ + GmacMmcRx65OctInt = 0x00001000, /* set when GmacMmcRx65To127OctetsG counter reaches half of max value */ + GmacMmcRx64OctInt = 0x00000800, /* set when GmacMmcRx64OctetsGb counter reaches half of max value */ + GmacMmcRxOverSizeInt = 0x00000400, /* set when GmacMmcRxOverSizeG counter reaches half of max value */ + GmacMmcRxUnderSizeInt = 0x00000200, /* set when GmacMmcRxUnderSizeG counter reaches half of max value */ + GmacMmcRxJabberErrorInt = 0x00000100, /* set when GmacMmcRxJabberError counter reaches half of max value */ + GmacMmcRxRuntErrorInt = 0x00000080, /* set when GmacMmcRxRuntError counter reaches half of max value */ + GmacMmcRxAlignErrorInt = 0x00000040, /* set when GmacMmcRxAlignError counter reaches half of max value */ + GmacMmcRxCrcErrorInt = 0x00000020, /* set when GmacMmcRxCrcError counter reaches half of max value */ + GmacMmcRxMcFramesInt = 0x00000010, /* set when GmacMmcRxMcFramesG counter reaches half of max value */ + GmacMmcRxBcFramesInt = 0x00000008, /* set when GmacMmcRxBcFramesG counter reaches half of max value */ + GmacMmcRxOctetGInt = 0x00000004, /* set when GmacMmcRxOctetCountG counter reaches half of max value */ + GmacMmcRxOctetGbInt = 0x00000002, /* set when GmacMmcRxOctetCountGb counter reaches half of max value */ + GmacMmcRxFrameInt = 0x00000001, /* set when GmacMmcRxFrameCountGb counter reaches half of max value */ +}; + +enum MMC_TX_INTR_MASK_AND_STATUS_BIT_DESCRIPTIONS +{ + + GmacMmcTxVlanInt = 0x01000000, /* set when GmacMmcTxVlanFramesG counter reaches half of max value */ + GmacMmcTxPauseFrameInt = 0x00800000, /* set when GmacMmcTxPauseFrames counter reaches half of max value */ + GmacMmcTxExessDefInt = 0x00400000, /* set when GmacMmcTxExessDef counter reaches half of max value */ + GmacMmcTxFrameInt = 0x00200000, /* set when GmacMmcTxFrameCount counter reaches half of max value */ + GmacMmcTxOctetInt = 0x00100000, /* set when GmacMmcTxOctetCountG counter reaches half of max value */ + GmacMmcTxCarrierErrorInt = 0x00080000, /* set when GmacMmcTxCarrierError counter reaches half of max value */ + GmacMmcTxExessColInt = 0x00040000, /* set when GmacMmcTxExessCol counter reaches half of max value */ + GmacMmcTxLateColInt = 0x00020000, /* set when GmacMmcTxLateCol counter reaches half of max value */ + GmacMmcTxDeferredInt = 0x00010000, /* set when GmacMmcTxDeferred counter reaches half of max value */ + GmacMmcTxMultiColInt = 0x00008000, /* set when GmacMmcTxMultiColG counter reaches half of max value */ + GmacMmcTxSingleCol = 0x00004000, /* set when GmacMmcTxSingleColG counter reaches half of max value */ + GmacMmcTxUnderFlowErrorInt = 0x00002000, /* set when GmacMmcTxUnderFlowError counter reaches half of max value */ + GmacMmcTxBcFramesGbInt = 0x00001000, /* set when GmacMmcTxBcFramesGb counter reaches half of max value */ + GmacMmcTxMcFramesGbInt = 0x00000800, /* set when GmacMmcTxMcFramesGb counter reaches half of max value */ + GmacMmcTxUcFramesInt = 0x00000400, /* set when GmacMmcTxUcFramesGb counter reaches half of max value */ + GmacMmcTx1024OctInt = 0x00000200, /* set when GmacMmcTx1024ToMaxOctetsGb counter reaches half of max value */ + GmacMmcTx512OctInt = 0x00000100, /* set when GmacMmcTx512To1023OctetsGb counter reaches half of max value */ + GmacMmcTx256OctInt = 0x00000080, /* set when GmacMmcTx256To511OctetsGb counter reaches half of max value */ + GmacMmcTx128OctInt = 0x00000040, /* set when GmacMmcTx128To255OctetsGb counter reaches half of max value */ + GmacMmcTx65OctInt = 0x00000020, /* set when GmacMmcTx65To127OctetsGb counter reaches half of max value */ + GmacMmcTx64OctInt = 0x00000010, /* set when GmacMmcTx64OctetsGb counter reaches half of max value */ + GmacMmcTxMcFramesInt = 0x00000008, /* set when GmacMmcTxMcFramesG counter reaches half of max value */ + GmacMmcTxBcFramesInt = 0x00000004, /* set when GmacMmcTxBcFramesG counter reaches half of max value */ + GmacMmcTxFrameGbInt = 0x00000002, /* set when GmacMmcTxFrameCountGb counter reaches half of max value */ + GmacMmcTxOctetGbInt = 0x00000001, /* set when GmacMmcTxOctetCountGb counter reaches half of max value */ + +}; + + +/********************************************************** + * Power Management (PMT) Block + **********************************************************/ + +/** + * PMT supports the reception of network (remote) wake-up frames and Magic packet frames. + * It generates interrupts for wake-up frames and Magic packets received by GMAC. + * PMT sits in Rx path and is enabled with remote wake-up frame enable and Magic packet enable. + * These enable are in PMT control and Status register and are programmed by apllication. + * + * When power down mode is enabled in PMT, all rx frames are dropped by the core. Core comes + * out of power down mode only when either Magic packe tor a Remote wake-up frame is received + * and the corresponding detection is enabled. + * + * Driver need not be modified to support this feature. Only Api to put the device in to power + * down mode is sufficient + */ + +#define WAKEUP_REG_LENGTH 8 /*This is the reg length for wake up register configuration*/ + +enum GmacPmtCtrlStatusBitDefinition +{ + GmacPmtFrmFilterPtrReset = 0x80000000, /* when set remote wake-up frame filter register pointer to 3'b000 */ + GmacPmtGlobalUnicast = 0x00000200, /* When set enables any unicast packet to be a wake-up frame */ + GmacPmtWakeupFrameReceived = 0x00000040, /* Wake up frame received */ + GmacPmtMagicPktReceived = 0x00000020, /* Magic Packet received */ + GmacPmtWakeupFrameEnable = 0x00000004, /* Wake-up frame enable */ + GmacPmtMagicPktEnable = 0x00000002, /* Magic packet enable */ + GmacPmtPowerDown = 0x00000001, /* Power Down */ +}; + + + + +/********************************************************** + * IEEE 1588-2008 Precision Time Protocol (PTP) Support + **********************************************************/ +enum PTPMessageType +{ + SYNC = 0x0, + Delay_Req = 0x1, + Pdelay_Req = 0x2, + Pdelay_Resp = 0x3, + Follow_up = 0x8, + Delay_Resp = 0x9, + Pdelay_Resp_Follow_Up = 0xA, + Announce = 0xB, + Signaling = 0xC, + Management = 0xD, +}; + + + +typedef struct TimeStampStruct +{ + u32 TSversion; /* PTP Version 1 or PTP version2 */ + u32 TSmessagetype; /* Message type associated with this time stamp */ + + u16 TShighest16; /* Highest 16 bit time stamp value, Valid onley when ADV_TIME_HIGH_WORD configured in corekit */ + u32 TSupper32; /* Most significant 32 bit time stamp value */ + u32 TSlower32; /* Least Significat 32 bit time stamp value */ + +} TimeStamp; + + +/** + * IEEE 1588-2008 is the optional module to support Ethernet frame time stamping. + * Sixty four (+16) bit time stamps are given in each frames transmit and receive status. + * The driver assumes the following + * 1. "IEEE 1588 Time Stamping" "TIME_STAMPING"is ENABLED in corekit + * 2. "IEEE 1588 External Time Stamp Input Enable" "EXT_TIME_STAMPING" is DISABLED in corekit + * 3. "IEEE 1588 Advanced Time Stamp support" "ADV_TIME_STAMPING" is ENABLED in corekit + * 4. "IEEE 1588 Higher Word Register Enable" "ADV_TIME_HIGH_WORD" is ENABLED in corekit + */ + +/* GmacTSControl = 0x0700, Controls the Timestamp update logic : only when IEEE 1588 time stamping is enabled in corekit */ +enum GmacTSControlReg +{ + GmacTSENMACADDR = 0x00040000, /* Enable Mac Addr for PTP filtering 18 RW 0 */ + + GmacTSCLKTYPE = 0x00030000, /* Select the type of clock node 17:16 RW 00 */ + /* + TSCLKTYPE TSMSTRENA TSEVNTENA Messages for wihich TS snapshot is taken + 00/01 X 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP + 00/01 1 0 DELAY_REQ + 00/01 0 1 SYNC + 10 NA 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP + 10 NA 1 SYNC, FOLLOW_UP + 11 NA 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP, PDELAY_REQ, PDELAY_RESP + 11 NA 1 SYNC, PDELAY_REQ, PDELAY_RESP + */ + GmacTSOrdClk = 0x00000000, /* 00=> Ordinary clock*/ + GmacTSBouClk = 0x00010000, /* 01=> Boundary clock*/ + GmacTSEtoEClk = 0x00020000, /* 10=> End-to-End transparent clock*/ + GmacTSPtoPClk = 0x00030000, /* 11=> P-to-P transparent clock*/ + + GmacTSMSTRENA = 0x00008000, /* Ena TS Snapshot for Master Messages 15 RW 0 */ + GmacTSEVNTENA = 0x00004000, /* Ena TS Snapshot for Event Messages 14 RW 0 */ + GmacTSIPV4ENA = 0x00002000, /* Ena TS snapshot for IPv4 13 RW 1 */ + GmacTSIPV6ENA = 0x00001000, /* Ena TS snapshot for IPv6 12 RW 0 */ + GmacTSIPENA = 0x00000800, /* Ena TS snapshot for PTP over E'net 11 RW 0 */ + GmacTSVER2ENA = 0x00000400, /* Ena PTP snooping for version 2 10 RW 0 */ + + GmacTSCTRLSSR = 0x00000200, /* Digital or Binary Rollover 9 RW 0 */ + + GmacTSENALL = 0x00000100, /* Enable TS fro all frames (Ver2 only) 8 RW 0 */ + + GmacTSADDREG = 0x00000020, /* Addend Register Update 5 RW_SC 0 */ + GmacTSUPDT = 0x00000008, /* Time Stamp Update 3 RW_SC 0 */ + GmacTSINT = 0x00000004, /* Time Atamp Initialize 2 RW_SC 0 */ + + GmacTSTRIG = 0x00000010, /* Time stamp interrupt Trigger Enable 4 RW_SC 0 */ + + GmacTSCFUPDT = 0x00000002, /* Time Stamp Fine/Coarse 1 RW 0 */ + GmacTSCUPDTCoarse = 0x00000000, /* 0=> Time Stamp update method is coarse */ + GmacTSCUPDTFine = 0x00000002, /* 1=> Time Stamp update method is fine */ + + GmacTSENA = 0x00000001, /* Time Stamp Enable 0 RW 0 */ +}; + + +/* GmacTSSubSecIncr = 0x0704, 8 bit value by which sub second register is incremented : only when IEEE 1588 time stamping without external timestamp input */ +enum GmacTSSubSecIncrReg +{ + GmacSSINCMsk = 0x000000FF, /* Only Lower 8 bits are valid bits 7:0 RW 00 */ +}; + +/* GmacTSLow = 0x070C, Indicates whether the timestamp low count is positive or negative; for Adv timestamp it is always zero */ +enum GmacTSSign +{ + GmacTSSign = 0x80000000, /* PSNT 31 RW 0 */ + GmacTSPositive = 0x00000000, + GmacTSNegative = 0x80000000, +}; + +/*GmacTargetTimeLow = 0x0718, 32 bit nano seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */ +enum GmacTSLowReg +{ + GmacTSDecThr = 0x3B9AC9FF, /*when TSCTRLSSR is set the max value for GmacTargetTimeLowReg and GmacTimeStampLow register is 0x3B9AC9FF at 1ns precision */ +}; + +/* GmacTSHighWord = 0x0724, Time Stamp Higher Word Register (Version 2 only); only lower 16 bits are valid */ +enum GmacTSHighWordReg +{ + GmacTSHighWordMask = 0x0000FFFF, /* Time Stamp Higher work register has only lower 16 bits valid */ +}; +/*GmacTSStatus = 0x0728, Time Stamp Status Register */ +enum GmacTSStatusReg +{ + GmacTSTargTimeReached = 0x00000002, /* Time Stamp Target Time Reached 1 RO 0 */ + GmacTSSecondsOverflow = 0x00000001, /* Time Stamp Seconds Overflow 0 RO 0 */ +}; + + +/********************************************************** + * Time stamp related functions + **********************************************************/ +void synopGMAC_TS_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_disable(synopGMACdevice *gmacdev); + +void synopGMAC_TS_int_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_int_disable(synopGMACdevice *gmacdev); + +void synopGMAC_TS_mac_addr_filt_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_mac_addr_filt_disable(synopGMACdevice *gmacdev); +void synopGMAC_TS_set_clk_type(synopGMACdevice *gmacdev, u32 clk_type); +void synopGMAC_TS_master_enable(synopGMACdevice *gmacdev); // Only for Ordinary clock and Boundary clock and "Advanced Time Stamp" +void synopGMAC_TS_master_disable(synopGMACdevice *gmacdev); // Only for Ordinary clock and Boundary clock and "Advanced Time Stamp" +void synopGMAC_TS_event_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_event_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV4_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV4_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV6_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV6_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_ptp_over_ethernet_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_ptp_over_ethernet_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_pkt_snoop_ver2(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_pkt_snoop_ver1(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" + +void synopGMAC_TS_digital_rollover_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_binary_rollover_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_all_frames_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_all_frames_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" + +s32 synopGMAC_TS_addend_update(synopGMACdevice *gmacdev, u32 addend_value); +s32 synopGMAC_TS_timestamp_update(synopGMACdevice *gmacdev, u32 high_value, u32 low_value); +s32 synopGMAC_TS_timestamp_init(synopGMACdevice *gmacdev, u32 high_value, u32 low_value); + +void synopGMAC_TS_coarse_update(synopGMACdevice *gmacdev); // Only if "fine correction" enabled +void synopGMAC_TS_fine_update(synopGMACdevice *gmacdev); // Only if "fine correction" enabled + +void synopGMAC_TS_subsecond_init(synopGMACdevice *gmacdev, u32 sub_sec_inc_val); // Update should happen making use of subsecond mask +void synopGMAC_TS_read_timestamp(synopGMACdevice *gmacdev, u16 * higher_sec_val, + u32 * sec_val, u32 * sub_sec_val); // Reads the timestamp low,high and higher(Ver2) registers in the the struct pointer; readonly contents +void synopGMAC_TS_load_target_timestamp(synopGMACdevice *gmacdev, u32 sec_val, u32 sub_sec_val); //Loads the timestamp target register with the values provided + +void synopGMAC_TS_load_timestamp_higher_val(synopGMACdevice *gmacdev, u32 higher_sec_val); +void synopGMAC_TS_read_timestamp_higher_val(synopGMACdevice *gmacdev, u16 * higher_sec_val); +void synopGMAC_TS_read_target_timestamp(synopGMACdevice *gmacdev, u32 * sec_val, u32 * sub_sec_val); //Read the target time stamp register contents + + +/********************************************************** + * Common functions + **********************************************************/ +s32 synopGMAC_set_mdc_clk_div(synopGMACdevice *gmacdev,u32 clk_div_val ); +u32 synopGMAC_get_mdc_clk_div(synopGMACdevice *gmacdev); +s32 synopGMAC_read_phy_reg(u32 RegBase,u32 PhyBase, u32 RegOffset, u16 * data); +s32 synopGMAC_write_phy_reg(u32 RegBase, u32 PhyBase, u32 RegOffset, u16 data); +s32 synopGMAC_phy_loopback(synopGMACdevice *gmacdev, bool loopback); +s32 synopGMAC_read_version (synopGMACdevice * gmacdev) ; +s32 synopGMAC_reset (synopGMACdevice * gmacdev ); +s32 synopGMAC_dma_bus_mode_init(synopGMACdevice * gmacdev, u32 init_value ); +s32 synopGMAC_dma_control_init(synopGMACdevice * gmacdev, u32 init_value ); +void synopGMAC_wd_enable(synopGMACdevice * gmacdev); +void synopGMAC_wd_disable(synopGMACdevice * gmacdev); +void synopGMAC_jab_enable(synopGMACdevice * gmacdev); +void synopGMAC_jab_disable(synopGMACdevice * gmacdev); +void synopGMAC_frame_burst_enable(synopGMACdevice * gmacdev); +void synopGMAC_frame_burst_disable(synopGMACdevice * gmacdev); +void synopGMAC_jumbo_frame_enable(synopGMACdevice * gmacdev); +void synopGMAC_jumbo_frame_disable(synopGMACdevice * gmacdev); +void synopGMAC_select_gmii(synopGMACdevice * gmacdev); +void synopGMAC_select_mii(synopGMACdevice * gmacdev); +void synopGMAC_rx_own_enable(synopGMACdevice * gmacdev); +void synopGMAC_rx_own_disable(synopGMACdevice * gmacdev); +void synopGMAC_loopback_on(synopGMACdevice * gmacdev); +void synopGMAC_loopback_off(synopGMACdevice * gmacdev); +void synopGMAC_set_full_duplex(synopGMACdevice * gmacdev); +void synopGMAC_set_half_duplex(synopGMACdevice * gmacdev); +void synopGMAC_retry_enable(synopGMACdevice * gmacdev); +void synopGMAC_retry_disable(synopGMACdevice * gmacdev); +void synopGMAC_pad_crc_strip_enable(synopGMACdevice * gmacdev); +void synopGMAC_pad_crc_strip_disable(synopGMACdevice * gmacdev); +void synopGMAC_back_off_limit(synopGMACdevice * gmacdev, u32 value); +void synopGMAC_deferral_check_enable(synopGMACdevice * gmacdev); +void synopGMAC_deferral_check_disable(synopGMACdevice * gmacdev); +void synopGMAC_rx_enable(synopGMACdevice * gmacdev); +void synopGMAC_rx_disable(synopGMACdevice * gmacdev); +void synopGMAC_tx_enable(synopGMACdevice * gmacdev); +void synopGMAC_tx_disable(synopGMACdevice * gmacdev); +void synopGMAC_frame_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_frame_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_write_hash_table_high(synopGMACdevice * gmacdev, u32 data); +void synopGMAC_write_hash_table_low(synopGMACdevice * gmacdev, u32 data); +void synopGMAC_hash_perfect_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_Hash_filter_only_enable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_dst_addr_filter_inverse(synopGMACdevice * gmacdev); +void synopGMAC_dst_addr_filter_normal(synopGMACdevice * gmacdev); +void synopGMAC_set_pass_control(synopGMACdevice * gmacdev,u32 passcontrol); +void synopGMAC_broadcast_enable(synopGMACdevice * gmacdev); +void synopGMAC_broadcast_disable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_enable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_disable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_hash_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_hash_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_promisc_enable(synopGMACdevice * gmacdev); +void synopGMAC_promisc_disable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_hash_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_hash_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_pause_frame_detect_enable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_pause_frame_detect_disable(synopGMACdevice * gmacdev); +void synopGMAC_rx_flow_control_enable(synopGMACdevice * gmacdev); +void synopGMAC_rx_flow_control_disable(synopGMACdevice * gmacdev); +void synopGMAC_tx_flow_control_enable(synopGMACdevice * gmacdev); +void synopGMAC_tx_flow_control_disable(synopGMACdevice * gmacdev); +void synopGMAC_tx_activate_flow_control(synopGMACdevice * gmacdev); +void synopGMAC_tx_deactivate_flow_control(synopGMACdevice * gmacdev); +void synopGMAC_pause_control(synopGMACdevice *gmacdev); +s32 synopGMAC_mac_init(synopGMACdevice * gmacdev); +s32 synopGMAC_set_mac_addr(synopGMACdevice *gmacdev, u32 MacHigh, u32 MacLow, u8 *MacAddr ); +s32 synopGMAC_get_mac_addr(synopGMACdevice *gmacdev, u32 MacHigh, u32 MacLow, u8 *MacAddr ); +s32 synopGMAC_attach (synopGMACdevice * gmacdev, u32 macBase, u32 dmaBase, u32 phyBase,u8 *mac_addr); +void synopGMAC_rx_desc_init_ring(DmaDesc *desc, bool last_ring_desc); +void synopGMAC_tx_desc_init_ring(DmaDesc *desc, bool last_ring_desc); +void synopGMAC_rx_desc_init_chain(DmaDesc * desc); +void synopGMAC_tx_desc_init_chain(DmaDesc * desc); +s32 synopGMAC_init_tx_rx_desc_queue(synopGMACdevice *gmacdev); +void synopGMAC_init_rx_desc_base(synopGMACdevice *gmacdev); +void synopGMAC_init_tx_desc_base(synopGMACdevice *gmacdev); +void synopGMAC_set_owner_dma(DmaDesc *desc); +void synopGMAC_set_desc_sof(DmaDesc *desc); +void synopGMAC_set_desc_eof(DmaDesc *desc); +bool synopGMAC_is_sof_in_rx_desc(DmaDesc *desc); +bool synopGMAC_is_eof_in_rx_desc(DmaDesc *desc); +bool synopGMAC_is_da_filter_failed(DmaDesc *desc); +bool synopGMAC_is_sa_filter_failed(DmaDesc *desc); +bool synopGMAC_is_desc_owned_by_dma(DmaDesc *desc); +u32 synopGMAC_get_rx_desc_frame_length(u32 status); +bool synopGMAC_is_desc_valid(u32 status); +bool synopGMAC_is_desc_empty(DmaDesc *desc); +bool synopGMAC_is_rx_desc_valid(u32 status); +bool synopGMAC_is_tx_aborted(u32 status); +bool synopGMAC_is_tx_carrier_error(u32 status); +u32 synopGMAC_get_tx_collision_count(u32 status); +u32 synopGMAC_is_exc_tx_collisions(u32 status); +bool synopGMAC_is_rx_frame_damaged(u32 status); +bool synopGMAC_is_rx_frame_collision(u32 status); +bool synopGMAC_is_rx_crc(u32 status); +bool synopGMAC_is_frame_dribbling_errors(u32 status); +bool synopGMAC_is_rx_frame_length_errors(u32 status); +bool synopGMAC_is_last_rx_desc(synopGMACdevice * gmacdev,DmaDesc *desc); +bool synopGMAC_is_last_tx_desc(synopGMACdevice * gmacdev,DmaDesc *desc); +bool synopGMAC_is_rx_desc_chained(DmaDesc * desc); +bool synopGMAC_is_tx_desc_chained(DmaDesc * desc); +void synopGMAC_get_desc_data(DmaDesc * desc, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Buffer2, u32 * Length2, u32 * Data2); +#ifdef ENH_DESC_8W +s32 synopGMAC_get_tx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Buffer2, u32 * Length2, u32 * Data2, + u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_low); +#else +s32 synopGMAC_get_tx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Buffer2, u32 * Length2, u32 * Data2 ); +#endif +s32 synopGMAC_set_tx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u32 Data1, u32 Buffer2, u32 Length2, u32 Data2,u32 offload_needed,u32 * index,DmaDesc *Dpr); +s32 synopGMAC_set_rx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u32 Data1, u32 Buffer2, u32 Length2, u32 Data2); +#ifdef ENH_DESC_8W +s32 synopGMAC_get_rx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Buffer2, u32 * Length2, u32 * Data2, + u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_low); +#else +s32 synopGMAC_get_rx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Buffer2, u32 * Length2, u32 * Data2); +#endif +void synopGMAC_clear_interrupt(synopGMACdevice *gmacdev); +u32 synopGMAC_get_interrupt_type(synopGMACdevice *gmacdev); +u32 synopGMAC_get_interrupt_mask(synopGMACdevice *gmacdev); +void synopGMAC_enable_interrupt(synopGMACdevice *gmacdev, u32 interrupts); +void synopGMAC_disable_interrupt_all(synopGMACdevice *gmacdev); +void synopGMAC_disable_interrupt(synopGMACdevice *gmacdev, u32 interrupts); +void synopGMAC_enable_dma_rx(synopGMACdevice * gmacdev); +void synopGMAC_enable_dma_tx(synopGMACdevice * gmacdev); +void synopGMAC_resume_dma_tx(synopGMACdevice * gmacdev); +void synopGMAC_resume_dma_rx(synopGMACdevice * gmacdev); +void synopGMAC_take_desc_ownership(DmaDesc * desc); +void synopGMAC_take_desc_ownership_rx(synopGMACdevice * gmacdev); +void synopGMAC_take_desc_ownership_tx(synopGMACdevice * gmacdev); +void synopGMAC_disable_dma_tx(synopGMACdevice * gmacdev); +void synopGMAC_disable_dma_rx(synopGMACdevice * gmacdev); +/******Following APIs are valid only for Enhanced Descriptor from 3.50a release onwards*******/ +bool synopGMAC_is_ext_status(synopGMACdevice *gmacdev,u32 status); +bool synopGMAC_ES_is_IP_header_error(synopGMACdevice *gmacdev,u32 ext_status); +bool synopGMAC_ES_is_rx_checksum_bypassed(synopGMACdevice *gmacdev,u32 ext_status); +bool synopGMAC_ES_is_IP_payload_error(synopGMACdevice *gmacdev,u32 ext_status); +/*******************PMT APIs***************************************/ +void synopGMAC_pmt_int_enable(synopGMACdevice *gmacdev); +void synopGMAC_pmt_int_disable(synopGMACdevice *gmacdev); +void synopGMAC_power_down_enable(synopGMACdevice *gmacdev); +void synopGMAC_power_down_disable(synopGMACdevice *gmacdev); +void synopGMAC_enable_pmt_interrupt(synopGMACdevice *gmacdev); +void synopGMAC_disable_pmt_interrupt(synopGMACdevice *gmacdev); +void synopGMAC_magic_packet_enable(synopGMACdevice *gmacdev); +void synopGMAC_wakeup_frame_enable(synopGMACdevice *gmacdev); +void synopGMAC_pmt_unicast_enable(synopGMACdevice *gmacdev); +bool synopGMAC_is_magic_packet_received(synopGMACdevice *gmacdev); +bool synopGMAC_is_wakeup_frame_received(synopGMACdevice *gmacdev); +void synopGMAC_write_wakeup_frame_register(synopGMACdevice *gmacdev, u32 * filter_contents); +/*******************MMC APIs***************************************/ +void synopGMAC_mmc_counters_stop(synopGMACdevice *gmacdev); +void synopGMAC_mmc_counters_resume(synopGMACdevice *gmacdev); +void synopGMAC_mmc_counters_set_selfclear(synopGMACdevice *gmacdev); +void synopGMAC_mmc_counters_reset_selfclear(synopGMACdevice *gmacdev); +void synopGMAC_mmc_counters_disable_rollover(synopGMACdevice *gmacdev); +void synopGMAC_mmc_counters_enable_rollover(synopGMACdevice *gmacdev); +u32 synopGMAC_read_mmc_counter(synopGMACdevice *gmacdev, u32 counter); +u32 synopGMAC_read_mmc_rx_int_status(synopGMACdevice *gmacdev); +u32 synopGMAC_read_mmc_tx_int_status(synopGMACdevice *gmacdev); +void synopGMAC_disable_mmc_tx_interrupt(synopGMACdevice *gmacdev, u32 mask); +void synopGMAC_enable_mmc_tx_interrupt(synopGMACdevice *gmacdev, u32 mask); +void synopGMAC_disable_mmc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask); +void synopGMAC_enable_mmc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask); +void synopGMAC_enable_mmc_ipc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask); +void synopGMAC_disable_mmc_ipc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask); +/*******************Ip checksum offloading APIs***************************************/ +void synopGMAC_enable_rx_chksum_offload(synopGMACdevice *gmacdev); +void synopGMAC_disable_rx_Ipchecksum_offload(synopGMACdevice *gmacdev); +void synopGMAC_rx_tcpip_chksum_drop_enable(synopGMACdevice *gmacdev); +void synopGMAC_rx_tcpip_chksum_drop_disable(synopGMACdevice *gmacdev); +u32 synopGMAC_is_rx_checksum_error(synopGMACdevice *gmacdev, u32 status); +bool synopGMAC_is_tx_ipv4header_checksum_error(synopGMACdevice *gmacdev, u32 status); +bool synopGMAC_is_tx_payload_checksum_error(synopGMACdevice *gmacdev, u32 status); +void synopGMAC_tx_checksum_offload_bypass(synopGMACdevice *gmacdev, DmaDesc *desc); +void synopGMAC_tx_checksum_offload_ipv4hdr(synopGMACdevice *gmacdev, DmaDesc *desc); +void synopGMAC_tx_checksum_offload_tcponly(synopGMACdevice *gmacdev, DmaDesc *desc); +void synopGMAC_tx_checksum_offload_tcp_pseudo(synopGMACdevice *gmacdev, DmaDesc *desc); + +#endif /* End of file */ diff --git a/bsp/ls1cdev/drivers/net/synopGMAC_Host.h b/bsp/ls1cdev/drivers/net/synopGMAC_Host.h new file mode 100644 index 0000000000..05f289c8c7 --- /dev/null +++ b/bsp/ls1cdev/drivers/net/synopGMAC_Host.h @@ -0,0 +1,88 @@ +/* + * File : synopGMAC_Host.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + +#ifndef SYNOP_GMAC_HOST_H +#define SYNOP_GMAC_HOST_H 1 + + +#include "synopGMAC_plat.h" +#include "synopGMAC_Dev.h" +#include "mii.h" + + + +struct net_device_stats +{ + unsigned long rx_packets; /* total packets received */ + unsigned long tx_packets; /* total packets transmitted */ + unsigned long rx_bytes; /* total bytes received */ + unsigned long tx_bytes; /* total bytes transmitted */ + unsigned long rx_errors; /* bad packets received */ + unsigned long tx_errors; /* packet transmit problems */ + unsigned long rx_dropped; /* no space in linux buffers */ + unsigned long tx_dropped; /* no space available in linux */ + unsigned long multicast; /* multicast packets received */ + unsigned long collisions; + + /* detailed rx_errors: */ + unsigned long rx_length_errors; + unsigned long rx_over_errors; /* receiver ring buff overflow */ + unsigned long rx_crc_errors; /* recved pkt with crc error */ + unsigned long rx_frame_errors; /* recv'd frame alignment error */ + unsigned long rx_fifo_errors; /* recv'r fifo overrun */ + unsigned long rx_missed_errors; /* receiver missed packet */ + + /* detailed tx_errors */ + unsigned long tx_aborted_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; + unsigned long tx_heartbeat_errors; + unsigned long tx_window_errors; + + /* for cslip etc */ + unsigned long rx_compressed; + unsigned long tx_compressed; +}; + + + +typedef struct synopGMACNetworkAdapter{ + +/*Device Dependent Data structur*/ +synopGMACdevice * synopGMACdev; + + +struct net_device_stats synopGMACNetStats; + + +struct mii_if_info mii; +} synopGMACPciNetworkAdapter; + + + + + + +#endif diff --git a/bsp/ls1cdev/drivers/net/synopGMAC_debug.h b/bsp/ls1cdev/drivers/net/synopGMAC_debug.h new file mode 100644 index 0000000000..9e65d1d945 --- /dev/null +++ b/bsp/ls1cdev/drivers/net/synopGMAC_debug.h @@ -0,0 +1,37 @@ +/* + * File : synopGMAC_debug.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +//#define GMAC_DEBUG +#include +#ifdef GMAC_DEBUG +#define DEBUG_MES rt_kprintf +#else +#define DEBUG_MES(...) +#endif + +#endif /*__DEBUG_H__*/ diff --git a/bsp/ls1cdev/drivers/net/synopGMAC_network_interface.h b/bsp/ls1cdev/drivers/net/synopGMAC_network_interface.h new file mode 100644 index 0000000000..5ee8bbf493 --- /dev/null +++ b/bsp/ls1cdev/drivers/net/synopGMAC_network_interface.h @@ -0,0 +1,98 @@ +/** \file + * Header file for the nework dependent functionality. + * The function prototype listed here are linux dependent. + * + * \internal + * ---------------------------REVISION HISTORY------------------- + * Synopsys 01/Aug/2007 Created + */ + +/* + * File : synopGMAC_network_interface.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + +#ifndef SYNOP_GMAC_NETWORK_INTERFACE_H +#define SYNOP_GMAC_NETWORK_INTERFACE_H 1 + +#include "synopGMAC_plat.h" +#include "synopGMAC_Host.h" +#include "synopGMAC_Dev.h" + +//#include +//#include +//#include + + +#define NET_IF_TIMEOUT (10*HZ) +#define CHECK_TIME (HZ) + +s32 synopGMAC_init_network_interface(char* xname,u64 synopGMACMappedAddr); +void synopGMAC_exit_network_interface(void); + +s32 synopGMAC_linux_open(struct eth_device *); +s32 synopGMAC_linux_close(struct eth_device *); +//s32 synopGMAC_linux_xmit_frames(struct ifnet *); +struct net_device_stats * synopGMAC_linux_get_stats(struct synopGMACNetworkAdapter *); +//void synopGMAC_linux_set_multicast_list(struct net_device *); +//s32 synopGMAC_linux_set_mac_address(struct synopGMACNetwokrAdapter*,void *); +//s32 synopGMAC_linux_change_mtu(struct net_device *,s32); +//s32 synopGMAC_linux_do_ioctl(struct ifnet *,struct ifreq *,s32); +//void synopGMAC_linux_tx_timeout(struct net_device *); + +s32 synopGMAC_test(synopGMACdevice * gmacdev_0,synopGMACdevice * gmacdev_1); + +void dumpreg(u64 ); +void dumpphyreg(); + +/* + * gethex(vp,p,n) + * convert n hex digits from p to binary, result in vp, + * rtn 1 on success + */ +static int gethex(u8 *vp, char *p, int n) +{ + u8 v; + int digit; + + for (v = 0; n > 0; n--) { + if (*p == 0) + return (0); + if (*p >= '0' && *p <= '9') + digit = *p - '0'; + else if (*p >= 'a' && *p <= 'f') + digit = *p - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') + digit = *p - 'A' + 10; + else + return (0); + + v <<= 4; + v |= digit; + p++; + } + *vp = v; + return (1); +} + +#endif /* End of file */ diff --git a/bsp/ls1cdev/drivers/net/synopGMAC_plat.c b/bsp/ls1cdev/drivers/net/synopGMAC_plat.c new file mode 100644 index 0000000000..8f70ad99d7 --- /dev/null +++ b/bsp/ls1cdev/drivers/net/synopGMAC_plat.c @@ -0,0 +1,150 @@ +/**\file + * This file defines the wrapper for the platform/OS related functions + * The function definitions needs to be modified according to the platform + * and the Operating system used. + * This file should be handled with greatest care while porting the driver + * to a different platform running different operating system other than + * Linux 2.6.xx. + * \internal + * ----------------------------REVISION HISTORY----------------------------- + * Synopsys 01/Aug/2007 Created + */ + + +/* + * File : synopGMAC_plat.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + +#include "synopGMAC_plat.h" +#include "synopGMAC_Dev.h" +#include +#include +extern void flush_cache(unsigned long start_addr, unsigned long size); +dma_addr_t __attribute__((weak)) gmac_dmamap(unsigned long va,u32 size) +{ + return VA_TO_PA (va); + //return UNCACHED_TO_PHYS(va); +} + + + +/** + * This is a wrapper function for Memory allocation routine. In linux Kernel + * it it kmalloc function + * @param[in] bytes in bytes to allocate + */ + +void *plat_alloc_memory(u32 bytes) +{ +//return (void*)malloc((size_t)bytes, M_DEVBUF, M_DONTWAIT); + void *buf = (void*)rt_malloc((u32)bytes); + + flush_cache((unsigned long)buf, bytes); + return buf; +} + +/** + * This is a wrapper function for consistent dma-able Memory allocation routine. + * In linux Kernel, it depends on pci dev structure + * @param[in] bytes in bytes to allocate + */ + +//void *plat_alloc_consistent_dmaable_memory(struct synopGMACdevice *dev, u32 size, u32 *addr) +void *plat_alloc_consistent_dmaable_memory(synopGMACdevice *pcidev, u32 size, u32 *addr) +{ + void *buf; + buf = (void*)rt_malloc((u32)(size+16)); + //CPU_IOFlushDCache( buf,size, SYNC_W); + unsigned long i = (unsigned long)buf; +// rt_kprintf("size = %d\n", size); +// rt_kprintf("bufaddr = %p\n", buf); +// rt_kprintf("i%%16 == %d\n", i%16); + if(i%16 == 8){ + i += 8; + } + else if(i%16 == 4){ + i += 12; + } + else if(i%16 == 12){ + i += 4; + } + + flush_cache(i, size); + *addr =gmac_dmamap(i, size); + buf = (unsigned char *)CACHED_TO_UNCACHED(i); +// rt_kprintf("bufaddr = %p\n", buf); + return buf; +} + + +/** + * This is a wrapper function for freeing consistent dma-able Memory. + * In linux Kernel, it depends on pci dev structure + * @param[in] bytes in bytes to allocate + */ + + +//void plat_free_consistent_dmaable_memory(void * addr) +void plat_free_consistent_dmaable_memory(synopGMACdevice *pcidev, u32 size, void * addr,u32 dma_addr) +{ + rt_free((void*)PHYS_TO_CACHED(UNCACHED_TO_PHYS(addr))); + return; +} + + + +/** + * This is a wrapper function for Memory free routine. In linux Kernel + * it it kfree function + * @param[in] buffer pointer to be freed + */ +void plat_free_memory(void *buffer) +{ + rt_free(buffer); + return ; +} + + + +dma_addr_t plat_dma_map_single(void *hwdev, void *ptr, + u32 size) +{ + unsigned long addr = (unsigned long) ptr; +//CPU_IOFlushDCache(addr,size, direction); + flush_cache(addr, size); +return gmac_dmamap(addr, size); +} + +/** + * This is a wrapper function for platform dependent delay + * Take care while passing the argument to this function + * @param[in] buffer pointer to be freed + */ +void plat_delay(u32 delay) +{ + while (delay--); + return; +} + + diff --git a/bsp/ls1cdev/drivers/net/synopGMAC_plat.h b/bsp/ls1cdev/drivers/net/synopGMAC_plat.h new file mode 100644 index 0000000000..4809598bfa --- /dev/null +++ b/bsp/ls1cdev/drivers/net/synopGMAC_plat.h @@ -0,0 +1,285 @@ +/**\file + * This file serves as the wrapper for the platform/OS dependent functions + * It is needed to modify these functions accordingly based on the platform and the + * OS. Whenever the synopsys GMAC driver ported on to different platform, this file + * should be handled at most care. + * The corresponding function definitions for non-inline functions are available in + * synopGMAC_plat.c file. + * \internal + * -------------------------------------REVISION HISTORY--------------------------- + * Synopsys 01/Aug/2007 Created + */ + +/* + * File : synopGMAC_plat.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + + +#ifndef SYNOP_GMAC_PLAT_H +#define SYNOP_GMAC_PLAT_H 1 + +/* sw +#include +#include +#include +#include +#include +*/ +#include "synopGMAC_types.h" +#include "synopGMAC_debug.h" +//#include "mii.h" +//#include "GMAC_Pmon.h" +//#include "synopGMAC_Host.h" +#include +//sw: copy the type define into here +#define IOCTL_READ_REGISTER SIOCDEVPRIVATE+1 +#define IOCTL_WRITE_REGISTER SIOCDEVPRIVATE+2 +#define IOCTL_READ_IPSTRUCT SIOCDEVPRIVATE+3 +#define IOCTL_READ_RXDESC SIOCDEVPRIVATE+4 +#define IOCTL_READ_TXDESC SIOCDEVPRIVATE+5 +#define IOCTL_POWER_DOWN SIOCDEVPRIVATE+6 + +#define SYNOP_GMAC0 1 + +typedef int bool; +//typedef unsigned long dma_addr_t; + +//sw +/* write/read MMIO register */ +#define writeb(val, addr) (*(volatile u8*)(addr) = (val)) +#define writew(val, addr) (*(volatile u16*)(addr) = (val)) +#define writel(val, addr) (*(volatile u32*)(addr) = (val)) +#define readb(addr) (*(volatile u8*)(addr)) +#define readw(addr) (*(volatile u16*)(addr)) +#define readl(addr) (*(volatile u32*)(addr)) + + +#define KUSEG_ADDR 0x0 +#define CACHED_MEMORY_ADDR 0x80000000 +#define UNCACHED_MEMORY_ADDR 0xa0000000 +#define KSEG2_ADDR 0xc0000000 +#define MAX_MEM_ADDR 0xbe000000 +#define RESERVED_ADDR 0xbfc80000 + +#define CACHED_TO_PHYS(x) ((unsigned)(x) & 0x7fffffff) +#define PHYS_TO_CACHED(x) ((unsigned)(x) | CACHED_MEMORY_ADDR) +#define UNCACHED_TO_PHYS(x) ((unsigned)(x) & 0x1fffffff) +#define PHYS_TO_UNCACHED(x) ((unsigned)(x) | UNCACHED_MEMORY_ADDR) +#define VA_TO_CINDEX(x) ((unsigned)(x) & 0xffffff | CACHED_MEMORY_ADDR) +#define CACHED_TO_UNCACHED(x) (PHYS_TO_UNCACHED(CACHED_TO_PHYS(x))) + +#define VA_TO_PA(x) UNCACHED_TO_PHYS(x) + + +/* sw +#define TR0(fmt, args...) printk(KERN_CRIT "SynopGMAC: " fmt, ##args) + +#ifdef DEBUG +#undef TR +# define TR(fmt, args...) printk(KERN_CRIT "SynopGMAC: " fmt, ##args) +#else +# define TR(fmt, args...) // not debugging: nothing +#endif +*/ +/* +#define TR0(fmt, args...) printf("SynopGMAC: " fmt, ##args) +*/ + +/* +#ifdef DEBUG +#undef TR +# define TR(fmt, args...) printf("SynopGMAC: " fmt, ##args) +#else +//# define TR(fmt, args...) // not debugging: nothing +#define TR(fmt, args...) printf("SynopGMAC: " fmt, ##args) +#endif +*/ + +//sw: nothing to display +#define TR0(fmt, args...) rt_kprintf(fmt, ##args) +#define TR(fmt, args...) rt_kprintf(fmt, ##args) +//#define TR rt_kprintf + +//typedef int bool; +enum synopGMAC_boolean + { + false = 0, + true = 1 + }; + + +#define DEFAULT_DELAY_VARIABLE 10 +#define DEFAULT_LOOP_VARIABLE 10000 + +/* There are platform related endian conversions + * + */ + +#define LE32_TO_CPU __le32_to_cpu +#define BE32_TO_CPU __be32_to_cpu +#define CPU_TO_LE32 __cpu_to_le32 + +/* Error Codes */ +#define ESYNOPGMACNOERR 0 +#define ESYNOPGMACNOMEM 1 +#define ESYNOPGMACPHYERR 2 +#define ESYNOPGMACBUSY 3 + +struct Network_interface_data +{ + u32 unit; + u32 addr; + u32 data; +}; + + +/** + * These are the wrapper function prototypes for OS/platform related routines + */ + +void * plat_alloc_memory(u32 ); +void plat_free_memory(void *); + +//void * plat_alloc_consistent_dmaable_memory(struct pci_dev *, u32, u32 *); +//void plat_free_consistent_dmaable_memory (struct pci_dev *, u32, void *, u32); + +void plat_delay(u32); + + +/** + * The Low level function to read register contents from Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * \return Returns the register contents + */ +static u32 synopGMACReadReg(u32 RegBase, u32 RegOffset) +{ + u32 addr; + u32 data; + + addr = RegBase + (u32)RegOffset; + data = *(volatile u32 *)addr; + +#if SYNOP_REG_DEBUG + TR("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__, (u32)RegBase, RegOffset, data ); +#endif + // rt_kprintf("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__, (u32)RegBase, RegOffset, data ); + return data; + +} + +/** + * The Low level function to write to a register in Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Data to be written + * \return void + */ +static void synopGMACWriteReg(u32 RegBase, u32 RegOffset, u32 RegData ) +{ + + u32 addr; + + addr = RegBase + (u32)RegOffset; +// rt_kprintf("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__,(u32) RegBase, RegOffset, RegData ); +#if SYNOP_REG_DEBUG + TR("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__,(u32) RegBase, RegOffset, RegData ); +#endif + *(volatile u32 *)addr = RegData; + + if(addr == 0xbfe1100c) + DEBUG_MES("regdata = %08x\n", RegData); + return; +} + +/** + * The Low level function to set bits of a register in Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Bit mask to set bits to logical 1 + * \return void + */ +static void synopGMACSetBits(u32 RegBase, u32 RegOffset, u32 BitPos) +{ + //u64 addr = (u64)RegBase + (u64)RegOffset; + u32 data; + data = synopGMACReadReg(RegBase, RegOffset); + data |= BitPos; + synopGMACWriteReg(RegBase, RegOffset, data); + // writel(data,(void *)addr); +#if SYNOP_REG_DEBUG + TR("%s !!!!!!!!!!!!! RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__, RegOffset, data ); +#endif + return; +} + + +/** + * The Low level function to clear bits of a register in Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Bit mask to clear bits to logical 0 + * \return void + */ +static void synopGMACClearBits(u32 RegBase, u32 RegOffset, u32 BitPos) +{ + u32 data; + data = synopGMACReadReg(RegBase, RegOffset); + data &= (~BitPos); + synopGMACWriteReg(RegBase, RegOffset, data); +#if SYNOP_REG_DEBUG + TR("%s !!!!!!!!!!!!! RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__, RegOffset, data ); +#endif + return; +} + +/** + * The Low level function to Check the setting of the bits. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Bit mask to set bits to logical 1 + * \return returns TRUE if set to '1' returns FALSE if set to '0'. Result undefined there are no bit set in the BitPos argument. + * + */ +static bool synopGMACCheckBits(u32 RegBase, u32 RegOffset, u32 BitPos) +{ + + u32 data; + data = synopGMACReadReg(RegBase, RegOffset); + data &= BitPos; + if(data) return true; + else return false; + +} + + + + + +#endif diff --git a/bsp/ls1cdev/drivers/net/synopGMAC_types.h b/bsp/ls1cdev/drivers/net/synopGMAC_types.h new file mode 100644 index 0000000000..d808bec846 --- /dev/null +++ b/bsp/ls1cdev/drivers/net/synopGMAC_types.h @@ -0,0 +1,39 @@ +/* + * File : synopGMAC_types.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) chinesebear + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-24 chinesebear first version + */ + + + +#ifndef __TYPES__H +#define __TYPES__H + +typedef unsigned char uint8_t; +typedef unsigned long long u64; +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; +typedef signed int s32; + +typedef u32 dma_addr_t; + +#endif /*__TYPES__H*/ diff --git a/bsp/ls1cdev/rtconfig.h b/bsp/ls1cdev/rtconfig.h index 410fd29254..99bb973b90 100644 --- a/bsp/ls1cdev/rtconfig.h +++ b/bsp/ls1cdev/rtconfig.h @@ -131,15 +131,21 @@ // // #define RT_USING_DFS_NFS // -#define RT_NFS_HOST_EXPORT "192.168.3.108:/" +#define RT_NFS_HOST_EXPORT "192.168.1.254:/" //
//
-// #define RT_USING_LWIP +#define RT_USING_LWIP +#define RT_USING_GMAC_INT_MODE +#define RT_USING_LWIP141 +//#define RT_LWIP_DEBUG +#define RT_LWIP_USING_RT_MEM + + // #define RT_LWIP_ICMP // -// #define RT_LWIP_IGMP +#define RT_LWIP_IGMP // #define RT_LWIP_UDP // @@ -148,10 +154,11 @@ #define RT_LWIP_DNS // #define RT_LWIP_PBUF_NUM 4 +#define RT_LWIP_PBUF_POOL_BUFSIZE 2048 // #define RT_LWIP_TCP_PCB_NUM 3 // -#define RT_LWIP_TCP_SND_BUF 2048 +#define RT_LWIP_TCP_SND_BUF 4096 // #define RT_LWIP_TCP_WND 2048 // @@ -159,7 +166,7 @@ // // #define RT_LWIP_DHCP // -#define RT_LWIP_TCP_SEG_NUM 4 +#define RT_LWIP_TCP_SEG_NUM 40 // #define RT_LWIP_TCPTHREAD_PRIORITY 12 // @@ -175,13 +182,13 @@ // #define RT_LWIP_IPADDR0 192 #define RT_LWIP_IPADDR1 168 -#define RT_LWIP_IPADDR2 3 -#define RT_LWIP_IPADDR3 108 +#define RT_LWIP_IPADDR2 1 +#define RT_LWIP_IPADDR3 254 // #define RT_LWIP_GWADDR0 192 #define RT_LWIP_GWADDR1 168 -#define RT_LWIP_GWADDR2 3 -#define RT_LWIP_GWADDR3 1 +#define RT_LWIP_GWADDR2 1 +#define RT_LWIP_GWADDR3 3 // #define RT_LWIP_MSKADDR0 255 #define RT_LWIP_MSKADDR1 255 diff --git a/bsp/stm32f10x/drivers/bxcan.h b/bsp/stm32f10x/drivers/bxcan.h index d2bdc4821f..5e6cad087c 100644 --- a/bsp/stm32f10x/drivers/bxcan.h +++ b/bsp/stm32f10x/drivers/bxcan.h @@ -47,8 +47,9 @@ #define CAN_TXMAILBOX_1 ((uint8_t)0x01) #define CAN_TXMAILBOX_2 ((uint8_t)0x02) - - #define CAN_MODE_MASK ((uint32_t) 0x00000003) +void CAN1_RX0_IRQHandler(void); +void CAN1_TX_IRQHandler(void); + #endif /*BXCAN_H_*/ diff --git a/bsp/stm32f10x/drivers/stm32f10x_it.c b/bsp/stm32f10x/drivers/stm32f10x_it.c index bf5cf55565..4f89e8a68d 100644 --- a/bsp/stm32f10x/drivers/stm32f10x_it.c +++ b/bsp/stm32f10x/drivers/stm32f10x_it.c @@ -25,6 +25,7 @@ #include "stm32f10x_it.h" #include #include +#include "bxcan.h" /** @addtogroup Template_Project * @{ @@ -144,6 +145,24 @@ void EXTI4_IRQHandler(void) } #endif /* RT_USING_LWIP */ +#ifndef STM32F10X_CL +/* CAN and USB IRQ for stm32 none connectivity line devices + */ +void USB_LP_CAN1_RX0_IRQHandler(void) +{ +#ifdef RT_USING_CAN + CAN1_RX0_IRQHandler(); +#endif +} +void USB_HP_CAN1_TX_IRQHandler(void) +{ +#ifdef RT_USING_CAN + CAN1_TX_IRQHandler(); +#endif +} +#endif + + /** * @} */ diff --git a/bsp/stm32f10x/project.uvprojx b/bsp/stm32f10x/project.uvprojx index 7888fee443..8f84c4c435 100644 --- a/bsp/stm32f10x/project.uvprojx +++ b/bsp/stm32f10x/project.uvprojx @@ -10,6 +10,8 @@ rtthread-stm32 0x4 ARM-ADS + 5050169::V5.05 update 2 (build 169)::.\ARMCC_505u2 + 5050169::V5.05 update 2 (build 169)::.\ARMCC_505u2 STM32F103ZE diff --git a/bsp/stm32f10x/rtconfig.h b/bsp/stm32f10x/rtconfig.h index f448846001..2cda86f2a1 100644 --- a/bsp/stm32f10x/rtconfig.h +++ b/bsp/stm32f10x/rtconfig.h @@ -194,4 +194,6 @@ /* nanopb support */ /* #define RT_USING_NANOPB */ +#define RT_USING_CPU_FFS + #endif diff --git a/bsp/stm32f20x/stm32_rom.icf b/bsp/stm32f20x/stm32_rom.icf index 293cd6ab01..95cc8d50cf 100644 --- a/bsp/stm32f20x/stm32_rom.icf +++ b/bsp/stm32f20x/stm32_rom.icf @@ -28,8 +28,8 @@ do not initialize { section .noinit }; keep { section FSymTab }; keep { section VSymTab }; +keep { section .rti_fn* }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly, block RTT_INIT_FUNC }; -place in RAM_region { readwrite, - block CSTACK, block HEAP }; \ No newline at end of file +place in RAM_region { readwrite, block CSTACK, last block HEAP}; diff --git a/bsp/stm32f40x/drivers/usart.c b/bsp/stm32f40x/drivers/usart.c index 5b60188392..0838d214e2 100644 --- a/bsp/stm32f40x/drivers/usart.c +++ b/bsp/stm32f40x/drivers/usart.c @@ -567,53 +567,53 @@ static void GPIO_Configuration(void) #ifdef RT_USING_UART1 /* Configure USART1 Rx/tx PIN */ GPIO_InitStructure.GPIO_Pin = UART1_GPIO_RX | UART1_GPIO_TX; - GPIO_Init(UART1_GPIO, &GPIO_InitStructure); - - /* Connect alternate function */ + /* Connect alternate function */ GPIO_PinAFConfig(UART1_GPIO, UART1_TX_PIN_SOURCE, GPIO_AF_USART1); - GPIO_PinAFConfig(UART1_GPIO, UART1_RX_PIN_SOURCE, GPIO_AF_USART1); + GPIO_PinAFConfig(UART1_GPIO, UART1_RX_PIN_SOURCE, GPIO_AF_USART1); + + GPIO_Init(UART1_GPIO, &GPIO_InitStructure); #endif /* RT_USING_UART1 */ #ifdef RT_USING_UART2 /* Configure USART2 Rx/tx PIN */ GPIO_InitStructure.GPIO_Pin = UART2_GPIO_RX | UART2_GPIO_TX; - GPIO_Init(UART2_GPIO, &GPIO_InitStructure); - /* Connect alternate function */ GPIO_PinAFConfig(UART2_GPIO, UART2_TX_PIN_SOURCE, GPIO_AF_USART2); GPIO_PinAFConfig(UART2_GPIO, UART2_RX_PIN_SOURCE, GPIO_AF_USART2); + + GPIO_Init(UART2_GPIO, &GPIO_InitStructure); #endif /* RT_USING_UART2 */ #ifdef RT_USING_UART3 /* Configure USART3 Rx/tx PIN */ GPIO_InitStructure.GPIO_Pin = UART3_GPIO_TX | UART3_GPIO_RX; - GPIO_Init(UART3_GPIO, &GPIO_InitStructure); - /* Connect alternate function */ GPIO_PinAFConfig(UART3_GPIO, UART3_TX_PIN_SOURCE, GPIO_AF_USART3); GPIO_PinAFConfig(UART3_GPIO, UART3_RX_PIN_SOURCE, GPIO_AF_USART3); + + GPIO_Init(UART3_GPIO, &GPIO_InitStructure); #endif /* RT_USING_UART3 */ #ifdef RT_USING_UART4 /* Configure USART4 Rx/tx PIN */ GPIO_InitStructure.GPIO_Pin = UART4_GPIO_TX | UART4_GPIO_RX; - GPIO_Init(UART4_GPIO, &GPIO_InitStructure); - /* Connect alternate function */ GPIO_PinAFConfig(UART4_GPIO, UART4_TX_PIN_SOURCE, GPIO_AF_UART4); GPIO_PinAFConfig(UART4_GPIO, UART4_RX_PIN_SOURCE, GPIO_AF_UART4); + + GPIO_Init(UART4_GPIO, &GPIO_InitStructure); #endif /* RT_USING_UART4 */ #ifdef RT_USING_UART5 /* Configure USART5 Rx/tx PIN */ GPIO_InitStructure.GPIO_Pin = UART5_GPIO_TX; + /* Connect alternate function */ + GPIO_PinAFConfig(UART5_TX, UART5_TX_PIN_SOURCE, GPIO_AF_UART5); GPIO_Init(UART5_TX, &GPIO_InitStructure); + GPIO_InitStructure.GPIO_Pin = UART5_GPIO_RX; - GPIO_Init(UART5_RX, &GPIO_InitStructure); - - /* Connect alternate function */ - GPIO_PinAFConfig(UART5_TX, UART5_TX_PIN_SOURCE, GPIO_AF_UART5); GPIO_PinAFConfig(UART5_RX, UART5_RX_PIN_SOURCE, GPIO_AF_UART5); + GPIO_Init(UART5_RX, &GPIO_InitStructure); #endif /* RT_USING_UART5 */ } diff --git a/bsp/x86/Makefile b/bsp/x86/Makefile new file mode 100644 index 0000000000..cdb4f4ca8c --- /dev/null +++ b/bsp/x86/Makefile @@ -0,0 +1,45 @@ + +CC = gcc -O0 -m32 -fno-builtin -fno-stack-protector -nostdinc -nostdlib +LD = ld -melf_i386 -nostdlib + +all: rtthread rtsym exe dll floppy.img + @mkdir -p tmp + @sudo mount -t vfat floppy.img tmp -o loop + @sudo cp -fv rtthread.elf tmp/boot/oskernel + @sudo rm tmp/bin/* -fr + @sudo cp out/* tmp/bin/ -fv + @sudo umount tmp + +rtthread: + @scons + +rtsym: + @./src/extract.sh ./rtthread-ia32.map ./src/rt_thread_sym.h + +obj: + mkdir -p obj + +out: + mkdir -p out + +dll: obj out + $(CC) -shared -s -fPIC -e main -Isrc src/hello.c -o out/hello.mo + +disasm: obj out + $(CC) -shared -S -fPIC -Isrc src/hello.c -o obj/hello.s + cat obj/hello.s + objdump --disassemble out/hello.mo + +exe: obj out + + +clean: + scons -c clean + rm -fr build rtthread* out obj + +floppy.img: + wget https://github.com/bajdcc/tinix/raw/master/floppy.img + +# https://en.wikibooks.org/wiki/QEMU/Devices/Network +run: + qemu-system-i386 -fda floppy.img -boot a -m 64M -serial stdio -net nic,model=ne2k_pci diff --git a/bsp/x86/applications/application.c b/bsp/x86/applications/application.c index 0883216976..38f974def1 100644 --- a/bsp/x86/applications/application.c +++ b/bsp/x86/applications/application.c @@ -1,100 +1,86 @@ -/** File : application.c +/* + * File : application.c * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2012, RT-Thread Develop Team + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://openlab.rt-thread.com/license/LICENSE + * 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 2 of the License, or + * (at your option) any later version. * - -* Change Logs: + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: * Date Author Notes - * 2006-09-15 QiuYi the first version + * 2009-01-05 Bernard the first version */ -/** - * @addtogroup QEMU - */ - -/*@{*/ - #include -ALIGN(RT_ALIGN_SIZE) -static char thread_led1_stack[1024]; -struct rt_thread thread_led1; -static void rt_thread_entry_led1(void *parameter) +#ifdef RT_USING_DFS +#include +#include +#include "floppy.h" +#ifdef RT_USING_MODULE +#include +#endif +extern int elm_init(void); +#endif + +/* components initialization for simulator */ +void components_init(void) { - unsigned int count=0; +#ifdef RT_USING_DFS + rt_floppy_init(); + /* initialize the device file system */ + dfs_init(); - while (1) +#ifdef RT_USING_DFS_ELMFAT + /* initialize the elm chan FatFS file system*/ + elm_init(); +#endif + +#ifdef RT_USING_MODULE + rt_system_module_init(); +#endif +#endif +} +void rt_init_thread_entry(void *parameter) +{ + components_init(); + + /* File system Initialization */ +#ifdef RT_USING_DFS { - /* led1 on */ -#ifndef RT_USING_FINSH - rt_kprintf("led1 on,count : %d\r\n",count); -#endif - count ++; - /* sleep 0.5 second and switch to other thread */ - rt_thread_delay(RT_TICK_PER_SECOND / 2); - /* led1 off */ -#ifndef RT_USING_FINSH - rt_kprintf("led1 off\r\n"); +#ifdef RT_USING_DFS_ELMFAT + /* mount sd card fatfs as root directory */ + if (dfs_mount("floppy", "/", "elm", 0, 0) == 0) + rt_kprintf("fatfs initialized!\n"); + else + rt_kprintf("fatfs initialization failed!\n"); #endif - rt_thread_delay(RT_TICK_PER_SECOND / 2); } +#endif } -ALIGN(RT_ALIGN_SIZE) -static char thread_led2_stack[1024]; -struct rt_thread thread_led2; -void rt_thread_entry_led2(void *parameter) +int rt_application_init() { - unsigned int count=0; + rt_thread_t tid; - while (1) - { - /* led2 on */ -#ifndef RT_USING_FINSH - rt_kprintf("led2 on,count : %d\r\n",count); -#endif - count ++; - rt_thread_delay(RT_TICK_PER_SECOND); + tid = rt_thread_create("init", + rt_init_thread_entry, RT_NULL, + 2048, RT_THREAD_PRIORITY_MAX / 3, 20); - /* led2 off */ -#ifndef RT_USING_FINSH - rt_kprintf("led2 off\r\n"); -#endif - rt_thread_delay(RT_TICK_PER_SECOND); - } -} - -/** - * This function will be invoked to initalize user application when system - * startup. - */ - -int rt_application_init(void) -{ - // init led1 thread - rt_thread_init(&thread_led1, - "led1", - rt_thread_entry_led1, - RT_NULL, - &thread_led1_stack[0], - sizeof(thread_led1_stack),11,5); - rt_thread_startup(&thread_led1); - - // init led2 thread - rt_thread_init(&thread_led2, - "led2", - rt_thread_entry_led2, - RT_NULL, - &thread_led2_stack[0], - sizeof(thread_led2_stack),12,5); - rt_thread_startup(&thread_led2); + if (tid != RT_NULL) + rt_thread_startup(tid); return 0; } - -/*@}*/ diff --git a/bsp/x86/drivers/board.c b/bsp/x86/drivers/board.c index 29589b0712..4d91604ab3 100644 --- a/bsp/x86/drivers/board.c +++ b/bsp/x86/drivers/board.c @@ -71,5 +71,12 @@ void reboot(void) } FINSH_FUNCTION_EXPORT(reboot, reboot PC) #endif - +#ifdef RT_USING_DFS +#include +time_t time(time_t* tm) +{ + (void)tm; + return 0; +} +#endif /*@}*/ diff --git a/bsp/x86/drivers/console.c b/bsp/x86/drivers/console.c index 53e833cc0a..1c1eb05e02 100644 --- a/bsp/x86/drivers/console.c +++ b/bsp/x86/drivers/console.c @@ -17,18 +17,19 @@ #include - -//#include "serial.h" - static unsigned addr_6845; static rt_uint16_t *crt_buf; static rt_int16_t crt_pos; -//extern void rt_serial_init(void); -extern char rt_keyboard_getc(void); -//extern char rt_serial_getc(void); +extern void init_keyboard(); +extern void rt_keyboard_isr(void); +extern rt_bool_t rt_keyboard_getc(char* c); -static void rt_console_putc(int c); +extern void rt_serial_init(void); +extern char rt_serial_getc(void); +extern void rt_serial_putc(const char c); + +void rt_console_putc(int c); /** * @addtogroup QEMU @@ -126,10 +127,10 @@ static void rt_cga_putc(int c) * * @param c the char to write */ -static void rt_console_putc(int c) +void rt_console_putc(int c) { rt_cga_putc(c); -// rt_serial_putc(c); + rt_serial_putc(c); } /* RT-Thread Device Interface */ @@ -217,39 +218,47 @@ static rt_size_t rt_console_read(rt_device_t dev, rt_off_t pos, void* buffer, rt static void rt_console_isr(int vector, void* param) { char c; + rt_bool_t ret; rt_base_t level; - while(1) - { - c = rt_keyboard_getc(); + if(INTUART0_RX == vector) + { + c = rt_serial_getc(); + ret = RT_TRUE; + } + else + { + rt_keyboard_isr(); - if(c == 0) - { - break; - } - else if(c > 0) - { - /* disable interrupt */ - level = rt_hw_interrupt_disable(); + ret = rt_keyboard_getc(&c); + } - /* save character */ - rx_buffer[save_index] = c; - save_index ++; - if (save_index >= CONSOLE_RX_BUFFER_SIZE) - save_index = 0; + if(ret == RT_FALSE) + { + /* do nothing */ + } + else + { + /* disable interrupt */ + level = rt_hw_interrupt_disable(); - /* if the next position is read index, discard this 'read char' */ - if (save_index == read_index) - { - read_index ++; - if (read_index >= CONSOLE_RX_BUFFER_SIZE) - read_index = 0; - } + /* save character */ + rx_buffer[save_index] = c; + save_index ++; + if (save_index >= CONSOLE_RX_BUFFER_SIZE) + save_index = 0; - /* enable interrupt */ - rt_hw_interrupt_enable(level); - } - } + /* if the next position is read index, discard this 'read char' */ + if (save_index == read_index) + { + read_index ++; + if (read_index >= CONSOLE_RX_BUFFER_SIZE) + read_index = 0; + } + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + } /* invoke callback */ if (console_device.rx_indicate != RT_NULL) @@ -258,10 +267,9 @@ static void rt_console_isr(int vector, void* param) /* get rx length */ rx_length = read_index > save_index ? - CONSOLE_RX_BUFFER_SIZE - read_index + save_index : - save_index - read_index; + CONSOLE_RX_BUFFER_SIZE - read_index + save_index : + save_index - read_index; -// rt_kprintf("\r\nrx_length %d\r\n", rx_length); if(rx_length > 0) { console_device.rx_indicate(&console_device, rx_length); @@ -269,7 +277,7 @@ static void rt_console_isr(int vector, void* param) } else { -// rt_kprintf("\r\nconsole_device.rx_indicate == RT_NULL\r\n"); + } } @@ -280,11 +288,16 @@ static void rt_console_isr(int vector, void* param) void rt_hw_console_init(void) { rt_cga_init(); + rt_serial_init(); + init_keyboard(); /* install keyboard isr */ rt_hw_interrupt_install(INTKEYBOARD, rt_console_isr, RT_NULL, "kbd"); rt_hw_interrupt_umask(INTKEYBOARD); + rt_hw_interrupt_install(INTUART0_RX, rt_console_isr, RT_NULL, "COM1"); + rt_hw_interrupt_umask(INTUART0_RX); + console_device.type = RT_Device_Class_Char; console_device.rx_indicate = RT_NULL; console_device.tx_complete = RT_NULL; diff --git a/bsp/x86/drivers/dma.h b/bsp/x86/drivers/dma.h new file mode 100644 index 0000000000..f1a8563cb1 --- /dev/null +++ b/bsp/x86/drivers/dma.h @@ -0,0 +1,187 @@ +#ifndef _DMA_H +#define _DMA_H + + +#define MAX_DMA_CHANNELS 8 + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG 0x08 /* command register (w) */ +#define DMA1_STAT_REG 0x08 /* status register (r) */ +#define DMA1_REQ_REG 0x09 /* request register (w) */ +#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ +#define DMA1_MODE_REG 0x0B /* mode register (w) */ +#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ +#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ +#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ + +#define DMA2_CMD_REG 0xD0 /* command register (w) */ +#define DMA2_STAT_REG 0xD0 /* status register (r) */ +#define DMA2_REQ_REG 0xD2 /* request register (w) */ +#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ +#define DMA2_MODE_REG 0xD6 /* mode register (w) */ +#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ +#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ +#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ + +#define DMA_ADDR_0 0x00 /* DMA address registers */ +#define DMA_ADDR_1 0x02 +#define DMA_ADDR_2 0x04 +#define DMA_ADDR_3 0x06 +#define DMA_ADDR_4 0xC0 +#define DMA_ADDR_5 0xC4 +#define DMA_ADDR_6 0xC8 +#define DMA_ADDR_7 0xCC + +#define DMA_CNT_0 0x01 /* DMA count registers */ +#define DMA_CNT_1 0x03 +#define DMA_CNT_2 0x05 +#define DMA_CNT_3 0x07 +#define DMA_CNT_4 0xC2 +#define DMA_CNT_5 0xC6 +#define DMA_CNT_6 0xCA +#define DMA_CNT_7 0xCE + +#define DMA_PAGE_0 0x87 /* DMA page registers */ +#define DMA_PAGE_1 0x83 +#define DMA_PAGE_2 0x81 +#define DMA_PAGE_3 0x82 +#define DMA_PAGE_5 0x8B +#define DMA_PAGE_6 0x89 +#define DMA_PAGE_7 0x8A + +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + +/* + * 启用指定的DMA通道 + */ +static __inline__ void EnableDma(unsigned int dmanr) +{ + if (dmanr<=3) + OUTB(dmanr, DMA1_MASK_REG); + else + OUTB(dmanr & 3, DMA2_MASK_REG); +} + +/* + * 禁用指定的DMA通道 + */ +static __inline__ void DisableDma(unsigned int dmanr) +{ + if (dmanr<=3) + OUTB(dmanr | 4, DMA1_MASK_REG); + else + OUTB((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* + * 清空DMA 晶体计数器 + */ +static __inline__ void ClearDmaFF(unsigned int dmanr) +{ + if (dmanr<=3) + OUTB(0, DMA1_CLEAR_FF_REG); + else + OUTB(0, DMA2_CLEAR_FF_REG); +} + +/* + * 清空DMA 晶体计数器 + */ +static __inline__ void SetDmaMode(unsigned int dmanr, char mode) +{ + if (dmanr<=3) + OUTB(mode | dmanr, DMA1_MODE_REG); + else + OUTB(mode | (dmanr&3), DMA2_MODE_REG); +} + +/* + * 设定DMA 页面寄存器 + */ +static __inline__ void SetDmaPage(unsigned int dmanr, char pagenr) +{ + switch(dmanr) { + case 0: + OUTB(pagenr, DMA_PAGE_0); + break; + case 1: + OUTB(pagenr, DMA_PAGE_1); + break; + case 2: + OUTB(pagenr, DMA_PAGE_2); + break; + case 3: + OUTB(pagenr, DMA_PAGE_3); + break; + case 5: + OUTB(pagenr & 0xfe, DMA_PAGE_5); + break; + case 6: + OUTB(pagenr & 0xfe, DMA_PAGE_6); + break; + case 7: + OUTB(pagenr & 0xfe, DMA_PAGE_7); + break; + } +} + + +/* + * 设定DMA 传输高速缓冲区地址 + */ +static __inline__ void SetDmaAddr(unsigned int dmanr, unsigned int a) +{ + SetDmaPage(dmanr, a>>16); + if (dmanr <= 3) { + OUTB( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + OUTB( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + } else { + OUTB( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + OUTB( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + } +} + + +/* + * 设定DMA 传输块数 + */ +static __inline__ void SetDmaCount(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + OUTB( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + OUTB( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + } else { + OUTB( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + OUTB( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + } +} + + +/* + * 获得DMA 传输剩余块数 + */ +static __inline__ int GetDmaResidue(unsigned int dmanr) +{ + unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE + : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + + /* using short to get 16-bit wrap around */ + unsigned short count; + count = 1 + inb(io_port); + count += inb(io_port) << 8; + return (dmanr<=3)? count : (count<<1); +} + +#endif + diff --git a/bsp/x86/drivers/floppy.c b/bsp/x86/drivers/floppy.c new file mode 100644 index 0000000000..058bf1b941 --- /dev/null +++ b/bsp/x86/drivers/floppy.c @@ -0,0 +1,360 @@ + +#include +#include + +#include + +typedef rt_uint8_t u8; +typedef rt_uint16_t u16; +typedef rt_uint32_t u32; + +typedef rt_int8_t s8; +typedef rt_int16_t s16; +typedef rt_int32_t s32; + +#define OUTB(v,p) outb(p,v) + +#include "floppy.h" +#include "dma.h" + +#define NULL RT_NULL +#define SECTOR_SIZE 512 +#define panic(str,...) do { rt_kprintf("panic::" str,##__VA_ARGS__); while(1); } while(0) + +#define _local_irq_save(level) level = rt_hw_interrupt_disable() +#define _local_irq_restore(level) rt_hw_interrupt_enable(level) + +static u8 floppy_buffer[512]; /* 软盘高速缓冲区地址指针 */ + +#define MAX_REPLIES 7 +static u8 floppy_reply_buffer[MAX_REPLIES]; /* 软驱回应缓冲区 */ +#define ST0 (floppy_reply_buffer[0]) /* 软驱回应0号字节 */ +#define ST1 (floppy_reply_buffer[1]) /* 软驱回应1号字节 */ +#define ST2 (floppy_reply_buffer[2]) /* 软驱回应2号字节 */ +#define ST3 (floppy_reply_buffer[3]) /* 软驱回应3号字节 */ + + +static char *floppy_inc_name; /* 软驱型号名 */ +static char *floppy_type; +static u32 floppy_motor=0; /* 软驱马达状态字节 */ +static u32 floppy_size =0; +/**********************功能函数***************************/ +static void floppy_result(void); /* 获得软驱响应状态 */ +static u32 floppy_sendbyte(u32); /* 向软驱控制寄存器发送一个控制字节 */ +static u32 floppy_getbyte(void); /* 从软驱数据寄存器得到一个数据字节 */ +static u32 floppy_get_info(void); /* 得到软驱信息 */ +static void floppy_motorOn(void); /* 打开软驱马达 */ +static void floppy_motorOff(void); /* 关闭软驱马达 */ +static void floppy_setmode(void); /* 软驱模式设置 */ +static void block_to_hts(u32, u32*, u32*, u32*); /* 逻辑块转为磁盘头、磁道号和扇区号 */ +static void floppy_setupDMA(void); /* 设置软驱DMA通道 */ +static void floppy_read_cmd(u32 blk); /* 从软盘上读取指定的逻辑块到缓冲区 */ + + +void floppy_result(void) +{ + u8 stat, i,count; + i=0; + for(count=0; count<0xFF; count++) + { + stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR|STATUS_BUSY); //读取状态寄存器 + if (stat == STATUS_READY) + return; + if (stat == (STATUS_READY|STATUS_DIR|STATUS_BUSY)) + { + if(i>7) break; + floppy_reply_buffer[i++]=inb_p(FD_DATA); + } + } + + panic("Get floppy status times out !\n"); +} + +u32 floppy_sendbyte( u32 value ) +{ + u8 stat, i; + + for ( i = 0; i < 128; i++ ) { + stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR); //读取状态寄存器 + if ( stat == STATUS_READY ) + { + OUTB( value ,FD_DATA); //将参数写入数据寄存器 + return 1; + } + io_delay(); // 作一些延迟 + } + return 0; +} + + +u32 floppy_getbyte(void) +{ + u8 stat, i; + + for ( i = 0; i < 128; i++ ) { + stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR|STATUS_BUSY); //读取状态寄存器 + if (stat == STATUS_READY) + return -1; + if ( stat == 0xD0 ) + return inb(FD_DATA); + io_delay(); + } + return 0; +} + + +u32 floppy_get_info(void) +{ + u32 i; + u8 CmType, FdType; + + floppy_sendbyte(0x10); + i = floppy_getbyte(); + + switch (i) + { + case 0x80: floppy_inc_name = "NEC765A controller"; break; + case 0x90: floppy_inc_name = "NEC765B controller"; break; + default: floppy_inc_name = "Enhanced controller"; break; + } + + CmType = readcmos(0x10); //read floppy type from cmos + FdType = (CmType>>4) & 0x07; + + if ( FdType == 0 ) + panic("Floppy driver not found!"); + + switch( FdType ) + { + case 0x02: // 1.2MB + floppy_type = "1.2MB"; + floppy_size = 2458*512; + break; + + case 0x04: // 1.44MB 标准软盘 + floppy_type = "1.44MB"; + floppy_size = 2880*512; + break; + + case 0x05: // 2.88MB + floppy_type = "2.88MB"; + floppy_size = 2*2880*512; + break; + } + return 1; +} + + +void floppy_motorOn( void ) +{ + u32 eflags; + if (!floppy_motor) + { + _local_irq_save(eflags); + OUTB(28,FD_DOR); + floppy_motor = 1; + _local_irq_restore(eflags); + } + return; +} + + +void floppy_motorOff( void ) +{ + u32 eflags; + if (floppy_motor) + { + _local_irq_save(eflags); + OUTB(12,FD_DOR); + floppy_motor = 0; + _local_irq_restore(eflags); + + } + return; +} + + +void floppy_setmode(void) +{ + floppy_sendbyte (FD_SPECIFY); + floppy_sendbyte (0xcf); + floppy_sendbyte (0x06); + OUTB (0,FD_DCR); +} + + +void block_to_hts(u32 block, u32 *head, u32 *track, u32 *sector ) +{ + *head = ( block % ( 18 * 2 ) ) /18; + *track = block / ( 18 * 2 ); + *sector = block % 18 + 1; +} + + +void floppy_setupDMA(void) +{ + u32 eflags; + _local_irq_save(eflags); + DisableDma(2); + ClearDmaFF(2); + SetDmaMode(2,DMA_MODE_READ); + SetDmaAddr(2,(unsigned long)floppy_buffer); + SetDmaCount(2,512); + EnableDma(2); + _local_irq_restore(eflags); +} + + +void floppy_read_cmd(u32 blk) +{ + u32 head; + u32 track; + u32 sector; + + block_to_hts(blk,&head,&track,§or); + + floppy_motorOn(); + io_delay(); + + floppy_setupDMA(); + io_delay(); + + floppy_setmode(); + io_delay(); + floppy_sendbyte (FD_READ); //send read command + floppy_sendbyte (head*4 + 0); + floppy_sendbyte (track); /* Cylinder */ + floppy_sendbyte (head); /* Head */ + floppy_sendbyte (sector); /* Sector */ + floppy_sendbyte (2); /* 0=128, 1=256, 2=512, 3=1024, ... */ + floppy_sendbyte (18); + //floppy_sendbyte (sector+secs-1); /* Last sector in track:here are sectors count */ + floppy_sendbyte (0x1B); + floppy_sendbyte (0xff); + return; +} + +static struct rt_device devF; +static struct rt_mutex lock; +static struct rt_semaphore sem; + +/* RT-Thread device interface */ + +static rt_err_t rt_floppy_init_internal(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_err_t rt_floppy_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t rt_floppy_close(rt_device_t dev) +{ + return RT_EOK; +} + +/* position: block page address, not bytes address + * buffer: + * size : how many blocks + */ +static rt_size_t rt_floppy_read(rt_device_t device, rt_off_t position, void *buffer, rt_size_t size) +{ + rt_size_t doSize = size; + + rt_mutex_take(&lock, RT_WAITING_FOREVER); + while(size>0) + { + floppy_read_cmd(position); + + rt_sem_take(&sem, RT_WAITING_FOREVER); /* waiting isr sem forever */ + + floppy_result(); + io_delay(); + + if(ST1 != 0 || ST2 != 0) + { + panic("ST0 %d ST1 %d ST2 %d\n",ST0,ST1,ST2); + } + + rt_memcpy(buffer, floppy_buffer, 512); + + floppy_motorOff(); + io_delay(); + + position += 1; + size -= 1; + } + rt_mutex_release(&lock); + + return doSize; +} + +/* position: block page address, not bytes address + * buffer: + * size : how many blocks + */ +static rt_size_t rt_floppy_write(rt_device_t device, rt_off_t position, const void *buffer, rt_size_t size) +{ + rt_mutex_take(&lock, RT_WAITING_FOREVER); + panic("FIXME:I don't know how!\n"); + rt_mutex_release(&lock); + return size; +} + +static rt_err_t rt_floppy_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + RT_ASSERT(dev != RT_NULL); + + if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) + { + struct rt_device_blk_geometry *geometry; + + geometry = (struct rt_device_blk_geometry *)args; + if (geometry == RT_NULL) return -RT_ERROR; + + geometry->bytes_per_sector = SECTOR_SIZE; + geometry->block_size = SECTOR_SIZE; + + geometry->sector_count = floppy_size / SECTOR_SIZE; + } + + return RT_EOK; +} + +static void rt_floppy_isr(int vector, void* param) +{ + (void)vector; + (void)param; + rt_sem_release(&sem); +} + +void rt_floppy_init(void) +{ + struct rt_device *device; + + rt_mutex_init(&lock,"fdlock", RT_IPC_FLAG_FIFO); + rt_sem_init(&sem, "fdsem", 0, RT_IPC_FLAG_FIFO); + + rt_hw_interrupt_install(FLOPPY_IRQ, rt_floppy_isr, RT_NULL, "floppy"); + rt_hw_interrupt_umask(FLOPPY_IRQ); + + floppy_get_info(); + rt_kprintf("Floppy Inc : %s Floppy Type : %s\n",floppy_inc_name,floppy_type); + + device = &(devF); + + device->type = RT_Device_Class_Block; + device->init = rt_floppy_init_internal; + device->open = rt_floppy_open; + device->close = rt_floppy_close; + device->read = rt_floppy_read; + device->write = rt_floppy_write; + device->control = rt_floppy_control; + device->user_data = NULL; + + rt_device_register(device, "floppy", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); + +} diff --git a/bsp/x86/drivers/floppy.h b/bsp/x86/drivers/floppy.h new file mode 100644 index 0000000000..f619508c43 --- /dev/null +++ b/bsp/x86/drivers/floppy.h @@ -0,0 +1,71 @@ +#ifndef _FLOPPY_H +#define _FLOPPY_H + +#define FD_STATUS 0x3f4 // 主状态寄存器端口。 +#define FD_DATA 0x3f5 // 数据端口。 +#define FD_DOR 0x3f2 // 数字输出寄存器(也称为数字控制寄存器)。 +#define FD_DIR 0x3f7 // 数字输入寄存器。 +#define FD_DCR 0x3f7 // 数据传输率控制寄存器。 + +/* 主状态寄存器各比特位的含义 */ + +#define STATUS_BUSYMASK 0x0F // 驱动器忙位(每位对应一个驱动器)。 +#define STATUS_BUSY 0x10 // 软盘控制器忙。 +#define STATUS_DMA 0x20 // 0 - 为DMA 数据传输模式,1 - 为非DMA 模式。 +#define STATUS_DIR 0x40 // 传输方向:0 - CPU .. fdc,1 - 相反。 +#define STATUS_READY 0x80 // 数据寄存器就绪位。 + + +/*状态字节0(ST0)各比特位的含义 */ + +#define ST0_DS 0x03 // 驱动器选择号(发生中断时驱动器号)。 +#define ST0_HA 0x04 // 磁头号。 +#define ST0_NR 0x08 // 磁盘驱动器未准备好。 +#define ST0_ECE 0x10 // 设备检测出错(零磁道校准出错)。 +#define ST0_SE 0x20 // 寻道或重新校正操作执行结束。 +#define ST0_INTR 0xC0 // 中断代码位(中断原因),00 - 命令正常结束; + // 01 - 命令异常结束;10 - 命令无效;11 - FDD 就绪状态改变。 + +/*状态字节1(ST1)各比特位的含义 */ + +#define ST1_MAM 0x01 // 未找到地址标志(ID AM)。 +#define ST1_WP 0x02 // 写保护。 +#define ST1_ND 0x04 // 未找到指定的扇区。 +#define ST1_OR 0x10 // 数据传输超时(DMA 控制器故障)。 +#define ST1_CRC 0x20 // CRC 检验出错。 +#define ST1_EOC 0x80 // 访问超过一个磁道上的最大扇区号。 + +/*状态字节2(ST2)各比特位的含义 */ + +#define ST2_MAM 0x01 // 未找到数据地址标志。 +#define ST2_BC 0x02 // 磁道坏。 +#define ST2_SNS 0x04 // 检索(扫描)条件不满足。 +#define ST2_SEH 0x08 // 检索条件满足。 +#define ST2_WC 0x10 // 磁道(柱面)号不符。 +#define ST2_CRC 0x20 // 数据场CRC 校验错。 +#define ST2_CM 0x40 // 读数据遇到删除标志。 + +/*状态字节3(ST3)各比特位的含义 */ + +#define ST3_HA 0x04 // 磁头号。 +#define ST3_TZ 0x10 // 零磁道信号。 +#define ST3_WP 0x40 // 写保护。 + + +/* 软盘命令码 */ + +#define FD_RECALIBRATE 0x07 // 重新校正(磁头退到零磁道)。 +#define FD_SEEK 0x0F // 磁头寻道。 +#define FD_READ 0xE6 // 读数据(MT 多磁道操作,MFM 格式,跳过删除数据)。 +#define FD_WRITE 0xC5 // 写数据(MT,MFM)。 +#define FD_SENSEI 0x08 // 检测中断状态。 +#define FD_SPECIFY 0x03 // 设定驱动器参数(步进速率、磁头卸载时间等)。 + + +/* DMA 命令 */ +#define DMA_READ 0x46 // DMA 读盘,DMA 方式字(送DMA 端口12,11)。 +#define DMA_WRITE 0x4A + +extern void rt_floppy_init(void); + +#endif diff --git a/bsp/x86/drivers/include/bsp.h b/bsp/x86/drivers/include/bsp.h index 8739e185ad..724f518c6e 100644 --- a/bsp/x86/drivers/include/bsp.h +++ b/bsp/x86/drivers/include/bsp.h @@ -74,7 +74,16 @@ extern "C" { #define INTTIMER0 0 #define INTKEYBOARD 1 #define INTUART0_RX 4 - +#define CLOCK_IRQ 0 +#define KEYBOARD_IRQ 1 +#define CASCADE_IRQ 2 /* cascade enable for 2nd AT controller */ +#define ETHER_IRQ 3 /* default ethernet interrupt vector */ +#define SECONDARY_IRQ 3 /* RS232 interrupt vector for port 2 */ +#define RS232_IRQ 4 /* RS232 interrupt vector for port 1 */ +#define XT_WINI_IRQ 5 /* xt winchester */ +#define FLOPPY_IRQ 6 /* floppy disk */ +#define PRINTER_IRQ 7 +#define AT_WINI_IRQ 14 /* at winchester */ /* I/O Addresses of the two 8259A programmable interrupt controllers */ #define IO_PIC1 0x20 /* Master(IRQs 0-7) */ #define IO_PIC2 0xa0 /* Slave(IRQs 8-15) */ @@ -101,6 +110,16 @@ extern "C" { #define KBSTATP 0x64 /* kbd controller status port(I) */ #define KBS_DIB 0x01 /* kbd data in buffer */ #define KBDATAP 0x60 /* kbd data port(I) */ +/* AT keyboard */ +/* 8042 ports */ +#define KB_DATA 0x60 /* I/O port for keyboard data + Read : Read Output Buffer + Write: Write Input Buffer(8042 Data&8048 Command) */ +#define KB_CMD 0x64 /* I/O port for keyboard command + Read : Read Status Register + Write: Write Input Buffer(8042 Command) */ +#define LED_CODE 0xED +#define KB_ACK 0xFA /*******************************************************************/ /* Serial Register */ diff --git a/bsp/x86/drivers/include/i386.h b/bsp/x86/drivers/include/i386.h index fe023d754a..68c854932b 100644 --- a/bsp/x86/drivers/include/i386.h +++ b/bsp/x86/drivers/include/i386.h @@ -11,6 +11,18 @@ static __inline unsigned char inb(int port) __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port)); return data; } +static __inline unsigned char inb_p(unsigned short port) +{ + unsigned char _v; + __asm__ __volatile__ ("inb %1, %0\n\t" + // "outb %0,$0x80\n\t" + // "outb %0,$0x80\n\t" + // "outb %0,$0x80\n\t" + "outb %0,$0x80" + :"=a" (_v) + :"d" ((unsigned short) port)); + return _v; +} static __inline unsigned short inw(int port) { @@ -39,11 +51,34 @@ static __inline void outb(int port, unsigned char data) __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port)); } + +static __inline void outb_p(char value, unsigned short port) +{ + __asm__ __volatile__ ("outb %0,%1\n\t" + "outb %0,$0x80" + ::"a" ((char) value),"d" ((unsigned short) port)); +} + static __inline void outw(int port, unsigned short data) { __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port)); } +static __inline unsigned char readcmos(int reg) +{ + outb(0x70,reg); + return (unsigned char) inb(0x71); +} + +#define io_delay() \ + __asm__ __volatile__ ("pushal \n\t"\ + "mov $0x3F6, %dx \n\t" \ + "inb %dx, %al \n\t" \ + "inb %dx, %al \n\t" \ + "inb %dx, %al \n\t" \ + "inb %dx, %al \n\t" \ + "popal") + /* Gate descriptors are slightly different*/ struct Gatedesc { unsigned gd_off_15_0 : 16; // low 16 bits of offset in segment diff --git a/bsp/x86/drivers/keyboard.c b/bsp/x86/drivers/keyboard.c index 21c9fba28d..3716c367cc 100644 --- a/bsp/x86/drivers/keyboard.c +++ b/bsp/x86/drivers/keyboard.c @@ -10,129 +10,357 @@ * Change Logs: * Date Author Notes * 2006-09-15 QiuYi the first version + * 2017-08-16 Parai the 2nd version */ #include #include #include +#include "keyboard.h" +#include "keymap.h" -#define NO 0 +#define FALSE RT_FALSE +#define TRUE RT_TRUE +#define PRIVATE static +#define PUBLIC +#define t_bool rt_bool_t +#define t_8 rt_uint8_t +#define t_32 rt_uint32_t -#define SHIFT (1 << 0) -#define CTL (1 << 1) -#define ALT (1 << 2) +PRIVATE KB_INPUT kb_in; +PRIVATE t_bool code_with_E0 = FALSE; +PRIVATE t_bool shift_l; /* l shift state */ +PRIVATE t_bool shift_r; /* r shift state */ +PRIVATE t_bool alt_l; /* l alt state */ +PRIVATE t_bool alt_r; /* r left state */ +PRIVATE t_bool ctrl_l; /* l ctrl state */ +PRIVATE t_bool ctrl_r; /* l ctrl state */ +PRIVATE t_bool caps_lock; /* Caps Lock */ +PRIVATE t_bool num_lock; /* Num Lock */ +PRIVATE t_bool scroll_lock; /* Scroll Lock */ +PRIVATE int column = 0; /* keyrow[column] is one value of keymap */ -#define CAPSLOCK (1<<3) -#define NUMLOCK (1<<4) -#define SCROLLOCK (1<<5) +PRIVATE t_8 get_byte_from_kb_buf(); +PRIVATE void set_leds(); +PRIVATE void kb_wait(); +PRIVATE void kb_ack(); -static int shiftcode[256] = +PUBLIC void init_keyboard() { - [29] CTL, - [42] SHIFT, - [54] SHIFT, - [56] ALT, -}; + kb_in.count = 0; + kb_in.p_head = kb_in.p_tail = kb_in.buf; -static int togglecode[256] = + caps_lock = 0; + num_lock = 1; + scroll_lock = 0; + + set_leds(); +} +PUBLIC rt_bool_t keyboard_read(rt_uint32_t *pkey) { - [58] CAPSLOCK, - [69] NUMLOCK, - [70] SCROLLOCK, -}; + t_8 scan_code; + t_bool make; /* TRUE : make */ + /* FALSE: break */ + t_32 key = 0; + t_32* keyrow; -static char normalmap[256] = + if(kb_in.count > 0){ + code_with_E0 = FALSE; + scan_code = get_byte_from_kb_buf(); + + /* start scan */ + if (scan_code == 0xE1) { + int i; + static const t_8 pausebreak_scan_code[] = {0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5}; + t_bool is_pausebreak = TRUE; + for(i=1;i<6;i++){ + if (get_byte_from_kb_buf() != pausebreak_scan_code[i]) { + is_pausebreak = FALSE; + break; + } + } + if (is_pausebreak) { + key = PAUSEBREAK; + } + } + else if (scan_code == 0xE0) { + code_with_E0 = TRUE; + scan_code = get_byte_from_kb_buf(); + + /* PrintScreen pressed */ + if (scan_code == 0x2A) { + code_with_E0 = FALSE; + if ((scan_code = get_byte_from_kb_buf()) == 0xE0) { + code_with_E0 = TRUE; + if ((scan_code = get_byte_from_kb_buf()) == 0x37) { + key = PRINTSCREEN; + make = TRUE; + } + } + } + /* PrintScreen released */ + else if (scan_code == 0xB7) { + code_with_E0 = FALSE; + if ((scan_code = get_byte_from_kb_buf()) == 0xE0) { + code_with_E0 = TRUE; + if ((scan_code = get_byte_from_kb_buf()) == 0xAA) { + key = PRINTSCREEN; + make = FALSE; + } + } + } + } /* if is not PrintScreen, scan_code is the one after 0xE0 */ + if ((key != PAUSEBREAK) && (key != PRINTSCREEN)) { + /* is Make Code or Break Code */ + make = (scan_code & FLAG_BREAK ? FALSE : TRUE); + + keyrow = &keymap[(scan_code & 0x7F) * MAP_COLS]; + + column = 0; + + t_bool caps = shift_l || shift_r; + if (caps_lock) { + if ((keyrow[0] >= 'a') && (keyrow[0] <= 'z')){ + caps = !caps; + } + } + if (caps) { + column = 1; + } + + if (code_with_E0) { + column = 2; + } + + key = keyrow[column]; + + switch(key) { + case SHIFT_L: + shift_l = make; + break; + case SHIFT_R: + shift_r = make; + break; + case CTRL_L: + ctrl_l = make; + break; + case CTRL_R: + ctrl_r = make; + break; + case ALT_L: + alt_l = make; + break; + case ALT_R: + alt_l = make; + break; + case CAPS_LOCK: + if (make) { + caps_lock = !caps_lock; + set_leds(); + } + break; + case NUM_LOCK: + if (make) { + num_lock = !num_lock; + set_leds(); + } + break; + case SCROLL_LOCK: + if (make) { + scroll_lock = !scroll_lock; + set_leds(); + } + break; + default: + break; + } + } + + if(make){ /* ignore Break Code */ + t_bool pad = FALSE; + + /* handle the small pad first */ + if ((key >= PAD_SLASH) && (key <= PAD_9)) { + pad = TRUE; + switch(key) { /* '/', '*', '-', '+', and 'Enter' in num pad */ + case PAD_SLASH: + key = '/'; + break; + case PAD_STAR: + key = '*'; + break; + case PAD_MINUS: + key = '-'; + break; + case PAD_PLUS: + key = '+'; + break; + case PAD_ENTER: + key = ENTER; + break; + default: /* keys whose value depends on the NumLock */ + if (num_lock) { /* '0' ~ '9' and '.' in num pad */ + if ((key >= PAD_0) && (key <= PAD_9)) { + key = key - PAD_0 + '0'; + } + else if (key == PAD_DOT) { + key = '.'; + } + } + else{ + switch(key) { + case PAD_HOME: + key = HOME; + break; + case PAD_END: + key = END; + break; + case PAD_PAGEUP: + key = PAGEUP; + break; + case PAD_PAGEDOWN: + key = PAGEDOWN; + break; + case PAD_INS: + key = INSERT; + break; + case PAD_UP: + key = UP; + break; + case PAD_DOWN: + key = DOWN; + break; + case PAD_LEFT: + key = LEFT; + break; + case PAD_RIGHT: + key = RIGHT; + break; + case PAD_DOT: + key = DELETE; + break; + default: + break; + } + } + break; + } + } + key |= shift_l ? FLAG_SHIFT_L : 0; + key |= shift_r ? FLAG_SHIFT_R : 0; + key |= ctrl_l ? FLAG_CTRL_L : 0; + key |= ctrl_r ? FLAG_CTRL_R : 0; + key |= alt_l ? FLAG_ALT_L : 0; + key |= alt_r ? FLAG_ALT_R : 0; + key |= pad ? FLAG_PAD : 0; + + *pkey = key; + return TRUE; + } + } + + return FALSE; +} + +PRIVATE t_8 get_byte_from_kb_buf() { - NO, 033, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', '\b', '\t', - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', '\n', NO, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - '\'', '`', NO, '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', NO, '*', - NO, ' ', NO, NO, NO, NO, NO, NO, - NO, NO, NO, NO, NO, NO, NO, '7', - '8', '9', '-', '4', '5', '6', '+', '1', - '2', '3', '0', '.', -}; + t_8 scan_code; -static char shiftmap[256] = + RT_ASSERT(kb_in.count>0); + scan_code = *(kb_in.p_tail); + kb_in.p_tail++; + if (kb_in.p_tail == kb_in.buf + KB_IN_BYTES) { + kb_in.p_tail = kb_in.buf; + } + kb_in.count--; + + return scan_code; +} + +PRIVATE void kb_wait() /* wait inpit cache of 8042 */ { - NO, 033, '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '_', '+', '\b', '\t', - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', '\n', NO, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', - '"', '~', NO, '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', NO, '*', - NO, ' ', NO, NO, NO, NO, NO, NO, - NO, NO, NO, NO, NO, NO, NO, '7', - '8', '9', '-', '4', '5', '6', '+', '1', - '2', '3', '0', '.', -}; + t_8 kb_stat; -#define C(x) (x-'@') + do { + kb_stat = inb(KB_CMD); + } while (kb_stat & 0x02); +} -static char ctlmap[256] = +PRIVATE void kb_ack() { - NO, NO, NO, NO, NO, NO, NO, NO, - NO, NO, NO, NO, NO, NO, NO, NO, - C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'), - C('O'), C('P'), NO, NO, '\r', NO, C('A'), C('S'), - C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), NO, - NO, NO, NO, C('\\'), C('Z'), C('X'), C('C'), C('V'), - C('B'), C('N'), C('M'), NO, NO, C('/'), NO, NO, -}; + t_8 kb_read; -static char *charcode[4] = + do { + kb_read = inb(KB_DATA); + } while (kb_read != KB_ACK); +} + +PRIVATE void set_leds() { - normalmap, - shiftmap, - ctlmap, - ctlmap, -}; + t_8 leds = (caps_lock << 2) | (num_lock << 1) | scroll_lock; + + kb_wait(); + outb(KB_DATA, LED_CODE); + kb_ack(); + + kb_wait(); + outb(KB_DATA, leds); + kb_ack(); +} /** * @addtogroup QEMU */ /*@{*/ -/** - * This function get a char from the keyboard - */ -char rt_keyboard_getc(void) +void rt_keyboard_isr(void) { - int c; rt_uint8_t data; - static rt_uint32_t shift; if ((inb(KBSTATP) & KBS_DIB) == 0) - return -1; + return ; data = inb(KBDATAP); - if (data & 0x80) + if (kb_in.count < KB_IN_BYTES) { + *(kb_in.p_head) = data; + kb_in.p_head++; + if (kb_in.p_head == kb_in.buf + KB_IN_BYTES) { + kb_in.p_head = kb_in.buf; + } + kb_in.count++; + } +} +/* generally, this should be called in task level for all key inpit support, +but here only support a key that is composed of 2 bytes */ +rt_bool_t rt_keyboard_getc(char* c) +{ + if(kb_in.count>=2) { - /* key up */ - shift &= ~shiftcode[data&~0x80]; - return 0; + rt_uint32_t key = 0; + rt_bool_t rv=keyboard_read(&key); + + switch(key) + { + case TAB: + *c = '\t'; + break; + case ENTER: + *c = '\n'; + break; + case BACKSPACE: + *c = '\b'; + break; + default: + *c = key; + break; + } + + return rv; } - /* key down */ - shift |= shiftcode[data]; - shift ^= togglecode[data]; - c = charcode[shift&(CTL|SHIFT)][data]; - - if (shift&CAPSLOCK) - { - if ('a' <= c && c <= 'z') - c += 'A' - 'a'; - else if ('A' <= c && c <= 'Z') - c += 'a' - 'A'; - } - - return c; + return RT_FALSE; } /*@}*/ diff --git a/bsp/x86/drivers/keyboard.h b/bsp/x86/drivers/keyboard.h new file mode 100644 index 0000000000..f3e849df96 --- /dev/null +++ b/bsp/x86/drivers/keyboard.h @@ -0,0 +1,132 @@ + +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + keyboard.h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Forrest Yu, 2005 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + +#ifndef _TINIX_KEYBOARD_H_ +#define _TINIX_KEYBOARD_H_ + + +/************************************************************************/ +/* Macros Declaration */ +/************************************************************************/ +#define KB_IN_BYTES 32 /* size of keyboard input buffer */ +#define MAP_COLS 3 /* Number of columns in keymap */ +#define NR_SCAN_CODES 0x80 /* Number of scan codes (rows in keymap) */ + +#define FLAG_BREAK 0x0080 /* Break Code */ +#define FLAG_EXT 0x0100 /* Normal function keys */ +#define FLAG_SHIFT_L 0x0200 /* Shift key */ +#define FLAG_SHIFT_R 0x0400 /* Shift key */ +#define FLAG_CTRL_L 0x0800 /* Control key */ +#define FLAG_CTRL_R 0x1000 /* Control key */ +#define FLAG_ALT_L 0x2000 /* Alternate key */ +#define FLAG_ALT_R 0x4000 /* Alternate key */ +#define FLAG_PAD 0x8000 /* keys in num pad */ + +#define MASK_RAW 0x01FF /* raw key value = code passed to tty & MASK_RAW + the value can be found either in the keymap column 0 + or in the list below */ + +/* Special keys */ +#define ESC (0x01 + FLAG_EXT) /* Esc */ +#define TAB (0x02 + FLAG_EXT) /* Tab */ +#define ENTER (0x03 + FLAG_EXT) /* Enter */ +#define BACKSPACE (0x04 + FLAG_EXT) /* BackSpace */ + +#define GUI_L (0x05 + FLAG_EXT) /* L GUI */ +#define GUI_R (0x06 + FLAG_EXT) /* R GUI */ +#define APPS (0x07 + FLAG_EXT) /* APPS */ + +/* Shift, Ctrl, Alt */ +#define SHIFT_L (0x08 + FLAG_EXT) /* L Shift */ +#define SHIFT_R (0x09 + FLAG_EXT) /* R Shift */ +#define CTRL_L (0x0A + FLAG_EXT) /* L Ctrl */ +#define CTRL_R (0x0B + FLAG_EXT) /* R Ctrl */ +#define ALT_L (0x0C + FLAG_EXT) /* L Alt */ +#define ALT_R (0x0D + FLAG_EXT) /* R Alt */ + +/* Lock keys */ +#define CAPS_LOCK (0x0E + FLAG_EXT) /* Caps Lock */ +#define NUM_LOCK (0x0F + FLAG_EXT) /* Number Lock */ +#define SCROLL_LOCK (0x10 + FLAG_EXT) /* Scroll Lock */ + +/* Function keys */ +#define F1 (0x11 + FLAG_EXT) /* F1 */ +#define F2 (0x12 + FLAG_EXT) /* F2 */ +#define F3 (0x13 + FLAG_EXT) /* F3 */ +#define F4 (0x14 + FLAG_EXT) /* F4 */ +#define F5 (0x15 + FLAG_EXT) /* F5 */ +#define F6 (0x16 + FLAG_EXT) /* F6 */ +#define F7 (0x17 + FLAG_EXT) /* F7 */ +#define F8 (0x18 + FLAG_EXT) /* F8 */ +#define F9 (0x19 + FLAG_EXT) /* F9 */ +#define F10 (0x1A + FLAG_EXT) /* F10 */ +#define F11 (0x1B + FLAG_EXT) /* F11 */ +#define F12 (0x1C + FLAG_EXT) /* F12 */ + +/* Control Pad */ +#define PRINTSCREEN (0x1D + FLAG_EXT) /* Print Screen */ +#define PAUSEBREAK (0x1E + FLAG_EXT) /* Pause/Break */ +#define INSERT (0x1F + FLAG_EXT) /* Insert */ +#define DELETE (0x20 + FLAG_EXT) /* Delete */ +#define HOME (0x21 + FLAG_EXT) /* Home */ +#define END (0x22 + FLAG_EXT) /* End */ +#define PAGEUP (0x23 + FLAG_EXT) /* Page Up */ +#define PAGEDOWN (0x24 + FLAG_EXT) /* Page Down */ +#define UP (0x25 + FLAG_EXT) /* Up */ +#define DOWN (0x26 + FLAG_EXT) /* Down */ +#define LEFT (0x27 + FLAG_EXT) /* Left */ +#define RIGHT (0x28 + FLAG_EXT) /* Right */ + +/* ACPI keys */ +#define POWER (0x29 + FLAG_EXT) /* Power */ +#define SLEEP (0x2A + FLAG_EXT) /* Sleep */ +#define WAKE (0x2B + FLAG_EXT) /* Wake Up */ + +/* Num Pad */ +#define PAD_SLASH (0x2C + FLAG_EXT) /* / */ +#define PAD_STAR (0x2D + FLAG_EXT) /* * */ +#define PAD_MINUS (0x2E + FLAG_EXT) /* - */ +#define PAD_PLUS (0x2F + FLAG_EXT) /* + */ +#define PAD_ENTER (0x30 + FLAG_EXT) /* Enter */ +#define PAD_DOT (0x31 + FLAG_EXT) /* . */ +#define PAD_0 (0x32 + FLAG_EXT) /* 0 */ +#define PAD_1 (0x33 + FLAG_EXT) /* 1 */ +#define PAD_2 (0x34 + FLAG_EXT) /* 2 */ +#define PAD_3 (0x35 + FLAG_EXT) /* 3 */ +#define PAD_4 (0x36 + FLAG_EXT) /* 4 */ +#define PAD_5 (0x37 + FLAG_EXT) /* 5 */ +#define PAD_6 (0x38 + FLAG_EXT) /* 6 */ +#define PAD_7 (0x39 + FLAG_EXT) /* 7 */ +#define PAD_8 (0x3A + FLAG_EXT) /* 8 */ +#define PAD_9 (0x3B + FLAG_EXT) /* 9 */ +#define PAD_UP PAD_8 /* Up */ +#define PAD_DOWN PAD_2 /* Down */ +#define PAD_LEFT PAD_4 /* Left */ +#define PAD_RIGHT PAD_6 /* Right */ +#define PAD_HOME PAD_7 /* Home */ +#define PAD_END PAD_1 /* End */ +#define PAD_PAGEUP PAD_9 /* Page Up */ +#define PAD_PAGEDOWN PAD_3 /* Page Down */ +#define PAD_INS PAD_0 /* Ins */ +#define PAD_MID PAD_5 /* Middle key */ +#define PAD_DEL PAD_DOT /* Del */ + + +/************************************************************************/ +/* Stucture Definition */ +/************************************************************************/ +/* Keyboard structure, 1 per console. */ +typedef struct s_kb { + char* p_head; /* input cache pointer */ + char* p_tail; /* read cache pointer */ + int count; + char buf[KB_IN_BYTES]; +}KB_INPUT; + + + +#endif /* _TINIX_KEYBOARD_H_ */ diff --git a/bsp/x86/drivers/keymap.h b/bsp/x86/drivers/keymap.h new file mode 100644 index 0000000000..3031438a1b --- /dev/null +++ b/bsp/x86/drivers/keymap.h @@ -0,0 +1,239 @@ + +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + keymap.h +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Forrest Yu, 2005 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + +/********************************************************************/ +/* "scan code" <--> "key" map. */ +/* It should be and can only be included by keyboard.c! */ +/********************************************************************/ + +#ifndef _TINIX_KEYMAP_H_ +#define _TINIX_KEYMAP_H_ + + +/* Keymap for US MF-2 keyboard. */ + +rt_uint32_t keymap[NR_SCAN_CODES * MAP_COLS] = { + +/* scan-code !Shift Shift E0 XX */ +/* ==================================================================== */ +/* 0x00 - none */ 0, 0, 0, +/* 0x01 - ESC */ ESC, ESC, 0, +/* 0x02 - '1' */ '1', '!', 0, +/* 0x03 - '2' */ '2', '@', 0, +/* 0x04 - '3' */ '3', '#', 0, +/* 0x05 - '4' */ '4', '$', 0, +/* 0x06 - '5' */ '5', '%', 0, +/* 0x07 - '6' */ '6', '^', 0, +/* 0x08 - '7' */ '7', '&', 0, +/* 0x09 - '8' */ '8', '*', 0, +/* 0x0A - '9' */ '9', '(', 0, +/* 0x0B - '0' */ '0', ')', 0, +/* 0x0C - '-' */ '-', '_', 0, +/* 0x0D - '=' */ '=', '+', 0, +/* 0x0E - BS */ BACKSPACE, BACKSPACE, 0, +/* 0x0F - TAB */ TAB, TAB, 0, +/* 0x10 - 'q' */ 'q', 'Q', 0, +/* 0x11 - 'w' */ 'w', 'W', 0, +/* 0x12 - 'e' */ 'e', 'E', 0, +/* 0x13 - 'r' */ 'r', 'R', 0, +/* 0x14 - 't' */ 't', 'T', 0, +/* 0x15 - 'y' */ 'y', 'Y', 0, +/* 0x16 - 'u' */ 'u', 'U', 0, +/* 0x17 - 'i' */ 'i', 'I', 0, +/* 0x18 - 'o' */ 'o', 'O', 0, +/* 0x19 - 'p' */ 'p', 'P', 0, +/* 0x1A - '[' */ '[', '{', 0, +/* 0x1B - ']' */ ']', '}', 0, +/* 0x1C - CR/LF */ ENTER, ENTER, PAD_ENTER, +/* 0x1D - l. Ctrl */ CTRL_L, CTRL_L, CTRL_R, +/* 0x1E - 'a' */ 'a', 'A', 0, +/* 0x1F - 's' */ 's', 'S', 0, +/* 0x20 - 'd' */ 'd', 'D', 0, +/* 0x21 - 'f' */ 'f', 'F', 0, +/* 0x22 - 'g' */ 'g', 'G', 0, +/* 0x23 - 'h' */ 'h', 'H', 0, +/* 0x24 - 'j' */ 'j', 'J', 0, +/* 0x25 - 'k' */ 'k', 'K', 0, +/* 0x26 - 'l' */ 'l', 'L', 0, +/* 0x27 - ';' */ ';', ':', 0, +/* 0x28 - '\'' */ '\'', '"', 0, +/* 0x29 - '`' */ '`', '~', 0, +/* 0x2A - l. SHIFT */ SHIFT_L, SHIFT_L, 0, +/* 0x2B - '\' */ '\\', '|', 0, +/* 0x2C - 'z' */ 'z', 'Z', 0, +/* 0x2D - 'x' */ 'x', 'X', 0, +/* 0x2E - 'c' */ 'c', 'C', 0, +/* 0x2F - 'v' */ 'v', 'V', 0, +/* 0x30 - 'b' */ 'b', 'B', 0, +/* 0x31 - 'n' */ 'n', 'N', 0, +/* 0x32 - 'm' */ 'm', 'M', 0, +/* 0x33 - ',' */ ',', '<', 0, +/* 0x34 - '.' */ '.', '>', 0, +/* 0x35 - '/' */ '/', '?', PAD_SLASH, +/* 0x36 - r. SHIFT */ SHIFT_R, SHIFT_R, 0, +/* 0x37 - '*' */ '*', '*', 0, +/* 0x38 - ALT */ ALT_L, ALT_L, ALT_R, +/* 0x39 - ' ' */ ' ', ' ', 0, +/* 0x3A - CapsLock */ CAPS_LOCK, CAPS_LOCK, 0, +/* 0x3B - F1 */ F1, F1, 0, +/* 0x3C - F2 */ F2, F2, 0, +/* 0x3D - F3 */ F3, F3, 0, +/* 0x3E - F4 */ F4, F4, 0, +/* 0x3F - F5 */ F5, F5, 0, +/* 0x40 - F6 */ F6, F6, 0, +/* 0x41 - F7 */ F7, F7, 0, +/* 0x42 - F8 */ F8, F8, 0, +/* 0x43 - F9 */ F9, F9, 0, +/* 0x44 - F10 */ F10, F10, 0, +/* 0x45 - NumLock */ NUM_LOCK, NUM_LOCK, 0, +/* 0x46 - ScrLock */ SCROLL_LOCK, SCROLL_LOCK, 0, +/* 0x47 - Home */ PAD_HOME, '7', HOME, +/* 0x48 - CurUp */ PAD_UP, '8', UP, +/* 0x49 - PgUp */ PAD_PAGEUP, '9', PAGEUP, +/* 0x4A - '-' */ PAD_MINUS, '-', 0, +/* 0x4B - Left */ PAD_LEFT, '4', LEFT, +/* 0x4C - MID */ PAD_MID, '5', 0, +/* 0x4D - Right */ PAD_RIGHT, '6', RIGHT, +/* 0x4E - '+' */ PAD_PLUS, '+', 0, +/* 0x4F - End */ PAD_END, '1', END, +/* 0x50 - Down */ PAD_DOWN, '2', DOWN, +/* 0x51 - PgDown */ PAD_PAGEDOWN, '3', PAGEDOWN, +/* 0x52 - Insert */ PAD_INS, '0', INSERT, +/* 0x53 - Delete */ PAD_DOT, '.', DELETE, +/* 0x54 - Enter */ 0, 0, 0, +/* 0x55 - ??? */ 0, 0, 0, +/* 0x56 - ??? */ 0, 0, 0, +/* 0x57 - F11 */ F11, F11, 0, +/* 0x58 - F12 */ F12, F12, 0, +/* 0x59 - ??? */ 0, 0, 0, +/* 0x5A - ??? */ 0, 0, 0, +/* 0x5B - ??? */ 0, 0, GUI_L, +/* 0x5C - ??? */ 0, 0, GUI_R, +/* 0x5D - ??? */ 0, 0, APPS, +/* 0x5E - ??? */ 0, 0, 0, +/* 0x5F - ??? */ 0, 0, 0, +/* 0x60 - ??? */ 0, 0, 0, +/* 0x61 - ??? */ 0, 0, 0, +/* 0x62 - ??? */ 0, 0, 0, +/* 0x63 - ??? */ 0, 0, 0, +/* 0x64 - ??? */ 0, 0, 0, +/* 0x65 - ??? */ 0, 0, 0, +/* 0x66 - ??? */ 0, 0, 0, +/* 0x67 - ??? */ 0, 0, 0, +/* 0x68 - ??? */ 0, 0, 0, +/* 0x69 - ??? */ 0, 0, 0, +/* 0x6A - ??? */ 0, 0, 0, +/* 0x6B - ??? */ 0, 0, 0, +/* 0x6C - ??? */ 0, 0, 0, +/* 0x6D - ??? */ 0, 0, 0, +/* 0x6E - ??? */ 0, 0, 0, +/* 0x6F - ??? */ 0, 0, 0, +/* 0x70 - ??? */ 0, 0, 0, +/* 0x71 - ??? */ 0, 0, 0, +/* 0x72 - ??? */ 0, 0, 0, +/* 0x73 - ??? */ 0, 0, 0, +/* 0x74 - ??? */ 0, 0, 0, +/* 0x75 - ??? */ 0, 0, 0, +/* 0x76 - ??? */ 0, 0, 0, +/* 0x77 - ??? */ 0, 0, 0, +/* 0x78 - ??? */ 0, 0, 0, +/* 0x78 - ??? */ 0, 0, 0, +/* 0x7A - ??? */ 0, 0, 0, +/* 0x7B - ??? */ 0, 0, 0, +/* 0x7C - ??? */ 0, 0, 0, +/* 0x7D - ??? */ 0, 0, 0, +/* 0x7E - ??? */ 0, 0, 0, +/* 0x7F - ??? */ 0, 0, 0 +}; + +/*====================================================================================* + Appendix: Scan code set 1 + *====================================================================================* + +KEY MAKE BREAK ----- KEY MAKE BREAK ----- KEY MAKE BREAK +-------------------------------------------------------------------------------------- +A 1E 9E 9 0A 8A [ 1A 9A +B 30 B0 ` 29 89 INSERT E0,52 E0,D2 +C 2E AE - 0C 8C HOME E0,47 E0,C7 +D 20 A0 = 0D 8D PG UP E0,49 E0,C9 +E 12 92 \ 2B AB DELETE E0,53 E0,D3 +F 21 A1 BKSP 0E 8E END E0,4F E0,CF +G 22 A2 SPACE 39 B9 PG DN E0,51 E0,D1 +H 23 A3 TAB 0F 8F U ARROW E0,48 E0,C8 +I 17 97 CAPS 3A BA L ARROW E0,4B E0,CB +J 24 A4 L SHFT 2A AA D ARROW E0,50 E0,D0 +K 25 A5 L CTRL 1D 9D R ARROW E0,4D E0,CD +L 26 A6 L GUI E0,5B E0,DB NUM 45 C5 +M 32 B2 L ALT 38 B8 KP / E0,35 E0,B5 +N 31 B1 R SHFT 36 B6 KP * 37 B7 +O 18 98 R CTRL E0,1D E0,9D KP - 4A CA +P 19 99 R GUI E0,5C E0,DC KP + 4E CE +Q 10 19 R ALT E0,38 E0,B8 KP EN E0,1C E0,9C +R 13 93 APPS E0,5D E0,DD KP . 53 D3 +S 1F 9F ENTER 1C 9C KP 0 52 D2 +T 14 94 ESC 01 81 KP 1 4F CF +U 16 96 F1 3B BB KP 2 50 D0 +V 2F AF F2 3C BC KP 3 51 D1 +W 11 91 F3 3D BD KP 4 4B CB +X 2D AD F4 3E BE KP 5 4C CC +Y 15 95 F5 3F BF KP 6 4D CD +Z 2C AC F6 40 C0 KP 7 47 C7 +0 0B 8B F7 41 C1 KP 8 48 C8 +1 02 82 F8 42 C2 KP 9 49 C9 +2 03 83 F9 43 C3 ] 1B 9B +3 04 84 F10 44 C4 ; 27 A7 +4 05 85 F11 57 D7 ' 28 A8 +5 06 86 F12 58 D8 , 33 B3 + +6 07 87 PRTSCRN E0,2A E0,B7 . 34 B4 + E0,37 E0,AA + +7 08 88 SCROLL 46 C6 / 35 B5 + +8 09 89 PAUSE E1,1D,45 -NONE- + E1,9D,C5 + + +----------------- +ACPI Scan Codes: +------------------------------------------- +Key Make Code Break Code +------------------------------------------- +Power E0, 5E E0, DE +Sleep E0, 5F E0, DF +Wake E0, 63 E0, E3 + + +------------------------------- +Windows Multimedia Scan Codes: +------------------------------------------- +Key Make Code Break Code +------------------------------------------- +Next Track E0, 19 E0, 99 +Previous Track E0, 10 E0, 90 +Stop E0, 24 E0, A4 +Play/Pause E0, 22 E0, A2 +Mute E0, 20 E0, A0 +Volume Up E0, 30 E0, B0 +Volume Down E0, 2E E0, AE +Media Select E0, 6D E0, ED +E-Mail E0, 6C E0, EC +Calculator E0, 21 E0, A1 +My Computer E0, 6B E0, EB +WWW Search E0, 65 E0, E5 +WWW Home E0, 32 E0, B2 +WWW Back E0, 6A E0, EA +WWW Forward E0, 69 E0, E9 +WWW Stop E0, 68 E0, E8 +WWW Refresh E0, 67 E0, E7 +WWW Favorites E0, 66 E0, E6 + +*=====================================================================================*/ + + + +#endif /* _TINIX_KEYMAP_H_ */ diff --git a/bsp/x86/drivers/serial.c b/bsp/x86/drivers/serial.c index e2796aa063..51b7a0d96d 100644 --- a/bsp/x86/drivers/serial.c +++ b/bsp/x86/drivers/serial.c @@ -17,7 +17,6 @@ #include #include -extern char rt_keyboard_getc(void); /** * @addtogroup QEMU @@ -45,13 +44,11 @@ void rt_serial_init(void) */ char rt_serial_getc(void) { - return rt_keyboard_getc(); -#if 0 while(!(inb(COM1+COMSTATUS) & COMDATA)); return inb(COM1+COMREAD); -#endif + } /** diff --git a/bsp/x86/rtconfig.h b/bsp/x86/rtconfig.h index 47c996cc46..780a1abc94 100644 --- a/bsp/x86/rtconfig.h +++ b/bsp/x86/rtconfig.h @@ -17,7 +17,7 @@ /* SECTION: RT_DEBUG */ /* Thread Debug */ #define RT_DEBUG -#define RT_THREAD_DEBUG +#define RT_DEBUG_MODULE 0 #define RT_USING_OVERFLOW_CHECK @@ -69,6 +69,8 @@ /* SECTION: finsh, a C-Express shell */ #define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_USING_MSH_ONLY /* Using symbol table */ #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION @@ -175,4 +177,7 @@ /* #define RTGUI_IMAGE_XPM */ /* #define RTGUI_IMAGE_BMP */ +#define RT_USING_LIBDL +#define RT_USING_MODULE +#define MODULE_USING_386 #endif diff --git a/bsp/x86/rtconfig.py b/bsp/x86/rtconfig.py index 9819969924..c602315d06 100644 --- a/bsp/x86/rtconfig.py +++ b/bsp/x86/rtconfig.py @@ -32,20 +32,20 @@ BUILD = 'debug' if PLATFORM == 'gcc': # toolchains - PREFIX = 'i686-elf-' - CC = PREFIX + 'gcc' - AS = PREFIX + 'gcc' + PREFIX = '' + CC = PREFIX + 'gcc -m32 -fno-builtin -fno-stack-protector -nostdinc' + AS = PREFIX + 'gcc -m32' AR = PREFIX + 'ar' - LINK = PREFIX + 'gcc' + LINK = PREFIX + 'ld -melf_i386' TARGET_EXT = 'elf' SIZE = PREFIX + 'size' OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' - DEVICE = ' -mtune=generic' + DEVICE = '' CFLAGS = DEVICE + ' -Wall' AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' - LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-ia32.map,-cref,-u,_start -T x86_ram.lds -nostdlib' + LFLAGS = DEVICE + ' -Map rtthread-ia32.map -T x86_ram.lds -nostdlib' CPATH = '' LPATH = '' diff --git a/bsp/x86/src/extract.sh b/bsp/x86/src/extract.sh new file mode 100755 index 0000000000..89f8baef7a --- /dev/null +++ b/bsp/x86/src/extract.sh @@ -0,0 +1,28 @@ +#! /bin/sh + + +imap=$1 +iout=$2 + +echo "!!! extract symbol from $imap to $iout !!!" + +symlist="rt_kprintf \ +rt_kputs \ +rt_vsprintf \ +rt_sprintf \ +rt_snprintf \ +rt_thread_create \ +" + +echo "#ifndef RT_THREAD_SYM_H_H" > $iout +echo "#define RT_THREAD_SYM_H_H" >> $iout + +for sym in $symlist +do +dlim=`echo $sym | cut -b 1` +addr=`cat $imap | grep $sym | head -n 1 | cut -d $dlim -f 1` + +echo "#define __abs_$sym $addr" >> $iout +done + +echo "#endif /* RT_THREAD_SYM_H_H */" >> $iout diff --git a/bsp/x86/src/hello.c b/bsp/x86/src/hello.c new file mode 100644 index 0000000000..a075f18ef1 --- /dev/null +++ b/bsp/x86/src/hello.c @@ -0,0 +1,36 @@ + +#include +const char* g_str = "Hello World!"; + +static int a = 1234; +int b = 5678; + +extern void rt_kprintf(const char* fmt,...); + +int add(int a, int b) +{ + return a+b; +} + +int main(int argc, char* argv[]) +{ + int i; + char str[32] = "Hello World\n"; + + for(i=0; i + +typedef unsigned int size_t; + +typedef int (*sprintf_fcn_t)(char *buf ,const char *format, ...); +typedef int (*snprintf_fcn_t)(char *buf, size_t size, const char *format, ...); +typedef void (*puts_fcn_t)(const char *str); +typedef void (*printf_fcn_t)(const char *fmt, ...); + +#define printf ((printf_fcn_t)__abs_rt_kprintf) +#define puts ((printf_fcn_t)__abs_rt_kputs) +#define sprintf ((printf_fcn_t)__abs_rt_sprintf) +#define snprintf ((printf_fcn_t)__abs_rt_snprintf) + +#endif diff --git a/bsp/x86/x86_ram.lds b/bsp/x86/x86_ram.lds index 27fe392708..afac69f04b 100644 --- a/bsp/x86/x86_ram.lds +++ b/bsp/x86/x86_ram.lds @@ -21,10 +21,13 @@ SECTIONS KEEP(*(VSymTab)) __vsymtab_end = .; . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)); + __rtmsymtab_end = .; } . = ALIGN(4); - .rodata : { *(.rodata) } + .rodata : { *(.rodata*) } . = ALIGN(4); .data : { *(.data) } diff --git a/components/drivers/can/can.c b/components/drivers/can/can.c index d1cc21dd3f..bbd1e2dcf6 100644 --- a/components/drivers/can/can.c +++ b/components/drivers/can/can.c @@ -154,20 +154,11 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da rt_uint32_t result; struct rt_can_sndbxinx_list *tx_tosnd = RT_NULL; + rt_sem_take(&(tx_fifo->sem), RT_WAITING_FOREVER); level = rt_hw_interrupt_disable(); - if (!rt_list_isempty(&tx_fifo->freelist)) - { - tx_tosnd = rt_list_entry(tx_fifo->freelist.next, struct rt_can_sndbxinx_list, list); - RT_ASSERT(tx_tosnd != RT_NULL); - rt_list_remove(&tx_tosnd->list); - } - else - { - rt_hw_interrupt_enable(level); - - rt_completion_wait(&(tx_fifo->completion), RT_WAITING_FOREVER); - continue; - } + tx_tosnd = rt_list_entry(tx_fifo->freelist.next, struct rt_can_sndbxinx_list, list); + RT_ASSERT(tx_tosnd != RT_NULL); + rt_list_remove(&tx_tosnd->list); rt_hw_interrupt_enable(level); no = ((rt_uint32_t)tx_tosnd - (rt_uint32_t)tx_fifo->buffer) / sizeof(struct rt_can_sndbxinx_list); @@ -178,6 +169,7 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da level = rt_hw_interrupt_disable(); rt_list_insert_after(&tx_fifo->freelist, &tx_tosnd->list); rt_hw_interrupt_enable(level); + rt_sem_release(&(tx_fifo->sem)); continue; } @@ -191,8 +183,8 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da rt_list_remove(&tx_tosnd->list); } rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list); - rt_completion_done(&(tx_fifo->completion)); rt_hw_interrupt_enable(level); + rt_sem_release(&(tx_fifo->sem)); if (result == RT_CAN_SND_RESULT_OK) { @@ -280,7 +272,7 @@ rt_inline int _can_int_tx_priv(struct rt_can_device *can, const struct rt_can_ms static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag) { struct rt_can_device *can; - + char tmpname[16]; RT_ASSERT(dev != RT_NULL); can = (struct rt_can_device *)dev; @@ -341,7 +333,9 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag) rt_completion_init(&(tx_fifo->buffer[i].completion)); tx_fifo->buffer[i].result = RT_CAN_SND_RESULT_OK; } - rt_completion_init(&(tx_fifo->completion)); + + rt_sprintf(tmpname, "%stl", dev->parent.name); + rt_sem_init(&(tx_fifo->sem), tmpname, can->config.sndboxnumber, RT_IPC_FLAG_FIFO); can->can_tx = tx_fifo; dev->open_flag |= RT_DEVICE_FLAG_INT_TX; @@ -535,14 +529,20 @@ static rt_err_t rt_can_control(struct rt_device *dev, tx_fifo = (struct rt_can_tx_fifo *) can->can_tx; if (can->config.privmode) { - rt_completion_done(&(tx_fifo->completion)); - for (i = 0; i < can->config.sndboxnumber; i++) { - level = rt_hw_interrupt_disable(); - rt_list_remove(&tx_fifo->buffer[i].list); + level = rt_hw_interrupt_disable(); + if(rt_list_isempty(&tx_fifo->buffer[i].list)) + { + rt_sem_release(&(tx_fifo->sem)); + } + else + { + rt_list_remove(&tx_fifo->buffer[i].list); + } rt_hw_interrupt_enable(level); } + } else { diff --git a/components/drivers/i2c/i2c_core.c b/components/drivers/i2c/i2c_core.c index 739ae7ad43..67778ce0d3 100644 --- a/components/drivers/i2c/i2c_core.c +++ b/components/drivers/i2c/i2c_core.c @@ -67,7 +67,7 @@ rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus, #ifdef RT_I2C_DEBUG for (ret = 0; ret < num; ret++) { - i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d%s\n", ret, + i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d\n", ret, (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W', msgs[ret].addr, msgs[ret].len); } diff --git a/components/drivers/include/drivers/can.h b/components/drivers/include/drivers/can.h index 71b577eba0..ecf3b5f51e 100644 --- a/components/drivers/include/drivers/can.h +++ b/components/drivers/include/drivers/can.h @@ -280,7 +280,7 @@ struct rt_can_sndbxinx_list struct rt_can_tx_fifo { struct rt_can_sndbxinx_list *buffer; - struct rt_completion completion; + struct rt_semaphore sem; struct rt_list_node freelist; }; diff --git a/components/drivers/spi/sfud/LICENSE b/components/drivers/spi/sfud/LICENSE index 6b761d3f4a..f956e1683d 100644 --- a/components/drivers/spi/sfud/LICENSE +++ b/components/drivers/spi/sfud/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 Armink (armink.ztl@gmail.com) +Copyright (c) 2016-2017 Armink (armink.ztl@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/components/drivers/spi/sfud/README.md b/components/drivers/spi/sfud/README.md index 69ea4a67f6..13ef219154 100644 --- a/components/drivers/spi/sfud/README.md +++ b/components/drivers/spi/sfud/README.md @@ -10,7 +10,7 @@ - 资源占用 - 标准占用:RAM:0.2KB ROM:5.5KB - 最小占用:RAM:0.1KB ROM:3.6KB -- 设计思路:这里要首先跟大家介绍一个标准: **SFDP** ,它是 JEDEC (固态技术协会)制定的串行 Flash 功能的参数表标准,最新版 V1.6B ([点击这里查看](https://www.jedec.org/standards-documents/docs/jesd216b))。该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粗粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数,如果该 Flash 不支持 SFDP,则查询配置文件 ( `/sfud/inc/sfud_flash_def.h` ) 中提供的 **Flash 参数信息表** 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息(添加方法详细见 [2.5 添加库目前不支持的 Flash](#25-添加库目前不支持的-flash))。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。 +- 设计思路:这里要首先跟大家介绍一个标准: **SFDP** ,它是 JEDEC (固态技术协会)制定的串行 Flash 功能的参数表标准,最新版 V1.6B ([点击这里查看](https://www.jedec.org/standards-documents/docs/jesd216b))。该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数,如果该 Flash 不支持 SFDP,则查询配置文件 ( [`/sfud/inc/sfud_flash_def.h`](https://github.com/armink/SFUD/blob/master/sfud/inc/sfud_flash_def.h#L110-L122) ) 中提供的 **Flash 参数信息表** 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息(添加方法详细见 [2.5 添加库目前不支持的 Flash](#25-添加库目前不支持的-flash))。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。 ## 1、为什么选择 SFUD @@ -25,7 +25,7 @@ 下表为所有在 Demo 平台上进行过真机测试的 Flash。目前 SFUD 提供的 **Flash 参数信息表** 只包括下表中 **不支持** SFDP 标准的 Flash,其他不支持 SFDP 标准的 Flash 需要大家以后 **共同来完善和维护** **([Github](https://github.com/armink/SFUD)|[OSChina](http://git.oschina.net/armink/SFUD)|[Coding](https://coding.net/u/armink/p/SFUD/git))** 。如果觉得这个开源项目很赞,可以点击 [项目主页](https://github.com/armink/SFUD) 右上角的 **Star** ,同时把它推荐给更多有需要的朋友。 -|型号|制造商|容量|最高速度|SFDP|备注| +|型号|制造商|容量|最高速度|SFDP 标准|备注| |:--:|:----:|:--:|:--:|:--:|:--:| |[W25Q40BV](http://microchip.ua/esp8266/W25Q40BV(EOL).pdf)|Winbond|4Mb|50Mhz|不支持|已停产| |[W25Q80DV](http://www.winbond.com/resource-files/w25q80dv_revg_07212015.pdf)|Winbond|8Mb|104Mhz|支持|| @@ -39,7 +39,8 @@ |[SST25VF016B](http://ww1.microchip.com/downloads/en/DeviceDoc/20005044C.pdf)|Microchip|16Mb|50MHz|不支持| SST 已被 Microchip 收购| |[M25P32](https://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/m25p/m25p32.pdf)|Micron|32Mb|75Mhz|不支持|| |[EN25Q32B](http://www.kean.com.au/oshw/WR703N/teardown/EN25Q32B%2032Mbit%20SPI%20Flash.pdf)|EON|32Mb|104MHz|不支持|| -|[GD25Q64B](http://www.gigadevice.com/product/download/24.html)|GigaDevice|64Mb|120Mhz|不支持|| +|[GD25Q64B](http://www.gigadevice.com/product/detail/5/364.html)|GigaDevice|64Mb|120Mhz|不支持|| +|[GD25Q16B](http://www.gigadevice.com/product/detail/5/410.html)|GigaDevice|16Mb|120Mhz|不支持| by [TanekLiang](https://github.com/TanekLiang) | |[S25FL216K](http://www.cypress.com/file/197346/download)|Cypress|16Mb|65Mhz|不支持|| |[S25FL164K](http://www.cypress.com/file/196886/download)|Cypress|64Mb|108Mhz|支持|| |[A25LQ64](http://www.amictechnology.com/datasheets/A25LQ64.pdf)|AMIC|64Mb|104Mhz|支持|| @@ -50,8 +51,12 @@ ### 2.2 API 说明 +先说明下本库主要使用的一个结构体 `sfud_flash` 。其定义位于 `/sfud/inc/sfud_def.h`。每个 SPI Flash 会对应一个该结构体,该结构体指针下面统称为 Flash 设备对象。初始化成功后在 `sfud_flash->chip` 结构体中会存放 SPI Flash 的常见参数。如果 SPI Flash 还支持 SFDP ,还可以通过 `sfud_flash->sfdp` 看到更加全面的参数信息。以下很多函数都将使用 Flash 设备对象作为第一个入参,实现对指定 SPI Flash 的操作。 + #### 2.2.1 初始化 SFUD 库 +> 注意:初始化完的 SPI Flash 默认都 **已取消写保护** 状态,如需开启写保护,请使用 sfud_write_status 函数修改 SPI Flash 状态。 + ```C sfud_err sfud_init(void) ``` @@ -92,11 +97,13 @@ sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t |:----- |:----| |flash |Flash 设备对象| |addr |起始地址| -|size |读取数据的大小| +|size |从起始地址开始读取数据的总大小| |data |读取到的数据| #### 2.2.6 擦除 Flash 数据 +> 注意:擦除操作将会按照 Flash 芯片的擦除粒度(详见 Flash 数据手册,一般为 block 大小。初始化完成后,可以通过 `sfud_flash->chip.erase_gran` 查看)对齐,请注意保证起始地址和擦除数据大小按照 Flash 芯片的擦除粒度对齐,否则执行擦除操作后,将会导致其他数据丢失。 + ```C sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size) ``` @@ -105,7 +112,7 @@ sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size) |:----- |:----| |flash |Flash 设备对象| |addr |起始地址| -|size |擦除数据的大小| +|size |从起始地址开始擦除数据的总大小| #### 2.2.7 擦除 Flash 全部数据 @@ -127,11 +134,13 @@ sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const u |:----- |:----| |flash |Flash 设备对象| |addr |起始地址| -|size |写数据的大小| +|size |从起始地址开始写入数据的总大小| |data |待写入的数据| #### 2.2.9 先擦除再往 Flash 写数据 +> 注意:擦除操作将会按照 Flash 芯片的擦除粒度(详见 Flash 数据手册,一般为 block 大小。初始化完成后,可以通过 `sfud_flash->chip.erase_gran` 查看)对齐,请注意保证起始地址和擦除数据大小按照 Flash 芯片的擦除粒度对齐,否则执行擦除操作后,将会导致其他数据丢失。 + ```C sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data) ``` @@ -140,7 +149,7 @@ sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, c |:----- |:----| |flash |Flash 设备对象| |addr |起始地址| -|size |写数据的大小| +|size |从起始地址开始写入数据的总大小| |data |待写入的数据| #### 2.2.10 读取 Flash 状态 @@ -211,7 +220,7 @@ enum { ### 2.5 添加库目前不支持的 Flash -这里需要修改 `/sfud/inc/sfdu_flash_def.h` ,所有已经支持的 Flash 见 `SFUD_FLASH_CHIP_TABLE` 宏定义,需要提前准备的 Flash 参数内容分别为:| 名称 | 制造商 ID | 类型 ID | 容量 ID | 容量 | 写模式 | 擦除粗粒度(擦除的最小单位) | 擦除粗粒度对应的命令 | 。这里以添加 兆易创新 ( GigaDevice ) 的 `GD25Q64B` Flash 来举例。 +这里需要修改 `/sfud/inc/sfdu_flash_def.h` ,所有已经支持的 Flash 见 `SFUD_FLASH_CHIP_TABLE` 宏定义,需要提前准备的 Flash 参数内容分别为:| 名称 | 制造商 ID | 类型 ID | 容量 ID | 容量 | 写模式 | 擦除粒度(擦除的最小单位) | 擦除粒度对应的命令 | 。这里以添加 兆易创新 ( GigaDevice ) 的 `GD25Q64B` Flash 来举例。 此款 Flash 为兆易创新的早期生产的型号,所以不支持 SFDP 标准。首先需要下载其数据手册,找到 0x9F 命令返回的 3 种 ID, 这里需要最后面两字节 ID ,即 `type id` 及 `capacity id` 。 `GD25Q64B` 对应这两个 ID 分别为 `0x40` 及 `0x17` 。上面要求的其他 Flash 参数都可以在数据手册中找到,这里要重点说明下 **写模式** 这个参数,库本身提供的写模式共计有 4 种,详见文件顶部的 `sfud_write_mode` 枚举类型,同一款 Flash 可以同时支持多种写模式,视情况而定。对于 `GD25Q64B` 而言,其支持的写模式应该为 `SFUD_WM_PAGE_256B` ,即写 1-256 字节每页。结合上述 `GD25Q64B` 的 Flash 参数应如下: @@ -232,4 +241,4 @@ enum { ### 2.7 许可 -采用 MIT 开源协议,细节请阅读项目中的 LICENSE 文件内容。 \ No newline at end of file +采用 MIT 开源协议,细节请阅读项目中的 LICENSE 文件内容。 diff --git a/components/drivers/spi/sfud/inc/sfud_def.h b/components/drivers/spi/sfud/inc/sfud_def.h index 44dd03c745..cc38c3fa1a 100644 --- a/components/drivers/spi/sfud/inc/sfud_def.h +++ b/components/drivers/spi/sfud/inc/sfud_def.h @@ -41,12 +41,16 @@ extern "C" { /* debug print function. Must be implement by user. */ #ifdef SFUD_DEBUG_MODE +#ifndef SFUD_DEBUG #define SFUD_DEBUG(...) sfud_log_debug(__FILE__, __LINE__, __VA_ARGS__) +#endif /* SFUD_DEBUG */ #else #define SFUD_DEBUG(...) -#endif +#endif /* SFUD_DEBUG_MODE */ +#ifndef SFUD_INFO #define SFUD_INFO(...) sfud_log_info(__VA_ARGS__) +#endif /* assert for developer. */ #ifdef SFUD_DEBUG_MODE @@ -73,7 +77,7 @@ if (!(EXPR)) \ else {if (__delay_temp) {__delay_temp();} retry --;} /* software version number */ -#define SFUD_SW_VERSION "0.10.14" +#define SFUD_SW_VERSION "1.0.1" /* * all defined supported command */ diff --git a/components/drivers/spi/sfud/inc/sfud_flash_def.h b/components/drivers/spi/sfud/inc/sfud_flash_def.h index b593297df6..06c95b775a 100644 --- a/components/drivers/spi/sfud/inc/sfud_flash_def.h +++ b/components/drivers/spi/sfud/inc/sfud_flash_def.h @@ -1,7 +1,7 @@ /* * This file is part of the Serial Flash Universal Driver Library. * - * Copyright (c) 2016, Armink, + * Copyright (c) 2016-2017, Armink, * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -103,8 +103,8 @@ typedef struct { #ifdef SFUD_USING_FLASH_INFO_TABLE /* SFUD supported flash chip information table. If the flash not support JEDEC JESD216 standard, - * then the SFUD will find the flash chip information by this table. Developer can add other flash to here. - * The configuration information name and index reference the sfud_flash_chip structure. + * then the SFUD will find the flash chip information by this table. You can add other flash to here then + * notice me for update it. The configuration information name and index reference the sfud_flash_chip structure. * | name | mf_id | type_id | capacity_id | capacity | write_mode | erase_gran | erase_gran_cmd | */ #define SFUD_FLASH_CHIP_TABLE \ @@ -115,6 +115,7 @@ typedef struct { {"M25P32", SFUD_MF_ID_MICRON, 0x20, 0x16, 4*1024*1024, SFUD_WM_PAGE_256B, 64*1024, 0xD8}, \ {"EN25Q32B", SFUD_MF_ID_EON, 0x30, 0x16, 4*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \ {"GD25Q64B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, 8*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \ + {"GD25Q16B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x15, 2*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \ {"S25FL216K", SFUD_MF_ID_CYPRESS, 0x40, 0x15, 2*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \ {"A25L080", SFUD_MF_ID_AMIC, 0x30, 0x14, 1*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \ {"F25L004", SFUD_MF_ID_ESMT, 0x20, 0x13, 512*1024, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \ diff --git a/components/drivers/spi/sfud/src/sfud.c b/components/drivers/spi/sfud/src/sfud.c index b616e3fad8..475cbd5d9e 100644 --- a/components/drivers/spi/sfud/src/sfud.c +++ b/components/drivers/spi/sfud/src/sfud.c @@ -110,7 +110,7 @@ sfud_err sfud_init(void) { cur_flash_result = sfud_device_init(&flash_table[i]); if (cur_flash_result != SFUD_SUCCESS) { - cur_flash_result = cur_flash_result; + all_flash_result = cur_flash_result; } } @@ -587,12 +587,9 @@ static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, c sfud_err result = SFUD_SUCCESS; const sfud_spi *spi = &flash->spi; uint8_t cmd_data[6], cmd_size; - const size_t data_size = 2; bool first_write = true; SFUD_ASSERT(flash); - SFUD_ASSERT(size >= 2); - /* must be call this function after initialize OK */ SFUD_ASSERT(flash->init_ok); /* check the flash address bound */ if (addr + size > flash->chip.capacity) { @@ -603,41 +600,35 @@ static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, c if (spi->lock) { spi->lock(spi); } - + /* The address must be even for AAI write mode. So it must write one byte first when address is odd. */ + if (addr % 2 != 0) { + result = page256_or_1_byte_write(flash, addr++, 1, 1, data++); + if (result != SFUD_SUCCESS) { + goto __exit; + } + size--; + } /* set the flash write enable */ result = set_write_enabled(flash, true); if (result != SFUD_SUCCESS) { goto __exit; } - /* loop write operate. write unit is write granularity */ + /* loop write operate. */ cmd_data[0] = SFUD_CMD_AAI_WORD_PROGRAM; - while (size) { + while (size >= 2) { if (first_write) { make_adress_byte_array(flash, addr, &cmd_data[1]); cmd_size = flash->addr_in_4_byte ? 5 : 4; - if (addr % 2 == 0) { - cmd_data[cmd_size] = *data; - cmd_data[cmd_size + 1] = *(data + 1); - } else { - cmd_data[cmd_size] = 0xFF; - cmd_data[cmd_size + 1] = *data; - size++; - data--; - } + cmd_data[cmd_size] = *data; + cmd_data[cmd_size + 1] = *(data + 1); first_write = false; } else { cmd_size = 1; - if (size != 1) { - cmd_data[1] = *data; - cmd_data[2] = *(data + 1); - } else { - cmd_data[1] = *data; - cmd_data[2] = 0xFF; - size++; - } + cmd_data[1] = *data; + cmd_data[2] = *(data + 1); } - result = spi->wr(spi, cmd_data, cmd_size + data_size, NULL, 0); + result = spi->wr(spi, cmd_data, cmd_size + 2, NULL, 0); if (result != SFUD_SUCCESS) { SFUD_INFO("Error: Flash write SPI communicate error."); goto __exit; @@ -649,12 +640,20 @@ static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, c } size -= 2; - data += data_size; + addr += 2; + data += 2; + } + /* set the flash write disable for exit AAI mode */ + result = set_write_enabled(flash, false); + /* write last one byte data when origin write size is odd */ + if (result == SFUD_SUCCESS && size == 1) { + result = page256_or_1_byte_write(flash, addr, 1, 1, data); } __exit: - /* set the flash write disable for exist AAI mode */ - set_write_enabled(flash, false); + if (result != SFUD_SUCCESS) { + set_write_enabled(flash, false); + } /* unlock SPI */ if (spi->unlock) { spi->unlock(spi); diff --git a/components/drivers/spi/sfud/src/sfud_sfdp.c b/components/drivers/spi/sfud/src/sfud_sfdp.c index 95157e613f..32873ab8cb 100644 --- a/components/drivers/spi/sfud/src/sfud_sfdp.c +++ b/components/drivers/spi/sfud/src/sfud_sfdp.c @@ -119,7 +119,7 @@ static bool read_sfdp_header(sfud_flash *flash) { header[1] == 'F' && header[2] == 'D' && header[3] == 'P')) { - SFUD_INFO("Error: Check SFDP signature error. It's must be 50444653h('S' 'F' 'D' 'P')."); + SFUD_DEBUG("Error: Check SFDP signature error. It's must be 50444653h('S' 'F' 'D' 'P')."); return false; } sfdp->minor_rev = header[4]; diff --git a/components/finsh/shell.c b/components/finsh/shell.c index 7e8a84ab27..2d157be3bd 100644 --- a/components/finsh/shell.c +++ b/components/finsh/shell.c @@ -214,6 +214,9 @@ static void finsh_wait_auth(void) rt_bool_t input_finish = RT_FALSE; char password[FINSH_PASSWORD_MAX] = { 0 }; rt_size_t cur_pos = 0; + /* password not set */ + if (rt_strlen(finsh_get_password()) == 0) return; + while (1) { rt_kprintf("Password for finsh: "); @@ -410,7 +413,12 @@ void finsh_thread_entry(void *parameter) #ifdef FINSH_USING_AUTH /* set the default password when the password isn't setting */ if (rt_strlen(finsh_get_password()) == 0) - RT_ASSERT(finsh_set_password(FINSH_DEFAULT_PASSWORD) == RT_EOK); + { + if (finsh_set_password(FINSH_DEFAULT_PASSWORD) != RT_EOK) + { + rt_kprintf("Finsh password set failed.\n"); + } + } /* waiting authenticate success */ finsh_wait_auth(); #endif diff --git a/components/libc/armlibc/sys/errno.h b/components/libc/armlibc/sys/errno.h index e4371d749a..0aba5f5e19 100644 --- a/components/libc/armlibc/sys/errno.h +++ b/components/libc/armlibc/sys/errno.h @@ -6,73 +6,75 @@ #include /* using device error codes */ -#define ENOENT DFS_STATUS_ENOENT -#define EIO DFS_STATUS_EIO -#define ENXIO DFS_STATUS_ENXIO -#define EBADF DFS_STATUS_EBADF -#define EAGAIN DFS_STATUS_EAGAIN -#define ENOMEM DFS_STATUS_ENOMEM -#define EBUSY DFS_STATUS_EBUSY -#define EEXIST DFS_STATUS_EEXIST -#define EXDEV DFS_STATUS_EXDEV -#define ENODEV DFS_STATUS_ENODEV -#define ENOTDIR DFS_STATUS_ENOTDIR -#define EISDIR DFS_STATUS_EISDIR -#define EINVAL DFS_STATUS_EINVAL -#define ENOSPC DFS_STATUS_ENOSPC -#define EROFS DFS_STATUS_EROFS -#define ENOSYS DFS_STATUS_ENOSYS -#define ENOTEMPTY DFS_STATUS_ENOTEMPTY +#define ENOENT DFS_STATUS_ENOENT +#define EIO DFS_STATUS_EIO +#define ENXIO DFS_STATUS_ENXIO +#define EBADF DFS_STATUS_EBADF +#define EAGAIN DFS_STATUS_EAGAIN +#define ENOMEM DFS_STATUS_ENOMEM +#define EBUSY DFS_STATUS_EBUSY +#define EEXIST DFS_STATUS_EEXIST +#define EXDEV DFS_STATUS_EXDEV +#define ENODEV DFS_STATUS_ENODEV +#define ENOTDIR DFS_STATUS_ENOTDIR +#define EISDIR DFS_STATUS_EISDIR +#define EINVAL DFS_STATUS_EINVAL +#define ENOSPC DFS_STATUS_ENOSPC +#define EROFS DFS_STATUS_EROFS +#define ENOSYS DFS_STATUS_ENOSYS +#define ENOTEMPTY DFS_STATUS_ENOTEMPTY #else /* error codes */ -#define ENOENT 2 /* No such file or directory */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define EBADF 9 /* Bad file number */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* no memory */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENOSPC 28 /* No space left on device */ -#define EROFS 30 /* Read-only file system */ -#define ENOSYS 38 /* Function not implemented */ -#define ENOTEMPTY 39 /* Directory not empty */ +#define ENOENT 2 /* No such file or directory */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define EBADF 9 /* Bad file number */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* no memory */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENOSPC 28 /* No space left on device */ +#define EROFS 30 /* Read-only file system */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ #endif -#define EPERM 1 /* Not super-user */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EFAULT 14 /* Bad address */ -#define ENFILE 23 /* Too many open files in system */ -#define ERANGE 34 /* Math result not representable */ -#define EDEADLK 45 /* Deadlock condition */ -#define EBADMSG 77 /* Trying to read unreadable message */ -#define EMSGSIZE 90 /* Message too long */ -#define ENOPROTOOPT 92 /* Protocol not available */ -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ -#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ -#define EADDRINUSE 98 /* Address already in use */ -#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ -#define ENETDOWN 100 /* Network is down */ -#define ENETUNREACH 101 /* Network is unreachable */ -#define ECONNABORTED 103 /* Software caused connection abort */ -#define ECONNRESET 104 /* Connection reset by peer */ -#define ENOBUFS 105 /* No buffer space available */ -#define ENOTCONN 107 /* Transport endpoint is not connected */ -#define EINPROGRESS 115 /* Operation now in progress */ -#define ETIMEDOUT 116 /* Connection timed out */ -#define EHOSTUNREACH 113 /* No route to host */ -#define EALREADY 114 /* Operation already in progress */ -#define ENOTSUP 134 /* Not supported */ -#define ENSRNOTFOUND 163 /* Domain name not found */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define EPERM 1 /* Not super-user */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENFILE 23 /* Too many open files in system */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 45 /* Deadlock condition */ +#define EBADMSG 77 /* Trying to read unreadable message */ +#define EMSGSIZE 90 /* Message too long */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ETIMEDOUT 116 /* Connection timed out */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define ENOTSUP 134 /* Not supported */ +#define ENSRNOTFOUND 163 /* Domain name not found */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ #endif diff --git a/components/libc/libdl/dlopen.c b/components/libc/libdl/dlopen.c index 5e063eed96..2c091079b2 100644 --- a/components/libc/libdl/dlopen.c +++ b/components/libc/libdl/dlopen.c @@ -27,7 +27,7 @@ void* dlopen(const char *filename, int flags) /* check parameters */ RT_ASSERT(filename != RT_NULL); - if (filename[0] != '/') /* it's a absolute path, use it directly */ + if (filename[0] != '/') /* it's a relative path, prefix with MODULE_ROOT_DIR */ { fullpath = rt_malloc(strlen(def_path) + strlen(filename) + 2); @@ -37,8 +37,7 @@ void* dlopen(const char *filename, int flags) } else { - rt_kprintf("use absolute path\n"); - return RT_NULL; + fullpath = (char*)filename; /* absolute path, use it directly */ } /* find in module list */ @@ -47,7 +46,11 @@ void* dlopen(const char *filename, int flags) if(module != RT_NULL) module->nref++; else module = rt_module_open(fullpath); - rt_free(fullpath); + if(fullpath != filename) + { + rt_free(fullpath); + } + return (void*)module; } diff --git a/components/net/lwip-2.0.2/SConscript b/components/net/lwip-2.0.2/SConscript index 1007e77b77..fa8a087c8d 100644 --- a/components/net/lwip-2.0.2/SConscript +++ b/components/net/lwip-2.0.2/SConscript @@ -29,7 +29,6 @@ src/core/udp.c src/netif/ethernet.c src/netif/ethernetif.c src/netif/lowpan6.c -src/netif/slipif.c """) ipv4_src = Split(""" @@ -76,10 +75,6 @@ if GetDepend(['RT_LWIP_PPP']): src += ppp_src path += [GetCurrentDir() + '/src/netif/ppp'] -# For testing apps -if GetDepend(['RT_USING_NETUTILS']): - src += Glob('./apps/*.c') - group = DefineGroup('lwIP', src, depend = ['RT_USING_LWIP', 'RT_USING_LWIP202'], CPPPATH = path) Return('group') diff --git a/components/net/lwip-2.0.2/src/apps/README.md b/components/net/lwip-2.0.2/src/apps/README.md new file mode 100644 index 0000000000..26670858c5 --- /dev/null +++ b/components/net/lwip-2.0.2/src/apps/README.md @@ -0,0 +1,6 @@ +Some net apps for current version LwIP. + +The RT-Thread develop team ported apps. It's easy to use it on finsh/msh. + +- ping +- tftp diff --git a/components/net/lwip-2.0.2/src/apps/SConscript b/components/net/lwip-2.0.2/src/apps/SConscript new file mode 100644 index 0000000000..2bc01cc16e --- /dev/null +++ b/components/net/lwip-2.0.2/src/apps/SConscript @@ -0,0 +1,13 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('tftp/*.c') + +if GetDepend(['RT_LWIP_ICMP', 'RT_LWIP_RAW']): + src += Glob('ping/*.c') + +CPPPATH = [cwd] + +group = DefineGroup('LwIP', src, depend = ['RT_USING_NETUTILS', 'RT_USING_LWIP202'], CPPPATH = CPPPATH) + +Return('group') \ No newline at end of file diff --git a/components/net/lwip-2.0.2/apps/ping.c b/components/net/lwip-2.0.2/src/apps/ping/ping.c similarity index 100% rename from components/net/lwip-2.0.2/apps/ping.c rename to components/net/lwip-2.0.2/src/apps/ping/ping.c diff --git a/components/net/lwip-2.0.2/src/apps/tftp/tftp_port.c b/components/net/lwip-2.0.2/src/apps/tftp/tftp_port.c new file mode 100644 index 0000000000..129cc7da17 --- /dev/null +++ b/components/net/lwip-2.0.2/src/apps/tftp/tftp_port.c @@ -0,0 +1,87 @@ +/* + * File : tftp_port.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-17 armink first version. + */ + + +#include +#include +#include + +static struct tftp_context ctx; + +static void* tftp_open(const char* fname, const char* mode, u8_t write) +{ + int fd = -1; + + if (!rt_strcmp(mode, "octet")) + { + if (write) + { + fd = open(fname, O_WRONLY | O_CREAT, 0); + } + else + { + fd = open(fname, O_RDONLY, 0); + } + } + else + { + rt_kprintf("tftp: No support this mode(%s).", mode); + } + + return (void *) fd; +} + +static int tftp_write(void* handle, struct pbuf* p) +{ + int fd = (int) handle; + + return write(fd, p->payload, p->len); +} + +#if defined(RT_USING_FINSH) +#include + +static void tftp_server(uint8_t argc, char **argv) +{ + ctx.open = tftp_open; + ctx.close = (void (*)(void *)) close; + ctx.read = (int (*)(void *, void *, int)) read; + ctx.write = tftp_write; + + if (tftp_init(&ctx) == ERR_OK) + { + rt_kprintf("TFTP server start successfully.\n"); + } + else + { + rt_kprintf("TFTP server start failed.\n"); + } +} +FINSH_FUNCTION_EXPORT(tftp_server, start tftp server.); + +#if defined(FINSH_USING_MSH) +MSH_CMD_EXPORT(tftp_server, start tftp server.); +#endif /* defined(FINSH_USING_MSH) */ + +#endif /* defined(RT_USING_FINSH) */ diff --git a/components/net/lwip-2.0.2/src/apps/tftp/tftp_server.c b/components/net/lwip-2.0.2/src/apps/tftp/tftp_server.c index 243b0924bd..afaa3bb08d 100644 --- a/components/net/lwip-2.0.2/src/apps/tftp/tftp_server.c +++ b/components/net/lwip-2.0.2/src/apps/tftp/tftp_server.c @@ -226,8 +226,8 @@ recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16 case PP_HTONS(TFTP_WRQ): { const char tftp_null = 0; - char filename[TFTP_MAX_FILENAME_LEN]; - char mode[TFTP_MAX_MODE_LEN]; + char filename[TFTP_MAX_FILENAME_LEN + 1] = { 0 }; + char mode[TFTP_MAX_MODE_LEN] = { 0 }; u16_t filename_end_offset; u16_t mode_end_offset; diff --git a/components/net/lwip-2.0.2/src/lwipopts.h b/components/net/lwip-2.0.2/src/lwipopts.h index 8afc0b97c4..d846cf2fb0 100644 --- a/components/net/lwip-2.0.2/src/lwipopts.h +++ b/components/net/lwip-2.0.2/src/lwipopts.h @@ -287,6 +287,12 @@ #define DEFAULT_UDP_RECVMBOX_SIZE 1 /* ---------- RAW options ---------- */ +#ifdef RT_LWIP_RAW +#define LWIP_RAW 1 +#else +#define LWIP_RAW 0 +#endif + #define DEFAULT_RAW_RECVMBOX_SIZE 1 #define DEFAULT_ACCEPTMBOX_SIZE 10 @@ -348,9 +354,30 @@ #endif /* PPP_SUPPORT */ -/* no read/write/close for socket */ -#define LWIP_POSIX_SOCKETS_IO_NAMES 0 -#define LWIP_NETIF_API 1 +/** + * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. + * Disable this option if you use a POSIX operating system that uses the same + * names (read, write & close). (only used if you use sockets.c) + */ +#ifndef LWIP_POSIX_SOCKETS_IO_NAMES +#define LWIP_POSIX_SOCKETS_IO_NAMES 0 +#endif + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#ifndef LWIP_TCP_KEEPALIVE +#define LWIP_TCP_KEEPALIVE 1 +#endif + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#ifndef LWIP_NETIF_API +#define LWIP_NETIF_API 1 +#endif /* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. */ #define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT) @@ -419,4 +446,22 @@ #define SO_REUSE 0 #endif +/* + ------------------------------------ + ------- Applications options ------- + ------------------------------------ +*/ + +/** + * Max. length of TFTP filename + */ +#ifdef RT_LWIP_TFTP_MAX_FILENAME_LEN +#define TFTP_MAX_FILENAME_LEN RT_LWIP_TFTP_MAX_FILENAME_LEN +#elif defined(RT_DFS_ELM_MAX_LFN) +#define TFTP_MAX_FILENAME_LEN RT_DFS_ELM_MAX_LFN +#else +#define TFTP_MAX_FILENAME_LEN 64 +#endif + + #endif /* __LWIPOPTS_H__ */ diff --git a/components/net/netutils/README.md b/components/net/netutils/README.md new file mode 100644 index 0000000000..49545bab32 --- /dev/null +++ b/components/net/netutils/README.md @@ -0,0 +1 @@ +Some net utils which using standard interface such as BSD Sockets. \ No newline at end of file diff --git a/components/net/netutils/SConscript b/components/net/netutils/SConscript new file mode 100644 index 0000000000..853b94a857 --- /dev/null +++ b/components/net/netutils/SConscript @@ -0,0 +1,10 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + +CPPPATH = [cwd] + +group = DefineGroup('LwIP', src, depend = ['RT_USING_NETUTILS'], CPPPATH = CPPPATH) + +Return('group') \ No newline at end of file diff --git a/components/net/lwip-2.0.2/apps/telnet.c b/components/net/netutils/telnet.c similarity index 100% rename from components/net/lwip-2.0.2/apps/telnet.c rename to components/net/netutils/telnet.c diff --git a/include/rtdef.h b/include/rtdef.h index 77c302dffa..9c6cd8207f 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -110,7 +110,7 @@ typedef rt_base_t rt_off_t; /**< Type for offset */ #include #define SECTION(x) @ x #define RT_UNUSED - #define RT_USED + #define RT_USED __root #define PRAGMA(x) _Pragma(#x) #define ALIGN(n) PRAGMA(data_alignment=n) #define WEAK __weak diff --git a/libcpu/arm/cortex-m0/context_gcc.S b/libcpu/arm/cortex-m0/context_gcc.S index 3186a5ae9f..227a9aac2d 100644 --- a/libcpu/arm/cortex-m0/context_gcc.S +++ b/libcpu/arm/cortex-m0/context_gcc.S @@ -181,7 +181,8 @@ rt_hw_context_switch_to: NOP MSR MSP, R0 - CPSIE I /* enable interrupts at processor level */ + /* enable interrupts at processor level */ + CPSIE I /* never reach here! */ diff --git a/libcpu/arm/cortex-m3/context_gcc.S b/libcpu/arm/cortex-m3/context_gcc.S index ca961bbd87..5181cb2712 100644 --- a/libcpu/arm/cortex-m3/context_gcc.S +++ b/libcpu/arm/cortex-m3/context_gcc.S @@ -162,7 +162,9 @@ rt_hw_context_switch_to: NOP MSR msp, r0 - CPSIE I /* enable interrupts at processor level */ + /* enable interrupts at processor level */ + CPSIE F + CPSIE I /* never reach here! */ diff --git a/libcpu/arm/cortex-m3/context_iar.S b/libcpu/arm/cortex-m3/context_iar.S index ad9fa0dd0f..95dee8062d 100644 --- a/libcpu/arm/cortex-m3/context_iar.S +++ b/libcpu/arm/cortex-m3/context_iar.S @@ -161,7 +161,9 @@ rt_hw_context_switch_to: NOP MSR msp, r0 - CPSIE I ; enable interrupts at processor level + ; enable interrupts at processor level + CPSIE F + CPSIE I ; never reach here! diff --git a/libcpu/arm/cortex-m3/context_rvds.S b/libcpu/arm/cortex-m3/context_rvds.S index ebfd5c8da8..a4191203be 100644 --- a/libcpu/arm/cortex-m3/context_rvds.S +++ b/libcpu/arm/cortex-m3/context_rvds.S @@ -168,6 +168,7 @@ rt_hw_context_switch_to PROC MSR msp, r0 ; enable interrupts at processor level + CPSIE F CPSIE I ; never reach here! diff --git a/libcpu/arm/cortex-m3/cpuport.c b/libcpu/arm/cortex-m3/cpuport.c index f938bab800..10989ffc5b 100644 --- a/libcpu/arm/cortex-m3/cpuport.c +++ b/libcpu/arm/cortex-m3/cpuport.c @@ -368,11 +368,12 @@ __asm int __rt_ffs(int value) { CMP r0, #0x00 BEQ exit + RBIT r0, r0 CLZ r0, r0 ADDS r0, r0, #0x01 - exit +exit BX lr } #elif defined(__IAR_SYSTEMS_ICC__) @@ -380,9 +381,11 @@ int __rt_ffs(int value) { if (value == 0) return value; - __ASM("RBIT r0, r0"); - __ASM("CLZ r0, r0"); - __ASM("ADDS r0, r0, #0x01"); + asm("RBIT %0, %1" : "=r"(value) : "r"(value)); + asm("CLZ %0, %1" : "=r"(value) : "r"(value)); + asm("ADDS %0, %1, #0x01" : "=r"(value) : "r"(value)); + + return value; } #elif defined(__GNUC__) int __rt_ffs(int value) diff --git a/libcpu/arm/cortex-m4/context_gcc.S b/libcpu/arm/cortex-m4/context_gcc.S index 908a44f847..af6c9934d4 100644 --- a/libcpu/arm/cortex-m4/context_gcc.S +++ b/libcpu/arm/cortex-m4/context_gcc.S @@ -203,7 +203,9 @@ rt_hw_context_switch_to: NOP MSR msp, r0 - CPSIE I /* enable interrupts at processor level */ + /* enable interrupts at processor level */ + CPSIE F + CPSIE I /* never reach here! */ diff --git a/libcpu/arm/cortex-m4/context_iar.S b/libcpu/arm/cortex-m4/context_iar.S index 8761a97052..4cc9539112 100644 --- a/libcpu/arm/cortex-m4/context_iar.S +++ b/libcpu/arm/cortex-m4/context_iar.S @@ -207,7 +207,9 @@ rt_hw_context_switch_to: NOP MSR msp, r0 - CPSIE I ; enable interrupts at processor level + ; enable interrupts at processor level + CPSIE F + CPSIE I ; never reach here! diff --git a/libcpu/arm/cortex-m4/context_rvds.S b/libcpu/arm/cortex-m4/context_rvds.S index fa7a1c90f8..ea894ed000 100644 --- a/libcpu/arm/cortex-m4/context_rvds.S +++ b/libcpu/arm/cortex-m4/context_rvds.S @@ -208,6 +208,7 @@ rt_hw_context_switch_to PROC MSR msp, r0 ; enable interrupts at processor level + CPSIE F CPSIE I ; never reach here! diff --git a/libcpu/arm/cortex-m4/cpuport.c b/libcpu/arm/cortex-m4/cpuport.c index 47d8473997..e74c337c60 100644 --- a/libcpu/arm/cortex-m4/cpuport.c +++ b/libcpu/arm/cortex-m4/cpuport.c @@ -238,6 +238,7 @@ __asm int __rt_ffs(int value) { CMP r0, #0x00 BEQ exit + RBIT r0, r0 CLZ r0, r0 ADDS r0, r0, #0x01 @@ -250,9 +251,11 @@ int __rt_ffs(int value) { if (value == 0) return value; - __ASM("RBIT r0, r0"); - __ASM("CLZ r0, r0"); - __ASM("ADDS r0, r0, #0x01"); + asm("RBIT %0, %1" : "=r"(value) : "r"(value)); + asm("CLZ %0, %1" : "=r"(value) : "r"(value)); + asm("ADDS %0, %1, #0x01" : "=r"(value) : "r"(value)); + + return value; } #elif defined(__GNUC__) int __rt_ffs(int value) diff --git a/libcpu/arm/cortex-m7/context_gcc.S b/libcpu/arm/cortex-m7/context_gcc.S index 908a44f847..af6c9934d4 100644 --- a/libcpu/arm/cortex-m7/context_gcc.S +++ b/libcpu/arm/cortex-m7/context_gcc.S @@ -203,7 +203,9 @@ rt_hw_context_switch_to: NOP MSR msp, r0 - CPSIE I /* enable interrupts at processor level */ + /* enable interrupts at processor level */ + CPSIE F + CPSIE I /* never reach here! */ diff --git a/libcpu/arm/cortex-m7/context_iar.S b/libcpu/arm/cortex-m7/context_iar.S index 8761a97052..4cc9539112 100644 --- a/libcpu/arm/cortex-m7/context_iar.S +++ b/libcpu/arm/cortex-m7/context_iar.S @@ -207,7 +207,9 @@ rt_hw_context_switch_to: NOP MSR msp, r0 - CPSIE I ; enable interrupts at processor level + ; enable interrupts at processor level + CPSIE F + CPSIE I ; never reach here! diff --git a/libcpu/arm/cortex-m7/context_rvds.S b/libcpu/arm/cortex-m7/context_rvds.S index 53a3756783..38410c8a3b 100644 --- a/libcpu/arm/cortex-m7/context_rvds.S +++ b/libcpu/arm/cortex-m7/context_rvds.S @@ -208,6 +208,7 @@ rt_hw_context_switch_to PROC MSR msp, r0 ; enable interrupts at processor level + CPSIE F CPSIE I ; never reach here! diff --git a/libcpu/arm/cortex-m7/cpuport.c b/libcpu/arm/cortex-m7/cpuport.c index 47d8473997..e74c337c60 100644 --- a/libcpu/arm/cortex-m7/cpuport.c +++ b/libcpu/arm/cortex-m7/cpuport.c @@ -238,6 +238,7 @@ __asm int __rt_ffs(int value) { CMP r0, #0x00 BEQ exit + RBIT r0, r0 CLZ r0, r0 ADDS r0, r0, #0x01 @@ -250,9 +251,11 @@ int __rt_ffs(int value) { if (value == 0) return value; - __ASM("RBIT r0, r0"); - __ASM("CLZ r0, r0"); - __ASM("ADDS r0, r0, #0x01"); + asm("RBIT %0, %1" : "=r"(value) : "r"(value)); + asm("CLZ %0, %1" : "=r"(value) : "r"(value)); + asm("ADDS %0, %1, #0x01" : "=r"(value) : "r"(value)); + + return value; } #elif defined(__GNUC__) int __rt_ffs(int value) diff --git a/libcpu/mips/loongson_1c/cpuport.c b/libcpu/mips/loongson_1c/cpuport.c index 6cdae024c4..f4914dfec4 100644 --- a/libcpu/mips/loongson_1c/cpuport.c +++ b/libcpu/mips/loongson_1c/cpuport.c @@ -121,5 +121,41 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_ad return (rt_uint8_t *)stk; } +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set pop \n" \ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) + +#if defined(CONFIG_CPU_LOONGSON2) +#define Hit_Invalidate_I 0x00 +#else +#define Hit_Invalidate_I 0x10 +#endif +#define Hit_Invalidate_D 0x11 +#define CONFIG_SYS_CACHELINE_SIZE 32 +#define Hit_Writeback_Inv_D 0x15 + + +void flush_cache(unsigned long start_addr, unsigned long size) +{ + unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; + unsigned long addr = start_addr & ~(lsize - 1); + unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); + + while (1) { + cache_op(Hit_Writeback_Inv_D, addr); + cache_op(Hit_Invalidate_I, addr); + if (addr == aend) + break; + addr += lsize; + } +} + + /*@}*/ diff --git a/libcpu/risc-v/e310/start_gcc.S b/libcpu/risc-v/e310/start_gcc.S index 8ed2a03d37..5f1b087b78 100644 --- a/libcpu/risc-v/e310/start_gcc.S +++ b/libcpu/risc-v/e310/start_gcc.S @@ -21,7 +21,7 @@ ; * Date Author Notes ; * 2017-07-16 zhangjun for hifive1 ; */ -#include +#include "sifive/smp.h" #define CLINT_CTRL_ADDR 0x02000000 .section .init @@ -29,116 +29,116 @@ .type _start,@function _start: - .cfi_startproc - .cfi_undefined ra + .cfi_startproc + .cfi_undefined ra .option push .option norelax - la gp, __global_pointer$ + la gp, __global_pointer$ .option pop - la sp, _sp + la sp, _sp /* *disable all interrupt at startup */ - csrrc a5, mstatus, 0xb + csrrc a5, mstatus, 0xb #if defined(ENABLE_SMP) - smp_pause(t0, t1) + smp_pause(t0, t1) #endif - /* Load data section */ - la a0, _data_lma - la a1, _data - la a2, _edata - bgeu a1, a2, 2f + /* Load data section */ + la a0, _data_lma + la a1, _data + la a2, _edata + bgeu a1, a2, 2f 1: - lw t0, (a0) - sw t0, (a1) - addi a0, a0, 4 - addi a1, a1, 4 - bltu a1, a2, 1b + lw t0, (a0) + sw t0, (a1) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a1, a2, 1b 2: - /* Clear bss section */ - la a0, __bss_start - la a1, _end - bgeu a0, a1, 2f + /* Clear bss section */ + la a0, __bss_start + la a1, _end + bgeu a0, a1, 2f 1: - sw zero, (a0) - addi a0, a0, 4 - bltu a0, a1, 1b + sw zero, (a0) + addi a0, a0, 4 + bltu a0, a1, 1b 2: - /* Call global constructors */ - la a0, __libc_fini_array - call atexit - call __libc_init_array - /*call _init directly in rt-thread*/ + /* Call global constructors */ + la a0, __libc_fini_array + call atexit + call __libc_init_array + /*call _init directly in rt-thread*/ call _init #ifndef __riscv_float_abi_soft - /* Enable FPU */ - li t0, MSTATUS_FS - csrs mstatus, t0 - csrr t1, mstatus - and t1, t1, t0 - beqz t1, 1f - fssr x0 + /* Enable FPU */ + li t0, MSTATUS_FS + csrs mstatus, t0 + csrr t1, mstatus + and t1, t1, t0 + beqz t1, 1f + fssr x0 1: #endif #if defined(ENABLE_SMP) - smp_resume(t0, t1) + smp_resume(t0, t1) - csrr a0, mhartid - bnez a0, 2f + csrr a0, mhartid + bnez a0, 2f #endif - auipc ra, 0 - addi sp, sp, -16 + auipc ra, 0 + addi sp, sp, -16 #if __riscv_xlen == 32 - sw ra, 8(sp) + sw ra, 8(sp) #else - sd ra, 8(sp) + sd ra, 8(sp) #endif - /* argc = argv = 0 */ - li a0, 0 - li a1, 0 - call main - tail exit + /* argc = argv = 0 */ + li a0, 0 + li a1, 0 + call main + tail exit 1: - j 1b + j 1b #if defined(ENABLE_SMP) 2: - la t0, trap_entry - csrw mtvec, t0 + la t0, trap_entry + csrw mtvec, t0 - csrr a0, mhartid - la t1, _sp - slli t0, a0, 10 - sub sp, t1, t0 + csrr a0, mhartid + la t1, _sp + slli t0, a0, 10 + sub sp, t1, t0 - auipc ra, 0 - addi sp, sp, -16 + auipc ra, 0 + addi sp, sp, -16 #if __riscv_xlen == 32 - sw ra, 8(sp) + sw ra, 8(sp) #else - sd ra, 8(sp) + sd ra, 8(sp) #endif - call secondary_main - tail exit + call secondary_main + tail exit 1: - j 1b + j 1b #endif - .cfi_endproc + .cfi_endproc #include "encoding.h" #include "sifive/bits.h" - .section .text.entry + .section .text.entry .align 2 .global trap_entry trap_entry: diff --git a/src/module.c b/src/module.c index c1a3475655..888701930d 100644 --- a/src/module.c +++ b/src/module.c @@ -27,6 +27,7 @@ * 2012-11-23 Bernard using RT_DEBUG_LOG instead of rt_kprintf. * 2012-11-28 Bernard remove rt_current_module and user * can use rt_module_unload to remove a module. + * 2017-08-20 parai support intel 386 machine */ #include @@ -223,6 +224,10 @@ static int rt_module_arm_relocate(struct rt_module *module, *where &= 0xf000000f; *where |= 0x01a0f000; break; +#ifdef MODULE_USING_386 + case R_386_GLOB_DAT: + case R_386_JUMP_SLOT: +#endif case R_ARM_GLOB_DAT: case R_ARM_JUMP_SLOT: *where = (Elf32_Addr)sym_val; @@ -236,6 +241,9 @@ static int rt_module_arm_relocate(struct rt_module *module, RT_DEBUG_LOG(RT_DEBUG_MODULE, ("R_ARM_GOT_BREL: 0x%x -> 0x%x 0x%x\n", where, *where, sym_val)); break; +#endif +#ifdef MODULE_USING_386 + case R_386_RELATIVE: #endif case R_ARM_RELATIVE: *where = (Elf32_Addr)sym_val + *where; @@ -543,7 +551,11 @@ static struct rt_module *_load_shared_object(const char *name, sym->st_shndx)); if ((sym->st_shndx != SHT_NULL) || - (ELF_ST_BIND(sym->st_info) == STB_LOCAL)) + (ELF_ST_BIND(sym->st_info) == STB_LOCAL) +#ifdef MODULE_USING_386 + || ( (ELF_ST_BIND(sym->st_info) == STB_GLOBAL) && (ELF_ST_TYPE(sym->st_info) == STT_OBJECT) ) +#endif + ) { rt_module_arm_relocate(module, rel, (Elf32_Addr)(module->module_space diff --git a/src/module.h b/src/module.h index 1ae9eedbec..90d4dc9524 100644 --- a/src/module.h +++ b/src/module.h @@ -208,6 +208,13 @@ typedef struct #define R_ARM_THM_JUMP24 30 #define R_ARM_V4BX 40 +/* + * Relocation type for arm + */ +#define R_386_GLOB_DAT 6 +#define R_386_JUMP_SLOT 7 +#define R_386_RELATIVE 8 + /* Program Header */ typedef struct {