Initial commit.

This commit is contained in:
imi415 2022-02-18 16:00:01 +08:00
commit ff9f140a9b
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
75 changed files with 45895 additions and 0 deletions

11
.clang-format Normal file
View File

@ -0,0 +1,11 @@
BasedOnStyle: Google
IndentWidth: 4
AlignConsecutiveMacros: AcrossEmptyLines
AlignConsecutiveDeclarations: true
AlignConsecutiveAssignments: true
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: false
AfterStruct: false
SplitEmptyFunction: false
ColumnLimit: 120

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/Makefile
/cmake-build-*
/lib/mruby/build_config.rb.lock
/lib/mruby/build
/.mxproject
/.vscode

Binary file not shown.

View File

@ -0,0 +1,37 @@
/* ----------------------------------------------------------------------
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* $Date: 14/04/08 10:21a $Revision: V1.0.2
*
* Project: CMSIS DSP Library
* Title: arm_common_tables.h
*
* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
*
* Target Processor: Cortex-M4/Cortex-M3
*
* Version 1.0.2 2010/11/11
* Documentation updated.
*
* Version 1.0.1 2010/10/05
* Production release and review comments incorporated.
*
* Version 1.0.0 2010/09/20
* Production release and review comments incorporated.
* -------------------------------------------------------------------- */
#ifndef _ARM_COMMON_TABLES_H
#define _ARM_COMMON_TABLES_H
#include "arm_math.h"
extern const uint16_t armBitRevTable[1024];
extern const q15_t armRecipTableQ15[64];
extern const q31_t armRecipTableQ31[64];
extern const q31_t realCoefAQ31[1024];
extern const q31_t realCoefBQ31[1024];
extern const float32_t twiddleCoef[6144];
extern const q31_t twiddleCoefQ31[6144];
extern const q15_t twiddleCoefQ15[6144];
#endif /* ARM_COMMON_TABLES_H */

7556
BSP/CMSIS/Include/arm_math.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,673 @@
/**************************************************************************//**
* @file core_cm0.h
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
* @version V3.01
* @date 13. March 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CORE_CM0_H_GENERIC
#define __CORE_CM0_H_GENERIC
/** @addtogroup CMSIS_Definitions CMSIS
@{
*/
/** \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.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup Cortex_M0
@{
*/
/* CMSIS CM0 definitions */
#define __CM0_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
#define __CM0_CMSIS_VERSION_SUB (0x01) /*!< [15:0] CMSIS HAL sub version */
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | \
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00) /*!< 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 ( __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 ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU 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
#endif
/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
*/
#define __FPU_USED 0
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#endif /* __CORE_CM0_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0_H_DEPENDANT
#define __CORE_CM0_H_DEPENDANT
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0_REV
#define __CM0_REV 0x0000
#warning "__CM0_REV not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2
#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
<strong>IO Type Qualifiers</strong> 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_M0 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
******************************************************************************/
/** \defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/** \brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
#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[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31];
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31];
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31];
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31];
uint32_t RESERVED4[64];
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/** \brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
uint32_t RESERVED0;
__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 */
uint32_t RESERVED1;
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State 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_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 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_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 */
/* 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_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 */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/** \brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__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_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR)
are only accessible over DAP and not via processor. Therefore
they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
/** \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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \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[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1: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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
/** \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[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
else {
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}
/** \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[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
else {
return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
/** \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_SYSRESETREQ_Msk);
__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 <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 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 */
#endif /* __CORE_CM0_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */
/*@}*/ /* end of group CMSIS_Definitions */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,778 @@
/**************************************************************************//**
* @file core_cm0plus.h
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
* @version V3.01
* @date 22. March 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CORE_CM0PLUS_H_GENERIC
#define __CORE_CM0PLUS_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.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup Cortex-M0+
@{
*/
/* CMSIS CM0P definitions */
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
#define __CM0PLUS_CMSIS_VERSION_SUB (0x01) /*!< [15:0] CMSIS HAL sub version */
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \
__CM0PLUS_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00) /*!< 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 ( __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 ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU 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
#endif
/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
*/
#define __FPU_USED 0
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#endif /* __CORE_CM0PLUS_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0PLUS_H_DEPENDANT
#define __CORE_CM0PLUS_H_DEPENDANT
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0PLUS_REV
#define __CM0PLUS_REV 0x0000
#warning "__CM0PLUS_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __VTOR_PRESENT
#define __VTOR_PRESENT 0
#warning "__VTOR_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2
#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
<strong>IO Type Qualifiers</strong> 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-M0+ */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/** \defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/** \brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
#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[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31];
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31];
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31];
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31];
uint32_t RESERVED4[64];
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/** \brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
#if (__VTOR_PRESENT == 1)
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
#else
uint32_t RESERVED0;
#endif
__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 */
uint32_t RESERVED1;
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State 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_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
#if (__VTOR_PRESENT == 1)
/* SCB Interrupt Control State 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 */
#endif
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_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 */
/* 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_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 */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/** \brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__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 */
#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 */
} 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 8 /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register */
#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR)
are only accessible over DAP and not via processor. Therefore
they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0+ Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
/** \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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \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[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1: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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
/** \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[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
else {
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}
/** \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[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0+ system interrupts */
else {
return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
/** \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_SYSRESETREQ_Msk);
__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 <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 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 */
#endif /* __CORE_CM0PLUS_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */
#ifdef __cplusplus
}
#endif

1612
BSP/CMSIS/Include/core_cm3.h Normal file

File diff suppressed because it is too large Load Diff

1757
BSP/CMSIS/Include/core_cm4.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,649 @@
/**************************************************************************//**
* @file core_cm4_simd.h
* @brief CMSIS Cortex-M4 SIMD Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CORE_CM4_SIMD_H
#define __CORE_CM4_SIMD_H
/*******************************************************************************
* 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 */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
#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) )
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
#include <cmsis_iar.h>
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
#include <cmsis_ccs.h>
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
__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);
}
#define __SMLALD(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
#define __SMLALDX(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
__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);
}
#define __SMLSLD(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
#define __SMLSLDX(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
__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; \
})
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
/* not yet supported */
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CORE_CM4_SIMD_H */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,620 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/** @addtogroup CMSIS_Definitions CMSIS
@{
*/
/* ########################### 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)
/** \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 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) */
#if (__CORTEX_M == 0x04)
/** \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) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#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");
}
/** \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");
}
/** \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) );
}
/** \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) );
}
/** \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) );
}
/** \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) );
}
#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");
}
/** \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");
}
/** \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_max" : "=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) );
}
/** \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) );
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \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;
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
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)
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#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 instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
/*@}*/ /* end of group CMSIS_Definitions */
#endif /* __CORE_CMFUNC_H */

View File

@ -0,0 +1,624 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/** @addtogroup CMSIS_Definitions CMSIS
@{
*/
/* ########################## 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() __isb(0xF)
/** \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() __dsb(0xF)
/** \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() __dmb(0xF)
/** \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
*/
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
/** \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__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
/** \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
#if (__CORTEX_M >= 0x03)
/** \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
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command 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 performs a exclusive LDR command 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 performs a exclusive LDR command 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 performs a exclusive STR command 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 performs a exclusive STR command 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 performs a exclusive STR command 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 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
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \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");
}
/** \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");
}
/** \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");
}
/** \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)
{
uint32_t result;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \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" : "=r" (result) : "r" (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)
{
uint32_t result;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \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)
{
__ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) );
return(op1);
}
#if (__CORTEX_M >= 0x03)
/** \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;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command 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)
{
uint8_t result;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command 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)
{
uint16_t result;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command 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) : "r" (addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command 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) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command 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) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command 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) : "r" (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");
}
/** \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 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
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#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.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/*@}*/ /* end of group CMSIS_Definitions */
#endif /* __CORE_CMINSTR_H */

View File

@ -0,0 +1,798 @@
/**************************************************************************//**
* @file core_sc000.h
* @brief CMSIS SC000 Core Peripheral Access Layer Header File
* @version V3.01
* @date 22. March 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CORE_SC000_H_GENERIC
#define __CORE_SC000_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.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup SC000
@{
*/
/* CMSIS SC000 definitions */
#define __SC000_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
#define __SC000_CMSIS_VERSION_SUB (0x01) /*!< [15:0] CMSIS HAL sub version */
#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16) | \
__SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_SC (0) /*!< Cortex secure core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __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 ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU 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
#endif
/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
*/
#define __FPU_USED 0
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#endif /* __CORE_SC000_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_SC000_H_DEPENDANT
#define __CORE_SC000_H_DEPENDANT
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __SC000_REV
#define __SC000_REV 0x0000
#warning "__SC000_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2
#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
<strong>IO Type Qualifiers</strong> 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 SC000 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/** \defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/** \brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
#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[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31];
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31];
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31];
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31];
uint32_t RESERVED4[64];
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/** \brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__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 */
uint32_t RESERVED0[1];
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
uint32_t RESERVED1[154];
__IO uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features 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_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 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_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 */
/* 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_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 */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/* SCB Security Features Register Definitions */
#define SCB_SFCR_UNIBRTIMING_Pos 0 /*!< SCB SFCR: UNIBRTIMING Position */
#define SCB_SFCR_UNIBRTIMING_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SFCR: UNIBRTIMING Mask */
#define SCB_SFCR_SECKEY_Pos 16 /*!< SCB SFCR: SECKEY Position */
#define SCB_SFCR_SECKEY_Msk (0xFFFFUL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SFCR: SECKEY 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[2];
__IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
} SCnSCB_Type;
/* Auxiliary Control Register Definitions */
#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 */
#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 */
} 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 8 /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register */
#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR)
are only accessible over DAP and not via processor. Therefore
they are not covered by the Cortex-M0 header file.
@{
*/
/*@} 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 SC000 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
/** \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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \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[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1: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[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
/** \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[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
else {
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}
/** \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[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for SC000 system interrupts */
else {
return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
/** \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_SYSRESETREQ_Msk);
__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 <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 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 */
#endif /* __CORE_SC000_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

14
BSP/CMSIS/index.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Redirect to the CMSIS main page after 0 seconds</title>
<meta http-equiv="refresh" content="0; URL=Documentation/General/html/index.html">
<meta name="keywords" content="automatic redirection">
</head>
<body>
If the automatic redirection is failing, click <a href="Documentation/General/html/index.html">open CMSIS Documentation</a>.
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,66 @@
/**************************************************************************//**
* @file system_NUC200Series.h
* @version V3.0
* $Revision: 6 $
* $Date: 14/11/27 5:30p $
* @brief NUC200 Series CMSIS System Header File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __SYSTEM_NUC2xx_H
#define __SYSTEM_NUC2xx_H
#ifdef __cplusplus
extern "C" {
#endif
/*---------------------------------------------------------------------------------------------------------*/
/* Macro Definition */
/*---------------------------------------------------------------------------------------------------------*/
/* Using UART0 or UART1 */
#define DEBUG_PORT UART0
/*----------------------------------------------------------------------------
Define SYSCLK
*----------------------------------------------------------------------------*/
#define __HXT (12000000UL) /*!< External Crystal Clock Frequency */
#define __LXT (32768UL) /*!< External Crystal Clock Frequency 32.768KHz */
#define __HIRC (22118400UL) /*!< Internal 22M RC Oscillator Frequency */
#define __LIRC (10000UL) /*!< Internal 10K RC Oscillator Frequency */
#define __HSI (50000000UL) /*!< PLL default output is 50MHz */
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
extern uint32_t CyclesPerUs; /*!< Cycles per micro second */
extern uint32_t PllClock; /*!< PLL Output Clock Frequency */
/**
* Initialize the system
*
* @param None
* @return None
*
* @brief Setup the microcontroller system
* Initialize GPIO directions and values
*/
extern void SystemInit(void);
/**
* Update SystemCoreClock variable
*
* @param None
* @return None
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from CPU registers.
*/
extern void SystemCoreClockUpdate(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,410 @@
;/*---------------------------------------------------------------------------------------------------------*/
;/* */
;/* SPDX-License-Identifier: Apache-2.0 */
;/* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved. */
;/* */
;/*---------------------------------------------------------------------------------------------------------*/
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CLK_BA_base EQU 0x50000200
PWRCON EQU 0x00
AHBCLK EQU 0x04
APBCLK EQU 0x08
CLKSEL0 EQU 0x10
CLKSEL1 EQU 0x14
CLKDIV EQU 0x18
PLLCON EQU 0x20
TEST_S EQU 0x30
CLK_BA_APBCLK EQU 0x50000208
;// Define clock enable registers
ADC_COMP_CLK EQU 0x50000208
ADC_enable EQU 0x10000000
COMP_enable EQU 0x40000000
PDMA_CLK EQU 0x50000204
PDMA_enable EQU 0x00000003
;; bit 0 CPU_EN
;; bit 1 PDMA_EN
;// Define COMP registers base
COMP_base EQU 0x400D0000
CMP1CR EQU 0x00
CMP2CR EQU 0x04
CMPSR EQU 0x08
;// Define ADC registers base
ADC_base EQU 0x400E0000
ADDR0 EQU 0x00
ADDR1 EQU 0x04
ADDR2 EQU 0x08
ADDR3 EQU 0x0c
ADDR4 EQU 0x10
ADDR5 EQU 0x14
ADDR6 EQU 0x18
ADDR7 EQU 0x1c
ADCR EQU 0x20
ADCHER EQU 0x24
ADCMPR0 EQU 0x28
ADCMPR1 EQU 0x2c
ADSR EQU 0x30
ADCALR EQU 0x34
ADCFCR EQU 0x38
ADCALD EQU 0x3c
;// Pattern Table
pattern_55555555 EQU 0x55555555
pattern_aaaaaaaa EQU 0xaaaaaaaa
pattern_00005555 EQU 0x00005555
pattern_0000aaaa EQU 0x0000aaaa
pattern_05550515 EQU 0x05550515
pattern_0aaa0a2a EQU 0x0aaa0a2a
;// Define PDMA regsiter base
PDMA_BA_ch0_base EQU 0x50008000
PDMA_BA_ch1_base EQU 0x50008100
PDMA_BA_ch2_base EQU 0x50008200
PDMA_BA_ch3_base EQU 0x50008300
PDMA_BA_ch4_base EQU 0x50008400
PDMA_BA_ch5_base EQU 0x50008500
PDMA_BA_ch6_base EQU 0x50008600
PDMA_BA_ch7_base EQU 0x50008700
PDMA_BA_GCR EQU 0x50008F00
PDMA_BA_GCR_base EQU 0x50008F00
PDMA_GCRCSR EQU 0X00
PDMA_PDSSR2 EQU 0X04
PDMA_PDSSR1 EQU 0X08 ;; PDMA channel select 0x77000000
PDMA_GCRISR EQU 0X0C
PDMA_GLOBAL_enable EQU 0x0000FF00
PDMA_CSR EQU 0X00
PDMA_SAR EQU 0X04
PDMA_DAR EQU 0X08
PDMA_BCR EQU 0X0C
PDMA_CSAR EQU 0X14
PDMA_CDAR EQU 0X18
PDMA_CBSR EQU 0X1C
PDMA_IER EQU 0X20
PDMA_ISR EQU 0X24
PDMA_CTCSR EQU 0X28
PDMA_SASOCR EQU 0X2C
PDMA_DASOCR EQU 0X30
PDMA_SBUF0 EQU 0X80
PDMA_SBUF1 EQU 0X84
PDMA_SBUF2 EQU 0X88
PDMA_SBUF3 EQU 0X8C
;// Define VIC control register
VIC_base EQU 0xFFFF0000
VIC_SCR15 EQU 0x003c
VIC_SVR15 EQU 0x00bc
VIC_SCR16 EQU 0x0040
VIC_SVR16 EQU 0x00c0
VIC_SCR30 EQU 0x0078
VIC_SVR30 EQU 0x00f8
VIC_MECR EQU 0x0318
VIC_MDCR EQU 0x031c
VIC_EOSCR EQU 0x0130
;//==================================
INT_BA_base EQU 0x50000300
;// Parameter table
ADC_PDMA_CFG EQU 0x00002980
ADC_PDMA_DST EQU 0xC0000000
ADC_PDMA_SRC EQU 0xE0024200
ADC_PDMA_TCBL EQU 0x00030008
;//==================================
GPIO_base EQU 0x50004000
GPIOB_PMD EQU 0x0040
GPIOB_OFFD EQU 0x0044
GPIOB_DOUT EQU 0x0048
GPIOB_DMASK EQU 0x004C
GPIOB_PIN EQU 0x0050
GPIOB_DBEN EQU 0x0054
GPIOB_IMD EQU 0x0058
GPIOB_IEN EQU 0x005C
GPIOB_ISRC EQU 0x0060
;//==================================
GCR_base EQU 0x50000000
GPB_MFP EQU 0x0034
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IF :LNOT: :DEF: Stack_Size
Stack_Size EQU 0x00000400
ENDIF
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
IF :LNOT: :DEF: Heap_Size
Heap_Size EQU 0x00000000
ENDIF
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
; maximum of 32 External Interrupts are possible
DCD BOD_IRQHandler
DCD WDT_IRQHandler
DCD EINT0_IRQHandler
DCD EINT1_IRQHandler
DCD GPAB_IRQHandler
DCD GPCDEF_IRQHandler
DCD PWMA_IRQHandler
DCD PWMB_IRQHandler
DCD TMR0_IRQHandler
DCD TMR1_IRQHandler
DCD TMR2_IRQHandler
DCD TMR3_IRQHandler
DCD UART02_IRQHandler
DCD UART1_IRQHandler
DCD SPI0_IRQHandler
DCD SPI1_IRQHandler
DCD SPI2_IRQHandler
DCD SPI3_IRQHandler
DCD I2C0_IRQHandler
DCD I2C1_IRQHandler
DCD CAN0_IRQHandler
DCD CAN1_IRQHandler
DCD SC012_IRQHandler
DCD USBD_IRQHandler
DCD PS2_IRQHandler
DCD ACMP_IRQHandler
DCD PDMA_IRQHandler
DCD I2S_IRQHandler
DCD PWRWU_IRQHandler
DCD ADC_IRQHandler
DCD Default_Handler
DCD RTC_IRQHandler
AREA |.text|, CODE, READONLY
; Reset Handler
ENTRY
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =0x50000100
; Unlock Register
LDR R1, =0x59
STR R1, [R0]
LDR R1, =0x16
STR R1, [R0]
LDR R1, =0x88
STR R1, [R0]
; Init POR
LDR R2, =0x50000024
LDR R1, =0x00005AA5
STR R1, [R2]
; Lock register
MOVS R1, #0
STR R1, [R0]
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_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
EXPORT BOD_IRQHandler [WEAK]
EXPORT WDT_IRQHandler [WEAK]
EXPORT EINT0_IRQHandler [WEAK]
EXPORT EINT1_IRQHandler [WEAK]
EXPORT GPAB_IRQHandler [WEAK]
EXPORT GPCDEF_IRQHandler [WEAK]
EXPORT PWMA_IRQHandler [WEAK]
EXPORT PWMB_IRQHandler [WEAK]
EXPORT TMR0_IRQHandler [WEAK]
EXPORT TMR1_IRQHandler [WEAK]
EXPORT TMR2_IRQHandler [WEAK]
EXPORT TMR3_IRQHandler [WEAK]
EXPORT UART02_IRQHandler [WEAK]
EXPORT UART1_IRQHandler [WEAK]
EXPORT SPI0_IRQHandler [WEAK]
EXPORT SPI1_IRQHandler [WEAK]
EXPORT SPI2_IRQHandler [WEAK]
EXPORT SPI3_IRQHandler [WEAK]
EXPORT I2C0_IRQHandler [WEAK]
EXPORT I2C1_IRQHandler [WEAK]
EXPORT CAN0_IRQHandler [WEAK]
EXPORT CAN1_IRQHandler [WEAK]
EXPORT SC012_IRQHandler [WEAK]
EXPORT USBD_IRQHandler [WEAK]
EXPORT PS2_IRQHandler [WEAK]
EXPORT ACMP_IRQHandler [WEAK]
EXPORT PDMA_IRQHandler [WEAK]
EXPORT I2S_IRQHandler [WEAK]
EXPORT PWRWU_IRQHandler [WEAK]
EXPORT ADC_IRQHandler [WEAK]
EXPORT RTC_IRQHandler [WEAK]
BOD_IRQHandler
WDT_IRQHandler
EINT0_IRQHandler
EINT1_IRQHandler
GPAB_IRQHandler
GPCDEF_IRQHandler
PWMA_IRQHandler
PWMB_IRQHandler
TMR0_IRQHandler
TMR1_IRQHandler
TMR2_IRQHandler
TMR3_IRQHandler
UART02_IRQHandler
UART1_IRQHandler
SPI0_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
SPI3_IRQHandler
I2C0_IRQHandler
I2C1_IRQHandler
CAN0_IRQHandler
CAN1_IRQHandler
SC012_IRQHandler
USBD_IRQHandler
PS2_IRQHandler
ACMP_IRQHandler
PDMA_IRQHandler
I2S_IRQHandler
PWRWU_IRQHandler
ADC_IRQHandler
RTC_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
LDR R0, = Heap_Mem
LDR R1, = (Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
ENDIF
END

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,195 @@
/* Linker script to configure memory regions. */
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128k */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x4000 /* 16k */
}
/* Library configurations */
GROUP(libgcc.a libc.a libm.a libnosys.a)
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
* __Vectors_End
* __Vectors_Size
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.vectors))
__Vectors_End = .;
__Vectors_Size = __Vectors_End - __Vectors;
__end__ = .;
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__HeapBase = .;
__end__ = .;
end = __end__;
KEEP(*(.heap*))
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
KEEP(*(.stack*))
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View File

@ -0,0 +1,116 @@
#ifndef ARM_SEMIHOSTING_H_
#define ARM_SEMIHOSTING_H_
// ----------------------------------------------------------------------------
// Semihosting operations.
enum OperationNumber
{
// Regular operations
SEMIHOSTING_EnterSVC = 0x17,
SEMIHOSTING_ReportException = 0x18,
SEMIHOSTING_SYS_CLOSE = 0x02,
SEMIHOSTING_SYS_CLOCK = 0x10,
SEMIHOSTING_SYS_ELAPSED = 0x30,
SEMIHOSTING_SYS_ERRNO = 0x13,
SEMIHOSTING_SYS_FLEN = 0x0C,
SEMIHOSTING_SYS_GET_CMDLINE = 0x15,
SEMIHOSTING_SYS_HEAPINFO = 0x16,
SEMIHOSTING_SYS_ISERROR = 0x08,
SEMIHOSTING_SYS_ISTTY = 0x09,
SEMIHOSTING_SYS_OPEN = 0x01,
SEMIHOSTING_SYS_READ = 0x06,
SEMIHOSTING_SYS_READC = 0x07,
SEMIHOSTING_SYS_REMOVE = 0x0E,
SEMIHOSTING_SYS_RENAME = 0x0F,
SEMIHOSTING_SYS_SEEK = 0x0A,
SEMIHOSTING_SYS_SYSTEM = 0x12,
SEMIHOSTING_SYS_TICKFREQ = 0x31,
SEMIHOSTING_SYS_TIME = 0x11,
SEMIHOSTING_SYS_TMPNAM = 0x0D,
SEMIHOSTING_SYS_WRITE = 0x05,
SEMIHOSTING_SYS_WRITEC = 0x03,
SEMIHOSTING_SYS_WRITE0 = 0x04,
// Codes returned by SEMIHOSTING_ReportException
ADP_Stopped_ApplicationExit = ((2 << 16) + 38),
ADP_Stopped_RunTimeError = ((2 << 16) + 35),
};
// ----------------------------------------------------------------------------
// SWI numbers and reason codes for RDI (Angel) monitors.
#define AngelSWI_ARM 0x123456
#ifdef __thumb__
#define AngelSWI 0xAB
#else
#define AngelSWI AngelSWI_ARM
#endif
// For thumb only architectures use the BKPT instruction instead of SWI.
#if defined(__ARM_ARCH_7M__) \
|| defined(__ARM_ARCH_7EM__) \
|| defined(__ARM_ARCH_6M__)
#define AngelSWIInsn "bkpt"
#define AngelSWIAsm bkpt
#else
#define AngelSWIInsn "swi"
#define AngelSWIAsm swi
#endif
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
// Testing the local semihosting handler cannot use another BKPT, since this
// configuration cannot trigger HaedFault exceptions while the debugger is
// connected, so we use an illegal op code, that will trigger an
// UsageFault exception.
#define AngelSWITestFault "setend be"
#define AngelSWITestFaultOpCode (0xB658)
#endif
static inline int
__attribute__ ((always_inline))
call_host (int reason, void* arg)
{
int value;
asm volatile (
" mov r0, %[rsn] \n"
" mov r1, %[arg] \n"
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
" " AngelSWITestFault " \n"
#else
" " AngelSWIInsn " %[swi] \n"
#endif
" mov %[val], r0"
: [val] "=r" (value) /* Outputs */
: [rsn] "r" (reason), [arg] "r" (arg), [swi] "i" (AngelSWI) /* Inputs */
: "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
// Clobbers r0 and r1, and lr if in supervisor mode
);
// Accordingly to page 13-77 of ARM DUI 0040D other registers
// can also be clobbered. Some memory positions may also be
// changed by a system call, so they should not be kept in
// registers. Note: we are assuming the manual is right and
// Angel is respecting the APCS.
return value;
}
// ----------------------------------------------------------------------------
// Function used in _exit() to return the status code as Angel exception.
static inline void
__attribute__ ((always_inline,noreturn))
report_exception (int reason)
{
call_host (SEMIHOSTING_ReportException, (void*) reason);
for (;;)
;
}
// ----------------------------------------------------------------------------
#endif // ARM_SEMIHOSTING_H_

View File

@ -0,0 +1,316 @@
/****************************************************************************//**
* @file startup_NUC200Series.S
* @version V1.00
* @brief CMSIS Device Startup File
*
* SPDX-License-Identifier: Apache-2.0
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
.syntax unified
.arch armv6-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0x00000400
#endif
.global __StackTop
.global __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 0x00000100
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .vectors
.align 2
.globl __Vectors
__Vectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved*/
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long BOD_IRQHandler
.long WDT_IRQHandler
.long EINT0_IRQHandler
.long EINT1_IRQHandler
.long GPAB_IRQHandler
.long GPCDEF_IRQHandler
.long PWMA_IRQHandler
.long PWMB_IRQHandler
.long TMR0_IRQHandler
.long TMR1_IRQHandler
.long TMR2_IRQHandler
.long TMR3_IRQHandler
.long UART02_IRQHandler
.long UART1_IRQHandler
.long SPI0_IRQHandler
.long SPI1_IRQHandler
.long SPI2_IRQHandler
.long SPI3_IRQHandler
.long I2C0_IRQHandler
.long I2C1_IRQHandler
.long CAN0_IRQHandler
.long CAN1_IRQHandler
.long SC012_IRQHandler
.long USBD_IRQHandler
.long PS2_IRQHandler
.long ACMP_IRQHandler
.long PDMA_IRQHandler
.long I2S_IRQHandler
.long PWRWU_IRQHandler
.long ADC_IRQHandler
.long Default_Handler
.long RTC_IRQHandler
.size __Vectors, . - __Vectors
.text
.thumb
.thumb_func
.align 2
.global Reset_Handler
.type Reset_Handler, % function
Reset_Handler:
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, = __copy_table_start__
ldr r5, = __copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
blt .L_loop0_0_done
ldr r0, [r1, r3]
str r0, [r2, r3]
b .L_loop0_0
.L_loop0_0_done:
adds r4, #12
b .L_loop0
.L_loop0_done:
#else
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, = __etext
ldr r2, = __data_start__
ldr r3, = __data_end__
subs r3, r2
ble .L_loop1_done
.L_loop1:
subs r3, #4
ldr r0, [r1, r3]
str r0, [r2, r3]
bgt .L_loop1
.L_loop1_done:
#endif /*__STARTUP_COPY_MULTIPLE */
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
*/
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, = __zero_table_start__
ldr r4, = __zero_table_end__
.L_loop2:
cmp r3, r4
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
movs r0, 0
.L_loop2_0:
subs r2, #4
blt .L_loop2_0_done
str r0, [r1, r2]
b .L_loop2_0
.L_loop2_0_done:
adds r3, #8
b .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, = __bss_start__
ldr r2, = __bss_end__
movs r0, 0
subs r2, r1
ble .L_loop3_done
.L_loop3:
subs r2, #4
str r0, [r1, r2]
bgt .L_loop3
.L_loop3_done:
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
#ifndef __NO_SYSTEM_INIT
bl SystemInit
#endif
#ifndef __START
#define __START _start
#endif
bl __START
.pool
.size Reset_Handler, . - Reset_Handler
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, % function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler SVC_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler BOD_IRQHandler
def_irq_handler WDT_IRQHandler
def_irq_handler EINT0_IRQHandler
def_irq_handler EINT1_IRQHandler
def_irq_handler GPAB_IRQHandler
def_irq_handler GPCDEF_IRQHandler
def_irq_handler PWMA_IRQHandler
def_irq_handler PWMB_IRQHandler
def_irq_handler TMR0_IRQHandler
def_irq_handler TMR1_IRQHandler
def_irq_handler TMR2_IRQHandler
def_irq_handler TMR3_IRQHandler
def_irq_handler UART02_IRQHandler
def_irq_handler UART1_IRQHandler
def_irq_handler SPI0_IRQHandler
def_irq_handler SPI1_IRQHandler
def_irq_handler SPI2_IRQHandler
def_irq_handler SPI3_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler I2C1_IRQHandler
def_irq_handler CAN0_IRQHandler
def_irq_handler CAN1_IRQHandler
def_irq_handler SC012_IRQHandler
def_irq_handler USBD_IRQHandler
def_irq_handler PS2_IRQHandler
def_irq_handler ACMP_IRQHandler
def_irq_handler PDMA_IRQHandler
def_irq_handler I2S_IRQHandler
def_irq_handler PWRWU_IRQHandler
def_irq_handler ADC_IRQHandler
def_irq_handler RTC_IRQHandler
.end

View File

@ -0,0 +1,184 @@
;/*---------------------------------------------------------------------------------------------------------*/
;/* */
;/* SPDX-License-Identifier: Apache-2.0 */
;/* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved. */
;/* */
;/*---------------------------------------------------------------------------------------------------------*/
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MODULE ?cstartup
;; Forward declaration of sections.
SECTION CSTACK:DATA:NOROOT(3) ;; 8 bytes alignment
SECTION .intvec:CODE:NOROOT(2);; 4 bytes alignment
EXTERN SystemInit
EXTERN __iar_program_start
PUBLIC __vector_table
DATA
__vector_table
DCD sfe(CSTACK)
DCD Reset_Handler
DCD NMI_Handler
DCD HardFault_Handler
DCD 0
DCD 0
DCD 0
DCD 0
DCD 0
DCD 0
DCD 0
DCD SVC_Handler
DCD 0
DCD 0
DCD PendSV_Handler
DCD SysTick_Handler
; External Interrupts
DCD BOD_IRQHandler ; Brownout low voltage detected interrupt
DCD WDT_IRQHandler ; Watch Dog Timer interrupt
DCD EINT0_IRQHandler ; External signal interrupt from PB.14 pin
DCD EINT1_IRQHandler ; External signal interrupt from PB.15 pin
DCD GPAB_IRQHandler ; GPIO interrupt from PA[15:0]/PB[13:0]
DCD GPCDEF_IRQHandler ; GPIO interrupt from PC[15:0]/PD[15:0]/PE[15:0]//PF[3:0]
DCD PWMA_IRQHandler ; PWM0 or PWM2 interrupt
DCD PWMB_IRQHandler ; PWM1 or PWM3 interrupt
DCD TMR0_IRQHandler ; Timer 0 interrupt
DCD TMR1_IRQHandler ; Timer 1 interrupt
DCD TMR2_IRQHandler ; Timer 2 interrupt
DCD TMR3_IRQHandler ; Timer 3 interrupt
DCD UART02_IRQHandler ; UART0 interrupt
DCD UART1_IRQHandler ; UART1 interrupt
DCD SPI0_IRQHandler ; SPI0 interrupt
DCD SPI1_IRQHandler ; SPI1 interrupt
DCD SPI2_IRQHandler ; SPI2 interrupt
DCD SPI3_IRQHandler ; SPI3 interrupt
DCD I2C0_IRQHandler ; I2C0 interrupt
DCD I2C1_IRQHandler ; I2C1 interrupt
DCD CAN0_IRQHandler ; CAN0 interrupt
DCD CAN1_IRQHandler ; CAN1 interrupt
DCD SC012_IRQHandler ; SC0/1/2 interrupt
DCD USBD_IRQHandler ; USB FS Device interrupt
DCD PS2_IRQHandler ; PS2 interrupt
DCD ACMP_IRQHandler ; Analog Comparator-0 or Comaprator-1 interrupt
DCD PDMA_IRQHandler ; PDMA interrupt
DCD I2S_IRQHandler ; I2S interrupt
DCD PWRWU_IRQHandler ; Clock controller interrupt for chip wake up from power-
DCD ADC_IRQHandler ; ADC interrupt
DCD Default_Handler ; Reserved
DCD RTC_IRQHandler ; Real time clock interrupt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:REORDER:NOROOT(2) ; 4 bytes alignment
Reset_Handler
LDR R0, =0x50000100
; Unlock Register
LDR R1, =0x59
STR R1, [R0]
LDR R1, =0x16
STR R1, [R0]
LDR R1, =0x88
STR R1, [R0]
; Init POR
LDR R2, =0x50000024
LDR R1, =0x00005AA5
STR R1, [R2]
; Lock register
MOVS R1, #0
STR R1, [R0]
LDR R0, =SystemInit
BLX R0
LDR R0, =__iar_program_start
BX R0
PUBWEAK HardFault_Handler
PUBWEAK NMI_Handler
PUBWEAK SVC_Handler
PUBWEAK PendSV_Handler
PUBWEAK SysTick_Handler
PUBWEAK BOD_IRQHandler
PUBWEAK WDT_IRQHandler
PUBWEAK EINT0_IRQHandler
PUBWEAK EINT1_IRQHandler
PUBWEAK GPAB_IRQHandler
PUBWEAK GPCDEF_IRQHandler
PUBWEAK PWMA_IRQHandler
PUBWEAK PWMB_IRQHandler
PUBWEAK TMR0_IRQHandler
PUBWEAK TMR1_IRQHandler
PUBWEAK TMR2_IRQHandler
PUBWEAK TMR3_IRQHandler
PUBWEAK UART02_IRQHandler
PUBWEAK UART1_IRQHandler
PUBWEAK SPI0_IRQHandler
PUBWEAK SPI1_IRQHandler
PUBWEAK SPI2_IRQHandler
PUBWEAK SPI3_IRQHandler
PUBWEAK I2C0_IRQHandler
PUBWEAK I2C1_IRQHandler
PUBWEAK CAN0_IRQHandler
PUBWEAK CAN1_IRQHandler
PUBWEAK SC012_IRQHandler
PUBWEAK USBD_IRQHandler
PUBWEAK PS2_IRQHandler
PUBWEAK ACMP_IRQHandler
PUBWEAK PDMA_IRQHandler
PUBWEAK I2S_IRQHandler
PUBWEAK PWRWU_IRQHandler
PUBWEAK ADC_IRQHandler
PUBWEAK RTC_IRQHandler
SECTION .text:CODE:REORDER:NOROOT(2)
HardFault_Handler
NMI_Handler
SVC_Handler
PendSV_Handler
SysTick_Handler
BOD_IRQHandler
WDT_IRQHandler
EINT0_IRQHandler
EINT1_IRQHandler
GPAB_IRQHandler
GPCDEF_IRQHandler
PWMA_IRQHandler
PWMB_IRQHandler
TMR0_IRQHandler
TMR1_IRQHandler
TMR2_IRQHandler
TMR3_IRQHandler
UART02_IRQHandler
UART1_IRQHandler
SPI0_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
SPI3_IRQHandler
I2C0_IRQHandler
I2C1_IRQHandler
CAN0_IRQHandler
CAN1_IRQHandler
SC012_IRQHandler
USBD_IRQHandler
PS2_IRQHandler
ACMP_IRQHandler
PDMA_IRQHandler
I2S_IRQHandler
PWRWU_IRQHandler
ADC_IRQHandler
RTC_IRQHandler
Default_Handler
B Default_Handler
END

View File

@ -0,0 +1,75 @@
/**************************************************************************//**
* @file system_NUC200Series.c
* @version V3.0
* $Revision: 5 $
* $Date: 14/11/21 5:08p $
* @brief NUC200 Series CMSIS System File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include <stdint.h>
#include "NUC200Series.h"
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = __HSI; /*!< System Clock Frequency (Core Clock) */
uint32_t CyclesPerUs = (__HSI / 1000000); /* Cycles per micro second */
uint32_t PllClock = __HSI; /*!< PLL Output Clock Frequency */
uint32_t gau32ClkSrcTbl[] = {__HXT, __LXT, __HSI, __LIRC, NULL, NULL, NULL, __HIRC};
/*----------------------------------------------------------------------------
Clock functions
This function is used to update the variable SystemCoreClock
and must be called whenever the core clock is changed.
*----------------------------------------------------------------------------*/
void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
{
uint32_t u32Freq, u32ClkSrc;
uint32_t u32HclkDiv;
/* Update PLL Clock */
PllClock = CLK_GetPLLClockFreq();
u32ClkSrc = CLK->CLKSEL0 & CLK_CLKSEL0_HCLK_S_Msk;
if(u32ClkSrc != CLK_CLKSEL0_HCLK_S_PLL)
{
/* Use the clock sources directly */
u32Freq = gau32ClkSrcTbl[u32ClkSrc];
}
else
{
/* Use PLL clock */
u32Freq = PllClock;
}
u32HclkDiv = (CLK->CLKDIV & CLK_CLKDIV_HCLK_N_Msk) + 1;
/* Update System Core Clock */
SystemCoreClock = u32Freq / u32HclkDiv;
CyclesPerUs = (SystemCoreClock + 500000) / 1000000;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: SystemInit */
/* */
/* Parameters: */
/* None */
/* */
/* Returns: */
/* None */
/* */
/* Description: */
/* The necessary initialization of system. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
void SystemInit(void)
{
}

58
BSP/README.md Normal file
View File

@ -0,0 +1,58 @@
# NUC200 CMSIS BSP
This BSP folder
## .\Document\
- Release Note<br>
Show all the revision history about specific BSP.
- Driver Reference Guide<br>
Describe the definition, input and output of each API.
## .\Library\
- CMSIS<br>
CMSIS definitions by ARM® Corp.
- Device<br>
CMSIS compliant device header file.
- StdDriver<br>
All peripheral driver header and source files.
## .\Sample Code\
- CardReader<br>
CCID Smart Card reader Sample Code.
- Hard\_Fault\_Sample<br>
Show hard fault information when hard fault happened.
- ISP<br>
Sample codes for In-System-Programming.
- Template<br>
Software Development Template.
- Semihost<br>
Show how to debug with semi-host message print.
- RegBased<br>
The sample codes which access control registers directly.
- StdDriver<br>
NUC200 Series Driver Samples.
# Licesne
**SPDX-License-Identifier: Apache-2.0**
Copyright in some of the content available in this BSP belongs to third parties.
Third parties license is specified in a file header or license file.
NUC200 BSP files are provided under the Apache-2.0 license.

View File

@ -0,0 +1,307 @@
/**************************************************************************//**
* @file sclib.h
* @version V1.00
* $Revision: 6 $
* $Date: 15/05/18 10:11a $
* @brief Smartcard library header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __SCLIB_H__
#define __SCLIB_H__
#include "NUC200Series.h"
/** @addtogroup Library Library
@{
*/
/** @addtogroup SCLIB Smartcard Library
@{
*/
/** @addtogroup SCLIB_EXPORTED_CONSTANTS Smartcard Library Exported Constants
@{
*/
#ifdef __cplusplus
extern "C"
{
#endif
#define SCLIB_MAX_ATR_LEN 32 ///< Max ATR length. ISO-7816 8.2.1
#define SCLIB_MIN_ATR_LEN 2 ///< Min ATR length, TS and T0
// Protocol
#define SCLIB_PROTOCOL_UNDEFINED 0x00000000 ///< There is no active protocol.
#define SCLIB_PROTOCOL_T0 0x00000001 ///< T=0 is the active protocol.
#define SCLIB_PROTOCOL_T1 0x00000002 ///< T=1 is the active protocol.
#define SCLIB_SUCCESS 0x00000000 ///< Command successful without error
// error code generate by interrupt handler
#define SCLIB_ERR_CARD_REMOVED 0x00000001 ///< Smartcard removed
#define SCLIB_ERR_OVER_RUN 0x00000002 ///< Rx FIFO over run
#define SCLIB_ERR_PARITY_ERROR 0x00000003 ///< Tx/Rx parity error
#define SCLIB_ERR_NO_STOP 0x00000004 ///< Stop bit not found
#define SCLIB_ERR_SILENT_BYTE 0x00000005 ///< I/O pin stay at low for longer than 1 character time
#define SCLIB_ERR_CMD 0x00000006
#define SCLIB_ERR_UNSUPPORTEDCARD 0x00000007
#define SCLIB_ERR_READ 0x00000008
#define SCLIB_ERR_WRITE 0x00000009
#define SCLIB_ERR_TIME0OUT 0x0000000A ///< Smartcard timer 0 timeout
#define SCLIB_ERR_TIME1OUT 0x0000000B ///< Smartcard timer 1 timeout
#define SCLIB_ERR_TIME2OUT 0x0000000C ///< Smartcard timer 2 timeout
#define SCLIB_ERR_AUTOCONVENTION 0x0000000D ///< Smartcard is neither direct nor inverse convention
#define SCLIB_ERR_CLOCK 0x0000000E ///< Smartcard clock frequency is not between 1MHz and 5 MHz
#define SCLIB_ERR_BGTIMEOUT 0x0000000E
// error code generate while parsing ATR and process PPS
#define SCLIB_ERR_ATR_UNRECOGNIZED 0x00001001 ///< Unrecognized ATR
#define SCLIB_ERR_ATR_INVALID_PARAM 0x00001002 ///< ATR parsing interface bytes error
#define SCLIB_ERR_ATR_INVALID_TCK 0x00001003 ///< TCK check byte error
#define SCLIB_ERR_PPS 0x00001004
// error code for T=1 protocol
#define SCLIB_ERR_T1_PARITY 0x00002001 ///< T=1 Parity Error Notice
#define SCLIB_ERR_T1_ICC 0x00002002 ///< ICC communication error
#define SCLIB_ERR_T1_PROTOCOL 0x00002003 ///< T=1 Protocol Error
#define SCLIB_ERR_T1_ABORT_RECEIVED 0x00002004 ///< Received ABORT request
#define SCLIB_ERR_T1_RESYNCH_RECEIVED 0x00002005 ///< Received RESYNCH request
#define SCLIB_ERR_T1_VPP_ERROR_RECEIVED 0x00002006 ///< Received VPP error
#define SCLIB_ERR_T1_WTXRES_RECEIVED 0x00002007 ///< Received BWT extension request
#define SCLIB_ERR_T1_IFSRES_RECEIVED 0x00002008 ///< Received max IFS offer
#define SCLIB_ERR_T1_ABORTRES_RECEIVED 0x00002009 ///< Received ABORT response
#define SCLIB_ERR_T1_CHECKSUM 0x0000200A ///< T=1 block check sum error
// error code for T=0 protocol
#define SCLIB_ERR_T0_PROTOCOL 0x00003003 ///< T=0 Protocol Error
// error code indicates application control flow error
#define SCLIB_ERR_DEACTIVE 0x0000F001 ///< Smartcard is deactivation
#define SCLIB_ERR_CARDBUSY 0x0000F002 ///< Smartcard is busy, previous transmission is not complete yet
/*@}*/ /* end of group NUC400_SCLIB_EXPORTED_CONSTANTS */
/** @addtogroup NUC400_SCLIB_EXPORTED_STRUCTS Smartcard Library Exported Structs
@{
*/
/**
* @brief A structure holds smartcard information
*/
typedef struct {
uint32_t T; ///< Protocol, ether \ref SCLIB_PROTOCOL_T0 or \ref SCLIB_PROTOCOL_T1.
uint32_t ATR_Len; ///< ATR length, between SCLIB_MAX_ATR_LEN and SCLIB_MIN_ATR_LEN
uint8_t ATR_Buf[SCLIB_MAX_ATR_LEN]; ///< Buffer holds ATR answered by smartcard
} SCLIB_CARD_INFO_T;
/**
* @brief A structure holds smartcard attribute, including convention, guard time, waiting time, IFCS... etc.
*/
typedef struct
{
uint8_t Fi; ///< Findex;
uint8_t Di; ///< Dindex;
uint8_t conv; ///< Convention, direct or inverse. 0 direct, 1 inverse
uint8_t chksum; ///< Checksum type
uint8_t GT; ///< Guard Time
uint8_t WI; ///< Wait integer for T0
uint8_t BWI; ///< Block waiting integer for T1;
uint8_t CWI; ///< Character waiting integer for T1;
uint8_t clkStop; ///< Card clock stop status. 00 Not allowed, 01 low, 02, high, 03 ether high or low
uint8_t IFSC; ///< size of negotiated IFCS
uint8_t NAD; ///< NAD value
} SCLIB_CARD_ATTRIB_T;
/*@}*/ /* end of group NUC400_SCLIB_EXPORTED_STRUCTS */
/** @addtogroup NUC400_SCLIB_EXPORTED_FUNCTIONS Smartcard Library Exported Functions
@{
*/
/**
* @brief Activate a smartcard
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @param[in] u32EMVCheck Enable EMV error check or not. Valid setting are \ref TRUE and \ref FALSE.
* By enable EMV error checking, this library will perform ATR checking according to
* EMV book 1 specification. Otherwise, the error checking follows ISO 7816-3
* @return Smartcard successfully activated or not
* @retval SCLIB_SUCCESS Smartcard activated successfully
* @retval Others Smartcard activation failed
* @note It is required to set smartcard interface clock between 1 MHz and 5 MHz before
* calling this API, otherwise this API return with \ref SCLIB_ERR_CLOCK error code.
* @note EMV book 1 is stricter than ISO-7816 on ATR checking. Enable EMV check iff the
* application supports EMV cards only.
*/
int32_t SCLIB_Activate(uint32_t num, uint32_t u32EMVCheck);
/**
* @brief Activate a smartcard with large delay between set VCC high and start CLK output
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @param[in] u32EMVCheck Enable EMV error check or not. Valid setting are \ref TRUE and \ref FALSE.
* By enable EMV error checking, this library will perform ATR checking according to
* EMV book 1 specification. Otherwise, the error checking follows ISO 7816-3
* @param[in] u32Delay Extra delay time between set VCC high and start CLK output, using ETU as time unit.
* @return Smartcard successfully activated or not
* @retval SCLIB_SUCCESS Smartcard activated successfully
* @retval Others Smartcard activation failed
* @note It is required to set smartcard interface clock between 1 MHz and 5 MHz before
* calling this API, otherwise this API return with \ref SCLIB_ERR_CLOCK error code.
* @note EMV book 1 is stricter than ISO-7816 on ATR checking. Enable EMV check iff the
* application supports EMV cards only.
* @note Only use this function instead of \ref SCLIB_Activate if there's large capacitor on VCC pin and
* VCC raise slowly.
*/
int32_t SCLIB_ActivateDelay(uint32_t num, uint32_t u32EMVCheck, uint32_t u32Delay);
/**
* @brief Cold reset a smartcard
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @return Smartcard cold reset success or not
* @retval SCLIB_SUCCESS Smartcard cold reset success
* @retval Others Smartcard cold reset failed
*/
int32_t SCLIB_ColdReset(uint32_t num);
/**
* @brief Warm reset a smartcard
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @return Smartcard warm reset success or not
* @retval SCLIB_SUCCESS Smartcard warm reset success
* @retval Others Smartcard warm reset failed
*/
int32_t SCLIB_WarmReset(uint32_t num);
/**
* @brief Deactivate a smartcard
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @return None
*/
void SCLIB_Deactivate(uint32_t num);
/**
* @brief Get the card information (e.g., protocol selected, ATR...) after activation success
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @param[out] s_info A pointer to \ref SCLIB_CARD_INFO_T holds the card information
* @return Success or not
* @retval SCLIB_SUCCESS Success, s_info contains card information
* @retval SCLIB_ERR_CARD_REMOVED Card removed, s_info does not contains card information
* @retval SCLIB_ERR_DEACTIVE Card is deactivated, s_info does not contains card information
*/
int32_t SCLIB_GetCardInfo(uint32_t num, SCLIB_CARD_INFO_T *s_info);
/**
* @brief Get the card attribute (e.g., Fi, Di, convention, guard time... etc. ) after activation success
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @param[out] s_attrib A pointer to \ref SCLIB_CARD_ATTRIB_T holds the card information
* @return Success or not
* @retval SCLIB_SUCCESS Success, s_info contains card information
* @retval SCLIB_ERR_CARD_REMOVED Card removed, s_info does not contains card information
* @retval SCLIB_ERR_DEACTIVE Card is deactivated, s_info does not contains card information
*/
int32_t SCLIB_GetCardAttrib(uint32_t num, SCLIB_CARD_ATTRIB_T *s_attrib);
/**
* @brief Start a smartcard transmission.
* @details SCLIB will start a transmission according to the protocol selected
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @param[in] cmdBuf Command buffer pointer
* @param[in] cmdLen Command length
* @param[out] rspBuf Buffer to holds card response
* @param[out] rspLen Response length received
* @return Smartcard transmission success or failed
* @retval SCLIB_SUCCESS Transmission success. rspBuf and rspLen holds response data and length
* @retval Others Transmission failed
* @note This API supports case 1, 2S, 3S, and 4S defined in ISO-7816, but does \b NOT support case 2E, 3E, and 4E.
*/
int32_t SCLIB_StartTransmission(uint32_t num, uint8_t *cmdBuf, uint32_t cmdLen, uint8_t *rspBuf, uint32_t *rspLen);
/**
* @brief Set interface device max information field size (IFSD)
* @details This function sends S block to notify card about the max size of information filed blocks that
* can be received by the interface device. According to EMV 9.2.4.3, this should be the first
* block transmitted by terminal to ICC after ATR.
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @param[in] size IFSD size. According to EMV spec 9.2.4.3 Error Free Operation, this field must be 0xFE.
* @return Smartcard transmission success or failed
* @retval SCLIB_SUCCESS Smartcard warm reset success
* @retval Others Smartcard warm reset failed
*/
int32_t SCLIB_SetIFSD(uint32_t num, uint8_t size);
/**
* @brief A callback called by library while smartcard request for a time extension
* @param[in] u32Protocol What protocol the card is using while it requested for a time extension.
* Could be ether \ref SCLIB_PROTOCOL_T0 or \ref SCLIB_PROTOCOL_T1
* @return None
* @note This function is defined with __weak attribute and does nothing in library.
* Application can provide its own time extension function. For example, and CCID reader
* can use this function to report this status to PC. See CCID rev 1.1 Table 6.2-3
*/
#if defined (__GNUC__)
void SCLIB_RequestTimeExtension () __attribute__ ((weak));
void SCLIB_RequestTimeExtension(uint32_t u32Protocol);
#else
__weak void SCLIB_RequestTimeExtension(uint32_t u32Protocol);
#endif
/**
* @brief Process card detect event in IRQ handler
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @return Card detect event occur or not
* @retval 1 Card detect event occurred
* @retval 0 Card detect event did not occur
* @note Smartcard IRQ handler shall call this function with correct interface number as parameter
*/
uint32_t SCLIB_CheckCDEvent(uint32_t num);
/**
* @brief Process time out event in IRQ handler
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @return Time out event occur or not
* @retval 1 Time out event occurred
* @retval 0 Time out event did not occur
* @note Smartcard IRQ handler shall call this function with correct interface number as parameter
*/
uint32_t SCLIB_CheckTimeOutEvent(uint32_t num);
/**
* @brief Process card transmission event in IRQ handler
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @return Transmission event occur or not
* @retval 1 Transmission event occurred
* @retval 0 Transmission event did not occur
* @note Smartcard IRQ handler shall call this function with correct interface number as parameter
*/
uint32_t SCLIB_CheckTxRxEvent(uint32_t num);
/**
* @brief Process error event in IRQ handler
* @param[in] num Smartcard interface number. From 0 ~ ( \ref SC_INTERFACE_NUM - 1)
* @return Error event occur or not
* @retval 1 Error event occurred
* @retval 0 Error event did not occur
* @note Smartcard IRQ handler shall call this function with correct interface number as parameter
*/
uint32_t SCLIB_CheckErrorEvent(uint32_t num);
#ifdef __cplusplus
}
#endif
#endif //__SCLIB_H__
/*@}*/ /* end of group SCLIB_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SC_Library */
/*@}*/ /* end of group Library */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

163
BSP/StdDriver/inc/acmp.h Normal file
View File

@ -0,0 +1,163 @@
/**************************************************************************//**
* @file acmp.h
* @version V3.00
* $Revision: 11 $
* $Date: 15/05/20 8:50p $
* @brief Analog Comparator (ACMP) driver header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __ACMP_H__
#define __ACMP_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup ACMP_Driver ACMP Driver
@{
*/
/** @addtogroup ACMP_EXPORTED_CONSTANTS ACMP Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* CMPCR constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ACMP_CR_VNEG_BANDGAP (1UL << ACMP_CMPCR_CMPCN_Pos) /*!< CMPCR setting for selecting band-gap voltage as the source of ACMP V-. */
#define ACMP_CR_VNEG_PIN (0UL << ACMP_CMPCR_CMPCN_Pos) /*!< CMPCR setting for selecting the voltage of ACMP negative input pin as the source of ACMP V-. */
#define ACMP_CR_HYSTERESIS_ENABLE (1UL << ACMP_CMPCR_CMP_HYSEN_Pos) /*!< CMPCR setting for enabling the hysteresis function. */
#define ACMP_CR_HYSTERESIS_DISABLE (0UL << ACMP_CMPCR_CMP_HYSEN_Pos) /*!< CMPCR setting for disabling the hysteresis function. */
#define ACMP_CR_INT_ENABLE (1UL << ACMP_CMPCR_CMPIE_Pos) /*!< CMPCR setting for enabling the interrupt function. */
#define ACMP_CR_INT_DISABLE (0UL << ACMP_CMPCR_CMPIE_Pos) /*!< CMPCR setting for disabling the interrupt function. */
#define ACMP_CR_ACMP_ENABLE (1UL << ACMP_CMPCR_CMPEN_Pos) /*!< CMPCR setting for enabling the ACMP analog circuit. */
#define ACMP_CR_ACMP_DISABLE (0UL << ACMP_CMPCR_CMPEN_Pos) /*!< CMPCR setting for disabling the ACMP analog circuit. */
/*@}*/ /* end of group ACMP_EXPORTED_CONSTANTS */
/** @addtogroup ACMP_EXPORTED_FUNCTIONS ACMP Exported Functions
@{
*/
/**
* @brief This macro is used to select ACMP negative input source
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @param[in] u32Src Comparator negative input selection. Including:
* - \ref ACMP_CR_VNEG_PIN
* - \ref ACMP_CR_VNEG_BANDGAP
* @return None
* @details This macro will set CMPCN bit of CMPCR register to determine the source of negative input.
*/
#define ACMP_SET_NEG_SRC(acmp, u32ChNum, u32Src) ((acmp)->CMPCR[(u32ChNum)%2] = ((acmp)->CMPCR[(u32ChNum)%2] & ~ACMP_CMPCR_CMPCN_Msk) | (u32Src))
/**
* @brief This macro is used to enable hysteresis function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set HYSEN bit of CMPCR register to enable hysteresis function.
*/
#define ACMP_ENABLE_HYSTERESIS(acmp, u32ChNum) ((acmp)->CMPCR[(u32ChNum)%2] |= ACMP_CMPCR_CMP_HYSEN_Msk)
/**
* @brief This macro is used to disable hysteresis function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear HYSEN bit of CMPCR register to disable hysteresis function.
*/
#define ACMP_DISABLE_HYSTERESIS(acmp, u32ChNum) ((acmp)->CMPCR[(u32ChNum)%2] &= ~ACMP_CMPCR_CMP_HYSEN_Msk)
/**
* @brief This macro is used to enable interrupt
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set CMPIE bit of CMPCR register to enable interrupt function.
*/
#define ACMP_ENABLE_INT(acmp, u32ChNum) ((acmp)->CMPCR[(u32ChNum)%2] |= ACMP_CMPCR_CMPIE_Msk)
/**
* @brief This macro is used to disable interrupt
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear CMPIE bit of CMPCR register to disable interrupt function.
*/
#define ACMP_DISABLE_INT(acmp, u32ChNum) ((acmp)->CMPCR[(u32ChNum)%2] &= ~ACMP_CMPCR_CMPIE_Msk)
/**
* @brief This macro is used to enable ACMP
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set CMPEN bit of CMPCR register to enable analog comparator.
*/
#define ACMP_ENABLE(acmp, u32ChNum) ((acmp)->CMPCR[(u32ChNum)%2] |= ACMP_CMPCR_CMPEN_Msk)
/**
* @brief This macro is used to disable ACMP
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear CMPEN bit of CMPCR register to disable analog comparator.
*/
#define ACMP_DISABLE(acmp, u32ChNum) ((acmp)->CMPCR[(u32ChNum)%2] &= ~ACMP_CMPCR_CMPEN_Msk)
/**
* @brief This macro is used to get ACMP output value
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return ACMP output value
* @details This macro will return the ACMP output value.
*/
#define ACMP_GET_OUTPUT(acmp, u32ChNum) (((acmp)->CMPSR & (ACMP_CMPSR_CO0_Msk<<(u32ChNum)))?1:0)
/**
* @brief This macro is used to get ACMP interrupt flag
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return ACMP interrupt occurred or not
* @details This macro will return the ACMP interrupt flag.
*/
#define ACMP_GET_INT_FLAG(acmp, u32ChNum) (((acmp)->CMPSR & (ACMP_CMPSR_CMPF0_Msk<<(u32ChNum)))?1:0)
/**
* @brief This macro is used to clear ACMP interrupt flag
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will write 1 to CMPFn bit of CMPSR register to clear interrupt flag.
*/
#define ACMP_CLR_INT_FLAG(acmp, u32ChNum) ((acmp)->CMPSR = (ACMP_CMPSR_CMPF0_Msk<<(u32ChNum)))
/* Function prototype declaration */
void ACMP_Open(ACMP_T *, uint32_t u32ChNum, uint32_t u32NegSrc, uint32_t u32HysteresisEn);
void ACMP_Close(ACMP_T *, uint32_t u32ChNum);
/*@}*/ /* end of group ACMP_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group ACMP_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__ACMP_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

362
BSP/StdDriver/inc/adc.h Normal file
View File

@ -0,0 +1,362 @@
/**************************************************************************//**
* @file adc.h
* @version V3.00
* $Revision: 14 $
* $Date: 15/05/06 4:39p $
* @brief ADC Driver Header File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __ADC_H__
#define __ADC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup ADC_Driver ADC Driver
@{
*/
/** @addtogroup ADC_EXPORTED_CONSTANTS ADC Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* ADCR Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ADC_ADCR_ADEN_CONVERTER_DISABLE (0UL<<ADC_ADCR_ADEN_Pos) /*!< ADC converter disable */
#define ADC_ADCR_ADEN_CONVERTER_ENABLE (1UL<<ADC_ADCR_ADEN_Pos) /*!< ADC converter enable */
#define ADC_ADCR_ADMD_SINGLE (0UL<<ADC_ADCR_ADMD_Pos) /*!< Single mode */
#define ADC_ADCR_ADMD_SINGLE_CYCLE (2UL<<ADC_ADCR_ADMD_Pos) /*!< Single cycle scan mode */
#define ADC_ADCR_ADMD_CONTINUOUS (3UL<<ADC_ADCR_ADMD_Pos) /*!< Continuous scan mode */
#define ADC_ADCR_DIFFEN_SINGLE_END (0UL<<ADC_ADCR_DIFFEN_Pos) /*!< Single end input mode */
#define ADC_ADCR_DIFFEN_DIFFERENTIAL (1UL<<ADC_ADCR_DIFFEN_Pos) /*!< Differential input type */
#define ADC_ADCR_DMOF_UNSIGNED_OUTPUT (0UL<<ADC_ADCR_DMOF_Pos) /*!< Select the straight binary format as the output format of the conversion result */
#define ADC_ADCR_DMOF_TWOS_COMPLEMENT (1UL<<ADC_ADCR_DMOF_Pos) /*!< Select the 2's complement format as the output format of the conversion result */
#define ADC_ADCR_TRGEN_DISABLE (0UL<<ADC_ADCR_TRGEN_Pos) /*!< Disable triggering of A/D conversion by external STADC pin or PWM */
#define ADC_ADCR_TRGEN_ENABLE (1UL<<ADC_ADCR_TRGEN_Pos) /*!< Enable triggering of A/D conversion by external STADC pin or PWM */
#define ADC_ADCR_TRGS_STADC (0UL<<ADC_ADCR_TRGS_Pos) /*!< A/D conversion is started by external STADC pin */
#define ADC_ADCR_TRGS_PWM (3UL<<ADC_ADCR_TRGS_Pos) /*!< A/D conversion is started by PWM */
#define ADC_ADCR_TRGCOND_LOW_LEVEL (0UL<<ADC_ADCR_TRGCOND_Pos) /*!< STADC Low level active */
#define ADC_ADCR_TRGCOND_HIGH_LEVEL (1UL<<ADC_ADCR_TRGCOND_Pos) /*!< STADC High level active */
#define ADC_ADCR_TRGCOND_FALLING_EDGE (2UL<<ADC_ADCR_TRGCOND_Pos) /*!< STADC Falling edge active */
#define ADC_ADCR_TRGCOND_RISING_EDGE (3UL<<ADC_ADCR_TRGCOND_Pos) /*!< STADC Rising edge active */
/*---------------------------------------------------------------------------------------------------------*/
/* ADCHER Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ADC_ADCHER_PRESEL_EXT_INPUT_SIGNAL (0UL<<ADC_ADCHER_PRESEL_Pos) /*!< The input source of channel 7 is the external analog input */
#define ADC_ADCHER_PRESEL_INT_BANDGAP (1UL<<ADC_ADCHER_PRESEL_Pos) /*!< The input source of channel 7 is the internal bandgap voltage */
#define ADC_ADCHER_PRESEL_INT_TEMPERATURE_SENSOR (2UL<<ADC_ADCHER_PRESEL_Pos) /*!< The input source of channel 7 is the output of internal temperature sensor */
/*---------------------------------------------------------------------------------------------------------*/
/* ADCMPR Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ADC_ADCMPR_CMPD(x) ((x) << ADC_ADCMPR_CMPD_Pos) /*!< Compare value for compare function */
#define ADC_ADCMPR_CMPMATCNT(x) (((x)-1) << ADC_ADCMPR_CMPMATCNT_Pos) /*!< Match count for compare function */
#define ADC_ADCMPR_CMPCH(x) ((x) << ADC_ADCMPR_CMPCH_Pos) /*!< Compare channel for compare function */
#define ADC_ADCMPR_CMPCOND_LESS_THAN (0<<ADC_ADCMPR_CMPCOND_Pos) /*!< The compare condition is "less than" */
#define ADC_ADCMPR_CMPCOND_GREATER_OR_EQUAL (1<<ADC_ADCMPR_CMPCOND_Pos) /*!< The compare condition is "greater than or equal to" */
#define ADC_ADCMPR_CMPIE_INTERRUPT_ENABLE (ADC_ADCMPR_CMPIE_Msk) /*!< The compare function interrupt enable */
/*---------------------------------------------------------------------------------------------------------*/
/* ADC Interrupt Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ADC_ADF_INT (ADC_ADSR_ADF_Msk) /*!< ADC convert complete interrupt */
#define ADC_CMP0_INT (ADC_ADSR_CMPF0_Msk) /*!< ADC comparator 0 interrupt */
#define ADC_CMP1_INT (ADC_ADSR_CMPF1_Msk) /*!< ADC comparator 1 interrupt */
/*---------------------------------------------------------------------------------------------------------*/
/* ADC Operation Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ADC_SINGLE_MODE 0 /*!< ADC single mode */
#define ADC_SINGLE_CYCLE_MODE 2 /*!< ADC single-cycle scan mode */
#define ADC_CONTINUOUS_MODE 3 /*!< ADC continuous scan mode */
/*---------------------------------------------------------------------------------------------------------*/
/* ADC Trigger Condition Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ADC_LOW_LEVEL 0 /*!< ADC external trigger condition is low level trigger */
#define ADC_HIGH_LEVEL 1 /*!< ADC external trigger condition is high level trigger */
#define ADC_FALLING_EDGE 2 /*!< ADC external trigger condition is falling edge trigger */
#define ADC_RISING_EDGE 3 /*!< ADC external trigger condition is rising edge trigger */
/*---------------------------------------------------------------------------------------------------------*/
/* ADC Compare Condition Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ADC_LESS_THAN 0 /*!< ADC compare condition is "less than the compare value" */
#define ADC_GREATER_OR_EQUAL 1 /*!< ADC compare condition is "greater than or equal to the compare value" */
/*---------------------------------------------------------------------------------------------------------*/
/* Constant Definitions of ADC Channel 7 Input Source */
/*---------------------------------------------------------------------------------------------------------*/
#define ADC_CH7_EXT_INPUT_SIGNAL 0 /*!< External input signal */
#define ADC_CH7_INT_BANDGAP 1 /*!< Internal band-gap voltage */
#define ADC_CH7_INT_TEMPERATURE_SENSOR 2 /*!< Internal temperature sensor */
/*@}*/ /* end of group ADC_EXPORTED_CONSTANTS */
/** @addtogroup ADC_EXPORTED_FUNCTIONS ADC Exported Functions
@{
*/
/**
* @brief Configure the analog input source of channel 7.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32Source Decides the analog input source of channel 7. Valid values are:
* - \ref ADC_ADCHER_PRESEL_EXT_INPUT_SIGNAL : External analog input.
* - \ref ADC_ADCHER_PRESEL_INT_BANDGAP : Internal bandgap voltage.
* - \ref ADC_ADCHER_PRESEL_INT_TEMPERATURE_SENSOR : Output of internal temperature sensor.
* @return None
* @details Channel 7 supports 3 input sources: External analog voltage, internal Band-gap voltage, and internal temperature sensor output.
* @note While using VBG as channel 7 source, ADC module clock must /b not exceed 300kHz.
*/
#define ADC_CONFIG_CH7(adc, u32Source) ((adc)->ADCHER = ((adc)->ADCHER & ~ADC_ADCHER_PRESEL_Msk) | (u32Source))
/**
* @brief Enable PDMA transfer.
* @param[in] adc The pointer of the specified ADC module
* @return None
* @details Enable PDMA to transfer the conversion data.
* @note While enable PDMA transfer, software must set ADIE = 0 to disable interrupt.
*/
#define ADC_ENABLE_PDMA(adc) ((adc)->ADCR |= ADC_ADCR_PTEN_Msk)
/**
* @brief Disable PDMA transfer.
* @param[in] adc The pointer of the specified ADC module
* @return None
* @details Disable PDMA to transfer the conversion data.
*/
#define ADC_DISABLE_PDMA(adc) ((adc)->ADCR &= ~ADC_ADCR_PTEN_Msk)
/**
* @brief Get conversion data of specified channel.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32ChNum ADC Channel, valid value are from 0 to 7.
* @return 16-bit data.
* @details Read RSLT bit field to get conversion data.
*/
#define ADC_GET_CONVERSION_DATA(adc, u32ChNum) ((adc)->ADDR[(u32ChNum)] & ADC_ADDR_RSLT_Msk)
/**
* @brief Return the user-specified interrupt flags.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32Mask The combination of following interrupt status bits. Each bit corresponds to a interrupt status.
* Valid values are:
* - \ref ADC_ADF_INT :Convert complete interrupt flag.
* - \ref ADC_CMP0_INT :Comparator 0 interrupt flag.
* - \ref ADC_CMP1_INT :Comparator 1 interrupt flag.
* @return User specified interrupt flags.
* @details Get the status of the ADC interrupt flag.
*/
#define ADC_GET_INT_FLAG(adc, u32Mask) ((adc)->ADSR & (u32Mask))
/**
* @brief This macro clear the selected interrupt status bits.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32Mask The combination of following interrupt status bits. Each bit corresponds to a interrupt status.
* Valid values are:
* - \ref ADC_ADF_INT :Convert complete interrupt flag.
* - \ref ADC_CMP0_INT :Comparator 0 interrupt flag.
* - \ref ADC_CMP1_INT :Comparator 1 interrupt flag.
* @return None
* @details ADF (ADSR[0])/CMPF0 (ADSR[1])/CMPF0 (ADSR[2]) can be cleared by writing 1 to itself.
*/
#define ADC_CLR_INT_FLAG(adc, u32Mask) ((adc)->ADSR = (u32Mask))
/**
* @brief Get the busy state of ADC.
* @param[in] adc The pointer of the specified ADC module.
* @retval 0 ADC is not busy.
* @retval 1 ADC is busy.
* @details BUSY(ADSR[3])is mirror of as ADST bit (ADCR[11]).
*/
#define ADC_IS_BUSY(adc) ((adc)->ADSR & ADC_ADSR_BUSY_Msk ? 1 : 0)
/**
* @brief Check if the ADC conversion data is over written or not.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32ChNum ADC Channel, valid value are from 0 to 7.
* @retval 0 ADC data is not overrun.
* @retval 1 ADC data is overrun.
* @details OVERRUN (ADSR[23:16]) is a mirror to OVERRUN (ADDR0~7[16]).
*/
#define ADC_IS_DATA_OVERRUN(adc, u32ChNum) ((adc)->ADSR & (0x1 << (ADC_ADSR_OVERRUN_Pos + (u32ChNum))) ? 1 : 0)
/**
* @brief Check if the ADC conversion data is valid or not.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32ChNum ADC Channel, valid value are from 0 to 7.
* @retval 0 ADC data is not valid.
* @retval 1 ADC data is valid.
* @details VALID (ADDR0~7[17]) is set to 1 when corresponding channel analog input conversion is completed and cleared by hardware after ADDR register is read.
*/
#define ADC_IS_DATA_VALID(adc, u32ChNum) ((adc)->ADSR & (0x1<<(ADC_ADSR_VALID_Pos+(u32ChNum))) ? 1 : 0)
/**
* @brief Power down ADC module.
* @param[in] adc The pointer of the specified ADC module.
* @return None
* @details Disable A/D converter analog circuit for saving power consumption.
* @note None
*/
#define ADC_POWER_DOWN(adc) ((adc)->ADCR &= ~ADC_ADCR_ADEN_Msk)
/**
* @brief Power on ADC module.
* @param[in] adc The pointer of the specified ADC module.
* @return None
* @details Before starting A/D conversion function, ADEN bit (ADCR[0]) should be set to 1.
*/
#define ADC_POWER_ON(adc) ((adc)->ADCR |= ADC_ADCR_ADEN_Msk)
/**
* @brief Configure the comparator 0 and enable it.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32ChNum Specifies the source channel, valid value are from 0 to 7.
* @param[in] u32Condition Specifies the compare condition. Valid values are:
* - \ref ADC_ADCMPR_CMPCOND_LESS_THAN :The compare condition is "less than the compare value".
* - \ref ADC_ADCMPR_CMPCOND_GREATER_OR_EQUAL :The compare condition is "greater than or equal to the compare value.
* @param[in] u32Data Specifies the compare value, valid value are between 0 ~ 0xFFF.
* @param[in] u32MatchCount Specifies the match count setting, valid values are between 1~16.
* @return None
* @details For example, ADC_ENABLE_CMP0(ADC, 5, ADC_ADCMPR_CMPCOND_GREATER_OR_EQUAL, 0x800, 10);
* Means ADC will assert comparator 0 flag if channel 5 conversion result is greater or
* equal to 0x800 for 10 times continuously.
* \hideinitializer
*/
#define ADC_ENABLE_CMP0(adc, \
u32ChNum, \
u32Condition, \
u32Data, \
u32MatchCount) ((adc)->ADCMPR[0] = ((u32ChNum) << ADC_ADCMPR_CMPCH_Pos) | \
(u32Condition) | \
((u32Data) << ADC_ADCMPR_CMPD_Pos) | \
(((u32MatchCount) - 1) << ADC_ADCMPR_CMPMATCNT_Pos) |\
ADC_ADCMPR_CMPEN_Msk)
/**
* @brief Disable comparator 0.
* @param[in] adc The pointer of the specified ADC module.
* @return None
* @details Set CMPEN (ADCMPR0[0]) to 0 to disable ADC controller to compare CMPD (ADCMPR0[27:16]).
*/
#define ADC_DISABLE_CMP0(adc) ((adc)->ADCMPR[0] = 0)
/**
* @brief Configure the comparator 1 and enable it.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32ChNum Specifies the source channel, valid value are from 0 to 7.
* @param[in] u32Condition Specifies the compare condition. Valid values are:
* - \ref ADC_ADCMPR_CMPCOND_LESS_THAN :The compare condition is "less than the compare value".
* - \ref ADC_ADCMPR_CMPCOND_GREATER_OR_EQUAL :The compare condition is "greater than or equal to the compare value.
* @param[in] u32Data Specifies the compare value, valid value are between 0 ~ 0xFFF.
* @param[in] u32MatchCount Specifies the match count setting, valid values are between 1~16.
* @return None
* @details For example, ADC_ENABLE_CMP1(ADC, 5, ADC_ADCMPR_CMPCOND_GREATER_OR_EQUAL, 0x800, 10);
* Means ADC will assert comparator 1 flag if channel 5 conversion result is greater or
* equal to 0x800 for 10 times continuously.
* \hideinitializer
*/
#define ADC_ENABLE_CMP1(adc, \
u32ChNum, \
u32Condition, \
u32Data, \
u32MatchCount) ((adc)->ADCMPR[1] = ((u32ChNum) << ADC_ADCMPR_CMPCH_Pos) | \
(u32Condition) | \
((u32Data) << ADC_ADCMPR_CMPD_Pos) | \
(((u32MatchCount) - 1) << ADC_ADCMPR_CMPMATCNT_Pos) |\
ADC_ADCMPR_CMPEN_Msk)
/**
* @brief Disable comparator 1.
* @param[in] adc The pointer of the specified ADC module.
* @return None
* @details Set CMPEN (ADCMPR1[0]) to 0 to disable ADC controller to compare CMPD (ADCMPR1[27:16]).
*/
#define ADC_DISABLE_CMP1(adc) ((adc)->ADCMPR[1] = 0)
/**
* @brief Set ADC input channel.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32Mask Channel enable bit. Each bit corresponds to a input channel. Bit 0 is channel 0, bit 1 is channel 1..., bit 7 is channel 7.
* @return None
* @details Enabled channel will be converted while ADC starts.
* @note NUC200 series MCU ADC can only convert 1 channel at a time. If more than 1 channels are enabled, only channel
* with smallest number will be convert.
*/
#define ADC_SET_INPUT_CHANNEL(adc, u32Mask) ((adc)->ADCHER = ((adc)->ADCHER & ~ADC_ADCHER_CHEN_Msk) | (u32Mask))
/**
* @brief Set the output format mode.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32Format Decides the output format. Valid values are:
* - \ref ADC_ADCR_DMOF_UNSIGNED_OUTPUT :Select the straight binary format as the output format of the conversion result.
* - \ref ADC_ADCR_DMOF_TWOS_COMPLEMENT :Select the 2's complement format as the output format of the conversion result.
* @return None
* @details The macro is used to set A/D differential input mode output format.
*/
#define ADC_SET_DMOF(adc, u32Format) ((adc)->ADCR = ((adc)->ADCR & ~ADC_ADCR_DMOF_Msk) | (u32Format))
/**
* @brief Start the A/D conversion.
* @param[in] adc The pointer of the specified ADC module.
* @return None
* @details ADST (ADCR[11]) can be set to 1 from three sources: software, PWM Center-aligned trigger and external pin STADC.
*/
#define ADC_START_CONV(adc) ((adc)->ADCR |= ADC_ADCR_ADST_Msk)
/**
* @brief Stop the A/D conversion.
* @param[in] adc The pointer of the specified ADC module.
* @return None
* @details ADST (ADCR[11]) will be cleared to 0 by hardware automatically at the ends of single mode and single-cycle scan mode.
* In continuous scan mode, A/D conversion is continuously performed until software writes 0 to this bit or chip reset.
*/
#define ADC_STOP_CONV(adc) ((adc)->ADCR &= ~ADC_ADCR_ADST_Msk)
void ADC_Open(ADC_T *adc,
uint32_t u32InputMode,
uint32_t u32OpMode,
uint32_t u32ChMask);
void ADC_Close(ADC_T *adc);
void ADC_EnableHWTrigger(ADC_T *adc,
uint32_t u32Source,
uint32_t u32Param);
void ADC_DisableHWTrigger(ADC_T *adc);
void ADC_EnableInt(ADC_T *adc, uint32_t u32Mask);
void ADC_DisableInt(ADC_T *adc, uint32_t u32Mask);
/*@}*/ /* end of group ADC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group ADC_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__ADC_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

561
BSP/StdDriver/inc/clk.h Normal file
View File

@ -0,0 +1,561 @@
/**************************************************************************//**
* @file clk.h
* @version V3.0
* $Revision: 42 $
* $Date: 17/07/20 1:59p $
* @brief Clock Control Driver Header File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __CLK_H__
#define __CLK_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup CLK_Driver CLK Driver
@{
*/
/** @addtogroup CLK_EXPORTED_CONSTANTS CLK Exported Constants
@{
*/
#define FREQ_25MHZ 25000000
#define FREQ_50MHZ 50000000
#define FREQ_100MHZ 100000000
#define FREQ_200MHZ 200000000
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL0 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL0_HCLK_S_HXT (0x0UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as external X'tal */
#define CLK_CLKSEL0_HCLK_S_LXT (0x1UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as external X'tal 32.768KHz*/
#define CLK_CLKSEL0_HCLK_S_PLL (0x2UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as PLL output */
#define CLK_CLKSEL0_HCLK_S_LIRC (0x3UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as internal 10KHz RC clock */
#define CLK_CLKSEL0_HCLK_S_HIRC (0x7UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL0_STCLK_S_HXT (0x0UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as external X'tal */
#define CLK_CLKSEL0_STCLK_S_LXT (0x1UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as external X'tal 32.768KHz*/
#define CLK_CLKSEL0_STCLK_S_HXT_DIV2 (0x2UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as external X'tal/2 */
#define CLK_CLKSEL0_STCLK_S_HCLK_DIV2 (0x3UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as HCLK/2 */
#define CLK_CLKSEL0_STCLK_S_HIRC_DIV2 (0x7UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as internal 22.1184MHz RC clock/2 */
#define CLK_CLKSEL0_STCLK_S_HCLK (0x1UL<<SysTick_CTRL_CLKSOURCE_Pos) /*!< Setting STCLK clock source as HCLK */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL1 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL1_WDT_S_LXT (0x1UL<<CLK_CLKSEL1_WDT_S_Pos) /*!< Setting WDT clock source as external X'tal 32.768KHz*/
#define CLK_CLKSEL1_WDT_S_HCLK_DIV2048 (0x2UL<<CLK_CLKSEL1_WDT_S_Pos) /*!< Setting WDT clock source as HCLK/2048 */
#define CLK_CLKSEL1_WDT_S_LIRC (0x3UL<<CLK_CLKSEL1_WDT_S_Pos) /*!< Setting WDT clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_ADC_S_HXT (0x0UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as external X'tal */
#define CLK_CLKSEL1_ADC_S_PLL (0x1UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as PLL */
#define CLK_CLKSEL1_ADC_S_HCLK (0x2UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as HCLK */
#define CLK_CLKSEL1_ADC_S_HIRC (0x3UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL1_SPI0_S_PLL (0x0UL<<CLK_CLKSEL1_SPI0_S_Pos) /*!< Setting SPI0 clock source as PLL */
#define CLK_CLKSEL1_SPI0_S_HCLK (0x1UL<<CLK_CLKSEL1_SPI0_S_Pos) /*!< Setting SPI0 clock source as HCLK */
#define CLK_CLKSEL1_SPI1_S_PLL (0x0UL<<CLK_CLKSEL1_SPI1_S_Pos) /*!< Setting SPI1 clock source as PLL */
#define CLK_CLKSEL1_SPI1_S_HCLK (0x1UL<<CLK_CLKSEL1_SPI1_S_Pos) /*!< Setting SPI1 clock source as HCLK */
#define CLK_CLKSEL1_SPI2_S_PLL (0x0UL<<CLK_CLKSEL1_SPI2_S_Pos) /*!< Setting SPI2 clock source as PLL */
#define CLK_CLKSEL1_SPI2_S_HCLK (0x1UL<<CLK_CLKSEL1_SPI2_S_Pos) /*!< Setting SPI2 clock source as HCLK */
#define CLK_CLKSEL1_SPI3_S_PLL (0x0UL<<CLK_CLKSEL1_SPI3_S_Pos) /*!< Setting SPI3 clock source as PLL */
#define CLK_CLKSEL1_SPI3_S_HCLK (0x1UL<<CLK_CLKSEL1_SPI3_S_Pos) /*!< Setting SPI3 clock source as HCLK */
#define CLK_CLKSEL1_TMR0_S_HXT (0x0UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as external X'tal */
#define CLK_CLKSEL1_TMR0_S_LXT (0x1UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as external X'tal 32.768KHz */
#define CLK_CLKSEL1_TMR0_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as HCLK */
#define CLK_CLKSEL1_TMR0_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as external trigger */
#define CLK_CLKSEL1_TMR0_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_TMR0_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL1_TMR1_S_HXT (0x0UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as external X'tal */
#define CLK_CLKSEL1_TMR1_S_LXT (0x1UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as external X'tal 32.768KHz */
#define CLK_CLKSEL1_TMR1_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as HCLK */
#define CLK_CLKSEL1_TMR1_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as external trigger */
#define CLK_CLKSEL1_TMR1_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_TMR1_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL1_TMR2_S_HXT (0x0UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as external X'tal */
#define CLK_CLKSEL1_TMR2_S_LXT (0x1UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as external X'tal 32.768KHz */
#define CLK_CLKSEL1_TMR2_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as HCLK */
#define CLK_CLKSEL1_TMR2_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as external trigger */
#define CLK_CLKSEL1_TMR2_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_TMR2_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL1_TMR3_S_HXT (0x0UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as external X'tal */
#define CLK_CLKSEL1_TMR3_S_LXT (0x1UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as external X'tal 32.768KHz */
#define CLK_CLKSEL1_TMR3_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as HCLK */
#define CLK_CLKSEL1_TMR3_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as external trigger */
#define CLK_CLKSEL1_TMR3_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_TMR3_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL1_UART_S_HXT (0x0UL<<CLK_CLKSEL1_UART_S_Pos) /*!< Setting UART clock source as external X'tal */
#define CLK_CLKSEL1_UART_S_PLL (0x1UL<<CLK_CLKSEL1_UART_S_Pos) /*!< Setting UART clock source as external PLL */
#define CLK_CLKSEL1_UART_S_HIRC (0x3UL<<CLK_CLKSEL1_UART_S_Pos) /*!< Setting UART clock source as external internal 22.1184MHz RC clock */
#define CLK_CLKSEL1_PWM01_S_HXT (0x0UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as external X'tal,
user must set CLK_CLKSEL2_PWM01_EXT_HXT concurrently to complete clock source as external X'tal setting*/
#define CLK_CLKSEL1_PWM01_S_LXT (0x1UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as external X'tal 32.768KHz,
user must set CLK_CLKSEL2_PWM01_EXT_LXT concurrently to complete clock source as external X'tal 32.768KHz setting*/
#define CLK_CLKSEL1_PWM01_S_HCLK (0x2UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as HCLK
user must set CLK_CLKSEL2_PWM01_EXT_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL1_PWM01_S_HIRC (0x3UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as internal 22.1184MHz RC clock,
user must set CLK_CLKSEL2_PWM01_EXT_HIRC concurrently to complete clock source as internal 22.1184MHz RC clock setting*/
#define CLK_CLKSEL1_PWM01_S_LIRC (0x3UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as internal 10KHz RC clock,
user must set CLK_CLKSEL2_PWM01_EXT_LIRC concurrently to complete clock source as internal 10KHz RC clock setting*/
#define CLK_CLKSEL1_PWM23_S_HXT (0x0UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as external X'tal,
user must set CLK_CLKSEL2_PWM23_EXT_HXT concurrently to complete clock source as external X'tal setting*/
#define CLK_CLKSEL1_PWM23_S_LXT (0x1UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as external X'tal 32.768KHz,
user must set CLK_CLKSEL2_PWM23_EXT_LXT concurrently to complete clock source as external X'tal 32.768KHz setting*/
#define CLK_CLKSEL1_PWM23_S_HCLK (0x2UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as HCLK,
user must set CLK_CLKSEL2_PWM23_EXT_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL1_PWM23_S_HIRC (0x3UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as internal 22.1184MHz RC clock,
user must set CLK_CLKSEL2_PWM23_EXT_HIRC concurrently to complete clock source as internal 22.1184MHz RC clock setting*/
#define CLK_CLKSEL1_PWM23_S_LIRC (0x3UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as internal 10KHz RC clock,
user must set CLK_CLKSEL2_PWM23_EXT_LIRC concurrently to complete clock source as internal 10KHz RC clock setting*/
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL2 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL2_I2S_S_HXT (0x0UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as external X'tal */
#define CLK_CLKSEL2_I2S_S_PLL (0x1UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as PLL */
#define CLK_CLKSEL2_I2S_S_HCLK (0x2UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as HCLK */
#define CLK_CLKSEL2_I2S_S_HIRC (0x3UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL2_FRQDIV_S_HXT (0x0UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Setting FRQDIV clock source as external X'tal */
#define CLK_CLKSEL2_FRQDIV_S_LXT (0x1UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Setting FRQDIV clock source as external X'tal 32.768KHz */
#define CLK_CLKSEL2_FRQDIV_S_HCLK (0x2UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Setting FRQDIV clock source as HCLK */
#define CLK_CLKSEL2_FRQDIV_S_HIRC (0x3UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Setting FRQDIV clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL2_PWM45_S_HXT (0x0UL<<CLK_CLKSEL2_PWM45_S_Pos) /*!< Setting PWM45 clock source as external X'tal,
user must set CLK_CLKSEL2_PWM45_EXT_HXT concurrently to complete clock source as external X'tal setting*/
#define CLK_CLKSEL2_PWM45_S_LXT (0x1UL<<CLK_CLKSEL2_PWM45_S_Pos) /*!< Setting PWM45 clock source as external X'tal 32.768KHz,
user must set CLK_CLKSEL2_PWM45_EXT_LXT concurrently to complete clock source as external X'tal 32.768KHz setting*/
#define CLK_CLKSEL2_PWM45_S_HCLK (0x2UL<<CLK_CLKSEL2_PWM45_S_Pos) /*!< Setting PWM45 clock source as HCLK,
user must set CLK_CLKSEL2_PWM45_EXT_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL2_PWM45_S_HIRC (0x3UL<<CLK_CLKSEL2_PWM45_S_Pos) /*!< Setting PWM45 clock source as internal 22.1184MHz RC clock,
user must set CLK_CLKSEL2_PWM45_EXT_HIRC concurrently to complete clock source as internal 22.1184MHz RC clock setting*/
#define CLK_CLKSEL2_PWM45_S_LIRC (0x3UL<<CLK_CLKSEL2_PWM45_S_Pos) /*!< Setting PWM45 clock source as internal 10KHz RC clock,
user must set CLK_CLKSEL2_PWM45_EXT_LIRC concurrently to complete clock source as internal 10KHz RC clock setting*/
#define CLK_CLKSEL2_PWM67_S_HXT (0x0UL<<CLK_CLKSEL2_PWM67_S_Pos) /*!< Setting PWM67 clock source as external X'tal,
user must set CLK_CLKSEL2_PWM67_EXT_HXT concurrently to complete clock source as external X'tal setting*/
#define CLK_CLKSEL2_PWM67_S_LXT (0x1UL<<CLK_CLKSEL2_PWM67_S_Pos) /*!< Setting PWM67 clock source as external X'tal 32.768KHz,
user must set CLK_CLKSEL2_PWM67_EXT_LXT concurrently to complete clock source as external X'tal 32.768KHz setting*/
#define CLK_CLKSEL2_PWM67_S_HCLK (0x2UL<<CLK_CLKSEL2_PWM67_S_Pos) /*!< Setting PWM67 clock source as HCLK,
user must set CLK_CLKSEL2_PWM67_EXT_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL2_PWM67_S_HIRC (0x3UL<<CLK_CLKSEL2_PWM67_S_Pos) /*!< Setting PWM67 clock source as internal 22.1184MHz RC clock,
user must set CLK_CLKSEL2_PWM67_EXT_HIRC concurrently to complete clock source as internal 22.1184MHz RC clock setting*/
#define CLK_CLKSEL2_PWM67_S_LIRC (0x3UL<<CLK_CLKSEL2_PWM67_S_Pos) /*!< Setting PWM67 clock source as internal 10KHz RC clock,
user must set CLK_CLKSEL2_PWM67_EXT_LIRC concurrently to complete clock source as internal 10KHz RC clock setting*/
#define CLK_CLKSEL2_PWM01_EXT_HXT (0x0UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as external X'tal,
user must set CLK_CLKSEL1_PWM01_HXT concurrently to complete clock source as external X'tal setting*/
#define CLK_CLKSEL2_PWM01_EXT_LXT (0x0UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as external X'tal 32.768KHz,
user must set CLK_CLKSEL1_PWM01_LXT concurrently to complete clock source as external X'tal 32.768KHz setting*/
#define CLK_CLKSEL2_PWM01_EXT_HCLK (0x0UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as HCLK,
user must set CLK_CLKSEL1_PWM01_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL2_PWM01_EXT_HIRC (0x0UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as internal 22.1184MHz RC clock,
user must set CLK_CLKSEL1_PWM01_HIRC concurrently to complete clock source as internal 22.1184MHz RC clock setting*/
#define CLK_CLKSEL2_PWM01_EXT_LIRC (0x1UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as internal 10KHz RC clock,
user must set CLK_CLKSEL1_PWM01_LIRC concurrently to complete clock source as internal 10KHz RC clock setting*/
#define CLK_CLKSEL2_PWM23_EXT_HXT (0x0UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as external X'tal,
user must set CLK_CLKSEL1_PWM23_HXT concurrently to complete clock source as external X'tal setting*/
#define CLK_CLKSEL2_PWM23_EXT_LXT (0x0UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as external X'tal 32.768KHz,
user must set CLK_CLKSEL1_PWM23_LXT concurrently to complete clock source as external X'tal 32.768KHz setting*/
#define CLK_CLKSEL2_PWM23_EXT_HCLK (0x0UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as HCLK,
user must set CLK_CLKSEL1_PWM23_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL2_PWM23_EXT_HIRC (0x0UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as internal 22.1184MHz RC clock,
user must set CLK_CLKSEL1_PWM23_HIRC concurrently to complete clock source as internal 22.1184MHz RC clock setting*/
#define CLK_CLKSEL2_PWM23_EXT_LIRC (0x1UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as internal 10KHz RC clock,
user must set CLK_CLKSEL1_PWM23_LIRC concurrently to complete clock source as internal 10KHz RC clock setting*/
#define CLK_CLKSEL2_PWM45_EXT_HXT (0x0UL<<CLK_CLKSEL2_PWM45_S_E_Pos)/*!< Setting PWM45 clock source as external X'tal,
user must set CLK_CLKSEL1_PWM45_HXT concurrently to complete clock source as external X'tal setting*/
#define CLK_CLKSEL2_PWM45_EXT_LXT (0x0UL<<CLK_CLKSEL2_PWM45_S_E_Pos)/*!< Setting PWM45 clock source as external X'tal 32.768KHz,
user must set CLK_CLKSEL1_PWM45_LXT concurrently to complete clock source as external X'tal 32.768KHz setting*/
#define CLK_CLKSEL2_PWM45_EXT_HCLK (0x0UL<<CLK_CLKSEL2_PWM45_S_E_Pos)/*!< Setting PWM45 clock source as HCLK,
user must set CLK_CLKSEL1_PWM45_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL2_PWM45_EXT_HIRC (0x0UL<<CLK_CLKSEL2_PWM45_S_E_Pos)/*!< Setting PWM45 clock source as internal 22.1184MHz RC clock,
user must set CLK_CLKSEL1_PWM45_HIRC concurrently to complete clock source as internal 22.1184MHz RC clock setting*/
#define CLK_CLKSEL2_PWM45_EXT_LIRC (0x1UL<<CLK_CLKSEL2_PWM45_S_E_Pos)/*!< Setting PWM45 clock source as internal 10KHz RC clock,
user must set CLK_CLKSEL1_PWM45_LIRC concurrently to complete clock source as internal 10KHz RC clock setting*/
#define CLK_CLKSEL2_PWM67_EXT_HXT (0x0UL<<CLK_CLKSEL2_PWM67_S_E_Pos)/*!< Setting PWM67 clock source as external X'tal,
user must set CLK_CLKSEL1_PWM67_HXT concurrently to complete clock source as external X'tal setting*/
#define CLK_CLKSEL2_PWM67_EXT_LXT (0x0UL<<CLK_CLKSEL2_PWM67_S_E_Pos)/*!< Setting PWM67 clock source as external X'tal 32.768KHz,
user must set CLK_CLKSEL1_PWM67_LXT concurrently to complete clock source as external X'tal 32.768KHz setting*/
#define CLK_CLKSEL2_PWM67_EXT_HCLK (0x0UL<<CLK_CLKSEL2_PWM67_S_E_Pos)/*!< Setting PWM67 clock source as HCLK,
user must set CLK_CLKSEL1_PWM67_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL2_PWM67_EXT_HIRC (0x0UL<<CLK_CLKSEL2_PWM67_S_E_Pos)/*!< Setting PWM67 clock source as internal 22.1184MHz RC clock,
user must set CLK_CLKSEL1_PWM67_HIRC concurrently to complete clock source as internal 22.1184MHz RC clock setting*/
#define CLK_CLKSEL2_PWM67_EXT_LIRC (0x1UL<<CLK_CLKSEL2_PWM67_S_E_Pos)/*!< Setting PWM67 clock source as internal 10KHz RC clock,
user must set CLK_CLKSEL1_PWM67_LIRC concurrently to complete clock source as internal 10KHz RC clock setting*/
#define CLK_CLKSEL2_WWDT_S_HCLK_DIV2048 (0x2UL<<CLK_CLKSEL2_WWDT_S_Pos) /*!< Setting WWDT clock source as HCLK/2048 */
#define CLK_CLKSEL2_WWDT_S_LIRC (0x3UL<<CLK_CLKSEL2_WWDT_S_Pos) /*!< Setting WWDT clock source as internal 10KHz RC clock */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL3 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL3_SC0_S_HXT (0x0UL<<CLK_CLKSEL3_SC0_S_Pos) /*!< Setting SC0 clock source as external X'tal */
#define CLK_CLKSEL3_SC0_S_PLL (0x1UL<<CLK_CLKSEL3_SC0_S_Pos) /*!< Setting SC0 clock source as PLL */
#define CLK_CLKSEL3_SC0_S_HCLK (0x2UL<<CLK_CLKSEL3_SC0_S_Pos) /*!< Setting SC0 clock source as HCLK */
#define CLK_CLKSEL3_SC0_S_HIRC (0x3UL<<CLK_CLKSEL3_SC0_S_Pos) /*!< Setting SC0 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL3_SC1_S_HXT (0x0UL<<CLK_CLKSEL3_SC1_S_Pos) /*!< Setting SC1 clock source as external X'tal */
#define CLK_CLKSEL3_SC1_S_PLL (0x1UL<<CLK_CLKSEL3_SC1_S_Pos) /*!< Setting SC1 clock source as PLL */
#define CLK_CLKSEL3_SC1_S_HCLK (0x2UL<<CLK_CLKSEL3_SC1_S_Pos) /*!< Setting SC1 clock source as HCLK */
#define CLK_CLKSEL3_SC1_S_HIRC (0x3UL<<CLK_CLKSEL3_SC1_S_Pos) /*!< Setting SC1 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL3_SC2_S_HXT (0x0UL<<CLK_CLKSEL3_SC2_S_Pos) /*!< Setting SC2 clock source as external X'tal */
#define CLK_CLKSEL3_SC2_S_PLL (0x1UL<<CLK_CLKSEL3_SC2_S_Pos) /*!< Setting SC2 clock source as PLL */
#define CLK_CLKSEL3_SC2_S_HCLK (0x2UL<<CLK_CLKSEL3_SC2_S_Pos) /*!< Setting SC2 clock source as HCLK */
#define CLK_CLKSEL3_SC2_S_HIRC (0x3UL<<CLK_CLKSEL3_SC2_S_Pos) /*!< Setting SC2 clock source as internal 22.1184MHz RC clock */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKDIV constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKDIV_HCLK(x) ((x)-1) /*!< CLKDIV Setting for HCLK clock divider. It could be 1~16 */
#define CLK_CLKDIV_USB(x) (((x)-1) << CLK_CLKDIV_USB_N_Pos) /*!< CLKDIV Setting for USB clock divider. It could be 1~16 */
#define CLK_CLKDIV_UART(x) (((x)-1) << CLK_CLKDIV_UART_N_Pos) /*!< CLKDIV Setting for UART clock divider. It could be 1~16 */
#define CLK_CLKDIV_ADC(x) (((x)-1) << CLK_CLKDIV_ADC_N_Pos) /*!< CLKDIV Setting for ADC clock divider. It could be 1~256 */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKDIV1 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKDIV1_SC0(x) (((x)-1) << CLK_CLKDIV1_SC0_N_Pos) /*!< CLKDIV1 Setting for SC0 clock divider. It could be 1~256*/
#define CLK_CLKDIV1_SC1(x) (((x)-1) << CLK_CLKDIV1_SC1_N_Pos) /*!< CLKDIV1 Setting for SC1 clock divider. It could be 1~256*/
#define CLK_CLKDIV1_SC2(x) (((x)-1) << CLK_CLKDIV1_SC2_N_Pos) /*!< CLKDIV1 Setting for SC2 clock divider. It could be 1~256*/
/*---------------------------------------------------------------------------------------------------------*/
/* PLLCON constant definitions. PLL = FIN * NF / NR / NO */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_PLLCON_PLL_SRC_HXT 0x00000000UL /*!< For PLL clock source is HXT. 4MHz < FIN < 24MHz */
#define CLK_PLLCON_PLL_SRC_HIRC 0x00080000UL /*!< For PLL clock source is HIRC.4MHz < FIN < 24MHz */
#define CLK_PLLCON_NR(x) (((x)-2)<<9) /*!< x must be constant and 2 <= x <= 33. 1.6MHz < FIN/NR < 15MHz */
#define CLK_PLLCON_NF(x) ((x)-2) /*!< x must be constant and 2 <= x <= 513. 100MHz < FIN*NF/NR < 200MHz. (120MHz < FIN*NF/NR < 200MHz is preferred.) */
#define CLK_PLLCON_NO_1 0x0000UL /*!< For output divider is 1 */
#define CLK_PLLCON_NO_2 0x4000UL /*!< For output divider is 2 */
#define CLK_PLLCON_NO_4 0xC000UL /*!< For output divider is 4 */
#if (__HXT == 12000000)
#define CLK_PLLCON_FOR_I2S (0xA54) /*!< Predefined PLLCON setting for 147428571.428571Hz PLL output with 12MHz X'tal */
#define CLK_PLLCON_50MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF( 25) | CLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 50MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_48MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(7) | CLK_PLLCON_NF(112) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 48MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_36MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(7) | CLK_PLLCON_NF( 84) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 36MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_32MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(6) | CLK_PLLCON_NF( 64) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 32MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_25MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF( 25) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 25MHz PLL output with 12MHz X'tal */
#else
# error "The PLL pre-definitions are only valid when external crystal is 12MHz"
#endif
#define CLK_PLLCON_50MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR(13) | CLK_PLLCON_NF( 59) | CLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 50.1918MHz PLL output with 22.1184MHz IRC */
#define CLK_PLLCON_48MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR(13) | CLK_PLLCON_NF(113) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 48.064985MHz PLL output with 22.1184MHz IRC*/
#define CLK_PLLCON_36MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR(12) | CLK_PLLCON_NF( 78) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 35.9424MHz PLL output with 22.1184MHz IRC */
#define CLK_PLLCON_32MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR( 9) | CLK_PLLCON_NF( 52) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 31.9488MHz PLL output with 22.1184MHz IRC*/
#define CLK_PLLCON_25MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR(13) | CLK_PLLCON_NF( 59) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 25.0959MHz PLL output with 22.1184MHz IRC*/
/*---------------------------------------------------------------------------------------------------------*/
/* MODULE constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
/* APBCLK(31:30)|CLKSEL(29:28)|CLKSEL_Msk(27:25 |CLKSEL_Pos(24:20)|CLKDIV(19:18)|CLKDIV_Msk(17:10)|CLKDIV_Pos(9:5)|IP_EN_Pos(4:0) */
#define MODULE_APBCLK(x) (((x) >>30) & 0x3) /*!< Calculate APBCLK offset on MODULE index, 0x0:AHBCLK, 0x1:APBCLK, 0x2:APBCLK1 */
#define MODULE_CLKSEL(x) (((x) >>28) & 0x3) /*!< Calculate CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2, 0x3:CLKSEL3 */
#define MODULE_CLKSEL_Msk(x) (((x) >>25) & 0x7) /*!< Calculate CLKSEL mask offset on MODULE index */
#define MODULE_CLKSEL_Pos(x) (((x) >>20) & 0x1f) /*!< Calculate CLKSEL position offset on MODULE index */
#define MODULE_CLKDIV(x) (((x) >>18) & 0x3) /*!< Calculate APBCLK CLKDIV on MODULE index, 0x0:CLKDIV, 0x1:CLKDIV1 */
#define MODULE_CLKDIV_Msk(x) (((x) >>10) & 0xff) /*!< Calculate CLKDIV mask offset on MODULE index */
#define MODULE_CLKDIV_Pos(x) (((x) >>5 ) & 0x1f) /*!< Calculate CLKDIV position offset on MODULE index */
#define MODULE_IP_EN_Pos(x) (((x) >>0 ) & 0x1f) /*!< Calculate APBCLK offset on MODULE index */
#define MODULE_NoMsk 0x0 /*!< Not mask on MODULE index */
#define NA MODULE_NoMsk /*!< Not Available */
#define MODULE_APBCLK_ENC(x) (((x) & 0x03) << 30) /*!< MODULE index, 0x0:AHBCLK, 0x1:APBCLK, 0x2:APBCLK1 */
#define MODULE_CLKSEL_ENC(x) (((x) & 0x03) << 28) /*!< CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2, 0x3:CLKSEL3 */
#define MODULE_CLKSEL_Msk_ENC(x) (((x) & 0x07) << 25) /*!< CLKSEL mask offset on MODULE index */
#define MODULE_CLKSEL_Pos_ENC(x) (((x) & 0x1f) << 20) /*!< CLKSEL position offset on MODULE index */
#define MODULE_CLKDIV_ENC(x) (((x) & 0x03) << 18) /*!< APBCLK CLKDIV on MODULE index, 0x0:CLKDIV, 0x1:CLKDIV1 */
#define MODULE_CLKDIV_Msk_ENC(x) (((x) & 0xff) << 10) /*!< CLKDIV mask offset on MODULE index */
#define MODULE_CLKDIV_Pos_ENC(x) (((x) & 0x1f) << 5) /*!< CLKDIV position offset on MODULE index */
#define MODULE_IP_EN_Pos_ENC(x) (((x) & 0x1f) << 0) /*!< APBCLK offset on MODULE index */
#define PDMA_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_PDMA_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PDMA Module */
#define ISP_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_ISP_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< ISP Module */
#define WDT_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_WDT_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 0)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< WDT Module */
#define TMR0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR0_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC( 8)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR0 Module */
#define TMR1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR1_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(12)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR1 Module */
#define TMR2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR2_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(16)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR2 Module */
#define TMR3_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR3_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(20)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR3 Module */
#define FDIV_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_FDIV_EN_Pos) |\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 2)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< FDIV Module */
#define I2C0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_I2C0_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2C0 Module */
#define I2C1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_I2C1_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2C1 Module */
#define SPI0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_SPI0_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 4)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI0 Module */
#define SPI1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_SPI1_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 5)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI1 Module */
#define SPI2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_SPI2_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 6)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI2 Module */
#define SPI3_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_SPI3_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 7)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI3 Module */
#define UART0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_UART0_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART0 Module */
#define UART1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_UART1_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART1 Module */
#define UART2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_UART2_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART2 Module */
#define PWM01_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PWM01_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(28)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM01 Module */
#define PWM23_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PWM23_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(30)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM23 Module */
#define PWM45_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PWM45_EN_Pos)|\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 4)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM45 Module */
#define PWM67_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PWM67_EN_Pos)|\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 6)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM67 Module */
#define USBD_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_USBD_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC(4)) /*!< USBD Module */
#define ADC_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_ADC_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 2)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0xFF)|MODULE_CLKDIV_Pos_ENC(16)) /*!< ADC Module */
#define I2S_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_I2S_EN_Pos) |\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 0)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2S Module */
#define ACMP_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_ACMP_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< ACMP Module */
#define PS2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PS2_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PS2 Module */
#define SC0_MODULE (MODULE_APBCLK_ENC( 2UL)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_SC0_EN_Pos) |\
MODULE_CLKSEL_ENC( 3)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 0)|\
MODULE_CLKDIV_ENC( 1)|MODULE_CLKDIV_Msk_ENC(0xFF)|MODULE_CLKDIV_Pos_ENC( 0)) /*!< SC0 Module */
#define SC1_MODULE (MODULE_APBCLK_ENC( 2UL)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_SC1_EN_Pos) |\
MODULE_CLKSEL_ENC( 3)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 2)|\
MODULE_CLKDIV_ENC( 1)|MODULE_CLKDIV_Msk_ENC(0xFF)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< SC1 Module */
#define SC2_MODULE (MODULE_APBCLK_ENC( 2UL)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_SC2_EN_Pos) |\
MODULE_CLKSEL_ENC( 3)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 4)|\
MODULE_CLKDIV_ENC( 1)|MODULE_CLKDIV_Msk_ENC(0xFF)|MODULE_CLKDIV_Pos_ENC(16)) /*!< SC2 Module */
#define RTC_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_RTC_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< RTC Module */
#define WWDT_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_WDT_EN_Pos) |\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(16)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< WWDT Module */
#define CLK_CLKSEL_PWM01_HXT (CLK_CLKSEL1_PWM01_S_HXT |CLK_CLKSEL2_PWM01_EXT_HXT) /*!< HXT Clock selection setting for PWM01 */
#define CLK_CLKSEL_PWM01_LXT (CLK_CLKSEL1_PWM01_S_LXT |CLK_CLKSEL2_PWM01_EXT_LXT) /*!< LXT Clock selection setting for PWM01 */
#define CLK_CLKSEL_PWM01_HCLK (CLK_CLKSEL1_PWM01_S_HCLK|CLK_CLKSEL2_PWM01_EXT_HCLK) /*!< HCLK Clock selection setting for PWM01 */
#define CLK_CLKSEL_PWM01_HIRC (CLK_CLKSEL1_PWM01_S_HIRC|CLK_CLKSEL2_PWM01_EXT_HIRC) /*!< HIRC Clock selection setting for PWM01 */
#define CLK_CLKSEL_PWM01_LIRC (CLK_CLKSEL1_PWM01_S_LIRC|CLK_CLKSEL2_PWM01_EXT_LIRC) /*!< LIRC Clock selection setting for PWM01 */
#define CLK_CLKSEL_PWM23_HXT (CLK_CLKSEL1_PWM23_S_HXT |CLK_CLKSEL2_PWM23_EXT_HXT) /*!< HXT Clock selection setting for PWM23 */
#define CLK_CLKSEL_PWM23_LXT (CLK_CLKSEL1_PWM23_S_LXT |CLK_CLKSEL2_PWM23_EXT_LXT) /*!< LXT Clock selection setting for PWM23 */
#define CLK_CLKSEL_PWM23_HCLK (CLK_CLKSEL1_PWM23_S_HCLK|CLK_CLKSEL2_PWM23_EXT_HCLK) /*!< HCLK Clock selection setting for PWM23 */
#define CLK_CLKSEL_PWM23_HIRC (CLK_CLKSEL1_PWM23_S_HIRC|CLK_CLKSEL2_PWM23_EXT_HIRC) /*!< HIRC Clock selection setting for PWM23 */
#define CLK_CLKSEL_PWM23_LIRC (CLK_CLKSEL1_PWM23_S_LIRC|CLK_CLKSEL2_PWM23_EXT_LIRC) /*!< LIRC Clock selection setting for PWM23 */
#define CLK_CLKSEL_PWM45_HXT (CLK_CLKSEL2_PWM45_S_HXT |CLK_CLKSEL2_PWM45_EXT_HXT) /*!< HXT Clock selection setting for PWM45 */
#define CLK_CLKSEL_PWM45_LXT (CLK_CLKSEL2_PWM45_S_LXT |CLK_CLKSEL2_PWM45_EXT_LXT) /*!< LXT Clock selection setting for PWM45 */
#define CLK_CLKSEL_PWM45_HCLK (CLK_CLKSEL2_PWM45_S_HCLK|CLK_CLKSEL2_PWM45_EXT_HCLK) /*!< HCLK Clock selection setting for PWM45 */
#define CLK_CLKSEL_PWM45_HIRC (CLK_CLKSEL2_PWM45_S_HIRC|CLK_CLKSEL2_PWM45_EXT_HIRC) /*!< HIRC Clock selection setting for PWM45 */
#define CLK_CLKSEL_PWM45_LIRC (CLK_CLKSEL2_PWM45_S_LIRC|CLK_CLKSEL2_PWM45_EXT_LIRC) /*!< LIRC Clock selection setting for PWM45 */
#define CLK_CLKSEL_PWM67_HXT (CLK_CLKSEL2_PWM67_S_HXT |CLK_CLKSEL2_PWM67_EXT_HXT) /*!< HXT Clock selection setting for PWM67 */
#define CLK_CLKSEL_PWM67_LXT (CLK_CLKSEL2_PWM67_S_LXT |CLK_CLKSEL2_PWM67_EXT_LXT) /*!< LXT Clock selection setting for PWM67 */
#define CLK_CLKSEL_PWM67_HCLK (CLK_CLKSEL2_PWM67_S_HCLK|CLK_CLKSEL2_PWM67_EXT_HCLK) /*!< HCLK Clock selection setting for PWM67 */
#define CLK_CLKSEL_PWM67_HIRC (CLK_CLKSEL2_PWM67_S_HIRC|CLK_CLKSEL2_PWM67_EXT_HIRC) /*!< HIRC Clock selection setting for PWM67 */
#define CLK_CLKSEL_PWM67_LIRC (CLK_CLKSEL2_PWM67_S_LIRC|CLK_CLKSEL2_PWM67_EXT_LIRC) /*!< LIRC Clock selection setting for PWM67 */
/*@}*/ /* end of group CLK_EXPORTED_CONSTANTS */
/** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions
@{
*/
/**
* @brief Get PLL clock frequency
* @param None
* @return PLL frequency
* @details This function get PLL frequency. The frequency unit is Hz.
*/
__STATIC_INLINE uint32_t CLK_GetPLLClockFreq(void)
{
uint32_t u32PllFreq = 0, u32PllReg;
uint32_t u32FIN, u32NF, u32NR, u32NO;
uint8_t au8NoTbl[4] = {1, 2, 2, 4};
u32PllReg = CLK->PLLCON;
if(u32PllReg & (CLK_PLLCON_PD_Msk | CLK_PLLCON_OE_Msk))
return 0; /* PLL is in power down mode or fix low */
if(u32PllReg & CLK_PLLCON_PLL_SRC_HIRC)
u32FIN = __HIRC; /* PLL source clock from HIRC */
else
u32FIN = __HXT; /* PLL source clock from HXT */
if(u32PllReg & CLK_PLLCON_BP_Msk)
return u32FIN; /* PLL is in bypass mode */
/* PLL is output enabled in normal work mode */
u32NO = au8NoTbl[((u32PllReg & CLK_PLLCON_OUT_DV_Msk) >> CLK_PLLCON_OUT_DV_Pos)];
u32NF = ((u32PllReg & CLK_PLLCON_FB_DV_Msk) >> CLK_PLLCON_FB_DV_Pos) + 2;
u32NR = ((u32PllReg & CLK_PLLCON_IN_DV_Msk) >> CLK_PLLCON_IN_DV_Pos) + 2;
/* u32FIN is shifted 2 bits to avoid overflow */
u32PllFreq = (((u32FIN >> 2) * u32NF) / (u32NR * u32NO) << 2);
return u32PllFreq;
}
/**
* @brief This function execute delay function.
* @param[in] us Delay time. The Max value is 2^24 / CPU Clock(MHz). Ex:
* 50MHz => 335544us, 48MHz => 349525us, 28MHz => 699050us ...
* @return None
* @details Use the SysTick to generate the delay time and the UNIT is in us.
* The SysTick clock source is from HCLK, i.e the same as system core clock.
*/
__STATIC_INLINE void CLK_SysTickDelay(uint32_t us)
{
SysTick->LOAD = us * CyclesPerUs;
SysTick->VAL = (0x00);
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
/* Waiting for down-count to zero */
while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
/* Disable SysTick counter */
SysTick->CTRL = 0;
}
/**
* @brief This function execute long delay function.
* @param[in] us Delay time.
* @return None
* @details Use the SysTick to generate the long delay time and the UNIT is in us.
* The SysTick clock source is from HCLK, i.e the same as system core clock.
* User can use SystemCoreClockUpdate() to calculate CyclesPerUs automatically before using this function.
*/
__STATIC_INLINE void CLK_SysTickLongDelay(uint32_t us)
{
uint32_t delay;
/* It should <= 335544us for each delay loop */
delay = 335544UL;
do
{
if(us > delay)
{
us -= delay;
}
else
{
delay = us;
us = 0UL;
}
SysTick->LOAD = delay * CyclesPerUs;
SysTick->VAL = (0x0UL);
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
/* Waiting for down-count to zero */
while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0UL);
/* Disable SysTick counter */
SysTick->CTRL = 0UL;
}while(us > 0UL);
}
void CLK_DisableCKO(void);
void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En);
void CLK_PowerDown(void);
void CLK_Idle(void);
uint32_t CLK_GetHXTFreq(void);
uint32_t CLK_GetLXTFreq(void);
uint32_t CLK_GetHCLKFreq(void);
uint32_t CLK_GetPCLKFreq(void);
uint32_t CLK_GetCPUFreq(void);
uint32_t CLK_SetCoreClock(uint32_t u32Hclk);
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv);
void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv);
void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc);
void CLK_EnableXtalRC(uint32_t u32ClkMask);
void CLK_DisableXtalRC(uint32_t u32ClkMask);
void CLK_EnableModuleClock(uint32_t u32ModuleIdx);
void CLK_DisableModuleClock(uint32_t u32ModuleIdx);
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq);
void CLK_DisablePLL(void);
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask);
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count);
void CLK_DisableSysTick(void);
/*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CLK_Driver */
/*@}*/ /* end of group Device_Driver */
#endif //__CLK_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

160
BSP/StdDriver/inc/crc.h Normal file
View File

@ -0,0 +1,160 @@
/**************************************************************************//**
* @file crc.h
* @version V3.00
* $Revision: 6 $
* $Date: 15/05/04 3:58p $
* @brief CRC driver header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __CRC_H__
#define __CRC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup CRC_Driver CRC Driver
@{
*/
/** @addtogroup CRC_EXPORTED_CONSTANTS CRC Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* CRC Polynomial Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define CRC_CCITT 0x00000000UL /*!<CRC Polynomial Mode - CCITT */
#define CRC_8 0x40000000UL /*!<CRC Polynomial Mode - CRC8 */
#define CRC_16 0x80000000UL /*!<CRC Polynomial Mode - CRC16 */
#define CRC_32 0xC0000000UL /*!<CRC Polynomial Mode - CRC32 */
/*---------------------------------------------------------------------------------------------------------*/
/* Checksum, Write data Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define CRC_CHECKSUM_COM 0x08000000UL /*!<CRC Checksum Complement */
#define CRC_CHECKSUM_RVS 0x02000000UL /*!<CRC Checksum Reverse */
#define CRC_WDATA_COM 0x04000000UL /*!<CRC Write Data Complement */
#define CRC_WDATA_RVS 0x01000000UL /*!<CRC Write Data Reverse */
/*---------------------------------------------------------------------------------------------------------*/
/* CPU Write Data Length Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define CRC_CPU_WDATA_8 0x00000000UL /*!<CRC 8-bit CPU Write Data */
#define CRC_CPU_WDATA_16 0x10000000UL /*!<CRC 16-bit CPU Write Data */
#define CRC_CPU_WDATA_32 0x20000000UL /*!<CRC 32-bit CPU Write Data */
/*@}*/ /* end of group CRC_EXPORTED_CONSTANTS */
/** @addtogroup CRC_EXPORTED_FUNCTIONS CRC Exported Functions
@{
*/
/**
* @brief Enable CRC Interrupt
*
* @param[in] u32Mask Interrupt mask
*
* @return None
*
* @details This macro enable the specify CRC interrupt function by u32Mask setting.
*/
#define CRC_ENABLE_INT(u32Mask) (CRC->DMAIER |= (u32Mask))
/**
* @brief Disable CRC Interrupt
*
* @param[in] u32Mask Interrupt mask
*
* @return None
*
* @details This macro disable the specify CRC interrupt function by u32Mask setting.
*/
#define CRC_DISABLE_INT(u32Mask) (CRC->DMAIER &= ~(u32Mask))
/**
* @brief Get CRC Interrupt Flag
*
* @param None
*
* @return Interrupt Flag Status
*
* @details This macro gets the CRC interrupt flags.
*/
#define CRC_GET_INT_FLAG() ((uint32_t)(CRC->DMAISR))
/**
* @brief Clear CRC Interrupt Flag
*
* @param[in] u32Mask Interrupt mask
*
* @return None
*
* @details This macro clear the specify CRC interrupt flag by u32Mask setting.
*/
#define CRC_CLR_INT_FLAG(u32Mask) (CRC->DMAISR = (u32Mask))
/**
* @brief Set CRC seed value
*
* @param[in] u32Seed Seed value
*
* @return None
*
* @details This macro set CRC seed value.
*
* @note User must to setting CRC_RST (CRC_CTL[1] CRC Engine Reset) to reload the new seed value
* to CRC controller.
*/
#define CRC_SET_SEED(u32Seed) { CRC->SEED = (u32Seed); CRC->CTL |= CRC_CTL_CRC_RST_Msk; }
/**
* @brief Get CRC Seed value
*
* @param None
*
* @return Seed Value
*
* @details This macro gets the current CRC seed value.
*/
#define CRC_GET_SEED() ((uint32_t)(CRC->SEED))
/**
* @brief CRC write data
*
* @param[in] u32Data write data
*
* @return None
*
* @details User can write data directly by this macro to perform CRC operation.
*/
#define CRC_WRITE_DATA(u32Data) (CRC->WDATA = (u32Data))
/*********************************************************************/
void CRC_Open(uint32_t u32Mode, uint32_t u32Attribute, uint32_t u32Seed, uint32_t u32DataLen);
void CRC_StartDMATransfer(uint32_t u32SrcAddr, uint32_t u32ByteCount);
uint32_t CRC_GetChecksum(void);
/*@}*/ /* end of group CRC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CRC_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__CRC_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

456
BSP/StdDriver/inc/fmc.h Normal file
View File

@ -0,0 +1,456 @@
/**************************************************************************//**
* @file FMC.h
* @version V3.0
* $Revision: 13 $
* $Date: 15/05/19 3:38p $
* @brief Flash Memory Controller Driver Header File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __FMC_H__
#define __FMC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup FMC_Driver FMC Driver
@{
*/
/** @addtogroup FMC_EXPORTED_CONSTANTS FMC Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Define Base Address */
/*---------------------------------------------------------------------------------------------------------*/
#define FMC_APROM_BASE 0x00000000UL /*!< APROM Base Address */
#define FMC_LDROM_BASE 0x00100000UL /*!< LDROM Base Address */
#define FMC_CONFIG_BASE 0x00300000UL /*!< CONFIG Base Address */
#define FMC_FLASH_PAGE_SIZE 0x200 /*!< Flash Page Size (512 Bytes) */
#define FMC_LDROM_SIZE 0x1000 /*!< LDROM Size (4K Bytes) */
/*---------------------------------------------------------------------------------------------------------*/
/* ISPCON constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define FMC_ISPCON_BS_LDROM 0x2 /*!< ISPCON setting to select to boot from LDROM */
#define FMC_ISPCON_BS_APROM 0x0 /*!< ISPCON setting to select to boot from APROM */
/*---------------------------------------------------------------------------------------------------------*/
/* ISPCMD constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define FMC_ISPCMD_READ 0x00 /*!< ISP Command: Read Flash */
#define FMC_ISPCMD_PROGRAM 0x21 /*!< ISP Command: Program Flash */
#define FMC_ISPCMD_PAGE_ERASE 0x22 /*!< ISP Command: Page Erase Flash */
#define FMC_ISPCMD_VECMAP 0x2e /*!< ISP Command: Set VECMAP */
#define FMC_ISPCMD_READ_UID 0x04 /*!< ISP Command: Read Unique ID */
#define FMC_ISPCMD_READ_CID 0x0B /*!< ISP Command: Read Company ID */
#define FMC_ISPCMD_READ_DID 0x0C /*!< ISP Command: Read Device ID */
/*@}*/ /* end of group FMC_EXPORTED_CONSTANTS */
/** @addtogroup FMC_EXPORTED_FUNCTIONS FMC Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* FMC Macro Definitions */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief Enable ISP Function
*
* @param None
*
* @return None
*
* @details This function will set ISPEN bit of ISPCON control register to enable ISP function.
*
*/
#define FMC_ENABLE_ISP() (FMC->ISPCON |= FMC_ISPCON_ISPEN_Msk)
/**
* @brief Disable ISP Function
*
* @param None
*
* @return None
*
* @details This function will clear ISPEN bit of ISPCON control register to disable ISP function.
*
*/
#define FMC_DISABLE_ISP() (FMC->ISPCON &= ~FMC_ISPCON_ISPEN_Msk)
/**
* @brief Enable LDROM Update Function
*
* @param None
*
* @return None
*
* @details This function will set LDUEN bit of ISPCON control register to enable LDROM update function.
* User needs to set LDUEN bit before they can update LDROM.
*
*/
#define FMC_ENABLE_LD_UPDATE() (FMC->ISPCON |= FMC_ISPCON_LDUEN_Msk)
/**
* @brief Disable LDROM Update Function
*
* @param None
*
* @return None
*
* @details This function will set ISPEN bit of ISPCON control register to disable LDROM update function.
*
*/
#define FMC_DISABLE_LD_UPDATE() (FMC->ISPCON &= ~FMC_ISPCON_LDUEN_Msk) /*!< Disable LDROM Update Function */
/**
* @brief Enable User Configuration Update Function
*
* @param None
*
* @return None
*
* @details This function will set CFGUEN bit of ISPCON control register to enable User Configuration update function.
* User needs to set CFGUEN bit before they can update User Configuration area.
*
*/
#define FMC_ENABLE_CFG_UPDATE() (FMC->ISPCON |= FMC_ISPCON_CFGUEN_Msk)
/**
* @brief Disable User Configuration Update Function
*
* @param None
*
* @return None
*
* @details This function will clear CFGUEN bit of ISPCON control register to disable User Configuration update function.
*
*/
#define FMC_DISABLE_CFG_UPDATE() (FMC->ISPCON &= ~FMC_ISPCON_CFGUEN_Msk) /*!< Disable CONFIG Update Function */
/**
* @brief Enable APROM Update Function
*
* @param None
*
* @return None
*
* @details This function will set APUEN bit of ISPCON control register to enable APROM update function.
* User needs to set APUEN bit before they can update APROM in APROM boot mode.
*
*/
#define FMC_ENABLE_AP_UPDATE() (FMC->ISPCON |= FMC_ISPCON_APUEN_Msk)
/**
* @brief Disable APROM Update Function
*
* @param None
*
* @return None
*
* @details This function will clear APUEN bit of ISPCON control register to disable APROM update function.
*
*/
#define FMC_DISABLE_AP_UPDATE() (FMC->ISPCON &= ~FMC_ISPCON_APUEN_Msk) /*!< Disable APROM Update Function */
/**
* @brief Get ISP fail flag
*
* @param None
*
* @retval 0 Previous ISP command execution result is successful
* @retval 1 Previous ISP command execution result is fail
*
* @details ISPFF flag of ISPCON is used to indicate ISP command success or fail.
* This function will return the ISPFF flag to identify ISP command OK or fail.
*
*/
#define FMC_GET_FAIL_FLAG() ((FMC->ISPCON & FMC_ISPCON_ISPFF_Msk) ? 1 : 0)
/**
* @brief Select booting from APROM
*
* @param None
*
* @return None
*
* @details If MCU is working without IAP, user need to set BS bit of ISPCON and reset CPU to execute the code of LDROM/APROM.
* This function is used to set BS bit of ISPCON to boot to APROM.
*
* @note To valid new BS bit setting, user also need to trigger CPU reset or System Reset Request after setting BS bit.
*
*/
#define FMC_SET_APROM_BOOT() (FMC->ISPCON &= ~FMC_ISPCON_BS_Msk)
/**
* @brief Select booting from APROM
*
* @param None
*
* @return None
*
* @details If MCU is working without IAP, user need to set/clear BS bit of ISPCON and reset CPU to execute the code of APROM/LDROM.
* This function is used to clear BS bit of ISPCON to boot to LDROM.
*
* @note To valid new BS bit setting, user also need to trigger CPU reset or System Reset Request after clear BS bit.
*
*/
#define FMC_SET_LDROM_BOOT() (FMC->ISPCON |= FMC_ISPCON_BS_Msk)
/*---------------------------------------------------------------------------------------------------------*/
/* inline functions */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief Program 32-bit data into specified address of flash
*
* @param[in] u32addr Flash address include APROM, LDROM, Data Flash, and CONFIG
* @param[in] u32data 32-bit Data to program
*
* @return None
*
* @details To program word data into Flash include APROM, LDROM, Data Flash, and CONFIG.
* The corresponding functions in CONFIG are listed in FMC section of Technical Reference Manual.
*
*/
static __INLINE void FMC_Write(uint32_t u32addr, uint32_t u32data)
{
FMC->ISPCMD = FMC_ISPCMD_PROGRAM; /* Set ISP Command Code */
FMC->ISPADR = u32addr; /* Set Target ROM Address. The address must be word alignment. */
FMC->ISPDAT = u32data; /* Set Data to Program */
FMC->ISPTRG = 0x1; /* Trigger to start ISP procedure */
__ISB(); /* To make sure ISP/CPU be Synchronized */
while(FMC->ISPTRG); /* Waiting for ISP Done */
}
/**
* @brief Read 32-bit Data from specified address of flash
*
* @param[in] u32addr Flash address include APROM, LDROM, Data Flash, and CONFIG
*
* @return The data of specified address
*
* @details To read word data from Flash include APROM, LDROM, Data Flash, and CONFIG.
*
*/
static __INLINE uint32_t FMC_Read(uint32_t u32addr)
{
FMC->ISPCMD = FMC_ISPCMD_READ; /* Set ISP Command Code */
FMC->ISPADR = u32addr; /* Set Target ROM Address. The address must be word alignment. */
FMC->ISPTRG = 0x1; /* Trigger to start ISP procedure */
__ISB(); /* To make sure ISP/CPU be Synchronized */
while(FMC->ISPTRG); /* Waiting for ISP Done */
return FMC->ISPDAT;
}
/**
* @brief Flash page erase
*
* @param[in] u32addr Flash address including APROM, LDROM, Data Flash, and CONFIG
*
* @details To do flash page erase. The target address could be APROM, LDROM, Data Flash, or CONFIG.
* The page size is 512 bytes.
*
* @retval 0 Success
* @retval -1 Erase failed
*
*/
static __INLINE int32_t FMC_Erase(uint32_t u32addr)
{
FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE; /* Set ISP Command Code */
FMC->ISPADR = u32addr; /* Set Target ROM Address. The address must be page alignment. */
FMC->ISPTRG = 0x1; /* Trigger to start ISP procedure */
__ISB(); /* To make sure ISP/CPU be Synchronized */
while(FMC->ISPTRG); /* Waiting for ISP Done */
/* Check ISPFF flag to know whether erase OK or fail. */
if(FMC->ISPCON & FMC_ISPCON_ISPFF_Msk)
{
FMC->ISPCON |= FMC_ISPCON_ISPFF_Msk;
return -1;
}
return 0;
}
/**
* @brief Read Unique ID
*
* @param[in] u8index UID index. 0 = UID[31:0], 1 = UID[63:32], 2 = UID[95:64]
*
* @return The 32-bit unique ID data of specified UID index.
*
* @details To read out 96-bit Unique ID.
*
*/
static __INLINE uint32_t FMC_ReadUID(uint8_t u8index)
{
FMC->ISPCMD = FMC_ISPCMD_READ_UID; /* Set ISP Command Code */
FMC->ISPADR = (u8index << 2); /* Set UID Address. It must be word alignment. */
FMC->ISPTRG = 0x1; /* Trigger to start ISP procedure */
__ISB(); /* To make sure ISP/CPU be Synchronized */
while(FMC->ISPTRG); /* Waiting for ISP Done */
return FMC->ISPDAT;
}
/**
* @brief Read company ID
*
* @param None
*
* @return The company ID (32-bit)
*
* @details The company ID of Nuvoton is fixed to be 0xDA
*
*/
static __INLINE uint32_t FMC_ReadCID(void)
{
FMC->ISPCMD = FMC_ISPCMD_READ_CID; /* Set ISP Command Code */
FMC->ISPADR = 0x0; /* Must keep 0x0 when read CID */
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
__ISB(); /* To make sure ISP/CPU be Synchronized */
while(FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ; /* Waiting for ISP Done */
return FMC->ISPDAT;
}
/**
* @brief Read product ID
*
* @param None
*
* @return The product ID (32-bit)
*
* @details This function is used to read product ID.
*
*/
static __INLINE uint32_t FMC_ReadPID(void)
{
FMC->ISPCMD = FMC_ISPCMD_READ_DID; /* Set ISP Command Code */
FMC->ISPADR = 0x04; /* Must keep 0x4 when read PID */
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
__ISB(); /* To make sure ISP/CPU be Synchronized */
while(FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk); /* Waiting for ISP Done */
return FMC->ISPDAT;
}
/**
* @brief To read UCID
*
* @param[in] u32Index Index of the UCID to read. u32Index must be 0, 1, 2, or 3.
*
* @return The UCID of specified index
*
* @details This function is used to read unique chip ID (UCID).
*
*/
static __INLINE uint32_t FMC_ReadUCID(uint32_t u32Index)
{
FMC->ISPCMD = FMC_ISPCMD_READ_UID; /* Set ISP Command Code */
FMC->ISPADR = (0x04 * u32Index) + 0x10; /* The UCID is at offset 0x10 with word alignment. */
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
__ISB(); /* To make sure ISP/CPU be Synchronized */
while(FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk); /* Waiting for ISP Done */
return FMC->ISPDAT;
}
/**
* @brief Set vector mapping address
*
* @param[in] u32PageAddr The page address to remap to address 0x0. The address must be page alignment.
*
* @return None
*
* @details This function is used to set VECMAP to map specified page to vector page (0x0).
*
* @note
* VECMAP only valid when new IAP function is enabled. (CBS = 10'b or 00'b)
*
*/
static __INLINE void FMC_SetVectorPageAddr(uint32_t u32PageAddr)
{
FMC->ISPCMD = FMC_ISPCMD_VECMAP; /* Set ISP Command Code */
FMC->ISPADR = u32PageAddr; /* The address of specified page which will be map to address 0x0. It must be page alignment. */
FMC->ISPTRG = 0x1; /* Trigger to start ISP procedure */
__ISB(); /* To make sure ISP/CPU be Synchronized */
while(FMC->ISPTRG); /* Waiting for ISP Done */
}
/**
* @brief Get current vector mapping address.
*
* @param None
*
* @return The current vector mapping address.
*
* @details To get VECMAP value which is the page address for remapping to vector page (0x0).
*
* @note
* VECMAP only valid when new IAP function is enabled. (CBS = 10'b or 00'b)
*
*/
static __INLINE uint32_t FMC_GetVECMAP(void)
{
return (FMC->ISPSTA & FMC_ISPSTA_VECMAP_Msk);
}
extern void FMC_Open(void);
extern void FMC_Close(void);
extern void FMC_EnableAPUpdate(void);
extern void FMC_DisableAPUpdate(void);
extern void FMC_EnableConfigUpdate(void);
extern void FMC_DisableConfigUpdate(void);
extern void FMC_EnableLDUpdate(void);
extern void FMC_DisableLDUpdate(void);
extern int32_t FMC_ReadConfig(uint32_t *u32Config, uint32_t u32Count);
extern int32_t FMC_WriteConfig(uint32_t *u32Config, uint32_t u32Count);
extern void FMC_SetBootSource(int32_t i32BootSrc);
extern int32_t FMC_GetBootSource(void);
extern uint32_t FMC_ReadDataFlashBaseAddr(void);
/*@}*/ /* end of group FMC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group FMC_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif

441
BSP/StdDriver/inc/gpio.h Normal file
View File

@ -0,0 +1,441 @@
/**************************************************************************//**
* @file GPIO.h
* @version V3.00
* $Revision: 14 $
* $Date: 15/05/04 3:58p $
* @brief General Purpose I/O Driver Header File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __GPIO_H__
#define __GPIO_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup GPIO_Driver GPIO Driver
@{
*/
/** @addtogroup GPIO_EXPORTED_CONSTANTS GPIO Exported Constants
@{
*/
#define GPIO_PIN_MAX 16 /*!< Specify Maximum Pins of Each GPIO Port */
/*---------------------------------------------------------------------------------------------------------*/
/* PMD Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_PMD_INPUT 0x0UL /*!< Input Mode */
#define GPIO_PMD_OUTPUT 0x1UL /*!< Output Mode */
#define GPIO_PMD_OPEN_DRAIN 0x2UL /*!< Open-Drain Mode */
#define GPIO_PMD_QUASI 0x3UL /*!< Quasi-bidirectional Mode */
/*---------------------------------------------------------------------------------------------------------*/
/* GPIO Interrupt Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_INT_RISING 0x00010000UL /*!< Interrupt enable by Input Rising Edge */
#define GPIO_INT_FALLING 0x00000001UL /*!< Interrupt enable by Input Falling Edge */
#define GPIO_INT_BOTH_EDGE 0x00010001UL /*!< Interrupt enable by both Rising Edge and Falling Edge */
#define GPIO_INT_HIGH 0x01010000UL /*!< Interrupt enable by Level-High */
#define GPIO_INT_LOW 0x01000001UL /*!< Interrupt enable by Level-Level */
/*---------------------------------------------------------------------------------------------------------*/
/* IMD Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_IMD_EDGE 0UL /*!< IMD Setting for Edge Trigger Mode */
#define GPIO_IMD_LEVEL 1UL /*!< IMD Setting for Edge Level Mode */
/*---------------------------------------------------------------------------------------------------------*/
/* DBNCECON Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_INT_CLK_ON 0x00000020UL /*!< DBNCECON setting for all IO pins edge detection circuit is always active after reset */
#define GPIO_INT_CLK_OFF 0x00000000UL /*!< DBNCECON setting for edge detection circuit is active only if IO pin corresponding GPIOx_IEN bit is set to 1 */
#define GPIO_DBCLKSRC_LIRC 0x00000010UL /*!< DBNCECON setting for de-bounce counter clock source is the internal 10 kHz */
#define GPIO_DBCLKSRC_HCLK 0x00000000UL /*!< DBNCECON setting for de-bounce counter clock source is the HCLK */
#define GPIO_DBCLKSEL_1 0x00000000UL /*!< DBNCECON setting for sampling cycle = 1 clocks */
#define GPIO_DBCLKSEL_2 0x00000001UL /*!< DBNCECON setting for sampling cycle = 2 clocks */
#define GPIO_DBCLKSEL_4 0x00000002UL /*!< DBNCECON setting for sampling cycle = 4 clocks */
#define GPIO_DBCLKSEL_8 0x00000003UL /*!< DBNCECON setting for sampling cycle = 8 clocks */
#define GPIO_DBCLKSEL_16 0x00000004UL /*!< DBNCECON setting for sampling cycle = 16 clocks */
#define GPIO_DBCLKSEL_32 0x00000005UL /*!< DBNCECON setting for sampling cycle = 32 clocks */
#define GPIO_DBCLKSEL_64 0x00000006UL /*!< DBNCECON setting for sampling cycle = 64 clocks */
#define GPIO_DBCLKSEL_128 0x00000007UL /*!< DBNCECON setting for sampling cycle = 128 clocks */
#define GPIO_DBCLKSEL_256 0x00000008UL /*!< DBNCECON setting for sampling cycle = 256 clocks */
#define GPIO_DBCLKSEL_512 0x00000009UL /*!< DBNCECON setting for sampling cycle = 512 clocks */
#define GPIO_DBCLKSEL_1024 0x0000000AUL /*!< DBNCECON setting for sampling cycle = 1024 clocks */
#define GPIO_DBCLKSEL_2048 0x0000000BUL /*!< DBNCECON setting for sampling cycle = 2048 clocks */
#define GPIO_DBCLKSEL_4096 0x0000000CUL /*!< DBNCECON setting for sampling cycle = 4096 clocks */
#define GPIO_DBCLKSEL_8192 0x0000000DUL /*!< DBNCECON setting for sampling cycle = 8192 clocks */
#define GPIO_DBCLKSEL_16384 0x0000000EUL /*!< DBNCECON setting for sampling cycle = 16384 clocks */
#define GPIO_DBCLKSEL_32768 0x0000000FUL /*!< DBNCECON setting for sampling cycle = 32768 clocks */
/* Define GPIO Pin Data Input/Output. It could be used to control each I/O pin by pin address mapping.
Example 1:
PA0 = 1;
It is used to set GPIO PA.0 to high;
Example 2:
if (PA0)
PA0 = 0;
If GPIO PA.0 pin status is high, then set GPIO PA.0 data output to low.
*/
#define GPIO_PIN_DATA(port, pin) (*((volatile uint32_t *)((GPIO_PIN_DATA_BASE+(0x40*(port))) + ((pin)<<2))))
#define PA0 GPIO_PIN_DATA(0, 0 ) /*!< Specify PA.0 Pin Data Input/Output */
#define PA1 GPIO_PIN_DATA(0, 1 ) /*!< Specify PA.1 Pin Data Input/Output */
#define PA2 GPIO_PIN_DATA(0, 2 ) /*!< Specify PA.2 Pin Data Input/Output */
#define PA3 GPIO_PIN_DATA(0, 3 ) /*!< Specify PA.3 Pin Data Input/Output */
#define PA4 GPIO_PIN_DATA(0, 4 ) /*!< Specify PA.4 Pin Data Input/Output */
#define PA5 GPIO_PIN_DATA(0, 5 ) /*!< Specify PA.5 Pin Data Input/Output */
#define PA6 GPIO_PIN_DATA(0, 6 ) /*!< Specify PA.6 Pin Data Input/Output */
#define PA7 GPIO_PIN_DATA(0, 7 ) /*!< Specify PA.7 Pin Data Input/Output */
#define PA8 GPIO_PIN_DATA(0, 8 ) /*!< Specify PA.8 Pin Data Input/Output */
#define PA9 GPIO_PIN_DATA(0, 9 ) /*!< Specify PA.9 Pin Data Input/Output */
#define PA10 GPIO_PIN_DATA(0, 10) /*!< Specify PA.10 Pin Data Input/Output */
#define PA11 GPIO_PIN_DATA(0, 11) /*!< Specify PA.11 Pin Data Input/Output */
#define PA12 GPIO_PIN_DATA(0, 12) /*!< Specify PA.12 Pin Data Input/Output */
#define PA13 GPIO_PIN_DATA(0, 13) /*!< Specify PA.13 Pin Data Input/Output */
#define PA14 GPIO_PIN_DATA(0, 14) /*!< Specify PA.14 Pin Data Input/Output */
#define PA15 GPIO_PIN_DATA(0, 15) /*!< Specify PA.15 Pin Data Input/Output */
#define PB0 GPIO_PIN_DATA(1, 0 ) /*!< Specify PB.0 Pin Data Input/Output */
#define PB1 GPIO_PIN_DATA(1, 1 ) /*!< Specify PB.1 Pin Data Input/Output */
#define PB2 GPIO_PIN_DATA(1, 2 ) /*!< Specify PB.2 Pin Data Input/Output */
#define PB3 GPIO_PIN_DATA(1, 3 ) /*!< Specify PB.3 Pin Data Input/Output */
#define PB4 GPIO_PIN_DATA(1, 4 ) /*!< Specify PB.4 Pin Data Input/Output */
#define PB5 GPIO_PIN_DATA(1, 5 ) /*!< Specify PB.5 Pin Data Input/Output */
#define PB6 GPIO_PIN_DATA(1, 6 ) /*!< Specify PB.6 Pin Data Input/Output */
#define PB7 GPIO_PIN_DATA(1, 7 ) /*!< Specify PB.7 Pin Data Input/Output */
#define PB8 GPIO_PIN_DATA(1, 8 ) /*!< Specify PB.8 Pin Data Input/Output */
#define PB9 GPIO_PIN_DATA(1, 9 ) /*!< Specify PB.9 Pin Data Input/Output */
#define PB10 GPIO_PIN_DATA(1, 10) /*!< Specify PB.10 Pin Data Input/Output */
#define PB11 GPIO_PIN_DATA(1, 11) /*!< Specify PB.11 Pin Data Input/Output */
#define PB12 GPIO_PIN_DATA(1, 12) /*!< Specify PB.12 Pin Data Input/Output */
#define PB13 GPIO_PIN_DATA(1, 13) /*!< Specify PB.13 Pin Data Input/Output */
#define PB14 GPIO_PIN_DATA(1, 14) /*!< Specify PB.14 Pin Data Input/Output */
#define PB15 GPIO_PIN_DATA(1, 15) /*!< Specify PB.15 Pin Data Input/Output */
#define PC0 GPIO_PIN_DATA(2, 0 ) /*!< Specify PC.0 Pin Data Input/Output */
#define PC1 GPIO_PIN_DATA(2, 1 ) /*!< Specify PC.1 Pin Data Input/Output */
#define PC2 GPIO_PIN_DATA(2, 2 ) /*!< Specify PC.2 Pin Data Input/Output */
#define PC3 GPIO_PIN_DATA(2, 3 ) /*!< Specify PC.3 Pin Data Input/Output */
#define PC4 GPIO_PIN_DATA(2, 4 ) /*!< Specify PC.4 Pin Data Input/Output */
#define PC5 GPIO_PIN_DATA(2, 5 ) /*!< Specify PC.5 Pin Data Input/Output */
#define PC6 GPIO_PIN_DATA(2, 6 ) /*!< Specify PC.6 Pin Data Input/Output */
#define PC7 GPIO_PIN_DATA(2, 7 ) /*!< Specify PC.7 Pin Data Input/Output */
#define PC8 GPIO_PIN_DATA(2, 8 ) /*!< Specify PC.8 Pin Data Input/Output */
#define PC9 GPIO_PIN_DATA(2, 9 ) /*!< Specify PC.9 Pin Data Input/Output */
#define PC10 GPIO_PIN_DATA(2, 10) /*!< Specify PC.10 Pin Data Input/Output */
#define PC11 GPIO_PIN_DATA(2, 11) /*!< Specify PC.11 Pin Data Input/Output */
#define PC12 GPIO_PIN_DATA(2, 12) /*!< Specify PC.12 Pin Data Input/Output */
#define PC13 GPIO_PIN_DATA(2, 13) /*!< Specify PC.13 Pin Data Input/Output */
#define PC14 GPIO_PIN_DATA(2, 14) /*!< Specify PC.14 Pin Data Input/Output */
#define PC15 GPIO_PIN_DATA(2, 15) /*!< Specify PC.15 Pin Data Input/Output */
#define PD0 GPIO_PIN_DATA(3, 0 ) /*!< Specify PD.0 Pin Data Input/Output */
#define PD1 GPIO_PIN_DATA(3, 1 ) /*!< Specify PD.1 Pin Data Input/Output */
#define PD2 GPIO_PIN_DATA(3, 2 ) /*!< Specify PD.2 Pin Data Input/Output */
#define PD3 GPIO_PIN_DATA(3, 3 ) /*!< Specify PD.3 Pin Data Input/Output */
#define PD4 GPIO_PIN_DATA(3, 4 ) /*!< Specify PD.4 Pin Data Input/Output */
#define PD5 GPIO_PIN_DATA(3, 5 ) /*!< Specify PD.5 Pin Data Input/Output */
#define PD6 GPIO_PIN_DATA(3, 6 ) /*!< Specify PD.6 Pin Data Input/Output */
#define PD7 GPIO_PIN_DATA(3, 7 ) /*!< Specify PD.7 Pin Data Input/Output */
#define PD8 GPIO_PIN_DATA(3, 8 ) /*!< Specify PD.8 Pin Data Input/Output */
#define PD9 GPIO_PIN_DATA(3, 9 ) /*!< Specify PD.9 Pin Data Input/Output */
#define PD10 GPIO_PIN_DATA(3, 10) /*!< Specify PD.10 Pin Data Input/Output */
#define PD11 GPIO_PIN_DATA(3, 11) /*!< Specify PD.11 Pin Data Input/Output */
#define PD12 GPIO_PIN_DATA(3, 12) /*!< Specify PD.12 Pin Data Input/Output */
#define PD13 GPIO_PIN_DATA(3, 13) /*!< Specify PD.13 Pin Data Input/Output */
#define PD14 GPIO_PIN_DATA(3, 14) /*!< Specify PD.14 Pin Data Input/Output */
#define PD15 GPIO_PIN_DATA(3, 15) /*!< Specify PD.15 Pin Data Input/Output */
#define PE0 GPIO_PIN_DATA(4, 0 ) /*!< Specify PE.0 Pin Data Input/Output */
#define PE1 GPIO_PIN_DATA(4, 1 ) /*!< Specify PE.1 Pin Data Input/Output */
#define PE2 GPIO_PIN_DATA(4, 2 ) /*!< Specify PE.2 Pin Data Input/Output */
#define PE3 GPIO_PIN_DATA(4, 3 ) /*!< Specify PE.3 Pin Data Input/Output */
#define PE4 GPIO_PIN_DATA(4, 4 ) /*!< Specify PE.4 Pin Data Input/Output */
#define PE5 GPIO_PIN_DATA(4, 5 ) /*!< Specify PE.5 Pin Data Input/Output */
#define PE6 GPIO_PIN_DATA(4, 6 ) /*!< Specify PE.6 Pin Data Input/Output */
#define PE7 GPIO_PIN_DATA(4, 7 ) /*!< Specify PE.7 Pin Data Input/Output */
#define PE8 GPIO_PIN_DATA(4, 8 ) /*!< Specify PE.8 Pin Data Input/Output */
#define PE9 GPIO_PIN_DATA(4, 9 ) /*!< Specify PE.9 Pin Data Input/Output */
#define PE10 GPIO_PIN_DATA(4, 10) /*!< Specify PE.10 Pin Data Input/Output */
#define PE11 GPIO_PIN_DATA(4, 11) /*!< Specify PE.11 Pin Data Input/Output */
#define PE12 GPIO_PIN_DATA(4, 12) /*!< Specify PE.12 Pin Data Input/Output */
#define PE13 GPIO_PIN_DATA(4, 13) /*!< Specify PE.13 Pin Data Input/Output */
#define PE14 GPIO_PIN_DATA(4, 14) /*!< Specify PE.14 Pin Data Input/Output */
#define PE15 GPIO_PIN_DATA(4, 15) /*!< Specify PE.15 Pin Data Input/Output */
#define PF0 GPIO_PIN_DATA(5, 0 ) /*!< Specify PF.0 Pin Data Input/Output */
#define PF1 GPIO_PIN_DATA(5, 1 ) /*!< Specify PF.1 Pin Data Input/Output */
#define PF2 GPIO_PIN_DATA(5, 2 ) /*!< Specify PF.2 Pin Data Input/Output */
#define PF3 GPIO_PIN_DATA(5, 3 ) /*!< Specify PF.3 Pin Data Input/Output */
/*@}*/ /* end of group GPIO_EXPORTED_CONSTANTS */
/** @addtogroup GPIO_EXPORTED_FUNCTIONS GPIO Exported Functions
@{
*/
/**
* @brief Clear GPIO Pin Interrupt Flag
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port.
* It could be BIT0 ~ BIT15 for PA, PB, PC, PD and PE GPIO port.
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Clear the interrupt status of specified GPIO pin.
*/
#define GPIO_CLR_INT_FLAG(port, u32PinMask) ((port)->ISRC = (u32PinMask))
/**
* @brief Disable Pin De-bounce Function
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port.
* It could be BIT0 ~ BIT15 for PA, PB, PC, PD and PE GPIO port.
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Disable the interrupt de-bounce function of specified GPIO pin.
*/
#define GPIO_DISABLE_DEBOUNCE(port, u32PinMask) ((port)->DBEN &= ~(u32PinMask))
/**
* @brief Enable Pin De-bounce Function
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port.
* It could be BIT0 ~ BIT15 for PA, PB, PC, PD and PE GPIO port.
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Enable the interrupt de-bounce function of specified GPIO pin.
*/
#define GPIO_ENABLE_DEBOUNCE(port, u32PinMask) ((port)->DBEN |= (u32PinMask))
/**
* @brief Disable I/O Digital Input Path
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port.
* It could be BIT0 ~ BIT15 for PA, PB, PC, PD and PE GPIO port.
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Disable I/O digital input path of specified GPIO pin.
*/
#define GPIO_DISABLE_DIGITAL_PATH(port, u32PinMask) ((port)->OFFD |= ((u32PinMask)<<16))
/**
* @brief Enable I/O Digital Input Path
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port.
* It could be BIT0 ~ BIT15 for PA, PB, PC, PD and PE GPIO port.
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Enable I/O digital input path of specified GPIO pin.
*/
#define GPIO_ENABLE_DIGITAL_PATH(port, u32PinMask) ((port)->OFFD &= ~((u32PinMask)<<16))
/**
* @brief Disable I/O DOUT mask
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port.
* It could be BIT0 ~ BIT15 for PA, PB, PC, PD and PE GPIO port.
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Disable I/O DOUT mask of specified GPIO pin.
*/
#define GPIO_DISABLE_DOUT_MASK(port, u32PinMask) ((port)->DMASK &= ~(u32PinMask))
/**
* @brief Enable I/O DOUT mask
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port.
* It could be BIT0 ~ BIT15 for PA, PB, PC, PD and PE GPIO port.
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Enable I/O DOUT mask of specified GPIO pin.
*/
#define GPIO_ENABLE_DOUT_MASK(port, u32PinMask) ((port)->DMASK |= (u32PinMask))
/**
* @brief Get GPIO Pin Interrupt Flag
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port.
* It could be BIT0 ~ BIT15 for PA, PB, PC, PD and PE GPIO port.
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @retval 0 No interrupt at specified GPIO pin
* @retval 1 The specified GPIO pin generate an interrupt
*
* @details Get the interrupt status of specified GPIO pin.
*/
#define GPIO_GET_INT_FLAG(port, u32PinMask) ((port)->ISRC & (u32PinMask))
/**
* @brief Set De-bounce Sampling Cycle Time
*
* @param[in] u32ClkSrc The de-bounce counter clock source. It could be GPIO_DBCLKSRC_HCLK or GPIO_DBCLKSRC_LIRC.
* @param[in] u32ClkSel The de-bounce sampling cycle selection. It could be \n
* GPIO_DBCLKSEL_1, GPIO_DBCLKSEL_2, GPIO_DBCLKSEL_4, GPIO_DBCLKSEL_8, \n
* GPIO_DBCLKSEL_16, GPIO_DBCLKSEL_32, GPIO_DBCLKSEL_64, GPIO_DBCLKSEL_128, \n
* GPIO_DBCLKSEL_256, GPIO_DBCLKSEL_512, GPIO_DBCLKSEL_1024, GPIO_DBCLKSEL_2048, \n
* GPIO_DBCLKSEL_4096, GPIO_DBCLKSEL_8192, GPIO_DBCLKSEL_16384, GPIO_DBCLKSEL_32768.
*
* @return None
*
* @details Set the interrupt de-bounce sampling cycle time based on the debounce counter clock source. \n
* Example: _GPIO_SET_DEBOUNCE_TIME(GPIO_DBCLKSRC_LIRC, GPIO_DBCLKSEL_4). \n
* It's meaning the De-debounce counter clock source is internal 10 KHz and sampling cycle selection is 4. \n
* Then the target de-bounce sampling cycle time is (4)*(1/(10*1000)) s = 4*0.0001 s = 400 us,
* and system will sampling interrupt input once per 400 us.
*/
#define GPIO_SET_DEBOUNCE_TIME(u32ClkSrc, u32ClkSel) (GPIO->DBNCECON = (GPIO_DBNCECON_ICLK_ON_Msk | (u32ClkSrc) | (u32ClkSel)))
/**
* @brief Get GPIO Port IN Data
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
*
* @return The specified port data
*
* @details Get the PIN register of specified GPIO port.
*/
#define GPIO_GET_IN_DATA(port) ((port)->PIN)
/**
* @brief Set GPIO Port OUT Data
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32Data GPIO port data.
*
* @return None
*
* @details Set the Data into specified GPIO port.
*/
#define GPIO_SET_OUT_DATA(port, u32Data) ((port)->DOUT = (u32Data))
/**
* @brief Toggle Specified GPIO pin
*
* @param[in] u32Pin Pxy
*
* @return None
*
* @details Toggle the specified GPIO pint.
*/
#define GPIO_TOGGLE(u32Pin) ((u32Pin) ^= 1)
/**
* @brief Enable External GPIO Interrupt 0
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32Pin The pin of specified GPIO port.
* It could be 0 ~ 15 for PA, PB, PC, PD and PE GPIO port.
* It could be 0 ~ 3 for PF GPIO port.
* @param[in] u32IntAttribs The interrupt attribute of specified GPIO pin. It could be \n
* GPIO_INT_RISING, GPIO_INT_FALLING, GPIO_INT_BOTH_EDGE, GPIO_INT_HIGH, GPIO_INT_LOW.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
#define GPIO_EnableEINT0 GPIO_EnableInt
/**
* @brief Disable External GPIO Interrupt 0
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32Pin The pin of specified GPIO port.
* It could be 0 ~ 15 for PA, PB, PC, PD and PE GPIO port.
* It could be 0 ~ 3 for PF GPIO port.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
#define GPIO_DisableEINT0 GPIO_DisableInt
/**
* @brief Enable External GPIO Interrupt 1
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32Pin The pin of specified GPIO port.
* It could be 0 ~ 15 for PA, PB, PC, PD and PE GPIO port.
* It could be 0 ~ 3 for PF GPIO port.
* @param[in] u32IntAttribs The interrupt attribute of specified GPIO pin. It could be \n
* GPIO_INT_RISING, GPIO_INT_FALLING, GPIO_INT_BOTH_EDGE, GPIO_INT_HIGH, GPIO_INT_LOW.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
#define GPIO_EnableEINT1 GPIO_EnableInt
/**
* @brief Disable External GPIO Interrupt 1
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32Pin The pin of specified GPIO port.
* It could be 0 ~ 15 for PA, PB, PC, PD and PE GPIO port.
* It could be 0 ~ 3 for PF GPIO port.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
#define GPIO_DisableEINT1 GPIO_DisableInt
void GPIO_SetMode(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode);
void GPIO_EnableInt(GPIO_T *port, uint32_t u32Pin, uint32_t u32IntAttribs);
void GPIO_DisableInt(GPIO_T *port, uint32_t u32Pin);
/*@}*/ /* end of group GPIO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group GPIO_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__GPIO_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

206
BSP/StdDriver/inc/i2c.h Normal file
View File

@ -0,0 +1,206 @@
/**************************************************************************//**
* @file i2c.h
* @version V3.0
* $Revision: 16 $
* $Date: 15/05/22 11:23a $
* @brief I2C Driver Header File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __I2C_H__
#define __I2C_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup I2C_Driver I2C Driver
@{
*/
/** @addtogroup I2C_EXPORTED_CONSTANTS I2C Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* I2CON constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define I2C_I2CON_STA_SI 0x28UL /*!< I2CON setting for I2C control bits. It would set STA and SI bits */
#define I2C_I2CON_STA_SI_AA 0x2CUL /*!< I2CON setting for I2C control bits. It would set STA, SI and AA bits */
#define I2C_I2CON_STO_SI 0x18UL /*!< I2CON setting for I2C control bits. It would set STO and SI bits */
#define I2C_I2CON_STO_SI_AA 0x1CUL /*!< I2CON setting for I2C control bits. It would set STO, SI and AA bits */
#define I2C_I2CON_SI 0x08UL /*!< I2CON setting for I2C control bits. It would set SI bit */
#define I2C_I2CON_SI_AA 0x0CUL /*!< I2CON setting for I2C control bits. It would set SI and AA bits */
#define I2C_I2CON_STA 0x20UL /*!< I2CON setting for I2C control bits. It would set STA bit */
#define I2C_I2CON_STO 0x10UL /*!< I2CON setting for I2C control bits. It would set STO bit */
#define I2C_I2CON_AA 0x04UL /*!< I2CON setting for I2C control bits. It would set AA bit */
#define I2C_GCMODE_ENABLE 1 /*!< Enable I2C GC Mode */
#define I2C_GCMODE_DISABLE 0 /*!< Disable I2C GC Mode */
/*@}*/ /* end of group I2C_EXPORTED_CONSTANTS */
/** @addtogroup I2C_EXPORTED_FUNCTIONS I2C Exported Functions
@{
*/
/**
* @brief The macro is used to set I2C bus condition at One Time
*
* @param[in] i2c Specify I2C port
* @param[in] u8Ctrl A byte writes to I2C control register
*
* @return None
*
* @details Set I2CON register to control I2C bus conditions of START, STOP, SI, ACK.
*/
#define I2C_SET_CONTROL_REG(i2c, u8Ctrl) ((i2c)->I2CON = ((i2c)->I2CON & ~0x3c) | (u8Ctrl))
/**
* @brief The macro is used to set START condition of I2C Bus
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details Set the I2C bus START condition in I2CON register.
*/
#define I2C_START(i2c) ((i2c)->I2CON = ((i2c)->I2CON & ~I2C_I2CON_SI_Msk) | I2C_I2CON_STA_Msk)
/**
* @brief The macro is used to wait I2C bus status get ready
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details When a new status is presented of I2C bus, the SI flag will be set in I2CON register.
*/
#define I2C_WAIT_READY(i2c) while(!((i2c)->I2CON & I2C_I2CON_SI_Msk))
/**
* @brief The macro is used to Read I2C Bus Data Register
*
* @param[in] i2c Specify I2C port
*
* @return A byte of I2C data register
*
* @details I2C controller read data from bus and save it in I2CDAT register.
*/
#define I2C_GET_DATA(i2c) ((i2c)->I2CDAT)
/**
* @brief Write a Data to I2C Data Register
*
* @param[in] i2c Specify I2C port
* @param[in] u8Data A byte that writes to data register
*
* @return None
*
* @details When write a data to I2CDAT register, the I2C controller will shift it to I2C bus.
*/
#define I2C_SET_DATA(i2c, u8Data) ((i2c)->I2CDAT = (u8Data))
/**
* @brief Get I2C Bus status code
*
* @param[in] i2c Specify I2C port
*
* @return I2C status code
*
* @details To get this status code to monitor I2C bus event.
*/
#define I2C_GET_STATUS(i2c) ((i2c)->I2CSTATUS)
/**
* @brief Get Time-out flag from I2C Bus
*
* @param[in] i2c Specify I2C port
*
* @retval 0 I2C Bus time-out is not happened
* @retval 1 I2C Bus time-out is happened
*
* @details When I2C bus occurs time-out event, the time-out flag will be set.
*/
#define I2C_GET_TIMEOUT_FLAG(i2c) ( ((i2c)->I2CTOC & I2C_I2CTOC_TIF_Msk) == I2C_I2CTOC_TIF_Msk ? 1:0 )
/**
* @brief To get wake-up flag from I2C Bus
*
* @param[in] i2c Specify I2C port
*
* @retval 0 Chip is not woken-up from power-down mode
* @retval 1 Chip is woken-up from power-down mode
*
* @details I2C bus occurs wake-up event, wake-up flag will be set.
*/
#define I2C_GET_WAKEUP_FLAG(i2c) ( ((i2c)->I2CWKUPSTS & I2C_I2CWKUPSTS_WKUPIF_Msk) == I2C_I2CWKUPSTS_WKUPIF_Msk ? 1:0 )
/**
* @brief To clear wake-up flag
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details If wake-up flag is set, use this macro to clear it.
*/
#define I2C_CLEAR_WAKEUP_FLAG(i2c) ((i2c)->I2CWKUPSTS |= I2C_I2CWKUPSTS_WKUPIF_Msk)
/*---------------------------------------------------------------------------------------------------------*/
/* inline functions */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief The macro is used to set STOP condition of I2C Bus
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details Set the I2C bus STOP condition in I2CON register and wait STOP condition finish.
*/
static __INLINE void I2C_STOP(I2C_T *i2c)
{
(i2c)->I2CON |= (I2C_I2CON_SI_Msk | I2C_I2CON_STO_Msk);
while((i2c)->I2CON & I2C_I2CON_STO_Msk);
}
void I2C_ClearTimeoutFlag(I2C_T *i2c);
void I2C_Close(I2C_T *i2c);
void I2C_Trigger(I2C_T *i2c, uint8_t u8Start, uint8_t u8Stop, uint8_t u8Si, uint8_t u8Ack);
void I2C_DisableInt(I2C_T *i2c);
void I2C_EnableInt(I2C_T *i2c);
uint32_t I2C_GetBusClockFreq(I2C_T *i2c);
uint32_t I2C_SetBusClockFreq(I2C_T *i2c, uint32_t u32BusClock);
uint32_t I2C_GetIntFlag(I2C_T *i2c);
uint32_t I2C_GetStatus(I2C_T *i2c);
uint32_t I2C_Open(I2C_T *i2c, uint32_t u32BusClock);
uint8_t I2C_GetData(I2C_T *i2c);
void I2C_SetSlaveAddr(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddr, uint8_t u8GCMode);
void I2C_SetSlaveAddrMask(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddrMask);
void I2C_EnableTimeout(I2C_T *i2c, uint8_t u8LongTimeout);
void I2C_DisableTimeout(I2C_T *i2c);
void I2C_EnableWakeup(I2C_T *i2c);
void I2C_DisableWakeup(I2C_T *i2c);
void I2C_SetData(I2C_T *i2c, uint8_t u8Data);
/*@}*/ /* end of group I2C_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group I2C_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__I2C_H__

300
BSP/StdDriver/inc/i2s.h Normal file
View File

@ -0,0 +1,300 @@
/**************************************************************************//**
* @file i2s.h
* @version V3.0
* $Revision: 12 $
* $Date: 15/05/04 3:58p $
* @brief I2S driver header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __I2S_H__
#define __I2S_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup I2S_Driver I2S Driver
@{
*/
/** @addtogroup I2S_EXPORTED_CONSTANTS I2S Exported Constants
@{
*/
#define I2S_DATABIT_8 (0 << I2S_CON_WORDWIDTH_Pos) /*!< I2S data width is 8-bit */
#define I2S_DATABIT_16 (1 << I2S_CON_WORDWIDTH_Pos) /*!< I2S data width is 16-bit */
#define I2S_DATABIT_24 (2 << I2S_CON_WORDWIDTH_Pos) /*!< I2S data width is 24-bit */
#define I2S_DATABIT_32 (3 << I2S_CON_WORDWIDTH_Pos) /*!< I2S data width is 32-bit */
/* Audio Format */
#define I2S_MONO I2S_CON_MONO_Msk /*!< Mono channel */
#define I2S_STEREO 0 /*!< Stereo channel */
/* I2S Data Format */
#define I2S_FORMAT_MSB I2S_CON_FORMAT_Msk /*!< MSB data format */
#define I2S_FORMAT_I2S 0 /*!< I2S data format */
/* I2S Operation mode */
#define I2S_MODE_SLAVE I2S_CON_SLAVE_Msk /*!< As slave mode */
#define I2S_MODE_MASTER 0 /*!< As master mode */
/* I2S FIFO Threshold */
#define I2S_FIFO_TX_LEVEL_WORD_0 0 /*!< TX threshold is 0 word */
#define I2S_FIFO_TX_LEVEL_WORD_1 (1 << I2S_CON_TXTH_Pos) /*!< TX threshold is 1 word */
#define I2S_FIFO_TX_LEVEL_WORD_2 (2 << I2S_CON_TXTH_Pos) /*!< TX threshold is 2 words */
#define I2S_FIFO_TX_LEVEL_WORD_3 (3 << I2S_CON_TXTH_Pos) /*!< TX threshold is 3 words */
#define I2S_FIFO_TX_LEVEL_WORD_4 (4 << I2S_CON_TXTH_Pos) /*!< TX threshold is 4 words */
#define I2S_FIFO_TX_LEVEL_WORD_5 (5 << I2S_CON_TXTH_Pos) /*!< TX threshold is 5 words */
#define I2S_FIFO_TX_LEVEL_WORD_6 (6 << I2S_CON_TXTH_Pos) /*!< TX threshold is 6 words */
#define I2S_FIFO_TX_LEVEL_WORD_7 (7 << I2S_CON_TXTH_Pos) /*!< TX threshold is 7 words */
#define I2S_FIFO_RX_LEVEL_WORD_1 0 /*!< RX threshold is 1 word */
#define I2S_FIFO_RX_LEVEL_WORD_2 (1 << I2S_CON_RXTH_Pos) /*!< RX threshold is 2 words */
#define I2S_FIFO_RX_LEVEL_WORD_3 (2 << I2S_CON_RXTH_Pos) /*!< RX threshold is 3 words */
#define I2S_FIFO_RX_LEVEL_WORD_4 (3 << I2S_CON_RXTH_Pos) /*!< RX threshold is 4 words */
#define I2S_FIFO_RX_LEVEL_WORD_5 (4 << I2S_CON_RXTH_Pos) /*!< RX threshold is 5 words */
#define I2S_FIFO_RX_LEVEL_WORD_6 (5 << I2S_CON_RXTH_Pos) /*!< RX threshold is 6 words */
#define I2S_FIFO_RX_LEVEL_WORD_7 (6 << I2S_CON_RXTH_Pos) /*!< RX threshold is 7 words */
#define I2S_FIFO_RX_LEVEL_WORD_8 (7 << I2S_CON_RXTH_Pos) /*!< RX threshold is 8 words */
/* I2S Record Channel */
#define I2S_MONO_RIGHT 0 /*!< Record mono right channel */
#define I2S_MONO_LEFT I2S_CON_RXLCH_Msk /*!< Record mono left channel */
/* I2S Channel */
#define I2S_RIGHT 0 /*!< Select right channel */
#define I2S_LEFT 1 /*!< Select left channel */
/*@}*/ /* end of group I2S_EXPORTED_CONSTANTS */
/** @addtogroup I2S_EXPORTED_FUNCTIONS I2S Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* inline functions */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief Enable zero cross detection function.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32ChMask The mask for left or right channel. Valid values are:
* - \ref I2S_RIGHT
* - \ref I2S_LEFT
* @return None
* @details This function will set RCHZCEN or LCHZCEN bit of I2SCON register to enable zero cross detection function.
*/
static __INLINE void I2S_ENABLE_TX_ZCD(I2S_T *i2s, uint32_t u32ChMask)
{
if(u32ChMask == I2S_RIGHT)
i2s->CON |= I2S_CON_RCHZCEN_Msk;
else
i2s->CON |= I2S_CON_LCHZCEN_Msk;
}
/**
* @brief Disable zero cross detection function.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32ChMask The mask for left or right channel. Valid values are:
* - \ref I2S_RIGHT
* - \ref I2S_LEFT
* @return None
* @details This function will clear RCHZCEN or LCHZCEN bit of I2SCON register to disable zero cross detection function.
*/
static __INLINE void I2S_DISABLE_TX_ZCD(I2S_T *i2s, uint32_t u32ChMask)
{
if(u32ChMask == I2S_RIGHT)
i2s->CON &= ~I2S_CON_RCHZCEN_Msk;
else
i2s->CON &= ~I2S_CON_LCHZCEN_Msk;
}
/**
* @brief Enable I2S TX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set TXDMA bit of I2SCON register to transmit data with PDMA.
*/
#define I2S_ENABLE_TXDMA(i2s) ( (i2s)->CON |= I2S_CON_TXDMA_Msk )
/**
* @brief Disable I2S TX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear TXDMA bit of I2SCON register to disable TX DMA function.
*/
#define I2S_DISABLE_TXDMA(i2s) ( (i2s)->CON &= ~I2S_CON_TXDMA_Msk )
/**
* @brief Enable I2S RX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set RXDMA bit of I2SCON register to receive data with PDMA.
*/
#define I2S_ENABLE_RXDMA(i2s) ( (i2s)->CON |= I2S_CON_RXDMA_Msk )
/**
* @brief Disable I2S RX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear RXDMA bit of I2SCON register to disable RX DMA function.
*/
#define I2S_DISABLE_RXDMA(i2s) ( (i2s)->CON &= ~I2S_CON_RXDMA_Msk )
/**
* @brief Enable I2S TX function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set TXEN bit of I2SCON register to enable I2S TX function.
*/
#define I2S_ENABLE_TX(i2s) ( (i2s)->CON |= I2S_CON_TXEN_Msk )
/**
* @brief Disable I2S TX function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear TXEN bit of I2SCON register to disable I2S TX function.
*/
#define I2S_DISABLE_TX(i2s) ( (i2s)->CON &= ~I2S_CON_TXEN_Msk )
/**
* @brief Enable I2S RX function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set RXEN bit of I2SCON register to enable I2S RX function.
*/
#define I2S_ENABLE_RX(i2s) ( (i2s)->CON |= I2S_CON_RXEN_Msk )
/**
* @brief Disable I2S RX function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear RXEN bit of I2SCON register to disable I2S RX function.
*/
#define I2S_DISABLE_RX(i2s) ( (i2s)->CON &= ~I2S_CON_RXEN_Msk )
/**
* @brief Enable TX Mute function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set MUTE bit of I2SCON register to enable I2S TX mute function.
*/
#define I2S_ENABLE_TX_MUTE(i2s) ( (i2s)->CON |= I2S_CON_MUTE_Msk )
/**
* @brief Disable TX Mute function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear MUTE bit of I2SCON register to disable I2S TX mute function.
*/
#define I2S_DISABLE_TX_MUTE(i2s) ( (i2s)->CON &= ~I2S_CON_MUTE_Msk )
/**
* @brief Clear TX FIFO.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear TX FIFO. The internal TX FIFO pointer will be reset to FIFO start point.
*/
#define I2S_CLR_TX_FIFO(i2s) ( (i2s)->CON |= I2S_CON_CLR_TXFIFO_Msk )
/**
* @brief Clear RX FIFO.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear RX FIFO. The internal RX FIFO pointer will be reset to FIFO start point.
*/
#define I2S_CLR_RX_FIFO(i2s) ( (i2s)->CON |= I2S_CON_CLR_RXFIFO_Msk )
/**
* @brief This function sets the recording source channel when mono mode is used.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32Ch Left or right channel. Valid values are:
* - \ref I2S_MONO_LEFT
* - \ref I2S_MONO_RIGHT
* @return None
* @details This function selects the recording source channel of monaural mode.
*/
static __INLINE void I2S_SET_MONO_RX_CHANNEL(I2S_T *i2s, uint32_t u32Ch)
{
u32Ch == I2S_MONO_LEFT ?
(i2s->CON |= I2S_CON_RXLCH_Msk) :
(i2s->CON &= ~I2S_CON_RXLCH_Msk);
}
/**
* @brief Write data to I2S TX FIFO.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32Data The value written to TX FIFO.
* @return None
* @details This macro will write a value to TX FIFO.
*/
#define I2S_WRITE_TX_FIFO(i2s, u32Data) ( (i2s)->TXFIFO = (u32Data) )
/**
* @brief Read RX FIFO.
* @param[in] i2s The pointer of the specified I2S module.
* @return The value read from RX FIFO.
* @details This function will return a value read from RX FIFO.
*/
#define I2S_READ_RX_FIFO(i2s) ( (i2s)->RXFIFO )
/**
* @brief Get the interrupt flag.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32Mask The mask value for all interrupt flags.
* @return The interrupt flags specified by the u32mask parameter.
* @details This macro will return the combination flags of I2SSTATUS register. The flags are specified by the u32mask parameter.
*/
#define I2S_GET_INT_FLAG(i2s, u32Mask) ( (i2s)->STATUS & (u32Mask) )
/**
* @brief Clear the interrupt flag.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32Mask The mask value for all interrupt flags.
* @return None
* @details This macro will clear the interrupt flags specified by the u32mask parameter.
*/
#define I2S_CLR_INT_FLAG(i2s, u32Mask) ( (i2s)->STATUS = (u32Mask) )
/**
* @brief Get transmit FIFO level
* @param[in] i2s The pointer of the specified I2S module.
* @return TX FIFO level
* @details This macro will return the number of available words in TX FIFO.
*/
#define I2S_GET_TX_FIFO_LEVEL(i2s) ( (((i2s)->STATUS & I2S_STATUS_TX_LEVEL_Msk) >> I2S_STATUS_TX_LEVEL_Pos) & 0xF )
/**
* @brief Get receive FIFO level
* @param[in] i2s The pointer of the specified I2S module.
* @return RX FIFO level
* @details This macro will return the number of available words in RX FIFO.
*/
#define I2S_GET_RX_FIFO_LEVEL(i2s) ( (((i2s)->STATUS & I2S_STATUS_RX_LEVEL_Msk) >> I2S_STATUS_RX_LEVEL_Pos) & 0xF )
/* Function prototype declaration */
uint32_t I2S_Open(I2S_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat);
void I2S_Close(I2S_T *i2s);
void I2S_EnableInt(I2S_T *i2s, uint32_t u32Mask);
void I2S_DisableInt(I2S_T *i2s, uint32_t u32Mask);
uint32_t I2S_EnableMCLK(I2S_T *i2s, uint32_t u32BusClock);
void I2S_DisableMCLK(I2S_T *i2s);
/*@}*/ /* end of group I2S_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group I2S_Driver */
/*@}*/ /* end of group Device_Driver */
#endif
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

197
BSP/StdDriver/inc/pdma.h Normal file
View File

@ -0,0 +1,197 @@
/**************************************************************************//**
* @file pdma.h
* @version V1.00
* $Revision: 14 $
* $Date: 15/05/04 3:58p $
* @brief PDMA Controller Driver Header File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2011 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __PDMA_H__
#define __PDMA_H__
/** @addtogroup Standard_Driver Standard Driver
* @{
*/
/** @addtogroup PDMA_Driver PDMA Driver
* @{
*/
/** @addtogroup PDMA_EXPORTED_CONSTANTS PDMA Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Data Width Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PDMA_WIDTH_8 0x00080000UL /*!<DMA Transfer Width 8-bit */
#define PDMA_WIDTH_16 0x00100000UL /*!<DMA Transfer Width 16-bit */
#define PDMA_WIDTH_32 0x00000000UL /*!<DMA Transfer Width 32-bit */
/*---------------------------------------------------------------------------------------------------------*/
/* Address Attribute Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PDMA_SAR_INC 0x00000000UL /*!<DMA SAR increment */
#define PDMA_SAR_FIX 0x00000020UL /*!<DMA SAR fix address */
#define PDMA_DAR_INC 0x00000000UL /*!<DMA DAR increment */
#define PDMA_DAR_FIX 0x00000080UL /*!<DMA DAR fix address */
/*---------------------------------------------------------------------------------------------------------*/
/* Peripheral Transfer Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PDMA_SPI0_TX 0x00000000UL /*!<DMA Connect to SPI0 TX */
#define PDMA_SPI1_TX 0x00000001UL /*!<DMA Connect to SPI1 TX */
#define PDMA_SPI2_TX 0x00000002UL /*!<DMA Connect to SPI2 TX */
#define PDMA_SPI3_TX 0x00000003UL /*!<DMA Connect to SPI2 TX */
#define PDMA_UART0_TX 0x00000004UL /*!<DMA Connect to UART0 TX */
#define PDMA_UART1_TX 0x00000005UL /*!<DMA Connect to UART1 TX */
#define PDMA_I2S_TX 0x00000006UL /*!<DMA Connect to I2S TX */
#define PDMA_SPI0_RX 0x00000007UL /*!<DMA Connect to SPI0 RX */
#define PDMA_SPI1_RX 0x00000008UL /*!<DMA Connect to SPI1 RX */
#define PDMA_SPI2_RX 0x00000009UL /*!<DMA Connect to SPI2 RX */
#define PDMA_SPI3_RX 0x0000000AUL /*!<DMA Connect to SPI2 RX */
#define PDMA_UART0_RX 0x0000000BUL /*!<DMA Connect to UART0 RX */
#define PDMA_UART1_RX 0x0000000CUL /*!<DMA Connect to UART1 RX */
#define PDMA_I2S_RX 0x0000000DUL /*!<DMA Connect to I2S RX */
#define PDMA_ADC 0x0000000EUL /*!<DMA Connect to ADC */
#define PDMA_MEM 0x0000001FUL /*!<DMA Connect to Memory */
/*@}*/ /* end of group PDMA_EXPORTED_CONSTANTS */
/** @addtogroup PDMA_EXPORTED_FUNCTIONS PDMA Exported Functions
@{
*/
/**
* @brief Get PDMA Global Interrupt Status
*
* @param None
*
* @return Interrupt Status
*
* @details This macro gets the global interrupt status.
*/
#define PDMA_GET_INT_STATUS() ((uint32_t)(PDMA_GCR->GCRISR))
/**
* @brief Get PDMA Channel Interrupt Status
*
* @param[in] u32Ch Selected DMA channel
*
* @return Interrupt Status
*
* @details This macro gets the channel interrupt status.
*/
#define PDMA_GET_CH_INT_STS(u32Ch) (*((__IO uint32_t *)((uint32_t)&PDMA0->ISR + (uint32_t)((u32Ch)*0x100))))
/**
* @brief Clear PDMA Channel Interrupt Flag
*
* @param[in] u32Ch Selected DMA channel
* @param[in] u32Mask Interrupt Mask
*
* @return None
*
* @details This macro clear the channel interrupt flag.
*/
#define PDMA_CLR_CH_INT_FLAG(u32Ch, u32Mask) (*((__IO uint32_t *)((uint32_t)&PDMA0->ISR + (uint32_t)((u32Ch)*0x100))) = (u32Mask))
/**
* @brief Check Channel Status
*
* @param[in] u32Ch The selected channel
*
* @retval 0 The selected channel is idle
* @retval 1 The selected channel is busy
*
* @details Check the selected channel is busy or not.
*/
#define PDMA_IS_CH_BUSY(u32Ch) ((*((__IO uint32_t *)((uint32_t)&PDMA0->CSR +(uint32_t)((u32Ch)*0x100)))&PDMA_CSR_TRIG_EN_Msk)? 1 : 0)
/**
* @brief Set Source Address
*
* @param[in] u32Ch The selected channel
* @param[in] u32Addr The selected address
*
* @return None
*
* @details This macro set the selected channel source address.
*/
#define PDMA_SET_SRC_ADDR(u32Ch, u32Addr) (*((__IO uint32_t *)((uint32_t)&PDMA0->SAR + (uint32_t)((u32Ch)*0x100))) = (u32Addr))
/**
* @brief Set Destination Address
*
* @param[in] u32Ch The selected channel
* @param[in] u32Addr The selected address
*
* @return None
*
* @details This macro set the selected channel destination address.
*/
#define PDMA_SET_DST_ADDR(u32Ch, u32Addr) (*((__IO uint32_t *)((uint32_t)&PDMA0->DAR + (uint32_t)((u32Ch)*0x100))) = (u32Addr))
/**
* @brief Set Transfer Count
*
* @param[in] u32Ch The selected channel
* @param[in] u32Count Transfer Count
*
* @return None
*
* @details This macro set the selected channel transfer count.
* \hideinitializer
*/
#define PDMA_SET_TRANS_CNT(u32Ch, u32Count) { \
if (((uint32_t)*((__IO uint32_t *)((uint32_t)&PDMA0->CSR + (uint32_t)((u32Ch)*0x100))) & PDMA_CSR_APB_TWS_Msk) == PDMA_WIDTH_32) \
*((__IO uint32_t *)((uint32_t)&PDMA0->BCR + (uint32_t)((u32Ch)*0x100))) = ((u32Count) << 2); \
else if (((uint32_t)*((__IO uint32_t *)((uint32_t)&PDMA0->CSR + (uint32_t)((u32Ch)*0x100))) & PDMA_CSR_APB_TWS_Msk) == PDMA_WIDTH_8) \
*((__IO uint32_t *)((uint32_t)&PDMA0->BCR + (uint32_t)((u32Ch)*0x100))) = (u32Count); \
else if (((uint32_t)*((__IO uint32_t *)((uint32_t)&PDMA0->CSR + (uint32_t)((u32Ch)*0x100))) & PDMA_CSR_APB_TWS_Msk) == PDMA_WIDTH_16) \
*((__IO uint32_t *)((uint32_t)&PDMA0->BCR + (uint32_t)((u32Ch)*0x100))) = ((u32Count) << 1); \
}
/**
* @brief Stop the channel
*
* @param[in] u32Ch The selected channel
*
* @return None
*
* @details This macro stop the selected channel.
*/
#define PDMA_STOP(u32Ch) (*((__IO uint32_t *)((uint32_t)&PDMA0->CSR + (uint32_t)((u32Ch)*0x100))) &= ~PDMA_CSR_PDMACEN_Msk)
void PDMA_Open(uint32_t u32Mask);
void PDMA_Close(void);
void PDMA_SetTransferCnt(uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount);
void PDMA_SetTransferAddr(uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl);
void PDMA_SetTransferMode(uint32_t u32Ch, uint32_t u32Periphral, uint32_t u32ScatterEn, uint32_t u32DescAddr);
void PDMA_Trigger(uint32_t u32Ch);
void PDMA_EnableInt(uint32_t u32Ch, uint32_t u32Mask);
void PDMA_DisableInt(uint32_t u32Ch, uint32_t u32Mask);
/**
* @} End of PDMA Device Function Interface
*/
/**
* @} End of Function Interface
*/
/**
* @} End of Device_Driver
*/
#endif // __PDMA_H__

250
BSP/StdDriver/inc/ps2.h Normal file
View File

@ -0,0 +1,250 @@
/**************************************************************************//**
* @file ps2.h
* @version V3.00
* $Revision: 16 $
* $Date: 15/05/20 11:39a $
* @brief NUC200 PS/2 Driver Header File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __PS2_H__
#define __PS2_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup PS2_Driver PS2 Driver
@{
*/
/** @addtogroup PS2_EXPORTED_FUNCTIONS PS2 Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Define Macros and functions */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief To Set PS/2 Tx FIFO length
*
* @param[in] u32Count Tx FIFO length
*
* @return None
*
* @details Before PS/2 data transmit, program needs to set the FIFO depth.
* \hideinitializer
*/
#define PS2_SET_TX_BYTE_CNT(u32Count) (PS2->PS2CON = (PS2->PS2CON & ~PS2_PS2CON_TXFIFO_DEPTH_Msk) \
| (((u32Count)-1) << PS2_PS2CON_TXFIFO_DEPTH_Pos))
/**
* @brief This function use to Get PS/2 Status
*
* @param None
*
* @return PS/2 bus status
*
* @details To get PS/2 bus status which are about Byte index, Tx/Rx status, Error status and PS/2 line status.
*/
#define PS2_GET_STATUS() (PS2->PS2STATUS)
/**
* @brief This function is used to Clear PS/2 Status
*
* @param[in] u32Mask Clear the specified status of PS/2 module:
* 1. PS2D_PS2STATUS_FRAMERR_Msk 2. PS2D_PS2STATUS_RXOVF_Msk
*
* @return None
*
* @details To clear PS/2 bus status which are about Byte index, TX/RX status, Error status, PS/2 line status.
*/
#define PS2_CLR_STATUS(u32Mask) (PS2->PS2STATUS = (u32Mask))
/**
* @brief This function is used to Clear PS/2 Tx FIFO
*
* @param None
*
* @return None
*
* @details Write 1 to terminate PS/2 device to host transmission.
*
* @note Write 1 is always clear Tx FIFO, and need write 0 to STOP the clear action.
*/
__STATIC_INLINE void PS2_CLEAR_TX_FIFO(void)
{
PS2->PS2CON |= PS2_PS2CON_CLRFIFO_Msk;
PS2->PS2CON &= ~PS2_PS2CON_CLRFIFO_Msk;
}
/**
* @brief This function is used to Clear PS2 Rx interrupt
*
* @param None
*
* @return None
*
* @details To disable PS/2 receive interrupt occurs.
*/
#define PS2_CLR_RX_INT_FLAG() (PS2->PS2INTID = PS2_PS2INTID_RXINT_Msk)
/**
* @brief This function is used to Clear PS/2 Tx Interrupt
*
* @param None
*
* @return None
*
* @details To disable PS/2 transmit interrupt occurs.
*/
#define PS2_CLR_TX_INT_FLAG() (PS2->PS2INTID = PS2_PS2INTID_TXINT_Msk)
/**
* @brief This function is used to Get PS/2 Interrupt
*
* @param[in] u32IntFlag Interrupt flag of PS2_PS2INTID_TXINT_Msk, PS2_PS2INTID_RXINT_Msk
*
* @retval 1 Interrupt occurs
* @retval 0 Interrupt not occurs
*
* @details To check PS/2 bus interrupt occur from TX or RX
*/
#define PS2_GET_INT_FLAG(u32IntFlag) ((PS2->PS2INTID & (u32IntFlag))?1:0)
/**
* @brief Disable PS2CLK and PS2DATA pins override.
*
* @param None
*
* @return None
*
* @details To disable the override control of PS2CLK and PS2DATA pins.
*/
#define PS2_DISABLE_OVERRIDE() (PS2->PS2CON &= ~PS2_PS2CON_OVERRIDE_Msk)
/**
* @brief Enable PS2CLK and PS2DATA pins Override.
*
* @param None
*
* @return None
*
* @details TO enable the override control of PS2CLK and PS2DATA pins.
*/
#define PS2_ENABLE_OVERRIDE() (PS2->PS2CON |= PS2_PS2CON_OVERRIDE_Msk)
/**
* @brief This function is used to Get Indicates which data byte in transmit data shift register
*
* @param None
*
* @return The indicates which data byte in transmit data shift register.
*
* @details To get a indication which a data byte in the data shift register.
*/
#define PS2_GET_TX_BYTE_INDEX() ((PS2->PS2STATUS & PS2_PS2STATUS_BYTEIDX_Msk) >> PS2_PS2STATUS_BYTEIDX_Pos)
/**
* @brief This function is used to set PS2DATA Pin low.
*
* @param None
*
* @return None
*
* @details To control the PS2DATA pin state to low.
*/
#define PS2_SET_DATA_LOW() (PS2->PS2CON &= ~PS2_PS2CON_FPS2DAT_Msk)
/**
* @brief This function is used to set PS2DATA Pin high
*
* @param None
*
* @return None
*
* @details To control the PS2DATA pin state to high.
*/
#define PS2_SET_DATA_HIGH() (PS2->PS2CON |= PS2_PS2CON_FPS2DAT_Msk)
/**
* @brief This function is used to set PS2CLK Pin low.
*
* @param None
*
* @return None
*
* @details To control the PS2CLK pin state to low.
*/
#define PS2_SET_CLK_LOW() (PS2->PS2CON &= ~PS2_PS2CON_FPS2CLK_Msk)
/**
* @brief This function is used to set PS2CLK Pin high.
*
* @param None
*
* @return None
*
* @details To control the PS2CLK pin state to high.
*/
#define PS2_SET_CLK_HIGH() (PS2->PS2CON |= PS2_PS2CON_FPS2CLK_Msk)
/**
* @brief Disable always sends acknowledge
*
* @param None
*
* @return None
*
* @details If parity error or Stop bit is not received correctly, acknowledge will not be sent to host at 12th clock.
*/
#define PS2_DISABLE_ACK_ALWAYS() (PS2->PS2CON |= PS2_PS2CON_ACK_Msk)
/**
* @brief Always sends acknowledge
*
* @param None
*
* @return None
*
* @details Always send acknowledge to host at 12th clock for host to device communication.
*/
#define PS2_ENABLE_ACK_ALWAYS() (PS2->PS2CON &= ~PS2_PS2CON_ACK_Msk)
/*---------------------------------------------------------------------------------------------------------*/
/* Define Function Prototypes */
/*---------------------------------------------------------------------------------------------------------*/
void PS2_Open(void);
void PS2_Close(void);
uint8_t PS2_Read(void);
int32_t PS2_Write(uint32_t *pu32Buf, uint32_t u32ByteCount);
void PS2_EnableInt(uint32_t u32Mask);
void PS2_DisableInt(uint32_t u32Mask);
/*@}*/ /* end of group PS2_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group PS2_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__PS2_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

237
BSP/StdDriver/inc/pwm.h Normal file
View File

@ -0,0 +1,237 @@
/**************************************************************************//**
* @file pwm.h
* @version V3.00
* $Revision: 12 $
* $Date: 15/05/06 2:33p $
* @brief PWM driver header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __PWM_H__
#define __PWM_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup PWM_Driver PWM Driver
@{
*/
/** @addtogroup PWM_EXPORTED_CONSTANTS PWM Exported Constants
@{
*/
#define PWM_CHANNEL_NUM (4) /*!< PWM channel number */
#define PWM_CLK_DIV_1 (4UL) /*!< PWM clock divide by 1 */
#define PWM_CLK_DIV_2 (0UL) /*!< PWM clock divide by 2 */
#define PWM_CLK_DIV_4 (1UL) /*!< PWM clock divide by 4 */
#define PWM_CLK_DIV_8 (2UL) /*!< PWM clock divide by 8 */
#define PWM_CLK_DIV_16 (3UL) /*!< PWM clock divide by 16 */
#define PWM_EDGE_ALIGNED (0UL) /*!< PWM working in edge aligned type */
#define PWM_CENTER_ALIGNED (1UL) /*!< PWM working in center aligned type */
#define PWM_PERIOD_INT_UNDERFLOW (0) /*!< PWM period interrupt triggered if counter underflow */
#define PWM_PERIOD_INT_MATCH_CNR (PWM_PIER_INT01TYPE_Msk) /*!< PWM period interrupt triggered if counter match CNR */
#define PWM_CAPTURE_INT_RISING_LATCH (PWM_CCR0_CRL_IE0_Msk) /*!< PWM capture interrupt if channel has rising transition */
#define PWM_CAPTURE_INT_FALLING_LATCH (PWM_CCR0_CFL_IE0_Msk) /*!< PWM capture interrupt if channel has falling transition */
/*---------------------------------------------------------------------------------------------------------*/
/* PWM Group channel number constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_CH0 0x0 /*!< PWM Group A/B channel 0 */
#define PWM_CH1 0x1 /*!< PWM Group A/B channel 1 */
#define PWM_CH2 0x2 /*!< PWM Group A/B channel 2 */
#define PWM_CH3 0x3 /*!< PWM Group A/B channel 3 */
#define PWM_CCR_MASK 0x000F000F /*!< PWM CCR0/CCR2 bit0~3 and bit16~19 mask */
/*@}*/ /* end of group PWM_EXPORTED_CONSTANTS */
/** @addtogroup PWM_EXPORTED_FUNCTIONS PWM Exported Functions
@{
*/
/**
* @brief Enable output inverter of specified channel(s)
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel
* Bit 0 represents channel 0, bit 1 represents channel 1...
* @return None
* @details This macro is used to enable capture input inverter for specified channel(s).
* \hideinitializer
*/
#define PWM_ENABLE_OUTPUT_INVERTER(pwm, u32ChannelMask) \
do{ \
int i;\
(pwm)->PCR &= ~(PWM_PCR_CH0INV_Msk|PWM_PCR_CH1INV_Msk|PWM_PCR_CH2INV_Msk|PWM_PCR_CH3INV_Msk);\
for(i = 0; i < 4; i++) { \
if((u32ChannelMask) & (1 << i)) \
(pwm)->PCR |= (PWM_PCR_CH0INV_Msk << (PWM_PCR_CH0INV_Pos * (i * 4))); \
} \
}while(0)
/**
* @brief Get captured rising data of specified channel
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @return The timer counter, 0~0xFFFF
* @details This macro is used to get captured rising data for specified channel.
*/
#define PWM_GET_CAPTURE_RISING_DATA(pwm, u32ChannelNum) (*((__IO uint32_t *) ((((uint32_t)&((pwm)->CRLR0)) + (u32ChannelNum) * 8))))
/**
* @brief Get captured falling data of specified channel
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @return The timer counter, 0~0xFFFF
* @details This macro is used to get captured falling data for specified channel.
*/
#define PWM_GET_CAPTURE_FALLING_DATA(pwm, u32ChannelNum) (*((__IO uint32_t *) ((((uint32_t)&((pwm)->CFLR0)) + (u32ChannelNum) * 8))))
/**
* @brief Set the prescaler of the selected channel
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32Prescaler Clock prescaler of specified channel. Valid values are between 1 ~ 0xFF
* @return None
* @details This macro is used to set timer pre-scale for specified channel.
* @note If u32Prescaler = 0, corresponding PWM-timer will be stopped.
* @note If u32Prescaler = x (x not equal to 0), it means Clock input is divided by (x + 1) before it is fed to the corresponding PWM counter.
*/
#define PWM_SET_PRESCALER(pwm, u32ChannelNum, u32Prescaler) \
((pwm)->PPR = ((pwm)->PPR & ~(PWM_PPR_CP01_Msk << (((u32ChannelNum) >> 1) * 8))) | ((u32Prescaler) << (((u32ChannelNum) >> 1) * 8)))
/**
* @brief Set the divider of the selected channel
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32Divider Clock divider of specified channel. Valid values are
* - \ref PWM_CLK_DIV_1
* - \ref PWM_CLK_DIV_2
* - \ref PWM_CLK_DIV_4
* - \ref PWM_CLK_DIV_8
* - \ref PWM_CLK_DIV_16
* @return None
* @details This macro is used to set Timer clock source divider selection for specified channel.
*/
#define PWM_SET_DIVIDER(pwm, u32ChannelNum, u32Divider) \
((pwm)->CSR = ((pwm)->CSR & ~(PWM_CSR_CSR0_Msk << ((u32ChannelNum) * 4))) | ((u32Divider) << ((u32ChannelNum) * 4)))
/**
* @brief Set the duty of the selected channel
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32CMR Duty of specified channel. Valid values are between 0~0xFFFF
* @return None
* @details This macro is used to set PWM Comparator value for specified channel.
* @note This new setting will take effect on next PWM period.
*/
#define PWM_SET_CMR(pwm, u32ChannelNum, u32CMR) (*((__IO uint32_t *) ((((uint32_t)&((pwm)->CMR0)) + (u32ChannelNum) * 12))) = (u32CMR))
/**
* @brief Set the period of the selected channel
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32CNR Period of specified channel. Valid values are between 0~0xFFFF
* @return None
* @details This macro is used to set timer loaded value(CNR) for specified channel.\n
* Loaded value determines the PWM period.
* @note This new setting will take effect on next PWM period.
* @note PWM counter will stop if period length set to 0.
*/
#define PWM_SET_CNR(pwm, u32ChannelNum, u32CNR) (*((__IO uint32_t *) ((((uint32_t)&((pwm)->CNR0)) + (u32ChannelNum) * 12))) = (u32CNR))
/**
* @brief Set the PWM aligned type
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel
* Bit 0 represents channel 0, bit 1 represents channel 1...
* @param[in] u32AlignedType PWM aligned type, valid values are:
* - \ref PWM_EDGE_ALIGNED
* - \ref PWM_CENTER_ALIGNED
* @return None
* @details This macro is used to set the PWM aligned type.
* @note PWM trigger ADC function is only supported when PWM operating at Center-aligned type.
* \hideinitializer
*/
#define PWM_SET_ALIGNED_TYPE(pwm, u32ChannelMask, u32AlignedType) \
do{ \
int i; \
for(i = 0; i < 4; i++) { \
if((u32ChannelMask) & (1 << i)) \
(pwm)->PCR = ((pwm)->PCR & ~(PWM_PCR_PWM01TYPE_Msk << (i >> 1))) | ((u32AlignedType) << (PWM_PCR_PWM01TYPE_Pos + (i >> 1))); \
} \
}while(0)
uint32_t PWM_ConfigCaptureChannel(PWM_T *pwm,
uint32_t u32ChannelNum,
uint32_t u32UnitTimeNsec,
uint32_t u32CaptureEdge);
uint32_t PWM_ConfigOutputChannel(PWM_T *pwm,
uint32_t u32ChannelNum,
uint32_t u32Frequncy,
uint32_t u32DutyCycle);
void PWM_Start(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_Stop(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_ForceStop(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_EnableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition);
void PWM_DisableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_ClearADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition);
uint32_t PWM_GetADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_EnableCapture(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_DisableCapture(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_EnableOutput(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_DisableOutput(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_EnableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration);
void PWM_DisableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_EnableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge);
void PWM_DisableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge);
void PWM_ClearCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge);
uint32_t PWM_GetCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_EnableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType);
void PWM_DisableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_ClearDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum);
uint32_t PWM_GetDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_EnablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType);
void PWM_DisablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_ClearPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum);
uint32_t PWM_GetPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum);
/*@}*/ /* end of group PWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group PWM_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__PWM_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

258
BSP/StdDriver/inc/rtc.h Normal file
View File

@ -0,0 +1,258 @@
/**************************************************************************//**
* @file rtc.h
* @version V3.00
* $Revision: 13 $
* $Date: 15/05/08 2:51p $
* @brief RTC driver header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __RTC_H__
#define __RTC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup RTC_Driver RTC Driver
@{
*/
/** @addtogroup RTC_EXPORTED_CONSTANTS RTC Exported Constants
@{
*/
#define RTC_INIT_KEY 0xA5EB1357UL /*!< RTC Initiation Key to make RTC leaving reset state */
#define RTC_WRITE_KEY 0x0000A965UL /*!< RTC Access Key to enable RTC read/write accessible and kept 1024 RTC clock */
#define RTC_WAIT_COUNT 0xFFFFFFFF /*!< Initial Time-out Value */
#define RTC_YEAR2000 2000 /*!< RTC Reference for compute year data */
#define RTC_FCR_REFERENCE 32761 /*!< RTC Reference for frequency compensation */
#define RTC_CLOCK_12 0 /*!< RTC as 12-hour time scale with AM and PM indication */
#define RTC_CLOCK_24 1 /*!< RTC as 24-hour time scale */
#define RTC_AM 1 /*!< RTC as AM indication */
#define RTC_PM 2 /*!< RTC as PM indication */
#define RTC_TICK_1_SEC 0x0UL /*!< RTC time tick is 1 second */
#define RTC_TICK_1_2_SEC 0x1UL /*!< RTC time tick is 1/2 second */
#define RTC_TICK_1_4_SEC 0x2UL /*!< RTC time tick is 1/4 second */
#define RTC_TICK_1_8_SEC 0x3UL /*!< RTC time tick is 1/8 second */
#define RTC_TICK_1_16_SEC 0x4UL /*!< RTC time tick is 1/16 second */
#define RTC_TICK_1_32_SEC 0x5UL /*!< RTC time tick is 1/32 second */
#define RTC_TICK_1_64_SEC 0x6UL /*!< RTC time tick is 1/64 second */
#define RTC_TICK_1_128_SEC 0x7UL /*!< RTC time tick is 1/128 second */
#define RTC_SUNDAY 0x0UL /*!< Day of the Week is Sunday */
#define RTC_MONDAY 0x1UL /*!< Day of the Week is Monday */
#define RTC_TUESDAY 0x2UL /*!< Day of the Week is Tuesday */
#define RTC_WEDNESDAY 0x3UL /*!< Day of the Week is Wednesday */
#define RTC_THURSDAY 0x4UL /*!< Day of the Week is Thursday */
#define RTC_FRIDAY 0x5UL /*!< Day of the Week is Friday */
#define RTC_SATURDAY 0x6UL /*!< Day of the Week is Saturday */
#define RTC_SNOOPER_LOW_LEVEL 0x0UL /*!< Snooper pin detected is low-level trigger */
#define RTC_SNOOPER_HIGH_LEVEL 0x2UL /*!< Snooper pin detected is high-level trigger */
#define RTC_SNOOPER_FALLING_EDGE 0x8UL /*!< Snooper pin detected is falling-edge trigger */
#define RTC_SNOOPER_RISING_EDGE 0xAUL /*!< Snooper pin detected is rising-edge trigger */
#define RTC_SNOOPER_DETECT_Msk 0xAUL /*!< Snooper pin detected mask bits */
/*@}*/ /* end of group RTC_EXPORTED_CONSTANTS */
/** @addtogroup RTC_EXPORTED_STRUCTS RTC Exported Structs
@{
*/
/**
* @details RTC define Time Data Struct
*/
typedef struct
{
uint32_t u32Year; /*!< Year value */
uint32_t u32Month; /*!< Month value */
uint32_t u32Day; /*!< Day value */
uint32_t u32DayOfWeek; /*!< Day of week value */
uint32_t u32Hour; /*!< Hour value */
uint32_t u32Minute; /*!< Minute value */
uint32_t u32Second; /*!< Second value */
uint32_t u32TimeScale; /*!< 12-Hour, 24-Hour */
uint32_t u32AmPm; /*!< Only Time Scale select 12-hr used */
} S_RTC_TIME_DATA_T;
/*@}*/ /* end of group RTC_EXPORTED_STRUCTS */
/** @addtogroup RTC_EXPORTED_FUNCTIONS RTC Exported Functions
@{
*/
/**
* @brief Indicate is Leap Year or not
*
* @param None
*
* @retval 0 This year is not a leap year
* @retval 1 This year is a leap year
*
* @details According to current date, return this year is leap year or not.
*/
#define RTC_IS_LEAP_YEAR() ((RTC->LIR & RTC_LIR_LIR_Msk)? 1:0)
/**
* @brief Clear RTC Alarm Interrupt Flag
*
* @param None
*
* @return None
*
* @details This macro is used to clear RTC alarm interrupt flag.
*/
#define RTC_CLEAR_ALARM_INT_FLAG() (RTC->RIIR = RTC_RIIR_AIF_Msk)
/**
* @brief Clear RTC Tick Interrupt Flag
*
* @param None
*
* @return None
*
* @details This macro is used to clear RTC tick interrupt flag.
*/
#define RTC_CLEAR_TICK_INT_FLAG() (RTC->RIIR = RTC_RIIR_TIF_Msk)
/**
* @brief Get RTC Alarm Interrupt Flag
*
* @param None
*
* @retval 0 RTC alarm interrupt did not occur
* @retval 1 RTC alarm interrupt occurred
*
* @details This macro indicate RTC alarm interrupt occurred or not.
*/
#define RTC_GET_ALARM_INT_FLAG() ((RTC->RIIR & RTC_RIIR_AIF_Msk)? 1:0)
/**
* @brief Get RTC Time Tick Interrupt Flag
*
* @param None
*
* @retval 0 RTC time tick interrupt did not occur
* @retval 1 RTC time tick interrupt occurred
*
* @details This macro indicate RTC time tick interrupt occurred or not.
*/
#define RTC_GET_TICK_INT_FLAG() ((RTC->RIIR & RTC_RIIR_TIF_Msk)? 1:0)
/**
* @brief Clear RTC Snooper Interrupt Flag
*
* @param None
*
* @return None
*
* @details This macro clear RTC snooper pin interrupt flag.
*/
#define RTC_CLEAR_SNOOPER_INT_FLAG() (RTC->RIIR = RTC_RIIR_SNOOPIF_Msk)
/**
* @brief Get RTC Snooper Pin Flag
*
* @param None
*
* @retval 0 RTC snooper pin interrupt did not occur
* @retval 1 RTC snooper pin interrupt occurred
*
* @details This macro indicate RTC snooper pin interrupt occurred or not.
*/
#define RTC_GET_SNPPOER_INT_FLAG() ((RTC->RIIR & RTC_RIIR_SNOOPIF_Msk)? 1:0)
/**
* @brief Read Spare Register
*
* @param[in] u32RegNum The spare register number, 0~19.
*
* @return Spare register content
*
* @details Read the specify spare register content.
* @note The returned value is valid only when SPRRDY(SPRCTL[7] SPR Register Ready) bit is set. \n
* And its controlled by RTC Access Enable Register.
*/
#define RTC_READ_SPARE_REGISTER(u32RegNum) (RTC->SPR[(u32RegNum)])
/**
* @brief Write Spare Register
*
* @param[in] u32RegNum The spare register number, 0~19.
* @param[in] u32RegValue The spare register value.
*
* @return None
*
* @details Write specify data to spare register.
* @note This macro is effect only when SPRRDY(SPRCTL[7] SPR Register Ready) bit is set. \n
* And its controlled by RTC Access Enable Register.
*/
#define RTC_WRITE_SPARE_REGISTER(u32RegNum, u32RegValue) (RTC->SPR[(u32RegNum)] = (u32RegValue))
/**
* @brief Wait RTC Access Enable
*
* @param None
*
* @return None
*
* @details This function is used to enable the maximum RTC read/write accessible time.
*/
static __INLINE void RTC_WaitAccessEnable(void)
{
/* To wait AER bit is cleared and enable AER bit (Access bit) again */
while((RTC->AER & RTC_AER_ENF_Msk) == RTC_AER_ENF_Msk);
RTC->AER = RTC_WRITE_KEY;
/* To wait AER bit is set and user can access the RTC registers from now on */
while((RTC->AER & RTC_AER_ENF_Msk) == 0x0);
}
void RTC_Open(S_RTC_TIME_DATA_T *sPt);
void RTC_Close(void);
void RTC_32KCalibration(int32_t i32FrequencyX100);
void RTC_GetDateAndTime(S_RTC_TIME_DATA_T *sPt);
void RTC_GetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt);
void RTC_SetDateAndTime(S_RTC_TIME_DATA_T *sPt);
void RTC_SetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt);
void RTC_SetDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day, uint32_t u32DayOfWeek);
void RTC_SetTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm);
void RTC_SetAlarmDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day);
void RTC_SetAlarmTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm);
uint32_t RTC_GetDayOfWeek(void);
void RTC_SetTickPeriod(uint32_t u32TickSelection);
void RTC_EnableInt(uint32_t u32IntFlagMask);
void RTC_DisableInt(uint32_t u32IntFlagMask);
void RTC_EnableSpareRegister(void);
void RTC_DisableSpareRegister(void);
void RTC_EnableSnooperDetection(uint32_t u32PinCondition);
void RTC_DisableSnooperDetection(void);
/*@}*/ /* end of group RTC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group RTC_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__RTC_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

275
BSP/StdDriver/inc/sc.h Normal file
View File

@ -0,0 +1,275 @@
/**************************************************************************//**
* @file sc.h
* @version V3.00
* $Revision: 11 $
* $Date: 15/05/12 2:18p $
* @brief Smartcard (SC) driver header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __SC_H__
#define __SC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup SC_Driver SC Driver
@{
*/
/** @addtogroup SC_EXPORTED_CONSTANTS SC Exported Constants
@{
*/
#define SC_INTERFACE_NUM 3 /*!< Smartcard interface numbers */
#define SC_PIN_STATE_HIGH 1 /*!< Smartcard pin status high */
#define SC_PIN_STATE_LOW 0 /*!< Smartcard pin status low */
#define SC_PIN_STATE_IGNORE 0xFFFFFFFF /*!< Ignore pin status */
#define SC_CLK_ON 1 /*!< Smartcard clock on */
#define SC_CLK_OFF 0 /*!< Smartcard clock off */
#define SC_TMR_MODE_0 (0ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 0, down count */
#define SC_TMR_MODE_1 (1ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 1, down count, start after detect start bit */
#define SC_TMR_MODE_2 (2ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 2, down count, start after receive start bit */
#define SC_TMR_MODE_3 (3ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 3, down count, use for activation, only timer 0 support this mode */
#define SC_TMR_MODE_4 (4ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 4, down count with reload after timeout */
#define SC_TMR_MODE_5 (5ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 5, down count, start after detect start bit, reload after timeout */
#define SC_TMR_MODE_6 (6ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 6, down count, start after receive start bit, reload after timeout */
#define SC_TMR_MODE_7 (7ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 7, down count, start and reload after detect start bit */
#define SC_TMR_MODE_8 (8ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 8, up count */
#define SC_TMR_MODE_F (0xF << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 15, down count, reload after detect start bit */
/*@}*/ /* end of group SC_EXPORTED_CONSTANTS */
/** @addtogroup SC_EXPORTED_FUNCTIONS SC Exported Functions
@{
*/
/**
* @brief Enable smartcard interrupt.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32Mask Interrupt mask to be enabled. A combination of
* - \ref SC_IER_ACON_ERR_IE_Msk
* - \ref SC_IER_RTMR_IE_Msk
* - \ref SC_IER_INIT_IE_Msk
* - \ref SC_IER_CD_IE_Msk
* - \ref SC_IER_BGT_IE_Msk
* - \ref SC_IER_TMR2_IE_Msk
* - \ref SC_IER_TMR1_IE_Msk
* - \ref SC_IER_TMR0_IE_Msk
* - \ref SC_IER_TERR_IE_Msk
* - \ref SC_IER_TBE_IE_Msk
* - \ref SC_IER_RDA_IE_Msk
* @return None
* @details The macro is used to enable Auto-convention error interrupt, Receiver buffer time-out interrupt, Initial end interrupt,
* Card detect interrupt, Block guard time interrupt, Timer2 interrupt, Timer1 interrupt, Timer0 interrupt,
* Transfer error interrupt, Transmit buffer empty interrupt or Receive data reach trigger level interrupt.
* \hideinitializer
*/
#define SC_ENABLE_INT(sc, u32Mask) ((sc)->IER |= (u32Mask))
/**
* @brief Disable smartcard interrupt.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32Mask Interrupt mask to be disabled. A combination of
* - \ref SC_IER_ACON_ERR_IE_Msk
* - \ref SC_IER_RTMR_IE_Msk
* - \ref SC_IER_INIT_IE_Msk
* - \ref SC_IER_CD_IE_Msk
* - \ref SC_IER_BGT_IE_Msk
* - \ref SC_IER_TMR2_IE_Msk
* - \ref SC_IER_TMR1_IE_Msk
* - \ref SC_IER_TMR0_IE_Msk
* - \ref SC_IER_TERR_IE_Msk
* - \ref SC_IER_TBE_IE_Msk
* - \ref SC_IER_RDA_IE_Msk
* @return None
* @details The macro is used to disable Auto-convention error interrupt, Receiver buffer time-out interrupt, Initial end interrupt,
* Card detect interrupt, Block guard time interrupt, Timer2 interrupt, Timer1 interrupt, Timer0 interrupt,
* Transfer error interrupt, Transmit buffer empty interrupt or Receive data reach trigger level interrupt.
* \hideinitializer
*/
#define SC_DISABLE_INT(sc, u32Mask) ((sc)->IER &= ~(u32Mask))
/**
* @brief This macro set VCC pin state of smartcard interface.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32State Pin state of VCC pin, valid parameters are:
* \ref SC_PIN_STATE_HIGH :Smartcard pin status high.
* \ref SC_PIN_STATE_LOW :Smartcard pin status low.
* @return None
* @details User can set POW_EN (SC_PINCSR[0]) and POW_INV (SC_PINCSR[11])to decide SC_PWR pin is in high or low level.
* \hideinitializer
*/
#define SC_SET_VCC_PIN(sc, u32State) \
do {\
while((sc)->PINCSR & SC_PINCSR_SYNC_Msk);\
if((u32State))\
(sc)->PINCSR |= SC_PINCSR_POW_EN_Msk;\
else\
(sc)->PINCSR &= ~SC_PINCSR_POW_EN_Msk;\
}while(0)
/**
* @brief Set CLK output status.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32OnOff Clock on or off for selected smartcard module, valid values are:
* \ref SC_CLK_ON :Smartcard clock on.
* \ref SC_CLK_OFF :Smartcard clock off.
* @return None
* @details User can set CLK_KEEP (SC_PINCSR[6]) to decide SC_CLK pin always keeps free running or not.
* \hideinitializer
*/
#define SC_SET_CLK_PIN(sc, u32OnOff)\
do {\
while((sc)->PINCSR & SC_PINCSR_SYNC_Msk);\
if((u32OnOff))\
(sc)->PINCSR |= SC_PINCSR_CLK_KEEP_Msk;\
else\
(sc)->PINCSR &= ~(SC_PINCSR_CLK_KEEP_Msk);\
}while(0)
/**
* @brief Set I/O pin state.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32State Pin state of I/O pin, valid parameters are:
* \ref SC_PIN_STATE_HIGH :Smartcard pin status high.
* \ref SC_PIN_STATE_LOW :Smartcard pin status low.
* @return None
* @details User can set SC_DATA_O(SC_PINCSR[9]) to decide SC_DATA_O pin to high or low.
* \hideinitializer
*/
#define SC_SET_IO_PIN(sc, u32State)\
do {\
while((sc)->PINCSR & SC_PINCSR_SYNC_Msk);\
if((u32State))\
(sc)->PINCSR |= SC_PINCSR_SC_DATA_O_Msk;\
else\
(sc)->PINCSR &= ~SC_PINCSR_SC_DATA_O_Msk;\
}while(0)
/**
* @brief Set RST pin state.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32State Pin state of RST pin, valid parameters are:
* \ref SC_PIN_STATE_HIGH :Smartcard pin status high.
* \ref SC_PIN_STATE_LOW :Smartcard pin status low.
* @return None
* @details User can set SC_RST(SC_PINCSR[1]) to decide SC_RST pin to high or low.
* \hideinitializer
*/
#define SC_SET_RST_PIN(sc, u32State)\
do {\
while((sc)->PINCSR & SC_PINCSR_SYNC_Msk);\
if((u32State))\
(sc)->PINCSR |= SC_PINCSR_SC_RST_Msk;\
else\
(sc)->PINCSR &= ~SC_PINCSR_SC_RST_Msk;\
}while(0)
/**
* @brief Read one byte from smartcard module receive FIFO.
* @param[in] sc The pointer of smartcard module.
* @return One byte read from receive FIFO.
* @details By reading RBR register, the SC will return an 8-bit received data.
* \hideinitializer
*/
#define SC_READ(sc) ((char)((sc)->RBR))
/**
* @brief Write one byte to smartcard module transmit FIFO.
* @param[in] sc The pointer of smartcard module.
* @param[in] u8Data Data to write to transmit FIFO.
* @return None
* @details By writing data to THR register, the SC will send out an 8-bit data.
* \hideinitializer
*/
#define SC_WRITE(sc, u8Data) ((sc)->THR = (u8Data))
/**
* @brief This macro set smartcard stop bit length.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32Len Stop bit length, ether 1 or 2.
* @return None
* @details Stop bit length must be 1 for T = 1 protocol and 2 for T = 0 protocol.
* \hideinitializer
*/
#define SC_SET_STOP_BIT_LEN(sc, u32Len) ((sc)->CTL = ((sc)->CTL & ~SC_CTL_SLEN_Msk) | ((u32Len) == 1 ? SC_CTL_SLEN_Msk : 0))
/**
* @brief Enable/Disable Tx error retry, and set Tx error retry count.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32Count The number of times of Tx error retry count, between 0~8. 0 means disable Tx error retry.
* @return None
* @details This macro enable/disable transmitter retry function when parity error has occurred, and set error retry count.
*/
__STATIC_INLINE void SC_SetTxRetry(SC_T *sc, uint32_t u32Count)
{
while((sc)->CTL & SC_CTL_SYNC_Msk);
if((u32Count) == 0) // disable Tx error retry
{
(sc)->CTL &= ~(SC_CTL_TX_ERETRY_Msk | SC_CTL_TX_ERETRY_EN_Msk);
}
else
{
(sc)->CTL = ((sc)->CTL & ~SC_CTL_TX_ERETRY_Msk) | (((u32Count) - 1) << SC_CTL_TX_ERETRY_Pos) | SC_CTL_TX_ERETRY_EN_Msk;
}
}
/**
* @brief Enable/Disable Rx error retry, and set Rx error retry count.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32Count The number of times of Rx error retry count, between 0~8. 0 means disable Rx error retry.
* @return None
* @details This macro enable/disable receiver retry function when parity error has occurred, and set error retry count.
*/
__STATIC_INLINE void SC_SetRxRetry(SC_T *sc, uint32_t u32Count)
{
while((sc)->CTL & SC_CTL_SYNC_Msk);
if((u32Count) == 0) // disable Rx error retry
{
(sc)->CTL &= ~(SC_CTL_RX_ERETRY_Msk | SC_CTL_RX_ERETRY_EN_Msk);
}
else
{
(sc)->CTL = ((sc)->CTL & ~SC_CTL_RX_ERETRY_Msk) | (((u32Count) - 1) << SC_CTL_RX_ERETRY_Pos) | SC_CTL_RX_ERETRY_EN_Msk;
}
}
uint32_t SC_IsCardInserted(SC_T *sc);
void SC_ClearFIFO(SC_T *sc);
void SC_Close(SC_T *sc);
void SC_Open(SC_T *sc, uint32_t u32CardDet, uint32_t u32PWR);
void SC_ResetReader(SC_T *sc);
void SC_SetBlockGuardTime(SC_T *sc, uint32_t u32BGT);
void SC_SetCharGuardTime(SC_T *sc, uint32_t u32CGT);
void SC_StopAllTimer(SC_T *sc);
void SC_StartTimer(SC_T *sc, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount);
void SC_StopTimer(SC_T *sc, uint32_t u32TimerNum);
/*@}*/ /* end of group SC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SC_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__SC_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

392
BSP/StdDriver/inc/spi.h Normal file
View File

@ -0,0 +1,392 @@
/**************************************************************************//**
* @file spi.h
* @version V3.0
* $Revision: 15 $
* $Date: 15/05/28 9:45p $
* @brief SPI Driver Header File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __SPI_H__
#define __SPI_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup SPI_Driver SPI Driver
@{
*/
/** @addtogroup SPI_EXPORTED_CONSTANTS SPI Exported Constants
@{
*/
#define SPI_MODE_0 (SPI_CNTRL_TX_NEG_Msk) /*!< CLKP=0; RX_NEG=0; TX_NEG=1 */
#define SPI_MODE_1 (SPI_CNTRL_RX_NEG_Msk) /*!< CLKP=0; RX_NEG=1; TX_NEG=0 */
#define SPI_MODE_2 (SPI_CNTRL_CLKP_Msk | SPI_CNTRL_RX_NEG_Msk) /*!< CLKP=1; RX_NEG=1; TX_NEG=0 */
#define SPI_MODE_3 (SPI_CNTRL_CLKP_Msk | SPI_CNTRL_TX_NEG_Msk) /*!< CLKP=1; RX_NEG=0; TX_NEG=1 */
#define SPI_SLAVE (SPI_CNTRL_SLAVE_Msk) /*!< Set as slave */
#define SPI_MASTER (0x0) /*!< Set as master */
#define SPI_SS0 (1<<SPI_SSR_SSR_Pos) /*!< Select SPIn_SS0 */
#define SPI_SS1 (2<<SPI_SSR_SSR_Pos) /*!< Select SPIn_SS1 */
#define SPI_SS_ACTIVE_HIGH (SPI_SSR_SS_LVL_Msk) /*!< SS active high */
#define SPI_SS_ACTIVE_LOW (0x0) /*!< SS active low */
#define SPI_UNIT_INT_MASK (0x01) /*!< Unit transfer interrupt mask */
#define SPI_SSTA_INT_MASK (0x02) /*!< Slave 3-Wire mode start interrupt mask */
#define SPI_FIFO_TX_INT_MASK (0x04) /*!< FIFO TX interrupt mask */
#define SPI_FIFO_RX_INT_MASK (0x08) /*!< FIFO RX interrupt mask */
#define SPI_FIFO_RXOV_INT_MASK (0x10) /*!< FIFO RX overrun interrupt mask */
#define SPI_FIFO_TIMEOUT_INT_MASK (0x20) /*!< FIFO RX timeout interrupt mask */
#define SPI_BUSY_MASK (0x01) /*!< Busy status mask */
#define SPI_RX_EMPTY_MASK (0x02) /*!< RX empty status mask */
#define SPI_RX_FULL_MASK (0x04) /*!< RX full status mask */
#define SPI_TX_EMPTY_MASK (0x08) /*!< TX empty status mask */
#define SPI_TX_FULL_MASK (0x10) /*!< TX full status mask */
#define SPI_FIFO_SIZE (8) /*!< NUC200 Series provides separate 8-layer transmit and receive FIFO buffers */
/*@}*/ /* end of group SPI_EXPORTED_CONSTANTS */
/** @addtogroup SPI_EXPORTED_FUNCTIONS SPI Exported Functions
@{
*/
/**
* @brief Abort the current transfer in Slave 3-wire mode.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set the SLV_ABORT bit of SPI_CNTRL2 register to abort the current transfer in Slave 3-wire mode.
*/
#define SPI_ABORT_3WIRE_TRANSFER(spi) ((spi)->CNTRL2 |= SPI_CNTRL2_SLV_ABORT_Msk)
/**
* @brief Clear the Slave 3-wire mode start interrupt flag.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Write 1 to SLV_START_INTSTS bit of SPI_STATUS register to clear the Slave 3-wire mode start interrupt flag.
*/
#define SPI_CLR_3WIRE_START_INT_FLAG(spi) ((spi)->STATUS = SPI_STATUS_SLV_START_INTSTS_Msk)
/**
* @brief Clear the unit transfer interrupt flag.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Write 1 to IF bit of SPI_STATUS register to clear the unit transfer interrupt flag.
*/
#define SPI_CLR_UNIT_TRANS_INT_FLAG(spi) ((spi)->STATUS = SPI_STATUS_IF_Msk)
/**
* @brief Disable 2-bit Transfer mode.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Clear TWOB bit of SPI_CNTRL register to disable 2-bit Transfer mode.
*/
#define SPI_DISABLE_2BIT_MODE(spi) ((spi)->CNTRL &= ~SPI_CNTRL_TWOB_Msk)
/**
* @brief Disable Slave 3-wire mode.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Clear NOSLVSEL bit of SPI_CNTRL2 register to disable Slave 3-wire mode.
*/
#define SPI_DISABLE_3WIRE_MODE(spi) ((spi)->CNTRL2 &= ~SPI_CNTRL2_NOSLVSEL_Msk)
/**
* @brief Disable Dual I/O mode.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Clear DUAL_IO_EN bit of SPI_CNTRL2 register to disable Dual I/O mode.
*/
#define SPI_DISABLE_DUAL_MODE(spi) ((spi)->CNTRL2 &= ~SPI_CNTRL2_DUAL_IO_EN_Msk)
/**
* @brief Enable 2-bit Transfer mode.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set TWOB bit of SPI_CNTRL register to enable 2-bit Transfer mode.
*/
#define SPI_ENABLE_2BIT_MODE(spi) ((spi)->CNTRL |= SPI_CNTRL_TWOB_Msk)
/**
* @brief Enable Slave 3-wire mode.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set NOSLVSEL bit of SPI_CNTRL2 register to enable Slave 3-wire mode.
* Only available in Slave mode.
*/
#define SPI_ENABLE_3WIRE_MODE(spi) ((spi)->CNTRL2 |= SPI_CNTRL2_NOSLVSEL_Msk)
/**
* @brief Enable Dual input mode.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Clear DUAL_IO_DIR bit and set DUAL_IO_EN bit of SPI_CNTRL2 register to enable Dual input mode.
*/
#define SPI_ENABLE_DUAL_INPUT_MODE(spi) ((spi)->CNTRL2 = ((spi)->CNTRL2 & (~SPI_CNTRL2_DUAL_IO_DIR_Msk)) | SPI_CNTRL2_DUAL_IO_EN_Msk)
/**
* @brief Enable Dual output mode.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set DUAL_IO_DIR bit and DUAL_IO_EN bit of SPI_CNTRL2 register to enable Dual output mode.
*/
#define SPI_ENABLE_DUAL_OUTPUT_MODE(spi) ((spi)->CNTRL2 |= (SPI_CNTRL2_DUAL_IO_EN_Msk | SPI_CNTRL2_DUAL_IO_DIR_Msk))
/**
* @brief Trigger RX PDMA function.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set RX_DMA_GO bit of SPI_DMA register to enable RX PDMA transfer function.
*/
#define SPI_TRIGGER_RX_PDMA(spi) ((spi)->DMA |= SPI_DMA_RX_DMA_GO_Msk)
/**
* @brief Trigger TX PDMA function.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set TX_DMA_GO bit of SPI_DMA register to enable TX PDMA transfer function.
*/
#define SPI_TRIGGER_TX_PDMA(spi) ((spi)->DMA |= SPI_DMA_TX_DMA_GO_Msk)
/**
* @brief Trigger TX and RX PDMA function.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set TX_DMA_GO bit and RX_DMA_GO bit of SPI_DMA register to enable TX and RX PDMA transfer function.
*/
#define SPI_TRIGGER_TX_RX_PDMA(spi) ((spi)->DMA |= (SPI_DMA_TX_DMA_GO_Msk | SPI_DMA_RX_DMA_GO_Msk))
/**
* @brief Get the count of available data in RX FIFO.
* @param[in] spi The pointer of the specified SPI module.
* @return The count of available data in RX FIFO.
* @details Read RX_FIFO_COUNT (SPI_STATUS[15:12]) to get the count of available data in RX FIFO.
*/
#define SPI_GET_RX_FIFO_COUNT(spi) (((spi)->STATUS & SPI_STATUS_RX_FIFO_COUNT_Msk) >> SPI_STATUS_RX_FIFO_COUNT_Pos)
/**
* @brief Get the RX FIFO empty flag.
* @param[in] spi The pointer of the specified SPI module.
* @retval 0 RX FIFO is not empty.
* @retval 1 RX FIFO is empty.
* @details Read RX_EMPTY bit of SPI_STATUS register to get the RX FIFO empty flag.
*/
#define SPI_GET_RX_FIFO_EMPTY_FLAG(spi) (((spi)->STATUS & SPI_STATUS_RX_EMPTY_Msk)>>SPI_STATUS_RX_EMPTY_Pos)
/**
* @brief Get the TX FIFO empty flag.
* @param[in] spi The pointer of the specified SPI module.
* @retval 0 TX FIFO is not empty.
* @retval 1 TX FIFO is empty.
* @details Read TX_EMPTY bit of SPI_STATUS register to get the TX FIFO empty flag.
*/
#define SPI_GET_TX_FIFO_EMPTY_FLAG(spi) (((spi)->STATUS & SPI_STATUS_TX_EMPTY_Msk)>>SPI_STATUS_TX_EMPTY_Pos)
/**
* @brief Get the TX FIFO full flag.
* @param[in] spi The pointer of the specified SPI module.
* @retval 0 TX FIFO is not full.
* @retval 1 TX FIFO is full.
* @details Read TX_FULL bit of SPI_STATUS register to get the TX FIFO full flag.
*/
#define SPI_GET_TX_FIFO_FULL_FLAG(spi) (((spi)->STATUS & SPI_STATUS_TX_FULL_Msk)>>SPI_STATUS_TX_FULL_Pos)
/**
* @brief Get the datum read from RX0 register.
* @param[in] spi The pointer of the specified SPI module.
* @return Data in RX0 register.
* @details Read SPI_RX0 register to get the received datum.
*/
#define SPI_READ_RX0(spi) ((spi)->RX[0])
/**
* @brief Get the datum read from RX1 register.
* @param[in] spi The pointer of the specified SPI module.
* @return Data in RX1 register.
* @details Read SPI_RX1 register to get the received datum.
*/
#define SPI_READ_RX1(spi) ((spi)->RX[1])
/**
* @brief Write datum to TX0 register.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32TxData The datum which user attempt to transfer through SPI bus.
* @return None.
* @details Write u32TxData to TX0 register.
*/
#define SPI_WRITE_TX0(spi, u32TxData) ((spi)->TX[0] = (u32TxData))
/**
* @brief Write datum to TX1 register.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32TxData The datum which user attempt to transfer through SPI bus.
* @return None.
* @details Write u32TxData to TX1 register.
*/
#define SPI_WRITE_TX1(spi, u32TxData) ((spi)->TX[1] = (u32TxData))
/**
* @brief Set SPIn_SS0, SPIn_SS1 pin to high or low state.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] ss0 0 = Set SPIn_SS0 to low. 1 = Set SPIn_SS0 to high.
* @param[in] ss1 0 = Set SPIn_SS1 to low. 1 = Set SPIn_SS1 to high.
* @return None.
* @details Disable automatic slave selection function and set SPIn_SS0/SPIn_SS1 pin to specified high/low state.
* Only available in Master mode.
*/
#define SPI_SET_SS_LEVEL(spi, ss0, ss1) ((spi)->SSR = ((spi)->SSR & ~(SPI_SSR_AUTOSS_Msk|SPI_SSR_SS_LVL_Msk|SPI_SSR_SSR_Msk)) | (((ss1)^1) << 1) | ((ss0)^1))
/**
* @brief Set SPIn_SS0 pin to high state.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Disable automatic slave selection function and set SPIn_SS0 pin to high state. Only available in Master mode.
*/
#define SPI_SET_SS0_HIGH(spi) ((spi)->SSR = ((spi)->SSR & ~(SPI_SSR_AUTOSS_Msk|SPI_SSR_SS_LVL_Msk|SPI_SS0)))
/**
* @brief Set SPIn_SS1 pin to high state.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Disable automatic slave selection function and set SPIn_SS1 pin to high state. Only available in Master mode.
*/
#define SPI_SET_SS1_HIGH(spi) ((spi)->SSR = ((spi)->SSR & ~(SPI_SSR_AUTOSS_Msk|SPI_SSR_SS_LVL_Msk|SPI_SS1)))
/**
* @brief Set SPIn_SS0 pin to low state.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Disable automatic slave selection function and set SPIn_SS0 pin to low state. Only available in Master mode.
*/
#define SPI_SET_SS0_LOW(spi) ((spi)->SSR = ((spi)->SSR & ~(SPI_SSR_AUTOSS_Msk|SPI_SSR_SS_LVL_Msk|SPI_SS0)) | SPI_SS0)
/**
* @brief Set SPIn_SS1 pin to low state.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Disable automatic slave selection function and set SPIn_SS1 pin to low state. Only available in Master mode.
*/
#define SPI_SET_SS1_LOW(spi) ((spi)->SSR = ((spi)->SSR & ~(SPI_SSR_AUTOSS_Msk|SPI_SSR_SS_LVL_Msk|SPI_SS1)) | SPI_SS1)
/**
* @brief Enable Byte Reorder function.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set REORDER bit of SPI_CNTRL register to enable Byte Reorder function.
*/
#define SPI_ENABLE_BYTE_REORDER(spi) ((spi)->CNTRL |= SPI_CNTRL_REORDER_Msk)
/**
* @brief Disable Byte Reorder function.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Clear REORDER bit of SPI_CNTRL register to disable Byte Reorder function.
*/
#define SPI_DISABLE_BYTE_REORDER(spi) ((spi)->CNTRL &= ~SPI_CNTRL_REORDER_Msk)
/**
* @brief Set the length of suspend interval.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32SuspCycle Decides the length of suspend interval.
* @return None.
* @details Set the length of suspend interval according to u32SuspCycle.
* The length of suspend interval is ((u32SuspCycle + 0.5) * the length of one SPI bus clock cycle).
* Only available in Master mode.
*/
#define SPI_SET_SUSPEND_CYCLE(spi, u32SuspCycle) ((spi)->CNTRL = ((spi)->CNTRL & ~SPI_CNTRL_SP_CYCLE_Msk) | ((u32SuspCycle) << SPI_CNTRL_SP_CYCLE_Pos))
/**
* @brief Set the SPI transfer sequence with LSB first.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set LSB bit of SPI_CNTRL register to set the SPI transfer sequence with LSB first.
*/
#define SPI_SET_LSB_FIRST(spi) ((spi)->CNTRL |= SPI_CNTRL_LSB_Msk)
/**
* @brief Set the SPI transfer sequence with MSB first.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Clear LSB bit of SPI_CNTRL register to set the SPI transfer sequence with MSB first.
*/
#define SPI_SET_MSB_FIRST(spi) ((spi)->CNTRL &= ~SPI_CNTRL_LSB_Msk)
/**
* @brief Set the data width of a SPI transaction.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32Width The bit width of transfer data.
* @return None.
* @details The data width can be 8 ~ 32 bits.
*/
#define SPI_SET_DATA_WIDTH(spi, u32Width) ((spi)->CNTRL = ((spi)->CNTRL & ~SPI_CNTRL_TX_BIT_LEN_Msk) | (((u32Width)&0x1F) << SPI_CNTRL_TX_BIT_LEN_Pos))
/**
* @brief Get the SPI busy state.
* @param[in] spi The pointer of the specified SPI module.
* @retval 0 SPI controller is not busy.
* @retval 1 SPI controller is busy.
* @details This macro will return the busy state of SPI controller.
*/
#define SPI_IS_BUSY(spi) ( ((spi)->CNTRL & SPI_CNTRL_GO_BUSY_Msk)>>SPI_CNTRL_GO_BUSY_Pos )
/**
* @brief Set the GO_BUSY bit to trigger SPI transfer.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details If FIFO mode is disabled, user can use this macro to trigger the data transfer after all configuration is ready.
* If FIFO mode is enabled, user should not use this macro to trigger the data transfer. SPI controller will trigger the data transfer
* automatically after user write to SPI_TX0/1 register.
*/
#define SPI_TRIGGER(spi) ((spi)->CNTRL |= SPI_CNTRL_GO_BUSY_Msk)
/* Function prototype declaration */
uint32_t SPI_Open(SPI_T *spi, uint32_t u32MasterSlave, uint32_t u32SPIMode, uint32_t u32DataWidth, uint32_t u32BusClock);
void SPI_Close(SPI_T *spi);
void SPI_ClearRxFIFO(SPI_T *spi);
void SPI_ClearTxFIFO(SPI_T *spi);
void SPI_DisableAutoSS(SPI_T *spi);
void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel);
uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock);
void SPI_EnableFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold);
void SPI_DisableFIFO(SPI_T *spi);
uint32_t SPI_GetBusClock(SPI_T *spi);
void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask);
void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask);
uint32_t SPI_GetIntFlag(SPI_T *spi, uint32_t u32Mask);
void SPI_ClearIntFlag(SPI_T *spi, uint32_t u32Mask);
uint32_t SPI_GetStatus(SPI_T *spi, uint32_t u32Mask);
/**
* @} End of SPI Device Function Interface
*/
/**
* @} End of Function Interface
*/
/**
* @} End of Device_Driver
*/
#endif

1462
BSP/StdDriver/inc/sys.h Normal file

File diff suppressed because it is too large Load Diff

394
BSP/StdDriver/inc/timer.h Normal file
View File

@ -0,0 +1,394 @@
/**************************************************************************//**
* @file timer.h
* @version V3.00
* $Revision: 11 $
* $Date: 15/05/04 3:58p $
* @brief Timer driver header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __TIMER_H__
#define __TIMER_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup TIMER_Driver TIMER Driver
@{
*/
/** @addtogroup TIMER_EXPORTED_CONSTANTS TIMER Exported Constants
@{
*/
#define TIMER_ONESHOT_MODE (0UL << TIMER_TCSR_MODE_Pos) /*!< Timer working in one-shot mode */
#define TIMER_PERIODIC_MODE (1UL << TIMER_TCSR_MODE_Pos) /*!< Timer working in periodic mode */
#define TIMER_TOGGLE_MODE (2UL << TIMER_TCSR_MODE_Pos) /*!< Timer working in toggle-output mode */
#define TIMER_CONTINUOUS_MODE (3UL << TIMER_TCSR_MODE_Pos) /*!< Timer working in continuous counting mode */
#define TIMER_CAPTURE_FREE_COUNTING_MODE (0UL << TIMER_TEXCON_RSTCAPSEL_Pos) /*!< Timer capture event to get timer counter value */
#define TIMER_CAPTURE_COUNTER_RESET_MODE (1UL << TIMER_TEXCON_RSTCAPSEL_Pos) /*!< Timer capture event to reset timer counter */
#define TIMER_CAPTURE_FALLING_EDGE (0UL << TIMER_TEXCON_TEX_EDGE_Pos) /*!< Falling edge trigger timer capture */
#define TIMER_CAPTURE_RISING_EDGE (1UL << TIMER_TEXCON_TEX_EDGE_Pos) /*!< Rising edge trigger timer capture */
#define TIMER_CAPTURE_FALLING_AND_RISING_EDGE (2UL << TIMER_TEXCON_TEX_EDGE_Pos) /*!< Both falling and rising edge trigger timer capture */
#define TIMER_COUNTER_FALLING_EDGE (0UL << TIMER_TEXCON_TX_PHASE_Pos) /*!< Counter increase on falling edge */
#define TIMER_COUNTER_RISING_EDGE (1UL << TIMER_TEXCON_TX_PHASE_Pos) /*!< Counter increase on rising edge */
/*@}*/ /* end of group TIMER_EXPORTED_CONSTANTS */
/** @addtogroup TIMER_EXPORTED_FUNCTIONS TIMER Exported Functions
@{
*/
/**
* @brief Set Timer Compare Value
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Value Timer compare value. Valid values are between 2 to 0xFFFFFF.
*
* @return None
*
* @details This macro is used to set new Timer compared value.
*/
#define TIMER_SET_CMP_VALUE(timer, u32Value) ((timer)->TCMPR = (u32Value))
/**
* @brief Set Timer Prescale Value
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Value Timer prescale value. Valid values are between 0 to 0xFF.
*
* @return None
*
* @details This macro is used to set new Timer prescale value.
* @note Clock input is divided by (prescale + 1) before it is fed into timer.
*/
#define TIMER_SET_PRESCALE_VALUE(timer, u32Value) ((timer)->TCSR = ((timer)->TCSR & ~TIMER_TCSR_PRESCALE_Msk) | (u32Value))
/**
* @brief Check specify Timer Status
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @retval 0 Timer 24-bit up counter is inactive
* @retval 1 Timer 24-bit up counter is active
*
* @details This macro is used to check if specify Timer channel is inactive or active.
*/
#define TIMER_IS_ACTIVE(timer) ((timer)->TCSR & TIMER_TCSR_CACT_Msk ? 1 : 0)
/**
* @brief Start Timer Counting
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to start Timer counting.
*/
static __INLINE void TIMER_Start(TIMER_T *timer)
{
timer->TCSR |= TIMER_TCSR_CEN_Msk;
}
/**
* @brief Stop Timer Counting
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to stop/suspend Timer counting.
*/
static __INLINE void TIMER_Stop(TIMER_T *timer)
{
timer->TCSR &= ~TIMER_TCSR_CEN_Msk;
}
/**
* @brief Enable Timer Interrupt Wakeup Function
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to enable the Timer interrupt wake-up function.
* @note To wake the system from Power-down mode, timer clock source must be ether LXT or LIRC.
*/
static __INLINE void TIMER_EnableWakeup(TIMER_T *timer)
{
timer->TCSR |= TIMER_TCSR_WAKE_EN_Msk;
}
/**
* @brief Disable Timer Wakeup Function
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to disable the Timer interrupt wake-up function.
*/
static __INLINE void TIMER_DisableWakeup(TIMER_T *timer)
{
timer->TCSR &= ~TIMER_TCSR_WAKE_EN_Msk;
}
/**
* @brief Enable Capture Pin De-bounce
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to enable the capture pin detection de-bounce function.
*/
static __INLINE void TIMER_EnableCaptureDebounce(TIMER_T *timer)
{
timer->TEXCON |= TIMER_TEXCON_TEXDB_Msk;
}
/**
* @brief Disable Capture Pin De-bounce
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to disable the capture pin detection de-bounce function.
*/
static __INLINE void TIMER_DisableCaptureDebounce(TIMER_T *timer)
{
timer->TEXCON &= ~TIMER_TEXCON_TEXDB_Msk;
}
/**
* @brief Enable Counter Pin De-bounce
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to enable the counter pin detection de-bounce function.
*/
static __INLINE void TIMER_EnableEventCounterDebounce(TIMER_T *timer)
{
timer->TEXCON |= TIMER_TEXCON_TCDB_Msk;
}
/**
* @brief Disable Counter Pin De-bounce
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to disable the counter pin detection de-bounce function.
*/
static __INLINE void TIMER_DisableEventCounterDebounce(TIMER_T *timer)
{
timer->TEXCON &= ~TIMER_TEXCON_TCDB_Msk;
}
/**
* @brief Enable Timer Time-out Interrupt
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to enable the Timer time-out interrupt function.
*/
static __INLINE void TIMER_EnableInt(TIMER_T *timer)
{
timer->TCSR |= TIMER_TCSR_IE_Msk;
}
/**
* @brief Disable Timer Time-out Interrupt
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to disable the Timer time-out interrupt function.
*/
static __INLINE void TIMER_DisableInt(TIMER_T *timer)
{
timer->TCSR &= ~TIMER_TCSR_IE_Msk;
}
/**
* @brief Enable Capture Interrupt
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to enable the Timer capture trigger interrupt function.
*/
static __INLINE void TIMER_EnableCaptureInt(TIMER_T *timer)
{
timer->TEXCON |= TIMER_TEXCON_TEXIEN_Msk;
}
/**
* @brief Disable Capture Interrupt
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function is used to disable the Timer capture trigger interrupt function.
*/
static __INLINE void TIMER_DisableCaptureInt(TIMER_T *timer)
{
timer->TEXCON &= ~TIMER_TEXCON_TEXIEN_Msk;
}
/**
* @brief Get Timer Time-out Interrupt Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @retval 0 Timer time-out interrupt did not occur
* @retval 1 Timer time-out interrupt occurred
*
* @details This function indicates Timer time-out interrupt occurred or not.
*/
static __INLINE uint32_t TIMER_GetIntFlag(TIMER_T *timer)
{
return (timer->TISR & TIMER_TISR_TIF_Msk ? 1 : 0);
}
/**
* @brief Clear Timer time-out Interrupt Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function clears Timer time-out interrupt flag.
*/
static __INLINE void TIMER_ClearIntFlag(TIMER_T *timer)
{
timer->TISR = TIMER_TISR_TIF_Msk;
}
/**
* @brief Get Timer Capture Interrupt Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @retval 0 Timer capture interrupt did not occur
* @retval 1 Timer capture interrupt occurred
*
* @details This function indicates Timer capture interrupt occurred or not.
*/
static __INLINE uint32_t TIMER_GetCaptureIntFlag(TIMER_T *timer)
{
return timer->TEXISR;
}
/**
* @brief Clear Timer capture Interrupt Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function clears Timer capture interrupt flag.
*/
static __INLINE void TIMER_ClearCaptureIntFlag(TIMER_T *timer)
{
timer->TEXISR = TIMER_TEXISR_TEXIF_Msk;
}
/**
* @brief Get Timer Wakeup Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @retval 0 Timer did not wake up system
* @retval 1 Timer Timer wake up system
*
* @details This function indicates Timer has waked up system or not.
*/
static __INLINE uint32_t TIMER_GetWakeupFlag(TIMER_T *timer)
{
return (timer->TISR & TIMER_TISR_TWF_Msk ? 1 : 0);
}
/**
* @brief Clear Timer Wake-up Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This function clears the Timer wake-up system flag.
*/
static __INLINE void TIMER_ClearWakeupFlag(TIMER_T *timer)
{
timer->TISR = TIMER_TISR_TWF_Msk;
}
/**
* @brief Get Capture value
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return Capture Value
*
* @details This function reports the current timer capture data value.
*/
static __INLINE uint32_t TIMER_GetCaptureData(TIMER_T *timer)
{
return timer->TCAP;
}
/**
* @brief Get Counter value
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return Counter Value
*
* @details This function reports the current 24-bit timer counter value.
*/
static __INLINE uint32_t TIMER_GetCounter(TIMER_T *timer)
{
return timer->TDR;
}
uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq);
void TIMER_Close(TIMER_T *timer);
void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec);
void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge);
void TIMER_DisableCapture(TIMER_T *timer);
void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge);
void TIMER_DisableEventCounter(TIMER_T *timer);
uint32_t TIMER_GetModuleClock(TIMER_T *timer);
/*@}*/ /* end of group TIMER_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group TIMER_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__TIMER_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

460
BSP/StdDriver/inc/uart.h Normal file
View File

@ -0,0 +1,460 @@
/**************************************************************************//**
* @file UART.h
* @version V3.0
* $Revision: 27 $
* $Date: 15/06/04 11:16a $
* @brief UART Interface Controller Driver Header File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2011 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __UART_H__
#define __UART_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup UART_Driver UART Driver
@{
*/
/** @addtogroup UART_EXPORTED_CONSTANTS UART Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* UART FIFO size constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART0_FIFO_SIZE 64 /*!< UART0 supports separated receive/transmit 64/64 bytes entry FIFO */
#define UART1_FIFO_SIZE 16 /*!< UART1 supports separated receive/transmit 16/16 bytes entry FIFO */
#define UART2_FIFO_SIZE 16 /*!< UART2 supports separated receive/transmit 16/16 bytes entry FIFO */
/*---------------------------------------------------------------------------------------------------------*/
/* UA_FCR constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_FCR_RFITL_1BYTE (0x0 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 1 byte */
#define UART_FCR_RFITL_4BYTES (0x1 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 4 bytes */
#define UART_FCR_RFITL_8BYTES (0x2 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 8 bytes */
#define UART_FCR_RFITL_14BYTES (0x3 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 14 bytes */
#define UART_FCR_RFITL_30BYTES (0x4 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 30 bytes */
#define UART_FCR_RFITL_46BYTES (0x5 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 46 bytes */
#define UART_FCR_RFITL_62BYTES (0x6 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 62 bytes */
#define UART_FCR_RTS_TRI_LEV_1BYTE (0x0 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 1 byte */
#define UART_FCR_RTS_TRI_LEV_4BYTES (0x1 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 4 bytes */
#define UART_FCR_RTS_TRI_LEV_8BYTES (0x2 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 8 bytes */
#define UART_FCR_RTS_TRI_LEV_14BYTES (0x3 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 14 bytes */
#define UART_FCR_RTS_TRI_LEV_30BYTES (0x4 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 30 bytes */
#define UART_FCR_RTS_TRI_LEV_46BYTES (0x5 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 46 bytes */
#define UART_FCR_RTS_TRI_LEV_62BYTES (0x6 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 62 bytes */
/*---------------------------------------------------------------------------------------------------------*/
/* UA_LCR constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_WORD_LEN_5 (0) /*!< UA_LCR setting to set UART word length to 5 bits */
#define UART_WORD_LEN_6 (1) /*!< UA_LCR setting to set UART word length to 6 bits */
#define UART_WORD_LEN_7 (2) /*!< UA_LCR setting to set UART word length to 7 bits */
#define UART_WORD_LEN_8 (3) /*!< UA_LCR setting to set UART word length to 8 bits */
#define UART_PARITY_NONE (0x0 << UART_LCR_PBE_Pos) /*!< UA_LCR setting to set UART as no parity */
#define UART_PARITY_ODD (0x1 << UART_LCR_PBE_Pos) /*!< UA_LCR setting to set UART as odd parity */
#define UART_PARITY_EVEN (0x3 << UART_LCR_PBE_Pos) /*!< UA_LCR setting to set UART as even parity */
#define UART_PARITY_MARK (0x5 << UART_LCR_PBE_Pos) /*!< UA_LCR setting to keep parity bit as '1' */
#define UART_PARITY_SPACE (0x7 << UART_LCR_PBE_Pos) /*!< UA_LCR setting to keep parity bit as '0' */
#define UART_STOP_BIT_1 (0x0 << UART_LCR_NSB_Pos) /*!< UA_LCR setting for one stop bit */
#define UART_STOP_BIT_1_5 (0x1 << UART_LCR_NSB_Pos) /*!< UA_LCR setting for 1.5 stop bit when 5-bit word length */
#define UART_STOP_BIT_2 (0x1 << UART_LCR_NSB_Pos) /*!< UA_LCR setting for two stop bit when 6, 7, 8-bit word length */
/*---------------------------------------------------------------------------------------------------------*/
/* UART RTS LEVEL TRIGGER constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_RTS_IS_LOW_LEV_ACTIVE (0x1 << UART_MCR_LEV_RTS_Pos) /*!< Set RTS is Low Level Active */
#define UART_RTS_IS_HIGH_LEV_ACTIVE (0x0 << UART_MCR_LEV_RTS_Pos) /*!< Set RTS is High Level Active */
/*---------------------------------------------------------------------------------------------------------*/
/* UA_IRCR constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_IRCR_TX_SELECT (0x1 << UART_IRCR_TX_SELECT_Pos) /*!< Set IrDA function Tx mode */
#define UART_IRCR_RX_SELECT (0x0 << UART_IRCR_TX_SELECT_Pos) /*!< Set IrDA function Rx mode */
/*---------------------------------------------------------------------------------------------------------*/
/* UA_FUNC_SEL constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_FUNC_SEL_UART (0x0 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UA_FUNC_SEL setting to set UART Function (Default) */
#define UART_FUNC_SEL_LIN (0x1 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UA_FUNC_SEL setting to set LIN Function */
#define UART_FUNC_SEL_IrDA (0x2 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UA_FUNC_SEL setting to set IrDA Function */
#define UART_FUNC_SEL_RS485 (0x3 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UA_FUNC_SEL setting to set RS485 Function */
/*---------------------------------------------------------------------------------------------------------*/
/* UA_LIN_CTL constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_LIN_CTL_LINS_EN (0x1UL << UART_LIN_CTL_LINS_EN_Pos) /*!< UA_LIN_CTL setting to set LIN Slave Mode Enable */
#define UART_LIN_CTL_LINS_HDET_EN (0x1UL << UART_LIN_CTL_LINS_HDET_EN_Pos) /*!< UA_LIN_CTL setting to set LIN Slave Header Detection Enable */
#define UART_LIN_CTL_LINS_ARS_EN (0x1UL << UART_LIN_CTL_LINS_ARS_EN_Pos) /*!< UA_LIN_CTL setting to set LIN Slave Automatic Resynchronization Mode Enable */
#define UART_LIN_CTL_LINS_DUM_EN (0x1UL << UART_LIN_CTL_LINS_DUM_EN_Pos) /*!< UA_LIN_CTL setting to set LIN Slave Divider Update Method Enable */
#define UART_LIN_CTL_LIN_MUTE_EN (0x1UL << UART_LIN_CTL_LIN_MUTE_EN_Pos) /*!< UA_LIN_CTL setting to set LIN Mute Mode Enable */
#define UART_LIN_CTL_LIN_SHD (0x1UL << UART_LIN_CTL_LIN_SHD_Pos) /*!< UA_LIN_CTL setting to set LIN TX Send Header Enable */
#define UART_LIN_CTL_LIN_IDPEN (0x1UL << UART_LIN_CTL_LIN_IDPEN_Pos) /*!< UA_LIN_CTL setting to set LIN ID Parity Enable */
#define UART_LIN_CTL_LIN_BKDET_EN (0x1UL << UART_LIN_CTL_LIN_BKDET_EN_Pos) /*!< UA_LIN_CTL setting to set LIN Break Detection Enable */
#define UART_LIN_CTL_LIN_RX_DIS (0x1UL << UART_LIN_CTL_LIN_RX_DIS_Pos) /*!< UA_LIN_CTL setting to set LIN Receiver Disable */
#define UART_LIN_CTL_BIT_ERR_EN (0x1UL << UART_LIN_CTL_BIT_ERR_EN_Pos) /*!< UA_LIN_CTL setting to set Bit Error Detect Enable */
#define UART_LIN_CTL_LIN_BKFL(x) (((x)-1) << UART_LIN_CTL_LIN_BKFL_Pos) /*!< UA_LIN_CTL setting to set LIN Break Field Length, x = 10 ~ 15, default value is 12 */
#define UART_LIN_CTL_LIN_BS_LEN(x) (((x)-1) << UART_LIN_CTL_LIN_BS_LEN_Pos)/*!< UA_LIN_CTL setting to set LIN Break/Sync Delimiter Length, x = 1 ~ 4 */
#define UART_LIN_CTL_LIN_HEAD_SEL_BREAK (0x0UL << UART_LIN_CTL_LIN_HEAD_SEL_Pos) /*!< UA_LIN_CTL setting to set LIN Header Select to break field */
#define UART_LIN_CTL_LIN_HEAD_SEL_BREAK_SYNC (0x1UL << UART_LIN_CTL_LIN_HEAD_SEL_Pos) /*!< UA_LIN_CTL setting to set LIN Header Select to break field and sync field */
#define UART_LIN_CTL_LIN_HEAD_SEL_BREAK_SYNC_ID (0x2UL << UART_LIN_CTL_LIN_HEAD_SEL_Pos) /*!< UA_LIN_CTL setting to set LIN Header Select to break field, sync field and ID field*/
#define UART_LIN_CTL_LIN_LIN_PID(x) ((x) << UART_LIN_CTL_LIN_PID_Pos) /*!< UA_LIN_CTL setting to set LIN PID value */
/*---------------------------------------------------------------------------------------------------------*/
/* UART BAUDRATE MODE constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_BAUD_MODE0 (0) /*!< Set UART Baudrate Mode is Mode0 */
#define UART_BAUD_MODE2 (UART_BAUD_DIV_X_EN_Msk | UART_BAUD_DIV_X_ONE_Msk) /*!< Set UART Baudrate Mode is Mode2 */
/*@}*/ /* end of group UART_EXPORTED_CONSTANTS */
/** @addtogroup UART_EXPORTED_FUNCTIONS UART Exported Functions
@{
*/
/**
* @brief Calculate UART baudrate mode0 divider
*
* @param[in] u32SrcFreq UART clock frequency
* @param[in] u32BaudRate Baudrate of UART module
*
* @return UART baudrate mode0 divider
*
* @details This macro calculate UART baudrate mode0 divider.
*/
#define UART_BAUD_MODE0_DIVIDER(u32SrcFreq, u32BaudRate) ((((u32SrcFreq) + ((u32BaudRate)*8)) / (u32BaudRate) >> 4)-2)
/**
* @brief Calculate UART baudrate mode2 divider
*
* @param[in] u32SrcFreq UART clock frequency
* @param[in] u32BaudRate Baudrate of UART module
*
* @return UART baudrate mode2 divider
*
* @details This macro calculate UART baudrate mode2 divider.
*/
#define UART_BAUD_MODE2_DIVIDER(u32SrcFreq, u32BaudRate) ((((u32SrcFreq) + ((u32BaudRate)/2)) / (u32BaudRate))-2)
/**
* @brief Write data
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u8Data Data byte to transmit.
*
* @return None
*
* @details This macro write Data to Tx data register.
*/
#define UART_WRITE(uart, u8Data) ((uart)->THR = (u8Data))
/**
* @brief Read data
*
* @param[in] uart The pointer of the specified UART module.
*
* @return The oldest data byte in RX FIFO.
*
* @details This macro read Rx data register.
*/
#define UART_READ(uart) ((uart)->RBR)
/**
* @brief Get Tx empty
*
* @param[in] uart The pointer of the specified UART module.
*
* @retval 0 Tx FIFO is not empty
* @retval >=1 Tx FIFO is empty
*
* @details This macro get Tx empty register value.
*/
#define UART_GET_TX_EMPTY(uart) ((uart)->FSR & UART_FSR_TX_EMPTY_Msk)
/**
* @brief Get Rx empty
*
* @param[in] uart The pointer of the specified UART module.
*
* @retval 0 Rx FIFO is not empty
* @retval >=1 Rx FIFO is empty
*
* @details This macro get Rx empty register value.
*/
#define UART_GET_RX_EMPTY(uart) ((uart)->FSR & UART_FSR_RX_EMPTY_Msk)
/**
* @brief Check specified uart port transmission is over.
*
* @param[in] uart The pointer of the specified UART module.
*
* @retval 0 Transmission is not over.
* @retval 1 Transmission is over.
*
* @details This macro return if Tx FIFO is empty and specified uart port transmission is over nor not.
*/
#define UART_IS_TX_EMPTY(uart) (((uart)->FSR & UART_FSR_TE_FLAG_Msk) >> UART_FSR_TE_FLAG_Pos)
/**
* @brief Wait specified uart port transmission is over
*
* @param[in] uart The pointer of the specified UART module.
*
* @return None
*
* @details This macro wait specified uart port transmission is over.
*/
#define UART_WAIT_TX_EMPTY(uart) while(!((((uart)->FSR) & UART_FSR_TE_FLAG_Msk) >> UART_FSR_TE_FLAG_Pos))
/**
* @brief Check RX is ready or not
*
* @param[in] uart The pointer of the specified UART module.
*
* @retval 0 The number of bytes in the RX FIFO is less than the RFITL
* @retval 1 The number of bytes in the RX FIFO equals or larger than RFITL
*
* @details This macro check receive data available interrupt flag is set or not.
*/
#define UART_IS_RX_READY(uart) (((uart)->ISR & UART_ISR_RDA_IF_Msk)>>UART_ISR_RDA_IF_Pos)
/**
* @brief Check TX FIFO is full or not
*
* @param[in] uart The pointer of the specified UART module.
*
* @retval 1 TX FIFO is full
* @retval 0 TX FIFO is not full
*
* @details This macro check TX FIFO is full or not.
*/
#define UART_IS_TX_FULL(uart) (((uart)->FSR & UART_FSR_TX_FULL_Msk)>>UART_FSR_TX_FULL_Pos)
/**
* @brief Check RX FIFO is full or not
*
* @param[in] uart The pointer of the specified UART module.
*
* @retval 1 RX FIFO is full
* @retval 0 RX FIFO is not full
*
* @details This macro check RX FIFO is full or not.
*/
#define UART_IS_RX_FULL(uart) (((uart)->FSR & UART_FSR_RX_FULL_Msk)>>UART_FSR_RX_FULL_Pos)
/**
* @brief Get Tx full register value
*
* @param[in] uart The pointer of the specified UART module.
*
* @retval 0 Tx FIFO is not full.
* @retval >=1 Tx FIFO is full.
*
* @details This macro get Tx full register value.
*/
#define UART_GET_TX_FULL(uart) ((uart)->FSR & UART_FSR_TX_FULL_Msk)
/**
* @brief Get Rx full register value
*
* @param[in] uart The pointer of the specified UART module.
*
* @retval 0 Rx FIFO is not full.
* @retval >=1 Rx FIFO is full.
*
* @details This macro get Rx full register value.
*/
#define UART_GET_RX_FULL(uart) ((uart)->FSR & UART_FSR_RX_FULL_Msk)
/**
* @brief Enable specified UART interrupt
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32eIntSel Interrupt type select
* - UART_IER_LIN_IEN_Msk : Lin bus interrupt
* - UART_IER_WAKE_EN_Msk : Wakeup interrupt
* - UART_IER_BUF_ERR_IEN_Msk : Buffer Error interrupt
* - UART_IER_TOUT_IEN_Msk : Rx time-out interrupt
* - UART_IER_MODEM_IEN_Msk : Modem interrupt
* - UART_IER_RLS_IEN_Msk : Rx Line status interrupt
* - UART_IER_THRE_IEN_Msk : Tx empty interrupt
* - UART_IER_RDA_IEN_Msk : Rx ready interrupt
*
* @return None
*
* @details This macro enable specified UART interrupt.
*/
#define UART_ENABLE_INT(uart, u32eIntSel) ((uart)->IER |= (u32eIntSel))
/**
* @brief Disable specified UART interrupt
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32eIntSel Interrupt type select
* - UART_IER_LIN_IEN_Msk : Lin bus interrupt
* - UART_IER_WAKE_EN_Msk : Wakeup interrupt
* - UART_IER_BUF_ERR_IEN_Msk : Buffer Error interrupt
* - UART_IER_TOUT_IEN_Msk : Rx time-out interrupt
* - UART_IER_MODEM_IEN_Msk : Modem interrupt
* - UART_IER_RLS_IEN_Msk : Rx Line status interrupt
* - UART_IER_THRE_IEN_Msk : Tx empty interrupt
* - UART_IER_RDA_IEN_Msk : Rx ready interrupt
* @return None
*
* @details This macro enable specified UART interrupt.
*/
#define UART_DISABLE_INT(uart, u32eIntSel) ((uart)->IER &= ~ (u32eIntSel))
/**
* @brief Get specified interrupt indicator status
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32eIntTypeFlag Interrupt Type Flag, should be
* - UART_ISR_HW_BUF_ERR_INT_Msk : In DMA Mode, Buffer Error Interrupt Indicator
* - UART_ISR_HW_TOUT_INT_Msk : In DMA Mode, Rx Time-out Interrupt Indicator
* - UART_ISR_HW_MODEM_INT_Msk : In DMA Mode, MODEM Status Interrupt Indicator
* - UART_ISR_HW_RLS_INT_Msk : In DMA Mode, Rx Line Status Interrupt Indicator
* - UART_ISR_HW_BUF_ERR_IF_Msk : In DMA Mode, Buffer Error Interrupt Flag
* - UART_ISR_HW_TOUT_IF_Msk : In DMA Mode, Rx Time-out Interrupt Flag
* - UART_ISR_HW_MODEM_IF_Msk : In DMA Mode, MODEM Status Interrupt Flag
* - UART_ISR_HW_RLS_IF_Msk : In DMA Mode, Rx Line Status Interrupt Flag
* - UART_ISR_LIN_INT_Msk : LIN Bus Interrupt Indicator
* - UART_ISR_BUF_ERR_INT_Msk : Buffer Error Interrupt Indicator
* - UART_ISR_TOUT_INT_Msk : Rx Time-out Interrupt Indicator
* - UART_ISR_MODEM_INT_Msk : MODEM Status Interrupt Indicator
* - UART_ISR_RLS_INT_Msk : Rx Line Status Interrupt Indicator
* - UART_ISR_THRE_INT_Msk : Tx Empty Interrupt Indicator
* - UART_ISR_RDA_INT_Msk : Rx Ready Interrupt Indicator
* - UART_ISR_LIN_IF_Msk : LIN Bus Interrupt Flag
* - UART_ISR_BUF_ERR_IF_Msk : Buffer Error Interrupt Flag
* - UART_ISR_TOUT_IF_Msk : Rx Time-out Interrupt Flag
* - UART_ISR_MODEM_IF_Msk : MODEM Status Interrupt Flag
* - UART_ISR_RLS_IF_Msk : Rx Line Status Interrupt Flag
* - UART_ISR_THRE_IF_Msk : Tx Empty Interrupt Flag
* - UART_ISR_RDA_IF_Msk : Rx Ready Interrupt Flag
*
* @retval 0 The specified interrupt is not happened.
* @retval 1 The specified interrupt is happened.
*
* @details This macro get specified interrupt flag or interrupt indicator status.
*/
#define UART_GET_INT_FLAG(uart,u32eIntTypeFlag) (((uart)->ISR & (u32eIntTypeFlag))?1:0)
/**
* @brief Set RTS pin to low
*
* @param[in] uart The pointer of the specified UART module.
*
* @return None
*
* @details This macro set RTS pin to low.
*/
__STATIC_INLINE void UART_CLEAR_RTS(UART_T* uart)
{
(uart)->MCR |= UART_MCR_LEV_RTS_Msk;
(uart)->MCR &= ~UART_MCR_RTS_Msk;
}
/**
* @brief Set RTS pin to high
*
* @param[in] uart The pointer of the specified UART module.
*
* @return None
*
* @details This macro set RTS pin to high.
*/
__STATIC_INLINE void UART_SET_RTS(UART_T* uart)
{
(uart)->MCR |= UART_MCR_LEV_RTS_Msk | UART_MCR_RTS_Msk;
}
/**
* @brief Clear RS-485 Address Byte Detection Flag
*
* @param[in] uart The pointer of the specified UART module.
*
* @return None
*
* @details This macro clear RS-485 address byte detection flag.
*/
#define UART_RS485_CLEAR_ADDR_FLAG(uart) ((uart)->FSR = UART_FSR_RS485_ADD_DETF_Msk)
/**
* @brief Get RS-485 Address Byte Detection Flag
*
* @param[in] uart The pointer of the specified UART module.
*
* @retval 0 Receiver detects a data that is not an address bit.
* @retval 1 Receiver detects a data that is an address bit.
*
* @details This macro get RS-485 address byte detection flag.
*/
#define UART_RS485_GET_ADDR_FLAG(uart) (((uart)->FSR & UART_FSR_RS485_ADD_DETF_Msk) >> UART_FSR_RS485_ADD_DETF_Pos)
void UART_ClearIntFlag(UART_T* uart , uint32_t u32InterruptFlag);
void UART_Close(UART_T* uart);
void UART_DisableFlowCtrl(UART_T* uart);
void UART_DisableInt(UART_T* uart, uint32_t u32InterruptFlag);
void UART_EnableFlowCtrl(UART_T* uart);
void UART_EnableInt(UART_T* uart, uint32_t u32InterruptFlag);
void UART_Open(UART_T* uart, uint32_t u32baudrate);
uint32_t UART_Read(UART_T* uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes);
void UART_SetLine_Config(UART_T* uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits);
void UART_SetTimeoutCnt(UART_T* uart, uint32_t u32TOC);
void UART_SelectIrDAMode(UART_T* uart, uint32_t u32Buadrate, uint32_t u32Direction);
void UART_SelectRS485Mode(UART_T* uart, uint32_t u32Mode, uint32_t u32Addr);
void UART_SelectLINMode(UART_T* uart, uint32_t u32Mode, uint32_t u32BreakLength);
uint32_t UART_Write(UART_T* uart, uint8_t *pu8TxBuf, uint32_t u32WriteBytes);
/*@}*/ /* end of group UART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group UART_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__UART_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

668
BSP/StdDriver/inc/usbd.h Normal file
View File

@ -0,0 +1,668 @@
/**************************************************************************//**
* @file usbd.h
* @version V3.0
* $Revision: 17 $
* $Date: 15/05/28 8:42p $
* @brief USB driver header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __USBD_H__
#define __USBD_H__
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup USBD_Driver USBD Driver
@{
*/
/** @addtogroup USBD_EXPORTED_STRUCTS USBD Exported Structs
@{
*/
typedef struct s_usbd_info
{
const uint8_t *gu8DevDesc; /*!< Pointer for USB Device Descriptor */
const uint8_t *gu8ConfigDesc; /*!< Pointer for USB Configuration Descriptor */
const uint8_t **gu8StringDesc; /*!< Pointer for USB String Descriptor pointers */
const uint8_t *gu8HidReportDesc; /*!< Pointer for USB HID Report Descriptor */
} S_USBD_INFO_T;
extern const S_USBD_INFO_T gsInfo;
/*@}*/ /* end of group USBD_EXPORTED_STRUCTS */
/** @addtogroup USBD_EXPORTED_CONSTANTS USBD Exported Constants
@{
*/
#define USBD_BUF_BASE (USBD_BASE+0x100)
#define USBD_MAX_EP 6
#define EP0 0 /*!< Endpoint 0 */
#define EP1 1 /*!< Endpoint 1 */
#define EP2 2 /*!< Endpoint 2 */
#define EP3 3 /*!< Endpoint 3 */
#define EP4 4 /*!< Endpoint 4 */
#define EP5 5 /*!< Endpoint 5 */
/*!<USB Request Type */
#define REQ_STANDARD 0x00
#define REQ_CLASS 0x20
#define REQ_VENDOR 0x40
/*!<USB Standard Request */
#define GET_STATUS 0x00
#define CLEAR_FEATURE 0x01
#define SET_FEATURE 0x03
#define SET_ADDRESS 0x05
#define GET_DESCRIPTOR 0x06
#define SET_DESCRIPTOR 0x07
#define GET_CONFIGURATION 0x08
#define SET_CONFIGURATION 0x09
#define GET_INTERFACE 0x0A
#define SET_INTERFACE 0x0B
#define SYNC_FRAME 0x0C
/*!<USB Descriptor Type */
#define DESC_DEVICE 0x01
#define DESC_CONFIG 0x02
#define DESC_STRING 0x03
#define DESC_INTERFACE 0x04
#define DESC_ENDPOINT 0x05
#define DESC_QUALIFIER 0x06
#define DESC_OTHERSPEED 0x07
/*!<USB HID Descriptor Type */
#define DESC_HID 0x21
#define DESC_HID_RPT 0x22
/*!<USB Descriptor Length */
#define LEN_DEVICE 18
#define LEN_CONFIG 9
#define LEN_INTERFACE 9
#define LEN_ENDPOINT 7
#define LEN_HID 9
#define LEN_CCID 0x36
/*!<USB Endpoint Type */
#define EP_ISO 0x01
#define EP_BULK 0x02
#define EP_INT 0x03
#define EP_INPUT 0x80
#define EP_OUTPUT 0x00
/*!<USB Feature Selector */
#define FEATURE_DEVICE_REMOTE_WAKEUP 0x01
#define FEATURE_ENDPOINT_HALT 0x00
/******************************************************************************/
/* USB Specific Macros */
/******************************************************************************/
#define USBD_WAKEUP_EN USBD_INTEN_WAKEUP_EN_Msk /*!< USB Wake-up Enable */
#define USBD_DRVSE0 USBD_DRVSE0_DRVSE0_Msk /*!< Drive SE0 */
#define USBD_DPPU_EN USBD_ATTR_DPPU_EN_Msk /*!< USB D+ Pull-up Enable */
#define USBD_PWRDN USBD_ATTR_PWRDN_Msk /*!< PHY Turn-On */
#define USBD_PHY_EN USBD_ATTR_PHY_EN_Msk /*!< PHY Enable */
#define USBD_USB_EN USBD_ATTR_USB_EN_Msk /*!< USB Enable */
#define USBD_INT_BUS USBD_INTEN_BUS_IE_Msk /*!< USB Bus Event Interrupt */
#define USBD_INT_USB USBD_INTEN_USB_IE_Msk /*!< USB USB Event Interrupt */
#define USBD_INT_FLDET USBD_INTEN_FLDET_IE_Msk /*!< USB Float Detect Interrupt */
#define USBD_INT_WAKEUP (USBD_INTEN_WAKEUP_IE_Msk | USBD_INTEN_WAKEUP_EN_Msk) /*!< USB Wake-up Interrupt */
#define USBD_INTSTS_WAKEUP USBD_INTSTS_WAKEUP_STS_Msk /*!< USB Wakeup Interrupt Status */
#define USBD_INTSTS_FLDET USBD_INTSTS_FLDET_STS_Msk /*!< USB Float Detect Interrupt Status */
#define USBD_INTSTS_BUS USBD_INTSTS_BUS_STS_Msk /*!< USB Bus Event Interrupt Status */
#define USBD_INTSTS_USB USBD_INTSTS_USB_STS_Msk /*!< USB USB Event Interrupt Status */
#define USBD_INTSTS_SETUP USBD_INTSTS_SETUP_Msk /*!< USB Setup Event */
#define USBD_INTSTS_EP0 0x00010000 /*!< USB Endpoint 0 Event */
#define USBD_INTSTS_EP1 0x00020000 /*!< USB Endpoint 1 Event */
#define USBD_INTSTS_EP2 0x00040000 /*!< USB Endpoint 2 Event */
#define USBD_INTSTS_EP3 0x00080000 /*!< USB Endpoint 3 Event */
#define USBD_INTSTS_EP4 0x00100000 /*!< USB Endpoint 4 Event */
#define USBD_INTSTS_EP5 0x00200000 /*!< USB Endpoint 5 Event */
#define USBD_STATE_USBRST USBD_ATTR_USBRST_Msk /*!< USB Bus Reset */
#define USBD_STATE_SUSPEND USBD_ATTR_SUSPEND_Msk /*!< USB Bus Suspend */
#define USBD_STATE_RESUME USBD_ATTR_RESUME_Msk /*!< USB Bus Resume */
#define USBD_STATE_TIMEOUT USBD_ATTR_TIMEOUT_Msk /*!< USB Bus Timeout */
#define USBD_CFGP_SSTALL USBD_CFGP_SSTALL_Msk /*!< Set Stall */
#define USBD_CFG_CSTALL USBD_CFG_CSTALL_Msk /*!< Clear Stall */
#define USBD_CFG_EPMODE_DISABLE (0ul << USBD_CFG_STATE_Pos)/*!< Endpoint Disable */
#define USBD_CFG_EPMODE_OUT (1ul << USBD_CFG_STATE_Pos)/*!< Out Endpoint */
#define USBD_CFG_EPMODE_IN (2ul << USBD_CFG_STATE_Pos)/*!< In Endpoint */
#define USBD_CFG_TYPE_ISO (1ul << USBD_CFG_ISOCH_Pos) /*!< Isochronous */
#define USBD_STATE_DETACHED 0x00 /*!<USB Device Detached State Definition */
#define USBD_STATE_ATTACHED 0x01 /*!<USB Device Attached State Definition */
#define USBD_STATE_DEFAULT 0x11 /*!<USB Device Default State Definition */
#define USBD_STATE_ADDRESS 0x31 /*!<USB Device Addressed State Definition */
#define USBD_STATE_CONFIGURED 0x71 /*!<USB Device Configured State Definition */
#define USBD_STATE_FLAG_DEFAULT 0x10 /*!<USB Device State Default Flag */
#define USBD_STATE_FLAG_ADDRESS 0x20 /*!<USB Device State Addressed Flag */
#define USBD_STATE_FLAG_CONFIGURED 0x40 /*!<USB Device State Configured Flag */
#define USBD_STATE_FLAG_SUSPENDED 0x80 /*!<USB Device State Suspended Flag */
/*@}*/ /* end of group USBD_EXPORTED_CONSTANTS */
/** @addtogroup USBD_EXPORTED_FUNCTIONS USBD Exported Functions
@{
*/
/**
* @brief Compare two input numbers and return maximum one.
*
* @param[in] a First number to be compared.
* @param[in] b Second number to be compared.
*
* @return Maximum value between a and b.
*
* @details If a > b, then return a. Otherwise, return b.
*/
#define Maximum(a,b) ((a)>(b) ? (a) : (b))
/**
* @brief Compare two input numbers and return minimum one
*
* @param[in] a First number to be compared
* @param[in] b Second number to be compared
*
* @return Minimum value between a and b
*
* @details If a < b, then return a. Otherwise, return b.
*/
#define Minimum(a,b) ((a)<(b) ? (a) : (b))
/**
* @brief Enable USB
*
* @param None
*
* @return None
*
* @details To set USB ATTR control register to enable USB and PHY.
*
*/
#define USBD_ENABLE_USB() ((uint32_t)(USBD->ATTR |= (USBD_USB_EN|USBD_PHY_EN)))
/**
* @brief Disable USB
*
* @param None
*
* @return None
*
* @details To set USB ATTR control register to disable USB.
*
*/
#define USBD_DISABLE_USB() ((uint32_t)(USBD->ATTR &= ~USBD_USB_EN))
/**
* @brief Enable USB PHY
*
* @param None
*
* @return None
*
* @details To set USB ATTR control register to enable USB PHY.
*
*/
#define USBD_ENABLE_PHY() ((uint32_t)(USBD->ATTR |= USBD_PHY_EN))
/**
* @brief Disable USB PHY
*
* @param None
*
* @return None
*
* @details To set USB ATTR control register to disable USB PHY.
*
*/
#define USBD_DISABLE_PHY() ((uint32_t)(USBD->ATTR &= ~USBD_PHY_EN))
/**
* @brief Enable SE0. Force USB PHY transceiver to drive SE0.
*
* @param None
*
* @return None
*
* @details Set DRVSE0 bit of USB_DRVSE0 register to enable software-disconnect function. Force USB PHY transceiver to drive SE0 to bus.
*
*/
#define USBD_SET_SE0() ((uint32_t)(USBD->DRVSE0 |= USBD_DRVSE0))
/**
* @brief Disable SE0
*
* @param None
*
* @return None
*
* @details Clear DRVSE0 bit of USB_DRVSE0 register to disable software-disconnect function.
*
*/
#define USBD_CLR_SE0() ((uint32_t)(USBD->DRVSE0 &= ~USBD_DRVSE0))
/**
* @brief Set USB device address
*
* @param[in] addr The USB device address.
*
* @return None
*
* @details Write USB device address to USB_FADDR register.
*
*/
#define USBD_SET_ADDR(addr) (USBD->FADDR = (addr))
/**
* @brief Get USB device address
*
* @param None
*
* @return USB device address
*
* @details Read USB_FADDR register to get USB device address.
*
*/
#define USBD_GET_ADDR() ((uint32_t)(USBD->FADDR))
/**
* @brief Enable USB interrupt function
*
* @param[in] intr The combination of the specified interrupt enable bits.
* Each bit corresponds to a interrupt enable bit.
* This parameter decides which interrupts will be enabled.
* (USBD_INT_WAKEUP, USBD_INT_FLDET, USBD_INT_USB, USBD_INT_BUS)
*
* @return None
*
* @details Enable USB related interrupt functions specified by intr parameter.
*
*/
#define USBD_ENABLE_INT(intr) (USBD->INTEN |= (intr))
/**
* @brief Get interrupt status
*
* @param None
*
* @return The value of USB_INTSTS register
*
* @details Return all interrupt flags of USB_INTSTS register.
*
*/
#define USBD_GET_INT_FLAG() ((uint32_t)(USBD->INTSTS))
/**
* @brief Clear USB interrupt flag
*
* @param[in] flag The combination of the specified interrupt flags.
* Each bit corresponds to a interrupt source.
* This parameter decides which interrupt flags will be cleared.
* (USBD_INTSTS_WAKEUP, USBD_INTSTS_FLDET, USBD_INTSTS_BUS, USBD_INTSTS_USB)
*
* @return None
*
* @details Clear USB related interrupt flags specified by flag parameter.
*
*/
#define USBD_CLR_INT_FLAG(flag) (USBD->INTSTS = (flag))
/**
* @brief Get endpoint status
*
* @param None
*
* @return The value of USB_EPSTS register.
*
* @details Return all endpoint status.
*
*/
#define USBD_GET_EP_FLAG() ((uint32_t)(USBD->EPSTS))
/**
* @brief Get USB bus state
*
* @param None
*
* @return The value of USB_ATTR[3:0].
* Bit 0 indicates USB bus reset status.
* Bit 1 indicates USB bus suspend status.
* Bit 2 indicates USB bus resume status.
* Bit 3 indicates USB bus time-out status.
*
* @details Return USB_ATTR[3:0] for USB bus events.
*
*/
#define USBD_GET_BUS_STATE() ((uint32_t)(USBD->ATTR & 0xf))
/**
* @brief Check cable connection state
*
* @param None
*
* @retval 0 USB cable is not attached.
* 1 USB cable is attached.
*
* @details Check the connection state by FLDET bit of USB_FLDET register.
*
*/
#define USBD_IS_ATTACHED() ((uint32_t)(USBD->FLDET & USBD_FLDET_FLDET_Msk))
/**
* @brief Stop USB transaction of the specified endpoint
*
* @param[in] ep The USB endpoint buffer number.
*
* @return None
*
* @details Write 1 to CLRRDY bit of USB_CFGPx register to stop USB transaction of the specified endpoint.
*
*/
#define USBD_STOP_TRANSACTION(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) |= USBD_CFGP_CLRRDY_Msk)
/**
* @brief Set USB DATA1 PID for the specified endpoint
*
* @param[in] ep The USB endpoint buffer number.
*
* @return None
*
* @details Set DSQ_SYNC bit of USB_CFGx register to specify the DATA1 PID for the following IN token transaction.
* Base on this setting, hardware will toggle PID between DATA0 and DATA1 automatically for IN token transactions.
*
*/
#define USBD_SET_DATA1(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) |= USBD_CFG_DSQ_SYNC_Msk)
/**
* @brief Set USB DATA0 PID for the specified endpoint
*
* @param[in] ep The USB endpoint buffer number.
*
* @return None
*
* @details Clear DSQ_SYNC bit of USB_CFGx register to specify the DATA0 PID for the following IN token transaction.
* Base on this setting, hardware will toggle PID between DATA0 and DATA1 automatically for IN token transactions.
*
*/
#define USBD_SET_DATA0(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) &= (~USBD_CFG_DSQ_SYNC_Msk))
/**
* @brief Set USB payload size (IN data)
*
* @param[in] ep The USB endpoint buffer number.
*
* @param[in] size The transfer length.
*
* @return None
*
* @details This macro will write the transfer length to USB_MXPLDx register for IN data transaction.
*
*/
#define USBD_SET_PAYLOAD_LEN(ep, size) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].MXPLD + (uint32_t)((ep) << 4))) = (size))
/**
* @brief Get USB payload size (OUT data)
*
* @param[in] ep The USB endpoint buffer number.
*
* @return The value of USB_MXPLDx register.
*
* @details Get the data length of OUT data transaction by reading USB_MXPLDx register.
*
*/
#define USBD_GET_PAYLOAD_LEN(ep) ((uint32_t)*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].MXPLD + (uint32_t)((ep) << 4))))
/**
* @brief Configure endpoint
*
* @param[in] ep The USB endpoint buffer number.
*
* @param[in] config The USB configuration.
*
* @return None
*
* @details This macro will write config parameter to USB_CFGx register of specified endpoint.
*
*/
#define USBD_CONFIG_EP(ep, config) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) = (config))
/**
* @brief Set USB endpoint buffer
*
* @param[in] ep The USB endpoint buffer number.
*
* @param[in] offset The SRAM offset.
*
* @return None
*
* @details This macro will set the SRAM offset for the specified endpoint.
*
*/
#define USBD_SET_EP_BUF_ADDR(ep, offset) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].BUFSEG + (uint32_t)((ep) << 4))) = (offset))
/**
* @brief Get the offset of the specified USB endpoint buffer
*
* @param[in] ep The USB endpoint buffer number.
*
* @return The offset of the specified endpoint buffer.
*
* @details This macro will return the SRAM offset of the specified endpoint.
*
*/
#define USBD_GET_EP_BUF_ADDR(ep) ((uint32_t)*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].BUFSEG + (uint32_t)((ep) << 4))))
/**
* @brief Set USB endpoint stall state
*
* @param[in] ep The USB endpoint ID (USB endpoint buffer number).
*
* @return None
*
* @details Set USB endpoint stall state for the specified endpoint ID. Endpoint will respond STALL token automatically.
*
*/
#define USBD_SET_EP_STALL(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) |= USBD_CFGP_SSTALL_Msk)
/**
* @brief Clear USB endpoint stall state
*
* @param[in] ep The USB endpoint ID (USB endpoint buffer number).
*
* @return None
*
* @details Clear USB endpoint stall state for the specified endpoint ID. Endpoint will respond ACK/NAK token.
*/
#define USBD_CLR_EP_STALL(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) &= ~USBD_CFGP_SSTALL_Msk)
/**
* @brief Get USB endpoint stall state
*
* @param[in] ep The USB endpoint ID (USB endpoint buffer number).
*
* @retval 0 USB endpoint is not stalled.
* @retval Others USB endpoint is stalled.
*
* @details Get USB endpoint stall state of the specified endpoint ID.
*
*/
#define USBD_GET_EP_STALL(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) & USBD_CFGP_SSTALL_Msk)
/**
* @brief To support byte access between USB SRAM and system SRAM
*
* @param[in] dest Destination pointer.
*
* @param[in] src Source pointer.
*
* @param[in] size Byte count.
*
* @return None
*
* @details This function will copy the number of data specified by size and src parameters to the address specified by dest parameter.
*
*/
static __INLINE void USBD_MemCopy(uint8_t *dest, uint8_t *src, int32_t size)
{
while(size--) *dest++ = *src++;
}
/**
* @brief Set USB endpoint stall state
*
* @param[in] epnum USB endpoint number
*
* @return None
*
* @details Set USB endpoint stall state. Endpoint will respond STALL token automatically.
*
*/
static __INLINE void USBD_SetStall(uint8_t epnum)
{
uint32_t u32CfgAddr;
uint32_t u32Cfg;
int i;
for(i = 0; i < USBD_MAX_EP; i++)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
if((u32Cfg & 0xf) == epnum)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
*((__IO uint32_t *)(u32CfgAddr)) = (u32Cfg | USBD_CFGP_SSTALL);
break;
}
}
}
/**
* @brief Clear USB endpoint stall state
*
* @param[in] epnum USB endpoint number
*
* @return None
*
* @details Clear USB endpoint stall state. Endpoint will respond ACK/NAK token.
*/
static __INLINE void USBD_ClearStall(uint8_t epnum)
{
uint32_t u32CfgAddr;
uint32_t u32Cfg;
int i;
for(i = 0; i < USBD_MAX_EP; i++)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
if((u32Cfg & 0xf) == epnum)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
*((__IO uint32_t *)(u32CfgAddr)) = (u32Cfg & ~USBD_CFGP_SSTALL);
break;
}
}
}
/**
* @brief Get USB endpoint stall state
*
* @param[in] epnum USB endpoint number
*
* @retval 0 USB endpoint is not stalled.
* @retval Others USB endpoint is stalled.
*
* @details Get USB endpoint stall state.
*
*/
static __INLINE uint32_t USBD_GetStall(uint8_t epnum)
{
uint32_t u32CfgAddr;
uint32_t u32Cfg;
int i;
for(i = 0; i < USBD_MAX_EP; i++)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
if((u32Cfg & 0xf) == epnum)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */
break;
}
}
return ((*((__IO uint32_t *)(u32CfgAddr))) & USBD_CFGP_SSTALL);
}
extern volatile uint8_t g_usbd_RemoteWakeupEn;
typedef void (*VENDOR_REQ)(void); /*!< Functional pointer type declaration for Vendor class */
typedef void (*CLASS_REQ)(void); /*!< Functional pointer type definition for USB class request callback handler */
typedef void (*SET_INTERFACE_REQ)(void); /*!< Functional pointer type definition for USB set interface request callback handler */
typedef void (*SET_CONFIG_CB)(void); /*!< Functional pointer type declaration for USB set configuration request callback handler */
/*--------------------------------------------------------------------*/
void USBD_Open(const S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface);
void USBD_Start(void);
void USBD_GetSetupPacket(uint8_t *buf);
void USBD_ProcessSetupPacket(void);
void USBD_StandardRequest(void);
void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size);
void USBD_CtrlIn(void);
void USBD_PrepareCtrlOut(uint8_t *pu8Buf, uint32_t u32Size);
void USBD_CtrlOut(void);
void USBD_SwReset(void);
void USBD_SetVendorRequest(VENDOR_REQ pfnVendorReq);
void USBD_SetConfigCallback(SET_CONFIG_CB pfnSetConfigCallback);
void USBD_LockEpStall(uint32_t u32EpBitmap);
/*@}*/ /* end of group USBD_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group USBD_Driver */
/*@}*/ /* end of group Device_Driver */
#endif //__USBD_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

201
BSP/StdDriver/inc/wdt.h Normal file
View File

@ -0,0 +1,201 @@
/**************************************************************************//**
* @file wdt.h
* @version V3.00
* $Revision: 8 $
* $Date: 15/05/04 3:58p $
* @brief WDT driver header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __WDT_H__
#define __WDT_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup WDT_Driver WDT Driver
@{
*/
/** @addtogroup WDT_EXPORTED_CONSTANTS WDT Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* WTCR Constants Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define WDT_TIMEOUT_2POW4 (0UL << WDT_WTCR_WTIS_Pos) /*!< Setting WDT time-out interval to 2^4 * WDT clocks */
#define WDT_TIMEOUT_2POW6 (1UL << WDT_WTCR_WTIS_Pos) /*!< Setting WDT time-out interval to 2^6 * WDT clocks */
#define WDT_TIMEOUT_2POW8 (2UL << WDT_WTCR_WTIS_Pos) /*!< Setting WDT time-out interval to 2^8 * WDT clocks */
#define WDT_TIMEOUT_2POW10 (3UL << WDT_WTCR_WTIS_Pos) /*!< Setting WDT time-out interval to 2^10 * WDT clocks */
#define WDT_TIMEOUT_2POW12 (4UL << WDT_WTCR_WTIS_Pos) /*!< Setting WDT time-out interval to 2^12 * WDT clocks */
#define WDT_TIMEOUT_2POW14 (5UL << WDT_WTCR_WTIS_Pos) /*!< Setting WDT time-out interval to 2^14 * WDT clocks */
#define WDT_TIMEOUT_2POW16 (6UL << WDT_WTCR_WTIS_Pos) /*!< Setting WDT time-out interval to 2^16 * WDT clocks */
#define WDT_TIMEOUT_2POW18 (7UL << WDT_WTCR_WTIS_Pos) /*!< Setting WDT time-out interval to 2^18 * WDT clocks */
/*---------------------------------------------------------------------------------------------------------*/
/* WTCRALT Constants Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define WDT_RESET_DELAY_1026CLK (0UL << WDT_WTCRALT_WTRDSEL_Pos) /*!< Setting WDT reset delay period to 1026 * WDT clocks */
#define WDT_RESET_DELAY_130CLK (1UL << WDT_WTCRALT_WTRDSEL_Pos) /*!< Setting WDT reset delay period to 130 * WDT clocks */
#define WDT_RESET_DELAY_18CLK (2UL << WDT_WTCRALT_WTRDSEL_Pos) /*!< Setting WDT reset delay period to 18 * WDT clocks */
#define WDT_RESET_DELAY_3CLK (3UL << WDT_WTCRALT_WTRDSEL_Pos) /*!< Setting WDT reset delay period to 3 * WDT clocks */
/*@}*/ /* end of group WDT_EXPORTED_CONSTANTS */
/** @addtogroup WDT_EXPORTED_FUNCTIONS WDT Exported Functions
@{
*/
/**
* @brief Clear WDT Reset System Flag
*
* @param None
*
* @return None
*
* @details This macro clear WDT time-out reset system flag.
*/
#define WDT_CLEAR_RESET_FLAG() (WDT->WTCR = (WDT->WTCR & ~(WDT_WTCR_WTIF_Msk | WDT_WTCR_WTWKF_Msk)) | WDT_WTCR_WTRF_Msk)
/**
* @brief Clear WDT Time-out Interrupt Flag
*
* @param None
*
* @return None
*
* @details This macro clear WDT time-out interrupt flag.
*/
#define WDT_CLEAR_TIMEOUT_INT_FLAG() (WDT->WTCR = (WDT->WTCR & ~(WDT_WTCR_WTRF_Msk | WDT_WTCR_WTWKF_Msk)) | WDT_WTCR_WTIF_Msk)
/**
* @brief Clear WDT Wake-up Flag
*
* @param None
*
* @return None
*
* @details This macro clear WDT time-out wake-up system flag.
*/
#define WDT_CLEAR_TIMEOUT_WAKEUP_FLAG() (WDT->WTCR = (WDT->WTCR & ~(WDT_WTCR_WTRF_Msk | WDT_WTCR_WTIF_Msk)) | WDT_WTCR_WTWKF_Msk)
/**
* @brief Get WDT Time-out Reset Flag
*
* @param None
*
* @retval 0 WDT did not cause system reset
* @retval 1 WDT caused system reset
*
* @details This macro indicate WDT time-out to reset system or not.
*/
#define WDT_GET_RESET_FLAG() ((WDT->WTCR & WDT_WTCR_WTRF_Msk)? 1 : 0)
/**
* @brief Get WDT Time-out Interrupt Flag
*
* @param None
*
* @retval 0 WDT time-out interrupt did not occur
* @retval 1 WDT time-out interrupt occurred
*
* @details This macro indicate WDT time-out interrupt occurred or not.
*/
#define WDT_GET_TIMEOUT_INT_FLAG() ((WDT->WTCR & WDT_WTCR_WTIF_Msk)? 1 : 0)
/**
* @brief Get WDT Time-out Wake-up Flag
*
* @param None
*
* @retval 0 WDT did not wake up system
* @retval 1 WDT waked up system
*
* @details This macro indicate WDT time-out waked system up or not
*/
#define WDT_GET_TIMEOUT_WAKEUP_FLAG() ((WDT->WTCR & WDT_WTCR_WTWKF_Msk)? 1 : 0)
/**
* @brief Reset WDT Counter
*
* @param None
*
* @return None
*
* @details This macro is used to reset 18-bit WDT counter.
* @note If WDT is activated and enabled to reset system, user must reset WDT counter \n
* before WDT time-out plus reset delay reached. Or WDT generate a reset signal.
*/
#define WDT_RESET_COUNTER() (WDT->WTCR = (WDT->WTCR & ~(WDT_WTCR_WTIF_Msk | WDT_WTCR_WTWKF_Msk | WDT_WTCR_WTRF_Msk)) | WDT_WTCR_WTR_Msk)
/**
* @brief Stop WDT Counting
*
* @param None
*
* @return None
*
* @details This function stops WDT counting and disable WDT module.
*/
static __INLINE void WDT_Close(void)
{
WDT->WTCR = 0;
return;
}
/**
* @brief Enable WDT Time-out Interrupt
*
* @param None
*
* @return None
*
* @details This function enable the WDT time-out interrupt.
*/
static __INLINE void WDT_EnableInt(void)
{
WDT->WTCR |= WDT_WTCR_WTIE_Msk;
return;
}
/**
* @brief Disable WDT Time-out Interrupt
*
* @param None
*
* @return None
*
* @details This function disables the WDT time-out interrupt.
*/
static __INLINE void WDT_DisableInt(void)
{
// Do not touch write 1 clear bits
WDT->WTCR &= ~(WDT_WTCR_WTIE_Msk | WDT_WTCR_WTRF_Msk | WDT_WTCR_WTIF_Msk | WDT_WTCR_WTWKF_Msk);
return;
}
void WDT_Open(uint32_t u32TimeoutInterval, uint32_t u32ResetDelay, uint32_t u32EnableReset, uint32_t u32EnableWakeup);
/*@}*/ /* end of group WDT_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group WDT_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__WDT_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

145
BSP/StdDriver/inc/wwdt.h Normal file
View File

@ -0,0 +1,145 @@
/**************************************************************************//**
* @file wwdt.h
* @version V3.00
* $Revision: 9 $
* $Date: 15/05/04 3:58p $
* @brief WWDT driver header file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __WWDT_H__
#define __WWDT_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup WWDT_Driver WWDT Driver
@{
*/
/** @addtogroup WWDT_EXPORTED_CONSTANTS WWDT Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* WWDTCR Constants Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define WWDT_PRESCALER_1 (0 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 1 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_2 (1 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 2 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_4 (2 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 4 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_8 (3 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 8 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_16 (4 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 16 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_32 (5 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 32 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_64 (6 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 64 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_128 (7 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 128 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_192 (8 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 192 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_256 (9 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 256 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_384 (10 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 384 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_512 (11 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 512 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_768 (12 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 768 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_1024 (13 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 1024 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_1536 (14 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 1536 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_2048 (15 << WWDT_WWDTCR_PERIODSEL_Pos) /*!< Select max time-out period to 2048 * (64*WWDT_CLK) */
#define WWDT_RELOAD_WORD (0x00005AA5) /*!< Fill this value to WWDTRLD register to reload WWDT counter */
/*@}*/ /* end of group WWDT_EXPORTED_CONSTANTS */
/** @addtogroup WWDT_EXPORTED_FUNCTIONS WWDT Exported Functions
@{
*/
/**
* @brief Clear WWDT Reset System Flag
*
* @param None
*
* @return None
*
* @details This macro is used to clear WWDT counter time-out reset system flag.
*/
#define WWDT_CLEAR_RESET_FLAG() (WWDT->WWDTSR = WWDT_WWDTSR_WWDTRF_Msk)
/**
* @brief Clear WWDT Compared Match Interrupt Flag
*
* @param None
*
* @return None
*
* @details This macro is used to clear WWDT counter compare match interrupt flag.
*/
#define WWDT_CLEAR_INT_FLAG() (WWDT->WWDTSR = WWDT_WWDTSR_WWDTIF_Msk)
/**
* @brief Get WWDT Reset Flag
*
* @param None
*
* @retval 0 WWDT did not cause system reset
* @retval 1 WWDT counter time-out caused system reset
*
* @details This macro is used to indicate WWDT counter time-out reset system flag.
*/
#define WWDT_GET_RESET_FLAG() ((WWDT->WWDTSR & WWDT_WWDTSR_WWDTRF_Msk)? 1:0)
/**
* @brief Get WWDT Compared Match Interrupt Flag
*
* @param None
*
* @retval 0 WWDT counter compare match interrupt did not occur
* @retval 1 WWDT counter compare match interrupt occurred
*
* @details This macro is used to indicate WWDT counter compare match interrupt occurred or not.
*/
#define WWDT_GET_INT_FLAG() ((WWDT->WWDTSR & WWDT_WWDTSR_WWDTIF_Msk)? 1:0)
/**
* @brief Get WWDT Counter value
*
* @param None
*
* @return WWDT Counter Value
*
* @details This macro to reflects the current WWDT counter value.
*/
#define WWDT_GET_COUNTER() (WWDT->WWDTCVR)
/**
* @brief Reload WWDT Counter
*
* @param None
*
* @return None
*
* @details This macro is used to reload the WWDT counter value to 0x3F.
* @note After WWDT enabled, user must reload WWDT counter while current counter is less than compare value \n
* and larger than 0, otherwise WWDT will cause system reset immediately.
*/
#define WWDT_RELOAD_COUNTER() (WWDT->WWDTRLD = WWDT_RELOAD_WORD)
void WWDT_Open(uint32_t u32PreScale, uint32_t u32CmpValue, uint32_t u32EnableInt);
/*@}*/ /* end of group WWDT_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group WWDT_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__WWDT_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

83
BSP/StdDriver/src/acmp.c Normal file
View File

@ -0,0 +1,83 @@
/**************************************************************************//**
* @file acmp.c
* @version V3.00
* $Revision: 8 $
* $Date: 15/05/04 3:58p $
* @brief Analog Comparator(ACMP) driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup ACMP_Driver ACMP Driver
@{
*/
/** @addtogroup ACMP_EXPORTED_FUNCTIONS ACMP Exported Functions
@{
*/
/**
* @brief Configure the specified ACMP module
*
* @param[in] Acmp The pointer of the specified ACMP module.
* @param[in] u32ChNum Comparator number.
* @param[in] u32NegSrc Comparator negative input selection. Including:
* - \ref ACMP_CR_VNEG_PIN
* - \ref ACMP_CR_VNEG_BANDGAP
* @param[in] u32HysteresisEn The hysteresis function option. Including:
* - \ref ACMP_CR_HYSTERESIS_ENABLE
* - \ref ACMP_CR_HYSTERESIS_DISABLE
*
* @return None
*
* @details Configure hysteresis function, select the source of negative input and enable analog comparator.
*/
void ACMP_Open(ACMP_T *Acmp, uint32_t u32ChNum, uint32_t u32NegSrc, uint32_t u32HysteresisEn)
{
Acmp->CMPCR[u32ChNum] = (Acmp->CMPCR[u32ChNum] & (~(ACMP_CMPCR_CMPCN_Msk | ACMP_CMPCR_CMP_HYSEN_Msk))) | (u32NegSrc | u32HysteresisEn | ACMP_CMPCR_CMPEN_Msk);
}
/**
* @brief Close analog comparator
*
* @param[in] Acmp The pointer of the specified ACMP module.
* @param[in] u32ChNum Comparator number.
*
* @return None
*
* @details This function will clear CMPEN bit of CMPCR register to disable analog comparator.
*/
void ACMP_Close(ACMP_T *Acmp, uint32_t u32ChNum)
{
Acmp->CMPCR[u32ChNum] &= (~ACMP_CMPCR_CMPEN_Msk);
}
/*@}*/ /* end of group ACMP_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group ACMP_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

165
BSP/StdDriver/src/adc.c Normal file
View File

@ -0,0 +1,165 @@
/**************************************************************************//**
* @file adc.c
* @version V3.00
* $Revision: 10 $
* $Date: 15/05/04 3:59p $
* @brief ADC driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup ADC_Driver ADC Driver
@{
*/
/** @addtogroup ADC_EXPORTED_FUNCTIONS ADC Exported Functions
@{
*/
/**
* @brief This function configures ADC module to be ready for convert the input from selected channel.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32InputMode Decides the ADC analog input mode. Valid values are:
* - \ref ADC_ADCR_DIFFEN_SINGLE_END :Single end input mode.
* - \ref ADC_ADCR_DIFFEN_DIFFERENTIAL :Differential input type.
* @param[in] u32OpMode Decides the ADC operation mode. Valid values are:
* - \ref ADC_ADCR_ADMD_SINGLE :Single mode.
* - \ref ADC_ADCR_ADMD_SINGLE_CYCLE :Single cycle scan mode.
* - \ref ADC_ADCR_ADMD_CONTINUOUS :Continuous scan mode.
* @param[in] u32ChMask Channel enable bit. Each bit corresponds to a input channel. Bit 0 is channel 0, bit 1 is channel 1..., bit 7 is channel 7.
* @return None
* @details Before starting A/D conversion function, ADEN(ADCR[0]) should be set to 1.
* @note NUC200 series MCU ADC can only convert 1 channel at a time. If more than 1 channels are enabled, only channel
* with smallest number will be convert.
* @note This function does not turn on ADC power nor does trigger ADC conversion.
*/
void ADC_Open(ADC_T *adc,
uint32_t u32InputMode,
uint32_t u32OpMode,
uint32_t u32ChMask)
{
(adc)->ADCR = ((adc)->ADCR & (~(ADC_ADCR_DIFFEN_Msk | ADC_ADCR_ADMD_Msk))) | \
(u32InputMode) | \
(u32OpMode);
(adc)->ADCHER = ((adc)->ADCHER & ~ADC_ADCHER_CHEN_Msk) | (u32ChMask);
return;
}
/**
* @brief Disable ADC module.
* @param[in] adc The pointer of the specified ADC module.
* @return None
* @details Disable A/D converter analog circuit for saving power consumption.
*/
void ADC_Close(ADC_T *adc)
{
(adc)->ADCR &= (~ADC_ADCR_ADEN_Msk);
return;
}
/**
* @brief Configure the hardware trigger condition and enable hardware trigger.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32Source Decides the hardware trigger source. Valid values are:
* - \ref ADC_ADCR_TRGS_STADC :A/D conversion is started by external STADC pin.
* - \ref ADC_ADCR_TRGS_PWM :A/D conversion is started by PWM.
* @param[in] u32Param ADC trigger by external pin, this parameter is used to set trigger condition. Valid values are:
* - \ref ADC_ADCR_TRGCOND_LOW_LEVEL :STADC Low level active.
* - \ref ADC_ADCR_TRGCOND_HIGH_LEVEL :STADC High level active.
* - \ref ADC_ADCR_TRGCOND_FALLING_EDGE :STADC Falling edge active.
* - \ref ADC_ADCR_TRGCOND_RISING_EDGE :STADC Rising edge active.
* @return None
* @details Software should disable TRGEN (ADCR[8]) and ADST (ADCR[11]) before change TRGS(ADCR[5:4]).
*/
void ADC_EnableHWTrigger(ADC_T *adc,
uint32_t u32Source,
uint32_t u32Param)
{
(adc)->ADCR &= ~(ADC_ADCR_TRGS_Msk | ADC_ADCR_TRGCOND_Msk | ADC_ADCR_TRGEN_Msk);
(adc)->ADCR |= (u32Source) | (u32Param) | ADC_ADCR_TRGEN_Msk;
return;
}
/**
* @brief Disable hardware trigger ADC function.
* @param[in] adc The pointer of the specified ADC module.
* @return None
* @details Disable triggering of A/D conversion by hardware (external STADC pin or PWM Center-aligned trigger).
*/
void ADC_DisableHWTrigger(ADC_T *adc)
{
(adc)->ADCR &= ~(ADC_ADCR_TRGS_Msk | ADC_ADCR_TRGCOND_Msk | ADC_ADCR_TRGEN_Msk);
return;
}
/**
* @brief Enable the interrupt(s) selected by u32Mask parameter.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32Mask The combination of interrupt status bits listed below. Each bit
* corresponds to a interrupt status. This parameter decides which
* interrupts will be enabled.
* - \ref ADC_ADF_INT :ADC convert complete interrupt.
* - \ref ADC_CMP0_INT :ADC comparator 0 interrupt.
* - \ref ADC_CMP1_INT :ADC comparator 1 interrupt.
* @return None
* @details A/D conversion end interrupt request is generated if ADIE bit (ADCR[1]) is set to 1.
* If the compare function is enabled and the compare condition matches the setting of CMPCOND (ADCMPR0/1[2])
* and CMPMATCNT (ADCMPR0/1[11:8]), CMPF0/1 bit (ADSR[1]/[2]) will be asserted, in the meanwhile,
* if CMPIE (ADCMPR0/1[1]) is set to 1, a compare interrupt request is generated.
*/
void ADC_EnableInt(ADC_T *adc, uint32_t u32Mask)
{
if((u32Mask) & ADC_ADF_INT)
(adc)->ADCR |= ADC_ADCR_ADIE_Msk;
if((u32Mask) & ADC_CMP0_INT)
(adc)->ADCMPR[0] |= ADC_ADCMPR_CMPIE_Msk;
if((u32Mask) & ADC_CMP1_INT)
(adc)->ADCMPR[1] |= ADC_ADCMPR_CMPIE_Msk;
return;
}
/**
* @brief Disable the interrupt(s) selected by u32Mask parameter.
* @param[in] adc The pointer of the specified ADC module.
* @param[in] u32Mask The combination of interrupt status bits listed below. Each bit
* corresponds to a interrupt status. This parameter decides which
* interrupts will be disabled.
* - \ref ADC_ADF_INT :ADC convert complete interrupt.
* - \ref ADC_CMP0_INT :ADC comparator 0 interrupt.
* - \ref ADC_CMP1_INT :ADC comparator 1 interrupt.
* @return None
* @details The function is used to disable convert complete interrupt, comparator 0 interrupt or comparator 1 interrupt.
*/
void ADC_DisableInt(ADC_T *adc, uint32_t u32Mask)
{
if((u32Mask) & ADC_ADF_INT)
(adc)->ADCR &= ~ADC_ADCR_ADIE_Msk;
if((u32Mask) & ADC_CMP0_INT)
(adc)->ADCMPR[0] &= ~ADC_ADCMPR_CMPIE_Msk;
if((u32Mask) & ADC_CMP1_INT)
(adc)->ADCMPR[1] &= ~ADC_ADCMPR_CMPIE_Msk;
return;
}
/*@}*/ /* end of group ADC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group ADC_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

749
BSP/StdDriver/src/clk.c Normal file
View File

@ -0,0 +1,749 @@
/**************************************************************************//**
* @file clk.c
* @version V3.00
* $Revision: 49 $
* $Date: 15/10/20 8:30a $
* @brief CLK driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup CLK_Driver CLK Driver
@{
*/
/** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions
@{
*/
/**
* @brief Disable frequency output function
* @param None
* @return None
* @details This function disable frequency output function.
*/
void CLK_DisableCKO(void)
{
/* Disable CKO clock source */
CLK_DisableModuleClock(FDIV_MODULE);
}
/**
* @brief This function enable frequency divider module clock.
* enable frequency divider clock function and configure frequency divider.
* @param[in] u32ClkSrc is frequency divider function clock source. Including :
* - \ref CLK_CLKSEL2_FRQDIV_S_HXT
* - \ref CLK_CLKSEL2_FRQDIV_S_LXT
* - \ref CLK_CLKSEL2_FRQDIV_S_HCLK
* - \ref CLK_CLKSEL2_FRQDIV_S_HIRC
* @param[in] u32ClkDiv is divider output frequency selection.
* @param[in] u32ClkDivBy1En is not supported.
* @return None
*
* @details Output selected clock to CKO. The output clock frequency is divided by u32ClkDiv.
* The formula is:
* CKO frequency = (Clock source frequency) / 2^(u32ClkDiv + 1)
* This function is just used to set CKO clock.
* User must enable I/O for CKO clock output pin by themselves.
*/
void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En)
{
/* CKO = clock source / 2^(u32ClkDiv + 1) */
CLK->FRQDIV = CLK_FRQDIV_DIVIDER_EN_Msk | u32ClkDiv;
/* Enable CKO clock source */
CLK_EnableModuleClock(FDIV_MODULE);
/* Select CKO clock source */
CLK_SetModuleClock(FDIV_MODULE, u32ClkSrc, 0);
}
/**
* @brief Enter to Power-down mode
* @param None
* @return None
* @details This function let system enter to Power-down mode.
*/
void CLK_PowerDown(void)
{
/* Set the processor uses deep sleep as its low power mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
/* Set system Power-down enabled and Power-down entry condition */
CLK->PWRCON |= (CLK_PWRCON_PWR_DOWN_EN_Msk | CLK_PWRCON_PD_WAIT_CPU_Msk);
/* Chip enter Power-down mode after CPU run WFI instruction */
__WFI();
}
/**
* @brief Enter to Idle mode.
* @param None
* @return None
* @details This function let system enter to Idle mode.
*/
void CLK_Idle(void)
{
/* Set the processor uses sleep as its low power mode */
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
/* Set chip in idle mode because of WFI command */
CLK->PWRCON &= ~CLK_PWRCON_PWR_DOWN_EN_Msk;
/* Chip enter idle mode after CPU run WFI instruction */
__WFI();
}
/**
* @brief Get external high speed crystal clock frequency
* @param None
* @return External high frequency crystal frequency
* @details This function get external high frequency crystal frequency. The frequency unit is Hz.
*/
uint32_t CLK_GetHXTFreq(void)
{
if(CLK->PWRCON & CLK_PWRCON_XTL12M_EN_Msk)
return __HXT;
else
return 0;
}
/**
* @brief Get external low speed crystal clock frequency
* @param None
* @return External low speed crystal clock frequency
* @details This function get external low frequency crystal frequency. The frequency unit is Hz.
*/
uint32_t CLK_GetLXTFreq(void)
{
if(CLK->PWRCON & CLK_PWRCON_XTL32K_EN_Msk)
return __LXT;
else
return 0;
}
/**
* @brief Get HCLK frequency
* @param None
* @return HCLK frequency
* @details This function get HCLK frequency. The frequency unit is Hz.
*/
uint32_t CLK_GetHCLKFreq(void)
{
SystemCoreClockUpdate();
return SystemCoreClock;
}
/**
* @brief Get PCLK frequency
* @param None
* @return PCLK frequency
* @details This function get PCLK frequency. The frequency unit is Hz.
*/
uint32_t CLK_GetPCLKFreq(void)
{
SystemCoreClockUpdate();
return SystemCoreClock;
}
/**
* @brief Get CPU frequency
* @param None
* @return CPU frequency
* @details This function get CPU frequency. The frequency unit is Hz.
*/
uint32_t CLK_GetCPUFreq(void)
{
SystemCoreClockUpdate();
return SystemCoreClock;
}
/**
* @brief Set HCLK frequency
* @param[in] u32Hclk is HCLK frequency
* @return HCLK frequency
* @details This function set HCLK frequency. The frequency unit is Hz. The range of u32Hclk is 25 MHz ~ 50 MHz.
* The register write-protection function should be disabled before using this function.
*/
uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
{
uint32_t u32HIRCSTB;
/* Read HIRC clock source stable flag */
u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk;
/* Boundary Check */
if(u32Hclk > FREQ_50MHZ)
u32Hclk = FREQ_50MHZ;
if(u32Hclk < FREQ_25MHZ)
u32Hclk = FREQ_25MHZ;
/* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */
CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;
while((CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk) == 0);
CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK_S_Msk)) | CLK_CLKSEL0_HCLK_S_HIRC;
/* Disable PLL to Avoid PLL Unstable while Setting */
CLK->PLLCON |= CLK_PLLCON_PD_Msk;
/* Configure PLL setting if HXT clock is stable */
if(CLK->CLKSTATUS & CLK_CLKSTATUS_XTL12M_STB_Msk)
{
u32Hclk = CLK_EnablePLL(CLK_PLLCON_PLL_SRC_HXT, u32Hclk);
}
/* Configure PLL setting if HXT clock is not stable */
else
{
u32Hclk = CLK_EnablePLL(CLK_PLLCON_PLL_SRC_HIRC, u32Hclk);
/* Read HIRC clock source stable flag */
u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk;
}
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL, CLK_CLKDIV_HCLK(1));
/* Disable HIRC if HIRC is disabled before setting core clock */
if(u32HIRCSTB == 0)
CLK->PWRCON &= ~CLK_PWRCON_OSC22M_EN_Msk;
return u32Hclk;
}
/**
* @brief Set HCLK clock source and HCLK clock divider
* @param[in] u32ClkSrc is HCLK clock source. Including :
* - \ref CLK_CLKSEL0_HCLK_S_HXT
* - \ref CLK_CLKSEL0_HCLK_S_LXT
* - \ref CLK_CLKSEL0_HCLK_S_PLL
* - \ref CLK_CLKSEL0_HCLK_S_LIRC
* - \ref CLK_CLKSEL0_HCLK_S_HIRC
* @param[in] u32ClkDiv is HCLK clock divider. Including :
* - \ref CLK_CLKDIV_HCLK(x)
* @return None
* @details This function set HCLK clock source and HCLK clock divider.
* The register write-protection function should be disabled before using this function.
*/
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
{
uint32_t u32HIRCSTB;
/* Read HIRC clock source stable flag */
u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk;
/* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */
CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;
while((CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk) == 0);
CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK_S_Msk)) | CLK_CLKSEL0_HCLK_S_HIRC;
/* Apply new Divider */
CLK->CLKDIV = (CLK->CLKDIV & (~CLK_CLKDIV_HCLK_N_Msk)) | u32ClkDiv;
/* Switch to new HCLK source */
CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK_S_Msk)) | u32ClkSrc;
/* Update System Core Clock */
SystemCoreClockUpdate();
/* Disable HIRC if HIRC is disabled before switching HCLK source */
if(u32HIRCSTB == 0)
CLK->PWRCON &= ~CLK_PWRCON_OSC22M_EN_Msk;
}
/**
* @brief This function set selected module clock source and module clock divider
* @param[in] u32ModuleIdx is module index.
* @param[in] u32ClkSrc is module clock source.
* @param[in] u32ClkDiv is module clock divider.
* @return None
* @details Valid parameter combinations listed in following table:
*
* |Module index |Clock source |Divider |
* | :---------------- | :---------------------------------- | :--------------------- |
* |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDT_S_LIRC | x |
* |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDT_S_HCLK_DIV2048 | x |
* |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDT_S_LXT | x |
* |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADC_S_HXT |\ref CLK_CLKDIV_ADC(x) |
* |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADC_S_PLL |\ref CLK_CLKDIV_ADC(x) |
* |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADC_S_HCLK |\ref CLK_CLKDIV_ADC(x) |
* |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADC_S_HIRC |\ref CLK_CLKDIV_ADC(x) |
* |\ref SPI0_MODULE |\ref CLK_CLKSEL1_SPI0_S_HCLK | x |
* |\ref SPI0_MODULE |\ref CLK_CLKSEL1_SPI0_S_PLL | x |
* |\ref SPI1_MODULE |\ref CLK_CLKSEL1_SPI1_S_HCLK | x |
* |\ref SPI1_MODULE |\ref CLK_CLKSEL1_SPI1_S_PLL | x |
* |\ref SPI2_MODULE |\ref CLK_CLKSEL1_SPI2_S_HCLK | x |
* |\ref SPI2_MODULE |\ref CLK_CLKSEL1_SPI2_S_PLL | x |
* |\ref SPI3_MODULE |\ref CLK_CLKSEL1_SPI3_S_HCLK | x |
* |\ref SPI3_MODULE |\ref CLK_CLKSEL1_SPI3_S_PLL | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_HXT | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_LXT | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_HCLK | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_EXT_TRG | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_LIRC | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_HIRC | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_HXT | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_LXT | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_HCLK | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_EXT_TRG | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_LIRC | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_HIRC | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2_S_HXT | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2_S_LXT | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2_S_HCLK | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2_S_EXT_TRG | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2_S_LIRC | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2_S_HIRC | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3_S_HXT | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3_S_LXT | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3_S_HCLK | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3_S_EXT_TRG | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3_S_LIRC | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3_S_HIRC | x |
* |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART_S_HXT |\ref CLK_CLKDIV_UART(x) |
* |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART_S_PLL |\ref CLK_CLKDIV_UART(x) |
* |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART_S_HIRC |\ref CLK_CLKDIV_UART(x) |
* |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART_S_HXT |\ref CLK_CLKDIV_UART(x) |
* |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART_S_PLL |\ref CLK_CLKDIV_UART(x) |
* |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART_S_HIRC |\ref CLK_CLKDIV_UART(x) |
* |\ref UART2_MODULE |\ref CLK_CLKSEL1_UART_S_HXT |\ref CLK_CLKDIV_UART(x) |
* |\ref UART2_MODULE |\ref CLK_CLKSEL1_UART_S_PLL |\ref CLK_CLKDIV_UART(x) |
* |\ref UART2_MODULE |\ref CLK_CLKSEL1_UART_S_HIRC |\ref CLK_CLKDIV_UART(x) |
* |\ref PWM01_MODULE |\ref CLK_CLKSEL_PWM01_HXT | x |
* |\ref PWM01_MODULE |\ref CLK_CLKSEL_PWM01_LXT | x |
* |\ref PWM01_MODULE |\ref CLK_CLKSEL_PWM01_HCLK | x |
* |\ref PWM01_MODULE |\ref CLK_CLKSEL_PWM01_HIRC | x |
* |\ref PWM01_MODULE |\ref CLK_CLKSEL_PWM01_LIRC | x |
* |\ref PWM23_MODULE |\ref CLK_CLKSEL_PWM23_HXT | x |
* |\ref PWM23_MODULE |\ref CLK_CLKSEL_PWM23_LXT | x |
* |\ref PWM23_MODULE |\ref CLK_CLKSEL_PWM23_HCLK | x |
* |\ref PWM23_MODULE |\ref CLK_CLKSEL_PWM23_HIRC | x |
* |\ref PWM23_MODULE |\ref CLK_CLKSEL_PWM23_LIRC | x |
* |\ref I2S_MODULE |\ref CLK_CLKSEL2_I2S_S_HXT | x |
* |\ref I2S_MODULE |\ref CLK_CLKSEL2_I2S_S_PLL | x |
* |\ref I2S_MODULE |\ref CLK_CLKSEL2_I2S_S_HCLK | x |
* |\ref I2S_MODULE |\ref CLK_CLKSEL2_I2S_S_HIRC | x |
* |\ref FDIV_MODULE |\ref CLK_CLKSEL2_FRQDIV_S_HXT | x |
* |\ref FDIV_MODULE |\ref CLK_CLKSEL2_FRQDIV_S_LXT | x |
* |\ref FDIV_MODULE |\ref CLK_CLKSEL2_FRQDIV_S_HCLK | x |
* |\ref FDIV_MODULE |\ref CLK_CLKSEL2_FRQDIV_S_HIRC | x |
* |\ref PWM45_MODULE |\ref CLK_CLKSEL_PWM45_HXT | x |
* |\ref PWM45_MODULE |\ref CLK_CLKSEL_PWM45_LXT | x |
* |\ref PWM45_MODULE |\ref CLK_CLKSEL_PWM45_HCLK | x |
* |\ref PWM45_MODULE |\ref CLK_CLKSEL_PWM45_HIRC | x |
* |\ref PWM45_MODULE |\ref CLK_CLKSEL_PWM45_LIRC | x |
* |\ref PWM67_MODULE |\ref CLK_CLKSEL_PWM67_HXT | x |
* |\ref PWM67_MODULE |\ref CLK_CLKSEL_PWM67_LXT | x |
* |\ref PWM67_MODULE |\ref CLK_CLKSEL_PWM67_HCLK | x |
* |\ref PWM67_MODULE |\ref CLK_CLKSEL_PWM67_HIRC | x |
* |\ref PWM67_MODULE |\ref CLK_CLKSEL_PWM67_LIRC | x |
* |\ref WWDT_MODULE |\ref CLK_CLKSEL2_WWDT_S_HCLK_DIV2048 | x |
* |\ref WWDT_MODULE |\ref CLK_CLKSEL2_WWDT_S_LIRC | x |
* |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0_S_HXT |\ref CLK_CLKDIV1_SC0(x) |
* |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0_S_PLL |\ref CLK_CLKDIV1_SC0(x) |
* |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0_S_HCLK |\ref CLK_CLKDIV1_SC0(x) |
* |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0_S_HIRC |\ref CLK_CLKDIV1_SC0(x) |
* |\ref SC1_MODULE |\ref CLK_CLKSEL3_SC1_S_HXT |\ref CLK_CLKDIV1_SC1(x) |
* |\ref SC1_MODULE |\ref CLK_CLKSEL3_SC1_S_PLL |\ref CLK_CLKDIV1_SC1(x) |
* |\ref SC1_MODULE |\ref CLK_CLKSEL3_SC1_S_HCLK |\ref CLK_CLKDIV1_SC1(x) |
* |\ref SC1_MODULE |\ref CLK_CLKSEL3_SC1_S_HIRC |\ref CLK_CLKDIV1_SC1(x) |
* |\ref SC2_MODULE |\ref CLK_CLKSEL3_SC2_S_HXT |\ref CLK_CLKDIV1_SC2(x) |
* |\ref SC2_MODULE |\ref CLK_CLKSEL3_SC2_S_PLL |\ref CLK_CLKDIV1_SC2(x) |
* |\ref SC2_MODULE |\ref CLK_CLKSEL3_SC2_S_HCLK |\ref CLK_CLKDIV1_SC2(x) |
* |\ref SC2_MODULE |\ref CLK_CLKSEL3_SC2_S_HIRC |\ref CLK_CLKDIV1_SC2(x) |
* |\ref USBD_MODULE | x |\ref CLK_CLKDIV_USB(x) |
*/
void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
{
uint32_t u32sel = 0, u32div = 0;
uint32_t u32SelTbl[4] = {0x0, 0x4, 0xC, 0x24};
uint32_t u32DivTbl[2] = {0x0, 0x20};
if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk)
{
/* Get clock select control register address */
u32sel = (uint32_t)&CLK->CLKSEL0 + (u32SelTbl[MODULE_CLKSEL(u32ModuleIdx)]);
/* Set new clock selection setting */
M32(u32sel) = (M32(u32sel) & (~(MODULE_CLKSEL_Msk(u32ModuleIdx) << MODULE_CLKSEL_Pos(u32ModuleIdx)))) | u32ClkSrc;
/* We need to set CLKSEL2 ext control bit for PWM */
if(u32ModuleIdx == PWM01_MODULE)
CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_PWM01_S_E_Msk)) | (u32ClkSrc & CLK_CLKSEL2_PWM01_S_E_Msk);
else if(u32ModuleIdx == PWM23_MODULE)
CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_PWM23_S_E_Msk)) | (u32ClkSrc & CLK_CLKSEL2_PWM23_S_E_Msk);
else if(u32ModuleIdx == PWM45_MODULE)
CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_PWM45_S_E_Msk)) | (u32ClkSrc & CLK_CLKSEL2_PWM45_S_E_Msk);
else if(u32ModuleIdx == PWM67_MODULE)
CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_PWM67_S_E_Msk)) | (u32ClkSrc & CLK_CLKSEL2_PWM67_S_E_Msk);
}
if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk)
{
/* Get clock divider control register address */
u32div = (uint32_t)&CLK->CLKDIV + (u32DivTbl[MODULE_CLKDIV(u32ModuleIdx)]);
/* Apply new divider */
M32(u32div) = (M32(u32div) & (~(MODULE_CLKDIV_Msk(u32ModuleIdx) << MODULE_CLKDIV_Pos(u32ModuleIdx)))) | u32ClkDiv;
}
}
/**
* @brief Set SysTick clock source
* @param[in] u32ClkSrc is module clock source. Including:
* - \ref CLK_CLKSEL0_STCLK_S_HXT
* - \ref CLK_CLKSEL0_STCLK_S_LXT
* - \ref CLK_CLKSEL0_STCLK_S_HXT_DIV2
* - \ref CLK_CLKSEL0_STCLK_S_HCLK_DIV2
* - \ref CLK_CLKSEL0_STCLK_S_HIRC_DIV2
* @return None
* @details This function set SysTick clock source.
*/
void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)
{
CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLK_S_Msk) | u32ClkSrc;
}
/**
* @brief Enable clock source
* @param[in] u32ClkMask is clock source mask. Including :
* - \ref CLK_PWRCON_XTL12M_EN_Msk
* - \ref CLK_PWRCON_XTL32K_EN_Msk
* - \ref CLK_PWRCON_OSC22M_EN_Msk
* - \ref CLK_PWRCON_OSC10K_EN_Msk
* @return None
* @details This function enable clock source.
*/
void CLK_EnableXtalRC(uint32_t u32ClkMask)
{
CLK->PWRCON |= u32ClkMask;
}
/**
* @brief Disable clock source
* @param[in] u32ClkMask is clock source mask. Including :
* - \ref CLK_PWRCON_XTL12M_EN_Msk
* - \ref CLK_PWRCON_XTL32K_EN_Msk
* - \ref CLK_PWRCON_OSC22M_EN_Msk
* - \ref CLK_PWRCON_OSC10K_EN_Msk
* @return None
* @details This function disable clock source.
*/
void CLK_DisableXtalRC(uint32_t u32ClkMask)
{
CLK->PWRCON &= ~u32ClkMask;
}
/**
* @brief Enable module clock
* @param[in] u32ModuleIdx is module index. Including :
* - \ref PDMA_MODULE
* - \ref ISP_MODULE
* - \ref WDT_MODULE
* - \ref WWDT_MODULE
* - \ref RTC_MODULE
* - \ref TMR0_MODULE
* - \ref TMR1_MODULE
* - \ref TMR2_MODULE
* - \ref TMR3_MODULE
* - \ref FDIV_MODULE
* - \ref I2C0_MODULE
* - \ref I2C1_MODULE
* - \ref SPI0_MODULE
* - \ref SPI1_MODULE
* - \ref SPI2_MODULE
* - \ref SPI3_MODULE
* - \ref UART0_MODULE
* - \ref UART1_MODULE
* - \ref UART2_MODULE
* - \ref PWM01_MODULE
* - \ref PWM23_MODULE
* - \ref PWM45_MODULE
* - \ref PWM67_MODULE
* - \ref USBD_MODULE
* - \ref ADC_MODULE
* - \ref I2S_MODULE
* - \ref ACMP_MODULE
* - \ref PS2_MODULE
* - \ref SC0_MODULE
* - \ref SC1_MODULE
* - \ref SC2_MODULE
* @return None
* @details This function enable module clock.
*/
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
{
uint32_t u32OffsetTbl[4] = {0x0, 0x4, 0x2C, 0x0};
*(volatile uint32_t *)((uint32_t)&CLK->AHBCLK + u32OffsetTbl[MODULE_APBCLK(u32ModuleIdx)]) |= 1 << MODULE_IP_EN_Pos(u32ModuleIdx);
}
/**
* @brief Disable module clock
* @param[in] u32ModuleIdx is module index. Including :
* - \ref PDMA_MODULE
* - \ref ISP_MODULE
* - \ref WDT_MODULE
* - \ref WWDT_MODULE
* - \ref RTC_MODULE
* - \ref TMR0_MODULE
* - \ref TMR1_MODULE
* - \ref TMR2_MODULE
* - \ref TMR3_MODULE
* - \ref FDIV_MODULE
* - \ref I2C0_MODULE
* - \ref I2C1_MODULE
* - \ref SPI0_MODULE
* - \ref SPI1_MODULE
* - \ref SPI2_MODULE
* - \ref SPI3_MODULE
* - \ref UART0_MODULE
* - \ref UART1_MODULE
* - \ref UART2_MODULE
* - \ref PWM01_MODULE
* - \ref PWM23_MODULE
* - \ref PWM45_MODULE
* - \ref PWM67_MODULE
* - \ref USBD_MODULE
* - \ref ADC_MODULE
* - \ref I2S_MODULE
* - \ref ACMP_MODULE
* - \ref PS2_MODULE
* - \ref SC0_MODULE
* - \ref SC1_MODULE
* - \ref SC2_MODULE
* @return None
* @details This function disable module clock.
*/
void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
{
uint32_t u32OffsetTbl[4] = {0x0, 0x4, 0x2C, 0x0};
*(volatile uint32_t *)((uint32_t)&CLK->AHBCLK + u32OffsetTbl[MODULE_APBCLK(u32ModuleIdx)]) &= ~(1 << MODULE_IP_EN_Pos(u32ModuleIdx));
}
/**
* @brief Set PLL frequency
* @param[in] u32PllClkSrc is PLL clock source. Including :
* - \ref CLK_PLLCON_PLL_SRC_HXT
* - \ref CLK_PLLCON_PLL_SRC_HIRC
* @param[in] u32PllFreq is PLL frequency
* @return PLL frequency
* @details This function set PLL frequency.
* The register write-protection function should be disabled before using this function.
*/
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
{
uint32_t u32PllSrcClk, u32NR, u32NF, u32NO, u32CLK_SRC;
uint32_t u32Tmp, u32Tmp2, u32Tmp3, u32Min, u32MinNF, u32MinNR;
/* Disable PLL first to avoid unstable when setting PLL. */
CLK->PLLCON = CLK_PLLCON_PD_Msk;
/* PLL source clock is from HXT */
if(u32PllClkSrc == CLK_PLLCON_PLL_SRC_HXT)
{
/* Enable HXT clock */
CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk;
/* Wait for HXT clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
/* Select PLL source clock from HXT */
u32CLK_SRC = CLK_PLLCON_PLL_SRC_HXT;
u32PllSrcClk = __HXT;
/* u32NR start from 2 */
u32NR = 2;
}
/* PLL source clock is from HIRC */
else
{
/* Enable HIRC clock */
CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;
/* Wait for HIRC clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
/* Select PLL source clock from HIRC */
u32CLK_SRC = CLK_PLLCON_PLL_SRC_HIRC;
u32PllSrcClk = __HIRC;
/* u32NR start from 4 when FIN = 22.1184MHz to avoid calculation overflow */
u32NR = 4;
}
/* Select "NO" according to request frequency */
if((u32PllFreq <= FREQ_200MHZ) && (u32PllFreq > FREQ_100MHZ))
{
u32NO = 0;
}
else if((u32PllFreq <= FREQ_100MHZ) && (u32PllFreq > FREQ_50MHZ))
{
u32NO = 1;
u32PllFreq = u32PllFreq << 1;
}
else if((u32PllFreq <= FREQ_50MHZ) && (u32PllFreq >= FREQ_25MHZ))
{
u32NO = 3;
u32PllFreq = u32PllFreq << 2;
}
else
{
/* Wrong frequency request. Just return default setting. */
goto lexit;
}
/* Find best solution */
u32Min = (uint32_t) - 1;
u32MinNR = 0;
u32MinNF = 0;
for(; u32NR <= 33; u32NR++)
{
u32Tmp = u32PllSrcClk / u32NR;
if((u32Tmp > 1600000) && (u32Tmp < 15000000))
{
for(u32NF = 2; u32NF <= 513; u32NF++)
{
u32Tmp2 = u32Tmp * u32NF;
if((u32Tmp2 >= 100000000) && (u32Tmp2 <= 200000000))
{
u32Tmp3 = (u32Tmp2 > u32PllFreq) ? u32Tmp2 - u32PllFreq : u32PllFreq - u32Tmp2;
if(u32Tmp3 < u32Min)
{
u32Min = u32Tmp3;
u32MinNR = u32NR;
u32MinNF = u32NF;
/* Break when get good results */
if(u32Min == 0)
break;
}
}
}
}
}
/* Enable and apply new PLL setting. */
CLK->PLLCON = u32CLK_SRC | (u32NO << 14) | ((u32MinNR - 2) << 9) | (u32MinNF - 2);
/* Waiting for PLL clock stable */
CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);
/* Return actual PLL output clock frequency */
return u32PllSrcClk / ((u32NO + 1) * u32MinNR) * u32MinNF;
lexit:
/* Apply default PLL setting and return */
if(u32PllClkSrc == CLK_PLLCON_PLL_SRC_HXT)
CLK->PLLCON = 0xC22E; /* 48MHz */
else
CLK->PLLCON = 0x8D66F; /* 48.06498462MHz */
CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);
return CLK_GetPLLClockFreq();
}
/**
* @brief Disable PLL
* @param None
* @return None
* @details This function disable PLL.
*/
void CLK_DisablePLL(void)
{
CLK->PLLCON |= CLK_PLLCON_PD_Msk;
}
/**
* @brief This function check selected clock source status
* @param[in] u32ClkMask is selected clock source. Including :
* - \ref CLK_CLKSTATUS_XTL12M_STB_Msk
* - \ref CLK_CLKSTATUS_XTL32K_STB_Msk
* - \ref CLK_CLKSTATUS_OSC22M_STB_Msk
* - \ref CLK_CLKSTATUS_OSC10K_STB_Msk
* - \ref CLK_CLKSTATUS_PLL_STB_Msk
*
* @retval 0 clock is not stable
* @retval 1 clock is stable
*
* @details To wait for clock ready by specified CLKSTATUS bit or timeout (~300ms)
*/
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
{
int32_t i32TimeOutCnt = 1200000;
while((CLK->CLKSTATUS & u32ClkMask) != u32ClkMask)
{
if(i32TimeOutCnt-- <= 0)
return 0;
}
return 1;
}
/**
* @brief Enable System Tick counter
* @param[in] u32ClkSrc is System Tick clock source. Including:
* - \ref CLK_CLKSEL0_STCLK_S_HXT
* - \ref CLK_CLKSEL0_STCLK_S_LXT
* - \ref CLK_CLKSEL0_STCLK_S_HXT_DIV2
* - \ref CLK_CLKSEL0_STCLK_S_HCLK_DIV2
* - \ref CLK_CLKSEL0_STCLK_S_HIRC_DIV2
* - \ref CLK_CLKSEL0_STCLK_S_HCLK
* @param[in] u32Count is System Tick reload value. It could be 0~0xFFFFFF.
* @return None
* @details This function set System Tick clock source, reload value, enable System Tick counter and interrupt.
* The register write-protection function should be disabled before using this function.
*/
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
{
/* Set System Tick counter disabled */
SysTick->CTRL = 0;
/* Set System Tick clock source */
if( u32ClkSrc == CLK_CLKSEL0_STCLK_S_HCLK )
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
else
CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLK_S_Msk) | u32ClkSrc;
/* Set System Tick reload value */
SysTick->LOAD = u32Count;
/* Clear System Tick current value and counter flag */
SysTick->VAL = 0;
/* Set System Tick interrupt enabled and counter enabled */
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
}
/**
* @brief Disable System Tick counter
* @param None
* @return None
* @details This function disable System Tick counter.
*/
void CLK_DisableSysTick(void)
{
/* Set System Tick counter disabled */
SysTick->CTRL = 0;
}
/*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CLK_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

102
BSP/StdDriver/src/crc.c Normal file
View File

@ -0,0 +1,102 @@
/**************************************************************************//**
* @file crc.c
* @version V3.00
* $Revision: 8 $
* $Date: 15/05/04 3:59p $
* @brief CRC driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup CRC_Driver CRC Driver
@{
*/
/** @addtogroup CRC_EXPORTED_FUNCTIONS CRC Exported Functions
@{
*/
/**
* @brief CRC Open
*
* @param[in] u32Mode CRC Polynomial Mode. CRC_CCITT, CRC_8, CRC_16, CRC_32
* @param[in] u32Attribute Parameter attribute. CRC_CHECKSUM_COM, CRC_CHECKSUM_RVS, CRC_WDATA_COM, CRC_WDATA_RVS
* @param[in] u32Seed Seed value.
* @param[in] u32DataLen CPU Write Data Length. CRC_CPU_WDATA_8, CRC_CPU_WDATA_16, CRC_CPU_WDATA_32
*
* @return None
*
* @details This function enable the CRC channel by specify CRC mode, attribute, initial seed and write data length.
*/
void CRC_Open(uint32_t u32Mode, uint32_t u32Attribute, uint32_t u32Seed, uint32_t u32DataLen)
{
/* Enable CRC channel clock */
PDMA_GCR->GCRCSR |= PDMA_GCRCSR_CRC_CLK_EN_Msk;
CRC->SEED = u32Seed;
CRC->CTL = u32Mode | u32Attribute | u32DataLen | CRC_CTL_CRCCEN_Msk;
/* Setting RST bit will reload the initial seed value (CRC_SEED register) */
CRC->CTL |= CRC_CTL_CRC_RST_Msk;
}
/**
* @brief CRC Start DMA transfer
*
* @param[in] u32SrcAddr Source address
* @param[in] u32ByteCount Calculate byte count
*
* @return None
*
* @details This function start CRC DMA transfer from specify source address and byte counts.
*/
void CRC_StartDMATransfer(uint32_t u32SrcAddr, uint32_t u32ByteCount)
{
CRC->DMASAR = u32SrcAddr;
CRC->DMABCR = u32ByteCount;
CRC->CTL |= CRC_CTL_TRIG_EN_Msk;
}
/**
* @brief Get CRC Checksum
*
* @param[in] None
*
* @return Checksum
*
* @details This macro get the CRC checksum result by current CRC polynomial mode.
*/
uint32_t CRC_GetChecksum(void)
{
switch(CRC->CTL & CRC_CTL_CRC_MODE_Msk)
{
case CRC_CCITT:
case CRC_16:
return (CRC->CHECKSUM & 0xFFFF);
case CRC_32:
return (CRC->CHECKSUM);
case CRC_8:
return (CRC->CHECKSUM & 0xFF);
default:
return 0;
}
}
/*@}*/ /* end of group CRC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CRC_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

282
BSP/StdDriver/src/fmc.c Normal file
View File

@ -0,0 +1,282 @@
/**************************************************************************//**
* @file fmc.c
* @version V3.00
* $Revision: 8 $
* $Date: 15/05/04 3:59p $
* @brief FMC driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
//* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup FMC_Driver FMC Driver
@{
*/
/** @addtogroup FMC_EXPORTED_FUNCTIONS FMC Exported Functions
@{
*/
/**
* @brief Set boot source from LDROM or APROM after next software reset
*
* @param[in] i32BootSrc
* 1: Boot from LDROM,
* 0: Boot from APROM
*
* @return None
*
* @details This function is used to switch APROM boot or LDROM boot. User need to call
* FMC_SetBootSource to select boot source first, then use CPU reset or
* System Reset Request to reset system.
*
*/
void FMC_SetBootSource(int32_t i32BootSrc)
{
if(i32BootSrc)
FMC->ISPCON |= FMC_ISPCON_BS_Msk; /* Boot from LDROM */
else
FMC->ISPCON &= ~FMC_ISPCON_BS_Msk;/* Boot from APROM */
}
/**
* @brief Disable ISP Functions
*
* @param None
*
* @return None
*
* @details This function will clear ISPEN bit of ISPCON to disable ISP function
*
*/
void FMC_Close(void)
{
FMC->ISPCON &= ~FMC_ISPCON_ISPEN_Msk;
}
/**
* @brief Disable APROM update function
*
* @param None
*
* @return None
*
* @details Disable APROM update function will forbid APROM programming when boot form APROM.
* APROM update is default to be disable.
*
*/
void FMC_DisableAPUpdate(void)
{
FMC->ISPCON &= ~FMC_ISPCON_APUEN_Msk;
}
/**
* @brief Disable User Configuration update function
*
* @param None
*
* @return None
*
* @details Disable User Configuration update function will forbid User Configuration programming.
* User Configuration update is default to be disable.
*/
void FMC_DisableConfigUpdate(void)
{
FMC->ISPCON &= ~FMC_ISPCON_CFGUEN_Msk;
}
/**
* @brief Disable LDROM update function
*
* @param None
*
* @return None
* @details Disable LDROM update function will forbid LDROM programming.
* LDROM update is default to be disable.
*/
void FMC_DisableLDUpdate(void)
{
FMC->ISPCON &= ~FMC_ISPCON_LDUEN_Msk;
}
/**
* @brief Enable APROM update function
*
* @param None
*
* @return None
*
* @details Enable APROM to be able to program when boot from APROM.
*
*/
void FMC_EnableAPUpdate(void)
{
FMC->ISPCON |= FMC_ISPCON_APUEN_Msk;
}
/**
* @brief Enable User Configuration update function
*
* @param None
*
* @return None
*
* @details Enable User Configuration to be able to program.
*
*/
void FMC_EnableConfigUpdate(void)
{
FMC->ISPCON |= FMC_ISPCON_CFGUEN_Msk;
}
/**
* @brief Enable LDROM update function
*
* @param None
*
* @return None
*
* @details Enable LDROM to be able to program.
*
*/
void FMC_EnableLDUpdate(void)
{
FMC->ISPCON |= FMC_ISPCON_LDUEN_Msk;
}
/**
* @brief Get the current boot source
*
* @param None
*
* @retval 0 This chip is currently booting from APROM
* @retval 1 This chip is currently booting from LDROM
*
* @note This function only show the boot source.
* User need to read ISPSTA register to know if IAP mode supported or not in relative boot.
*/
int32_t FMC_GetBootSource(void)
{
if(FMC->ISPCON & FMC_ISPCON_BS_Msk)
return 1;
else
return 0;
}
/**
* @brief Enable FMC ISP function
*
* @param None
*
* @return None
*
* @details ISPEN bit of ISPCON must be set before we can use ISP commands.
* Therefore, To use all FMC function APIs, user needs to call FMC_Open() first to enable ISP functions.
*
* @note ISP functions are write-protected. user also needs to unlock it by calling SYS_UnlockReg() before using all ISP functions.
*
*/
void FMC_Open(void)
{
FMC->ISPCON |= FMC_ISPCON_ISPEN_Msk;
}
/**
* @brief Get the base address of Data Flash if enabled.
*
* @param None
*
* @return The base address of Data Flash
*
* @details This function is used to return the base address of Data Flash.
*
*/
uint32_t FMC_ReadDataFlashBaseAddr(void)
{
return FMC->DFBADR;
}
/**
* @brief Read the User Configuration words.
*
* @param[out] u32Config The word buffer to store the User Configuration data.
* @param[in] u32Count The word count to be read.
*
* @retval 0 Success
* @retval -1 Failed
*
* @details This function is used to read the settings of user configuration.
* if u32Count = 1, Only CONFIG0 will be returned to the buffer specified by u32Config.
* if u32Count = 2, Both CONFIG0 and CONFIG1 will be returned.
*/
int32_t FMC_ReadConfig(uint32_t *u32Config, uint32_t u32Count)
{
int32_t i;
for(i = 0; i < u32Count; i++)
u32Config[i] = FMC_Read(FMC_CONFIG_BASE + i * 4);
return 0;
}
/**
* @brief Write User Configuration
*
* @param[in] u32Config The word buffer to store the User Configuration data.
* @param[in] u32Count The word count to program to User Configuration.
*
* @retval 0 Success
* @retval -1 Failed
*
* @details User must enable User Configuration update before writing it.
* User must erase User Configuration before writing it.
* User Configuration is also be page erase. User needs to backup necessary data
* before erase User Configuration.
*/
int32_t FMC_WriteConfig(uint32_t *u32Config, uint32_t u32Count)
{
int32_t i;
for(i = 0; i < u32Count; i++)
{
FMC_Write(FMC_CONFIG_BASE + i * 4, u32Config[i]);
if(FMC_Read(FMC_CONFIG_BASE + i * 4) != u32Config[i])
return -1;
}
return 0;
}
/*@}*/ /* end of group FMC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group FMC_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

100
BSP/StdDriver/src/gpio.c Normal file
View File

@ -0,0 +1,100 @@
/**************************************************************************//**
* @file gpio.c
* @version V3.00
* $Revision: 9 $
* $Date: 15/05/04 3:59p $
* @brief GPIO driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup GPIO_Driver GPIO Driver
@{
*/
/** @addtogroup GPIO_EXPORTED_FUNCTIONS GPIO Exported Functions
@{
*/
/**
* @brief Set GPIO operation mode
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port.
* It could be BIT0 ~ BIT15 for PA, PB, PC, PD and PE GPIO port.
* It could be BIT0 ~ BIT3 for PF GPIO port.
* @param[in] u32Mode Operation mode. . It could be \n
* GPIO_PMD_INPUT, GPIO_PMD_OUTPUT, GPIO_PMD_OPEN_DRAIN, GPIO_PMD_QUASI.
*
* @return None
*
* @details This function is used to set specified GPIO operation mode.
*/
void GPIO_SetMode(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode)
{
uint32_t i;
for(i = 0; i < GPIO_PIN_MAX; i++)
{
if(u32PinMask & (1 << i))
{
port->PMD = (port->PMD & ~(0x3 << (i << 1))) | (u32Mode << (i << 1));
}
}
}
/**
* @brief Enable GPIO interrupt
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32Pin The pin of specified GPIO port.
* It could be 0 ~ 15 for PA, PB, PC, PD and PE GPIO port.
* It could be 0 ~ 3 for PF GPIO port.
* @param[in] u32IntAttribs The interrupt attribute of specified GPIO pin. It could be \n
* GPIO_INT_RISING, GPIO_INT_FALLING, GPIO_INT_BOTH_EDGE, GPIO_INT_HIGH, GPIO_INT_LOW.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
void GPIO_EnableInt(GPIO_T *port, uint32_t u32Pin, uint32_t u32IntAttribs)
{
port->IMD |= (((u32IntAttribs >> 24) & 0xFFUL) << u32Pin);
port->IEN |= ((u32IntAttribs & 0xFFFFFFUL) << u32Pin);
}
/**
* @brief Disable GPIO interrupt
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
* @param[in] u32Pin The pin of specified GPIO port.
* It could be 0 ~ 15 for PA, PB, PC, PD and PE GPIO port.
* It could be 0 ~ 3 for PF GPIO port.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
void GPIO_DisableInt(GPIO_T *port, uint32_t u32Pin)
{
port->IMD &= ~(1UL << u32Pin);
port->IEN &= ~((0x00010001UL) << u32Pin);
}
/*@}*/ /* end of group GPIO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group GPIO_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

389
BSP/StdDriver/src/i2c.c Normal file
View File

@ -0,0 +1,389 @@
/**************************************************************************//**
* @file i2c.c
* @version V3.00
* $Revision: 14 $
* $Date: 15/05/20 11:55a $
* @brief I2C driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup I2C_Driver I2C Driver
@{
*/
/** @addtogroup I2C_EXPORTED_FUNCTIONS I2C Exported Functions
@{
*/
/**
* @brief Enable specify I2C Controller and set Clock Divider
*
* @param[in] i2c Specify I2C port
* @param[in] u32BusClock The target I2C Bus clock in Hz
*
* @return Actual I2C bus clock frequency
*
* @details The function enable the specify I2C Controller and set proper Clock Divider
* in I2C CLOCK DIVIDED REGISTER (I2CLK) according to the target I2C Bus clock.
* I2C Bus clock = PCLK / (4*(divider+1).
*
*/
uint32_t I2C_Open(I2C_T *i2c, uint32_t u32BusClock)
{
uint32_t u32Div;
u32Div = (uint32_t)(((SystemCoreClock * 10) / (u32BusClock * 4) + 5) / 10 - 1); /* Compute proper divider for I2C clock */
i2c->I2CLK = u32Div;
/* Enable I2C */
i2c->I2CON |= I2C_I2CON_ENS1_Msk;
return (SystemCoreClock / ((u32Div + 1) << 2));
}
/**
* @brief Disable specify I2C Controller
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details Reset I2C Controller and disable specify I2C port.
*
*/
void I2C_Close(I2C_T *i2c)
{
/* Reset I2C Controller */
if((uint32_t)i2c == I2C0_BASE)
{
SYS->IPRSTC2 |= SYS_IPRSTC2_I2C0_RST_Msk;
SYS->IPRSTC2 &= ~SYS_IPRSTC2_I2C0_RST_Msk;
}
else if((uint32_t)i2c == I2C1_BASE)
{
SYS->IPRSTC2 |= SYS_IPRSTC2_I2C1_RST_Msk;
SYS->IPRSTC2 &= ~SYS_IPRSTC2_I2C1_RST_Msk;
}
/* Disable I2C */
i2c->I2CON &= ~I2C_I2CON_ENS1_Msk;
}
/**
* @brief Clear Time-out Counter flag
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details When Time-out flag will be set, use this function to clear I2C Bus Time-out Counter flag .
*
*/
void I2C_ClearTimeoutFlag(I2C_T *i2c)
{
i2c->I2CTOC |= I2C_I2CTOC_TIF_Msk;
}
/**
* @brief Set control bit of I2C Controller
*
* @param[in] i2c Specify I2C port
* @param[in] u8Start Set I2C START condition
* @param[in] u8Stop Set I2C STOP condition
* @param[in] u8Si Clear SI flag
* @param[in] u8Ack Set I2C ACK bit
*
* @return None
*
* @details The function set I2C control bit of I2C Bus protocol.
*
*/
void I2C_Trigger(I2C_T *i2c, uint8_t u8Start, uint8_t u8Stop, uint8_t u8Si, uint8_t u8Ack)
{
uint32_t u32Reg = 0;
if(u8Start)
u32Reg |= I2C_I2CON_STA;
if(u8Stop)
u32Reg |= I2C_I2CON_STO;
if(u8Si)
u32Reg |= I2C_I2CON_SI;
if(u8Ack)
u32Reg |= I2C_I2CON_AA;
i2c->I2CON = (i2c->I2CON & ~0x3C) | u32Reg;
}
/**
* @brief Disable Interrupt of I2C Controller
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details The function is used for disable I2C interrupt
*
*/
void I2C_DisableInt(I2C_T *i2c)
{
i2c->I2CON &= ~I2C_I2CON_EI_Msk;
}
/**
* @brief Enable Interrupt of I2C Controller
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details The function is used for enable I2C interrupt
*
*/
void I2C_EnableInt(I2C_T *i2c)
{
i2c->I2CON |= I2C_I2CON_EI_Msk;
}
/**
* @brief Get I2C Bus clock
*
* @param[in] i2c Specify I2C port
*
* @return The actual I2C Bus clock in Hz
*
* @details To get the actual I2C Bus clock frequency.
*/
uint32_t I2C_GetBusClockFreq(I2C_T *i2c)
{
uint32_t u32Divider = i2c->I2CLK;
return (SystemCoreClock / ((u32Divider + 1) << 2));
}
/**
* @brief Set I2C Bus clock
*
* @param[in] i2c Specify I2C port
* @param[in] u32BusClock The target I2C Bus clock in Hz
*
* @return The actual I2C Bus clock in Hz
*
* @details To set the actual I2C Bus clock frequency.
*/
uint32_t I2C_SetBusClockFreq(I2C_T *i2c, uint32_t u32BusClock)
{
uint32_t u32Div;
u32Div = (uint32_t)(((SystemCoreClock * 10) / (u32BusClock * 4) + 5) / 10 - 1); /* Compute proper divider for I2C clock */
i2c->I2CLK = u32Div;
return (SystemCoreClock / ((u32Div + 1) << 2));
}
/**
* @brief Get Interrupt Flag
*
* @param[in] i2c Specify I2C port
*
* @return I2C interrupt flag status
*
* @details To get I2C Bus interrupt flag.
*/
uint32_t I2C_GetIntFlag(I2C_T *i2c)
{
return ((i2c->I2CON & I2C_I2CON_SI_Msk) == I2C_I2CON_SI_Msk ? 1 : 0);
}
/**
* @brief Get I2C bus Status Code
*
* @param[in] i2c Specify I2C port
*
* @return I2C Status Code
*
* @details To get I2C Bus Status Code.
*/
uint32_t I2C_GetStatus(I2C_T *i2c)
{
return (i2c->I2CSTATUS);
}
/**
* @brief Read a byte from I2C Bus
*
* @param[in] i2c Specify I2C port
*
* @return I2C Data
*
* @details To read a byte data from specify I2C port.
*/
uint8_t I2C_GetData(I2C_T *i2c)
{
return (i2c->I2CDAT);
}
/**
* @brief Send a byte to I2C Bus
*
* @param[in] i2c I2C port
* @param[in] u8Data The data to send to I2C Bus
*
* @return None
*
* @details This function is used to write a byte to specified I2C port
*/
void I2C_SetData(I2C_T *i2c, uint8_t u8Data)
{
i2c->I2CDAT = u8Data;
}
/**
* @brief Set 7-bit Slave Address and GC Mode
*
* @param[in] i2c I2C port
* @param[in] u8SlaveNo Set the number of I2C address register (0~3)
* @param[in] u8SlaveAddr 7-bit slave address
* @param[in] u8GCMode Enable/Disable GC Mode (I2C_GCMODE_ENABLE / I2C_GCMODE_DISABLE)
*
* @return None
*
* @details This function is used to set 7-bit slave addresses in I2C SLAVE ADDRESS REGISTER (I2CADDR0~3)
* and enable GC Mode.
*
*/
void I2C_SetSlaveAddr(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddr, uint8_t u8GCMode)
{
switch(u8SlaveNo)
{
case 1:
i2c->I2CADDR1 = (u8SlaveAddr << 1) | u8GCMode;
break;
case 2:
i2c->I2CADDR2 = (u8SlaveAddr << 1) | u8GCMode;
break;
case 3:
i2c->I2CADDR3 = (u8SlaveAddr << 1) | u8GCMode;
break;
case 0:
default:
i2c->I2CADDR0 = (u8SlaveAddr << 1) | u8GCMode;
break;
}
}
/**
* @brief Configure the mask bits of 7-bit Slave Address
*
* @param[in] i2c I2C port
* @param[in] u8SlaveNo Set the number of I2C address mask register (0~3)
* @param[in] u8SlaveAddrMask A byte for slave address mask
*
* @return None
*
* @details This function is used to set 7-bit slave addresses.
*
*/
void I2C_SetSlaveAddrMask(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddrMask)
{
switch(u8SlaveNo)
{
case 1:
i2c->I2CADM1 = u8SlaveAddrMask << 1;
break;
case 2:
i2c->I2CADM2 = u8SlaveAddrMask << 1;
break;
case 3:
i2c->I2CADM3 = u8SlaveAddrMask << 1;
break;
case 0:
default:
i2c->I2CADM0 = u8SlaveAddrMask << 1;
break;
}
}
/**
* @brief Enable Time-out Counter function and support Long Time-out
*
* @param[in] i2c I2C port
* @param[in] u8LongTimeout Configure DIV4 to enable Long Time-out (0/1)
*
* @return None
*
* @details This function enable Time-out counter function and configure DIV4 to support Long
* Time-out.
*
*/
void I2C_EnableTimeout(I2C_T *i2c, uint8_t u8LongTimeout)
{
if(u8LongTimeout)
i2c->I2CTOC |= I2C_I2CTOC_DIV4_Msk;
else
i2c->I2CTOC &= ~I2C_I2CTOC_DIV4_Msk;
i2c->I2CTOC |= I2C_I2CTOC_ENTI_Msk;
}
/**
* @brief Disable Time-out Counter Function
*
* @param[in] i2c I2C port
*
* @return None
*
* @details To disable Time-out counter function in I2CTOC register.
*
*/
void I2C_DisableTimeout(I2C_T *i2c)
{
i2c->I2CTOC &= ~I2C_I2CTOC_ENTI_Msk;
}
/**
* @brief Enable I2C Wake-up Function
*
* @param[in] i2c I2C port
*
* @return None
*
* @details To enable Wake-up function of I2C Wake-up control register.
*
*/
void I2C_EnableWakeup(I2C_T *i2c)
{
i2c->I2CWKUPCON |= I2C_I2CWKUPCON_WKUPEN_Msk;
}
/**
* @brief Disable I2C Wake-up Function
*
* @param[in] i2c I2C port
*
* @return None
*
* @details To disable Wake-up function of I2C Wake-up control register.
*
*/
void I2C_DisableWakeup(I2C_T *i2c)
{
i2c->I2CWKUPCON &= ~I2C_I2CWKUPCON_WKUPEN_Msk;
}
/*@}*/ /* end of group I2C_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group I2C_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

204
BSP/StdDriver/src/i2s.c Normal file
View File

@ -0,0 +1,204 @@
/**************************************************************************//**
* @file i2s.c
* @version V3.0
* $Revision: 15 $
* $Date: 15/05/04 3:59p $
* @brief I2S driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup I2S_Driver I2S Driver
@{
*/
/** @addtogroup I2S_EXPORTED_FUNCTIONS I2S Exported Functions
@{
*/
/**
* @brief This function is used to get I2S source clock frequency.
* @param[in] i2s The pointer of the specified I2S module.
* @return I2S source clock frequency (Hz).
* @details Return the source clock frequency according to the setting of I2S_S (CLKSEL2[1:0]).
*/
static uint32_t I2S_GetSourceClockFreq(I2S_T *i2s)
{
uint32_t u32Freq, u32ClkSrcSel;
u32ClkSrcSel = CLK->CLKSEL2 & CLK_CLKSEL2_I2S_S_Msk;
switch(u32ClkSrcSel)
{
case CLK_CLKSEL2_I2S_S_HXT:
u32Freq = __HXT;
break;
case CLK_CLKSEL2_I2S_S_PLL:
u32Freq = CLK_GetPLLClockFreq();
break;
case CLK_CLKSEL2_I2S_S_HIRC:
u32Freq = __HIRC;
break;
case CLK_CLKSEL2_I2S_S_HCLK:
u32Freq = SystemCoreClock;
break;
default:
u32Freq = __HIRC;
break;
}
return u32Freq;
}
/**
* @brief This function configures some parameters of I2S interface for general purpose use.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32MasterSlave I2S operation mode. Valid values are:
* - \ref I2S_MODE_MASTER
* - \ref I2S_MODE_SLAVE
* @param[in] u32SampleRate Sample rate
* @param[in] u32WordWidth Data length. Valid values are:
* - \ref I2S_DATABIT_8
* - \ref I2S_DATABIT_16
* - \ref I2S_DATABIT_24
* - \ref I2S_DATABIT_32
* @param[in] u32Channels Audio format. Valid values are:
* - \ref I2S_MONO
* - \ref I2S_STEREO
* @param[in] u32DataFormat Data format. Valid values are:
* - \ref I2S_FORMAT_I2S
* - \ref I2S_FORMAT_MSB
* @return Real sample rate.
* @details This function will configure I2S controller according to the input parameters. Set TX and RX FIFO threshold to middle value.
* The actual sample rate may be different from the target sample rate. The real sample rate will be returned for reference.
* @note Both the TX and RX functions will be enabled.
*/
uint32_t I2S_Open(I2S_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat)
{
uint8_t u8Divider;
uint32_t u32BitRate, u32SrcClk;
/* Reset I2S */
SYS->IPRSTC2 |= SYS_IPRSTC2_I2S_RST_Msk;
SYS->IPRSTC2 &= ~SYS_IPRSTC2_I2S_RST_Msk;
/* Configure I2S controller according to input parameters. */
i2s->CON = u32MasterSlave | u32WordWidth | u32Channels | u32DataFormat | I2S_FIFO_TX_LEVEL_WORD_4 | I2S_FIFO_RX_LEVEL_WORD_4;
/* Get I2S source clock frequency */
u32SrcClk = I2S_GetSourceClockFreq(i2s);
/* Calculate bit clock rate */
u32BitRate = u32SampleRate * (((u32WordWidth >> 4) & 0x3) + 1) * 16;
u8Divider = ((u32SrcClk / u32BitRate) >> 1) - 1;
i2s->CLKDIV = (i2s->CLKDIV & ~I2S_CLKDIV_BCLK_DIV_Msk) | (u8Divider << 8);
/* Calculate real sample rate */
u32BitRate = u32SrcClk / ((u8Divider + 1) * 2);
u32SampleRate = u32BitRate / ((((u32WordWidth >> 4) & 0x3) + 1) * 16);
/* Enable TX, RX and I2S controller */
i2s->CON |= (I2S_CON_RXEN_Msk | I2S_CON_TXEN_Msk | I2S_CON_I2SEN_Msk);
return u32SampleRate;
}
/**
* @brief Disable I2S function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details Disable I2S function.
*/
void I2S_Close(I2S_T *i2s)
{
i2s->CON &= ~I2S_CON_I2SEN_Msk;
}
/**
* @brief Enable interrupt function.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32Mask The combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt bit.
* @return None
* @details This function enables the interrupt according to the mask parameter.
*/
void I2S_EnableInt(I2S_T *i2s, uint32_t u32Mask)
{
i2s->IE |= u32Mask;
}
/**
* @brief Disable interrupt function.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32Mask The combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt bit.
* @return None
* @details This function disables the interrupt according to the mask parameter.
*/
void I2S_DisableInt(I2S_T *i2s, uint32_t u32Mask)
{
i2s->IE &= ~u32Mask;
}
/**
* @brief Enable master clock (MCLK).
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32BusClock The target MCLK clock.
* @return Actual MCLK clock
* @details Set the master clock rate according to u32BusClock parameter and enable master clock output.
* The actual master clock rate may be different from the target master clock rate. The real master clock rate will be returned for reference.
*/
uint32_t I2S_EnableMCLK(I2S_T *i2s, uint32_t u32BusClock)
{
uint8_t u8Divider;
uint32_t u32SrcClk, u32Reg;
u32SrcClk = I2S_GetSourceClockFreq(i2s);
if(u32BusClock == u32SrcClk)
u8Divider = 0;
else
u8Divider = (u32SrcClk / u32BusClock) >> 1;
i2s->CLKDIV = (i2s->CLKDIV & ~I2S_CLKDIV_MCLK_DIV_Msk) | u8Divider;
i2s->CON |= I2S_CON_MCLKEN_Msk;
u32Reg = i2s->CLKDIV & I2S_CLKDIV_MCLK_DIV_Msk;
if(u32Reg == 0)
return u32SrcClk;
else
return ((u32SrcClk >> 1) / u32Reg);
}
/**
* @brief Disable master clock (MCLK).
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details Disable master clock output.
*/
void I2S_DisableMCLK(I2S_T *i2s)
{
i2s->CON &= ~I2S_CON_MCLKEN_Msk;
}
/*@}*/ /* end of group I2S_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group I2S_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

284
BSP/StdDriver/src/pdma.c Normal file
View File

@ -0,0 +1,284 @@
/**************************************************************************//**
* @file pdma.c
* @version V3.00
* $Revision: 9 $
* $Date: 15/05/04 3:59p $
* @brief PDMA driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup PDMA_Driver PDMA Driver
@{
*/
/** @addtogroup PDMA_EXPORTED_FUNCTIONS PDMA Exported Functions
@{
*/
/**
* @brief PDMA Open
*
* @param[in] u32Mask Channel enable bits.
*
* @return None
*
* @details This function enable the PDMA channels.
*/
void PDMA_Open(uint32_t u32Mask)
{
PDMA_GCR->GCRCSR |= (u32Mask << 8);
}
/**
* @brief PDMA Close
*
* @param None
*
* @return None
*
* @details This function disable all PDMA channels.
*/
void PDMA_Close(void)
{
PDMA_GCR->GCRCSR = 0;
}
/**
* @brief Set PDMA Transfer Count
*
* @param[in] u32Ch The selected channel
* @param[in] u32Width Data width. Valid values are
* - \ref PDMA_WIDTH_8
* - \ref PDMA_WIDTH_16
* - \ref PDMA_WIDTH_32
* @param[in] u32TransCount Transfer count
*
* @return None
*
* @details This function set the selected channel data width and transfer count.
*/
void PDMA_SetTransferCnt(uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch));
pdma->CSR = (pdma->CSR & ~PDMA_CSR_APB_TWS_Msk) | u32Width;
switch(u32Width)
{
case PDMA_WIDTH_32:
pdma->BCR = (u32TransCount << 2);
break;
case PDMA_WIDTH_8:
pdma->BCR = u32TransCount;
break;
case PDMA_WIDTH_16:
pdma->BCR = (u32TransCount << 1);
break;
default:
;
}
}
/**
* @brief Set PDMA Transfer Address
*
* @param[in] u32Ch The selected channel
* @param[in] u32SrcAddr Source address
* @param[in] u32SrcCtrl Source control attribute. Valid values are
* - \ref PDMA_SAR_INC
* - \ref PDMA_SAR_FIX
* @param[in] u32DstAddr destination address
* @param[in] u32DstCtrl destination control attribute. Valid values are
* - \ref PDMA_DAR_INC
* - \ref PDMA_DAR_FIX
*
* @return None
*
* @details This function set the selected channel source/destination address and attribute.
*/
void PDMA_SetTransferAddr(uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch));
pdma->SAR = u32SrcAddr;
pdma->DAR = u32DstAddr;
pdma->CSR = (pdma->CSR & ~(PDMA_CSR_SAD_SEL_Msk | PDMA_CSR_DAD_SEL_Msk)) | (u32SrcCtrl | u32DstCtrl);
}
/**
* @brief Set PDMA Transfer Mode
*
* @param[in] u32Ch The selected channel
* @param[in] u32Peripheral The selected peripheral. Valid values are
* - \ref PDMA_SPI0_TX
* - \ref PDMA_SPI1_TX
* - \ref PDMA_SPI2_TX
* - \ref PDMA_SPI3_TX
* - \ref PDMA_UART0_TX
* - \ref PDMA_UART1_TX
* - \ref PDMA_I2S_TX
* - \ref PDMA_SPI0_RX
* - \ref PDMA_SPI1_RX
* - \ref PDMA_SPI2_RX
* - \ref PDMA_SPI3_RX
* - \ref PDMA_UART0_RX
* - \ref PDMA_UART1_RX
* - \ref PDMA_I2S_RX
* - \ref PDMA_ADC
* - \ref PDMA_MEM
* @param[in] u32ScatterEn Scatter-gather mode enable
* @param[in] u32DescAddr Scatter-gather descriptor address
*
* @return None
*
* @details This function set the selected channel transfer mode. Include peripheral setting.
*/
void PDMA_SetTransferMode(uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
{
uint32_t u32Index = 0;
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch));
if(u32Peripheral > PDMA_ADC) /* Memory-to-Memory */
pdma->CSR = (pdma->CSR & ~(PDMA_CSR_MODE_SEL_Msk));
else if(u32Peripheral > PDMA_I2S_TX) /* Peripheral-to-Memory */
pdma->CSR = (pdma->CSR & ~(PDMA_CSR_MODE_SEL_Msk) | (0x1 << PDMA_CSR_MODE_SEL_Pos));
else /* Memory-to-Peripheral */
pdma->CSR = (pdma->CSR & ~(PDMA_CSR_MODE_SEL_Msk) | (0x2 << PDMA_CSR_MODE_SEL_Pos));
switch(u32Peripheral)
{
case 0:
PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI0_TXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI0_TXSEL_Pos);
break;
case 1:
PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI1_TXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI1_TXSEL_Pos);
break;
case 2:
PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI2_TXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI2_TXSEL_Pos);
break;
case 3:
PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI3_TXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI3_TXSEL_Pos);
break;
case 4:
PDMA_GCR->PDSSR1 = (PDMA_GCR->PDSSR1 & ~PDMA_PDSSR1_UART0_TXSEL_Msk) | (u32Ch << PDMA_PDSSR1_UART0_TXSEL_Pos);
break;
case 5:
PDMA_GCR->PDSSR1 = (PDMA_GCR->PDSSR1 & ~PDMA_PDSSR1_UART1_TXSEL_Msk) | (u32Ch << PDMA_PDSSR1_UART1_TXSEL_Pos);
break;
case 6:
PDMA_GCR->PDSSR2 = (PDMA_GCR->PDSSR2 & ~PDMA_PDSSR2_I2S_TXSEL_Msk) | (u32Ch << PDMA_PDSSR2_I2S_TXSEL_Pos);
break;
case 7:
PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI0_RXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI0_RXSEL_Pos);
break;
case 8:
PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI1_RXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI1_RXSEL_Pos);
break;
case 9:
PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI2_RXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI2_RXSEL_Pos);
break;
case 10:
PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI3_RXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI3_RXSEL_Pos);
break;
case 11:
PDMA_GCR->PDSSR1 = (PDMA_GCR->PDSSR1 & ~PDMA_PDSSR1_UART0_RXSEL_Msk) | (u32Ch << PDMA_PDSSR1_UART0_RXSEL_Pos);
break;
case 12:
PDMA_GCR->PDSSR1 = (PDMA_GCR->PDSSR1 & ~PDMA_PDSSR1_UART1_RXSEL_Msk) | (u32Ch << PDMA_PDSSR1_UART1_RXSEL_Pos);
break;
case 13:
PDMA_GCR->PDSSR2 = (PDMA_GCR->PDSSR2 & ~PDMA_PDSSR2_I2S_RXSEL_Msk) | (u32Ch << PDMA_PDSSR2_I2S_RXSEL_Pos);
break;
case 14:
PDMA_GCR->PDSSR1 = (PDMA_GCR->PDSSR1 & ~PDMA_PDSSR1_ADC_RXSEL_Msk) | (u32Ch << PDMA_PDSSR1_ADC_RXSEL_Pos);
break;
default:/* select PDMA channel as memory to memory */
for(u32Index = 0; u32Index < 8; u32Index++)
{
if((PDMA_GCR->PDSSR0 & (0xF << (u32Index * 4))) == (u32Ch << (u32Index * 4)))
PDMA_GCR->PDSSR0 |= 0xF << (u32Index * 4);
if((PDMA_GCR->PDSSR1 & (0xF << (u32Index * 4))) == (u32Ch << (u32Index * 4)))
PDMA_GCR->PDSSR1 |= 0xF << (u32Index * 4);
if((PDMA_GCR->PDSSR2 & (0xF << (u32Index * 4))) == (u32Ch << (u32Index * 4)))
PDMA_GCR->PDSSR2 |= 0xF << (u32Index * 4);
}
}
}
/**
* @brief Trigger PDMA
*
* @param[in] u32Ch The selected channel
*
* @return None
*
* @details This function trigger the selected channel.
*/
void PDMA_Trigger(uint32_t u32Ch)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch));
pdma->CSR |= (PDMA_CSR_TRIG_EN_Msk | PDMA_CSR_PDMACEN_Msk);
}
/**
* @brief Enable Interrupt
*
* @param[in] u32Ch The selected channel
* @param[in] u32Mask The Interrupt Type
*
* @return None
*
* @details This function enable the selected channel interrupt.
*/
void PDMA_EnableInt(uint32_t u32Ch, uint32_t u32Mask)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch));
pdma->IER |= u32Mask;
}
/**
* @brief Disable Interrupt
*
* @param[in] u32Ch The selected channel
* @param[in] u32Mask The Interrupt Type
*
* @return None
*
* @details This function disable the selected channel interrupt.
*/
void PDMA_DisableInt(uint32_t u32Ch, uint32_t u32Mask)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch));
pdma->IER &= ~u32Mask;
}
/*@}*/ /* end of group PDMA_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group PDMA_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

201
BSP/StdDriver/src/ps2.c Normal file
View File

@ -0,0 +1,201 @@
/**************************************************************************//**
* @file ps2.c
* @version V3.00
* $Revision: 14 $
* $Date: 15/05/04 3:59p $
* @brief PS/2 driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "NUC200Series.h"
/*---------------------------------------------------------------------------------------------------------*/
/* Includes of local headers */
/*---------------------------------------------------------------------------------------------------------*/
#include "ps2.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup PS2_Driver PS2 Driver
@{
*/
/** @addtogroup PS2_EXPORTED_FUNCTIONS PS2 Exported Functions
@{
*/
/**
* @brief Enable PS/2 Interrupt
*
* @param[in] u32Mask The specified interrupt of PS/2 module:
* - PS2D_PS2CON_TXINTEN_Msk: PS/2 Tx interrupt
* - PS2D_PS2CON_RXINTEN_Msk: PS/2 Rx interrupt
*
* @return None
*
* @details The function is used to enable PS/2 specified Tx or Rx interrupt.
*/
void PS2_EnableInt(uint32_t u32Mask)
{
PS2->PS2CON |= u32Mask;
}
/**
* @brief Disable PS/2 Interrupt.
*
* @param[in] u32Mask The specified interrupt of PS2 module:
* - PS2D_PS2CON_TXINTEN_Msk: PS2 Tx interrupt
* - PS2D_PS2CON_RXINTEN_Msk: PS2 Rx interrupt
*
* @return None
*
* @details The function is used to disable PS/2 specified Tx or Rx interrupt.
*/
void PS2_DisableInt(uint32_t u32Mask)
{
PS2->PS2CON &= ~u32Mask;
}
/**
* @brief Enable PS/2 function and Set Parameter
*
* @param None
*
* @return None
*
* @details This function is used to enable PS/2 function and set one byte per transfer.
*/
void PS2_Open(void)
{
/* Reset PS2 device */
SYS->IPRSTC2 |= SYS_IPRSTC2_PS2_RST_Msk;
SYS->IPRSTC2 &= ~SYS_IPRSTC2_PS2_RST_Msk;
/* Enable PS2 module */
PS2->PS2CON |= PS2_PS2CON_PS2EN_Msk;
/* Set One byte per transfer */
PS2->PS2CON &= ~PS2_PS2CON_TXFIFO_DEPTH_Msk;
/* Clear Tx FIFO */
PS2->PS2CON |= PS2_PS2CON_CLRFIFO_Msk;
PS2->PS2CON &= (~PS2_PS2CON_CLRFIFO_Msk);
}
/**
* @brief Disable PS/2 function
*
* @param None
*
* @return None
*
* @details This function use to disable PS/2 function.
*/
void PS2_Close(void)
{
/* Enable PS2 module */
PS2->PS2CON &= ~PS2_PS2CON_PS2EN_Msk;
}
/**
* @brief This function use to read PS/2 Rx data.
*
* @param None
*
* @return Rx data
*
* @details To get PS/2 receive 8 bits data from PS2RXDATA register.
*/
uint8_t PS2_Read(void)
{
return (uint8_t)(PS2->PS2RXDATA & PS2_PS2RXDATA_RXDATA_Msk);
}
/**
* @brief This function use to transmit PS/2 data.
*
* @param[in] pu32Buf The buffer to send the data to PS/2 transmission FIFO.
* @param[in] u32ByteCount The byte number of data.
*
* @retval 0 transmit data time-out
* @retval 1 transmit data successful
*
* @details Write data to PS/2 transmit FIFO and set the depth of Tx transmit bytes, then check every data transmission success or time-out.
*/
int32_t PS2_Write(uint32_t *pu32Buf, uint32_t u32ByteCount)
{
uint32_t u32TxFIFO_Depth = 16;
uint32_t u32delayno, txcnt, remainder;
uint8_t i = 0;
txcnt = u32ByteCount / u32TxFIFO_Depth;
remainder = u32ByteCount % u32TxFIFO_Depth;
if(remainder) txcnt++;
u32delayno = 0;
while(!(PS2->PS2STATUS & PS2_PS2STATUS_TXEMPTY_Msk))
{
u32delayno++;
if(u32delayno >= 0xF00000)
return FALSE; // Time Out
}
if(u32ByteCount >= u32TxFIFO_Depth)//Tx FIFO is 16 bytes
PS2_SET_TX_BYTE_CNT(u32TxFIFO_Depth);
do
{
u32delayno = 0;
while(!(PS2->PS2STATUS & PS2_PS2STATUS_TXEMPTY_Msk))
{
u32delayno++;
if(u32delayno >= 0xF00000)
return FALSE; // Time Out
}
if((txcnt == 1) && (remainder != 0))
PS2_SET_TX_BYTE_CNT(u32ByteCount);
PS2->PS2TXDATA0 = pu32Buf[i];
PS2->PS2TXDATA1 = pu32Buf[i + 1];
PS2->PS2TXDATA2 = pu32Buf[i + 2];
PS2->PS2TXDATA3 = pu32Buf[i + 3];
i = i + 4;
}
while(--txcnt);
u32delayno = 0;
while(!(PS2->PS2STATUS & PS2_PS2STATUS_TXEMPTY_Msk))
{
u32delayno++;
if(u32delayno >= 0xF00000)
return FALSE; // Time Out
}
return TRUE;
}
/*@}*/ /* end of group PS2_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group PS2_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

672
BSP/StdDriver/src/pwm.c Normal file
View File

@ -0,0 +1,672 @@
/**************************************************************************//**
* @file pwm.c
* @version V3.00
* $Revision: 12 $
* $Date: 15/05/05 3:35p $
* @brief PWM driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup PWM_Driver PWM Driver
@{
*/
/** @addtogroup PWM_EXPORTED_FUNCTIONS PWM Exported Functions
@{
*/
/**
* @brief Configure PWM capture and get the nearest unit time.
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32UnitTimeNsec The unit time of counter
* @param[in] u32CaptureEdge The condition to latch the counter. This parameter is not used
* @return The nearest unit time in nano second.
* @details This function is used to configure PWM capture and get the nearest unit time.
*/
uint32_t PWM_ConfigCaptureChannel(PWM_T *pwm,
uint32_t u32ChannelNum,
uint32_t u32UnitTimeNsec,
uint32_t u32CaptureEdge)
{
uint32_t u32Src;
uint32_t u32PWMClockSrc;
uint32_t u32PWMClkTbl[8] = {__HXT, __LXT, NULL, __HIRC, NULL, NULL, NULL, __LIRC};
uint32_t u32NearestUnitTimeNsec;
uint8_t u8Divider = 1;
/* this table is mapping divider value to register configuration */
uint32_t u32PWMDividerToRegTbl[17] = {NULL, 4, 0, NULL, 1, NULL, NULL, NULL, 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 3};
uint16_t u16Prescale = 2;
uint16_t u16CNR = 0xFFFF;
if(pwm == PWMA)
{
if(u32ChannelNum < 2)/* channel 0 and channel 1 */
u32Src = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM01_S_EXT_Msk)) >> (CLK_CLKSEL2_PWM01_S_EXT_Pos - 2)) | (CLK->CLKSEL1 & (CLK_CLKSEL1_PWM01_S_Msk)) >> (CLK_CLKSEL1_PWM01_S_Pos);
else /* channel 2 and channel 3 */
u32Src = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM23_S_EXT_Msk)) >> (CLK_CLKSEL2_PWM23_S_EXT_Pos - 2)) | (CLK->CLKSEL1 & (CLK_CLKSEL1_PWM23_S_Msk)) >> (CLK_CLKSEL1_PWM23_S_Pos);
}
else /*pwm == PWMB*/
{
if(u32ChannelNum < 2)/* channel 0 and channel 1 */
u32Src = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM45_S_EXT_Msk)) >> (CLK_CLKSEL2_PWM45_S_EXT_Pos - 2)) | (CLK->CLKSEL2 & (CLK_CLKSEL2_PWM45_S_Msk)) >> (CLK_CLKSEL2_PWM45_S_Pos);
else /* channel 2 and channel 3 */
u32Src = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM67_S_EXT_Msk)) >> (CLK_CLKSEL2_PWM67_S_EXT_Pos - 2)) | (CLK->CLKSEL2 & (CLK_CLKSEL2_PWM67_S_Msk)) >> (CLK_CLKSEL2_PWM67_S_Pos);
}
if(u32Src == 2)
{
SystemCoreClockUpdate();
u32PWMClockSrc = SystemCoreClock;
}
else
{
u32PWMClockSrc = u32PWMClkTbl[u32Src];
}
u32PWMClockSrc /= 1000;
for(; u16Prescale <= 0x100; u16Prescale++)
{
u32NearestUnitTimeNsec = (1000000 * u16Prescale * u8Divider) / u32PWMClockSrc;
if(u32NearestUnitTimeNsec < u32UnitTimeNsec)
{
if((u16Prescale == 0x100) && (u8Divider == 16)) //limit to the maximum unit time(nano second)
break;
if(u16Prescale == 0x100)
{
u16Prescale = 2;
u8Divider <<= 1; // clk divider could only be 1, 2, 4, 8, 16
continue;
}
if(!((1000000 * ((u16Prescale * u8Divider) + 1)) > (u32NearestUnitTimeNsec * u32PWMClockSrc)))
break;
continue;
}
break;
}
// Store return value here 'cos we're gonna change u8Divider & u16Prescale & u16CNR to the real value to fill into register
u16Prescale -= 1;
// convert to real register value
u8Divider = u32PWMDividerToRegTbl[u8Divider];
// every two channels share a prescaler
(pwm)->PPR = ((pwm)->PPR & ~(PWM_PPR_CP01_Msk << ((u32ChannelNum >> 1) * 8))) | (u16Prescale << ((u32ChannelNum >> 1) * 8));
(pwm)->CSR = ((pwm)->CSR & ~(PWM_CSR_CSR0_Msk << (4 * u32ChannelNum))) | (u8Divider << (4 * u32ChannelNum));
// set PWM to edge aligned type
(pwm)->PCR &= ~(PWM_PCR_PWM01TYPE_Msk << (u32ChannelNum >> 1));
(pwm)->PCR |= PWM_PCR_CH0MOD_Msk << (8 * u32ChannelNum);
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CNR0)) + (u32ChannelNum) * 12))) = u16CNR;
return (u32NearestUnitTimeNsec);
}
/**
* @brief Configure PWM generator and get the nearest frequency in edge aligned auto-reload mode
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32Frequency Target generator frequency
* @param[in] u32DutyCycle Target generator duty cycle percentage. Valid range are between 0 ~ 100. 10 means 10%, 20 means 20%...
* @return Nearest frequency clock in nano second
* @details This function is used to configure PWM generator and get the nearest frequency in edge aligned auto-reload mode.
* @note Since every two channels, (0 & 1), (2 & 3), shares a prescaler. Call this API to configure PWM frequency may affect
* existing frequency of other channel.
*/
uint32_t PWM_ConfigOutputChannel(PWM_T *pwm,
uint32_t u32ChannelNum,
uint32_t u32Frequency,
uint32_t u32DutyCycle)
{
uint32_t u32Src;
uint32_t u32PWMClockSrc;
uint32_t u32PWMClkTbl[8] = {__HXT, __LXT, NULL, __HIRC, NULL, NULL, NULL, __LIRC};
uint32_t i;
uint8_t u8Divider = 1, u8Prescale = 0xFF;
/* this table is mapping divider value to register configuration */
uint32_t u32PWMDividerToRegTbl[17] = {NULL, 4, 0, NULL, 1, NULL, NULL, NULL, 2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 3};
uint16_t u16CNR = 0xFFFF;
if(pwm == PWMA)
{
if(u32ChannelNum < 2)/* channel 0 and channel 1 */
u32Src = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM01_S_EXT_Msk)) >> (CLK_CLKSEL2_PWM01_S_EXT_Pos - 2)) | (CLK->CLKSEL1 & (CLK_CLKSEL1_PWM01_S_Msk)) >> (CLK_CLKSEL1_PWM01_S_Pos);
else /* channel 2 and channel 3 */
u32Src = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM23_S_EXT_Msk)) >> (CLK_CLKSEL2_PWM23_S_EXT_Pos - 2)) | (CLK->CLKSEL1 & (CLK_CLKSEL1_PWM23_S_Msk)) >> (CLK_CLKSEL1_PWM23_S_Pos);
}
else /*pwm == PWMB*/
{
if(u32ChannelNum < 2)/* channel 0 and channel 1 */
u32Src = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM45_S_EXT_Msk)) >> (CLK_CLKSEL2_PWM45_S_EXT_Pos - 2)) | (CLK->CLKSEL2 & (CLK_CLKSEL2_PWM45_S_Msk)) >> (CLK_CLKSEL2_PWM45_S_Pos);
else /* channel 2 and channel 3 */
u32Src = ((CLK->CLKSEL2 & (CLK_CLKSEL2_PWM67_S_EXT_Msk)) >> (CLK_CLKSEL2_PWM67_S_EXT_Pos - 2)) | (CLK->CLKSEL2 & (CLK_CLKSEL2_PWM67_S_Msk)) >> (CLK_CLKSEL2_PWM67_S_Pos);
}
if(u32Src == 2)
{
SystemCoreClockUpdate();
u32PWMClockSrc = SystemCoreClock;
}
else
{
u32PWMClockSrc = u32PWMClkTbl[u32Src];
}
for(; u8Divider < 17; u8Divider <<= 1) // clk divider could only be 1, 2, 4, 8, 16
{
i = (u32PWMClockSrc / u32Frequency) / u8Divider;
// If target value is larger than CNR * prescale, need to use a larger divider
if(i > (0x10000 * 0x100))
continue;
// CNR = 0xFFFF + 1, get a prescaler that CNR value is below 0xFFFF
u8Prescale = (i + 0xFFFF) / 0x10000;
// u8Prescale must at least be 2, otherwise the output stop
if(u8Prescale < 3)
u8Prescale = 2;
i /= u8Prescale;
if(i <= 0x10000)
{
if(i == 1)
u16CNR = 1; // Too fast, and PWM cannot generate expected frequency...
else
u16CNR = i;
break;
}
}
// Store return value here 'cos we're gonna change u8Divider & u8Prescale & u16CNR to the real value to fill into register
i = u32PWMClockSrc / (u8Prescale * u8Divider * u16CNR);
u8Prescale -= 1;
u16CNR -= 1;
// convert to real register value
u8Divider = u32PWMDividerToRegTbl[u8Divider];
// every two channels share a prescaler
(pwm)->PPR = ((pwm)->PPR & ~(PWM_PPR_CP01_Msk << ((u32ChannelNum >> 1) * 8))) | (u8Prescale << ((u32ChannelNum >> 1) * 8));
(pwm)->CSR = ((pwm)->CSR & ~(PWM_CSR_CSR0_Msk << (4 * u32ChannelNum))) | (u8Divider << (4 * u32ChannelNum));
// set PWM to edge aligned type
(pwm)->PCR &= ~(PWM_PCR_PWM01TYPE_Msk << (u32ChannelNum >> 1));
(pwm)->PCR |= PWM_PCR_CH0MOD_Msk << (8 * u32ChannelNum);
if(u32DutyCycle)
{
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CMR0)) + u32ChannelNum * 12))) = u32DutyCycle * (u16CNR + 1) / 100 - 1;
}
else
{
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CMR0)) + u32ChannelNum * 12))) = 0;
}
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CNR0)) + (u32ChannelNum) * 12))) = u16CNR;
return(i);
}
/**
* @brief Start PWM module
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
* Bit 0 is channel 0, bit 1 is channel 1...
* @return None
* @details This function is used to start PWM module.
*/
void PWM_Start(PWM_T *pwm, uint32_t u32ChannelMask)
{
uint32_t u32Mask = 0, i;
for(i = 0; i < PWM_CHANNEL_NUM; i ++)
{
if(u32ChannelMask & (1 << i))
{
u32Mask |= (PWM_PCR_CH0EN_Msk << (i * 8));
}
}
(pwm)->PCR |= u32Mask;
}
/**
* @brief Stop PWM module
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
* Bit 0 is channel 0, bit 1 is channel 1...
* @return None
* @details This function is used to stop PWM module.
*/
void PWM_Stop(PWM_T *pwm, uint32_t u32ChannelMask)
{
uint32_t i;
for(i = 0; i < PWM_CHANNEL_NUM; i ++)
{
if(u32ChannelMask & (1 << i))
{
*((__IO uint32_t *)((((uint32_t) & ((pwm)->CNR0)) + i * 12))) = 0;
}
}
}
/**
* @brief Stop PWM generation immediately by clear channel enable bit
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
* Bit 0 is channel 0, bit 1 is channel 1...
* @return None
* @details This function is used to stop PWM generation immediately by clear channel enable bit.
*/
void PWM_ForceStop(PWM_T *pwm, uint32_t u32ChannelMask)
{
uint32_t u32Mask = 0, i;
for(i = 0; i < PWM_CHANNEL_NUM; i ++)
{
if(u32ChannelMask & (1 << i))
{
u32Mask |= (PWM_PCR_CH0EN_Msk << (i * 8));
}
}
(pwm)->PCR &= ~u32Mask;
}
/**
* @brief Enable selected channel to trigger ADC
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32Condition This parameter is not used
* @return None
* @details This function is used to enable selected channel to trigger ADC.
* @note This function is only supported when PWM operating at Center-aligned type.
*/
void PWM_EnableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
{
(pwm)->TCON |= (PWM_TCON_PWM0TEN_Msk << u32ChannelNum);
}
/**
* @brief Disable selected channel to trigger ADC
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @return None
* @details This function is used to disable selected channel to trigger ADC.
*/
void PWM_DisableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum)
{
(pwm)->TCON = ((pwm)->TCON & ~(PWM_TCON_PWM0TEN_Msk << u32ChannelNum));
}
/**
* @brief Clear selected channel trigger ADC flag
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32Condition This parameter is not used
* @return None
* @details This function is used to clear selected channel trigger ADC flag.
*/
void PWM_ClearADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition)
{
(pwm)->TSTATUS = (PWM_TSTATUS_PWM0TF_Msk << u32ChannelNum);
}
/**
* @brief Get selected channel trigger ADC flag
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @retval 0 The specified channel trigger ADC to start of conversion flag is not set
* @retval 1 The specified channel trigger ADC to start of conversion flag is set
* @details This function is used to get PWM trigger ADC to start of conversion flag for specified channel.
*/
uint32_t PWM_GetADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum)
{
return (((pwm)->TSTATUS & (PWM_TSTATUS_PWM0TF_Msk << (u32ChannelNum))) ? 1 : 0);
}
/**
* @brief Enable capture of selected channel(s)
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
* Bit 0 is channel 0, bit 1 is channel 1...
* @return None
* @details This function is used to enable capture of selected channel(s).
*/
void PWM_EnableCapture(PWM_T *pwm, uint32_t u32ChannelMask)
{
uint32_t i;
for(i = 0; i < PWM_CHANNEL_NUM; i ++)
{
if(u32ChannelMask & (1 << i))
{
if(i < 2)
{
(pwm)->CCR0 |= PWM_CCR0_CAPCH0EN_Msk << (i * 16);
}
else
{
(pwm)->CCR2 |= PWM_CCR2_CAPCH2EN_Msk << ((i - 2) * 16);
}
}
}
(pwm)->CAPENR |= u32ChannelMask;
(pwm)->PBCR = 1;
}
/**
* @brief Disable capture of selected channel(s)
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
* Bit 0 is channel 0, bit 1 is channel 1...
* @return None
* @details This function is used to disable capture of selected channel(s).
*/
void PWM_DisableCapture(PWM_T *pwm, uint32_t u32ChannelMask)
{
uint32_t i;
for(i = 0; i < PWM_CHANNEL_NUM; i ++)
{
if(u32ChannelMask & (1 << i))
{
if(i < 2)
{
(pwm)->CCR0 &= ~(PWM_CCR0_CAPCH0EN_Msk << (i * 16));
}
else
{
(pwm)->CCR2 &= ~(PWM_CCR2_CAPCH2EN_Msk << ((i - 2) * 16));
}
}
}
(pwm)->CAPENR &= ~u32ChannelMask;
}
/**
* @brief Enables PWM output generation of selected channel(s)
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel.
* Set bit 0 to 1 enables channel 0 output, set bit 1 to 1 enables channel 1 output...
* @return None
* @details This function is used to enables PWM output generation of selected channel(s).
*/
void PWM_EnableOutput(PWM_T *pwm, uint32_t u32ChannelMask)
{
(pwm)->POE |= u32ChannelMask;
}
/**
* @brief Disables PWM output generation of selected channel(s)
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel
* Set bit 0 to 1 disables channel 0 output, set bit 1 to 1 disables channel 1 output...
* @return None
* @details This function is used to disables PWM output generation of selected channel(s).
*/
void PWM_DisableOutput(PWM_T *pwm, uint32_t u32ChannelMask)
{
(pwm)->POE &= ~u32ChannelMask;
}
/**
* @brief Enable Dead zone of selected channel
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32Duration Dead Zone length in PWM clock count, valid values are between 0~0xFF, but 0 means there is no
* dead zone.
* @return None
* @details This function is used to enable Dead zone of selected channel.
*/
void PWM_EnableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration)
{
// every two channels shares the same setting
u32ChannelNum >>= 1;
// set duration
(pwm)->PPR = ((pwm)->PPR & ~(PWM_PPR_DZI01_Msk << (8 * u32ChannelNum))) | (u32Duration << (PWM_PPR_DZI01_Pos + 8 * u32ChannelNum));
// enable dead zone
(pwm)->PCR |= (PWM_PCR_DZEN01_Msk << u32ChannelNum);
}
/**
* @brief Disable Dead zone of selected channel
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @return None
* @details This function is used to disable Dead zone of selected channel.
*/
void PWM_DisableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum)
{
// every two channels shares the same setting
u32ChannelNum >>= 1;
// enable dead zone
(pwm)->PCR &= ~(PWM_PCR_DZEN01_Msk << u32ChannelNum);
}
/**
* @brief Enable capture interrupt of selected channel.
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32Edge Rising or falling edge to latch counter.
* - \ref PWM_CAPTURE_INT_RISING_LATCH
* - \ref PWM_CAPTURE_INT_FALLING_LATCH
* @return None
* @details This function is used to enable capture interrupt of selected channel.
*/
void PWM_EnableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
if(u32ChannelNum < 2)
(pwm)->CCR0 |= u32Edge << (u32ChannelNum * 16);
else
(pwm)->CCR2 |= u32Edge << ((u32ChannelNum - 2) * 16);
}
/**
* @brief Disable capture interrupt of selected channel.
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32Edge Rising or falling edge to latch counter.
* - \ref PWM_CAPTURE_INT_RISING_LATCH
* - \ref PWM_CAPTURE_INT_FALLING_LATCH
* @return None
* @details This function is used to disable capture interrupt of selected channel.
*/
void PWM_DisableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
if(u32ChannelNum < 2)
(pwm)->CCR0 &= ~(u32Edge << (u32ChannelNum * 16));
else
(pwm)->CCR2 &= ~(u32Edge << ((u32ChannelNum - 2) * 16));
}
/**
* @brief Clear capture interrupt of selected channel.
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32Edge Rising or falling edge to latch counter.
* - \ref PWM_CAPTURE_INT_RISING_LATCH
* - \ref PWM_CAPTURE_INT_FALLING_LATCH
* @return None
* @details This function is used to clear capture interrupt of selected channel.
*/
void PWM_ClearCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
//clear capture interrupt flag, and clear CRLR or CFLR latched indicator
if(u32ChannelNum < 2)
(pwm)->CCR0 = ((pwm)->CCR0 & PWM_CCR_MASK) | (PWM_CCR0_CAPIF0_Msk << (u32ChannelNum * 16)) | (u32Edge << (u32ChannelNum * 16 + 5));
else
(pwm)->CCR2 = ((pwm)->CCR2 & PWM_CCR_MASK) | (PWM_CCR2_CAPIF2_Msk << ((u32ChannelNum - 2) * 16)) | (u32Edge << ((u32ChannelNum - 2) * 16 + 5));
}
/**
* @brief Get capture interrupt of selected channel.
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @retval 0 No capture interrupt
* @retval 1 Rising edge latch interrupt
* @retval 2 Falling edge latch interrupt
* @retval 3 Rising and falling latch interrupt
* @details This function is used to get capture interrupt of selected channel.
*/
uint32_t PWM_GetCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
{
if(u32ChannelNum < 2)
{
return (((pwm)->CCR0 & ((PWM_CCR0_CRLRI0_Msk | PWM_CCR0_CFLRI0_Msk) << (u32ChannelNum * 16))) >> (PWM_CCR0_CRLRI0_Pos + u32ChannelNum * 16));
}
else
{
return (((pwm)->CCR2 & ((PWM_CCR2_CRLRI2_Msk | PWM_CCR2_CFLRI2_Msk) << ((u32ChannelNum - 2) * 16))) >> (PWM_CCR2_CRLRI2_Pos + (u32ChannelNum - 2) * 16));
}
}
/**
* @brief Enable duty interrupt of selected channel
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32IntDutyType This parameter is not used
* @return None
* @details This function is used to enable duty interrupt of selected channel.
* Every two channels, (0 & 1), (2 & 3), shares the duty interrupt type setting.
*/
void PWM_EnableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType)
{
(pwm)->PIER |= (PWM_PIER_PWMDIE0_Msk << u32ChannelNum);
}
/**
* @brief Disable duty interrupt of selected channel
* @param[in] pwm The pointer of the specified PWM module
* - PWMA : PWM Group A
* - PWMB : PWM Group B
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @return None
* @details This function is used to disable duty interrupt of selected channel.
*/
void PWM_DisableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum)
{
(pwm)->PIER &= ~(PWM_PIER_PWMDIE0_Msk << u32ChannelNum);
}
/**
* @brief Clear duty interrupt flag of selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @return None
* @details This function is used to clear duty interrupt flag of selected channel.
*/
void PWM_ClearDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
{
(pwm)->PIIR = PWM_PIIR_PWMDIF0_Msk << u32ChannelNum;
}
/**
* @brief Get duty interrupt flag of selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @retval 0 Duty interrupt did not occur
* @retval 1 Duty interrupt occurred
* @details This function is used to get duty interrupt flag of selected channel.
*/
uint32_t PWM_GetDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
{
return (((pwm)->PIIR & (PWM_PIIR_PWMDIF0_Msk << u32ChannelNum)) ? 1 : 0);
}
/**
* @brief Enable period interrupt of selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @param[in] u32IntPeriodType Period interrupt type, could be either
* - \ref PWM_PERIOD_INT_UNDERFLOW
* - \ref PWM_PERIOD_INT_MATCH_CNR
* @return None
* @details This function is used to enable period interrupt of selected channel.
* Every two channels, (0 & 1), (2 & 3), shares the period interrupt type setting.
*/
void PWM_EnablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType)
{
(pwm)->PIER = ((pwm)->PIER & ~(PWM_PIER_INT01TYPE_Msk << (u32ChannelNum >> 1))) | \
(PWM_PIER_PWMIE0_Msk << u32ChannelNum) | (u32IntPeriodType << (u32ChannelNum >> 1));
}
/**
* @brief Disable period interrupt of selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @return None
* @details This function is used to disable period interrupt of selected channel.
*/
void PWM_DisablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum)
{
(pwm)->PIER &= ~(PWM_PIER_PWMIE0_Msk << u32ChannelNum);
}
/**
* @brief Clear period interrupt of selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @return None
* @details This function is used to clear period interrupt of selected channel.
*/
void PWM_ClearPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
{
(pwm)->PIIR = (PWM_PIIR_PWMIF0_Msk << u32ChannelNum);
}
/**
* @brief Get period interrupt of selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~3
* @retval 0 Period interrupt did not occur
* @retval 1 Period interrupt occurred
* @details This function is used to get period interrupt of selected channel.
*/
uint32_t PWM_GetPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum)
{
return (((pwm)->PIIR & (PWM_PIIR_PWMIF0_Msk << (u32ChannelNum))) ? 1 : 0);
}
/*@}*/ /* end of group PWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group PWM_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,760 @@
/**************************************************************************//**
* @file retarget.c
* @version V3.00
* $Revision: 10 $
* $Date: 15/11/03 9:02a $
* @brief Debug Port and Semihost Setting Source File
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2011 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include "NUC200Series.h"
#if defined ( __CC_ARM )
#if (__ARMCC_VERSION < 400000)
#else
/* Insist on keeping widthprec, to avoid X propagation by benign code in C-lib */
#pragma import _printf_widthprec
#endif
#endif
/*---------------------------------------------------------------------------------------------------------*/
/* Global variables */
/*---------------------------------------------------------------------------------------------------------*/
#if !(defined(__ICCARM__) && (__VER__ >= 6010000))
struct __FILE
{
int handle; /* Add whatever you need here */
};
#endif
FILE __stdout;
FILE __stdin;
enum { r0, r1, r2, r3, r12, lr, pc, psr};
/**
* @brief Helper function to dump register while hard fault occurred
* @param[in] stack pointer points to the dumped registers in SRAM
* @return None
* @details This function is implement to print r0, r1, r2, r3, r12, lr, pc, psr
*/
static void stackDump(uint32_t stack[])
{
printf("r0 = 0x%x\n", stack[r0]);
printf("r1 = 0x%x\n", stack[r1]);
printf("r2 = 0x%x\n", stack[r2]);
printf("r3 = 0x%x\n", stack[r3]);
printf("r12 = 0x%x\n", stack[r12]);
printf("lr = 0x%x\n", stack[lr]);
printf("pc = 0x%x\n", stack[pc]);
printf("psr = 0x%x\n", stack[psr]);
}
/**
* @brief Hard fault handler
* @param[in] stack pointer points to the dumped registers in SRAM
* @return None
* @details Replace while(1) at the end of this function with chip reset if WDT is not enabled for end product
*/
void Hard_Fault_Handler(uint32_t stack[])
{
printf("In Hard Fault Handler\n");
stackDump(stack);
// Replace while(1) with chip reset if WDT is not enabled for end product
while(1);
//SYS->IPRSTC1 = SYS_IPRSTC1_CHIP_RST_Msk;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Routine to write a char */
/*---------------------------------------------------------------------------------------------------------*/
#if defined(DEBUG_ENABLE_SEMIHOST)
/* The static buffer is used to speed up the semihost */
static char g_buf[16];
static char g_buf_len = 0;
/* Make sure won't goes here only because --gnu is defined , so
add !__CC_ARM and !__ICCARM__ checking */
# if defined ( __GNUC__ ) && !(__CC_ARM) && !(__ICCARM__)
# elif defined(__ICCARM__)
void SH_End(void)
{
asm("MOVS R0,#1 \n" //; Set return value to 1
"BX lr \n" //; Return
);
}
void SH_ICE(void)
{
asm("CMP R2,#0 \n"
"BEQ SH_End \n"
"STR R0,[R2] \n" //; Save the return value to *pn32Out_R0
);
}
/**
*
* @brief The function to process semihosted command
* @param[in] n32In_R0 : semihost register 0
* @param[in] n32In_R1 : semihost register 1
* @param[out] pn32Out_R0: semihost register 0
* @retval 0: No ICE debug
* @retval 1: ICE debug
*
*/
int32_t SH_DoCommand(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0)
{
asm("BKPT 0xAB \n" //; This instruction will cause ICE trap or system HardFault
"B SH_ICE \n"
"SH_HardFault: \n" //; Captured by HardFault
"MOVS R0,#0 \n" //; Set return value to 0
"BX lr \n" //; Return
);
return 1; //; Return 1 when it is trap by ICE
}
/**
* @brief Get LR value and branch to Hard_Fault_Handler function
* @param None
* @return None
* @details This function is use to get LR value and branch to Hard_Fault_Handler function.
*/
void Get_LR_and_Branch(void)
{
asm("MOV R1, LR \n" //; LR current value
"B Hard_Fault_Handler \n"
);
}
/**
* @brief Get MSP value and branch to Get_LR_and_Branch function
* @param None
* @return None
* @details This function is use to get stack pointer value and branch to Get_LR_and_Branch function.
*/
void Stack_Use_MSP(void)
{
asm("MRS R0, MSP \n" //; read MSP
"B Get_LR_and_Branch \n"
);
}
/**
* @brief Get stack pointer value and branch to Get_LR_and_Branch function
* @param None
* @return None
* @details This function is use to get stack pointer value and branch to Get_LR_and_Branch function.
*/
void HardFault_Handler_Ret(void)
{
asm("MOVS r0, #4 \n"
"MOV r1, LR \n"
"TST r0, r1 \n" //; check LR bit 2
"BEQ Stack_Use_MSP \n" //; stack use MSP
"MRS R0, PSP \n" //; stack use PSP, read PSP
"B Get_LR_and_Branch \n"
);
}
/**
* @brief This function is implemented to support semihost
* @param None
* @returns None
* @details This function is implement to support semihost message print.
*
*/
void SP_Read_Ready(void)
{
asm("LDR R1, [R0, #24] \n" //; Get previous PC
"LDRH R3, [R1] \n" //; Get instruction
"LDR R2, [pc, #8] \n" //; The special BKPT instruction
"CMP R3, R2 \n" //; Test if the instruction at previous PC is BKPT
"BNE HardFault_Handler_Ret \n" //; Not BKPT
"ADDS R1, #4 \n" //; Skip BKPT and next line
"STR R1, [R0, #24] \n" //; Save previous PC
"BX lr \n" //; Return
"DCD 0xBEAB \n" //; BKPT instruction code
"B HardFault_Handler_Ret \n"
);
}
/**
* @brief Get stack pointer value and branch to Get_LR_and_Branch function
* @param None
* @return None
* @details This function is use to get stack pointer value and branch to Get_LR_and_Branch function.
*/
void SP_is_PSP(void)
{
asm(
"MRS R0, PSP \n" //; stack use PSP, read PSP
"B Get_LR_and_Branch \n"
);
}
/**
* @brief This HardFault handler is implemented to support semihost
*
* @param None
*
* @returns None
*
* @details This function is implement to support semihost message print.
*
*/
void HardFault_Handler (void)
{
asm("MOV R0, lr \n"
"LSLS R0, #29 \n" //; Check bit 2
"BMI SP_is_PSP \n" //; previous stack is PSP
"MRS R0, MSP \n" //; previous stack is MSP, read MSP
"B SP_Read_Ready \n"
);
while(1);
}
# else
/**
* @brief This HardFault handler is implemented to support semihost
* @param None
* @returns None
* @details This function is implement to support semihost message print.
*
*/
__asm int32_t HardFault_Handler(void)
{
MOV R0, LR
LSLS R0, #29 //; Check bit 2
BMI SP_is_PSP //; previous stack is PSP
MRS R0, MSP //; previous stack is MSP, read MSP
B SP_Read_Ready
SP_is_PSP
MRS R0, PSP //; Read PSP
SP_Read_Ready
LDR R1, [R0, #24] //; Get previous PC
LDRH R3, [R1] //; Get instruction
LDR R2, =0xBEAB //; The special BKPT instruction
CMP R3, R2 //; Test if the instruction at previous PC is BKPT
BNE HardFault_Handler_Ret //; Not BKPT
ADDS R1, #4 //; Skip BKPT and next line
STR R1, [R0, #24] //; Save previous PC
BX LR //; Return
HardFault_Handler_Ret
/* TODO: Implement your own hard fault handler here. */
MOVS r0, #4
MOV r1, LR
TST r0, r1 //; check LR bit 2
BEQ Stack_Use_MSP //; stack use MSP
MRS R0, PSP ;stack use PSP //; stack use PSP, read PSP
B Get_LR_and_Branch
Stack_Use_MSP
MRS R0, MSP ; stack use MSP //; read MSP
Get_LR_and_Branch
MOV R1, LR ; LR current value //; LR current value
LDR R2,=__cpp(Hard_Fault_Handler) //; branch to Hard_Fault_Handler
BX R2
B .
ALIGN
}
/**
*
* @brief The function to process semihosted command
* @param[in] n32In_R0 : semihost register 0
* @param[in] n32In_R1 : semihost register 1
* @param[out] pn32Out_R0: semihost register 0
* @retval 0: No ICE debug
* @retval 1: ICE debug
*
*/
__asm int32_t SH_DoCommand(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0)
{
BKPT 0xAB //; Wait ICE or HardFault
//; ICE will step over BKPT directly
//; HardFault will step BKPT and the next line
B SH_ICE
SH_HardFault //; Captured by HardFault
MOVS R0, #0 //; Set return value to 0
BX lr //; Return
SH_ICE //; Captured by ICE
//; Save return value
CMP R2, #0
BEQ SH_End
STR R0, [R2] //; Save the return value to *pn32Out_R0
SH_End
MOVS R0, #1 //; Set return value to 1
BX lr //; Return
}
#endif
#else // Non-semihost
/* Make sure won't goes here only because --gnu is defined , so
add !__CC_ARM and !__ICCARM__ checking */
# if defined ( __GNUC__ ) && !(__CC_ARM) && !(__ICCARM__)
/**
* @brief This HardFault handler is implemented to show r0, r1, r2, r3, r12, lr, pc, psr
*
* @param None
*
* @returns None
*
* @details This function is implement to print r0, r1, r2, r3, r12, lr, pc, psr.
*
*/
void HardFault_Handler(void)
{
asm("MOVS r0, #4 \n"
"MOV r1, LR \n"
"TST r0, r1 \n" /*; check LR bit 2 */
"BEQ 1f \n" /*; stack use MSP */
"MRS R0, PSP \n" /*; stack use PSP, read PSP */
"MOV R1, LR \n" /*; LR current value */
"B Hard_Fault_Handler \n"
"1: \n"
"MRS R0, MSP \n" /*; LR current value */
"B Hard_Fault_Handler \n"
::[Hard_Fault_Handler] "r" (Hard_Fault_Handler) // input
);
while(1);
}
# elif defined(__ICCARM__)
void Get_LR_and_Branch(void)
{
asm("MOV R1, LR \n" //; LR current value
"B Hard_Fault_Handler \n"
);
}
void Stack_Use_MSP(void)
{
asm("MRS R0, MSP \n" //; read MSP
"B Get_LR_and_Branch \n"
);
}
/**
* @brief This HardFault handler is implemented to show r0, r1, r2, r3, r12, lr, pc, psr
*
* @param None
*
* @returns None
*
* @details This function is implement to print r0, r1, r2, r3, r12, lr, pc, psr.
*
*/
void HardFault_Handler(void)
{
asm("MOVS r0, #4 \n"
"MOV r1, LR \n"
"TST r0, r1 \n" //; check LR bit 2
"BEQ Stack_Use_MSP \n" //; stack use MSP
"MRS R0, PSP \n" //; stack use PSP, read PSP
"B Get_LR_and_Branch \n"
);
while(1);
}
# else
/**
* @brief This HardFault handler is implemented to show r0, r1, r2, r3, r12, lr, pc, psr
*
* @param None
*
* @return None
*
* @details The function extracts the location of stack frame and passes it to Hard_Fault_Handler function as a pointer
*
*/
__asm int32_t HardFault_Handler(void)
{
MOVS r0, #4
MOV r1, LR
TST r0, r1 //; check LR bit 2
BEQ Stack_Use_MSP //; stack use MSP
MRS R0, PSP //; stack use PSP, read PSP
B Get_LR_and_Branch
Stack_Use_MSP
MRS R0, MSP //; read MSP
Get_LR_and_Branch
MOV R1, LR //; LR current value
LDR R2,=__cpp(Hard_Fault_Handler) //; branch to Hard_Fault_Handler
BX R2
}
#endif
#endif
/**
* @brief Routine to send a char
*
* @param[in] ch Character to send to debug port.
*
* @returns Send value from UART debug port
*
* @details Send a target char to UART debug port .
*/
#ifndef NONBLOCK_PRINTF
void SendChar_ToUART(int ch)
{
while(DEBUG_PORT->FSR & UART_FSR_TX_FULL_Msk);
if(ch == '\n')
{
DEBUG_PORT->DATA = '\r';
while(DEBUG_PORT->FSR & UART_FSR_TX_FULL_Msk);
}
DEBUG_PORT->DATA = ch;
}
#else
/* Non-block implement of send char */
#define BUF_SIZE 2048
void SendChar_ToUART(int ch)
{
static uint8_t u8Buf[BUF_SIZE] = {0};
static int32_t i32Head = 0;
static int32_t i32Tail = 0;
int32_t i32Tmp;
/* Only flush the data in buffer to UART when ch == 0 */
if(ch)
{
// Push char
if(ch == '\n')
{
i32Tmp = i32Head + 1;
if(i32Tmp >= BUF_SIZE) i32Tmp = 0;
if(i32Tmp != i32Tail)
{
u8Buf[i32Head] = '\r';
i32Head = i32Tmp;
}
}
i32Tmp = i32Head + 1;
if(i32Tmp >= BUF_SIZE) i32Tmp = 0;
if(i32Tmp != i32Tail)
{
u8Buf[i32Head] = ch;
i32Head = i32Tmp;
}
}
else
{
if(i32Tail == i32Head)
return;
}
// pop char
do
{
i32Tmp = i32Tail + 1;
if(i32Tmp >= BUF_SIZE) i32Tmp = 0;
if((DEBUG_PORT->FSR & UART_FSR_TX_FULL_Msk) == 0)
{
DEBUG_PORT->THR = u8Buf[i32Tail];
i32Tail = i32Tmp;
}
else
break; // FIFO full
}
while(i32Tail != i32Head);
}
#endif
/**
* @brief Routine to send a char
*
* @param[in] ch Character to send to debug port.
*
* @returns Send value from UART debug port or semihost
*
* @details Send a target char to UART debug port or semihost.
*/
void SendChar(int ch)
{
#if defined(DEBUG_ENABLE_SEMIHOST)
g_buf[g_buf_len++] = ch;
g_buf[g_buf_len] = '\0';
if(g_buf_len + 1 >= sizeof(g_buf) || ch == '\n' || ch == '\0')
{
/* Send the char */
if(SH_DoCommand(0x04, (int)g_buf, NULL) != 0)
{
g_buf_len = 0;
return;
}
else
{
g_buf_len = 0;
}
}
#else
SendChar_ToUART(ch);
#endif
}
/**
* @brief Routine to get a char
*
* @param None
*
* @returns Get value from UART debug port or semihost
*
* @details Wait UART debug port or semihost to input a char.
*/
char GetChar(void)
{
#ifdef DEBUG_ENABLE_SEMIHOST
# if defined ( __CC_ARM )
int nRet;
while(SH_DoCommand(0x101, 0, &nRet) != 0)
{
if(nRet != 0)
{
SH_DoCommand(0x07, 0, &nRet);
return (char)nRet;
}
}
# else
int nRet;
while(SH_DoCommand(0x7, 0, &nRet) != 0)
{
if(nRet != 0)
return (char)nRet;
}
# endif
return (0);
#else
while(1)
{
if((DEBUG_PORT->FSR & UART_FSR_RX_EMPTY_Msk) == 0)
{
return (DEBUG_PORT->DATA);
}
}
#endif
}
/**
* @brief Check any char input from UART
*
* @param None
*
* @retval 1: No any char input
* @retval 0: Have some char input
*
* @details Check UART RSR RX EMPTY or not to determine if any char input from UART
*/
int kbhit(void)
{
return !((DEBUG_PORT->FSR & UART_FSR_RX_EMPTY_Msk) == 0);
}
/**
* @brief Check if debug message finished
*
* @param None
*
* @retval 1: Message is finished
* @retval 0: Message is transmitting.
*
* @details Check if message finished (FIFO empty of debug port)
*/
int IsDebugFifoEmpty(void)
{
return ((DEBUG_PORT->FSR & UART_FSR_TE_FLAG_Msk) != 0);
}
/**
* @brief C library retargetting
*
* @param[in] ch Character to send to debug port.
*
* @returns None
*
* @details Check if message finished (FIFO empty of debug port)
*/
void _ttywrch(int ch)
{
SendChar(ch);
return;
}
/**
* @brief Write character to stream
*
* @param[in] ch Character to be written. The character is passed as its int promotion.
* @param[in] stream Pointer to a FILE object that identifies the stream where the character is to be written.
*
* @returns If there are no errors, the same character that has been written is returned.
* If an error occurs, EOF is returned and the error indicator is set (see ferror).
*
* @details Writes a character to the stream and advances the position indicator.\n
* The character is written at the current position of the stream as indicated \n
* by the internal position indicator, which is then advanced one character.
*
* @note The above descriptions are copied from http://www.cplusplus.com/reference/clibrary/cstdio/fputc/.
*
*
*/
int fputc(int ch, FILE *stream)
{
SendChar(ch);
return ch;
}
#if defined ( __GNUC__ )
#if !defined(OS_USE_SEMIHOSTING)
int _write (int fd, char *ptr, int len)
{
int i = len;
while(i--)
{
while(DEBUG_PORT->FSR & UART_FSR_TX_FULL_Msk);
if(*ptr == '\n')
{
DEBUG_PORT->DATA = '\r';
while(DEBUG_PORT->FSR & UART_FSR_TX_FULL_Msk);
}
DEBUG_PORT->DATA = *ptr++;
}
return len;
}
int _read (int fd, char *ptr, int len)
{
while((DEBUG_PORT->FSR & UART_FSR_RX_EMPTY_Msk) != 0);
*ptr = DEBUG_PORT->DATA;
return 1;
}
#endif
#else
/**
* @brief Get character from UART debug port or semihosting input
*
* @param[in] stream Pointer to a FILE object that identifies the stream on which the operation is to be performed.
*
* @returns The character read from UART debug port or semihosting
*
* @details For get message from debug port or semihosting.
*
*/
int fgetc(FILE *stream)
{
return (GetChar());
}
/**
* @brief Check error indicator
*
* @param[in] stream Pointer to a FILE object that identifies the stream.
*
* @returns If the error indicator associated with the stream was set, the function returns a nonzero value.
* Otherwise, it returns a zero value.
*
* @details Checks if the error indicator associated with stream is set, returning a value different
* from zero if it is. This indicator is generally set by a previous operation on the stream that failed.
*
* @note The above descriptions are copied from http://www.cplusplus.com/reference/clibrary/cstdio/ferror/.
*
*/
int ferror(FILE *stream)
{
return EOF;
}
#endif
#ifdef DEBUG_ENABLE_SEMIHOST
# ifdef __ICCARM__
void __exit(int return_code)
{
/* Check if link with ICE */
if(SH_DoCommand(0x18, 0x20026, NULL) == 0)
{
/* Make sure all message is print out */
while(IsDebugFifoEmpty() == 0);
}
label:
goto label; /* endless loop */
}
# else
void _sys_exit(int return_code)
{
/* Check if link with ICE */
if(SH_DoCommand(0x18, 0x20026, NULL) == 0)
{
/* Make sure all message is print out */
while(IsDebugFifoEmpty() == 0);
}
label:
goto label; /* endless loop */
}
# endif
#endif

786
BSP/StdDriver/src/rtc.c Normal file
View File

@ -0,0 +1,786 @@
/**************************************************************************//**
* @file rtc.c
* @version V3.00
* $Revision: 13 $
* $Date: 15/05/06 6:51p $
* @brief RTC driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/// @cond HIDDEN_SYMBOLS
/*---------------------------------------------------------------------------------------------------------*/
/* Macro, type and constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define RTC_GLOBALS
/*---------------------------------------------------------------------------------------------------------*/
/* Global file scope (static) variables */
/*---------------------------------------------------------------------------------------------------------*/
static volatile uint32_t g_u32hiYear, g_u32loYear, g_u32hiMonth, g_u32loMonth, g_u32hiDay, g_u32loDay;
static volatile uint32_t g_u32hiHour, g_u32loHour, g_u32hiMin, g_u32loMin, g_u32hiSec, g_u32loSec;
/// @endcond HIDDEN_SYMBOLS
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup RTC_Driver RTC Driver
@{
*/
/** @addtogroup RTC_EXPORTED_FUNCTIONS RTC Exported Functions
@{
*/
/**
* @brief Initialize RTC setting and start counting
*
* @param[in] sPt Specify the time property and current date and time. It includes: \n
* u32Year: Year value. \n
* u32Month: Month value. \n
* u32Day: Day value. \n
* u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
* RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
* RTC_SATURDAY] \n
* u32Hour: Hour value. \n
* u32Minute: Minute value. \n
* u32Second: Second value. \n
* u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n
* u8AmPm: [RTC_AM / RTC_PM] \n
*
* @return None
*
* @details This function is used to: \n
* 1. Write initial key to let RTC start count. \n
* 2. Input parameter indicates start date/time. \n
* @note Null pointer for using default starting date/time.
*/
void RTC_Open(S_RTC_TIME_DATA_T *sPt)
{
RTC->INIR = RTC_INIT_KEY;
if(RTC->INIR != 0x1)
{
RTC->INIR = RTC_INIT_KEY;
while(RTC->INIR != 0x1);
}
if(sPt == NULL)
return ;
/* Set RTC date and time */
RTC_SetDateAndTime(sPt);
/* Waiting for RTC settings stable */
while((RTC->AER & RTC_AER_ENF_Msk) == RTC_AER_ENF_Msk);
}
/**
* @brief Disable RTC Clock
*
* @param None
*
* @return None
*
* @details This API disable RTC peripheral clock and stops RTC counting.
*/
void RTC_Close(void)
{
CLK->APBCLK &= ~CLK_APBCLK_RTC_EN_Msk;
}
/**
* @brief Set 32k Frequency Compensation Data
*
* @param[in] i32FrequencyX100 Specify the RTC clock X100, ex: 3277365 means 32773.65.
*
* @return None
*
* @details This API is used to compensate the 32 kHz frequency by current LXT frequency for RTC application.
*/
void RTC_32KCalibration(int32_t i32FrequencyX100)
{
int32_t i32RegInt, i32RegFra;
/* Compute integer and fraction for RTC FCR register */
i32RegInt = (i32FrequencyX100 / 100) - RTC_FCR_REFERENCE;
i32RegFra = (((i32FrequencyX100 % 100)) * 60) / 100;
/* Judge Integer part is reasonable */
if((i32RegInt < 0) | (i32RegInt > 15))
{
return ;
}
RTC_WaitAccessEnable();
RTC->FCR = (uint32_t)((i32RegInt << 8) | i32RegFra);
}
/**
* @brief Get Current RTC Date and Time
*
* @param[out] sPt The returned pointer is specified the current RTC value. It includes: \n
* u32Year: Year value \n
* u32Month: Month value \n
* u32Day: Day value \n
* u32DayOfWeek: Day of week \n
* u32Hour: Hour value \n
* u32Minute: Minute value \n
* u32Second: Second value \n
* u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n
* u8AmPm: [RTC_AM / RTC_PM] \n
*
* @return None
*
* @details This API is used to get the current RTC date and time value.
*/
void RTC_GetDateAndTime(S_RTC_TIME_DATA_T *sPt)
{
uint32_t u32Tmp;
sPt->u32TimeScale = RTC->TSSR & RTC_TSSR_24H_12H_Msk; /* 12/24-hour */
sPt->u32DayOfWeek = RTC->DWR & RTC_DWR_DWR_Msk; /* Day of the week */
/* Get [Date digit] data */
g_u32hiYear = (RTC->CLR & RTC_CLR_10YEAR_Msk) >> RTC_CLR_10YEAR_Pos;
g_u32loYear = (RTC->CLR & RTC_CLR_1YEAR_Msk) >> RTC_CLR_1YEAR_Pos;
g_u32hiMonth = (RTC->CLR & RTC_CLR_10MON_Msk) >> RTC_CLR_10MON_Pos;
g_u32loMonth = (RTC->CLR & RTC_CLR_1MON_Msk) >> RTC_CLR_1MON_Pos;
g_u32hiDay = (RTC->CLR & RTC_CLR_10DAY_Msk) >> RTC_CLR_10DAY_Pos;
g_u32loDay = (RTC->CLR & RTC_CLR_1DAY_Msk);
/* Get [Time digit] data */
g_u32hiHour = (RTC->TLR & RTC_TLR_10HR_Msk) >> RTC_TLR_10HR_Pos;
g_u32loHour = (RTC->TLR & RTC_TLR_1HR_Msk) >> RTC_TLR_1HR_Pos;
g_u32hiMin = (RTC->TLR & RTC_TLR_10MIN_Msk) >> RTC_TLR_10MIN_Pos;
g_u32loMin = (RTC->TLR & RTC_TLR_1MIN_Msk) >> RTC_TLR_1MIN_Pos;
g_u32hiSec = (RTC->TLR & RTC_TLR_10SEC_Msk) >> RTC_TLR_10SEC_Pos;
g_u32loSec = (RTC->TLR & RTC_TLR_1SEC_Msk);
/* Compute to 20XX year */
u32Tmp = (g_u32hiYear * 10);
u32Tmp += g_u32loYear;
sPt->u32Year = u32Tmp + RTC_YEAR2000;
/* Compute 0~12 month */
u32Tmp = (g_u32hiMonth * 10);
sPt->u32Month = u32Tmp + g_u32loMonth;
/* Compute 0~31 day */
u32Tmp = (g_u32hiDay * 10);
sPt->u32Day = u32Tmp + g_u32loDay;
/* Compute 12/24 hour */
if(sPt->u32TimeScale == RTC_CLOCK_12)
{
u32Tmp = (g_u32hiHour * 10);
u32Tmp += g_u32loHour;
sPt->u32Hour = u32Tmp; /* AM: 1~12. PM: 21~32. */
if(sPt->u32Hour >= 21)
{
sPt->u32AmPm = RTC_PM;
sPt->u32Hour -= 20;
}
else
{
sPt->u32AmPm = RTC_AM;
}
u32Tmp = (g_u32hiMin * 10);
u32Tmp += g_u32loMin;
sPt->u32Minute = u32Tmp;
u32Tmp = (g_u32hiSec * 10);
u32Tmp += g_u32loSec;
sPt->u32Second = u32Tmp;
}
else
{
u32Tmp = (g_u32hiHour * 10);
u32Tmp += g_u32loHour;
sPt->u32Hour = u32Tmp;
u32Tmp = (g_u32hiMin * 10);
u32Tmp += g_u32loMin;
sPt->u32Minute = u32Tmp;
u32Tmp = (g_u32hiSec * 10);
u32Tmp += g_u32loSec;
sPt->u32Second = u32Tmp;
}
}
/**
* @brief Get RTC Alarm Date and Time
*
* @param[out] sPt The returned pointer is specified the RTC alarm value. It includes: \n
* u32Year: Year value \n
* u32Month: Month value \n
* u32Day: Day value \n
* u32DayOfWeek: Day of week \n
* u32Hour: Hour value \n
* u32Minute: Minute value \n
* u32Second: Second value \n
* u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n
* u8AmPm: [RTC_AM / RTC_PM] \n
*
* @return None
*
* @details This API is used to get the RTC alarm date and time setting.
*/
void RTC_GetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt)
{
uint32_t u32Tmp;
sPt->u32TimeScale = RTC->TSSR & RTC_TSSR_24H_12H_Msk; /* 12/24-hour */
sPt->u32DayOfWeek = RTC->DWR & RTC_DWR_DWR_Msk; /* Day of the week */
/* Get alarm [Date digit] data */
RTC_WaitAccessEnable();
g_u32hiYear = (RTC->CAR & RTC_CAR_10YEAR_Msk) >> RTC_CAR_10YEAR_Pos;
g_u32loYear = (RTC->CAR & RTC_CAR_1YEAR_Msk) >> RTC_CAR_1YEAR_Pos;
g_u32hiMonth = (RTC->CAR & RTC_CAR_10MON_Msk) >> RTC_CAR_10MON_Pos;
g_u32loMonth = (RTC->CAR & RTC_CAR_1MON_Msk) >> RTC_CAR_1MON_Pos;
g_u32hiDay = (RTC->CAR & RTC_CAR_10DAY_Msk) >> RTC_CAR_10DAY_Pos;
g_u32loDay = (RTC->CAR & RTC_CAR_1DAY_Msk);
/* Get alarm [Time digit] data */
RTC_WaitAccessEnable();
g_u32hiHour = (RTC->TAR & RTC_TAR_10HR_Msk) >> RTC_TAR_10HR_Pos;
g_u32loHour = (RTC->TAR & RTC_TAR_1HR_Msk) >> RTC_TAR_1HR_Pos;
g_u32hiMin = (RTC->TAR & RTC_TAR_10MIN_Msk) >> RTC_TAR_10MIN_Pos;
g_u32loMin = (RTC->TAR & RTC_TAR_1MIN_Msk) >> RTC_TAR_1MIN_Pos;
g_u32hiSec = (RTC->TAR & RTC_TAR_10SEC_Msk) >> RTC_TAR_10SEC_Pos;
g_u32loSec = (RTC->TAR & RTC_TAR_1SEC_Msk);
/* Compute to 20XX year */
u32Tmp = (g_u32hiYear * 10);
u32Tmp += g_u32loYear;
sPt->u32Year = u32Tmp + RTC_YEAR2000;
/* Compute 0~12 month */
u32Tmp = (g_u32hiMonth * 10);
sPt->u32Month = u32Tmp + g_u32loMonth;
/* Compute 0~31 day */
u32Tmp = (g_u32hiDay * 10);
sPt->u32Day = u32Tmp + g_u32loDay;
/* Compute 12/24 hour */
if(sPt->u32TimeScale == RTC_CLOCK_12)
{
u32Tmp = (g_u32hiHour * 10);
u32Tmp += g_u32loHour;
sPt->u32Hour = u32Tmp; /* AM: 1~12. PM: 21~32. */
if(sPt->u32Hour >= 21)
{
sPt->u32AmPm = RTC_PM;
sPt->u32Hour -= 20;
}
else
{
sPt->u32AmPm = RTC_AM;
}
u32Tmp = (g_u32hiMin * 10);
u32Tmp += g_u32loMin;
sPt->u32Minute = u32Tmp;
u32Tmp = (g_u32hiSec * 10);
u32Tmp += g_u32loSec;
sPt->u32Second = u32Tmp;
}
else
{
u32Tmp = (g_u32hiHour * 10);
u32Tmp += g_u32loHour;
sPt->u32Hour = u32Tmp;
u32Tmp = (g_u32hiMin * 10);
u32Tmp += g_u32loMin;
sPt->u32Minute = u32Tmp;
u32Tmp = (g_u32hiSec * 10);
u32Tmp += g_u32loSec;
sPt->u32Second = u32Tmp;
}
}
/**
* @brief Update Current RTC Date and Time
*
* @param[in] sPt Specify the time property and current date and time. It includes: \n
* u32Year: Year value. \n
* u32Month: Month value. \n
* u32Day: Day value. \n
* u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
* RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
* RTC_SATURDAY] \n
* u32Hour: Hour value. \n
* u32Minute: Minute value. \n
* u32Second: Second value. \n
* u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n
* u8AmPm: [RTC_AM / RTC_PM] \n
*
* @return None
*
* @details This API is used to update current date and time to RTC.
*/
void RTC_SetDateAndTime(S_RTC_TIME_DATA_T *sPt)
{
uint32_t u32RegCLR, u32RegTLR;
if(sPt == NULL)
return ;
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC 24/12 hour setting and Day of the Week */
/*-----------------------------------------------------------------------------------------------------*/
RTC_WaitAccessEnable();
if(sPt->u32TimeScale == RTC_CLOCK_12)
{
RTC->TSSR &= ~RTC_TSSR_24H_12H_Msk;
/*-------------------------------------------------------------------------------------------------*/
/* Important, range of 12-hour PM mode is 21 up to 32 */
/*-------------------------------------------------------------------------------------------------*/
if(sPt->u32AmPm == RTC_PM)
sPt->u32Hour += 20;
}
else
{
RTC->TSSR |= RTC_TSSR_24H_12H_Msk;
}
/* Set Day of the Week */
RTC->DWR = sPt->u32DayOfWeek;
u32RegCLR = ((sPt->u32Year - RTC_YEAR2000) / 10) << 20;
u32RegCLR |= (((sPt->u32Year - RTC_YEAR2000) % 10) << 16);
u32RegCLR |= ((sPt->u32Month / 10) << 12);
u32RegCLR |= ((sPt->u32Month % 10) << 8);
u32RegCLR |= ((sPt->u32Day / 10) << 4);
u32RegCLR |= (sPt->u32Day % 10);
u32RegTLR = ((sPt->u32Hour / 10) << 20);
u32RegTLR |= ((sPt->u32Hour % 10) << 16);
u32RegTLR |= ((sPt->u32Minute / 10) << 12);
u32RegTLR |= ((sPt->u32Minute % 10) << 8);
u32RegTLR |= ((sPt->u32Second / 10) << 4);
u32RegTLR |= (sPt->u32Second % 10);
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC Calender and Time Loading */
/*-----------------------------------------------------------------------------------------------------*/
RTC_WaitAccessEnable();
RTC->CLR = (uint32_t)u32RegCLR;
RTC->TLR = (uint32_t)u32RegTLR;
}
/**
* @brief Update RTC Alarm Date and Time
*
* @param[in] sPt Specify the time property and alarm date and time. It includes: \n
* u32Year: Year value. \n
* u32Month: Month value. \n
* u32Day: Day value. \n
* u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
* RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
* RTC_SATURDAY] \n
* u32Hour: Hour value. \n
* u32Minute: Minute value. \n
* u32Second: Second value. \n
* u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n
* u8AmPm: [RTC_AM / RTC_PM] \n
*
* @return None
*
* @details This API is used to update alarm date and time setting to RTC.
*/
void RTC_SetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt)
{
uint32_t u32RegCAR, u32RegTAR;
if(sPt == NULL)
return ;
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC 24/12 hour setting and Day of the Week */
/*-----------------------------------------------------------------------------------------------------*/
RTC_WaitAccessEnable();
if(sPt->u32TimeScale == RTC_CLOCK_12)
{
RTC->TSSR &= ~RTC_TSSR_24H_12H_Msk;
/*-------------------------------------------------------------------------------------------------*/
/* Important, range of 12-hour PM mode is 21 up to 32 */
/*-------------------------------------------------------------------------------------------------*/
if(sPt->u32AmPm == RTC_PM)
sPt->u32Hour += 20;
}
else
{
RTC->TSSR |= RTC_TSSR_24H_12H_Msk;
}
/* Set Day of the Week */
RTC->DWR = sPt->u32DayOfWeek;
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC Calender and Time Loading */
/*-----------------------------------------------------------------------------------------------------*/
u32RegCAR = ((sPt->u32Year - RTC_YEAR2000) / 10) << 20;
u32RegCAR |= (((sPt->u32Year - RTC_YEAR2000) % 10) << 16);
u32RegCAR |= ((sPt->u32Month / 10) << 12);
u32RegCAR |= ((sPt->u32Month % 10) << 8);
u32RegCAR |= ((sPt->u32Day / 10) << 4);
u32RegCAR |= (sPt->u32Day % 10);
u32RegTAR = ((sPt->u32Hour / 10) << 20);
u32RegTAR |= ((sPt->u32Hour % 10) << 16);
u32RegTAR |= ((sPt->u32Minute / 10) << 12);
u32RegTAR |= ((sPt->u32Minute % 10) << 8);
u32RegTAR |= ((sPt->u32Second / 10) << 4);
u32RegTAR |= (sPt->u32Second % 10);
RTC_WaitAccessEnable();
RTC->CAR = (uint32_t)u32RegCAR;
RTC->TAR = (uint32_t)u32RegTAR;
}
/**
* @brief Update RTC Current Date
*
* @param[in] u32Year The year calendar digit of current RTC setting.
* @param[in] u32Month The month calendar digit of current RTC setting.
* @param[in] u32Day The day calendar digit of current RTC setting.
* @param[in] u32DayOfWeek The Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
* RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
* RTC_SATURDAY]
*
* @return None
*
* @details This API is used to update current date to RTC.
*/
void RTC_SetDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day, uint32_t u32DayOfWeek)
{
uint32_t u32RegCLR;
u32RegCLR = ((u32Year - RTC_YEAR2000) / 10) << 20;
u32RegCLR |= (((u32Year - RTC_YEAR2000) % 10) << 16);
u32RegCLR |= ((u32Month / 10) << 12);
u32RegCLR |= ((u32Month % 10) << 8);
u32RegCLR |= ((u32Day / 10) << 4);
u32RegCLR |= (u32Day % 10);
RTC_WaitAccessEnable();
/* Set Day of the Week */
RTC->DWR = u32DayOfWeek & RTC_DWR_DWR_Msk;
/* Set RTC Calender Loading */
RTC->CLR = (uint32_t)u32RegCLR;
}
/**
* @brief Update RTC Current Time
*
* @param[in] u32Hour The hour time digit of current RTC setting.
* @param[in] u32Minute The minute time digit of current RTC setting.
* @param[in] u32Second The second time digit of current RTC setting.
* @param[in] u32TimeMode The 24-Hour / 12-Hour Time Scale Selection. [RTC_CLOCK_12 / RTC_CLOCK_24]
* @param[in] u32AmPm 12-hour time scale with AM and PM indication. Only Time Scale select 12-hour used. [RTC_AM / RTC_PM]
*
* @return None
*
* @details This API is used to update current time to RTC.
*/
void RTC_SetTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm)
{
uint32_t u32RegTLR;
/* Important, range of 12-hour PM mode is 21 up to 32 */
if((u32TimeMode == RTC_CLOCK_12) && (u32AmPm == RTC_PM))
u32Hour += 20;
u32RegTLR = ((u32Hour / 10) << 20);
u32RegTLR |= ((u32Hour % 10) << 16);
u32RegTLR |= ((u32Minute / 10) << 12);
u32RegTLR |= ((u32Minute % 10) << 8);
u32RegTLR |= ((u32Second / 10) << 4);
u32RegTLR |= (u32Second % 10);
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC 24/12 hour setting and Day of the Week */
/*-----------------------------------------------------------------------------------------------------*/
RTC_WaitAccessEnable();
if(u32TimeMode == RTC_CLOCK_12)
{
RTC->TSSR &= ~RTC_TSSR_24H_12H_Msk;
}
else
{
RTC->TSSR |= RTC_TSSR_24H_12H_Msk;
}
RTC->TLR = (uint32_t)u32RegTLR;
}
/**
* @brief Update RTC Alarm Date
*
* @param[in] u32Year The year calendar digit of RTC alarm setting.
* @param[in] u32Month The month calendar digit of RTC alarm setting.
* @param[in] u32Day The day calendar digit of RTC alarm setting.
*
* @return None
*
* @details This API is used to update alarm date setting to RTC.
*/
void RTC_SetAlarmDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day)
{
uint32_t u32RegCAR;
u32RegCAR = ((u32Year - RTC_YEAR2000) / 10) << 20;
u32RegCAR |= (((u32Year - RTC_YEAR2000) % 10) << 16);
u32RegCAR |= ((u32Month / 10) << 12);
u32RegCAR |= ((u32Month % 10) << 8);
u32RegCAR |= ((u32Day / 10) << 4);
u32RegCAR |= (u32Day % 10);
RTC_WaitAccessEnable();
/* Set RTC Alarm Date */
RTC->CAR = (uint32_t)u32RegCAR;
}
/**
* @brief Update RTC Alarm Time
*
* @param[in] u32Hour The hour time digit of RTC alarm setting.
* @param[in] u32Minute The minute time digit of RTC alarm setting.
* @param[in] u32Second The second time digit of RTC alarm setting.
* @param[in] u32TimeMode The 24-Hour / 12-Hour Time Scale Selection. [RTC_CLOCK_12 / RTC_CLOCK_24]
* @param[in] u32AmPm 12-hour time scale with AM and PM indication. Only Time Scale select 12-hour used. [RTC_AM / RTC_PM]
*
* @return None
*
* @details This API is used to update alarm time setting to RTC.
*/
void RTC_SetAlarmTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm)
{
uint32_t u32RegTAR;
/* Important, range of 12-hour PM mode is 21 up to 32 */
if((u32TimeMode == RTC_CLOCK_12) && (u32AmPm == RTC_PM))
u32Hour += 20;
u32RegTAR = ((u32Hour / 10) << 20);
u32RegTAR |= ((u32Hour % 10) << 16);
u32RegTAR |= ((u32Minute / 10) << 12);
u32RegTAR |= ((u32Minute % 10) << 8);
u32RegTAR |= ((u32Second / 10) << 4);
u32RegTAR |= (u32Second % 10);
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC 24/12 hour setting and Day of the Week */
/*-----------------------------------------------------------------------------------------------------*/
RTC_WaitAccessEnable();
if(u32TimeMode == RTC_CLOCK_12)
{
RTC->TSSR &= ~RTC_TSSR_24H_12H_Msk;
}
else
{
RTC->TSSR |= RTC_TSSR_24H_12H_Msk;
}
/* Set RTC Alarm Time */
RTC->TAR = (uint32_t)u32RegTAR;
}
/**
* @brief Get Day of the Week
*
* @param None
*
* @retval 0 Sunday
* @retval 1 Monday
* @retval 2 Tuesday
* @retval 3 Wednesday
* @retval 4 Thursday
* @retval 5 Friday
* @retval 6 Saturday
*
* @details This API is used to get day of the week of current RTC setting.
*/
uint32_t RTC_GetDayOfWeek(void)
{
return (RTC->DWR & RTC_DWR_DWR_Msk);
}
/**
* @brief Set RTC Tick Period Time
*
* @param[in] u32TickSelection It is used to set the RTC time tick period for Periodic Time Tick request. \n
* It consists of: \n
* RTC_TICK_1_SEC: Time tick is 1 second \n
* RTC_TICK_1_2_SEC: Time tick is 1/2 second \n
* RTC_TICK_1_4_SEC: Time tick is 1/4 second \n
* RTC_TICK_1_8_SEC: Time tick is 1/8 second \n
* RTC_TICK_1_16_SEC: Time tick is 1/16 second \n
* RTC_TICK_1_32_SEC: Time tick is 1/32 second \n
* RTC_TICK_1_64_SEC: Time tick is 1/64 second \n
* RTC_TICK_1_128_SEC: Time tick is 1/128 second
*
* @return None
*
* @details This API is used to set time tick period for periodic time tick interrupt.
*/
void RTC_SetTickPeriod(uint32_t u32TickSelection)
{
RTC_WaitAccessEnable();
RTC->TTR = (RTC->TTR & ~RTC_TTR_TTR_Msk) | u32TickSelection;
}
/**
* @brief Enable RTC Interrupt
*
* @param[in] u32IntFlagMask The structure of interrupt source. It consists of: \n
* RTC_RIER_AIER_Msk: Alarm interrupt \n
* RTC_RIER_TIER_Msk: Tick interrupt \n
* RTC_RIER_SNOOPIER_Msk: Snooper Pin Event Detection Interrupt \n
*
* @return None
*
* @details This API is used to enable the specify RTC interrupt function.
*/
void RTC_EnableInt(uint32_t u32IntFlagMask)
{
RTC->RIER |= u32IntFlagMask;
}
/**
* @brief Disable RTC Interrupt
*
* @param[in] u32IntFlagMask The structure of interrupt source. It consists of: \n
* RTC_RIER_AIER_Msk: Alarm interrupt \n
* RTC_RIER_TIER_Msk: Tick interrupt \n
* RTC_RIER_SNOOPIER_Msk: Snooper Pin Event Detection interrupt \n
*
* @return None
*
* @details This API is used to disable the specify RTC interrupt function.
*/
void RTC_DisableInt(uint32_t u32IntFlagMask)
{
if(u32IntFlagMask & RTC_RIER_TIER_Msk)
{
RTC->RIER &= ~RTC_RIER_TIER_Msk;
RTC->RIIR |= RTC_RIIR_TIF_Msk;
}
if(u32IntFlagMask & RTC_RIER_AIER_Msk)
{
RTC->RIER &= ~RTC_RIER_AIER_Msk;
RTC->RIIR |= RTC_RIIR_AIF_Msk;
}
if(u32IntFlagMask & RTC_RIER_SNOOPIER_Msk)
{
RTC->RIER &= ~RTC_RIER_SNOOPIER_Msk;
RTC->RIIR |= RTC_RIIR_SNOOPIF_Msk;
}
}
/**
* @brief Enable Spare Register
*
* @param None
*
* @return None
*
* @details This API is used to enable the spare register 0~19 can be accessed.
*/
void RTC_EnableSpareRegister(void)
{
RTC_WaitAccessEnable();
RTC->SPRCTL |= RTC_SPRCTL_SPREN_Msk;
while(!(RTC->SPRCTL & RTC_SPRCTL_SPRRDY_Msk));
}
/**
* @brief Disable Spare Register
*
* @param None
*
* @return None
*
* @details This API is used to disable the spare register 0~19 cannot be accessed.
*/
void RTC_DisableSpareRegister(void)
{
RTC_WaitAccessEnable();
RTC->SPRCTL &= ~RTC_SPRCTL_SPREN_Msk;
}
/**
* @brief Enable Snooper Pin Detect
*
* @param[in] u32PinCondition Snooper pin trigger condition. Possible options are
* - \ref RTC_SNOOPER_LOW_LEVEL
* - \ref RTC_SNOOPER_HIGH_LEVEL
* - \ref RTC_SNOOPER_FALLING_EDGE
* - \ref RTC_SNOOPER_RISING_EDGE
*
* @return None
*
* @details This API is used to enable the snooper pin detect function with specify trigger condition.
*/
void RTC_EnableSnooperDetection(uint32_t u32PinCondition)
{
RTC_WaitAccessEnable();
RTC->SPRCTL = ((RTC->SPRCTL & ~RTC_SNOOPER_DETECT_Msk) | u32PinCondition) | RTC_SPRCTL_SNOOPEN_Msk;
}
/**
* @brief Disable Snooper Pin Detect
*
* @param None
*
* @return None
*
* @details This API is used to disable the snooper pin detect function.
*/
void RTC_DisableSnooperDetection(void)
{
RTC_WaitAccessEnable();
RTC->SPRCTL &= ~RTC_SPRCTL_SNOOPEN_Msk;
}
/*@}*/ /* end of group RTC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group RTC_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

280
BSP/StdDriver/src/sc.c Normal file
View File

@ -0,0 +1,280 @@
/**************************************************************************//**
* @file sc.c
* @version V3.00
* $Revision: 10 $
* $Date: 15/05/12 2:26p $
* @brief Smartcard(SC) driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
// Below are variables used locally by SC driver and does not want to parse by doxygen unless HIDDEN_SYMBOLS is defined
/// @cond HIDDEN_SYMBOLS
static uint32_t u32CardStateIgnore[SC_INTERFACE_NUM] = {0, 0, 0};
/// @endcond HIDDEN_SYMBOLS
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup SC_Driver SC Driver
@{
*/
/** @addtogroup SC_EXPORTED_FUNCTIONS SC Exported Functions
@{
*/
/**
* @brief This function indicates specified smartcard slot status.
* @param[in] sc The pointer of smartcard module.
* @retval TRUE Card insert.
* @retval FALSE Card remove.
* @details This function is used to check if specified smart card slot is presented.
*/
uint32_t SC_IsCardInserted(SC_T *sc)
{
// put conditions into two variable to remove IAR compilation warning
uint32_t cond1 = ((sc->PINCSR & SC_PINCSR_CD_PIN_ST_Msk) >> SC_PINCSR_CD_PIN_ST_Pos);
uint32_t cond2 = ((sc->PINCSR & SC_PINCSR_CD_LEV_Msk) >> SC_PINCSR_CD_LEV_Pos);
if(sc == SC0 && u32CardStateIgnore[0] == 1)
return TRUE;
else if(sc == SC1 && u32CardStateIgnore[1] == 1)
return TRUE;
else if(sc == SC2 && u32CardStateIgnore[2] == 1)
return TRUE;
else if(cond1 != cond2)
return FALSE;
else
return TRUE;
}
/**
* @brief Reset the Tx/Rx FIFO.
* @param[in] sc The pointer of smartcard module.
* @return None
* @details This function reset both transmit and receive FIFO of specified smartcard module.
*/
void SC_ClearFIFO(SC_T *sc)
{
sc->ALTCTL |= (SC_ALTCTL_TX_RST_Msk | SC_ALTCTL_RX_RST_Msk);
}
/**
* @brief This function disable specified smartcard module.
* @param[in] sc The pointer of smartcard module.
* @return None
* @details SC will force all transition to IDLE state.
*/
void SC_Close(SC_T *sc)
{
sc->IER = 0;
sc->PINCSR = 0;
sc->ALTCTL = 0;
sc->CTL = 0;
}
/**
* @brief This function initialized smartcard module.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32CD Card detect polarity, select the CD pin state which indicates card insert. Could be:
* -\ref SC_PIN_STATE_HIGH.
* -\ref SC_PIN_STATE_LOW.
* -\ref SC_PIN_STATE_IGNORE, no card detect pin, always assumes card present.
* @param[in] u32PWR Power on polarity, select the PWR pin state which could set smartcard VCC to high level. Could be:
* -\ref SC_PIN_STATE_HIGH.
* -\ref SC_PIN_STATE_LOW.
* @return None
* @details Initialization process configures smartcard and enables engine clock.
*/
void SC_Open(SC_T *sc, uint32_t u32CD, uint32_t u32PWR)
{
uint32_t u32Reg = 0, u32Intf;
if(sc == SC0)
u32Intf = 0;
else if(sc == SC1)
u32Intf = 1;
else
u32Intf = 2;
if(u32CD != SC_PIN_STATE_IGNORE)
{
u32Reg = u32CD ? 0 : SC_PINCSR_CD_LEV_Msk;
u32CardStateIgnore[u32Intf] = 0;
}
else
{
u32CardStateIgnore[u32Intf] = 1;
}
u32Reg |= u32PWR ? 0 : SC_PINCSR_POW_INV_Msk;
sc->PINCSR = u32Reg;
sc->CTL = SC_CTL_SC_CEN_Msk;
}
/**
* @brief This function reset specified smartcard module to its default state for activate smartcard.
* @param[in] sc The pointer of smartcard module.
* @return None
* @details Reset the Tx/Rx FIFO & clock & initial default parameter.
*/
void SC_ResetReader(SC_T *sc)
{
uint32_t u32Intf;
if(sc == SC0)
u32Intf = 0;
else if(sc == SC1)
u32Intf = 1;
else
u32Intf = 2;
// Reset FIFO
sc->ALTCTL |= (SC_ALTCTL_TX_RST_Msk | SC_ALTCTL_RX_RST_Msk);
// Set Rx trigger level to 1 character, longest card detect debounce period, disable error retry (EMV ATR does not use error retry)
sc->CTL &= ~(SC_CTL_RX_FTRI_LEV_Msk | SC_CTL_CD_DEB_SEL_Msk | SC_CTL_TX_ERETRY_Msk | SC_CTL_RX_ERETRY_Msk);
// Enable auto convention, and all three smartcard internal timers
sc->CTL |= SC_CTL_AUTO_CON_EN_Msk | SC_CTL_TMR_SEL_Msk;
// Disable Rx timeout
sc->RFTMR = 0;
// 372 clocks per ETU by default
sc->ETUCR = 371;
// Enable auto de-activation while card removal
sc->PINCSR |= SC_PINCSR_ADAC_CD_EN_Msk;
/* Enable necessary interrupt for smartcard operation */
if(u32CardStateIgnore[u32Intf]) // Do not enable card detect interrupt if card present state ignore
sc->IER = (SC_IER_RDA_IE_Msk |
SC_IER_TERR_IE_Msk |
SC_IER_TMR0_IE_Msk |
SC_IER_TMR1_IE_Msk |
SC_IER_TMR2_IE_Msk |
SC_IER_BGT_IE_Msk |
SC_IER_ACON_ERR_IE_Msk);
else
sc->IER = (SC_IER_RDA_IE_Msk |
SC_IER_TERR_IE_Msk |
SC_IER_TMR0_IE_Msk |
SC_IER_TMR1_IE_Msk |
SC_IER_TMR2_IE_Msk |
SC_IER_BGT_IE_Msk |
SC_IER_CD_IE_Msk |
SC_IER_ACON_ERR_IE_Msk);
return;
}
/**
* @brief Set Block Guard Time.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32BGT Block guard time using ETU as unit, valid range are between 1 ~ 32.
* @return None
* @details This function block guard time (BGT) of specified smartcard module.
*/
void SC_SetBlockGuardTime(SC_T *sc, uint32_t u32BGT)
{
sc->CTL = (sc->CTL & ~SC_CTL_BGT_Msk) | ((u32BGT - 1) << SC_CTL_BGT_Pos);
}
/**
* @brief Set character guard time.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32CGT Character guard time using ETU as unit, valid range are between 11 ~ 267.
* @return None
* @details This function character guard time (CGT) of specified smartcard module.
* @note Before using this API, user should set the correct stop bit length first.
*/
void SC_SetCharGuardTime(SC_T *sc, uint32_t u32CGT)
{
u32CGT -= sc->CTL & SC_CTL_SLEN_Msk ? 11 : 12;
sc->EGTR = u32CGT;
}
/**
* @brief Stop all Timer counting.
* @param[in] sc The pointer of smartcard module.
* @return None
* @details This function stop all smartcard timer of specified smartcard module.
* @note This function stop the timers within smartcard module, \b not timer module.
*/
void SC_StopAllTimer(SC_T *sc)
{
sc->ALTCTL &= ~(SC_ALTCTL_TMR0_SEN_Msk | SC_ALTCTL_TMR1_SEN_Msk | SC_ALTCTL_TMR2_SEN_Msk);
}
/**
* @brief This function configure and start a smartcard timer of specified smartcard module.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32TimerNum Timer(s) to start. Valid values are 0, 1, 2.
* @param[in] u32Mode Timer operating mode, valid values are:
* - \ref SC_TMR_MODE_0
* - \ref SC_TMR_MODE_1
* - \ref SC_TMR_MODE_2
* - \ref SC_TMR_MODE_3
* - \ref SC_TMR_MODE_4
* - \ref SC_TMR_MODE_5
* - \ref SC_TMR_MODE_6
* - \ref SC_TMR_MODE_7
* - \ref SC_TMR_MODE_8
* - \ref SC_TMR_MODE_F
* @param[in] u32ETUCount Timer timeout duration, ETU based. For timer 0, valid range are between 1~0x1000000ETUs.
* For timer 1 and timer 2, valid range are between 1 ~ 0x100 ETUs.
* @return None
* @details Enable Timer starting, counter will count when condition match.
* @note This function start the timer within smartcard module, \b not timer module.
* @note Depend on the timer operating mode, timer may not start counting immediately.
*/
void SC_StartTimer(SC_T *sc, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount)
{
uint32_t reg = u32Mode | (SC_TMR0_CNT_Msk & (u32ETUCount - 1));
if(u32TimerNum == 0)
{
sc->TMR0 = reg;
sc->ALTCTL |= SC_ALTCTL_TMR0_SEN_Msk;
}
else if(u32TimerNum == 1)
{
sc->TMR1 = reg;
sc->ALTCTL |= SC_ALTCTL_TMR1_SEN_Msk;
}
else // timer 2
{
sc->TMR2 = reg;
sc->ALTCTL |= SC_ALTCTL_TMR2_SEN_Msk;
}
}
/**
* @brief Stop Timer counting.
* @param[in] sc The pointer of smartcard module.
* @param[in] u32TimerNum Timer(s) to stop. Valid values are 0, 1, 2.
* @return None
* @details This function stop a smartcard timer of specified smartcard module.
* @note This function stop the timer within smartcard module, \b not timer module.
*/
void SC_StopTimer(SC_T *sc, uint32_t u32TimerNum)
{
if(u32TimerNum == 0)
sc->ALTCTL &= ~SC_ALTCTL_TMR0_SEN_Msk;
else if(u32TimerNum == 1)
sc->ALTCTL &= ~SC_ALTCTL_TMR1_SEN_Msk;
else // timer 2
sc->ALTCTL &= ~SC_ALTCTL_TMR2_SEN_Msk;
}
/*@}*/ /* end of group SC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SC_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

638
BSP/StdDriver/src/spi.c Normal file
View File

@ -0,0 +1,638 @@
/**************************************************************************//**
* @file spi.c
* @version V3.00
* $Revision: 12 $
* $Date: 15/05/04 3:59p $
* @brief SPI driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup SPI_Driver SPI Driver
@{
*/
/** @addtogroup SPI_EXPORTED_FUNCTIONS SPI Exported Functions
@{
*/
/**
* @brief This function make SPI module be ready to transfer.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32MasterSlave Decides the SPI module is operating in master mode or in slave mode. (SPI_SLAVE, SPI_MASTER)
* @param[in] u32SPIMode Decides the transfer timing. (SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, SPI_MODE_3)
* @param[in] u32DataWidth Decides the data width of a SPI transaction.
* @param[in] u32BusClock The expected frequency of SPI bus clock in Hz.
* @return Actual frequency of SPI peripheral clock.
* @details By default, the SPI transfer sequence is MSB first and the automatic slave selection function is disabled.
* In Slave mode, the u32BusClock must be NULL and the SPI clock divider setting will be 0.
* The actual clock rate may be different from the target SPI clock rate.
* For example, if the SPI source clock rate is 12MHz and the target SPI bus clock rate is 7MHz, the
* actual SPI clock rate will be 6MHz.
* @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
* @note If u32BusClock >= system clock frequency, SPI peripheral clock source will be set to HCLK and DIVIDER will be set to 0.
* @note In slave mode, the SPI peripheral clock rate will be set to equal to system clock rate.
*/
uint32_t SPI_Open(SPI_T *spi,
uint32_t u32MasterSlave,
uint32_t u32SPIMode,
uint32_t u32DataWidth,
uint32_t u32BusClock)
{
uint32_t u32ClkSrc = 0, u32Div, u32HCLKFreq;
if(u32DataWidth == 32)
u32DataWidth = 0;
/* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
spi->CNTRL = u32MasterSlave | (u32DataWidth << SPI_CNTRL_TX_BIT_LEN_Pos) | (u32SPIMode);
/* Set BCn = 1: f_spi = f_spi_clk_src / (DIVIDER + 1) */
spi->CNTRL2 |= SPI_CNTRL2_BCn_Msk;
/* Get system clock frequency */
u32HCLKFreq = CLK_GetHCLKFreq();
if(u32MasterSlave == SPI_MASTER)
{
/* Default setting: slave select signal is active low; disable automatic slave select function. */
spi->SSR = SPI_SS_ACTIVE_LOW;
/* Check clock source of SPI */
if(spi == SPI0)
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI0_S_Msk) == CLK_CLKSEL1_SPI0_S_HCLK)
u32ClkSrc = u32HCLKFreq;
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
else if(spi == SPI1)
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI1_S_Msk) == CLK_CLKSEL1_SPI1_S_HCLK)
u32ClkSrc = u32HCLKFreq;
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
else if(spi == SPI2)
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI2_S_Msk) == CLK_CLKSEL1_SPI2_S_HCLK)
u32ClkSrc = u32HCLKFreq;
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
else
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI3_S_Msk) == CLK_CLKSEL1_SPI3_S_HCLK)
u32ClkSrc = u32HCLKFreq;
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
if(u32BusClock >= u32HCLKFreq)
{
/* Select HCLK as the clock source of SPI */
if(spi == SPI0)
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI0_S_Msk)) | CLK_CLKSEL1_SPI0_S_HCLK;
else if(spi == SPI1)
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI1_S_Msk)) | CLK_CLKSEL1_SPI1_S_HCLK;
else if(spi == SPI2)
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI2_S_Msk)) | CLK_CLKSEL1_SPI2_S_HCLK;
else
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI3_S_Msk)) | CLK_CLKSEL1_SPI3_S_HCLK;
/* Set DIVIDER = 0 */
spi->DIVIDER = 0;
/* Return slave peripheral clock rate */
return u32HCLKFreq;
}
else if(u32BusClock >= u32ClkSrc)
{
/* Set DIVIDER = 0 */
spi->DIVIDER = 0;
/* Return master peripheral clock rate */
return u32ClkSrc;
}
else if(u32BusClock == 0)
{
/* Set BCn = 0: f_spi = f_spi_clk_src / ((DIVIDER + 1) * 2) */
spi->CNTRL2 &= (~SPI_CNTRL2_BCn_Msk);
/* Set DIVIDER to the maximum value 0xFF */
spi->DIVIDER = (spi->DIVIDER & (~SPI_DIVIDER_DIVIDER_Msk)) | (0xFF << SPI_DIVIDER_DIVIDER_Pos);
/* Return master peripheral clock rate */
return (u32ClkSrc / ((0xFF + 1) * 2));
}
else
{
u32Div = (((u32ClkSrc * 10) / u32BusClock + 5) / 10) - 1; /* Round to the nearest integer */
if(u32Div > 0xFF)
{
/* Set BCn = 0: f_spi = f_spi_clk_src / ((DIVIDER + 1) * 2) */
spi->CNTRL2 &= (~SPI_CNTRL2_BCn_Msk);
u32Div = (((u32ClkSrc * 10) / (u32BusClock * 2) + 5) / 10) - 1; /* Round to the nearest integer */
if(u32Div > 0xFF)
u32Div = 0xFF;
spi->DIVIDER = (spi->DIVIDER & (~SPI_DIVIDER_DIVIDER_Msk)) | (u32Div << SPI_DIVIDER_DIVIDER_Pos);
/* Return master peripheral clock rate */
return (u32ClkSrc / ((u32Div + 1) * 2));
}
else
{
spi->DIVIDER = (spi->DIVIDER & (~SPI_DIVIDER_DIVIDER_Msk)) | (u32Div << SPI_DIVIDER_DIVIDER_Pos);
/* Return master peripheral clock rate */
return (u32ClkSrc / (u32Div + 1));
}
}
}
else /* For slave mode, force the SPI peripheral clock rate to system clock rate. */
{
/* Default setting: slave select signal is low level active. */
spi->SSR = SPI_SSR_SS_LTRIG_Msk;
/* Select HCLK as the clock source of SPI */
if(spi == SPI0)
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI0_S_Msk)) | CLK_CLKSEL1_SPI0_S_HCLK;
else if(spi == SPI1)
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI1_S_Msk)) | CLK_CLKSEL1_SPI1_S_HCLK;
else if(spi == SPI2)
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI2_S_Msk)) | CLK_CLKSEL1_SPI2_S_HCLK;
else
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI3_S_Msk)) | CLK_CLKSEL1_SPI3_S_HCLK;
/* Set DIVIDER = 0 */
spi->DIVIDER = 0;
/* Return slave peripheral clock rate */
return u32HCLKFreq;
}
}
/**
* @brief Disable SPI controller.
* @param[in] spi The pointer of the specified SPI module.
* @return None
* @details This function will reset SPI controller.
*/
void SPI_Close(SPI_T *spi)
{
if(spi == SPI0)
{
/* Reset SPI */
SYS->IPRSTC2 |= SYS_IPRSTC2_SPI0_RST_Msk;
SYS->IPRSTC2 &= ~SYS_IPRSTC2_SPI0_RST_Msk;
}
else if(spi == SPI1)
{
/* Reset SPI */
SYS->IPRSTC2 |= SYS_IPRSTC2_SPI1_RST_Msk;
SYS->IPRSTC2 &= ~SYS_IPRSTC2_SPI1_RST_Msk;
}
else if(spi == SPI2)
{
/* Reset SPI */
SYS->IPRSTC2 |= SYS_IPRSTC2_SPI2_RST_Msk;
SYS->IPRSTC2 &= ~SYS_IPRSTC2_SPI2_RST_Msk;
}
else
{
/* Reset SPI */
SYS->IPRSTC2 |= SYS_IPRSTC2_SPI3_RST_Msk;
SYS->IPRSTC2 &= ~SYS_IPRSTC2_SPI3_RST_Msk;
}
}
/**
* @brief Clear RX FIFO buffer.
* @param[in] spi The pointer of the specified SPI module.
* @return None
* @details This function will clear SPI RX FIFO buffer.
*/
void SPI_ClearRxFIFO(SPI_T *spi)
{
spi->FIFO_CTL |= SPI_FIFO_CTL_RX_CLR_Msk;
}
/**
* @brief Clear TX FIFO buffer.
* @param[in] spi The pointer of the specified SPI module.
* @return None
* @details This function will clear SPI TX FIFO buffer.
*/
void SPI_ClearTxFIFO(SPI_T *spi)
{
spi->FIFO_CTL |= SPI_FIFO_CTL_TX_CLR_Msk;
}
/**
* @brief Disable the automatic slave selection function.
* @param[in] spi The pointer of the specified SPI module.
* @return None
* @details This function will disable the automatic slave selection function and set slave selection signal to inactive state.
*/
void SPI_DisableAutoSS(SPI_T *spi)
{
spi->SSR &= ~(SPI_SSR_AUTOSS_Msk | SPI_SSR_SSR_Msk);
}
/**
* @brief Enable the automatic slave selection function.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32SSPinMask Specifies slave selection pins. (SPI_SS0, SPI_SS1)
* @param[in] u32ActiveLevel Specifies the active level of slave selection signal. (SPI_SS_ACTIVE_HIGH, SPI_SS_ACTIVE_LOW)
* @return None
* @details This function will enable the automatic slave selection function. Only available in Master mode.
* The slave selection pin and the active level will be set in this function.
*/
void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
{
spi->SSR = (spi->SSR & (~(SPI_SSR_AUTOSS_Msk | SPI_SSR_SS_LVL_Msk | SPI_SSR_SSR_Msk))) | (u32SSPinMask | u32ActiveLevel | SPI_SSR_AUTOSS_Msk);
}
/**
* @brief Set the SPI bus clock.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32BusClock The expected frequency of SPI bus clock in Hz.
* @return Actual frequency of SPI bus clock.
* @details This function is only available in Master mode. The actual clock rate may be different from the target SPI bus clock rate.
* For example, if the SPI source clock rate is 12MHz and the target SPI bus clock rate is 7MHz, the actual SPI bus clock
* rate will be 6MHz.
* @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
* @note If u32BusClock >= system clock frequency, SPI peripheral clock source will be set to HCLK and DIVIDER will be set to 0.
*/
uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock)
{
uint32_t u32ClkSrc, u32HCLKFreq;
uint32_t u32Div;
/* Set BCn = 1: f_spi = f_spi_clk_src / (DIVIDER + 1) */
spi->CNTRL2 |= SPI_CNTRL2_BCn_Msk;
/* Get system clock frequency */
u32HCLKFreq = CLK_GetHCLKFreq();
/* Check clock source of SPI */
if(spi == SPI0)
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI0_S_Msk) == CLK_CLKSEL1_SPI0_S_HCLK)
u32ClkSrc = u32HCLKFreq;
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
else if(spi == SPI1)
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI1_S_Msk) == CLK_CLKSEL1_SPI1_S_HCLK)
u32ClkSrc = u32HCLKFreq;
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
else if(spi == SPI2)
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI2_S_Msk) == CLK_CLKSEL1_SPI2_S_HCLK)
u32ClkSrc = u32HCLKFreq;
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
else
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI3_S_Msk) == CLK_CLKSEL1_SPI3_S_HCLK)
u32ClkSrc = u32HCLKFreq;
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
if(u32BusClock >= u32HCLKFreq)
{
/* Select HCLK as the clock source of SPI */
if(spi == SPI0)
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI0_S_Msk)) | CLK_CLKSEL1_SPI0_S_HCLK;
else if(spi == SPI1)
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI1_S_Msk)) | CLK_CLKSEL1_SPI1_S_HCLK;
else if(spi == SPI2)
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI2_S_Msk)) | CLK_CLKSEL1_SPI2_S_HCLK;
else
CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_SPI3_S_Msk)) | CLK_CLKSEL1_SPI3_S_HCLK;
/* Set DIVIDER = 0 */
spi->DIVIDER = 0;
/* Return slave peripheral clock rate */
return u32HCLKFreq;
}
else if(u32BusClock >= u32ClkSrc)
{
/* Set DIVIDER = 0 */
spi->DIVIDER = 0;
/* Return master peripheral clock rate */
return u32ClkSrc;
}
else if(u32BusClock == 0)
{
/* Set BCn = 0: f_spi = f_spi_clk_src / ((DIVIDER + 1) * 2) */
spi->CNTRL2 &= (~SPI_CNTRL2_BCn_Msk);
/* Set DIVIDER to the maximum value 0xFF */
spi->DIVIDER = (spi->DIVIDER & (~SPI_DIVIDER_DIVIDER_Msk)) | (0xFF << SPI_DIVIDER_DIVIDER_Pos);
/* Return master peripheral clock rate */
return (u32ClkSrc / ((0xFF + 1) * 2));
}
else
{
u32Div = (((u32ClkSrc * 10) / u32BusClock + 5) / 10) - 1; /* Round to the nearest integer */
if(u32Div > 0xFF)
{
/* Set BCn = 0: f_spi = f_spi_clk_src / ((DIVIDER + 1) * 2) */
spi->CNTRL2 &= (~SPI_CNTRL2_BCn_Msk);
u32Div = (((u32ClkSrc * 10) / (u32BusClock * 2) + 5) / 10) - 1; /* Round to the nearest integer */
if(u32Div > 0xFF)
u32Div = 0xFF;
spi->DIVIDER = (spi->DIVIDER & (~SPI_DIVIDER_DIVIDER_Msk)) | (u32Div << SPI_DIVIDER_DIVIDER_Pos);
/* Return master peripheral clock rate */
return (u32ClkSrc / ((u32Div + 1) * 2));
}
else
{
spi->DIVIDER = (spi->DIVIDER & (~SPI_DIVIDER_DIVIDER_Msk)) | (u32Div << SPI_DIVIDER_DIVIDER_Pos);
/* Return master peripheral clock rate */
return (u32ClkSrc / (u32Div + 1));
}
}
}
/**
* @brief Enable FIFO mode.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32TxThreshold Decides the TX FIFO threshold.
* @param[in] u32RxThreshold Decides the RX FIFO threshold.
* @return None
* @details Enable FIFO mode with user-specified TX FIFO threshold and RX FIFO threshold configurations.
*/
void SPI_EnableFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
{
spi->FIFO_CTL = (spi->FIFO_CTL & ~(SPI_FIFO_CTL_TX_THRESHOLD_Msk | SPI_FIFO_CTL_RX_THRESHOLD_Msk)) |
((u32TxThreshold << SPI_FIFO_CTL_TX_THRESHOLD_Pos) |
(u32RxThreshold << SPI_FIFO_CTL_RX_THRESHOLD_Pos));
spi->CNTRL |= SPI_CNTRL_FIFO_Msk;
}
/**
* @brief Disable FIFO mode.
* @param[in] spi The pointer of the specified SPI module.
* @return None
* @details Clear FIFO bit of SPI_CNTRL register to disable FIFO mode.
*/
void SPI_DisableFIFO(SPI_T *spi)
{
spi->CNTRL &= ~SPI_CNTRL_FIFO_Msk;
}
/**
* @brief Get the actual frequency of SPI bus clock. Only available in Master mode.
* @param[in] spi The pointer of the specified SPI module.
* @return Actual SPI bus clock frequency.
* @details This function will calculate the actual SPI bus clock rate according to the settings of SPIn_S, BCn and DIVIDER. Only available in Master mode.
*/
uint32_t SPI_GetBusClock(SPI_T *spi)
{
uint32_t u32Div;
uint32_t u32ClkSrc;
/* Get DIVIDER setting */
u32Div = (spi->DIVIDER & SPI_DIVIDER_DIVIDER_Msk) >> SPI_DIVIDER_DIVIDER_Pos;
/* Check clock source of SPI */
if(spi == SPI0)
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI0_S_Msk) == CLK_CLKSEL1_SPI0_S_HCLK)
u32ClkSrc = CLK_GetHCLKFreq();
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
else if(spi == SPI1)
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI1_S_Msk) == CLK_CLKSEL1_SPI1_S_HCLK)
u32ClkSrc = CLK_GetHCLKFreq();
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
else if(spi == SPI2)
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI2_S_Msk) == CLK_CLKSEL1_SPI2_S_HCLK)
u32ClkSrc = CLK_GetHCLKFreq();
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
else
{
if((CLK->CLKSEL1 & CLK_CLKSEL1_SPI3_S_Msk) == CLK_CLKSEL1_SPI3_S_HCLK)
u32ClkSrc = CLK_GetHCLKFreq();
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
if(spi->CNTRL2 & SPI_CNTRL2_BCn_Msk) /* BCn = 1: f_spi = f_spi_clk_src / (DIVIDER + 1) */
{
/* Return SPI bus clock rate */
return (u32ClkSrc / (u32Div + 1));
}
else /* BCn = 0: f_spi = f_spi_clk_src / ((DIVIDER + 1) * 2) */
{
/* Return SPI bus clock rate */
return (u32ClkSrc / ((u32Div + 1) * 2));
}
}
/**
* @brief Enable interrupt function.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32Mask The combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt bit.
* This parameter decides which interrupts will be enabled.
* (SPI_UNIT_INT_MASK, SPI_SSTA_INT_MASK, SPI_FIFO_TX_INT_MASK,
* SPI_FIFO_RX_INT_MASK, SPI_FIFO_RXOV_INT_MASK, SPI_FIFO_TIMEOUT_INT_MASK)
* @return None
* @details Enable SPI related interrupts specified by u32Mask parameter.
*/
void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask)
{
/* Enable unit transfer interrupt flag */
if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
spi->CNTRL |= SPI_CNTRL_IE_Msk;
/* Enable slave 3-wire mode start interrupt flag */
if((u32Mask & SPI_SSTA_INT_MASK) == SPI_SSTA_INT_MASK)
spi->CNTRL2 |= SPI_CNTRL2_SSTA_INTEN_Msk;
/* Enable TX threshold interrupt flag */
if((u32Mask & SPI_FIFO_TX_INT_MASK) == SPI_FIFO_TX_INT_MASK)
spi->FIFO_CTL |= SPI_FIFO_CTL_TX_INTEN_Msk;
/* Enable RX threshold interrupt flag */
if((u32Mask & SPI_FIFO_RX_INT_MASK) == SPI_FIFO_RX_INT_MASK)
spi->FIFO_CTL |= SPI_FIFO_CTL_RX_INTEN_Msk;
/* Enable RX overrun interrupt flag */
if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
spi->FIFO_CTL |= SPI_FIFO_CTL_RXOV_INTEN_Msk;
/* Enable RX time-out interrupt flag */
if((u32Mask & SPI_FIFO_TIMEOUT_INT_MASK) == SPI_FIFO_TIMEOUT_INT_MASK)
spi->FIFO_CTL |= SPI_FIFO_CTL_TIMEOUT_INTEN_Msk;
}
/**
* @brief Disable interrupt function.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32Mask The combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt bit.
* This parameter decides which interrupts will be disabled.
* (SPI_UNIT_INT_MASK, SPI_SSTA_INT_MASK, SPI_FIFO_TX_INT_MASK,
* SPI_FIFO_RX_INT_MASK, SPI_FIFO_RXOV_INT_MASK, SPI_FIFO_TIMEOUT_INT_MASK)
* @return None
* @details Disable SPI related interrupts specified by u32Mask parameter.
*/
void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask)
{
/* Disable unit transfer interrupt flag */
if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
spi->CNTRL &= ~SPI_CNTRL_IE_Msk;
/* Disable slave 3-wire mode start interrupt flag */
if((u32Mask & SPI_SSTA_INT_MASK) == SPI_SSTA_INT_MASK)
spi->CNTRL2 &= ~SPI_CNTRL2_SSTA_INTEN_Msk;
/* Disable TX threshold interrupt flag */
if((u32Mask & SPI_FIFO_TX_INT_MASK) == SPI_FIFO_TX_INT_MASK)
spi->FIFO_CTL &= ~SPI_FIFO_CTL_TX_INTEN_Msk;
/* Disable RX threshold interrupt flag */
if((u32Mask & SPI_FIFO_RX_INT_MASK) == SPI_FIFO_RX_INT_MASK)
spi->FIFO_CTL &= ~SPI_FIFO_CTL_RX_INTEN_Msk;
/* Disable RX overrun interrupt flag */
if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
spi->FIFO_CTL &= ~SPI_FIFO_CTL_RXOV_INTEN_Msk;
/* Disable RX time-out interrupt flag */
if((u32Mask & SPI_FIFO_TIMEOUT_INT_MASK) == SPI_FIFO_TIMEOUT_INT_MASK)
spi->FIFO_CTL &= ~SPI_FIFO_CTL_TIMEOUT_INTEN_Msk;
}
/**
* @brief Get interrupt flag.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32Mask The combination of all related interrupt sources.
* Each bit corresponds to a interrupt source.
* This parameter decides which interrupt flags will be read.
* (SPI_UNIT_INT_MASK, SPI_SSTA_INT_MASK, SPI_FIFO_TX_INT_MASK,
* SPI_FIFO_RX_INT_MASK, SPI_FIFO_RXOV_INT_MASK, SPI_FIFO_TIMEOUT_INT_MASK)
* @return Interrupt flags of selected sources.
* @details Get SPI related interrupt flags specified by u32Mask parameter.
*/
uint32_t SPI_GetIntFlag(SPI_T *spi, uint32_t u32Mask)
{
uint32_t u32IntFlag = 0;
/* Check unit transfer interrupt flag */
if((u32Mask & SPI_UNIT_INT_MASK) && (spi->CNTRL & SPI_CNTRL_IF_Msk))
u32IntFlag |= SPI_UNIT_INT_MASK;
/* Check slave 3-wire mode start interrupt flag */
if((u32Mask & SPI_SSTA_INT_MASK) && (spi->CNTRL2 & SPI_CNTRL2_SLV_START_INTSTS_Msk))
u32IntFlag |= SPI_SSTA_INT_MASK;
/* Check TX threshold interrupt flag */
if((u32Mask & SPI_FIFO_TX_INT_MASK) && (spi->STATUS & SPI_STATUS_TX_INTSTS_Msk))
u32IntFlag |= SPI_FIFO_TX_INT_MASK;
/* Check RX threshold interrupt flag */
if((u32Mask & SPI_FIFO_RX_INT_MASK) && (spi->STATUS & SPI_STATUS_RX_INTSTS_Msk))
u32IntFlag |= SPI_FIFO_RX_INT_MASK;
/* Check RX overrun interrupt flag */
if((u32Mask & SPI_FIFO_RXOV_INT_MASK) && (spi->STATUS & SPI_STATUS_RX_OVERRUN_Msk))
u32IntFlag |= SPI_FIFO_RXOV_INT_MASK;
/* Check RX time-out interrupt flag */
if((u32Mask & SPI_FIFO_TIMEOUT_INT_MASK) && (spi->STATUS & SPI_STATUS_TIMEOUT_Msk))
u32IntFlag |= SPI_FIFO_TIMEOUT_INT_MASK;
return u32IntFlag;
}
/**
* @brief Clear interrupt flag.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32Mask The combination of all related interrupt sources.
* Each bit corresponds to a interrupt source.
* This parameter decides which interrupt flags will be cleared.
* (SPI_UNIT_INT_MASK, SPI_SSTA_INT_MASK,
* SPI_FIFO_RXOV_INT_MASK, SPI_FIFO_TIMEOUT_INT_MASK)
* @return None
* @details Clear SPI related interrupt flags specified by u32Mask parameter.
*/
void SPI_ClearIntFlag(SPI_T *spi, uint32_t u32Mask)
{
if(u32Mask & SPI_UNIT_INT_MASK)
spi->CNTRL |= SPI_CNTRL_IF_Msk; /* Clear unit transfer interrupt flag */
if(u32Mask & SPI_SSTA_INT_MASK)
spi->CNTRL2 |= SPI_CNTRL2_SLV_START_INTSTS_Msk; /* Clear slave 3-wire mode start interrupt flag */
if(u32Mask & SPI_FIFO_RXOV_INT_MASK)
spi->STATUS = SPI_STATUS_RX_OVERRUN_Msk; /* Clear RX overrun interrupt flag */
if(u32Mask & SPI_FIFO_TIMEOUT_INT_MASK)
spi->STATUS = SPI_STATUS_TIMEOUT_Msk; /* Clear RX time-out interrupt flag */
}
/**
* @brief Get SPI status.
* @param[in] spi The pointer of the specified SPI module.
* @param[in] u32Mask The combination of all related sources.
* Each bit corresponds to a source.
* This parameter decides which flags will be read.
* (SPI_BUSY_MASK, SPI_RX_EMPTY_MASK, SPI_RX_FULL_MASK,
* SPI_TX_EMPTY_MASK, SPI_TX_FULL_MASK)
* @return Flags of selected sources.
* @details Get SPI related status specified by u32Mask parameter.
*/
uint32_t SPI_GetStatus(SPI_T *spi, uint32_t u32Mask)
{
uint32_t u32Flag = 0;
/* Check busy status */
if((u32Mask & SPI_BUSY_MASK) && (spi->CNTRL & SPI_CNTRL_GO_BUSY_Msk))
u32Flag |= SPI_BUSY_MASK;
/* Check RX empty flag */
if((u32Mask & SPI_RX_EMPTY_MASK) && (spi->CNTRL & SPI_CNTRL_RX_EMPTY_Msk))
u32Flag |= SPI_RX_EMPTY_MASK;
/* Check RX full flag */
if((u32Mask & SPI_RX_FULL_MASK) && (spi->CNTRL & SPI_CNTRL_RX_FULL_Msk))
u32Flag |= SPI_RX_FULL_MASK;
/* Check TX empty flag */
if((u32Mask & SPI_TX_EMPTY_MASK) && (spi->CNTRL & SPI_CNTRL_TX_EMPTY_Msk))
u32Flag |= SPI_TX_EMPTY_MASK;
/* Check TX full flag */
if((u32Mask & SPI_TX_FULL_MASK) && (spi->CNTRL & SPI_CNTRL_TX_FULL_Msk))
u32Flag |= SPI_TX_FULL_MASK;
return u32Flag;
}
/*@}*/ /* end of group SPI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SPI_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

206
BSP/StdDriver/src/sys.c Normal file
View File

@ -0,0 +1,206 @@
/**************************************************************************//**
* @file sys.c
* @version V3.00
* $Revision: 16 $
* $Date: 15/05/04 3:59p $
* @brief SYS driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup SYS_Driver SYS Driver
@{
*/
/** @addtogroup SYS_EXPORTED_FUNCTIONS SYS Exported Functions
@{
*/
/**
* @brief Clear reset source
* @param[in] u32Src is system reset source. Including :
* - \ref SYS_RSTSRC_RSTS_CPU_Msk
* - \ref SYS_RSTSRC_RSTS_SYS_Msk
* - \ref SYS_RSTSRC_RSTS_BOD_Msk
* - \ref SYS_RSTSRC_RSTS_LVR_Msk
* - \ref SYS_RSTSRC_RSTS_WDT_Msk
* - \ref SYS_RSTSRC_RSTS_RESET_Msk
* - \ref SYS_RSTSRC_RSTS_POR_Msk
* @return None
* @details This function clear the selected system reset source.
*/
void SYS_ClearResetSrc(uint32_t u32Src)
{
SYS->RSTSRC |= u32Src;
}
/**
* @brief Get Brown-out detector output status
* @param None
* @retval 0 System voltage is higher than BOD_VL setting or BOD_EN is 0.
* @retval 1 System voltage is lower than BOD_VL setting.
* @details This function get Brown-out detector output status.
* If the BOD_EN is 0, this function always return 0.
*/
uint32_t SYS_GetBODStatus(void)
{
return (SYS->BODCR & SYS_BODCR_BOD_OUT_Msk) ? 1 : 0;
}
/**
* @brief Get reset source
* @param None
* @return Reset source
* @details This function get the system reset source register value.
*/
uint32_t SYS_GetResetSrc(void)
{
return (SYS->RSTSRC);
}
/**
* @brief Check if register lock is set
* @param None
* @retval 0 Write-protection function is disabled.
* @retval 1 Write-protection function is enabled.
* @details This function check register write-protection bit setting.
*/
uint32_t SYS_IsRegLocked(void)
{
return !(SYS->REGWRPROT & SYS_REGWRPROT_REGPROTDIS_Msk);
}
/**
* @brief Get product ID
* @param None
* @return Product ID
* @details This function get product ID.
*/
uint32_t SYS_ReadPDID(void)
{
return SYS->PDID;
}
/**
* @brief Reset chip with chip reset
* @param None
* @return None
* @details This function reset chip with chip reset.
*/
void SYS_ResetChip(void)
{
SYS->IPRSTC1 |= SYS_IPRSTC1_CHIP_RST_Msk;
}
/**
* @brief Reset chip with CPU reset
* @param None
* @return None
* @details This function reset CPU with CPU reset.
*/
void SYS_ResetCPU(void)
{
SYS->IPRSTC1 |= SYS_IPRSTC1_CPU_RST_Msk;
}
/**
* @brief Reset Module
* @param[in] u32ModuleIndex is module index. Including :
* - \ref PDMA_RST
* - \ref GPIO_RST
* - \ref TMR0_RST
* - \ref TMR1_RST
* - \ref TMR2_RST
* - \ref TMR3_RST
* - \ref I2C0_RST
* - \ref I2C1_RST
* - \ref SPI0_RST
* - \ref SPI1_RST
* - \ref SPI2_RST
* - \ref SPI3_RST
* - \ref UART0_RST
* - \ref UART1_RST
* - \ref UART2_RST
* - \ref PWM03_RST
* - \ref PWM47_RST
* - \ref ACMP_RST
* - \ref PS2_RST
* - \ref USBD_RST
* - \ref ADC_RST
* - \ref I2S_RST
* - \ref SC0_RST
* - \ref SC1_RST
* - \ref SC2_RST
* @return None
* @details This function reset selected module.
*/
void SYS_ResetModule(uint32_t u32ModuleIndex)
{
/* Generate reset signal to the corresponding module */
*(volatile uint32_t *)((uint32_t)&SYS->IPRSTC1 + (u32ModuleIndex >> 24)) |= 1 << (u32ModuleIndex & 0x00ffffff);
/* Release corresponding module from reset state */
*(volatile uint32_t *)((uint32_t)&SYS->IPRSTC1 + (u32ModuleIndex >> 24)) &= ~(1 << (u32ModuleIndex & 0x00ffffff));
}
/**
* @brief Enable and set Brown-out detector function
* @param[in] i32Mode is reset or interrupt mode. Including :
* - \ref SYS_BODCR_BOD_RST_EN
* - \ref SYS_BODCR_BOD_INTERRUPT_EN
* @param[in] u32BODLevel is Brown-out voltage level. Including :
* - \ref SYS_BODCR_BOD_VL_4_4V
* - \ref SYS_BODCR_BOD_VL_3_7V
* - \ref SYS_BODCR_BOD_VL_2_7V
* - \ref SYS_BODCR_BOD_VL_2_2V
* @return None
* @details This function configure Brown-out detector function.
* It configure Brown-out detector reset or interrupt mode, enable Brown-out function and set Brown-out voltage level.
*
*/
void SYS_EnableBOD(int32_t i32Mode, uint32_t u32BODLevel)
{
SYS->BODCR |= SYS_BODCR_BOD_EN_Msk;
SYS->BODCR = (SYS->BODCR & ~SYS_BODCR_BOD_RSTEN_Msk) | i32Mode;
SYS->BODCR = (SYS->BODCR & ~SYS_BODCR_BOD_VL_Msk) | u32BODLevel;
}
/**
* @brief Disable Brown-out detector function
* @param None
* @return None
* @details This function disable Brown-out detector function.
*/
void SYS_DisableBOD(void)
{
SYS->BODCR &= ~SYS_BODCR_BOD_EN_Msk;
}
/*@}*/ /* end of group SYS_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SYS_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

269
BSP/StdDriver/src/timer.c Normal file
View File

@ -0,0 +1,269 @@
/**************************************************************************//**
* @file timer.c
* @version V3.00
* $Revision: 11 $
* $Date: 15/05/04 3:59p $
* @brief Timer driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup TIMER_Driver TIMER Driver
@{
*/
/** @addtogroup TIMER_EXPORTED_FUNCTIONS TIMER Exported Functions
@{
*/
/**
* @brief Open Timer in specified mode and frequency
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Mode Operation mode. Possible options are
* - \ref TIMER_ONESHOT_MODE
* - \ref TIMER_PERIODIC_MODE
* - \ref TIMER_TOGGLE_MODE
* - \ref TIMER_CONTINUOUS_MODE
* @param[in] u32Freq Target working frequency
*
* @return Real Timer working frequency
*
* @details This API is used to configure timer to operate in specified mode and frequency.
* If timer cannot work in target frequency, a closest frequency will be chose and returned.
* @note After calling this API, Timer is \b NOT running yet. But could start timer running be calling
* \ref TIMER_Start macro or program registers directly.
*/
uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
{
uint32_t u32Clk = TIMER_GetModuleClock(timer);
uint32_t u32Cmpr = 0UL, u32Prescale = 0UL;
/* Fastest possible timer working freq is (u32Clk / 2). While cmpr = 2, prescaler = 0. */
if(u32Freq > (u32Clk / 2UL))
{
u32Cmpr = 2UL;
}
else
{
u32Cmpr = u32Clk / u32Freq;
u32Prescale = (u32Cmpr >> 24); /* for 24 bits CMPDAT */
if (u32Prescale > 0UL)
u32Cmpr = u32Cmpr / (u32Prescale + 1UL);
}
timer->TCSR = u32Mode | u32Prescale;
timer->TCMPR = u32Cmpr;
return(u32Clk / (u32Cmpr * (u32Prescale + 1UL)));
}
/**
* @brief Stop Timer Counting
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This API stops Timer counting and disable all Timer interrupt function.
*/
void TIMER_Close(TIMER_T *timer)
{
timer->TCSR = 0;
timer->TEXCON = 0;
}
/**
* @brief Create a specify delay time
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Usec Delay period in micro seconds. Valid values are between 100~1000000 (100 micro second ~ 1 second).
*
* @return None
*
* @details This API is used to create a delay loop for u32usec micro seconds.
* @note This API overwrites the register setting of the timer used to count the delay time.
* @note This API use polling mode. So there is no need to enable interrupt for the timer module used to generate delay.
*/
void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
{
uint32_t u32Clk = TIMER_GetModuleClock(timer);
uint32_t u32Prescale = 0UL, u32Delay = (SystemCoreClock / u32Clk) + 1UL;
uint32_t u32Cmpr, u32NsecPerTick;
/* Clear current timer configuration */
timer->TCSR = 0UL;
timer->TEXCON = 0UL;
if(u32Clk <= 1000000UL) /* min delay is 1000 us if timer clock source is <= 1 MHz */
{
if(u32Usec < 1000UL)
{
u32Usec = 1000UL;
}
if(u32Usec > 1000000UL)
{
u32Usec = 1000000UL;
}
}
else
{
if(u32Usec < 100UL)
{
u32Usec = 100UL;
}
if(u32Usec > 1000000UL)
{
u32Usec = 1000000UL;
}
}
if(u32Clk <= 1000000UL)
{
u32Prescale = 0UL;
u32NsecPerTick = 1000000000UL / u32Clk;
u32Cmpr = (u32Usec * 1000UL) / u32NsecPerTick;
}
else
{
u32Cmpr = u32Usec * (u32Clk / 1000000UL);
u32Prescale = (u32Cmpr >> 24); /* for 24 bits CMPDAT */
if (u32Prescale > 0UL)
u32Cmpr = u32Cmpr / (u32Prescale + 1UL);
}
timer->TCMPR = u32Cmpr;
timer->TCSR = TIMER_TCSR_CEN_Msk | TIMER_ONESHOT_MODE | u32Prescale;
/*
When system clock is faster than timer clock, it is possible timer active bit cannot set in time while we check it.
And the while loop below return immediately, so put a tiny delay here allowing timer start counting and raise active flag.
*/
for(; u32Delay > 0UL; u32Delay--)
{
__NOP();
}
while(timer->TCSR & TIMER_TCSR_CACT_Msk);
}
/**
* @brief Enable Timer Capture Function
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32CapMode Timer capture mode. Could be
* - \ref TIMER_CAPTURE_FREE_COUNTING_MODE
* - \ref TIMER_CAPTURE_COUNTER_RESET_MODE
* @param[in] u32Edge Timer capture edge. Possible values are
* - \ref TIMER_CAPTURE_FALLING_EDGE
* - \ref TIMER_CAPTURE_RISING_EDGE
* - \ref TIMER_CAPTURE_FALLING_AND_RISING_EDGE
*
* @return None
*
* @details This API is used to enable timer capture function with specified mode and capture edge.
* @note Timer frequency should be configured separately by using \ref TIMER_Open API, or program registers directly.
*/
void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
{
timer->TEXCON = (timer->TEXCON & ~(TIMER_TEXCON_RSTCAPSEL_Msk |
TIMER_TEXCON_TEX_EDGE_Msk)) |
u32CapMode | u32Edge | TIMER_TEXCON_TEXEN_Msk;
}
/**
* @brief Disable Timer Capture Function
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This API is used to disable the Timer capture function.
*/
void TIMER_DisableCapture(TIMER_T *timer)
{
timer->TEXCON &= ~TIMER_TEXCON_TEXEN_Msk;
}
/**
* @brief Enable Timer Counter Function
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Edge Detection edge of counter pin. Could be ether
* - \ref TIMER_COUNTER_FALLING_EDGE, or
* - \ref TIMER_COUNTER_RISING_EDGE
*
* @return None
*
* @details This function is used to enable the Timer counter function with specify detection edge.
* @note Timer compare value should be configured separately by using \ref TIMER_SET_CMP_VALUE macro or program registers directly.
* @note While using event counter function, \ref TIMER_TOGGLE_MODE cannot set as timer operation mode.
*/
void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
{
timer->TEXCON = (timer->TEXCON & ~TIMER_TEXCON_TX_PHASE_Msk) | u32Edge;
timer->TCSR |= TIMER_TCSR_CTB_Msk;
}
/**
* @brief Disable Timer Counter Function
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This API is used to disable the Timer event counter function.
*/
void TIMER_DisableEventCounter(TIMER_T *timer)
{
timer->TCSR &= ~TIMER_TCSR_CTB_Msk;
}
/**
* @brief Get Timer Clock Frequency
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return Timer clock frequency
*
* @details This API is used to get the clock frequency of Timer.
* @note This API cannot return correct clock rate if timer source is external clock input.
*/
uint32_t TIMER_GetModuleClock(TIMER_T *timer)
{
uint32_t u32Src;
const uint32_t au32Clk[] = {__HXT, __LXT, 0, 0, 0, __LIRC, 0, __HIRC};
if(timer == TIMER0)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0_S_Msk) >> CLK_CLKSEL1_TMR0_S_Pos;
else if(timer == TIMER1)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1_S_Msk) >> CLK_CLKSEL1_TMR1_S_Pos;
else if(timer == TIMER2)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR2_S_Msk) >> CLK_CLKSEL1_TMR2_S_Pos;
else // Timer 3
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR3_S_Msk) >> CLK_CLKSEL1_TMR3_S_Pos;
if(u32Src == 2)
{
return(SystemCoreClock);
}
return(au32Clk[u32Src]);
}
/*@}*/ /* end of group TIMER_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group TIMER_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

495
BSP/StdDriver/src/uart.c Normal file
View File

@ -0,0 +1,495 @@
/**************************************************************************//**
* @file uart.c
* @version V3.00
* $Revision: 18 $
* $Date: 16/03/04 9:25a $
* @brief UART driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup UART_Driver UART Driver
@{
*/
/** @addtogroup UART_EXPORTED_FUNCTIONS UART Exported Functions
@{
*/
/**
* @brief Clear UART specified interrupt flag
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32InterruptFlag The specified interrupt of UART module.
* - UART_ISR_LIN_INT_Msk : LIN bus interrupt
* - UART_ISR_BUF_ERR_INT_Msk : Buffer Error interrupt
* - UART_ISR_MODEM_INT_Msk : Modem interrupt
* - UART_ISR_RLS_INT_Msk : Rx Line status interrupt
*
* @return None
*
* @details The function is used to clear UART specified interrupt flag.
*/
void UART_ClearIntFlag(UART_T* uart , uint32_t u32InterruptFlag)
{
if(u32InterruptFlag & UART_ISR_RLS_INT_Msk) /* clear Receive Line Status Interrupt */
{
uart->FSR = UART_FSR_BIF_Msk | UART_FSR_FEF_Msk | UART_FSR_PEF_Msk;
uart->FSR = UART_FSR_RS485_ADD_DETF_Msk;
}
if(u32InterruptFlag & UART_ISR_MODEM_INT_Msk) /* clear Modem Interrupt */
uart->MSR |= UART_MSR_DCTSF_Msk;
if(u32InterruptFlag & UART_ISR_BUF_ERR_INT_Msk) /* clear Buffer Error Interrupt */
{
uart->FSR = UART_FSR_RX_OVER_IF_Msk | UART_FSR_TX_OVER_IF_Msk;
}
if(u32InterruptFlag & UART_ISR_LIN_INT_Msk) /* clear LIN break Interrupt */
{
uart->ISR = UART_ISR_LIN_IF_Msk;
uart->LIN_SR = UART_LIN_SR_BIT_ERR_F_Msk | UART_LIN_SR_LINS_BKDET_F_Msk |
UART_LIN_SR_LINS_SYNC_F_Msk | UART_LIN_SR_LINS_IDPERR_F_Msk |
UART_LIN_SR_LINS_HERR_F_Msk | UART_LIN_SR_LINS_HDET_F_Msk ;
}
}
/**
* @brief Disable UART interrupt
*
* @param[in] uart The pointer of the specified UART module.
*
* @return None
*
* @details The function is used to disable UART interrupt.
*/
void UART_Close(UART_T* uart)
{
uart->IER = 0;
}
/**
* @brief Disable UART auto flow control function
*
* @param[in] uart The pointer of the specified UART module.
*
* @return None
*
* @details The function is used to disable UART auto flow control.
*/
void UART_DisableFlowCtrl(UART_T* uart)
{
uart->IER &= ~(UART_IER_AUTO_RTS_EN_Msk | UART_IER_AUTO_CTS_EN_Msk);
}
/**
* @brief Disable UART specified interrupt
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32InterruptFlag The specified interrupt of UART module.
* - UART_IER_LIN_IEN_Msk : LIN bus interrupt
* - UART_IER_WAKE_EN_Msk : Wakeup interrupt
* - UART_IER_BUF_ERR_IEN_Msk : Buffer Error interrupt
* - UART_IER_RTO_IEN_Msk : Rx time-out interrupt
* - UART_IER_MODEM_IEN_Msk : Modem interrupt
* - UART_IER_RLS_IEN_Msk : Rx Line status interrupt
* - UART_IER_THRE_IEN_Msk : Tx empty interrupt
* - UART_IER_RDA_IEN_Msk : Rx ready interrupt
*
* @return None
*
* @details The function is used to disable UART specified interrupt and disable NVIC UART IRQ.
*/
void UART_DisableInt(UART_T* uart, uint32_t u32InterruptFlag)
{
/* Disable UART specified interrupt */
UART_DISABLE_INT(uart, u32InterruptFlag);
/* Disable NVIC UART IRQ */
if(uart == UART0)
NVIC_DisableIRQ(UART02_IRQn);
else if(uart == UART1)
NVIC_DisableIRQ(UART1_IRQn);
else
NVIC_DisableIRQ(UART02_IRQn);
}
/**
* @brief Enable UART auto flow control function
*
* @param[in] uart The pointer of the specified UART module.
*
* @return None
*
* @details The function is used to Enable UART auto flow control.
*/
void UART_EnableFlowCtrl(UART_T* uart)
{
/* Set RTS pin output is low level active */
uart->MCR |= UART_MCR_LEV_RTS_Msk;
/* Set CTS pin input is low level active */
uart->MSR |= UART_MSR_LEV_CTS_Msk;
/* Set RTS and CTS auto flow control enable */
uart->IER |= UART_IER_AUTO_RTS_EN_Msk | UART_IER_AUTO_CTS_EN_Msk;
}
/**
* @brief Enable UART specified interrupt
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32InterruptFlag The specified interrupt of UART module:
* - UART_IER_LIN_IEN_Msk : LIN bus interrupt
* - UART_IER_WAKE_EN_Msk : Wakeup interrupt
* - UART_IER_BUF_ERR_IEN_Msk : Buffer Error interrupt
* - UART_IER_RTO_IEN_Msk : Rx time-out interrupt
* - UART_IER_MODEM_IEN_Msk : Modem interrupt
* - UART_IER_RLS_IEN_Msk : Rx Line status interrupt
* - UART_IER_THRE_IEN_Msk : Tx empty interrupt
* - UART_IER_RDA_IEN_Msk : Rx ready interrupt
*
* @return None
*
* @details The function is used to enable UART specified interrupt and enable NVIC UART IRQ.
*/
void UART_EnableInt(UART_T* uart, uint32_t u32InterruptFlag)
{
/* Enable UART specified interrupt */
UART_ENABLE_INT(uart, u32InterruptFlag);
/* Enable NVIC UART IRQ */
if(uart == UART0)
NVIC_EnableIRQ(UART02_IRQn);
else if(uart == UART1)
NVIC_EnableIRQ(UART1_IRQn);
else
NVIC_EnableIRQ(UART02_IRQn);
}
/**
* @brief Open and set UART function
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32baudrate The baudrate of UART module.
*
* @return None
*
* @details This function use to enable UART function and set baud-rate.
*/
void UART_Open(UART_T* uart, uint32_t u32baudrate)
{
uint8_t u8UartClkSrcSel, u8UartClkDivNum;
uint32_t u32ClkTbl[4] = {__HXT, 0, 0, __HIRC};
uint32_t u32Baud_Div = 0;
/* Get UART clock source selection */
u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART_S_Msk) >> CLK_CLKSEL1_UART_S_Pos;
/* Get UART clock divider number */
u8UartClkDivNum = (CLK->CLKDIV & CLK_CLKDIV_UART_N_Msk) >> CLK_CLKDIV_UART_N_Pos;
/* Select UART function */
uart->FUN_SEL = UART_FUNC_SEL_UART;
/* Set UART line configuration */
uart->LCR = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
/* Set UART Rx and RTS trigger level */
uart->FCR &= ~(UART_FCR_RFITL_Msk | UART_FCR_RTS_TRI_LEV_Msk);
/* Get PLL clock frequency if UART clock source selection is PLL */
if(u8UartClkSrcSel == 1)
u32ClkTbl[u8UartClkSrcSel] = CLK_GetPLLClockFreq();
/* Set UART baud rate */
if(u32baudrate != 0)
{
u32Baud_Div = UART_BAUD_MODE2_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate);
if(u32Baud_Div > 0xFFFF)
uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate));
else
uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div);
}
}
/**
* @brief Read UART data
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] pu8RxBuf The buffer to receive the data of receive FIFO.
* @param[in] u32ReadBytes The the read bytes number of data.
*
* @return u32Count Receive byte count
*
* @details The function is used to read Rx data from RX FIFO and the data will be stored in pu8RxBuf.
*/
uint32_t UART_Read(UART_T* uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes)
{
uint32_t u32Count, u32delayno;
for(u32Count = 0; u32Count < u32ReadBytes; u32Count++)
{
u32delayno = 0;
while(uart->FSR & UART_FSR_RX_EMPTY_Msk) /* Check RX empty => failed */
{
u32delayno++;
if(u32delayno >= 0x40000000)
return FALSE;
}
pu8RxBuf[u32Count] = uart->RBR; /* Get Data from UART RX */
}
return u32Count;
}
/**
* @brief Set UART line configuration
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32baudrate The register value of baudrate of UART module.
* If u32baudrate = 0, UART baudrate will not change.
* @param[in] u32data_width The data length of UART module.
* - UART_WORD_LEN_5
* - UART_WORD_LEN_6
* - UART_WORD_LEN_7
* - UART_WORD_LEN_8
* @param[in] u32parity The parity setting (none/odd/even/mark/space) of UART module.
* - UART_PARITY_NONE
* - UART_PARITY_ODD
* - UART_PARITY_EVEN
* - UART_PARITY_MARK
* - UART_PARITY_SPACE
* @param[in] u32stop_bits The stop bit length (1/1.5/2 bit) of UART module.
* - UART_STOP_BIT_1
* - UART_STOP_BIT_1_5
* - UART_STOP_BIT_2
*
* @return None
*
* @details This function use to config UART line setting.
*/
void UART_SetLine_Config(UART_T* uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits)
{
uint8_t u8UartClkSrcSel, u8UartClkDivNum;
uint32_t u32ClkTbl[4] = {__HXT, 0, 0, __HIRC};
uint32_t u32Baud_Div = 0;
/* Get UART clock source selection */
u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART_S_Msk) >> CLK_CLKSEL1_UART_S_Pos;
/* Get UART clock divider number */
u8UartClkDivNum = (CLK->CLKDIV & CLK_CLKDIV_UART_N_Msk) >> CLK_CLKDIV_UART_N_Pos;
/* Get PLL clock frequency if UART clock source selection is PLL */
if(u8UartClkSrcSel == 1)
u32ClkTbl[u8UartClkSrcSel] = CLK_GetPLLClockFreq();
/* Set UART baud rate */
if(u32baudrate != 0)
{
u32Baud_Div = UART_BAUD_MODE2_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate);
if(u32Baud_Div > 0xFFFF)
uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate));
else
uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div);
}
/* Set UART line configuration */
uart->LCR = u32data_width | u32parity | u32stop_bits;
}
/**
* @brief Set Rx timeout count
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32TOC Rx timeout counter.
*
* @return None
*
* @details This function use to set Rx timeout count.
*/
void UART_SetTimeoutCnt(UART_T* uart, uint32_t u32TOC)
{
/* Set time-out interrupt comparator */
uart->TOR = (uart->TOR & ~UART_TOR_TOIC_Msk) | (u32TOC);
/* Set time-out counter enable */
uart->IER |= UART_IER_TIME_OUT_EN_Msk;
}
/**
* @brief Select and configure IrDA function
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32Buadrate The baudrate of UART module.
* @param[in] u32Direction The direction(transmit:1/receive:0) of UART module in IrDA mode:
* - UART_IRCR_TX_SELECT
* - UART_IRCR_RX_SELECT
*
* @return None
*
* @details The function is used to configure IrDA relative settings. It consists of TX or RX mode and baudrate.
*/
void UART_SelectIrDAMode(UART_T* uart, uint32_t u32Buadrate, uint32_t u32Direction)
{
uint8_t u8UartClkSrcSel, u8UartClkDivNum;
uint32_t u32ClkTbl[4] = {__HXT, 0, 0, __HIRC};
uint32_t u32Baud_Div;
/* Select IrDA function mode */
uart->FUN_SEL = UART_FUNC_SEL_IrDA;
/* Get UART clock source selection */
u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART_S_Msk) >> CLK_CLKSEL1_UART_S_Pos;
/* Get UART clock divider number */
u8UartClkDivNum = (CLK->CLKDIV & CLK_CLKDIV_UART_N_Msk) >> CLK_CLKDIV_UART_N_Pos;
/* Get PLL clock frequency if UART clock source selection is PLL */
if(u8UartClkSrcSel == 1)
u32ClkTbl[u8UartClkSrcSel] = CLK_GetPLLClockFreq();
/* Set UART IrDA baud rate in mode 0 */
if(u32Buadrate != 0)
{
u32Baud_Div = UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32Buadrate);
if(u32Baud_Div < 0xFFFF)
uart->BAUD = (UART_BAUD_MODE0 | u32Baud_Div);
}
/* Configure IrDA relative settings */
if(u32Direction == UART_IRCR_RX_SELECT)
{
uart->IRCR |= UART_IRCR_INV_RX_Msk; //Rx signal is inverse
uart->IRCR &= ~UART_IRCR_TX_SELECT_Msk;
}
else
{
uart->IRCR &= ~UART_IRCR_INV_TX_Msk; //Tx signal is not inverse
uart->IRCR |= UART_IRCR_TX_SELECT_Msk;
}
}
/**
* @brief Select and configure RS485 function
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32Mode The operation mode(NMM/AUD/AAD).
* - UART_ALT_CSR_RS485_NMM_Msk
* - UART_ALT_CSR_RS485_AUD_Msk
* - UART_ALT_CSR_RS485_AAD_Msk
* @param[in] u32Addr The RS485 address.
*
* @return None
*
* @details The function is used to set RS485 relative setting.
*/
void UART_SelectRS485Mode(UART_T* uart, uint32_t u32Mode, uint32_t u32Addr)
{
/* Select UART RS485 function mode */
uart->FUN_SEL = UART_FUNC_SEL_RS485;
/* Set RS585 configuration */
uart->ALT_CSR &= ~(UART_ALT_CSR_RS485_NMM_Msk | UART_ALT_CSR_RS485_AUD_Msk | UART_ALT_CSR_RS485_AAD_Msk | UART_ALT_CSR_ADDR_MATCH_Msk);
uart->ALT_CSR |= (u32Mode | (u32Addr << UART_ALT_CSR_ADDR_MATCH_Pos));
}
/**
* @brief Select and configure LIN function
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32Mode The LIN direction :
* - UART_ALT_CSR_LIN_TX_EN_Msk
* - UART_ALT_CSR_LIN_RX_EN_Msk
* - (UART_ALT_CSR_LIN_TX_EN_Msk|UART_ALT_CSR_LIN_RX_EN_Msk)
* @param[in] u32BreakLength The breakfield length.
*
* @return None
*
* @details The function is used to set LIN relative setting.
*/
void UART_SelectLINMode(UART_T* uart, uint32_t u32Mode, uint32_t u32BreakLength)
{
/* Select LIN function mode */
uart->FUN_SEL = UART_FUNC_SEL_LIN;
/* Select LIN function setting : Tx enable, Rx enable and break field length */
uart->ALT_CSR &= ~(UART_ALT_CSR_LIN_TX_EN_Msk | UART_ALT_CSR_LIN_RX_EN_Msk | UART_ALT_CSR_UA_LIN_BKFL_Msk);
uart->ALT_CSR |= (u32Mode | (u32BreakLength << UART_ALT_CSR_UA_LIN_BKFL_Pos));
}
/**
* @brief Write UART data
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] pu8TxBuf The buffer to send the data to UART transmission FIFO.
* @param[out] u32WriteBytes The byte number of data.
*
* @return u32Count transfer byte count
*
* @details The function is to write data into TX buffer to transmit data by UART.
*/
uint32_t UART_Write(UART_T* uart, uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
{
uint32_t u32Count, u32delayno;
for(u32Count = 0; u32Count != u32WriteBytes; u32Count++)
{
u32delayno = 0;
while((uart->FSR & UART_FSR_TE_FLAG_Msk) == 0) /* Wait Tx empty and Time-out manner */
{
u32delayno++;
if(u32delayno >= 0x40000000)
return FALSE;
}
uart->THR = pu8TxBuf[u32Count]; /* Send UART Data from buffer */
}
return u32Count;
}
/*@}*/ /* end of group UART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group UART_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2012 Nuvoton Technology Corp. ***/

689
BSP/StdDriver/src/usbd.c Normal file
View File

@ -0,0 +1,689 @@
/**************************************************************************//**
* @file usbd.c
* @version V3.00
* $Revision: 19 $
* $Date: 15/07/17 1:36p $
* @brief USBD driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include "NUC200Series.h"
#if 0
#define DBG_PRINTF printf
#else
#define DBG_PRINTF(...)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup USBD_Driver USBD Driver
@{
*/
/** @addtogroup USBD_EXPORTED_FUNCTIONS USBD Exported Functions
@{
*/
/* Global variables for Control Pipe */
uint8_t g_usbd_SetupPacket[8] = {0}; /*!< Setup packet buffer */
volatile uint8_t g_usbd_RemoteWakeupEn = 0; /*!< Remote wake up function enable flag */
static volatile uint8_t *g_usbd_CtrlInPointer = 0;
static volatile uint32_t g_usbd_CtrlInSize = 0;
static volatile uint8_t *g_usbd_CtrlOutPointer = 0;
static volatile uint32_t g_usbd_CtrlOutSize = 0;
static volatile uint32_t g_usbd_CtrlOutSizeLimit = 0;
static volatile uint32_t g_usbd_UsbAddr = 0;
static volatile uint32_t g_usbd_UsbConfig = 0;
static volatile uint32_t g_usbd_CtrlMaxPktSize = 8;
static volatile uint32_t g_usbd_UsbAltInterface = 0;
static volatile uint32_t g_usbd_CtrlOutToggle = 0;
static volatile uint8_t g_usbd_CtrlInZeroFlag = 0;
const S_USBD_INFO_T *g_usbd_sInfo; /*!< A pointer for USB information structure */
VENDOR_REQ g_usbd_pfnVendorRequest = NULL; /*!< USB Vendor Request Functional Pointer */
CLASS_REQ g_usbd_pfnClassRequest = NULL; /*!< USB Class Request Functional Pointer */
SET_INTERFACE_REQ g_usbd_pfnSetInterface = NULL; /*!< USB Set Interface Functional Pointer */
SET_CONFIG_CB g_usbd_pfnSetConfigCallback = NULL; /*!< USB Set configuration callback function pointer */
uint32_t g_u32EpStallLock = 0; /*!< Bit map flag to lock specified EP when SET_FEATURE */
/**
* @brief This function makes USBD module to be ready to use
*
* @param[in] param The structure of USBD information.
* @param[in] pfnClassReq USB Class request callback function.
* @param[in] pfnSetInterface USB Set Interface request callback function.
*
* @return None
*
* @details This function will enable USB controller, USB PHY transceiver and pull-up resistor of USB_D+ pin. USB PHY will drive SE0 to bus.
*/
void USBD_Open(const S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface)
{
g_usbd_sInfo = param;
g_usbd_pfnClassRequest = pfnClassReq;
g_usbd_pfnSetInterface = pfnSetInterface;
/* get EP0 maximum packet size */
g_usbd_CtrlMaxPktSize = g_usbd_sInfo->gu8DevDesc[7];
/* Initial USB engine */
USBD->ATTR = 0x7D0;
/* Force SE0 */
USBD_SET_SE0();
}
/**
* @brief This function makes USB host to recognize the device
*
* @param None
*
* @return None
*
* @details Enable WAKEUP, FLDET, USB and BUS interrupts. Disable software-disconnect function after 100ms delay with SysTick timer.
*/
void USBD_Start(void)
{
CLK_SysTickDelay(100000);
/* Disable software-disconnect function */
USBD_CLR_SE0();
/* Clear USB-related interrupts before enable interrupt */
USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
/* Enable USB-related interrupts. */
USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
}
/**
* @brief Get the received SETUP packet
*
* @param[in] buf A buffer pointer used to store 8-byte SETUP packet.
*
* @return None
*
* @details Store SETUP packet to a user-specified buffer.
*
*/
void USBD_GetSetupPacket(uint8_t *buf)
{
USBD_MemCopy(buf, g_usbd_SetupPacket, 8);
}
/**
* @brief Process SETUP packet
*
* @param None
*
* @return None
*
* @details Parse SETUP packet and perform the corresponding action.
*
*/
void USBD_ProcessSetupPacket(void)
{
g_usbd_CtrlOutToggle = 0;
/* Get SETUP packet from USB buffer */
USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8);
/* Check the request type */
switch(g_usbd_SetupPacket[0] & 0x60)
{
case REQ_STANDARD: // Standard
{
USBD_StandardRequest();
break;
}
case REQ_CLASS: // Class
{
if(g_usbd_pfnClassRequest != NULL)
{
g_usbd_pfnClassRequest();
}
break;
}
case REQ_VENDOR: // Vendor
{
if(g_usbd_pfnVendorRequest != NULL)
{
g_usbd_pfnVendorRequest();
}
break;
}
default: // reserved
{
/* Setup error, stall the device */
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
break;
}
}
}
/**
* @brief Process GetDescriptor request
*
* @param None
*
* @return None
*
* @details Parse GetDescriptor request and perform the corresponding action.
*
*/
void USBD_GetDescriptor(void)
{
uint32_t u32Len;
g_usbd_CtrlInZeroFlag = (uint8_t)0;
u32Len = 0;
u32Len = g_usbd_SetupPacket[7];
u32Len <<= 8;
u32Len += g_usbd_SetupPacket[6];
switch(g_usbd_SetupPacket[3])
{
// Get Device Descriptor
case DESC_DEVICE:
{
u32Len = Minimum(u32Len, LEN_DEVICE);
DBG_PRINTF("Get device desc, %d\n", u32Len);
USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8DevDesc, u32Len);
USBD_PrepareCtrlOut(0, 0);
break;
}
// Get Configuration Descriptor
case DESC_CONFIG:
{
uint32_t u32TotalLen;
u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3];
u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8);
if(u32Len > u32TotalLen)
{
u32Len = u32TotalLen;
if((u32Len % g_usbd_CtrlMaxPktSize) == 0)
{
g_usbd_CtrlInZeroFlag = (uint8_t)1;
}
}
USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8ConfigDesc, u32Len);
USBD_PrepareCtrlOut(0, 0);
break;
}
// Get HID Descriptor
case DESC_HID:
{
u32Len = Minimum(u32Len, LEN_HID);
USBD_PrepareCtrlIn((uint8_t *)&g_usbd_sInfo->gu8ConfigDesc[LEN_CONFIG + LEN_INTERFACE], u32Len);
USBD_PrepareCtrlOut(0, 0);
break;
}
// Get Report Descriptor
case DESC_HID_RPT:
{
uint32_t u32TotalLen;
uint32_t u32RptDescLen;
/* Get configuration descriptor size */
u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3];
u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8);
/* Calculate the offset of HID report descriptor size to get report descriptor size.
User may need to modify this if configuration descriptor changed. */
u32RptDescLen = g_usbd_sInfo->gu8ConfigDesc[u32TotalLen - LEN_ENDPOINT - 1];
u32RptDescLen = g_usbd_sInfo->gu8ConfigDesc[u32TotalLen - LEN_ENDPOINT - 2] + (u32RptDescLen << 8);
if(u32Len > u32RptDescLen)
{
u32Len = u32RptDescLen;
if((u32Len % g_usbd_CtrlMaxPktSize) == 0)
{
g_usbd_CtrlInZeroFlag = (uint8_t)1;
}
}
USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8HidReportDesc, u32Len);
USBD_PrepareCtrlOut(0, 0);
break;
}
// Get String Descriptor
case DESC_STRING:
{
// Get String Descriptor
if(g_usbd_SetupPacket[2] < 4)
{
if(u32Len > g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]][0])
{
u32Len = g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]][0];
if((u32Len % g_usbd_CtrlMaxPktSize) == 0)
{
g_usbd_CtrlInZeroFlag = (uint8_t)1;
}
}
USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]], u32Len);
USBD_PrepareCtrlOut(0, 0);
break;
}
else
{
// Not support. Reply STALL.
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
DBG_PRINTF("Unsupported string desc (%d). Stall ctrl pipe.\n", g_usbd_SetupPacket[2]);
break;
}
}
default:
// Not support. Reply STALL.
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
DBG_PRINTF("Unsupported get desc type. stall ctrl pipe\n");
break;
}
}
/**
* @brief Process standard request
*
* @param None
*
* @return None
*
* @details Parse standard request and perform the corresponding action.
*
*/
void USBD_StandardRequest(void)
{
/* clear global variables for new request */
g_usbd_CtrlInPointer = 0;
g_usbd_CtrlInSize = 0;
if(g_usbd_SetupPacket[0] & 0x80) /* request data transfer direction */
{
// Device to host
switch(g_usbd_SetupPacket[1])
{
case GET_CONFIGURATION:
{
// Return current configuration setting
/* Data stage */
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbConfig;
USBD_SET_DATA1(EP1);
USBD_SET_PAYLOAD_LEN(EP1, 0);
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 1);
/* Status stage */
USBD_PrepareCtrlOut(0, 0);
DBG_PRINTF("Get configuration\n");
break;
}
case GET_DESCRIPTOR:
{
USBD_GetDescriptor();
/* Status stage */
USBD_PrepareCtrlOut(0, 0);
DBG_PRINTF("Get descriptor\n");
break;
}
case GET_INTERFACE:
{
// Return current interface setting
/* Data stage */
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbAltInterface;
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 1);
/* Status stage */
USBD_PrepareCtrlOut(0, 0);
DBG_PRINTF("Get interface\n");
break;
}
case GET_STATUS:
{
// Device
if(g_usbd_SetupPacket[0] == 0x80)
{
uint8_t u8Tmp;
u8Tmp = 0;
if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x40) u8Tmp |= 1; // Self-Powered/Bus-Powered.
if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x20) u8Tmp |= (g_usbd_RemoteWakeupEn << 1); // Remote wake up
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = u8Tmp;
}
// Interface
else if(g_usbd_SetupPacket[0] == 0x81)
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0;
// Endpoint
else if(g_usbd_SetupPacket[0] == 0x82)
{
uint8_t ep = g_usbd_SetupPacket[4] & 0xF;
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = USBD_GetStall(ep) ? 1 : 0;
}
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0) + 1) = 0;
/* Data stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 2);
/* Status stage */
USBD_PrepareCtrlOut(0, 0);
DBG_PRINTF("Get status\n");
break;
}
default:
{
/* Setup error, stall the device */
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
DBG_PRINTF("Unknown request. stall ctrl pipe.\n");
break;
}
}
}
else
{
// Host to device
switch(g_usbd_SetupPacket[1])
{
case CLEAR_FEATURE:
{
if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT)
{
int32_t epNum, i;
/* EP number stall is not allow to be clear in MSC class "Error Recovery Test".
a flag: g_u32EpStallLock is added to support it */
epNum = g_usbd_SetupPacket[4] & 0xF;
for(i = 0; i < USBD_MAX_EP; i++)
{
if(((USBD->EP[i].CFG & 0xF) == epNum) && ((g_u32EpStallLock & (1 << i)) == 0))
{
USBD->EP[i].CFGP &= ~USBD_CFGP_SSTALL_Msk;
USBD->EP[i].CFG &= ~USBD_CFG_DSQ_SYNC_Msk;
DBG_PRINTF("Clr stall ep%d %x\n", i, USBD->EP[i].CFGP);
}
}
}
else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP)
g_usbd_RemoteWakeupEn = 0;
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
DBG_PRINTF("Clear feature op %d\n", g_usbd_SetupPacket[2]);
break;
}
case SET_ADDRESS:
{
g_usbd_UsbAddr = g_usbd_SetupPacket[2];
DBG_PRINTF("Set addr to %d\n", g_usbd_UsbAddr);
// DATA IN for end of setup
/* Status Stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
break;
}
case SET_CONFIGURATION:
{
g_usbd_UsbConfig = g_usbd_SetupPacket[2];
if(g_usbd_pfnSetConfigCallback)
g_usbd_pfnSetConfigCallback();
// DATA IN for end of setup
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
DBG_PRINTF("Set config to %d\n", g_usbd_UsbConfig);
break;
}
case SET_FEATURE:
{
if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT)
{
USBD_SetStall(g_usbd_SetupPacket[4] & 0xF);
DBG_PRINTF("Set feature. stall ep %d\n", g_usbd_SetupPacket[4] & 0xF);
}
else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP)
{
g_usbd_RemoteWakeupEn = 1;
DBG_PRINTF("Set feature. enable remote wakeup\n");
}
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
break;
}
case SET_INTERFACE:
{
g_usbd_UsbAltInterface = g_usbd_SetupPacket[2];
if(g_usbd_pfnSetInterface != NULL)
g_usbd_pfnSetInterface();
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
DBG_PRINTF("Set interface to %d\n", g_usbd_UsbAltInterface);
break;
}
default:
{
/* Setup error, stall the device */
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
DBG_PRINTF("Unsupported request. stall ctrl pipe.\n");
break;
}
}
}
}
/**
* @brief Prepare the first Control IN pipe
*
* @param[in] pu8Buf The pointer of data sent to USB host.
* @param[in] u32Size The IN transfer size.
*
* @return None
*
* @details Prepare data for Control IN transfer.
*
*/
void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size)
{
DBG_PRINTF("Prepare Ctrl In %d\n", u32Size);
if(u32Size > g_usbd_CtrlMaxPktSize)
{
// Data size > MXPLD
g_usbd_CtrlInPointer = pu8Buf + g_usbd_CtrlMaxPktSize;
g_usbd_CtrlInSize = u32Size - g_usbd_CtrlMaxPktSize;
USBD_SET_DATA1(EP0);
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, g_usbd_CtrlMaxPktSize);
USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize);
}
else
{
// Data size <= MXPLD
g_usbd_CtrlInPointer = 0;
g_usbd_CtrlInSize = 0;
USBD_SET_DATA1(EP0);
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, u32Size);
USBD_SET_PAYLOAD_LEN(EP0, u32Size);
}
}
/**
* @brief Repeat Control IN pipe
*
* @param None
*
* @return None
*
* @details This function processes the remained data of Control IN transfer.
*
*/
void USBD_CtrlIn(void)
{
DBG_PRINTF("Ctrl In Ack. residue %d\n", g_usbd_CtrlInSize);
if(g_usbd_CtrlInSize)
{
// Process remained data
if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize)
{
// Data size > MXPLD
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize);
USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize);
g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize;
g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize;
}
else
{
// Data size <= MXPLD
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlInSize);
USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlInSize);
g_usbd_CtrlInPointer = 0;
g_usbd_CtrlInSize = 0;
}
}
else // No more data for IN token
{
// In ACK for Set address
if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == SET_ADDRESS))
{
if((USBD_GET_ADDR() != g_usbd_UsbAddr) && (USBD_GET_ADDR() == 0))
{
USBD_SET_ADDR(g_usbd_UsbAddr);
}
}
/* For the case of data size is integral times maximum packet size */
if(g_usbd_CtrlInZeroFlag)
{
USBD_SET_PAYLOAD_LEN(EP0, 0);
g_usbd_CtrlInZeroFlag = 0;
}
DBG_PRINTF("Ctrl In done.\n");
}
}
/**
* @brief Prepare the first Control OUT pipe
*
* @param[in] pu8Buf The pointer of data received from USB host.
* @param[in] u32Size The OUT transfer size.
*
* @return None
*
* @details This function is used to prepare the first Control OUT transfer.
*
*/
void USBD_PrepareCtrlOut(uint8_t *pu8Buf, uint32_t u32Size)
{
g_usbd_CtrlOutPointer = pu8Buf;
g_usbd_CtrlOutSize = 0;
g_usbd_CtrlOutSizeLimit = u32Size;
USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize);
}
/**
* @brief Repeat Control OUT pipe
*
* @param None
*
* @return None
*
* @details This function processes the successive Control OUT transfer.
*
*/
void USBD_CtrlOut(void)
{
uint32_t u32Size;
DBG_PRINTF("Ctrl Out Ack %d\n", g_usbd_CtrlOutSize);
if(g_usbd_CtrlOutToggle != (USBD->EPSTS & USBD_EPSTS_EPSTS1_Msk))
{
g_usbd_CtrlOutToggle = USBD->EPSTS & USBD_EPSTS_EPSTS1_Msk;
if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit)
{
u32Size = USBD_GET_PAYLOAD_LEN(EP1);
USBD_MemCopy((uint8_t *)g_usbd_CtrlOutPointer, (uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1), u32Size);
g_usbd_CtrlOutPointer += u32Size;
g_usbd_CtrlOutSize += u32Size;
if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit)
USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize);
}
}
else
{
USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize);
}
}
/**
* @brief Reset software flags
*
* @param None
*
* @return None
*
* @details This function resets all variables for protocol and resets USB device address to 0.
*
*/
void USBD_SwReset(void)
{
int i;
// Reset all variables for protocol
g_usbd_CtrlInPointer = 0;
g_usbd_CtrlInSize = 0;
g_usbd_CtrlOutPointer = 0;
g_usbd_CtrlOutSize = 0;
g_usbd_CtrlOutSizeLimit = 0;
g_u32EpStallLock = 0;
memset(g_usbd_SetupPacket, 0, 8);
/* Reset PID DATA0 */
for(i=0; i<USBD_MAX_EP; i++)
USBD->EP[i].CFG &= ~USBD_CFG_DSQ_SYNC_Msk;
// Reset USB device address
USBD_SET_ADDR(0);
}
void USBD_SetVendorRequest(VENDOR_REQ pfnVendorReq)
{
g_usbd_pfnVendorRequest = pfnVendorReq;
}
void USBD_SetConfigCallback(SET_CONFIG_CB pfnSetConfigCallback)
{
g_usbd_pfnSetConfigCallback = pfnSetConfigCallback;
}
void USBD_LockEpStall(uint32_t u32EpBitmap)
{
g_u32EpStallLock = u32EpBitmap;
}
/*@}*/ /* end of group USBD_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group USBD_Driver */
/*@}*/ /* end of group Device_Driver */
#ifdef __cplusplus
}
#endif
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

71
BSP/StdDriver/src/wdt.c Normal file
View File

@ -0,0 +1,71 @@
/**************************************************************************//**
* @file wdt.c
* @version V3.00
* $Revision: 10 $
* $Date: 15/05/04 3:59p $
* @brief WDT driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup WDT_Driver WDT Driver
@{
*/
/** @addtogroup WDT_EXPORTED_FUNCTIONS WDT Exported Functions
@{
*/
/**
* @brief Initialize WDT counter and start counting
*
* @param[in] u32TimeoutInterval Time-out interval period of WDT module. Valid values are:
* - \ref WDT_TIMEOUT_2POW4
* - \ref WDT_TIMEOUT_2POW6
* - \ref WDT_TIMEOUT_2POW8
* - \ref WDT_TIMEOUT_2POW10
* - \ref WDT_TIMEOUT_2POW12
* - \ref WDT_TIMEOUT_2POW14
* - \ref WDT_TIMEOUT_2POW16
* - \ref WDT_TIMEOUT_2POW18
* @param[in] u32ResetDelay Configure reset delay period while WDT time-out happened. Valid values are:
* - \ref WDT_RESET_DELAY_1026CLK
* - \ref WDT_RESET_DELAY_130CLK
* - \ref WDT_RESET_DELAY_18CLK
* - \ref WDT_RESET_DELAY_3CLK
* @param[in] u32EnableReset Enable WDT reset system function. Valid values are TRUE and FALSE.
* @param[in] u32EnableWakeup Enable WDT wake-up system function. Valid values are TRUE and FALSE.
*
* @return None
*
* @details This function make WDT module start counting with different time-out interval and reset delay period.
* @note Please make sure that Register Write-Protection Function has been disabled before using this function.
*/
void WDT_Open(uint32_t u32TimeoutInterval,
uint32_t u32ResetDelay,
uint32_t u32EnableReset,
uint32_t u32EnableWakeup)
{
WDT->WTCRALT = u32ResetDelay;
WDT->WTCR = u32TimeoutInterval | WDT_WTCR_WTE_Msk |
(u32EnableReset << WDT_WTCR_WTRE_Pos) |
(u32EnableWakeup << WDT_WTCR_WTWKE_Pos);
return;
}
/*@}*/ /* end of group WDT_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group WDT_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

72
BSP/StdDriver/src/wwdt.c Normal file
View File

@ -0,0 +1,72 @@
/**************************************************************************//**
* @file wwdt.c
* @version V3.00
* $Revision: 8 $
* $Date: 15/05/04 3:59p $
* @brief WWDT driver source file
*
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC200Series.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup WWDT_Driver WWDT Driver
@{
*/
/** @addtogroup WWDT_EXPORTED_FUNCTIONS WWDT Exported Functions
@{
*/
/**
* @brief Open WWDT function to start counting
*
* @param[in] u32PreScale Prescale period for the WWDT counter period. Valid values are:
* - \ref WWDT_PRESCALER_1
* - \ref WWDT_PRESCALER_2
* - \ref WWDT_PRESCALER_4
* - \ref WWDT_PRESCALER_8
* - \ref WWDT_PRESCALER_16
* - \ref WWDT_PRESCALER_32
* - \ref WWDT_PRESCALER_64
* - \ref WWDT_PRESCALER_128
* - \ref WWDT_PRESCALER_192
* - \ref WWDT_PRESCALER_256
* - \ref WWDT_PRESCALER_384
* - \ref WWDT_PRESCALER_512
* - \ref WWDT_PRESCALER_768
* - \ref WWDT_PRESCALER_1024
* - \ref WWDT_PRESCALER_1536
* - \ref WWDT_PRESCALER_2048
* @param[in] u32CmpValue Setting the window compared value. Valid values are between 0x0 to 0x3F.
* @param[in] u32EnableInt Enable WWDT interrupt function. Valid values are TRUE and FALSE.
*
* @return None
*
* @details This function make WWDT module start counting with different counter period and compared window value.
* @note Application can call this function valid only once after boot up.
*/
void WWDT_Open(uint32_t u32PreScale,
uint32_t u32CmpValue,
uint32_t u32EnableInt)
{
WWDT->WWDTCR = u32PreScale |
(u32CmpValue << WWDT_WWDTCR_WINCMP_Pos) |
((u32EnableInt == TRUE) ? WWDT_WWDTCR_WWDTIE_Msk : 0) |
WWDT_WWDTCR_WWDTEN_Msk;
return;
}
/*@}*/ /* end of group WWDT_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group WWDT_Driver */
/*@}*/ /* end of group Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

117
CMakeLists.txt Normal file
View File

@ -0,0 +1,117 @@
cmake_minimum_required(VERSION 3.10)
project(NUC200_Template)
enable_language(CXX)
enable_language(ASM)
# Extra CFlags
set(TARGET_CFLAGS_EXTRA "")
set(TARGET_CXXFLAGS_EXTRA "")
set(TARGET_LDFLAGS_EXTRA "-Wl,--print-memory-usage")
# Different linker scripts
set(TARGET_LDSCRIPT_FLASH "${CMAKE_SOURCE_DIR}/BSP/Device/Nuvoton/NUC200Series/Source/GCC/gcc_arm.ld")
# Copy them from Makefile
set(TARGET_C_SOURCES
# "BSP/Device/Nuvoton/NUC200Series/Source/GCC/_syscalls.c" # Not used
"BSP/Device/Nuvoton/NUC200Series/Source/system_NUC200Series.c"
"BSP/StdDriver/src/acmp.c"
"BSP/StdDriver/src/adc.c"
"BSP/StdDriver/src/clk.c"
"BSP/StdDriver/src/crc.c"
"BSP/StdDriver/src/fmc.c"
"BSP/StdDriver/src/gpio.c"
"BSP/StdDriver/src/i2c.c"
"BSP/StdDriver/src/i2s.c"
"BSP/StdDriver/src/pdma.c"
"BSP/StdDriver/src/ps2.c"
"BSP/StdDriver/src/pwm.c"
# "BSP/StdDriver/src/retarget.c" # Low quality code.
"BSP/StdDriver/src/rtc.c"
"BSP/StdDriver/src/sc.c"
"BSP/StdDriver/src/spi.c"
"BSP/StdDriver/src/sys.c"
"BSP/StdDriver/src/timer.c"
"BSP/StdDriver/src/uart.c"
"BSP/StdDriver/src/usbd.c"
"BSP/StdDriver/src/wdt.c"
"BSP/StdDriver/src/wwdt.c"
"src/main.c"
)
# Copy them from Makefile
set(TARGET_ASM_SOURCES
"BSP/Device/Nuvoton/NUC200Series/Source/GCC/startup_NUC200Series.S"
)
# Copy them from Makefile
set(TARGET_C_DEFINES
)
# Copy them from Makefile
set(TARGET_C_INCLUDES
"BSP/CMSIS/Include"
"BSP/Device/Nuvoton/NUC200Series/Include"
"BSP/SmartcardLib/Include"
"BSP/StdDriver/inc"
)
# Shared libraries linked with application
set(TARGET_LIBS
"smartcard"
)
# Shared library and linker script search paths
set(TARGET_LIB_DIRECTORIES
"BSP/SmartcardLib"
)
# Device specific settings, goes to CFLAGS and LDFLAGS
set(TARGET_CFLAGS_HARDWARE "-mcpu=cortex-m0 -mthumb")
# Conditional flags
# DEBUG
set(CMAKE_C_FLAGS_DEBUG "-DDEBUG -Og -g")
set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -Og -g")
set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG -Og -g")
# RELEASE
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2 -flto")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O2 -flto")
set(CMAKE_ASM_FLAGS_RELEASE "-DNDEBUG -O2 -flto")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-flto")
# Final compiler flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TARGET_CFLAGS_HARDWARE} ${TARGET_CFLAGS_EXTRA} -Wall -fdata-sections -ffunction-sections")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TARGET_CFLAGS_HARDWARE} ${TARGET_CXXFLAGS_EXTRA} -Wall -fdata-sections -ffunction-sections")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_C_FLAGS} -x assembler-with-cpp")
set(CMAKE_EXE_LINKER_FLAGS "-specs=nano.specs -Wl,--gc-sections -lc -lm -lnosys ${TARGET_LDFLAGS_EXTRA}")
# Include sub directories here
# Shared sources, includes and definitions
add_compile_definitions(${TARGET_C_DEFINES})
include_directories(${TARGET_C_INCLUDES})
link_directories(${TARGET_LIB_DIRECTORIES})
link_libraries(${TARGET_LIBS})
# Main targets are added here
# **** Internal Flash ****
# Create ELF
add_executable("${CMAKE_PROJECT_NAME}_FLASH.elf" ${TARGET_C_SOURCES} ${TARGET_ASM_SOURCES})
target_link_options("${CMAKE_PROJECT_NAME}_FLASH.elf"
PRIVATE "-T${TARGET_LDSCRIPT_FLASH}"
PRIVATE "-Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}_FLASH.map,--cref"
)
add_custom_command(OUTPUT "${CMAKE_PROJECT_NAME}_FLASH.hex"
COMMAND ${CMAKE_OBJCOPY} "-O" "ihex" "${CMAKE_PROJECT_NAME}_FLASH.elf" "${CMAKE_PROJECT_NAME}_FLASH.hex"
DEPENDS "${CMAKE_PROJECT_NAME}_FLASH.elf"
)
add_custom_target("${CMAKE_PROJECT_NAME}_FLASH_HEX" DEPENDS "${CMAKE_PROJECT_NAME}_FLASH.hex")
# **** Cortex-M0 does not support SCB->VTOR configuration, so RAM debug is not possible. ****

4
arm-none-eabi.cmake Normal file
View File

@ -0,0 +1,4 @@
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
# Make CMake happy about those compilers
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")

38
run_debugserver.sh Executable file
View File

@ -0,0 +1,38 @@
#!/bin/bash
run_jlinkserver() {
JLinkGDBServerCLExe -if SWD -device STM32H750VBTx \
-ir -localhostonly -nogui \
-rtos GDBServer/RTOSPlugin_FreeRTOS.so
}
run_openocd_stlink() {
openocd -f "interface/stlink.cfg" -f "target/stm32h7x.cfg"
}
run_openocd_jlink() {
openocd -f "interface/jlink.cfg" -c "transport select swd" -f "target/stm32h7x.cfg"
}
run_pyocd() {
pyocd gdbserver -t stm32h750vbtx -f 24m --persist
}
case $1 in
jlink)
run_jlinkserver
;;
pyocd)
run_pyocd
;;
openocd-stlink)
run_openocd_stlink
;;
openocd-jlink)
run_openocd_jlink
;;
esac

8
src/main.c Normal file
View File

@ -0,0 +1,8 @@
#include "NUC200Series.h"
int main(int argc, const char *argv[]) {
SystemCoreClockUpdate();
for(;;) {
}
}