change files

This commit is contained in:
Grey Huang
2019-10-25 18:47:35 +08:00
parent b548a03df4
commit b76a703108
181 changed files with 7927 additions and 12141 deletions

View File

@@ -0,0 +1,414 @@
/**************************************************************************//**
* @file ACMP.h
* @version V1.00
* @brief M251 series ACMP Driver Header File
*
* @copyright (C) 2018 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
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* ACMP_CTL constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ACMP_CTL_FILTSEL_OFF (0UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for filter function disabled. \hideinitializer */
#define ACMP_CTL_FILTSEL_1PCLK (1UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 1 PCLK filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_2PCLK (2UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 2 PCLKs filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_4PCLK (3UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 4 PCLKs filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_8PCLK (4UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 8 PCLKs filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_16PCLK (5UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 16 PCLKs filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_32PCLK (6UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 32 PCLKs filter count. \hideinitializer */
#define ACMP_CTL_FILTSEL_64PCLK (7UL << ACMP_CTL_FILTSEL_Pos) /*!< ACMP_CTL setting for 64 PCLKs filter count. \hideinitializer */
#define ACMP_CTL_INTPOL_RF (0UL << ACMP_CTL_INTPOL_Pos) /*!< ACMP_CTL setting for selecting rising edge and falling edge as interrupt condition. \hideinitializer */
#define ACMP_CTL_INTPOL_R (1UL << ACMP_CTL_INTPOL_Pos) /*!< ACMP_CTL setting for selecting rising edge as interrupt condition. \hideinitializer */
#define ACMP_CTL_INTPOL_F (2UL << ACMP_CTL_INTPOL_Pos) /*!< ACMP_CTL setting for selecting falling edge as interrupt condition. \hideinitializer */
#define ACMP_CTL_POSSEL_P0 (0UL << ACMP_CTL_POSSEL_Pos) /*!< ACMP_CTL setting for selecting ACMPx_P0 pin as the source of ACMP V+. \hideinitializer */
#define ACMP_CTL_POSSEL_P1 (1UL << ACMP_CTL_POSSEL_Pos) /*!< ACMP_CTL setting for selecting ACMPx_P1 pin as the source of ACMP V+. \hideinitializer */
#define ACMP_CTL_POSSEL_P2 (2UL << ACMP_CTL_POSSEL_Pos) /*!< ACMP_CTL setting for selecting ACMPx_P2 pin as the source of ACMP V+. \hideinitializer */
#define ACMP_CTL_POSSEL_P3 (3UL << ACMP_CTL_POSSEL_Pos) /*!< ACMP_CTL setting for selecting ACMPx_P3 pin as the source of ACMP V+. \hideinitializer */
#define ACMP_CTL_NEGSEL_PIN (0UL << ACMP_CTL_NEGSEL_Pos) /*!< ACMP_CTL setting for selecting the voltage of ACMP negative input pin as the source of ACMP V-. \hideinitializer */
#define ACMP_CTL_NEGSEL_CRV (1UL << ACMP_CTL_NEGSEL_Pos) /*!< ACMP_CTL setting for selecting internal comparator reference voltage as the source of ACMP V-. \hideinitializer */
#define ACMP_CTL_NEGSEL_VBG (2UL << ACMP_CTL_NEGSEL_Pos) /*!< ACMP_CTL setting for selecting internal Band-gap voltage as the source of ACMP V-. \hideinitializer */
#define ACMP_CTL_NEGSEL_DAC (3UL << ACMP_CTL_NEGSEL_Pos) /*!< ACMP_CTL setting for selecting DAC output voltage as the source of ACMP V-. \hideinitializer */
#define ACMP_CTL_HYSTERESIS_30MV (3UL << ACMP_CTL_HYSSEL_Pos) /*!< ACMP_CTL setting for enabling the hysteresis function at 30mV. \hideinitializer */
#define ACMP_CTL_HYSTERESIS_20MV (2UL << ACMP_CTL_HYSSEL_Pos) /*!< ACMP_CTL setting for enabling the hysteresis function at 20mV. \hideinitializer */
#define ACMP_CTL_HYSTERESIS_10MV (1UL << ACMP_CTL_HYSSEL_Pos) /*!< ACMP_CTL setting for enabling the hysteresis function at 10mV. \hideinitializer */
#define ACMP_CTL_HYSTERESIS_DISABLE (0UL << ACMP_CTL_HYSSEL_Pos) /*!< ACMP_CTL setting for disabling the hysteresis function. \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* ACMP_VREF constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ACMP_VREF_CRVSSEL_AVDD (0UL << ACMP_VREF_CRVSSEL_Pos) /*!< ACMP_VREF setting for selecting analog supply voltage AVDD as the CRV source voltage \hideinitializer */
#define ACMP_VREF_CRVSSEL_INTVREF (1UL << ACMP_VREF_CRVSSEL_Pos) /*!< ACMP_VREF setting for selecting internal reference voltage as the CRV source voltage \hideinitializer */
/*@}*/ /* end of group ACMP_EXPORTED_CONSTANTS */
/** @addtogroup ACMP_EXPORTED_FUNCTIONS ACMP Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Define Macros and functions */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief This macro is used to enable output inverse function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set ACMPOINV bit of ACMP_CTL register to enable output inverse function.
* \hideinitializer
*/
#define ACMP_ENABLE_OUTPUT_INVERSE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_ACMPOINV_Msk)
/**
* @brief This macro is used to disable output inverse function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear ACMPOINV bit of ACMP_CTL register to disable output inverse function.
* \hideinitializer
*/
#define ACMP_DISABLE_OUTPUT_INVERSE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_ACMPOINV_Msk)
/**
* @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 is comparator negative input selection. Including:
* - \ref ACMP_CTL_NEGSEL_PIN
* - \ref ACMP_CTL_NEGSEL_CRV
* - \ref ACMP_CTL_NEGSEL_VBG
* - \ref ACMP_CTL_NEGSEL_DAC
* @return None
* @details This macro will set NEGSEL (ACMP_CTL[5:4]) to determine the source of negative input.
* \hideinitializer
*/
#define ACMP_SET_NEG_SRC(acmp, u32ChNum, u32Src) ((acmp)->CTL[(u32ChNum)] = ((acmp)->CTL[(u32ChNum)] & ~ACMP_CTL_NEGSEL_Msk) | (u32Src))
/**
* @brief This macro is used to enable hysteresis function and set hysteresis to 30mV
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* \hideinitializer
*/
#define ACMP_ENABLE_HYSTERESIS(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_HYSTERESIS_30MV)
/**
* @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 HYSEL bits of ACMP_CTL register to disable hysteresis function.
* \hideinitializer
*/
#define ACMP_DISABLE_HYSTERESIS(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_HYSSEL_Msk)
/**
* @brief This macro is used to select hysteresis level
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @param[in] u32HysSel The hysteresis function option. Including:
* - \ref ACMP_CTL_HYSTERESIS_30MV
* - \ref ACMP_CTL_HYSTERESIS_20MV
* - \ref ACMP_CTL_HYSTERESIS_10MV
* - \ref ACMP_CTL_HYSTERESIS_DISABLE
* \hideinitializer
* @return None
*/
#define ACMP_CONFIG_HYSTERESIS(acmp, u32ChNum, u32HysSel) ((acmp)->CTL[(u32ChNum)] = ((acmp)->CTL[(u32ChNum)] & ~ACMP_CTL_HYSSEL_Msk) | (u32HysSel))
/**
* @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 ACMPIE bit of ACMP_CTL register to enable interrupt function.
* If wake-up function is enabled, the wake-up interrupt will be enabled as well.
* \hideinitializer
*/
#define ACMP_ENABLE_INT(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_ACMPIE_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 ACMPIE bit of ACMP_CTL register to disable interrupt function.
* \hideinitializer
*/
#define ACMP_DISABLE_INT(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_ACMPIE_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 ACMPEN bit of ACMP_CTL register to enable analog comparator.
* \hideinitializer
*/
#define ACMP_ENABLE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_ACMPEN_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 ACMPEN bit of ACMP_CTL register to disable analog comparator.
* \hideinitializer
*/
#define ACMP_DISABLE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_ACMPEN_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.
* \hideinitializer
*/
#define ACMP_GET_OUTPUT(acmp, u32ChNum) (((acmp)->STATUS & (ACMP_STATUS_ACMPO0_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 (1) or not (0)
* @details This macro will return the ACMP interrupt flag.
* \hideinitializer
*/
#define ACMP_GET_INT_FLAG(acmp, u32ChNum) (((acmp)->STATUS & (ACMP_STATUS_ACMPIF0_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 ACMPIFn bit of ACMP_STATUS register to clear interrupt flag.
* \hideinitializer
*/
#define ACMP_CLR_INT_FLAG(acmp, u32ChNum) ((acmp)->STATUS = (ACMP_STATUS_ACMPIF0_Msk<<((u32ChNum))))
/**
* @brief This macro is used to clear ACMP wake-up 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 WKIFn bit of ACMP_STATUS register to clear interrupt flag.
* \hideinitializer
*/
#define ACMP_CLR_WAKEUP_INT_FLAG(acmp, u32ChNum) ((acmp)->STATUS = (ACMP_STATUS_WKIF0_Msk<<((u32ChNum))))
/**
* @brief This macro is used to enable ACMP wake-up function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set WKEN (ACMP_CTL[16]) to enable ACMP wake-up function.
* \hideinitializer
*/
#define ACMP_ENABLE_WAKEUP(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_WKEN_Msk)
/**
* @brief This macro is used to disable ACMP wake-up function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear WKEN (ACMP_CTL[16]) to disable ACMP wake-up function.
* \hideinitializer
*/
#define ACMP_DISABLE_WAKEUP(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_WKEN_Msk)
/**
* @brief This macro is used to select ACMP positive input pin
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @param[in] u32Pin Comparator positive pin selection. Including:
* - \ref ACMP_CTL_POSSEL_P0
* - \ref ACMP_CTL_POSSEL_P1
* - \ref ACMP_CTL_POSSEL_P2
* - \ref ACMP_CTL_POSSEL_P3
* @return None
* @details This macro will set POSSEL (ACMP_CTL[7:6]) to determine the comparator positive input pin.
* \hideinitializer
*/
#define ACMP_SELECT_P(acmp, u32ChNum, u32Pin) ((acmp)->CTL[(u32ChNum)] = ((acmp)->CTL[(u32ChNum)] & ~ACMP_CTL_POSSEL_Msk) | (u32Pin))
/**
* @brief This macro is used to enable ACMP filter function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set OUTSEL (ACMP_CTL[12]) to enable output filter function.
* \hideinitializer
*/
#define ACMP_ENABLE_FILTER(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_OUTSEL_Msk)
/**
* @brief This macro is used to disable ACMP filter function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear OUTSEL (ACMP_CTL[12]) to disable output filter function.
* \hideinitializer
*/
#define ACMP_DISABLE_FILTER(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_OUTSEL_Msk)
/**
* @brief This macro is used to set ACMP filter function
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @param[in] u32Cnt is comparator filter count setting.
* - \ref ACMP_CTL_FILTSEL_OFF
* - \ref ACMP_CTL_FILTSEL_1PCLK
* - \ref ACMP_CTL_FILTSEL_2PCLK
* - \ref ACMP_CTL_FILTSEL_4PCLK
* - \ref ACMP_CTL_FILTSEL_8PCLK
* - \ref ACMP_CTL_FILTSEL_16PCLK
* - \ref ACMP_CTL_FILTSEL_32PCLK
* - \ref ACMP_CTL_FILTSEL_64PCLK
* @return None
* @details When ACMP output filter function is enabled, the output sampling count is determined by FILTSEL (ACMP_CTL[15:13]).
* \hideinitializer
*/
#define ACMP_SET_FILTER(acmp, u32ChNum, u32Cnt) ((acmp)->CTL[(u32ChNum)] = ((acmp)->CTL[(u32ChNum)] & ~ACMP_CTL_FILTSEL_Msk) | (u32Cnt))
/**
* @brief This macro is used to select comparator reference voltage
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32Level The comparator reference voltage setting.
* The formula is:
* comparator reference voltage = CRV source voltage x (1/6 + u32Level/24)
* The range of u32Level is 0 ~ 15.
* @return None
* @details When CRV is selected as ACMP negative input source, the CRV level is determined by CRVCTL (ACMP_VREF[3:0]).
* \hideinitializer
*/
#define ACMP_CRV_SEL(acmp, u32Level) ((acmp)->VREF = ((acmp)->VREF & ~ACMP_VREF_CRVCTL_Msk) | ((u32Level)<<ACMP_VREF_CRVCTL_Pos))
/**
* @brief This macro is used to select the source of CRV
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32Src is the source of CRV. Including:
* - \ref ACMP_VREF_CRVSSEL_AVDD
* - \ref ACMP_VREF_CRVSSEL_INTVREF
* @return None
* @details The source of CRV can be VDDA or internal reference voltage. The internal reference voltage level is determined by SYS_VREFCTL register.
* \hideinitializer
*/
#define ACMP_SELECT_CRV_SRC(acmp, u32Src) ((acmp)->VREF = ((acmp)->VREF & ~ACMP_VREF_CRVSSEL_Msk) | (u32Src))
/**
* @brief This macro is used to select ACMP interrupt condition
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @param[in] u32Cond Comparator interrupt condition selection. Including:
* - \ref ACMP_CTL_INTPOL_RF
* - \ref ACMP_CTL_INTPOL_R
* - \ref ACMP_CTL_INTPOL_F
* @return None
* @details The ACMP output interrupt condition can be rising edge, falling edge or any edge.
* \hideinitializer
*/
#define ACMP_SELECT_INT_COND(acmp, u32ChNum, u32Cond) ((acmp)->CTL[(u32ChNum)] = ((acmp)->CTL[(u32ChNum)] & ~ACMP_CTL_INTPOL_Msk) | (u32Cond))
/**
* @brief This macro is used to enable ACMP window latch mode
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set WLATEN (ACMP_CTL[17]) to enable ACMP window latch mode.
* When ACMP0/1_WLAT pin is at high level, ACMPO0/1 passes through window latch
* block; when ACMP0/1_WLAT pin is at low level, the output of window latch block,
* WLATOUT, is frozen.
* \hideinitializer
*/
#define ACMP_ENABLE_WINDOW_LATCH(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_WLATEN_Msk)
/**
* @brief This macro is used to disable ACMP window latch mode
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear WLATEN (ACMP_CTL[17]) to disable ACMP window latch mode.
* \hideinitializer
*/
#define ACMP_DISABLE_WINDOW_LATCH(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_WLATEN_Msk)
/**
* @brief This macro is used to enable ACMP window compare mode
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will set WCMPSEL (ACMP_CTL[18]) to enable ACMP window compare mode.
* When window compare mode is enabled, user can connect the specific analog voltage
* source to either the positive inputs of both comparators or the negative inputs of
* both comparators. The upper bound and lower bound of the designated range are
* determined by the voltages applied to the other inputs of both comparators. If the
* output of a comparator is low and the other comparator outputs high, which means two
* comparators implies the upper and lower bound. User can directly monitor a specific
* analog voltage source via ACMPWO (ACMP_STATUS[16]).
* \hideinitializer
*/
#define ACMP_ENABLE_WINDOW_COMPARE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] |= ACMP_CTL_WCMPSEL_Msk)
/**
* @brief This macro is used to disable ACMP window compare mode
* @param[in] acmp The pointer of the specified ACMP module
* @param[in] u32ChNum The ACMP number
* @return None
* @details This macro will clear WCMPSEL (ACMP_CTL[18]) to disable ACMP window compare mode.
* \hideinitializer
*/
#define ACMP_DISABLE_WINDOW_COMPARE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)] &= ~ACMP_CTL_WCMPSEL_Msk)
/* Function prototype declaration */
void ACMP_Open(ACMP_T *acmp, uint32_t u32ChNum, uint32_t u32NegSrc, uint32_t u32HysSel);
void ACMP_Close(ACMP_T *acmp, uint32_t u32ChNum);
/*@}*/ /* end of group ACMP_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group ACMP_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __ACMP_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,376 @@
/******************************************************************************
* @file bpwm.h
* @version V0.10
* @brief M251 series BPWM driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __BPWM_H__
#define __BPWM_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup BPWM_Driver BPWM Driver
@{
*/
/** @addtogroup BPWM_EXPORTED_CONSTANTS BPWM Exported Constants
@{
*/
#define BPWM_CHANNEL_NUM (6UL) /*!< BPWM channel number */
#define BPWM_CH_0_MASK (0x1UL) /*!< BPWM channel 0 mask */
#define BPWM_CH_1_MASK (0x2UL) /*!< BPWM channel 1 mask */
#define BPWM_CH_2_MASK (0x4UL) /*!< BPWM channel 2 mask */
#define BPWM_CH_3_MASK (0x8UL) /*!< BPWM channel 3 mask */
#define BPWM_CH_4_MASK (0x10UL) /*!< BPWM channel 4 mask */
#define BPWM_CH_5_MASK (0x20UL) /*!< BPWM channel 5 mask */
/*---------------------------------------------------------------------------------------------------------*/
/* Counter Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_UP_COUNTER (0UL) /*!< Up counter type */
#define BPWM_DOWN_COUNTER (1UL) /*!< Down counter type */
#define BPWM_UP_DOWN_COUNTER (2UL) /*!< Up-Down counter type */
/*---------------------------------------------------------------------------------------------------------*/
/* Aligned Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_EDGE_ALIGNED (1UL) /*!< BPWM working in edge aligned type(down count) */
#define BPWM_CENTER_ALIGNED (2UL) /*!< BPWM working in center aligned type */
/*---------------------------------------------------------------------------------------------------------*/
/* Output Level Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_OUTPUT_NOTHING (0UL) /*!< BPWM output nothing */
#define BPWM_OUTPUT_LOW (1UL) /*!< BPWM output low */
#define BPWM_OUTPUT_HIGH (2UL) /*!< BPWM output high */
#define BPWM_OUTPUT_TOGGLE (3UL) /*!< BPWM output toggle */
/*---------------------------------------------------------------------------------------------------------*/
/* Synchronous Start Function Control Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_SSCTL_SSRC_PWM0 (0UL<<BPWM_SSCTL_SSRC_Pos) /*!< Synchronous start source comes from BPWM0 */
#define BPWM_SSCTL_SSRC_PWM1 (1UL<<BPWM_SSCTL_SSRC_Pos) /*!< Synchronous start source comes from BPWM1 */
#define BPWM_SSCTL_SSRC_BPWM0 (2UL<<BPWM_SSCTL_SSRC_Pos) /*!< Synchronous start source comes from PWM0 */
#define BPWM_SSCTL_SSRC_BPWM1 (3UL<<BPWM_SSCTL_SSRC_Pos) /*!< Synchronous start source comes from PWM1 */
/*---------------------------------------------------------------------------------------------------------*/
/* Trigger Source Select Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_TRIGGER_ADC_EVEN_ZERO_POINT (0UL) /*!< BPWM trigger ADC while counter of even channel matches zero point */
#define BPWM_TRIGGER_ADC_EVEN_PERIOD_POINT (1UL) /*!< BPWM trigger ADC while counter of even channel matches period point */
#define BPWM_TRIGGER_ADC_EVEN_ZERO_OR_PERIOD_POINT (2UL) /*!< BPWM trigger ADC while counter of even channel matches zero or period point */
#define BPWM_TRIGGER_ADC_EVEN_CMP_UP_COUNT_POINT (3UL) /*!< BPWM trigger ADC while counter of even channel matches up count to comparator point */
#define BPWM_TRIGGER_ADC_EVEN_CMP_DOWN_COUNT_POINT (4UL) /*!< BPWM trigger ADC while counter of even channel matches down count to comparator point */
#define BPWM_TRIGGER_ADC_ODD_CMP_UP_COUNT_POINT (8UL) /*!< BPWM trigger ADC while counter of odd channel matches up count to comparator point */
#define BPWM_TRIGGER_ADC_ODD_CMP_DOWN_COUNT_POINT (9UL) /*!< BPWM trigger ADC while counter of odd channel matches down count to comparator point */
/*---------------------------------------------------------------------------------------------------------*/
/* Capture Control Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_CAPTURE_INT_RISING_LATCH (1UL) /*!< BPWM capture interrupt if channel has rising transition */
#define BPWM_CAPTURE_INT_FALLING_LATCH (0x100UL) /*!< BPWM capture interrupt if channel has falling transition */
/*---------------------------------------------------------------------------------------------------------*/
/* Duty Interrupt Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_DUTY_INT_DOWN_COUNT_MATCH_CMP (BPWM_INTEN_CMPDIEN0_Msk) /*!< BPWM duty interrupt triggered if down count match comparator */
#define BPWM_DUTY_INT_UP_COUNT_MATCH_CMP (BPWM_INTEN_CMPUIEN0_Msk) /*!< BPWM duty interrupt triggered if up down match comparator */
/*---------------------------------------------------------------------------------------------------------*/
/* Load Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_LOAD_MODE_IMMEDIATE (BPWM_CTL0_IMMLDEN0_Msk) /*!< BPWM immediately load mode */
#define BPWM_LOAD_MODE_CENTER (BPWM_CTL0_CTRLD0_Msk) /*!< BPWM center load mode */
/*---------------------------------------------------------------------------------------------------------*/
/* Clock Source Select Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define BPWM_CLKSRC_BPWM_CLK (0UL) /*!< BPWM Clock source selects to BPWM0_CLK or BPWM1_CLK */
#define BPWM_CLKSRC_TIMER0 (1UL) /*!< BPWM Clock source selects to TIMER0 overflow */
#define BPWM_CLKSRC_TIMER1 (2UL) /*!< BPWM Clock source selects to TIMER1 overflow */
#define BPWM_CLKSRC_TIMER2 (3UL) /*!< BPWM Clock source selects to TIMER2 overflow */
#define BPWM_CLKSRC_TIMER3 (4UL) /*!< BPWM Clock source selects to TIMER3 overflow */
/*@}*/ /* end of group BPWM_EXPORTED_CONSTANTS */
/** @addtogroup BPWM_EXPORTED_FUNCTIONS BPWM Exported Functions
@{
*/
/**
* @brief Enable timer synchronous start counting function of specified channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @param[in] u32SyncSrc Synchronous start source selection, valid values are:
* - \ref BPWM_SSCTL_SSRC_PWM0
* - \ref BPWM_SSCTL_SSRC_PWM1
* - \ref BPWM_SSCTL_SSRC_BPWM0
* - \ref BPWM_SSCTL_SSRC_BPWM1
* @return None
* @details This macro is used to enable timer synchronous start counting function of specified channel(s).
* @note All channels share channel 0's setting.
* \hideinitializer
*/
#define BPWM_ENABLE_TIMER_SYNC(bpwm, u32ChannelMask, u32SyncSrc) ((bpwm)->SSCTL = ((bpwm)->SSCTL & ~BPWM_SSCTL_SSRC_Msk) | (u32SyncSrc) | BPWM_SSCTL_SSEN0_Msk)
/**
* @brief Disable timer synchronous start counting function of specified channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This macro is used to disable timer synchronous start counting function of specified channel(s).
* @note All channels share channel 0's setting.
* \hideinitializer
*/
#define BPWM_DISABLE_TIMER_SYNC(bpwm, u32ChannelMask) ((bpwm)->SSCTL &= ~BPWM_SSCTL_SSEN0_Msk)
/**
* @brief This macro enable BPWM counter synchronous start counting function.
* @param[in] bpwm The pointer of the specified BPWM module
* @return None
* @details This macro is used to make selected BPWM0 and BPWM1 channel(s) start counting at the same time.
* To configure synchronous start counting channel(s) by BPWM_ENABLE_TIMER_SYNC() and BPWM_DISABLE_TIMER_SYNC().
* \hideinitializer
*/
#define BPWM_TRIGGER_SYNC_START(bpwm) ((bpwm)->SSTRG = BPWM_SSTRG_CNTSEN_Msk)
/**
* @brief This macro enable output inverter of specified channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* @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
* \hideinitializer
*/
#define BPWM_ENABLE_OUTPUT_INVERTER(bpwm, u32ChannelMask) ((bpwm)->POLCTL = (u32ChannelMask))
/**
* @brief This macro get captured rising data
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return None
* \hideinitializer
*/
#define BPWM_GET_CAPTURE_RISING_DATA(bpwm, u32ChannelNum) ((bpwm)->CAPDAT[(u32ChannelNum)].RCAPDAT)
/**
* @brief This macro get captured falling data
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return None
* \hideinitializer
*/
#define BPWM_GET_CAPTURE_FALLING_DATA(bpwm, u32ChannelNum) ((bpwm)->CAPDAT[(u32ChannelNum)].FCAPDAT)
/**
* @brief This macro mask output logic to high or low
* @param[in] bpwm The pointer of the specified BPWM module
* @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] u32LevelMask Output logic to high or low
* @return None
* @details This macro is used to mask output logic to high or low of specified channel(s).
* @note If u32ChannelMask parameter is 0, then mask function will be disabled.
* \hideinitializer
*/
#define BPWM_MASK_OUTPUT(bpwm, u32ChannelMask, u32LevelMask) \
{ \
(bpwm)->MSKEN = (u32ChannelMask); \
(bpwm)->MSK = (u32LevelMask); \
}
/**
* @brief This macro set the prescaler of all channels
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @param[in] u32Prescaler Clock prescaler of specified channel. Valid values are between 1 ~ 0xFFF
* @return None
* \hideinitializer
*/
#define BPWM_SET_PRESCALER(bpwm, u32ChannelNum, u32Prescaler) ((bpwm)->CLKPSC = (u32Prescaler))
/**
* @brief This macro get the prescaler of the selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5. This parameter is not used.
* @return Return Clock prescaler of specified channel. Valid values are between 0 ~ 0xFFF
* @details This macro is used to get the prescaler of specified channel.
* @note All channels share channel 0's setting.
* The clock of BPWM counter is divided by (u32Prescaler + 1).
* \hideinitializer
*/
#define BPWM_GET_PRESCALER(bpwm, u32ChannelNum) (bpwm)->CLKPSC
/**
* @brief This macro set the duty of the selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32CMR Duty of specified channel. Valid values are between 0~0xFFFF
* @return None
* @note This new setting will take effect on next BPWM period
* \hideinitializer
*/
#define BPWM_SET_CMR(bpwm, u32ChannelNum, u32CMR) ((bpwm)->CMPDAT[(u32ChannelNum)] = (u32CMR))
/**
* @brief This macro get the duty of the selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return Return the duty of specified channel. Valid values are between 0~0xFFFF
* @details This macro is used to get the duty of specified channel.
* \hideinitializer
*/
#define BPWM_GET_CMR(bpwm, u32ChannelNum) ((bpwm)->CMPDAT[(u32ChannelNum)])
/**
* @brief This macro set the period of all channels
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @param[in] u32CNR Period of specified channel. Valid values are between 0~0xFFFF
* @return None
* @note This new setting will take effect on next BPWM period
* @note BPWM counter will stop if period length set to 0
* \hideinitializer
*/
#define BPWM_SET_CNR(bpwm, u32ChannelNum, u32CNR) ((bpwm)->PERIOD = (u32CNR))
/**
* @brief This macro get the period of all channels
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return Return the period of specified channel.
* @details This macro is used to get the period of specified channel.
* \hideinitializer
*/
#define BPWM_GET_CNR(bpwm, u32ChannelNum) ((bpwm)->PERIOD)
/**
* @brief This macro set the BPWM aligned type
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @param[in] u32AlignedType BPWM aligned type, valid values are:
* - \ref BPWM_UP_COUNTER
* - \ref BPWM_DOWN_COUNTER
* - \ref BPWM_UP_DOWN_COUNTER
* @return None
* @note All channels share channel 0's setting.
* \hideinitializer
*/
#define BPWM_SET_ALIGNED_TYPE(bpwm, u32ChannelMask, u32AlignedType) ((bpwm)->CTL1 = (u32AlignedType))
/**
* @brief Clear counter of channel 0
* @param[in] bpwm The pointer of the specified BPWM module
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This macro is used to clear counter of channel 0
* \hideinitializer
*/
#define BPWM_CLR_COUNTER(bpwm, u32ChannelMask) ((bpwm)->CNTCLR = (BPWM_CNTCLR_CNTCLR0_Msk))
/**
* @brief Set output level at zero, compare up, period(center) and compare down of specified channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* @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] u32ZeroLevel output level at zero point, valid values are:
* - \ref BPWM_OUTPUT_NOTHING
* - \ref BPWM_OUTPUT_LOW
* - \ref BPWM_OUTPUT_HIGH
* - \ref BPWM_OUTPUT_TOGGLE
* @param[in] u32CmpUpLevel output level at compare up point, valid values are:
* - \ref BPWM_OUTPUT_NOTHING
* - \ref BPWM_OUTPUT_LOW
* - \ref BPWM_OUTPUT_HIGH
* - \ref BPWM_OUTPUT_TOGGLE
* @param[in] u32PeriodLevel output level at period(center) point, valid values are:
* - \ref BPWM_OUTPUT_NOTHING
* - \ref BPWM_OUTPUT_LOW
* - \ref BPWM_OUTPUT_HIGH
* - \ref BPWM_OUTPUT_TOGGLE
* @param[in] u32CmpDownLevel output level at compare down point, valid values are:
* - \ref BPWM_OUTPUT_NOTHING
* - \ref BPWM_OUTPUT_LOW
* - \ref BPWM_OUTPUT_HIGH
* - \ref BPWM_OUTPUT_TOGGLE
* @return None
* @details This macro is used to Set output level at zero, compare up, period(center) and compare down of specified channel(s)
* \hideinitializer
*/
#define BPWM_SET_OUTPUT_LEVEL(bpwm, u32ChannelMask, u32ZeroLevel, u32CmpUpLevel, u32PeriodLevel, u32CmpDownLevel) \
do{ \
uint32_t i; \
for(i = 0UL; i < 6UL; i++) { \
if((u32ChannelMask) & (1UL << i)) { \
(bpwm)->WGCTL0 = (((bpwm)->WGCTL0 & ~(3UL << (i << 1UL))) | ((u32ZeroLevel) << (i << 1UL))); \
(bpwm)->WGCTL0 = (((bpwm)->WGCTL0 & ~(3UL << (BPWM_WGCTL0_PRDPCTL0_Pos + (i << 1UL)))) | ((u32PeriodLevel) << (BPWM_WGCTL0_PRDPCTL0_Pos + (i << 1UL)))); \
(bpwm)->WGCTL1 = (((bpwm)->WGCTL1 & ~(3UL << (i << 1UL))) | ((u32CmpUpLevel) << (i << 1UL))); \
(bpwm)->WGCTL1 = (((bpwm)->WGCTL1 & ~(3UL << (BPWM_WGCTL1_CMPDCTL0_Pos + (i << 1UL)))) | ((u32CmpDownLevel) << (BPWM_WGCTL1_CMPDCTL0_Pos + (i << 1UL)))); \
} \
} \
}while(0)
/*---------------------------------------------------------------------------------------------------------*/
/* Define BPWM functions prototype */
/*---------------------------------------------------------------------------------------------------------*/
uint32_t BPWM_ConfigCaptureChannel(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32UnitTimeNsec, uint32_t u32CaptureEdge);
uint32_t BPWM_ConfigOutputChannel(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Frequency, uint32_t u32DutyCycle);
void BPWM_Start(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_Stop(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_ForceStop(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_EnableADCTrigger(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Condition);
void BPWM_DisableADCTrigger(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_ClearADCTriggerFlag(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Condition);
uint32_t BPWM_GetADCTriggerFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_EnableCapture(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_DisableCapture(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_EnableOutput(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_DisableOutput(BPWM_T *bpwm, uint32_t u32ChannelMask);
void BPWM_EnableCaptureInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge);
void BPWM_DisableCaptureInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge);
void BPWM_ClearCaptureIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge);
uint32_t BPWM_GetCaptureIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_EnableDutyInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType);
void BPWM_DisableDutyInt(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_ClearDutyIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
uint32_t BPWM_GetDutyIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_EnablePeriodInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType);
void BPWM_DisablePeriodInt(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_ClearPeriodIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
uint32_t BPWM_GetPeriodIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_EnableZeroInt(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_DisableZeroInt(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_ClearZeroIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
uint32_t BPWM_GetZeroIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_EnableLoadMode(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32LoadMode);
void BPWM_DisableLoadMode(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32LoadMode);
void BPWM_SetClockSource(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32ClkSrcSel);
uint32_t BPWM_GetWrapAroundFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
void BPWM_ClearWrapAroundFlag(BPWM_T *bpwm, uint32_t u32ChannelNum);
/*@}*/ /* end of group BPWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group BPWM_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __BPWM_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,627 @@
/****************************************************************************
* @file clk.h
* @version V1.10
* @brief M251 series CLK driver source file
*
* @copyright (C) 2018 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_4MHZ 4000000UL
#define FREQ_8MHZ 8000000UL
#define FREQ_16MHZ 16000000UL
#define FREQ_25MHZ 25000000UL
#define FREQ_32MHZ 32000000UL
#define FREQ_48MHZ 48000000UL
#define FREQ_50MHZ 50000000UL
#define FREQ_64MHZ 64000000UL
#define FREQ_72MHZ 72000000UL
#define FREQ_96MHZ 96000000UL
#define FREQ_100MHZ 100000000UL
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL0 constant definitions. (Write-protection) */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL0_HCLKSEL_HXT (0x00UL<<CLK_CLKSEL0_HCLKSEL_Pos) /*!< Setting clock source as external X'tal */
#define CLK_CLKSEL0_HCLKSEL_LXT (0x01UL<<CLK_CLKSEL0_HCLKSEL_Pos) /*!< Setting clock source as external X'tal 32.768KHz*/
#define CLK_CLKSEL0_HCLKSEL_PLL (0x02UL<<CLK_CLKSEL0_HCLKSEL_Pos) /*!< Setting clock source as PLL output */
#define CLK_CLKSEL0_HCLKSEL_LIRC (0x03UL<<CLK_CLKSEL0_HCLKSEL_Pos) /*!< Setting clock source as internal 10KHz RC clock */
#define CLK_CLKSEL0_HCLKSEL_MIRC (0x05UL<<CLK_CLKSEL0_HCLKSEL_Pos) /*!< Setting clock source as USBPLL clock */
#define CLK_CLKSEL0_HCLKSEL_HIRC (0x07UL<<CLK_CLKSEL0_HCLKSEL_Pos) /*!< Setting clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL0_STCLKSEL_HXT (0x00UL<<CLK_CLKSEL0_STCLKSEL_Pos) /*!< Setting clock source as external X'tal */
#define CLK_CLKSEL0_STCLKSEL_LXT (0x01UL<<CLK_CLKSEL0_STCLKSEL_Pos) /*!< Setting clock source as external X'tal 32.768KHz*/
#define CLK_CLKSEL0_STCLKSEL_HXT_DIV2 (0x02UL<<CLK_CLKSEL0_STCLKSEL_Pos) /*!< Setting clock source as external X'tal/2 */
#define CLK_CLKSEL0_STCLKSEL_HCLK_DIV2 (0x03UL<<CLK_CLKSEL0_STCLKSEL_Pos) /*!< Setting clock source as HCLK/2 */
#define CLK_CLKSEL0_STCLKSEL_HIRC_DIV2 (0x07UL<<CLK_CLKSEL0_STCLKSEL_Pos) /*!< Setting clock source as internal 22.1184MHz RC clock/2 */
#define SysTick_CTRL_STCLKSEL_HCLK (0x01UL<<SysTick_CTRL_CLKSOURCE_Pos) /*!< Setting SysTick clock source as HCLK */
#define CLK_CLKSEL0_STCLKSEL_HCLK SysTick_CTRL_STCLKSEL_HCLK /*!< Setting SysTick clock source as HCLK (Backward compatible) */
#define CLK_CLKSEL0_USBDSEL_HIRC (0x00UL<<CLK_CLKSEL0_USBDSEL_Pos) /*!< Setting clock source as external X'tal */
#define CLK_CLKSEL0_USBDSEL_PLL (0x01UL<<CLK_CLKSEL0_USBDSEL_Pos) /*!< Setting clock source as external X'tal 32.768KHz*/
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL1 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL1_WDTSEL_LXT (0x1UL<<CLK_CLKSEL1_WDTSEL_Pos) /*!< Setting WDT clock source as external X'tal 32.768KHz*/
#define CLK_CLKSEL1_WDTSEL_HCLK_DIV2048 (0x2UL<<CLK_CLKSEL1_WDTSEL_Pos) /*!< Setting WDT clock source as HCLK/2048 */
#define CLK_CLKSEL1_WDTSEL_LIRC (0x3UL<<CLK_CLKSEL1_WDTSEL_Pos) /*!< Setting WDT clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_WWDTSEL_HCLK_DIV2048 (0x2UL<<CLK_CLKSEL1_WWDTSEL_Pos) /*!< Setting WDT clock source as HCLK/2048 */
#define CLK_CLKSEL1_WWDTSEL_LIRC (0x3UL<<CLK_CLKSEL1_WWDTSEL_Pos) /*!< Setting WDT clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_CLKOSEL_HXT (0x0UL<<CLK_CLKSEL1_CLKOSEL_Pos) /*!< Setting CLKO clock source as external X'tal */
#define CLK_CLKSEL1_CLKOSEL_LXT (0x1UL<<CLK_CLKSEL1_CLKOSEL_Pos) /*!< Setting CLKO clock source as external X'tal 32.768KHz */
#define CLK_CLKSEL1_CLKOSEL_HCLK (0x2UL<<CLK_CLKSEL1_CLKOSEL_Pos) /*!< Setting CLKO clock source as HCLK */
#define CLK_CLKSEL1_CLKOSEL_HIRC (0x3UL<<CLK_CLKSEL1_CLKOSEL_Pos) /*!< Setting CLKO clock source as external internal 48MHz RC clock */
#define CLK_CLKSEL1_CLKOSEL_LIRC (0x4UL<<CLK_CLKSEL1_CLKOSEL_Pos) /*!< Setting CLKO clock source as external internal 32.768KHz RC clock */
#define CLK_CLKSEL1_CLKOSEL_MIRC (0x5UL<<CLK_CLKSEL1_CLKOSEL_Pos) /*!< Setting CLKO clock source as external internal 4.032MHz RC clock */
#define CLK_CLKSEL1_CLKOSEL_PLL (0x6UL<<CLK_CLKSEL1_CLKOSEL_Pos) /*!< Setting CLKO clock source as PLL */
#define CLK_CLKSEL1_CLKOSEL_SOF (0x7UL<<CLK_CLKSEL1_CLKOSEL_Pos) /*!< Setting CLKO clock source as USB SOF 1kHz */
#define CLK_CLKSEL1_TMR0SEL_HXT (0x0UL<<CLK_CLKSEL1_TMR0SEL_Pos) /*!< Setting Timer 0 clock source as external X'tal */
#define CLK_CLKSEL1_TMR0SEL_LXT (0x1UL<<CLK_CLKSEL1_TMR0SEL_Pos) /*!< Setting Timer 0 clock source as external X'tal 32.768KHz */
#define CLK_CLKSEL1_TMR0SEL_PCLK0 (0x2UL<<CLK_CLKSEL1_TMR0SEL_Pos) /*!< Setting Timer 0 clock source as PCLK */
#define CLK_CLKSEL1_TMR0SEL_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR0SEL_Pos) /*!< Setting Timer 0 clock source as external trigger */
#define CLK_CLKSEL1_TMR0SEL_LIRC (0x5UL<<CLK_CLKSEL1_TMR0SEL_Pos) /*!< Setting Timer 0 clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_TMR0SEL_HIRC (0x7UL<<CLK_CLKSEL1_TMR0SEL_Pos) /*!< Setting Timer 0 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL1_TMR1SEL_HXT (0x0UL<<CLK_CLKSEL1_TMR1SEL_Pos) /*!< Setting Timer 0 clock source as external X'tal */
#define CLK_CLKSEL1_TMR1SEL_LXT (0x1UL<<CLK_CLKSEL1_TMR1SEL_Pos) /*!< Setting Timer 0 clock source as external X'tal 32.768KHz */
#define CLK_CLKSEL1_TMR1SEL_PCLK0 (0x2UL<<CLK_CLKSEL1_TMR1SEL_Pos) /*!< Setting Timer 0 clock source as PCLK */
#define CLK_CLKSEL1_TMR1SEL_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR1SEL_Pos) /*!< Setting Timer 0 clock source as external trigger */
#define CLK_CLKSEL1_TMR1SEL_LIRC (0x5UL<<CLK_CLKSEL1_TMR1SEL_Pos) /*!< Setting Timer 0 clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_TMR1SEL_HIRC (0x7UL<<CLK_CLKSEL1_TMR1SEL_Pos) /*!< Setting Timer 0 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL1_TMR2SEL_HXT (0x0UL<<CLK_CLKSEL1_TMR2SEL_Pos) /*!< Setting Timer 0 clock source as external X'tal */
#define CLK_CLKSEL1_TMR2SEL_LXT (0x1UL<<CLK_CLKSEL1_TMR2SEL_Pos) /*!< Setting Timer 0 clock source as external X'tal 32.768KHz */
#define CLK_CLKSEL1_TMR2SEL_PCLK1 (0x2UL<<CLK_CLKSEL1_TMR2SEL_Pos) /*!< Setting Timer 0 clock source as PCLK */
#define CLK_CLKSEL1_TMR2SEL_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR2SEL_Pos) /*!< Setting Timer 0 clock source as external trigger */
#define CLK_CLKSEL1_TMR2SEL_LIRC (0x5UL<<CLK_CLKSEL1_TMR2SEL_Pos) /*!< Setting Timer 0 clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_TMR2SEL_HIRC (0x7UL<<CLK_CLKSEL1_TMR2SEL_Pos) /*!< Setting Timer 0 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL1_TMR3SEL_HXT (0x0UL<<CLK_CLKSEL1_TMR3SEL_Pos) /*!< Setting Timer 0 clock source as external X'tal */
#define CLK_CLKSEL1_TMR3SEL_LXT (0x1UL<<CLK_CLKSEL1_TMR3SEL_Pos) /*!< Setting Timer 0 clock source as external X'tal 32.768KHz */
#define CLK_CLKSEL1_TMR3SEL_PCLK1 (0x2UL<<CLK_CLKSEL1_TMR3SEL_Pos) /*!< Setting Timer 0 clock source as PCLK */
#define CLK_CLKSEL1_TMR3SEL_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR3SEL_Pos) /*!< Setting Timer 0 clock source as external trigger */
#define CLK_CLKSEL1_TMR3SEL_LIRC (0x5UL<<CLK_CLKSEL1_TMR3SEL_Pos) /*!< Setting Timer 0 clock source as internal 10KHz RC clock */
#define CLK_CLKSEL1_TMR3SEL_HIRC (0x7UL<<CLK_CLKSEL1_TMR3SEL_Pos) /*!< Setting Timer 0 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL1_UART0SEL_HXT (0x0UL<<CLK_CLKSEL1_UART0SEL_Pos) /*!< Setting UART0 clock source as external X'tal */
#define CLK_CLKSEL1_UART0SEL_PLL (0x1UL<<CLK_CLKSEL1_UART0SEL_Pos) /*!< Setting UART0 clock source as external PLL */
#define CLK_CLKSEL1_UART0SEL_LXT (0x2UL<<CLK_CLKSEL1_UART0SEL_Pos) /*!< Setting UART0 clock source as external X'tal */
#define CLK_CLKSEL1_UART0SEL_HIRC (0x3UL<<CLK_CLKSEL1_UART0SEL_Pos) /*!< Setting UART0 clock source as external internal 48MHz RC clock */
#define CLK_CLKSEL1_UART0SEL_PCLK0 (0x4UL<<CLK_CLKSEL1_UART0SEL_Pos) /*!< Setting UART0 clock source as external PCLK */
#define CLK_CLKSEL1_UART0SEL_LIRC (0x5UL<<CLK_CLKSEL1_UART0SEL_Pos) /*!< Setting UART0 clock source as external internal 38.4KHz RC clock */
#define CLK_CLKSEL1_UART1SEL_HXT (0x0UL<<CLK_CLKSEL1_UART1SEL_Pos) /*!< Setting UART1 clock source as external X'tal */
#define CLK_CLKSEL1_UART1SEL_PLL (0x1UL<<CLK_CLKSEL1_UART1SEL_Pos) /*!< Setting UART1 clock source as external PLL */
#define CLK_CLKSEL1_UART1SEL_LXT (0x2UL<<CLK_CLKSEL1_UART1SEL_Pos) /*!< Setting UART1 clock source as external X'tal */
#define CLK_CLKSEL1_UART1SEL_HIRC (0x3UL<<CLK_CLKSEL1_UART1SEL_Pos) /*!< Setting UART1 clock source as external internal 48MHz RC clock */
#define CLK_CLKSEL1_UART1SEL_PCLK1 (0x4UL<<CLK_CLKSEL1_UART1SEL_Pos) /*!< Setting UART1 clock source as external PCLK */
#define CLK_CLKSEL1_UART1SEL_LIRC (0x5UL<<CLK_CLKSEL1_UART1SEL_Pos) /*!< Setting UART1 clock source as external internal 38.4KHz RC clock */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL2 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL2_PWM0SEL_PLL (0x0UL<<CLK_CLKSEL2_PWM0SEL_Pos) /*!< Setting PWM0 and PWM1 clock source as external X'tal */
#define CLK_CLKSEL2_PWM0SEL_PCLK0 (0x1UL<<CLK_CLKSEL2_PWM0SEL_Pos) /*!< Setting PWM0 and PWM1 clock source as PCLK */
#define CLK_CLKSEL2_PWM1SEL_PLL (0x0UL<<CLK_CLKSEL2_PWM1SEL_Pos) /*!< Setting PWM0 and PWM1 clock source as external X'tal */
#define CLK_CLKSEL2_PWM1SEL_PCLK1 (0x1UL<<CLK_CLKSEL2_PWM1SEL_Pos) /*!< Setting PWM0 and PWM1 clock source as PCLK */
#define CLK_CLKSEL2_QSPI0SEL_HXT (0x0UL<<CLK_CLKSEL2_QSPI0SEL_Pos) /*!< Setting SPI clock source as HXT */
#define CLK_CLKSEL2_QSPI0SEL_PLL (0x1UL<<CLK_CLKSEL2_QSPI0SEL_Pos) /*!< Setting SPI clock source as PLL */
#define CLK_CLKSEL2_QSPI0SEL_PCLK0 (0x2UL<<CLK_CLKSEL2_QSPI0SEL_Pos) /*!< Setting SPI clock source as PCLK0 */
#define CLK_CLKSEL2_QSPI0SEL_HIRC (0x3UL<<CLK_CLKSEL2_QSPI0SEL_Pos) /*!< Setting SPI clock source as HIRC */
#define CLK_CLKSEL2_SPI0SEL_HXT (0x0UL<<CLK_CLKSEL2_SPI0SEL_Pos) /*!< Setting SPI clock source as HXT */
#define CLK_CLKSEL2_SPI0SEL_PLL (0x1UL<<CLK_CLKSEL2_SPI0SEL_Pos) /*!< Setting SPI clock source as PLL */
#define CLK_CLKSEL2_SPI0SEL_PCLK1 (0x2UL<<CLK_CLKSEL2_SPI0SEL_Pos) /*!< Setting SPI clock source as PCLK0 */
#define CLK_CLKSEL2_SPI0SEL_HIRC (0x3UL<<CLK_CLKSEL2_SPI0SEL_Pos) /*!< Setting SPI clock source as HIRC */
#define CLK_CLKSEL2_BPWM0SEL_PLL (0x0UL<<CLK_CLKSEL2_BPWM0SEL_Pos) /*!< Setting PWM0 and PWM1 clock source as external X'tal */
#define CLK_CLKSEL2_BPWM0SEL_PCLK0 (0x1UL<<CLK_CLKSEL2_BPWM0SEL_Pos) /*!< Setting PWM0 and PWM1 clock source as PCLK */
#define CLK_CLKSEL2_BPWM1SEL_PLL (0x0UL<<CLK_CLKSEL2_BPWM1SEL_Pos) /*!< Setting PWM0 and PWM1 clock source as external X'tal */
#define CLK_CLKSEL2_BPWM1SEL_PCLK1 (0x1UL<<CLK_CLKSEL2_BPWM1SEL_Pos) /*!< Setting PWM0 and PWM1 clock source as PCLK */
#define CLK_CLKSEL2_PSIOSEL_HXT (0x0UL<<CLK_CLKSEL2_PSIOSEL_Pos)
#define CLK_CLKSEL2_PSIOSEL_LXT (0x1UL<<CLK_CLKSEL2_PSIOSEL_Pos)
#define CLK_CLKSEL2_PSIOSEL_PCLK1 (0x2UL<<CLK_CLKSEL2_PSIOSEL_Pos)
#define CLK_CLKSEL2_PSIOSEL_PLL (0x3UL<<CLK_CLKSEL2_PSIOSEL_Pos)
#define CLK_CLKSEL2_PSIOSEL_LIRC (0x4UL<<CLK_CLKSEL2_PSIOSEL_Pos)
#define CLK_CLKSEL2_PSIOSEL_HIRC (0x7UL<<CLK_CLKSEL2_PSIOSEL_Pos)
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL3 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL3_SC0SEL_HXT (0x0UL<<CLK_CLKSEL3_SC0SEL_Pos) /*!< Setting SC0 clock source as external X'tal */
#define CLK_CLKSEL3_SC0SEL_PLL (0x1UL<<CLK_CLKSEL3_SC0SEL_Pos) /*!< Setting SC0 clock source as PLL */
#define CLK_CLKSEL3_SC0SEL_PCLK0 (0x2UL<<CLK_CLKSEL3_SC0SEL_Pos) /*!< Setting SC0 clock source as PCLK */
#define CLK_CLKSEL3_SC0SEL_HIRC (0x3UL<<CLK_CLKSEL3_SC0SEL_Pos) /*!< Setting SC0 clock source as internal 22.1184MHz RC clock */
#define CLK_CLKSEL3_UART2SEL_HXT (0x0UL<<CLK_CLKSEL3_UART2SEL_Pos) /*!< Setting UART2 clock source as external X'tal */
#define CLK_CLKSEL3_UART2SEL_PLL (0x1UL<<CLK_CLKSEL3_UART2SEL_Pos) /*!< Setting UART2 clock source as external PLL */
#define CLK_CLKSEL3_UART2SEL_LXT (0x2UL<<CLK_CLKSEL3_UART2SEL_Pos) /*!< Setting UART2 clock source as external X'tal */
#define CLK_CLKSEL3_UART2SEL_HIRC (0x3UL<<CLK_CLKSEL3_UART2SEL_Pos) /*!< Setting UART2 clock source as external internal 48MHz RC clock */
#define CLK_CLKSEL3_UART2SEL_PCLK0 (0x4UL<<CLK_CLKSEL3_UART2SEL_Pos) /*!< Setting UART2 clock source as external PCLK */
#define CLK_CLKSEL3_UART2SEL_LIRC (0x5UL<<CLK_CLKSEL3_UART2SEL_Pos) /*!< Setting UART2 clock source as external internal 38.4KHz RC clock */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKDIV0 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKDIV0_HCLK(x) (((x)-1) << CLK_CLKDIV0_HCLKDIV_Pos) /*!< CLKDIV Setting for HCLK clock divider. It could be 1~16 */
#define CLK_CLKDIV0_USB(x) (((x)-1) << CLK_CLKDIV0_USBDIV_Pos) /*!< CLKDIV Setting for USB clock divider. It could be 1~16, has to be 1 or even */
#define CLK_CLKDIV0_UART0(x) (((x)-1) << CLK_CLKDIV0_UART0DIV_Pos) /*!< CLKDIV Setting for UART clock divider. It could be 1~16 */
#define CLK_CLKDIV0_UART1(x) (((x)-1) << CLK_CLKDIV0_UART1DIV_Pos) /*!< CLKDIV Setting for UART clock divider. It could be 1~16 */
#define CLK_CLKDIV0_EADC(x) (((x)-1) << CLK_CLKDIV0_EADCDIV_Pos) /*!< CLKDIV Setting for EADC clock divider. It could be 1~256 */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKDIV1 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKDIV1_SC0(x) (((x)-1) << CLK_CLKDIV1_SC0DIV_Pos) /*!< CLKDIV Setting for SC0 clock divider. It could be 1~256 */
#define CLK_CLKDIV1_PSIO(x) (((x)-1) << CLK_CLKDIV1_PSIODIV_Pos)/*!< CLKDIV Setting for PSIO clock divider. It could be 1~256 */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKDIV4 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKDIV4_UART2(x) (((x)-1) << CLK_CLKDIV4_UART2DIV_Pos) /*!< CLKDIV Setting for UART clock divider. It could be 1~16 */
/*---------------------------------------------------------------------------------------------------------*/
/* PCLKDIV constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_PCLKDIV_APB0DIV_DIV1 (0x0UL<<CLK_PCLKDIV_APB0DIV_Pos)
#define CLK_PCLKDIV_APB0DIV_DIV2 (0x1UL<<CLK_PCLKDIV_APB0DIV_Pos)
#define CLK_PCLKDIV_APB0DIV_DIV4 (0x2UL<<CLK_PCLKDIV_APB0DIV_Pos)
#define CLK_PCLKDIV_APB0DIV_DIV8 (0x3UL<<CLK_PCLKDIV_APB0DIV_Pos)
#define CLK_PCLKDIV_APB0DIV_DIV16 (0x4UL<<CLK_PCLKDIV_APB0DIV_Pos)
#define CLK_PCLKDIV_APB0DIV_DIV32 (0x5UL<<CLK_PCLKDIV_APB0DIV_Pos)
#define CLK_PCLKDIV_APB1DIV_DIV1 (0x0UL<<CLK_PCLKDIV_APB1DIV_Pos)
#define CLK_PCLKDIV_APB1DIV_DIV2 (0x1UL<<CLK_PCLKDIV_APB1DIV_Pos)
#define CLK_PCLKDIV_APB1DIV_DIV4 (0x2UL<<CLK_PCLKDIV_APB1DIV_Pos)
#define CLK_PCLKDIV_APB1DIV_DIV8 (0x3UL<<CLK_PCLKDIV_APB1DIV_Pos)
#define CLK_PCLKDIV_APB1DIV_DIV16 (0x4UL<<CLK_PCLKDIV_APB1DIV_Pos)
#define CLK_PCLKDIV_APB1DIV_DIV32 (0x5UL<<CLK_PCLKDIV_APB1DIV_Pos)
/*---------------------------------------------------------------------------------------------------------*/
/* PLLCTL constant definitions. PLL = FIN * NF / NR / NO */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_PLLCTL_PLLSRC_HXT (0x0ul << CLK_PLLCTL_PLLSRC_Pos) /*!< For PLL clock source is HXT. 4~12MHz < FIN < 24MHz */
#define CLK_PLLCTL_PLLSRC_HIRC_DIV4 (0x1ul << CLK_PLLCTL_PLLSRC_Pos) /*!< For PLL clock source is HIRC/4. 12 MHz< FIN < 12MHz */
#define CLK_PLLCTL_PLLSRC_MIRC (0x3ul << CLK_PLLCTL_PLLSRC_Pos) /*!< For PLL clock source is MIRC. 4 MHz< FIN < 4MHz */
#define CLK_PLLCTL_NF(x) (x) /*!< x must be constant and 1 <= x <= 63. 64MHz < FIN*NF/NR < 100MHz. */
#define CLK_PLLCTL_NR(x) ((x)<<CLK_PLLCTL_INDIV_Pos) /*!< x must be constant and 1 <= x <= 15. 4MHz < FIN/NR < 8MHz */
#define CLK_PLLCTL_NO_1 0x0000UL /*!< For output divider is 1 */
#define CLK_PLLCTL_NO_2 0x4000UL /*!< For output divider is 2 */
#define CLK_PLLCTL_NO_4 0xC000UL /*!< For output divider is 4 */
#define CLK_PLLCTL_16MHz_HXT (CLK_PLLCTL_PLLSRC_HXT | CLK_PLLCTL_NR(3) | CLK_PLLCTL_NF(16) | CLK_PLLCTL_NO_4)
#define CLK_PLLCTL_48MHz_HXT (CLK_PLLCTL_PLLSRC_HXT | CLK_PLLCTL_NR(2) | CLK_PLLCTL_NF(16) | CLK_PLLCTL_NO_2) /*!< Predefined PLLCTL setting for 48MHz PLL output with HXT(12MHz X'tal) */
#define CLK_PLLCTL_50MHz_HXT (CLK_PLLCTL_PLLSRC_HXT | CLK_PLLCTL_NR(3) | CLK_PLLCTL_NF(25) | CLK_PLLCTL_NO_2)
#define CLK_PLLCTL_72MHz_HXT (CLK_PLLCTL_PLLSRC_HXT | CLK_PLLCTL_NR(2) | CLK_PLLCTL_NF(12) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_80MHz_HXT (CLK_PLLCTL_PLLSRC_HXT | CLK_PLLCTL_NR(3) | CLK_PLLCTL_NF(20) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_96MHz_HXT (CLK_PLLCTL_PLLSRC_HXT | CLK_PLLCTL_NR(2) | CLK_PLLCTL_NF(16) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_100MHz_HXT (CLK_PLLCTL_PLLSRC_HXT | CLK_PLLCTL_NR(3) | CLK_PLLCTL_NF(25) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_16MHz_HIRC_DIV4 (CLK_PLLCTL_PLLSRC_HIRC_DIV4 | CLK_PLLCTL_NR(3) | CLK_PLLCTL_NF(16) | CLK_PLLCTL_NO_4)
#define CLK_PLLCTL_48MHz_HIRC_DIV4 (CLK_PLLCTL_PLLSRC_HIRC_DIV4 | CLK_PLLCTL_NR(2) | CLK_PLLCTL_NF(16) | CLK_PLLCTL_NO_2) /*!< Predefined PLLCTL setting for 48MHz PLL output with HIRC_DIV4(12MHz IRC) */
#define CLK_PLLCTL_50MHz_HIRC_DIV4 (CLK_PLLCTL_PLLSRC_HIRC_DIV4 | CLK_PLLCTL_NR(3) | CLK_PLLCTL_NF(25) | CLK_PLLCTL_NO_2)
#define CLK_PLLCTL_72MHz_HIRC_DIV4 (CLK_PLLCTL_PLLSRC_HIRC_DIV4 | CLK_PLLCTL_NR(2) | CLK_PLLCTL_NF(12) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_80MHz_HIRC_DIV4 (CLK_PLLCTL_PLLSRC_HIRC_DIV4 | CLK_PLLCTL_NR(3) | CLK_PLLCTL_NF(20) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_96MHz_HIRC_DIV4 (CLK_PLLCTL_PLLSRC_HIRC_DIV4 | CLK_PLLCTL_NR(2) | CLK_PLLCTL_NF(16) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_100MHz_HIRC_DIV4 (CLK_PLLCTL_PLLSRC_HIRC_DIV4 | CLK_PLLCTL_NR(3) | CLK_PLLCTL_NF(25) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_16MHz_MIRC (CLK_PLLCTL_PLLSRC_MIRC | CLK_PLLCTL_NR(1) | CLK_PLLCTL_NF(16) | CLK_PLLCTL_NO_4)
#define CLK_PLLCTL_48MHz_MIRC (CLK_PLLCTL_PLLSRC_MIRC | CLK_PLLCTL_NR(1) | CLK_PLLCTL_NF(24) | CLK_PLLCTL_NO_2) /*!< Predefined PLLCTL setting for 48MHz PLL output with MIRC(4MHz IRC) */
#define CLK_PLLCTL_50MHz_MIRC (CLK_PLLCTL_PLLSRC_MIRC | CLK_PLLCTL_NR(1) | CLK_PLLCTL_NF(25) | CLK_PLLCTL_NO_2)
#define CLK_PLLCTL_72MHz_MIRC (CLK_PLLCTL_PLLSRC_MIRC | CLK_PLLCTL_NR(1) | CLK_PLLCTL_NF(18) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_80MHz_MIRC (CLK_PLLCTL_PLLSRC_MIRC | CLK_PLLCTL_NR(1) | CLK_PLLCTL_NF(20) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_96MHz_MIRC (CLK_PLLCTL_PLLSRC_MIRC | CLK_PLLCTL_NR(1) | CLK_PLLCTL_NF(24) | CLK_PLLCTL_NO_1)
#define CLK_PLLCTL_100MHz_MIRC (CLK_PLLCTL_PLLSRC_MIRC | CLK_PLLCTL_NR(1) | CLK_PLLCTL_NF(25) | CLK_PLLCTL_NO_1)
/*---------------------------------------------------------------------------------------------------------*/
/* 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 AHBCLK/APBCLK offset on MODULE index, 0x0:AHBCLK, 0x1:APBCLK0, 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, 0x2:CLKDIV3, 0x3:CLKDIV4 */
#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:APBCLK0, 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, 0x2:CLKDIV3, 0x3:CLKDIV4*/
#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) /*!< AHBCLK/APBCLK offset on MODULE index */
//AHBCLK
#define PDMA_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_PDMACKEN_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_ISPCKEN_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 CRC_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_CRCCKEN_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)) /*!< CRC Module */
#define EBI_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_EBICKEN_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)) /*!< EBI Module */
#define CRPT_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_CRYPTCKEN_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)) /*!< CRPT Module */
#define FMCIDLE_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_FMCIDLE_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)) /*!< FMCIDLE Module */
//APBCLK0
#define WDT_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_WDTCKEN_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 WWDT_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_WDTCKEN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 2)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< WWDT Module */
#define CLKO_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_CLKOCKEN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC( 4)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< CLKO Module */
#define TMR0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_TMR0CKEN_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_APBCLK0_TMR1CKEN_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_APBCLK0_TMR2CKEN_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_APBCLK0_TMR3CKEN_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 UART0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_UART0CKEN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|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_APBCLK0_UART1CKEN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(28)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 12)) /*!< UART1 Module */
#define UART2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_UART2CKEN_Pos)|\
MODULE_CLKSEL_ENC( 3)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(24)|\
MODULE_CLKDIV_ENC( 3)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 0)) /*!< UART2 Module */
#define I2C0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_I2C0CKEN_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_APBCLK0_I2C1CKEN_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 QSPI0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_QSPI0CKEN_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)) /*!< QSPI0 Module */
#define SPI0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_SPI0CKEN_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)) /*!< SPI0 Module */
#define RTC_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_RTCCKEN_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 EADC_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_EADCCKEN_Pos)|\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0xFF)|MODULE_CLKDIV_Pos_ENC(16)) /*!< ADC Module */
#define ACMP01_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_ACMP01CKEN_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 USBD_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_USBDCKEN_Pos)|\
MODULE_CLKSEL_ENC( 0)|MODULE_CLKSEL_Msk_ENC(1)|MODULE_CLKSEL_Pos_ENC(8)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC(4)) /*!< USBD Module */
//APBCLK1
#define PWM0_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_PWM0CKEN_Pos)|\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 0)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM0 Module */
#define PWM1_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_PWM1CKEN_Pos)|\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 1)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM1 Module */
#define DAC_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_DACCKEN_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)) /*!< DAC Module */
#define OPA_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_OPACKEN_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)) /*!< OPA Module */
#define USCI0_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_USCI0CKEN_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)) /*!< USCI0 Module */
#define USCI1_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_USCI1CKEN_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)) /*!< USCI1 Module */
#define USCI2_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_USCI2CKEN_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)) /*!< USCI2 Module */
#define SC0_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_SC0CKEN_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 BPWM0_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_BPWM0CKEN_Pos)|\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 8)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< BPWM0 Module */
#define BPWM1_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_BPWM1CKEN_Pos)|\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 9)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< BPWM0 Module */
#define PSIO_MODULE (MODULE_APBCLK_ENC( 2)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_PSIOCKEN_Pos)|\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC( 28)|\
MODULE_CLKDIV_ENC( 1)|MODULE_CLKDIV_Msk_ENC(0xFF)|MODULE_CLKDIV_Pos_ENC( 24)) /*!< PSIO Module */
/*---------------------------------------------------------------------------------------------------------*/
/* PDMSEL constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_PMUCTL_PDMSEL_PD (0x0UL<<CLK_PMUCTL_PDMSEL_Pos)
#define CLK_PMUCTL_PDMSEL_FWPD (0x2UL<<CLK_PMUCTL_PDMSEL_Pos)
#define CLK_PMUCTL_PDMSEL_DPD (0x6UL<<CLK_PMUCTL_PDMSEL_Pos)
/*---------------------------------------------------------------------------------------------------------*/
/* WKTMRIS constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_PMUCTL_WKTMRIS_128 (0x0UL << CLK_PMUCTL_WKTMRIS_Pos) /*!< Select Wake-up Timer Time-out Interval is 128 OSC10K clocks (~3.34 ms) */
#define CLK_PMUCTL_WKTMRIS_256 (0x1UL << CLK_PMUCTL_WKTMRIS_Pos) /*!< Select Wake-up Timer Time-out Interval is 256 OSC10K clocks (~6.67 ms) */
#define CLK_PMUCTL_WKTMRIS_512 (0x2UL << CLK_PMUCTL_WKTMRIS_Pos) /*!< Select Wake-up Timer Time-out Interval is 512 OSC10K clocks (~13.34 ms) */
#define CLK_PMUCTL_WKTMRIS_1024 (0x3UL << CLK_PMUCTL_WKTMRIS_Pos) /*!< Select Wake-up Timer Time-out Interval is 1024 OSC10K clocks (~26.67ms) */
#define CLK_PMUCTL_WKTMRIS_4096 (0x4UL << CLK_PMUCTL_WKTMRIS_Pos) /*!< Select Wake-up Timer Time-out Interval is 4096 OSC10K clocks (~106.67ms) */
#define CLK_PMUCTL_WKTMRIS_8192 (0x5UL << CLK_PMUCTL_WKTMRIS_Pos) /*!< Select Wake-up Timer Time-out Interval is 8192 OSC10K clocks (~213.34ms) */
#define CLK_PMUCTL_WKTMRIS_16384 (0x6UL << CLK_PMUCTL_WKTMRIS_Pos) /*!< Select Wake-up Timer Time-out Interval is 16384 OSC10K clocks (~426.67ms) */
#define CLK_PMUCTL_WKTMRIS_32768 (0x7UL << CLK_PMUCTL_WKTMRIS_Pos) /*!< Select Wake-up Timer Time-out Interval is 65536 OSC10K clocks (~852.34ms) */
/*---------------------------------------------------------------------------------------------------------*/
/* DPD Pin Rising/Falling Edge Wake-up Enable constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_DPDWKPIN_0 (0x0UL) /*!< Wake-up pin0 (GPC.0) at Deep Power-down mode */
#define CLK_DPDWKPIN_1 (0x1UL) /*!< Wake-up pin1 (GPB.0) at Deep Power-down mode */
#define CLK_DPDWKPIN_2 (0x2UL) /*!< Wake-up pin2 (GPB.2) at Deep Power-down mode */
#define CLK_DPDWKPIN_3 (0x3UL) /*!< Wake-up pin3 (GPB.12) at Deep Power-down mode */
#define CLK_DPDWKPIN_4 (0x4UL) /*!< Wake-up pin4 (GPF.6) at Deep Power-down mode */
#define CLK_DPDWKPIN_RISING (0x1UL)
#define CLK_DPDWKPIN_FALLING (0x2UL)
#define CLK_DPDWKPIN_BOTHEDGE (0x3UL)
#define CLK_DPDWKPIN0_DISABLE (0x0UL << CLK_PMUCTL_WKPINEN0_Pos) /*!< Disable Wake-up pin0 (GPC.0) at Deep Power-down mode */
#define CLK_DPDWKPIN0_RISING (0x1UL << CLK_PMUCTL_WKPINEN0_Pos) /*!< Enable Wake-up pin0 (GPC.0) rising edge at Deep Power-down mode */
#define CLK_DPDWKPIN0_FALLING (0x2UL << CLK_PMUCTL_WKPINEN0_Pos) /*!< Enable Wake-up pin0 (GPC.0) falling edge at Deep Power-down mode */
#define CLK_DPDWKPIN0_BOTHEDGE (0x3UL << CLK_PMUCTL_WKPINEN0_Pos) /*!< Enable Wake-up pin0 (GPC.0) both edge at Deep Power-down mode */
#define CLK_DPDWKPIN1_DISABLE (0x0UL << CLK_PMUCTL_WKPINEN1_Pos) /*!< Disable Wake-up pin1 (GPB.0) at Deep Power-down mode */
#define CLK_DPDWKPIN1_RISING (0x1UL << CLK_PMUCTL_WKPINEN1_Pos) /*!< Enable Wake-up pin1 (GPB.0) rising edge at Deep Power-down mode */
#define CLK_DPDWKPIN1_FALLING (0x2UL << CLK_PMUCTL_WKPINEN1_Pos) /*!< Enable Wake-up pin1 (GPB.0) falling edge at Deep Power-down mode */
#define CLK_DPDWKPIN1_BOTHEDGE (0x3UL << CLK_PMUCTL_WKPINEN1_Pos) /*!< Enable Wake-up pin1 (GPB.0) both edge at Deep Power-down mode */
#define CLK_DPDWKPIN2_DISABLE (0x0UL << CLK_PMUCTL_WKPINEN2_Pos) /*!< Disable Wake-up pin2 (GPB.2) at Deep Power-down mode */
#define CLK_DPDWKPIN2_RISING (0x1UL << CLK_PMUCTL_WKPINEN2_Pos) /*!< Enable Wake-up pin2 (GPB.2) rising edge at Deep Power-down mode */
#define CLK_DPDWKPIN2_FALLING (0x2UL << CLK_PMUCTL_WKPINEN2_Pos) /*!< Enable Wake-up pin2 (GPB.2) falling edge at Deep Power-down mode */
#define CLK_DPDWKPIN2_BOTHEDGE (0x3UL << CLK_PMUCTL_WKPINEN2_Pos) /*!< Enable Wake-up pin2 (GPB.2) both edge at Deep Power-down mode */
#define CLK_DPDWKPIN3_DISABLE (0x0UL << CLK_PMUCTL_WKPINEN3_Pos) /*!< Disable Wake-up pin3 (GPB.12) at Deep Power-down mode */
#define CLK_DPDWKPIN3_RISING (0x1UL << CLK_PMUCTL_WKPINEN3_Pos) /*!< Enable Wake-up pin3 (GPB.12) rising edge at Deep Power-down mode */
#define CLK_DPDWKPIN3_FALLING (0x2UL << CLK_PMUCTL_WKPINEN3_Pos) /*!< Enable Wake-up pin3 (GPB.12) falling edge at Deep Power-down mode */
#define CLK_DPDWKPIN3_BOTHEDGE (0x3UL << CLK_PMUCTL_WKPINEN3_Pos) /*!< Enable Wake-up pin3 (GPB.12) both edge at Deep Power-down mode */
#define CLK_DPDWKPIN4_DISABLE (0x0UL << CLK_PMUCTL_WKPINEN4_Pos) /*!< Disable Wake-up pin4 (GPF.6) at Deep Power-down mode */
#define CLK_DPDWKPIN4_RISING (0x1UL << CLK_PMUCTL_WKPINEN4_Pos) /*!< Enable Wake-up pin4 (GPF.6) rising edge at Deep Power-down mode */
#define CLK_DPDWKPIN4_FALLING (0x2UL << CLK_PMUCTL_WKPINEN4_Pos) /*!< Enable Wake-up pin4 (GPF.6) falling edge at Deep Power-down mode */
#define CLK_DPDWKPIN4_BOTHEDGE (0x3UL << CLK_PMUCTL_WKPINEN4_Pos) /*!< Enable Wake-up pin4 (GPF.6) both edge at Deep Power-down mode */
#define CLK_DISABLE_WKTMR(void) (CLK->PMUCTL &= ~CLK_PMUCTL_WKTMREN_Msk) /*!< Disable Wake-up timer at Standby or Deep Power-down mode */
#define CLK_ENABLE_WKTMR(void) (CLK->PMUCTL |= CLK_PMUCTL_WKTMREN_Msk) /*!< Enable Wake-up timer at Standby or Deep Power-down mode */
#define CLK_DISABLE_DPDWKPIN0(void) (CLK->PMUCTL &= ~CLK_PMUCTL_WKPINEN0_Msk) /*!< Disable Wake-up pin0 (GPC.0) at Deep Power-down mode */
#define CLK_DISABLE_DPDWKPIN1(void) (CLK->PMUCTL &= ~CLK_PMUCTL_WKPINEN1_Msk) /*!< Disable Wake-up pin1 (GPB.0) at Deep Power-down mode */
#define CLK_DISABLE_DPDWKPIN2(void) (CLK->PMUCTL &= ~CLK_PMUCTL_WKPINEN2_Msk) /*!< Disable Wake-up pin2 (GPB.2) at Deep Power-down mode */
#define CLK_DISABLE_DPDWKPIN3(void) (CLK->PMUCTL &= ~CLK_PMUCTL_WKPINEN3_Msk) /*!< Disable Wake-up pin3 (GPB.12) at Deep Power-down mode */
#define CLK_DISABLE_DPDWKPIN4(void) (CLK->PMUCTL &= ~CLK_PMUCTL_WKPINEN4_Msk) /*!< Disable Wake-up pin4 (GPF.6) at Deep Power-down mode */
#define CLK_DISABLE_WKPINDB(void) (CLK->PMUCTL &= ~CLK_PMUCTL_WKPINDBEN_Msk) /*!< Disable Wake-up pin De-bounce function */
#define CLK_ENABLE_WKPINDB(void) (CLK->PMUCTL |= CLK_PMUCTL_WKPINDBEN_Msk) /*!< Enable Wake-up pin De-bounce function */
#define CLK_DISABLE_RTCWK(void) (CLK->PMUCTL &= ~CLK_PMUCTL_RTCWKEN_Msk) /*!< Disable RTC Wake-up at Standby or Deep Power-down mode \hideinitializer */
#define CLK_ENABLE_RTCWK(void) (CLK->PMUCTL |= CLK_PMUCTL_RTCWKEN_Msk) /*!< Enable RTC Wake-up at Standby or Deep Power-down mode \hideinitializer */
/**
* @brief Set Wake-up Timer Time-out Interval
*
* @param[in] u32Interval The de-bounce sampling cycle selection. It could be
* - \ref CLK_PMUCTL_WKTMRIS_128
* - \ref CLK_PMUCTL_WKTMRIS_256
* - \ref CLK_PMUCTL_WKTMRIS_512
* - \ref CLK_PMUCTL_WKTMRIS_1024
* - \ref CLK_PMUCTL_WKTMRIS_4096
* - \ref CLK_PMUCTL_WKTMRIS_8192
* - \ref CLK_PMUCTL_WKTMRIS_16384
* - \ref CLK_PMUCTL_WKTMRIS_32768
*
* @return None
*
* @details This function set Wake-up Timer Time-out Interval.
*
*
*/
#define CLK_SET_WKTMR_INTERVAL(u32Interval) (CLK->PMUCTL |= (u32Interval))
/*---------------------------------------------------------------------------------------------------------*/
/* static inline functions */
/*---------------------------------------------------------------------------------------------------------*/
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
__STATIC_INLINE void CLK_SysTickDelay(uint32_t u32USec);
__STATIC_INLINE void CLK_SysTickLongDelay(uint32_t u32USec);
/**
* @brief This function execute delay function.
* @param[in] u32USec 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.
* User can use SystemCoreClockUpdate() to calculate CyclesPerUs automatically before using this function.
*/
__STATIC_INLINE void CLK_SysTickDelay(uint32_t u32USec)
{
SysTick->LOAD = u32USec * CyclesPerUs;
SysTick->VAL = (0x0u);
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
/* Waiting for down-count to zero */
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0u)
{
}
/* Disable SysTick counter */
SysTick->CTRL = 0u;
}
/**
* @brief This function execute long delay function.
* @param[in] u32USec 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 u32USec)
{
uint32_t u32Delay;
/* It should <= 349525us for each delay loop */
u32Delay = 349525UL;
do
{
if (u32USec > u32Delay)
{
u32USec -= u32Delay;
}
else
{
u32Delay = u32USec;
u32USec = 0UL;
}
SysTick->LOAD = u32Delay * 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 (u32USec > 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_GetPCLK0Freq(void);
uint32_t CLK_GetPCLK1Freq(void);
uint32_t CLK_GetHCLKFreq(void);
uint32_t CLK_GetCPUFreq(void);
uint32_t CLK_GetPLLClockFreq(void);
void CLK_DisablePLL(void);
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq);
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv);
uint32_t CLK_SetCoreClock(uint32_t u32Hclk);
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_WaitClockReady(uint32_t u32ClkMask);
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count);
void CLK_DisableSysTick(void);
void CLK_SetPowerDownMode(uint32_t u32PDMode);
void CLK_EnableDPDWKPin(uint32_t u32Pin, uint32_t u32TriggerType);
void CLK_EnableDPDWKPin0(uint32_t u32TriggerType);
void CLK_EnableDPDWKPin1(uint32_t u32TriggerType);
void CLK_EnableDPDWKPin2(uint32_t u32TriggerType);
void CLK_EnableDPDWKPin3(uint32_t u32TriggerType);
void CLK_EnableDPDWKPin4(uint32_t u32TriggerType);
uint32_t CLK_GetPMUWKSrc(void);
uint32_t CLK_GetModuleClockSource(uint32_t u32ModuleIdx);
uint32_t CLK_GetModuleClockDivider(uint32_t u32ModuleIdx);
/*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CLK_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __CLK_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,109 @@
/**************************************************************************//**
* @file crc.h
* @version V0.10
* @brief M251 series Cyclic Redundancy Check(CRC) driver header file
*
* @copyright (C) 2018 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 (0UL << CRC_CTL_CRCMODE_Pos) /*!<CRC Polynomial Mode - CCITT \hideinitializer */
#define CRC_8 (1UL << CRC_CTL_CRCMODE_Pos) /*!<CRC Polynomial Mode - CRC8 \hideinitializer */
#define CRC_16 (2UL << CRC_CTL_CRCMODE_Pos) /*!<CRC Polynomial Mode - CRC16 \hideinitializer */
#define CRC_32 (3UL << CRC_CTL_CRCMODE_Pos) /*!<CRC Polynomial Mode - CRC32 \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Checksum, Write data Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define CRC_CHECKSUM_COM (CRC_CTL_CHKSFMT_Msk) /*!<CRC Checksum Complement \hideinitializer */
#define CRC_CHECKSUM_RVS (CRC_CTL_CHKSREV_Msk) /*!<CRC Checksum Reverse \hideinitializer */
#define CRC_WDATA_COM (CRC_CTL_DATFMT_Msk) /*!<CRC Write Data Complement \hideinitializer */
#define CRC_WDATA_RVS (CRC_CTL_DATREV_Msk) /*!<CRC Write Data Reverse \hideinitializer */
/*---------------------------------------------------------------------------------------------------------------*/
/* CPU Write Data Length Constant Definitions */
/*---------------------------------------------------------------------------------------------------------------*/
#define CRC_CPU_WDATA_8 (0UL << CRC_CTL_DATLEN_Pos) /*!<CRC CPU Write Data length is 8-bit \hideinitializer */
#define CRC_CPU_WDATA_16 (1UL << CRC_CTL_DATLEN_Pos) /*!<CRC CPU Write Data length is 16-bit \hideinitializer */
#define CRC_CPU_WDATA_32 (2UL << CRC_CTL_DATLEN_Pos) /*!<CRC CPU Write Data length is 32-bit \hideinitializer */
/*@}*/ /* end of group CRC_EXPORTED_CONSTANTS */
/** @addtogroup CRC_EXPORTED_FUNCTIONS CRC Exported Functions
@{
*/
/**
* @brief Set CRC Seed Value
*
* @param[in] u32Seed Seed value
*
* @return None
*
* @details This macro is used to set CRC seed value.
*
* @note User must to perform CRC_CHKSINIT(CRC_CTL[1] CRC Engine Reset) to reload the new seed value
* to CRC controller.
*/
#define CRC_SET_SEED(u32Seed) do{ CRC->SEED = (u32Seed); CRC->CTL |= CRC_CTL_CHKSINIT_Msk; }while(0)
/**
* @brief Get CRC Seed Value
*
* @param None
*
* @return CRC seed value
*
* @details This macro gets the current CRC seed value.
*/
#define CRC_GET_SEED() (CRC->SEED)
/**
* @brief CRC Write Data
*
* @param[in] u32Data Write data
*
* @return None
*
* @details User can write data directly to CRC Write Data Register(CRC_DAT) by this macro to perform CRC operation.
*/
#define CRC_WRITE_DATA(u32Data) (CRC->DAT = (u32Data))
void CRC_Open(uint32_t u32Mode, uint32_t u32Attribute, uint32_t u32Seed, uint32_t u32DataLen);
uint32_t CRC_GetChecksum(void);
/*@}*/ /* end of group CRC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CRC_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __CRC_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,188 @@
/**************************************************************************//**
* @file crypto.h
* @version V1.10
* @brief Cryptographic Accelerator driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __CRYPTO_H__
#define __CRYPTO_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup CRYPTO_Driver CRYPTO Driver
@{
*/
/** @addtogroup CRYPTO_EXPORTED_CONSTANTS CRYPTO Exported Constants
@{
*/
#define PRNG_KEY_SIZE_64 0UL /*!< Select to generate 64-bit random key \hideinitializer */
#define PRNG_KEY_SIZE_128 1UL /*!< Select to generate 128-bit random key \hideinitializer */
#define PRNG_KEY_SIZE_192 2UL /*!< Select to generate 192-bit random key \hideinitializer */
#define PRNG_KEY_SIZE_256 3UL /*!< Select to generate 256-bit random key \hideinitializer */
#define PRNG_SEED_CONT 0UL /*!< PRNG using current seed \hideinitializer */
#define PRNG_SEED_RELOAD 1UL /*!< PRNG reload new seed \hideinitializer */
#define AES_KEY_SIZE_128 0UL /*!< AES select 128-bit key length \hideinitializer */
#define AES_KEY_SIZE_192 1UL /*!< AES select 192-bit key length \hideinitializer */
#define AES_KEY_SIZE_256 2UL /*!< AES select 256-bit key length \hideinitializer */
#define AES_MODE_ECB 0UL /*!< AES select ECB mode \hideinitializer */
#define AES_MODE_CBC 1UL /*!< AES select CBC mode \hideinitializer */
#define AES_MODE_CFB 2UL /*!< AES select CFB mode \hideinitializer */
#define AES_MODE_OFB 3UL /*!< AES select OFB mode \hideinitializer */
#define AES_MODE_CTR 4UL /*!< AES select CTR mode \hideinitializer */
#define AES_MODE_CBC_CS1 0x10UL /*!< AES select CBC CS1 mode \hideinitializer */
#define AES_MODE_CBC_CS2 0x11UL /*!< AES select CBC CS2 mode \hideinitializer */
#define AES_MODE_CBC_CS3 0x12UL /*!< AES select CBC CS3 mode \hideinitializer */
#define AES_NO_SWAP 0UL /*!< AES do not swap input and output data \hideinitializer */
#define AES_OUT_SWAP 1UL /*!< AES swap output data \hideinitializer */
#define AES_IN_SWAP 2UL /*!< AES swap input data \hideinitializer */
#define AES_IN_OUT_SWAP 3UL /*!< AES swap both input and output data \hideinitializer */
#define CRYPTO_DMA_FIRST 0x4UL /*!< Do first encrypt/decrypt in DMA cascade \hideinitializer */
#define CRYPTO_DMA_ONE_SHOT 0x5UL /*!< Do one shot encrypt/decrypt with DMA \hideinitializer */
#define CRYPTO_DMA_CONTINUE 0x6UL /*!< Do continuous encrypt/decrypt in DMA cascade \hideinitializer */
#define CRYPTO_DMA_LAST 0x7UL /*!< Do last encrypt/decrypt in DMA cascade \hideinitializer */
/*@}*/ /* end of group CRYPTO_EXPORTED_CONSTANTS */
/** @addtogroup CRYPTO_EXPORTED_MACROS CRYPTO Exported Macros
@{
*/
/*----------------------------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------------------------*/
/**
* @brief This macro enables PRNG interrupt.
* @param crpt Specified cripto module
* @return None
* \hideinitializer
*/
#define PRNG_ENABLE_INT(crpt) ((crpt)->INTEN |= CRPT_INTEN_PRNGIEN_Msk)
/**
* @brief This macro disables PRNG interrupt.
* @param crpt Specified cripto module
* @return None
* \hideinitializer
*/
#define PRNG_DISABLE_INT(crpt) ((crpt)->INTEN &= ~CRPT_INTEN_PRNGIEN_Msk)
/**
* @brief This macro gets PRNG interrupt flag.
* @param crpt Specified cripto module
* @return PRNG interrupt flag.
* \hideinitializer
*/
#define PRNG_GET_INT_FLAG(crpt) ((crpt)->INTSTS & CRPT_INTSTS_PRNGIF_Msk)
/**
* @brief This macro clears PRNG interrupt flag.
* @param crpt Specified cripto module
* @return None
* \hideinitializer
*/
#define PRNG_CLR_INT_FLAG(crpt) ((crpt)->INTSTS = CRPT_INTSTS_PRNGIF_Msk)
/**
* @brief This macro enables AES interrupt.
* @param crpt Specified cripto module
* @return None
* \hideinitializer
*/
#define AES_ENABLE_INT(crpt) ((crpt)->INTEN |= (CRPT_INTEN_AESIEN_Msk|CRPT_INTEN_AESEIEN_Msk))
/**
* @brief This macro disables AES interrupt.
* @param crpt Specified cripto module
* @return None
* \hideinitializer
*/
#define AES_DISABLE_INT(crpt) ((crpt)->INTEN &= ~(CRPT_INTEN_AESIEN_Msk|CRPT_INTEN_AESEIEN_Msk))
/**
* @brief This macro gets AES interrupt flag.
* @param crpt Specified cripto module
* @return AES interrupt flag.
* \hideinitializer
*/
#define AES_GET_INT_FLAG(crpt) ((crpt)->INTSTS & (CRPT_INTSTS_AESIF_Msk|CRPT_INTSTS_AESEIF_Msk))
/**
* @brief This macro clears AES interrupt flag.
* @param crpt Specified cripto module
* @return None
* \hideinitializer
*/
#define AES_CLR_INT_FLAG(crpt) ((crpt)->INTSTS = (CRPT_INTSTS_AESIF_Msk|CRPT_INTSTS_AESEIF_Msk))
/**
* @brief This macro enables AES key protection.
* @param crpt Specified cripto module
* @return None
* \hideinitializer
*/
#define AES_ENABLE_KEY_PROTECT(crpt) ((crpt)->AES_CTL |= CRPT_AES_CTL_KEYPRT_Msk)
/**
* @brief This macro disables AES key protection.
* @param crpt Specified cripto module
* @return None
* \hideinitializer
*/
#define AES_DISABLE_KEY_PROTECT(crpt) ((crpt)->AES_CTL = ((crpt)->AES_CTL & ~CRPT_AES_CTL_KEYPRT_Msk) | (0x16UL<<CRPT_AES_CTL_KEYUNPRT_Pos)); \
((crpt)->AES_CTL &= ~CRPT_AES_CTL_KEYPRT_Msk)
/*@}*/ /* end of group CRYPTO_EXPORTED_MACROS */
/** @addtogroup CRYPTO_EXPORTED_FUNCTIONS CRYPTO Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Functions */
/*---------------------------------------------------------------------------------------------------------*/
void PRNG_Open(CRPT_T *crpt, uint32_t u32KeySize, uint32_t u32SeedReload, uint32_t u32Seed);
void PRNG_Start(CRPT_T *crpt);
void PRNG_Read(CRPT_T *crpt, uint32_t au32RandKey[]);
void AES_Open(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32EncDec, uint32_t u32OpMode, uint32_t u32KeySize, uint32_t u32SwapType);
void AES_Start(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32DMAMode);
void AES_SetKey(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32Keys[], uint32_t u32KeySize);
void AES_SetInitVect(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32IV[]);
void AES_SetDMATransfer(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32SrcAddr, uint32_t u32DstAddr, uint32_t u32TransCnt);
/*@}*/ /* end of group CRYPTO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CRYPTO_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __CRYPTO_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,249 @@
/**************************************************************************//**
* @file dac.h
* @version V0.10
* @brief M251 series DAC driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __DAC_H__
#define __DAC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup DAC_Driver DAC Driver
@{
*/
/** @addtogroup DAC_EXPORTED_CONSTANTS DAC Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* DAC_CTL Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define DAC_CTL_LALIGN_RIGHT_ALIGN (0UL<<DAC_CTL_LALIGN_Pos) /*!< Right alignment. \hideinitializer */
#define DAC_CTL_LALIGN_LEFT_ALIGN (1UL<<DAC_CTL_LALIGN_Pos) /*!< Left alignment \hideinitializer */
#define DAC_WRITE_DAT_TRIGGER (0UL) /*!< Write DAC_DAT trigger \hideinitializer */
#define DAC_SOFTWARE_TRIGGER (0UL|DAC_CTL_TRGEN_Msk) /*!< Software trigger \hideinitializer */
#define DAC_LOW_LEVEL_TRIGGER ((0UL<<DAC_CTL_ETRGSEL_Pos)|(1UL<<DAC_CTL_TRGSEL_Pos)|DAC_CTL_TRGEN_Msk) /*!< STDAC pin low level trigger \hideinitializer */
#define DAC_HIGH_LEVEL_TRIGGER ((1UL<<DAC_CTL_ETRGSEL_Pos)|(1UL<<DAC_CTL_TRGSEL_Pos)|DAC_CTL_TRGEN_Msk) /*!< STDAC pin high level trigger \hideinitializer */
#define DAC_FALLING_EDGE_TRIGGER ((2UL<<DAC_CTL_ETRGSEL_Pos)|(1UL<<DAC_CTL_TRGSEL_Pos)|DAC_CTL_TRGEN_Msk) /*!< STDAC pin falling edge trigger \hideinitializer */
#define DAC_RISING_EDGE_TRIGGER ((3UL<<DAC_CTL_ETRGSEL_Pos)|(1UL<<DAC_CTL_TRGSEL_Pos)|DAC_CTL_TRGEN_Msk) /*!< STDAC pin rising edge trigger \hideinitializer */
#define DAC_TIMER0_TRIGGER ((2UL<<DAC_CTL_TRGSEL_Pos)|DAC_CTL_TRGEN_Msk) /*!< Timer 0 trigger \hideinitializer */
#define DAC_TIMER1_TRIGGER ((3UL<<DAC_CTL_TRGSEL_Pos)|DAC_CTL_TRGEN_Msk) /*!< Timer 1 trigger \hideinitializer */
#define DAC_TIMER2_TRIGGER ((4UL<<DAC_CTL_TRGSEL_Pos)|DAC_CTL_TRGEN_Msk) /*!< Timer 2 trigger \hideinitializer */
#define DAC_TIMER3_TRIGGER ((5UL<<DAC_CTL_TRGSEL_Pos)|DAC_CTL_TRGEN_Msk) /*!< Timer 3 trigger \hideinitializer */
#define DAC_TRIGGER_MODE_DISABLE (0UL<<DAC_CTL_TRGEN_Pos) /*!< Trigger mode disable \hideinitializer */
#define DAC_TRIGGER_MODE_ENABLE (1UL<<DAC_CTL_TRGEN_Pos) /*!< Trigger mode enable \hideinitializer */
/*@}*/ /* end of group DAC_EXPORTED_CONSTANTS */
/** @addtogroup DAC_EXPORTED_FUNCTIONS DAC Exported Functions
@{
*/
/**
* @brief Start the D/A conversion.
* @param[in] dac The pointer of the specified DAC module.
* @return None
* @details User writes SWTRG bit (DAC_SWTRG[0]) to generate one shot pulse and it is cleared to 0 by hardware automatically.
* \hideinitializer
*/
#define DAC_START_CONV(dac) ((dac)->SWTRG = DAC_SWTRG_SWTRG_Msk)
/**
* @brief Enable DAC data left-aligned.
* @param[in] dac The pointer of the specified DAC module.
* @return None
* @details User has to load data into DAC_DAT[15:4] bits. DAC_DAT[31:16] and DAC_DAT[3:0] are ignored in DAC conversion.
* \hideinitializer
*/
#define DAC_ENABLE_LEFT_ALIGN(dac) ((dac)->CTL |= DAC_CTL_LALIGN_Msk)
/**
* @brief Enable DAC data right-aligned.
* @param[in] dac The pointer of the specified DAC module.
* @return None
* @details User has to load data into DAC_DAT[11:0] bits, DAC_DAT[31:12] are ignored in DAC conversion.
* \hideinitializer
*/
#define DAC_ENABLE_RIGHT_ALIGN(dac) ((dac)->CTL &= ~DAC_CTL_LALIGN_Msk)
/**
* @brief Enable output voltage buffer.
* @param[in] dac The pointer of the specified DAC module.
* @return None
* @details The DAC integrates a voltage output buffer that can be used to reduce output impedance and
* drive external loads directly without having to add an external operational amplifier.
* \hideinitializer
*/
#define DAC_ENABLE_BYPASS_BUFFER(dac) ((dac)->CTL |= DAC_CTL_BYPASS_Msk)
/**
* @brief Disable output voltage buffer.
* @param[in] dac The pointer of the specified DAC module.
* @return None
* @details This macro is used to disable output voltage buffer.
* \hideinitializer
*/
#define DAC_DISABLE_BYPASS_BUFFER(dac) ((dac)->CTL &= ~DAC_CTL_BYPASS_Msk)
/**
* @brief Enable the interrupt.
* @param[in] dac The pointer of the specified DAC module.
* @param[in] u32Ch Not used in M251 DAC.
* @return None
* @details This macro is used to enable DAC interrupt.
* \hideinitializer
*/
#define DAC_ENABLE_INT(dac, u32Ch) ((dac)->CTL |= DAC_CTL_DACIEN_Msk)
/**
* @brief Disable the interrupt.
* @param[in] dac The pointer of the specified DAC module.
* @param[in] u32Ch Not used in M251 DAC.
* @return None
* @details This macro is used to disable DAC interrupt.
* \hideinitializer
*/
#define DAC_DISABLE_INT(dac, u32Ch) ((dac)->CTL &= ~DAC_CTL_DACIEN_Msk)
/**
* @brief Enable DMA under-run interrupt.
* @param[in] dac The pointer of the specified DAC module.
* @return None
* @details This macro is used to enable DMA under-run interrupt.
* \hideinitializer
*/
#define DAC_ENABLE_DMAUDR_INT(dac) ((dac)->CTL |= DAC_CTL_DMAURIEN_Msk)
/**
* @brief Disable DMA under-run interrupt.
* @param[in] dac The pointer of the specified DAC module.
* @return None
* @details This macro is used to disable DMA under-run interrupt.
* \hideinitializer
*/
#define DAC_DISABLE_DMAUDR_INT(dac) ((dac)->CTL &= ~DAC_CTL_DMAURIEN_Msk)
/**
* @brief Enable PDMA mode.
* @param[in] dac The pointer of the specified DAC module.
* @return None
* @details DAC DMA request is generated when a hardware trigger event occurs while DMAEN (DAC_CTL[2]) is set.
* \hideinitializer
*/
#define DAC_ENABLE_PDMA(dac) ((dac)->CTL |= DAC_CTL_DMAEN_Msk)
/**
* @brief Disable PDMA mode.
* @param[in] dac The pointer of the specified DAC module.
* @return None
* @details This macro is used to disable DMA mode.
* \hideinitializer
*/
#define DAC_DISABLE_PDMA(dac) ((dac)->CTL &= ~DAC_CTL_DMAEN_Msk)
/**
* @brief Write data for conversion.
* @param[in] dac The pointer of the specified DAC module.
* @param[in] u32Ch Not used in M251 DAC.
* @param[in] u32Data Decides the data for conversion, valid range are between 0~0xFFF.
* @return None
* @details 12 bit left alignment: user has to load data into DAC_DAT[15:4] bits.
* 12 bit right alignment: user has to load data into DAC_DAT[11:0] bits.
* \hideinitializer
*/
#define DAC_WRITE_DATA(dac, u32Ch, u32Data) ((dac)->DAT = (u32Data))
/**
* @brief Read DAC 12-bit holding data.
* @param[in] dac The pointer of the specified DAC module.
* @param[in] u32Ch Not used in M251 DAC.
* @return Return DAC 12-bit holding data.
* @details This macro is used to read DAC_DAT register.
* \hideinitializer
*/
#define DAC_READ_DATA(dac, u32Ch) ((dac)->DAT)
/**
* @brief Get the busy state of DAC.
* @param[in] dac The pointer of the specified DAC module.
* @param[in] u32Ch Not used in M251 DAC.
* @retval 0 Idle state.
* @retval 1 Busy state.
* @details This macro is used to read BUSY bit (DAC_STATUS[8]) to get busy state.
* \hideinitializer
*/
#define DAC_IS_BUSY(dac, u32Ch) (((dac)->STATUS & DAC_STATUS_BUSY_Msk) >> DAC_STATUS_BUSY_Pos)
/**
* @brief Get the interrupt flag.
* @param[in] dac The pointer of the specified DAC module.
* @param[in] u32Ch Not used in M251 DAC.
* @retval 0 DAC is in conversion state.
* @retval 1 DAC conversion finish.
* @details This macro is used to read FINISH bit (DAC_STATUS[0]) to get DAC conversion complete finish flag.
* \hideinitializer
*/
#define DAC_GET_INT_FLAG(dac, u32Ch) ((dac)->STATUS & DAC_STATUS_FINISH_Msk)
/**
* @brief Get the DMA under-run flag.
* @param[in] dac The pointer of the specified DAC module.
* @retval 0 No DMA under-run error condition occurred.
* @retval 1 DMA under-run error condition occurred.
* @details This macro is used to read DMAUDR bit (DAC_STATUS[1]) to get DMA under-run state.
* \hideinitializer
*/
#define DAC_GET_DMAUDR_FLAG(dac) (((dac)->STATUS & DAC_STATUS_DMAUDR_Msk) >> DAC_STATUS_DMAUDR_Pos)
/**
* @brief This macro clear the interrupt status bit.
* @param[in] dac The pointer of the specified DAC module.
* @param[in] u32Ch Not used in M251 DAC.
* @return None
* @details User writes FINISH bit (DAC_STATUS[0]) to clear DAC conversion complete finish flag.
* \hideinitializer
*/
#define DAC_CLR_INT_FLAG(dac, u32Ch) ((dac)->STATUS = DAC_STATUS_FINISH_Msk)
/**
* @brief This macro clear the DMA under-run flag.
* @param[in] dac The pointer of the specified DAC module.
* @return None
* @details User writes DMAUDR bit (DAC_STATUS[1]) to clear DMA under-run flag.
* \hideinitializer
*/
#define DAC_CLR_DMAUDR_FLAG(dac) ((dac)->STATUS = DAC_STATUS_DMAUDR_Msk)
void DAC_Open(DAC_T *dac, uint32_t u32Ch, uint32_t u32TrgSrc);
void DAC_Close(DAC_T *dac, uint32_t u32Ch);
uint32_t DAC_SetDelayTime(DAC_T *dac, uint32_t u32Delay);
/*@}*/ /* end of group DAC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group DAC_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __DAC_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,737 @@
/****************************************************************************//**
* @file eadc.h
* @version V0.10
* @brief M251 series EADC driver header file
*
* @note
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __EADC_H__
#define __EADC_H__
/*---------------------------------------------------------------------------------------------------------*/
/* Include related headers */
/*---------------------------------------------------------------------------------------------------------*/
#include "M251.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup EADC_Driver EADC Driver
@{
*/
/** @addtogroup EADC_EXPORTED_CONSTANTS EADC Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* EADC_SCTLn Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define EADC_SCTL_CHSEL(x) ((x) << EADC_SCTL_CHSEL_Pos) /*!< A/D sample module channel selection */
#define EADC_SCTL_TRGDLYDIV(x) ((x) << EADC_SCTL_TRGDLYDIV_Pos) /*!< A/D sample module start of conversion trigger delay clock divider selection */
#define EADC_SCTL_TRGDLYCNT(x) ((x) << EADC_SCTL_TRGDLYCNT_Pos) /*!< A/D sample module start of conversion trigger delay time */
#define EADC_SOFTWARE_TRIGGER (0UL<<EADC_SCTL_TRGSEL_Pos) /*!< Software trigger */
#define EADC_FALLING_EDGE_TRIGGER ((1UL<<EADC_SCTL_TRGSEL_Pos) | EADC_SCTL_EXTFEN_Msk) /*!< STADC pin falling edge trigger */
#define EADC_RISING_EDGE_TRIGGER ((1UL<<EADC_SCTL_TRGSEL_Pos) | EADC_SCTL_EXTREN_Msk) /*!< STADC pin rising edge trigger */
#define EADC_FALLING_RISING_EDGE_TRIGGER ((1UL<<EADC_SCTL_TRGSEL_Pos) | EADC_SCTL_EXTFEN_Msk | EADC_SCTL_EXTREN_Msk) /*!< STADC pin both falling and rising edge trigger */
#define EADC_ADINT0_TRIGGER (2UL<<EADC_SCTL_TRGSEL_Pos) /*!< EADC ADINT0 interrupt EOC pulse trigger */
#define EADC_ADINT1_TRIGGER (3UL<<EADC_SCTL_TRGSEL_Pos) /*!< EADC ADINT1 interrupt EOC pulse trigger */
#define EADC_TIMER0_TRIGGER (4UL<<EADC_SCTL_TRGSEL_Pos) /*!< Timer0 overflow pulse trigger */
#define EADC_TIMER1_TRIGGER (5UL<<EADC_SCTL_TRGSEL_Pos) /*!< Timer1 overflow pulse trigger */
#define EADC_TIMER2_TRIGGER (6UL<<EADC_SCTL_TRGSEL_Pos) /*!< Timer2 overflow pulse trigger */
#define EADC_TIMER3_TRIGGER (7UL<<EADC_SCTL_TRGSEL_Pos) /*!< Timer3 overflow pulse trigger */
#define EADC_PWM0TG0_TRIGGER (8UL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM0TG0 trigger */
#define EADC_PWM0TG1_TRIGGER (9UL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM0TG1 trigger */
#define EADC_PWM0TG2_TRIGGER (0xAUL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM0TG2 trigger */
#define EADC_PWM0TG3_TRIGGER (0xBUL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM0TG3 trigger */
#define EADC_PWM0TG4_TRIGGER (0xCUL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM0TG4 trigger */
#define EADC_PWM0TG5_TRIGGER (0xDUL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM0TG5 trigger */
#define EADC_PWM1TG0_TRIGGER (0xEUL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM1TG0 trigger */
#define EADC_PWM1TG1_TRIGGER (0xFUL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM1TG1 trigger */
#define EADC_PWM1TG2_TRIGGER (0x10UL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM1TG2 trigger */
#define EADC_PWM1TG3_TRIGGER (0x11UL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM1TG3 trigger */
#define EADC_PWM1TG4_TRIGGER (0x12UL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM1TG4 trigger */
#define EADC_PWM1TG5_TRIGGER (0x13UL<<EADC_SCTL_TRGSEL_Pos) /*!< PWM1TG5 trigger */
#define EADC_BPWM0TG_TRIGGER (0x14UL<<EADC_SCTL_TRGSEL_Pos) /*!< BPWM0TG trigger */
#define EADC_BPWM1TG_TRIGGER (0x15UL<<EADC_SCTL_TRGSEL_Pos) /*!< BPWM1TG trigger */
#define EADC_SCTL_TRGDLYDIV_DIVIDER_1 (0<<EADC_SCTL_TRGDLYDIV_Pos) /*!< Trigger delay clock frequency is ADC_CLK/1 */
#define EADC_SCTL_TRGDLYDIV_DIVIDER_2 (0x1UL<<EADC_SCTL_TRGDLYDIV_Pos) /*!< Trigger delay clock frequency is ADC_CLK/2 */
#define EADC_SCTL_TRGDLYDIV_DIVIDER_4 (0x2UL<<EADC_SCTL_TRGDLYDIV_Pos) /*!< Trigger delay clock frequency is ADC_CLK/4 */
#define EADC_SCTL_TRGDLYDIV_DIVIDER_16 (0x3UL<<EADC_SCTL_TRGDLYDIV_Pos) /*!< Trigger delay clock frequency is ADC_CLK/16 */
/*---------------------------------------------------------------------------------------------------------*/
/* EADC_CMPn Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define EADC_CMP_CMPCOND_LESS_THAN (0UL<<EADC_CMP_CMPCOND_Pos) /*!< The compare condition is "less than" */
#define EADC_CMP_CMPCOND_GREATER_OR_EQUAL (1UL<<EADC_CMP_CMPCOND_Pos) /*!< The compare condition is "greater than or equal to" */
#define EADC_CMP_CMPWEN_ENABLE (EADC_CMP_CMPWEN_Msk) /*!< Compare window mode enable */
#define EADC_CMP_CMPWEN_DISABLE (~EADC_CMP_CMPWEN_Msk) /*!< Compare window mode disable */
#define EADC_CMP_ADCMPIE_ENABLE (EADC_CMP_ADCMPIE_Msk) /*!< A/D result compare interrupt enable */
#define EADC_CMP_ADCMPIE_DISABLE (~EADC_CMP_ADCMPIE_Msk) /*!< A/D result compare interrupt disable */
/*---------------------------------------------------------------------------------------------------------*/
/* EADC_MnCTL1 Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define EADC_MCTL1_ACU_1 (0x0UL<<EADC_MCTL1_ACU_Pos) /*!< Accumulated 1 time */
#define EADC_MCTL1_ACU_2 (0x1UL<<EADC_MCTL1_ACU_Pos) /*!< Accumulated 2 times */
#define EADC_MCTL1_ACU_4 (0x2UL<<EADC_MCTL1_ACU_Pos) /*!< Accumulated 4 times */
#define EADC_MCTL1_ACU_8 (0x3UL<<EADC_MCTL1_ACU_Pos) /*!< Accumulated 8 times */
#define EADC_MCTL1_ACU_16 (0x4UL<<EADC_MCTL1_ACU_Pos) /*!< Accumulated 16 times */
#define EADC_MCTL1_ACU_32 (0x5UL<<EADC_MCTL1_ACU_Pos) /*!< Accumulated 32 times */
#define EADC_MCTL1_ACU_64 (0x6UL<<EADC_MCTL1_ACU_Pos) /*!< Accumulated 64 times */
#define EADC_MCTL1_ACU_128 (0x7UL<<EADC_MCTL1_ACU_Pos) /*!< Accumulated 128 times */
#define EADC_MCTL1_ACU_256 (0x8UL<<EADC_MCTL1_ACU_Pos) /*!< Accumulated 256 times */
/*---------------------------------------------------------------------------------------------------------*/
/* EADC_PWRCTL Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define EADC_PWRCTL_AUTOPDTHT_1 (0x0UL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 1 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_2 (0x1UL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 2 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_3 (0x2UL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 3 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_4 (0x3UL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 4 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_5 (0x4UL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 5 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_6 (0x5UL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 6 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_7 (0x6UL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 7 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_8 (0x7UL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 8 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_16 (0x8UL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 16 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_32 (0x9UL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 32 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_64 (0xAUL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 64 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_128 (0xBUL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 128 EADC clock */
#define EADC_PWRCTL_AUTOPDTHT_256 (0xCUL<<EADC_PWRCTL_AUTOPDTHT_Pos) /*!< Auto Power Down Threshold Time 256 EADC clock */
/*@}*/ /* end of group EADC_EXPORTED_CONSTANTS */
/** @addtogroup EADC_EXPORTED_FUNCTIONS EADC Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* EADC Macro Definitions */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief A/D Converter Control Circuits Reset.
* @param[in] eadc The pointer of the specified EADC module.
* @return None
* @details ADCRST bit (EADC_CTL[1]) remains 1 during EADC reset, when EADC reset end, the ADCRST bit is automatically cleared to 0.
*/
#define EADC_CONV_RESET(eadc) ((eadc)->CTL |= EADC_CTL_ADCRST_Msk)
/**
* @brief Enable PDMA transfer.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
* @return None
* @details When A/D conversion is completed, the converted data is loaded into EADC_DATn (n=0~15) register,
* user can enable this bit to generate a PDMA data transfer request.
*/
#define EADC_ENABLE_PDMA(eadc, u32ModuleNum) (eadc)->PDMACTL |= (0x1 << u32ModuleNum)
/**
* @brief Disable PDMA transfer.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
* @return None
* @details This macro is used to disable PDMA transfer.
*/
#define EADC_DISABLE_PDMA(eadc, u32ModuleNum) (eadc)->PDMACTL &= ~(0x1 << u32ModuleNum)
/**
* @brief Set ADIFn at A/D start of conversion.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
* @return None
* @details The A/D converter generates ADIFn (EADC_STATUS2[n], n=0~3) at the start of conversion.
*/
#define EADC_ENABLE_INT_POSITION(eadc, u32ModuleNum) ((((eadc)->SCTL[(u32ModuleNum)])) |= EADC_SCTL_INTPOS_Msk)
/**
* @brief Set ADIFn at A/D end of conversion.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
* @return None
* @details The A/D converter generates ADIFn (EADC_STATUS2[n], n=0~3) at the end of conversion.
*/
#define EADC_DISABLE_INT_POSITION(eadc, u32ModuleNum) ((((eadc)->SCTL[(u32ModuleNum)])) &= (~EADC_SCTL_INTPOS_Msk))
/**
* @brief Enable the interrupt.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32Mask Decides the combination of interrupt status bits. Each bit corresponds to a interrupt status.
* This parameter decides which interrupts will be enabled. Bit 0 is ADCIEN0, bit 1 is ADCIEN1..., bit 3 is ADCIEN3.
* @return None
* @details The A/D converter generates a conversion end ADIFn (EADC_STATUS2[n], n=0~3) upon the end of specific sample module A/D conversion.
* If ADCIENn bit (EADC_CTL[n+2]) is set then conversion end interrupt request ADINTn is generated (n=0~3).
*/
#define EADC_ENABLE_INT(eadc, u32Mask) ((eadc)->CTL |= ((u32Mask) << EADC_CTL_ADCIEN0_Pos))
/**
* @brief Disable the interrupt.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32Mask Decides the combination of interrupt status bits. Each bit corresponds to a interrupt status.
* This parameter decides which interrupts will be disabled. Bit 0 is ADCIEN0, bit 1 is ADCIEN1..., bit 3 is ADCIEN3.
* @return None
* @details Specific sample module A/D ADINT0 interrupt function disabled.
*/
#define EADC_DISABLE_INT(eadc, u32Mask) ((eadc)->CTL &= (~((u32Mask) << EADC_CTL_ADCIEN0_Pos)))
/**
* @brief Enable the sample module interrupt.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32IntSel Decides which interrupt source will be used, valid value are from 0 to 3.
* @param[in] u32ModuleMask the combination of sample module interrupt status bits. Each bit corresponds to a sample module interrupt status.
* This parameter decides which sample module interrupts will be enabled, valid range are between 1~0x7FFFF.
* @return None
* @details There are 4 EADC interrupts ADINT0~3, and each of these interrupts has its own interrupt vector address.
*/
#define EADC_ENABLE_SAMPLE_MODULE_INT(eadc, u32IntSel, u32ModuleMask) ((((eadc)->INTSRC[(u32IntSel)])) |= (u32ModuleMask))
/**
* @brief Disable the sample module interrupt.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32IntSel Decides which interrupt source will be used, valid value are from 0 to 3.
* @param[in] u32ModuleMask the combination of sample module interrupt status bits. Each bit corresponds to a sample module interrupt status.
* This parameter decides which sample module interrupts will be disabled, valid range are between 1~0x7FFFF.
* @return None
* @details There are 4 EADC interrupts ADINT0~3, and each of these interrupts has its own interrupt vector address.
*/
#define EADC_DISABLE_SAMPLE_MODULE_INT(eadc, u32IntSel, u32ModuleMask) ((((eadc)->INTSRC[(u32IntSel)])) &= (~(u32ModuleMask)))
/**
* @brief Start the A/D conversion.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleMask The combination of sample module. Each bit corresponds to a sample module.
* This parameter decides which sample module will be converted, valid range are between 1~0x7FFFF.
* Bit 0 is sample module 0, bit 1 is sample module 1..., bit 18 is sample module 18.
* @return None
* @details After write EADC_SWTRG register to start EADC conversion, the EADC_PENDSTS register will show which sample module will conversion.
*/
#define EADC_START_CONV(eadc, u32ModuleMask) ((eadc)->SWTRG = (u32ModuleMask))
/**
* @brief Cancel the conversion for sample module.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleMask The combination of sample module. Each bit corresponds to a sample module.
* This parameter decides which sample module will stop the conversion, valid range are between 1~0x7FFFF.
* Bit 0 is sample module 0, bit 1 is sample module 1..., bit 18 is sample module18.
* @return None
* @details If user want to disable the conversion of the sample module, user can write EADC_PENDSTS register to clear it.
*/
#define EADC_STOP_CONV(eadc, u32ModuleMask) ((eadc)->PENDSTS = (u32ModuleMask))
/**
* @brief Get the conversion pending flag.
* @param[in] eadc The pointer of the specified EADC module.
* @return Return the conversion pending sample module.
* @details This STPFn (EADC_PENDSTS[n], n=0~18) bit remains 1 during pending state, when the respective EADC conversion is end,
* the STPFn (EADC_PENDSTS[n], n=0~18) bit is automatically cleared to 0.
*/
#define EADC_GET_PENDING_CONV(eadc) ((eadc)->PENDSTS)
/**
* @brief Get the conversion data of the user-specified sample module.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 18.
* @return Return the conversion data of the user-specified sample module.
* @details This macro is used to read RESULT bit (EADC_DATn[15:0], n=0~18) field to get conversion data.
*/
#define EADC_GET_CONV_DATA(eadc, u32ModuleNum) ((((eadc)->DAT[(u32ModuleNum)])) & EADC_DAT_RESULT_Msk)
/**
* @brief Get the data overrun flag of the user-specified sample module.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleMask The combination of data overrun status bits. Each bit corresponds to a data overrun status, valid range are between 1~0x7FFFF.
* @return Return the data overrun flag of the user-specified sample module.
* @details This macro is used to read OV bit (EADC_STATUS0[31:16], EADC_STATUS1[18:16]) field to get data overrun status.
*/
#define EADC_GET_DATA_OVERRUN_FLAG(eadc, u32ModuleMask) ((((eadc)->STATUS0 >> EADC_STATUS0_OV_Pos) | ((eadc)->STATUS1 & EADC_STATUS1_OV_Msk)) & (u32ModuleMask))
/**
* @brief Get the data valid flag of the user-specified sample module.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleMask The combination of data valid status bits. Each bit corresponds to a data valid status, valid range are between 1~0x7FFFF.
* @return Return the data valid flag of the user-specified sample module.
* @details This macro is used to read VALID bit (EADC_STATUS0[15:0], EADC_STATUS1[2:0]) field to get data overrun status.
*/
#define EADC_GET_DATA_VALID_FLAG(eadc, u32ModuleMask) ((((eadc)->STATUS0 & EADC_STATUS0_VALID_Msk) | (((eadc)->STATUS1 & EADC_STATUS1_VALID_Msk) << 16)) & (u32ModuleMask))
/**
* @brief Get the user-specified interrupt flags.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32Mask The combination of interrupt status bits. Each bit corresponds to a interrupt status.
* Bit 0 is ADIF0, bit 1 is ADIF1..., bit 3 is ADIF3.
* Bit 4 is ADCMPF0, bit 5 is ADCMPF1..., bit 7 is ADCMPF3.
* Or use combination of following pre-define mask:
* - \ref EADC_STATUS2_ADIF0_Msk : ADIF0 mask
* - \ref EADC_STATUS2_ADIF1_Msk : ADIF1 mask
* - \ref EADC_STATUS2_ADIF2_Msk : ADIF2 mask
* - \ref EADC_STATUS2_ADIF3_Msk : ADIF3 mask
* - \ref EADC_STATUS2_ADCMPF0_Msk : ADCMPF0 mask
* - \ref EADC_STATUS2_ADCMPF1_Msk : ADCMPF1 mask
* - \ref EADC_STATUS2_ADCMPF2_Msk : ADCMPF2 mask
* - \ref EADC_STATUS2_ADCMPF3_Msk : ADCMPF3 mask
* @return Return the user-specified interrupt flags.
* @details This macro is used to get the user-specified interrupt flags.
*/
#define EADC_GET_INT_FLAG(eadc, u32Mask) ((eadc)->STATUS2 & (u32Mask))
/**
* @brief Get the user-specified sample module overrun flags.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleMask The combination of sample module overrun status bits. Each bit corresponds to a sample module overrun status, valid range are between 1~0x7FFFF.
* @return Return the user-specified sample module overrun flags.
* @details This macro is used to get the user-specified sample module overrun flags.
*/
#define EADC_GET_SAMPLE_MODULE_OV_FLAG(eadc, u32ModuleMask) ((eadc)->OVSTS & (u32ModuleMask))
/**
* @brief Clear the selected interrupt status bits.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32Mask The combination of compare interrupt status bits. Each bit corresponds to a compare interrupt status.
* Bit 0 is ADIF0, bit 1 is ADIF1..., bit 3 is ADIF3.
* Bit 4 is ADCMPF0, bit 5 is ADCMPF1..., bit 7 is ADCMPF3.
* Or use combination of following pre-define mask:
* - \ref EADC_STATUS2_ADIF0_Msk : ADIF0 mask
* - \ref EADC_STATUS2_ADIF1_Msk : ADIF1 mask
* - \ref EADC_STATUS2_ADIF2_Msk : ADIF2 mask
* - \ref EADC_STATUS2_ADIF3_Msk : ADIF3 mask
* - \ref EADC_STATUS2_ADCMPF0_Msk : ADCMPF0 mask
* - \ref EADC_STATUS2_ADCMPF1_Msk : ADCMPF1 mask
* - \ref EADC_STATUS2_ADCMPF2_Msk : ADCMPF2 mask
* - \ref EADC_STATUS2_ADCMPF3_Msk : ADCMPF3 mask
* @return None
* @details This macro is used to clear clear the selected interrupt status bits.
*/
#define EADC_CLR_INT_FLAG(eadc, u32Mask) ((eadc)->STATUS2 = (u32Mask))
/**
* @brief Clear the selected sample module overrun status bits.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleMask The combination of sample module overrun status bits. Each bit corresponds to a sample module overrun status.
* Bit 0 is SPOVF0, bit 1 is SPOVF1..., bit 18 is SPOVF18.
* @return None
* @details This macro is used to clear the selected sample module overrun status bits.
*/
#define EADC_CLR_SAMPLE_MODULE_OV_FLAG(eadc, u32ModuleMask) ((eadc)->OVSTS = (u32ModuleMask))
/**
* @brief Check all sample module A/D result data register overrun flags.
* @param[in] eadc The pointer of the specified EADC module.
* @retval 0 None of sample module data register overrun flag is set to 1.
* @retval 1 Any one of sample module data register overrun flag is set to 1.
* @details The AOV bit (EADC_STATUS2[27]) will keep 1 when any one of sample module data register overrun flag OVn (EADC_DATn[16], n=0~18) is set to 1.
*/
#define EADC_IS_DATA_OV(eadc) (((eadc)->STATUS2 & EADC_STATUS2_AOV_Msk) >> EADC_STATUS2_AOV_Pos)
/**
* @brief Check all sample module A/D result data register valid flags.
* @param[in] eadc The pointer of the specified EADC module.
* @retval 0 None of sample module data register valid flag is set to 1.
* @retval 1 Any one of sample module data register valid flag is set to 1.
* @details The AVALID bit (EADC_STATUS2[26]) will keep 1 when any one of sample module data register valid flag VALIDn (EADC_DATn[17], n=0~18) is set to 1.
*/
#define EADC_IS_DATA_VALID(eadc) (((eadc)->STATUS2 & EADC_STATUS2_AVALID_Msk) >> EADC_STATUS2_AVALID_Pos)
/**
* @brief Check all A/D sample module start of conversion overrun flags.
* @param[in] eadc The pointer of the specified EADC module.
* @retval 0 None of sample module event overrun flag is set to 1.
* @retval 1 Any one of sample module event overrun flag is set to 1.
* @details The STOVF bit (EADC_STATUS2[25]) will keep 1 when any one of sample module event overrun flag SPOVFn (EADC_OVSTS[n], n=0~18) is set to 1.
*/
#define EADC_IS_SAMPLE_MODULE_OV(eadc) (((eadc)->STATUS2 & EADC_STATUS2_STOVF_Msk) >> EADC_STATUS2_STOVF_Pos)
/**
* @brief Check all A/D interrupt flag overrun bits.
* @param[in] eadc The pointer of the specified EADC module.
* @retval 0 None of ADINT interrupt flag is overwritten to 1.
* @retval 1 Any one of ADINT interrupt flag is overwritten to 1.
* @details The ADOVIF bit (EADC_STATUS2[24]) will keep 1 when any one of ADINT interrupt flag ADOVIFn (EADC_STATUS2[n+8], n=0~3) is overwritten to 1.
*/
#define EADC_IS_INT_FLAG_OV(eadc) (((eadc)->STATUS2 & EADC_STATUS2_ADOVIF_Msk) >> EADC_STATUS2_ADOVIF_Pos)
/**
* @brief Get the busy state of EADC.
* @param[in] eadc The pointer of the specified EADC module.
* @retval 0 Idle state.
* @retval 1 Busy state.
* @details This macro is used to read BUSY bit (EADC_STATUS2[23]) to get busy state.
*/
#define EADC_IS_BUSY(eadc) (((eadc)->STATUS2 & EADC_STATUS2_BUSY_Msk) >> EADC_STATUS2_BUSY_Pos)
/**
* @brief Configure the comparator 0 and enable it.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum specifies the compare sample module, valid values are from 0 to 18.
* @param[in] u32Condition specifies the compare condition. Valid values are:
* - \ref EADC_CMP_CMPCOND_LESS_THAN : The compare condition is "less than the compare value"
* - \ref EADC_CMP_CMPCOND_GREATER_OR_EQUAL : The compare condition is "greater than or equal to the compare value"
* @param[in] u16CMPData specifies the compare value, valid range are between 0~0xFFF.
* @param[in] u32MatchCount specifies the match count setting, valid range are between 1~0xF.
* @return None
* @details For example, EADC_ENABLE_CMP0(EADC, 5, EADC_CMP_CMPCOND_GREATER_OR_EQUAL, 0x800, 10);
* Means EADC will assert comparator 0 flag if sample module 5 conversion result is greater or
* equal to 0x800 for 10 times continuously, and a compare interrupt request is generated.
*/
#define EADC_ENABLE_CMP0(eadc,\
u32ModuleNum,\
u32Condition,\
u16CMPData,\
u32MatchCount) ((eadc)->CMP[0] = (((u32ModuleNum) << EADC_CMP_CMPSPL_Pos) |\
(u32Condition) |\
((u16CMPData) << EADC_CMP_CMPDAT_Pos) |\
(((u32MatchCount) - 1) << EADC_CMP_CMPMCNT_Pos) |\
EADC_CMP_ADCMPEN_Msk))
/**
* @brief Configure the comparator 1 and enable it.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum specifies the compare sample module, valid value are from 0 to 18.
* @param[in] u32Condition specifies the compare condition. Valid values are:
* - \ref EADC_CMP_CMPCOND_LESS_THAN : The compare condition is "less than the compare value"
* - \ref EADC_CMP_CMPCOND_GREATER_OR_EQUAL : The compare condition s "greater than or equal to the compare value"
* @param[in] u16CMPData specifies the compare value, valid range are between 0~0xFFF.
* @param[in] u32MatchCount specifies the match count setting, valid range are between 1~0xF.
* @return None
* @details For example, EADC_ENABLE_CMP1(EADC, 5, EADC_CMP_CMPCOND_GREATER_OR_EQUAL, 0x800, 10);
* Means EADC will assert comparator 1 flag if sample module 5 conversion result is greater or
* equal to 0x800 for 10 times continuously, and a compare interrupt request is generated.
*/
#define EADC_ENABLE_CMP1(eadc,\
u32ModuleNum,\
u32Condition,\
u16CMPData,\
u32MatchCount) ((eadc)->CMP[1] = (((u32ModuleNum) << EADC_CMP_CMPSPL_Pos) |\
(u32Condition) |\
((u16CMPData) << EADC_CMP_CMPDAT_Pos) |\
(((u32MatchCount) - 1) << EADC_CMP_CMPMCNT_Pos) |\
EADC_CMP_ADCMPEN_Msk))
/**
* @brief Configure the comparator 2 and enable it.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum specifies the compare sample module, valid value are from 0 to 18.
* @param[in] u32Condition specifies the compare condition. Valid values are:
* - \ref EADC_CMP_CMPCOND_LESS_THAN : The compare condition is "less than the compare value"
* - \ref EADC_CMP_CMPCOND_GREATER_OR_EQUAL : The compare condition is "greater than or equal to the compare value"
* @param[in] u16CMPData specifies the compare value, valid range are between 0~0xFFF.
* @param[in] u32MatchCount specifies the match count setting, valid range are between 0~0xF.
* @return None
* @details For example, EADC_ENABLE_CMP2(EADC, 5, EADC_CMP_CMPCOND_GREATER_OR_EQUAL, 0x800, 10);
* Means EADC will assert comparator 2 flag if sample module 5 conversion result is greater or
* equal to 0x800 for 10 times continuously, and a compare interrupt request is generated.
*/
#define EADC_ENABLE_CMP2(eadc,\
u32ModuleNum,\
u32Condition,\
u16CMPData,\
u32MatchCount) ((eadc)->CMP[2] = (((u32ModuleNum) << EADC_CMP_CMPSPL_Pos) |\
(u32Condition) |\
((u16CMPData) << EADC_CMP_CMPDAT_Pos) |\
(((u32MatchCount) - 1) << EADC_CMP_CMPMCNT_Pos) |\
EADC_CMP_ADCMPEN_Msk))
/**
* @brief Configure the comparator 3 and enable it.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum specifies the compare sample module, valid value are from 0 to 18.
* @param[in] u32Condition specifies the compare condition. Valid values are:
* - \ref EADC_CMP_CMPCOND_LESS_THAN : The compare condition is "less than the compare value"
* - \ref EADC_CMP_CMPCOND_GREATER_OR_EQUAL : The compare condition is "greater than or equal to the compare value"
* @param[in] u16CMPData specifies the compare value, valid range are between 0~0xFFF.
* @param[in] u32MatchCount specifies the match count setting, valid range are between 1~0xF.
* @return None
* @details For example, EADC_ENABLE_CMP3(EADC, 5, EADC_CMP_CMPCOND_GREATER_OR_EQUAL, 0x800, 10);
* Means EADC will assert comparator 3 flag if sample module 5 conversion result is greater or
* equal to 0x800 for 10 times continuously, and a compare interrupt request is generated.
*/
#define EADC_ENABLE_CMP3(eadc,\
u32ModuleNum,\
u32Condition,\
u16CMPData,\
u32MatchCount) ((eadc)->CMP[3] = (((u32ModuleNum) << EADC_CMP_CMPSPL_Pos) |\
(u32Condition) |\
((u16CMPData) << EADC_CMP_CMPDAT_Pos) |\
(((u32MatchCount) - 1) << EADC_CMP_CMPMCNT_Pos) |\
EADC_CMP_ADCMPEN_Msk))
/**
* @brief Enable the compare window mode.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32CMP Specifies the compare register, valid values are 0 and 2.
* @return None
* @details ADCMPF0 (EADC_STATUS2[4]) will be set when both EADC_CMP0 and EADC_CMP1 compared condition matched.
* ADCMPF2 (EADC_STATUS2[6]) will be set when both EADC_CMP2 and EADC_CMP3 compared condition matched.
*/
#define EADC_ENABLE_CMP_WINDOW_MODE(eadc, u32CMP) ((((eadc)->CMP[(u32CMP)])) |= EADC_CMP_CMPWEN_Msk)
/**
* @brief Disable the compare window mode.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32CMP Specifies the compare register, valid values are 0 and 2.
* @return None
* @details ADCMPF0 (EADC_STATUS2[4]) will be set when EADC_CMP0 compared condition matched.
* ADCMPF2 (EADC_STATUS2[6]) will be set when EADC_CMP2 compared condition matched.
*/
#define EADC_DISABLE_CMP_WINDOW_MODE(eadc, u32CMP) ((((eadc)->CMP[(u32CMP)])) &= (~EADC_CMP_CMPWEN_Msk))
/**
* @brief Enable the compare interrupt.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32CMP Specifies the compare register, valid values are from 0 to 3.
* @return None
* @details If the compare function is enabled and the compare condition matches the setting of CMPCOND (EADC_CMPn[2], n=0~3)
* and CMPMCNT (EADC_CMPn[11:8], n=0~3), ADCMPFn (EADC_STATUS2[n+4], n=0~3) will be asserted, in the meanwhile,
* if ADCMPIE (EADC_CMPn[1], n=0~3) is set to 1, a compare interrupt request is generated.
*/
#define EADC_ENABLE_CMP_INT(eadc, u32CMP) ((((eadc)->CMP[(u32CMP)])) |= EADC_CMP_ADCMPIE_Msk)
/**
* @brief Disable the compare interrupt.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32CMP Specifies the compare register, valid value are from 0 to 3.
* @return None
* @details This macro is used to disable the compare interrupt.
*/
#define EADC_DISABLE_CMP_INT(eadc, u32CMP) ((((eadc)->CMP[(u32CMP)])) &= (~EADC_CMP_ADCMPIE_Msk))
/**
* @brief Disable comparator 0.
* @param[in] eadc The pointer of the specified EADC module.
* @return None
* @details This macro is used to disable comparator 0.
*/
#define EADC_DISABLE_CMP0(eadc) ((eadc)->CMP[0] &= (~EADC_CMP_ADCMPEN_Msk))
/**
* @brief Disable comparator 1.
* @param[in] eadc The pointer of the specified EADC module.
* @return None
* @details This macro is used to disable comparator 1.
*/
#define EADC_DISABLE_CMP1(eadc) ((eadc)->CMP[1] &= (~EADC_CMP_ADCMPEN_Msk))
/**
* @brief Disable comparator 2.
* @param[in] eadc The pointer of the specified EADC module.
* @return None
* @details This macro is used to disable comparator 2.
*/
#define EADC_DISABLE_CMP2(eadc) ((eadc)->CMP[2] &= (~EADC_CMP_ADCMPEN_Msk))
/**
* @brief Disable comparator 3.
* @param[in] eadc The pointer of the specified EADC module.
* @return None
* @details This macro is used to disable comparator 3.
*/
#define EADC_DISABLE_CMP3(eadc) ((eadc)->CMP[3] &= (~EADC_CMP_ADCMPEN_Msk))
/**
* @brief Enable conversion result left alignment.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
* @return None
* @details The 12-bit conversion result will be left aligned and stored in EADC_DATn[15:4] (n=0~15).
*/
#define EADC_ENABLE_LEFT_ALIGN(eadc, u32ModuleNum) ((((eadc)->MCTL1[(u32ModuleNum)])) |= EADC_MCTL1_ALIGN_Msk)
/**
* @brief Disable conversion result left alignment.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
* @return None
* @details The 12-bit conversion result will be right aligned and stored in EADC_DATn[11:0] (n=0~15).
*/
#define EADC_DISABLE_LEFT_ALIGN(eadc, u32ModuleNum) ((((eadc)->MCTL1[(u32ModuleNum)])) &= (~EADC_MCTL1_ALIGN_Msk))
/**
* @brief Enable average mode.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
* @return None
* @details Conversion results in data register will be averaged.
* @note This average mode needs to work with accumulated mode that configured by ACU (EADC_MnCTL1[7:4], n=0~15) bit field.
*/
#define EADC_ENABLE_AVG(eadc, u32ModuleNum) ((((eadc)->MCTL1[(u32ModuleNum)])) |= EADC_MCTL1_AVG_Msk)
/**
* @brief Disable average mode.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
* @return None
* @details Conversion results in data register will not be averaged.
*/
#define EADC_DISABLE_AVG(eadc, u32ModuleNum) ((((eadc)->MCTL1[(u32ModuleNum)])) &= (~EADC_MCTL1_AVG_Msk))
/**
* @brief Configure the Accumulation feature and enable it.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum specifies the compare sample module, valid value are from 0 to 15.
* @param[in] u16ACUNum specifies the number of accumulation, valid values are
* - \ref EADC_MCTL1_ACU_1 : 1 conversion result will be accumulated.
* - \ref EADC_MCTL1_ACU_2 : 2 conversion result will be accumulated.
* - \ref EADC_MCTL1_ACU_4 : 4 conversion result will be accumulated.
* - \ref EADC_MCTL1_ACU_8 : 8 conversion result will be accumulated.
* - \ref EADC_MCTL1_ACU_16 : 16 conversion result will be accumulated.
* - \ref EADC_MCTL1_ACU_32 : 32 conversion result will be accumulated. The result is right shift 1 bit to fit within the available 16-bit register size.
* - \ref EADC_MCTL1_ACU_64 : 64 conversion result will be accumulated. The result is right shift 2 bits to fit within the available 16-bit register size.
* - \ref EADC_MCTL1_ACU_128 : 128 conversion result will be accumulated. The result is right shift 3 bits to fit within the available 16-bit register size.
* - \ref EADC_MCTL1_ACU_256 : 256 conversion result will be accumulated. The result is right shift 4 bits to fit within the available 16-bit register size.
* @return None
* @details When accumulating more than 16 samples, the result will be too large to match the
* 16-bit RESULT register size (EADC_DATn[15:0]. To avoid overflow, the result is
* right shifted automatically to fit within the available 16-bit register size.
* The number of automatic right shifts is specified in parameter list above.
*
*/
#define EADC_ENABLE_ACU(eadc,\
u32ModuleNum,\
u16ACUNum) ((((eadc)->MCTL1[(u32ModuleNum)])) = (((((eadc)->MCTL1[(u32ModuleNum)])) & (~EADC_MCTL1_ACU_Msk)) |\
(u16ACUNum)))
/**
* @brief Disable the Accumulation feature.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum specifies the compare sample module, valid value are from 0 to 15.
* @return None
*/
#define EADC_DISABLE_ACU(eadc, u32ModuleNum) ((((eadc)->MCTL1[(u32ModuleNum)])) &= (~EADC_MCTL1_ACU_Msk))
/**
* @brief Configure the Auto Power On/Off mode and enable it.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32PowerOffThreshold specifies the auto power off threshold time. Valid values are:
* - \ref EADC_PWRCTL_AUTOPDTHT_1 : Auto Power Off Threshold Time 1 EADC clock
* - \ref EADC_PWRCTL_AUTOPDTHT_2 : Auto Power Off Threshold Time 2 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_3 : Auto Power Off Threshold Time 3 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_4 : Auto Power Off Threshold Time 4 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_5 : Auto Power Off Threshold Time 5 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_6 : Auto Power Off Threshold Time 6 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_7 : Auto Power Off Threshold Time 7 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_8 : Auto Power Off Threshold Time 8 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_16 : Auto Power Off Threshold Time 16 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_32 : Auto Power Off Threshold Time 32 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_64 : Auto Power Off Threshold Time 64 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_128 : Auto Power Off Threshold Time 128 EADC clocks
* - \ref EADC_PWRCTL_AUTOPDTHT_256 : Auto Power Off Threshold Time 256 EADC clocks
* @param[in] u32PowerOnTime specifies the auto power on start-up time, valid range are between 0~0xFFF.
* @return None
* @details If the interval of time in idle state is longer than u32PowerOffThreshold, EADC will
* auto power off A/D converter analog circuit to reduce power consumption.
* EADC will automatically wakes-up when a conversion is started by software or hardware trigger.
* A start-up time is automatically inserted between the trigger event and the sampling time of the EADC.
* The start-up time = ((1/EADC_CLK) * u32PowerOnTime) and must be longer than 10us.
* @note The ADCEN bit (EADC_CTL[0]) will be set to 0 when EADC power off and set to 1 when EADC be wake-up.
*/
#define EADC_ENABLE_AUTOFF(eadc,\
u32PowerOffThreshold,\
u32PowerOnTime) ((eadc)->PWRCTL = ((u32PowerOffThreshold) |\
((u32PowerOnTime) << EADC_PWRCTL_STUPT_Pos) |\
EADC_PWRCTL_AUTOFF_Msk))
/**
* @brief Disable the Auto Power On/Off mode.
* @param[in] eadc The pointer of the specified EADC module.
* @return None
*/
#define EADC_DISABLE_AUTOFF(eadc) ((eadc)->PWRCTL &= (~EADC_PWRCTL_AUTOFF_Msk))
/**
* @brief Configure the Offset Cancellation feature and enable it.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] i16OffsetCancel specifies the signed value of offset cancellation, valid values are -16 to 15.
* @return None
* @details When i16OffsetCancel is set to 0, the offset cancellation trim bits have no effect to A/D result.
*/
#define EADC_ENABLE_OFFSETCANCEL(eadc,\
i16OffsetCancel) {(eadc)->CTL |= EADC_CTL_CALEN_Msk;\
(eadc)->OFFSETCAL = (i16OffsetCancel & EADC_OFFSETCAL_OFFSETCANCEL_Msk);}
/**
* @brief Disable the Offset Cancellation feature.
* @param[in] eadc The pointer of the specified EADC module.
* @return None
*/
#define EADC_DISABLE_OFFSETCANCEL(eadc) {(eadc)->OFFSETCAL = 0;\
(eadc)->CTL &= (~EADC_CTL_CALEN_Msk);}
/*---------------------------------------------------------------------------------------------------------*/
/* Define EADC functions prototype */
/*---------------------------------------------------------------------------------------------------------*/
void EADC_Open(EADC_T *eadc, uint32_t u32InputMode);
void EADC_Close(EADC_T *eadc);
void EADC_ConfigSampleModule(EADC_T *eadc, uint32_t u32ModuleNum, uint32_t u32TriggerSource, uint32_t u32Channel);
void EADC_SetTriggerDelayTime(EADC_T *eadc, uint32_t u32ModuleNum, uint32_t u32TriggerDelayTime, uint32_t u32DelayClockDivider);
void EADC_SetExtendSampleTime(EADC_T *eadc, uint32_t u32ModuleNum, uint32_t u32ExtendSampleTime);
/*@}*/ /* end of group EADC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group EADC_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __EADC_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,350 @@
/**************************************************************************//**
* @file ebi.h
* @version V0.10
* @brief M251 series EBI driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
****************************************************************************/
#ifndef __EBI_H__
#define __EBI_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup EBI_Driver EBI Driver
@{
*/
/** @addtogroup EBI_EXPORTED_FUNCTIONS EBI Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Miscellaneous Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define EBI_BANK0_BASE_ADDR 0x60000000UL /*!< EBI bank0 base address \hideinitializer */
#define EBI_BANK1_BASE_ADDR 0x60100000UL /*!< EBI bank1 base address \hideinitializer */
#define EBI_BANK2_BASE_ADDR 0x60200000UL /*!< EBI bank2 base address \hideinitializer */
#define EBI_MAX_SIZE 0x00100000UL /*!< Maximum EBI size for each bank is 1 MB \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Constants for EBI bank number */
/*---------------------------------------------------------------------------------------------------------*/
#define EBI_BANK0 0UL /*!< EBI bank 0 \hideinitializer */
#define EBI_BANK1 1UL /*!< EBI bank 1 \hideinitializer */
#define EBI_BANK2 2UL /*!< EBI bank 2 \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Constants for EBI data bus width */
/*---------------------------------------------------------------------------------------------------------*/
#define EBI_BUSWIDTH_8BIT 8UL /*!< EBI bus width is 8-bit \hideinitializer */
#define EBI_BUSWIDTH_16BIT 16UL /*!< EBI bus width is 16-bit \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Constants for EBI CS Active Level */
/*---------------------------------------------------------------------------------------------------------*/
#define EBI_CS_ACTIVE_LOW 0UL /*!< EBI CS active level is low \hideinitializer */
#define EBI_CS_ACTIVE_HIGH 1UL /*!< EBI CS active level is high \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Constants for EBI MCLK divider and Timing */
/*---------------------------------------------------------------------------------------------------------*/
#define EBI_MCLKDIV_1 0x0UL /*!< EBI output clock(MCLK) is HCLK/1 \hideinitializer */
#define EBI_MCLKDIV_2 0x1UL /*!< EBI output clock(MCLK) is HCLK/2 \hideinitializer */
#define EBI_MCLKDIV_4 0x2UL /*!< EBI output clock(MCLK) is HCLK/4 \hideinitializer */
#define EBI_MCLKDIV_8 0x3UL /*!< EBI output clock(MCLK) is HCLK/8 \hideinitializer */
#define EBI_MCLKDIV_16 0x4UL /*!< EBI output clock(MCLK) is HCLK/16 \hideinitializer */
#define EBI_MCLKDIV_32 0x5UL /*!< EBI output clock(MCLK) is HCLK/32 \hideinitializer */
#define EBI_MCLKDIV_64 0x6UL /*!< EBI output clock(MCLK) is HCLK/64 \hideinitializer */
#define EBI_MCLKDIV_128 0x7UL /*!< EBI output clock(MCLK) is HCLK/128 \hideinitializer */
#define EBI_TIMING_FASTEST 0x0UL /*!< EBI timing is the fastest \hideinitializer */
#define EBI_TIMING_VERYFAST 0x1UL /*!< EBI timing is very fast \hideinitializer */
#define EBI_TIMING_FAST 0x2UL /*!< EBI timing is fast \hideinitializer */
#define EBI_TIMING_NORMAL 0x3UL /*!< EBI timing is normal \hideinitializer */
#define EBI_TIMING_SLOW 0x4UL /*!< EBI timing is slow \hideinitializer */
#define EBI_TIMING_VERYSLOW 0x5UL /*!< EBI timing is very slow \hideinitializer */
#define EBI_TIMING_SLOWEST 0x6UL /*!< EBI timing is the slowest \hideinitializer */
#define EBI_OPMODE_NORMAL 0x0UL /*!< EBI bus operate in normal mode \hideinitializer */
#define EBI_OPMODE_CACCESS (EBI_CTL_CACCESS_Msk) /*!< EBI bus operate in Continuous Data Access mode \hideinitializer */
/*@}*/ /* end of group EBI_EXPORTED_CONSTANTS */
/** @addtogroup M251_EBI_EXPORTED_FUNCTIONS EBI Exported Functions
@{
*/
/**
* @brief Read 8-bit data on EBI bank0
*
* @param[in] u32Addr The data address on EBI bank0.
*
* @return 8-bit Data
*
* @details This macro is used to read 8-bit data from specify address on EBI bank0.
* \hideinitializer
*/
#define EBI0_READ_DATA8(u32Addr) (*((volatile unsigned char *)(EBI_BANK0_BASE_ADDR+(u32Addr))))
/**
* @brief Write 8-bit data to EBI bank0
*
* @param[in] u32Addr The data address on EBI bank0.
* @param[in] u32Data Specify data to be written.
*
* @return None
*
* @details This macro is used to write 8-bit data to specify address on EBI bank0.
* \hideinitializer
*/
#define EBI0_WRITE_DATA8(u32Addr, u32Data) (*((volatile unsigned char *)(EBI_BANK0_BASE_ADDR+(u32Addr))) = (u32Data))
/**
* @brief Read 16-bit data on EBI bank0
*
* @param[in] u32Addr The data address on EBI bank0.
*
* @return 16-bit Data
*
* @details This macro is used to read 16-bit data from specify address on EBI bank0.
* \hideinitializer
*/
#define EBI0_READ_DATA16(u32Addr) (*((volatile unsigned short *)(EBI_BANK0_BASE_ADDR+(u32Addr))))
/**
* @brief Write 16-bit data to EBI bank0
*
* @param[in] u32Addr The data address on EBI bank0.
* @param[in] u32Data Specify data to be written.
*
* @return None
*
* @details This macro is used to write 16-bit data to specify address on EBI bank0.
* \hideinitializer
*/
#define EBI0_WRITE_DATA16(u32Addr, u32Data) (*((volatile unsigned short *)(EBI_BANK0_BASE_ADDR+(u32Addr))) = (u32Data))
/**
* @brief Read 32-bit data on EBI bank0
*
* @param[in] u32Addr The data address on EBI bank0.
*
* @return 32-bit Data
*
* @details This macro is used to read 32-bit data from specify address on EBI bank0.
* \hideinitializer
*/
#define EBI0_READ_DATA32(u32Addr) (*((volatile unsigned int *)(EBI_BANK0_BASE_ADDR+(u32Addr))))
/**
* @brief Write 32-bit data to EBI bank0
*
* @param[in] u32Addr The data address on EBI bank0.
* @param[in] u32Data Specify data to be written.
*
* @return None
*
* @details This macro is used to write 32-bit data to specify address on EBI bank0.
* \hideinitializer
*/
#define EBI0_WRITE_DATA32(u32Addr, u32Data) (*((volatile unsigned int *)(EBI_BANK0_BASE_ADDR+(u32Addr))) = (u32Data))
/**
* @brief Read 8-bit data on EBI bank1
*
* @param[in] u32Addr The data address on EBI bank1.
*
* @return 8-bit Data
*
* @details This macro is used to read 8-bit data from specify address on EBI bank1.
* \hideinitializer
*/
#define EBI1_READ_DATA8(u32Addr) (*((volatile unsigned char *)(EBI_BANK1_BASE_ADDR+(u32Addr))))
/**
* @brief Write 8-bit data to EBI bank1
*
* @param[in] u32Addr The data address on EBI bank1.
* @param[in] u32Data Specify data to be written.
*
* @return None
*
* @details This macro is used to write 8-bit data to specify address on EBI bank1.
* \hideinitializer
*/
#define EBI1_WRITE_DATA8(u32Addr, u32Data) (*((volatile unsigned char *)(EBI_BANK1_BASE_ADDR+(u32Addr))) = (u32Data))
/**
* @brief Read 16-bit data on EBI bank1
*
* @param[in] u32Addr The data address on EBI bank1.
*
* @return 16-bit Data
*
* @details This macro is used to read 16-bit data from specify address on EBI bank1.
* \hideinitializer
*/
#define EBI1_READ_DATA16(u32Addr) (*((volatile unsigned short *)(EBI_BANK1_BASE_ADDR+(u32Addr))))
/**
* @brief Write 16-bit data to EBI bank1
*
* @param[in] u32Addr The data address on EBI bank1.
* @param[in] u32Data Specify data to be written.
*
* @return None
*
* @details This macro is used to write 16-bit data to specify address on EBI bank1.
* \hideinitializer
*/
#define EBI1_WRITE_DATA16(u32Addr, u32Data) (*((volatile unsigned short *)(EBI_BANK1_BASE_ADDR+(u32Addr))) = (u32Data))
/**
* @brief Read 32-bit data on EBI bank1
*
* @param[in] u32Addr The data address on EBI bank1.
*
* @return 32-bit Data
*
* @details This macro is used to read 32-bit data from specify address on EBI bank1.
* \hideinitializer
*/
#define EBI1_READ_DATA32(u32Addr) (*((volatile unsigned int *)(EBI_BANK1_BASE_ADDR+(u32Addr))))
/**
* @brief Write 32-bit data to EBI bank1
*
* @param[in] u32Addr The data address on EBI bank1.
* @param[in] u32Data Specify data to be written.
*
* @return None
*
* @details This macro is used to write 32-bit data to specify address on EBI bank1.
* \hideinitializer
*/
#define EBI1_WRITE_DATA32(u32Addr, u32Data) (*((volatile unsigned int *)(EBI_BANK1_BASE_ADDR+(u32Addr))) = (u32Data))
/**
* @brief Read 8-bit data on EBI bank2
*
* @param[in] u32Addr The data address on EBI bank2.
*
* @return 8-bit Data
*
* @details This macro is used to read 8-bit data from specify address on EBI bank2.
* \hideinitializer
*/
#define EBI2_READ_DATA8(u32Addr) (*((volatile unsigned char *)(EBI_BANK2_BASE_ADDR+(u32Addr))))
/**
* @brief Write 8-bit data to EBI bank2
*
* @param[in] u32Addr The data address on EBI bank2.
* @param[in] u32Data Specify data to be written.
*
* @return None
*
* @details This macro is used to write 8-bit data to specify address on EBI bank2.
* \hideinitializer
*/
#define EBI2_WRITE_DATA8(u32Addr, u32Data) (*((volatile unsigned char *)(EBI_BANK2_BASE_ADDR+(u32Addr))) = (u32Data))
/**
* @brief Read 16-bit data on EBI bank2
*
* @param[in] u32Addr The data address on EBI bank2.
*
* @return 16-bit Data
*
* @details This macro is used to read 16-bit data from specify address on EBI bank2.
* \hideinitializer
*/
#define EBI2_READ_DATA16(u32Addr) (*((volatile unsigned short *)(EBI_BANK2_BASE_ADDR+(u32Addr))))
/**
* @brief Write 16-bit data to EBI bank2
*
* @param[in] u32Addr The data address on EBI bank2.
* @param[in] u32Data Specify data to be written.
*
* @return None
*
* @details This macro is used to write 16-bit data to specify address on EBI bank2.
* \hideinitializer
*/
#define EBI2_WRITE_DATA16(u32Addr, u32Data) (*((volatile unsigned short *)(EBI_BANK2_BASE_ADDR+(u32Addr))) = (u32Data))
/**
* @brief Read 32-bit data on EBI bank2
*
* @param[in] u32Addr The data address on EBI bank2.
*
* @return 32-bit Data
*
* @details This macro is used to read 32-bit data from specify address on EBI bank2.
* \hideinitializer
*/
#define EBI2_READ_DATA32(u32Addr) (*((volatile unsigned int *)(EBI_BANK2_BASE_ADDR+(u32Addr))))
/**
* @brief Write 32-bit data to EBI bank2
*
* @param[in] u32Addr The data address on EBI bank2.
* @param[in] u32Data Specify data to be written.
*
* @return None
*
* @details This macro is used to write 32-bit data to specify address on EBI bank2.
* \hideinitializer
*/
#define EBI2_WRITE_DATA32(u32Addr, u32Data) (*((volatile unsigned int *)(EBI_BANK2_BASE_ADDR+(u32Addr))) = (u32Data))
/**
* @brief Enable EBI Write Buffer
*
* @param None
*
* @return None
*
* @details This macro is used to improve EBI write operation for EBI bank0 and bank1.
* \hideinitializer
*/
#define EBI_ENABLE_WRITE_BUFFER() (EBI->CTL0 |= EBI_CTL_WBUFEN_Msk);
/**
* @brief Disable EBI Write Buffer
*
* @param None
*
* @return None
*
* @details This macro is used to disable EBI write buffer function.
* \hideinitializer
*/
#define EBI_DISABLE_WRITE_BUFFER() (EBI->CTL0 &= ~EBI_CTL_WBUFEN_Msk);
void EBI_Open(uint32_t u32Bank, uint32_t u32DataWidth, uint32_t u32TimingClass, uint32_t u32BusMode, uint32_t u32CSActiveLevel);
void EBI_Close(uint32_t u32Bank);
void EBI_SetBusTiming(uint32_t u32Bank, uint32_t u32TimingConfig, uint32_t u32MclkDiv);
/*@}*/ /* end of group EBI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group EBI_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __EBI_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,697 @@
/**************************************************************************//**
* @file fmc.h
* @version V3.0
* @brief M251 Series Flash Memory Controller(FMC) driver header file
*
* @note
* @copyright (C) 2018 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
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Global constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define ISBEN 0
/*---------------------------------------------------------------------------------------------------------*/
/* Define Base Address */
/*---------------------------------------------------------------------------------------------------------*/
#define FMC_APROM_BASE 0x00000000UL /*!< APROM Base Address */
#define FMC_APROM_END 0x00040000UL /*!< APROM end address */
#define FMC_LDROM_BASE 0x00100000UL /*!< LDROM Base Address */
#define FMC_LDROM_END 0x00101000UL /*!< LDROM end address */
#define FMC_XOM_BASE 0x00200000UL /*!< XOM Base Address */
#define FMC_CONFIG_BASE 0x00300000UL /*!< CONFIG Base Address */
#define FMC_CONFIG0_ADDR (FMC_CONFIG_BASE) /*!< CONFIG 0 Address */
#define FMC_CONFIG1_ADDR (FMC_CONFIG_BASE + 0x4UL) /*!< CONFIG 1 Address */
#define FMC_CONFIG2_ADDR (FMC_CONFIG_BASE + 0x8UL) /*!< CONFIG 2 Address */
#define FMC_XOMR0BASE_ADDR (FMC_XOM_BASE) /*!< XOMR 0 Base Address */
#define FMC_APROM_SIZE FMC_APROM_END /*!< APROM Size */
#define FMC_LDROM_SIZE 0x1000UL /*!< LDROM Size (4 Kbytes) */
#define FMC_FLASH_PAGE_SIZE 0x200UL /*!< Flash Page Size (512 Bytes) */
#define FMC_PAGE_ADDR_MASK 0xFFFFFE00UL /*!< Flash page address mask */
/*---------------------------------------------------------------------------------------------------------*/
/* ISPCTL constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define FMC_ISPCTL_BS_LDROM 0x1UL /*!< ISPCTL setting to select to boot from LDROM */
#define FMC_ISPCTL_BS_APROM 0x0UL /*!< ISPCTL setting to select to boot from APROM */
/*---------------------------------------------------------------------------------------------------------*/
/* ISPCMD constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define FMC_ISPCMD_READ 0x00UL /*!< ISP Command: Read Flash */
#define FMC_ISPCMD_READ_UID 0x04UL /*!< ISP Command: Read Unique ID */
#define FMC_ISPCMD_READ_ALL1 0x08UL /*!< ISP Command: Read all-one result */
#define FMC_ISPCMD_READ_CID 0x0BUL /*!< ISP Command: Read Company ID */
#define FMC_ISPCMD_READ_PID 0x0CUL /*!< ISP Command: Read Device ID */
#define FMC_ISPCMD_CHECKSUM 0x0DUL /*!< ISP Command: Read Checksum */
#define FMC_ISPCMD_PROGRAM 0x21UL /*!< ISP Command: 32-bit Program Flash */
#define FMC_ISPCMD_PAGE_ERASE 0x22UL /*!< ISP Command: Page Erase Flash */
#define FMC_ISPCMD_MULTI_PROG 0x27UL /*!< ISP Command: Flash Multi-Word Program */
#define FMC_ISPCMD_RUN_ALL1 0x28UL /*!< ISP Command: Run all-one verification*/
#define FMC_ISPCMD_CAL_CHECKSUM 0x2DUL /*!< ISP Command: Run Check Calculation */
#define FMC_ISPCMD_VECMAP 0x2EUL /*!< ISP Command: Set vector mapping */
#define READ_ALLONE_YES 0xA11FFFFFUL /*!< Check-all-one result is all one. */
#define READ_ALLONE_NOT 0xA1100000UL /*!< Check-all-one result is not all one. */
#define READ_ALLONE_CMD_FAIL 0xFFFFFFFFUL /*!< Check-all-one command failed. */
/*@}*/ /* 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 ISPCTL control register to enable ISP function.
*
*/
#define FMC_ENABLE_ISP() (FMC->ISPCTL |= FMC_ISPCTL_ISPEN_Msk) /*!< Enable ISP Function */
/**
* @brief Disable ISP Function
*
* @param None
*
* @return None
*
* @details This function will clear ISPEN bit of ISPCTL control register to disable ISP function.
*
*/
#define FMC_DISABLE_ISP() (FMC->ISPCTL &= ~FMC_ISPCTL_ISPEN_Msk) /*!< Disable ISP Function */
/**
* @brief Enable LDROM Update Function
*
* @param None
*
* @return None
*
* @details This function will set LDUEN bit of ISPCTL control register to enable LDROM update function.
* User needs to set LDUEN bit before they can update LDROM.
*
*/
#define FMC_ENABLE_LD_UPDATE() (FMC->ISPCTL |= FMC_ISPCTL_LDUEN_Msk) /*!< Enable LDROM Update Function */
/**
* @brief Disable LDROM Update Function
*
* @param None
*
* @return None
*
* @details This function will set ISPEN bit of ISPCTL control register to disable LDROM update function.
*
*/
#define FMC_DISABLE_LD_UPDATE() (FMC->ISPCTL &= ~FMC_ISPCTL_LDUEN_Msk) /*!< Disable LDROM Update Function */
/**
* @brief Enable User Configuration Update Function
*
* @param None
*
* @return None
*
* @details This function will set CFGUEN bit of ISPCTL 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->ISPCTL |= FMC_ISPCTL_CFGUEN_Msk) /*!< Enable CONFIG Update Function */
/**
* @brief Disable User Configuration Update Function
*
* @param None
*
* @return None
*
* @details This function will clear CFGUEN bit of ISPCTL control register to disable User Configuration update function.
*
*/
#define FMC_DISABLE_CFG_UPDATE() (FMC->ISPCTL &= ~FMC_ISPCTL_CFGUEN_Msk) /*!< Disable CONFIG Update Function */
/**
* @brief Enable APROM Update Function
*
* @param None
*
* @return None
*
* @details This function will set APUEN bit of ISPCTL 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->ISPCTL |= FMC_ISPCTL_APUEN_Msk) /*!< Enable APROM Update Function */
/**
* @brief Disable APROM Update Function
*
* @param None
*
* @return None
*
* @details This function will clear APUEN bit of ISPCTL control register to disable APROM update function.
*
*/
#define FMC_DISABLE_AP_UPDATE() (FMC->ISPCTL &= ~FMC_ISPCTL_APUEN_Msk) /*!< Disable APROM Update Function */
/**
* @brief Next Booting Selection function
*
* @param[in] x Booting from APROM(0)/LDROM(1)
*
* @return None
*
* @details This function will set MCU next booting from LDROM/APROM.
*
* @note When use this macro, the Boot Loader booting selection MBS(CONFIG0[5]) must be set.
*
*/
#define FMC_SELECT_NEXT_BOOT(x) (FMC->ISPCTL = (FMC->ISPCTL & ~FMC_ISPCTL_BS_Msk) | ((x) << FMC_ISPCTL_BS_Pos)) /*!< Select Next Booting, x = 0 or 1 */
/**
* @brief Get MCU Booting Status
*
* @param None
*
* @return None
*
* @details This function will get status of chip next booting from LDROM/APROM.
*
*/
#define FMC_GET_BOOT_STATUS() ((FMC->ISPCTL & FMC_ISPCTL_BS_Msk)?1:0) /*!< Get MCU Booting Status */
/**
* @brief Get ISP fail flag
*
* @param None
*
* @return None
*
* @details This function will get the status of ISP falil flag
*
*/
#define FMC_GET_FAIL_FLAG() ((FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk) ? 1UL : 0UL) /*!< Get ISP fail flag */
/**
* @brief Clear ISP fail flag
*
* @param None
*
* @return None
*
* @details This function will clear the status of ISP falil flag
*
*/
#define FMC_CLR_FAIL_FLAG() (FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk) /*!< Clear ISP fail flag */
/**
* @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.
*
*/
#define FMC_DisableAPUpdate() (FMC->ISPCTL &= ~FMC_ISPCTL_APUEN_Msk) /*!< Disable AP update */
/**
* @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.
*/
#define FMC_DisableConfigUpdate() (FMC->ISPCTL &= ~FMC_ISPCTL_CFGUEN_Msk) /*!< Disable config update */
/**
* @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.
*/
#define FMC_DisableLDUpdate() (FMC->ISPCTL &= ~FMC_ISPCTL_LDUEN_Msk) /*!< Disable LD update */
/**
* @brief Enable APROM update function
*
* @param None
*
* @return None
*
* @details Enable APROM to be able to program when boot from APROM.
*
*/
#define FMC_EnableAPUpdate() (FMC->ISPCTL |= FMC_ISPCTL_APUEN_Msk) /*!< Enable AP update */
/**
* @brief Enable User Configuration update function
*
* @param None
*
* @return None
*
* @details Enable User Configuration to be able to program.
*
*/
#define FMC_EnableConfigUpdate() (FMC->ISPCTL |= FMC_ISPCTL_CFGUEN_Msk) /*!< Enable config update */
/**
* @brief Enable LDROM update function
*
* @param None
*
* @return None
*
* @details Enable LDROM to be able to program.
*
*/
#define FMC_EnableLDUpdate() (FMC->ISPCTL |= FMC_ISPCTL_LDUEN_Msk) /*!< Enable LD update */
/*---------------------------------------------------------------------------------------------------------*/
/* inline functions */
/*---------------------------------------------------------------------------------------------------------*/
static __INLINE uint32_t FMC_ReadUID(uint8_t u8Index);
static __INLINE uint32_t FMC_ReadCID(void);
static __INLINE uint32_t FMC_ReadPID(void);
static __INLINE uint32_t FMC_ReadUCID(uint32_t u32Index);
static __INLINE uint32_t FMC_ReadVBGCode(void);
static __INLINE uint32_t FMC_ReadVTEMPCode(void);
static __INLINE uint32_t FMC_ReadADCOffset(void);
static __INLINE void FMC_SetVectorPageAddr(uint32_t u32PageAddr);
static __INLINE uint32_t FMC_GetVECMAP(void);
static __INLINE uint32_t FMC_GetCheckSum(uint32_t u32Addr, int32_t i32Size);
static __INLINE void FMC_Write128(uint32_t u32Addr, uint32_t pu32Buf[]);
/**
* @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;
FMC->ISPADDR = ((uint32_t)u8Index << 2u);
FMC->ISPDAT = 0u;
FMC->ISPTRG = 0x1u;
#if ISBEN
__ISB();
#endif
while (FMC->ISPTRG) {}
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->ISPADDR = 0x0u; /* Must keep 0x0 when read CID */
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
#if ISBEN
__ISB();
#endif /* 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_PID; /* Set ISP Command Code */
FMC->ISPADDR = 0x04u; /* Must keep 0x4 when read PID */
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
#if ISBEN
__ISB();
#endif /* 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->ISPADDR = (0x04u * u32Index) + 0x10u; /* The UCID is at offset 0x10 with word alignment. */
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
#if ISBEN
__ISB();
#endif /* To make sure ISP/CPU be Synchronized */
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) {} /* Waiting for ISP Done */
return FMC->ISPDAT;
}
/**
* @brief To read bang-gap voltage code
*
* @param[in] None
*
* @return The bang-gap voltage code
*
* @details This function is used to read bang-gap voltage code
*
*/
static __INLINE uint32_t FMC_ReadVBGCode(void)
{
FMC->ISPCMD = FMC_ISPCMD_READ_UID; /* Set ISP Command Code */
FMC->ISPADDR = 0x70; /* The VBG is at offset 0x70 with word alignment. */
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
#if ISBEN
__ISB();
#endif /* To make sure ISP/CPU be Synchronized */
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) {} /* Waiting for ISP Done */
return FMC->ISPDAT;
}
/**
* @brief To read the temperature sensor ADC code
*
* @param[in] None
*
* @return The temperature sensor ADC code
*
* @details This function is used to read temperature sensor ADC code
*
*/
static __INLINE uint32_t FMC_ReadVTEMPCode(void)
{
FMC->ISPCMD = FMC_ISPCMD_READ_UID; /* Set ISP Command Code */
FMC->ISPADDR = 0x74; /* The VTEMP code is at offset 0x74 with word alignment */
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
#if ISBEN
__ISB();
#endif /* To make sure ISP/CPU be Synchronized */
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) {} /* Waiting for ISP Done */
return FMC->ISPDAT;
}
/**
* @brief To read the calibration value for ADC offset
*
* @param[in] None
*
* @return The calibration value for ADC offset
*
* @details This function is used to read the calibration value for ADC offset
*
*/
static __INLINE uint32_t FMC_ReadADCOffset(void)
{
FMC->ISPCMD = FMC_ISPCMD_READ_UID; /* Set ISP Command Code */
FMC->ISPADDR = 0x78; /* The calibration value for ADC offset is at offset 0x78 with word alignment */
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */
#if ISBEN
__ISB();
#endif /* 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 To set VECMAP to remap specified page address to 0x0.
*
* @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->ISPADDR = u32PageAddr; /* The address of specified page which will be map to address 0x0. It must be page alignment. */
FMC->ISPTRG = 0x1u; /* Trigger to start ISP procedure */
#if ISBEN
__ISB();
#endif /* 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->ISPSTS & FMC_ISPSTS_VECMAP_Msk);
}
/**
* @brief Get Flash Checksum
*
* @param[in] u32Addr Specific flash start address
* @param[in] i32Size Specific a size of Flash area
*
* @return A checksum value of a flash block.
*
* @details To get VECMAP value which is the page address for remapping to vector page (0x0).
*
*/
static __INLINE uint32_t FMC_GetCheckSum(uint32_t u32Addr, int32_t i32Size)
{
FMC->ISPCMD = FMC_ISPCMD_CAL_CHECKSUM;
FMC->ISPADDR = u32Addr;
FMC->ISPDAT = (uint32_t)i32Size;
FMC->ISPTRG = 0x1u;
#if ISBEN
__ISB();
#endif
while (FMC->ISPTRG) {}
FMC->ISPCMD = FMC_ISPCMD_CHECKSUM;
FMC->ISPTRG = 0x1u;
while (FMC->ISPTRG) {}
return FMC->ISPDAT;
}
/**
* @brief Program Multi-Word data into specified address of flash
*
* @param[in] u32Addr Flash address include APROM, LDROM, Data Flash, and CONFIG
* @param[in] pu32Buf A data pointer is point to a data buffer start address;
*
* @return None
*
* @details To program multi-words data into Flash include APROM, LDROM, and CONFIG.
*
*/
static __INLINE void FMC_Write128(uint32_t u32Addr, uint32_t pu32Buf[])
{
uint32_t i, idx, u32OnProg;
int32_t err;
idx = 0u;
FMC->ISPCMD = FMC_ISPCMD_MULTI_PROG;
FMC->ISPADDR = u32Addr;
do
{
err = 0;
u32OnProg = 1u;
FMC->MPDAT0 = pu32Buf[idx + 0u];
FMC->MPDAT1 = pu32Buf[idx + 1u];
FMC->MPDAT2 = pu32Buf[idx + 2u];
FMC->MPDAT3 = pu32Buf[idx + 3u];
FMC->ISPTRG = 0x1u;
idx += 4u;
for (i = idx; i < 128u / 4u; i += 4u) /* Max data length is 128 bytes (128/4 words)*/
{
__set_PRIMASK(1u); /* Mask interrupt to avoid status check coherence error*/
do
{
if ((FMC->MPSTS & FMC_MPSTS_MPBUSY_Msk) == 0u)
{
__set_PRIMASK(0u);
FMC->ISPADDR = FMC->MPADDR & (~0xful);
idx = (FMC->ISPADDR - u32Addr) / 4u;
err = -1;
}
}
while ((FMC->MPSTS & (3u << FMC_MPSTS_D0_Pos)) && (err == 0));
if (err == 0)
{
/* Update new data for D0 */
FMC->MPDAT0 = pu32Buf[i];
FMC->MPDAT1 = pu32Buf[i + 1u];
do
{
if ((FMC->MPSTS & FMC_MPSTS_MPBUSY_Msk) == 0u)
{
__set_PRIMASK(0u);
FMC->ISPADDR = FMC->MPADDR & (~0xful);
idx = (FMC->ISPADDR - u32Addr) / 4u;
err = -1;
}
}
while ((FMC->MPSTS & (3u << FMC_MPSTS_D2_Pos)) && (err == 0));
if (err == 0)
{
/* Update new data for D2*/
FMC->MPDAT2 = pu32Buf[i + 2u];
FMC->MPDAT3 = pu32Buf[i + 3u];
__set_PRIMASK(0u);
}
}
if (err < 0)
{
break;
}
}
if (err == 0)
{
u32OnProg = 0u;
while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) {}
}
}
while (u32OnProg);
}
void FMC_Open(void);
void FMC_Close(void);
int32_t FMC_ReadConfig(uint32_t u32Config[], uint32_t u32Count);
int32_t FMC_WriteConfig(uint32_t u32Config[], uint32_t u32Count);
void FMC_SetBootSource(int32_t i32BootSrc);
int32_t FMC_GetBootSource(void);
uint32_t FMC_CheckAllOne(uint32_t u32addr, uint32_t u32count);
uint32_t FMC_GetChkSum(uint32_t u32addr, uint32_t u32count);
int32_t FMC_Is_XOM_Actived(uint32_t xom_num);
int32_t FMC_Erase_XOM(uint32_t xom_num);
int32_t FMC_Erase(uint32_t u32Addr);
int32_t FMC_Config_XOM(uint32_t xom_num, uint32_t xom_base, uint8_t xom_page);
uint32_t FMC_Read(uint32_t u32Addr);
void FMC_Write(uint32_t u32Addr, uint32_t u32Data);
/*@}*/ /* end of group FMC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group FMC_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __FMC_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,473 @@
/**************************************************************************//**
* @file crc.h
* @version V0.10
* @brief M251 series GPIO driver header file
*
* @copyright (C) 2018 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 16UL /*!< Specify Maximum Pins of Each GPIO Port */
/* 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 PC14 GPIO_PIN_DATA(2, 14) /*!< Specify PC.14 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 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 */
#define PF4 GPIO_PIN_DATA(5, 4 ) /*!< Specify PF.4 Pin Data Input/Output */
#define PF5 GPIO_PIN_DATA(5, 5 ) /*!< Specify PF.5 Pin Data Input/Output */
#define PF6 GPIO_PIN_DATA(5, 6 ) /*!< Specify PF.6 Pin Data Input/Output */
#define PF7 GPIO_PIN_DATA(5, 7 ) /*!< Specify PF.7 Pin Data Input/Output */
#define PF14 GPIO_PIN_DATA(5, 14) /*!< Specify PF.14 Pin Data Input/Output */
/*---------------------------------------------------------------------------------------------------------*/
/* PMD Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_MODE_INPUT 0x0UL /*!< Input Mode */
#define GPIO_MODE_OUTPUT 0x1UL /*!< Output Mode */
#define GPIO_MODE_OPEN_DRAIN 0x2UL /*!< Open-Drain Mode */
#define GPIO_MODE_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 */
/*---------------------------------------------------------------------------------------------------------*/
/* GPIO_INTTYPE Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_INTTYPE_EDGE 0UL /*!< GPIO_INTTYPE Setting for Edge Trigger Mode */
#define GPIO_INTTYPE_LEVEL 1UL /*!< GPIO_INTTYPE Setting for Edge Level Mode */
/*---------------------------------------------------------------------------------------------------------*/
/* GPIO Slew Rate Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_SLEWCTL_NORMAL 0x0UL /*!< GPIO slew setting for nornal Mode */
#define GPIO_SLEWCTL_HIGH 0x1UL /*!< GPIO slew setting for high Mode */
/*---------------------------------------------------------------------------------------------------------*/
/* GPIO Pull-up And Pull-down Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_PUSEL_DISABLE 0x0UL /*!< GPIO PUSEL setting for Disable Mode */
#define GPIO_PUSEL_PULL_UP 0x1UL /*!< GPIO PUSEL setting for Pull-up Mode */
#define GPIO_PUSEL_PULL_DOWN 0x2UL /*!< GPIO PUSEL setting for Pull-down Mode */
/*---------------------------------------------------------------------------------------------------------*/
/* GPIO_DBCTL Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_DBCTL_ICLK_ON 0x003F0000UL /*!< GPIO_DBCTL setting for all IO pins edge detection circuit is always active after reset */
#define GPIO_DBCTL_ICLK_OFF 0x00000000UL /*!< GPIO_DBCTL setting for edge detection circuit is active only if IO pin corresponding GPIOx_IEN bit is set to 1 */
#define GPIO_DBCTL_DBCLKSRC_LIRC 0x00000010UL /*!< GPIO_DBCTL setting for de-bounce counter clock source is the internal 32k Hz */
#define GPIO_DBCTL_DBCLKSRC_HCLK 0x00000000UL /*!< GPIO_DBCTL setting for de-bounce counter clock source is the HCLK */
#define GPIO_DBCTL_DBCLKSEL_1 0x00000000UL /*!< GPIO_DBCTL setting for sampling cycle = 1 clocks */
#define GPIO_DBCTL_DBCLKSEL_2 0x00000001UL /*!< GPIO_DBCTL setting for sampling cycle = 2 clocks */
#define GPIO_DBCTL_DBCLKSEL_4 0x00000002UL /*!< GPIO_DBCTL setting for sampling cycle = 4 clocks */
#define GPIO_DBCTL_DBCLKSEL_8 0x00000003UL /*!< GPIO_DBCTL setting for sampling cycle = 8 clocks */
#define GPIO_DBCTL_DBCLKSEL_16 0x00000004UL /*!< GPIO_DBCTL setting for sampling cycle = 16 clocks */
#define GPIO_DBCTL_DBCLKSEL_32 0x00000005UL /*!< GPIO_DBCTL setting for sampling cycle = 32 clocks */
#define GPIO_DBCTL_DBCLKSEL_64 0x00000006UL /*!< GPIO_DBCTL setting for sampling cycle = 64 clocks */
#define GPIO_DBCTL_DBCLKSEL_128 0x00000007UL /*!< GPIO_DBCTL setting for sampling cycle = 128 clocks */
#define GPIO_DBCTL_DBCLKSEL_256 0x00000008UL /*!< GPIO_DBCTL setting for sampling cycle = 256 clocks */
#define GPIO_DBCTL_DBCLKSEL_512 0x00000009UL /*!< GPIO_DBCTL setting for sampling cycle = 512 clocks */
#define GPIO_DBCTL_DBCLKSEL_1024 0x0000000AUL /*!< GPIO_DBCTL setting for sampling cycle = 1024 clocks */
#define GPIO_DBCTL_DBCLKSEL_2048 0x0000000BUL /*!< GPIO_DBCTL setting for sampling cycle = 2048 clocks */
#define GPIO_DBCTL_DBCLKSEL_4096 0x0000000CUL /*!< GPIO_DBCTL setting for sampling cycle = 4096 clocks */
#define GPIO_DBCTL_DBCLKSEL_8192 0x0000000DUL /*!< GPIO_DBCTL setting for sampling cycle = 8192 clocks */
#define GPIO_DBCTL_DBCLKSEL_16384 0x0000000EUL /*!< GPIO_DBCTL setting for sampling cycle = 16384 clocks */
#define GPIO_DBCTL_DBCLKSEL_32768 0x0000000FUL /*!< GPIO_DBCTL setting for sampling cycle = 32768 clocks */
/**
* @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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
*
* @return None
*
* @details Clear the interrupt status of specified GPIO pin.
*/
#define GPIO_CLR_INT_FLAG(port, u32PinMask) ((port)->INTSRC = (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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
*
* @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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
*
* @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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
*
* @return None
*
* @details Disable I/O digital input path of specified GPIO pin.
*/
#define GPIO_DISABLE_DIGITAL_PATH(port, u32PinMask) ((port)->DINOFF |= ((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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
*
* @return None
*
* @details Enable I/O digital input path of specified GPIO pin.
*/
#define GPIO_ENABLE_DIGITAL_PATH(port, u32PinMask) ((port)->DINOFF &= ~((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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
*
* @return None
*
* @details Disable I/O DOUT mask of specified GPIO pin.
*/
#define GPIO_DISABLE_DOUT_MASK(port, u32PinMask) ((port)->DATMSK &= ~(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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
*
* @return None
*
* @details Enable I/O DOUT mask of specified GPIO pin.
*/
#define GPIO_ENABLE_DOUT_MASK(port, u32PinMask) ((port)->DATMSK |= (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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
*
* @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)->INTSRC & (u32PinMask))
/**
* @brief Set De-bounce Sampling Cycle Time
*
* @param[in] u32ClkSrc The de-bounce counter clock source. It could be GPIO_DBCTL_DBCLKSRC_HCLK or GPIO_DBCTL_DBCLKSRC_LIRC.
* @param[in] u32ClkSel The de-bounce sampling cycle selection. It could be
* - \ref GPIO_DBCTL_DBCLKSEL_1
* - \ref GPIO_DBCTL_DBCLKSEL_2
* - \ref GPIO_DBCTL_DBCLKSEL_4
* - \ref GPIO_DBCTL_DBCLKSEL_8
* - \ref GPIO_DBCTL_DBCLKSEL_16
* - \ref GPIO_DBCTL_DBCLKSEL_32
* - \ref GPIO_DBCTL_DBCLKSEL_64
* - \ref GPIO_DBCTL_DBCLKSEL_128
* - \ref GPIO_DBCTL_DBCLKSEL_256
* - \ref GPIO_DBCTL_DBCLKSEL_512
* - \ref GPIO_DBCTL_DBCLKSEL_1024
* - \ref GPIO_DBCTL_DBCLKSEL_2048
* - \ref GPIO_DBCTL_DBCLKSEL_4096
* - \ref GPIO_DBCTL_DBCLKSEL_8192
* - \ref GPIO_DBCTL_DBCLKSEL_16384
* - \ref GPIO_DBCTL_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_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_4). \n
* It's meaning the debounce counter clock source is internal 38.4 KHz and sampling cycle selection is 4. \n
* Then the target de-bounce sampling cycle time is (4)*(1/(38.4*1000)) s = 1.04*0.0001 s = 104 us,
* and system will sampling interrupt input once per 104 us.
* Note: all GPIO ports use the same debounce source clock and de-bounce sampling cycle, but each port can close
* its clock source for power saving by setting ICLKONx bit to 0.
*/
#define GPIO_SET_DEBOUNCE_TIME(u32ClkSrc, u32ClkSel) (GPIO->DBCTL = ((GPIO_DBCTL_ICLK_ON) | (u32ClkSrc) | (u32ClkSel) ))
/**
* @brief Set GPIO Interrupt Clock on bit
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
*
* @return None
*
* @details Set the I/O pins edge detection circuit always active after reset for specified port.
*/
#define GPIO_SET_DEBOUNCE_ICLKON(port) (GPIO->DBCTL |= ((0x1UL << ((((uint32_t)port - (uint32_t)GPIO_BASE) / 0x40) + 16))))
/**
* @brief Clear GPIO Interrupt Clock on bit
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF.
*
* @return None
*
* @details Set edge detection circuit active only if I/O pin edge interrupt enabled for specified port
*/
#define GPIO_CLR_DEBOUNCE_ICLKON(port) (GPIO->DBCTL &= ~((0x1UL << ((((uint32_t)port - (uint32_t)GPIO_BASE) / 0x40) + 16))))
/**
* @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
*
* @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 BIT0 ~ BIT15 for PA, PB, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
*
* @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_EnableEINT GPIO_EnableInt
/**
* @brief Disable External 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 BIT0 ~ BIT15 for PA, PB, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
#define GPIO_DisableEINT 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);
void GPIO_SetSlewCtl(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode);
void GPIO_SetPullCtl(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode);
/*@}*/ /* end of group GPIO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group GPIO_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __GPIO_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,488 @@
/**************************************************************************//**
* @file I2C.h
* @version V0.10
* @brief M251 Series I2C Driver Header File
*
* @copyright (C) 2018 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
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* I2C_CTL constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define I2C_CTL_STA_SI 0x28UL /*!< I2C_CTL setting for I2C control bits. It would set STA and SI bits */
#define I2C_CTL_STA_SI_AA 0x2CUL /*!< I2C_CTL setting for I2C control bits. It would set STA, SI and AA bits */
#define I2C_CTL_STO_SI 0x18UL /*!< I2C_CTL setting for I2C control bits. It would set STO and SI bits */
#define I2C_CTL_STO_SI_AA 0x1CUL /*!< I2C_CTL setting for I2C control bits. It would set STO, SI and AA bits */
#define I2C_CTL_SI 0x08UL /*!< I2C_CTL setting for I2C control bits. It would set SI bit */
#define I2C_CTL_SI_AA 0x0CUL /*!< I2C_CTL setting for I2C control bits. It would set SI and AA bits */
#define I2C_CTL_STA 0x20UL /*!< I2C_CTL setting for I2C control bits. It would set STA bit */
#define I2C_CTL_STO 0x10UL /*!< I2C_CTL setting for I2C control bits. It would set STO bit */
#define I2C_CTL_AA 0x04UL /*!< I2C_CTL setting for I2C control bits. It would set AA bit */
/*---------------------------------------------------------------------------------------------------------*/
/* I2C GCMode constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define I2C_GCMODE_ENABLE 1 /*!< Enable I2C GC Mode */
#define I2C_GCMODE_DISABLE 0 /*!< Disable I2C GC Mode */
/*---------------------------------------------------------------------------------------------------------*/
/* I2C SMBUS constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define I2C_SMBH_ENABLE 1 /*!< Enable SMBus Host Mode enable */
#define I2C_SMBD_ENABLE 0 /*!< Enable SMBus Device Mode enable */
#define I2C_PECTX_ENABLE 1 /*!< Enable SMBus Packet Error Check Transmit function */
#define I2C_PECTX_DISABLE 0 /*!< Disable SMBus Packet Error Check Transmit function */
/*@}*/ /* 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 I2C_CTL register to control I2C bus conditions of START, STOP, SI, ACK.
*/
#define I2C_SET_CONTROL_REG(i2c, u8Ctrl) ((i2c)->CTL0 = ((i2c)->CTL0 & ~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 I2C_CTL register.
*/
#define I2C_START(i2c) ((i2c)->CTL0 = ((i2c)->CTL0 & ~I2C_CTL0_SI_Msk) | I2C_CTL0_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 I2C_CTL register.
*/
#define I2C_WAIT_READY(i2c) while(!((i2c)->CTL0 & I2C_CTL0_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)->DAT)
/**
* @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 I2C_DAT register, the I2C controller will shift it to I2C bus.
*/
#define I2C_SET_DATA(i2c, u8Data) ((i2c)->DAT = (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)->STATUS0)
/**
* @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)->TOCTL & I2C_TOCTL_TOIF_Msk) == I2C_TOCTL_TOIF_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)->WKSTS & I2C_WKSTS_WKIF_Msk) == I2C_WKSTS_WKIF_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)->WKSTS = I2C_WKSTS_WKIF_Msk)
/**
* @brief To get SMBus Status
*
* @param[in] i2c Specify I2C port
*
* @return SMBus status
*
* @details To get the Bus Management status of I2C_BUSSTS register
*
*/
#define I2C_SMBUS_GET_STATUS(i2c) ((i2c)->BUSSTS)
/**
* @brief Get SMBus CRC value
*
* @param[in] i2c Specify I2C port
*
* @return Packet error check byte value
*
* @details The CRC check value after a transmission or a reception by count by using CRC8
*
*/
#define I2C_SMBUS_GET_PEC_VALUE(i2c) ((i2c)->PKTCRC)
/**
* @brief Set SMBus Bytes number of Transmission or reception
*
* @param[in] i2c Specify I2C port
* @param[in] u32PktSize Transmit / Receive bytes
*
* @return None
*
* @details The transmission or receive byte number in one transaction when PECEN is set. The maximum is 255 bytes.
*
*/
#define I2C_SMBUS_SET_PACKET_BYTE_COUNT(i2c, u32PktSize) ((i2c)->PKTSIZE = (u32PktSize))
/**
* @brief Enable SMBus Alert function
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details Device Mode(BMHEN=0): If ALERTEN(I2C_BUSCTL[4]) is set, the Alert pin will pull lo, and reply ACK when get ARP from host
* Host Mode(BMHEN=1): If ALERTEN(I2C_BUSCTL[4]) is set, the Alert pin is supported to receive alert state(Lo trigger)
*
*/
#define I2C_SMBUS_ENABLE_ALERT(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_ALERTEN_Msk)
/**
* @brief Disable SMBus Alert pin function
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details Device Mode(BMHEN=0): If ALERTEN(I2C_BUSCTL[4]) is clear, the Alert pin will pull hi, and reply NACK when get ARP from host
* Host Mode(BMHEN=1): If ALERTEN(I2C_BUSCTL[4]) is clear, the Alert pin is not supported to receive alert state(Lo trigger)
*
*/
#define I2C_SMBUS_DISABLE_ALERT(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_ALERTEN_Msk)
/**
* @brief Set SMBus SUSCON pin is output mode
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details This function to set SUSCON(I2C_BUSCTL[6]) pin is output mode.
*
*
*/
#define I2C_SMBUS_SET_SUSCON_OUT(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_SCTLOEN_Msk)
/**
* @brief Set SMBus SUSCON pin is input mode
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details This function to set SUSCON(I2C_BUSCTL[6]) pin is input mode.
*
*
*/
#define I2C_SMBUS_SET_SUSCON_IN(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_SCTLOEN_Msk)
/**
* @brief Set SMBus SUSCON pin output high state
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details This function to set SUSCON(I2C_BUSCTL[6]) pin is output hi state.
*
*/
#define I2C_SMBUS_SET_SUSCON_HIGH(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_SCTLOSTS_Msk)
/**
* @brief Set SMBus SUSCON pin output low state
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details This function to set SUSCON(I2C_BUSCTL[6]) pin is output lo state.
*
*/
#define I2C_SMBUS_SET_SUSCON_LOW(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_SCTLOSTS_Msk)
/**
* @brief Enable SMBus Acknowledge control by manual
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details The 9th bit can response the ACK or NACK according the received data by user. When the byte is received, SCLK line stretching to low between the 8th and 9th SCLK pulse.
*
*/
#define I2C_SMBUS_ACK_MANUAL(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_ACKMEN_Msk)
/**
* @brief Disable SMBus Acknowledge control by manual
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details Disable acknowledge response control by user.
*
*/
#define I2C_SMBUS_ACK_AUTO(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_ACKMEN_Msk)
/**
* @brief Enable SMBus Acknowledge manual interrupt
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details This function is used to enable SMBUS acknowledge manual interrupt on the 9th clock cycle when SMBUS=1 and ACKMEN=1
*
*/
#define I2C_SMBUS_9THBIT_INT_ENABLE(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_ACKM9SI_Msk)
/**
* @brief Disable SMBus Acknowledge manual interrupt
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details This function is used to disable SMBUS acknowledge manual interrupt on the 9th clock cycle when SMBUS=1 and ACKMEN=1
*
*/
#define I2C_SMBUS_9THBIT_INT_DISABLE(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_ACKM9SI_Msk)
/**
* @brief Enable SMBus PEC clear at REPEAT START
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details This function is used to enable the condition of REAEAT START can clear the PEC calculation.
*
*/
#define I2C_SMBUS_RST_PEC_AT_START_ENABLE(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_PECCLR_Msk)
/**
* @brief Disable SMBus PEC clear at Repeat START
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details This function is used to disable the condition of Repeat START can clear the PEC calculation.
*
*/
#define I2C_SMBUS_RST_PEC_AT_START_DISABLE(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_PECCLR_Msk)
/**
* @brief Enable RX PDMA function.
* @param[in] i2c The pointer of the specified I2C module.
* @return None.
* @details Set RXPDMAEN bit of I2C_CTL1 register to enable RX PDMA transfer function.
* \hideinitializer
*/
#define I2C_ENABLE_RX_PDMA(i2c) ((i2c)->CTL1 |= I2C_CTL1_RXPDMAEN_Msk)
/**
* @brief Enable TX PDMA function.
* @param[in] i2c The pointer of the specified I2C module.
* @return None.
* @details Set TXPDMAEN bit of I2C_CTL1 register to enable TX PDMA transfer function.
* \hideinitializer
*/
#define I2C_ENABLE_TX_PDMA(i2c) ((i2c)->CTL1 |= I2C_CTL1_TXPDMAEN_Msk)
/**
* @brief Disable RX PDMA transfer.
* @param[in] i2c The pointer of the specified I2C module.
* @return None.
* @details Clear RXPDMAEN bit of I2C_CTL1 register to disable RX PDMA transfer function.
* \hideinitializer
*/
#define I2C_DISABLE_RX_PDMA(i2c) ((i2c)->CTL1 &= ~I2C_CTL1_RXPDMAEN_Msk)
/**
* @brief Disable TX PDMA transfer.
* @param[in] i2c The pointer of the specified I2C module.
* @return None.
* @details Clear TXPDMAEN bit of I2C_CTL1 register to disable TX PDMA transfer function.
* \hideinitializer
*/
#define I2C_DISABLE_TX_PDMA(i2c) ((i2c)->CTL1 &= ~I2C_CTL1_TXPDMAEN_Msk)
/**
* @brief Enable PDMA stretch function.
* @param[in] i2c The pointer of the specified I2C module.
* @return None.
* @details Enable this function is to stretch bus by hardware after PDMA transfer is done if SI is not cleared.
* \hideinitializer
*/
#define I2C_ENABLE_PDMA_STRETCH(i2c) ((i2c)->CTL1 |= I2C_CTL1_PDMASTR_Msk)
/**
* @brief Disable PDMA stretch function.
* @param[in] i2c The pointer of the specified I2C module.
* @return None.
* @details I2C will send STOP after PDMA transfers done automatically.
* \hideinitializer
*/
#define I2C_DISABLE_PDMA_STRETCH(i2c) ((i2c)->CTL1 &= ~I2C_CTL1_PDMASTR_Msk)
/**
* @brief Reset PDMA function.
* @param[in] i2c The pointer of the specified I2C module.
* @return None.
* @details I2C PDMA engine will be reset after this function is called.
* \hideinitializer
*/
#define I2C_DISABLE_RST_PDMA(i2c) ((i2c)->CTL1 |= I2C_CTL1_PDMARST_Msk)
/*---------------------------------------------------------------------------------------------------------*/
/* inline functions */
/*---------------------------------------------------------------------------------------------------------*/
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
__STATIC_INLINE void I2C_STOP(I2C_T *i2c);
/**
* @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 I2C_CTL register.
*/
__STATIC_INLINE void I2C_STOP(I2C_T *i2c)
{
(i2c)->CTL0 |= (I2C_CTL0_SI_Msk | I2C_CTL0_STO_Msk);
while (i2c->CTL0 & I2C_CTL0_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_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);
uint32_t I2C_SetBusClockFreq(I2C_T *i2c, uint32_t u32BusClock);
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);
uint8_t I2C_WriteByte(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t data);
uint32_t I2C_WriteMultiBytes(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t data[], uint32_t u32wLen);
uint8_t I2C_WriteByteOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t data);
uint32_t I2C_WriteMultiBytesOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t data[], uint32_t u32wLen);
uint8_t I2C_WriteByteTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t data);
uint32_t I2C_WriteMultiBytesTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t data[], uint32_t u32wLen);
uint8_t I2C_ReadByte(I2C_T *i2c, uint8_t u8SlaveAddr);
uint32_t I2C_ReadMultiBytes(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t rdata[], uint32_t u32rLen);
uint8_t I2C_ReadByteOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr);
uint32_t I2C_ReadMultiBytesOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t rdata[], uint32_t u32rLen);
uint8_t I2C_ReadByteTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr);
uint32_t I2C_ReadMultiBytesTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t rdata[], uint32_t u32rLen);
uint32_t I2C_SMBusGetStatus(I2C_T *i2c);
void I2C_SMBusClearInterruptFlag(I2C_T *i2c, uint8_t u8ClrSMBusIntFlag);
void I2C_SMBusSetPacketByteCount(I2C_T *i2c, uint32_t u32PktSize);
void I2C_SMBusOpen(I2C_T *i2c, uint8_t u8HostDevice);
void I2C_SMBusClose(I2C_T *i2c);
void I2C_SMBusPECTxEnable(I2C_T *i2c, uint8_t u8PECTxEn);
uint8_t I2C_SMBusGetPECValue(I2C_T *i2c);
void I2C_SMBusIdleTimeout(I2C_T *i2c, uint32_t us, uint32_t u32Hclk);
void I2C_SMBusTimeout(I2C_T *i2c, uint32_t ms, uint32_t u32Pclk);
void I2C_SMBusClockLoTimeout(I2C_T *i2c, uint32_t ms, uint32_t u32Pclk);
/*@}*/ /* end of group I2C_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group I2C_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __I2C_H__ */

View File

@@ -0,0 +1,201 @@
/**************************************************************************//**
* @file opa.h
* @version V1.00
* @brief M251 series OPA driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __OPA_H__
#define __OPA_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup OPA_Driver OPA Driver
@{
*/
/** @addtogroup OPA_EXPORTED_CONSTANTS OPA Exported Constants
@{
*/
#define OPA_CALIBRATION_CLK_1K (0UL) /*!< OPA calibration clock select 1 KHz \hideinitializer */
#define OPA_CALIBRATION_RV_1_2_AVDD (0UL) /*!< OPA calibration reference voltage select 1/2 AVDD \hideinitializer */
#define OPA_CALIBRATION_RV_H_L_VCM (1UL) /*!< OPA calibration reference voltage select from high vcm to low vcm \hideinitializer */
/*@}*/ /* end of group OPA_EXPORTED_CONSTANTS */
/** @addtogroup OPA_EXPORTED_FUNCTIONS OPA Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Define OPA functions prototype */
/*---------------------------------------------------------------------------------------------------------*/
__STATIC_INLINE int32_t OPA_Calibration(OPA_T *opa, uint32_t u32OpaNum, uint32_t u32ClockSel, uint32_t u32RefVol);
/**
* @brief This macro is used to power on the OPA circuit
* @param[in] opa The pointer of the specified OPA module
* @param[in] u32OpaNum The OPA number. 0 for OPA0.
* @return None
* @details This macro will set OPENx (x=0) bit of OPA_CTL register to power on the OPA circuit.
* \hideinitializer
*/
#define OPA_POWER_ON(opa, u32OpaNum) ((opa)->CTL |= (1UL<<(OPA_CTL_OPEN0_Pos+(u32OpaNum))))
/**
* @brief This macro is used to power down the OPA circuit
* @param[in] opa The pointer of the specified OPA module
* @param[in] u32OpaNum The OPA number. 0 for OPA0.
* @return None
* @details This macro will clear OPENx (x=0) bit of OPA_CTL register to power down the OPA circuit.
* \hideinitializer
*/
#define OPA_POWER_DOWN(opa, u32OpaNum) ((opa)->CTL &= ~(1UL<<(OPA_CTL_OPEN0_Pos+(u32OpaNum))))
/**
* @brief This macro is used to enable the OPA Schmitt trigger buffer
* @param[in] opa The pointer of the specified OPA module
* @param[in] u32OpaNum The OPA number. 0 for OPA0.
* @return None
* @details This macro will set OPDOENx (x=0) bit of OPA_CTL register to enable the OPA Schmitt trigger buffer.
* \hideinitializer
*/
#define OPA_ENABLE_SCH_TRIGGER(opa, u32OpaNum) ((opa)->CTL |= (1UL<<(OPA_CTL_OPDOEN0_Pos+(u32OpaNum))))
/**
* @brief This macro is used to disable the OPA Schmitt trigger buffer
* @param[in] opa The pointer of the specified OPA module
* @param[in] u32OpaNum The OPA number. 0 for OPA0.
* @return None
* @details This macro will clear OPDOENx (x=0) bit of OPA_CTL register to disable the OPA Schmitt trigger buffer.
* \hideinitializer
*/
#define OPA_DISABLE_SCH_TRIGGER(opa, u32OpaNum) ((opa)->CTL &= ~(1UL<<(OPA_CTL_OPDOEN0_Pos+(u32OpaNum))))
/**
* @brief This macro is used to enable OPA Schmitt trigger digital output interrupt
* @param[in] opa The pointer of the specified OPA module
* @param[in] u32OpaNum The OPA number. 0 for OPA0.
* @return None
* @details This macro will set OPDOIENx (x=0) bit of OPA_CTL register to enable the OPA Schmitt trigger digital output interrupt.
* \hideinitializer
*/
#define OPA_ENABLE_INT(opa, u32OpaNum) ((opa)->CTL |= (1UL<<(OPA_CTL_OPDOIEN0_Pos+(u32OpaNum))))
/**
* @brief This macro is used to disable OPA Schmitt trigger digital output interrupt
* @param[in] opa The pointer of the specified OPA module
* @param[in] u32OpaNum The OPA number. 0 for OPA0.
* @return None
* @details This macro will clear OPDOIENx (x=0) bit of OPA_CTL register to disable the OPA Schmitt trigger digital output interrupt.
* \hideinitializer
*/
#define OPA_DISABLE_INT(opa, u32OpaNum) ((opa)->CTL &= ~(1UL<<(OPA_CTL_OPDOIEN0_Pos+(u32OpaNum))))
/**
* @brief This macro is used to get OPA digital output state
* @param[in] opa The pointer of the specified OPA module
* @param[in] u32OpaNum The OPA number. 0 for OPA0.
* @return OPA digital output state
* @details This macro will return the OPA digital output value.
* \hideinitializer
*/
#define OPA_GET_DIGITAL_OUTPUT(opa, u32OpaNum) (((opa)->STATUS & (OPA_STATUS_OPDO0_Msk<<(u32OpaNum)))?1UL:0UL)
/**
* @brief This macro is used to get OPA interrupt flag
* @param[in] opa The pointer of the specified OPA module
* @param[in] u32OpaNum The OPA number. 0 for OPA0.
* @retval 0 OPA interrupt does not occur.
* @retval 1 OPA interrupt occurs.
* @details This macro will return the OPA interrupt flag.
* \hideinitializer
*/
#define OPA_GET_INT_FLAG(opa, u32OpaNum) (((opa)->STATUS & (OPA_STATUS_OPDOIF0_Msk<<(u32OpaNum)))?1UL:0UL)
/**
* @brief This macro is used to clear OPA interrupt flag
* @param[in] opa The pointer of the specified OPA module
* @param[in] u32OpaNum The OPA number. 0 for OPA0.
* @return None
* @details This macro will write 1 to OPDOIFx (x=0) bit of OPA_STATUS register to clear interrupt flag.
* \hideinitializer
*/
#define OPA_CLR_INT_FLAG(opa, u32OpaNum) ((opa)->STATUS = (OPA_STATUS_OPDOIF0_Msk<<(u32OpaNum)))
/**
* @brief This function is used to configure and start OPA calibration
* @param[in] opa The pointer of the specified OPA module
* @param[in] u32OpaNum The OPA number. 0 for OPA0.
* @param[in] u32ClockSel Select OPA calibration clock
* - \ref OPA_CALIBRATION_CLK_1K
* @param[in] u32RefVol Select OPA reference voltage
* - \ref OPA_CALIBRATION_RV_1_2_AVDD
* - \ref OPA_CALIBRATION_RV_H_L_VCM
* @retval 0 PMOS and NMOS calibration successfully.
* @retval -1 only PMOS calibration failed.
* @retval -2 only NMOS calibration failed.
* @retval -3 PMOS and NMOS calibration failed.
*/
__STATIC_INLINE int32_t OPA_Calibration(OPA_T *opa, uint32_t u32OpaNum, uint32_t u32ClockSel, uint32_t u32RefVol)
{
uint32_t u32CALResult;
int32_t i32Ret = 0L;
(opa)->CALCTL = (((opa)->CALCTL) & ~(0x30ul << (u32OpaNum << 1))) | (((u32ClockSel) << 4) << (u32OpaNum << 1));
(opa)->CALCTL = (((opa)->CALCTL) & ~(OPA_CALCTL_CALRVS0_Msk << (u32OpaNum))) | (((u32RefVol) << OPA_CALCTL_CALRVS0_Pos) << (u32OpaNum));
(opa)->CALCTL |= (OPA_CALCTL_CALTRG0_Msk << (u32OpaNum));
while ((opa)->CALCTL & (OPA_CALCTL_CALTRG0_Msk << (u32OpaNum))) {}
u32CALResult = ((opa)->CALST >> ((u32OpaNum) * 4U)) & (OPA_CALST_CALNS0_Msk | OPA_CALST_CALPS0_Msk);
if (u32CALResult == 0ul)
{
i32Ret = 0L;
}
else if (u32CALResult == OPA_CALST_CALNS0_Msk)
{
i32Ret = -2L;
}
else if (u32CALResult == OPA_CALST_CALPS0_Msk)
{
i32Ret = -1L;
}
else if (u32CALResult == (uint32_t)(OPA_CALST_CALNS0_Msk | OPA_CALST_CALPS0_Msk))
{
i32Ret = -3L;
}
else
{
}
return i32Ret;
}
/*@}*/ /* end of group OPA_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group OPA_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __OPA_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,353 @@
/**************************************************************************//**
* @file pdma.h
* @version V3.00
* @brief M251 series PDMA driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __PDMA_H__
#define __PDMA_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup PDMA_Driver PDMA Driver
@{
*/
/** @addtogroup PDMA_EXPORTED_CONSTANTS PDMA Exported Constants
@{
*/
#define PDMA_CH_MAX 8UL /*!< Specify Maximum Channels of PDMA \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Operation Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PDMA_OP_STOP 0x00000000UL /*!<DMA Stop Mode \hideinitializer */
#define PDMA_OP_BASIC 0x00000001UL /*!<DMA Basic Mode \hideinitializer */
#define PDMA_OP_SCATTER 0x00000002UL /*!<DMA Scatter-gather Mode \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Data Width Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PDMA_WIDTH_8 0x00000000UL /*!<DMA Transfer Width 8-bit \hideinitializer */
#define PDMA_WIDTH_16 0x00001000UL /*!<DMA Transfer Width 16-bit \hideinitializer */
#define PDMA_WIDTH_32 0x00002000UL /*!<DMA Transfer Width 32-bit \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Address Attribute Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PDMA_SAR_INC 0x00000000UL /*!<DMA SAR increment \hideinitializer */
#define PDMA_SAR_FIX 0x00000300UL /*!<DMA SAR fix address \hideinitializer */
#define PDMA_DAR_INC 0x00000000UL /*!<DMA DAR increment \hideinitializer */
#define PDMA_DAR_FIX 0x00000C00UL /*!<DMA DAR fix address \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Burst Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PDMA_REQ_SINGLE 0x00000004UL /*!<DMA Single Request \hideinitializer */
#define PDMA_REQ_BURST 0x00000000UL /*!<DMA Burst Request \hideinitializer */
#define PDMA_BURST_128 0x00000000UL /*!<DMA Burst 128 Transfers \hideinitializer */
#define PDMA_BURST_64 0x00000010UL /*!<DMA Burst 64 Transfers \hideinitializer */
#define PDMA_BURST_32 0x00000020UL /*!<DMA Burst 32 Transfers \hideinitializer */
#define PDMA_BURST_16 0x00000030UL /*!<DMA Burst 16 Transfers \hideinitializer */
#define PDMA_BURST_8 0x00000040UL /*!<DMA Burst 8 Transfers \hideinitializer */
#define PDMA_BURST_4 0x00000050UL /*!<DMA Burst 4 Transfers \hideinitializer */
#define PDMA_BURST_2 0x00000060UL /*!<DMA Burst 2 Transfers \hideinitializer */
#define PDMA_BURST_1 0x00000070UL /*!<DMA Burst 1 Transfers \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Table Interrupt Disable Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PDMA_TBINTDIS_ENABLE (0x0UL<<PDMA_DSCT_CTL_TBINTDIS_Pos) /*!<DMA Table Interrupt Enabled \hideinitializer */
#define PDMA_TBINTDIS_DISABLE (0x1UL<<PDMA_DSCT_CTL_TBINTDIS_Pos) /*!<DMA Table Interrupt Disabled \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Peripheral Transfer Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PDMA_MEM 0UL /*!<DMA Connect to Memory \hideinitializer */
#define PDMA_UART0_TX 4UL /*!<DMA Connect to UART0_TX \hideinitializer */
#define PDMA_UART0_RX 5UL /*!<DMA Connect to UART0_RX \hideinitializer */
#define PDMA_UART1_TX 6UL /*!<DMA Connect to UART1_TX \hideinitializer */
#define PDMA_UART1_RX 7UL /*!<DMA Connect to UART1_RX \hideinitializer */
#define PDMA_UART2_TX 8UL /*!<DMA Connect to UART2_TX \hideinitializer */
#define PDMA_UART2_RX 9UL /*!<DMA Connect to UART2_RX \hideinitializer */
#define PDMA_USCI0_TX 16UL /*!<DMA Connect to USCI0_TX \hideinitializer */
#define PDMA_USCI0_RX 17UL /*!<DMA Connect to USCI0_RX \hideinitializer */
#define PDMA_USCI1_TX 18UL /*!<DMA Connect to USCI1_TX \hideinitializer */
#define PDMA_USCI1_RX 19UL /*!<DMA Connect to USCI1_RX \hideinitializer */
#define PDMA_QSPI0_TX 20UL /*!<DMA Connect to QSPI0_TX \hideinitializer */
#define PDMA_QSPI0_RX 21UL /*!<DMA Connect to QSPI0_RX \hideinitializer */
#define PDMA_SPI0_TX 22UL /*!<DMA Connect to SPI0_TX \hideinitializer */
#define PDMA_SPI0_RX 23UL /*!<DMA Connect to SPI0_RX \hideinitializer */
#define PDMA_PWM0_P1_RX 32UL /*!<DMA Connect to PWM0_P1 \hideinitializer */
#define PDMA_PWM0_P2_RX 33UL /*!<DMA Connect to PWM0_P2 \hideinitializer */
#define PDMA_PWM0_P3_RX 34UL /*!<DMA Connect to PWM0_P3 \hideinitializer */
#define PDMA_PWM1_P1_RX 35UL /*!<DMA Connect to PWM1_P1 \hideinitializer */
#define PDMA_PWM1_P2_RX 36UL /*!<DMA Connect to PWM1_P2 \hideinitializer */
#define PDMA_PWM1_P3_RX 37UL /*!<DMA Connect to PWM1_P3 \hideinitializer */
#define PDMA_I2C0_TX 38UL /*!<DMA Connect to I2C0_TX \hideinitializer */
#define PDMA_I2C0_RX 39UL /*!<DMA Connect to I2C0_RX \hideinitializer */
#define PDMA_I2C1_TX 40UL /*!<DMA Connect to I2C1_TX \hideinitializer */
#define PDMA_I2C1_RX 41UL /*!<DMA Connect to I2C1_RX \hideinitializer */
#define PDMA_TMR0 46UL /*!<DMA Connect to TMR0 \hideinitializer */
#define PDMA_TMR1 47UL /*!<DMA Connect to TMR1 \hideinitializer */
#define PDMA_TMR2 48UL /*!<DMA Connect to TMR2 \hideinitializer */
#define PDMA_TMR3 49UL /*!<DMA Connect to TMR3 \hideinitializer */
#define PDMA_EADC_RX 50UL /*!<DMA Connect to EADC_RX \hideinitializer */
#define PDMA_DAC0_TX 51UL /*!<DMA Connect to DAC0_TX \hideinitializer */
#define PDMA_PSIO_TX 66UL /*!<DMA Connect to PSIO_TX \hideinitializer */
#define PDMA_PSIO_RX 67UL /*!<DMA Connect to PSIO_RX \hideinitializer */
#define PDMA_USCI2_TX 68UL /*!<DMA Connect to USCI2_TX \hideinitializer */
#define PDMA_USCI2_RX 69UL /*!<DMA Connect to USCI2_RX \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* Interrupt Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PDMA_INT_TRANS_DONE 0x00000000UL /*!<Transfer Done Interrupt \hideinitializer */
#define PDMA_INT_TEMPTY 0x00000001UL /*!<Table Empty Interrupt \hideinitializer */
#define PDMA_INT_TIMEOUT 0x00000002UL /*!<Timeout Interrupt \hideinitializer */
/*@}*/ /* end of group PDMA_EXPORTED_CONSTANTS */
/** @addtogroup PDMA_EXPORTED_FUNCTIONS PDMA Exported Functions
@{
*/
/**
* @brief Get PDMA Interrupt Status
*
* @param[in] pdma The pointer of the specified PDMA module
*
* @return None
*
* @details This macro gets the interrupt status.
* \hideinitializer
*/
#define PDMA_GET_INT_STATUS(pdma) ((uint32_t)(pdma->INTSTS))
/**
* @brief Get Transfer Done Interrupt Status
*
* @param[in] pdma The pointer of the specified PDMA module
*
* @return None
*
* @details Get the transfer done Interrupt status.
* \hideinitializer
*/
#define PDMA_GET_TD_STS(pdma) ((uint32_t)(pdma->TDSTS))
/**
* @brief Clear Transfer Done Interrupt Status
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Mask The channel mask
*
* @return None
*
* @details Clear the transfer done Interrupt status.
* \hideinitializer
*/
#define PDMA_CLR_TD_FLAG(pdma, u32Mask) ((uint32_t)(pdma->TDSTS = (u32Mask)))
/**
* @brief Get Target Abort Interrupt Status
*
* @param[in] pdma The pointer of the specified PDMA module
*
* @return None
*
* @details Get the target abort Interrupt status.
* \hideinitializer
*/
#define PDMA_GET_ABORT_STS(pdma) ((uint32_t)(pdma->ABTSTS))
/**
* @brief Clear Target Abort Interrupt Status
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Mask The channel mask
*
* @return None
*
* @details Clear the target abort Interrupt status.
* \hideinitializer
*/
#define PDMA_CLR_ABORT_FLAG(pdma, u32Mask) ((uint32_t)(pdma->ABTSTS = (u32Mask)))
/**
* @brief Get Alignment Interrupt Status
*
* @param[in] pdma The pointer of the specified PDMA module
*
* @return None
*
* @details Get Alignment Interrupt status.
* \hideinitializer
*/
#define PDMA_GET_ALIGN_STS(pdma) ((uint32_t)(PDMA->ALIGN))
/**
* @brief Clear Alignment Interrupt Status
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Mask The channel mask
*
* @return None
*
* @details Clear the Alignment Interrupt status.
* \hideinitializer
*/
#define PDMA_CLR_ALIGN_FLAG(pdma,u32Mask) ((uint32_t)(pdma->ALIGN = (u32Mask)))
/**
* @brief Clear Timeout Interrupt Status
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
*
* @return None
*
* @details Clear the selected channel timeout interrupt status.
* \hideinitializer
*/
#define PDMA_CLR_TMOUT_FLAG(pdma, u32Ch) ((uint32_t)(pdma->INTSTS = (1 << ((u32Ch) + 8))))
/**
* @brief Check Channel Status
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
*
* @retval 0 Idle state
* @retval 1 Busy state
*
* @details Check the selected channel is busy or not.
* \hideinitializer
*/
#define PDMA_IS_CH_BUSY(pdma, u32Ch) ((uint32_t)(pdma->TRGSTS & (1 << (u32Ch)))? 1 : 0)
/**
* @brief Set Source Address
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
* @param[in] u32Addr The selected address
*
* @return None
*
* @details This macro set the selected channel source address.
* \hideinitializer
*/
#define PDMA_SET_SRC_ADDR(pdma, u32Ch, u32Addr) ((uint32_t)(pdma->DSCT[(u32Ch)].SA = (u32Addr)))
/**
* @brief Set Destination Address
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
* @param[in] u32Addr The selected address
*
* @return None
*
* @details This macro set the selected channel destination address.
* \hideinitializer
*/
#define PDMA_SET_DST_ADDR(pdma, u32Ch, u32Addr) ((uint32_t)(pdma->DSCT[(u32Ch)].DA = (u32Addr)))
/**
* @brief Set Transfer Count
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
* @param[in] u32TransCount Transfer Count
*
* @return None
*
* @details This macro set the selected channel transfer count.
* \hideinitializer
*/
#define PDMA_SET_TRANS_CNT(pdma, u32Ch, u32TransCount) ((uint32_t)(pdma->DSCT[(u32Ch)].CTL=(pdma->DSCT[(u32Ch)].CTL&~PDMA_DSCT_CTL_TXCNT_Msk)|(((u32TransCount)-1) << PDMA_DSCT_CTL_TXCNT_Pos)))
/**
* @brief Set Scatter-gather descriptor Address
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
* @param[in] u32Addr The descriptor address
*
* @return None
*
* @details This macro set the selected channel scatter-gather descriptor address.
* \hideinitializer
*/
#define PDMA_SET_SCATTER_DESC(pdma, u32Ch, u32Addr) ((uint32_t)(pdma->DSCT[(u32Ch)].NEXT = (u32Addr) - (pdma->SCATBA)))
/**
* @brief Stop the channel
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
*
* @return None
*
* @details This macro stop the selected channel.
* \hideinitializer
*/
#define PDMA_STOP(pdma, u32Ch) ((uint32_t)(pdma->PAUSE = (1 << (u32Ch))))
/**
* @brief Pause the channel
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
*
* @return None
*
* @details This macro pause the selected channel.
* \hideinitializer
*/
#define PDMA_PAUSE(pdma, u32Ch) ((uint32_t)(pdma->PAUSE = (1 << (u32Ch))))
/*---------------------------------------------------------------------------------------------------------*/
/* Define PDMA functions prototype */
/*---------------------------------------------------------------------------------------------------------*/
void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask);
void PDMA_Close(PDMA_T *pdma);
void PDMA_SetTransferCnt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount);
void PDMA_SetTransferAddr(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl);
void PDMA_SetTransferMode(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr);
void PDMA_SetBurstType(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize);
void PDMA_EnableTimeout(PDMA_T *pdma, uint32_t u32Mask);
void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask);
void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt);
void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch);
void PDMA_EnableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask);
void PDMA_DisableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask);
void PDMA_SetStride(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32DestLen, uint32_t u32SrcLen, uint32_t u32TransCount);
/*@}*/ /* end of group PDMA_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group PDMA_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __PDMA_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,510 @@
/******************************************************************************
* @file pwm.h
* @version V0.10
* @brief M251 series PWM driver header file
*
* @copyright (C) 2018 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 (6UL) /*!< PWM channel number */
#define PWM_CH_0_MASK (0x1UL) /*!< PWM channel 0 mask */
#define PWM_CH_1_MASK (0x2UL) /*!< PWM channel 1 mask */
#define PWM_CH_2_MASK (0x4UL) /*!< PWM channel 2 mask */
#define PWM_CH_3_MASK (0x8UL) /*!< PWM channel 3 mask */
#define PWM_CH_4_MASK (0x10UL) /*!< PWM channel 4 mask */
#define PWM_CH_5_MASK (0x20UL) /*!< PWM channel 5 mask */
/*---------------------------------------------------------------------------------------------------------*/
/* Counter Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_UP_COUNTER (0UL) /*!< Up counter type */
#define PWM_DOWN_COUNTER (1UL) /*!< Down counter type */
#define PWM_UP_DOWN_COUNTER (2UL) /*!< Up-Down counter type */
/*---------------------------------------------------------------------------------------------------------*/
/* Aligned Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_EDGE_ALIGNED (1UL) /*!< PWM working in edge aligned type(down count) */
#define PWM_CENTER_ALIGNED (2UL) /*!< PWM working in center aligned type */
/*---------------------------------------------------------------------------------------------------------*/
/* Output Level Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_OUTPUT_NOTHING (0UL) /*!< PWM output nothing */
#define PWM_OUTPUT_LOW (1UL) /*!< PWM output low */
#define PWM_OUTPUT_HIGH (2UL) /*!< PWM output high */
#define PWM_OUTPUT_TOGGLE (3UL) /*!< PWM output toggle */
/*---------------------------------------------------------------------------------------------------------*/
/* Synchronous Start Function Control Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_SSCTL_SSRC_PWM0 (0UL<<PWM_SSCTL_SSRC_Pos) /*!< Synchronous start source comes from PWM0 */
#define PWM_SSCTL_SSRC_PWM1 (1UL<<PWM_SSCTL_SSRC_Pos) /*!< Synchronous start source comes from PWM1 */
#define PWM_SSCTL_SSRC_BPWM0 (2UL<<PWM_SSCTL_SSRC_Pos) /*!< Synchronous start source comes from BPWM0 */
#define PWM_SSCTL_SSRC_BPWM1 (3UL<<PWM_SSCTL_SSRC_Pos) /*!< Synchronous start source comes from BPWM1 */
/*---------------------------------------------------------------------------------------------------------*/
/* Trigger Source Select Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_TRIGGER_ADC_EVEN_ZERO_POINT (0UL) /*!< PWM trigger EADC while counter of even channel matches zero point */
#define PWM_TRIGGER_ADC_EVEN_PERIOD_POINT (1UL) /*!< PWM trigger EADC while counter of even channel matches period point */
#define PWM_TRIGGER_ADC_EVEN_ZERO_OR_PERIOD_POINT (2UL) /*!< PWM trigger EADC while counter of even channel matches zero or period point */
#define PWM_TRIGGER_ADC_EVEN_CMP_UP_COUNT_POINT (3UL) /*!< PWM trigger EADC while counter of even channel matches up count to comparator point */
#define PWM_TRIGGER_ADC_EVEN_CMP_DOWN_COUNT_POINT (4UL) /*!< PWM trigger EADC while counter of even channel matches down count to comparator point */
#define PWM_TRIGGER_ADC_ODD_CMP_UP_COUNT_POINT (8UL) /*!< PWM trigger EADC while counter of odd channel matches up count to comparator point */
#define PWM_TRIGGER_ADC_ODD_CMP_DOWN_COUNT_POINT (9UL) /*!< PWM trigger EADC while counter of odd channel matches down count to comparator point */
/*---------------------------------------------------------------------------------------------------------*/
/* Fail brake Control Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_FB_EDGE_ACMP0 (PWM_BRKCTL_CPO0EBEN_Msk) /*!< Comparator 0 as edge-detect fault brake source */
#define PWM_FB_EDGE_ACMP1 (PWM_BRKCTL_CPO1EBEN_Msk) /*!< Comparator 1 as edge-detect fault brake source */
#define PWM_FB_EDGE_BKP0 (PWM_BRKCTL_BRKP0EEN_Msk) /*!< BKP0 pin as edge-detect fault brake source */
#define PWM_FB_EDGE_BKP1 (PWM_BRKCTL_BRKP1EEN_Msk) /*!< BKP1 pin as edge-detect fault brake source */
#define PWM_FB_EDGE_SYS_CSS (PWM_BRKCTL_SYSEBEN_Msk | PWM_FAILBRK_CSSBRKEN_Msk) /*!< System fail condition: clock security system detection as edge-detect fault brake source */
#define PWM_FB_EDGE_SYS_BOD (PWM_BRKCTL_SYSEBEN_Msk | PWM_FAILBRK_BODBRKEN_Msk) /*!< System fail condition: brown-out detection as edge-detect fault brake source */
#define PWM_FB_EDGE_SYS_COR (PWM_BRKCTL_SYSEBEN_Msk | PWM_FAILBRK_CORBRKEN_Msk) /*!< System fail condition: core lockup detection as edge-detect fault brake source */
#define PWM_FB_LEVEL_ACMP0 (PWM_BRKCTL_CPO0LBEN_Msk) /*!< Comparator 0 as level-detect fault brake source */
#define PWM_FB_LEVEL_ACMP1 (PWM_BRKCTL_CPO1LBEN_Msk) /*!< Comparator 1 as level-detect fault brake source */
#define PWM_FB_LEVEL_BKP0 (PWM_BRKCTL_BRKP0LEN_Msk) /*!< BKP0 pin as level-detect fault brake source */
#define PWM_FB_LEVEL_BKP1 (PWM_BRKCTL_BRKP1LEN_Msk) /*!< BKP1 pin as level-detect fault brake source */
#define PWM_FB_LEVEL_SYS_CSS (PWM_BRKCTL_SYSLBEN_Msk | PWM_FAILBRK_CSSBRKEN_Msk) /*!< System fail condition: clock security system detection as level-detect fault brake source */
#define PWM_FB_LEVEL_SYS_BOD (PWM_BRKCTL_SYSLBEN_Msk | PWM_FAILBRK_BODBRKEN_Msk) /*!< System fail condition: brown-out detection as level-detect fault brake source */
#define PWM_FB_LEVEL_SYS_COR (PWM_BRKCTL_SYSLBEN_Msk | PWM_FAILBRK_CORBRKEN_Msk) /*!< System fail condition: core lockup detection as level-detect fault brake source */
#define PWM_FB_EDGE (0UL) /*!< edge-detect fault brake */
#define PWM_FB_LEVEL (8UL) /*!< level-detect fault brake */
/*---------------------------------------------------------------------------------------------------------*/
/* Capture Control Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_CAPTURE_INT_RISING_LATCH (1UL) /*!< PWM capture interrupt if channel has rising transition */
#define PWM_CAPTURE_INT_FALLING_LATCH (0x100UL) /*!< PWM capture interrupt if channel has falling transition */
#define PWM_CAPTURE_PDMA_RISING_LATCH (0x2UL) /*!< PWM capture rising latched data transfer by PDMA */
#define PWM_CAPTURE_PDMA_FALLING_LATCH (0x4UL) /*!< PWM capture falling latched data transfer by PDMA */
#define PWM_CAPTURE_PDMA_RISING_FALLING_LATCH (0x6UL) /*!< PWM capture rising and falling latched data transfer by PDMA */
/*---------------------------------------------------------------------------------------------------------*/
/* Duty Interrupt Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_DUTY_INT_DOWN_COUNT_MATCH_CMP (PWM_INTEN0_CMPDIEN0_Msk) /*!< PWM duty interrupt triggered if down count match comparator */
#define PWM_DUTY_INT_UP_COUNT_MATCH_CMP (PWM_INTEN0_CMPUIEN0_Msk) /*!< PWM duty interrupt triggered if up down match comparator */
/*---------------------------------------------------------------------------------------------------------*/
/* Load Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_LOAD_MODE_IMMEDIATE (PWM_CTL0_IMMLDEN0_Msk) /*!< PWM immediately load mode */
#define PWM_LOAD_MODE_CENTER (PWM_CTL0_CTRLD0_Msk) /*!< PWM center load mode */
/*---------------------------------------------------------------------------------------------------------*/
/* Noise Filter Clock Divide Select Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_NF_CLK_DIV_1 (0UL) /*!< Noise filter clock is HCLK divide by 1 */
#define PWM_NF_CLK_DIV_2 (1UL) /*!< Noise filter clock is HCLK divide by 2 */
#define PWM_NF_CLK_DIV_4 (2UL) /*!< Noise filter clock is HCLK divide by 4 */
#define PWM_NF_CLK_DIV_8 (3UL) /*!< Noise filter clock is HCLK divide by 8 */
#define PWM_NF_CLK_DIV_16 (4UL) /*!< Noise filter clock is HCLK divide by 16 */
#define PWM_NF_CLK_DIV_32 (5UL) /*!< Noise filter clock is HCLK divide by 32 */
#define PWM_NF_CLK_DIV_64 (6UL) /*!< Noise filter clock is HCLK divide by 64 */
#define PWM_NF_CLK_DIV_128 (7UL) /*!< Noise filter clock is HCLK divide by 128 */
/*---------------------------------------------------------------------------------------------------------*/
/* Clock Source Select Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define PWM_CLKSRC_PWM_CLK (0UL) /*!< PWM Clock source selects to PWM0_CLK or PWM1_CLK */
#define PWM_CLKSRC_TIMER0 (1UL) /*!< PWM Clock source selects to TIMER0 overflow */
#define PWM_CLKSRC_TIMER1 (2UL) /*!< PWM Clock source selects to TIMER1 overflow */
#define PWM_CLKSRC_TIMER2 (3UL) /*!< PWM Clock source selects to TIMER2 overflow */
#define PWM_CLKSRC_TIMER3 (4UL) /*!< PWM Clock source selects to TIMER3 overflow */
/*@}*/ /* end of group PWM_EXPORTED_CONSTANTS */
/** @addtogroup PWM_EXPORTED_FUNCTIONS PWM Exported Functions
@{
*/
/**
* @brief This macro enable complementary mode
* @param[in] pwm The pointer of the specified PWM module
* @return None
* @details This macro is used to enable complementary mode of PWM module.
* \hideinitializer
*/
#define PWM_ENABLE_COMPLEMENTARY_MODE(pwm) ((pwm)->CTL1 = (pwm)->CTL1 | PWM_CTL1_OUTMODE0_Msk | PWM_CTL1_OUTMODE2_Msk | PWM_CTL1_OUTMODE4_Msk)
/**
* @brief This macro disable complementary mode, and enable independent mode.
* @param[in] pwm The pointer of the specified PWM module
* @return None
* @details This macro is used to disable complementary mode of PWM module.
* \hideinitializer
*/
#define PWM_DISABLE_COMPLEMENTARY_MODE(pwm) ((pwm)->CTL1 = (pwm)->CTL1 & ~PWM_CTL1_OUTMODE0_Msk & ~PWM_CTL1_OUTMODE2_Msk & ~PWM_CTL1_OUTMODE4_Msk)
/**
* @brief Enable timer synchronous start counting function of specified channel(s)
* @param[in] pwm The pointer of the specified PWM module
* @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] u32SyncSrc Synchronous start source selection, valid values are:
* - \ref PWM_SSCTL_SSRC_PWM0
* - \ref PWM_SSCTL_SSRC_PWM1
* - \ref PWM_SSCTL_SSRC_BPWM0
* - \ref PWM_SSCTL_SSRC_BPWM1
* @return None
* @details This macro is used to enable timer synchronous start counting function of specified channel(s).
* @note Every two channels share the same setting.
* \hideinitializer
*/
#define PWM_ENABLE_TIMER_SYNC(pwm, u32ChannelMask, u32SyncSrc) \
do{ \
uint32_t i;\
(pwm)->SSCTL = ((pwm)->SSCTL & ~PWM_SSCTL_SSRC_Msk) | (u32SyncSrc) ; \
for(i = 0UL; i < 6UL; i++) { \
if((u32ChannelMask) & (1UL << i)) \
(pwm)->SSCTL |= (1UL << ((i >> 1UL) << 1UL)); \
} \
}while(0)
/**
* @brief Disable timer synchronous start counting function of specified channel(s)
* @param[in] pwm The pointer of the specified PWM module
* @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 disable timer synchronous start counting function of specified channel(s).
* @note Every two channels share the same setting.
* \hideinitializer
*/
#define PWM_DISABLE_TIMER_SYNC(pwm, u32ChannelMask) \
do{ \
uint32_t i;\
for(i = 0UL; i < 6UL; i++) { \
if((u32ChannelMask) & (1UL << i)) \
(pwm)->SSCTL &= ~(1UL << ((i >> 1UL) << 1UL)); \
} \
}while(0)
/**
* @brief This macro enable PWM counter synchronous start counting function.
* @param[in] pwm The pointer of the specified PWM module
* @return None
* @details This macro is used to make selected PWM0 and PWM1 channel(s) start counting at the same time.
* To configure synchronous start counting channel(s) by PWM_ENABLE_TIMER_SYNC() and PWM_DISABLE_TIMER_SYNC().
* \hideinitializer
*/
#define PWM_TRIGGER_SYNC_START(pwm) ((pwm)->SSTRG = PWM_SSTRG_CNTSEN_Msk)
/**
* @brief This macro enable output inverter of specified channel(s)
* @param[in] pwm The pointer of the specified PWM module
* @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 output inverter of specified channel(s).
* \hideinitializer
*/
#define PWM_ENABLE_OUTPUT_INVERTER(pwm, u32ChannelMask) ((pwm)->POLCTL = (u32ChannelMask))
/**
* @brief This macro get captured rising data
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return None
* @details This macro is used to get captured rising data of specified channel.
* \hideinitializer
*/
#define PWM_GET_CAPTURE_RISING_DATA(pwm, u32ChannelNum) ((pwm)->CAPDAT[(u32ChannelNum)].RCAPDAT)
/**
* @brief This macro get captured falling data
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return None
* @details This macro is used to get captured falling data of specified channel.
* \hideinitializer
*/
#define PWM_GET_CAPTURE_FALLING_DATA(pwm, u32ChannelNum) ((pwm)->CAPDAT[(u32ChannelNum)].FCAPDAT)
/**
* @brief This macro mask output logic to high or low
* @param[in] pwm The pointer of the specified PWM module
* @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] u32LevelMask Output logic to high or low
* @return None
* @details This macro is used to mask output logic to high or low of specified channel(s).
* @note If u32ChannelMask parameter is 0, then mask function will be disabled.
* \hideinitializer
*/
#define PWM_MASK_OUTPUT(pwm, u32ChannelMask, u32LevelMask) \
do{ \
(pwm)->MSKEN = (u32ChannelMask); \
(pwm)->MSK = (u32LevelMask); \
}while(0)
/**
* @brief This macro set the prescaler of the selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32Prescaler Clock prescaler of specified channel. Valid values are between 1 ~ 0xFFF
* @return None
* @details This macro is used to set the prescaler of specified channel.
* @note Every even channel N, and channel (N + 1) share a prescaler. So if channel 0 prescaler changed,
* channel 1 will also be affected. The clock of PWM counter is divided by (u32Prescaler + 1).
* \hideinitializer
*/
#define PWM_SET_PRESCALER(pwm, u32ChannelNum, u32Prescaler) ((pwm)->CLKPSC[(u32ChannelNum) >> 1UL] = (u32Prescaler))
/**
* @brief This macro get the prescaler of the selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return Return Clock prescaler of specified channel. Valid values are between 0 ~ 0xFFF
* @details This macro is used to get the prescaler of specified channel.
* @note Every even channel N, and channel (N + 1) share a prescaler. So if channel 0 prescaler changed, channel 1 will also be affected.
* The clock of PWM counter is divided by (u32Prescaler + 1).
* \hideinitializer
*/
#define PWM_GET_PRESCALER(pwm, u32ChannelNum) ((pwm)->CLKPSC[(u32ChannelNum) >> 1UL])
/**
* @brief This macro set the comparator of the selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32CMR Comparator of specified channel. Valid values are between 0~0xFFFF
* @return None
* @details This macro is used to set the comparator of specified channel.
* @note This new setting will take effect on next PWM period.
* \hideinitializer
*/
#define PWM_SET_CMR(pwm, u32ChannelNum, u32CMR) ((pwm)->CMPDAT[(u32ChannelNum)] = (u32CMR))
/**
* @brief This macro get the comparator of the selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return Return the comparator of specified channel. Valid values are between 0~0xFFFF
* @details This macro is used to get the comparator of specified channel.
* \hideinitializer
*/
#define PWM_GET_CMR(pwm, u32ChannelNum) ((pwm)->CMPDAT[(u32ChannelNum)])
/**
* @brief This macro set the period of the selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0, 2, 4. Every two channels share the same setting.
* @param[in] u32CNR Period of specified channel. Valid values are between 0~0xFFFF
* @return None
* @details This macro is used to set the period of specified channel.
* @note This new setting will take effect on next PWM period.
* @note PWM counter will stop if period length set to 0.
* \hideinitializer
*/
#define PWM_SET_CNR(pwm, u32ChannelNum, u32CNR) ((pwm)->PERIOD[(((u32ChannelNum) >> 1UL) << 1UL)] = (u32CNR))
/**
* @brief This macro get the period of the selected channel
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return Return the period of specified channel. Valid values are between 0~0xFFFF
* @details This macro is used to get the period of specified channel.
* \hideinitializer
*/
#define PWM_GET_CNR(pwm, u32ChannelNum) ((pwm)->PERIOD[(((u32ChannelNum) >> 1UL) << 1UL)])
/**
* @brief This macro set the PWM aligned type
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelMask Combination of enabled channels. Every two channels share the same setting.
* @param[in] u32AlignedType PWM aligned type, valid values are:
* - \ref PWM_UP_COUNTER
* - \ref PWM_DOWN_COUNTER
* - \ref PWM_UP_DOWN_COUNTER
* @return None
* @details This macro is used to set the PWM aligned type of specified channel(s).
* \hideinitializer
*/
#define PWM_SET_ALIGNED_TYPE(pwm, u32ChannelMask, u32AlignedType) \
do{ \
uint32_t i; \
for(i = 0UL; i < 6UL; i++) { \
if((u32ChannelMask) & (1UL << i)) \
(pwm)->CTL1 = (((pwm)->CTL1 & ~(3UL << ((i >> 1UL) << 2UL))) | ((u32AlignedType) << ((i >> 1UL) << 2UL))); \
} \
}while(0)
/**
* @brief Clear counter of specified channel(s)
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelMask Combination of enabled channels. Every two channels share the same setting.
* @return None
* @details This macro is used to clear counter of specified channel(s).
* \hideinitializer
*/
#define PWM_CLR_COUNTER(pwm, u32ChannelMask) \
do{ \
uint32_t i; \
for(i = 0UL; i < 6UL; i++) { \
if((u32ChannelMask) & (1UL << i)) \
((pwm)->CNTCLR |= (1UL << ((i >> 1UL) << 1UL))); \
} \
}while(0)
/**
* @brief Set output level at zero, compare up, period(center) and compare down of specified channel(s)
* @param[in] pwm The pointer of the specified PWM module
* @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] u32ZeroLevel output level at zero point, valid values are:
* - \ref PWM_OUTPUT_NOTHING
* - \ref PWM_OUTPUT_LOW
* - \ref PWM_OUTPUT_HIGH
* - \ref PWM_OUTPUT_TOGGLE
* @param[in] u32CmpUpLevel output level at compare up point, valid values are:
* - \ref PWM_OUTPUT_NOTHING
* - \ref PWM_OUTPUT_LOW
* - \ref PWM_OUTPUT_HIGH
* - \ref PWM_OUTPUT_TOGGLE
* @param[in] u32PeriodLevel output level at period(center) point, valid values are:
* - \ref PWM_OUTPUT_NOTHING
* - \ref PWM_OUTPUT_LOW
* - \ref PWM_OUTPUT_HIGH
* - \ref PWM_OUTPUT_TOGGLE
* @param[in] u32CmpDownLevel output level at compare down point, valid values are:
* - \ref PWM_OUTPUT_NOTHING
* - \ref PWM_OUTPUT_LOW
* - \ref PWM_OUTPUT_HIGH
* - \ref PWM_OUTPUT_TOGGLE
* @return None
* @details This macro is used to Set output level at zero, compare up, period(center) and compare down of specified channel(s).
* \hideinitializer
*/
#define PWM_SET_OUTPUT_LEVEL(pwm, u32ChannelMask, u32ZeroLevel, u32CmpUpLevel, u32PeriodLevel, u32CmpDownLevel) \
do{ \
uint32_t i; \
for(i = 0UL; i < 6UL; i++) { \
if((u32ChannelMask) & (1UL << i)) { \
(pwm)->WGCTL0 = (((pwm)->WGCTL0 & ~(3UL << (i << 1UL))) | ((u32ZeroLevel) << (i << 1UL))); \
(pwm)->WGCTL0 = (((pwm)->WGCTL0 & ~(3UL << (PWM_WGCTL0_PRDPCTL0_Pos + (i << 1UL)))) | ((u32PeriodLevel) << (PWM_WGCTL0_PRDPCTL0_Pos + (i << 1UL)))); \
(pwm)->WGCTL1 = (((pwm)->WGCTL1 & ~(3UL << (i << 1UL))) | ((u32CmpUpLevel) << (i << 1UL))); \
(pwm)->WGCTL1 = (((pwm)->WGCTL1 & ~(3UL << (PWM_WGCTL1_CMPDCTL0_Pos + (i << 1UL)))) | ((u32CmpDownLevel) << (PWM_WGCTL1_CMPDCTL0_Pos + (i << 1UL)))); \
} \
} \
}while(0)
/**
* @brief Trigger brake event from specified channel(s) by using sw trigger
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel
* Bit 0 represents channel 0, bit 1 represents channel 2 and bit 2 represents channel 4
* @param[in] u32BrakeType Type of brake trigger. It supports PWM_FB_EDGE and PWM_FB_LEVEL.
* - \ref PWM_FB_EDGE
* - \ref PWM_FB_LEVEL
* @return None
* @details This macro is used to trigger brake event from specified channel(s) by using sw trigger.
* \hideinitializer
*/
#define PWM_TRIGGER_BRAKE(pwm, u32ChannelMask, u32BrakeType) ((pwm)->SWBRK |= ((u32ChannelMask) << (u32BrakeType)))
/**
* @brief Set Dead zone clock source
* @param[in] pwm The pointer of the specified PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32AfterPrescaler Dead zone clock source is from prescaler output. Valid values are TRUE (after prescaler) or FALSE (before prescaler).
* @return None
* @details This macro is used to set Dead zone clock source. Every two channels share the same setting.
* @note The write-protection function should be disabled before using this function.
* \hideinitializer
*/
#define PWM_SET_DEADZONE_CLK_SRC(pwm, u32ChannelNum, u32AfterPrescaler) \
(((pwm)->DTCTL[(u32ChannelNum) >> 1UL]) = ((pwm)->DTCTL[(u32ChannelNum) >> 1UL] & ~PWM_DTCTL0_1_DTCKSEL_Msk) | \
((u32AfterPrescaler) << PWM_DTCTL0_1_DTCKSEL_Pos))
/*---------------------------------------------------------------------------------------------------------*/
/* Define PWM functions prototype */
/*---------------------------------------------------------------------------------------------------------*/
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 u32Frequency, 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_EnableFaultBrake(PWM_T *pwm, uint32_t u32ChannelMask, uint32_t u32LevelMask, uint32_t u32BrakeSource);
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_EnableLoadMode(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32LoadMode);
void PWM_DisableLoadMode(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32LoadMode);
void PWM_EnableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource);
void PWM_DisableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource);
void PWM_ClearFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource);
uint32_t PWM_GetFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource);
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);
void PWM_EnableZeroInt(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_DisableZeroInt(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_ClearZeroIntFlag(PWM_T *pwm, uint32_t u32ChannelNum);
uint32_t PWM_GetZeroIntFlag(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_SetClockSource(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32ClkSrcSel);
void PWM_EnableBrakeNoiseFilter(PWM_T *pwm, uint32_t u32BrakePinNum, uint32_t u32ClkCnt, uint32_t u32ClkDivSel);
void PWM_DisableBrakeNoiseFilter(PWM_T *pwm, uint32_t u32BrakePinNum);
void PWM_EnableBrakePinInverse(PWM_T *pwm, uint32_t u32BrakePinNum);
void PWM_DisableBrakePinInverse(PWM_T *pwm, uint32_t u32BrakePinNum);
void PWM_SetBrakePinSource(PWM_T *pwm, uint32_t u32BrakePinNum, uint32_t u32SelAnotherModule);
uint32_t PWM_GetWrapAroundFlag(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_ClearWrapAroundFlag(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_EnablePDMA(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32RisingFirst, uint32_t u32Mode);
void PWM_DisablePDMA(PWM_T *pwm, uint32_t u32ChannelNum);
/*@}*/ /* end of group PWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group PWM_Driver */
/*@}*/ /* end of group Standard_Driver*/
#ifdef __cplusplus
}
#endif
#endif /* __PWM_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,389 @@
/**************************************************************************//**
* @file qspi.h
* @version V0.10
* @brief M251 series QSPI driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __QSPI_H__
#define __QSPI_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup QSPI_Driver QSPI Driver
@{
*/
/** @addtogroup QSPI_EXPORTED_CONSTANTS QSPI Exported Constants
@{
*/
#define QSPI_MODE_0 (QSPI_CTL_TXNEG_Msk) /*!< CLKPOL=0; RXNEG=0; TXNEG=1 \hideinitializer */
#define QSPI_MODE_1 (QSPI_CTL_RXNEG_Msk) /*!< CLKPOL=0; RXNEG=1; TXNEG=0 \hideinitializer */
#define QSPI_MODE_2 (QSPI_CTL_CLKPOL_Msk | QSPI_CTL_RXNEG_Msk) /*!< CLKPOL=1; RXNEG=1; TXNEG=0 \hideinitializer */
#define QSPI_MODE_3 (QSPI_CTL_CLKPOL_Msk | QSPI_CTL_TXNEG_Msk) /*!< CLKPOL=1; RXNEG=0; TXNEG=1 \hideinitializer */
#define QSPI_SLAVE (QSPI_CTL_SLAVE_Msk) /*!< Set as slave \hideinitializer */
#define QSPI_MASTER (0x0UL) /*!< Set as master \hideinitializer */
#define QSPI_SS (QSPI_SSCTL_SS_Msk) /*!< Set SS \hideinitializer */
#define QSPI_SS_ACTIVE_HIGH (QSPI_SSCTL_SSACTPOL_Msk) /*!< SS active high \hideinitializer */
#define QSPI_SS_ACTIVE_LOW (0x0UL) /*!< SS active low \hideinitializer */
/* QSPI Interrupt Mask */
#define QSPI_UNIT_INT_MASK (0x001UL) /*!< Unit transfer interrupt mask \hideinitializer */
#define QSPI_SSACT_INT_MASK (0x002UL) /*!< Slave selection signal active interrupt mask \hideinitializer */
#define QSPI_SSINACT_INT_MASK (0x004UL) /*!< Slave selection signal inactive interrupt mask \hideinitializer */
#define QSPI_SLVUR_INT_MASK (0x008UL) /*!< Slave under run interrupt mask \hideinitializer */
#define QSPI_SLVBE_INT_MASK (0x010UL) /*!< Slave bit count error interrupt mask \hideinitializer */
#define QSPI_SLVTO_INT_MASK (0x020UL) /*!< Slave Mode Time-out interrupt mask \hideinitializer */
#define QSPI_TXUF_INT_MASK (0x040UL) /*!< Slave TX underflow interrupt mask \hideinitializer */
#define QSPI_FIFO_TXTH_INT_MASK (0x080UL) /*!< FIFO TX threshold interrupt mask \hideinitializer */
#define QSPI_FIFO_RXTH_INT_MASK (0x100UL) /*!< FIFO RX threshold interrupt mask \hideinitializer */
#define QSPI_FIFO_RXOV_INT_MASK (0x200UL) /*!< FIFO RX overrun interrupt mask \hideinitializer */
#define QSPI_FIFO_RXTO_INT_MASK (0x400UL) /*!< FIFO RX time-out interrupt mask \hideinitializer */
/* QSPI Status Mask */
#define QSPI_BUSY_MASK (0x01UL) /*!< Busy status mask \hideinitializer */
#define QSPI_RX_EMPTY_MASK (0x02UL) /*!< RX empty status mask \hideinitializer */
#define QSPI_RX_FULL_MASK (0x04UL) /*!< RX full status mask \hideinitializer */
#define QSPI_TX_EMPTY_MASK (0x08UL) /*!< TX empty status mask \hideinitializer */
#define QSPI_TX_FULL_MASK (0x10UL) /*!< TX full status mask \hideinitializer */
#define QSPI_TXRX_RESET_MASK (0x20UL) /*!< TX or RX reset status mask \hideinitializer */
#define QSPI_QSPIEN_STS_MASK (0x40UL) /*!< QSPIEN status mask \hideinitializer */
#define QSPI_SSLINE_STS_MASK (0x80UL) /*!< QSPIx_SS line status mask \hideinitializer */
/*@}*/ /* end of group QSPI_EXPORTED_CONSTANTS */
/** @addtogroup QSPI_EXPORTED_FUNCTIONS QSPI Exported Functions
@{
*/
/**
* @brief Clear the unit transfer interrupt flag.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Write 1 to UNITIF bit of QSPI_STATUS register to clear the unit transfer interrupt flag.
* \hideinitializer
*/
#define QSPI_CLR_UNIT_TRANS_INT_FLAG(qspi) ((qspi)->STATUS = QSPI_STATUS_UNITIF_Msk)
/**
* @brief Trigger RX PDMA function.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Set RXPDMAEN bit of QSPI_PDMACTL register to enable RX PDMA transfer function.
* \hideinitializer
*/
#define QSPI_TRIGGER_RX_PDMA(qspi) ((qspi)->PDMACTL |= QSPI_PDMACTL_RXPDMAEN_Msk)
/**
* @brief Trigger TX PDMA function.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Set TXPDMAEN bit of QSPI_PDMACTL register to enable TX PDMA transfer function.
* \hideinitializer
*/
#define QSPI_TRIGGER_TX_PDMA(qspi) ((qspi)->PDMACTL |= QSPI_PDMACTL_TXPDMAEN_Msk)
/**
* @brief Disable RX PDMA transfer.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Clear RXPDMAEN bit of QSPI_PDMACTL register to disable RX PDMA transfer function.
* \hideinitializer
*/
#define QSPI_DISABLE_RX_PDMA(qspi) ( (qspi)->PDMACTL &= ~QSPI_PDMACTL_RXPDMAEN_Msk )
/**
* @brief Disable TX PDMA transfer.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Clear TXPDMAEN bit of QSPI_PDMACTL register to disable TX PDMA transfer function.
* \hideinitializer
*/
#define QSPI_DISABLE_TX_PDMA(qspi) ( (qspi)->PDMACTL &= ~QSPI_PDMACTL_TXPDMAEN_Msk )
/**
* @brief Get the count of available data in RX FIFO.
* @param[in] qspi The pointer of the specified QSPI module.
* @return The count of available data in RX FIFO.
* @details Read RXCNT (QSPI_STATUS[27:24]) to get the count of available data in RX FIFO.
* \hideinitializer
*/
#define QSPI_GET_RX_FIFO_COUNT(qspi) (((qspi)->STATUS & QSPI_STATUS_RXCNT_Msk) >> QSPI_STATUS_RXCNT_Pos)
/**
* @brief Get the RX FIFO empty flag.
* @param[in] qspi The pointer of the specified QSPI module.
* @retval 0 RX FIFO is not empty.
* @retval 1 RX FIFO is empty.
* @details Read RXEMPTY bit of QSPI_STATUS register to get the RX FIFO empty flag.
* \hideinitializer
*/
#define QSPI_GET_RX_FIFO_EMPTY_FLAG(qspi) (((qspi)->STATUS & QSPI_STATUS_RXEMPTY_Msk)>>QSPI_STATUS_RXEMPTY_Pos)
/**
* @brief Get the TX FIFO empty flag.
* @param[in] qspi The pointer of the specified QSPI module.
* @retval 0 TX FIFO is not empty.
* @retval 1 TX FIFO is empty.
* @details Read TXEMPTY bit of QSPI_STATUS register to get the TX FIFO empty flag.
* \hideinitializer
*/
#define QSPI_GET_TX_FIFO_EMPTY_FLAG(qspi) (((qspi)->STATUS & QSPI_STATUS_TXEMPTY_Msk)>>QSPI_STATUS_TXEMPTY_Pos)
/**
* @brief Get the TX FIFO full flag.
* @param[in] qspi The pointer of the specified QSPI module.
* @retval 0 TX FIFO is not full.
* @retval 1 TX FIFO is full.
* @details Read TXFULL bit of QSPI_STATUS register to get the TX FIFO full flag.
* \hideinitializer
*/
#define QSPI_GET_TX_FIFO_FULL_FLAG(qspi) (((qspi)->STATUS & QSPI_STATUS_TXFULL_Msk)>>QSPI_STATUS_TXFULL_Pos)
/**
* @brief Get the datum read from RX register.
* @param[in] qspi The pointer of the specified QSPI module.
* @return Data in RX register.
* @details Read QSPI_RX register to get the received datum.
* \hideinitializer
*/
#define QSPI_READ_RX(qspi) ((qspi)->RX)
/**
* @brief Write datum to TX register.
* @param[in] qspi The pointer of the specified QSPI module.
* @param[in] u32TxData The datum which user attempt to transfer through QSPI bus.
* @return None.
* @details Write u32TxData to QSPI_TX register.
* \hideinitializer
*/
#define QSPI_WRITE_TX(qspi, u32TxData) ((qspi)->TX = (u32TxData))
/**
* @brief Set QSPIx_SS pin to high state.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Disable automatic slave selection function and set QSPIx_SS pin to high state.
* \hideinitializer
*/
#define QSPI_SET_SS_HIGH(qspi) ((qspi)->SSCTL = ((qspi)->SSCTL & (~QSPI_SSCTL_AUTOSS_Msk)) | (QSPI_SSCTL_SSACTPOL_Msk | QSPI_SSCTL_SS_Msk))
/**
* @brief Set QSPIx_SS pin to low state.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Disable automatic slave selection function and set QSPIx_SS pin to low state.
* \hideinitializer
*/
#define QSPI_SET_SS_LOW(qspi) ((qspi)->SSCTL = ((qspi)->SSCTL & (~(QSPI_SSCTL_AUTOSS_Msk | QSPI_SSCTL_SSACTPOL_Msk))) | QSPI_SSCTL_SS_Msk)
/**
* @brief Enable Byte Reorder function.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Enable Byte Reorder function. The suspend interval depends on the setting of SUSPITV (QSPI_CTL[7:4]).
* \hideinitializer
*/
#define QSPI_ENABLE_BYTE_REORDER(qspi) ((qspi)->CTL |= QSPI_CTL_REORDER_Msk)
/**
* @brief Disable Byte Reorder function.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Clear REORDER bit field of QSPI_CTL register to disable Byte Reorder function.
* \hideinitializer
*/
#define QSPI_DISABLE_BYTE_REORDER(qspi) ((qspi)->CTL &= ~QSPI_CTL_REORDER_Msk)
/**
* @brief Set the length of suspend interval.
* @param[in] qspi The pointer of the specified QSPI module.
* @param[in] u32SuspCycle Decides the length of suspend interval. It could be 0 ~ 15.
* @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 QSPI bus clock cycle).
* \hideinitializer
*/
#define QSPI_SET_SUSPEND_CYCLE(qspi, u32SuspCycle) ((qspi)->CTL = ((qspi)->CTL & ~QSPI_CTL_SUSPITV_Msk) | ((u32SuspCycle) << QSPI_CTL_SUSPITV_Pos))
/**
* @brief Set the QSPI transfer sequence with LSB first.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Set LSB bit of QSPI_CTL register to set the QSPI transfer sequence with LSB first.
* \hideinitializer
*/
#define QSPI_SET_LSB_FIRST(qspi) ((qspi)->CTL |= QSPI_CTL_LSB_Msk)
/**
* @brief Set the QSPI transfer sequence with MSB first.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Clear LSB bit of QSPI_CTL register to set the QSPI transfer sequence with MSB first.
* \hideinitializer
*/
#define QSPI_SET_MSB_FIRST(qspi) ((qspi)->CTL &= ~QSPI_CTL_LSB_Msk)
/**
* @brief Set the data width of a QSPI transaction.
* @param[in] qspi The pointer of the specified QSPI module.
* @param[in] u32Width The bit width of one transaction.
* @return None.
* @details The data width can be 8 ~ 32 bits.
* \hideinitializer
*/
#define QSPI_SET_DATA_WIDTH(qspi, u32Width) ((qspi)->CTL = ((qspi)->CTL & ~QSPI_CTL_DWIDTH_Msk) | (((u32Width)&0x1F) << QSPI_CTL_DWIDTH_Pos))
/**
* @brief Get the QSPI busy state.
* @param[in] qspi The pointer of the specified QSPI module.
* @retval 0 QSPI controller is not busy.
* @retval 1 QSPI controller is busy.
* @details This macro will return the busy state of QSPI controller.
* \hideinitializer
*/
#define QSPI_IS_BUSY(qspi) ( ((qspi)->STATUS & QSPI_STATUS_BUSY_Msk)>>QSPI_STATUS_BUSY_Pos )
/**
* @brief Enable QSPI controller.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Set QSPIEN (QSPI_CTL[0]) to enable QSPI controller.
* \hideinitializer
*/
#define QSPI_ENABLE(qspi) ((qspi)->CTL |= QSPI_CTL_QSPIEN_Msk)
/**
* @brief Disable QSPI controller.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Clear QSPIEN (QSPI_CTL[0]) to disable QSPI controller.
* \hideinitializer
*/
#define QSPI_DISABLE(qspi) ((qspi)->CTL &= ~QSPI_CTL_QSPIEN_Msk)
/**
* @brief Disable 2-bit Transfer mode.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Clear TWOBIT bit of QSPI_CTL register to disable 2-bit Transfer mode.
*/
#define QSPI_DISABLE_2BIT_MODE(qspi) ( (qspi)->CTL &= ~QSPI_CTL_TWOBIT_Msk )
/**
* @brief Enable 2-bit Transfer mode.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Set TWOBIT bit of QSPI_CTL register to enable 2-bit Transfer mode.
*/
#define QSPI_ENABLE_2BIT_MODE(qspi) ( (qspi)->CTL |= QSPI_CTL_TWOBIT_Msk )
/**
* @brief Disable Slave 3-wire mode.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Clear SLV3WIRE bit of QSPI_SSCTL register to disable Slave 3-wire mode.
*/
#define QSPI_DISABLE_3WIRE_MODE(qspi) ( (qspi)->SSCTL &= ~QSPI_SSCTL_SLV3WIRE_Msk )
/**
* @brief Enable Slave 3-wire mode.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None.
* @details Set SLV3WIRE bit of QSPI_SSCTL register to enable Slave 3-wire mode.
*/
#define QSPI_ENABLE_3WIRE_MODE(qspi) ( (qspi)->SSCTL |= QSPI_SSCTL_SLV3WIRE_Msk )
/**
* @brief Disable QSPI Dual IO function.
* @param[in] qspi is the base address of QSPI module.
* @return none
* \hideinitializer
*/
#define QSPI_DISABLE_DUAL_MODE(qspi) ( (qspi)->CTL &= ~QSPI_CTL_DUALIOEN_Msk )
/**
* @brief Enable Dual IO function and set QSPI Dual IO direction to input.
* @param[in] qspi is the base address of QSPI module.
* @return none
* \hideinitializer
*/
#define QSPI_ENABLE_DUAL_INPUT_MODE(qspi) ( (qspi)->CTL = ((qspi)->CTL & ~QSPI_CTL_DATDIR_Msk) | QSPI_CTL_DUALIOEN_Msk )
/**
* @brief Enable Dual IO function and set QSPI Dual IO direction to output.
* @param[in] qspi is the base address of QSPI module.
* @return none
* \hideinitializer
*/
#define QSPI_ENABLE_DUAL_OUTPUT_MODE(qspi) ( (qspi)->CTL |= QSPI_CTL_DATDIR_Msk | QSPI_CTL_DUALIOEN_Msk )
/**
* @brief Disable QSPI Dual IO function.
* @param[in] qspi is the base address of QSPI module.
* @return none
* \hideinitializer
*/
#define QSPI_DISABLE_QUAD_MODE(qspi) ( (qspi)->CTL &= ~QSPI_CTL_QUADIOEN_Msk )
/**
* @brief Set QSPI Quad IO direction to input.
* @param[in] qspi is the base address of QSPI module.
* @return none
* \hideinitializer
*/
#define QSPI_ENABLE_QUAD_INPUT_MODE(qspi) ( (qspi)->CTL = ((qspi)->CTL & ~QSPI_CTL_DATDIR_Msk) | QSPI_CTL_QUADIOEN_Msk )
/**
* @brief Set QSPI Quad IO direction to output.
* @param[in] qspi is the base address of QSPI module.
* @return none
* \hideinitializer
*/
#define QSPI_ENABLE_QUAD_OUTPUT_MODE(qspi) ( (qspi)->CTL |= QSPI_CTL_DATDIR_Msk | QSPI_CTL_QUADIOEN_Msk )
/* Function prototype declaration */
uint32_t QSPI_Open(QSPI_T *qspi, uint32_t u32MasterSlave, uint32_t u32QSPIMode, uint32_t u32DataWidth, uint32_t u32BusClock);
void QSPI_Close(QSPI_T *qspi);
void QSPI_ClearRxFIFO(QSPI_T *qspi);
void QSPI_ClearTxFIFO(QSPI_T *qspi);
void QSPI_DisableAutoSS(QSPI_T *qspi);
void QSPI_EnableAutoSS(QSPI_T *qspi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel);
uint32_t QSPI_SetBusClock(QSPI_T *qspi, uint32_t u32BusClock);
void QSPI_SetFIFO(QSPI_T *qspi, uint32_t u32TxThreshold, uint32_t u32RxThreshold);
uint32_t QSPI_GetBusClock(QSPI_T *qspi);
void QSPI_EnableInt(QSPI_T *qspi, uint32_t u32Mask);
void QSPI_DisableInt(QSPI_T *qspi, uint32_t u32Mask);
uint32_t QSPI_GetIntFlag(QSPI_T *qspi, uint32_t u32Mask);
void QSPI_ClearIntFlag(QSPI_T *qspi, uint32_t u32Mask);
uint32_t QSPI_GetStatus(QSPI_T *qspi, uint32_t u32Mask);
/*@}*/ /* end of group QSPI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group QSPI_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __QSPI_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,360 @@
/**************************************************************************//**
* @file rtc.h
* @version V1.00
* @brief M251 series RTC driver header file
*
* @copyright (C) 2018 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
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* RTC Initial Keyword Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define RTC_INIT_KEY 0xA5EB1357UL /*!< RTC Initiation Key to make RTC leaving reset state \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* RTC Frequency Compensation Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define RTC_INTEGER_32752 (0x0ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32752HZ \hideinitializer */
#define RTC_INTEGER_32753 (0x1ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32753HZ \hideinitializer */
#define RTC_INTEGER_32754 (0x2ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32754HZ \hideinitializer */
#define RTC_INTEGER_32755 (0x3ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32755HZ \hideinitializer */
#define RTC_INTEGER_32756 (0x4ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32756HZ \hideinitializer */
#define RTC_INTEGER_32757 (0x5ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32757HZ \hideinitializer */
#define RTC_INTEGER_32758 (0x6ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32758HZ \hideinitializer */
#define RTC_INTEGER_32759 (0x7ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32759HZ \hideinitializer */
#define RTC_INTEGER_32760 (0x8ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32760HZ \hideinitializer */
#define RTC_INTEGER_32761 (0x9ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32761HZ \hideinitializer */
#define RTC_INTEGER_32762 (0xaul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32762HZ \hideinitializer */
#define RTC_INTEGER_32763 (0xbul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32763HZ \hideinitializer */
#define RTC_INTEGER_32764 (0xcul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32764HZ \hideinitializer */
#define RTC_INTEGER_32765 (0xdul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32765HZ \hideinitializer */
#define RTC_INTEGER_32766 (0xeul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32766HZ \hideinitializer */
#define RTC_INTEGER_32767 (0xful << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32767HZ \hideinitializer */
#define RTC_INTEGER_32768 (0x10ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32768HZ \hideinitializer */
#define RTC_INTEGER_32769 (0x11ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32769HZ \hideinitializer */
#define RTC_INTEGER_32770 (0x12ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32770HZ \hideinitializer */
#define RTC_INTEGER_32771 (0x13ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32771HZ \hideinitializer */
#define RTC_INTEGER_32772 (0x14ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32772HZ \hideinitializer */
#define RTC_INTEGER_32773 (0x15ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32773HZ \hideinitializer */
#define RTC_INTEGER_32774 (0x16ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32774HZ \hideinitializer */
#define RTC_INTEGER_32775 (0x17ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32775HZ \hideinitializer */
#define RTC_INTEGER_32776 (0x18ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32776HZ \hideinitializer */
#define RTC_INTEGER_32777 (0x19ul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32777HZ \hideinitializer */
#define RTC_INTEGER_32778 (0x1aul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32778HZ \hideinitializer */
#define RTC_INTEGER_32779 (0x1bul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32779HZ \hideinitializer */
#define RTC_INTEGER_32780 (0x1cul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32780HZ \hideinitializer */
#define RTC_INTEGER_32781 (0x1dul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32781HZ \hideinitializer */
#define RTC_INTEGER_32782 (0x1eul << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32782HZ \hideinitializer */
#define RTC_INTEGER_32783 (0x1ful << RTC_FREQADJ_INTEGER_Pos ) /*!< RTC Frequency is 32783HZ \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* RTC Time Attribute Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define RTC_CLOCK_12 0UL /*!< RTC as 12-hour time scale with AM and PM indication \hideinitializer */
#define RTC_CLOCK_24 1UL /*!< RTC as 24-hour time scale \hideinitializer */
#define RTC_AM 1UL /*!< RTC as AM indication \hideinitializer */
#define RTC_PM 2UL /*!< RTC as PM indication \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* RTC Tick Period Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define RTC_TICK_1_SEC 0x0UL /*!< RTC time tick period is 1 second \hideinitializer */
#define RTC_TICK_1_2_SEC 0x1UL /*!< RTC time tick period is 1/2 second \hideinitializer */
#define RTC_TICK_1_4_SEC 0x2UL /*!< RTC time tick period is 1/4 second \hideinitializer */
#define RTC_TICK_1_8_SEC 0x3UL /*!< RTC time tick period is 1/8 second \hideinitializer */
#define RTC_TICK_1_16_SEC 0x4UL /*!< RTC time tick period is 1/16 second \hideinitializer */
#define RTC_TICK_1_32_SEC 0x5UL /*!< RTC time tick period is 1/32 second \hideinitializer */
#define RTC_TICK_1_64_SEC 0x6UL /*!< RTC time tick period is 1/64 second \hideinitializer */
#define RTC_TICK_1_128_SEC 0x7UL /*!< RTC time tick period is 1/128 second \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* RTC Day of Week Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define RTC_SUNDAY 0x0UL /*!< Day of the Week is Sunday \hideinitializer */
#define RTC_MONDAY 0x1UL /*!< Day of the Week is Monday \hideinitializer */
#define RTC_TUESDAY 0x2UL /*!< Day of the Week is Tuesday \hideinitializer */
#define RTC_WEDNESDAY 0x3UL /*!< Day of the Week is Wednesday \hideinitializer */
#define RTC_THURSDAY 0x4UL /*!< Day of the Week is Thursday \hideinitializer */
#define RTC_FRIDAY 0x5UL /*!< Day of the Week is Friday \hideinitializer */
#define RTC_SATURDAY 0x6UL /*!< Day of the Week is Saturday \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* RTC Miscellaneous Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define RTC_WAIT_COUNT 0xFFFFFFFFUL /*!< Initial Time-out Value \hideinitializer */
#define RTC_YEAR2000 2000UL /*!< RTC Reference for compute year data \hideinitializer */
#define RTC_FCR_REFERENCE 32761UL /*!< RTC Reference for frequency compensation \hideinitializer */
#define RTC_TAMPER0_SELECT (0x1ul << 0) /*!< Select Tamper 0 \hideinitializer */
#define MAX_TAMPER_PIN_NUM 1ul /*!< Tamper Pin number \hideinitializer */
#define RTC_TAMPER_HIGH_LEVEL_DETECT 0ul /*!< Tamper pin detect voltage level is High \hideinitializer */
#define RTC_TAMPER_LOW_LEVEL_DETECT 1ul /*!< Tamper pin detect voltage level is low \hideinitializer */
#define RTC_TAMPER_DEBOUNCE_ENABLE 1ul /*!< Enable RTC tamper pin de-bounce function \hideinitializer */
#define RTC_TAMPER_DEBOUNCE_DISABLE 0ul /*!< Disable RTC tamper pin de-bounce function \hideinitializer */
/*@}*/ /* 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.
* \hideinitializer
*/
#define RTC_IS_LEAP_YEAR() (RTC->LEAPYEAR & RTC_LEAPYEAR_LEAPYEAR_Msk ? 1:0)
/**
* @brief Clear RTC Alarm Interrupt Flag
*
* @param None
*
* @return None
*
* @details This macro is used to clear RTC alarm interrupt flag.
* \hideinitializer
*/
#define RTC_CLEAR_ALARM_INT_FLAG() (RTC->INTSTS = RTC_INTSTS_ALMIF_Msk)
/**
* @brief Clear RTC Tick Interrupt Flag
*
* @param None
*
* @return None
*
* @details This macro is used to clear RTC tick interrupt flag.
* \hideinitializer
*/
#define RTC_CLEAR_TICK_INT_FLAG() (RTC->INTSTS = RTC_INTSTS_TICKIF_Msk)
/**
* @brief Clear RTC Tamper Interrupt Flag
*
* @param u32TamperFlag Tamper interrupt flag. It consists of: \n
* - \ref RTC_INTSTS_TAMP0IF_Msk
*
* @return None
*
* @details This macro is used to clear RTC snooper pin interrupt flag.
* \hideinitializer
*/
#define RTC_CLEAR_TAMPER_INT_FLAG(u32TamperFlag) (RTC->INTSTS = (u32TamperFlag))
/**
* @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 indicates RTC alarm interrupt occurred or not.
* \hideinitializer
*/
#define RTC_GET_ALARM_INT_FLAG() ((RTC->INTSTS & RTC_INTSTS_ALMIF_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 indicates RTC time tick interrupt occurred or not.
* \hideinitializer
*/
#define RTC_GET_TICK_INT_FLAG() ((RTC->INTSTS & RTC_INTSTS_TICKIF_Msk)? 1:0)
/**
* @brief Get RTC Tamper Interrupt Flag
*
* @param None
*
* @retval 0 RTC snooper pin interrupt did not occur
* @retval 1 RTC snooper pin interrupt occurred
*
* @details This macro indicates RTC snooper pin interrupt occurred or not.
* \hideinitializer
*/
#define RTC_GET_TAMPER_INT_FLAG() ((RTC->INTSTS & (0x0100))? 1:0)
/**
* @brief Get RTC TAMPER Interrupt Status
*
* @param None
*
* @retval RTC_INTSTS_TAMP0IF_Msk Tamper 0 interrupt flag is generated
*
* @details This macro indicates RTC snooper pin interrupt occurred or not.
* \hideinitializer
*/
#define RTC_GET_TAMPER_INT_STATUS() ((RTC->INTSTS & (0x0100)))
/**
* @brief Enable RTC Tick Wake-up Function
*
* @param None
*
* @return None
*
* @details This macro is used to enable RTC tick interrupt wake-up function.
* \hideinitializer
*/
#define RTC_ENABLE_TICK_WAKEUP() ((RTC->INTEN |= RTC_INTEN_TICKIEN_Msk))
/**
* @brief Disable RTC Tick Wake-up Function
*
* @param None
*
* @return None
*
* @details This macro is used to disable RTC tick interrupt wake-up function.
* \hideinitializer
*/
#define RTC_DISABLE_TICK_WAKEUP() ((RTC->INTEN &= ~RTC_INTEN_TICKIEN_Msk));
/**
* @brief Enable RTC Alarm Wake-up Function
*
* @param None
*
* @return None
*
* @details This macro is used to enable RTC Alarm interrupt wake-up function.
* \hideinitializer
*/
#define RTC_ENABLE_ALARM_WAKEUP() ((RTC->INTEN |= RTC_INTEN_ALMIEN_Msk))
/**
* @brief Disable RTC Alarm Wake-up Function
*
* @param None
*
* @return None
*
* @details This macro is used to disable RTC Alarm interrupt wake-up function.
* \hideinitializer
*/
#define RTC_DISABLE_ALARM_WAKEUP() ((RTC->INTEN &= ~RTC_INTEN_ALMIEN_Msk));
/**
* @brief Read Spare Register
*
* @param[in] u32RegNum The spare register number, 0~4.
*
* @return Spare register content
*
* @details Read the specify spare register content.
* @note The returned value is valid only when SPRRWEN(SPRCTL[2] RTC Spare Function control register) bit is set. \n
* And its controlled by RTC Spare Function control register(RTC_SPRCTL).
* \hideinitializer
*/
#define RTC_READ_SPARE_REGISTER(u32RegNum) (RTC->SPR[(u32RegNum)])
/**
* @brief Write Spare Register
*
* @param[in] u32RegNum The spare register number, 0~4.
* @param[in] u32RegValue The spare register value.
*
* @return None
*
* @details Write specify data to spare register.
* @note This macro is effect only when SPRRWEN(SPRCTL[2] RTC Spare Function control register) bit is set. \n
* And its controlled by RTC Spare Function control register(RTC_SPRCTL).
* \hideinitializer
*/
#define RTC_WRITE_SPARE_REGISTER(u32RegNum, u32RegValue) (RTC->SPR[(u32RegNum)] = (u32RegValue))
void RTC_Open(S_RTC_TIME_DATA_T *psPt);
void RTC_Close(void);
void RTC_32KCalibration(int32_t i32FrequencyX10000);
void RTC_GetDateAndTime(S_RTC_TIME_DATA_T *psPt);
void RTC_GetAlarmDateAndTime(S_RTC_TIME_DATA_T *psPt);
void RTC_SetDateAndTime(S_RTC_TIME_DATA_T *psPt);
void RTC_SetAlarmDateAndTime(S_RTC_TIME_DATA_T *psPt);
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);
void RTC_SetAlarmDateMask(uint8_t u8IsTenYMsk, uint8_t u8IsYMsk, uint8_t u8IsTenMMsk, uint8_t u8IsMMsk, uint8_t u8IsTenDMsk, uint8_t u8IsDMsk);
void RTC_SetAlarmTimeMask(uint8_t u8IsTenHMsk, uint8_t u8IsHMsk, uint8_t u8IsTenMMsk, uint8_t u8IsMMsk, uint8_t u8IsTenSMsk, uint8_t u8IsSMsk);
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_EnableSpareAccess(void);
void RTC_DisableSpareRegister(void);
void RTC_StaticTamperEnable(uint32_t u32TamperSelect, uint32_t u32DetecLevel, uint32_t u32DebounceEn);
void RTC_StaticTamperDisable(uint32_t u32TamperSelect);
/*@}*/ /* end of group RTC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group RTC_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __RTC_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,383 @@
/**************************************************************************//**
* @file sc.h
* @version V3.00
* @brief Smart Card(SC) driver header file
*
* @note
* @copyright (C) 2018 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 (1ul) /*!< Smartcard interface numbers \hideinitializer */
#define SC_PIN_STATE_HIGH (1ul) /*!< Smartcard pin status high \hideinitializer */
#define SC_PIN_STATE_LOW (0ul) /*!< Smartcard pin status low \hideinitializer */
#define SC_PIN_STATE_IGNORE (0xFFFFFFFFul) /*!< Ignore pin status \hideinitializer */
#define SC_CLK_ON (1ul) /*!< Smartcard clock on \hideinitializer */
#define SC_CLK_OFF (0ul) /*!< Smartcard clock off \hideinitializer */
#define SC_TMR_MODE_0 (0ul << SC_TMRCTL0_OPMODE_Pos) /*!<Timer Operation Mode 0, down count \hideinitializer */
#define SC_TMR_MODE_1 (1ul << SC_TMRCTL0_OPMODE_Pos) /*!<Timer Operation Mode 1, down count, start after detect start bit \hideinitializer */
#define SC_TMR_MODE_2 (2ul << SC_TMRCTL0_OPMODE_Pos) /*!<Timer Operation Mode 2, down count, start after receive start bit \hideinitializer */
#define SC_TMR_MODE_3 (3ul << SC_TMRCTL0_OPMODE_Pos) /*!<Timer Operation Mode 3, down count, use for activation, only timer 0 support this mode \hideinitializer */
#define SC_TMR_MODE_4 (4ul << SC_TMRCTL0_OPMODE_Pos) /*!<Timer Operation Mode 4, down count with reload after timeout \hideinitializer */
#define SC_TMR_MODE_5 (5ul << SC_TMRCTL0_OPMODE_Pos) /*!<Timer Operation Mode 5, down count, start after detect start bit, reload after timeout \hideinitializer */
#define SC_TMR_MODE_6 (6ul << SC_TMRCTL0_OPMODE_Pos) /*!<Timer Operation Mode 6, down count, start after receive start bit, reload after timeout \hideinitializer */
#define SC_TMR_MODE_7 (7ul << SC_TMRCTL0_OPMODE_Pos) /*!<Timer Operation Mode 7, down count, start and reload after detect start bit \hideinitializer */
#define SC_TMR_MODE_8 (8ul << SC_TMRCTL0_OPMODE_Pos) /*!<Timer Operation Mode 8, up count \hideinitializer */
#define SC_TMR_MODE_F (0xF << SC_TMRCTL0_OPMODE_Pos) /*!<Timer Operation Mode 15, down count, reload after detect start bit \hideinitializer */
/*@}*/ /* end of group SC_EXPORTED_CONSTANTS */
/** @addtogroup SC_EXPORTED_FUNCTIONS SC Exported Functions
@{
*/
/**
* @brief Enable Smartcard Interrupt
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32Mask Interrupt mask to be enabled. A combination of
* - \ref SC_INTEN_ACERRIEN_Msk
* - \ref SC_INTEN_RXTOIEN_Msk
* - \ref SC_INTEN_INITIEN_Msk
* - \ref SC_INTEN_CDIEN_Msk
* - \ref SC_INTEN_BGTIEN_Msk
* - \ref SC_INTEN_TMR2IEN_Msk
* - \ref SC_INTEN_TMR1IEN_Msk
* - \ref SC_INTEN_TMR0IEN_Msk
* - \ref SC_INTEN_TERRIEN_Msk
* - \ref SC_INTEN_TBEIEN_Msk
* - \ref SC_INTEN_RDAIEN_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(psSC, u32Mask) ((psSC)->INTEN |= (u32Mask))
/**
* @brief Disable Smartcard Interrupt
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32Mask Interrupt mask to be disabled. A combination of
* - \ref SC_INTEN_ACERRIEN_Msk
* - \ref SC_INTEN_RXTOIEN_Msk
* - \ref SC_INTEN_INITIEN_Msk
* - \ref SC_INTEN_CDIEN_Msk
* - \ref SC_INTEN_BGTIEN_Msk
* - \ref SC_INTEN_TMR2IEN_Msk
* - \ref SC_INTEN_TMR1IEN_Msk
* - \ref SC_INTEN_TMR0IEN_Msk
* - \ref SC_INTEN_TERRIEN_Msk
* - \ref SC_INTEN_TBEIEN_Msk
* - \ref SC_INTEN_RDAIEN_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(psSC, u32Mask) ((psSC)->INTEN &= ~(u32Mask))
/**
* @brief Check Smartcard Interrupt Status Flag
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32Mask Interrupt mask to be disabled. A combination of
* - \ref SC_INTSTS_ACERRIF_Msk
* - \ref SC_INTSTS_RXTOIF_Msk
* - \ref SC_INTSTS_INITIF_Msk
* - \ref SC_INTSTS_CDIF_Msk
* - \ref SC_INTSTS_BGTIF_Msk
* - \ref SC_INTSTS_TMR2IF_Msk
* - \ref SC_INTSTS_TMR1IF_Msk
* - \ref SC_INTSTS_TMR0IF_Msk
* - \ref SC_INTSTS_TERRIF_Msk
* - \ref SC_INTSTS_TBEIF_Msk
* - \ref SC_INTSTS_RDAIF_Msk
*
* @return None
*
* @details The macro is used to check 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_CHECK_INTSTS(psSC, u32Mask) ((psSC)->INTSTS &= u32Mask)
/**
* @brief Clear Smartcard Interrupt Status Flag
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32Mask Interrupt mask to be disabled. A combination of
* - \ref SC_INTSTS_ACERRIF_Msk
* - \ref SC_INTSTS_RXTOIF_Msk
* - \ref SC_INTSTS_INITIF_Msk
* - \ref SC_INTSTS_CDIF_Msk
* - \ref SC_INTSTS_BGTIF_Msk
* - \ref SC_INTSTS_TMR2IF_Msk
* - \ref SC_INTSTS_TMR1IF_Msk
* - \ref SC_INTSTS_TMR0IF_Msk
* - \ref SC_INTSTS_TERRIF_Msk
* - \ref SC_INTSTS_TBEIF_Msk
* - \ref SC_INTSTS_RDAIF_Msk
*
* @return None
*
* @details The macro is used to check 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_CLEAR_INTSTS(psSC, u32Mask) ((psSC)->INTSTS = u32Mask)
/**
* @brief Set ETU Divider
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32Mask ETU divider value
*
* @return None
*
* @details The macro is used to give ETU divider. Its value must be given more than 4.
* \hideinitializer
*/
#define SC_SET_ETUDIV(psSC, u32Mask) ((psSC)->ETUCTL = (((psSC)->ETUCTL&(~SC_ETUCTL_ETURDIV_Msk)) | (u32Mask <<SC_ETUCTL_ETURDIV_Pos)))
/**
* @brief Set Smartcard Power Pin State
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32State Set pin state of power pin, valid parameters are:
* - \ref SC_PIN_STATE_HIGH
* - \ref SC_PIN_STATE_LOW
*
* @return None
*
* @details User can set PWREN (SC_PINCTL[0]) and PWRINV (SC_PINCTL[11]) to decide SC_PWR pin is in high or low level.
* \hideinitializer
*/
#define SC_SET_VCC_PIN(psSC, u32State) \
do {\
while((psSC)->PINCTL & SC_PINCTL_SYNC_Msk);\
if(u32State)\
(psSC)->PINCTL |= SC_PINCTL_PWREN_Msk;\
else\
(psSC)->PINCTL &= ~SC_PINCTL_PWREN_Msk;\
}while(0)
/**
* @brief Set Smartcard Clock Status
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32OnOff Set clock on or off for selected smartcard module, valid values are:
* - \ref SC_CLK_ON
* - \ref SC_CLK_OFF
*
* @return None
*
* @details User can set CLKKEEP (SC_PINCTL[6]) to decide SC_CLK pin always keeps free running or not.
* \hideinitializer
*/
#define SC_SET_CLK_PIN(psSC, u32OnOff)\
do {\
while((psSC)->PINCTL & SC_PINCTL_SYNC_Msk);\
if(u32OnOff)\
(psSC)->PINCTL |= SC_PINCTL_CLKKEEP_Msk;\
else\
(psSC)->PINCTL &= ~(SC_PINCTL_CLKKEEP_Msk);\
}while(0)
/**
* @brief Set Smartcard I/O Pin State
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32State Set pin state of I/O pin, valid parameters are:
* - \ref SC_PIN_STATE_HIGH
* - \ref SC_PIN_STATE_LOW
*
* @return None
*
* @details User can set SCDATA (SC_PINCTL[9]) to decide SC_DATA pin to high or low.
* \hideinitializer
*/
#define SC_SET_IO_PIN(psSC, u32State)\
do {\
while((psSC)->PINCTL & SC_PINCTL_SYNC_Msk);\
if(u32State)\
(psSC)->PINCTL |= SC_PINCTL_SCDATA_Msk;\
else\
(psSC)->PINCTL &= ~SC_PINCTL_SCDATA_Msk;\
}while(0)
/**
* @brief Set Smartcard Reset Pin State
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32State Set pin state of reset pin, valid parameters are:
* - \ref SC_PIN_STATE_HIGH
* - \ref SC_PIN_STATE_LOW
*
* @return None
*
* @details User can set SCRST (SC_PINCTL[1]) to decide SC_RST pin to high or low.
* \hideinitializer
*/
#define SC_SET_RST_PIN(psSC, u32State)\
do {\
while((psSC)->PINCTL & SC_PINCTL_SYNC_Msk);\
if(u32State)\
(psSC)->PINCTL |= SC_PINCTL_RSTEN_Msk;\
else\
(psSC)->PINCTL &= ~SC_PINCTL_RSTEN_Msk;\
}while(0)
/**
* @brief Read One Byte Data
*
* @param[in] psSC The pointer of smartcard module.
*
* @return One byte read from receive FIFO
*
* @details By reading DAT register, the SC will return an 8-bit received data.
* \hideinitializer
*/
#define SC_READ(psSC) ((char)((psSC)->DAT))
/**
* @brief Write One Byte Data
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u8Data Data to write to transmit FIFO.
*
* @return None
*
* @details By writing data to DAT register, the SC will send out an 8-bit data.
* \hideinitializer
*/
#define SC_WRITE(psSC, u8Data) ((psSC)->DAT = (u8Data))
/**
* @brief Set Smartcard Stop Bit Length
*
* @param[in] psSC 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(psSC, u32Len) ((psSC)->CTL = ((psSC)->CTL & ~SC_CTL_NSB_Msk) | (((u32Len) == 1)? SC_CTL_NSB_Msk : 0))
/*---------------------------------------------------------------------------------------------------------*/
/* static inline functions */
/*---------------------------------------------------------------------------------------------------------*/
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
__STATIC_INLINE void SC_SetTxRetry(SC_T *psSC, uint32_t u32Count);
__STATIC_INLINE void SC_SetRxRetry(SC_T *psSC, uint32_t u32Count);
/**
* @brief Set Tx Error Retry Count
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32Count The number of Tx error retry count, between 0~8 and 0 means disable Tx error retry function.
*
* @return None
*
* @details This function is used to enable/disable transmitter retry function when parity error has occurred, and set error retry count.
* @note Set error retry count to 0 will disable Tx error retry function.
*/
__STATIC_INLINE void SC_SetTxRetry(SC_T *psSC, uint32_t u32Count)
{
while ((psSC)->CTL & SC_CTL_SYNC_Msk) {}
/* Retry count must set while enable bit disabled, so disable it first */
(psSC)->CTL &= ~(SC_CTL_TXRTY_Msk | SC_CTL_TXRTYEN_Msk);
if ((u32Count) != 0UL)
{
while ((psSC)->CTL & SC_CTL_SYNC_Msk) {}
(psSC)->CTL |= (((u32Count) - 1UL) << SC_CTL_TXRTY_Pos) | SC_CTL_TXRTYEN_Msk;
}
}
/**
* @brief Set Rx Error Retry Count
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32Count The number of Rx error retry count, between 0~8 and 0 means disable Rx error retry function.
*
* @return None
*
* @details This function is used to enable/disable receiver retry function when parity error has occurred, and set error retry count.
* @note Set error retry count to 0 will disable Rx error retry function.
*/
__STATIC_INLINE void SC_SetRxRetry(SC_T *psSC, uint32_t u32Count)
{
while ((psSC)->CTL & SC_CTL_SYNC_Msk) {}
/* Retry count must set while enable bit disabled, so disable it first */
(psSC)->CTL &= ~(SC_CTL_RXRTY_Msk | SC_CTL_RXRTYEN_Msk);
if ((u32Count) != 0UL)
{
while ((psSC)->CTL & SC_CTL_SYNC_Msk) {}
(psSC)->CTL |= (((u32Count) - 1UL) << SC_CTL_RXRTY_Pos) | SC_CTL_RXRTYEN_Msk;
}
}
uint32_t SC_IsCardInserted(SC_T *psSC);
void SC_ClearFIFO(SC_T *psSC);
void SC_Close(SC_T *psSC);
void SC_Open(SC_T *psSC, uint32_t u32CardDet, uint32_t u32PWR);
void SC_ResetReader(SC_T *psSC);
void SC_SetBlockGuardTime(SC_T *psSC, uint32_t u32BGT);
void SC_SetCharGuardTime(SC_T *psSC, uint32_t u32CGT);
void SC_StopAllTimer(SC_T *psSC);
void SC_StartTimer(SC_T *psSC, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount);
void SC_StopTimer(SC_T *psSC, uint32_t u32TimerNum);
uint32_t SC_GetInterfaceClock(SC_T *psSC);
/*@}*/ /* end of group SC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SC_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __SC_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,266 @@
/**************************************************************************//**
* @file scuart.h
* @version V1.00
* @brief M251 Smartcard UART mode (SCUART) driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __SCUART_H__
#define __SCUART_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup SCUART_Driver SCUART Driver
@{
*/
/** @addtogroup SCUART_EXPORTED_CONSTANTS SCUART Exported Constants
@{
*/
#define SCUART_CHAR_LEN_5 (0x3ul << SC_UARTCTL_WLS_Pos) /*!< Set SCUART word length to 5 bits \hideinitializer */
#define SCUART_CHAR_LEN_6 (0x2ul << SC_UARTCTL_WLS_Pos) /*!< Set SCUART word length to 6 bits \hideinitializer */
#define SCUART_CHAR_LEN_7 (0x1ul << SC_UARTCTL_WLS_Pos) /*!< Set SCUART word length to 7 bits \hideinitializer */
#define SCUART_CHAR_LEN_8 (0UL) /*!< Set SCUART word length to 8 bits \hideinitializer */
#define SCUART_PARITY_NONE (SC_UARTCTL_PBOFF_Msk) /*!< Set SCUART transfer with no parity \hideinitializer */
#define SCUART_PARITY_ODD (SC_UARTCTL_OPE_Msk) /*!< Set SCUART transfer with odd parity \hideinitializer */
#define SCUART_PARITY_EVEN (0UL) /*!< Set SCUART transfer with even parity \hideinitializer */
#define SCUART_STOP_BIT_1 (SC_CTL_NSB_Msk) /*!< Set SCUART transfer with one stop bit \hideinitializer */
#define SCUART_STOP_BIT_2 (0UL) /*!< Set SCUART transfer with two stop bits \hideinitializer */
/*@}*/ /* end of group SCUART_EXPORTED_CONSTANTS */
/** @addtogroup SCUART_EXPORTED_FUNCTIONS SCUART Exported Functions
@{
*/
/* TX Macros */
/**
* @brief Write Data to Tx data register
* @param[in] psSC The base address of smartcard module.
* @param[in] u8Data Data byte to transmit
* @return None
* \hideinitializer
*/
#define SCUART_WRITE(psSC, u8Data) ((psSC)->DAT = (u8Data))
/**
* @brief Get TX FIFO empty flag status from register
* @param[in] psSC The base address of smartcard module
* @return Transmit FIFO empty status
* @retval 0 Transmit FIFO is not empty
* @retval SC_STATUS_TXEMPTY_Msk Transmit FIFO is empty
* \hideinitializer
*/
#define SCUART_GET_TX_EMPTY(psSC) ((psSC)->STATUS & SC_STATUS_TXEMPTY_Msk)
/**
* @brief Get TX FIFO full flag status from register
* @param[in] psSC The base address of smartcard module
* @return Transmit FIFO full status
* @retval 0 Transmit FIFO is not full
* @retval SC_STATUS_TXFULL_Msk Transmit FIFO is full
* \hideinitializer
*/
#define SCUART_GET_TX_FULL(psSC) ((psSC)->STATUS & SC_STATUS_TXFULL_Msk)
/**
* @brief Wait specified smartcard port transmission complete
* @param[in] psSC The base address of smartcard module
* @return None
* @note This Macro blocks until transmit complete.
* \hideinitializer
*/
#define SCUART_WAIT_TX_EMPTY(psSC) while((psSC)->STATUS & SC_STATUS_TXACT_Msk)
/**
* @brief Check specified smartcard port transmit FIFO is full or not
* @param[in] psSC The base address of smartcard module
* @return Transmit FIFO full status
* @retval 0 Transmit FIFO is not full
* @retval 1 Transmit FIFO is full
* \hideinitializer
*/
#define SCUART_IS_TX_FULL(psSC) ((psSC)->STATUS & SC_STATUS_TXFULL_Msk ? 1 : 0)
/**
* @brief Check specified smartcard port transmission is over
* @param[in] psSC The base address of smartcard module
* @return Transmit complete status
* @retval 0 Transmit is not complete
* @retval 1 Transmit complete
* \hideinitializer
*/
#define SCUART_IS_TX_EMPTY(psSC) ((psSC)->STATUS & SC_STATUS_TXACT_Msk ? 0 : 1)
/**
* @brief Check specified Smartcard port Transmission Status
* @param[in] psSC The pointer of smartcard module.
* @retval 0 Transmit is completed
* @retval 1 Transmit is active
* @details TXACT (SC_STATUS[31]) is set by hardware when Tx transfer is in active and the STOP bit of the last byte has been transmitted.
* \hideinitializer
*/
#define SCUART_IS_TX_ACTIVE(psSC) (((psSC)->STATUS & SC_STATUS_TXACT_Msk)? 1 : 0)
/* RX Macros */
/**
* @brief Read Rx data register
* @param[in] psSC The base address of smartcard module
* @return The oldest data byte in RX FIFO
* \hideinitializer
*/
#define SCUART_READ(psSC) ((psSC)->DAT)
/**
* @brief Get RX FIFO empty flag status from register
* @param[in] psSC The base address of smartcard module
* @return Receive FIFO empty status
* @retval 0 Receive FIFO is not empty
* @retval SC_STATUS_RXEMPTY_Msk Receive FIFO is empty
* \hideinitializer
*/
#define SCUART_GET_RX_EMPTY(psSC) ((psSC)->STATUS & SC_STATUS_RXEMPTY_Msk)
/**
* @brief Get RX FIFO full flag status from register
* @param[in] psSC The base address of smartcard module
* @return Receive FIFO full status
* @retval 0 Receive FIFO is not full
* @retval SC_STATUS_RXFULLF_Msk Receive FIFO is full
* \hideinitializer
*/
#define SCUART_GET_RX_FULL(psSC) ((psSC)->STATUS & SC_STATUS_RXFULL_Msk)
/**
* @brief Check if receive data number in FIFO reach FIFO trigger level or not
* @param[in] psSC The base address of smartcard module
* @return Receive FIFO data status
* @retval 0 The number of bytes in receive FIFO is less than trigger level
* @retval 1 The number of bytes in receive FIFO equals or larger than trigger level
* @note If receive trigger level is \b not 1 byte, this macro return 0 does not necessary indicates there is \b no data in FIFO
* \hideinitializer
*/
#define SCUART_IS_RX_READY(psSC) ((psSC)->INTSTS & SC_INTSTS_RDAIF_Msk ? 1 : 0)
/**
* @brief Check specified smartcard port receive FIFO is full or not
* @param[in] psSC The base address of smartcard module
* @return Receive FIFO full status
* @retval 0 Receive FIFO is not full
* @retval 1 Receive FIFO is full
* \hideinitializer
*/
#define SCUART_IS_RX_FULL(psSC) ((psSC)->STATUS & SC_STATUS_RXFULL_Msk ? 1 : 0)
/* Interrupt Macros */
/**
* @brief Enable specified interrupts
* @param[in] psSC The base address of smartcard module
* @param[in] u32Mask Interrupt masks to enable, a combination of following bits
* - \ref SC_INTEN_RXTOIEN_Msk
* - \ref SC_INTEN_TERRIEN_Msk
* - \ref SC_INTEN_TBEIEN_Msk
* - \ref SC_INTEN_RDAIEN_Msk
* @return None
* \hideinitializer
*/
#define SCUART_ENABLE_INT(psSC, u32Mask) ((psSC)->INTEN |= (u32Mask))
/**
* @brief Disable specified interrupts
* @param[in] psSC The base address of smartcard module
* @param[in] u32Mask Interrupt masks to disable, a combination of following bits
* - \ref SC_INTEN_RXTOIEN_Msk
* - \ref SC_INTEN_TERRIEN_Msk
* - \ref SC_INTEN_TBEIEN_Msk
* - \ref SC_INTEN_RDAIEN_Msk
* @return None
* \hideinitializer
*/
#define SCUART_DISABLE_INT(psSC, u32Mask) ((psSC)->INTEN &= ~(u32Mask))
/**
* @brief Get specified interrupt flag/status
* @param[in] psSC The base address of smartcard module
* @param[in] u32Type Interrupt flag/status to check, could be one of following value
* - \ref SC_INTSTS_RXTOIF_Msk
* - \ref SC_INTSTS_TERRIF_Msk
* - \ref SC_INTSTS_TBEIF_Msk
* - \ref SC_INTSTS_RDAIF_Msk
* @return The status of specified interrupt
* @retval 0 Specified interrupt does not happened
* @retval 1 Specified interrupt happened
* \hideinitializer
*/
#define SCUART_GET_INT_FLAG(psSC, u32Type) ((psSC)->INTSTS & (u32Type) ? 1 : 0)
/**
* @brief Clear specified interrupt flag/status
* @param[in] psSC The base address of smartcard module
* @param[in] u32Type Interrupt flag/status to clear, could be the combination of following values
* - \ref SC_INTSTS_RXTOIF_Msk
* - \ref SC_INTSTS_TERRIF_Msk
* - \ref SC_INTSTS_TBEIF_Msk
* @return None
* \hideinitializer
*/
#define SCUART_CLR_INT_FLAG(psSC, u32Type) ((psSC)->INTSTS = (u32Type))
/**
* @brief Get receive error flag/status
* @param[in] psSC The base address of smartcard module
* @return Current receive error status, could one of following errors:
* @retval SC_STATUS_PEF_Msk Parity error
* @retval SC_STATUS_FEF_Msk Frame error
* @retval SC_STATUS_BEF_Msk Break error
* \hideinitializer
*/
#define SCUART_GET_ERR_FLAG(psSC) ((psSC)->STATUS & (SC_STATUS_PEF_Msk | SC_STATUS_FEF_Msk | SC_STATUS_BEF_Msk))
/**
* @brief Clear specified receive error flag/status
* @param[in] psSC The base address of smartcard module
* @param[in] u32Mask Receive error flag/status to clear, combination following values
* - \ref SC_STATUS_PEF_Msk
* - \ref SC_STATUS_FEF_Msk
* - \ref SC_STATUS_BEF_Msk
* @return None
* \hideinitializer
*/
#define SCUART_CLR_ERR_FLAG(psSC, u32Mask) ((psSC)->STATUS = (u32Mask))
void SCUART_Close(SC_T *psSC);
uint32_t SCUART_Open(SC_T *psSC, uint32_t u32baudrate);
uint32_t SCUART_Read(SC_T *psSC, uint8_t pu8RxBuf[], uint32_t u32ReadBytes);
uint32_t SCUART_SetLineConfig(SC_T *psSC, uint32_t u32Baudrate, uint32_t u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits);
void SCUART_SetTimeoutCnt(SC_T *psSC, uint32_t u32TOC);
void SCUART_Write(SC_T *psSC, uint8_t pu8TxBuf[], uint32_t u32WriteBytes);
/*@}*/ /* end of group SCUART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SCUART_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __SCUART_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,595 @@
/**************************************************************************//**
* @file spi.h
* @version V0.10
* @brief M251 series SPI driver header file
*
* @copyright (C) 2018 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_CTL_TXNEG_Msk) /*!< CLKPOL=0; RXNEG=0; TXNEG=1 \hideinitializer */
#define SPI_MODE_1 (SPI_CTL_RXNEG_Msk) /*!< CLKPOL=0; RXNEG=1; TXNEG=0 \hideinitializer */
#define SPI_MODE_2 (SPI_CTL_CLKPOL_Msk | SPI_CTL_RXNEG_Msk) /*!< CLKPOL=1; RXNEG=1; TXNEG=0 \hideinitializer */
#define SPI_MODE_3 (SPI_CTL_CLKPOL_Msk | SPI_CTL_TXNEG_Msk) /*!< CLKPOL=1; RXNEG=0; TXNEG=1 \hideinitializer */
#define SPI_SLAVE (SPI_CTL_SLAVE_Msk) /*!< Set as slave \hideinitializer */
#define SPI_MASTER (0x0UL) /*!< Set as master \hideinitializer */
#define SPI_SS (SPI_SSCTL_SS_Msk) /*!< Set SS \hideinitializer */
#define SPI_SS_ACTIVE_HIGH (SPI_SSCTL_SSACTPOL_Msk) /*!< SS active high \hideinitializer */
#define SPI_SS_ACTIVE_LOW (0x0UL) /*!< SS active low \hideinitializer */
/* SPI Interrupt Mask */
#define SPI_UNIT_INT_MASK (0x001UL) /*!< Unit transfer interrupt mask \hideinitializer */
#define SPI_SSACT_INT_MASK (0x002UL) /*!< Slave selection signal active interrupt mask \hideinitializer */
#define SPI_SSINACT_INT_MASK (0x004UL) /*!< Slave selection signal inactive interrupt mask \hideinitializer */
#define SPI_SLVUR_INT_MASK (0x008UL) /*!< Slave under run interrupt mask \hideinitializer */
#define SPI_SLVBE_INT_MASK (0x010UL) /*!< Slave bit count error interrupt mask \hideinitializer */
#define SPI_TXUF_INT_MASK (0x040UL) /*!< Slave TX underflow interrupt mask \hideinitializer */
#define SPI_FIFO_TXTH_INT_MASK (0x080UL) /*!< FIFO TX threshold interrupt mask \hideinitializer */
#define SPI_FIFO_RXTH_INT_MASK (0x100UL) /*!< FIFO RX threshold interrupt mask \hideinitializer */
#define SPI_FIFO_RXOV_INT_MASK (0x200UL) /*!< FIFO RX overrun interrupt mask \hideinitializer */
#define SPI_FIFO_RXTO_INT_MASK (0x400UL) /*!< FIFO RX time-out interrupt mask \hideinitializer */
/* SPI Status Mask */
#define SPI_BUSY_MASK (0x01UL) /*!< Busy status mask \hideinitializer */
#define SPI_RX_EMPTY_MASK (0x02UL) /*!< RX empty status mask \hideinitializer */
#define SPI_RX_FULL_MASK (0x04UL) /*!< RX full status mask \hideinitializer */
#define SPI_TX_EMPTY_MASK (0x08UL) /*!< TX empty status mask \hideinitializer */
#define SPI_TX_FULL_MASK (0x10UL) /*!< TX full status mask \hideinitializer */
#define SPI_TXRX_RESET_MASK (0x20UL) /*!< TX or RX reset status mask \hideinitializer */
#define SPI_SPIEN_STS_MASK (0x40UL) /*!< SPIEN status mask \hideinitializer */
#define SPI_SSLINE_STS_MASK (0x80UL) /*!< SPIx_SS line status mask \hideinitializer */
/* I2S Data Width */
#define SPII2S_DATABIT_8 (0UL << SPI_I2SCTL_WDWIDTH_Pos) /*!< I2S data width is 8-bit \hideinitializer */
#define SPII2S_DATABIT_16 (1UL << SPI_I2SCTL_WDWIDTH_Pos) /*!< I2S data width is 16-bit \hideinitializer */
#define SPII2S_DATABIT_24 (2UL << SPI_I2SCTL_WDWIDTH_Pos) /*!< I2S data width is 24-bit \hideinitializer */
#define SPII2S_DATABIT_32 (3UL << SPI_I2SCTL_WDWIDTH_Pos) /*!< I2S data width is 32-bit \hideinitializer */
/* I2S Audio Format */
#define SPII2S_MONO SPI_I2SCTL_MONO_Msk /*!< Monaural channel \hideinitializer */
#define SPII2S_STEREO (0UL) /*!< Stereo channel \hideinitializer */
/* I2S Data Format */
#define SPII2S_FORMAT_I2S (0UL<<SPI_I2SCTL_FORMAT_Pos) /*!< I2S data format \hideinitializer */
#define SPII2S_FORMAT_MSB (1UL<<SPI_I2SCTL_FORMAT_Pos) /*!< MSB justified data format \hideinitializer */
#define SPII2S_FORMAT_PCMA (2UL<<SPI_I2SCTL_FORMAT_Pos) /*!< PCM mode A data format \hideinitializer */
#define SPII2S_FORMAT_PCMB (3UL<<SPI_I2SCTL_FORMAT_Pos) /*!< PCM mode B data format \hideinitializer */
/* I2S Operation mode */
#define SPII2S_MODE_SLAVE SPI_I2SCTL_SLAVE_Msk /*!< As slave mode \hideinitializer */
#define SPII2S_MODE_MASTER (0UL) /*!< As master mode \hideinitializer */
/* I2S TX FIFO Threshold */
#define SPII2S_FIFO_TX_LEVEL_WORD_0 (0UL) /*!< TX threshold is 0 word \hideinitializer */
#define SPII2S_FIFO_TX_LEVEL_WORD_1 (1UL << SPI_FIFOCTL_TXTH_Pos) /*!< TX threshold is 1 word \hideinitializer */
#define SPII2S_FIFO_TX_LEVEL_WORD_2 (2UL << SPI_FIFOCTL_TXTH_Pos) /*!< TX threshold is 2 words \hideinitializer */
#define SPII2S_FIFO_TX_LEVEL_WORD_3 (3UL << SPI_FIFOCTL_TXTH_Pos) /*!< TX threshold is 3 words \hideinitializer */
/* I2S RX FIFO Threshold */
#define SPII2S_FIFO_RX_LEVEL_WORD_1 (0UL) /*!< RX threshold is 1 word \hideinitializer */
#define SPII2S_FIFO_RX_LEVEL_WORD_2 (1UL << SPI_FIFOCTL_RXTH_Pos) /*!< RX threshold is 2 words \hideinitializer */
#define SPII2S_FIFO_RX_LEVEL_WORD_3 (2UL << SPI_FIFOCTL_RXTH_Pos) /*!< RX threshold is 3 words \hideinitializer */
#define SPII2S_FIFO_RX_LEVEL_WORD_4 (3UL << SPI_FIFOCTL_RXTH_Pos) /*!< RX threshold is 4 words \hideinitializer */
/* I2S Record Channel */
#define SPII2S_MONO_RIGHT (0UL) /*!< Record mono right channel \hideinitializer */
#define SPII2S_MONO_LEFT SPI_I2SCTL_RXLCH_Msk /*!< Record mono left channel \hideinitializer */
/* I2S Channel */
#define SPII2S_RIGHT (0UL) /*!< Select right channel \hideinitializer */
#define SPII2S_LEFT (1UL) /*!< Select left channel \hideinitializer */
/* I2S Interrupt Mask */
#define SPII2S_FIFO_TXTH_INT_MASK (0x01UL) /*!< TX FIFO threshold interrupt mask \hideinitializer */
#define SPII2S_FIFO_RXTH_INT_MASK (0x02UL) /*!< RX FIFO threshold interrupt mask \hideinitializer */
#define SPII2S_FIFO_RXOV_INT_MASK (0x04UL) /*!< RX FIFO overrun interrupt mask \hideinitializer */
#define SPII2S_FIFO_RXTO_INT_MASK (0x08UL) /*!< RX FIFO time-out interrupt mask \hideinitializer */
#define SPII2S_TXUF_INT_MASK (0x10UL) /*!< TX FIFO underflow interrupt mask \hideinitializer */
#define SPII2S_RIGHT_ZC_INT_MASK (0x20UL) /*!< Right channel zero cross interrupt mask \hideinitializer */
#define SPII2S_LEFT_ZC_INT_MASK (0x40UL) /*!< Left channel zero cross interrupt mask \hideinitializer */
#define SPII2S_SLV_CLKERR_INT_MASK (0x80UL) /*!< Slave mode bit clock loss interrupt mask \hideinitializer */
/*@}*/ /* end of group SPI_EXPORTED_CONSTANTS */
/** @addtogroup SPI_EXPORTED_FUNCTIONS SPI Exported Functions
@{
*/
/**
* @brief Clear the unit transfer interrupt flag.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Write 1 to UNITIF bit of SPI_STATUS register to clear the unit transfer interrupt flag.
* \hideinitializer
*/
#define SPI_CLR_UNIT_TRANS_INT_FLAG(spi) ((spi)->STATUS = SPI_STATUS_UNITIF_Msk)
/**
* @brief Trigger RX PDMA function.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set RXPDMAEN bit of SPI_PDMACTL register to enable RX PDMA transfer function.
* \hideinitializer
*/
#define SPI_TRIGGER_RX_PDMA(spi) ((spi)->PDMACTL |= SPI_PDMACTL_RXPDMAEN_Msk)
/**
* @brief Trigger TX PDMA function.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set TXPDMAEN bit of SPI_PDMACTL register to enable TX PDMA transfer function.
* \hideinitializer
*/
#define SPI_TRIGGER_TX_PDMA(spi) ((spi)->PDMACTL |= SPI_PDMACTL_TXPDMAEN_Msk)
/**
* @brief Disable RX PDMA transfer.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Clear RXPDMAEN bit of SPI_PDMACTL register to disable RX PDMA transfer function.
* \hideinitializer
*/
#define SPI_DISABLE_RX_PDMA(spi) ( (spi)->PDMACTL &= ~SPI_PDMACTL_RXPDMAEN_Msk )
/**
* @brief Disable TX PDMA transfer.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Clear TXPDMAEN bit of SPI_PDMACTL register to disable TX PDMA transfer function.
* \hideinitializer
*/
#define SPI_DISABLE_TX_PDMA(spi) ( (spi)->PDMACTL &= ~SPI_PDMACTL_TXPDMAEN_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 RXCNT (SPI_STATUS[27:24]) to get the count of available data in RX FIFO.
* \hideinitializer
*/
#define SPI_GET_RX_FIFO_COUNT(spi) (((spi)->STATUS & SPI_STATUS_RXCNT_Msk) >> SPI_STATUS_RXCNT_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 RXEMPTY bit of SPI_STATUS register to get the RX FIFO empty flag.
* \hideinitializer
*/
#define SPI_GET_RX_FIFO_EMPTY_FLAG(spi) (((spi)->STATUS & SPI_STATUS_RXEMPTY_Msk)>>SPI_STATUS_RXEMPTY_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 TXEMPTY bit of SPI_STATUS register to get the TX FIFO empty flag.
* \hideinitializer
*/
#define SPI_GET_TX_FIFO_EMPTY_FLAG(spi) (((spi)->STATUS & SPI_STATUS_TXEMPTY_Msk)>>SPI_STATUS_TXEMPTY_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 TXFULL bit of SPI_STATUS register to get the TX FIFO full flag.
* \hideinitializer
*/
#define SPI_GET_TX_FIFO_FULL_FLAG(spi) (((spi)->STATUS & SPI_STATUS_TXFULL_Msk)>>SPI_STATUS_TXFULL_Pos)
/**
* @brief Get the datum read from RX register.
* @param[in] spi The pointer of the specified SPI module.
* @return Data in RX register.
* @details Read SPI_RX register to get the received datum.
* \hideinitializer
*/
#define SPI_READ_RX(spi) ((spi)->RX)
/**
* @brief Write datum to TX 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 SPI_TX register.
* \hideinitializer
*/
#define SPI_WRITE_TX(spi, u32TxData) ((spi)->TX = (u32TxData))
/**
* @brief Set SPIx_SS pin to high state.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Disable automatic slave selection function and set SPIx_SS pin to high state.
* \hideinitializer
*/
#define SPI_SET_SS_HIGH(spi) ((spi)->SSCTL = ((spi)->SSCTL & (~SPI_SSCTL_AUTOSS_Msk)) | (SPI_SSCTL_SSACTPOL_Msk | SPI_SSCTL_SS_Msk))
/**
* @brief Set SPIx_SS pin to low state.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Disable automatic slave selection function and set SPIx_SS pin to low state.
* \hideinitializer
*/
#define SPI_SET_SS_LOW(spi) ((spi)->SSCTL = ((spi)->SSCTL & (~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SSACTPOL_Msk))) | SPI_SSCTL_SS_Msk)
/**
* @brief Enable Byte Reorder function.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Enable Byte Reorder function. The suspend interval depends on the setting of SUSPITV (SPI_CTL[7:4]).
* \hideinitializer
*/
#define SPI_ENABLE_BYTE_REORDER(spi) ((spi)->CTL |= SPI_CTL_REORDER_Msk)
/**
* @brief Disable Byte Reorder function.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Clear REORDER bit field of SPI_CTL register to disable Byte Reorder function.
* \hideinitializer
*/
#define SPI_DISABLE_BYTE_REORDER(spi) ((spi)->CTL &= ~SPI_CTL_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. It could be 0 ~ 15.
* @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).
* \hideinitializer
*/
#define SPI_SET_SUSPEND_CYCLE(spi, u32SuspCycle) ((spi)->CTL = ((spi)->CTL & ~SPI_CTL_SUSPITV_Msk) | ((u32SuspCycle) << SPI_CTL_SUSPITV_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_CTL register to set the SPI transfer sequence with LSB first.
* \hideinitializer
*/
#define SPI_SET_LSB_FIRST(spi) ((spi)->CTL |= SPI_CTL_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_CTL register to set the SPI transfer sequence with MSB first.
* \hideinitializer
*/
#define SPI_SET_MSB_FIRST(spi) ((spi)->CTL &= ~SPI_CTL_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 one transaction.
* @return None.
* @details The data width can be 8 ~ 32 bits.
* \hideinitializer
*/
#define SPI_SET_DATA_WIDTH(spi, u32Width) ((spi)->CTL = ((spi)->CTL & ~SPI_CTL_DWIDTH_Msk) | (((u32Width)&0x1F) << SPI_CTL_DWIDTH_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.
* \hideinitializer
*/
#define SPI_IS_BUSY(spi) ( ((spi)->STATUS & SPI_STATUS_BUSY_Msk)>>SPI_STATUS_BUSY_Pos )
/**
* @brief Enable SPI controller.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Set SPIEN (SPI_CTL[0]) to enable SPI controller.
* \hideinitializer
*/
#define SPI_ENABLE(spi) ((spi)->CTL |= SPI_CTL_SPIEN_Msk)
/**
* @brief Disable SPI controller.
* @param[in] spi The pointer of the specified SPI module.
* @return None.
* @details Clear SPIEN (SPI_CTL[0]) to disable SPI controller.
* \hideinitializer
*/
#define SPI_DISABLE(spi) ((spi)->CTL &= ~SPI_CTL_SPIEN_Msk)
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
__STATIC_INLINE void SPII2S_ENABLE_TX_ZCD(SPI_T *i2s, uint32_t u32ChMask);
__STATIC_INLINE void SPII2S_DISABLE_TX_ZCD(SPI_T *i2s, uint32_t u32ChMask);
__STATIC_INLINE void SPII2S_SET_MONO_RX_CHANNEL(SPI_T *i2s, uint32_t u32Ch);
/**
* @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 SPII2S_RIGHT
* - \ref SPII2S_LEFT
* @return None
* @details This function will set RZCEN or LZCEN bit of SPI_I2SCTL register to enable zero cross detection function.
*/
__STATIC_INLINE void SPII2S_ENABLE_TX_ZCD(SPI_T *i2s, uint32_t u32ChMask)
{
if (u32ChMask == SPII2S_RIGHT)
{
i2s->I2SCTL |= SPI_I2SCTL_RZCEN_Msk;
}
else
{
i2s->I2SCTL |= SPI_I2SCTL_LZCEN_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 SPII2S_RIGHT
* - \ref SPII2S_LEFT
* @return None
* @details This function will clear RZCEN or LZCEN bit of SPI_I2SCTL register to disable zero cross detection function.
*/
__STATIC_INLINE void SPII2S_DISABLE_TX_ZCD(SPI_T *i2s, uint32_t u32ChMask)
{
if (u32ChMask == SPII2S_RIGHT)
{
i2s->I2SCTL &= ~SPI_I2SCTL_RZCEN_Msk;
}
else
{
i2s->I2SCTL &= ~SPI_I2SCTL_LZCEN_Msk;
}
}
/**
* @brief Enable I2S TX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set TXPDMAEN bit of SPI_PDMACTL register to transmit data with PDMA.
* \hideinitializer
*/
#define SPII2S_ENABLE_TXDMA(i2s) ( (i2s)->PDMACTL |= SPI_PDMACTL_TXPDMAEN_Msk )
/**
* @brief Disable I2S TX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear TXPDMAEN bit of SPI_PDMACTL register to disable TX DMA function.
* \hideinitializer
*/
#define SPII2S_DISABLE_TXDMA(i2s) ( (i2s)->PDMACTL &= ~SPI_PDMACTL_TXPDMAEN_Msk )
/**
* @brief Enable I2S RX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set RXPDMAEN bit of SPI_PDMACTL register to receive data with PDMA.
* \hideinitializer
*/
#define SPII2S_ENABLE_RXDMA(i2s) ( (i2s)->PDMACTL |= SPI_PDMACTL_RXPDMAEN_Msk )
/**
* @brief Disable I2S RX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear RXPDMAEN bit of SPI_PDMACTL register to disable RX DMA function.
* \hideinitializer
*/
#define SPII2S_DISABLE_RXDMA(i2s) ( (i2s)->PDMACTL &= ~SPI_PDMACTL_RXPDMAEN_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 SPI_I2SCTL register to enable I2S TX function.
* \hideinitializer
*/
#define SPII2S_ENABLE_TX(i2s) ( (i2s)->I2SCTL |= SPI_I2SCTL_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 SPI_I2SCTL register to disable I2S TX function.
* \hideinitializer
*/
#define SPII2S_DISABLE_TX(i2s) ( (i2s)->I2SCTL &= ~SPI_I2SCTL_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 SPI_I2SCTL register to enable I2S RX function.
* \hideinitializer
*/
#define SPII2S_ENABLE_RX(i2s) ( (i2s)->I2SCTL |= SPI_I2SCTL_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 SPI_I2SCTL register to disable I2S RX function.
* \hideinitializer
*/
#define SPII2S_DISABLE_RX(i2s) ( (i2s)->I2SCTL &= ~SPI_I2SCTL_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 SPI_I2SCTL register to enable I2S TX mute function.
* \hideinitializer
*/
#define SPII2S_ENABLE_TX_MUTE(i2s) ( (i2s)->I2SCTL |= SPI_I2SCTL_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 SPI_I2SCTL register to disable I2S TX mute function.
* \hideinitializer
*/
#define SPII2S_DISABLE_TX_MUTE(i2s) ( (i2s)->I2SCTL &= ~SPI_I2SCTL_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.
* \hideinitializer
*/
#define SPII2S_CLR_TX_FIFO(i2s) ( (i2s)->FIFOCTL |= SPI_FIFOCTL_TXFBCLR_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.
* \hideinitializer
*/
#define SPII2S_CLR_RX_FIFO(i2s) ( (i2s)->FIFOCTL |= SPI_FIFOCTL_RXFBCLR_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 SPII2S_MONO_LEFT
* - \ref SPII2S_MONO_RIGHT
* @return None
* @details This function selects the recording source channel of monaural mode.
* \hideinitializer
*/
__STATIC_INLINE void SPII2S_SET_MONO_RX_CHANNEL(SPI_T *i2s, uint32_t u32Ch)
{
u32Ch == SPII2S_MONO_LEFT ?
(i2s->I2SCTL |= SPI_I2SCTL_RXLCH_Msk) :
(i2s->I2SCTL &= ~SPI_I2SCTL_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.
* \hideinitializer
*/
#define SPII2S_WRITE_TX_FIFO(i2s, u32Data) ( (i2s)->TX = (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.
* \hideinitializer
*/
#define SPII2S_READ_RX_FIFO(i2s) ( (i2s)->RX )
/**
* @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 interrupt flags of SPI_I2SSTS register. The flags are specified by the u32mask parameter.
* \hideinitializer
*/
#define SPII2S_GET_INT_FLAG(i2s, u32Mask) ( (i2s)->I2SSTS & (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.
* @note Except TX and RX FIFO threshold interrupt flags, the other interrupt flags can be cleared by writing 1 to itself.
* \hideinitializer
*/
#define SPII2S_CLR_INT_FLAG(i2s, u32Mask) ( (i2s)->I2SSTS = (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.
* \hideinitializer
*/
#define SPII2S_GET_TX_FIFO_LEVEL(i2s) ( ((i2s)->I2SSTS & SPI_I2SSTS_TXCNT_Msk) >> SPI_I2SSTS_TXCNT_Pos )
/**
* @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.
* \hideinitializer
*/
#define SPII2S_GET_RX_FIFO_LEVEL(i2s) ( ((i2s)->I2SSTS & SPI_I2SSTS_RXCNT_Msk) >> SPI_I2SSTS_RXCNT_Pos )
/* 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_SetFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold);
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);
uint32_t SPII2S_Open(SPI_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat);
void SPII2S_Close(SPI_T *i2s);
void SPII2S_EnableInt(SPI_T *i2s, uint32_t u32Mask);
void SPII2S_DisableInt(SPI_T *i2s, uint32_t u32Mask);
uint32_t SPII2S_EnableMCLK(SPI_T *i2s, uint32_t u32BusClock);
void SPII2S_DisableMCLK(SPI_T *i2s);
void SPII2S_SetFIFO(SPI_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold);
/*@}*/ /* end of group SPI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SPI_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,529 @@
/**************************************************************************//**
* @file timer.h
* @version V0.10
* @brief M251 series Timer driver header file
*
* @note
* @copyright (C) 2018 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
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* TIMER Operation Mode, External Counter and Capture Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define TIMER_ONESHOT_MODE (0UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in one-shot mode */
#define TIMER_PERIODIC_MODE (1UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in periodic mode */
#define TIMER_TOGGLE_MODE (2UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in toggle-output mode */
#define TIMER_CONTINUOUS_MODE (3UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in continuous counting mode */
#define TIMER_TOUT_PIN_FROM_TX (0UL << TIMER_CTL_TGLPINSEL_Pos) /*!< Timer toggle-output pin is from Tx pin */
#define TIMER_TOUT_PIN_FROM_TX_EXT (1UL << TIMER_CTL_TGLPINSEL_Pos) /*!< Timer toggle-output pin is from Tx_EXT pin */
#define TIMER_CAPTURE_FREE_COUNTING_MODE (0UL << TIMER_EXTCTL_CAPFUNCS_Pos) /*!< Timer capture event to get timer counter value */
#define TIMER_CAPTURE_COUNTER_RESET_MODE (1UL << TIMER_EXTCTL_CAPFUNCS_Pos) /*!< Timer capture event to reset timer counter */
#define TIMER_COUNTER_EVENT_FALLING (0UL << TIMER_EXTCTL_CNTPHASE_Pos) /*!< Counter increase on falling edge detection */
#define TIMER_COUNTER_EVENT_RISING (1UL << TIMER_EXTCTL_CNTPHASE_Pos) /*!< Counter increase on rising edge detection */
#define TIMER_CAPTURE_EVENT_FALLING (0UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< Falling edge detection to trigger capture event */
#define TIMER_CAPTURE_EVENT_RISING (1UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< Rising edge detection to trigger capture event */
#define TIMER_CAPTURE_EVENT_FALLING_RISING (2UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< Both falling and rising edge detection to trigger capture event, and first event at falling edge */
#define TIMER_CAPTURE_EVENT_RISING_FALLING (3UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< Both rising and falling edge detection to trigger capture event, and first event at rising edge */
#define TIMER_CAPTURE_EVENT_GET_LOW_PERIOD (6UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< First capture event is at falling edge, follows are at at rising edge */
#define TIMER_CAPTURE_EVENT_GET_HIGH_PERIOD (7UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< First capture event is at rising edge, follows are at at falling edge */
/* For new Trigger Source Selection */
#define TIMER_TRGSEL_TIMEOUT_EVENT (0UL << TIMER_TRGCTL_TRGSSEL_Pos)
#define TIMER_TRGSEL_CAPTURE_EVENT (1UL << TIMER_TRGCTL_TRGSSEL_Pos)
#define TIMER_TRG_TO_PWM (TIMER_TRGCTL_TRGPWM_Msk)
#define TIMER_TRG_TO_EADC (TIMER_TRGCTL_TRGEADC_Msk)
#define TIMER_TRG_TO_PDMA (TIMER_TRGCTL_TRGPDMA_Msk)
#define TIMER_TRG_TO_DAC (TIMER_TRGCTL_TRGDAC_Msk)
/* Capture Sourdce Selection */
#define TIMER_CAPTURE_FROM_EXTERNAL (0UL << TIMER_CTL_CAPSRC_Pos)
#define TIMER_CAPTURE_FROM_INTERNAL (1UL << TIMER_CTL_CAPSRC_Pos)
/* Capture Sourdce Divider */
#define TIMER_CAPTURE_SRCDIV_1 (0UL << TIMER_EXTCTL_CAPDIVSCL_Pos)
#define TIMER_CAPTURE_SRCDIV_2 (1UL << TIMER_EXTCTL_CAPDIVSCL_Pos)
#define TIMER_CAPTURE_SRCDIV_4 (2UL << TIMER_EXTCTL_CAPDIVSCL_Pos)
#define TIMER_CAPTURE_SRCDIV_8 (3UL << TIMER_EXTCTL_CAPDIVSCL_Pos)
#define TIMER_CAPTURE_SRCDIV_16 (4UL << TIMER_EXTCTL_CAPDIVSCL_Pos)
#define TIMER_CAPTURE_SRCDIV_32 (5UL << TIMER_EXTCTL_CAPDIVSCL_Pos)
#define TIMER_CAPTURE_SRCDIV_64 (6UL << TIMER_EXTCTL_CAPDIVSCL_Pos)
#define TIMER_CAPTURE_SRCDIV_128 (7UL << TIMER_EXTCTL_CAPDIVSCL_Pos)
#define TIMER_CAPTURE_SRCDIV_256 (8UL << TIMER_EXTCTL_CAPDIVSCL_Pos)
/* Internal Capture Sourdce Selection */
#define TIMER_INTER_CAPTURE_FROM_ACMP0 (0UL << TIMER_EXTCTL_INTERCAPSEL_Pos)
#define TIMER_INTER_CAPTURE_FROM_ACMP1 (1UL << TIMER_EXTCTL_INTERCAPSEL_Pos)
#define TIMER_INTER_CAPTURE_FROM_HXT (2UL << TIMER_EXTCTL_INTERCAPSEL_Pos)
#define TIMER_INTER_CAPTURE_FROM_LXT (3UL << TIMER_EXTCTL_INTERCAPSEL_Pos)
#define TIMER_INTER_CAPTURE_FROM_HIRC (4UL << TIMER_EXTCTL_INTERCAPSEL_Pos)
#define TIMER_INTER_CAPTURE_FROM_LIRC (5UL << TIMER_EXTCTL_INTERCAPSEL_Pos)
#define TIMER_INTER_CAPTURE_FROM_MIRC (6UL << TIMER_EXTCTL_INTERCAPSEL_Pos)
/*@}*/ /* end of group TIMER_EXPORTED_CONSTANTS */
/** @addtogroup TIMER_EXPORTED_FUNCTIONS TIMER Exported Functions
@{
*/
/**
* @brief Set Timer Compared 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 timer compared value to adjust timer time-out interval.
* @note 1. Never write 0x0 or 0x1 in this field, or the core will run into unknown state. \n
* 2. If update timer compared value in continuous counting mode, timer counter value will keep counting continuously. \n
* But if timer is operating at other modes, the timer up counter will restart counting and start from 0.
*/
#define TIMER_SET_CMP_VALUE(timer, u32Value) ((timer)->CMP = (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 timer prescale value and timer source clock will be divided by (prescale + 1) \n
* before it is fed into timer.
*/
#define TIMER_SET_PRESCALE_VALUE(timer, u32Value) ((timer)->CTL = ((timer)->CTL & ~TIMER_CTL_PSC_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 counter is inactive or active.
*/
#define TIMER_IS_ACTIVE(timer) (((timer)->CTL & TIMER_CTL_ACTSTS_Msk)? 1 : 0)
/**
* @brief Select Toggle-output Pin
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32ToutSel Toggle-output pin selection, valid values are:
* - \ref TIMER_TOUT_PIN_FROM_TX
* - \ref TIMER_TOUT_PIN_FROM_TX_EXT
*
* @return None
*
* @details This macro is used to select timer toggle-output pin is output on Tx or Tx_EXT pin.
*/
#define TIMER_SELECT_TOUT_PIN(timer, u32ToutSel) ((timer)->CTL = ((timer)->CTL & ~TIMER_CTL_TGLPINSEL_Msk) | (u32ToutSel))
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
__STATIC_INLINE void TIMER_Start(TIMER_T *timer);
__STATIC_INLINE void TIMER_Stop(TIMER_T *timer);
__STATIC_INLINE void TIMER_EnableWakeup(TIMER_T *timer);
__STATIC_INLINE void TIMER_DisableWakeup(TIMER_T *timer);
__STATIC_INLINE void TIMER_StartCapture(TIMER_T *timer);
__STATIC_INLINE void TIMER_StopCapture(TIMER_T *timer);
__STATIC_INLINE void TIMER_EnableCaptureDebounce(TIMER_T *timer);
__STATIC_INLINE void TIMER_DisableCaptureDebounce(TIMER_T *timer);
__STATIC_INLINE void TIMER_EnableEventCounterDebounce(TIMER_T *timer);
__STATIC_INLINE void TIMER_DisableEventCounterDebounce(TIMER_T *timer);
__STATIC_INLINE void TIMER_EnableInt(TIMER_T *timer);
__STATIC_INLINE void TIMER_DisableInt(TIMER_T *timer);
__STATIC_INLINE void TIMER_EnableCaptureInt(TIMER_T *timer);
__STATIC_INLINE void TIMER_DisableCaptureInt(TIMER_T *timer);
__STATIC_INLINE uint32_t TIMER_GetIntFlag(TIMER_T *timer);
__STATIC_INLINE void TIMER_ClearIntFlag(TIMER_T *timer);
__STATIC_INLINE uint32_t TIMER_GetCaptureIntFlag(TIMER_T *timer);
__STATIC_INLINE void TIMER_ClearCaptureIntFlag(TIMER_T *timer);
__STATIC_INLINE uint32_t TIMER_GetWakeupFlag(TIMER_T *timer);
__STATIC_INLINE void TIMER_ClearWakeupFlag(TIMER_T *timer);
__STATIC_INLINE uint32_t TIMER_GetCaptureData(TIMER_T *timer);
__STATIC_INLINE uint32_t TIMER_GetCounter(TIMER_T *timer);
__STATIC_INLINE void TIMER_ResetCounter(TIMER_T *timer);
/**
* @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->CTL |= TIMER_CTL_CNTEN_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->CTL &= ~TIMER_CTL_CNTEN_Msk;
}
/**
* @brief Enable Timer Interrupt Wake-up 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 and interrupt source could be time-out interrupt, \n
* counter event interrupt or capture trigger interrupt.
* @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->CTL |= TIMER_CTL_WKEN_Msk;
}
/**
* @brief Disable Timer Wake-up 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->CTL &= ~TIMER_CTL_WKEN_Msk;
}
/**
* @brief Start Timer Capture 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 start Timer capture function.
*/
__STATIC_INLINE void TIMER_StartCapture(TIMER_T *timer)
{
timer->EXTCTL |= TIMER_EXTCTL_CAPEN_Msk;
}
/**
* @brief Stop Timer Capture 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 stop Timer capture function.
*/
__STATIC_INLINE void TIMER_StopCapture(TIMER_T *timer)
{
timer->EXTCTL &= ~TIMER_EXTCTL_CAPEN_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 detect de-bounce function of capture pin.
*/
__STATIC_INLINE void TIMER_EnableCaptureDebounce(TIMER_T *timer)
{
timer->EXTCTL |= TIMER_EXTCTL_CAPDBEN_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 detect de-bounce function of capture pin.
*/
__STATIC_INLINE void TIMER_DisableCaptureDebounce(TIMER_T *timer)
{
timer->EXTCTL &= ~TIMER_EXTCTL_CAPDBEN_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 detect de-bounce function of counter pin.
*/
__STATIC_INLINE void TIMER_EnableEventCounterDebounce(TIMER_T *timer)
{
timer->EXTCTL |= TIMER_EXTCTL_CNTDBEN_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 detect de-bounce function of counter pin.
*/
__STATIC_INLINE void TIMER_DisableEventCounterDebounce(TIMER_T *timer)
{
timer->EXTCTL &= ~TIMER_EXTCTL_CNTDBEN_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->CTL |= TIMER_CTL_INTEN_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->CTL &= ~TIMER_CTL_INTEN_Msk;
}
/**
* @brief Enable Capture Trigger 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->EXTCTL |= TIMER_EXTCTL_CAPIEN_Msk;
}
/**
* @brief Disable Capture Trigger 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->EXTCTL &= ~TIMER_EXTCTL_CAPIEN_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->INTSTS & TIMER_INTSTS_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 to 0.
*/
__STATIC_INLINE void TIMER_ClearIntFlag(TIMER_T *timer)
{
timer->INTSTS = TIMER_INTSTS_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 trigger interrupt occurred or not.
*/
__STATIC_INLINE uint32_t TIMER_GetCaptureIntFlag(TIMER_T *timer)
{
return timer->EINTSTS;
}
/**
* @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 trigger interrupt flag to 0.
*/
__STATIC_INLINE void TIMER_ClearCaptureIntFlag(TIMER_T *timer)
{
timer->EINTSTS = TIMER_EINTSTS_CAPIF_Msk;
}
/**
* @brief Get Timer Wake-up Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @retval 0 Timer does not cause CPU wake-up
* @retval 1 Timer interrupt event cause CPU wake-up
*
* @details This function indicates timer interrupt event has waked up system or not.
*/
__STATIC_INLINE uint32_t TIMER_GetWakeupFlag(TIMER_T *timer)
{
return (timer->INTSTS & TIMER_INTSTS_TWKF_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 to 0.
*/
__STATIC_INLINE void TIMER_ClearWakeupFlag(TIMER_T *timer)
{
timer->INTSTS = TIMER_INTSTS_TWKF_Msk;
}
/**
* @brief Get Capture value
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return 24-bit Capture Value
*
* @details This function reports the current 24-bit timer capture value.
*/
__STATIC_INLINE uint32_t TIMER_GetCaptureData(TIMER_T *timer)
{
return timer->CAP;
}
/**
* @brief Get Counter value
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return 24-bit Counter Value
*
* @details This function reports the current 24-bit timer counter value.
*/
__STATIC_INLINE uint32_t TIMER_GetCounter(TIMER_T *timer)
{
return timer->CNT;
}
/**
* @brief Reset Counter
*
* @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 reset current counter value and internal prescale counter value.
*/
__STATIC_INLINE void TIMER_ResetCounter(TIMER_T *timer)
{
timer->CNT = 0UL;
while ((timer->CNT & TIMER_CNT_RSTACT_Msk) == TIMER_CNT_RSTACT_Msk)
{
;
}
}
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_CaptureSelect(TIMER_T *timer, uint32_t u32Src);
void TIMER_DisableCapture(TIMER_T *timer);
void TIMER_SetTriggerSource(TIMER_T *timer, uint32_t u32Src);
void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask);
void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge);
void TIMER_DisableEventCounter(TIMER_T *timer);
uint32_t TIMER_GetModuleClock(TIMER_T *timer);
void TIMER_EnableFreqCounter(TIMER_T *timer, uint32_t u32DropCount, uint32_t u32Timeout, uint32_t u32EnableInt);
void TIMER_DisableFreqCounter(TIMER_T *timer);
/*@}*/ /* end of group TIMER_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group TIMER_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __TIMER_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,436 @@
/**************************************************************************//**
* @file timer_pwm.h
* @version V1.00
* @brief M251 series Timer PWM Controller(Timer PWM) driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __TIMER_PWM_H__
#define __TIMER_PWM_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup TIMER_PWM_Driver TIMER PWM Driver
@{
*/
/** @addtogroup TIMER_PWM_EXPORTED_CONSTANTS TIMER PWM Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* TPWM Output Channel Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define TPWM_CH0 (BIT0) /*!< Indicate PWMx_CH0 \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* TPWM Output Channel Selection Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define TPWM_TOUT_PIN_FROM_TX (BIT0) /*!< Indicate PWMx output to Tx pins \hideinitializer */
#define TPWM_TOUT_PIN_FROM_TX_EXT (BIT8) /*!< Indicate PWMx output to Tx_ext pins \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* TPWM Counter Mode Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define TPWM_AUTO_RELOAD_MODE (0UL) /*!< Auto-reload mode \hideinitializer */
#define TPWM_ONE_SHOT_MODE (1UL) /*!< One-shot mode \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* TPWM Output Level Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define TPWM_OUTPUT_TOGGLE (0UL) /*!< Timer PWM output toggle \hideinitializer */
#define TPWM_OUTPUT_NOTHING (1UL) /*!< Timer PWM output nothing \hideinitializer */
#define TPWM_OUTPUT_LOW (2UL) /*!< Timer PWM output low \hideinitializer */
#define TPWM_OUTPUT_HIGH (3UL) /*!< Timer PWM output high \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* TPWM Trigger ADC/DAC/PDMA Source Select Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define TPWM_TRIGGER_AT_PERIOD_POINT (0UL) /*!< Timer PWM trigger EADC while counter period point event occurred \hideinitializer */
#define TPWM_TRIGGER_AT_COMPARE_POINT (1UL) /*!< Timer PWM trigger EADC while counter compare point event occurred \hideinitializer */
#define TPWM_TRIGGER_AT_PERIOD_OR_COMPARE_POINT (2UL) /*!< Timer PWM trigger EADC while counter period or compare point event occurred \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* TPWM Counter Clock Source Select Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define TPWM_CLKSRC_HXT (0UL) /*!< Timer PWM Clock source selects to HXT \hideinitializer \hideinitializer */
#define TPWM_CLKSRC_LXT (1UL) /*!< Timer PWM Clock source selects to LXT \hideinitializer \hideinitializer */
#define TPWM_CLKSRC_PCLK (2UL) /*!< Timer PWM Clock source selects to PCLK \hideinitializer \hideinitializer */
#define TPWM_CLKSRC_TX (3UL) /*!< Timer PWM Clock source selects to TX \hideinitializer \hideinitializer */
#define TPWM_CLKSRC_LIRC (5UL) /*!< Timer PWM Clock source selects to LIRC \hideinitializer \hideinitializer */
#define TPWM_CLKSRC_HIRC (7UL) /*!< Timer PWM Clock source selects to HIRC \hideinitializer \hideinitializer */
/*@}*/ /* end of group TIMER_PWM_EXPORTED_CONSTANTS */
/** @addtogroup TIMER_PWM_EXPORTED_FUNCTIONS TIMER PWM Exported Functions
@{
*/
/**
* @brief Enable PWM Counter Mode
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro is used to enable specified Timer channel as PWM counter mode, then timer counter mode is invalid.
* @note All registers about time counter function will be cleared to 0 and timer clock source will be changed to PCLKx automatically after executing this macro.
* \hideinitializer
*/
#define TPWM_ENABLE_PWM_MODE(timer) ((timer)->CTL |= TIMER_CTL_FUNCSEL_Msk)
/**
* @brief Disable PWM Counter Mode
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro is used to disable specified Timer channel as PWM counter mode, then timer counter mode is available.
* @note All registers about PWM counter function will be cleared to 0 after executing this macro.
* \hideinitializer
*/
#define TPWM_DISABLE_PWM_MODE(timer) ((timer)->CTL &= ~TIMER_CTL_FUNCSEL_Msk)
/**
* @brief Start PWM Counter
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro is used to enable PWM generator and start counter counting.
* \hideinitializer
*/
#define TPWM_START_COUNTER(timer) ((timer)->PWMCTL |= TIMER_PWMCTL_CNTEN_Msk)
/**
* @brief Stop PWM Counter
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro is used to stop PWM counter after current period is completed.
* \hideinitializer
*/
#define TPWM_STOP_COUNTER(timer) ((timer)->PWMPERIOD = 0x0UL)
/**
* @brief Set Counter Clock Prescaler
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @param[in] u32Prescaler Clock prescaler of specified channel. Valid values are between 0x0~0xFFF.
*
* @return None
*
* @details This macro is used to set the prescaler of specified TIMER PWM.
* @note If prescaler is 0, then there is no scaling in counter clock source.
* \hideinitializer
*/
#define TPWM_SET_PRESCALER(timer, u32Prescaler) ((timer)->PWMCLKPSC = (u32Prescaler))
/**
* @brief Get Counter Clock Prescaler
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return Target prescaler setting, CLKPSC (TIMERx_PWMCLKPSC[11:0])
*
* @details Get the prescaler setting, the target counter clock divider is (CLKPSC + 1).
* \hideinitializer
*/
#define TPWM_GET_PRESCALER(timer) ((timer)->PWMCLKPSC)
/**
* @brief Set Counter Period
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @param[in] u32Period Period of specified channel. Valid values are between 0x0~0xFFFF.
*
* @return None
*
* @details This macro is used to set the period of specified TIMER PWM.
* \hideinitializer
*/
#define TPWM_SET_PERIOD(timer, u32Period) ((timer)->PWMPERIOD = (u32Period))
/**
* @brief Get Counter Period
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return Target period setting, PERIOD (TIMERx_PWMPERIOD[15:0])
*
* @details This macro is used to get the period of specified TIMER PWM.
* \hideinitializer
*/
#define TPWM_GET_PERIOD(timer) ((timer)->PWMPERIOD)
/**
* @brief Set Comparator Value
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @param[in] u32Cmp Comparator of specified channel. Valid values are between 0x0~0xFFFF.
*
* @return None
*
* @details This macro is used to set the comparator value of specified TIMER PWM.
* \hideinitializer
*/
#define TPWM_SET_CMPDAT(timer, u32Cmp) ((timer)->PWMCMPDAT = (u32Cmp))
/**
* @brief Get Comparator Value
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return Target comparator setting, CMPDAT (TIMERx_PWMCMPDAT[15:0])
*
* @details This macro is used to get the comparator value of specified TIMER PWM.
* \hideinitializer
*/
#define TPWM_GET_CMPDAT(timer) ((timer)->PWMCMPDAT)
/**
* @brief Clear Counter
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro is used to clear counter of specified TIMER PWM.
* \hideinitializer
*/
#define TPWM_CLEAR_COUNTER(timer) ((timer)->PWMCNTCLR = TIMER_PWMCNTCLR_CNTCLR_Msk)
/**
* @brief Enable Output Function
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @param[in] u32Channel Enable specified channel output function. Valid values are:
* - \ref TPWM_CH0
*
* @return None
*
* @details This macro is used to enable output function of specified output pins.
* @note If the corresponding bit in u32ChMask parameter is 0, then output function will be disabled in this channel.
* \hideinitializer
*/
#define TPWM_ENABLE_OUTPUT(timer, u32Channel) ((timer)->PWMPOCTL = (u32Channel))
/**
* @brief Select Toggle-output Pin
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32ToutSel Toggle-output pin selection, valid values are:
* - \ref TPWM_TOUT_PIN_FROM_TX
* - \ref TPWM_TOUT_PIN_FROM_TX_EXT
*
* @return None
*
* @details This macro is used to select timer toggle-output pin is output on Tx or Tx_EXT pin.
*/
#define TPWM_SELECT_TOUT_PIN(timer, u32ToutSel) ((timer)->PWMPOCTL = ((timer)->PWMPOCTL & ~TIMER_PWMPOCTL_POSEL_Msk) | (u32ToutSel))
/**
* @brief Set Output Inverse
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @param[in] u32Channel Set specified channel output is inversed or not. Valid values are:
* - \ref TPWM_CH0
*
* @return None
*
* @details This macro is used to enable output inverse of specified output pins.
* @note If u32ChMask parameter is 0, then output inverse function will be disabled.
* \hideinitializer
*/
#define TPWM_SET_OUTPUT_INVERSE(timer, u32Channel) ((timer)->PWMPOLCTL = (u32Channel))
/**
* @brief Enable Period Event Interrupt
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro is used to enable the period event interrupt function.
* \hideinitializer
*/
#define TPWM_ENABLE_PERIOD_INT(timer) ((timer)->PWMINTEN0 |= TIMER_PWMINTEN0_PIEN_Msk)
/**
* @brief Disable Period Event Interrupt
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro is used to disable the period event interrupt function.
* \hideinitializer
*/
#define TPWM_DISABLE_PERIOD_INT(timer) ((timer)->PWMINTEN0 &= ~TIMER_PWMINTEN0_PIEN_Msk)
/**
* @brief Get Period Event Interrupt Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @retval 0 Period event interrupt did not occur
* @retval 1 Period event interrupt occurred
*
* @details This macro indicates period event occurred or not.
* \hideinitializer
*/
#define TPWM_GET_PERIOD_INT_FLAG(timer) (((timer)->PWMINTSTS0 & TIMER_PWMINTSTS0_PIF_Msk)? 1 : 0)
/**
* @brief Clear Period Event Interrupt Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro clears period event interrupt flag.
* \hideinitializer
*/
#define TPWM_CLEAR_PERIOD_INT_FLAG(timer) ((timer)->PWMINTSTS0 = TIMER_PWMINTSTS0_PIF_Msk)
/**
* @brief Enable Compare Up Event Interrupt
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro is used to enable the compare up event interrupt function.
* \hideinitializer
*/
#define TPWM_ENABLE_CMP_UP_INT(timer) ((timer)->PWMINTEN0 |= TIMER_PWMINTEN0_CMPUIEN_Msk)
/**
* @brief Disable Compare Up Event Interrupt
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro is used to disable the compare up event interrupt function.
* \hideinitializer
*/
#define TPWM_DISABLE_CMP_UP_INT(timer) ((timer)->PWMINTEN0 &= ~TIMER_PWMINTEN0_CMPUIEN_Msk)
/**
* @brief Get Compare Up Event Interrupt Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @retval 0 Compare up event interrupt did not occur
* @retval 1 Compare up event interrupt occurred
*
* @details This macro indicates compare up event occurred or not.
* \hideinitializer
*/
#define TPWM_GET_CMP_UP_INT_FLAG(timer) (((timer)->PWMINTSTS0 & TIMER_PWMINTSTS0_CMPUIF_Msk)? 1 : 0)
/**
* @brief Clear Compare Up Event Interrupt Flag
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro clears compare up event interrupt flag.
* \hideinitializer
*/
#define TPWM_CLEAR_CMP_UP_INT_FLAG(timer) ((timer)->PWMINTSTS0 = TIMER_PWMINTSTS0_CMPUIF_Msk)
/**
* @brief Get Counter Reach Maximum Count Status
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @retval 0 Timer PWM counter never counts to maximum value
* @retval 1 Timer PWM counter counts to maximum value, 0xFFFF
*
* @details This macro indicates Timer PWM counter has count to 0xFFFF or not.
* \hideinitializer
*/
#define TPWM_GET_REACH_MAX_CNT_STATUS(timer) (((timer)->PWMSTATUS & TIMER_PWMSTATUS_CNTMAXF_Msk)? 1 : 0)
/**
* @brief Clear Counter Reach Maximum Count Status
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro clears reach maximum count status.
* \hideinitializer
*/
#define TPWM_CLEAR_REACH_MAX_CNT_STATUS(timer) ((timer)->PWMSTATUS = TIMER_PWMSTATUS_CNTMAXF_Msk)
/**
* @brief Get Trigger ADC Status
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @retval 0 Trigger ADC start conversion is not occur
* @retval 1 Specified counter compare event has trigger ADC start conversion
*
* @details This macro is used to indicate PWM counter compare event has triggered ADC start conversion.
* \hideinitializer
*/
#define TPWM_GET_TRG_ADC_STATUS(timer) (((timer)->PWMSTATUS & TIMER_PWMSTATUS_EADCTRGF_Msk)? 1 : 0)
/**
* @brief Clear Trigger ADC Status
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @details This macro is used to clear PWM counter compare event trigger ADC status.
* \hideinitializer
*/
#define TPWM_CLEAR_TRG_ADC_STATUS(timer) ((timer)->PWMSTATUS = TIMER_PWMSTATUS_EADCTRGF_Msk)
uint32_t TPWM_GetModuleClock(TIMER_T *timer);
uint32_t TPWM_ConfigOutputFreqAndDuty(TIMER_T *timer, uint32_t u32Frequency, uint32_t u32DutyCycle);
void TPWM_EnableCounter(TIMER_T *timer);
void TPWM_DisableCounter(TIMER_T *timer);
void TPWM_EnableTriggerADC(TIMER_T *timer, uint32_t u32Condition);
void TPWM_DisableTriggerADC(TIMER_T *timer);
void TPWM_EnableTriggerDAC(TIMER_T *timer, uint32_t u32Condition);
void TPWM_DisableTriggerDAC(TIMER_T *timer);
void TPWM_EnableTriggerPDMA(TIMER_T *timer, uint32_t u32Condition);
void TPWM_DisableTriggerPDMA(TIMER_T *timer);
void TPWM_SetLoadMode(TIMER_T *timer, uint32_t u32LoadMode);
/*@}*/ /* end of group TIMER_PWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group TIMER_PWM_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __TIMER_PWM_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,500 @@
/****************************************************************************
* @file uart.h
* @version V1.00
* @brief M251 series UART driver source file
*
* @copyright (C) 2018 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 16ul /*!< UART0 supports separated receive/transmit 16/16 bytes entry FIFO \hideinitializer */
#define UART1_FIFO_SIZE 16ul /*!< UART1 supports separated receive/transmit 16/16 bytes entry FIFO \hideinitializer */
#define UART2_FIFO_SIZE 16ul /*!< UART2 supports separated receive/transmit 16/16 bytes entry FIFO \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* UART_FIFO constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_FIFO_RFITL_1BYTE (0x0ul << UART_FIFO_RFITL_Pos) /*!< UART_FIFO setting to set RX FIFO Trigger Level to 1 byte \hideinitializer */
#define UART_FIFO_RFITL_4BYTES (0x1ul << UART_FIFO_RFITL_Pos) /*!< UART_FIFO setting to set RX FIFO Trigger Level to 4 bytes \hideinitializer */
#define UART_FIFO_RFITL_8BYTES (0x2ul << UART_FIFO_RFITL_Pos) /*!< UART_FIFO setting to set RX FIFO Trigger Level to 8 bytes \hideinitializer */
#define UART_FIFO_RFITL_14BYTES (0x3ul << UART_FIFO_RFITL_Pos) /*!< UART_FIFO setting to set RX FIFO Trigger Level to 14 bytes \hideinitializer */
#define UART_FIFO_RTSTRGLV_1BYTE (0x0ul << UART_FIFO_RTSTRGLV_Pos) /*!< UART_FIFO setting to set RTS Trigger Level to 1 byte \hideinitializer */
#define UART_FIFO_RTSTRGLV_4BYTES (0x1ul << UART_FIFO_RTSTRGLV_Pos) /*!< UART_FIFO setting to set RTS Trigger Level to 4 bytes \hideinitializer */
#define UART_FIFO_RTSTRGLV_8BYTES (0x2ul << UART_FIFO_RTSTRGLV_Pos) /*!< UART_FIFO setting to set RTS Trigger Level to 8 bytes \hideinitializer */
#define UART_FIFO_RTSTRGLV_14BYTES (0x3ul << UART_FIFO_RTSTRGLV_Pos) /*!< UART_FIFO setting to set RTS Trigger Level to 14 bytes \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* UART_LINE constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_WORD_LEN_5 (0ul) /*!< UART_LINE setting to set UART word length to 5 bits \hideinitializer */
#define UART_WORD_LEN_6 (1ul) /*!< UART_LINE setting to set UART word length to 6 bits \hideinitializer */
#define UART_WORD_LEN_7 (2ul) /*!< UART_LINE setting to set UART word length to 7 bits \hideinitializer */
#define UART_WORD_LEN_8 (3ul) /*!< UART_LINE setting to set UART word length to 8 bits \hideinitializer */
#define UART_PARITY_NONE (0x0ul << UART_LINE_PBE_Pos) /*!< UART_LINE setting to set UART as no parity \hideinitializer */
#define UART_PARITY_ODD (0x1ul << UART_LINE_PBE_Pos) /*!< UART_LINE setting to set UART as odd parity \hideinitializer */
#define UART_PARITY_EVEN (0x3ul << UART_LINE_PBE_Pos) /*!< UART_LINE setting to set UART as even parity \hideinitializer */
#define UART_PARITY_MARK (0x5ul << UART_LINE_PBE_Pos) /*!< UART_LINE setting to keep parity bit as '1' \hideinitializer */
#define UART_PARITY_SPACE (0x7ul << UART_LINE_PBE_Pos) /*!< UART_LINE setting to keep parity bit as '0' \hideinitializer */
#define UART_STOP_BIT_1 (0x0ul << UART_LINE_NSB_Pos) /*!< UART_LINE setting for one stop bit \hideinitializer */
#define UART_STOP_BIT_1_5 (0x1ul << UART_LINE_NSB_Pos) /*!< UART_LINE setting for 1.5 stop bit when 5-bit word length \hideinitializer */
#define UART_STOP_BIT_2 (0x1ul << UART_LINE_NSB_Pos) /*!< UART_LINE setting for two stop bit when 6, 7, 8-bit word length \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* UART RTS ACTIVE LEVEL constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_RTS_IS_LOW_LEV_ACTIVE (0x1ul << UART_MODEM_RTSACTLV_Pos) /*!< Set RTS is Low Level Active \hideinitializer */
#define UART_RTS_IS_HIGH_LEV_ACTIVE (0x0ul << UART_MODEM_RTSACTLV_Pos) /*!< Set RTS is High Level Active \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* UART_IRDA constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_IRDA_TXEN (0x1ul << UART_IRDA_TXEN_Pos) /*!< Set IrDA function Tx mode \hideinitializer */
#define UART_IRDA_RXEN (0x0ul << UART_IRDA_TXEN_Pos) /*!< Set IrDA function Rx mode \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* UART_FUNCSEL constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_FUNCSEL_UART (0x0ul << UART_FUNCSEL_FUNCSEL_Pos) /*!< UART_FUNCSEL setting to set UART Function (Default) \hideinitializer */
#define UART_FUNCSEL_LIN (0x1ul << UART_FUNCSEL_FUNCSEL_Pos) /*!< UART_FUNCSEL setting to set LIN Function \hideinitializer */
#define UART_FUNCSEL_IrDA (0x2ul << UART_FUNCSEL_FUNCSEL_Pos) /*!< UART_FUNCSEL setting to set IrDA Function \hideinitializer */
#define UART_FUNCSEL_RS485 (0x3ul << UART_FUNCSEL_FUNCSEL_Pos) /*!< UART_FUNCSEL setting to set RS485 Function \hideinitializer */
#define UART_FUNCSEL_SINGLE_WIRE (0x4ul << UART_FUNCSEL_FUNCSEL_Pos) /*!< UART_FUNCSEL setting to set Single Wire Function \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* UART_LINCTL constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_LINCTL_BRKFL(x) (((x)-1) << UART_LINCTL_BRKFL_Pos) /*!< UART_LINCTL setting to set LIN Break Field Length, x = 10 ~ 15, default value is 12 \hideinitializer */
#define UART_LINCTL_BSL(x) (((x)-1) << UART_LINCTL_BSL_Pos) /*!< UART_LINCTL setting to set LIN Break/Sync Delimiter Length, x = 1 ~ 4 \hideinitializer */
#define UART_LINCTL_HSEL_BREAK (0x0UL << UART_LINCTL_HSEL_Pos) /*!< UART_LINCTL setting to set LIN Header Select to break field \hideinitializer */
#define UART_LINCTL_HSEL_BREAK_SYNC (0x1UL << UART_LINCTL_HSEL_Pos) /*!< UART_LINCTL setting to set LIN Header Select to break field and sync field \hideinitializer */
#define UART_LINCTL_HSEL_BREAK_SYNC_ID (0x2UL << UART_LINCTL_HSEL_Pos) /*!< UART_LINCTL setting to set LIN Header Select to break field, sync field and ID field \hideinitializer */
#define UART_LINCTL_PID(x) ((x) << UART_LINCTL_PID_Pos) /*!< UART_LINCTL setting to set LIN PID value \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* UART BAUDRATE MODE constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_BAUD_MODE0 (0ul) /*!< Set UART Baudrate Mode is Mode0 \hideinitializer */
#define UART_BAUD_MODE2 (UART_BAUD_BAUDM1_Msk | UART_BAUD_BAUDM0_Msk) /*!< Set UART Baudrate Mode is Mode2 \hideinitializer */
/*@}*/ /* 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.
* \hideinitializer
*/
#define UART_BAUD_MODE0_DIVIDER(u32SrcFreq, u32BaudRate) ((((u32SrcFreq) + ((u32BaudRate)*8ul)) / (u32BaudRate) >> 4ul)-2ul)
/**
* @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.
* \hideinitializer
*/
#define UART_BAUD_MODE2_DIVIDER(u32SrcFreq, u32BaudRate) ((((u32SrcFreq) + ((u32BaudRate)/2ul)) / (u32BaudRate))-2ul)
/**
* @brief Write UART 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.
* \hideinitializer
*/
#define UART_WRITE(uart, u8Data) ((uart)->DAT = (u8Data))
/**
* @brief Read UART 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.
* \hideinitializer
*/
#define UART_READ(uart) ((uart)->DAT)
/**
* @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 Transmitter FIFO empty register value.
* \hideinitializer
*/
#define UART_GET_TX_EMPTY(uart) ((uart)->FIFOSTS & UART_FIFOSTS_TXEMPTY_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 Receiver FIFO empty register value.
* \hideinitializer
*/
#define UART_GET_RX_EMPTY(uart) ((uart)->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk)
/**
* @brief Check specified UART port transmission is over.
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 0 Tx transmission is not over
* @retval 1 Tx transmission is over
*
* @details This macro return Transmitter Empty Flag register bit value.
* It indicates if specified UART port transmission is over nor not.
* \hideinitializer
*/
#define UART_IS_TX_EMPTY(uart) (((uart)->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk) >> UART_FIFOSTS_TXEMPTYF_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.
* \hideinitializer
*/
#define UART_WAIT_TX_EMPTY(uart) while(!((((uart)->FIFOSTS) & UART_FIFOSTS_TXEMPTYF_Msk) >> UART_FIFOSTS_TXEMPTYF_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.
* \hideinitializer
*/
#define UART_IS_RX_READY(uart) (((uart)->INTSTS & UART_INTSTS_RDAIF_Msk)>>UART_INTSTS_RDAIF_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.
* \hideinitializer
*/
#define UART_IS_TX_FULL(uart) (((uart)->FIFOSTS & UART_FIFOSTS_TXFULL_Msk)>>UART_FIFOSTS_TXFULL_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.
* \hideinitializer
*/
#define UART_IS_RX_FULL(uart) (((uart)->FIFOSTS & UART_FIFOSTS_RXFULL_Msk)>>UART_FIFOSTS_RXFULL_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.
* \hideinitializer
*/
#define UART_GET_TX_FULL(uart) ((uart)->FIFOSTS & UART_FIFOSTS_TXFULL_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.
* \hideinitializer
*/
#define UART_GET_RX_FULL(uart) ((uart)->FIFOSTS & UART_FIFOSTS_RXFULL_Msk)
/**
* @brief Rx Idel Status register value
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 0 Rx is busy.
* @retval 1 Rx is Idel(Default)
*
* @details This macro get Rx Idel Status register value.
* \hideinitializer
*/
#define UART_RX_IDEL(uart) (((uart)->FIFOSTS & UART_FIFOSTS_RXIDLE_Msk )>> UART_FIFOSTS_RXIDLE_Pos)
/**
* @brief Enable specified UART interrupt
*
* @param[in] uart The pointer of the specified UART module
* @param[in] u32IntSel Interrupt type select
* - \ref UART_INTEN_TXENDIEN_Msk : Transmitter Empty interrupt
* - \ref UART_INTEN_ABRIEN_Msk : Auto baud rate interrupt
* - \ref UART_INTEN_SWBEIEN_Msk : Single-wire bit error detection interrupt
* - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt
* - \ref UART_INTEN_WKIEN_Msk : Wakeup interrupt
* - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt
* - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt
* - \ref UART_INTEN_MODEMIEN_Msk : Modem interrupt
* - \ref UART_INTEN_RLSIEN_Msk : Rx Line status interrupt
* - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt
* - \ref UART_INTEN_RDAIEN_Msk : Rx ready interrupt
*
* @return None
*
* @details This macro enable specified UART interrupt.
* \hideinitializer
*/
#define UART_ENABLE_INT(uart, u32IntSel) ((uart)->INTEN |= (u32IntSel))
/**
* @brief Disable specified UART interrupt
*
* @param[in] uart The pointer of the specified UART module
* @param[in] u32IntSel Interrupt type select
* - \ref UART_INTEN_TXENDIEN_Msk : Transmitter Empty interrupt
* - \ref UART_INTEN_ABRIEN_Msk : Auto baud rate interrupt
* - \ref UART_INTEN_SWBEIEN_Msk : Single-wire bit error detection interrupt
* - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt
* - \ref UART_INTEN_WKIEN_Msk : Wakeup interrupt
* - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt
* - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt
* - \ref UART_INTEN_MODEMIEN_Msk : Modem status interrupt
* - \ref UART_INTEN_RLSIEN_Msk : Receive Line status interrupt
* - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt
* - \ref UART_INTEN_RDAIEN_Msk : Rx ready interrupt
*
* @return None
*
* @details This macro enable specified UART interrupt.
* \hideinitializer
*/
#define UART_DISABLE_INT(uart, u32IntSel) ((uart)->INTEN &= ~ (u32IntSel))
/**
* @brief Get specified interrupt flag/status
*
* @param[in] uart The pointer of the specified UART module
* @param[in] u32IntTypeFlag Interrupt Type Flag, should be
* - \ref UART_INTSTS_ABRINT_Msk : Auto-baud Rate Interrupt Indicator
* - \ref UART_INTSTS_TXENDINT_Msk : Transmitter Empty Interrupt Indicator
* - \ref UART_INTSTS_HWBUFEINT_Msk : In PDMA Mode, Buffer Error Interrupt Indicator
* - \ref UART_INTSTS_HWTOINT_Msk : In PDMA Mode, Time-out Interrupt Indicator
* - \ref UART_INTSTS_HWMODINT_Msk : In PDMA Mode, MODEM Status Interrupt Indicator
* - \ref UART_INTSTS_HWRLSINT_Msk : In PDMA Mode, Receive Line Status Interrupt Indicator
* - \ref UART_INTSTS_SWBEINT_Msk : In Single-wire Mode, Bit Error Detect Interrupt Indicator
* - \ref UART_INTSTS_TXENDIF_Msk : Transmitter Empty Interrupt Flag
* - \ref UART_INTSTS_HWBUFEIF_Msk : In PDMA Mode, Buffer Error Interrupt Flag
* - \ref UART_INTSTS_HWTOIF_Msk : In PDMA Mode, Time-out Interrupt Flag
* - \ref UART_INTSTS_HWMODIF_Msk : In PDMA Mode, MODEM Interrupt Flag
* - \ref UART_INTSTS_HWRLSIF_Msk : In PDMA Mode, Receive Line Status Flag
* - \ref UART_INTSTS_SWBEIF_Msk : In Single-wire Mode, Bit Error Detection Interrupt Flag
* - \ref UART_INTSTS_LININT_Msk : LIN Bus Interrupt Indicator
* - \ref UART_INTSTS_WKINT_Msk : Wake-up Interrupt Indicator
* - \ref UART_INTSTS_BUFERRINT_Msk : Buffer Error Interrupt Indicator
* - \ref UART_INTSTS_RXTOINT_Msk : Time-out Interrupt Indicator
* - \ref UART_INTSTS_MODEMINT_Msk : Modem Status Interrupt Indicator
* - \ref UART_INTSTS_RLSINT_Msk : Receive Line Status Interrupt Indicator
* - \ref UART_INTSTS_THREINT_Msk : Transmit Holding Register Empty Interrupt Indicator
* - \ref UART_INTSTS_RDAINT_Msk : Receive Data Available Interrupt Indicator
* - \ref UART_INTSTS_LINIF_Msk : LIN Bus Flag
* - \ref UART_INTSTS_WKIF_Msk : Wake-up Interrupt Flag
* - \ref UART_INTSTS_BUFERRIF_Msk : Buffer Error Interrupt Flag
* - \ref UART_INTSTS_RXTOIF_Msk : Rx Time-out Interrupt Flag
* - \ref UART_INTSTS_MODEMIF_Msk : Modem Interrupt Flag
* - \ref UART_INTSTS_RLSIF_Msk : Receive Line Status Interrupt Flag
* - \ref UART_INTSTS_THREIF_Msk : Tx Empty Interrupt Flag
* - \ref UART_INTSTS_RDAIF_Msk : Rx Ready Interrupt Flag
*
* @retval 0 The specified interrupt is not happened.
* 1 The specified interrupt is happened.
*
* @details This macro get specified interrupt flag or interrupt indicator status.
* \hideinitializer
*/
#define UART_GET_INT_FLAG(uart,u32IntTypeFlag) (((uart)->INTSTS & (u32IntTypeFlag))?1:0)
/**
* @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.
* \hideinitializer
*/
#define UART_RS485_CLEAR_ADDR_FLAG(uart) ((uart)->FIFOSTS = UART_FIFOSTS_ADDRDETF_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.
* \hideinitializer
*/
#define UART_RS485_GET_ADDR_FLAG(uart) (((uart)->FIFOSTS & UART_FIFOSTS_ADDRDETF_Msk) >> UART_FIFOSTS_ADDRDETF_Pos)
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
__STATIC_INLINE void UART_CLEAR_RTS(UART_T *uart);
__STATIC_INLINE void UART_SET_RTS(UART_T *uart);
/**
* @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->MODEM |= UART_MODEM_RTSACTLV_Msk;
uart->MODEM &= ~UART_MODEM_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->MODEM |= UART_MODEM_RTSACTLV_Msk | UART_MODEM_RTS_Msk;
}
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 u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits);
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);
void UART_SelectSingleWireMode(UART_T *uart);
/*@}*/ /* end of group UART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group UART_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /*__UART_H__*/
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,700 @@
/******************************************************************************
* @file usbd.h
* @version V0.10
* @brief M251 series USB driver header file
*
* @copyrightt (C) 2017 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __USBD_H__
#define __USBD_H__
#ifdef __cplusplus
extern "C"
{
#endif
/*!< Definition for enabling Link Power Management(LPM) function.
LPM related handler will raise after LPM event happen.
if bcdUSB >= 0x0201, USB version is equal or higher than 2.1,
OS(Windows) will issue "get BOS descriptor" request to check the support of LPM.
Notice:
If bcdUSB >= 0x0201, where USB version is equal or higher than 2.1,
WIN8 ~ WIN10 will fail to enumerate the device if device stalls the "get BOS descriptor" request.
WIN7 can still enumerate this device even though the "get BOS descriptor" request been stalled.
*/
//#define SUPPORT_LPM
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup USBD_Driver USBD Driver
@{
*/
/** @addtogroup USBD_EXPORTED_STRUCTS USBD Exported Structs
@{
*/
typedef struct s_usbd_info
{
uint8_t *gu8DevDesc; /*!< Pointer for USB Device Descriptor */
uint8_t *gu8ConfigDesc; /*!< Pointer for USB Configuration Descriptor */
uint8_t **gu8StringDesc; /*!< Pointer for USB String Descriptor pointers */
uint8_t **gu8HidReportDesc; /*!< Pointer for USB HID Report Descriptor */
uint8_t *gu8BosDesc; /*!< Pointer for USB BOS Descriptor */
uint32_t *gu32HidReportSize; /*!< Pointer for HID Report descriptor Size */
uint32_t *gu32ConfigHidDescIdx; /*!< Pointer for HID Descriptor start index */
} S_USBD_INFO_T; /*!< Device description structure */
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+0x100ul) /*!< USBD buffer base address \hideinitializer */
#define USBD_MAX_EP 12ul /*!< Total EP number \hideinitializer */
#define EP0 0ul /*!< Endpoint 0 \hideinitializer */
#define EP1 1ul /*!< Endpoint 1 \hideinitializer */
#define EP2 2ul /*!< Endpoint 2 \hideinitializer */
#define EP3 3ul /*!< Endpoint 3 \hideinitializer */
#define EP4 4ul /*!< Endpoint 4 \hideinitializer */
#define EP5 5ul /*!< Endpoint 5 \hideinitializer */
#define EP6 6ul /*!< Endpoint 6 \hideinitializer */
#define EP7 7ul /*!< Endpoint 7 \hideinitializer */
#define EP8 8ul /*!< Endpoint 8 \hideinitializer */
#define EP9 9ul /*!< Endpoint 9 \hideinitializer */
#define EP10 10ul /*!< Endpoint 10 \hideinitializer */
#define EP11 11ul /*!< Endpoint 11 \hideinitializer */
/*!<USB Request Type */
#define REQ_STANDARD 0x00ul
#define REQ_CLASS 0x20ul
#define REQ_VENDOR 0x40ul
/*!<USB Standard Request */
#define GET_STATUS 0x00ul
#define CLEAR_FEATURE 0x01ul
#define SET_FEATURE 0x03ul
#define SET_ADDRESS 0x05ul
#define GET_DESCRIPTOR 0x06ul
#define SET_DESCRIPTOR 0x07ul
#define GET_CONFIGURATION 0x08ul
#define SET_CONFIGURATION 0x09ul
#define GET_INTERFACE 0x0Aul
#define SET_INTERFACE 0x0Bul
#define SYNC_FRAME 0x0Cul
/*!<USB Descriptor Type */
#define DESC_DEVICE 0x01ul
#define DESC_CONFIG 0x02ul
#define DESC_STRING 0x03ul
#define DESC_INTERFACE 0x04ul
#define DESC_ENDPOINT 0x05ul
#define DESC_QUALIFIER 0x06ul
#define DESC_OTHERSPEED 0x07ul
#define DESC_IFPOWER 0x08ul
#define DESC_OTG 0x09ul
#define DESC_BOS 0x0Ful
#define DESC_CAPABILITY 0x10ul
/*!<USB Device Capability Type */
#define CAP_WIRELESS 0x01ul
#define CAP_USB20_EXT 0x02ul
/*!<USB HID Descriptor Type */
#define DESC_HID 0x21ul
#define DESC_HID_RPT 0x22ul
/*!<USB Descriptor Length */
#define LEN_DEVICE 18ul
#define LEN_QUALIFIER 10ul
#define LEN_CONFIG 9ul
#define LEN_INTERFACE 9ul
#define LEN_ENDPOINT 7ul
#define LEN_OTG 5ul
#define LEN_BOS 5ul
#define LEN_HID 9ul
#define LEN_CCID 0x36ul
#define LEN_DEVCAP 7ul
/*!<USB Endpoint Type */
#define EP_ISO 0x01ul
#define EP_BULK 0x02ul
#define EP_INT 0x03ul
#define EP_INPUT 0x80ul
#define EP_OUTPUT 0x00ul
/*!<USB Feature Selector */
#define FEATURE_DEVICE_REMOTE_WAKEUP 0x01ul
#define FEATURE_ENDPOINT_HALT 0x00ul
/******************************************************************************/
/* USB Specific Macros */
/******************************************************************************/
#define USBD_WAKEUP_EN USBD_INTEN_WKEN_Msk /*!< USB Wake-up Enable */
#define USBD_DRVSE0 USBD_SE0_SE0_Msk /*!< Drive SE0 */
#define USBD_DPPU_EN USBD_ATTR_DPPUEN_Msk /*!< USB D+ Pull-up Enable */
#define USBD_PWRDN USBD_ATTR_PWRDN_Msk /*!< PHY Turn-On */
#define USBD_PHY_EN USBD_ATTR_PHYEN_Msk /*!< PHY Enable */
#define USBD_USB_EN USBD_ATTR_USBEN_Msk /*!< USB Enable */
#define USBD_RWAKEUP USBD_ATTR_RWAKEUP_Msk /*!< Remote Wake Up Enable */
#define USBD_LPMACK USBD_ATTR_LPMACK_Msk /*!< LPM Enable */
#define USBD_BYTEM USBD_ATTR_BYTEM_Msk /*!< Byte Mode Enable */
#define USBD_INT_BUS USBD_INTEN_BUSIEN_Msk /*!< USB Bus Event Interrupt */
#define USBD_INT_USB USBD_INTEN_USBIEN_Msk /*!< USB Event Interrupt */
#define USBD_INT_FLDET USBD_INTEN_VBDETIEN_Msk /*!< USB VBUS Detection Interrupt */
#define USBD_INT_WAKEUP (USBD_INTEN_NEVWKIEN_Msk | USBD_INTEN_WKEN_Msk) /*!< USB No-Event-Wake-Up Interrupt */
#define USBD_INTSTS_WAKEUP USBD_INTSTS_NEVWKIF_Msk /*!< USB No-Event-Wake-Up Interrupt Status */
#define USBD_INTSTS_FLDET USBD_INTSTS_VBDETIF_Msk /*!< USB Float Detect Interrupt Status */
#define USBD_INTSTS_BUS USBD_INTSTS_BUSIF_Msk /*!< USB Bus Event Interrupt Status */
#define USBD_INTSTS_USB USBD_INTSTS_USBIF_Msk /*!< USB Event Interrupt Status */
#define USBD_INTSTS_SETUP USBD_INTSTS_SETUP_Msk /*!< USB Setup Event */
#define USBD_INTSTS_EP0 USBD_INTSTS_EPEVT0_Msk /*!< USB Endpoint 0 Event */
#define USBD_INTSTS_EP1 USBD_INTSTS_EPEVT1_Msk /*!< USB Endpoint 1 Event */
#define USBD_INTSTS_EP2 USBD_INTSTS_EPEVT2_Msk /*!< USB Endpoint 2 Event */
#define USBD_INTSTS_EP3 USBD_INTSTS_EPEVT3_Msk /*!< USB Endpoint 3 Event */
#define USBD_INTSTS_EP4 USBD_INTSTS_EPEVT4_Msk /*!< USB Endpoint 4 Event */
#define USBD_INTSTS_EP5 USBD_INTSTS_EPEVT5_Msk /*!< USB Endpoint 5 Event */
#define USBD_INTSTS_EP6 USBD_INTSTS_EPEVT6_Msk /*!< USB Endpoint 6 Event */
#define USBD_INTSTS_EP7 USBD_INTSTS_EPEVT7_Msk /*!< USB Endpoint 7 Event */
#define USBD_INTSTS_EP8 USBD_INTSTS_EPEVT8_Msk /*!< USB Endpoint 8 Event */
#define USBD_INTSTS_EP9 USBD_INTSTS_EPEVT9_Msk /*!< USB Endpoint 9 Event */
#define USBD_INTSTS_EP10 USBD_INTSTS_EPEVT10_Msk /*!< USB Endpoint 10 Event */
#define USBD_INTSTS_EP11 USBD_INTSTS_EPEVT11_Msk /*!< USB Endpoint 11 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_TOUT_Msk /*!< USB Bus Timeout */
#define USBD_STATE_L1RESUME USBD_ATTR_L1RESUME_Msk /*!< USB Bus L1RESUME */
#define USBD_STATE_L1SUSPEND USBD_ATTR_L1SUSPEND_Msk /*!< USB BUS L1SUSPEND */
#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 */
/*@}*/ /* 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 USBD_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 USBD_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 |= 0x7D0))
/**
* @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->SE0 |= 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->SE0 &= ~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] and USB_ATTR[13:12].
* 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.
* Bit 12 indicates USB bus LPM L1 suspend status.
* Bit 13 indicates USB bus LPM L1 resume status.
*
* @details Return USB_ATTR[3:0] and USB_ATTR[13:12] for USB bus events.
*
* \hideinitializer
*/
#define USBD_GET_BUS_STATE() ((uint32_t)(USBD->ATTR & 0x300f))
/**
* @brief Check cable connection state
*
* @param None
*
* @retval 0 USB cable is not attached.
* @retval 1 USB cable is attached.
*
* @details Check the connection state by FLDET bit of USB_FLDET register.
*
*/
#define USBD_IS_ATTACHED() ((uint32_t)(USBD->VBUSDET & USBD_VBUSDET_VBUSDET_Msk))
/**
* @brief Stop USB transaction of the specified endpoint ID
*
* @param[in] ep The USB endpoint ID. M251 Series supports 12 hardware endpoint ID. This parameter could be 0 ~ 11.
*
* @return None
*
* @details Write 1 to CLRRDY bit of USB_CFGPx register to stop USB transaction of the specified endpoint ID.
*
*/
#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 ID
*
* @param[in] ep The USB endpoint ID. M251 Series supports 12 hardware endpoint ID. This parameter could be 0 ~ 11.
*
* @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_DSQSYNC_Msk)
/**
* @brief Set USB DATA0 PID for the specified endpoint ID
*
* @param[in] ep The USB endpoint ID. M251 Series supports 12 hardware endpoint ID. This parameter could be 0 ~ 11.
*
* @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_DSQSYNC_Msk))
/**
* @brief Set USB payload size (IN data)
*
* @param[in] ep The USB endpoint ID. M251 Series supports 12 hardware endpoint ID. This parameter could be 0 ~ 11.
*
* @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 ID. M251 Series supports 12 endpoint ID. This parameter could be 0 ~ 11.
*
* @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 ID. M251 Series supports 12 hardware endpoint ID. This parameter could be 0 ~ 11.
*
* @param[in] config The USB configuration.
*
* @return None
*
* @details This macro will write config parameter to USB_CFGx register of specified endpoint ID.
*
*/
#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 ID. M251 Series supports 12 hardware endpoint ID. This parameter could be 0 ~ 11.
*
* @param[in] offset The SRAM offset.
*
* @return None
*
* @details This macro will set the SRAM offset for the specified endpoint ID.
*
*/
#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 ID. M251 Series supports 12 hardware endpoint ID. This parameter could be 0 ~ 11.
*
* @return The offset of the specified endpoint buffer.
*
* @details This macro will return the SRAM offset of the specified endpoint ID.
*
*/
#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. M251 Series supports 12 hardware endpoint ID. This parameter could be 0 ~ 11.
*
* @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. M251 Series supports 12 hardware endpoint ID. This parameter could be 0 ~ 11.
*
* @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. M251 Series supports 12 hardware endpoint ID. This parameter could be 0 ~ 11.
*
* @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, uint32_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;
uint32_t i;
for (i = 0ul; 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 & 0xful) == 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;
uint32_t i;
for (i = 0ul; 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 & 0xful) == 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;
uint32_t i;
for (i = 0ul; i < USBD_MAX_EP; i++)
{
u32CfgAddr = (uint32_t)(i << 4ul) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
if ((u32Cfg & 0xful) == epnum)
{
u32CfgAddr = (uint32_t)(i << 4ul) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */
break;
}
}
return ((*((__IO uint32_t *)(u32CfgAddr))) & USBD_CFGP_SSTALL);
}
extern volatile uint8_t g_USBD_u8RemoteWakeupEn;
typedef void (*VENDOR_REQ)(void); /*!< Functional pointer type definition for Vendor class */
typedef void (*CLASS_REQ)(void); /*!< Functional pointer type declaration for USB class request callback handler */
typedef void (*SET_INTERFACE_REQ)(void); /*!< Functional pointer type declaration 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 Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __USBD_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,331 @@
/**************************************************************************//**
* @file usci_i2c.h
* @version V0.10
* @brief M251 series USCI I2C(UI2C) driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __USCI_I2C_H__
#define __USCI_I2C_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup USCI_I2C_Driver USCI_I2C Driver
@{
*/
/** @addtogroup USCI_I2C_EXPORTED_CONSTANTS USCI_I2C Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* USCI_I2C master event definitions */
/*---------------------------------------------------------------------------------------------------------*/
enum UI2C_MASTER_EVENT
{
MASTER_SEND_ADDRESS = 10, /*!< Master send address to Slave */
MASTER_SEND_H_WR_ADDRESS, /*!< Master send High address to Slave */
MASTER_SEND_H_RD_ADDRESS, /*!< Master send address to Slave (Read ADDR) */
MASTER_SEND_L_ADDRESS, /*!< Master send Low address to Slave */
MASTER_SEND_DATA, /*!< Master Send Data to Slave */
MASTER_SEND_REPEAT_START, /*!< Master send repeat start to Slave */
MASTER_READ_DATA, /*!< Master Get Data from Slave */
MASTER_STOP, /*!< Master send stop to Slave */
MASTER_SEND_START /*!< Master send start to Slave */
};
/*---------------------------------------------------------------------------------------------------------*/
/* USCI_I2C slave event definitions */
/*---------------------------------------------------------------------------------------------------------*/
enum UI2C_SLAVE_EVENT
{
SLAVE_ADDRESS_ACK = 100, /*!< Slave send address ACK */
SLAVE_H_WR_ADDRESS_ACK, /*!< Slave send High address ACK */
SLAVE_L_WR_ADDRESS_ACK, /*!< Slave send Low address ACK */
SLAVE_GET_DATA, /*!< Slave Get Data from Master (Write CMD) */
SLAVE_SEND_DATA, /*!< Slave Send Data to Master (Read CMD) */
SLAVE_H_RD_ADDRESS_ACK, /*!< Slave send High address ACK */
SLAVE_L_RD_ADDRESS_ACK /*!< Slave send Low address ACK */
};
/*---------------------------------------------------------------------------------------------------------*/
/* USCI_CTL constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define UI2C_CTL_PTRG 0x20UL /*!< USCI_CTL setting for I2C control bits. It would set PTRG bit \hideinitializer */
#define UI2C_CTL_STA 0x08UL /*!< USCI_CTL setting for I2C control bits. It would set STA bit \hideinitializer */
#define UI2C_CTL_STO 0x04UL /*!< USCI_CTL setting for I2C control bits. It would set STO bit \hideinitializer */
#define UI2C_CTL_AA 0x02UL /*!< USCI_CTL setting for I2C control bits. It would set AA bit \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* USCI_I2C GCMode constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define UI2C_GCMODE_ENABLE (1U) /*!< Enable USCI_I2C GC Mode \hideinitializer */
#define UI2C_GCMODE_DISABLE (0U) /*!< Disable USCI_I2C GC Mode \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* USCI_I2C Wakeup Mode constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define UI2C_DATA_TOGGLE_WK (0x0U << UI2C_WKCTL_WKADDREN_Pos) /*!< Wakeup according data toggle \hideinitializer */
#define UI2C_ADDR_MATCH_WK (0x1U << UI2C_WKCTL_WKADDREN_Pos) /*!< Wakeup according address match \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* USCI_I2C interrupt mask definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UI2C_TO_INT_MASK (0x001U) /*!< Time-out interrupt mask \hideinitializer */
#define UI2C_STAR_INT_MASK (0x002U) /*!< Start condition received interrupt mask \hideinitializer */
#define UI2C_STOR_INT_MASK (0x004U) /*!< Stop condition received interrupt mask \hideinitializer */
#define UI2C_NACK_INT_MASK (0x008U) /*!< Non-acknowledge interrupt mask \hideinitializer */
#define UI2C_ARBLO_INT_MASK (0x010U) /*!< Arbitration lost interrupt mask \hideinitializer */
#define UI2C_ERR_INT_MASK (0x020U) /*!< Error interrupt mask \hideinitializer */
#define UI2C_ACK_INT_MASK (0x040U) /*!< Acknowledge interrupt mask \hideinitializer */
/*@}*/ /* end of group USCI_I2C_EXPORTED_CONSTANTS */
/** @addtogroup USCI_I2C_EXPORTED_FUNCTIONS USCI_I2C Exported Functions
@{
*/
/**
* @brief This macro sets the USCI_I2C protocol control register at one time
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
* @param[in] u8Ctrl Set the register value of USCI_I2C control register.
*
* @return None
*
* @details Set UI2C_PROTCTL register to control USCI_I2C bus conditions of START, STOP, SI, ACK.
* \hideinitializer
*/
#define UI2C_SET_CONTROL_REG(psUI2C, u8Ctrl) ((psUI2C)->PROTCTL = ((psUI2C)->PROTCTL & ~0x2EU) | (u8Ctrl))
/**
* @brief This macro only set START bit to protocol control register of USCI_I2C module.
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
*
* @return None
*
* @details Set the USCI_I2C bus START condition in UI2C_PROTCTL register.
* \hideinitializer
*/
#define UI2C_START(psUI2C) ((psUI2C)->PROTCTL = ((psUI2C)->PROTCTL & ~UI2C_PROTCTL_PTRG_Msk) | UI2C_PROTCTL_STA_Msk)
/**
* @brief This macro only set STOP bit to the control register of USCI_I2C module
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
*
* @return None
*
* @details Set the USCI_I2C bus STOP condition in UI2C_PROTCTL register.
* \hideinitializer
*/
#define UI2C_STOP(psUI2C) ((psUI2C)->PROTCTL = ((psUI2C)->PROTCTL & ~0x2E) | (UI2C_PROTCTL_PTRG_Msk | UI2C_PROTCTL_STO_Msk))
/**
* @brief This macro returns the data stored in data register of USCI_I2C module
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
*
* @return Data
*
* @details Read a byte data value of UI2C_RXDAT register from USCI_I2C bus
* \hideinitializer
*/
#define UI2C_GET_DATA(psUI2C) ((psUI2C)->RXDAT)
/**
* @brief This macro writes the data to data register of USCI_I2C module
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
* @param[in] u8Data The data which will be written to data register of USCI_I2C module.
*
* @return None
*
* @details Write a byte data value of UI2C_TXDAT register, then sends address or data to USCI I2C bus
* \hideinitializer
*/
#define UI2C_SET_DATA(psUI2C, u8Data) ((psUI2C)->TXDAT = (u8Data))
/**
* @brief This macro returns time-out flag
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
*
* @retval 0 USCI_I2C bus time-out is not happened
* @retval 1 USCI_I2C bus time-out is happened
*
* @details USCI_I2C bus occurs time-out event, the time-out flag will be set. If not occurs time-out event, this bit is cleared.
* \hideinitializer
*/
#define UI2C_GET_TIMEOUT_FLAG(psUI2C) (((psUI2C)->PROTSTS & UI2C_PROTSTS_TOIF_Msk) == UI2C_PROTSTS_TOIF_Msk ? 1:0)
/**
* @brief This macro returns wake-up flag
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
*
* @retval 0 Chip is not woken-up from power-down mode
* @retval 1 Chip is woken-up from power-down mode
*
* @details USCI_I2C controller wake-up flag will be set when USCI_I2C bus occurs wake-up from deep-sleep.
* \hideinitializer
*/
#define UI2C_GET_WAKEUP_FLAG(psUI2C) (((psUI2C)->WKSTS & UI2C_WKSTS_WKF_Msk) == UI2C_WKSTS_WKF_Msk ? 1:0)
/**
* @brief This macro is used to clear USCI_I2C wake-up flag
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
*
* @return None
*
* @details If USCI_I2C wake-up flag is set, use this macro to clear it.
* \hideinitializer
*/
#define UI2C_CLR_WAKEUP_FLAG(psUI2C) ((psUI2C)->WKSTS = UI2C_WKSTS_WKF_Msk)
/**
* @brief This macro disables the USCI_I2C 10-bit address mode
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
*
* @return None
*
* @details The UI2C_I2C is 7-bit address mode, when disable USCI_I2C 10-bit address match function.
* \hideinitializer
*/
#define UI2C_DISABLE_10BIT_ADDR_MODE(psUI2C) ((psUI2C)->PROTCTL &= ~(UI2C_PROTCTL_ADDR10EN_Msk))
/**
* @brief This macro enables the 10-bit address mode
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
*
* @return None
*
* @details To enable USCI_I2C 10-bit address match function.
* \hideinitializer
*/
#define UI2C_ENABLE_10BIT_ADDR_MODE(psUI2C) ((psUI2C)->PROTCTL |= UI2C_PROTCTL_ADDR10EN_Msk)
/**
* @brief This macro gets USCI_I2C protocol interrupt flag or bus status
*
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
*
* @return A word data of USCI_I2C_PROTSTS register
*
* @details Read a word data of USCI_I2C PROTSTS register to get USCI_I2C bus Interrupt flags or status.
* \hideinitializer
*/
#define UI2C_GET_PROT_STATUS(psUI2C) ((psUI2C)->PROTSTS)
/**
* @brief This macro clears specified protocol interrupt flag
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
* @param[in] u32IntTypeFlag Interrupt Type Flag, should be
* - \ref UI2C_PROTSTS_ACKIF_Msk
* - \ref UI2C_PROTSTS_ERRIF_Msk
* - \ref UI2C_PROTSTS_ARBLOIF_Msk
* - \ref UI2C_PROTSTS_NACKIF_Msk
* - \ref UI2C_PROTSTS_STORIF_Msk
* - \ref UI2C_PROTSTS_STARIF_Msk
* - \ref UI2C_PROTSTS_TOIF_Msk
* @return None
*
* @details To clear interrupt flag when USCI_I2C occurs interrupt and set interrupt flag.
* \hideinitializer
*/
#define UI2C_CLR_PROT_INT_FLAG(psUI2C,u32IntTypeFlag) ((psUI2C)->PROTSTS = (u32IntTypeFlag))
/**
* @brief This macro enables specified protocol interrupt
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
* @param[in] u32IntSel Interrupt Type, should be
* - \ref UI2C_PROTIEN_ACKIEN_Msk
* - \ref UI2C_PROTIEN_ERRIEN_Msk
* - \ref UI2C_PROTIEN_ARBLOIEN_Msk
* - \ref UI2C_PROTIEN_NACKIEN_Msk
* - \ref UI2C_PROTIEN_STORIEN_Msk
* - \ref UI2C_PROTIEN_STARIEN_Msk
* - \ref UI2C_PROTIEN_TOIEN_Msk
* @return None
*
* @details Set specified USCI_I2C protocol interrupt bits to enable interrupt function.
* \hideinitializer
*/
#define UI2C_ENABLE_PROT_INT(psUI2C, u32IntSel) ((psUI2C)->PROTIEN |= (u32IntSel))
/**
* @brief This macro disables specified protocol interrupt
* @param[in] psUI2C The pointer of the specified USCI_I2C module.
* @param[in] u32IntSel Interrupt Type, should be
* - \ref UI2C_PROTIEN_ACKIEN_Msk
* - \ref UI2C_PROTIEN_ERRIEN_Msk
* - \ref UI2C_PROTIEN_ARBLOIEN_Msk
* - \ref UI2C_PROTIEN_NACKIEN_Msk
* - \ref UI2C_PROTIEN_STORIEN_Msk
* - \ref UI2C_PROTIEN_STARIEN_Msk
* - \ref UI2C_PROTIEN_TOIEN_Msk
* @return None
*
* @details Clear specified USCI_I2C protocol interrupt bits to disable interrupt function.
* \hideinitializer
*/
#define UI2C_DISABLE_PROT_INT(psUI2C, u32IntSel) ((psUI2C)->PROTIEN &= ~ (u32IntSel))
uint32_t UI2C_Open(UI2C_T *psUI2C, uint32_t u32BusClock);
void UI2C_Close(UI2C_T *psUI2C);
void UI2C_ClearTimeoutFlag(UI2C_T *psUI2C);
void UI2C_Trigger(UI2C_T *psUI2C, uint8_t u8Start, uint8_t u8Stop, uint8_t u8Ptrg, uint8_t u8Ack);
void UI2C_DisableInt(UI2C_T *psUI2C, uint32_t u32Mask);
void UI2C_EnableInt(UI2C_T *psUI2C, uint32_t u32Mask);
uint32_t UI2C_GetBusClockFreq(UI2C_T *psUI2C);
uint32_t UI2C_SetBusClockFreq(UI2C_T *psUI2C, uint32_t u32BusClock);
uint32_t UI2C_GetIntFlag(UI2C_T *psUI2C, uint32_t u32Mask);
void UI2C_ClearIntFlag(UI2C_T *psUI2C, uint32_t u32Mask);
uint32_t UI2C_GetData(UI2C_T *psUI2C);
void UI2C_SetData(UI2C_T *psUI2C, uint8_t u8Data);
void UI2C_SetSlaveAddr(UI2C_T *psUI2C, uint8_t u8SlaveNo, uint16_t u16SlaveAddr, uint8_t u8GCMode);
void UI2C_SetSlaveAddrMask(UI2C_T *psUI2C, uint8_t u8SlaveNo, uint16_t u16SlaveAddrMask);
void UI2C_EnableTimeout(UI2C_T *psUI2C, uint32_t u32TimeoutCnt);
void UI2C_DisableTimeout(UI2C_T *psUI2C);
void UI2C_EnableWakeup(UI2C_T *psUI2C, uint8_t u8WakeupMode);
void UI2C_DisableWakeup(UI2C_T *psUI2C);
uint8_t UI2C_WriteByte(UI2C_T *psUI2C, uint8_t u8SlaveAddr, const uint8_t u8Data);
uint32_t UI2C_WriteMultiBytes(UI2C_T *psUI2C, uint8_t u8SlaveAddr, const uint8_t *pu8Data, uint32_t u32WLen);
uint8_t UI2C_WriteByteOneReg(UI2C_T *psUI2C, uint8_t u8SlaveAddr, uint8_t u8DataAddr, const uint8_t u8Data);
uint32_t UI2C_WriteMultiBytesOneReg(UI2C_T *psUI2C, uint8_t u8SlaveAddr, uint8_t u8DataAddr, const uint8_t *pu8Data, uint32_t u32WLen);
uint8_t UI2C_WriteByteTwoRegs(UI2C_T *psUI2C, uint8_t u8SlaveAddr, uint16_t u16DataAddr, const uint8_t u8Data);
uint32_t UI2C_WriteMultiBytesTwoRegs(UI2C_T *psUI2C, uint8_t u8SlaveAddr, uint16_t u16DataAddr, const uint8_t *pu8Data, uint32_t u32WLen);
uint8_t UI2C_ReadByte(UI2C_T *psUI2C, uint8_t u8SlaveAddr);
uint32_t UI2C_ReadMultiBytes(UI2C_T *psUI2C, uint8_t u8SlaveAddr, uint8_t *pu8RData, uint32_t u32RLen);
uint8_t UI2C_ReadByteOneReg(UI2C_T *psUI2C, uint8_t u8SlaveAddr, uint8_t u8DataAddr);
uint32_t UI2C_ReadMultiBytesOneReg(UI2C_T *psUI2C, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t *pu8RData, uint32_t u32RLen);
uint8_t UI2C_ReadByteTwoRegs(UI2C_T *psUI2C, uint8_t u8SlaveAddr, uint16_t u16DataAddr);
uint32_t UI2C_ReadMultiBytesTwoRegs(UI2C_T *psUI2C, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t *pu8RData, uint32_t u32RLen);
/*@}*/ /* end of group USCI_I2C_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group USCI_I2C_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __USCI_I2C_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,410 @@
/****************************************************************************//**
* @file usci_spi.h
* @version V0.10
* @brief M251 series USCI_SPI driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __USCI_SPI_H__
#define __USCI_SPI_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup USCI_SPI_Driver USCI_SPI Driver
@{
*/
/** @addtogroup USCI_SPI_EXPORTED_CONSTANTS USCI_SPI Exported Constants
@{
*/
#define USPI_MODE_0 (0x0 << USPI_PROTCTL_SCLKMODE_Pos) /*!< SCLK idle low; data transmit with falling edge and receive with rising edge \hideinitializer */
#define USPI_MODE_1 (0x1 << USPI_PROTCTL_SCLKMODE_Pos) /*!< SCLK idle low; data transmit with rising edge and receive with falling edge \hideinitializer */
#define USPI_MODE_2 (0x2 << USPI_PROTCTL_SCLKMODE_Pos) /*!< SCLK idle high; data transmit with rising edge and receive with falling edge \hideinitializer */
#define USPI_MODE_3 (0x3 << USPI_PROTCTL_SCLKMODE_Pos) /*!< SCLK idle high; data transmit with falling edge and receive with rising edge \hideinitializer */
#define USPI_SLAVE (USPI_PROTCTL_SLAVE_Msk) /*!< Set as slave \hideinitializer */
#define USPI_MASTER (0x0ul) /*!< Set as master \hideinitializer */
#define USPI_SS (USPI_PROTCTL_SS_Msk) /*!< Set SS \hideinitializer */
#define USPI_SS_ACTIVE_HIGH (0x0ul) /*!< SS active high \hideinitializer */
#define USPI_SS_ACTIVE_LOW (USPI_LINECTL_CTLOINV_Msk) /*!< SS active low \hideinitializer */
/* USCI_SPI Interrupt Mask */
#define USPI_SSINACT_INT_MASK (0x001ul) /*!< Slave Slave Inactive interrupt mask \hideinitializer */
#define USPI_SSACT_INT_MASK (0x002ul) /*!< Slave Slave Active interrupt mask \hideinitializer */
#define USPI_SLVTO_INT_MASK (0x004ul) /*!< Slave Mode Time-out interrupt mask \hideinitializer */
#define USPI_SLVBE_INT_MASK (0x008ul) /*!< Slave Mode Bit Count Error interrupt mask \hideinitializer */
#define USPI_TXUDR_INT_MASK (0x010ul) /*!< Slave Transmit Under Run interrupt mask \hideinitializer */
#define USPI_RXOV_INT_MASK (0x020ul) /*!< Receive Buffer Overrun interrupt mask \hideinitializer */
#define USPI_TXST_INT_MASK (0x040ul) /*!< Transmit Start interrupt mask \hideinitializer */
#define USPI_TXEND_INT_MASK (0x080ul) /*!< Transmit End interrupt mask \hideinitializer */
#define USPI_RXST_INT_MASK (0x100ul) /*!< Receive Start interrupt mask \hideinitializer */
#define USPI_RXEND_INT_MASK (0x200ul) /*!< Receive End interrupt mask \hideinitializer */
/* USCI_SPI Status Mask */
#define USPI_BUSY_MASK (0x01ul) /*!< Busy status mask \hideinitializer */
#define USPI_RX_EMPTY_MASK (0x02ul) /*!< RX empty status mask \hideinitializer */
#define USPI_RX_FULL_MASK (0x04ul) /*!< RX full status mask \hideinitializer */
#define USPI_TX_EMPTY_MASK (0x08ul) /*!< TX empty status mask \hideinitializer */
#define USPI_TX_FULL_MASK (0x10ul) /*!< TX full status mask \hideinitializer */
#define USPI_SSLINE_STS_MASK (0x20ul) /*!< USCI_SPI_SS line status mask \hideinitializer */
/*@}*/ /* end of group USCI_SPI_EXPORTED_CONSTANTS */
/** @addtogroup USCI_SPI_EXPORTED_FUNCTIONS USCI_SPI Exported Functions
@{
*/
/**
* @brief Disable slave 3-wire mode.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
* \hideinitializer
*/
#define USPI_DISABLE_3WIRE_MODE(psUSPI) ( (psUSPI)->PROTCTL &= ~USPI_PROTCTL_SLV3WIRE_Msk )
/**
* @brief Enable slave 3-wire mode.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
* \hideinitializer
*/
#define USPI_ENABLE_3WIRE_MODE(psUSPI) ( (psUSPI)->PROTCTL |= USPI_PROTCTL_SLV3WIRE_Msk )
/**
* @brief Get the Rx buffer empty flag.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return Rx buffer flag
* @retval 0: Rx buffer is not empty
* @retval 1: Rx buffer is empty
* \hideinitializer
*/
#define USPI_GET_RX_EMPTY_FLAG(psUSPI) ( ((psUSPI)->BUFSTS & USPI_BUFSTS_RXEMPTY_Msk) == USPI_BUFSTS_RXEMPTY_Msk ? 1:0 )
/**
* @brief Get the Tx buffer empty flag.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return Tx buffer flag
* @retval 0: Tx buffer is not empty
* @retval 1: Tx buffer is empty
* \hideinitializer
*/
#define USPI_GET_TX_EMPTY_FLAG(psUSPI) ( ((psUSPI)->BUFSTS & USPI_BUFSTS_TXEMPTY_Msk) == USPI_BUFSTS_TXEMPTY_Msk ? 1:0 )
/**
* @brief Get the Tx buffer full flag.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return Tx buffer flag
* @retval 0: Tx buffer is not full
* @retval 1: Tx buffer is full
* \hideinitializer
*/
#define USPI_GET_TX_FULL_FLAG(psUSPI) ( ((psUSPI)->BUFSTS & USPI_BUFSTS_TXFULL_Msk) == USPI_BUFSTS_TXFULL_Msk ? 1:0 )
/**
* @brief Get the datum read from RX register.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return data in Rx register
* \hideinitializer
*/
#define USPI_READ_RX(psUSPI) ((psUSPI)->RXDAT)
/**
* @brief Write datum to TX register.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32TxData The datum which user attempt to transfer through USCI_SPI bus.
* @return None
* \hideinitializer
*/
#define USPI_WRITE_TX(psUSPI, u32TxData) ( (psUSPI)->TXDAT = (u32TxData) )
/**
* @brief Set USCI_SPI_SS pin to high state.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None.
* @details Disable automatic slave selection function and set USCI_SPI_SS pin to high state. Only available in Master mode.
* \hideinitializer
*/
#define USPI_SET_SS_HIGH(psUSPI) \
do{ \
(psUSPI)->LINECTL |= (USPI_LINECTL_CTLOINV_Msk); \
(psUSPI)->PROTCTL = ((psUSPI)->PROTCTL & ~(USPI_PROTCTL_AUTOSS_Msk | USPI_PROTCTL_SS_Msk)); \
}while(0)
/**
* @brief Set USCI_SPI_SS pin to low state.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None.
* @details Disable automatic slave selection function and set USCI_SPI_SS pin to low state. Only available in Master mode.
* \hideinitializer
*/
#define USPI_SET_SS_LOW(psUSPI) \
do{ \
(psUSPI)->LINECTL |= (USPI_LINECTL_CTLOINV_Msk); \
(psUSPI)->PROTCTL = (((psUSPI)->PROTCTL & ~USPI_PROTCTL_AUTOSS_Msk) | USPI_PROTCTL_SS_Msk); \
}while(0)
/**
* @brief Set the length of suspend interval.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32SuspCycle Decide the length of suspend interval.
* @return None
* \hideinitializer
*/
#define USPI_SET_SUSPEND_CYCLE(psUSPI, u32SuspCycle) ( (psUSPI)->PROTCTL = ((psUSPI)->PROTCTL & ~USPI_PROTCTL_SUSPITV_Msk) | ((u32SuspCycle) << USPI_PROTCTL_SUSPITV_Pos) )
/**
* @brief Set the USCI_SPI transfer sequence with LSB first.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
* \hideinitializer
*/
#define USPI_SET_LSB_FIRST(psUSPI) ( (psUSPI)->LINECTL |= USPI_LINECTL_LSB_Msk )
/**
* @brief Set the USCI_SPI transfer sequence with MSB first.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
* \hideinitializer
*/
#define USPI_SET_MSB_FIRST(psUSPI) ( (psUSPI)->LINECTL &= ~USPI_LINECTL_LSB_Msk )
/**
* @brief Set the data width of a USCI_SPI transaction.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32Width The data width
* @return None
* \hideinitializer
*/
#define USPI_SET_DATA_WIDTH(psUSPI,u32Width) \
do{ \
if((u32Width) == 16ul){ \
(psUSPI)->LINECTL = ((psUSPI)->LINECTL & ~USPI_LINECTL_DWIDTH_Msk) | (0 << USPI_LINECTL_DWIDTH_Pos); \
}else { \
(psUSPI)->LINECTL = ((psUSPI)->LINECTL & ~USPI_LINECTL_DWIDTH_Msk) | ((u32Width) << USPI_LINECTL_DWIDTH_Pos); \
} \
}while(0)
/**
* @brief Get the USCI_SPI busy state.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return USCI_SPI busy status
* @retval 0: USCI_SPI module is not busy
* @retval 1: USCI_SPI module is busy
* \hideinitializer
*/
#define USPI_IS_BUSY(psUSPI) ( ((psUSPI)->PROTSTS & USPI_PROTSTS_BUSY_Msk) == USPI_PROTSTS_BUSY_Msk ? 1:0 )
/**
* @brief Get the USCI_SPI wakeup flag.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return Wakeup status.
* @retval 0 Flag is not set.
* @retval 1 Flag is set.
* \hideinitializer
*/
#define USPI_GET_WAKEUP_FLAG(psUSPI) ( ((psUSPI)->WKSTS & USPI_WKSTS_WKF_Msk) == USPI_WKSTS_WKF_Msk ? 1:0)
/**
* @brief Clear the USCI_SPI wakeup flag.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
* \hideinitializer
*/
#define USPI_CLR_WAKEUP_FLAG(psUSPI) ( (psUSPI)->WKSTS |= USPI_WKSTS_WKF_Msk)
/**
* @brief Get protocol interrupt flag/status.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return The interrupt flag/status of protocol status register.
* \hideinitializer
*/
#define USPI_GET_PROT_STATUS(psUSPI) ( (psUSPI)->PROTSTS)
/**
* @brief Clear specified protocol interrupt flag.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32IntTypeFlag Interrupt Type Flag, should be
* - \ref USPI_PROTSTS_SSACTIF_Msk
* - \ref USPI_PROTSTS_SSINAIF_Msk
* - \ref USPI_PROTSTS_SLVBEIF_Msk
* - \ref USPI_PROTSTS_SLVTOIF_Msk
* - \ref USPI_PROTSTS_RXENDIF_Msk
* - \ref USPI_PROTSTS_RXSTIF_Msk
* - \ref USPI_PROTSTS_TXENDIF_Msk
* - \ref USPI_PROTSTS_TXSTIF_Msk
* @return None
* \hideinitializer
*/
#define USPI_CLR_PROT_INT_FLAG(psUSPI,u32IntTypeFlag) ( (psUSPI)->PROTSTS = (u32IntTypeFlag))
/**
* @brief Get buffer interrupt flag/status.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return The interrupt flag/status of buffer status register.
* \hideinitializer
*/
#define USPI_GET_BUF_STATUS(psUSPI) ( (psUSPI)->BUFSTS)
/**
* @brief Clear specified buffer interrupt flag.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32IntTypeFlag Interrupt Type Flag, should be
* - \ref USPI_BUFSTS_TXUDRIF_Msk
* - \ref USPI_BUFSTS_RXOVIF_Msk
* @return None
* \hideinitializer
*/
#define USPI_CLR_BUF_INT_FLAG(psUSPI,u32IntTypeFlag) ( (psUSPI)->BUFSTS = (u32IntTypeFlag))
/**
* @brief Enable specified protocol interrupt.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32IntSel Interrupt Type, should be
* - \ref USPI_PROTIEN_SLVBEIEN_Msk
* - \ref USPI_PROTIEN_SLVTOIEN_Msk
* - \ref USPI_PROTIEN_SSACTIEN_Msk
* - \ref USPI_PROTIEN_SSINAIEN_Msk
* @return None
* \hideinitializer
*/
#define USPI_ENABLE_PROT_INT(psUSPI, u32IntSel) ((psUSPI)->PROTIEN |= (u32IntSel))
/**
* @brief Disable specified protocol interrupt.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32IntSel Interrupt Type, should be
* - \ref USPI_PROTIEN_SLVBEIEN_Msk
* - \ref USPI_PROTIEN_SLVTOIEN_Msk
* - \ref USPI_PROTIEN_SSACTIEN_Msk
* - \ref USPI_PROTIEN_SSINAIEN_Msk
* @return None
* \hideinitializer
*/
#define USPI_DISABLE_PROT_INT(psUSPI, u32IntSel) ((psUSPI)->PROTIEN &= ~ (u32IntSel))
/**
* @brief Enable specified buffer interrupt.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32IntSel Interrupt Type, should be
* - \ref USPI_BUFCTL_RXOVIEN_Msk
* - \ref USPI_BUFCTL_TXUDRIEN_Msk
* @return None
* \hideinitializer
*/
#define USPI_ENABLE_BUF_INT(psUSPI, u32IntSel) ((psUSPI)->BUFCTL |= (u32IntSel))
/**
* @brief Disable specified buffer interrupt.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32IntSel Interrupt Type, should be
* - \ref USPI_BUFCTL_RXOVIEN_Msk
* - \ref USPI_BUFCTL_TXUDRIEN_Msk
* @return None
* \hideinitializer
*/
#define USPI_DISABLE_BUF_INT(psUSPI, u32IntSel) ((psUSPI)->BUFCTL &= ~ (u32IntSel))
/**
* @brief Enable specified transfer interrupt.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32IntSel Interrupt Type, should be
* - \ref USPI_INTEN_RXENDIEN_Msk
* - \ref USPI_INTEN_RXSTIEN_Msk
* - \ref USPI_INTEN_TXENDIEN_Msk
* - \ref USPI_INTEN_TXSTIEN_Msk
* @return None
* \hideinitializer
*/
#define USPI_ENABLE_TRANS_INT(psUSPI, u32IntSel) ((psUSPI)->INTEN |= (u32IntSel))
/**
* @brief Disable specified transfer interrupt.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32IntSel Interrupt Type, should be
* - \ref USPI_INTEN_RXENDIEN_Msk
* - \ref USPI_INTEN_RXSTIEN_Msk
* - \ref USPI_INTEN_TXENDIEN_Msk
* - \ref USPI_INTEN_TXSTIEN_Msk
* @return None
* \hideinitializer
*/
#define USPI_DISABLE_TRANS_INT(psUSPI, u32IntSel) ((psUSPI)->INTEN &= ~ (u32IntSel))
/**
* @brief Trigger RX PDMA function.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None.
* @details Set RXPDMAEN bit of USPI_PDMACTL register to enable RX PDMA transfer function.
* \hideinitializer
*/
#define USPI_TRIGGER_RX_PDMA(psUSPI) ((psUSPI)->PDMACTL |= USPI_PDMACTL_RXPDMAEN_Msk|USPI_PDMACTL_PDMAEN_Msk)
/**
* @brief Trigger TX PDMA function.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None.
* @details Set TXPDMAEN bit of USPI_PDMACTL register to enable TX PDMA transfer function.
* \hideinitializer
*/
#define USPI_TRIGGER_TX_PDMA(psUSPI) ((psUSPI)->PDMACTL |= USPI_PDMACTL_TXPDMAEN_Msk|USPI_PDMACTL_PDMAEN_Msk)
/**
* @brief Disable RX PDMA transfer.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None.
* @details Clear RXPDMAEN bit of USPI_PDMACTL register to disable RX PDMA transfer function.
* \hideinitializer
*/
#define USPI_DISABLE_RX_PDMA(psUSPI) ( (psUSPI)->PDMACTL &= ~USPI_PDMACTL_RXPDMAEN_Msk )
/**
* @brief Disable TX PDMA transfer.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None.
* @details Clear TXPDMAEN bit of USPI_PDMACTL register to disable TX PDMA transfer function.
* \hideinitializer
*/
#define USPI_DISABLE_TX_PDMA(psUSPI) ( (psUSPI)->PDMACTL &= ~USPI_PDMACTL_TXPDMAEN_Msk )
uint32_t USPI_Open(USPI_T *psUSPI, uint32_t u32MasterSlave, uint32_t u32SPIMode, uint32_t u32DataWidth, uint32_t u32BusClock);
void USPI_Close(USPI_T *psUSPI);
void USPI_ClearRxBuf(USPI_T *psUSPI);
void USPI_ClearTxBuf(USPI_T *psUSPI);
void USPI_DisableAutoSS(USPI_T *psUSPI);
void USPI_EnableAutoSS(USPI_T *psUSPI, uint32_t u32SSPinMask, uint32_t u32ActiveLevel);
uint32_t USPI_SetBusClock(USPI_T *psUSPI, uint32_t u32BusClock);
uint32_t USPI_GetBusClock(USPI_T *psUSPI);
void USPI_EnableInt(USPI_T *psUSPI, uint32_t u32Mask);
void USPI_DisableInt(USPI_T *psUSPI, uint32_t u32Mask);
uint32_t USPI_GetIntFlag(USPI_T *psUSPI, uint32_t u32Mask);
void USPI_ClearIntFlag(USPI_T *psUSPI, uint32_t u32Mask);
uint32_t USPI_GetStatus(USPI_T *psUSPI, uint32_t u32Mask);
void USPI_EnableWakeup(USPI_T *psUSPI);
void USPI_DisableWakeup(USPI_T *psUSPI);
/*@}*/ /* end of group USCI_SPI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group USCI_SPI_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __USCI_SPI_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,490 @@
/**************************************************************************//**
* @file usci_uart.h
* @version V0.10
* @brief M251 series USCI UART (UUART) driver header file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __USCI_UART_H__
#define __USCI_UART_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup USCI_UART_Driver USCI_UART Driver
@{
*/
/** @addtogroup USCI_UART_EXPORTED_CONSTANTS USCI_UART Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* UUART_LINECTL constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UUART_WORD_LEN_6 (6ul << UUART_LINECTL_DWIDTH_Pos) /*!< UUART_LINECTL setting to set UART word length to 6 bits \hideinitializer */
#define UUART_WORD_LEN_7 (7ul << UUART_LINECTL_DWIDTH_Pos) /*!< UUART_LINECTL setting to set UART word length to 7 bits \hideinitializer */
#define UUART_WORD_LEN_8 (8ul << UUART_LINECTL_DWIDTH_Pos) /*!< UUART_LINECTL setting to set UART word length to 8 bits \hideinitializer */
#define UUART_WORD_LEN_9 (9ul << UUART_LINECTL_DWIDTH_Pos) /*!< UUART_LINECTL setting to set UART word length to 9 bits \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* UUART_PROTCTL constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UUART_PARITY_NONE (0x0ul << UUART_PROTCTL_PARITYEN_Pos) /*!< UUART_PROTCTL setting to set UART as no parity \hideinitializer */
#define UUART_PARITY_ODD (0x1ul << UUART_PROTCTL_PARITYEN_Pos) /*!< UUART_PROTCTL setting to set UART as odd parity \hideinitializer */
#define UUART_PARITY_EVEN (0x3ul << UUART_PROTCTL_PARITYEN_Pos) /*!< UUART_PROTCTL setting to set UART as even parity \hideinitializer */
#define UUART_STOP_BIT_1 (0x0ul) /*!< UUART_PROTCTL setting for one stop bit \hideinitializer */
#define UUART_STOP_BIT_2 (0x1ul) /*!< UUART_PROTCTL setting for two stop bit \hideinitializer */
/*---------------------------------------------------------------------------------------------------------*/
/* USCI UART interrupt mask definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UUART_ABR_INT_MASK (0x002ul) /*!< Auto-baud rate interrupt mask \hideinitializer */
#define UUART_RLS_INT_MASK (0x004ul) /*!< Receive line status interrupt mask \hideinitializer */
#define UUART_BUF_RXOV_INT_MASK (0x008ul) /*!< Buffer RX overrun interrupt mask \hideinitializer */
#define UUART_TXST_INT_MASK (0x010ul) /*!< TX start interrupt mask \hideinitializer */
#define UUART_TXEND_INT_MASK (0x020ul) /*!< Tx end interrupt mask \hideinitializer */
#define UUART_RXST_INT_MASK (0x040ul) /*!< RX start interrupt mask \hideinitializer */
#define UUART_RXEND_INT_MASK (0x080ul) /*!< RX end interrupt mask \hideinitializer */
/*@}*/ /* end of group USCI_UART_EXPORTED_CONSTANTS */
/** @addtogroup USCI_UART_EXPORTED_FUNCTIONS USCI_UART Exported Functions
@{
*/
/**
* @brief Write USCI_UART data
*
* @param[in] psUUART The pointer of the specified USCI_UART module
* @param[in] u8Data Data byte to transmit.
*
* @return None
*
* @details This macro write Data to Tx data register.
* \hideinitializer
*/
#define UUART_WRITE(psUUART, u8Data) ((psUUART)->TXDAT = (u8Data))
/**
* @brief Read USCI_UART data
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @return The oldest data byte in RX buffer.
*
* @details This macro read Rx data register.
* \hideinitializer
*/
#define UUART_READ(psUUART) ((psUUART)->RXDAT)
/**
* @brief Get Tx empty
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @retval 0 Tx buffer is not empty
* @retval >=1 Tx buffer is empty
*
* @details This macro get Transmitter buffer empty register value.
* \hideinitializer
*/
#define UUART_GET_TX_EMPTY(psUUART) ((psUUART)->BUFSTS & UUART_BUFSTS_TXEMPTY_Msk)
/**
* @brief Get Rx empty
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @retval 0 Rx buffer is not empty
* @retval >=1 Rx buffer is empty
*
* @details This macro get Receiver buffer empty register value.
* \hideinitializer
*/
#define UUART_GET_RX_EMPTY(psUUART) ((psUUART)->BUFSTS & UUART_BUFSTS_RXEMPTY_Msk)
/**
* @brief Check specified usci_uart port transmission is over.
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @retval 0 Tx transmission is not over
* @retval 1 Tx transmission is over
*
* @details This macro return Transmitter Empty Flag register bit value. \n
* It indicates if specified usci_uart port transmission is over nor not.
* \hideinitializer
*/
#define UUART_IS_TX_EMPTY(psUUART) (((psUUART)->BUFSTS & UUART_BUFSTS_TXEMPTY_Msk) >> UUART_BUFSTS_TXEMPTY_Pos)
/**
* @brief Check specified usci_uart port receiver is empty.
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @retval 0 Rx receiver is not empty
* @retval 1 Rx receiver is empty
*
* @details This macro return Receive Empty Flag register bit value. \n
* It indicates if specified usci_uart port receiver is empty nor not.
* \hideinitializer
*/
#define UUART_IS_RX_EMPTY(psUUART) (((psUUART)->BUFSTS & UUART_BUFSTS_RXEMPTY_Msk) >> UUART_BUFSTS_RXEMPTY_Pos)
/**
* @brief Wait specified usci_uart port transmission is over
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @return None
*
* @details This macro wait specified usci_uart port transmission is over.
* \hideinitializer
*/
#define UUART_WAIT_TX_EMPTY(psUUART) while(!((((psUUART)->BUFSTS) & UUART_BUFSTS_TXEMPTY_Msk) >> UUART_BUFSTS_TXEMPTY_Pos))
/**
* @brief Check TX buffer is full or not
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @retval 1 TX buffer is full
* @retval 0 TX buffer is not full
*
* @details This macro check TX buffer is full or not.
* \hideinitializer
*/
#define UUART_IS_TX_FULL(psUUART) (((psUUART)->BUFSTS & UUART_BUFSTS_TXFULL_Msk)>>UUART_BUFSTS_TXFULL_Pos)
/**
* @brief Check RX buffer is full or not
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @retval 1 RX buffer is full
* @retval 0 RX buffer is not full
*
* @details This macro check RX buffer is full or not.
* \hideinitializer
*/
#define UUART_IS_RX_FULL(psUUART) (((psUUART)->BUFSTS & UUART_BUFSTS_RXFULL_Msk)>>UUART_BUFSTS_RXFULL_Pos)
/**
* @brief Get Tx full register value
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @retval 0 Tx buffer is not full.
* @retval >=1 Tx buffer is full.
*
* @details This macro get Tx full register value.
* \hideinitializer
*/
#define UUART_GET_TX_FULL(psUUART) ((psUUART)->BUFSTS & UUART_BUFSTS_TXFULL_Msk)
/**
* @brief Get Rx full register value
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @retval 0 Rx buffer is not full.
* @retval >=1 Rx buffer is full.
*
* @details This macro get Rx full register value.
* \hideinitializer
*/
#define UUART_GET_RX_FULL(psUUART) ((psUUART)->BUFSTS & UUART_BUFSTS_RXFULL_Msk)
/**
* @brief Enable specified USCI_UART protocol interrupt
*
* @param[in] psUUART The pointer of the specified USCI_UART module
* @param[in] u32IntSel Interrupt type select
* - \ref UUART_PROTIEN_RLSIEN_Msk : Rx Line status interrupt
* - \ref UUART_PROTIEN_ABRIEN_Msk : Auto-baud rate interrupt
*
* @return None
*
* @details This macro enable specified USCI_UART protocol interrupt.
* \hideinitializer
*/
#define UUART_ENABLE_PROT_INT(psUUART, u32IntSel) ((psUUART)->PROTIEN |= (u32IntSel))
/**
* @brief Disable specified USCI_UART protocol interrupt
*
* @param[in] psUUART The pointer of the specified USCI_UART module
* @param[in] u32IntSel Interrupt type select
* - \ref UUART_PROTIEN_RLSIEN_Msk : Rx Line status interrupt
* - \ref UUART_PROTIEN_ABRIEN_Msk : Auto-baud rate interrupt
*
* @return None
*
* @details This macro disable specified USCI_UART protocol interrupt.
* \hideinitializer
*/
#define UUART_DISABLE_PROT_INT(psUUART, u32IntSel) ((psUUART)->PROTIEN &= ~(u32IntSel))
/**
* @brief Enable specified USCI_UART buffer interrupt
*
* @param[in] psUUART The pointer of the specified USCI_UART module
* @param[in] u32IntSel Interrupt type select
* - \ref UUART_BUFCTL_RXOVIEN_Msk : Receive buffer overrun error interrupt
*
* @return None
*
* @details This macro enable specified USCI_UART buffer interrupt.
* \hideinitializer
*/
#define UUART_ENABLE_BUF_INT(psUUART, u32IntSel) ((psUUART)->BUFCTL |= (u32IntSel))
/**
* @brief Disable specified USCI_UART buffer interrupt
*
* @param[in] psUUART The pointer of the specified USCI_UART module
* @param[in] u32IntSel Interrupt type select
* - \ref UUART_BUFCTL_RXOVIEN_Msk : Receive buffer overrun error interrupt
*
* @return None
*
* @details This macro disable specified USCI_UART buffer interrupt.
* \hideinitializer
*/
#define UUART_DISABLE_BUF_INT(psUUART, u32IntSel) ((psUUART)->BUFCTL &= ~ (u32IntSel))
/**
* @brief Enable specified USCI_UART transfer interrupt
*
* @param[in] psUUART The pointer of the specified USCI_UART module
* @param[in] u32IntSel Interrupt type select
* - \ref UUART_INTEN_RXENDIEN_Msk : Receive end interrupt
* - \ref UUART_INTEN_RXSTIEN_Msk : Receive start interrupt
* - \ref UUART_INTEN_TXENDIEN_Msk : Transmit end interrupt
* - \ref UUART_INTEN_TXSTIEN_Msk : Transmit start interrupt
*
* @return None
*
* @details This macro enable specified USCI_UART transfer interrupt.
* \hideinitializer
*/
#define UUART_ENABLE_TRANS_INT(psUUART, u32IntSel) ((psUUART)->INTEN |= (u32IntSel))
/**
* @brief Disable specified USCI_UART transfer interrupt
*
* @param[in] psUUART The pointer of the specified USCI_UART module
* @param[in] u32IntSel Interrupt type select
* - \ref UUART_INTEN_RXENDIEN_Msk : Receive end interrupt
* - \ref UUART_INTEN_RXSTIEN_Msk : Receive start interrupt
* - \ref UUART_INTEN_TXENDIEN_Msk : Transmit end interrupt
* - \ref UUART_INTEN_TXSTIEN_Msk : Transmit start interrupt
*
* @return None
*
* @details This macro disable specified USCI_UART transfer interrupt.
* \hideinitializer
*/
#define UUART_DISABLE_TRANS_INT(psUUART, u32IntSel) ((psUUART)->INTEN &= ~(u32IntSel))
/**
* @brief Get protocol interrupt flag/status
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @return The interrupt flag/status of protocol status register.
*
* @details This macro get protocol status register value.
* \hideinitializer
*/
#define UUART_GET_PROT_STATUS(psUUART) ((psUUART)->PROTSTS)
/**
* @brief Clear specified protocol interrupt flag
*
* @param[in] psUUART The pointer of the specified USCI_UART module
* @param[in] u32IntTypeFlag Interrupt Type Flag, should be
* - \ref UUART_PROTSTS_ABERRSTS_Msk : Auto-baud Rate Error Interrupt Indicator
* - \ref UUART_PROTSTS_ABRDETIF_Msk : Auto-baud Rate Detected Interrupt Flag
* - \ref UUART_PROTSTS_BREAK_Msk : Break Flag
* - \ref UUART_PROTSTS_FRMERR_Msk : Framing Error Flag
* - \ref UUART_PROTSTS_PARITYERR_Msk : Parity Error Flag
* - \ref UUART_PROTSTS_RXENDIF_Msk : Receive End Interrupt Flag
* - \ref UUART_PROTSTS_RXSTIF_Msk : Receive Start Interrupt Flag
* - \ref UUART_PROTSTS_TXENDIF_Msk : Transmit End Interrupt Flag
* - \ref UUART_PROTSTS_TXSTIF_Msk : Transmit Start Interrupt Flag
*
* @return None
*
* @details This macro clear specified protocol interrupt flag.
* \hideinitializer
*/
#define UUART_CLR_PROT_INT_FLAG(psUUART,u32IntTypeFlag) ((psUUART)->PROTSTS = (u32IntTypeFlag))
/**
* @brief Get transmit/receive buffer interrupt flag/status
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @return The interrupt flag/status of buffer status register.
*
* @details This macro get buffer status register value.
* \hideinitializer
*/
#define UUART_GET_BUF_STATUS(psUUART) ((psUUART)->BUFSTS)
/**
* @brief Clear specified buffer interrupt flag
*
* @param[in] psUUART The pointer of the specified USCI_UART module
* @param[in] u32IntTypeFlag Interrupt Type Flag, should be
* - \ref UUART_BUFSTS_RXOVIF_Msk : Receive Buffer Over-run Error Interrupt Indicator
*
* @return None
*
* @details This macro clear specified buffer interrupt flag.
* \hideinitializer
*/
#define UUART_CLR_BUF_INT_FLAG(psUUART,u32IntTypeFlag) ((psUUART)->BUFSTS = (u32IntTypeFlag))
/**
* @brief Get wakeup flag
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @retval 0 Chip did not wake up from power-down mode.
* @retval 1 Chip waked up from power-down mode.
*
* @details This macro get wakeup flag.
* \hideinitializer
*/
#define UUART_GET_WAKEUP_FLAG(psUUART) ((psUUART)->WKSTS & UUART_WKSTS_WKF_Msk ? 1: 0 )
/**
* @brief Clear wakeup flag
*
* @param[in] psUUART The pointer of the specified USCI_UART module
*
* @return None
*
* @details This macro clear wakeup flag.
* \hideinitializer
*/
#define UUART_CLR_WAKEUP_FLAG(psUUART) ((psUUART)->WKSTS = UUART_WKSTS_WKF_Msk)
/**
* @brief Trigger RX PDMA function.
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
*
* @return None.
*
* @details Set RXPDMAEN bit of UUART_PDMACTL register to enable RX PDMA transfer function.
* \hideinitializer
*/
#define UUART_TRIGGER_RX_PDMA(psUUART) ((psUUART)->PDMACTL |= UUART_PDMACTL_RXPDMAEN_Msk|UUART_PDMACTL_PDMAEN_Msk)
/**
* @brief Trigger TX PDMA function.
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
*
* @return None.
*
* @details Set TXPDMAEN bit of UUART_PDMACTL register to enable TX PDMA transfer function.
* \hideinitializer
*/
#define UUART_TRIGGER_TX_PDMA(psUUART) ((psUUART)->PDMACTL |= UUART_PDMACTL_TXPDMAEN_Msk|UUART_PDMACTL_PDMAEN_Msk)
/**
* @brief Disable RX PDMA transfer.
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
*
* @return None.
*
* @details Clear RXPDMAEN bit of UUART_PDMACTL register to disable RX PDMA transfer function.
* \hideinitializer
*/
#define UUART_DISABLE_RX_PDMA(psUUART) ( (psUUART)->PDMACTL &= ~UUART_PDMACTL_RXPDMAEN_Msk )
/**
* @brief Disable TX PDMA transfer.
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
*
* @return None.
*
* @details Clear TXPDMAEN bit of UUART_PDMACTL register to disable TX PDMA transfer function.
* \hideinitializer
*/
#define UUART_DISABLE_TX_PDMA(psUUART) ( (psUUART)->PDMACTL &= ~UUART_PDMACTL_TXPDMAEN_Msk )
void UUART_ClearIntFlag(UUART_T *psUUART, uint32_t u32Mask);
uint32_t UUART_GetIntFlag(UUART_T *psUUART, uint32_t u32Mask);
void UUART_Close(UUART_T *psUUART);
void UUART_DisableInt(UUART_T *psUUART, uint32_t u32Mask);
void UUART_EnableInt(UUART_T *psUUART, uint32_t u32Mask);
uint32_t UUART_Open(UUART_T *psUUART, uint32_t u32Baudrate);
uint32_t UUART_Read(UUART_T *psUUART, uint8_t pu8RxBuf[], uint32_t u32ReadBytes);
uint32_t UUART_SetLine_Config(UUART_T *psUUART, uint32_t u32Baudrate, uint32_t u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits);
uint32_t UUART_Write(UUART_T *psUUART, uint8_t pu8TxBuf[], uint32_t u32WriteBytes);
void UUART_EnableWakeup(UUART_T *psUUART, uint32_t u32WakeupMode);
void UUART_DisableWakeup(UUART_T *psUUART);
void UUART_EnableFlowCtrl(UUART_T *psUUART);
void UUART_DisableFlowCtrl(UUART_T *psUUART);
/*@}*/ /* end of group USCI_UART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group USCI_UART_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __USCI_UART_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,222 @@
/**************************************************************************//**
* @file wdt.h
* @version V0.10
* @brief M251 series WDT driver header file
*
* @copyright (C) 2018 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
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* WDT Time-out Interval Period Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define WDT_TIMEOUT_2POW4 (0UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^4 * WDT clocks */
#define WDT_TIMEOUT_2POW6 (1UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^6 * WDT clocks */
#define WDT_TIMEOUT_2POW8 (2UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^8 * WDT clocks */
#define WDT_TIMEOUT_2POW10 (3UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^10 * WDT clocks */
#define WDT_TIMEOUT_2POW12 (4UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^12 * WDT clocks */
#define WDT_TIMEOUT_2POW14 (5UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^14 * WDT clocks */
#define WDT_TIMEOUT_2POW16 (6UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^16 * WDT clocks */
#define WDT_TIMEOUT_2POW18 (7UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^18 * WDT clocks */
#define WDT_TIMEOUT_2POW20 (8UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^20 * WDT clocks */
/*---------------------------------------------------------------------------------------------------------*/
/* WDT Reset Delay Period Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define WDT_RESET_DELAY_1026CLK (0UL << WDT_ALTCTL_RSTDSEL_Pos) /*!< Setting WDT reset delay period to 1026 * WDT clocks */
#define WDT_RESET_DELAY_130CLK (1UL << WDT_ALTCTL_RSTDSEL_Pos) /*!< Setting WDT reset delay period to 130 * WDT clocks */
#define WDT_RESET_DELAY_18CLK (2UL << WDT_ALTCTL_RSTDSEL_Pos) /*!< Setting WDT reset delay period to 18 * WDT clocks */
#define WDT_RESET_DELAY_3CLK (3UL << WDT_ALTCTL_RSTDSEL_Pos) /*!< Setting WDT reset delay period to 3 * WDT clocks */
/*---------------------------------------------------------------------------------------------------------*/
/* WDT Free Reset Counter Keyword Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define WDT_FREE_RESET_COUNTER_KEY (0x00005AA5) /*!< Fill this value to WDT_RSTCNT register to free reset WDT counter */
/*@}*/ /* 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 clears WDT time-out reset system flag.
*
* \hideinitializer
*/
#define WDT_CLEAR_RESET_FLAG() (WDT->CTL = (WDT->CTL & ~(WDT_CTL_IF_Msk | WDT_CTL_WKF_Msk)) | WDT_CTL_RSTF_Msk)
/**
* @brief Clear WDT Time-out Interrupt Flag
*
* @param None
*
* @return None
*
* @details This macro clears WDT time-out interrupt flag.
*
* \hideinitializer
*/
#define WDT_CLEAR_TIMEOUT_INT_FLAG() (WDT->CTL = (WDT->CTL & ~(WDT_CTL_RSTF_Msk | WDT_CTL_WKF_Msk)) | WDT_CTL_IF_Msk)
/**
* @brief Clear WDT Wake-up Flag
*
* @param None
*
* @return None
*
* @details This macro clears WDT time-out wake-up system flag.
*
* \hideinitializer
*/
#define WDT_CLEAR_TIMEOUT_WAKEUP_FLAG() (WDT->CTL = (WDT->CTL & ~(WDT_CTL_RSTF_Msk | WDT_CTL_IF_Msk)) | WDT_CTL_WKF_Msk)
/**
* @brief Get WDT Time-out Reset Flag
*
* @param None
*
* @retval 0 WDT time-out reset system did not occur
* @retval 1 WDT time-out reset system occurred
*
* @details This macro indicates system has been reset by WDT time-out reset or not.
*
* \hideinitializer
*/
#define WDT_GET_RESET_FLAG() ((WDT->CTL & WDT_CTL_RSTF_Msk)? 1UL : 0UL)
/**
* @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 indicates WDT time-out interrupt occurred or not.
*
* \hideinitializer
*/
#define WDT_GET_TIMEOUT_INT_FLAG() ((WDT->CTL & WDT_CTL_IF_Msk)? 1UL : 0UL)
/**
* @brief Get WDT Time-out Wake-up Flag
*
* @param None
*
* @retval 0 WDT time-out interrupt does not cause CPU wake-up
* @retval 1 WDT time-out interrupt event cause CPU wake-up
*
* @details This macro indicates WDT time-out interrupt event has waked up system or not.
*
* \hideinitializer
*/
#define WDT_GET_TIMEOUT_WAKEUP_FLAG() ((WDT->CTL & WDT_CTL_WKF_Msk)? 1UL : 0UL)
/**
* @brief Reset WDT Counter
*
* @param None
*
* @return None
*
* @details This macro is used to reset the internal 18-bit WDT up counter value.
* @note If WDT is activated and time-out reset system function is enabled also, user should \n
* reset the 18-bit WDT up counter value to avoid generate WDT time-out reset signal to \n
* reset system before the WDT time-out reset delay period expires.
*
* \hideinitializer
*/
#define WDT_RESET_COUNTER() (WDT->RSTCNT = WDT_FREE_RESET_COUNTER_KEY)
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
__STATIC_INLINE void WDT_Close(void);
__STATIC_INLINE void WDT_EnableInt(void);
__STATIC_INLINE void WDT_DisableInt(void);
/**
* @brief Stop WDT Counting
*
* @param None
*
* @return None
*
* @details This function will stop WDT counting and disable WDT module.
*/
__STATIC_INLINE void WDT_Close(void)
{
WDT->CTL = 0UL;
return;
}
/**
* @brief Enable WDT Time-out Interrupt
*
* @param None
*
* @return None
*
* @details This function will enable the WDT time-out interrupt function.
*/
__STATIC_INLINE void WDT_EnableInt(void)
{
WDT->CTL |= WDT_CTL_INTEN_Msk;
return;
}
/**
* @brief Disable WDT Time-out Interrupt
*
* @param None
*
* @return None
*
* @details This function will disable the WDT time-out interrupt function.
*/
__STATIC_INLINE void WDT_DisableInt(void)
{
/* Do not touch another write 1 clear bits */
WDT->CTL &= ~(WDT_CTL_INTEN_Msk | WDT_CTL_RSTF_Msk | WDT_CTL_IF_Msk | WDT_CTL_WKF_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 Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __WDT_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,157 @@
/**************************************************************************//**
* @file wwdt.h
* @version V0.10
* @brief M251 series WWDT driver header file
*
* @copyright (C) 2018 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
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* WWDT Prescale Period Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define WWDT_PRESCALER_1 (0 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 1 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_2 (1 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 2 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_4 (2 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 4 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_8 (3 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 8 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_16 (4 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 16 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_32 (5 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 32 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_64 (6 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 64 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_128 (7 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 128 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_192 (8 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 192 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_256 (9 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 256 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_384 (10 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 384 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_512 (11 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 512 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_768 (12 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 768 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_1024 (13 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 1024 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_1536 (14 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 1536 * (64*WWDT_CLK) */
#define WWDT_PRESCALER_2048 (15 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 2048 * (64*WWDT_CLK) */
/*---------------------------------------------------------------------------------------------------------*/
/* WWDT Reload Counter Keyword Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define WWDT_RELOAD_WORD (0x00005AA5) /*!< Fill this value to WWDT_RLDCNT 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 time-out reset system flag.
*
* \hideinitializer
*/
#define WWDT_CLEAR_RESET_FLAG() (WWDT->STATUS = WWDT_STATUS_WWDTRF_Msk)
/**
* @brief Clear WWDT Compared Match Interrupt Flag
*
* @param None
*
* @return None
*
* @details This macro is used to clear WWDT compared match interrupt flag.
*
* \hideinitializer
*/
#define WWDT_CLEAR_INT_FLAG() (WWDT->STATUS = WWDT_STATUS_WWDTIF_Msk)
/**
* @brief Get WWDT Reset System Flag
*
* @param None
*
* @retval 0 WWDT time-out reset system did not occur
* @retval 1 WWDT time-out reset system occurred
*
* @details This macro is used to indicate system has been reset by WWDT time-out reset or not.
*
* \hideinitializer
*/
#define WWDT_GET_RESET_FLAG() ((WWDT->STATUS & WWDT_STATUS_WWDTRF_Msk)? 1 : 0)
/**
* @brief Get WWDT Compared Match Interrupt Flag
*
* @param None
*
* @retval 0 WWDT compare match interrupt did not occur
* @retval 1 WWDT compare match interrupt occurred
*
* @details This macro is used to indicate WWDT counter value matches CMPDAT value or not.
*
* \hideinitializer
*/
#define WWDT_GET_INT_FLAG() ((WWDT->STATUS & WWDT_STATUS_WWDTIF_Msk)? 1 : 0)
/**
* @brief Get WWDT Counter
*
* @param None
*
* @return WWDT Counter Value
*
* @details This macro reflects the current WWDT counter value.
*
* \hideinitializer
*/
#define WWDT_GET_COUNTER() (WWDT->CNT)
/**
* @brief Reload WWDT Counter
*
* @param None
*
* @return None
*
* @details This macro is used to reload the WWDT counter value to 0x3F.
* @note User can only write WWDT_RLDCNT register to reload WWDT counter value when current WWDT counter value \n
* between 0 and CMPDAT value. If user writes WWDT_RLDCNT when current WWDT counter value is larger than CMPDAT, \n
* WWDT reset signal will generate immediately to reset system.
*
* \hideinitializer
*/
#define WWDT_RELOAD_COUNTER() (WWDT->RLDCNT = 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 Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __WWDT_H__ */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,73 @@
/**************************************************************************//**
* @file acmp.c
* @version V1.00
* @brief M251 series Analog Comparator(ACMP) driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
/** @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_CTL_NEGSEL_PIN
* - \ref ACMP_CTL_NEGSEL_CRV
* - \ref ACMP_CTL_NEGSEL_VBG
* - \ref ACMP_CTL_NEGSEL_DAC
* @param[in] u32HysSel The hysteresis function option. Including:
* - \ref ACMP_CTL_HYSTERESIS_30MV
* - \ref ACMP_CTL_HYSTERESIS_20MV
* - \ref ACMP_CTL_HYSTERESIS_10MV
* - \ref ACMP_CTL_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 u32HysSel)
{
acmp->CTL[u32ChNum] = (acmp->CTL[u32ChNum] & (~(ACMP_CTL_NEGSEL_Msk | ACMP_CTL_HYSSEL_Msk))) | (u32NegSrc | u32HysSel | ACMP_CTL_ACMPEN_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 ACMPEN bit of ACMP_CTL register to disable analog comparator.
*/
void ACMP_Close(ACMP_T *acmp, uint32_t u32ChNum)
{
acmp->CTL[u32ChNum] &= (~ACMP_CTL_ACMPEN_Msk);
}
/*@}*/ /* end of group ACMP_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group ACMP_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,748 @@
/**************************************************************************//**
* @file bpwm.c
* @version V0.10
* @brief M251 series BPWM driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup BPWM_Driver BPWM Driver
@{
*/
/** @addtogroup BPWM_EXPORTED_FUNCTIONS BPWM Exported Functions
@{
*/
/**
* @brief Configure BPWM capture and get the nearest unit time.
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @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 BPWM capture and get the nearest unit time.
*/
uint32_t BPWM_ConfigCaptureChannel(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32UnitTimeNsec, uint32_t u32CaptureEdge)
{
uint32_t u32Src;
uint32_t u32BPWMClockSrc;
uint32_t u32NearestUnitTimeNsec;
uint16_t u16Prescale = 1UL, u16CNR = 0xFFFFUL;
uint8_t u8BreakLoop = 0UL;
if (bpwm == BPWM0)
{
u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM0SEL_Msk;
}
else /* (bpwm == BPWM1) */
{
u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM1SEL_Msk;
}
if (u32Src == 0UL)
{
//clock source is from PLL clock
u32BPWMClockSrc = CLK_GetPLLClockFreq();
}
else
{
//clock source is from PCLK
SystemCoreClockUpdate();
if (bpwm == BPWM0)
{
u32BPWMClockSrc = CLK_GetPCLK0Freq();
}
else /* (bpwm == BPWM1) */
{
u32BPWMClockSrc = CLK_GetPCLK1Freq();
}
}
u32BPWMClockSrc /= 1000UL;
for (u16Prescale = 1UL; u16Prescale <= 0x1000UL; u16Prescale++)
{
u32NearestUnitTimeNsec = (1000000UL * u16Prescale) / u32BPWMClockSrc;
if (u32NearestUnitTimeNsec < u32UnitTimeNsec)
{
if (u16Prescale == 0x1000UL)
{
/* limit to the maximum unit time(nano second) */
u8BreakLoop = 1UL;
}
if (!((1000000UL * (u16Prescale + 1UL) > (u32NearestUnitTimeNsec * u32BPWMClockSrc))))
{
u8BreakLoop = 1UL;
}
}
else
{
u8BreakLoop = 1UL;
}
if (u8BreakLoop)
{
break;
}
}
// convert to real register value
u16Prescale = u16Prescale - 1UL;
// all channels share a prescaler
BPWM_SET_PRESCALER(bpwm, u32ChannelNum, (uint32_t)u16Prescale);
// set BPWM to down count type(edge aligned)
(bpwm)->CTL1 = BPWM_DOWN_COUNTER;
BPWM_SET_CNR(bpwm, u32ChannelNum, u16CNR);
return (u32NearestUnitTimeNsec);
}
/**
* @brief This function Configure BPWM generator and get the nearest frequency in edge aligned(down countertype) auto-reload mode
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @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
* @note Since all channels shares a prescaler. Call this API to configure BPWM frequency may affect
* existing frequency of other channel.
*/
uint32_t BPWM_ConfigOutputChannel(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Frequency, uint32_t u32DutyCycle)
{
uint32_t u32Src;
uint32_t u32BPWMClockSrc;
uint32_t i;
uint16_t u16Prescale = 1UL, u16CNR = 0xFFFFUL;
if (bpwm == BPWM0)
{
u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM0SEL_Msk;
}
else /* (bpwm == BPWM1) */
{
u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_BPWM1SEL_Msk;
}
if (u32Src == 0UL)
{
//clock source is from PLL clock
u32BPWMClockSrc = CLK_GetPLLClockFreq();
}
else
{
//clock source is from PCLK
SystemCoreClockUpdate();
if (bpwm == BPWM0)
{
u32BPWMClockSrc = CLK_GetPCLK0Freq();
}
else /* (bpwm == BPWM1) */
{
u32BPWMClockSrc = CLK_GetPCLK1Freq();
}
}
for (u16Prescale = 1UL; u16Prescale < 0xFFFUL; u16Prescale++) //prescale could be 0~0xFFF
{
i = (u32BPWMClockSrc / u32Frequency) / u16Prescale;
// If target value is larger than CNR, need to use a larger prescaler
if (i <= (0x10000UL))
{
u16CNR = (uint16_t)i;
break;
}
}
// Store return value here 'cos we're gonna change u16Prescale & u16CNR to the real value to fill into register
i = u32BPWMClockSrc / ((uint32_t)u16Prescale * (uint32_t)u16CNR);
// convert to real register value
u16Prescale = u16Prescale - 1UL;
// all channels share a prescaler
BPWM_SET_PRESCALER(bpwm, u32ChannelNum, (uint32_t)u16Prescale);
// set BPWM to down count type
(bpwm)->CTL1 = BPWM_DOWN_COUNTER;
u16CNR = u16CNR - 1UL;
BPWM_SET_CNR(bpwm, u32ChannelNum, u16CNR);
if (u32DutyCycle)
{
if (u32DutyCycle >= 100UL)
BPWM_SET_CMR(bpwm, u32ChannelNum, u16CNR);
else
BPWM_SET_CMR(bpwm, u32ChannelNum, u32DutyCycle * (u16CNR + 1UL) / 100UL);
(bpwm)->WGCTL0 &= ~((BPWM_WGCTL0_PRDPCTL0_Msk | BPWM_WGCTL0_ZPCTL0_Msk) << (u32ChannelNum << 1UL));
(bpwm)->WGCTL0 |= (BPWM_OUTPUT_LOW << ((u32ChannelNum << 1UL) + BPWM_WGCTL0_PRDPCTL0_Pos));
(bpwm)->WGCTL1 &= ~((BPWM_WGCTL1_CMPDCTL0_Msk | BPWM_WGCTL1_CMPUCTL0_Msk) << (u32ChannelNum << 1UL));
(bpwm)->WGCTL1 |= (BPWM_OUTPUT_HIGH << ((u32ChannelNum << 1UL) + BPWM_WGCTL1_CMPDCTL0_Pos));
}
else
{
BPWM_SET_CMR(bpwm, u32ChannelNum, 0UL);
(bpwm)->WGCTL0 &= ~((BPWM_WGCTL0_PRDPCTL0_Msk | BPWM_WGCTL0_ZPCTL0_Msk) << (u32ChannelNum << 1UL));
(bpwm)->WGCTL0 |= (BPWM_OUTPUT_LOW << ((u32ChannelNum << 1UL) + BPWM_WGCTL0_ZPCTL0_Pos));
(bpwm)->WGCTL1 &= ~((BPWM_WGCTL1_CMPDCTL0_Msk | BPWM_WGCTL1_CMPUCTL0_Msk) << (u32ChannelNum << 1UL));
(bpwm)->WGCTL1 |= (BPWM_OUTPUT_HIGH << ((u32ChannelNum << 1UL) + BPWM_WGCTL1_CMPDCTL0_Pos));
}
return (i);
}
/**
* @brief Start BPWM module
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This function is used to start BPWM module.
* @note All channels share one counter.
*/
void BPWM_Start(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->CNTEN = BPWM_CNTEN_CNTEN0_Msk;
}
/**
* @brief Stop BPWM module
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This function is used to stop BPWM module.
* @note All channels share one period.
*/
void BPWM_Stop(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->PERIOD = 0UL;
}
/**
* @brief Stop BPWM generation immediately by clear channel enable bit
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelMask Combination of enabled channels. This parameter is not used.
* @return None
* @details This function is used to stop BPWM generation immediately by clear channel enable bit.
* @note All channels share one counter.
*/
void BPWM_ForceStop(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->CNTEN &= ~BPWM_CNTEN_CNTEN0_Msk;
}
/**
* @brief Enable selected channel to trigger ADC
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Condition The condition to trigger ADC. Combination of following conditions:
* - \ref BPWM_TRIGGER_ADC_EVEN_ZERO_POINT
* - \ref BPWM_TRIGGER_ADC_EVEN_PERIOD_POINT
* - \ref BPWM_TRIGGER_ADC_EVEN_ZERO_OR_PERIOD_POINT
* - \ref BPWM_TRIGGER_ADC_EVEN_CMP_UP_COUNT_POINT
* - \ref BPWM_TRIGGER_ADC_EVEN_CMP_DOWN_COUNT_POINT
* - \ref BPWM_TRIGGER_ADC_ODD_CMP_UP_COUNT_POINT
* - \ref BPWM_TRIGGER_ADC_ODD_CMP_DOWN_COUNT_POINT
* @return None
* @details This function is used to enable selected channel to trigger ADC
*/
void BPWM_EnableADCTrigger(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Condition)
{
if (u32ChannelNum < 4UL)
{
(bpwm)->EADCTS0 &= ~((BPWM_EADCTS0_TRGSEL0_Msk) << (u32ChannelNum << 3UL));
(bpwm)->EADCTS0 |= ((BPWM_EADCTS0_TRGEN0_Msk | u32Condition) << (u32ChannelNum << 3UL));
}
else
{
(bpwm)->EADCTS1 &= ~((BPWM_EADCTS1_TRGSEL4_Msk) << ((u32ChannelNum - 4UL) << 3UL));
(bpwm)->EADCTS1 |= ((BPWM_EADCTS1_TRGEN4_Msk | u32Condition) << ((u32ChannelNum - 4UL) << 3UL));
}
}
/**
* @brief Disable selected channel to trigger ADC
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return None
* @details This function is used to disable selected channel to trigger ADC
*/
void BPWM_DisableADCTrigger(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
if (u32ChannelNum < 4UL)
{
(bpwm)->EADCTS0 &= ~(BPWM_EADCTS0_TRGEN0_Msk << (u32ChannelNum << 3UL));
}
else
{
(bpwm)->EADCTS1 &= ~(BPWM_EADCTS1_TRGEN4_Msk << ((u32ChannelNum - 4UL) << 3UL));
}
}
/**
* @brief Clear selected channel trigger ADC flag
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Condition This parameter is not used
* @return None
* @details This function is used to clear selected channel trigger ADC flag
*/
void BPWM_ClearADCTriggerFlag(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Condition)
{
(bpwm)->STATUS = (BPWM_STATUS_EADCTRG0_Msk << u32ChannelNum);
}
/**
* @brief Get selected channel trigger ADC flag
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @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 BPWM trigger ADC to start of conversion flag for specified channel
*/
uint32_t BPWM_GetADCTriggerFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return (((bpwm)->STATUS & (BPWM_STATUS_EADCTRG0_Msk << u32ChannelNum)) ? 1UL : 0UL);
}
/**
* @brief Enable capture of selected channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @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 BPWM_EnableCapture(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->CAPINEN |= u32ChannelMask;
(bpwm)->CAPCTL |= u32ChannelMask;
}
/**
* @brief Disable capture of selected channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @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 BPWM_DisableCapture(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->CAPINEN &= ~u32ChannelMask;
(bpwm)->CAPCTL &= ~u32ChannelMask;
}
/**
* @brief Enables BPWM output generation of selected channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @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 BPWM output generation of selected channel(s)
*/
void BPWM_EnableOutput(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->POEN |= u32ChannelMask;
}
/**
* @brief Disables BPWM output generation of selected channel(s)
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @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 BPWM output generation of selected channel(s)
*/
void BPWM_DisableOutput(BPWM_T *bpwm, uint32_t u32ChannelMask)
{
(bpwm)->POEN &= ~u32ChannelMask;
}
/**
* @brief Enable capture interrupt of selected channel.
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Edge Rising or falling edge to latch counter.
* - \ref BPWM_CAPTURE_INT_RISING_LATCH
* - \ref BPWM_CAPTURE_INT_FALLING_LATCH
* @return None
* @details This function is used to enable capture interrupt of selected channel.
*/
void BPWM_EnableCaptureInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
(bpwm)->CAPIEN |= (u32Edge << u32ChannelNum);
}
/**
* @brief Disable capture interrupt of selected channel.
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Edge Rising or falling edge to latch counter.
* - \ref BPWM_CAPTURE_INT_RISING_LATCH
* - \ref BPWM_CAPTURE_INT_FALLING_LATCH
* @return None
* @details This function is used to disable capture interrupt of selected channel.
*/
void BPWM_DisableCaptureInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
(bpwm)->CAPIEN &= ~(u32Edge << u32ChannelNum);
}
/**
* @brief Clear capture interrupt of selected channel.
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32Edge Rising or falling edge to latch counter.
* - \ref BPWM_CAPTURE_INT_RISING_LATCH
* - \ref BPWM_CAPTURE_INT_FALLING_LATCH
* @return None
* @details This function is used to clear capture interrupt of selected channel.
*/
void BPWM_ClearCaptureIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
(bpwm)->CAPIF = (u32Edge << u32ChannelNum);
}
/**
* @brief Get capture interrupt of selected channel.
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @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 BPWM_GetCaptureIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return (((((bpwm)->CAPIF & (BPWM_CAPIF_CAPFIF0_Msk << u32ChannelNum)) ? 1UL : 0UL) << 1UL) | \
(((bpwm)->CAPIF & (BPWM_CAPIF_CAPRIF0_Msk << u32ChannelNum)) ? 1UL : 0UL));
}
/**
* @brief Enable duty interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32IntDutyType Duty interrupt type, could be either
* - \ref BPWM_DUTY_INT_DOWN_COUNT_MATCH_CMP
* - \ref BPWM_DUTY_INT_UP_COUNT_MATCH_CMP
* @return None
* @details This function is used to enable duty interrupt of selected channel.
*/
void BPWM_EnableDutyInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType)
{
(bpwm)->INTEN |= (u32IntDutyType << u32ChannelNum);
}
/**
* @brief Disable duty interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return None
* @details This function is used to disable duty interrupt of selected channel
*/
void BPWM_DisableDutyInt(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTEN &= ~((uint32_t)(BPWM_DUTY_INT_DOWN_COUNT_MATCH_CMP | BPWM_DUTY_INT_UP_COUNT_MATCH_CMP) << u32ChannelNum);
}
/**
* @brief Clear duty interrupt flag of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return None
* @details This function is used to clear duty interrupt flag of selected channel
*/
void BPWM_ClearDutyIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTSTS = (BPWM_INTSTS_CMPUIF0_Msk | BPWM_INTSTS_CMPDIF0_Msk) << u32ChannelNum;
}
/**
* @brief Get duty interrupt flag of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @return Duty interrupt flag of specified channel
* @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 BPWM_GetDutyIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return ((((bpwm)->INTSTS & ((BPWM_INTSTS_CMPDIF0_Msk | BPWM_INTSTS_CMPUIF0_Msk) << u32ChannelNum))) ? 1UL : 0UL);
}
/**
* @brief Enable period interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @param[in] u32IntPeriodType Period interrupt type. This parameter is not used.
* @return None
* @details This function is used to enable period interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_EnablePeriodInt(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType)
{
(bpwm)->INTEN |= BPWM_INTEN_PIEN0_Msk;
}
/**
* @brief Disable period interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to disable period interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_DisablePeriodInt(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTEN &= ~BPWM_INTEN_PIEN0_Msk;
}
/**
* @brief Clear period interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to clear period interrupt of selected channel
* @note All channels share channel 0's setting.
*/
void BPWM_ClearPeriodIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTSTS = BPWM_INTSTS_PIF0_Msk;
}
/**
* @brief Get period interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return Period interrupt flag of specified channel
* @retval 0 Period interrupt did not occur
* @retval 1 Period interrupt occurred
* @details This function is used to get period interrupt of selected channel
* @note All channels share channel 0's setting.
*/
uint32_t BPWM_GetPeriodIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return (((bpwm)->INTSTS & BPWM_INTSTS_PIF0_Msk) ? 1UL : 0UL);
}
/**
* @brief Enable zero interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to enable zero interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_EnableZeroInt(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTEN |= BPWM_INTEN_ZIEN0_Msk;
}
/**
* @brief Disable zero interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to disable zero interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_DisableZeroInt(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTEN &= ~BPWM_INTEN_ZIEN0_Msk;
}
/**
* @brief Clear zero interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to clear zero interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_ClearZeroIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->INTSTS = BPWM_INTSTS_ZIF0_Msk;
}
/**
* @brief Get zero interrupt of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return zero interrupt flag of specified channel
* @retval 0 zero interrupt did not occur
* @retval 1 zero interrupt occurred
* @details This function is used to get zero interrupt of selected channel.
* @note All channels share channel 0's setting.
*/
uint32_t BPWM_GetZeroIntFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return (((bpwm)->INTSTS & BPWM_INTSTS_ZIF0_Msk) ? 1UL : 0UL);
}
/**
* @brief Enable load mode of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32LoadMode BPWM counter loading mode.
* - \ref BPWM_LOAD_MODE_IMMEDIATE
* - \ref BPWM_LOAD_MODE_CENTER
* @return None
* @details This function is used to enable load mode of selected channel.
*/
void BPWM_EnableLoadMode(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32LoadMode)
{
(bpwm)->CTL0 |= (u32LoadMode << u32ChannelNum);
}
/**
* @brief Disable load mode of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. Valid values are between 0~5
* @param[in] u32LoadMode BPWM counter loading mode.
* - \ref BPWM_LOAD_MODE_IMMEDIATE
* - \ref BPWM_LOAD_MODE_CENTER
* @return None
* @details This function is used to disable load mode of selected channel.
*/
void BPWM_DisableLoadMode(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32LoadMode)
{
(bpwm)->CTL0 &= ~(u32LoadMode << u32ChannelNum);
}
/**
* @brief Set BPWM clock source
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @param[in] u32ClkSrcSel BPWM external clock source.
* - \ref BPWM_CLKSRC_BPWM_CLK
* - \ref BPWM_CLKSRC_TIMER0
* - \ref BPWM_CLKSRC_TIMER1
* - \ref BPWM_CLKSRC_TIMER2
* - \ref BPWM_CLKSRC_TIMER3
* @return None
* @details This function is used to set BPWM clock source.
* @note All channels share channel 0's setting.
*/
void BPWM_SetClockSource(BPWM_T *bpwm, uint32_t u32ChannelNum, uint32_t u32ClkSrcSel)
{
(bpwm)->CLKSRC = (u32ClkSrcSel);
}
/**
* @brief Get the time-base counter reached its maximum value flag of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return Count to max interrupt flag of specified channel
* @retval 0 Count to max interrupt did not occur
* @retval 1 Count to max interrupt occurred
* @details This function is used to get the time-base counter reached its maximum value flag of selected channel.
* @note All channels share channel 0's setting.
*/
uint32_t BPWM_GetWrapAroundFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
return (((bpwm)->STATUS & BPWM_STATUS_CNTMAX0_Msk) ? 1UL : 0UL);
}
/**
* @brief Clear the time-base counter reached its maximum value flag of selected channel
* @param[in] bpwm The pointer of the specified BPWM module
* - BPWM0 : BPWM Group 0
* - BPWM1 : BPWM Group 1
* @param[in] u32ChannelNum BPWM channel number. This parameter is not used.
* @return None
* @details This function is used to clear the time-base counter reached its maximum value flag of selected channel.
* @note All channels share channel 0's setting.
*/
void BPWM_ClearWrapAroundFlag(BPWM_T *bpwm, uint32_t u32ChannelNum)
{
(bpwm)->STATUS = BPWM_STATUS_CNTMAX0_Msk;
}
/*@}*/ /* end of group BPWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group BPWM_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,97 @@
/**************************************************************************//**
* @file crc.c
* @version V0.10
* @brief M251 CRC driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.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 operation polynomial mode. Valid values are:
* - \ref CRC_CCITT
* - \ref CRC_8
* - \ref CRC_16
* - \ref CRC_32
* @param[in] u32Attribute CRC operation data attribute. Valid values are combined with:
* - \ref CRC_CHECKSUM_COM
* - \ref CRC_CHECKSUM_RVS
* - \ref CRC_WDATA_COM
* - \ref CRC_WDATA_RVS
* @param[in] u32Seed Seed value.
* @param[in] u32DataLen CPU Write Data Length. Valid values are:
* - \ref CRC_CPU_WDATA_8
* - \ref CRC_CPU_WDATA_16
* - \ref CRC_CPU_WDATA_32
*
* @return None
*
* @details This function will enable the CRC controller by specify CRC operation mode, attribute, initial seed and write data length. \n
* After that, user can start to perform CRC calculate by calling CRC_WRITE_DATA macro or CRC_DAT register directly.
*/
void CRC_Open(uint32_t u32Mode, uint32_t u32Attribute, uint32_t u32Seed, uint32_t u32DataLen)
{
CRC->SEED = u32Seed;
CRC->CTL = u32Mode | u32Attribute | u32DataLen | CRC_CTL_CRCEN_Msk;
/* Setting CHKSINIT bit will reload the initial seed value(CRC_SEED register) to CRC controller */
CRC->CTL |= CRC_CTL_CHKSINIT_Msk;
}
/**
* @brief Get CRC Checksum
*
* @param[in] None
*
* @return Checksum Result
*
* @details This function gets the CRC checksum result by current CRC polynomial mode.
*/
uint32_t CRC_GetChecksum(void)
{
uint32_t ret;
switch (CRC->CTL & CRC_CTL_CRCMODE_Msk)
{
case CRC_CCITT:
case CRC_16:
ret = (CRC->CHECKSUM & 0xFFFFU);
break;
case CRC_32:
ret = (CRC->CHECKSUM);
break;
case CRC_8:
ret = (CRC->CHECKSUM & 0xFFU);
break;
default:
ret = 0U;
break;
}
return ret;
}
/*@}*/ /* end of group CRC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CRC_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,229 @@
/**************************************************************************//**
* @file crypto.c
* @version V1.10
* @brief Cryptographic Accelerator driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include "NuMicro.h"
#define ENABLE_DEBUG 0
#if ENABLE_DEBUG
#define CRPT_DBGMSG printf
#else
#define CRPT_DBGMSG(...) do { } while (0) /* disable debug */
#endif
#if defined(__ICCARM__)
#pragma diag_suppress=Pm073, Pm143 /* Misra C rule 14.7 */
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup CRYPTO_Driver CRYPTO Driver
@{
*/
/** @addtogroup CRYPTO_EXPORTED_FUNCTIONS CRYPTO Exported Functions
@{
*/
/* // @cond HIDDEN_SYMBOLS */
static uint32_t g_AES_au32CTL[1];
/* // @endcond HIDDEN_SYMBOLS */
/**
* @brief Open PRNG function
* @param[in] crpt Reference to Crypto module.
* @param[in] u32KeySize is PRNG key size, including:
* - \ref PRNG_KEY_SIZE_64
* - \ref PRNG_KEY_SIZE_128
* - \ref PRNG_KEY_SIZE_192
* - \ref PRNG_KEY_SIZE_256
* @param[in] u32SeedReload is PRNG seed reload or not, including:
* - \ref PRNG_SEED_CONT
* - \ref PRNG_SEED_RELOAD
* @param[in] u32Seed The new seed. Only valid when u32SeedReload is PRNG_SEED_RELOAD.
* @return None
*/
void PRNG_Open(CRPT_T *crpt, uint32_t u32KeySize, uint32_t u32SeedReload, uint32_t u32Seed)
{
if (u32SeedReload)
{
crpt->PRNG_SEED = u32Seed;
}
crpt->PRNG_CTL = (u32KeySize << CRPT_PRNG_CTL_KEYSZ_Pos) |
(u32SeedReload << CRPT_PRNG_CTL_SEEDRLD_Pos);
}
/**
* @brief Start to generate one PRNG key.
* @param[in] crpt Reference to Crypto module.
* @return None
*/
void PRNG_Start(CRPT_T *crpt)
{
crpt->PRNG_CTL |= CRPT_PRNG_CTL_START_Msk;
}
/**
* @brief Read the PRNG key.
* @param[in] crpt Reference to Crypto module.
* @param[out] au32RandKey The key buffer to store newly generated PRNG key.
* @return None
*/
void PRNG_Read(CRPT_T *crpt, uint32_t au32RandKey[])
{
uint32_t u32Idx, u32Wcnt;
u32Wcnt = (((crpt->PRNG_CTL & CRPT_PRNG_CTL_KEYSZ_Msk) >> CRPT_PRNG_CTL_KEYSZ_Pos) + 1U) * 2U;
for (u32Idx = 0U; u32Idx < u32Wcnt; u32Idx++)
{
au32RandKey[u32Idx] = crpt->PRNG_KEY[u32Idx];
}
crpt->PRNG_CTL &= ~CRPT_PRNG_CTL_SEEDRLD_Msk;
}
/**
* @brief Open AES encrypt/decrypt function.
* @param[in] crpt Reference to Crypto module.
* @param[in] u32Channel AES channel. Must be 0.
* @param[in] u32EncDec 1: AES encode; 0: AES decode
* @param[in] u32OpMode AES operation mode, including:
* - \ref AES_MODE_ECB
* - \ref AES_MODE_CBC
* - \ref AES_MODE_CFB
* - \ref AES_MODE_OFB
* - \ref AES_MODE_CTR
* - \ref AES_MODE_CBC_CS1
* - \ref AES_MODE_CBC_CS2
* - \ref AES_MODE_CBC_CS3
* @param[in] u32KeySize is AES key size, including:
* - \ref AES_KEY_SIZE_128
* - \ref AES_KEY_SIZE_192
* - \ref AES_KEY_SIZE_256
* @param[in] u32SwapType is AES input/output data swap control, including:
* - \ref AES_NO_SWAP
* - \ref AES_OUT_SWAP
* - \ref AES_IN_SWAP
* - \ref AES_IN_OUT_SWAP
* @return None
*/
void AES_Open(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32EncDec,
uint32_t u32OpMode, uint32_t u32KeySize, uint32_t u32SwapType)
{
crpt->AES_CTL = (u32EncDec << CRPT_AES_CTL_ENCRYPTO_Pos) |
(u32OpMode << CRPT_AES_CTL_OPMODE_Pos) |
(u32KeySize << CRPT_AES_CTL_KEYSZ_Pos) |
(u32SwapType << CRPT_AES_CTL_OUTSWAP_Pos);
g_AES_au32CTL[u32Channel] = crpt->AES_CTL;
}
/**
* @brief Start AES encrypt/decrypt
* @param[in] crpt Reference to Crypto module.
* @param[in] u32Channel AES channel. Must be 0.
* @param[in] u32DMAMode AES DMA control, including:
* - \ref CRYPTO_DMA_FIRST Do first encrypt/decrypt in DMA cascade.
* - \ref CRYPTO_DMA_ONE_SHOT Do one shot encrypt/decrypt with DMA.
* - \ref CRYPTO_DMA_CONTINUE Do continuous encrypt/decrypt in DMA cascade.
* - \ref CRYPTO_DMA_LAST Do last encrypt/decrypt in DMA cascade.
* @return None
*/
void AES_Start(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32DMAMode)
{
crpt->AES_CTL = g_AES_au32CTL[u32Channel];
crpt->AES_CTL |= CRPT_AES_CTL_START_Msk | (u32DMAMode << CRPT_AES_CTL_DMALAST_Pos);
}
/**
* @brief Set AES keys
* @param[in] crpt Reference to Crypto module.
* @param[in] u32Channel AES channel. Must be 0.
* @param[in] au32Keys An word array contains AES keys.
* @param[in] u32KeySize is AES key size, including:
* - \ref AES_KEY_SIZE_128
* - \ref AES_KEY_SIZE_192
* - \ref AES_KEY_SIZE_256
* @return None
*/
void AES_SetKey(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32Keys[], uint32_t u32KeySize)
{
uint32_t u32Idx, u32Wcnt, u32KeyRegAddr;
u32KeyRegAddr = (uint32_t)&crpt->AES_KEY[0] + (u32Channel * 0x3CUL);
u32Wcnt = 4UL + u32KeySize * 2UL;
for (u32Idx = 0U; u32Idx < u32Wcnt; u32Idx++)
{
outpw(u32KeyRegAddr, au32Keys[u32Idx]);
u32KeyRegAddr += 4UL;
}
}
/**
* @brief Set AES initial vectors
* @param[in] crpt Reference to Crypto module.
* @param[in] u32Channel AES channel. Must be 0.
* @param[in] au32IV A four entry word array contains AES initial vectors.
* @return None
*/
void AES_SetInitVect(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32IV[])
{
uint32_t u32Idx, u32KeyRegAddr;
u32KeyRegAddr = (uint32_t)&crpt->AES_IV[0] + (u32Channel * 0x3CUL);
for (u32Idx = 0U; u32Idx < 4U; u32Idx++)
{
outpw(u32KeyRegAddr, au32IV[u32Idx]);
u32KeyRegAddr += 4UL;
}
}
/**
* @brief Set AES DMA transfer configuration.
* @param[in] crpt Reference to Crypto module.
* @param[in] u32Channel AES channel. Must be 0.
* @param[in] u32SrcAddr AES DMA source address
* @param[in] u32DstAddr AES DMA destination address
* @param[in] u32TransCnt AES DMA transfer byte count
* @return None
*/
void AES_SetDMATransfer(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32SrcAddr,
uint32_t u32DstAddr, uint32_t u32TransCnt)
{
uint32_t u32RegAddr;
u32RegAddr = (uint32_t)&crpt->AES_SADDR + (u32Channel * 0x3CUL);
outpw(u32RegAddr, u32SrcAddr);
u32RegAddr = (uint32_t)&crpt->AES_DADDR + (u32Channel * 0x3CUL);
outpw(u32RegAddr, u32DstAddr);
u32RegAddr = (uint32_t)&crpt->AES_CNT + (u32Channel * 0x3CUL);
outpw(u32RegAddr, u32TransCnt);
}
/*@}*/ /* end of group CRYPTO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CRYPTO_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,87 @@
/**************************************************************************//**
* @file dac.c
* @version V0.10
* @brief M251 series DAC driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup DAC_Driver DAC Driver
@{
*/
/** @addtogroup DAC_EXPORTED_FUNCTIONS DAC Exported Functions
@{
*/
/**
* @brief This function make DAC module be ready to convert.
* @param[in] dac The pointer of the specified DAC module.
* @param[in] u32Ch Not used in M251 DAC.
* @param[in] u32TrgSrc Decides the trigger source. Valid values are:
* - \ref DAC_WRITE_DAT_TRIGGER :Write DAC_DAT trigger
* - \ref DAC_SOFTWARE_TRIGGER :Software trigger
* - \ref DAC_LOW_LEVEL_TRIGGER :STDAC pin low level trigger
* - \ref DAC_HIGH_LEVEL_TRIGGER :STDAC pin high level trigger
* - \ref DAC_FALLING_EDGE_TRIGGER :STDAC pin falling edge trigger
* - \ref DAC_RISING_EDGE_TRIGGER :STDAC pin rising edge trigger
* - \ref DAC_TIMER0_TRIGGER :Timer 0 trigger
* - \ref DAC_TIMER1_TRIGGER :Timer 1 trigger
* - \ref DAC_TIMER2_TRIGGER :Timer 2 trigger
* - \ref DAC_TIMER3_TRIGGER :Timer 3 trigger
* @return None
* @details The DAC conversion can be started by writing DAC_DAT, software trigger or hardware trigger.
* When TRGEN (DAC_CTL[4]) is 0, the data conversion is started by writing DAC_DAT register.
* When TRGEN (DAC_CTL[4]) is 1, the data conversion is started by SWTRG (DAC_SWTRG[0]) is set to 1,
* external STDAC pin, or timer event.
*/
void DAC_Open(DAC_T *dac,
uint32_t u32Ch,
uint32_t u32TrgSrc)
{
dac->CTL &= ~(DAC_CTL_ETRGSEL_Msk | DAC_CTL_TRGSEL_Msk | DAC_CTL_TRGEN_Msk);
dac->CTL |= (u32TrgSrc | DAC_CTL_DACEN_Msk);
}
/**
* @brief Disable DAC analog power.
* @param[in] dac The pointer of the specified DAC module.
* @param[in] u32Ch Not used in M251 DAC.
* @return None
* @details Disable DAC analog power for saving power consumption.
*/
void DAC_Close(DAC_T *dac, uint32_t u32Ch)
{
dac->CTL &= (~DAC_CTL_DACEN_Msk);
}
/**
* @brief Set delay time for DAC to become stable.
* @param[in] dac The pointer of the specified DAC module.
* @param[in] u32Delay Decides the DAC conversion settling time, the range is from 0~(1023/PCLK1*1000000) micro seconds.
* @return Real DAC conversion settling time (micro second).
* @details For example, DAC controller clock speed is 50MHz and DAC conversion setting time is 1 us, SETTLET (DAC_TCTL[9:0]) value must be greater than 0x32.
* @note User needs to write appropriate value to meet DAC conversion settling time base on PCLK (APB clock) speed.
*/
uint32_t DAC_SetDelayTime(DAC_T *dac, uint32_t u32Delay)
{
dac->TCTL = ((CLK_GetPCLK1Freq() * u32Delay / 1000000UL) & 0x3FFUL);
return ((dac->TCTL) * 1000000UL / CLK_GetPCLK1Freq());
}
/*@}*/ /* end of group DAC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group DAC_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,152 @@
/**************************************************************************//**
* @file eadc.c
* @version V0.10
* @brief M251 series EADC driver source file
*
* @note
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup EADC_Driver EADC Driver
@{
*/
/** @addtogroup EADC_EXPORTED_FUNCTIONS EADC Exported Functions
@{
*/
/**
* @brief This function make EADC_module be ready to convert.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32InputMode Decides the input mode. M251 don't support this feature.
* - \ref NULL :Always NULL.
* @return None
* @details This function is used to set analog input mode and enable A/D Converter.
* Before starting A/D conversion function, ADCEN bit (EADC_CTL[0]) should be set to 1.
* @note
*/
void EADC_Open(EADC_T *eadc, uint32_t u32InputMode)
{
eadc->CTL |= EADC_CTL_ADCEN_Msk;
/* Wait for EADC start up completely and ready for conversion */
while ((eadc->PWRCTL & EADC_PWRCTL_READY_Msk) == 0);
}
/**
* @brief Disable EADC_module.
* @param[in] eadc The pointer of the specified EADC module.
* @return None
* @details Clear ADCEN bit (EADC_CTL[0]) to disable A/D converter analog circuit power consumption.
*/
void EADC_Close(EADC_T *eadc)
{
eadc->CTL &= (~EADC_CTL_ADCEN_Msk);
}
/**
* @brief Configure the sample control logic module.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
* @param[in] u32TriggerSrc Decides the trigger source. Valid values are:
* - \ref EADC_SOFTWARE_TRIGGER : Disable trigger
* - \ref EADC_FALLING_EDGE_TRIGGER : STADC pin falling edge trigger
* - \ref EADC_RISING_EDGE_TRIGGER : STADC pin rising edge trigger
* - \ref EADC_FALLING_RISING_EDGE_TRIGGER : STADC pin both falling and rising edge trigger
* - \ref EADC_ADINT0_TRIGGER : EADC ADINT0 interrupt EOC pulse trigger
* - \ref EADC_ADINT1_TRIGGER : EADC ADINT1 interrupt EOC pulse trigger
* - \ref EADC_TIMER0_TRIGGER : Timer0 overflow pulse trigger
* - \ref EADC_TIMER1_TRIGGER : Timer1 overflow pulse trigger
* - \ref EADC_TIMER2_TRIGGER : Timer2 overflow pulse trigger
* - \ref EADC_TIMER3_TRIGGER : Timer3 overflow pulse trigger
* - \ref EADC_PWM0TG0_TRIGGER : PWM0TG0 trigger
* - \ref EADC_PWM0TG1_TRIGGER : PWM0TG1 trigger
* - \ref EADC_PWM0TG2_TRIGGER : PWM0TG2 trigger
* - \ref EADC_PWM0TG3_TRIGGER : PWM0TG3 trigger
* - \ref EADC_PWM0TG4_TRIGGER : PWM0TG4 trigger
* - \ref EADC_PWM0TG5_TRIGGER : PWM0TG5 trigger
* - \ref EADC_PWM1TG0_TRIGGER : PWM1TG0 trigger
* - \ref EADC_PWM1TG1_TRIGGER : PWM1TG1 trigger
* - \ref EADC_PWM1TG2_TRIGGER : PWM1TG2 trigger
* - \ref EADC_PWM1TG3_TRIGGER : PWM1TG3 trigger
* - \ref EADC_PWM1TG4_TRIGGER : PWM1TG4 trigger
* - \ref EADC_PWM1TG5_TRIGGER : PWM1TG5 trigger
* - \ref EADC_BPWM0TG_TRIGGER : BPWM0TG trigger
* @param[in] u32Channel Specifies the sample module channel, valid value are from 0 to 15.
* @return None
* @details Each of EADC control logic modules 0~15 which is configurable for EADC converter channel EADC_CH0~15 and trigger source.
* Sample module 16~18 is fixed for EADC channel 16, 17, 18 input sources as band-gap voltage, temperature sensor, and battery power (VBAT).
*/
void EADC_ConfigSampleModule(EADC_T *eadc, \
uint32_t u32ModuleNum, \
uint32_t u32TriggerSrc, \
uint32_t u32Channel)
{
((eadc->SCTL[u32ModuleNum])) &= (~(EADC_SCTL_EXTFEN_Msk | EADC_SCTL_EXTREN_Msk | EADC_SCTL_TRGSEL_Msk | EADC_SCTL_CHSEL_Msk));
((eadc->SCTL[u32ModuleNum])) |= (u32TriggerSrc | u32Channel);
}
/**
* @brief Set trigger delay time.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid values are from 0 to 15.
* @param[in] u32TriggerDelayTime Decides the trigger delay time, valid range are between 0~255.
* @param[in] u32DelayClockDivider Decides the trigger delay clock divider. Valid values are:
* - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_1 : Trigger delay clock frequency is EADC_CLK/1
* - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_2 : Trigger delay clock frequency is EADC_CLK/2
* - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_4 : Trigger delay clock frequency is EADC_CLK/4
* - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_16 : Trigger delay clock frequency is EADC_CLK/16
* @return None
* @details User can configure the trigger delay time by setting TRGDLYCNT (EADC_SCTLn[15:8], n=0~15) and TRGDLYDIV (EADC_SCTLn[7:6], n=0~15).
* Trigger delay time = (u32TriggerDelayTime) x Trigger delay clock period.
*/
void EADC_SetTriggerDelayTime(EADC_T *eadc, \
uint32_t u32ModuleNum, \
uint32_t u32TriggerDelayTime, \
uint32_t u32DelayClockDivider)
{
((eadc->SCTL[u32ModuleNum])) &= (~(EADC_SCTL_TRGDLYDIV_Msk | EADC_SCTL_TRGDLYCNT_Msk));
((eadc->SCTL[u32ModuleNum])) |= ((u32TriggerDelayTime << EADC_SCTL_TRGDLYCNT_Pos) | u32DelayClockDivider);
}
/**
* @brief Set EADC extend sample time.
* @param[in] eadc The pointer of the specified EADC module.
* @param[in] u32ModuleNum Decides the sample module number, valid values are from 0 to 18.
* @param[in] u32ExtendSampleTime Decides the extend sampling time, the range is from 0~255 EADC clock. Valid value are from 0 to 255.
* @return None
* @details When A/D converting at high conversion rate, the sampling time of analog input voltage may not enough
* if the analog channel has heavy loading to cause fully charge time is longer.
* User can extend A/D sampling time after trigger source is coming to get enough sampling time.
*/
void EADC_SetExtendSampleTime(EADC_T *eadc, uint32_t u32ModuleNum, uint32_t u32ExtendSampleTime)
{
if (u32ModuleNum < 16)
{
((eadc->SCTL[u32ModuleNum])) &= (~EADC_SCTL_EXTSMPT_Msk);
((eadc->SCTL[u32ModuleNum])) |= (u32ExtendSampleTime << EADC_SCTL_EXTSMPT_Pos);
}
else
{
((eadc->SCTL0[u32ModuleNum - 16])) &= (~EADC_SCTL0_EXTSMPT_Msk);
((eadc->SCTL0[u32ModuleNum - 16])) |= (u32ExtendSampleTime << EADC_SCTL0_EXTSMPT_Pos);
}
}
/*@}*/ /* end of group EADC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group EADC_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,194 @@
/**************************************************************************//**
* @file ebi.c
* @version V0.10
* @brief M251 series EBI driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
****************************************************************************/
#include "NuMicro.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup EBI_Driver EBI Driver
@{
*/
/** @addtogroup EBI_EXPORTED_FUNCTIONS EBI Exported Functions
@{
*/
/**
* @brief Initialize EBI for specify Bank
*
* @param[in] u32Bank Bank number for EBI. Valid values are:
* - \ref EBI_BANK0
* - \ref EBI_BANK1
* - \ref EBI_BANK2
* @param[in] u32DataWidth Data bus width. Valid values are:
* - \ref EBI_BUSWIDTH_8BIT
* - \ref EBI_BUSWIDTH_16BIT
* @param[in] u32TimingClass Default timing configuration. Valid values are:
* - \ref EBI_TIMING_FASTEST
* - \ref EBI_TIMING_VERYFAST
* - \ref EBI_TIMING_FAST
* - \ref EBI_TIMING_NORMAL
* - \ref EBI_TIMING_SLOW
* - \ref EBI_TIMING_VERYSLOW
* - \ref EBI_TIMING_SLOWEST
* @param[in] u32BusMode Set EBI bus operate mode. Valid values are:
* - \ref EBI_OPMODE_NORMAL
* - \ref EBI_OPMODE_CACCESS
* @param[in] u32CSActiveLevel CS is active High/Low. Valid values are:
* - \ref EBI_CS_ACTIVE_HIGH
* - \ref EBI_CS_ACTIVE_LOW
*
* @return None
*
* @details This function is used to open specify EBI bank with different bus width, timing setting and \n
* active level of CS pin to access EBI device.
* @note Write Buffer Enable(WBUFEN) and Extend Time Of ALE(TALE) are only available in EBI bank0 control register.
*/
void EBI_Open(uint32_t u32Bank, uint32_t u32DataWidth, uint32_t u32TimingClass, uint32_t u32BusMode, uint32_t u32CSActiveLevel)
{
uint32_t u32Index0 = (uint32_t)&EBI->CTL0 + (uint32_t)u32Bank * 0x10U;
uint32_t u32Index1 = (uint32_t)&EBI->TCTL0 + (uint32_t)u32Bank * 0x10U;
volatile uint32_t *pu32EBICTL = (uint32_t *)(u32Index0);
volatile uint32_t *pu32EBITCTL = (uint32_t *)(u32Index1);
if (u32DataWidth == EBI_BUSWIDTH_8BIT)
{
*pu32EBICTL &= ~EBI_CTL_DW16_Msk;
}
else
{
*pu32EBICTL |= EBI_CTL_DW16_Msk;
}
*pu32EBICTL |= u32BusMode;
switch (u32TimingClass)
{
case EBI_TIMING_FASTEST:
*pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
(EBI_MCLKDIV_1 << EBI_CTL_MCLKDIV_Pos) |
(u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk;
*pu32EBITCTL = 0x0U;
break;
case EBI_TIMING_VERYFAST:
*pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
(EBI_MCLKDIV_1 << EBI_CTL_MCLKDIV_Pos) |
(u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk |
(0x3U << EBI_CTL_TALE_Pos) ;
*pu32EBITCTL = 0x03003318U;
break;
case EBI_TIMING_FAST:
*pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
(EBI_MCLKDIV_2 << EBI_CTL_MCLKDIV_Pos) |
(u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk;
*pu32EBITCTL = 0x0U;
break;
case EBI_TIMING_NORMAL:
*pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
(EBI_MCLKDIV_2 << EBI_CTL_MCLKDIV_Pos) |
(u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk |
(0x3U << EBI_CTL_TALE_Pos) ;
*pu32EBITCTL = 0x03003318U;
break;
case EBI_TIMING_SLOW:
*pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
(EBI_MCLKDIV_2 << EBI_CTL_MCLKDIV_Pos) |
(u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk |
(0x7U << EBI_CTL_TALE_Pos) ;
*pu32EBITCTL = 0x07007738U;
break;
case EBI_TIMING_VERYSLOW:
*pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
(EBI_MCLKDIV_4 << EBI_CTL_MCLKDIV_Pos) |
(u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk |
(0x7U << EBI_CTL_TALE_Pos) ;
*pu32EBITCTL = 0x07007738U;
break;
case EBI_TIMING_SLOWEST:
*pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
(EBI_MCLKDIV_8 << EBI_CTL_MCLKDIV_Pos) |
(u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk |
(0x7U << EBI_CTL_TALE_Pos) ;
*pu32EBITCTL = 0x07007738U;
break;
default:
*pu32EBICTL &= ~EBI_CTL_EN_Msk;
break;
}
}
/**
* @brief Disable EBI on specify Bank
*
* @param[in] u32Bank Bank number for EBI. Valid values are:
* - \ref EBI_BANK0
* - \ref EBI_BANK1
* - \ref EBI_BANK2
*
* @return None
*
* @details This function is used to close specify EBI function.
*/
void EBI_Close(uint32_t u32Bank)
{
uint32_t u32Index = (uint32_t)&EBI->CTL0 + u32Bank * 0x10U;
volatile uint32_t *pu32EBICTL = (uint32_t *)(u32Index);
*pu32EBICTL &= ~EBI_CTL_EN_Msk;
}
/**
* @brief Set EBI Bus Timing for specify Bank
*
* @param[in] u32Bank Bank number for EBI. Valid values are:
* - \ref EBI_BANK0
* - \ref EBI_BANK1
* - \ref EBI_BANK2
* @param[in] u32TimingConfig Configure EBI timing settings, includes TACC, TAHD, W2X and R2R setting.
* @param[in] u32MclkDiv Divider for MCLK. Valid values are:
* - \ref EBI_MCLKDIV_1
* - \ref EBI_MCLKDIV_2
* - \ref EBI_MCLKDIV_4
* - \ref EBI_MCLKDIV_8
* - \ref EBI_MCLKDIV_16
* - \ref EBI_MCLKDIV_32
* - \ref EBI_MCLKDIV_64
* - \ref EBI_MCLKDIV_128
*
* @return None
*
* @details This function is used to configure specify EBI bus timing for access EBI device.
*/
void EBI_SetBusTiming(uint32_t u32Bank, uint32_t u32TimingConfig, uint32_t u32MclkDiv)
{
uint32_t u32Index0 = (uint32_t)&EBI->CTL0 + (uint32_t)u32Bank * 0x10U;
uint32_t u32Index1 = (uint32_t)&EBI->TCTL0 + (uint32_t)u32Bank * 0x10U;
volatile uint32_t *pu32EBICTL = (uint32_t *)(u32Index0);
volatile uint32_t *pu32EBITCTL = (uint32_t *)(u32Index1);
*pu32EBICTL = (*pu32EBICTL & ~EBI_CTL_MCLKDIV_Msk) | (u32MclkDiv << EBI_CTL_MCLKDIV_Pos);
*pu32EBITCTL = u32TimingConfig;
}
/*@}*/ /* end of group EBI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group EBI_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,520 @@
/**************************************************************************//**
* @file fmc.c
* @version V3.00
* @brief M251 Series Flash Memory Controller(FMC) driver source file
*
* @note
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "NuMicro.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->ISPCTL |= FMC_ISPCTL_BS_Msk; /* Boot from LDROM */
}
else
{
FMC->ISPCTL &= ~FMC_ISPCTL_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->ISPCTL &= ~FMC_ISPCTL_ISPEN_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)
{
int32_t ret = 0;
if (FMC->ISPCTL & FMC_ISPCTL_BS_Msk)
{
ret = 1;
}
return ret;
}
/**
* @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->ISPCTL |= FMC_ISPCTL_ISPEN_Msk;
}
/**
* @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)
{
uint32_t i;
for (i = 0u; i < u32Count; i++)
{
u32Config[i] = FMC_Read(FMC_CONFIG_BASE + i * 4u);
}
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 ret = 0;
uint32_t i;
for (i = 0u; i < u32Count; i++)
{
FMC_Write(FMC_CONFIG_BASE + i * 4u, u32Config[i]);
if (FMC_Read(FMC_CONFIG_BASE + i * 4u) != u32Config[i])
{
ret = 1;
}
}
return ret;
}
/**
* @brief Run CRC32 checksum calculation and get result.
*
* @param[in] u32addr Starting flash address. It must be a page aligned address.
* @param[in] u32count Byte count of flash to be calculated. It must be multiple of 512 bytes.
*
* @return Success or not.
* @retval 0 Success.
* @retval 0xFFFFFFFF Invalid parameter.
*
* details Run ISP checksum command to calculate specify area
*/
uint32_t FMC_GetChkSum(uint32_t u32addr, uint32_t u32count)
{
uint32_t ret;
if ((u32addr % 512UL) || (u32count % 512UL))
{
ret = 0xFFFFFFFF;
}
else
{
FMC->ISPCMD = FMC_ISPCMD_CAL_CHECKSUM;
FMC->ISPADDR = u32addr;
FMC->ISPDAT = u32count;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
FMC->ISPCMD = FMC_ISPCMD_CHECKSUM;
FMC->ISPADDR = u32addr;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
ret = FMC->ISPDAT;
}
return ret;
}
/**
* @brief Run flash all one verification and get result.
*
* @param[in] u32addr Starting flash address. It must be a page aligned address.
* @param[in] u32count Byte count of flash to be calculated. It must be multiple of 512 bytes.
*
* @retval READ_ALLONE_YES The contents of verified flash area are 0xFFFFFFFF.
* @retval READ_ALLONE_NOT Some contents of verified flash area are not 0xFFFFFFFF.
* @retval READ_ALLONE_CMD_FAIL Unexpected error occurred.
*
* @details Run ISP check all one command to check specify area is all one or not.
*/
uint32_t FMC_CheckAllOne(uint32_t u32addr, uint32_t u32count)
{
uint32_t ret = READ_ALLONE_CMD_FAIL;
FMC->ISPSTS = 0x80UL; /* clear check all one bit */
FMC->ISPCMD = FMC_ISPCMD_RUN_ALL1;
FMC->ISPADDR = u32addr;
FMC->ISPDAT = u32count;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
do
{
FMC->ISPCMD = FMC_ISPCMD_READ_ALL1;
FMC->ISPADDR = u32addr;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk) { }
}
while (FMC->ISPDAT == 0UL);
if (FMC->ISPDAT == READ_ALLONE_YES)
{
ret = FMC->ISPDAT;
}
if (FMC->ISPDAT == READ_ALLONE_NOT)
{
ret = FMC->ISPDAT;
}
return ret;
}
/**
* @brief Check the XOM is actived or not.
*
* @param[in] xom_num The XOM number. The value will always be 0 in M251 series.
*
* @retval 1 XOM is actived.
* @retval 0 XOM is not actived.
* @retval -2 Invalid XOM number.
*
* @details To get specify XOM active status
*/
int32_t FMC_Is_XOM_Actived(uint32_t xom_num)
{
uint32_t u32act;
int32_t ret = 0;
if (xom_num >= 1UL)
{
ret = -2;
}
if (ret >= 0)
{
u32act = (((FMC->XOMSTS) & 0xful) & (1ul << xom_num)) >> xom_num;
ret = (int32_t)u32act;
}
return ret;
}
/**
* @brief Config XOM Region
* @param[in] xom_num The XOM number. The value will always be 0 in M251 series.
* @param[in] xom_base The XOM region base address.
* @param[in] xom_page The XOM page number of region size.
*
* @retval 0 Success
* @retval 1 XOM is has already actived.
* @retval -1 Program failed.
* @retval -2 Invalid XOM number.
*
* @details Program XOM base address and XOM size(page)
*/
int32_t FMC_Config_XOM(uint32_t xom_num, uint32_t xom_base, uint8_t xom_page)
{
int32_t ret = 0;
if (xom_num >= 1UL)
{
ret = -2;
}
if (ret == 0)
{
ret = FMC_Is_XOM_Actived(xom_num);
}
if (ret == 0)
{
FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
FMC->ISPADDR = FMC_XOM_BASE + (xom_num * 0x10u);
FMC->ISPDAT = xom_base;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) {}
if (FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
{
FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
ret = -1;
}
}
if (ret == 0)
{
FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
FMC->ISPADDR = FMC_XOM_BASE + (xom_num * 0x10u + 0x04u);
FMC->ISPDAT = xom_page;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) {}
if (FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
{
FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
ret = -1;
}
}
if (ret == 0)
{
FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
FMC->ISPADDR = FMC_XOM_BASE + (xom_num * 0x10u + 0x08u);
FMC->ISPDAT = 0u;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) {}
if (FMC->ISPSTS & FMC_ISPSTS_ISPFF_Msk)
{
FMC->ISPSTS |= FMC_ISPSTS_ISPFF_Msk;
ret = -1;
}
}
return ret;
}
/**
* @brief Execute Erase XOM Region
*
* @param[in] xom_num The XOM number. The value will always be 0 in M251 series.
*
* @return XOM erase success or not.
* @retval 0 Success
* @retval -1 Erase failed
* @retval -2 Invalid XOM number.
*
* @details Execute FMC_ISPCMD_PAGE_ERASE command to erase XOM.
*/
int32_t FMC_Erase_XOM(uint32_t xom_num)
{
uint32_t u32Addr;
int32_t i32Active, err = 0;
if (xom_num >= 1UL)
{
err = -2;
}
i32Active = FMC_Is_XOM_Actived(xom_num);
if (i32Active)
{
u32Addr = FMC->XOMR0STS0;
FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE;
FMC->ISPADDR = u32Addr;
FMC->ISPDAT = 0x55aa03u;
FMC->ISPTRG = 0x1u;
#if ISBEN
__ISB();
#endif
while (FMC->ISPTRG) {}
/* Check ISPFF flag to know whether erase OK or fail. */
if (FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk)
{
FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk;
err = -1;
}
}
else
{
err = -1;
}
return err;
}
/**
* @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
*
*/
int32_t FMC_Erase(uint32_t u32Addr)
{
int32_t ret = 0;
FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE;
FMC->ISPADDR = u32Addr;
FMC->ISPTRG = 0x1u;
#if ISBEN
__ISB();
#endif
while (FMC->ISPTRG) {}
/* Check ISPFF flag to know whether erase OK or fail. */
if (FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk)
{
FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk;
ret = -1;
}
return ret;
}
/**
* @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.
*
*/
uint32_t FMC_Read(uint32_t u32Addr)
{
FMC->ISPCMD = FMC_ISPCMD_READ;
FMC->ISPADDR = u32Addr;
FMC->ISPDAT = 0u;
FMC->ISPTRG = 0x1u;
#if ISBEN
__ISB();
#endif
while (FMC->ISPTRG) {}
return FMC->ISPDAT;
}
/**
* @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.
*
*/
void FMC_Write(uint32_t u32Addr, uint32_t u32Data)
{
FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
FMC->ISPADDR = u32Addr;
FMC->ISPDAT = u32Data;
FMC->ISPTRG = 0x1u;
#if ISBEN
__ISB();
#endif
while (FMC->ISPTRG) {}
}
/*@}*/ /* end of group FMC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group FMC_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,163 @@
/**************************************************************************//**
* @file gpio.c
* @version V0.10
* @brief M251 GPIO driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
* @param[in] u32Mode Operation mode. It could be \n
* GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_OPEN_DRAIN, GPIO_MODE_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 = 0ul; i < GPIO_PIN_MAX; i++)
{
if (u32PinMask & (1ul << i))
{
port->MODE = (port->MODE & ~(0x3ul << (i << 1ul))) | (u32Mode << (i << 1ul));
}
}
}
/**
* @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 BIT0 ~ BIT15 for PA, PB, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
* @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->INTTYPE |= (((u32IntAttribs >> 24UL) & 0xFFUL) << u32Pin);
port->INTEN |= ((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 BIT0 ~ BIT15 for PA, PB, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
void GPIO_DisableInt(GPIO_T *port, uint32_t u32Pin)
{
/* Configure interrupt mode of specified pin */
port->INTTYPE &= ~(1UL << u32Pin);
/* Disable interrupt function of specified pin */
port->INTEN &= ~((0x00010001UL) << u32Pin);
}
/**
* @brief Set GPIO slew rate control
*
* @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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
* @param[in] u32Mode Slew rate mode. It could be
* - \ref GPIO_SLEWCTL_NORMAL (minimum 16 MHz at 2.7V)
* - \ref GPIO_SLEWCTL_HIGH (minimum 25 MHz at 2.7V)
*
* @return None
*
* @details This function is used to set specified GPIO operation mode.
*/
void GPIO_SetSlewCtl(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode)
{
uint32_t i;
for (i = 0ul; i < GPIO_PIN_MAX; i++)
{
if (u32PinMask & (1ul << i))
{
port->SLEWCTL = (port->SLEWCTL & ~(0x3ul << (i << 1ul))) | (u32Mode << (i << 1ul));
}
}
}
/**
* @brief Set GPIO Pull-up and Pull-down control
*
* @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, and PE.
* It could be BIT0 ~ BIT12, and BIT14 ~ BIT15 for PC.
* It could be BIT0 ~ BIT13, and BIT15 for PD.
* It could be BIT0 ~ BIT7 for PF.
* @param[in] u32Mode The pin mode of specified GPIO pin. It could be
* - \ref GPIO_PUSEL_DISABLE
* - \ref GPIO_PUSEL_PULL_UP
* - \ref GPIO_PUSEL_PULL_DOWN
*
* @return None
*
* @details Set the pin mode of specified GPIO pin.
*/
void GPIO_SetPullCtl(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode)
{
uint32_t i;
for (i = 0ul; i < GPIO_PIN_MAX; i++)
{
if (u32PinMask & (1ul << i))
{
port->PUSEL = (port->PUSEL & ~(0x3ul << (i << 1ul))) | (u32Mode << (i << 1ul));
}
}
}
/*@}*/ /* end of group GPIO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group GPIO_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,423 @@
/**************************************************************************//**
* @file pdma.c
* @version V1.00
* @brief M251 series PDMA driver source file
*
* @note
* @copyright (C) 2017 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "M251.h"
static uint8_t u8ChSelect[PDMA_CH_MAX];
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup PDMA_Driver PDMA Driver
@{
*/
/** @addtogroup PDMA_EXPORTED_FUNCTIONS PDMA Exported Functions
@{
*/
/**
* @brief PDMA Open
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Mask Channel enable bits.
*
* @return None
*
* @details This function enable the PDMA channels.
*/
void PDMA_Open(PDMA_T *pdma, uint32_t u32Mask)
{
uint32_t i;
for (i = 0UL; i < PDMA_CH_MAX; i++)
{
if ((1 << i) & u32Mask)
{
pdma->DSCT[i].CTL = 0UL;
u8ChSelect[i] = PDMA_MEM;
}
}
pdma->CHCTL |= u32Mask;
}
/**
* @brief PDMA Close
*
* @param[in] pdma The pointer of the specified PDMA module
*
* @return None
*
* @details This function disable all PDMA channels.
*/
void PDMA_Close(PDMA_T *pdma)
{
pdma->CHCTL = 0UL;
}
/**
* @brief Set PDMA Transfer Count
*
* @param[in] pdma The pointer of the specified PDMA module
* @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(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount)
{
pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXCNT_Msk | PDMA_DSCT_CTL_TXWIDTH_Msk);
pdma->DSCT[u32Ch].CTL |= (u32Width | ((u32TransCount - 1UL) << PDMA_DSCT_CTL_TXCNT_Pos));
}
/**
* @brief Set PDMA Stride Mode
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
* @param[in] u32DestLen Destination stride count
* @param[in] u32SrcLen Source stride count
* @param[in] u32TransCount Transfer count
*
* @return None
*
* @details This function set the selected stride mode.
*/
void PDMA_SetStride(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32DestLen, uint32_t u32SrcLen, uint32_t u32TransCount)
{
pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_STRIDE_EN_Msk;
pdma->STRIDE[u32Ch].ASOCR = (u32DestLen << 16) | u32SrcLen;
pdma->STRIDE[u32Ch].STC = u32TransCount;
}
/**
* @brief Set PDMA Transfer Address
*
* @param[in] pdma The pointer of the specified PDMA module
* @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(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl)
{
pdma->DSCT[u32Ch].SA = u32SrcAddr;
pdma->DSCT[u32Ch].DA = u32DstAddr;
pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_SAINC_Msk | PDMA_DSCT_CTL_DAINC_Msk);
pdma->DSCT[u32Ch].CTL |= (u32SrcCtrl | u32DstCtrl);
}
/**
* @brief Set PDMA Transfer Mode
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
* @param[in] u32Peripheral The selected peripheral. Valid values are
* - \ref PDMA_MEM
* - \ref PDMA_UART0_TX
* - \ref PDMA_UART0_RX
* - \ref PDMA_UART1_TX
* - \ref PDMA_UART1_RX
* - \ref PDMA_UART2_TX
* - \ref PDMA_UART2_RX
* - \ref PDMA_USCI0_TX
* - \ref PDMA_USCI0_RX
* - \ref PDMA_USCI1_TX
* - \ref PDMA_USCI1_RX
* - \ref PDMA_QSPI0_TX
* - \ref PDMA_QSPI0_RX
* - \ref PDMA_SPI0_TX
* - \ref PDMA_SPI0_RX
* - \ref PDMA_PWM0_P1_RX
* - \ref PDMA_PWM0_P2_RX
* - \ref PDMA_PWM0_P3_RX
* - \ref PDMA_PWM1_P1_RX
* - \ref PDMA_PWM1_P2_RX
* - \ref PDMA_PWM1_P3_RX
* - \ref PDMA_I2C0_TX
* - \ref PDMA_I2C0_RX
* - \ref PDMA_I2C1_TX
* - \ref PDMA_I2C1_RX
* - \ref PDMA_TMR0
* - \ref PDMA_TMR1
* - \ref PDMA_TMR2
* - \ref PDMA_TMR3
* - \ref PDMA_EADC_RX
* - \ref PDMA_DAC0_TX
* - \ref PDMA_PSIO_TX
* - \ref PDMA_PSIO_RX
* - \ref PDMA_USCI2_TX
* - \ref PDMA_USCI2_RX
* @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(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
{
u8ChSelect[u32Ch] = u32Peripheral;
switch (u32Ch)
{
case 0ul:
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC0_Msk) | u32Peripheral;
break;
case 1ul:
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC1_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC1_Pos);
break;
case 2ul:
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC2_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC2_Pos);
break;
case 3ul:
pdma->REQSEL0_3 = (pdma->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC3_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC3_Pos);
break;
case 4ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC4_Msk) | u32Peripheral;
break;
case 5ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC5_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC5_Pos);
break;
case 6ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC6_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC6_Pos);
break;
case 7ul:
pdma->REQSEL4_7 = (pdma->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC7_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC7_Pos);
break;
default:
break;
}
if (u32ScatterEn)
{
pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER;
pdma->DSCT[u32Ch].NEXT = u32DescAddr - (pdma->SCATBA);
}
else
{
pdma->DSCT[u32Ch].CTL = (pdma->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC;
}
}
/**
* @brief Set PDMA Burst Type and Size
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
* @param[in] u32BurstType Burst mode or single mode. Valid values are
* - \ref PDMA_REQ_SINGLE
* - \ref PDMA_REQ_BURST
* @param[in] u32BurstSize Set the size of burst mode. Valid values are
* - \ref PDMA_BURST_128
* - \ref PDMA_BURST_64
* - \ref PDMA_BURST_32
* - \ref PDMA_BURST_16
* - \ref PDMA_BURST_8
* - \ref PDMA_BURST_4
* - \ref PDMA_BURST_2
* - \ref PDMA_BURST_1
*
* @return None
*
* @details This function set the selected channel burst type and size.
*/
void PDMA_SetBurstType(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize)
{
pdma->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXTYPE_Msk | PDMA_DSCT_CTL_BURSIZE_Msk);
pdma->DSCT[u32Ch].CTL |= (u32BurstType | u32BurstSize);
}
/**
* @brief Enable timeout function
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Mask Channel enable bits.
*
* @return None
*
* @details This function enable timeout function of the selected channel(s).
*/
void PDMA_EnableTimeout(PDMA_T *pdma, uint32_t u32Mask)
{
pdma->TOUTEN |= u32Mask;
}
/**
* @brief Disable timeout function
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Mask Channel enable bits.
*
* @return None
*
* @details This function disable timeout function of the selected channel(s).
*/
void PDMA_DisableTimeout(PDMA_T *pdma, uint32_t u32Mask)
{
pdma->TOUTEN &= ~u32Mask;
}
/**
* @brief Set PDMA Timeout Count
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
* @param[in] u32OnOff Enable/disable time out function
* @param[in] u32TimeOutCnt Timeout count
*
* @return None
*
* @details This function set the timeout count.
* @note M251 only supported channel 0/1.
*/
void PDMA_SetTimeOut(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt)
{
switch (u32Ch)
{
case 0ul:
pdma->TOC0_1 = (pdma->TOC0_1 & ~PDMA_TOC0_1_TOC0_Msk) | u32TimeOutCnt;
break;
case 1ul:
pdma->TOC0_1 = (pdma->TOC0_1 & ~PDMA_TOC0_1_TOC1_Msk) | (u32TimeOutCnt << PDMA_TOC0_1_TOC1_Pos);
break;
default:
break;
}
if (u32OnOff)
pdma->TOUTEN |= (1 << u32Ch);
else
pdma->TOUTEN &= ~(1 << u32Ch);
}
/**
* @brief Trigger PDMA
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
*
* @return None
*
* @details This function trigger the selected channel.
*/
void PDMA_Trigger(PDMA_T *pdma, uint32_t u32Ch)
{
if (u8ChSelect[u32Ch] == PDMA_MEM)
{
pdma->SWREQ = (1ul << u32Ch);
}
else {}
}
/**
* @brief Enable Interrupt
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
* @param[in] u32Mask The Interrupt Type. Valid values are
* - \ref PDMA_INT_TRANS_DONE
* - \ref PDMA_INT_TEMPTY
* - \ref PDMA_INT_TIMEOUT
*
* @return None
*
* @details This function enable the selected channel interrupt.
*/
void PDMA_EnableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
{
switch (u32Mask)
{
case PDMA_INT_TRANS_DONE:
pdma->INTEN |= (1ul << u32Ch);
break;
case PDMA_INT_TEMPTY:
pdma->DSCT[u32Ch].CTL &= ~PDMA_DSCT_CTL_TBINTDIS_Msk;
break;
case PDMA_INT_TIMEOUT:
pdma->TOUTIEN |= (1ul << u32Ch);
break;
default:
break;
}
}
/**
* @brief Disable Interrupt
*
* @param[in] pdma The pointer of the specified PDMA module
* @param[in] u32Ch The selected channel
* @param[in] u32Mask The Interrupt Type. Valid values are
* - \ref PDMA_INT_TRANS_DONE
* - \ref PDMA_INT_TEMPTY
* - \ref PDMA_INT_TIMEOUT
*
* @return None
*
* @details This function disable the selected channel interrupt.
*/
void PDMA_DisableInt(PDMA_T *pdma, uint32_t u32Ch, uint32_t u32Mask)
{
switch (u32Mask)
{
case PDMA_INT_TRANS_DONE:
pdma->INTEN &= ~(1ul << u32Ch);
break;
case PDMA_INT_TEMPTY:
pdma->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_TBINTDIS_Msk;
break;
case PDMA_INT_TIMEOUT:
pdma->TOUTIEN &= ~(1ul << u32Ch);
break;
default:
break;
}
}
/*@}*/ /* end of group PDMA_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group PDMA_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,812 @@
/**************************************************************************//**
* @file qspi.c
* @version V0.10
* @brief M251 series QSPI driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup QSPI_Driver QSPI Driver
@{
*/
/** @addtogroup QSPI_EXPORTED_FUNCTIONS QSPI Exported Functions
@{
*/
/**
* @brief This function make QSPI module be ready to transfer.
* @param[in] qspi The pointer of the specified QSPI module.
* @param[in] u32MasterSlave Decides the QSPI module is operating in master mode or in slave mode. (QSPI_SLAVE, QSPI_MASTER)
* @param[in] u32QSPIMode Decides the transfer timing. (QSPI_MODE_0, QSPI_MODE_1, QSPI_MODE_2, QSPI_MODE_3)
* @param[in] u32DataWidth Decides the data width of a QSPI transaction.
* @param[in] u32BusClock The expected frequency of QSPI bus clock in Hz.
* @return Actual frequency of QSPI peripheral clock.
* @details By default, the QSPI transfer sequence is MSB first, the slave selection signal is active low and the automatic
* slave selection function is disabled.
* In Slave mode, the u32BusClock shall be NULL and the QSPI clock divider setting will be 0.
* The actual clock rate may be different from the target QSPI clock rate.
* For example, if the QSPI source clock rate is 12 MHz and the target QSPI bus clock rate is 7 MHz, the
* actual QSPI clock rate will be 6MHz.
* @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
* @note If u32BusClock >= system clock frequency, QSPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
* @note If u32BusClock >= QSPI peripheral clock source, DIVIDER will be set to 0.
* @note In slave mode, the QSPI peripheral clock rate will be equal to APB clock rate.
*/
uint32_t QSPI_Open(QSPI_T *qspi,
uint32_t u32MasterSlave,
uint32_t u32QSPIMode,
uint32_t u32DataWidth,
uint32_t u32BusClock)
{
uint32_t u32ClkSrc = 0UL, u32Div, u32HCLKFreq, u32RetValue = 0UL;
if (u32DataWidth == 32UL)
{
u32DataWidth = 0UL;
}
/* Get system clock frequency */
u32HCLKFreq = CLK_GetHCLKFreq();
if (u32MasterSlave == QSPI_MASTER)
{
/* Default setting: slave selection signal is active low; disable automatic slave selection function. */
qspi->SSCTL = QSPI_SS_ACTIVE_LOW;
/* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
qspi->CTL = u32MasterSlave | (u32DataWidth << QSPI_CTL_DWIDTH_Pos) | (u32QSPIMode) | QSPI_CTL_QSPIEN_Msk;
if (u32BusClock >= u32HCLKFreq)
{
/* Select PCLK as the clock source of QSPI */
CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_QSPI0SEL_Msk)) | CLK_CLKSEL2_QSPI0SEL_PCLK0;
}
/* Check clock source of QSPI */
if ((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_HXT)
{
u32ClkSrc = __HXT; /* Clock source is HXT */
}
else if ((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PLL)
{
u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
}
else if ((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PCLK0)
{
/* Clock source is PCLK0 */
u32ClkSrc = CLK_GetPCLK0Freq();
}
else
{
u32ClkSrc = __HIRC; /* Clock source is HIRC */
}
if (u32BusClock >= u32HCLKFreq)
{
/* Set DIVIDER = 0 */
qspi->CLKDIV = 0UL;
/* Return master peripheral clock rate */
u32RetValue = u32ClkSrc;
}
else if (u32BusClock >= u32ClkSrc)
{
/* Set DIVIDER = 0 */
qspi->CLKDIV = 0UL;
/* Return master peripheral clock rate */
u32RetValue = u32ClkSrc;
}
else if (u32BusClock == 0UL)
{
/* Set DIVIDER to the maximum value 0x1FF. f_qspi = f_qspi_clk_src / (DIVIDER + 1) */
qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk;
/* Return master peripheral clock rate */
u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
}
else
{
u32Div = (((u32ClkSrc * 10UL) / u32BusClock + 5UL) / 10UL) - 1UL; /* Round to the nearest integer */
if (u32Div > 0x1FFUL)
{
u32Div = 0x1FFUL;
qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk;
/* Return master peripheral clock rate */
u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
}
else
{
qspi->CLKDIV = (qspi->CLKDIV & (~QSPI_CLKDIV_DIVIDER_Msk)) | (u32Div << QSPI_CLKDIV_DIVIDER_Pos);
/* Return master peripheral clock rate */
u32RetValue = (u32ClkSrc / (u32Div + 1UL));
}
}
}
else /* For slave mode, force the QSPI peripheral clock rate to equal APB clock rate. */
{
/* Default setting: slave selection signal is low level active. */
qspi->SSCTL = QSPI_SS_ACTIVE_LOW;
/* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
qspi->CTL = u32MasterSlave | (u32DataWidth << QSPI_CTL_DWIDTH_Pos) | (u32QSPIMode) | QSPI_CTL_QSPIEN_Msk;
/* Set DIVIDER = 0 */
qspi->CLKDIV = 0UL;
/* Select PCLK as the clock source of QSPI */
CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_QSPI0SEL_Msk)) | CLK_CLKSEL2_QSPI0SEL_PCLK0;
/* Return slave peripheral clock rate */
u32RetValue = CLK_GetPCLK0Freq();
}
return u32RetValue;
}
/**
* @brief Disable QSPI controller.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None
* @details This function will reset QSPI controller.
*/
void QSPI_Close(QSPI_T *qspi)
{
/* Reset QSPI */
SYS->IPRST1 |= SYS_IPRST1_QSPI0RST_Msk;
SYS->IPRST1 &= ~SYS_IPRST1_QSPI0RST_Msk;
}
/**
* @brief Clear RX FIFO buffer.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None
* @details This function will clear QSPI RX FIFO buffer. The RXEMPTY (QSPI_STATUS[8]) will be set to 1.
*/
void QSPI_ClearRxFIFO(QSPI_T *qspi)
{
qspi->FIFOCTL |= QSPI_FIFOCTL_RXFBCLR_Msk;
}
/**
* @brief Clear TX FIFO buffer.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None
* @details This function will clear QSPI TX FIFO buffer. The TXEMPTY (QSPI_STATUS[16]) will be set to 1.
* @note The TX shift register will not be cleared.
*/
void QSPI_ClearTxFIFO(QSPI_T *qspi)
{
qspi->FIFOCTL |= QSPI_FIFOCTL_TXFBCLR_Msk;
}
/**
* @brief Disable the automatic slave selection function.
* @param[in] qspi The pointer of the specified QSPI module.
* @return None
* @details This function will disable the automatic slave selection function and set slave selection signal to inactive state.
*/
void QSPI_DisableAutoSS(QSPI_T *qspi)
{
qspi->SSCTL &= ~(QSPI_SSCTL_AUTOSS_Msk | QSPI_SSCTL_SS_Msk);
}
/**
* @brief Enable the automatic slave selection function.
* @param[in] qspi The pointer of the specified QSPI module.
* @param[in] u32SSPinMask Specifies slave selection pins. (QSPI_SS)
* @param[in] u32ActiveLevel Specifies the active level of slave selection signal. (QSPI_SS_ACTIVE_HIGH, QSPI_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 QSPI_EnableAutoSS(QSPI_T *qspi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
{
qspi->SSCTL = (qspi->SSCTL & (~(QSPI_SSCTL_AUTOSS_Msk | QSPI_SSCTL_SSACTPOL_Msk | QSPI_SSCTL_SS_Msk))) | (u32SSPinMask | u32ActiveLevel | QSPI_SSCTL_AUTOSS_Msk);
}
/**
* @brief Set the QSPI bus clock.
* @param[in] qspi The pointer of the specified QSPI module.
* @param[in] u32BusClock The expected frequency of QSPI bus clock in Hz.
* @return Actual frequency of QSPI bus clock.
* @details This function is only available in Master mode. The actual clock rate may be different from the target QSPI bus clock rate.
* For example, if the QSPI source clock rate is 12 MHz and the target QSPI bus clock rate is 7 MHz, the actual QSPI bus clock
* rate will be 6 MHz.
* @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
* @note If u32BusClock >= system clock frequency, QSPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
* @note If u32BusClock >= QSPI peripheral clock source, DIVIDER will be set to 0.
*/
uint32_t QSPI_SetBusClock(QSPI_T *qspi, uint32_t u32BusClock)
{
uint32_t u32ClkSrc, u32HCLKFreq;
uint32_t u32Div, u32RetValue;
/* Get system clock frequency */
u32HCLKFreq = CLK_GetHCLKFreq();
if (u32BusClock >= u32HCLKFreq)
{
/* Select PCLK as the clock source of QSPI */
CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_QSPI0SEL_Msk)) | CLK_CLKSEL2_QSPI0SEL_PCLK0;
}
/* Check clock source of SPI */
if ((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_HXT)
{
u32ClkSrc = __HXT; /* Clock source is HXT */
}
else if ((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PLL)
{
u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
}
else if ((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PCLK0)
{
/* Clock source is PCLK0 */
u32ClkSrc = CLK_GetPCLK0Freq();
}
else
{
u32ClkSrc = __HIRC; /* Clock source is HIRC */
}
if (u32BusClock >= u32HCLKFreq)
{
/* Set DIVIDER = 0 */
qspi->CLKDIV = 0UL;
/* Return master peripheral clock rate */
u32RetValue = u32ClkSrc;
}
else if (u32BusClock >= u32ClkSrc)
{
/* Set DIVIDER = 0 */
qspi->CLKDIV = 0UL;
/* Return master peripheral clock rate */
u32RetValue = u32ClkSrc;
}
else if (u32BusClock == 0UL)
{
/* Set DIVIDER to the maximum value 0x1FF. f_qspi = f_qspi_clk_src / (DIVIDER + 1) */
qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk;
/* Return master peripheral clock rate */
u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
}
else
{
u32Div = (((u32ClkSrc * 10UL) / u32BusClock + 5UL) / 10UL) - 1UL; /* Round to the nearest integer */
if (u32Div > 0x1FFUL)
{
u32Div = 0x1FFUL;
qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk;
/* Return master peripheral clock rate */
u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
}
else
{
qspi->CLKDIV = (qspi->CLKDIV & (~QSPI_CLKDIV_DIVIDER_Msk)) | (u32Div << QSPI_CLKDIV_DIVIDER_Pos);
/* Return master peripheral clock rate */
u32RetValue = (u32ClkSrc / (u32Div + 1UL));
}
}
return u32RetValue;
}
/**
* @brief Configure FIFO threshold setting.
* @param[in] qspi The pointer of the specified QSPI module.
* @param[in] u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 3.
* @param[in] u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 3.
* @return None
* @details Set TX FIFO threshold and RX FIFO threshold configurations.
*/
void QSPI_SetFIFO(QSPI_T *qspi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
{
qspi->FIFOCTL = (qspi->FIFOCTL & ~(QSPI_FIFOCTL_TXTH_Msk | QSPI_FIFOCTL_RXTH_Msk)) |
(u32TxThreshold << QSPI_FIFOCTL_TXTH_Pos) |
(u32RxThreshold << QSPI_FIFOCTL_RXTH_Pos);
}
/**
* @brief Get the actual frequency of QSPI bus clock. Only available in Master mode.
* @param[in] qspi The pointer of the specified QSPI module.
* @return Actual QSPI bus clock frequency in Hz.
* @details This function will calculate the actual QSPI bus clock rate according to the QSPInSEL and DIVIDER settings. Only available in Master mode.
*/
uint32_t QSPI_GetBusClock(QSPI_T *qspi)
{
uint32_t u32Div;
uint32_t u32ClkSrc;
/* Get DIVIDER setting */
u32Div = (qspi->CLKDIV & QSPI_CLKDIV_DIVIDER_Msk) >> QSPI_CLKDIV_DIVIDER_Pos;
/* Check clock source of QSPI */
if ((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_HXT)
{
u32ClkSrc = __HXT; /* Clock source is HXT */
}
else if ((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PLL)
{
u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
}
else if ((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PCLK0)
{
/* Clock source is PCLK0 */
u32ClkSrc = CLK_GetPCLK0Freq();
}
else
{
u32ClkSrc = __HIRC; /* Clock source is HIRC */
}
/* Return QSPI bus clock rate */
return (u32ClkSrc / (u32Div + 1UL));
}
/**
* @brief Enable interrupt function.
* @param[in] qspi The pointer of the specified QSPI module.
* @param[in] u32Mask The combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt enable bit.
* This parameter decides which interrupts will be enabled. It is combination of:
* - \ref QSPI_UNIT_INT_MASK
* - \ref QSPI_SSACT_INT_MASK
* - \ref QSPI_SSINACT_INT_MASK
* - \ref QSPI_SLVUR_INT_MASK
* - \ref QSPI_SLVBE_INT_MASK
* - \ref QSPI_SLVTO_INT_MASK
* - \ref QSPI_TXUF_INT_MASK
* - \ref QSPI_FIFO_TXTH_INT_MASK
* - \ref QSPI_FIFO_RXTH_INT_MASK
* - \ref QSPI_FIFO_RXOV_INT_MASK
* - \ref QSPI_FIFO_RXTO_INT_MASK
*
* @return None
* @details Enable QSPI related interrupts specified by u32Mask parameter.
*/
void QSPI_EnableInt(QSPI_T *qspi, uint32_t u32Mask)
{
/* Enable unit transfer interrupt flag */
if ((u32Mask & QSPI_UNIT_INT_MASK) == QSPI_UNIT_INT_MASK)
{
qspi->CTL |= QSPI_CTL_UNITIEN_Msk;
}
/* Enable slave selection signal active interrupt flag */
if ((u32Mask & QSPI_SSACT_INT_MASK) == QSPI_SSACT_INT_MASK)
{
qspi->SSCTL |= QSPI_SSCTL_SSACTIEN_Msk;
}
/* Enable slave selection signal inactive interrupt flag */
if ((u32Mask & QSPI_SSINACT_INT_MASK) == QSPI_SSINACT_INT_MASK)
{
qspi->SSCTL |= QSPI_SSCTL_SSINAIEN_Msk;
}
/* Enable slave TX under run interrupt flag */
if ((u32Mask & QSPI_SLVUR_INT_MASK) == QSPI_SLVUR_INT_MASK)
{
qspi->SSCTL |= QSPI_SSCTL_SLVURIEN_Msk;
}
/* Enable slave bit count error interrupt flag */
if ((u32Mask & QSPI_SLVBE_INT_MASK) == QSPI_SLVBE_INT_MASK)
{
qspi->SSCTL |= QSPI_SSCTL_SLVBEIEN_Msk;
}
/* Enable slave mode time-out interrupt flag */
if ((u32Mask & QSPI_SLVTO_INT_MASK) == QSPI_SLVTO_INT_MASK)
{
qspi->SSCTL |= QSPI_SSCTL_SLVTOIEN_Msk;
}
/* Enable slave TX underflow interrupt flag */
if ((u32Mask & QSPI_TXUF_INT_MASK) == QSPI_TXUF_INT_MASK)
{
qspi->FIFOCTL |= QSPI_FIFOCTL_TXUFIEN_Msk;
}
/* Enable TX threshold interrupt flag */
if ((u32Mask & QSPI_FIFO_TXTH_INT_MASK) == QSPI_FIFO_TXTH_INT_MASK)
{
qspi->FIFOCTL |= QSPI_FIFOCTL_TXTHIEN_Msk;
}
/* Enable RX threshold interrupt flag */
if ((u32Mask & QSPI_FIFO_RXTH_INT_MASK) == QSPI_FIFO_RXTH_INT_MASK)
{
qspi->FIFOCTL |= QSPI_FIFOCTL_RXTHIEN_Msk;
}
/* Enable RX overrun interrupt flag */
if ((u32Mask & QSPI_FIFO_RXOV_INT_MASK) == QSPI_FIFO_RXOV_INT_MASK)
{
qspi->FIFOCTL |= QSPI_FIFOCTL_RXOVIEN_Msk;
}
/* Enable RX time-out interrupt flag */
if ((u32Mask & QSPI_FIFO_RXTO_INT_MASK) == QSPI_FIFO_RXTO_INT_MASK)
{
qspi->FIFOCTL |= QSPI_FIFOCTL_RXTOIEN_Msk;
}
}
/**
* @brief Disable interrupt function.
* @param[in] qspi The pointer of the specified QSPI 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. It is combination of:
* - \ref QSPI_UNIT_INT_MASK
* - \ref QSPI_SSACT_INT_MASK
* - \ref QSPI_SSINACT_INT_MASK
* - \ref QSPI_SLVUR_INT_MASK
* - \ref QSPI_SLVBE_INT_MASK
* - \ref QSPI_SLVTO_INT_MASK
* - \ref QSPI_TXUF_INT_MASK
* - \ref QSPI_FIFO_TXTH_INT_MASK
* - \ref QSPI_FIFO_RXTH_INT_MASK
* - \ref QSPI_FIFO_RXOV_INT_MASK
* - \ref QSPI_FIFO_RXTO_INT_MASK
*
* @return None
* @details Disable QSPI related interrupts specified by u32Mask parameter.
*/
void QSPI_DisableInt(QSPI_T *qspi, uint32_t u32Mask)
{
/* Disable unit transfer interrupt flag */
if ((u32Mask & QSPI_UNIT_INT_MASK) == QSPI_UNIT_INT_MASK)
{
qspi->CTL &= ~QSPI_CTL_UNITIEN_Msk;
}
/* Disable slave selection signal active interrupt flag */
if ((u32Mask & QSPI_SSACT_INT_MASK) == QSPI_SSACT_INT_MASK)
{
qspi->SSCTL &= ~QSPI_SSCTL_SSACTIEN_Msk;
}
/* Disable slave selection signal inactive interrupt flag */
if ((u32Mask & QSPI_SSINACT_INT_MASK) == QSPI_SSINACT_INT_MASK)
{
qspi->SSCTL &= ~QSPI_SSCTL_SSINAIEN_Msk;
}
/* Disable slave TX under run interrupt flag */
if ((u32Mask & QSPI_SLVUR_INT_MASK) == QSPI_SLVUR_INT_MASK)
{
qspi->SSCTL &= ~QSPI_SSCTL_SLVURIEN_Msk;
}
/* Disable slave bit count error interrupt flag */
if ((u32Mask & QSPI_SLVBE_INT_MASK) == QSPI_SLVBE_INT_MASK)
{
qspi->SSCTL &= ~QSPI_SSCTL_SLVBEIEN_Msk;
}
/* Disable slave mode time-out interrupt flag */
if ((u32Mask & QSPI_SLVTO_INT_MASK) == QSPI_SLVTO_INT_MASK)
{
qspi->SSCTL &= ~QSPI_SSCTL_SLVTOIEN_Msk;
}
/* Disable slave TX underflow interrupt flag */
if ((u32Mask & QSPI_TXUF_INT_MASK) == QSPI_TXUF_INT_MASK)
{
qspi->FIFOCTL &= ~QSPI_FIFOCTL_TXUFIEN_Msk;
}
/* Disable TX threshold interrupt flag */
if ((u32Mask & QSPI_FIFO_TXTH_INT_MASK) == QSPI_FIFO_TXTH_INT_MASK)
{
qspi->FIFOCTL &= ~QSPI_FIFOCTL_TXTHIEN_Msk;
}
/* Disable RX threshold interrupt flag */
if ((u32Mask & QSPI_FIFO_RXTH_INT_MASK) == QSPI_FIFO_RXTH_INT_MASK)
{
qspi->FIFOCTL &= ~QSPI_FIFOCTL_RXTHIEN_Msk;
}
/* Disable RX overrun interrupt flag */
if ((u32Mask & QSPI_FIFO_RXOV_INT_MASK) == QSPI_FIFO_RXOV_INT_MASK)
{
qspi->FIFOCTL &= ~QSPI_FIFOCTL_RXOVIEN_Msk;
}
/* Disable RX time-out interrupt flag */
if ((u32Mask & QSPI_FIFO_RXTO_INT_MASK) == QSPI_FIFO_RXTO_INT_MASK)
{
qspi->FIFOCTL &= ~QSPI_FIFOCTL_RXTOIEN_Msk;
}
}
/**
* @brief Get interrupt flag.
* @param[in] qspi The pointer of the specified QSPI 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. It is combination of:
* - \ref QSPI_UNIT_INT_MASK
* - \ref QSPI_SSACT_INT_MASK
* - \ref QSPI_SSINACT_INT_MASK
* - \ref QSPI_SLVUR_INT_MASK
* - \ref QSPI_SLVBE_INT_MASK
* - \ref QSPI_SLVTO_INT_MASK
* - \ref QSPI_TXUF_INT_MASK
* - \ref QSPI_FIFO_TXTH_INT_MASK
* - \ref QSPI_FIFO_RXTH_INT_MASK
* - \ref QSPI_FIFO_RXOV_INT_MASK
* - \ref QSPI_FIFO_RXTO_INT_MASK
*
* @return Interrupt flags of selected sources.
* @details Get QSPI related interrupt flags specified by u32Mask parameter.
*/
uint32_t QSPI_GetIntFlag(QSPI_T *qspi, uint32_t u32Mask)
{
uint32_t u32IntFlag = 0U, u32TmpVal;
u32TmpVal = qspi->STATUS & QSPI_STATUS_UNITIF_Msk;
/* Check unit transfer interrupt flag */
if ((u32Mask & QSPI_UNIT_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_UNIT_INT_MASK;
}
u32TmpVal = qspi->STATUS & QSPI_STATUS_SSACTIF_Msk;
/* Check slave selection signal active interrupt flag */
if ((u32Mask & QSPI_SSACT_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_SSACT_INT_MASK;
}
u32TmpVal = qspi->STATUS & QSPI_STATUS_SSINAIF_Msk;
/* Check slave selection signal inactive interrupt flag */
if ((u32Mask & QSPI_SSINACT_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_SSINACT_INT_MASK;
}
u32TmpVal = qspi->STATUS & QSPI_STATUS_SLVURIF_Msk;
/* Check slave TX under run interrupt flag */
if ((u32Mask & QSPI_SLVUR_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_SLVUR_INT_MASK;
}
u32TmpVal = qspi->STATUS & QSPI_STATUS_SLVBEIF_Msk;
/* Check slave bit count error interrupt flag */
if ((u32Mask & QSPI_SLVBE_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_SLVBE_INT_MASK;
}
u32TmpVal = qspi->STATUS & QSPI_STATUS_SLVTOIF_Msk;
/* Check slave mode time-out interrupt flag */
if ((u32Mask & QSPI_SLVTO_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_SLVTO_INT_MASK;
}
u32TmpVal = qspi->STATUS & QSPI_STATUS_TXUFIF_Msk;
/* Check slave TX underflow interrupt flag */
if ((u32Mask & QSPI_TXUF_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_TXUF_INT_MASK;
}
u32TmpVal = qspi->STATUS & QSPI_STATUS_TXTHIF_Msk;
/* Check TX threshold interrupt flag */
if ((u32Mask & QSPI_FIFO_TXTH_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_FIFO_TXTH_INT_MASK;
}
u32TmpVal = qspi->STATUS & QSPI_STATUS_RXTHIF_Msk;
/* Check RX threshold interrupt flag */
if ((u32Mask & QSPI_FIFO_RXTH_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_FIFO_RXTH_INT_MASK;
}
u32TmpVal = qspi->STATUS & QSPI_STATUS_RXOVIF_Msk;
/* Check RX overrun interrupt flag */
if ((u32Mask & QSPI_FIFO_RXOV_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_FIFO_RXOV_INT_MASK;
}
u32TmpVal = qspi->STATUS & QSPI_STATUS_RXTOIF_Msk;
/* Check RX time-out interrupt flag */
if ((u32Mask & QSPI_FIFO_RXTO_INT_MASK) && (u32TmpVal))
{
u32IntFlag |= QSPI_FIFO_RXTO_INT_MASK;
}
return u32IntFlag;
}
/**
* @brief Clear interrupt flag.
* @param[in] qspi The pointer of the specified QSPI 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. It could be the combination of:
* - \ref QSPI_UNIT_INT_MASK
* - \ref QSPI_SSACT_INT_MASK
* - \ref QSPI_SSINACT_INT_MASK
* - \ref QSPI_SLVUR_INT_MASK
* - \ref QSPI_SLVBE_INT_MASK
* - \ref QSPI_SLVTO_INT_MASK
* - \ref QSPI_TXUF_INT_MASK
* - \ref QSPI_FIFO_RXOV_INT_MASK
* - \ref QSPI_FIFO_RXTO_INT_MASK
*
* @return None
* @details Clear QSPI related interrupt flags specified by u32Mask parameter.
*/
void QSPI_ClearIntFlag(QSPI_T *qspi, uint32_t u32Mask)
{
if (u32Mask & QSPI_UNIT_INT_MASK)
{
qspi->STATUS = QSPI_STATUS_UNITIF_Msk; /* Clear unit transfer interrupt flag */
}
if (u32Mask & QSPI_SSACT_INT_MASK)
{
qspi->STATUS = QSPI_STATUS_SSACTIF_Msk; /* Clear slave selection signal active interrupt flag */
}
if (u32Mask & QSPI_SSINACT_INT_MASK)
{
qspi->STATUS = QSPI_STATUS_SSINAIF_Msk; /* Clear slave selection signal inactive interrupt flag */
}
if (u32Mask & QSPI_SLVUR_INT_MASK)
{
qspi->STATUS = QSPI_STATUS_SLVURIF_Msk; /* Clear slave TX under run interrupt flag */
}
if (u32Mask & QSPI_SLVBE_INT_MASK)
{
qspi->STATUS = QSPI_STATUS_SLVBEIF_Msk; /* Clear slave bit count error interrupt flag */
}
if (u32Mask & QSPI_SLVTO_INT_MASK)
{
qspi->STATUS = QSPI_STATUS_SLVTOIF_Msk; /* Clear slave mode time-out interrupt flag */
}
if (u32Mask & QSPI_TXUF_INT_MASK)
{
qspi->STATUS = QSPI_STATUS_TXUFIF_Msk; /* Clear slave TX underflow interrupt flag */
}
if (u32Mask & QSPI_FIFO_RXOV_INT_MASK)
{
qspi->STATUS = QSPI_STATUS_RXOVIF_Msk; /* Clear RX overrun interrupt flag */
}
if (u32Mask & QSPI_FIFO_RXTO_INT_MASK)
{
qspi->STATUS = QSPI_STATUS_RXTOIF_Msk; /* Clear RX time-out interrupt flag */
}
}
/**
* @brief Get QSPI status.
* @param[in] qspi The pointer of the specified QSPI module.
* @param[in] u32Mask The combination of all related sources.
* Each bit corresponds to a source.
* This parameter decides which flags will be read. It is combination of:
* - \ref QSPI_BUSY_MASK
* - \ref QSPI_RX_EMPTY_MASK
* - \ref QSPI_RX_FULL_MASK
* - \ref QSPI_TX_EMPTY_MASK
* - \ref QSPI_TX_FULL_MASK
* - \ref QSPI_TXRX_RESET_MASK
* - \ref QSPI_QSPIEN_STS_MASK
* - \ref QSPI_SSLINE_STS_MASK
*
* @return Flags of selected sources.
* @details Get QSPI related status specified by u32Mask parameter.
*/
uint32_t QSPI_GetStatus(QSPI_T *qspi, uint32_t u32Mask)
{
uint32_t u32Flag = 0UL, u32TmpValue;
u32TmpValue = qspi->STATUS & QSPI_STATUS_BUSY_Msk;
/* Check busy status */
if ((u32Mask & QSPI_BUSY_MASK) && (u32TmpValue))
{
u32Flag |= QSPI_BUSY_MASK;
}
u32TmpValue = qspi->STATUS & QSPI_STATUS_RXEMPTY_Msk;
/* Check RX empty flag */
if ((u32Mask & QSPI_RX_EMPTY_MASK) && (u32TmpValue))
{
u32Flag |= QSPI_RX_EMPTY_MASK;
}
u32TmpValue = qspi->STATUS & QSPI_STATUS_RXFULL_Msk;
/* Check RX full flag */
if ((u32Mask & QSPI_RX_FULL_MASK) && (u32TmpValue))
{
u32Flag |= QSPI_RX_FULL_MASK;
}
u32TmpValue = qspi->STATUS & QSPI_STATUS_TXEMPTY_Msk;
/* Check TX empty flag */
if ((u32Mask & QSPI_TX_EMPTY_MASK) && (u32TmpValue))
{
u32Flag |= QSPI_TX_EMPTY_MASK;
}
u32TmpValue = qspi->STATUS & QSPI_STATUS_TXFULL_Msk;
/* Check TX full flag */
if ((u32Mask & QSPI_TX_FULL_MASK) && (u32TmpValue))
{
u32Flag |= QSPI_TX_FULL_MASK;
}
u32TmpValue = qspi->STATUS & QSPI_STATUS_TXRXRST_Msk;
/* Check TX/RX reset flag */
if ((u32Mask & QSPI_TXRX_RESET_MASK) && (u32TmpValue))
{
u32Flag |= QSPI_TXRX_RESET_MASK;
}
u32TmpValue = qspi->STATUS & QSPI_STATUS_QSPIENSTS_Msk;
/* Check QSPIEN flag */
if ((u32Mask & QSPI_QSPIEN_STS_MASK) && (u32TmpValue))
{
u32Flag |= QSPI_QSPIEN_STS_MASK;
}
u32TmpValue = qspi->STATUS & QSPI_STATUS_SSLINE_Msk;
/* Check QSPIx_SS line status */
if ((u32Mask & QSPI_SSLINE_STS_MASK) && (u32TmpValue))
{
u32Flag |= QSPI_SSLINE_STS_MASK;
}
return u32Flag;
}
/*@}*/ /* end of group QSPI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group QSPI_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,628 @@
/**************************************************************************//**
* @file retarget.c
* @version V0.10
* @brief M251 series serial driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
****************************************************************************/
#include <stdio.h>
#include "NuMicro.h"
#if defined (__ICCARM__)
#pragma diag_suppress=Pm150
#endif
#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
# define DEBUG_PORT UART0
# define BUF_SIZE 512
/*---------------------------------------------------------------------------------------------------------*/
/* Global variables */
/*---------------------------------------------------------------------------------------------------------*/
#if !(defined(__ICCARM__) && (__VER__ >= 6010000))
#if (__ARMCC_VERSION < 6040000)
struct __FILE
{
int handle; /* Add whatever you need here */
};
#endif
#endif
FILE __stdout;
FILE __stdin;
#if defined (__ARMCC_VERSION) || defined (__ICCARM__)
extern int32_t SH_DoCommand(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0);
#if defined( __ICCARM__ )
__WEAK
#else
__attribute__((weak))
#endif
uint32_t ProcessHardFault(uint32_t lr, uint32_t msp, uint32_t psp);
#endif
int kbhit(void);
int IsDebugFifoEmpty(void);
void _ttywrch(int ch);
int fputc(int ch, FILE *stream);
#if defined ( __GNUC__ ) && !defined (__ARMCC_VERSION)
#if !defined (OS_USE_SEMIHOSTING)
int _read(int fd, char *ptr, int len);
#endif
int _write(int fd, char *ptr, int len);
#endif
#if defined (__ARMCC_VERSION) || defined (__ICCARM__)
int fgetc(FILE *stream);
int ferror(FILE *stream);
#endif
char GetChar(void);
void SendChar_ToUART(int ch);
void SendChar(int ch);
static volatile int32_t g_ICE_Conneced = 1;
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 DumpStack(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]);
}
#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;
/**
*
* @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_Return(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0)
{
if (g_ICE_Conneced)
{
if (pn32Out_R0)
*pn32Out_R0 = n32In_R0;
return 1;
}
return 0;
}
#else // defined(DEBUG_ENABLE_SEMIHOST)
#if defined ( __GNUC__ ) && !defined (__ARMCC_VERSION)
/**
* @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("MOV R0, LR \n"
"MRS R1, MSP \n"
"MRS R2, PSP \n"
"LDR R3, =ProcessHardFault \n"
"BLX R3 \n"
"BX R0 \n"
);
}
#else
int32_t SH_Return(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0);
int32_t SH_Return(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0)
{
return 0;
}
#endif
#endif /* defined(DEBUG_ENABLE_SEMIHOST) */
#if defined( __ICCARM__ )
__WEAK
#else
__attribute__((weak))
#endif
uint32_t ProcessHardFault(uint32_t lr, uint32_t msp, uint32_t psp)
{
uint32_t *sp;
uint32_t inst;
/* It is casued by hardfault. Just process the hard fault */
/* TODO: Implement your hardfault handle code here */
/* Check the used stack */
// if(lr & 0x40UL) // M251 has no TrustZone.
{
/* Secure stack used */
if (lr & 4UL)
{
sp = (uint32_t *)psp;
}
else
{
sp = (uint32_t *)msp;
}
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
else
{
/* Non-secure stack used */
if (lr & 4)
sp = (uint32_t *)__TZ_get_PSP_NS();
else
sp = (uint32_t *)__TZ_get_MSP_NS();
}
#endif
/* Get the instruction caused the hardfault */
inst = M16(sp[6]);
if (inst == 0xBEAB)
{
/*
If the instruction is 0xBEAB, it means it is caused by BKPT without ICE connected.
We still return for output/input message to UART.
*/
g_ICE_Conneced = 0; // Set a flag for ICE offline
sp[6] += 2; // Return to next instruction
return lr; // Keep lr in R0
}
printf(" HardFault!\n\n");
DumpStack(sp);
/* Or *sp to remove compiler warning */
while (1U | *sp) {}
return lr;
}
/**
* @brief Routine to send a char
*
* @param[in] ch A character data writes 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->FIFOSTS & UART_FIFOSTS_TXFULL_Msk) {}
DEBUG_PORT->DAT = (uint32_t)ch;
if ((char)ch == '\n')
{
while (DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXFULL_Msk) {}
DEBUG_PORT->DAT = '\r';
}
}
#else
/* Non-block implement of send char */
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
i32Tmp = i32Head + 1;
if (i32Tmp > BUF_SIZE) i32Tmp = 0;
if (i32Tmp != i32Tail)
{
u8Buf[i32Head] = ch;
i32Head = i32Tmp;
}
if (ch == '\n')
{
i32Tmp = i32Head + 1;
if (i32Tmp > BUF_SIZE) i32Tmp = 0;
if (i32Tmp != i32Tail)
{
u8Buf[i32Head] = '\r';
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->DATA = u8Buf[i32Tail];
i32Tail = i32Tmp;
}
else
break; // FIFO full
} while (i32Tail != i32Head);
}
#endif /* else for NONBLOCK_PRINTF */
/**
* @brief Routine to send a char
*
* @param[in] ch : A character data writes to debug port
*
* @returns Send value from UART debug port or semihost
*
* @details Send a target char to UART debug port or semihost.
*/
#if !defined( __ICCARM__ )
#define __WEAK __attribute__((weak))
#endif
__WEAK 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 (g_ICE_Conneced)
{
if (SH_DoCommand(0x04, (int)g_buf, NULL) != 0)
{
g_buf_len = 0;
return;
}
}
else
{
#if (DEBUG_ENABLE_SEMIHOST == 1) // Re-direct to UART Debug Port only when DEBUG_ENABLE_SEMIHOST=1
int i;
for (i = 0; i < g_buf_len; i++)
SendChar_ToUART(g_buf[i]);
#endif
g_buf_len = 0;
}
}
#else
#if defined ( __GNUC__ ) && !defined (__ARMCC_VERSION)
char *ch0;
*ch0 = (char)ch;
_write(0, ch0, 1);
#else
SendChar_ToUART(ch);
#endif /* ( __GNUC__ ) */
#endif /* DEBUG_ENABLE_SEMIHOST */
}
/**
* @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(g_ICE_Conneced)
{
#if defined (__ICCARM__)
int nRet;
while (SH_DoCommand(0x7, 0, &nRet) != 0)
{
if (nRet != 0)
return (char)nRet;
}
#else
int nRet, nRet1;
while (SH_DoCommand(0x101, 0, &nRet) != 0)
{
if (nRet != 0)
{
SH_DoCommand(0x07, 0, &nRet);
return (char)nRet;
}
}
#endif
}
else
{
#if (DEBUG_ENABLE_SEMIHOST == 1) // Re-direct to UART Debug Port only when DEBUG_ENABLE_SEMIHOST=1
/* Use debug port when ICE is not connected at semihost mode */
while (!g_ICE_Conneced)
{
if ((DEBUG_PORT->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) == 0U)
{
return ((char)DEBUG_PORT->DAT);
}
}
#endif
}
return (0);
#else
while (1)
{
if ((DEBUG_PORT->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) == 0U)
{
return ((char)DEBUG_PORT->DAT);
}
}
#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->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) == 0U);
}
/**
* @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->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk) != 0U);
}
/**
* @brief C library retargetting
*
* @param[in] ch Write a character data
*
* @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__ ) && !defined (__ARMCC_VERSION)
#if defined (OS_USE_SEMIHOSTING)
#else
int _write(int fd, char *ptr, int len)
{
int i = len;
while (i--)
{
while (DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXFULL_Msk);
DEBUG_PORT->DAT = *ptr++;
if (*ptr == '\n')
{
while (DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXFULL_Msk);
DEBUG_PORT->DAT = '\r';
}
}
return len;
}
int _read(int fd, char *ptr, int len)
{
while ((DEBUG_PORT->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) != 0);
*ptr = DEBUG_PORT->DAT;
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 ((int)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

View File

@@ -0,0 +1,893 @@
/****************************************************************************
* @file rtc.c
* @version V1.00
* @brief M251 series CLK driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.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 module and start counting
*
* @param[in] psPt Specify the time property and current date and time. It includes: \n
* u32Year: Year value, range between 2000 ~ 2099. \n
* u32Month: Month value, range between 1 ~ 12. \n
* u32Day: Day value, range between 1 ~ 31. \n
* u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
* RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
* RTC_SATURDAY] \n
* u32Hour: Hour value, range between 0 ~ 23. \n
* u32Minute: Minute value, range between 0 ~ 59. \n
* u32Second: Second value, range between 0 ~ 59. \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
* 3. User has to make sure that parameters of RTC date/time are reasonable. \n
* @note Null pointer for using default starting date/time.
*/
void RTC_Open(S_RTC_TIME_DATA_T *psPt)
{
RTC->INIT = RTC_INIT_KEY;
if (RTC->INIT != RTC_INIT_ACTIVE_Msk)
{
RTC->INIT = RTC_INIT_KEY;
while (RTC->INIT != RTC_INIT_ACTIVE_Msk)
{
}
}
if (psPt == 0)
{
/* No RTC date/time data */
}
else
{
/* Set RTC date and time */
RTC_SetDateAndTime(psPt);
}
}
/**
* @brief Disable RTC Clock
*
* @param None
*
* @return None
*
* @details This API will disable RTC peripheral clock and stops RTC counting.
*/
void RTC_Close(void)
{
CLK->APBCLK0 &= ~CLK_APBCLK0_RTCCKEN_Msk;
}
/**
* @brief Set Frequency Compensation Data
*
* @param[in] i32FrequencyX10000 Specify the RTC clock X 10000, ex: 327736512 means 32773.6512.
*
* @return None
*
*/
void RTC_32KCalibration(int32_t i32FrequencyX10000)
{
/*
Frequency counter measurement : 32773.6512 Hz
*/
uint32_t u32Index;
uint32_t u32Compensate;
/* 327736512 %10000 = 6512 */
u32Compensate = (uint32_t)(i32FrequencyX10000 % 10000);
/*Fraction Part: (6512 X 64)/10000 = 41.6768(0x2A) => RTC_FREQADJ[5:0]=0x2A*/
u32Compensate = ((u32Compensate * 64) / 10000);
u32Compensate &= 0x3F;
/*
Formula for 32K compensation is
FREQADJ = 0~0x00001F00 (Frequency range : 32752Hz ~ 32783Hz)
*/
if (i32FrequencyX10000 >= (uint32_t)327840000)
{
u32Compensate = 0x1F3F;
}
else if (i32FrequencyX10000 < (uint32_t)327520000)
{
u32Compensate = 0x0;
}
else
{
/* Integer Part: 32773 => RTC_FREQADJ[12:8] = 0x15 */
for (u32Index = 0; u32Index < 0x20 ; u32Index++)
{
if ((i32FrequencyX10000 >= 327520000 + (u32Index * 10000)) && (i32FrequencyX10000 < 327520000 + ((u32Index + 1) * 10000)))
{
u32Compensate += (u32Index << RTC_FREQADJ_INTEGER_Pos);
break;
}
}
}
RTC->FREQADJ = (uint32_t)u32Compensate;
}
/**
* @brief Get Current RTC Date and Time
*
* @param[out] psPt 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 *psPt)
{
uint32_t u32Tmp;
psPt->u32TimeScale = RTC->CLKFMT & RTC_CLKFMT_24HEN_Msk; /* 12/24-hour */
psPt->u32DayOfWeek = RTC->WEEKDAY & RTC_WEEKDAY_WEEKDAY_Msk; /* Day of the week */
/* Get [Date digit] data */
g_u32HiYear = (RTC->CAL & RTC_CAL_TENYEAR_Msk) >> RTC_CAL_TENYEAR_Pos;
g_u32LoYear = (RTC->CAL & RTC_CAL_YEAR_Msk) >> RTC_CAL_YEAR_Pos;
g_u32HiMonth = (RTC->CAL & RTC_CAL_TENMON_Msk) >> RTC_CAL_TENMON_Pos;
g_u32LoMonth = (RTC->CAL & RTC_CAL_MON_Msk) >> RTC_CAL_MON_Pos;
g_u32HiDay = (RTC->CAL & RTC_CAL_TENDAY_Msk) >> RTC_CAL_TENDAY_Pos;
g_u32LoDay = (RTC->CAL & RTC_CAL_DAY_Msk) >> RTC_CAL_DAY_Pos;
/* Get [Time digit] data */
g_u32HiHour = (RTC->TIME & RTC_TIME_TENHR_Msk) >> RTC_TIME_TENHR_Pos;
g_u32LoHour = (RTC->TIME & RTC_TIME_HR_Msk) >> RTC_TIME_HR_Pos;
g_u32HiMin = (RTC->TIME & RTC_TIME_TENMIN_Msk) >> RTC_TIME_TENMIN_Pos;
g_u32LoMin = (RTC->TIME & RTC_TIME_MIN_Msk) >> RTC_TIME_MIN_Pos;
g_u32HiSec = (RTC->TIME & RTC_TIME_TENSEC_Msk) >> RTC_TIME_TENSEC_Pos;
g_u32LoSec = (RTC->TIME & RTC_TIME_SEC_Msk) >> RTC_TIME_SEC_Pos;
/* Compute to 20XX year */
u32Tmp = (g_u32HiYear * 10ul);
u32Tmp += g_u32LoYear;
psPt->u32Year = u32Tmp + RTC_YEAR2000;
/* Compute 0~12 month */
u32Tmp = (g_u32HiMonth * 10ul);
psPt->u32Month = u32Tmp + g_u32LoMonth;
/* Compute 0~31 day */
u32Tmp = (g_u32HiDay * 10ul);
psPt->u32Day = u32Tmp + g_u32LoDay;
/* Compute 12/24 hour */
if (psPt->u32TimeScale == RTC_CLOCK_12)
{
u32Tmp = (g_u32HiHour * 10ul);
u32Tmp += g_u32LoHour;
psPt->u32Hour = u32Tmp; /* AM: 1~12. PM: 21~32. */
if (psPt->u32Hour >= 21ul)
{
psPt->u32AmPm = RTC_PM;
psPt->u32Hour -= 20ul;
}
else
{
psPt->u32AmPm = RTC_AM;
}
u32Tmp = (g_u32HiMin * 10ul);
u32Tmp += g_u32LoMin;
psPt->u32Minute = u32Tmp;
u32Tmp = (g_u32HiSec * 10ul);
u32Tmp += g_u32LoSec;
psPt->u32Second = u32Tmp;
}
else
{
u32Tmp = (g_u32HiHour * 10ul);
u32Tmp += g_u32LoHour;
psPt->u32Hour = u32Tmp;
u32Tmp = (g_u32HiMin * 10ul);
u32Tmp += g_u32LoMin;
psPt->u32Minute = u32Tmp;
u32Tmp = (g_u32HiSec * 10ul);
u32Tmp += g_u32LoSec;
psPt->u32Second = u32Tmp;
}
}
/**
* @brief Get RTC Alarm Date and Time
*
* @param[out] psPt 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 *psPt)
{
uint32_t u32Tmp;
psPt->u32TimeScale = RTC->CLKFMT & RTC_CLKFMT_24HEN_Msk; /* 12/24-hour */
psPt->u32DayOfWeek = RTC->WEEKDAY & RTC_WEEKDAY_WEEKDAY_Msk; /* Day of the week */
/* Get alarm [Date digit] data */
g_u32HiYear = (RTC->CALM & RTC_CALM_TENYEAR_Msk) >> RTC_CALM_TENYEAR_Pos;
g_u32LoYear = (RTC->CALM & RTC_CALM_YEAR_Msk) >> RTC_CALM_YEAR_Pos;
g_u32HiMonth = (RTC->CALM & RTC_CALM_TENMON_Msk) >> RTC_CALM_TENMON_Pos;
g_u32LoMonth = (RTC->CALM & RTC_CALM_MON_Msk) >> RTC_CALM_MON_Pos;
g_u32HiDay = (RTC->CALM & RTC_CALM_TENDAY_Msk) >> RTC_CALM_TENDAY_Pos;
g_u32LoDay = (RTC->CALM & RTC_CALM_DAY_Msk) >> RTC_CALM_DAY_Pos;
/* Get alarm [Time digit] data */
g_u32HiHour = (RTC->TALM & RTC_TALM_TENHR_Msk) >> RTC_TALM_TENHR_Pos;
g_u32LoHour = (RTC->TALM & RTC_TALM_HR_Msk) >> RTC_TALM_HR_Pos;
g_u32HiMin = (RTC->TALM & RTC_TALM_TENMIN_Msk) >> RTC_TALM_TENMIN_Pos;
g_u32LoMin = (RTC->TALM & RTC_TALM_MIN_Msk) >> RTC_TALM_MIN_Pos;
g_u32HiSec = (RTC->TALM & RTC_TALM_TENSEC_Msk) >> RTC_TALM_TENSEC_Pos;
g_u32LoSec = (RTC->TALM & RTC_TALM_SEC_Msk) >> RTC_TALM_SEC_Pos;
/* Compute to 20XX year */
u32Tmp = (g_u32HiYear * 10ul);
u32Tmp += g_u32LoYear;
psPt->u32Year = u32Tmp + RTC_YEAR2000;
/* Compute 0~12 month */
u32Tmp = (g_u32HiMonth * 10ul);
psPt->u32Month = u32Tmp + g_u32LoMonth;
/* Compute 0~31 day */
u32Tmp = (g_u32HiDay * 10ul);
psPt->u32Day = u32Tmp + g_u32LoDay;
/* Compute 12/24 hour */
if (psPt->u32TimeScale == RTC_CLOCK_12)
{
u32Tmp = (g_u32HiHour * 10ul);
u32Tmp += g_u32LoHour;
psPt->u32Hour = u32Tmp; /* AM: 1~12. PM: 21~32. */
if (psPt->u32Hour >= 21ul)
{
psPt->u32AmPm = RTC_PM;
psPt->u32Hour -= 20ul;
}
else
{
psPt->u32AmPm = RTC_AM;
}
u32Tmp = (g_u32HiMin * 10ul);
u32Tmp += g_u32LoMin;
psPt->u32Minute = u32Tmp;
u32Tmp = (g_u32HiSec * 10ul);
u32Tmp += g_u32LoSec;
psPt->u32Second = u32Tmp;
}
else
{
u32Tmp = (g_u32HiHour * 10ul);
u32Tmp += g_u32LoHour;
psPt->u32Hour = u32Tmp;
u32Tmp = (g_u32HiMin * 10ul);
u32Tmp += g_u32LoMin;
psPt->u32Minute = u32Tmp;
u32Tmp = (g_u32HiSec * 10ul);
u32Tmp += g_u32LoSec;
psPt->u32Second = u32Tmp;
}
}
/**
* @brief Update Current RTC Date and Time
*
* @param[in] psPt Specify the time property and current date and time. It includes: \n
* u32Year: Year value, range between 2000 ~ 2099. \n
* u32Month: Month value, range between 1 ~ 12. \n
* u32Day: Day value, range between 1 ~ 31. \n
* u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
* RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
* RTC_SATURDAY] \n
* u32Hour: Hour value, range between 0 ~ 23. \n
* u32Minute: Minute value, range between 0 ~ 59. \n
* u32Second: Second value, range between 0 ~ 59. \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 *psPt)
{
uint32_t u32RegCAL, u32RegTIME;
if (psPt == 0ul)
{
/* No RTC date/time data */
}
else
{
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC 24/12 hour setting and Day of the Week */
/*-----------------------------------------------------------------------------------------------------*/
if (psPt->u32TimeScale == RTC_CLOCK_12)
{
RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk;
/*-------------------------------------------------------------------------------------------------*/
/* Important, range of 12-hour PM mode is 21 up to 32 */
/*-------------------------------------------------------------------------------------------------*/
if (psPt->u32AmPm == RTC_PM)
{
psPt->u32Hour += 20ul;
}
}
else
{
RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk;
}
/* Set Day of the Week */
RTC->WEEKDAY = psPt->u32DayOfWeek;
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC Current Date and Time */
/*-----------------------------------------------------------------------------------------------------*/
u32RegCAL = ((psPt->u32Year - RTC_YEAR2000) / 10ul) << 20;
u32RegCAL |= (((psPt->u32Year - RTC_YEAR2000) % 10ul) << 16);
u32RegCAL |= ((psPt->u32Month / 10ul) << 12);
u32RegCAL |= ((psPt->u32Month % 10ul) << 8);
u32RegCAL |= ((psPt->u32Day / 10ul) << 4);
u32RegCAL |= (psPt->u32Day % 10ul);
u32RegTIME = ((psPt->u32Hour / 10ul) << 20);
u32RegTIME |= ((psPt->u32Hour % 10ul) << 16);
u32RegTIME |= ((psPt->u32Minute / 10ul) << 12);
u32RegTIME |= ((psPt->u32Minute % 10ul) << 8);
u32RegTIME |= ((psPt->u32Second / 10ul) << 4);
u32RegTIME |= (psPt->u32Second % 10ul);
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC Calender and Time Loading */
/*-----------------------------------------------------------------------------------------------------*/
RTC->CAL = (uint32_t)u32RegCAL;
RTC->TIME = (uint32_t)u32RegTIME;
}
}
/**
* @brief Update RTC Alarm Date and Time
*
* @param[in] psPt Specify the time property and alarm date and time. It includes: \n
* u32Year: Year value, range between 2000 ~ 2099. \n
* u32Month: Month value, range between 1 ~ 12. \n
* u32Day: Day value, range between 1 ~ 31. \n
* u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
* RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
* RTC_SATURDAY] \n
* u32Hour: Hour value, range between 0 ~ 23. \n
* u32Minute: Minute value, range between 0 ~ 59. \n
* u32Second: Second value, range between 0 ~ 59. \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 *psPt)
{
uint32_t u32RegCALM, u32RegTALM;
if (psPt == 0)
{
/* No RTC date/time data */
}
else
{
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC 24/12 hour setting and Day of the Week */
/*-----------------------------------------------------------------------------------------------------*/
if (psPt->u32TimeScale == RTC_CLOCK_12)
{
RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk;
/*-------------------------------------------------------------------------------------------------*/
/* Important, range of 12-hour PM mode is 21 up to 32 */
/*-------------------------------------------------------------------------------------------------*/
if (psPt->u32AmPm == RTC_PM)
{
psPt->u32Hour += 20ul;
}
}
else
{
RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk;
}
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC Alarm Date and Time */
/*-----------------------------------------------------------------------------------------------------*/
u32RegCALM = ((psPt->u32Year - RTC_YEAR2000) / 10ul) << 20;
u32RegCALM |= (((psPt->u32Year - RTC_YEAR2000) % 10ul) << 16);
u32RegCALM |= ((psPt->u32Month / 10ul) << 12);
u32RegCALM |= ((psPt->u32Month % 10ul) << 8);
u32RegCALM |= ((psPt->u32Day / 10ul) << 4);
u32RegCALM |= (psPt->u32Day % 10ul);
u32RegTALM = ((psPt->u32Hour / 10ul) << 20);
u32RegTALM |= ((psPt->u32Hour % 10ul) << 16);
u32RegTALM |= ((psPt->u32Minute / 10ul) << 12);
u32RegTALM |= ((psPt->u32Minute % 10ul) << 8);
u32RegTALM |= ((psPt->u32Second / 10ul) << 4);
u32RegTALM |= (psPt->u32Second % 10ul);
RTC->CALM = (uint32_t)u32RegCALM;
RTC->TALM = (uint32_t)u32RegTALM;
}
}
/**
* @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 u32RegCAL;
u32RegCAL = ((u32Year - RTC_YEAR2000) / 10ul) << 20;
u32RegCAL |= (((u32Year - RTC_YEAR2000) % 10ul) << 16);
u32RegCAL |= ((u32Month / 10ul) << 12);
u32RegCAL |= ((u32Month % 10ul) << 8);
u32RegCAL |= ((u32Day / 10ul) << 4);
u32RegCAL |= (u32Day % 10ul);
/* Set Day of the Week */
RTC->WEEKDAY = u32DayOfWeek & RTC_WEEKDAY_WEEKDAY_Msk;
/* Set RTC Calender Loading */
RTC->CAL = (uint32_t)u32RegCAL;
}
/**
* @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 u32RegTIME;
/* Important, range of 12-hour PM mode is 21 up to 32 */
if ((u32TimeMode == RTC_CLOCK_12) && (u32AmPm == RTC_PM))
{
u32Hour += 20ul;
}
u32RegTIME = ((u32Hour / 10ul) << 20);
u32RegTIME |= ((u32Hour % 10ul) << 16);
u32RegTIME |= ((u32Minute / 10ul) << 12);
u32RegTIME |= ((u32Minute % 10ul) << 8);
u32RegTIME |= ((u32Second / 10ul) << 4);
u32RegTIME |= (u32Second % 10ul);
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC 24/12 hour setting and Day of the Week */
/*-----------------------------------------------------------------------------------------------------*/
if (u32TimeMode == RTC_CLOCK_12)
{
RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk;
}
else
{
RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk;
}
RTC->TIME = (uint32_t)u32RegTIME;
}
/**
* @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 u32RegCALM;
u32RegCALM = ((u32Year - RTC_YEAR2000) / 10ul) << 20;
u32RegCALM |= (((u32Year - RTC_YEAR2000) % 10ul) << 16);
u32RegCALM |= ((u32Month / 10ul) << 12);
u32RegCALM |= ((u32Month % 10ul) << 8);
u32RegCALM |= ((u32Day / 10ul) << 4);
u32RegCALM |= (u32Day % 10ul);
/* Set RTC Alarm Date */
RTC->CALM = (uint32_t)u32RegCALM;
}
/**
* @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 u32RegTALM;
/* Important, range of 12-hour PM mode is 21 up to 32 */
if ((u32TimeMode == (uint32_t)RTC_CLOCK_12) && (u32AmPm == (uint32_t)RTC_PM))
{
u32Hour += 20ul;
}
u32RegTALM = ((u32Hour / 10ul) << 20);
u32RegTALM |= ((u32Hour % 10ul) << 16);
u32RegTALM |= ((u32Minute / 10ul) << 12);
u32RegTALM |= ((u32Minute % 10ul) << 8);
u32RegTALM |= ((u32Second / 10ul) << 4);
u32RegTALM |= (u32Second % 10ul);
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC 24/12 hour setting and Day of the Week */
/*-----------------------------------------------------------------------------------------------------*/
if (u32TimeMode == (uint32_t)RTC_CLOCK_12)
{
RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk;
}
else
{
RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk;
}
/* Set RTC Alarm Time */
RTC->TALM = (uint32_t)u32RegTALM;
}
/**
* @brief Set RTC Alarm Date Mask Function
*
* @param[in] u8IsTenYMsk 1: enable 10-Year digit alarm mask; 0: disabled.
* @param[in] u8IsYMsk 1: enable 1-Year digit alarm mask; 0: disabled.
* @param[in] u8IsTenMMsk 1: enable 10-Mon digit alarm mask; 0: disabled.
* @param[in] u8IsMMsk 1: enable 1-Mon digit alarm mask; 0: disabled.
* @param[in] u8IsTenDMsk 1: enable 10-Day digit alarm mask; 0: disabled.
* @param[in] u8IsDMsk 1: enable 1-Day digit alarm mask; 0: disabled.
*
* @return None
*
* @details This API is used to enable or disable RTC alarm date mask function.
*/
void RTC_SetAlarmDateMask(uint8_t u8IsTenYMsk, uint8_t u8IsYMsk, uint8_t u8IsTenMMsk, uint8_t u8IsMMsk, uint8_t u8IsTenDMsk, uint8_t u8IsDMsk)
{
RTC->CAMSK = ((uint32_t)u8IsTenYMsk << RTC_CAMSK_MTENYEAR_Pos) |
((uint32_t)u8IsYMsk << RTC_CAMSK_MYEAR_Pos) |
((uint32_t)u8IsTenMMsk << RTC_CAMSK_MTENMON_Pos) |
((uint32_t)u8IsMMsk << RTC_CAMSK_MMON_Pos) |
((uint32_t)u8IsTenDMsk << RTC_CAMSK_MTENDAY_Pos) |
((uint32_t)u8IsDMsk << RTC_CAMSK_MDAY_Pos);
}
/**
* @brief Set RTC Alarm Time Mask Function
*
* @param[in] u8IsTenHMsk 1: enable 10-Hour digit alarm mask; 0: disabled.
* @param[in] u8IsHMsk 1: enable 1-Hour digit alarm mask; 0: disabled.
* @param[in] u8IsTenMMsk 1: enable 10-Min digit alarm mask; 0: disabled.
* @param[in] u8IsMMsk 1: enable 1-Min digit alarm mask; 0: disabled.
* @param[in] u8IsTenSMsk 1: enable 10-Sec digit alarm mask; 0: disabled.
* @param[in] u8IsSMsk 1: enable 1-Sec digit alarm mask; 0: disabled.
*
* @return None
*
* @details This API is used to enable or disable RTC alarm time mask function.
*/
void RTC_SetAlarmTimeMask(uint8_t u8IsTenHMsk, uint8_t u8IsHMsk, uint8_t u8IsTenMMsk, uint8_t u8IsMMsk, uint8_t u8IsTenSMsk, uint8_t u8IsSMsk)
{
RTC->TAMSK = ((uint32_t)u8IsTenHMsk << RTC_TAMSK_MTENHR_Pos) |
((uint32_t)u8IsHMsk << RTC_TAMSK_MHR_Pos) |
((uint32_t)u8IsTenMMsk << RTC_TAMSK_MTENMIN_Pos) |
((uint32_t)u8IsMMsk << RTC_TAMSK_MMIN_Pos) |
((uint32_t)u8IsTenSMsk << RTC_TAMSK_MTENSEC_Pos) |
((uint32_t)u8IsSMsk << RTC_TAMSK_MSEC_Pos);
}
/**
* @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 date.
*/
uint32_t RTC_GetDayOfWeek(void)
{
return (RTC->WEEKDAY & RTC_WEEKDAY_WEEKDAY_Msk);
}
/**
* @brief Set RTC Tick Period Time
*
* @param[in] u32TickSelection It is used to set the RTC tick period time for Periodic Time Tick request. \n
* It consists of:
* - \ref RTC_TICK_1_SEC : Time tick is 1 second
* - \ref RTC_TICK_1_2_SEC : Time tick is 1/2 second
* - \ref RTC_TICK_1_4_SEC : Time tick is 1/4 second
* - \ref RTC_TICK_1_8_SEC : Time tick is 1/8 second
* - \ref RTC_TICK_1_16_SEC : Time tick is 1/16 second
* - \ref RTC_TICK_1_32_SEC : Time tick is 1/32 second
* - \ref RTC_TICK_1_64_SEC : Time tick is 1/64 second
* - \ref RTC_TICK_1_128_SEC : Time tick is 1/128 second
*
* @return None
*
* @details This API is used to set RTC tick period time for each tick interrupt.
*/
void RTC_SetTickPeriod(uint32_t u32TickSelection)
{
RTC->TICK = (RTC->TICK & ~RTC_TICK_TICK_Msk) | u32TickSelection;
}
/**
* @brief Enable RTC Interrupt
*
* @param[in] u32IntFlagMask Specify the interrupt source. It consists of:
* - \ref RTC_INTEN_ALMIEN_Msk : Alarm interrupt
* - \ref RTC_INTEN_TICKIEN_Msk : Tick interrupt
* - \ref RTC_INTEN_TAMP0IEN_Msk : Tamper 0 Pin Event Detection interrupt
*
* @return None
*
* @details This API is used to enable the specify RTC interrupt function.
*/
void RTC_EnableInt(uint32_t u32IntFlagMask)
{
RTC->INTEN |= u32IntFlagMask;
}
/**
* @brief Disable RTC Interrupt
*
* @param[in] u32IntFlagMask Specify the interrupt source. It consists of:
* - \ref RTC_INTEN_ALMIEN_Msk : Alarm interrupt
* - \ref RTC_INTEN_TICKIEN_Msk : Tick interrupt
* - \ref RTC_INTEN_TAMP0IEN_Msk : Tamper 0 Pin Event Detection interrupt
*
* @return None
*
* @details This API is used to disable the specify RTC interrupt function.
*/
void RTC_DisableInt(uint32_t u32IntFlagMask)
{
RTC->INTEN &= ~u32IntFlagMask;
RTC->INTSTS = u32IntFlagMask;
}
/**
* @brief Enable Spare Registers Access
*
* @param None
*
* @return None
*
* @details This API is used to enable the spare registers 0~4 can be accessed.
*/
void RTC_EnableSpareAccess(void)
{
RTC->SPRCTL |= RTC_SPRCTL_SPRRWEN_Msk;
}
/**
* @brief Disable Spare Register
*
* @param None
*
* @return None
*
* @details This API is used to disable the spare register 0~4 cannot be accessed.
*/
void RTC_DisableSpareRegister(void)
{
RTC->SPRCTL &= ~RTC_SPRCTL_SPRRWEN_Msk;
}
/**
* @brief Static Tamper Detect
*
* @param[in] u32TamperSelect Tamper pin select. Possible options are
* - \ref RTC_TAMPER0_SELECT
*
* @param[in] u32DetecLevel Tamper pin detection level select. Possible options are
* - \ref RTC_TAMPER_HIGH_LEVEL_DETECT
* - \ref RTC_TAMPER_LOW_LEVEL_DETECT
*
* @param[in] u32DebounceEn Tamper pin de-bounce enable
* - \ref RTC_TAMPER_DEBOUNCE_ENABLE
* - \ref RTC_TAMPER_DEBOUNCE_DISABLE
*
* @return None
*
* @details This API is used to enable the tamper pin detect function with specify trigger condition.
*/
void RTC_StaticTamperEnable(uint32_t u32TamperSelect, uint32_t u32DetecLevel, uint32_t u32DebounceEn)
{
uint32_t u32Loop;
uint32_t u32Reg;
uint32_t u32TmpReg;
u32Reg = RTC->TAMPCTL;
u32TmpReg = (RTC_TAMPCTL_TAMP0EN_Msk | (u32DetecLevel << RTC_TAMPCTL_TAMP0LV_Pos) |
(u32DebounceEn << RTC_TAMPCTL_TAMP0DBEN_Pos));
for (u32Loop = 0ul; u32Loop < MAX_TAMPER_PIN_NUM; u32Loop++)
{
if (u32TamperSelect & (0x1ul << u32Loop))
{
u32Reg &= ~((RTC_TAMPCTL_TAMP0EN_Msk | RTC_TAMPCTL_TAMP0LV_Msk | RTC_TAMPCTL_TAMP0DBEN_Msk) << (u32Loop * 4ul));
u32Reg |= (u32TmpReg << (u32Loop * 4ul));
}
}
RTC->TAMPCTL = u32Reg;
}
/**
* @brief Static Tamper Disable
*
* @param[in] u32TamperSelect Tamper pin select. Possible options are
* - \ref RTC_TAMPER0_SELECT
*
* @return None
*
* @details This API is used to disable the static tamper pin detect.
*/
void RTC_StaticTamperDisable(uint32_t u32TamperSelect)
{
uint32_t u32Loop;
uint32_t u32Reg;
uint32_t u32TmpReg;
u32Reg = RTC->TAMPCTL;
u32TmpReg = (RTC_TAMPCTL_TAMP0EN_Msk);
for (u32Loop = 0ul; u32Loop < MAX_TAMPER_PIN_NUM; u32Loop++)
{
if (u32TamperSelect & (0x1ul << u32Loop))
{
u32Reg &= ~(u32TmpReg << (u32Loop * 4ul));
}
}
RTC->TAMPCTL = u32Reg;
}
/*@}*/ /* end of group RTC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group RTC_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,463 @@
/**************************************************************************//**
* @file sc.c
* @version V3.00
* @brief Smart Card(SC) driver source file
*
* @note
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.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] = {0UL};
/** @endcond HIDDEN_SYMBOLS */
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup SC_Driver SC Driver
@{
*/
/** @addtogroup SC_EXPORTED_FUNCTIONS SC Exported Functions
@{
*/
/**
* @brief Check Smartcard Slot Status
*
* @param[in] psSC The pointer of smartcard module.
*
* @retval TRUE Card insert
* @retval FALSE Card remove
*
* @details This function is used to check if specified smartcard slot is presented.
*/
uint32_t SC_IsCardInserted(SC_T *psSC)
{
uint32_t ret;
/* put conditions into two variable to remove IAR compilation warning */
uint32_t cond1 = ((psSC->STATUS & SC_STATUS_CDPINSTS_Msk) >> SC_STATUS_CDPINSTS_Pos);
uint32_t cond2 = ((psSC->CTL & SC_CTL_CDLV_Msk) >> SC_CTL_CDLV_Pos);
if ((psSC == SC0) && (u32CardStateIgnore[0] == 1UL))
{
ret = (uint32_t)TRUE;
}
else if (cond1 != cond2)
{
ret = (uint32_t)FALSE;
}
else
{
ret = (uint32_t)TRUE;
}
return ret;
}
/*
* @brief Reset the Tx/Rx FIFO
*
* @param[in] psSC 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 *psSC)
{
while (psSC->ALTCTL & SC_ALTCTL_SYNC_Msk)
{
;
}
psSC->ALTCTL |= (SC_ALTCTL_TXRST_Msk | SC_ALTCTL_RXRST_Msk);
}
/**
* @brief Disable specified Smartcard
*
* @param[in] psSC The pointer of smartcard module.
*
* @return None
*
* @details SC will force all transition to IDLE state.
*/
void SC_Close(SC_T *psSC)
{
psSC->INTEN = 0UL;
while (psSC->PINCTL & SC_PINCTL_SYNC_Msk)
{
;
}
psSC->PINCTL = 0UL;
psSC->ALTCTL = 0UL;
while (psSC->CTL & SC_CTL_SYNC_Msk)
{
;
}
psSC->CTL = 0UL;
}
/**
* @brief Initialized Smartcard
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32CardDet Card detect polarity, select the SC_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 SC_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 *psSC, uint32_t u32CardDet, uint32_t u32PWR)
{
uint32_t u32Reg = 0UL, u32Intf;
if (psSC == SC0)
{
u32Intf = 0UL;
}
else
{
u32Intf = 2UL;
}
if (u32CardDet != SC_PIN_STATE_IGNORE)
{
u32Reg = u32CardDet ? 0UL : SC_CTL_CDLV_Msk;
u32CardStateIgnore[u32Intf] = 0UL;
}
else
{
u32CardStateIgnore[u32Intf] = 1UL;
}
psSC->PINCTL = u32PWR ? 0UL : SC_PINCTL_PWRINV_Msk;
while (psSC->CTL & SC_CTL_SYNC_Msk)
{
;
}
psSC->CTL = SC_CTL_SCEN_Msk | u32Reg;
}
/**
* @brief Reset specified Smartcard
*
* @param[in] psSC The pointer of smartcard module.
*
* @return None
*
* @details Reset the Tx/Rx FIFO, clock and initial default parameter.
*/
void SC_ResetReader(SC_T *psSC)
{
uint32_t u32Intf;
if (psSC == SC0)
{
u32Intf = 0UL;
}
else
{
u32Intf = 2UL;
}
/* Reset FIFO, enable auto de-activation while card removal */
psSC->ALTCTL |= (SC_ALTCTL_TXRST_Msk | SC_ALTCTL_RXRST_Msk | SC_ALTCTL_ADACEN_Msk);
/* Set Rx trigger level to 1 character, longest card detect debounce period, disable error retry (EMV ATR does not use error retry) */
while (psSC->CTL & SC_CTL_SYNC_Msk)
{
;
}
psSC->CTL &= ~(SC_CTL_RXTRGLV_Msk |
SC_CTL_CDDBSEL_Msk |
SC_CTL_TXRTY_Msk |
SC_CTL_TXRTYEN_Msk |
SC_CTL_RXRTY_Msk |
SC_CTL_RXRTYEN_Msk);
while (psSC->CTL & SC_CTL_SYNC_Msk)
{
;
}
/* Enable auto convention, and all three smartcard internal timers */
psSC->CTL |= SC_CTL_AUTOCEN_Msk | SC_CTL_TMRSEL_Msk;
/* Disable Rx timeout */
psSC->RXTOUT = 0UL;
/* 372 clocks per ETU by default */
psSC->ETUCTL = 371UL;
/* Enable necessary interrupt for smartcard operation */
if (u32CardStateIgnore[u32Intf]) /* Do not enable card detect interrupt if card present state ignore */
{
psSC->INTEN = (SC_INTEN_RDAIEN_Msk |
SC_INTEN_TERRIEN_Msk |
SC_INTEN_TMR0IEN_Msk |
SC_INTEN_TMR1IEN_Msk |
SC_INTEN_TMR2IEN_Msk |
SC_INTEN_BGTIEN_Msk |
SC_INTEN_ACERRIEN_Msk);
}
else
{
psSC->INTEN = (SC_INTEN_RDAIEN_Msk |
SC_INTEN_TERRIEN_Msk |
SC_INTEN_TMR0IEN_Msk |
SC_INTEN_TMR1IEN_Msk |
SC_INTEN_TMR2IEN_Msk |
SC_INTEN_BGTIEN_Msk |
SC_INTEN_ACERRIEN_Msk |
SC_INTEN_CDIEN_Msk);
}
return;
}
/**
* @brief Set Block Guard Time
*
* @param[in] psSC 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 is used to configure block guard time (BGT) of specified smartcard module.
*/
void SC_SetBlockGuardTime(SC_T *psSC, uint32_t u32BGT)
{
psSC->CTL = (psSC->CTL & ~SC_CTL_BGT_Msk) | ((u32BGT - 1UL) << SC_CTL_BGT_Pos);
}
/**
* @brief Set Character Guard Time
*
* @param[in] psSC 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 is used to configure 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 *psSC, uint32_t u32CGT)
{
/* CGT is "START bit" + "8-bits" + "Parity bit" + "STOP bit(s)" + "EGT counts" */
u32CGT -= psSC->CTL & SC_CTL_NSB_Msk ? 11UL : 12UL;
psSC->EGT = u32CGT;
}
/**
* @brief Stop all Timer Counting
*
* @param[in] psSC 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 *psSC)
{
while (psSC->ALTCTL & SC_ALTCTL_SYNC_Msk)
{
;
}
psSC->ALTCTL &= ~(SC_ALTCTL_CNTEN0_Msk | SC_ALTCTL_CNTEN1_Msk | SC_ALTCTL_CNTEN2_Msk);
}
/**
* @brief Configure and Start specified Timer
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32TimerNum Specify time channel 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 ~ 0x1000000 ETUs.
* 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 *psSC, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount)
{
uint32_t reg = u32Mode | (SC_TMRCTL0_CNT_Msk & (u32ETUCount - 1UL));
/* before to set CNTEN0/1/2 of reg. ALTCTL, SCEN bit must be enabled */
if (u32TimerNum <= 2)
{
while (psSC->CTL & SC_CTL_SYNC_Msk) {};
psSC->CTL |= SC_CTL_TMRSEL_Msk | SC_CTL_SCEN_Msk;
while (psSC->CTL & SC_CTL_SYNC_Msk) {};
while (psSC->ALTCTL & SC_ALTCTL_SYNC_Msk) {};
}
switch (u32TimerNum)
{
case 0UL:
while (psSC->TMRCTL0 & SC_TMRCTL0_SYNC_Msk) {};
psSC->TMRCTL0 = reg;
psSC->ALTCTL |= SC_ALTCTL_CNTEN0_Msk;
break;
case 1UL:
while (psSC->TMRCTL1 & SC_TMRCTL1_SYNC_Msk) {};
psSC->TMRCTL1 = reg;
psSC->ALTCTL |= SC_ALTCTL_CNTEN1_Msk;
break;
case 2UL:
while (psSC->TMRCTL2 & SC_TMRCTL2_SYNC_Msk) {};
psSC->TMRCTL2 = reg;
psSC->ALTCTL |= SC_ALTCTL_CNTEN2_Msk;
break;
default:
break;
}
}
/**
* @brief Stop specified Timer Counting
*
* @param[in] psSC The pointer of smartcard module.
* @param[in] u32TimerNum Specify timer channel 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 *psSC, uint32_t u32TimerNum)
{
while (psSC->ALTCTL & SC_ALTCTL_SYNC_Msk) {}
if (u32TimerNum == 0UL) /* timer 0 */
{
psSC->ALTCTL &= ~SC_ALTCTL_CNTEN0_Msk;
}
else if (u32TimerNum == 1UL) /* timer 1 */
{
psSC->ALTCTL &= ~SC_ALTCTL_CNTEN1_Msk;
}
else /* timer 2 */
{
psSC->ALTCTL &= ~SC_ALTCTL_CNTEN2_Msk;
}
}
/**
* @brief Get specified Smartcard Clock Frequency
*
* @param[in] psSC The pointer of smartcard module.
*
* @return Smartcard frequency in kHZ
*
* @details This function is used to get specified smartcard module clock frequency in kHz.
*/
uint32_t SC_GetInterfaceClock(SC_T *psSC)
{
uint32_t u32ClkSrc, u32Num, u32Clk = __HIRC, u32Div;
/* Get smartcard module clock source and divider */
if (psSC == SC0)
{
u32Num = 0UL;
u32ClkSrc = CLK_GetModuleClockSource(SC0_MODULE);
u32Div = CLK_GetModuleClockDivider(SC0_MODULE);
// u32ClkSrc = __HXT;
// u32Div = SC0->ETUCTL&SC_ETUCTL_ETURDIV_Msk;
}
else
{
u32Clk = 0UL;
}
if (u32Clk == 0UL)
{
; /* Invalid sc port */
}
else
{
/* Get smartcard module clock */
if (u32ClkSrc == 0UL)
{
u32Clk = __HXT;
}
else if (u32ClkSrc == 1UL)
{
u32Clk = CLK_GetPLLClockFreq();
}
else if (u32ClkSrc == 2UL)
{
if (u32Num == 1UL)
{
u32Clk = CLK_GetPCLK1Freq();
}
else
{
u32Clk = CLK_GetPCLK0Freq();
}
}
else
{
u32Clk = __HIRC;
}
u32Clk /= (u32Div + 1UL) * 1000UL;
}
return u32Clk;
}
/*@}*/ /* end of group SC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SC_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,239 @@
/**************************************************************************//**
* @file scuart.c
* @brief M251 Smartcard UART mode (SCUART) driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
static uint32_t SCUART_GetClock(SC_T *sc);
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup SCUART_Driver SCUART Driver
@{
*/
/** @addtogroup SCUART_EXPORTED_FUNCTIONS SCUART Exported Functions
@{
*/
/**
* @brief The function is used to disable smartcard interface UART mode.
* @param sc The base address of smartcard module.
* @return None
*/
void SCUART_Close(SC_T *sc)
{
sc->INTEN = 0UL;
sc->UARTCTL = 0UL;
sc->CTL = 0UL;
}
/** @cond HIDDEN_SYMBOLS */
/**
* @brief This function returns module clock of specified SC interface
* @param[in] sc The base address of smartcard module.
* @return Module clock of specified SC interface
*/
static uint32_t SCUART_GetClock(SC_T *sc)
{
uint32_t u32ClkSrc, u32Num, u32Clk;
if (sc == SC0)
{
u32Num = 0UL;
}
else
{
u32Num = 2UL;
}
u32ClkSrc = (CLK->CLKSEL3 >> (2UL * u32Num)) & CLK_CLKSEL3_SC0SEL_Msk;
/* Get smartcard module clock */
if (u32ClkSrc == 0UL)
{
u32Clk = __HXT;
}
else if (u32ClkSrc == 1UL)
{
u32Clk = CLK_GetPLLClockFreq();
}
else if (u32ClkSrc == 2UL)
{
if (u32Num == 1UL)
{
u32Clk = CLK_GetPCLK1Freq();
}
else
{
u32Clk = CLK_GetPCLK0Freq();
}
}
else
{
u32Clk = __HIRC;
}
u32Clk /= (((CLK->CLKDIV1 >> (8UL * u32Num)) & CLK_CLKDIV1_SC0DIV_Msk) + 1UL);
return u32Clk;
}
/** @endcond HIDDEN_SYMBOLS */
/**
* @brief This function use to enable smartcard module UART mode and set baudrate.
* @param[in] sc The base address of smartcard module.
* @param[in] u32baudrate Target baudrate of smartcard module.
* @return Actual baudrate of smartcard mode
* @details This function configures character width to 8 bits, 1 stop bit, and no parity.
* And can use \ref SCUART_SetLineConfig function to update these settings
* The baudrate clock source comes from SC_CLK/SC_DIV, where SC_CLK is controlled
* by SCxSEL in CLKSEL3 register, SC_DIV is controlled by SCxDIV in CLKDIV1
* register. Since the baudrate divider is 12-bit wide and must be larger than 4,
* (clock source / baudrate) must be larger or equal to 5 and smaller or equal to
* 4096. Otherwise this function cannot configure SCUART to work with target baudrate.
*/
uint32_t SCUART_Open(SC_T *sc, uint32_t u32baudrate)
{
uint32_t u32Clk = SCUART_GetClock(sc), u32Div;
/* Calculate divider for target baudrate */
u32Div = (u32Clk + (u32baudrate >> 1) - 1UL) / u32baudrate - 1UL;
/* Enable smartcard interface and stop bit = 1 */
sc->CTL = SC_CTL_SCEN_Msk | SC_CTL_NSB_Msk;
/* Enable UART mode, disable parity and 8 bit per character */
sc->UARTCTL = SCUART_CHAR_LEN_8 | SCUART_PARITY_NONE | SC_UARTCTL_UARTEN_Msk;
sc->ETUCTL = u32Div;
return (u32Clk / (u32Div + 1UL));
}
/**
* @brief The function is used to read Rx data from RX FIFO.
* @param[in] sc The base address of smartcard module.
* @param[in] pu8RxBuf The buffer to store receive the data
* @param[in] u32ReadBytes Target number of characters to receive
* @return Actual character number reads to buffer
* @note This function does not block and return immediately if there's no data available
*/
uint32_t SCUART_Read(SC_T *sc, uint8_t pu8RxBuf[], uint32_t u32ReadBytes)
{
uint32_t u32Count;
for (u32Count = 0UL; u32Count < u32ReadBytes; u32Count++)
{
if (SCUART_GET_RX_EMPTY(sc)) /* no data available */
{
break;
}
pu8RxBuf[u32Count] = (uint8_t)SCUART_READ(sc); /* get data from FIFO */
}
return u32Count;
}
/**
* @brief This function use to configure smartcard UART mode line setting.
* @param[in] sc The base address of smartcard module.
* @param[in] u32Baudrate Target baudrate of smartcard module. If this value is 0, UART baudrate will not change.
* @param[in] u32DataWidth The data length, could be
* - \ref SCUART_CHAR_LEN_5
* - \ref SCUART_CHAR_LEN_6
* - \ref SCUART_CHAR_LEN_7
* - \ref SCUART_CHAR_LEN_8
* @param[in] u32Parity The parity setting, could be
* - \ref SCUART_PARITY_NONE
* - \ref SCUART_PARITY_ODD
* - \ref SCUART_PARITY_EVEN
* @param[in] u32StopBits The stop bit length, could be
* - \ref SCUART_STOP_BIT_1
* - \ref SCUART_STOP_BIT_2
* @return Actual baudrate of smartcard
* @details The baudrate clock source comes from SC_CLK/SC_DIV, where SC_CLK is controlled
* by SCxSEL in CLKSEL3 register, SC_DIV is controlled by SCxDIV in CLKDIV1
* register. Since the baudrate divider is 12-bit wide and must be larger than 4,
* (clock source / baudrate) must be larger or equal to 5 and smaller or equal to
* 4096. Otherwise this function cannot configure SCUART to work with target baudrate.
*/
uint32_t SCUART_SetLineConfig(SC_T *sc, uint32_t u32Baudrate, uint32_t u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits)
{
uint32_t u32Clk = SCUART_GetClock(sc), u32Div;
if (u32Baudrate == 0UL) /* keep original baudrate setting */
{
u32Div = sc->ETUCTL & SC_ETUCTL_ETURDIV_Msk;
}
else
{
/* Calculate divider for target baudrate */
u32Div = (u32Clk + (u32Baudrate >> 1) - 1UL) / u32Baudrate - 1UL;
sc->ETUCTL = u32Div;
}
/* Set stop bit */
sc->CTL = u32StopBits | SC_CTL_SCEN_Msk;
/* Set character width and parity */
sc->UARTCTL = u32Parity | u32DataWidth | SC_UARTCTL_UARTEN_Msk;
return (u32Clk / (u32Div + 1UL));
}
/**
* @brief This function use to set receive timeout count.
* @param[in] sc The base address of smartcard module.
* @param[in] u32TOC Rx timeout counter, using baudrate as counter unit. Valid range are 0~0x1FF,
* set this value to 0 will disable timeout counter
* @return None
* @details The time-out counter resets and starts counting whenever the RX buffer received a
* new data word. Once the counter decrease to 1 and no new data is received or CPU
* does not read any data from FIFO, a receiver time-out interrupt will be generated.
*/
void SCUART_SetTimeoutCnt(SC_T *sc, uint32_t u32TOC)
{
sc->RXTOUT = u32TOC;
}
/**
* @brief This function is to write data into transmit FIFO to send data out.
* @param[in] sc The base address of smartcard module.
* @param[in] pu8TxBuf The buffer containing data to send to transmit FIFO.
* @param[in] u32WriteBytes Number of data to send.
* @return None
* @note This function blocks until all data write into FIFO
*/
void SCUART_Write(SC_T *sc, uint8_t pu8TxBuf[], uint32_t u32WriteBytes)
{
uint32_t u32Count;
for (u32Count = 0UL; u32Count != u32WriteBytes; u32Count++)
{
/* Wait 'til FIFO not full */
while (SCUART_GET_TX_FULL(sc))
{
;
}
/* Write 1 byte to FIFO */
sc->DAT = pu8TxBuf[u32Count];
}
}
/*@}*/ /* end of group SCUART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SCUART_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,221 @@
/****************************************************************************
* @file sys.c
* @version V1.10
* @brief M251 series SYS driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
/** @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_RSTSTS_VBATLVRF_Msk
* - \ref SYS_RSTSTS_CPULKRF_Msk
* - \ref SYS_RSTSTS_CPURF_Msk
* - \ref SYS_RSTSTS_PMURF_Msk
* - \ref SYS_RSTSTS_SYSRF_Msk
* - \ref SYS_RSTSTS_BODRF_Msk
* - \ref SYS_RSTSTS_LVRF_Msk
* - \ref SYS_RSTSTS_WDTRF_Msk
* - \ref SYS_RSTSTS_PINRF_Msk
* - \ref SYS_RSTSTS_PORF_Msk
* @return None
* @details This function clear the selected system reset source.
*/
void SYS_ClearResetSrc(uint32_t u32Src)
{
SYS->RSTSTS |= 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.
*/
uint32_t SYS_GetBODStatus(void)
{
return ((SYS->BODCTL & SYS_BODCTL_BODOUT_Msk) >> SYS_BODCTL_BODOUT_Pos);
}
/**
* @brief Get reset status register value
* @param None
* @return Reset source
* @details This function get the system reset status register value.
*/
uint32_t SYS_GetResetSrc(void)
{
return (SYS->RSTSTS);
}
/**
* @brief Check if register is locked nor not
* @param None
* @retval 0 Write-protection function is disabled.
* 1 Write-protection function is enabled.
* @details This function check register write-protection bit setting.
*/
uint32_t SYS_IsRegLocked(void)
{
return !(SYS->REGLCTL & 0x1UL);
}
/**
* @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.
* The register write-protection function should be disabled before using this function.
*/
void SYS_ResetChip(void)
{
SYS->IPRST0 |= SYS_IPRST0_CHIPRST_Msk;
}
/**
* @brief Reset chip with CPU reset
* @param None
* @return None
* @details This function reset CPU with CPU reset.
* The register write-protection function should be disabled before using this function.
*/
void SYS_ResetCPU(void)
{
SYS->IPRST0 |= SYS_IPRST0_CPURST_Msk;
}
/**
* @brief Reset selected module
* @param[in] u32ModuleIndex is module index. Including :
* - \ref PDMA_RST
* - \ref EBI_RST
* - \ref CRC_RST
* - \ref CRPT_RST
* - \ref GPIO_RST
* - \ref TMR0_RST
* - \ref TMR1_RST
* - \ref TMR2_RST
* - \ref TMR3_RST
* - \ref ACMP01_RST
* - \ref I2C0_RST
* - \ref I2C1_RST
* - \ref QSPI0_RST
* - \ref SPI0_RST
* - \ref UART0_RST
* - \ref UART1_RST
* - \ref UART2_RST
* - \ref USBD_RST
* - \ref EADC_RST
* - \ref SC0_RST
* - \ref USCI0_RST
* - \ref USCI1_RST
* - \ref USCI2_RST
* - \ref DAC_RST
* - \ref PWM0_RST
* - \ref PWM1_RST
* - \ref BPWM0_RST
* - \ref BPWM1_RST
* - \ref OPA_RST
* - \ref PSIO_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->IPRST0 + (u32ModuleIndex >> 24UL)) |= 1UL << (u32ModuleIndex & 0x00ffffffUL);
/* Release corresponding module from reset state */
*(volatile uint32_t *)((uint32_t)&SYS->IPRST0 + (u32ModuleIndex >> 24UL)) &= ~(1UL << (u32ModuleIndex & 0x00ffffffUL));
}
/**
* @brief Enable and configure Brown-out detector function
* @param[in] i32Mode is reset or interrupt mode. Including :
* - \ref SYS_BODCTL_BOD_RST_EN
* - \ref SYS_BODCTL_BOD_INTERRUPT_EN
* @param[in] u32BODLevel is Brown-out voltage level. Including :
* - \ref SYS_BODCTL_BODVL_4_4V
* - \ref SYS_BODCTL_BODVL_3_7V
* - \ref SYS_BODCTL_BODVL_3_0V
* - \ref SYS_BODCTL_BODVL_2_7V
* - \ref SYS_BODCTL_BODVL_2_4V
* - \ref SYS_BODCTL_BODVL_2_0V
* - \ref SYS_BODCTL_BODVL_1_8V
* @return None
* @details This function configure Brown-out detector reset or interrupt mode, enable Brown-out function and set Brown-out voltage level.
* The register write-protection function should be disabled before using this function.
*/
void SYS_EnableBOD(int32_t i32Mode, uint32_t u32BODLevel)
{
/* Enable Brown-out Detector function */
SYS->BODCTL |= SYS_BODCTL_BODEN_Msk;
/* Enable Brown-out interrupt or reset function */
SYS->BODCTL = (SYS->BODCTL & ~SYS_BODCTL_BODRSTEN_Msk) | i32Mode;
/* Select Brown-out Detector threshold voltage */
SYS->BODCTL = (SYS->BODCTL & ~SYS_BODCTL_BODVL_Msk) | u32BODLevel;
}
/**
* @brief Disable Brown-out detector function
* @param None
* @return None
* @details This function disable Brown-out detector function.
* The register write-protection function should be disabled before using this function.
*/
void SYS_DisableBOD(void)
{
SYS->BODCTL &= ~SYS_BODCTL_BODEN_Msk;
}
/**
* @brief Set Power Level
* @param[in] u32PowerLevel is power level setting. Including :
* - \ref SYS_PLCTL_PLSEL_PL0
* - \ref SYS_PLCTL_PLSEL_PL2
* @return None
* @details This function select power level.
* The register write-protection function should be disabled before using this function.
*/
void SYS_SetPowerLevel(uint32_t u32PowerLevel)
{
/* Set power voltage level */
SYS->PLCTL = (SYS->PLCTL & (~SYS_PLCTL_PLSEL_Msk)) | (u32PowerLevel);
}
/*@}*/ /* end of group SYS_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group SYS_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,400 @@
/**************************************************************************//**
* @file timer.c
* @version V3.00
* @brief M251 series Timer Controller(Timer) driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup TIMER_Driver TIMER Driver
@{
*/
/** @addtogroup TIMER_EXPORTED_FUNCTIONS TIMER Exported Functions
@{
*/
/**
* @brief Open Timer with Operate 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, pre-scale = 0.
if (u32Freq > (u32Clk / 2UL))
{
u32Cmpr = 2UL;
}
else
{
if (u32Clk > 64000000UL)
{
u32Prescale = 7UL; // real prescaler value is 8
u32Clk >>= 3;
}
else if (u32Clk > 32000000UL)
{
u32Prescale = 3UL; // real prescaler value is 4
u32Clk >>= 2;
}
else if (u32Clk > 16000000UL)
{
u32Prescale = 1UL; // real prescaler value is 2
u32Clk >>= 1;
}
u32Cmpr = u32Clk / u32Freq;
}
timer->CTL = u32Mode | u32Prescale;
timer->CMP = 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->CTL = 0UL;
timer->EXTCTL = 0UL;
}
/**
* @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 by using timer one-shot mode.
* @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->CTL = 0UL;
timer->EXTCTL = 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
{
if (u32Clk > 64000000UL)
{
u32Prescale = 7UL; // real prescaler value is 8
u32Clk >>= 3;
}
else if (u32Clk > 32000000UL)
{
u32Prescale = 3UL; // real prescaler value is 4
u32Clk >>= 2;
}
else if (u32Clk > 16000000UL)
{
u32Prescale = 1UL; // real prescaler value is 2
u32Clk >>= 1;
}
if (u32Usec < 250UL)
{
u32Cmpr = (u32Usec * u32Clk) / 1000000UL;
}
else
{
u32NsecPerTick = 1000000000UL / u32Clk;
u32Cmpr = (u32Usec * 1000UL) / u32NsecPerTick;
}
}
timer->CMP = u32Cmpr;
timer->CTL = TIMER_CTL_CNTEN_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->CTL & TIMER_CTL_ACTSTS_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 trigger edge. Possible values are
* - \ref TIMER_CAPTURE_EVENT_FALLING
* - \ref TIMER_CAPTURE_EVENT_RISING
* - \ref TIMER_CAPTURE_EVENT_FALLING_RISING
* - \ref TIMER_CAPTURE_EVENT_RISING_FALLING
* - \ref TIMER_CAPTURE_EVENT_GET_LOW_PERIOD
* - \ref TIMER_CAPTURE_EVENT_GET_HIGH_PERIOD
*
* @return None
*
* @details This API is used to enable timer capture function with specify capture trigger edge \n
* to get current counter value or reset counter value to 0.
* @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->EXTCTL = (timer->EXTCTL & ~(TIMER_EXTCTL_CAPFUNCS_Msk | TIMER_EXTCTL_CAPEDGE_Msk)) |
u32CapMode | u32Edge | TIMER_EXTCTL_CAPEN_Msk;
}
/**
* @brief Select Timer Capture Source
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Src Timer capture source. Possible values are
* - \ref TIMER_CAPTURE_FROM_EXTERNAL
* - \ref TIMER_CAPTURE_FROM_INTERNAL
*
* @return None
*
* @details This API is used to select timer capture source from Tx_EXT or internal singal.
*/
void TIMER_CaptureSelect(TIMER_T *timer, uint32_t u32Src)
{
timer->CTL = (timer->CTL & (~TIMER_CTL_CAPSRC_Msk)) | u32Src;
}
/**
* @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->EXTCTL &= ~TIMER_EXTCTL_CAPEN_Msk;
}
/**
* @brief Set Timer Trigger Source
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Src Timer source from timeout or capture event
*
* @return None
*
* @details This macro is used to set timer trigger source
*/
void TIMER_SetTriggerSource(TIMER_T *timer, uint32_t u32Src)
{
timer->TRGCTL = (timer->TRGCTL & ~TIMER_TRGCTL_TRGSSEL_Msk) | u32Src;
}
/**
* @brief Set Timer Trigger Target
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Mask Timer trigger target to PWM/BPWM/DAC/EADC/PDMA
*
* @return None
*
* @details This macro is used to set timer trigger target
*/
void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask)
{
timer->TRGCTL = (timer->TRGCTL & ~(TIMER_TRGCTL_TRGPWM_Msk | TIMER_TRGCTL_TRGDAC_Msk | TIMER_TRGCTL_TRGEADC_Msk | TIMER_TRGCTL_TRGPDMA_Msk)) | u32Mask;
}
/**
* @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_EVENT_FALLING, or
* - \ref TIMER_COUNTER_EVENT_RISING
*
* @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->EXTCTL = (timer->EXTCTL & ~TIMER_EXTCTL_CNTPHASE_Msk) | u32Edge;
timer->CTL |= TIMER_CTL_EXTCNTEN_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->CTL &= ~TIMER_CTL_EXTCNTEN_Msk;
}
/**
* @brief Enable Timer Frequency Counter Function
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32DropCount This parameter has no effect in this BSP
* @param[in] u32Timeout This parameter has no effect in this BSP
* @param[in] u32EnableInt Enable interrupt assertion after capture complete or not. Valid values are TRUE and FALSE
*
* @return None
*
* @details This function is used to enable the Timer frequency counter function for
* calculate input event frequency. After enable this function, a pair of timers,
* TIMER0 and TIMER1, or TIMER2 and TIMER3 will be configured for this function.
* The mode used to calculate input event frequency is mentioned as
* "Inter Timer Trigger Mode" in Technical Reference Manual.
*/
void TIMER_EnableFreqCounter(TIMER_T *timer,
uint32_t u32DropCount,
uint32_t u32Timeout,
uint32_t u32EnableInt)
{
TIMER_T *ptimerTmp; /* store the timer base to configure compare value */
if (timer == TIMER0)
{
ptimerTmp = TIMER1;
}
else if (timer == TIMER2)
{
ptimerTmp = TIMER3;
}
else
{
ptimerTmp = 0UL ;
}
if (ptimerTmp != 0UL)
{
ptimerTmp->CMP = 0xFFFFFFUL;
ptimerTmp->EXTCTL = u32EnableInt ? TIMER_EXTCTL_CAPIEN_Msk : 0UL;
timer->CTL = TIMER_CTL_INTRGEN_Msk | TIMER_CTL_CNTEN_Msk;
}
}
/**
* @brief Disable Timer Frequency Counter Function
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return None
*
* @brief This function is used to disable the Timer frequency counter function.
*/
void TIMER_DisableFreqCounter(TIMER_T *timer)
{
timer->CTL &= ~TIMER_CTL_INTRGEN_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 timer clock frequency.
* @note This API cannot return correct clock rate if timer source is from external clock input.
*/
uint32_t TIMER_GetModuleClock(TIMER_T *timer)
{
uint32_t u32Src;
const uint32_t au32Clk[] = {__HXT, __LXT, 0UL, 0UL, 0UL, __LIRC, 0UL, __HIRC};
if (timer == TIMER0)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos;
else if (timer == TIMER1)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos;
else if (timer == TIMER2)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR2SEL_Msk) >> CLK_CLKSEL1_TMR2SEL_Pos;
else // Timer 3
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR3SEL_Msk) >> CLK_CLKSEL1_TMR3SEL_Pos;
if (u32Src == 2UL)
{
return (SystemCoreClock);
}
return (au32Clk[u32Src]);
}
/*@}*/ /* end of group TIMER_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group TIMER_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,240 @@
/**************************************************************************//**
* @file timer.c
* @version V3.00
* @brief Timer PWM Controller(Timer PWM) driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup TIMER_PWM_Driver TIMER PWM Driver
@{
*/
/** @addtogroup TIMER_PWM_EXPORTED_FUNCTIONS TIMER PWM Exported Functions
@{
*/
/**
* @brief Get PWM Clock Frequency
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
*
* @return PWM clock frequency
*
* @details This API is used to get the timer clock frequency.
* @note This API cannot return correct clock rate if timer source is from external clock input.
*/
uint32_t TPWM_GetModuleClock(TIMER_T *timer)
{
uint32_t u32Src;
const uint32_t au32Clk[] = {__HXT, __LXT, 0UL, 0UL, 0UL, __LIRC, 0UL, __HIRC};
if (timer == TIMER0)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos;
else if (timer == TIMER1)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos;
else if (timer == TIMER2)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR2SEL_Msk) >> CLK_CLKSEL1_TMR2SEL_Pos;
else // Timer 3
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR3SEL_Msk) >> CLK_CLKSEL1_TMR3SEL_Pos;
if (u32Src == 2UL)
{
return (SystemCoreClock);
}
return (au32Clk[u32Src]);
}
/**
* @brief Configure PWM Output Frequency and Duty Cycle
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @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 API is used to configure PWM output frequency and duty cycle in up count type and auto-reload operation mode.
* @note This API is only available if Timer PWM counter clock source is from TMRx_CLK.
*/
uint32_t TPWM_ConfigOutputFreqAndDuty(TIMER_T *timer, uint32_t u32Frequency, uint32_t u32DutyCycle)
{
uint32_t u32PWMClockFreq, u32TargetFreq;
uint32_t u32Prescaler = 0x100UL, u32Period, u32CMP;
u32PWMClockFreq = TPWM_GetModuleClock(timer);
/* Calculate u8PERIOD and u8PSC */
for (u32Prescaler = 1; u32Prescaler <= 0x100UL; u32Prescaler++)
{
u32Period = (u32PWMClockFreq / u32Prescaler) / u32Frequency;
/* If target u32Period is larger than 0x10000, need to use a larger prescaler */
if (u32Period > 0x10000UL)
continue;
break;
}
/* Store return value here 'cos we're gonna change u32Prescaler & u32Period to the real value to fill into register */
u32TargetFreq = (u32PWMClockFreq / u32Prescaler) / u32Period;
/* Set PWM to auto-reload mode */
timer->PWMCTL = (timer->PWMCTL & ~TIMER_PWMCTL_CNTMODE_Msk) | (TPWM_AUTO_RELOAD_MODE << TIMER_PWMCTL_CNTMODE_Pos);
/* Convert to real register value */
TPWM_SET_PRESCALER(timer, (u32Prescaler - 1UL));
TPWM_SET_PERIOD(timer, (u32Period - 1UL));
if (u32DutyCycle)
{
u32CMP = (u32DutyCycle * u32Period) / 100UL;
}
else
{
u32CMP = 0UL;
}
TPWM_SET_CMPDAT(timer, u32CMP);
return (u32TargetFreq);
}
/**
* @brief Enable PWM Counter
*
* @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 PWM generator and start counter counting.
*/
void TPWM_EnableCounter(TIMER_T *timer)
{
timer->PWMCTL |= TIMER_PWMCTL_CNTEN_Msk;
}
/**
* @brief Disable PWM Generator
*
* @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 PWM counter immediately by clear CNTEN (TIMERx_PWMCTL[0]) bit.
*/
void TPWM_DisableCounter(TIMER_T *timer)
{
timer->PWMCTL &= ~TIMER_PWMCTL_CNTEN_Msk;
}
/**
* @brief Enable Trigger ADC
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Condition The condition to trigger ADC. It could be one of following conditions:
* - \ref TPWM_TRIGGER_AT_PERIOD_POINT
* - \ref TPWM_TRIGGER_AT_COMPARE_POINT
* - \ref TPWM_TRIGGER_AT_PERIOD_OR_COMPARE_POINT
* @return None
*
* @details This function is used to enable specified counter compare event to trigger ADC.
*/
void TPWM_EnableTriggerADC(TIMER_T *timer, uint32_t u32Condition)
{
timer->PWMTRGCTL &= ~TIMER_PWMTRGCTL_TRGSEL_Msk;
timer->PWMTRGCTL |= TIMER_PWMTRGCTL_PWMTRGEADC_Msk | (u32Condition << TIMER_PWMTRGCTL_TRGSEL_Pos);
}
/**
* @brief Disable Trigger ADC
*
* @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 counter compare event to trigger ADC.
*/
void TPWM_DisableTriggerADC(TIMER_T *timer)
{
timer->PWMTRGCTL &= ~TIMER_PWMTRGCTL_PWMTRGEADC_Msk;
}
/**
* @brief Enable Trigger DAC
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Condition The condition to trigger DAC. It could be one of following conditions:
* - \ref TPWM_TRIGGER_AT_PERIOD_POINT
* - \ref TPWM_TRIGGER_AT_COMPARE_POINT
* - \ref TPWM_TRIGGER_AT_PERIOD_OR_COMPARE_POINT
* @return None
*
* @details This function is used to enable specified counter compare event to trigger ADC.
*/
void TPWM_EnableTriggerDAC(TIMER_T *timer, uint32_t u32Condition)
{
timer->PWMTRGCTL &= ~TIMER_PWMTRGCTL_TRGSEL_Msk;
timer->PWMTRGCTL |= TIMER_PWMTRGCTL_PWMTRGDAC_Msk | (u32Condition << TIMER_PWMTRGCTL_TRGSEL_Pos);
}
/**
* @brief Disable Trigger DAC
*
* @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 counter compare event to trigger ADC.
*/
void TPWM_DisableTriggerDAC(TIMER_T *timer)
{
timer->PWMTRGCTL &= ~TIMER_PWMTRGCTL_PWMTRGDAC_Msk;
}
/**
* @brief Enable Trigger PDMA
*
* @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Condition The condition to trigger PDMA. It could be one of following conditions:
* - \ref TPWM_TRIGGER_AT_PERIOD_POINT
* - \ref TPWM_TRIGGER_AT_COMPARE_POINT
* - \ref TPWM_TRIGGER_AT_PERIOD_OR_COMPARE_POINT
* @return None
*
* @details This function is used to enable specified counter compare event to trigger ADC.
*/
void TPWM_EnableTriggerPDMA(TIMER_T *timer, uint32_t u32Condition)
{
timer->PWMTRGCTL &= ~TIMER_PWMTRGCTL_TRGSEL_Msk;
timer->PWMTRGCTL |= TIMER_PWMTRGCTL_PWMTRGPDMA_Msk | (u32Condition << TIMER_PWMTRGCTL_TRGSEL_Pos);
}
/**
* @brief Disable Trigger PDMA
*
* @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 counter compare event to trigger ADC.
*/
void TPWM_DisableTriggerPDMA(TIMER_T *timer)
{
timer->PWMTRGCTL &= ~TIMER_PWMTRGCTL_PWMTRGPDMA_Msk;
}
/*@}*/ /* end of group TIMER_PWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group TIMER_PWM_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,659 @@
/****************************************************************************
* @file uart.c
* @version V1.00
* @brief M251 series UART driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.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.
* - \ref UART_INTSTS_SWBEINT_Msk : Single-wire Bit Error Detect Interrupt
* - \ref UART_INTSTS_LININT_Msk : LIN bus interrupt
* - \ref UART_INTEN_WKIEN_Msk : Wake-up interrupt
* - \ref UART_INTSTS_BUFERRINT_Msk : Buffer Error interrupt
* - \ref UART_INTSTS_MODEMINT_Msk : Modem Status interrupt
* - \ref UART_INTSTS_RLSINT_Msk : Receive 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_INTSTS_SWBEINT_Msk) /* Clear Bit Error Detection Interrupt */
{
uart->FIFOSTS = UART_INTSTS_SWBEIF_Msk;
}
if (u32InterruptFlag & UART_INTSTS_RLSINT_Msk) /* Clear Receive Line Status Interrupt */
{
uart->FIFOSTS = UART_FIFOSTS_BIF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_FEF_Msk;
uart->FIFOSTS = UART_FIFOSTS_ADDRDETF_Msk;
}
if (u32InterruptFlag & UART_INTSTS_MODEMINT_Msk) /* Clear Modem Status Interrupt */
{
uart->MODEMSTS |= UART_MODEMSTS_CTSDETF_Msk;
}
if (u32InterruptFlag & UART_INTSTS_BUFERRINT_Msk) /* Clear Buffer Error Interrupt */
{
uart->FIFOSTS = UART_FIFOSTS_RXOVIF_Msk | UART_FIFOSTS_TXOVIF_Msk;
}
if (u32InterruptFlag & UART_INTSTS_WKINT_Msk) /* Clear Wake-up Interrupt */
{
uart->WKSTS = UART_WKSTS_CTSWKF_Msk | UART_WKSTS_DATWKF_Msk |
UART_WKSTS_RFRTWKF_Msk | UART_WKSTS_RS485WKF_Msk |
UART_WKSTS_TOUTWKF_Msk;
}
if (u32InterruptFlag & UART_INTSTS_LININT_Msk) /* Clear LIN Bus Interrupt */
{
uart->INTSTS = UART_INTSTS_LINIF_Msk;
uart->LINSTS = UART_LINSTS_BITEF_Msk | UART_LINSTS_BRKDETF_Msk |
UART_LINSTS_SLVSYNCF_Msk | UART_LINSTS_SLVIDPEF_Msk |
UART_LINSTS_SLVHEF_Msk | UART_LINSTS_SLVHDETF_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->INTEN = 0ul;
}
/**
* @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->INTEN &= ~(UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_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.
* - \ref UART_INTSTS_SWBEINT_Msk : Single-wire Bit Error Detect Interrupt
* - \ref UART_INTEN_WKIEN_Msk : Wake-up interrupt
* - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt
* - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt
* - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt
* - \ref UART_INTEN_MODEMIEN_Msk : Modem status interrupt
* - \ref UART_INTEN_RLSIEN_Msk : Receive Line status interrupt
* - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt
* - \ref UART_INTEN_RDAIEN_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);
}
/**
* @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->MODEM |= UART_MODEM_RTSACTLV_Msk;
/* Set CTS pin input is low level active */
uart->MODEMSTS |= UART_MODEMSTS_CTSACTLV_Msk;
/* Set RTS and CTS auto flow control enable */
uart->INTEN |= UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk;
}
/**
* @brief The function is used to enable UART specified interrupt and enable NVIC UART IRQ.
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32InterruptFlag The specified interrupt of UART module:
* - \ref UART_INTSTS_SWBEINT_Msk : Single-wire Bit Error Detect Interrupt
* - \ref UART_INTEN_WKIEN_Msk : Wake-up interrupt
* - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt
* - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt
* - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt
* - \ref UART_INTEN_MODEMIEN_Msk : Modem status interrupt
* - \ref UART_INTEN_RLSIEN_Msk : Receive Line status interrupt
* - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt
* - \ref UART_INTEN_RDAIEN_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);
}
/**
* @brief Open and set UART function
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32BaudRate The baud rate 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)
{
uint32_t u32UartClkSrcSel = 0ul, u32UartClkDivNum = 0ul;
uint32_t au32ClkTbl[6ul] = {__HXT, 0ul, __LXT, __HIRC, 0ul, __LIRC};
uint32_t u32Baud_Div = 0ul;
if (uart == (UART_T *)UART0)
{
/* Get UART clock source selection */
u32UartClkSrcSel = ((uint32_t)(CLK->CLKSEL1 & CLK_CLKSEL1_UART0SEL_Msk)) >> CLK_CLKSEL1_UART0SEL_Pos;
/* Get UART clock divider number */
u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART0DIV_Msk) >> CLK_CLKDIV0_UART0DIV_Pos;
}
else if (uart == (UART_T *)UART1)
{
/* Get UART clock source selection */
u32UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART1SEL_Msk) >> CLK_CLKSEL1_UART1SEL_Pos;
/* Get UART clock divider number */
u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART1DIV_Msk) >> CLK_CLKDIV0_UART1DIV_Pos;
}
else if (uart == (UART_T *)UART2)
{
/* Get UART clock source selection */
u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART2SEL_Msk) >> CLK_CLKSEL3_UART2SEL_Pos;
/* Get UART clock divider number */
u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART2DIV_Msk) >> CLK_CLKDIV4_UART2DIV_Pos;
}
else {}
/* Select UART function */
uart->FUNCSEL = UART_FUNCSEL_UART;
/* Set UART line configuration */
uart->LINE = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
/* Set UART Rx and RTS trigger level */
uart->FIFO &= ~(UART_FIFO_RFITL_Msk | UART_FIFO_RTSTRGLV_Msk);
/* Get PLL clock frequency if UART clock source selection is PLL */
if (u32UartClkSrcSel == 1ul)
{
au32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq();
}
/* Get PCLK clock frequency if UART clock source selection is PCLK */
if (u32UartClkSrcSel == 4ul)
{
/* UART Port as UART0 or UART1 */
if ((uart == (UART_T *)UART0) || (uart == (UART_T *)UART2))
{
au32ClkTbl[u32UartClkSrcSel] = CLK_GetPCLK0Freq();
}
else /* UART Port as UART1*/
{
au32ClkTbl[u32UartClkSrcSel] = CLK_GetPCLK1Freq();
}
}
/* Set UART baud rate */
if (u32BaudRate != 0ul)
{
u32Baud_Div = UART_BAUD_MODE2_DIVIDER((au32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32BaudRate);
if (u32Baud_Div > 0xFFFFul)
{
uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((au32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), 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, u32DelayNum;
uint32_t u32Exit = 0ul;
for (u32Count = 0ul; u32Count < u32ReadBytes; u32Count++)
{
u32DelayNum = 0ul;
while (uart->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) /* Check RX empty => failed */
{
u32DelayNum++;
if (u32DelayNum >= 0x40000000ul)
{
u32Exit = 1ul;
break;
}
else
{
}
}
if (u32Exit == 1ul)
{
break;
}
else
{
pu8RxBuf[u32Count] = (uint8_t)uart->DAT; /* 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] u32DataWidth The data length of UART module.
* - \ref UART_WORD_LEN_5
* - \ref UART_WORD_LEN_6
* - \ref UART_WORD_LEN_7
* - \ref UART_WORD_LEN_8
* @param[in] u32Parity The parity setting (none/odd/even/mark/space) of UART module.
* - \ref UART_PARITY_NONE
* - \ref UART_PARITY_ODD
* - \ref UART_PARITY_EVEN
* - \ref UART_PARITY_MARK
* - \ref UART_PARITY_SPACE
* @param[in] u32StopBits The stop bit length (1/1.5/2 bit) of UART module.
* - \ref UART_STOP_BIT_1
* - \ref UART_STOP_BIT_1_5
* - \ref 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 u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits)
{
uint32_t u32UartClkSrcSel = 0ul, u32UartClkDivNum = 0ul;
uint32_t au32ClkTbl[6ul] = {__HXT, 0ul, __LXT, __HIRC, 0, __LIRC};
uint32_t u32Baud_Div = 0ul;
if (uart == (UART_T *)UART0)
{
/* Get UART clock source selection */
u32UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART0SEL_Msk) >> CLK_CLKSEL1_UART0SEL_Pos;
/* Get UART clock divider number */
u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART0DIV_Msk) >> CLK_CLKDIV0_UART0DIV_Pos;
}
else if (uart == (UART_T *)UART1)
{
/* Get UART clock source selection */
u32UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART1SEL_Msk) >> CLK_CLKSEL1_UART1SEL_Pos;
/* Get UART clock divider number */
u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART1DIV_Msk) >> CLK_CLKDIV0_UART1DIV_Pos;
}
else if (uart == (UART_T *)UART2)
{
/* Get UART clock source selection */
u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART2SEL_Msk) >> CLK_CLKSEL3_UART2SEL_Pos;
/* Get UART clock divider number */
u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART2DIV_Msk) >> CLK_CLKDIV4_UART2DIV_Pos;
}
else {}
/* Get PLL clock frequency if UART clock source selection is PLL */
if (u32UartClkSrcSel == 1ul)
{
au32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq();
}
/* Get PCLK clock frequency if UART clock source selection is PCLK */
if (u32UartClkSrcSel == 4ul)
{
if ((uart == (UART_T *)UART0) || (uart == (UART_T *)UART2))
{
au32ClkTbl[u32UartClkSrcSel] = CLK_GetPCLK0Freq();
}
else /* UART Port as UART1*/
{
au32ClkTbl[u32UartClkSrcSel] = CLK_GetPCLK1Freq();
}
}
/* Set UART baud rate */
if (u32BaudRate != 0ul)
{
u32Baud_Div = UART_BAUD_MODE2_DIVIDER((au32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32BaudRate);
if (u32Baud_Div > 0xFFFFul)
{
uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((au32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32BaudRate));
}
else
{
uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div);
}
}
/* Set UART line configuration */
uart->LINE = u32DataWidth | u32Parity | u32StopBits;
}
/**
* @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->TOUT = (uart->TOUT & ~UART_TOUT_TOIC_Msk) | (u32TOC);
/* Set time-out counter enable */
uart->INTEN |= UART_INTEN_TOCNTEN_Msk;
}
/**
* @brief Select and configure IrDA function
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32BuadRate The baud rate of UART module.
* @param[in] u32Direction The direction of UART module in IrDA mode:
* - \ref UART_IRDA_TXEN
* - \ref UART_IRDA_RXEN
*
* @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)
{
uint32_t u32UartClkSrcSel = 0ul, u32UartClkDivNum = 0ul;
uint32_t au32ClkTbl[6ul] = {__HXT, 0ul, __LXT, __HIRC, 0ul, __LIRC};
uint32_t u32Baud_Div;
/* Select IrDA function mode */
uart->FUNCSEL = UART_FUNCSEL_IrDA;
if (uart == UART0)
{
/* Get UART clock source selection */
u32UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART0SEL_Msk) >> CLK_CLKSEL1_UART0SEL_Pos;
/* Get UART clock divider number */
u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART0DIV_Msk) >> CLK_CLKDIV0_UART0DIV_Pos;
}
else if (uart == UART1)
{
/* Get UART clock source selection */
u32UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART1SEL_Msk) >> CLK_CLKSEL1_UART1SEL_Pos;
/* Get UART clock divider number */
u32UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UART1DIV_Msk) >> CLK_CLKDIV0_UART1DIV_Pos;
}
else if (uart == UART2)
{
/* Get UART clock source selection */
u32UartClkSrcSel = (CLK->CLKSEL3 & CLK_CLKSEL3_UART2SEL_Msk) >> CLK_CLKSEL3_UART2SEL_Pos;
/* Get UART clock divider number */
u32UartClkDivNum = (CLK->CLKDIV4 & CLK_CLKDIV4_UART2DIV_Msk) >> CLK_CLKDIV4_UART2DIV_Pos;
}
else
{
}
/* Get PLL clock frequency if UART clock source selection is PLL */
if (u32UartClkSrcSel == 1ul)
{
au32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq();
}
/* Get PCLK clock frequency if UART clock source selection is PCLK */
if (u32UartClkSrcSel == 4ul)
{
if ((uart == (UART_T *)UART0) || (uart == (UART_T *)UART2))
{
au32ClkTbl[u32UartClkSrcSel] = CLK_GetPCLK0Freq();
}
else /* UART Port as UART1*/
{
au32ClkTbl[u32UartClkSrcSel] = CLK_GetPCLK1Freq();
}
}
/* Set UART IrDA baud rate in mode 0 */
if (u32BuadRate != 0ul)
{
u32Baud_Div = UART_BAUD_MODE0_DIVIDER((au32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32BuadRate);
if (u32Baud_Div < 0xFFFFul)
{
uart->BAUD = (UART_BAUD_MODE0 | u32Baud_Div);
}
else
{
}
}
/* Configure IrDA relative settings */
if (u32Direction == UART_IRDA_RXEN)
{
uart->IRDA |= UART_IRDA_RXINV_Msk; /*Rx signal is inverse*/
uart->IRDA &= ~UART_IRDA_TXEN_Msk;
}
else
{
uart->IRDA &= ~UART_IRDA_TXINV_Msk; /*Tx signal is not inverse*/
uart->IRDA |= UART_IRDA_TXEN_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).
* - \ref UART_ALTCTL_RS485NMM_Msk
* - \ref UART_ALTCTL_RS485AUD_Msk
* - \ref UART_ALTCTL_RS485AAD_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->FUNCSEL = UART_FUNCSEL_RS485;
/* Set RS585 configuration */
uart->ALTCTL &= ~(UART_ALTCTL_RS485NMM_Msk | UART_ALTCTL_RS485AUD_Msk | UART_ALTCTL_RS485AAD_Msk | UART_ALTCTL_ADDRMV_Msk);
uart->ALTCTL |= (u32Mode | (u32Addr << UART_ALTCTL_ADDRMV_Pos));
}
/**
* @brief Select and configure LIN function
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32Mode The LIN direction :
* - \ref UART_ALTCTL_LINTXEN_Msk
* - \ref UART_ALTCTL_LINRXEN_Msk
* @param[in] u32BreakLength The break field 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->FUNCSEL = UART_FUNCSEL_LIN;
/* Select LIN function setting : Tx enable, Rx enable and break field length */
uart->ALTCTL &= ~(UART_ALTCTL_LINTXEN_Msk | UART_ALTCTL_LINRXEN_Msk | UART_ALTCTL_BRKFL_Msk);
uart->ALTCTL |= (u32Mode | (u32BreakLength << UART_ALTCTL_BRKFL_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, u32DelayNum;
uint32_t u32Exit = 0ul;
for (u32Count = 0ul; u32Count != u32WriteBytes; u32Count++)
{
u32DelayNum = 0ul;
while ((uart->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk) == 0ul) /* Wait Tx empty and Time-out manner */
{
u32DelayNum++;
if (u32DelayNum >= 0x40000000ul)
{
u32Exit = 1ul;
break;
}
else
{
}
}
if (u32Exit == 1ul)
{
break;
}
else
{
uart->DAT = pu8TxBuf[u32Count]; /* Send UART Data from buffer */
}
}
return u32Count;
}
/**
* @brief Select Single Wire mode function
*
* @param[in] uart The pointer of the specified UART module.
*
* @return None
*
* @details The function is used to select Single Wire mode.
*/
void UART_SelectSingleWireMode(UART_T *uart)
{
/* Select UART SingleWire function mode */
uart->FUNCSEL = ((uart->FUNCSEL & (~UART_FUNCSEL_FUNCSEL_Msk)) | UART_FUNCSEL_SINGLE_WIRE);
}
/*@}*/ /* end of group UART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group UART_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,784 @@
/**************************************************************************//**
* @file usbd.c
* @version V0.10
* @brief M251 series USBD driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <string.h>
#include "NuMicro.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_au8SetupPacket[8] = {0u}; /*!< Setup packet buffer */
volatile uint8_t g_USBD_u8RemoteWakeupEn = 0u; /*!< Remote wake up function enable flag */
/**
* @cond HIDDEN_SYMBOLS
*/
static volatile uint8_t *s_USBD_pu8CtrlInPointer = 0ul;
static volatile uint8_t *s_USBD_pu8CtrlOutPointer = 0ul;
static volatile uint32_t s_USBD_u32CtrlInSize = 0ul;
static volatile uint32_t s_USBD_u32CtrlOutSize = 0ul;
static volatile uint32_t s_USBD_u32CtrlOutSizeLimit = 0ul;
static volatile uint32_t s_USBD_u32UsbAddr = 0ul;
static volatile uint32_t s_USBD_u32UsbConfig = 0ul;
static volatile uint32_t s_USBD_u32CtrlMaxPktSize = 8ul;
static volatile uint32_t s_USBD_u32UsbAltInterface = 0ul;
static volatile uint8_t s_USBD_u8CtrlInZeroFlag = 0ul;
/**
* @endcond
*/
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_USBD_u32EpStallLock = 0ul; /*!< 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 */
s_USBD_u32CtrlMaxPktSize = g_USBD_sINFO->gu8DevDesc[7];
/* Initial USB engine */
#ifdef SUPPORT_LPM
USBD->ATTR = 0x7D0UL | USBD_LPMACK;
#else
USBD->ATTR = 0x7D0UL;
#endif
/* 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)
{
/* 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_au8SetupPacket, 8ul);
}
/**
* @brief Process SETUP packet
*
* @param None
*
* @return None
*
* @details Parse SETUP packet and perform the corresponding action.
*
*/
void USBD_ProcessSetupPacket(void)
{
/* Get SETUP packet from USB buffer */
USBD_MemCopy(g_USBD_au8SetupPacket, (uint8_t *)USBD_BUF_BASE, 8ul);
/* Check the request type */
switch (g_USBD_au8SetupPacket[0] & 0x60ul)
{
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;
u32Len = 0ul;
u32Len = g_USBD_au8SetupPacket[7];
u32Len <<= 8ul;
u32Len += g_USBD_au8SetupPacket[6];
switch (g_USBD_au8SetupPacket[3])
{
/* Get Device Descriptor */
case DESC_DEVICE:
{
u32Len = USBD_Minimum(u32Len, LEN_DEVICE);
DBG_PRINTF("Get device desc, %d\n", u32Len);
USBD_PrepareCtrlIn((uint8_t *)g_USBD_sINFO->gu8DevDesc, u32Len);
break;
}
/* Get Configuration Descriptor */
case DESC_CONFIG:
{
uint32_t u32TotalLen;
DBG_PRINTF("Get config desc len %d, acture len %d\n", u32Len, u32TotalLen);
u32TotalLen = g_USBD_sINFO->gu8ConfigDesc[3];
u32TotalLen = g_USBD_sINFO->gu8ConfigDesc[2] + (u32TotalLen << 8U);
DBG_PRINTF("Get config desc len %d, acture len %d\n", u32Len, u32TotalLen);
u32Len = USBD_Minimum(u32Len, u32TotalLen);
DBG_PRINTF("Minimum len %d\n", u32Len);
USBD_PrepareCtrlIn((uint8_t *)g_USBD_sINFO->gu8ConfigDesc, u32Len);
break;
}
/* Get BOS Descriptor */
case DESC_BOS:
{
uint32_t u32TotalLen;
u32TotalLen = g_USBD_sINFO->gu8BosDesc[3];
u32TotalLen = g_USBD_sINFO->gu8BosDesc[2] + (u32TotalLen << 8ul);
DBG_PRINTF("Get BOS desc len %d, acture len %d\n", u32Len, u32TotalLen);
u32Len = USBD_Minimum(u32Len, u32TotalLen);
DBG_PRINTF("Minimum len %d\n", u32Len);
USBD_PrepareCtrlIn((uint8_t *)g_USBD_sINFO->gu8BosDesc, u32Len);
break;
}
/* Get HID Descriptor */
case DESC_HID:
{
/* CV3.0 HID Class Descriptor Test,
Need to indicate index of the HID Descriptor within gu8ConfigDescriptor, specifically HID Composite device. */
uint32_t u32ConfigDescOffset; /* u32ConfigDescOffset is configuration descriptor offset (HID descriptor start index) */
u32Len = USBD_Minimum(u32Len, LEN_HID);
DBG_PRINTF("Get HID desc, %d\n", u32Len);
u32ConfigDescOffset = g_USBD_sINFO->gu32ConfigHidDescIdx[g_USBD_au8SetupPacket[4]];
USBD_PrepareCtrlIn((uint8_t *)&g_USBD_sINFO->gu8ConfigDesc[u32ConfigDescOffset], u32Len);
break;
}
/* Get Report Descriptor */
case DESC_HID_RPT:
{
DBG_PRINTF("Get HID report, %d\n", u32Len);
u32Len = USBD_Minimum(u32Len, g_USBD_sINFO->gu32HidReportSize[g_USBD_au8SetupPacket[4]]);
USBD_PrepareCtrlIn((uint8_t *)g_USBD_sINFO->gu8HidReportDesc[g_USBD_au8SetupPacket[4]], u32Len);
break;
}
/* Get String Descriptor */
case DESC_STRING:
{
/* Get String Descriptor */
if (g_USBD_au8SetupPacket[2] < 4ul)
{
u32Len = USBD_Minimum(u32Len, g_USBD_sINFO->gu8StringDesc[g_USBD_au8SetupPacket[2]][0]);
DBG_PRINTF("Get string desc %d\n", u32Len);
USBD_PrepareCtrlIn((uint8_t *)g_USBD_sINFO->gu8StringDesc[g_USBD_au8SetupPacket[2]], u32Len);
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_au8SetupPacket[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)
{
DBG_PRINTF("USBD_StandardRequest\n");
/* clear global variables for new request */
s_USBD_pu8CtrlInPointer = 0ul;
s_USBD_u32CtrlInSize = 0ul;
if (g_USBD_au8SetupPacket[0] & 0x80ul) /* request data transfer direction */
{
/* Device to host */
switch (g_USBD_au8SetupPacket[1])
{
case GET_CONFIGURATION:
{
/* Return current configuration setting */
/* Data stage */
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = (uint8_t)s_USBD_u32UsbConfig;
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 1ul);
/* Status stage */
USBD_PrepareCtrlOut(0, 0ul);
DBG_PRINTF("Get configuration\n");
break;
}
case GET_DESCRIPTOR:
{
USBD_GetDescriptor();
USBD_PrepareCtrlOut(0, 0ul); /* For status stage */
break;
}
case GET_INTERFACE:
{
/* Return current interface setting */
/* Data stage */
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = (uint8_t)s_USBD_u32UsbAltInterface;
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 1ul);
/* Status stage */
USBD_PrepareCtrlOut(0, 0ul);
DBG_PRINTF("Get interface\n");
break;
}
case GET_STATUS:
{
/* Device */
if (g_USBD_au8SetupPacket[0] == 0x80ul)
{
uint8_t u8Tmp;
u8Tmp = (uint8_t)0ul;
if (g_USBD_sINFO->gu8ConfigDesc[7] & 0x40ul) u8Tmp |= (uint8_t)1ul; /* Self-Powered/Bus-Powered. */
if (g_USBD_sINFO->gu8ConfigDesc[7] & 0x20) u8Tmp |= (uint8_t)(g_USBD_u8RemoteWakeupEn << 1ul); /* Remote wake up */
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = u8Tmp;
}
/* Interface */
else if (g_USBD_au8SetupPacket[0] == 0x81ul)
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = (uint8_t)0ul;
/* Endpoint */
else if (g_USBD_au8SetupPacket[0] == 0x82ul)
{
uint8_t ep = (uint8_t)g_USBD_au8SetupPacket[4] & 0xFul;
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = (uint8_t)(USBD_GetStall(ep) ? 1ul : 0ul);
}
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0) + 1) = (uint8_t)0ul;
/* Data stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 2ul);
/* Status stage */
USBD_PrepareCtrlOut(0, 0ul);
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_au8SetupPacket[1])
{
case CLEAR_FEATURE:
{
if (g_USBD_au8SetupPacket[2] == FEATURE_ENDPOINT_HALT)
{
uint32_t epNum, i;
/* EP number stall is not allow to be clear in MSC class "Error Recovery Test".
a flag: g_USBD_u32EpStallLock is added to support it */
epNum = (uint8_t)(g_USBD_au8SetupPacket[4] & 0xFul);
for (i = 0ul; i < USBD_MAX_EP; i++)
{
if (((USBD->EP[i].CFG & 0xFul) == epNum) && ((g_USBD_u32EpStallLock & (1ul << i)) == 0ul))
{
USBD->EP[i].CFGP &= ~USBD_CFGP_SSTALL_Msk;
USBD->EP[i].CFG &= ~USBD_CFG_DSQSYNC_Msk;
DBG_PRINTF("Clr stall ep%d %x\n", i, USBD->EP[i].CFGP);
}
}
}
else if (g_USBD_au8SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP)
g_USBD_u8RemoteWakeupEn = (uint8_t)0;
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0ul);
DBG_PRINTF("Clear feature op %d\n", g_USBD_au8SetupPacket[2]);
break;
}
case SET_ADDRESS:
{
s_USBD_u32UsbAddr = g_USBD_au8SetupPacket[2];
DBG_PRINTF("Set addr to %d\n", s_USBD_u32UsbAddr);
/* DATA IN for end of setup */
/* Status Stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0ul);
break;
}
case SET_CONFIGURATION:
{
s_USBD_u32UsbConfig = g_USBD_au8SetupPacket[2];
if (g_USBD_pfnSetConfigCallback)
g_USBD_pfnSetConfigCallback();
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0ul);
DBG_PRINTF("Set config to %d\n", s_USBD_u32UsbConfig);
break;
}
case SET_FEATURE:
{
if (g_USBD_au8SetupPacket[2] == FEATURE_ENDPOINT_HALT)
{
USBD_SetStall((uint8_t)(g_USBD_au8SetupPacket[4] & 0xFul));
DBG_PRINTF("Set feature. stall ep %d\n", g_USBD_au8SetupPacket[4] & 0xFul);
}
else if (g_USBD_au8SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP)
{
g_USBD_u8RemoteWakeupEn = (uint8_t)1ul;
DBG_PRINTF("Set feature. enable remote wakeup\n");
}
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0ul);
break;
}
case SET_INTERFACE:
{
s_USBD_u32UsbAltInterface = g_USBD_au8SetupPacket[2];
if (g_USBD_pfnSetInterface != NULL)
g_USBD_pfnSetInterface();
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0ul);
DBG_PRINTF("Set interface to %d\n", s_USBD_u32UsbAltInterface);
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 > s_USBD_u32CtrlMaxPktSize)
{
// Data size > MXPLD
s_USBD_pu8CtrlInPointer = pu8Buf + s_USBD_u32CtrlMaxPktSize;
s_USBD_u32CtrlInSize = u32Size - s_USBD_u32CtrlMaxPktSize;
USBD_SET_DATA1(EP0);
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, s_USBD_u32CtrlMaxPktSize);
USBD_SET_PAYLOAD_LEN(EP0, s_USBD_u32CtrlMaxPktSize);
}
else
{
// Data size <= MXPLD
s_USBD_pu8CtrlInPointer = 0ul;
s_USBD_u32CtrlInSize = 0ul;
if (u32Size == s_USBD_u32CtrlMaxPktSize)
{
s_USBD_u8CtrlInZeroFlag = (uint8_t)1ul;
}
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", s_USBD_u32CtrlInSize);
if (s_USBD_u32CtrlInSize)
{
// Process remained data
if (s_USBD_u32CtrlInSize > s_USBD_u32CtrlMaxPktSize)
{
// Data size > MXPLD
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)s_USBD_pu8CtrlInPointer, s_USBD_u32CtrlMaxPktSize);
USBD_SET_PAYLOAD_LEN(EP0, s_USBD_u32CtrlMaxPktSize);
s_USBD_pu8CtrlInPointer += s_USBD_u32CtrlMaxPktSize;
s_USBD_u32CtrlInSize -= s_USBD_u32CtrlMaxPktSize;
}
else
{
// Data size <= MXPLD
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)s_USBD_pu8CtrlInPointer, s_USBD_u32CtrlInSize);
USBD_SET_PAYLOAD_LEN(EP0, s_USBD_u32CtrlInSize);
if (s_USBD_u32CtrlInSize == s_USBD_u32CtrlMaxPktSize)
{
s_USBD_u8CtrlInZeroFlag = (uint8_t)1ul;
}
s_USBD_pu8CtrlInPointer = 0ul;
s_USBD_u32CtrlInSize = 0ul;
}
}
else // No more data for IN token
{
// In ACK for Set address
if ((g_USBD_au8SetupPacket[0] == REQ_STANDARD) && (g_USBD_au8SetupPacket[1] == SET_ADDRESS))
{
if ((USBD_GET_ADDR() != s_USBD_u32UsbAddr) && (USBD_GET_ADDR() == 0ul))
{
USBD_SET_ADDR(s_USBD_u32UsbAddr);
}
}
/* For the case of data size is integral times maximum packet size */
if (s_USBD_u8CtrlInZeroFlag)
{
USBD_SET_PAYLOAD_LEN(EP0, 0ul);
s_USBD_u8CtrlInZeroFlag = (uint8_t)0ul;
}
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)
{
s_USBD_pu8CtrlOutPointer = pu8Buf;
s_USBD_u32CtrlOutSize = 0ul;
s_USBD_u32CtrlOutSizeLimit = u32Size;
USBD_SET_PAYLOAD_LEN(EP1, s_USBD_u32CtrlMaxPktSize);
}
/**
* @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", s_USBD_u32CtrlOutSize);
if (s_USBD_u32CtrlOutSize < s_USBD_u32CtrlOutSizeLimit)
{
u32Size = USBD_GET_PAYLOAD_LEN(EP1);
USBD_MemCopy((uint8_t *)s_USBD_pu8CtrlOutPointer, (uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1), u32Size);
s_USBD_pu8CtrlOutPointer += u32Size;
s_USBD_u32CtrlOutSize += u32Size;
if (s_USBD_u32CtrlOutSize < s_USBD_u32CtrlOutSizeLimit)
USBD_SET_PAYLOAD_LEN(EP1, s_USBD_u32CtrlMaxPktSize);
}
}
/**
* @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)
{
uint32_t i;
// Reset all variables for protocol
s_USBD_pu8CtrlInPointer = 0ul;
s_USBD_u32CtrlInSize = 0ul;
s_USBD_pu8CtrlOutPointer = 0ul;
s_USBD_u32CtrlOutSize = 0ul;
s_USBD_u32CtrlOutSizeLimit = 0ul;
g_USBD_u32EpStallLock = 0ul;
memset(g_USBD_au8SetupPacket, 0, 8ul);
/* Reset PID DATA0 */
for (i = 0ul; i < USBD_MAX_EP; i++)
USBD->EP[i].CFG &= ~USBD_CFG_DSQSYNC_Msk;
// Reset USB device address
USBD_SET_ADDR(0ul);
}
/**
* @brief USBD Set Vendor Request
*
* @param[in] pfnVendorReq Vendor Request Callback Function
*
* @return None
*
* @details This function is used to set USBD vendor request callback function
*/
void USBD_SetVendorRequest(VENDOR_REQ pfnVendorReq)
{
g_USBD_pfnVendorRequest = pfnVendorReq;
}
/**
* @brief The callback function which called when get SET CONFIGURATION request
*
* @param[in] pfnSetConfigCallback Callback function pointer for SET CONFIGURATION request
*
* @return None
*
* @details This function is used to set the callback function which will be called at SET CONFIGURATION request.
*/
void USBD_SetConfigCallback(SET_CONFIG_CB pfnSetConfigCallback)
{
g_USBD_pfnSetConfigCallback = pfnSetConfigCallback;
}
/**
* @brief EP stall lock function to avoid stall clear by USB SET FEATURE request.
*
* @param[in] u32EpBitmap Use bitmap to select which endpoints will be locked
*
* @return None
*
* @details This function is used to lock relative endpoint to avoid stall clear by SET FEATURE request.
* If ep stall locked, user needs to reset USB device or re-configure device to clear it.
*/
void USBD_LockEpStall(uint32_t u32EpBitmap)
{
g_USBD_u32EpStallLock = u32EpBitmap;
}
/*@}*/ /* end of group USBD_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group USBD_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,708 @@
/****************************************************************************//**
* @file usci_spi.c
* @version V0.10
* @brief M251 series USCI_SPI driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup USCI_SPI_Driver USCI_SPI Driver
@{
*/
/** @addtogroup USCI_SPI_EXPORTED_FUNCTIONS USCI_SPI Exported Functions
@{
*/
/**
* @brief This function make USCI_SPI module be ready to transfer.
* By default, the USCI_SPI transfer sequence is MSB first, the slave selection
* signal is active low and the automatic slave select function is disabled. In
* Slave mode, the u32BusClock must be NULL and the USCI_SPI clock
* divider setting will be 0.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32MasterSlave Decide the USCI_SPI module is operating in master mode or in slave mode. Valid values are:
* - \ref USPI_SLAVE
* - \ref USPI_MASTER
* @param[in] u32SPIMode Decide the transfer timing. Valid values are:
* - \ref USPI_MODE_0
* - \ref USPI_MODE_1
* - \ref USPI_MODE_2
* - \ref USPI_MODE_3
* @param[in] u32DataWidth The data width of a USCI_SPI transaction.
* @param[in] u32BusClock The expected frequency of USCI_SPI bus clock in Hz.
* @return Actual frequency of USCI_SPI peripheral clock.
*/
uint32_t USPI_Open(USPI_T *psUSPI, uint32_t u32MasterSlave, uint32_t u32SPIMode, uint32_t u32DataWidth, uint32_t u32BusClock)
{
uint32_t u32ClkDiv = 0ul;
uint32_t u32Pclk;
uint32_t u32UspiClk = 0ul;
if ((psUSPI == (USPI_T *)USPI0) || (psUSPI == (USPI_T *)USPI2))
{
u32Pclk = CLK_GetPCLK0Freq();
}
else
{
u32Pclk = CLK_GetPCLK1Freq();
}
if (u32BusClock != 0ul)
{
u32ClkDiv = (uint32_t)((((((u32Pclk / 2ul) * 10ul) / (u32BusClock)) + 5ul) / 10ul) - 1ul); /* Compute proper divider for USCI_SPI clock */
}
else {}
/* Enable USCI_SPI protocol */
psUSPI->CTL &= ~USPI_CTL_FUNMODE_Msk;
psUSPI->CTL = 1ul << USPI_CTL_FUNMODE_Pos;
/* Data format configuration */
if (u32DataWidth == 16ul)
{
u32DataWidth = 0ul;
}
else {}
psUSPI->LINECTL &= ~USPI_LINECTL_DWIDTH_Msk;
psUSPI->LINECTL |= (u32DataWidth << USPI_LINECTL_DWIDTH_Pos);
/* MSB data format */
psUSPI->LINECTL &= ~USPI_LINECTL_LSB_Msk;
/* Set slave selection signal active low */
if (u32MasterSlave == USPI_MASTER)
{
psUSPI->LINECTL |= USPI_LINECTL_CTLOINV_Msk;
}
else
{
psUSPI->CTLIN0 |= USPI_CTLIN0_ININV_Msk;
}
/* Set operating mode and transfer timing */
psUSPI->PROTCTL &= ~(USPI_PROTCTL_SCLKMODE_Msk | USPI_PROTCTL_AUTOSS_Msk | USPI_PROTCTL_SLAVE_Msk);
psUSPI->PROTCTL |= (u32MasterSlave | u32SPIMode);
/* Set USCI_SPI bus clock */
psUSPI->BRGEN &= ~USPI_BRGEN_CLKDIV_Msk;
psUSPI->BRGEN |= (u32ClkDiv << USPI_BRGEN_CLKDIV_Pos);
psUSPI->PROTCTL |= USPI_PROTCTL_PROTEN_Msk;
if (u32BusClock != 0ul)
{
u32UspiClk = (uint32_t)(u32Pclk / ((u32ClkDiv + 1ul) << 1));
}
else {}
return u32UspiClk;
}
/**
* @brief Disable USCI_SPI function mode.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
*/
void USPI_Close(USPI_T *psUSPI)
{
psUSPI->CTL &= ~USPI_CTL_FUNMODE_Msk;
}
/**
* @brief Clear Rx buffer.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
*/
void USPI_ClearRxBuf(USPI_T *psUSPI)
{
psUSPI->BUFCTL |= USPI_BUFCTL_RXCLR_Msk;
}
/**
* @brief Clear Tx buffer.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
*/
void USPI_ClearTxBuf(USPI_T *psUSPI)
{
psUSPI->BUFCTL |= USPI_BUFCTL_TXCLR_Msk;
}
/**
* @brief Disable the automatic slave select function.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
*/
void USPI_DisableAutoSS(USPI_T *psUSPI)
{
psUSPI->PROTCTL &= ~(USPI_PROTCTL_AUTOSS_Msk | USPI_PROTCTL_SS_Msk);
}
/**
* @brief Enable the automatic slave select function. Only available in Master mode.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32SSPinMask This parameter is not used.
* @param[in] u32ActiveLevel The active level of slave select signal. Valid values are:
* - \ref USPI_SS_ACTIVE_HIGH
* - \ref USPI_SS_ACTIVE_LOW
* @return None
*/
void USPI_EnableAutoSS(USPI_T *psUSPI, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
{
psUSPI->LINECTL = (psUSPI->LINECTL & ~USPI_LINECTL_CTLOINV_Msk) | u32ActiveLevel;
psUSPI->PROTCTL |= USPI_PROTCTL_AUTOSS_Msk;
}
/**
* @brief Set the USCI_SPI bus clock. Only available in Master mode.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @param[in] u32BusClock The expected frequency of USCI_SPI bus clock.
* @return Actual frequency of USCI_SPI peripheral clock.
*/
uint32_t USPI_SetBusClock(USPI_T *psUSPI, uint32_t u32BusClock)
{
uint32_t u32ClkDiv;
uint32_t u32Pclk;
if ((psUSPI == USPI0) || (psUSPI == USPI2))
{
u32Pclk = CLK_GetPCLK0Freq();
}
else
{
u32Pclk = CLK_GetPCLK1Freq();
}
u32ClkDiv = (uint32_t)((((((u32Pclk / 2ul) * 10ul) / (u32BusClock)) + 5ul) / 10ul) - 1ul); /* Compute proper divider for USCI_SPI clock */
/* Set USCI_SPI bus clock */
psUSPI->BRGEN &= ~USPI_BRGEN_CLKDIV_Msk;
psUSPI->BRGEN |= (u32ClkDiv << USPI_BRGEN_CLKDIV_Pos);
return (u32Pclk / ((u32ClkDiv + 1ul) << 1));
}
/**
* @brief Get the actual frequency of USCI_SPI bus clock. Only available in Master mode.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return Actual USCI_SPI bus clock frequency.
*/
uint32_t USPI_GetBusClock(USPI_T *psUSPI)
{
uint32_t u32BusClk;
uint32_t u32ClkDiv;
u32ClkDiv = (psUSPI->BRGEN & USPI_BRGEN_CLKDIV_Msk) >> USPI_BRGEN_CLKDIV_Pos;
if ((psUSPI == USPI0) || (psUSPI == USPI2))
{
u32BusClk = (uint32_t)(CLK_GetPCLK0Freq() / ((u32ClkDiv + 1ul) << 1));
}
else
{
u32BusClk = (uint32_t)(CLK_GetPCLK1Freq() / ((u32ClkDiv + 1ul) << 1));
}
return u32BusClk;
}
/**
* @brief Enable related interrupts specified by u32Mask parameter.
* @param[in] psUSPI The pointer of the specified USCI_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. Valid values are:
* - \ref USPI_SSINACT_INT_MASK
* - \ref USPI_SSACT_INT_MASK
* - \ref USPI_SLVTO_INT_MASK
* - \ref USPI_SLVBE_INT_MASK
* - \ref USPI_TXUDR_INT_MASK
* - \ref USPI_RXOV_INT_MASK
* - \ref USPI_TXST_INT_MASK
* - \ref USPI_TXEND_INT_MASK
* - \ref USPI_RXST_INT_MASK
* - \ref USPI_RXEND_INT_MASK
* @return None
*/
void USPI_EnableInt(USPI_T *psUSPI, uint32_t u32Mask)
{
/* Enable slave selection signal inactive interrupt flag */
if ((u32Mask & USPI_SSINACT_INT_MASK) == USPI_SSINACT_INT_MASK)
{
psUSPI->PROTIEN |= USPI_PROTIEN_SSINAIEN_Msk;
}
else {}
/* Enable slave selection signal active interrupt flag */
if ((u32Mask & USPI_SSACT_INT_MASK) == USPI_SSACT_INT_MASK)
{
psUSPI->PROTIEN |= USPI_PROTIEN_SSACTIEN_Msk;
}
else {}
/* Enable slave time-out interrupt flag */
if ((u32Mask & USPI_SLVTO_INT_MASK) == USPI_SLVTO_INT_MASK)
{
psUSPI->PROTIEN |= USPI_PROTIEN_SLVTOIEN_Msk;
}
else {}
/* Enable slave bit count error interrupt flag */
if ((u32Mask & USPI_SLVBE_INT_MASK) == USPI_SLVBE_INT_MASK)
{
psUSPI->PROTIEN |= USPI_PROTIEN_SLVBEIEN_Msk;
}
else {}
/* Enable TX under run interrupt flag */
if ((u32Mask & USPI_TXUDR_INT_MASK) == USPI_TXUDR_INT_MASK)
{
psUSPI->BUFCTL |= USPI_BUFCTL_TXUDRIEN_Msk;
}
else {}
/* Enable RX overrun interrupt flag */
if ((u32Mask & USPI_RXOV_INT_MASK) == USPI_RXOV_INT_MASK)
{
psUSPI->BUFCTL |= USPI_BUFCTL_RXOVIEN_Msk;
}
else {}
/* Enable TX start interrupt flag */
if ((u32Mask & USPI_TXST_INT_MASK) == USPI_TXST_INT_MASK)
{
psUSPI->INTEN |= USPI_INTEN_TXSTIEN_Msk;
}
else {}
/* Enable TX end interrupt flag */
if ((u32Mask & USPI_TXEND_INT_MASK) == USPI_TXEND_INT_MASK)
{
psUSPI->INTEN |= USPI_INTEN_TXENDIEN_Msk;
}
else {}
/* Enable RX start interrupt flag */
if ((u32Mask & USPI_RXST_INT_MASK) == USPI_RXST_INT_MASK)
{
psUSPI->INTEN |= USPI_INTEN_RXSTIEN_Msk;
}
else {}
/* Enable RX end interrupt flag */
if ((u32Mask & USPI_RXEND_INT_MASK) == USPI_RXEND_INT_MASK)
{
psUSPI->INTEN |= USPI_INTEN_RXENDIEN_Msk;
}
else {}
}
/**
* @brief Disable related interrupts specified by u32Mask parameter.
* @param[in] psUSPI The pointer of the specified USCI_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. Valid values are:
* - \ref USPI_SSINACT_INT_MASK
* - \ref USPI_SSACT_INT_MASK
* - \ref USPI_SLVTO_INT_MASK
* - \ref USPI_SLVBE_INT_MASK
* - \ref USPI_TXUDR_INT_MASK
* - \ref USPI_RXOV_INT_MASK
* - \ref USPI_TXST_INT_MASK
* - \ref USPI_TXEND_INT_MASK
* - \ref USPI_RXST_INT_MASK
* - \ref USPI_RXEND_INT_MASK
* @return None
*/
void USPI_DisableInt(USPI_T *psUSPI, uint32_t u32Mask)
{
/* Disable slave selection signal inactive interrupt flag */
if ((u32Mask & USPI_SSINACT_INT_MASK) == USPI_SSINACT_INT_MASK)
{
psUSPI->PROTIEN &= ~USPI_PROTIEN_SSINAIEN_Msk;
}
else {}
/* Disable slave selection signal active interrupt flag */
if ((u32Mask & USPI_SSACT_INT_MASK) == USPI_SSACT_INT_MASK)
{
psUSPI->PROTIEN &= ~USPI_PROTIEN_SSACTIEN_Msk;
}
else {}
/* Disable slave time-out interrupt flag */
if ((u32Mask & USPI_SLVTO_INT_MASK) == USPI_SLVTO_INT_MASK)
{
psUSPI->PROTIEN &= ~USPI_PROTIEN_SLVTOIEN_Msk;
}
else {}
/* Disable slave bit count error interrupt flag */
if ((u32Mask & USPI_SLVBE_INT_MASK) == USPI_SLVBE_INT_MASK)
{
psUSPI->PROTIEN &= ~USPI_PROTIEN_SLVBEIEN_Msk;
}
else {}
/* Disable TX under run interrupt flag */
if ((u32Mask & USPI_TXUDR_INT_MASK) == USPI_TXUDR_INT_MASK)
{
psUSPI->BUFCTL &= ~USPI_BUFCTL_TXUDRIEN_Msk;
}
else {}
/* Disable RX overrun interrupt flag */
if ((u32Mask & USPI_RXOV_INT_MASK) == USPI_RXOV_INT_MASK)
{
psUSPI->BUFCTL &= ~USPI_BUFCTL_RXOVIEN_Msk;
}
else {}
/* Disable TX start interrupt flag */
if ((u32Mask & USPI_TXST_INT_MASK) == USPI_TXST_INT_MASK)
{
psUSPI->INTEN &= ~USPI_INTEN_TXSTIEN_Msk;
}
else {}
/* Disable TX end interrupt flag */
if ((u32Mask & USPI_TXEND_INT_MASK) == USPI_TXEND_INT_MASK)
{
psUSPI->INTEN &= ~USPI_INTEN_TXENDIEN_Msk;
}
else {}
/* Disable RX start interrupt flag */
if ((u32Mask & USPI_RXST_INT_MASK) == USPI_RXST_INT_MASK)
{
psUSPI->INTEN &= ~USPI_INTEN_RXSTIEN_Msk;
}
else {}
/* Disable RX end interrupt flag */
if ((u32Mask & USPI_RXEND_INT_MASK) == USPI_RXEND_INT_MASK)
{
psUSPI->INTEN &= ~USPI_INTEN_RXENDIEN_Msk;
}
else {}
}
/**
* @brief Get interrupt flag.
* @param[in] psUSPI The pointer of the specified USCI_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. It is combination of:
* - \ref USPI_SSINACT_INT_MASK
* - \ref USPI_SSACT_INT_MASK
* - \ref USPI_SLVTO_INT_MASK
* - \ref USPI_SLVBE_INT_MASK
* - \ref USPI_TXUDR_INT_MASK
* - \ref USPI_RXOV_INT_MASK
* - \ref USPI_TXST_INT_MASK
* - \ref USPI_TXEND_INT_MASK
* - \ref USPI_RXST_INT_MASK
* - \ref USPI_RXEND_INT_MASK
* @return Interrupt flags of selected sources.
*/
uint32_t USPI_GetIntFlag(USPI_T *psUSPI, uint32_t u32Mask)
{
uint32_t u32TmpFlag;
uint32_t u32IntFlag = 0ul;
/* Check slave selection signal inactive interrupt flag */
u32TmpFlag = psUSPI->PROTSTS & USPI_PROTSTS_SSINAIF_Msk;
if (((u32Mask & USPI_SSINACT_INT_MASK) == USPI_SSINACT_INT_MASK) && (u32TmpFlag == USPI_PROTSTS_SSINAIF_Msk))
{
u32IntFlag |= USPI_SSINACT_INT_MASK;
}
else {}
/* Check slave selection signal active interrupt flag */
u32TmpFlag = psUSPI->PROTSTS & USPI_PROTSTS_SSACTIF_Msk;
if (((u32Mask & USPI_SSACT_INT_MASK) == USPI_SSACT_INT_MASK) && (u32TmpFlag == USPI_PROTSTS_SSACTIF_Msk))
{
u32IntFlag |= USPI_SSACT_INT_MASK;
}
else {}
/* Check slave time-out interrupt flag */
u32TmpFlag = psUSPI->PROTSTS & USPI_PROTSTS_SLVTOIF_Msk;
if (((u32Mask & USPI_SLVTO_INT_MASK) == USPI_SLVTO_INT_MASK) && (u32TmpFlag == USPI_PROTSTS_SLVTOIF_Msk))
{
u32IntFlag |= USPI_SLVTO_INT_MASK;
}
else {}
/* Check slave bit count error interrupt flag */
u32TmpFlag = psUSPI->PROTSTS & USPI_PROTSTS_SLVBEIF_Msk;
if (((u32Mask & USPI_SLVBE_INT_MASK) == USPI_SLVBE_INT_MASK) && (u32TmpFlag == USPI_PROTSTS_SLVBEIF_Msk))
{
u32IntFlag |= USPI_SLVBE_INT_MASK;
}
else {}
/* Check TX under run interrupt flag */
u32TmpFlag = psUSPI->BUFSTS & USPI_BUFSTS_TXUDRIF_Msk;
if (((u32Mask & USPI_TXUDR_INT_MASK) == USPI_TXUDR_INT_MASK) && (u32TmpFlag == USPI_BUFSTS_TXUDRIF_Msk))
{
u32IntFlag |= USPI_TXUDR_INT_MASK;
}
else {}
/* Check RX overrun interrupt flag */
u32TmpFlag = psUSPI->BUFSTS & USPI_BUFSTS_RXOVIF_Msk;
if (((u32Mask & USPI_RXOV_INT_MASK) == USPI_RXOV_INT_MASK) && (u32TmpFlag == USPI_BUFSTS_RXOVIF_Msk))
{
u32IntFlag |= USPI_RXOV_INT_MASK;
}
else {}
/* Check TX start interrupt flag */
u32TmpFlag = psUSPI->PROTSTS & USPI_PROTSTS_TXSTIF_Msk;
if (((u32Mask & USPI_TXST_INT_MASK) == USPI_TXST_INT_MASK) && (u32TmpFlag == USPI_PROTSTS_TXSTIF_Msk))
{
u32IntFlag |= USPI_TXST_INT_MASK;
}
else {}
/* Check TX end interrupt flag */
u32TmpFlag = psUSPI->PROTSTS & USPI_PROTSTS_TXENDIF_Msk;
if (((u32Mask & USPI_TXEND_INT_MASK) == USPI_TXEND_INT_MASK) && (u32TmpFlag == USPI_PROTSTS_TXENDIF_Msk))
{
u32IntFlag |= USPI_TXEND_INT_MASK;
}
else {}
/* Check RX start interrupt flag */
u32TmpFlag = psUSPI->PROTSTS & USPI_PROTSTS_RXSTIF_Msk;
if (((u32Mask & USPI_RXST_INT_MASK) == USPI_RXST_INT_MASK) && (u32TmpFlag == USPI_PROTSTS_RXSTIF_Msk))
{
u32IntFlag |= USPI_RXST_INT_MASK;
}
else {}
/* Check RX end interrupt flag */
u32TmpFlag = psUSPI->PROTSTS & USPI_PROTSTS_RXENDIF_Msk;
if (((u32Mask & USPI_RXEND_INT_MASK) == USPI_RXEND_INT_MASK) && (u32TmpFlag == USPI_PROTSTS_RXENDIF_Msk))
{
u32IntFlag |= USPI_RXEND_INT_MASK;
}
else {}
return u32IntFlag;
}
/**
* @brief Clear interrupt flag.
* @param[in] psUSPI The pointer of the specified USCI_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. It could be the combination of:
* - \ref USPI_SSINACT_INT_MASK
* - \ref USPI_SSACT_INT_MASK
* - \ref USPI_SLVTO_INT_MASK
* - \ref USPI_SLVBE_INT_MASK
* - \ref USPI_TXUDR_INT_MASK
* - \ref USPI_RXOV_INT_MASK
* - \ref USPI_TXST_INT_MASK
* - \ref USPI_TXEND_INT_MASK
* - \ref USPI_RXST_INT_MASK
* - \ref USPI_RXEND_INT_MASK
* @return None
*/
void USPI_ClearIntFlag(USPI_T *psUSPI, uint32_t u32Mask)
{
/* Clear slave selection signal inactive interrupt flag */
if ((u32Mask & USPI_SSINACT_INT_MASK) == USPI_SSINACT_INT_MASK)
{
psUSPI->PROTSTS = USPI_PROTSTS_SSINAIF_Msk;
}
else {}
/* Clear slave selection signal active interrupt flag */
if ((u32Mask & USPI_SSACT_INT_MASK) == USPI_SSACT_INT_MASK)
{
psUSPI->PROTSTS = USPI_PROTSTS_SSACTIF_Msk;
}
else {}
/* Clear slave time-out interrupt flag */
if ((u32Mask & USPI_SLVTO_INT_MASK) == USPI_SLVTO_INT_MASK)
{
psUSPI->PROTSTS = USPI_PROTSTS_SLVTOIF_Msk;
}
else {}
/* Clear slave bit count error interrupt flag */
if ((u32Mask & USPI_SLVBE_INT_MASK) == USPI_SLVBE_INT_MASK)
{
psUSPI->PROTSTS = USPI_PROTSTS_SLVBEIF_Msk;
}
else {}
/* Clear TX under run interrupt flag */
if ((u32Mask & USPI_TXUDR_INT_MASK) == USPI_TXUDR_INT_MASK)
{
psUSPI->BUFSTS = USPI_BUFSTS_TXUDRIF_Msk;
}
else {}
/* Clear RX overrun interrupt flag */
if ((u32Mask & USPI_RXOV_INT_MASK) == USPI_RXOV_INT_MASK)
{
psUSPI->BUFSTS = USPI_BUFSTS_RXOVIF_Msk;
}
else {}
/* Clear TX start interrupt flag */
if ((u32Mask & USPI_TXST_INT_MASK) == USPI_TXST_INT_MASK)
{
psUSPI->PROTSTS = USPI_PROTSTS_TXSTIF_Msk;
}
else {}
/* Clear TX end interrupt flag */
if ((u32Mask & USPI_TXEND_INT_MASK) == USPI_TXEND_INT_MASK)
{
psUSPI->PROTSTS = USPI_PROTSTS_TXENDIF_Msk;
}
else {}
/* Clear RX start interrupt flag */
if ((u32Mask & USPI_RXST_INT_MASK) == USPI_RXST_INT_MASK)
{
psUSPI->PROTSTS = USPI_PROTSTS_RXSTIF_Msk;
}
else {}
/* Clear RX end interrupt flag */
if ((u32Mask & USPI_RXEND_INT_MASK) == USPI_RXEND_INT_MASK)
{
psUSPI->PROTSTS = USPI_PROTSTS_RXENDIF_Msk;
}
else {}
}
/**
* @brief Get USCI_SPI status.
* @param[in] psUSPI The pointer of the specified USCI_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. It is combination of:
* - \ref USPI_BUSY_MASK
* - \ref USPI_RX_EMPTY_MASK
* - \ref USPI_RX_FULL_MASK
* - \ref USPI_TX_EMPTY_MASK
* - \ref USPI_TX_FULL_MASK
* - \ref USPI_SSLINE_STS_MASK
* @return Flags of selected sources.
*/
uint32_t USPI_GetStatus(USPI_T *psUSPI, uint32_t u32Mask)
{
uint32_t u32Flag = 0ul;
uint32_t u32TmpFlag;
/* Check busy status */
u32TmpFlag = psUSPI->PROTSTS & USPI_PROTSTS_BUSY_Msk;
if (((u32Mask & USPI_BUSY_MASK) == USPI_BUSY_MASK) && (u32TmpFlag & USPI_PROTSTS_BUSY_Msk))
{
u32Flag |= USPI_BUSY_MASK;
}
else {}
/* Check RX empty flag */
u32TmpFlag = psUSPI->BUFSTS & USPI_BUFSTS_RXEMPTY_Msk;
if (((u32Mask & USPI_RX_EMPTY_MASK) == USPI_RX_EMPTY_MASK) && (u32TmpFlag == USPI_BUFSTS_RXEMPTY_Msk))
{
u32Flag |= USPI_RX_EMPTY_MASK;
}
else {}
/* Check RX full flag */
u32TmpFlag = psUSPI->BUFSTS & USPI_BUFSTS_RXFULL_Msk;
if (((u32Mask & USPI_RX_FULL_MASK) == USPI_RX_FULL_MASK) && (u32TmpFlag == USPI_BUFSTS_RXFULL_Msk))
{
u32Flag |= USPI_RX_FULL_MASK;
}
else {}
/* Check TX empty flag */
u32TmpFlag = psUSPI->BUFSTS & USPI_BUFSTS_TXEMPTY_Msk;
if (((u32Mask & USPI_TX_EMPTY_MASK) == USPI_TX_EMPTY_MASK) && (u32TmpFlag == USPI_BUFSTS_TXEMPTY_Msk))
{
u32Flag |= USPI_TX_EMPTY_MASK;
}
else {}
/* Check TX full flag */
u32TmpFlag = psUSPI->BUFSTS & USPI_BUFSTS_TXFULL_Msk;
if (((u32Mask & USPI_TX_FULL_MASK) == USPI_TX_FULL_MASK) && (u32TmpFlag == USPI_BUFSTS_TXFULL_Msk))
{
u32Flag |= USPI_TX_FULL_MASK;
}
else {}
/* Check USCI_SPI_SS line status */
u32TmpFlag = psUSPI->PROTSTS & USPI_PROTSTS_SSLINE_Msk;
if (((u32Mask & USPI_SSLINE_STS_MASK) == USPI_SSLINE_STS_MASK) && (u32TmpFlag & USPI_PROTSTS_SSLINE_Msk))
{
u32Flag |= USPI_SSLINE_STS_MASK;
}
else {}
return u32Flag;
}
/**
* @brief Enable USCI_SPI Wake-up Function.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
*/
void USPI_EnableWakeup(USPI_T *psUSPI)
{
psUSPI->WKCTL |= USPI_WKCTL_WKEN_Msk;
}
/**
* @brief Disable USCI_SPI Wake-up Function.
* @param[in] psUSPI The pointer of the specified USCI_SPI module.
* @return None
*/
void USPI_DisableWakeup(USPI_T *psUSPI)
{
psUSPI->WKCTL &= ~USPI_WKCTL_WKEN_Msk;
}
/*@}*/ /* end of group USCI_SPI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group USCI_SPI_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,748 @@
/**************************************************************************//**
* @file usci_uart.c
* @version V0.10
* @brief M251 series USCI UART (UUART) driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "NuMicro.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup USCI_UART_Driver USCI_UART Driver
@{
*/
/** @addtogroup USCI_UART_EXPORTED_FUNCTIONS USCI_UART Exported Functions
@{
*/
/**
* @brief Clear USCI_UART specified interrupt flag
*
* @param[in] psUUART The pointer of the specified USCI_UART 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. It could be the combination of:
* - \ref UUART_ABR_INT_MASK
* - \ref UUART_RLS_INT_MASK
* - \ref UUART_BUF_RXOV_INT_MASK
* - \ref UUART_TXST_INT_MASK
* - \ref UUART_TXEND_INT_MASK
* - \ref UUART_RXST_INT_MASK
* - \ref UUART_RXEND_INT_MASK
*
* @return None
*
* @details The function is used to clear USCI_UART related interrupt flags specified by u32Mask parameter.
*/
void UUART_ClearIntFlag(UUART_T *psUUART, uint32_t u32Mask)
{
if (u32Mask & UUART_ABR_INT_MASK) /* Clear Auto-baud Rate Interrupt */
{
psUUART->PROTSTS = UUART_PROTSTS_ABRDETIF_Msk;
}
if (u32Mask & UUART_RLS_INT_MASK) /* Clear Receive Line Status Interrupt */
{
psUUART->PROTSTS = (UUART_PROTSTS_BREAK_Msk | UUART_PROTSTS_FRMERR_Msk | UUART_PROTSTS_PARITYERR_Msk);
}
if (u32Mask & UUART_BUF_RXOV_INT_MASK) /* Clear Receive Buffer Over-run Error Interrupt */
{
psUUART->BUFSTS = UUART_BUFSTS_RXOVIF_Msk;
}
if (u32Mask & UUART_TXST_INT_MASK) /* Clear Transmit Start Interrupt */
{
psUUART->PROTSTS = UUART_PROTSTS_TXSTIF_Msk;
}
if (u32Mask & UUART_TXEND_INT_MASK) /* Clear Transmit End Interrupt */
{
psUUART->PROTSTS = UUART_PROTSTS_TXENDIF_Msk;
}
if (u32Mask & UUART_RXST_INT_MASK) /* Clear Receive Start Interrupt */
{
psUUART->PROTSTS = UUART_PROTSTS_RXSTIF_Msk;
}
if (u32Mask & UUART_RXEND_INT_MASK) /* Clear Receive End Interrupt */
{
psUUART->PROTSTS = UUART_PROTSTS_RXENDIF_Msk;
}
}
/**
* @brief Get USCI_UART specified interrupt flag
*
* @param[in] psUUART The pointer of the specified USCI_UART 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. It is combination of:
* - \ref UUART_ABR_INT_MASK
* - \ref UUART_RLS_INT_MASK
* - \ref UUART_BUF_RXOV_INT_MASK
* - \ref UUART_TXST_INT_MASK
* - \ref UUART_TXEND_INT_MASK
* - \ref UUART_RXST_INT_MASK
* - \ref UUART_RXEND_INT_MASK
*
* @return Interrupt flags of selected sources.
*
* @details The function is used to get USCI_UART related interrupt flags specified by u32Mask parameter.
*/
uint32_t UUART_GetIntFlag(UUART_T *psUUART, uint32_t u32Mask)
{
uint32_t u32IntFlag = 0ul;
uint32_t u32Tmp1, u32Tmp2;
/* Check Auto-baud Rate Interrupt Flag */
u32Tmp1 = (u32Mask & UUART_ABR_INT_MASK);
u32Tmp2 = (psUUART->PROTSTS & UUART_PROTSTS_ABRDETIF_Msk);
if (u32Tmp1 && u32Tmp2)
{
u32IntFlag |= UUART_ABR_INT_MASK;
}
/* Check Receive Line Status Interrupt Flag */
u32Tmp1 = (u32Mask & UUART_RLS_INT_MASK);
u32Tmp2 = (psUUART->PROTSTS & (UUART_PROTSTS_BREAK_Msk | UUART_PROTSTS_FRMERR_Msk | UUART_PROTSTS_PARITYERR_Msk));
if (u32Tmp1 && u32Tmp2)
{
u32IntFlag |= UUART_RLS_INT_MASK;
}
/* Check Receive Buffer Over-run Error Interrupt Flag */
u32Tmp1 = (u32Mask & UUART_BUF_RXOV_INT_MASK);
u32Tmp2 = (psUUART->BUFSTS & UUART_BUFSTS_RXOVIF_Msk);
if (u32Tmp1 && u32Tmp2)
{
u32IntFlag |= UUART_BUF_RXOV_INT_MASK;
}
/* Check Transmit Start Interrupt Flag */
u32Tmp1 = (u32Mask & UUART_TXST_INT_MASK);
u32Tmp2 = (psUUART->PROTSTS & UUART_PROTSTS_TXSTIF_Msk);
if (u32Tmp1 && u32Tmp2)
{
u32IntFlag |= UUART_TXST_INT_MASK;
}
/* Check Transmit End Interrupt Flag */
u32Tmp1 = (u32Mask & UUART_TXEND_INT_MASK);
u32Tmp2 = (psUUART->PROTSTS & UUART_PROTSTS_TXENDIF_Msk);
if (u32Tmp1 && u32Tmp2)
{
u32IntFlag |= UUART_TXEND_INT_MASK;
}
/* Check Receive Start Interrupt Flag */
u32Tmp1 = (u32Mask & UUART_RXST_INT_MASK);
u32Tmp2 = (psUUART->PROTSTS & UUART_PROTSTS_RXSTIF_Msk);
if (u32Tmp1 && u32Tmp2)
{
u32IntFlag |= UUART_RXST_INT_MASK;
}
/* Check Receive End Interrupt Flag */
u32Tmp1 = (u32Mask & UUART_RXEND_INT_MASK);
u32Tmp2 = (psUUART->PROTSTS & UUART_PROTSTS_RXENDIF_Msk);
if (u32Tmp1 && u32Tmp2)
{
u32IntFlag |= UUART_RXEND_INT_MASK;
}
return u32IntFlag;
}
/**
* @brief Disable USCI_UART function mode
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
*
* @return None
*
* @details The function is used to disable USCI_UART function mode.
*/
void UUART_Close(UUART_T *psUUART)
{
psUUART->CTL = 0ul;
}
/**
* @brief Disable interrupt function.
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
* @param[in] u32Mask The combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt enable bit.
* This parameter decides which interrupts will be disabled. It is combination of:
* - \ref UUART_ABR_INT_MASK
* - \ref UUART_RLS_INT_MASK
* - \ref UUART_BUF_RXOV_INT_MASK
* - \ref UUART_TXST_INT_MASK
* - \ref UUART_TXEND_INT_MASK
* - \ref UUART_RXST_INT_MASK
* - \ref UUART_RXEND_INT_MASK
*
* @return None
*
* @details The function is used to disabled USCI_UART related interrupts specified by u32Mask parameter.
*/
void UUART_DisableInt(UUART_T *psUUART, uint32_t u32Mask)
{
/* Disable Auto-baud rate interrupt flag */
if ((u32Mask & UUART_ABR_INT_MASK) == UUART_ABR_INT_MASK)
{
psUUART->PROTIEN &= ~UUART_PROTIEN_ABRIEN_Msk;
}
/* Disable receive line status interrupt flag */
if ((u32Mask & UUART_RLS_INT_MASK) == UUART_RLS_INT_MASK)
{
psUUART->PROTIEN &= ~UUART_PROTIEN_RLSIEN_Msk;
}
/* Disable RX overrun interrupt flag */
if ((u32Mask & UUART_BUF_RXOV_INT_MASK) == UUART_BUF_RXOV_INT_MASK)
{
psUUART->BUFCTL &= ~UUART_BUFCTL_RXOVIEN_Msk;
}
/* Disable TX start interrupt flag */
if ((u32Mask & UUART_TXST_INT_MASK) == UUART_TXST_INT_MASK)
{
psUUART->INTEN &= ~UUART_INTEN_TXSTIEN_Msk;
}
/* Disable TX end interrupt flag */
if ((u32Mask & UUART_TXEND_INT_MASK) == UUART_TXEND_INT_MASK)
{
psUUART->INTEN &= ~UUART_INTEN_TXENDIEN_Msk;
}
/* Disable RX start interrupt flag */
if ((u32Mask & UUART_RXST_INT_MASK) == UUART_RXST_INT_MASK)
{
psUUART->INTEN &= ~UUART_INTEN_RXSTIEN_Msk;
}
/* Disable RX end interrupt flag */
if ((u32Mask & UUART_RXEND_INT_MASK) == UUART_RXEND_INT_MASK)
{
psUUART->INTEN &= ~UUART_INTEN_RXENDIEN_Msk;
}
}
/**
* @brief Enable interrupt function.
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
* @param[in] u32Mask The combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt enable bit.
* This parameter decides which interrupts will be enabled. It is combination of:
* - \ref UUART_ABR_INT_MASK
* - \ref UUART_RLS_INT_MASK
* - \ref UUART_BUF_RXOV_INT_MASK
* - \ref UUART_TXST_INT_MASK
* - \ref UUART_TXEND_INT_MASK
* - \ref UUART_RXST_INT_MASK
* - \ref UUART_RXEND_INT_MASK
*
* @return None
*
* @details The function is used to enable USCI_UART related interrupts specified by u32Mask parameter.
*/
void UUART_EnableInt(UUART_T *psUUART, uint32_t u32Mask)
{
/* Enable Auto-baud rate interrupt flag */
if ((u32Mask & UUART_ABR_INT_MASK) == UUART_ABR_INT_MASK)
{
psUUART->PROTIEN |= UUART_PROTIEN_ABRIEN_Msk;
}
/* Enable receive line status interrupt flag */
if ((u32Mask & UUART_RLS_INT_MASK) == UUART_RLS_INT_MASK)
{
psUUART->PROTIEN |= UUART_PROTIEN_RLSIEN_Msk;
}
/* Enable RX overrun interrupt flag */
if ((u32Mask & UUART_BUF_RXOV_INT_MASK) == UUART_BUF_RXOV_INT_MASK)
{
psUUART->BUFCTL |= UUART_BUFCTL_RXOVIEN_Msk;
}
/* Enable TX start interrupt flag */
if ((u32Mask & UUART_TXST_INT_MASK) == UUART_TXST_INT_MASK)
{
psUUART->INTEN |= UUART_INTEN_TXSTIEN_Msk;
}
/* Enable TX end interrupt flag */
if ((u32Mask & UUART_TXEND_INT_MASK) == UUART_TXEND_INT_MASK)
{
psUUART->INTEN |= UUART_INTEN_TXENDIEN_Msk;
}
/* Enable RX start interrupt flag */
if ((u32Mask & UUART_RXST_INT_MASK) == UUART_RXST_INT_MASK)
{
psUUART->INTEN |= UUART_INTEN_RXSTIEN_Msk;
}
/* Enable RX end interrupt flag */
if ((u32Mask & UUART_RXEND_INT_MASK) == UUART_RXEND_INT_MASK)
{
psUUART->INTEN |= UUART_INTEN_RXENDIEN_Msk;
}
}
/**
* @brief Open and set USCI_UART function
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
* @param[in] u32Baudrate The baud rate of USCI_UART module.
*
* @return Real baud rate of USCI_UART module.
*
* @details This function use to enable USCI_UART function and set baud-rate.
*/
uint32_t UUART_Open(UUART_T *psUUART, uint32_t u32Baudrate)
{
uint32_t u32PCLKFreq, u32PDSCnt, u32DSCnt, u32ClkDiv;
uint32_t u32Tmp, u32Tmp2, u32Tmp3, u32Min, u32MinClkDiv, u32MinDSCnt;
uint32_t u32Div;
/* Get PCLK frequency */
if ((psUUART == UUART0) || (psUUART == UUART2))
{
u32PCLKFreq = CLK_GetPCLK0Freq();
}
else
{
u32PCLKFreq = CLK_GetPCLK1Freq();
}
/* Find out divide value */
u32Div = u32PCLKFreq / u32Baudrate;
/* Avoid decimal of divider being discarded and find divider that are closest to the baud rate */
u32Tmp = (u32PCLKFreq / u32Div) - u32Baudrate;
u32Tmp2 = u32Baudrate - (u32PCLKFreq / (u32Div + 1));
if (u32Tmp >= u32Tmp2)
{
u32Div = u32Div + 1;
}
/* Divide value = CLKDIV(MAX. = 0x400) * DSCNT(MAX. = 0x10) * PDSCNT */
u32Tmp = 0x400 * 0x10;
/* Find out PDSCNT value */
for (u32PDSCnt = 1; u32PDSCnt <= 0x04; u32PDSCnt++)
{
if (u32Div <= (u32Tmp * u32PDSCnt)) break;
}
/* PDSCNT MAX.= 0x4 */
if (u32PDSCnt > 0x4) u32PDSCnt = 0x4;
/* Avoid decimal of PDSCNT being discarded */
u32Tmp = u32Div / u32PDSCnt;
u32Tmp2 = (u32Div / u32Tmp) - u32PDSCnt;
u32Tmp3 = u32PDSCnt - (u32Div / (u32Tmp + 1));
if (u32Tmp2 >= u32Tmp3)
{
u32Div = u32Tmp + 1;
}
else u32Div = u32Tmp;
/* Find best solution of DSCNT and CLKDIV*/
u32Min = (uint32_t) - 1;
u32MinDSCnt = 0;
u32MinClkDiv = 0;
u32Tmp = 0;
for (u32DSCnt = 6; u32DSCnt <= 0x10; u32DSCnt++) /* DSCNT could be 0x5~0xF */
{
u32ClkDiv = u32Div / u32DSCnt;
if (u32ClkDiv >= 0x400)
{
u32ClkDiv = 0x400;
u32Tmp = u32Tmp2 = abs((int)(u32PCLKFreq / (u32ClkDiv * u32DSCnt * u32PDSCnt)) - (int)u32Baudrate);
}
else /* Avoid decimal of PDSCNT being discarded */
{
u32Tmp = abs((int)(u32PCLKFreq / (u32ClkDiv * u32DSCnt * u32PDSCnt)) - (int)u32Baudrate);
u32Tmp2 = abs((int)(u32PCLKFreq / ((u32ClkDiv + 1) * u32DSCnt * u32PDSCnt)) - (int)u32Baudrate);
}
if (u32Tmp > u32Tmp2)
{
u32ClkDiv = u32ClkDiv + 1;
}
else u32Tmp2 = u32Tmp;
/* Record the closest solution */
if (u32Tmp2 < u32Min)
{
u32Min = u32Tmp2;
u32MinDSCnt = u32DSCnt;
u32MinClkDiv = u32ClkDiv;
/* Break when get good results */
if (u32Min == 0)
{
break;
}
}
}
/* Enable USCI_UART protocol */
psUUART->CTL &= ~UUART_CTL_FUNMODE_Msk;
psUUART->CTL = 2 << UUART_CTL_FUNMODE_Pos;
/* Set USCI_UART line configuration */
psUUART->LINECTL = UUART_WORD_LEN_8 | UUART_LINECTL_LSB_Msk;
psUUART->DATIN0 = (2 << UUART_DATIN0_EDGEDET_Pos); /* Set falling edge detection */
/* Set USCI_UART baud rate */
psUUART->BRGEN = ((u32MinClkDiv - 1) << UUART_BRGEN_CLKDIV_Pos) |
((u32MinDSCnt - 1) << UUART_BRGEN_DSCNT_Pos) |
((u32PDSCnt - 1) << UUART_BRGEN_PDSCNT_Pos);
psUUART->PROTCTL |= UUART_PROTCTL_PROTEN_Msk;
return (u32PCLKFreq / u32PDSCnt / u32MinDSCnt / u32MinClkDiv);
}
/**
* @brief Read USCI_UART data
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
* @param[in] pu8RxBuf The buffer to receive the data of receive buffer.
* @param[in] u32ReadBytes The read bytes number of data.
*
* @return Receive byte count
*
* @details The function is used to read Rx data from RX buffer and the data will be stored in pu8RxBuf.
*/
uint32_t UUART_Read(UUART_T *psUUART, uint8_t pu8RxBuf[], uint32_t u32ReadBytes)
{
uint32_t u32Count, u32Delayno;
for (u32Count = 0ul; u32Count < u32ReadBytes; u32Count++)
{
u32Delayno = 0ul;
while (psUUART->BUFSTS & UUART_BUFSTS_RXEMPTY_Msk) /* Check RX empty => failed */
{
u32Delayno++;
if (u32Delayno >= 0x40000000ul)
{
break;
}
}
if (u32Delayno >= 0x40000000ul)
{
break;
}
pu8RxBuf[u32Count] = (uint8_t)psUUART->RXDAT; /* Get Data from USCI RX */
}
return u32Count;
}
/**
* @brief Set USCI_UART line configuration
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
* @param[in] u32Baudrate The register value of baud rate of USCI_UART module.
* If u32Baudrate = 0, USCI_UART baud rate will not change.
* @param[in] u32DataWidth The data length of USCI_UART module.
* - \ref UUART_WORD_LEN_6
* - \ref UUART_WORD_LEN_7
* - \ref UUART_WORD_LEN_8
* - \ref UUART_WORD_LEN_9
* @param[in] u32Parity The parity setting (none/odd/even) of USCI_UART module.
* - \ref UUART_PARITY_NONE
* - \ref UUART_PARITY_ODD
* - \ref UUART_PARITY_EVEN
* @param[in] u32StopBits The stop bit length (1/2 bit) of USCI_UART module.
* - \ref UUART_STOP_BIT_1
* - \ref UUART_STOP_BIT_2
*
* @return Real baud rate of USCI_UART module.
*
* @details This function use to config USCI_UART line setting.
*/
uint32_t UUART_SetLine_Config(UUART_T *psUUART, uint32_t u32Baudrate, uint32_t u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits)
{
uint32_t u32PCLKFreq, u32PDSCnt, u32DSCnt, u32ClkDiv;
uint32_t u32Tmp, u32Tmp2, u32Tmp3, u32Min, u32MinClkDiv, u32MinDSCnt;
uint32_t u32Div;
/* Get PCLK frequency */
if ((psUUART == UUART0) || (psUUART == UUART2))
{
u32PCLKFreq = CLK_GetPCLK0Freq();
}
else
{
u32PCLKFreq = CLK_GetPCLK1Freq();
}
if (u32Baudrate != 0)
{
u32Div = u32PCLKFreq / u32Baudrate;
u32Tmp = (u32PCLKFreq / u32Div) - u32Baudrate;
u32Tmp2 = u32Baudrate - (u32PCLKFreq / (u32Div + 1));
if (u32Tmp >= u32Tmp2)
{
u32Div = u32Div + 1;
}
u32Tmp = 0x400 * 0x10;
for (u32PDSCnt = 1; u32PDSCnt <= 0x04; u32PDSCnt++)
{
if (u32Div <= (u32Tmp * u32PDSCnt)) break;
}
if (u32PDSCnt > 0x4) u32PDSCnt = 0x4;
u32Tmp = u32Div / u32PDSCnt;
u32Tmp2 = (u32Div / u32Tmp) - u32PDSCnt;
u32Tmp3 = u32PDSCnt - (u32Div / (u32Tmp + 1));
if (u32Tmp2 >= u32Tmp3)
{
u32Div = u32Tmp + 1;
}
else u32Div = u32Tmp;
/* Find best solution */
u32Min = (uint32_t) - 1;
u32MinDSCnt = 0;
u32MinClkDiv = 0;
u32Tmp = 0;
for (u32DSCnt = 6; u32DSCnt <= 0x10; u32DSCnt++) /* DSCNT could be 0x5~0xF */
{
u32ClkDiv = u32Div / u32DSCnt;
if (u32ClkDiv >= 0x400)
{
u32ClkDiv = 0x400;
u32Tmp = u32Tmp2 = abs((int)(u32PCLKFreq / (u32ClkDiv * u32DSCnt * u32PDSCnt)) - (int)u32Baudrate);
}
else
{
u32Tmp = abs((int)(u32PCLKFreq / (u32ClkDiv * u32DSCnt * u32PDSCnt)) - (int)u32Baudrate);
u32Tmp2 = abs((int)(u32PCLKFreq / ((u32ClkDiv + 1) * u32DSCnt * u32PDSCnt)) - (int)u32Baudrate);
}
if (u32Tmp > u32Tmp2)
{
u32ClkDiv = u32ClkDiv + 1;
}
else u32Tmp2 = u32Tmp;
if (u32Tmp2 < u32Min)
{
u32Min = u32Tmp2;
u32MinDSCnt = u32DSCnt;
u32MinClkDiv = u32ClkDiv;
/* Break when get good results */
if (u32Min == 0)
{
break;
}
}
}
/* Set USCI_UART baud rate */
psUUART->BRGEN = ((u32MinClkDiv - 1) << UUART_BRGEN_CLKDIV_Pos) |
((u32MinDSCnt - 1) << UUART_BRGEN_DSCNT_Pos) |
((u32PDSCnt - 1) << UUART_BRGEN_PDSCNT_Pos);
}
else
{
u32PDSCnt = ((psUUART->BRGEN & UUART_BRGEN_PDSCNT_Msk) >> UUART_BRGEN_PDSCNT_Pos) + 1;
u32MinDSCnt = ((psUUART->BRGEN & UUART_BRGEN_DSCNT_Msk) >> UUART_BRGEN_DSCNT_Pos) + 1;
u32MinClkDiv = ((psUUART->BRGEN & UUART_BRGEN_CLKDIV_Msk) >> UUART_BRGEN_CLKDIV_Pos) + 1;
}
/* Set USCI_UART line configuration */
psUUART->LINECTL = (psUUART->LINECTL & ~UUART_LINECTL_DWIDTH_Msk) | u32DataWidth;
psUUART->PROTCTL = (psUUART->PROTCTL & ~(UUART_PROTCTL_STICKEN_Msk | UUART_PROTCTL_EVENPARITY_Msk |
UUART_PROTCTL_PARITYEN_Msk)) | u32Parity;
psUUART->PROTCTL = (psUUART->PROTCTL & ~UUART_PROTCTL_STOPB_Msk) | u32StopBits;
return (u32PCLKFreq / u32PDSCnt / u32MinDSCnt / u32MinClkDiv);
}
/**
* @brief Write USCI_UART data
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
* @param[in] pu8TxBuf The buffer to send the data to USCI transmission buffer.
* @param[out] u32WriteBytes The byte number of data.
*
* @return Transfer byte count
*
* @details The function is to write data into TX buffer to transmit data by USCI_UART.
*/
uint32_t UUART_Write(UUART_T *psUUART, uint8_t pu8TxBuf[], uint32_t u32WriteBytes)
{
uint32_t u32Count, u32Delayno;
for (u32Count = 0ul; u32Count != u32WriteBytes; u32Count++)
{
u32Delayno = 0ul;
while ((psUUART->BUFSTS & UUART_BUFSTS_TXEMPTY_Msk) == 0ul) /* Wait Tx empty */
{
u32Delayno++;
if (u32Delayno >= 0x40000000ul)
{
break;
}
}
if (u32Delayno >= 0x40000000ul)
{
break;
}
psUUART->TXDAT = (uint8_t)pu8TxBuf[u32Count]; /* Send USCI_UART Data to buffer */
}
return u32Count;
}
/**
* @brief Enable USCI_UART Wake-up Function
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
* @param[in] u32WakeupMode The wakeup mode of USCI_UART module.
* - \ref UUART_PROTCTL_DATWKEN_Msk : Data wake-up Mode
* - \ref UUART_PROTCTL_CTSWKEN_Msk : nCTS wake-up Mode
*
* @return None
*
* @details The function is used to enable Wake-up function of USCI_UART.
*/
void UUART_EnableWakeup(UUART_T *psUUART, uint32_t u32WakeupMode)
{
psUUART->PROTCTL |= u32WakeupMode;
psUUART->WKCTL |= UUART_WKCTL_WKEN_Msk;
}
/**
* @brief Disable USCI_UART Wake-up Function
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
*
* @return None
*
* @details The function is used to disable Wake-up function of USCI_UART.
*/
void UUART_DisableWakeup(UUART_T *psUUART)
{
psUUART->PROTCTL &= ~(UUART_PROTCTL_DATWKEN_Msk | UUART_PROTCTL_CTSWKEN_Msk);
psUUART->WKCTL &= ~UUART_WKCTL_WKEN_Msk;
}
/**
* @brief Enable USCI_UART auto flow control
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
*
* @return None
*
* @details The function is used to enable USCI_UART auto flow control.
*/
void UUART_EnableFlowCtrl(UUART_T *psUUART)
{
/* Set RTS signal is low level active */
psUUART->LINECTL &= ~UUART_LINECTL_CTLOINV_Msk;
/* Set CTS signal is low level active */
psUUART->CTLIN0 &= ~UUART_CTLIN0_ININV_Msk;
/* Enable CTS and RTS auto flow control function */
psUUART->PROTCTL |= UUART_PROTCTL_RTSAUTOEN_Msk | UUART_PROTCTL_CTSAUTOEN_Msk;
}
/**
* @brief Disable USCI_UART auto flow control
*
* @param[in] psUUART The pointer of the specified USCI_UART module.
*
* @return None
*
* @details The function is used to disable USCI_UART auto flow control.
*/
void UUART_DisableFlowCtrl(UUART_T *psUUART)
{
/* Disable CTS and RTS auto flow control function */
psUUART->PROTCTL &= ~(UUART_PROTCTL_RTSAUTOEN_Msk | UUART_PROTCTL_CTSAUTOEN_Msk);
}
/*@}*/ /* end of group USCI_UART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group USCI_UART_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,69 @@
/**************************************************************************//**
* @file wdt.c
* @version V0.10
* @brief M251 series WDT driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.h"
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup WDT_Driver WDT Driver
@{
*/
/** @addtogroup WDT_EXPORTED_FUNCTIONS WDT Exported Functions
@{
*/
/**
* @brief Initialize WDT 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
* * \ref WDT_TIMEOUT_2POW20
* @param[in] u32ResetDelay Configure WDT time-out reset delay period. 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 time-out reset system function. Valid values are TRUE and FALSE.
* @param[in] u32EnableWakeup Enable WDT time-out wake-up system function. Valid values are TRUE and FALSE.
*
* @return None
*
* @details This function makes WDT module start counting with different time-out interval, reset delay period and choose to \n
* enable or disable WDT time-out reset system or wake-up system.
* @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->ALTCTL = u32ResetDelay;
WDT->CTL = u32TimeoutInterval | WDT_CTL_WDTEN_Msk |
(u32EnableReset << WDT_CTL_RSTEN_Pos) |
(u32EnableWakeup << WDT_CTL_WKEN_Pos);
return;
}
/*@}*/ /* end of group WDT_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group WDT_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

View File

@@ -0,0 +1,68 @@
/**************************************************************************//**
* @file wwdt.c
* @version V0.10
* @brief M251 series WWDT driver source file
*
* @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NuMicro.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 makes WWDT module start counting with different counter period and compared window value.
* @note Application can call this function only once after boot up.
*/
void WWDT_Open(uint32_t u32PreScale,
uint32_t u32CmpValue,
uint32_t u32EnableInt)
{
WWDT->CTL = u32PreScale |
(u32CmpValue << WWDT_CTL_CMPDAT_Pos) |
((u32EnableInt == TRUE) ? WWDT_CTL_INTEN_Msk : 0U) |
WWDT_CTL_WWDTEN_Msk;
return;
}
/*@}*/ /* end of group WWDT_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group WWDT_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/