Nuvoton NUC123SD4AN0 MCU port, ready for Ducky One 2 Mini keyboard integration

This commit is contained in:
GitWellBack 2019-05-02 06:14:27 +10:00 committed by Reza Jelveh
parent 290fa44036
commit beaf559be9
43 changed files with 21345 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,409 @@
/**************************************************************************//**
* @file clk.h
* @version V3.0
* $Revision: 16 $
* $Date: 15/07/02 11:21a $
* @brief NUC123 Series Clock Control Driver Header File
*
* @note
* Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __CLK_H__
#define __CLK_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup CLK_Driver CLK Driver
@{
*/
/** @addtogroup CLK_EXPORTED_CONSTANTS CLK Exported Constants
@{
*/
#define FREQ_25MHZ 25000000
#define FREQ_50MHZ 50000000
#define FREQ_72MHZ 72000000
#define FREQ_100MHZ 100000000
#define FREQ_200MHZ 200000000
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL0 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL0_HCLK_S_HXT (0x0UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as HXT */
#define CLK_CLKSEL0_HCLK_S_PLL_DIV2 (0x1UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as PLL/2 */
#define CLK_CLKSEL0_HCLK_S_PLL (0x2UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as PLL */
#define CLK_CLKSEL0_HCLK_S_LIRC (0x3UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as LIRC */
#define CLK_CLKSEL0_HCLK_S_HIRC (0x7UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as HIRC */
#define CLK_CLKSEL0_STCLK_S_HXT (0x0UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as HXT */
#define CLK_CLKSEL0_STCLK_S_HXT_DIV2 (0x2UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as HXT/2 */
#define CLK_CLKSEL0_STCLK_S_HCLK_DIV2 (0x3UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as HCLK/2 */
#define CLK_CLKSEL0_STCLK_S_HIRC_DIV2 (0x7UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as HIRC/2 */
#define CLK_CLKSEL0_STCLK_S_HCLK (0x1UL<<SysTick_CTRL_CLKSOURCE_Pos) /*!< Setting STCLK clock source as HCLK */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL1 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL1_WDT_S_HCLK_DIV2048 (0x2UL<<CLK_CLKSEL1_WDT_S_Pos) /*!< Setting WDT clock source as HCLK/2048 */
#define CLK_CLKSEL1_WDT_S_LIRC (0x3UL<<CLK_CLKSEL1_WDT_S_Pos) /*!< Setting WDT clock source as LIRC */
#define CLK_CLKSEL1_ADC_S_HXT (0x0UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as HXT */
#define CLK_CLKSEL1_ADC_S_PLL (0x1UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as PLL */
#define CLK_CLKSEL1_ADC_S_HCLK (0x2UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as HCLK */
#define CLK_CLKSEL1_ADC_S_HIRC (0x3UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as HIRC */
#define CLK_CLKSEL1_SPI0_S_PLL (0x0UL<<CLK_CLKSEL1_SPI0_S_Pos) /*!< Setting SPI0 clock source as PLL */
#define CLK_CLKSEL1_SPI0_S_HCLK (0x1UL<<CLK_CLKSEL1_SPI0_S_Pos) /*!< Setting SPI0 clock source as HCLK */
#define CLK_CLKSEL1_SPI1_S_PLL (0x0UL<<CLK_CLKSEL1_SPI1_S_Pos) /*!< Setting SPI1 clock source as PLL */
#define CLK_CLKSEL1_SPI1_S_HCLK (0x1UL<<CLK_CLKSEL1_SPI1_S_Pos) /*!< Setting SPI1 clock source as HCLK */
#define CLK_CLKSEL1_SPI2_S_PLL (0x0UL<<CLK_CLKSEL1_SPI2_S_Pos) /*!< Setting SPI2 clock source as PLL */
#define CLK_CLKSEL1_SPI2_S_HCLK (0x1UL<<CLK_CLKSEL1_SPI2_S_Pos) /*!< Setting SPI2 clock source as HCLK */
#define CLK_CLKSEL1_TMR0_S_HXT (0x0UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as HXT */
#define CLK_CLKSEL1_TMR0_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as HCLK */
#define CLK_CLKSEL1_TMR0_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as external trigger */
#define CLK_CLKSEL1_TMR0_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as LIRC */
#define CLK_CLKSEL1_TMR0_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as HIRC */
#define CLK_CLKSEL1_TMR1_S_HXT (0x0UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as HXT */
#define CLK_CLKSEL1_TMR1_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as HCLK */
#define CLK_CLKSEL1_TMR1_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as external trigger */
#define CLK_CLKSEL1_TMR1_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as LIRC */
#define CLK_CLKSEL1_TMR1_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as HIRC*/
#define CLK_CLKSEL1_TMR2_S_HXT (0x0UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as external X'tal */
#define CLK_CLKSEL1_TMR2_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as HCLK */
#define CLK_CLKSEL1_TMR2_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as external trigger */
#define CLK_CLKSEL1_TMR2_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as LIRC */
#define CLK_CLKSEL1_TMR2_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as HIRC */
#define CLK_CLKSEL1_TMR3_S_HXT (0x0UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as HXT */
#define CLK_CLKSEL1_TMR3_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as HCLK */
#define CLK_CLKSEL1_TMR3_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as external trigger */
#define CLK_CLKSEL1_TMR3_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as LIRC*/
#define CLK_CLKSEL1_TMR3_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as HIRC */
#define CLK_CLKSEL1_UART_S_HXT (0x0UL<<CLK_CLKSEL1_UART_S_Pos) /*!< Setting UART clock source as HXT */
#define CLK_CLKSEL1_UART_S_PLL (0x1UL<<CLK_CLKSEL1_UART_S_Pos) /*!< Setting UART clock source as PLL */
#define CLK_CLKSEL1_UART_S_HIRC (0x3UL<<CLK_CLKSEL1_UART_S_Pos) /*!< Setting UART clock source as HIRC */
#define CLK_CLKSEL1_PWM01_S_HXT (0x0UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as HXT,
user must set CLK_CLKSEL2_PWM01_EXT_HXT concurrently to complete clock source as HXT setting*/
#define CLK_CLKSEL1_PWM01_S_HCLK (0x2UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as HCLK
user must set CLK_CLKSEL2_PWM01_EXT_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL1_PWM01_S_HIRC (0x3UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as HIRC clock,
user must set CLK_CLKSEL2_PWM01_EXT_HIRC concurrently to complete clock source as HIRC clock setting*/
#define CLK_CLKSEL1_PWM01_S_LIRC (0x3UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as LIRC clock,
user must set CLK_CLKSEL2_PWM01_EXT_LIRC concurrently to complete clock source as LIRC clock setting*/
#define CLK_CLKSEL1_PWM23_S_HXT (0x0UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as HXT,
user must set CLK_CLKSEL2_PWM23_EXT_HXT concurrently to complete clock source as HXT setting*/
#define CLK_CLKSEL1_PWM23_S_HCLK (0x2UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as HCLK,
user must set CLK_CLKSEL2_PWM23_EXT_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL1_PWM23_S_HIRC (0x3UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as HIRC clock,
user must set CLK_CLKSEL2_PWM23_EXT_HIRC concurrently to complete clock source as HIRC clock setting*/
#define CLK_CLKSEL1_PWM23_S_LIRC (0x3UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as LIRC clock,
user must set CLK_CLKSEL2_PWM23_EXT_LIRC concurrently to complete clock source as LIRC setting*/
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL2 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL2_I2S_S_HXT (0x0UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as HXT */
#define CLK_CLKSEL2_I2S_S_PLL (0x1UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as PLL */
#define CLK_CLKSEL2_I2S_S_HCLK (0x2UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as HCLK */
#define CLK_CLKSEL2_I2S_S_HIRC (0x3UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as HIRC */
#define CLK_CLKSEL2_FRQDIV_S_HXT (0x0UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Setting FRQDIV clock source as HXT */
#define CLK_CLKSEL2_FRQDIV_S_HCLK (0x2UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Setting FRQDIV clock source as HCLK */
#define CLK_CLKSEL2_FRQDIV_S_HIRC (0x3UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Setting FRQDIV clock source as HIRC */
#define CLK_CLKSEL2_PWM01_EXT_HXT (0x0UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as HXT,
user must set CLK_CLKSEL1_PWM01_HXT concurrently to complete clock source as HXT setting*/
#define CLK_CLKSEL2_PWM01_EXT_HCLK (0x0UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as HCLK,
user must set CLK_CLKSEL1_PWM01_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL2_PWM01_EXT_HIRC (0x0UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as HIRC,
user must set CLK_CLKSEL1_PWM01_HIRC concurrently to complete clock source as HIRC setting*/
#define CLK_CLKSEL2_PWM01_EXT_LIRC (0x1UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as LIRC,
user must set CLK_CLKSEL1_PWM01_LIRC concurrently to complete clock source as LIRC setting*/
#define CLK_CLKSEL2_PWM23_EXT_HXT (0x0UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as HXT,
user must set CLK_CLKSEL1_PWM23_HXT concurrently to complete clock source as HXT setting*/
#define CLK_CLKSEL2_PWM23_EXT_HCLK (0x0UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as HCLK,
user must set CLK_CLKSEL1_PWM23_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL2_PWM23_EXT_HIRC (0x0UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as HIRC clock,
user must set CLK_CLKSEL1_PWM23_HIRC concurrently to complete clock source as HIRC setting*/
#define CLK_CLKSEL2_PWM23_EXT_LIRC (0x1UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as LIRC,
user must set CLK_CLKSEL1_PWM23_LIRC concurrently to complete clock source as LIRC setting*/
#define CLK_CLKSEL2_WWDT_S_HCLK_DIV2048 (0x2UL<<CLK_CLKSEL2_WWDT_S_Pos) /*!< Setting WWDT clock source as HCLK/2048 */
#define CLK_CLKSEL2_WWDT_S_LIRC (0x3UL<<CLK_CLKSEL2_WWDT_S_Pos) /*!< Setting WWDT clock source as LIRC */
#define CLK_CLKSEL12_PWM01_S_HXT (CLK_CLKSEL1_PWM01_S_HXT | CLK_CLKSEL2_PWM01_EXT_HXT ) /*!< Setting PWM01 clock source as HXT */
#define CLK_CLKSEL12_PWM01_S_HCLK (CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK) /*!< Setting PWM01 clock source as HCLK */
#define CLK_CLKSEL12_PWM01_S_HIRC (CLK_CLKSEL1_PWM01_S_HIRC | CLK_CLKSEL2_PWM01_EXT_HIRC) /*!< Setting PWM01 clock source as HIRC */
#define CLK_CLKSEL12_PWM01_S_LIRC (CLK_CLKSEL1_PWM01_S_LIRC | CLK_CLKSEL2_PWM01_EXT_LIRC) /*!< Setting PWM01 clock source as LIRC */
#define CLK_CLKSEL12_PWM23_S_HXT (CLK_CLKSEL1_PWM23_S_HXT | CLK_CLKSEL2_PWM23_EXT_HXT ) /*!< Setting PWM23 clock source as HXT */
#define CLK_CLKSEL12_PWM23_S_HCLK (CLK_CLKSEL1_PWM23_S_HCLK | CLK_CLKSEL2_PWM23_EXT_HCLK) /*!< Setting PWM23 clock source as HCLK */
#define CLK_CLKSEL12_PWM23_S_HIRC (CLK_CLKSEL1_PWM23_S_HIRC | CLK_CLKSEL2_PWM23_EXT_HIRC) /*!< Setting PWM23 clock source as HIRC */
#define CLK_CLKSEL12_PWM23_S_LIRC (CLK_CLKSEL1_PWM23_S_LIRC | CLK_CLKSEL2_PWM23_EXT_LIRC) /*!< Setting PWM23 clock source as LIRC */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKDIV constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKDIV_HCLK(x) ((x)-1) /*!< CLKDIV Setting for HCLK clock divider. It could be 1~16 */
#define CLK_CLKDIV_USB(x) (((x)-1) << CLK_CLKDIV_USB_N_Pos) /*!< CLKDIV Setting for USB clock divider. It could be 1~16 */
#define CLK_CLKDIV_UART(x) (((x)-1) << CLK_CLKDIV_UART_N_Pos) /*!< CLKDIV Setting for UART clock divider. It could be 1~16 */
#define CLK_CLKDIV_ADC(x) (((x)-1) << CLK_CLKDIV_ADC_N_Pos) /*!< CLKDIV Setting for ADC clock divider. It could be 1~256 */
/*---------------------------------------------------------------------------------------------------------*/
/* PLLCON constant definitions. PLL = FIN * NF / NR / NO */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_PLLCON_PLL_SRC_HXT 0x00000000UL /*!< For PLL clock source is HXT. 4MHz < FIN < 24MHz */
#define CLK_PLLCON_PLL_SRC_HIRC 0x00080000UL /*!< For PLL clock source is HIRC.4MHz < FIN < 24MHz */
#define CLK_PLLCON_NR(x) (((x)-2)<<9) /*!< x must be constant and 2 <= x <= 33. 1.6MHz < FIN/NR < 15MHz */
#define CLK_PLLCON_NF(x) ((x)-2) /*!< x must be constant and 2 <= x <= 513. 100MHz < FIN*NF/NR < 200MHz. (120MHz < FIN*NF/NR < 200MHz is preferred.) */
#define CLK_PLLCON_NO_1 0x0000UL /*!< For output divider is 1 */
#define CLK_PLLCON_NO_2 0x4000UL /*!< For output divider is 2 */
#define CLK_PLLCON_NO_4 0xC000UL /*!< For output divider is 4 */
#if (__HXT == 12000000)
#define CLK_PLLCON_FOR_I2S (0xA54) /*!< Predefined PLLCON setting for 147428571.428571Hz PLL output with 12MHz X'tal */
#define CLK_PLLCON_144MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(2) | CLK_PLLCON_NF( 24) | CLK_PLLCON_NO_1) /*!< Predefined PLLCON setting for 72MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_72MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(2) | CLK_PLLCON_NF( 24) | CLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 72MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_50MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF( 25) | CLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 50MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_48MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(7) | CLK_PLLCON_NF(112) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 48MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_36MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(7) | CLK_PLLCON_NF( 84) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 36MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_32MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(6) | CLK_PLLCON_NF( 64) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 32MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_24MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(2) | CLK_PLLCON_NF( 16) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 24MHz PLL output with 12MHz X'tal */
#else
# error "The PLL pre-definitions are only valid when external crystal is 12MHz"
#endif
#define CLK_PLLCON_72MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR( 4) | CLK_PLLCON_NF( 26) | CLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 71.88488MHz PLL output with 22.1184MHz IRC */
#define CLK_PLLCON_50MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR(13) | CLK_PLLCON_NF( 59) | CLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 50.1918MHz PLL output with 22.1184MHz IRC */
#define CLK_PLLCON_48MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR(13) | CLK_PLLCON_NF(113) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 48.064985MHz PLL output with 22.1184MHz IRC*/
#define CLK_PLLCON_36MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR(12) | CLK_PLLCON_NF( 78) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 35.9424MHz PLL output with 22.1184MHz IRC */
#define CLK_PLLCON_32MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR( 9) | CLK_PLLCON_NF( 52) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 31.9488MHz PLL output with 22.1184MHz IRC*/
#define CLK_PLLCON_24MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR( 3) | CLK_PLLCON_NF( 13) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 23.9616MHz PLL output with 22.1184MHz IRC*/
/*---------------------------------------------------------------------------------------------------------*/
/* MODULE constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
/* APBCLK(31:30)|CLKSEL(29:28)|CLKSEL_Msk(27:25) |CLKSEL_Pos(24:20)|CLKDIV(19:18)|CLKDIV_Msk(17:10)|CLKDIV_Pos(9:5)|IP_EN_Pos(4:0) */
#define MODULE_APBCLK(x) (((x) >>30) & 0x3) /*!< Calculate APBCLK offset on MODULE index, 0x0:AHBCLK, 0x1:APBCLK */
#define MODULE_CLKSEL(x) (((x) >>28) & 0x3) /*!< Calculate CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2 */
#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 */
#define MODULE_CLKDIV_Msk(x) (((x) >>10) & 0xff) /*!< Calculate CLKDIV mask offset on MODULE index */
#define MODULE_CLKDIV_Pos(x) (((x) >>5 ) & 0x1f) /*!< Calculate CLKDIV position offset on MODULE index */
#define MODULE_IP_EN_Pos(x) (((x) >>0 ) & 0x1f) /*!< Calculate APBCLK offset on MODULE index */
#define MODULE_NoMsk 0x0 /*!< Not mask on MODULE index */
#define NA MODULE_NoMsk /*!< Not Available */
#define MODULE_APBCLK_ENC(x) (((x) & 0x03) << 30) /*!< MODULE index, 0x0:AHBCLK, 0x1:APBCLK */
#define MODULE_CLKSEL_ENC(x) (((x) & 0x03) << 28) /*!< CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2 */
#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 */
#define MODULE_CLKDIV_Msk_ENC(x) (((x) & 0xff) << 10) /*!< CLKDIV mask offset on MODULE index */
#define MODULE_CLKDIV_Pos_ENC(x) (((x) & 0x1f) << 5) /*!< CLKDIV position offset on MODULE index */
#define MODULE_IP_EN_Pos_ENC(x) (((x) & 0x1f) << 0) /*!< APBCLK offset on MODULE index */
#define PDMA_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_PDMA_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PDMA Module */
#define ISP_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_ISP_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< ISP Module */
#define WDT_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_WDT_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 0)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< WDT Module */
#define TMR0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR0_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC( 8)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR0 Module */
#define TMR1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR1_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(12)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR1 Module */
#define TMR2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR2_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(16)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR2 Module */
#define TMR3_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR3_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(20)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR3 Module */
#define FDIV_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_FDIV_EN_Pos) |\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 2)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< FDIV Module */
#define I2C0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_I2C0_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2C0 Module */
#define I2C1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_I2C1_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2C1 Module */
#define SPI0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_SPI0_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 4)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI0 Module */
#define SPI1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_SPI1_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 5)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI1 Module */
#define SPI2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_SPI2_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 6)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI2 Module */
#define UART0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_UART0_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART0 Module */
#define UART1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_UART1_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART1 Module */
#define PWM01_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PWM01_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(28)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM01 Module */
#define PWM23_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PWM23_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(30)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM23 Module */
#define USBD_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_USBD_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC(4)) /*!< USBD Module */
#define ADC_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_ADC_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 2)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0xFF)|MODULE_CLKDIV_Pos_ENC(16)) /*!< ADC Module */
#define I2S_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_I2S_EN_Pos) |\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 0)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2S Module */
#define PS2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PS2_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PS2 Module */
#define WWDT_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_WDT_EN_Pos) |\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(16)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< WWDT Module */
/*@}*/ /* end of group CLK_EXPORTED_CONSTANTS */
/** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions
@{
*/
/**
* @brief Get PLL clock frequency
* @param None
* @return PLL frequency
* @details This function get PLL frequency. The frequency unit is Hz.
*/
__STATIC_INLINE uint32_t CLK_GetPLLClockFreq(void)
{
uint32_t u32PllFreq = 0, u32PllReg;
uint32_t u32FIN, u32NF, u32NR, u32NO;
uint8_t au8NoTbl[4] = {1, 2, 2, 4};
u32PllReg = CLK->PLLCON;
if(u32PllReg & (CLK_PLLCON_PD_Msk | CLK_PLLCON_OE_Msk))
return 0; /* PLL is in power down mode or fix low */
if(u32PllReg & CLK_PLLCON_PLL_SRC_HIRC)
u32FIN = __HIRC; /* PLL source clock from HIRC */
else
u32FIN = __HXT; /* PLL source clock from HXT */
if(u32PllReg & CLK_PLLCON_BP_Msk)
return u32FIN; /* PLL is in bypass mode */
/* PLL is output enabled in normal work mode */
u32NO = au8NoTbl[((u32PllReg & CLK_PLLCON_OUT_DV_Msk) >> CLK_PLLCON_OUT_DV_Pos)];
u32NF = ((u32PllReg & CLK_PLLCON_FB_DV_Msk) >> CLK_PLLCON_FB_DV_Pos) + 2;
u32NR = ((u32PllReg & CLK_PLLCON_IN_DV_Msk) >> CLK_PLLCON_IN_DV_Pos) + 2;
/* u32FIN is shifted 2 bits to avoid overflow */
u32PllFreq = (((u32FIN >> 2) * u32NF) / (u32NR * u32NO) << 2);
return u32PllFreq;
}
/**
* @brief This function execute delay function.
* @param[in] us Delay time. The Max value is 2^24 / CPU Clock(MHz). Ex:
* 72MHz => 233016us, 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 us)
{
SysTick->LOAD = us * CyclesPerUs;
SysTick->VAL = (0x00);
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
/* Waiting for down-count to zero */
while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
/* Disable SysTick counter */
SysTick->CTRL = 0;
}
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_GetHCLKFreq(void);
uint32_t CLK_GetPCLKFreq(void);
uint32_t CLK_GetCPUFreq(void);
uint32_t CLK_SetCoreClock(uint32_t u32Hclk);
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv);
void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv);
void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc);
void CLK_EnableXtalRC(uint32_t u32ClkMask);
void CLK_DisableXtalRC(uint32_t u32ClkMask);
void CLK_EnableModuleClock(uint32_t u32ModuleIdx);
void CLK_DisableModuleClock(uint32_t u32ModuleIdx);
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq);
void CLK_DisablePLL(void);
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask);
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count);
void CLK_DisableSysTick(void);
/*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CLK_Driver */
/*@}*/ /* end of group Standard_Driver */
#endif //__CLK_H__
/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/

View File

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

View File

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

View File

@ -0,0 +1,457 @@
/**************************************************************************//**
* @file GPIO.h
* @version V3.00
* $Revision: 13 $
* $Date: 15/07/02 11:21a $
* @brief NUC123 Series General Purpose I/O Driver Header File
*
* @note
* Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __GPIO_H__
#define __GPIO_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup GPIO_Driver GPIO Driver
@{
*/
/** @addtogroup GPIO_EXPORTED_CONSTANTS GPIO Exported Constants
@{
*/
#define GPIO_PIN_MAX 16 /*!< Specify Maximum Pins of Each GPIO Port */
/*---------------------------------------------------------------------------------------------------------*/
/* PMD Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_PMD_INPUT 0x0UL /*!< Input Mode */
#define GPIO_PMD_OUTPUT 0x1UL /*!< Output Mode */
#define GPIO_PMD_OPEN_DRAIN 0x2UL /*!< Open-Drain Mode */
#define GPIO_PMD_QUASI 0x3UL /*!< Quasi-bidirectional Mode */
/*---------------------------------------------------------------------------------------------------------*/
/* GPIO Interrupt Type Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_INT_RISING 0x00010000UL /*!< Interrupt enable by Input Rising Edge */
#define GPIO_INT_FALLING 0x00000001UL /*!< Interrupt enable by Input Falling Edge */
#define GPIO_INT_BOTH_EDGE 0x00010001UL /*!< Interrupt enable by both Rising Edge and Falling Edge */
#define GPIO_INT_HIGH 0x01010000UL /*!< Interrupt enable by Level-High */
#define GPIO_INT_LOW 0x01000001UL /*!< Interrupt enable by Level-Level */
/*---------------------------------------------------------------------------------------------------------*/
/* IMD Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_IMD_EDGE 0UL /*!< IMD Setting for Edge Trigger Mode */
#define GPIO_IMD_LEVEL 1UL /*!< IMD Setting for Edge Level Mode */
/*---------------------------------------------------------------------------------------------------------*/
/* DBNCECON Constant Definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define GPIO_INT_CLK_ON 0x00000020UL /*!< DBNCECON setting for all IO pins edge detection circuit is always active after reset */
#define GPIO_INT_CLK_OFF 0x00000000UL /*!< DBNCECON setting for edge detection circuit is active only if IO pin corresponding GPIOx_IEN bit is set to 1 */
#define GPIO_DBCLKSRC_LIRC 0x00000010UL /*!< DBNCECON setting for de-bounce counter clock source is the internal 10 kHz */
#define GPIO_DBCLKSRC_HCLK 0x00000000UL /*!< DBNCECON setting for de-bounce counter clock source is the HCLK */
#define GPIO_DBCLKSEL_1 0x00000000UL /*!< DBNCECON setting for sampling cycle = 1 clocks */
#define GPIO_DBCLKSEL_2 0x00000001UL /*!< DBNCECON setting for sampling cycle = 2 clocks */
#define GPIO_DBCLKSEL_4 0x00000002UL /*!< DBNCECON setting for sampling cycle = 4 clocks */
#define GPIO_DBCLKSEL_8 0x00000003UL /*!< DBNCECON setting for sampling cycle = 8 clocks */
#define GPIO_DBCLKSEL_16 0x00000004UL /*!< DBNCECON setting for sampling cycle = 16 clocks */
#define GPIO_DBCLKSEL_32 0x00000005UL /*!< DBNCECON setting for sampling cycle = 32 clocks */
#define GPIO_DBCLKSEL_64 0x00000006UL /*!< DBNCECON setting for sampling cycle = 64 clocks */
#define GPIO_DBCLKSEL_128 0x00000007UL /*!< DBNCECON setting for sampling cycle = 128 clocks */
#define GPIO_DBCLKSEL_256 0x00000008UL /*!< DBNCECON setting for sampling cycle = 256 clocks */
#define GPIO_DBCLKSEL_512 0x00000009UL /*!< DBNCECON setting for sampling cycle = 512 clocks */
#define GPIO_DBCLKSEL_1024 0x0000000AUL /*!< DBNCECON setting for sampling cycle = 1024 clocks */
#define GPIO_DBCLKSEL_2048 0x0000000BUL /*!< DBNCECON setting for sampling cycle = 2048 clocks */
#define GPIO_DBCLKSEL_4096 0x0000000CUL /*!< DBNCECON setting for sampling cycle = 4096 clocks */
#define GPIO_DBCLKSEL_8192 0x0000000DUL /*!< DBNCECON setting for sampling cycle = 8192 clocks */
#define GPIO_DBCLKSEL_16384 0x0000000EUL /*!< DBNCECON setting for sampling cycle = 16384 clocks */
#define GPIO_DBCLKSEL_32768 0x0000000FUL /*!< DBNCECON setting for sampling cycle = 32768 clocks */
/* Define GPIO Pin Data Input/Output. It could be used to control each I/O pin by pin address mapping.
Example 1:
PA10 = 1;
It is used to set GPIO PA.10 to high;
Example 2:
if (PA10)
PA10 = 0;
If GPIO PA.10 pin status is high, then set GPIO PA.10 data output to low.
*/
#define GPIO_PIN_DATA(port, pin) (*((volatile uint32_t *)((GPIO_PIN_DATA_BASE+(0x40*(port))) + ((pin)<<2))))
#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 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 PC8 GPIO_PIN_DATA(2, 8 ) /*!< Specify PC.8 Pin Data Input/Output */
#define PC9 GPIO_PIN_DATA(2, 9 ) /*!< Specify PC.9 Pin Data Input/Output */
#define PC10 GPIO_PIN_DATA(2, 10) /*!< Specify PC.10 Pin Data Input/Output */
#define PC11 GPIO_PIN_DATA(2, 11) /*!< Specify PC.11 Pin Data Input/Output */
#define PC12 GPIO_PIN_DATA(2, 12) /*!< Specify PC.12 Pin Data Input/Output */
#define PC13 GPIO_PIN_DATA(2, 13) /*!< Specify PC.13 Pin Data Input/Output */
#define 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 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 PF0 GPIO_PIN_DATA(5, 0 ) /*!< Specify PF.0 Pin Data Input/Output */
#define PF1 GPIO_PIN_DATA(5, 1 ) /*!< Specify PF.1 Pin Data Input/Output */
#define PF2 GPIO_PIN_DATA(5, 2 ) /*!< Specify PF.2 Pin Data Input/Output */
#define PF3 GPIO_PIN_DATA(5, 3 ) /*!< Specify PF.3 Pin Data Input/Output */
/*@}*/ /* end of group GPIO_EXPORTED_CONSTANTS */
/** @addtogroup GPIO_EXPORTED_FUNCTIONS GPIO Exported Functions
@{
*/
/**
* @brief Clear GPIO Pin Interrupt Flag
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port. \n
* It could be BIT10 ~ BIT15 for PA GPIO port. \n
* It could be BIT0 ~ BIT10 and BIT12 ~ BIT15 for PB GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT13 for PC GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT11 for PD GPIO port. \n
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Clear the interrupt status of specified GPIO pin.
*/
#define GPIO_CLR_INT_FLAG(port, u32PinMask) ((port)->ISRC = (u32PinMask))
/**
* @brief Disable Pin De-bounce Function
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port. \n
* It could be BIT10 ~ BIT15 for PA GPIO port. \n
* It could be BIT0 ~ BIT10 and BIT12 ~ BIT15 for PB GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT13 for PC GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT11 for PD GPIO port. \n
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Disable the interrupt de-bounce function of specified GPIO pin.
*/
#define GPIO_DISABLE_DEBOUNCE(port, u32PinMask) ((port)->DBEN &= ~(u32PinMask))
/**
* @brief Enable Pin De-bounce Function
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port. \n
* It could be BIT10 ~ BIT15 for PA GPIO port. \n
* It could be BIT0 ~ BIT10 and BIT12 ~ BIT15 for PB GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT13 for PC GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT11 for PD GPIO port. \n
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Enable the interrupt de-bounce function of specified GPIO pin.
*/
#define GPIO_ENABLE_DEBOUNCE(port, u32PinMask) ((port)->DBEN |= (u32PinMask))
/**
* @brief Disable I/O Digital Input Path
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port. \n
* It could be BIT10 ~ BIT15 for PA GPIO port. \n
* It could be BIT0 ~ BIT10 and BIT12 ~ BIT15 for PB GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT13 for PC GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT11 for PD GPIO port. \n
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Disable I/O digital input path of specified GPIO pin.
*/
#define GPIO_DISABLE_DIGITAL_PATH(port, u32PinMask) ((port)->OFFD |= ((u32PinMask)<<16))
/**
* @brief Enable I/O Digital Input Path
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port \n.
* It could be BIT10 ~ BIT15 for PA GPIO port. \n
* It could be BIT0 ~ BIT10 and BIT12 ~ BIT15 for PB GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT13 for PC GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT11 for PD GPIO port. \n
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Enable I/O digital input path of specified GPIO pin.
*/
#define GPIO_ENABLE_DIGITAL_PATH(port, u32PinMask) ((port)->OFFD &= ~((u32PinMask)<<16))
/**
* @brief Disable I/O DOUT mask
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port. \n
* It could be BIT10 ~ BIT15 for PA GPIO port. \n
* It could be BIT0 ~ BIT10 and BIT12 ~ BIT15 for PB GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT13 for PC GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT11 for PD GPIO port. \n
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Disable I/O DOUT mask of specified GPIO pin.
*/
#define GPIO_DISABLE_DOUT_MASK(port, u32PinMask) ((port)->DMASK &= ~(u32PinMask))
/**
* @brief Enable I/O DOUT mask
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port. \n
* It could be BIT10 ~ BIT15 for PA GPIO port. \n
* It could be BIT0 ~ BIT10 and BIT12 ~ BIT15 for PB GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT13 for PC GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT11 for PD GPIO port. \n
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @return None
*
* @details Enable I/O DOUT mask of specified GPIO pin.
*/
#define GPIO_ENABLE_DOUT_MASK(port, u32PinMask) ((port)->DMASK |= (u32PinMask))
/**
* @brief Get GPIO Pin Interrupt Flag
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port. \n
* It could be BIT10 ~ BIT15 for PA GPIO port. \n
* It could be BIT0 ~ BIT10 and BIT12 ~ BIT15 for PB GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT13 for PC GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT11 for PD GPIO port. \n
* It could be BIT0 ~ BIT3 for PF GPIO port.
*
* @retval 0 No interrupt at specified GPIO pin
* @retval 1 The specified GPIO pin generate an interrupt
*
* @details Get the interrupt status of specified GPIO pin.
*/
#define GPIO_GET_INT_FLAG(port, u32PinMask) ((port)->ISRC & (u32PinMask))
/**
* @brief Set De-bounce Sampling Cycle Time
*
* @param[in] u32ClkSrc The de-bounce counter clock source. It could be :
* - \ref GPIO_DBCLKSRC_HCLK
* - \ref GPIO_DBCLKSRC_LIRC
* @param[in] u32ClkSel The de-bounce sampling cycle selection. It could be :
* - \ref GPIO_DBCLKSEL_1
* - \ref GPIO_DBCLKSEL_2
* - \ref GPIO_DBCLKSEL_4
* - \ref GPIO_DBCLKSEL_8
* - \ref GPIO_DBCLKSEL_16
* - \ref GPIO_DBCLKSEL_32
* - \ref GPIO_DBCLKSEL_64
* - \ref GPIO_DBCLKSEL_128
* - \ref GPIO_DBCLKSEL_256
* - \ref GPIO_DBCLKSEL_512
* - \ref GPIO_DBCLKSEL_1024
* - \ref GPIO_DBCLKSEL_2048
* - \ref GPIO_DBCLKSEL_4096
* - \ref GPIO_DBCLKSEL_8192
* - \ref GPIO_DBCLKSEL_16384
* - \ref GPIO_DBCLKSEL_32768
*
* @return None
*
* @details Set the interrupt de-bounce sampling cycle time based on the debounce counter clock source. \n
* Example: _GPIO_SET_DEBOUNCE_TIME(GPIO_DBNCECON_DBCLKSRC_LIRC, GPIO_DBCLKSEL_4). \n
* It's meaning the De-debounce counter clock source is internal 10 KHz and sampling cycle selection is 4. \n
* Then the target de-bounce sampling cycle time is (4)*(1/(10*1000)) s = 4*0.0001 s = 400 us,
* and system will sampling interrupt input once per 400 us.
*/
#define GPIO_SET_DEBOUNCE_TIME(u32ClkSrc, u32ClkSel) (GPIO->DBNCECON = (GPIO_DBNCECON_ICLK_ON_Msk | (u32ClkSrc) | (u32ClkSel)))
/**
* @brief Get GPIO Port IN Data
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD 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 or PF.
* @param[in] u32Data GPIO port data.
*
* @return None
*
* @details Set the Data into specified GPIO port.
*/
#define GPIO_SET_OUT_DATA(port, u32Data) ((port)->DOUT = (u32Data))
/**
* @brief Toggle Specified GPIO pin
*
* @param[in] u32Pin Pxy
*
* @return None
*
* @details Toggle the specified GPIO pint.
*/
#define GPIO_TOGGLE(u32Pin) ((u32Pin) ^= 1)
/**
* @brief Enable External GPIO Interrupt 0
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32Pin The pin of specified GPIO port. \n
* It could be 10 ~ 15 for PA GPIO port. \n
* It could be 0 ~ 10 and 12 ~ 15 for PB GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 13 for PC GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 11 for PD GPIO port. \n
* It could be 0 ~ 3 for PF GPIO port.
* @param[in] u32IntAttribs The interrupt attribute of specified GPIO pin. It could be \n
* - \ref GPIO_INT_RISING
* - \ref GPIO_INT_FALLING
* - \ref GPIO_INT_BOTH_EDGE
* - \ref GPIO_INT_HIGH
* - \ref GPIO_INT_LOW
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
#define GPIO_EnableEINT0 GPIO_EnableInt
/**
* @brief Disable External GPIO Interrupt 0
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32Pin The pin of specified GPIO port. \n
* It could be 10 ~ 15 for PA GPIO port. \n
* It could be 0 ~ 10 and 12 ~ 15 for PB GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 13 for PC GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 11 for PD GPIO port. \n
* It could be 0 ~ 3 for PF GPIO port.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
#define GPIO_DisableEINT0 GPIO_DisableInt
/**
* @brief Enable External GPIO Interrupt 1
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32Pin The pin of specified GPIO port. \n
* It could be 10 ~ 15 for PA GPIO port. \n
* It could be 0 ~ 10 and 12 ~ 15 for PB GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 13 for PC GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 11 for PD GPIO port. \n
* It could be 0 ~ 3 for PF GPIO port.
* @param[in] u32IntAttribs The interrupt attribute of specified GPIO pin. It could be \n
* GPIO_INT_RISING, GPIO_INT_FALLING, GPIO_INT_BOTH_EDGE, GPIO_INT_HIGH, GPIO_INT_LOW.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
#define GPIO_EnableEINT1 GPIO_EnableInt
/**
* @brief Disable External GPIO Interrupt 1
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32Pin The pin of specified GPIO port. \n
* It could be 10 ~ 15 for PA GPIO port. \n
* It could be 0 ~ 10 and 12 ~ 15 for PB GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 13 for PC GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 11 for PD GPIO port. \n
* It could be 0 ~ 3 for PF GPIO port.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
#define GPIO_DisableEINT1 GPIO_DisableInt
void GPIO_SetMode(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode);
void GPIO_EnableInt(GPIO_T *port, uint32_t u32Pin, uint32_t u32IntAttribs);
void GPIO_DisableInt(GPIO_T *port, uint32_t u32Pin);
/*@}*/ /* end of group GPIO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group GPIO_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif //__GPIO_H__
/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,211 @@
/**************************************************************************//**
* @file I2C.h
* @version V3.0
* $Revision: 10 $
* $Date: 16/06/22 11:46a $
* @brief NUC123 Series I2C Driver Header File
*
* @note
* Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __I2C_H__
#define __I2C_H__
#include "NUC123.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup I2C_Driver I2C Driver
@{
*/
/** @addtogroup I2C_EXPORTED_CONSTANTS I2C Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* I2CON constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define I2C_I2CON_STA_STO_SI 0x38UL /*!< I2CON setting for I2C control bits. It would set STA, STO and SI bits */
#define I2C_I2CON_STA_STO_SI_AA 0x3CUL /*!< I2CON setting for I2C control bits. It would set STA, STO, SI and AA bits */
#define I2C_I2CON_STA_SI 0x28UL /*!< I2CON setting for I2C control bits. It would set STA and SI bits */
#define I2C_I2CON_STA_SI_AA 0x2CUL /*!< I2CON setting for I2C control bits. It would set STA, SI and AA bits */
#define I2C_I2CON_STO_SI 0x18UL /*!< I2CON setting for I2C control bits. It would set STO and SI bits */
#define I2C_I2CON_STO_SI_AA 0x1CUL /*!< I2CON setting for I2C control bits. It would set STO, SI and AA bits */
#define I2C_I2CON_SI 0x08UL /*!< I2CON setting for I2C control bits. It would set SI bit */
#define I2C_I2CON_SI_AA 0x0CUL /*!< I2CON setting for I2C control bits. It would set SI and AA bits */
#define I2C_I2CON_STA 0x20UL /*!< I2CON setting for I2C control bits. It would set STA bit */
#define I2C_I2CON_STO 0x10UL /*!< I2CON setting for I2C control bits. It would set STO bit */
#define I2C_I2CON_AA 0x04UL /*!< I2CON setting for I2C control bits. It would set AA bit */
#define I2C_GCMODE_ENABLE 1 /*!< Enable I2C GC Mode */
#define I2C_GCMODE_DISABLE 0 /*!< Disable I2C GC Mode */
/*@}*/ /* end of group I2C_EXPORTED_CONSTANTS */
/** @addtogroup I2C_EXPORTED_FUNCTIONS I2C Exported Functions
@{
*/
/**
* @brief The macro is used to set I2C bus condition at One Time
*
* @param[in] i2c Specify I2C port
* @param[in] u8Ctrl A byte writes to I2C control register
*
* @return None
*
* @details Set I2CON register to control I2C bus conditions of START, STOP, SI, ACK.
*/
#define I2C_SET_CONTROL_REG(i2c, u8Ctrl) ((i2c)->I2CON = ((i2c)->I2CON & ~0x3c) | (u8Ctrl))
/**
* @brief The macro is used to set START condition of I2C Bus
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details Set the I2C bus START condition in I2CON register.
*/
#define I2C_START(i2c) ((i2c)->I2CON = ((i2c)->I2CON | I2C_I2CON_SI_Msk) | I2C_I2CON_STA_Msk)
/**
* @brief The macro is used to set STOP condition of I2C Bus
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details Set the I2C bus STOP condition in I2CON register.
*/
#define I2C_STOP(i2c) ((i2c)->I2CON = ((i2c)->I2CON | I2C_I2CON_SI_Msk) | I2C_I2CON_STO_Msk)
/**
* @brief The macro is used to wait I2C bus status get ready
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details When a new status is presented of I2C bus, the SI flag will be set in I2CON register.
*/
#define I2C_WAIT_READY(i2c) while(!((i2c)->I2CON & I2C_I2CON_SI_Msk))
/**
* @brief The macro is used to Read I2C Bus Data Register
*
* @param[in] i2c Specify I2C port
*
* @return A byte of I2C data register
*
* @details I2C controller read data from bus and save it in I2CDAT register.
*/
#define I2C_GET_DATA(i2c) ((i2c)->I2CDAT)
/**
* @brief Write a Data to I2C Data Register
*
* @param[in] i2c Specify I2C port
* @param[in] u8Data A byte that writes to data register
*
* @return None
*
* @details When write a data to I2CDAT register, the I2C controller will shift it to I2C bus.
*/
#define I2C_SET_DATA(i2c, u8Data) ((i2c)->I2CDAT = (u8Data))
/**
* @brief Get I2C Bus status code
*
* @param[in] i2c Specify I2C port
*
* @return I2C status code
*
* @details To get this status code to monitor I2C bus event.
*/
#define I2C_GET_STATUS(i2c) ((i2c)->I2CSTATUS)
/**
* @brief Get Time-out flag from I2C Bus
*
* @param[in] i2c Specify I2C port
*
* @retval 0 I2C Bus time-out is not happened
* @retval 1 I2C Bus time-out is happened
*
* @details When I2C bus occurs time-out event, the time-out flag will be set.
*/
#define I2C_GET_TIMEOUT_FLAG(i2c) ( ((i2c)->I2CTOC & I2C_I2CTOC_TIF_Msk) == I2C_I2CTOC_TIF_Msk ? 1:0 )
/**
* @brief To get wake-up flag from I2C Bus
*
* @param[in] i2c Specify I2C port
*
* @retval 0 Chip is not woken-up from power-down mode
* @retval 1 Chip is woken-up from power-down mode
*
* @details I2C bus occurs wake-up event, wake-up flag will be set.
*/
#define I2C_GET_WAKEUP_FLAG(i2c) ( ((i2c)->I2CWKUPSTS & I2C_I2CWKUPSTS_WKUPIF_Msk) == I2C_I2CWKUPSTS_WKUPIF_Msk ? 1:0 )
/**
* @brief To clear wake-up flag
*
* @param[in] i2c Specify I2C port
*
* @return None
*
* @details If wake-up flag is set, use this macro to clear it.
*/
#define I2C_CLEAR_WAKEUP_FLAG(i2c) ((i2c)->I2CWKUPSTS |= I2C_I2CWKUPSTS_WKUPIF_Msk)
void I2C_ClearTimeoutFlag(I2C_T *i2c);
void I2C_Close(I2C_T *i2c);
void I2C_Trigger(I2C_T *i2c, uint8_t u8Start, uint8_t u8Stop, uint8_t u8Si, uint8_t u8Ack);
void I2C_DisableInt(I2C_T *i2c);
void I2C_EnableInt(I2C_T *i2c);
uint32_t I2C_GetBusClockFreq(I2C_T *i2c);
uint32_t I2C_SetBusClockFreq(I2C_T *i2c, uint32_t u32BusClock);
uint32_t I2C_GetIntFlag(I2C_T *i2c);
uint32_t I2C_GetStatus(I2C_T *i2c);
uint32_t I2C_Open(I2C_T *i2c, uint32_t u32BusClock);
uint8_t I2C_GetData(I2C_T *i2c);
void I2C_SetSlaveAddr(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddr, uint8_t u8GCMode);
void I2C_SetSlaveAddrMask(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddrMask);
void I2C_EnableTimeout(I2C_T *i2c, uint8_t u8LongTimeout);
void I2C_DisableTimeout(I2C_T *i2c);
void I2C_EnableWakeup(I2C_T *i2c);
void I2C_DisableWakeup(I2C_T *i2c);
void I2C_SetData(I2C_T *i2c, uint8_t u8Data);
uint8_t I2C_WriteByte(I2C_T *i2c, uint8_t u8SlaveAddr, const uint8_t data);
uint32_t I2C_WriteMultiBytes(I2C_T *i2c, uint8_t u8SlaveAddr, const uint8_t *data, uint32_t u32wLen);
uint8_t I2C_WriteByteOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, const uint8_t data);
uint32_t I2C_WriteMultiBytesOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, const uint8_t *data, uint32_t u32wLen);
uint8_t I2C_WriteByteTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, const uint8_t data);
uint32_t I2C_WriteMultiBytesTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, const 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);
/*@}*/ /* 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,319 @@
/**************************************************************************//**
* @file i2s.h
* @version V3.0
* $Revision: 6 $
* $Date: 15/07/02 11:21a $
* @brief NUC123 series I2S driver header file
*
* @note
* Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __I2S_H__
#define __I2S_H__
#include "NUC123.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup I2S_Driver I2S Driver
@{
*/
/** @addtogroup I2S_EXPORTED_CONSTANTS I2S Exported Constants
@{
*/
#define I2S_DATABIT_8 (0 << I2S_CON_WORDWIDTH_Pos) /*!< I2S data width is 8-bit */
#define I2S_DATABIT_16 (1 << I2S_CON_WORDWIDTH_Pos) /*!< I2S data width is 16-bit */
#define I2S_DATABIT_24 (2 << I2S_CON_WORDWIDTH_Pos) /*!< I2S data width is 24-bit */
#define I2S_DATABIT_32 (3 << I2S_CON_WORDWIDTH_Pos) /*!< I2S data width is 32-bit */
/* Audio Format */
#define I2S_MONO I2S_CON_MONO_Msk /*!< Mono channel */
#define I2S_STEREO 0 /*!< Stereo channel */
/* I2S Data Format */
#define I2S_FORMAT_MSB I2S_CON_FORMAT_Msk /*!< MSB data format */
#define I2S_FORMAT_I2S 0 /*!< I2S data format */
#define I2S_FORMAT_PCM_A I2S_CON_PCM_Msk /*!< PCM mode A data format */
#define I2S_FORMAT_PCM_B (I2S_CON_PCM_Msk|I2S_CON_FORMAT_Msk) /*!< PCM mode B data format */
/* I2S Operation mode */
#define I2S_MODE_SLAVE I2S_CON_SLAVE_Msk /*!< As slave mode */
#define I2S_MODE_MASTER 0 /*!< As master mode */
/* I2S FIFO Threshold */
#define I2S_FIFO_TX_LEVEL_WORD_0 0 /*!< TX threshold is 0 word */
#define I2S_FIFO_TX_LEVEL_WORD_1 (1 << I2S_CON_TXTH_Pos) /*!< TX threshold is 1 word */
#define I2S_FIFO_TX_LEVEL_WORD_2 (2 << I2S_CON_TXTH_Pos) /*!< TX threshold is 2 words */
#define I2S_FIFO_TX_LEVEL_WORD_3 (3 << I2S_CON_TXTH_Pos) /*!< TX threshold is 3 words */
#define I2S_FIFO_TX_LEVEL_WORD_4 (4 << I2S_CON_TXTH_Pos) /*!< TX threshold is 4 words */
#define I2S_FIFO_TX_LEVEL_WORD_5 (5 << I2S_CON_TXTH_Pos) /*!< TX threshold is 5 words */
#define I2S_FIFO_TX_LEVEL_WORD_6 (6 << I2S_CON_TXTH_Pos) /*!< TX threshold is 6 words */
#define I2S_FIFO_TX_LEVEL_WORD_7 (7 << I2S_CON_TXTH_Pos) /*!< TX threshold is 7 words */
#define I2S_FIFO_RX_LEVEL_WORD_1 0 /*!< RX threshold is 1 word */
#define I2S_FIFO_RX_LEVEL_WORD_2 (1 << I2S_CON_RXTH_Pos) /*!< RX threshold is 2 words */
#define I2S_FIFO_RX_LEVEL_WORD_3 (2 << I2S_CON_RXTH_Pos) /*!< RX threshold is 3 words */
#define I2S_FIFO_RX_LEVEL_WORD_4 (3 << I2S_CON_RXTH_Pos) /*!< RX threshold is 4 words */
#define I2S_FIFO_RX_LEVEL_WORD_5 (4 << I2S_CON_RXTH_Pos) /*!< RX threshold is 5 words */
#define I2S_FIFO_RX_LEVEL_WORD_6 (5 << I2S_CON_RXTH_Pos) /*!< RX threshold is 6 words */
#define I2S_FIFO_RX_LEVEL_WORD_7 (6 << I2S_CON_RXTH_Pos) /*!< RX threshold is 7 words */
#define I2S_FIFO_RX_LEVEL_WORD_8 (7 << I2S_CON_RXTH_Pos) /*!< RX threshold is 8 words */
/* I2S Record Channel */
#define I2S_MONO_RIGHT 0 /*!< Record mono right channel */
#define I2S_MONO_LEFT I2S_CON_RXLCH_Msk /*!< Record mono left channel */
/* I2S Channel */
#define I2S_RIGHT 0 /*!< Select right channel */
#define I2S_LEFT 1 /*!< Select left channel */
/*@}*/ /* end of group I2S_EXPORTED_CONSTANTS */
/** @addtogroup I2S_EXPORTED_FUNCTIONS I2S Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* inline functions */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief Enable zero cross detection function.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32ChMask The mask for left or right channel. Valid values are:
* - \ref I2S_RIGHT
* - \ref I2S_LEFT
* @return None
* @details This function will set RCHZCEN or LCHZCEN bit of I2SCON register to enable zero cross detection function.
*/
static __INLINE void I2S_ENABLE_TX_ZCD(I2S_T *i2s, uint32_t u32ChMask)
{
if(u32ChMask == I2S_RIGHT)
i2s->CON |= I2S_CON_RCHZCEN_Msk;
else
i2s->CON |= I2S_CON_LCHZCEN_Msk;
}
/**
* @brief Disable zero cross detection function.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32ChMask The mask for left or right channel. Valid values are:
* - \ref I2S_RIGHT
* - \ref I2S_LEFT
* @return None
* @details This function will clear RCHZCEN or LCHZCEN bit of I2SCON register to disable zero cross detection function.
*/
static __INLINE void I2S_DISABLE_TX_ZCD(I2S_T *i2s, uint32_t u32ChMask)
{
if(u32ChMask == I2S_RIGHT)
i2s->CON &= ~I2S_CON_RCHZCEN_Msk;
else
i2s->CON &= ~I2S_CON_LCHZCEN_Msk;
}
/**
* @brief Enable I2S TX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set TXDMA bit of I2SCON register to transmit data with PDMA.
*/
#define I2S_ENABLE_TXDMA(i2s) ( (i2s)->CON |= I2S_CON_TXDMA_Msk )
/**
* @brief Disable I2S TX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear TXDMA bit of I2SCON register to disable TX DMA function.
*/
#define I2S_DISABLE_TXDMA(i2s) ( (i2s)->CON &= ~I2S_CON_TXDMA_Msk )
/**
* @brief Enable I2S RX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set RXDMA bit of I2SCON register to receive data with PDMA.
*/
#define I2S_ENABLE_RXDMA(i2s) ( (i2s)->CON |= I2S_CON_RXDMA_Msk )
/**
* @brief Disable I2S RX DMA function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear RXDMA bit of I2SCON register to disable RX DMA function.
*/
#define I2S_DISABLE_RXDMA(i2s) ( (i2s)->CON &= ~I2S_CON_RXDMA_Msk )
/**
* @brief Enable I2S TX function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set TXEN bit of I2SCON register to enable I2S TX function.
*/
#define I2S_ENABLE_TX(i2s) ( (i2s)->CON |= I2S_CON_TXEN_Msk )
/**
* @brief Disable I2S TX function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear TXEN bit of I2SCON register to disable I2S TX function.
*/
#define I2S_DISABLE_TX(i2s) ( (i2s)->CON &= ~I2S_CON_TXEN_Msk )
/**
* @brief Enable I2S RX function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set RXEN bit of I2SCON register to enable I2S RX function.
*/
#define I2S_ENABLE_RX(i2s) ( (i2s)->CON |= I2S_CON_RXEN_Msk )
/**
* @brief Disable I2S RX function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear RXEN bit of I2SCON register to disable I2S RX function.
*/
#define I2S_DISABLE_RX(i2s) ( (i2s)->CON &= ~I2S_CON_RXEN_Msk )
/**
* @brief Enable TX Mute function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will set MUTE bit of I2SCON register to enable I2S TX mute function.
*/
#define I2S_ENABLE_TX_MUTE(i2s) ( (i2s)->CON |= I2S_CON_MUTE_Msk )
/**
* @brief Disable TX Mute function.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear MUTE bit of I2SCON register to disable I2S TX mute function.
*/
#define I2S_DISABLE_TX_MUTE(i2s) ( (i2s)->CON &= ~I2S_CON_MUTE_Msk )
/**
* @brief Clear TX FIFO.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear TX FIFO. The internal TX FIFO pointer will be reset to FIFO start point.
*/
#define I2S_CLR_TX_FIFO(i2s) ( (i2s)->CON |= I2S_CON_CLR_TXFIFO_Msk )
/**
* @brief Clear RX FIFO.
* @param[in] i2s The pointer of the specified I2S module.
* @return None
* @details This macro will clear RX FIFO. The internal RX FIFO pointer will be reset to FIFO start point.
*/
#define I2S_CLR_RX_FIFO(i2s) ( (i2s)->CON |= I2S_CON_CLR_RXFIFO_Msk )
/**
* @brief This function sets the recording source channel when mono mode is used.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32Ch Left or right channel. Valid values are:
* - \ref I2S_MONO_LEFT
* - \ref I2S_MONO_RIGHT
* @return None
* @details This function selects the recording source channel of monaural mode.
*/
static __INLINE void I2S_SET_MONO_RX_CHANNEL(I2S_T *i2s, uint32_t u32Ch)
{
u32Ch == I2S_MONO_LEFT ?
(i2s->CON |= I2S_CON_RXLCH_Msk) :
(i2s->CON &= ~I2S_CON_RXLCH_Msk);
}
/**
* @brief Write data to I2S TX FIFO.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32Data The value written to TX FIFO.
* @return None
* @details This macro will write a value to TX FIFO.
*/
#define I2S_WRITE_TX_FIFO(i2s, u32Data) ( (i2s)->TXFIFO = (u32Data) )
/**
* @brief Read RX FIFO.
* @param[in] i2s The pointer of the specified I2S module.
* @return The value read from RX FIFO.
* @details This function will return a value read from RX FIFO.
*/
#define I2S_READ_RX_FIFO(i2s) ( (i2s)->RXFIFO )
/**
* @brief Get the interrupt flag.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32Mask The mask value for all interrupt flags. Valid values are:
* - \ref I2S_STATUS_LZCF_Msk
* - \ref I2S_STATUS_RZCF_Msk
* - \ref I2S_STATUS_TXTHF_Msk
* - \ref I2S_STATUS_TXOVF_Msk
* - \ref I2S_STATUS_TXUDF_Msk
* - \ref I2S_STATUS_RXTHF_Msk
* - \ref I2S_STATUS_RXOVF_Msk
* - \ref I2S_STATUS_RXUDF_Msk
* - \ref I2S_STATUS_I2STXINT_Msk
* - \ref I2S_STATUS_I2SRXINT_Msk
* - \ref I2S_STATUS_I2SINT_Msk
* @return The interrupt flags specified by the u32mask parameter.
* @details This macro will return the combination flags of I2SSTATUS register. The flags are specified by the u32mask parameter.
*/
#define I2S_GET_INT_FLAG(i2s, u32Mask) ( (i2s)->STATUS & (u32Mask) )
/**
* @brief Clear the interrupt flag.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32Mask The mask value for all interrupt flags. Valid values are:
* - \ref I2S_STATUS_LZCF_Msk
* - \ref I2S_STATUS_RZCF_Msk
* - \ref I2S_STATUS_TXOVF_Msk
* - \ref I2S_STATUS_TXUDF_Msk
* - \ref I2S_STATUS_RXOVF_Msk
* - \ref I2S_STATUS_RXUDF_Msk
* @return None
* @details This macro will clear the interrupt flags specified by the u32mask parameter.
*/
#define I2S_CLR_INT_FLAG(i2s, u32Mask) ( (i2s)->STATUS = (u32Mask) )
/**
* @brief Get transmit FIFO level
* @param[in] i2s The pointer of the specified I2S module.
* @return TX FIFO level
* @details This macro will return the number of available words in TX FIFO.
*/
#define I2S_GET_TX_FIFO_LEVEL(i2s) ( (((i2s)->STATUS & I2S_STATUS_TX_LEVEL_Msk) >> I2S_STATUS_TX_LEVEL_Pos) & 0xF )
/**
* @brief Get receive FIFO level
* @param[in] i2s The pointer of the specified I2S module.
* @return RX FIFO level
* @details This macro will return the number of available words in RX FIFO.
*/
#define I2S_GET_RX_FIFO_LEVEL(i2s) ( (((i2s)->STATUS & I2S_STATUS_RX_LEVEL_Msk) >> I2S_STATUS_RX_LEVEL_Pos) & 0xF )
/* Function prototype declaration */
uint32_t I2S_Open(I2S_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat);
void I2S_Close(I2S_T *i2s);
void I2S_EnableInt(I2S_T *i2s, uint32_t u32Mask);
void I2S_DisableInt(I2S_T *i2s, uint32_t u32Mask);
uint32_t I2S_EnableMCLK(I2S_T *i2s, uint32_t u32BusClock);
void I2S_DisableMCLK(I2S_T *i2s);
/*@}*/ /* end of group I2S_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group I2S_Driver */
/*@}*/ /* end of group Standard_Driver */
#endif
/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,427 @@
/**************************************************************************//**
* @file UART.h
* @version V3.0
* $Revision: 15 $
* $Date: 15/07/02 11:21a $
* @brief NUC123 Series UART Interface Controller Driver Header File
*
* @note
* Copyright (C) 2014~2015 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 16 /*!< UART0 supports separated receive/transmit 16/16 bytes entry FIFO */
#define UART1_FIFO_SIZE 16 /*!< UART1 supports separated receive/transmit 16/16 bytes entry FIFO */
/*---------------------------------------------------------------------------------------------------------*/
/* UA_FCR constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_FCR_RFITL_1BYTE (0x0 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 1 byte */
#define UART_FCR_RFITL_4BYTES (0x1 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 4 bytes */
#define UART_FCR_RFITL_8BYTES (0x2 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 8 bytes */
#define UART_FCR_RFITL_14BYTES (0x3 << UART_FCR_RFITL_Pos) /*!< UA_FCR setting to set RX FIFO Trigger Level to 14 bytes */
#define UART_FCR_RTS_TRI_LEV_1BYTE (0x0 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 1 byte */
#define UART_FCR_RTS_TRI_LEV_4BYTES (0x1 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 4 bytes */
#define UART_FCR_RTS_TRI_LEV_8BYTES (0x2 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 8 bytes */
#define UART_FCR_RTS_TRI_LEV_14BYTES (0x3 << UART_FCR_RTS_TRI_LEV_Pos) /*!< UA_FCR setting to set RTS Trigger Level to 14 bytes */
/*---------------------------------------------------------------------------------------------------------*/
/* UA_LCR constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_WORD_LEN_5 (0) /*!< UA_LCR setting to set UART word length to 5 bits */
#define UART_WORD_LEN_6 (1) /*!< UA_LCR setting to set UART word length to 6 bits */
#define UART_WORD_LEN_7 (2) /*!< UA_LCR setting to set UART word length to 7 bits */
#define UART_WORD_LEN_8 (3) /*!< UA_LCR setting to set UART word length to 8 bits */
#define UART_PARITY_NONE (0x0 << UART_LCR_PBE_Pos) /*!< UA_LCR setting to set UART as no parity */
#define UART_PARITY_ODD (0x1 << UART_LCR_PBE_Pos) /*!< UA_LCR setting to set UART as odd parity */
#define UART_PARITY_EVEN (0x3 << UART_LCR_PBE_Pos) /*!< UA_LCR setting to set UART as even parity */
#define UART_PARITY_MARK (0x5 << UART_LCR_PBE_Pos) /*!< UA_LCR setting to keep parity bit as '1' */
#define UART_PARITY_SPACE (0x7 << UART_LCR_PBE_Pos) /*!< UA_LCR setting to keep parity bit as '0' */
#define UART_STOP_BIT_1 (0x0 << UART_LCR_NSB_Pos) /*!< UA_LCR setting for one stop bit */
#define UART_STOP_BIT_1_5 (0x1 << UART_LCR_NSB_Pos) /*!< UA_LCR setting for 1.5 stop bit when 5-bit word length */
#define UART_STOP_BIT_2 (0x1 << UART_LCR_NSB_Pos) /*!< UA_LCR setting for two stop bit when 6, 7, 8-bit word length */
/*---------------------------------------------------------------------------------------------------------*/
/* UART RTS LEVEL TRIGGER constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_RTS_IS_LOW_LEV_ACTIVE (0x1 << UART_MCR_LEV_RTS_Pos) /*!< Set RTS is Low Level Active */
#define UART_RTS_IS_HIGH_LEV_ACTIVE (0x0 << UART_MCR_LEV_RTS_Pos) /*!< Set RTS is High Level Active */
/*---------------------------------------------------------------------------------------------------------*/
/* UA_IRCR constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_IRCR_TX_SELECT (0x1 << UART_IRCR_TX_SELECT_Pos) /*!< Set IrDA function Tx mode */
#define UART_IRCR_RX_SELECT (0x0 << UART_IRCR_TX_SELECT_Pos) /*!< Set IrDA function Rx mode */
/*---------------------------------------------------------------------------------------------------------*/
/* UA_FUNC_SEL constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_FUNC_SEL_UART (0x0 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UA_FUNC_SEL setting to set UART Function (Default) */
#define UART_FUNC_SEL_IrDA (0x2 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UA_FUNC_SEL setting to set IrDA Function */
#define UART_FUNC_SEL_RS485 (0x3 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UA_FUNC_SEL setting to set RS485 Function */
/*---------------------------------------------------------------------------------------------------------*/
/* UART BAUDRATE MODE constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_BAUD_MODE0 (0) /*!< Set UART Baudrate Mode is Mode0 */
#define UART_BAUD_MODE2 (UART_BAUD_DIV_X_EN_Msk | UART_BAUD_DIV_X_ONE_Msk) /*!< Set UART Baudrate Mode is Mode2 */
/*@}*/ /* end of group UART_EXPORTED_CONSTANTS */
/** @addtogroup UART_EXPORTED_FUNCTIONS UART Exported Functions
@{
*/
/**
* @brief Calculate UART baudrate mode0 divider
*
* @param[in] u32SrcFreq UART clock frequency
* @param[in] u32BaudRate Baudrate of UART module
*
* @return UART baudrate mode0 divider
*
* @details This macro calculate UART baudrate mode0 divider.
*/
#define UART_BAUD_MODE0_DIVIDER(u32SrcFreq, u32BaudRate) ((((u32SrcFreq) + ((u32BaudRate)*8)) / (u32BaudRate) >> 4)-2)
/**
* @brief Calculate UART baudrate mode2 divider
*
* @param[in] u32SrcFreq UART clock frequency
* @param[in] u32BaudRate Baudrate of UART module
*
* @return UART baudrate mode2 divider
*
* @details This macro calculate UART baudrate mode2 divider.
*/
#define UART_BAUD_MODE2_DIVIDER(u32SrcFreq, u32BaudRate) ((((u32SrcFreq) + ((u32BaudRate)/2)) / (u32BaudRate))-2)
/**
* @brief Write data
*
* @param[in] uart The pointer of the specified UART module
* @param[in] u8Data Data byte to transmit
*
* @return None
*
* @details This macro write Data to Tx data register.
*/
#define UART_WRITE(uart, u8Data) ((uart)->THR = (u8Data))
/**
* @brief Read data
*
* @param[in] uart The pointer of the specified UART module
*
* @return The oldest data byte in RX FIFO
*
* @details This macro read Rx data register.
*/
#define UART_READ(uart) ((uart)->RBR)
/**
* @brief Get Tx empty
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 0 Tx FIFO is not empty
* @retval >=1 Tx FIFO is empty
*
* @details This macro get Tx empty register value.
*/
#define UART_GET_TX_EMPTY(uart) ((uart)->FSR & UART_FSR_TX_EMPTY_Msk)
/**
* @brief Get Rx empty
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 0 Rx FIFO is not empty
* @retval >=1 Rx FIFO is empty
*
* @details This macro get Rx empty register value.
*/
#define UART_GET_RX_EMPTY(uart) ((uart)->FSR & UART_FSR_RX_EMPTY_Msk)
/**
* @brief Check specified uart port transmission is over.
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 0 Transmission is not over.
* @retval 1 Transmission is over.
*
* @details This macro return if Tx FIFO is empty and specified uart port transmission is over nor not.
*/
#define UART_IS_TX_EMPTY(uart) (((uart)->FSR & UART_FSR_TE_FLAG_Msk) >> UART_FSR_TE_FLAG_Pos)
/**
* @brief Wait specified uart port transmission is over
*
* @param[in] uart The pointer of the specified UART module
*
* @return None
*
* @details This macro wait specified uart port transmission is over.
*/
#define UART_WAIT_TX_EMPTY(uart) while(!((((uart)->FSR) & UART_FSR_TE_FLAG_Msk) >> UART_FSR_TE_FLAG_Pos))
/**
* @brief Check RX is ready or not
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 0 The number of bytes in the RX FIFO is less than the RFITL
* @retval 1 The number of bytes in the RX FIFO equals or larger than RFITL
*
* @details This macro check receive data available interrupt flag is set or not.
*/
#define UART_IS_RX_READY(uart) (((uart)->ISR & UART_ISR_RDA_IF_Msk)>>UART_ISR_RDA_IF_Pos)
/**
* @brief Check TX FIFO is full or not
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 1 TX FIFO is full
* @retval 0 TX FIFO is not full
*
* @details This macro check TX FIFO is full or not.
*/
#define UART_IS_TX_FULL(uart) (((uart)->FSR & UART_FSR_TX_FULL_Msk)>>UART_FSR_TX_FULL_Pos)
/**
* @brief Check RX FIFO is full or not
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 1 RX FIFO is full
* @retval 0 RX FIFO is not full
*
* @details This macro check RX FIFO is full or not.
*/
#define UART_IS_RX_FULL(uart) (((uart)->FSR & UART_FSR_RX_FULL_Msk)>>UART_FSR_RX_FULL_Pos)
/**
* @brief Get Tx full register value
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 0 Tx FIFO is not full.
* @retval >=1 Tx FIFO is full.
*
* @details This macro get Tx full register value.
*/
#define UART_GET_TX_FULL(uart) ((uart)->FSR & UART_FSR_TX_FULL_Msk)
/**
* @brief Get Rx full register value
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 0 Rx FIFO is not full.
* @retval >=1 Rx FIFO is full.
*
* @details This macro get Rx full register value.
*/
#define UART_GET_RX_FULL(uart) ((uart)->FSR & UART_FSR_RX_FULL_Msk)
/**
* @brief Enable specified UART interrupt
*
* @param[in] uart The pointer of the specified UART module
* @param[in] u32eIntSel Interrupt type select
* - UART_IER_WAKE_EN_Msk : Wakeup interrupt
* - UART_IER_BUF_ERR_IEN_Msk : Buffer Error interrupt
* - UART_IER_TOUT_IEN_Msk : Rx time-out interrupt
* - UART_IER_MODEM_IEN_Msk : Modem interrupt
* - UART_IER_RLS_IEN_Msk : Rx Line status interrupt
* - UART_IER_THRE_IEN_Msk : Tx empty interrupt
* - UART_IER_RDA_IEN_Msk : Rx ready interrupt
*
* @return None
*
* @details This macro enable specified UART interrupt.
*/
#define UART_ENABLE_INT(uart, u32eIntSel) ((uart)->IER |= (u32eIntSel))
/**
* @brief Disable specified UART interrupt
*
* @param[in] uart The pointer of the specified UART module
* @param[in] u32eIntSel Interrupt type select
* - UART_IER_WAKE_EN_Msk : Wakeup interrupt
* - UART_IER_BUF_ERR_IEN_Msk : Buffer Error interrupt
* - UART_IER_TOUT_IEN_Msk : Rx time-out interrupt
* - UART_IER_MODEM_IEN_Msk : Modem interrupt
* - UART_IER_RLS_IEN_Msk : Rx Line status interrupt
* - UART_IER_THRE_IEN_Msk : Tx empty interrupt
* - UART_IER_RDA_IEN_Msk : Rx ready interrupt
* @return None
*
* @details This macro enable specified UART interrupt.
*/
#define UART_DISABLE_INT(uart, u32eIntSel) ((uart)->IER &= ~ (u32eIntSel))
/**
* @brief Get specified interrupt indicator status
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32eIntTypeFlag Interrupt Type Flag, should be
* - UART_ISR_HW_BUF_ERR_INT_Msk : In DMA Mode, Buffer Error Interrupt Indicator
* - UART_ISR_HW_TOUT_INT_Msk : In DMA Mode, Rx Time-out Interrupt Indicator
* - UART_ISR_HW_MODEM_INT_Msk : In DMA Mode, MODEM Status Interrupt Indicator
* - UART_ISR_HW_RLS_INT_Msk : In DMA Mode, Rx Line Status Interrupt Indicator
* - UART_ISR_HW_BUF_ERR_IF_Msk : In DMA Mode, Buffer Error Interrupt Flag
* - UART_ISR_HW_TOUT_IF_Msk : In DMA Mode, Rx Time-out Interrupt Flag
* - UART_ISR_HW_MODEM_IF_Msk : In DMA Mode, MODEM Status Interrupt Flag
* - UART_ISR_HW_RLS_IF_Msk : In DMA Mode, Rx Line Status Interrupt Flag
* - UART_ISR_LIN_INT_Msk : LIN Bus Interrupt Indicator
* - UART_ISR_BUF_ERR_INT_Msk : Buffer Error Interrupt Indicator
* - UART_ISR_TOUT_INT_Msk : Rx Time-out Interrupt Indicator
* - UART_ISR_MODEM_INT_Msk : MODEM Status Interrupt Indicator
* - UART_ISR_RLS_INT_Msk : Rx Line Status Interrupt Indicator
* - UART_ISR_THRE_INT_Msk : Tx Empty Interrupt Indicator
* - UART_ISR_RDA_INT_Msk : Rx Ready Interrupt Indicator
* - UART_ISR_LIN_IF_Msk : LIN Bus Interrupt Flag
* - UART_ISR_BUF_ERR_IF_Msk : Buffer Error Interrupt Flag
* - UART_ISR_TOUT_IF_Msk : Rx Time-out Interrupt Flag
* - UART_ISR_MODEM_IF_Msk : MODEM Status Interrupt Flag
* - UART_ISR_RLS_IF_Msk : Rx Line Status Interrupt Flag
* - UART_ISR_THRE_IF_Msk : Tx Empty Interrupt Flag
* - UART_ISR_RDA_IF_Msk : Rx Ready Interrupt Flag
*
* @retval 0 The specified interrupt is not happened.
* 1 The specified interrupt is happened.
*
* @details This macro get specified interrupt flag or interrupt indicator status.
*/
#define UART_GET_INT_FLAG(uart,u32eIntTypeFlag) (((uart)->ISR & (u32eIntTypeFlag))?1:0)
/**
* @brief Set RTS pin to low
*
* @param[in] uart The pointer of the specified UART module
*
* @return None
*
* @details This macro set RTS pin to low.
*/
__STATIC_INLINE void UART_CLEAR_RTS(UART_T* uart)
{
(uart)->MCR |= UART_MCR_LEV_RTS_Msk;
(uart)->MCR &= ~UART_MCR_RTS_Msk;
}
/**
* @brief Set RTS pin to high
*
* @param[in] uart The pointer of the specified UART module
* @return None
*
* @details This macro set RTS pin to high.
*/
__STATIC_INLINE void UART_SET_RTS(UART_T* uart)
{
(uart)->MCR |= UART_MCR_LEV_RTS_Msk | UART_MCR_RTS_Msk;
}
/**
* @brief Clear RS-485 Address Byte Detection Flag
*
* @param[in] uart The pointer of the specified UART module
*
* @return None
*
* @details This macro clear RS-485 address byte detection flag.
*/
#define UART_RS485_CLEAR_ADDR_FLAG(uart) ((uart)->FSR = UART_FSR_RS485_ADD_DETF_Msk)
/**
* @brief Get RS-485 Address Byte Detection Flag
*
* @param[in] uart The pointer of the specified UART module
*
* @retval 0 Receiver detects a data that is not an address bit.
* @retval 1 Receiver detects a data that is an address bit.
*
* @details This macro get RS-485 address byte detection flag.
*/
#define UART_RS485_GET_ADDR_FLAG(uart) (((uart)->FSR & UART_FSR_RS485_ADD_DETF_Msk) >> UART_FSR_RS485_ADD_DETF_Pos)
void UART_ClearIntFlag(UART_T* uart , uint32_t u32InterruptFlag);
void UART_Close(UART_T* uart);
void UART_DisableFlowCtrl(UART_T* uart);
void UART_DisableInt(UART_T* uart, uint32_t u32InterruptFlag);
void UART_EnableFlowCtrl(UART_T* uart);
void UART_EnableInt(UART_T* uart, uint32_t u32InterruptFlag);
void UART_Open(UART_T* uart, uint32_t u32baudrate);
uint32_t UART_Read(UART_T* uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes);
void UART_SetLine_Config(UART_T* uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits);
void UART_SetTimeoutCnt(UART_T* uart, uint32_t u32TOC);
void UART_SelectIrDAMode(UART_T* uart, uint32_t u32Buadrate, uint32_t u32Direction);
void UART_SelectRS485Mode(UART_T* uart, uint32_t u32Mode, uint32_t u32Addr);
uint32_t UART_Write(UART_T* uart, uint8_t *pu8TxBuf, uint32_t u32WriteBytes);
/*@}*/ /* end of group UART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group UART_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif //__UART_H__
/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,663 @@
/**************************************************************************//**
* @file usbd.h
* @version V3.0
* $Revision: 18 $
* $Date: 15/09/03 11:15a $
* @brief NUC123 series USB driver header file
*
* @note
* Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __USBD_H__
#define __USBD_H__
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup USBD_Driver USBD Driver
@{
*/
/** @addtogroup USBD_EXPORTED_STRUCTS USBD Exported Structs
@{
*/
typedef struct s_usbd_info
{
const uint8_t *gu8DevDesc; /*!< Pointer for USB Device Descriptor */
const uint8_t *gu8ConfigDesc; /*!< Pointer for USB Configuration Descriptor */
const uint8_t **gu8StringDesc; /*!< Pointer for USB String Descriptor pointers */
const uint8_t **gu8HidReportDesc; /*!< Pointer for USB HID Report Descriptor */
const uint32_t *gu32HidReportSize; /*!< Pointer for HID Report descriptor Size */
const uint32_t *gu32ConfigHidDescIdx; /*!< Pointer for HID Descriptor start index */
} S_USBD_INFO_T;
extern const S_USBD_INFO_T gsInfo;
/*@}*/ /* end of group USBD_EXPORTED_STRUCTS */
/** @addtogroup USBD_EXPORTED_CONSTANTS USBD Exported Constants
@{
*/
#define USBD_BUF_BASE (USBD_BASE+0x100)
#define USBD_MAX_EP 8
#define EP0 0 /*!< Endpoint 0 */
#define EP1 1 /*!< Endpoint 1 */
#define EP2 2 /*!< Endpoint 2 */
#define EP3 3 /*!< Endpoint 3 */
#define EP4 4 /*!< Endpoint 4 */
#define EP5 5 /*!< Endpoint 5 */
#define EP6 6 /*!< Endpoint 6 */
#define EP7 7 /*!< Endpoint 7 */
/*!<USB Request Type */
#define REQ_STANDARD 0x00
#define REQ_CLASS 0x20
#define REQ_VENDOR 0x40
/*!<USB Standard Request */
#define GET_STATUS 0x00
#define CLEAR_FEATURE 0x01
#define SET_FEATURE 0x03
#define SET_ADDRESS 0x05
#define GET_DESCRIPTOR 0x06
#define SET_DESCRIPTOR 0x07
#define GET_CONFIGURATION 0x08
#define SET_CONFIGURATION 0x09
#define GET_INTERFACE 0x0A
#define SET_INTERFACE 0x0B
#define SYNC_FRAME 0x0C
/*!<USB Descriptor Type */
#define DESC_DEVICE 0x01
#define DESC_CONFIG 0x02
#define DESC_STRING 0x03
#define DESC_INTERFACE 0x04
#define DESC_ENDPOINT 0x05
#define DESC_QUALIFIER 0x06
#define DESC_OTHERSPEED 0x07
/*!<USB HID Descriptor Type */
#define DESC_HID 0x21
#define DESC_HID_RPT 0x22
/*!<USB Descriptor Length */
#define LEN_DEVICE 18
#define LEN_CONFIG 9
#define LEN_INTERFACE 9
#define LEN_ENDPOINT 7
#define LEN_HID 9
#define LEN_CCID 0x36
/*!<USB Endpoint Type */
#define EP_ISO 0x01
#define EP_BULK 0x02
#define EP_INT 0x03
#define EP_INPUT 0x80
#define EP_OUTPUT 0x00
/*!<USB Feature Selector */
#define FEATURE_DEVICE_REMOTE_WAKEUP 0x01
#define FEATURE_ENDPOINT_HALT 0x00
/******************************************************************************/
/* USB Specific Macros */
/******************************************************************************/
#define USBD_WAKEUP_EN USBD_INTEN_WAKEUP_EN_Msk /*!< USB Wake-up Enable */
#define USBD_DRVSE0 USBD_DRVSE0_DRVSE0_Msk /*!< Drive SE0 */
#define USBD_DPPU_EN USBD_ATTR_DPPU_EN_Msk /*!< USB D+ Pull-up Enable */
#define USBD_PWRDN USBD_ATTR_PWRDN_Msk /*!< PHY Turn-On */
#define USBD_PHY_EN USBD_ATTR_PHY_EN_Msk /*!< PHY Enable */
#define USBD_USB_EN USBD_ATTR_USB_EN_Msk /*!< USB Enable */
#define USBD_INT_BUS USBD_INTEN_BUS_IE_Msk /*!< USB Bus Event Interrupt */
#define USBD_INT_USB USBD_INTEN_USB_IE_Msk /*!< USB USB Event Interrupt */
#define USBD_INT_FLDET USBD_INTEN_FLDET_IE_Msk /*!< USB Float Detect Interrupt */
#define USBD_INT_WAKEUP (USBD_INTEN_WAKEUP_IE_Msk | USBD_INTEN_WAKEUP_EN_Msk) /*!< USB Wake-up Interrupt */
#define USBD_INTSTS_WAKEUP USBD_INTSTS_WAKEUP_STS_Msk /*!< USB Wakeup Interrupt Status */
#define USBD_INTSTS_FLDET USBD_INTSTS_FLDET_STS_Msk /*!< USB Float Detect Interrupt Status */
#define USBD_INTSTS_BUS USBD_INTSTS_BUS_STS_Msk /*!< USB Bus Event Interrupt Status */
#define USBD_INTSTS_USB USBD_INTSTS_USB_STS_Msk /*!< USB USB Event Interrupt Status */
#define USBD_INTSTS_SETUP USBD_INTSTS_SETUP_Msk /*!< USB Setup Event */
#define USBD_INTSTS_EP0 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_STATE_USBRST USBD_ATTR_USBRST_Msk /*!< USB Bus Reset */
#define USBD_STATE_SUSPEND USBD_ATTR_SUSPEND_Msk /*!< USB Bus Suspend */
#define USBD_STATE_RESUME USBD_ATTR_RESUME_Msk /*!< USB Bus Resume */
#define USBD_STATE_TIMEOUT USBD_ATTR_TIMEOUT_Msk /*!< USB Bus Timeout */
#define USBD_CFGP_SSTALL USBD_CFGP_SSTALL_Msk /*!< Set Stall */
#define USBD_CFG_CSTALL USBD_CFG_CSTALL_Msk /*!< Clear Stall */
#define USBD_CFG_EPMODE_DISABLE (0ul << USBD_CFG_STATE_Pos)/*!< Endpoint Disable */
#define USBD_CFG_EPMODE_OUT (1ul << USBD_CFG_STATE_Pos)/*!< Out Endpoint */
#define USBD_CFG_EPMODE_IN (2ul << USBD_CFG_STATE_Pos)/*!< In Endpoint */
#define USBD_CFG_TYPE_ISO (1ul << USBD_CFG_ISOCH_Pos) /*!< Isochronous */
/*@}*/ /* end of group USBD_EXPORTED_CONSTANTS */
/** @addtogroup USBD_EXPORTED_FUNCTIONS USBD Exported Functions
@{
*/
/**
* @brief Compare two input numbers and return maximum one.
*
* @param[in] a First number to be compared.
* @param[in] b Second number to be compared.
*
* @return Maximum value between a and b.
*
* @details If a > b, then return a. Otherwise, return b.
*/
#define Maximum(a,b) ((a)>(b) ? (a) : (b))
/**
* @brief Compare two input numbers and return minimum one
*
* @param[in] a First number to be compared
* @param[in] b Second number to be compared
*
* @return Minimum value between a and b
*
* @details If a < b, then return a. Otherwise, return b.
*/
#define Minimum(a,b) ((a)<(b) ? (a) : (b))
/**
* @brief Enable USB
*
* @param None
*
* @return None
*
* @details To set USB ATTR control register to enable USB and PHY.
*
*/
#define USBD_ENABLE_USB() ((uint32_t)(USBD->ATTR |= (USBD_USB_EN|USBD_PHY_EN)))
/**
* @brief Disable USB
*
* @param None
*
* @return None
*
* @details To set USB ATTR control register to disable USB.
*
*/
#define USBD_DISABLE_USB() ((uint32_t)(USBD->ATTR &= ~USBD_USB_EN))
/**
* @brief Enable USB PHY
*
* @param None
*
* @return None
*
* @details To set USB ATTR control register to enable USB PHY.
*
*/
#define USBD_ENABLE_PHY() ((uint32_t)(USBD->ATTR |= USBD_PHY_EN))
/**
* @brief Disable USB PHY
*
* @param None
*
* @return None
*
* @details To set USB ATTR control register to disable USB PHY.
*
*/
#define USBD_DISABLE_PHY() ((uint32_t)(USBD->ATTR &= ~USBD_PHY_EN))
/**
* @brief Enable SE0. Force USB PHY transceiver to drive SE0.
*
* @param None
*
* @return None
*
* @details Set DRVSE0 bit of USB_DRVSE0 register to enable software-disconnect function. Force USB PHY transceiver to drive SE0 to bus.
*
*/
#define USBD_SET_SE0() ((uint32_t)(USBD->DRVSE0 |= USBD_DRVSE0))
/**
* @brief Disable SE0
*
* @param None
*
* @return None
*
* @details Clear DRVSE0 bit of USB_DRVSE0 register to disable software-disconnect function.
*
*/
#define USBD_CLR_SE0() ((uint32_t)(USBD->DRVSE0 &= ~USBD_DRVSE0))
/**
* @brief Set USB device address
*
* @param[in] addr The USB device address.
*
* @return None
*
* @details Write USB device address to USB_FADDR register.
*
*/
#define USBD_SET_ADDR(addr) (USBD->FADDR = (addr))
/**
* @brief Get USB device address
*
* @param None
*
* @return USB device address
*
* @details Read USB_FADDR register to get USB device address.
*
*/
#define USBD_GET_ADDR() ((uint32_t)(USBD->FADDR))
/**
* @brief Enable USB interrupt function
*
* @param[in] intr The combination of the specified interrupt enable bits.
* Each bit corresponds to a interrupt enable bit.
* This parameter decides which interrupts will be enabled.
* (USBD_INT_WAKEUP, USBD_INT_FLDET, USBD_INT_USB, USBD_INT_BUS)
*
* @return None
*
* @details Enable USB related interrupt functions specified by intr parameter.
*
*/
#define USBD_ENABLE_INT(intr) (USBD->INTEN |= (intr))
/**
* @brief Get interrupt status
*
* @param None
*
* @return The value of USB_INTSTS register
*
* @details Return all interrupt flags of USB_INTSTS register.
*
*/
#define USBD_GET_INT_FLAG() ((uint32_t)(USBD->INTSTS))
/**
* @brief Clear USB interrupt flag
*
* @param[in] flag The combination of the specified interrupt flags.
* Each bit corresponds to a interrupt source.
* This parameter decides which interrupt flags will be cleared.
* (USBD_INTSTS_WAKEUP, USBD_INTSTS_FLDET, USBD_INTSTS_BUS, USBD_INTSTS_USB)
*
* @return None
*
* @details Clear USB related interrupt flags specified by flag parameter.
*
*/
#define USBD_CLR_INT_FLAG(flag) (USBD->INTSTS = (flag))
/**
* @brief Get endpoint status
*
* @param None
*
* @return The value of USB_EPSTS register.
*
* @details Return all endpoint status.
*
*/
#define USBD_GET_EP_FLAG() ((uint32_t)(USBD->EPSTS))
/**
* @brief Get USB bus state
*
* @param None
*
* @return The value of USB_ATTR[3:0].
* Bit 0 indicates USB bus reset status.
* Bit 1 indicates USB bus suspend status.
* Bit 2 indicates USB bus resume status.
* Bit 3 indicates USB bus time-out status.
*
* @details Return USB_ATTR[3:0] for USB bus events.
*
*/
#define USBD_GET_BUS_STATE() ((uint32_t)(USBD->ATTR & 0xf))
/**
* @brief Check cable connection state
*
* @param None
*
* @retval 0 USB cable is not attached.
* @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->FLDET & USBD_FLDET_FLDET_Msk))
/**
* @brief Stop USB transaction of the specified endpoint ID
*
* @param[in] ep The USB endpoint ID. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @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. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @return None
*
* @details Set DSQ_SYNC bit of USB_CFGx register to specify the DATA1 PID for the following IN token transaction.
* Base on this setting, hardware will toggle PID between DATA0 and DATA1 automatically for IN token transactions.
*
*/
#define USBD_SET_DATA1(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) |= USBD_CFG_DSQ_SYNC_Msk)
/**
* @brief Set USB DATA0 PID for the specified endpoint ID
*
* @param[in] ep The USB endpoint ID. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @return None
*
* @details Clear DSQ_SYNC bit of USB_CFGx register to specify the DATA0 PID for the following IN token transaction.
* Base on this setting, hardware will toggle PID between DATA0 and DATA1 automatically for IN token transactions.
*
*/
#define USBD_SET_DATA0(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) &= (~USBD_CFG_DSQ_SYNC_Msk))
/**
* @brief Set USB payload size (IN data)
*
* @param[in] ep The USB endpoint ID. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @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. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @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. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @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. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @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. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @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. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @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. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @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. NUC123 supports 8 hardware endpoint ID. This parameter could be 0 ~ 7.
*
* @retval 0 USB endpoint is not stalled.
* @retval Others USB endpoint is stalled.
*
* @details Get USB endpoint stall state of the specified endpoint ID.
*
*/
#define USBD_GET_EP_STALL(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) & USBD_CFGP_SSTALL_Msk)
/**
* @brief To support byte access between USB SRAM and system SRAM
*
* @param[in] dest Destination pointer.
*
* @param[in] src Source pointer.
*
* @param[in] size Byte count.
*
* @return None
*
* @details This function will copy the number of data specified by size and src parameters to the address specified by dest parameter.
*
*/
static __INLINE void USBD_MemCopy(uint8_t *dest, uint8_t *src, int32_t size)
{
while(size--) *dest++ = *src++;
}
/**
* @brief Set USB endpoint stall state
*
* @param[in] epnum USB endpoint number
*
* @return None
*
* @details Set USB endpoint stall state. Endpoint will respond STALL token automatically.
*
*/
static __INLINE void USBD_SetStall(uint8_t epnum)
{
uint32_t u32CfgAddr;
uint32_t u32Cfg;
int i;
for(i = 0; i < USBD_MAX_EP; i++)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
if((u32Cfg & 0xf) == epnum)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
*((__IO uint32_t *)(u32CfgAddr)) = (u32Cfg | USBD_CFGP_SSTALL);
break;
}
}
}
/**
* @brief Clear USB endpoint stall state
*
* @param[in] epnum USB endpoint number
*
* @return None
*
* @details Clear USB endpoint stall state. Endpoint will respond ACK/NAK token.
*/
static __INLINE void USBD_ClearStall(uint8_t epnum)
{
uint32_t u32CfgAddr;
uint32_t u32Cfg;
int i;
for(i = 0; i < USBD_MAX_EP; i++)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
if((u32Cfg & 0xf) == epnum)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
*((__IO uint32_t *)(u32CfgAddr)) = (u32Cfg & ~USBD_CFGP_SSTALL);
break;
}
}
}
/**
* @brief Get USB endpoint stall state
*
* @param[in] epnum USB endpoint number
*
* @retval 0 USB endpoint is not stalled.
* @retval Others USB endpoint is stalled.
*
* @details Get USB endpoint stall state.
*
*/
static __INLINE uint32_t USBD_GetStall(uint8_t epnum)
{
uint32_t u32CfgAddr;
uint32_t u32Cfg;
int i;
for(i = 0; i < USBD_MAX_EP; i++)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */
u32Cfg = *((__IO uint32_t *)(u32CfgAddr));
if((u32Cfg & 0xf) == epnum)
{
u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */
break;
}
}
return ((*((__IO uint32_t *)(u32CfgAddr))) & USBD_CFGP_SSTALL);
}
extern volatile uint8_t g_usbd_RemoteWakeupEn;
typedef void (*VENDOR_REQ)(void); /*!< Functional pointer type declaration for Vendor class */
typedef void (*CLASS_REQ)(void); /*!< Functional pointer type 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 */
#endif //__USBD_H__
/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/

View File

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

View File

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

View File

@ -0,0 +1,65 @@
/**************************************************************************//**
* @file system_NUC123.h
* @version V3.0
* $Revision: 5 $
* $Date: 15/07/02 11:21a $
* @brief NUC123 Series CMSIS System Header File
*
* @note
* Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __SYSTEM_NUC123_H
#define __SYSTEM_NUC123_H
#ifdef __cplusplus
extern "C" {
#endif
/*---------------------------------------------------------------------------------------------------------*/
/* Macro Definition */
/*---------------------------------------------------------------------------------------------------------*/
#ifndef DEBUG_PORT
# define DEBUG_PORT UART0 /*!< Select Debug Port which is used for retarget.c to output debug message to UART */
#endif
/*----------------------------------------------------------------------------
Define SYSCLK
*----------------------------------------------------------------------------*/
#define __HXT (12000000UL) /*!< External Crystal Clock Frequency */
#define __LXT (32768UL) /*!< External Crystal Clock Frequency 32.768KHz */
#define __HIRC (22118400UL) /*!< Internal 22M RC Oscillator Frequency */
#define __LIRC (10000UL) /*!< Internal 10K RC Oscillator Frequency */
#define __HSI (50000000UL) /*!< PLL default output is 50MHz */
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
extern uint32_t CyclesPerUs; /*!< Cycles per micro second */
extern uint32_t PllClock; /*!< PLL Output Clock Frequency */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system
* Initialize GPIO directions and values
*/
extern void SystemInit(void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from CPU registers.
*/
extern void SystemCoreClockUpdate(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,85 @@
/*
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* NUC123SD4AN0 memory setup.
*/
MEMORY
{
flash0 : org = 0x00000000, len = 64k
flash1 : org = 0x00000000, len = 0
flash2 : org = 0x00000000, len = 0
flash3 : org = 0x00000000, len = 0
flash4 : org = 0x00000000, len = 0
flash5 : org = 0x00000000, len = 0
flash6 : org = 0x00000000, len = 0
flash7 : org = 0x00000000, len = 0
ram0 : org = 0x20000000, len = 20k
ram1 : org = 0x00000000, len = 0
ram2 : org = 0x00000000, len = 0
ram3 : org = 0x00000000, len = 0
ram4 : org = 0x00000000, len = 0
ram5 : org = 0x00000000, len = 0
ram6 : org = 0x00000000, len = 0
ram7 : org = 0x00000000, len = 0
}
/* For each data/text section two region are defined, a virtual region
and a load region (_LMA suffix).*/
/* Flash region to be used for exception vectors.*/
REGION_ALIAS("VECTORS_FLASH", flash0);
REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
/* Flash region to be used for constructors and destructors.*/
REGION_ALIAS("XTORS_FLASH", flash0);
REGION_ALIAS("XTORS_FLASH_LMA", flash0);
/* Flash region to be used for code text.*/
REGION_ALIAS("TEXT_FLASH", flash0);
REGION_ALIAS("TEXT_FLASH_LMA", flash0);
/* Flash region to be used for read only data.*/
REGION_ALIAS("RODATA_FLASH", flash0);
REGION_ALIAS("RODATA_FLASH_LMA", flash0);
/* Flash region to be used for various.*/
REGION_ALIAS("VARIOUS_FLASH", flash0);
REGION_ALIAS("VARIOUS_FLASH_LMA", flash0);
/* Flash region to be used for RAM(n) initialization data.*/
REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0);
/* RAM region to be used for Main stack. This stack accommodates the processing
of all exceptions and interrupts.*/
REGION_ALIAS("MAIN_STACK_RAM", ram0);
/* RAM region to be used for the process stack. This is the stack used by
the main() function.*/
REGION_ALIAS("PROCESS_STACK_RAM", ram0);
/* RAM region to be used for data segment.*/
REGION_ALIAS("DATA_RAM", ram0);
REGION_ALIAS("DATA_RAM_LMA", flash0);
/* RAM region to be used for BSS segment.*/
REGION_ALIAS("BSS_RAM", ram0);
/* RAM region to be used for the default heap.*/
REGION_ALIAS("HEAP_RAM", ram0);
/* Generic rules inclusion.*/
INCLUDE rules.ld

View File

@ -0,0 +1,12 @@
# List of the ChibiOS generic NUC123SD4AN0 startup and CMSIS files.
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v6m.S
STARTUPINC = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC \
$(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/devices/NUC123SD4AN0 \
$(CHIBIOS)/os/common/ext/CMSIS/include \
$(CHIBIOS_CONTRIB)/os/common/ext/CMSIS/Nuvoton/NUMICRO
STARTUPLD = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/ld

View File

@ -0,0 +1,84 @@
/*
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file NUC123SD4AN0/cmparams.h
* @brief ARM Cortex-M0 parameters for the NUC123SD4AN0.
*
* @defgroup ARMCMx_NUC123 NUC123SD4AN0 Specific Parameters
* @ingroup ARMCMx_SPECIFIC
* @details This file contains the Cortex-M0 specific parameters for the
* NUC123SD4AN0 platform.
* @{
*/
#ifndef CMPARAMS_H
#define CMPARAMS_H
/**
* @brief Cortex core model.
*/
#define CORTEX_MODEL 0
/**
* @brief Floating Point unit presence.
*/
#define CORTEX_HAS_FPU 0
/**
* @brief Number of bits in priority masks.
*/
#define CORTEX_PRIORITY_BITS 2
/**
* @brief Number of interrupt vectors.
* @note This number does not include the 16 system vectors and must be
* rounded to a multiple of 8.
*/
#define CORTEX_NUM_VECTORS 32
/* The following code is not processed when the file is included from an
asm module.*/
#if !defined(_FROM_ASM_)
/* If the device type is not externally defined, for example from the Makefile,
then a file named board.h is included. This file must contain a device
definition compatible with the vendor include file.*/
#if !defined (NUC123SD4AN0)
#include "board.h"
#endif
/* Including the device CMSIS header. Note, we are not using the definitions
from this header because we need this file to be usable also from
assembler source files. We verify that the info matches instead.*/
#include "NUC123.h"
/*lint -save -e9029 [10.4] Signedness comes from external files, it is
unpredictable but gives no problems.*/
#if CORTEX_MODEL != __CORTEX_M
#error "CMSIS __CORTEX_M mismatch"
#endif
#if CORTEX_PRIORITY_BITS != __NVIC_PRIO_BITS
#error "CMSIS __NVIC_PRIO_BITS mismatch"
#endif
/*lint -restore*/
#endif /* !defined(_FROM_ASM_) */
#endif /* CMPARAMS_H */
/** @} */

View File

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

View File

@ -0,0 +1,409 @@
/**************************************************************************//**
* @file clk.h
* @version V3.0
* $Revision: 16 $
* $Date: 15/07/02 11:21a $
* @brief NUC123 Series Clock Control Driver Header File
*
* @note
* Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __CLK_H__
#define __CLK_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup CLK_Driver CLK Driver
@{
*/
/** @addtogroup CLK_EXPORTED_CONSTANTS CLK Exported Constants
@{
*/
#define FREQ_25MHZ 25000000
#define FREQ_50MHZ 50000000
#define FREQ_72MHZ 72000000
#define FREQ_100MHZ 100000000
#define FREQ_200MHZ 200000000
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL0 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL0_HCLK_S_HXT (0x0UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as HXT */
#define CLK_CLKSEL0_HCLK_S_PLL_DIV2 (0x1UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as PLL/2 */
#define CLK_CLKSEL0_HCLK_S_PLL (0x2UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as PLL */
#define CLK_CLKSEL0_HCLK_S_LIRC (0x3UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as LIRC */
#define CLK_CLKSEL0_HCLK_S_HIRC (0x7UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!< Setting HCLK clock source as HIRC */
#define CLK_CLKSEL0_STCLK_S_HXT (0x0UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as HXT */
#define CLK_CLKSEL0_STCLK_S_HXT_DIV2 (0x2UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as HXT/2 */
#define CLK_CLKSEL0_STCLK_S_HCLK_DIV2 (0x3UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as HCLK/2 */
#define CLK_CLKSEL0_STCLK_S_HIRC_DIV2 (0x7UL<<CLK_CLKSEL0_STCLK_S_Pos) /*!< Setting STCLK clock source as HIRC/2 */
#define CLK_CLKSEL0_STCLK_S_HCLK (0x1UL<<SysTick_CTRL_CLKSOURCE_Pos) /*!< Setting STCLK clock source as HCLK */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL1 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL1_WDT_S_HCLK_DIV2048 (0x2UL<<CLK_CLKSEL1_WDT_S_Pos) /*!< Setting WDT clock source as HCLK/2048 */
#define CLK_CLKSEL1_WDT_S_LIRC (0x3UL<<CLK_CLKSEL1_WDT_S_Pos) /*!< Setting WDT clock source as LIRC */
#define CLK_CLKSEL1_ADC_S_HXT (0x0UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as HXT */
#define CLK_CLKSEL1_ADC_S_PLL (0x1UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as PLL */
#define CLK_CLKSEL1_ADC_S_HCLK (0x2UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as HCLK */
#define CLK_CLKSEL1_ADC_S_HIRC (0x3UL<<CLK_CLKSEL1_ADC_S_Pos) /*!< Setting ADC clock source as HIRC */
#define CLK_CLKSEL1_SPI0_S_PLL (0x0UL<<CLK_CLKSEL1_SPI0_S_Pos) /*!< Setting SPI0 clock source as PLL */
#define CLK_CLKSEL1_SPI0_S_HCLK (0x1UL<<CLK_CLKSEL1_SPI0_S_Pos) /*!< Setting SPI0 clock source as HCLK */
#define CLK_CLKSEL1_SPI1_S_PLL (0x0UL<<CLK_CLKSEL1_SPI1_S_Pos) /*!< Setting SPI1 clock source as PLL */
#define CLK_CLKSEL1_SPI1_S_HCLK (0x1UL<<CLK_CLKSEL1_SPI1_S_Pos) /*!< Setting SPI1 clock source as HCLK */
#define CLK_CLKSEL1_SPI2_S_PLL (0x0UL<<CLK_CLKSEL1_SPI2_S_Pos) /*!< Setting SPI2 clock source as PLL */
#define CLK_CLKSEL1_SPI2_S_HCLK (0x1UL<<CLK_CLKSEL1_SPI2_S_Pos) /*!< Setting SPI2 clock source as HCLK */
#define CLK_CLKSEL1_TMR0_S_HXT (0x0UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as HXT */
#define CLK_CLKSEL1_TMR0_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as HCLK */
#define CLK_CLKSEL1_TMR0_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as external trigger */
#define CLK_CLKSEL1_TMR0_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as LIRC */
#define CLK_CLKSEL1_TMR0_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!< Setting TMR0 clock source as HIRC */
#define CLK_CLKSEL1_TMR1_S_HXT (0x0UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as HXT */
#define CLK_CLKSEL1_TMR1_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as HCLK */
#define CLK_CLKSEL1_TMR1_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as external trigger */
#define CLK_CLKSEL1_TMR1_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as LIRC */
#define CLK_CLKSEL1_TMR1_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!< Setting TMR1 clock source as HIRC*/
#define CLK_CLKSEL1_TMR2_S_HXT (0x0UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as external X'tal */
#define CLK_CLKSEL1_TMR2_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as HCLK */
#define CLK_CLKSEL1_TMR2_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as external trigger */
#define CLK_CLKSEL1_TMR2_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as LIRC */
#define CLK_CLKSEL1_TMR2_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR2_S_Pos) /*!< Setting TMR2 clock source as HIRC */
#define CLK_CLKSEL1_TMR3_S_HXT (0x0UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as HXT */
#define CLK_CLKSEL1_TMR3_S_HCLK (0x2UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as HCLK */
#define CLK_CLKSEL1_TMR3_S_EXT_TRG (0x3UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as external trigger */
#define CLK_CLKSEL1_TMR3_S_LIRC (0x5UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as LIRC*/
#define CLK_CLKSEL1_TMR3_S_HIRC (0x7UL<<CLK_CLKSEL1_TMR3_S_Pos) /*!< Setting TMR3 clock source as HIRC */
#define CLK_CLKSEL1_UART_S_HXT (0x0UL<<CLK_CLKSEL1_UART_S_Pos) /*!< Setting UART clock source as HXT */
#define CLK_CLKSEL1_UART_S_PLL (0x1UL<<CLK_CLKSEL1_UART_S_Pos) /*!< Setting UART clock source as PLL */
#define CLK_CLKSEL1_UART_S_HIRC (0x3UL<<CLK_CLKSEL1_UART_S_Pos) /*!< Setting UART clock source as HIRC */
#define CLK_CLKSEL1_PWM01_S_HXT (0x0UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as HXT,
user must set CLK_CLKSEL2_PWM01_EXT_HXT concurrently to complete clock source as HXT setting*/
#define CLK_CLKSEL1_PWM01_S_HCLK (0x2UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as HCLK
user must set CLK_CLKSEL2_PWM01_EXT_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL1_PWM01_S_HIRC (0x3UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as HIRC clock,
user must set CLK_CLKSEL2_PWM01_EXT_HIRC concurrently to complete clock source as HIRC clock setting*/
#define CLK_CLKSEL1_PWM01_S_LIRC (0x3UL<<CLK_CLKSEL1_PWM01_S_Pos) /*!< Setting PWM01 clock source as LIRC clock,
user must set CLK_CLKSEL2_PWM01_EXT_LIRC concurrently to complete clock source as LIRC clock setting*/
#define CLK_CLKSEL1_PWM23_S_HXT (0x0UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as HXT,
user must set CLK_CLKSEL2_PWM23_EXT_HXT concurrently to complete clock source as HXT setting*/
#define CLK_CLKSEL1_PWM23_S_HCLK (0x2UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as HCLK,
user must set CLK_CLKSEL2_PWM23_EXT_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL1_PWM23_S_HIRC (0x3UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as HIRC clock,
user must set CLK_CLKSEL2_PWM23_EXT_HIRC concurrently to complete clock source as HIRC clock setting*/
#define CLK_CLKSEL1_PWM23_S_LIRC (0x3UL<<CLK_CLKSEL1_PWM23_S_Pos) /*!< Setting PWM23 clock source as LIRC clock,
user must set CLK_CLKSEL2_PWM23_EXT_LIRC concurrently to complete clock source as LIRC setting*/
/*---------------------------------------------------------------------------------------------------------*/
/* CLKSEL2 constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKSEL2_I2S_S_HXT (0x0UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as HXT */
#define CLK_CLKSEL2_I2S_S_PLL (0x1UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as PLL */
#define CLK_CLKSEL2_I2S_S_HCLK (0x2UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as HCLK */
#define CLK_CLKSEL2_I2S_S_HIRC (0x3UL<<CLK_CLKSEL2_I2S_S_Pos) /*!< Setting I2S clock source as HIRC */
#define CLK_CLKSEL2_FRQDIV_S_HXT (0x0UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Setting FRQDIV clock source as HXT */
#define CLK_CLKSEL2_FRQDIV_S_HCLK (0x2UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Setting FRQDIV clock source as HCLK */
#define CLK_CLKSEL2_FRQDIV_S_HIRC (0x3UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!< Setting FRQDIV clock source as HIRC */
#define CLK_CLKSEL2_PWM01_EXT_HXT (0x0UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as HXT,
user must set CLK_CLKSEL1_PWM01_HXT concurrently to complete clock source as HXT setting*/
#define CLK_CLKSEL2_PWM01_EXT_HCLK (0x0UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as HCLK,
user must set CLK_CLKSEL1_PWM01_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL2_PWM01_EXT_HIRC (0x0UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as HIRC,
user must set CLK_CLKSEL1_PWM01_HIRC concurrently to complete clock source as HIRC setting*/
#define CLK_CLKSEL2_PWM01_EXT_LIRC (0x1UL<<CLK_CLKSEL2_PWM01_S_E_Pos)/*!< Setting PWM01 clock source as LIRC,
user must set CLK_CLKSEL1_PWM01_LIRC concurrently to complete clock source as LIRC setting*/
#define CLK_CLKSEL2_PWM23_EXT_HXT (0x0UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as HXT,
user must set CLK_CLKSEL1_PWM23_HXT concurrently to complete clock source as HXT setting*/
#define CLK_CLKSEL2_PWM23_EXT_HCLK (0x0UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as HCLK,
user must set CLK_CLKSEL1_PWM23_HCLK concurrently to complete clock source as HCLK setting*/
#define CLK_CLKSEL2_PWM23_EXT_HIRC (0x0UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as HIRC clock,
user must set CLK_CLKSEL1_PWM23_HIRC concurrently to complete clock source as HIRC setting*/
#define CLK_CLKSEL2_PWM23_EXT_LIRC (0x1UL<<CLK_CLKSEL2_PWM23_S_E_Pos)/*!< Setting PWM23 clock source as LIRC,
user must set CLK_CLKSEL1_PWM23_LIRC concurrently to complete clock source as LIRC setting*/
#define CLK_CLKSEL2_WWDT_S_HCLK_DIV2048 (0x2UL<<CLK_CLKSEL2_WWDT_S_Pos) /*!< Setting WWDT clock source as HCLK/2048 */
#define CLK_CLKSEL2_WWDT_S_LIRC (0x3UL<<CLK_CLKSEL2_WWDT_S_Pos) /*!< Setting WWDT clock source as LIRC */
#define CLK_CLKSEL12_PWM01_S_HXT (CLK_CLKSEL1_PWM01_S_HXT | CLK_CLKSEL2_PWM01_EXT_HXT ) /*!< Setting PWM01 clock source as HXT */
#define CLK_CLKSEL12_PWM01_S_HCLK (CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK) /*!< Setting PWM01 clock source as HCLK */
#define CLK_CLKSEL12_PWM01_S_HIRC (CLK_CLKSEL1_PWM01_S_HIRC | CLK_CLKSEL2_PWM01_EXT_HIRC) /*!< Setting PWM01 clock source as HIRC */
#define CLK_CLKSEL12_PWM01_S_LIRC (CLK_CLKSEL1_PWM01_S_LIRC | CLK_CLKSEL2_PWM01_EXT_LIRC) /*!< Setting PWM01 clock source as LIRC */
#define CLK_CLKSEL12_PWM23_S_HXT (CLK_CLKSEL1_PWM23_S_HXT | CLK_CLKSEL2_PWM23_EXT_HXT ) /*!< Setting PWM23 clock source as HXT */
#define CLK_CLKSEL12_PWM23_S_HCLK (CLK_CLKSEL1_PWM23_S_HCLK | CLK_CLKSEL2_PWM23_EXT_HCLK) /*!< Setting PWM23 clock source as HCLK */
#define CLK_CLKSEL12_PWM23_S_HIRC (CLK_CLKSEL1_PWM23_S_HIRC | CLK_CLKSEL2_PWM23_EXT_HIRC) /*!< Setting PWM23 clock source as HIRC */
#define CLK_CLKSEL12_PWM23_S_LIRC (CLK_CLKSEL1_PWM23_S_LIRC | CLK_CLKSEL2_PWM23_EXT_LIRC) /*!< Setting PWM23 clock source as LIRC */
/*---------------------------------------------------------------------------------------------------------*/
/* CLKDIV constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_CLKDIV_HCLK(x) ((x)-1) /*!< CLKDIV Setting for HCLK clock divider. It could be 1~16 */
#define CLK_CLKDIV_USB(x) (((x)-1) << CLK_CLKDIV_USB_N_Pos) /*!< CLKDIV Setting for USB clock divider. It could be 1~16 */
#define CLK_CLKDIV_UART(x) (((x)-1) << CLK_CLKDIV_UART_N_Pos) /*!< CLKDIV Setting for UART clock divider. It could be 1~16 */
#define CLK_CLKDIV_ADC(x) (((x)-1) << CLK_CLKDIV_ADC_N_Pos) /*!< CLKDIV Setting for ADC clock divider. It could be 1~256 */
/*---------------------------------------------------------------------------------------------------------*/
/* PLLCON constant definitions. PLL = FIN * NF / NR / NO */
/*---------------------------------------------------------------------------------------------------------*/
#define CLK_PLLCON_PLL_SRC_HXT 0x00000000UL /*!< For PLL clock source is HXT. 4MHz < FIN < 24MHz */
#define CLK_PLLCON_PLL_SRC_HIRC 0x00080000UL /*!< For PLL clock source is HIRC.4MHz < FIN < 24MHz */
#define CLK_PLLCON_NR(x) (((x)-2)<<9) /*!< x must be constant and 2 <= x <= 33. 1.6MHz < FIN/NR < 15MHz */
#define CLK_PLLCON_NF(x) ((x)-2) /*!< x must be constant and 2 <= x <= 513. 100MHz < FIN*NF/NR < 200MHz. (120MHz < FIN*NF/NR < 200MHz is preferred.) */
#define CLK_PLLCON_NO_1 0x0000UL /*!< For output divider is 1 */
#define CLK_PLLCON_NO_2 0x4000UL /*!< For output divider is 2 */
#define CLK_PLLCON_NO_4 0xC000UL /*!< For output divider is 4 */
#if (__HXT == 12000000)
#define CLK_PLLCON_FOR_I2S (0xA54) /*!< Predefined PLLCON setting for 147428571.428571Hz PLL output with 12MHz X'tal */
#define CLK_PLLCON_144MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(2) | CLK_PLLCON_NF( 24) | CLK_PLLCON_NO_1) /*!< Predefined PLLCON setting for 72MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_72MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(2) | CLK_PLLCON_NF( 24) | CLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 72MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_50MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(3) | CLK_PLLCON_NF( 25) | CLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 50MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_48MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(7) | CLK_PLLCON_NF(112) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 48MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_36MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(7) | CLK_PLLCON_NF( 84) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 36MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_32MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(6) | CLK_PLLCON_NF( 64) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 32MHz PLL output with 12MHz X'tal */
#define CLK_PLLCON_24MHz_HXT (CLK_PLLCON_PLL_SRC_HXT | CLK_PLLCON_NR(2) | CLK_PLLCON_NF( 16) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 24MHz PLL output with 12MHz X'tal */
#else
# error "The PLL pre-definitions are only valid when external crystal is 12MHz"
#endif
#define CLK_PLLCON_72MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR( 4) | CLK_PLLCON_NF( 26) | CLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 71.88488MHz PLL output with 22.1184MHz IRC */
#define CLK_PLLCON_50MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR(13) | CLK_PLLCON_NF( 59) | CLK_PLLCON_NO_2) /*!< Predefined PLLCON setting for 50.1918MHz PLL output with 22.1184MHz IRC */
#define CLK_PLLCON_48MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR(13) | CLK_PLLCON_NF(113) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 48.064985MHz PLL output with 22.1184MHz IRC*/
#define CLK_PLLCON_36MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR(12) | CLK_PLLCON_NF( 78) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 35.9424MHz PLL output with 22.1184MHz IRC */
#define CLK_PLLCON_32MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR( 9) | CLK_PLLCON_NF( 52) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 31.9488MHz PLL output with 22.1184MHz IRC*/
#define CLK_PLLCON_24MHz_HIRC (CLK_PLLCON_PLL_SRC_HIRC | CLK_PLLCON_NR( 3) | CLK_PLLCON_NF( 13) | CLK_PLLCON_NO_4) /*!< Predefined PLLCON setting for 23.9616MHz PLL output with 22.1184MHz IRC*/
/*---------------------------------------------------------------------------------------------------------*/
/* MODULE constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
/* APBCLK(31:30)|CLKSEL(29:28)|CLKSEL_Msk(27:25) |CLKSEL_Pos(24:20)|CLKDIV(19:18)|CLKDIV_Msk(17:10)|CLKDIV_Pos(9:5)|IP_EN_Pos(4:0) */
#define MODULE_APBCLK(x) (((x) >>30) & 0x3) /*!< Calculate APBCLK offset on MODULE index, 0x0:AHBCLK, 0x1:APBCLK */
#define MODULE_CLKSEL(x) (((x) >>28) & 0x3) /*!< Calculate CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2 */
#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 */
#define MODULE_CLKDIV_Msk(x) (((x) >>10) & 0xff) /*!< Calculate CLKDIV mask offset on MODULE index */
#define MODULE_CLKDIV_Pos(x) (((x) >>5 ) & 0x1f) /*!< Calculate CLKDIV position offset on MODULE index */
#define MODULE_IP_EN_Pos(x) (((x) >>0 ) & 0x1f) /*!< Calculate APBCLK offset on MODULE index */
#define MODULE_NoMsk 0x0 /*!< Not mask on MODULE index */
#define NA MODULE_NoMsk /*!< Not Available */
#define MODULE_APBCLK_ENC(x) (((x) & 0x03) << 30) /*!< MODULE index, 0x0:AHBCLK, 0x1:APBCLK */
#define MODULE_CLKSEL_ENC(x) (((x) & 0x03) << 28) /*!< CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2 */
#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 */
#define MODULE_CLKDIV_Msk_ENC(x) (((x) & 0xff) << 10) /*!< CLKDIV mask offset on MODULE index */
#define MODULE_CLKDIV_Pos_ENC(x) (((x) & 0x1f) << 5) /*!< CLKDIV position offset on MODULE index */
#define MODULE_IP_EN_Pos_ENC(x) (((x) & 0x1f) << 0) /*!< APBCLK offset on MODULE index */
#define PDMA_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_PDMA_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PDMA Module */
#define ISP_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_ISP_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< ISP Module */
#define WDT_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_WDT_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 0)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< WDT Module */
#define TMR0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR0_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC( 8)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR0 Module */
#define TMR1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR1_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(12)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR1 Module */
#define TMR2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR2_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(16)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR2 Module */
#define TMR3_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_TMR3_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(20)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR3 Module */
#define FDIV_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_FDIV_EN_Pos) |\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 2)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< FDIV Module */
#define I2C0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_I2C0_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2C0 Module */
#define I2C1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_I2C1_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2C1 Module */
#define SPI0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_SPI0_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 4)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI0 Module */
#define SPI1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_SPI1_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 5)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI1 Module */
#define SPI2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_SPI2_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 6)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI2 Module */
#define UART0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_UART0_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART0 Module */
#define UART1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_UART1_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART1 Module */
#define PWM01_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PWM01_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(28)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM01 Module */
#define PWM23_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PWM23_EN_Pos)|\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(30)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM23 Module */
#define USBD_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_USBD_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC(4)) /*!< USBD Module */
#define ADC_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_ADC_EN_Pos) |\
MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 2)|\
MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0xFF)|MODULE_CLKDIV_Pos_ENC(16)) /*!< ADC Module */
#define I2S_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_I2S_EN_Pos) |\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 0)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2S Module */
#define PS2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_PS2_EN_Pos) |\
MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PS2 Module */
#define WWDT_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK_WDT_EN_Pos) |\
MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(16)|\
MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< WWDT Module */
/*@}*/ /* end of group CLK_EXPORTED_CONSTANTS */
/** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions
@{
*/
/**
* @brief Get PLL clock frequency
* @param None
* @return PLL frequency
* @details This function get PLL frequency. The frequency unit is Hz.
*/
__STATIC_INLINE uint32_t CLK_GetPLLClockFreq(void)
{
uint32_t u32PllFreq = 0, u32PllReg;
uint32_t u32FIN, u32NF, u32NR, u32NO;
uint8_t au8NoTbl[4] = {1, 2, 2, 4};
u32PllReg = CLK->PLLCON;
if(u32PllReg & (CLK_PLLCON_PD_Msk | CLK_PLLCON_OE_Msk))
return 0; /* PLL is in power down mode or fix low */
if(u32PllReg & CLK_PLLCON_PLL_SRC_HIRC)
u32FIN = __HIRC; /* PLL source clock from HIRC */
else
u32FIN = __HXT; /* PLL source clock from HXT */
if(u32PllReg & CLK_PLLCON_BP_Msk)
return u32FIN; /* PLL is in bypass mode */
/* PLL is output enabled in normal work mode */
u32NO = au8NoTbl[((u32PllReg & CLK_PLLCON_OUT_DV_Msk) >> CLK_PLLCON_OUT_DV_Pos)];
u32NF = ((u32PllReg & CLK_PLLCON_FB_DV_Msk) >> CLK_PLLCON_FB_DV_Pos) + 2;
u32NR = ((u32PllReg & CLK_PLLCON_IN_DV_Msk) >> CLK_PLLCON_IN_DV_Pos) + 2;
/* u32FIN is shifted 2 bits to avoid overflow */
u32PllFreq = (((u32FIN >> 2) * u32NF) / (u32NR * u32NO) << 2);
return u32PllFreq;
}
/**
* @brief This function execute delay function.
* @param[in] us Delay time. The Max value is 2^24 / CPU Clock(MHz). Ex:
* 72MHz => 233016us, 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 us)
{
SysTick->LOAD = us * CyclesPerUs;
SysTick->VAL = (0x00);
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
/* Waiting for down-count to zero */
while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
/* Disable SysTick counter */
SysTick->CTRL = 0;
}
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_GetHCLKFreq(void);
uint32_t CLK_GetPCLKFreq(void);
uint32_t CLK_GetCPUFreq(void);
uint32_t CLK_SetCoreClock(uint32_t u32Hclk);
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv);
void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv);
void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc);
void CLK_EnableXtalRC(uint32_t u32ClkMask);
void CLK_DisableXtalRC(uint32_t u32ClkMask);
void CLK_EnableModuleClock(uint32_t u32ModuleIdx);
void CLK_DisableModuleClock(uint32_t u32ModuleIdx);
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq);
void CLK_DisablePLL(void);
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask);
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count);
void CLK_DisableSysTick(void);
/*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group CLK_Driver */
/*@}*/ /* end of group Standard_Driver */
#endif //__CLK_H__
/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,2 @@
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/CLKv1/clk.c
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/CLKv1

View File

@ -0,0 +1,10 @@
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/gpio.c
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1
ifeq ($(USE_SMART_BUILD),yes)
ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/hal_pal_lld.c
endif
else
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/hal_pal_lld.c
endif

View File

@ -0,0 +1,115 @@
/**************************************************************************//**
* @file gpio.c
* @version V3.00
* $Revision: 8 $
* $Date: 16/06/08 9:58a $
* @brief NUC123 series GPIO driver source file
*
* @note
* Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NUC123.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 or PF.
* @param[in] u32PinMask The single or multiple pins of specified GPIO port. \n
* It could be BIT10 ~ BIT15 for PA GPIO port. \n
* It could be BIT0 ~ BIT10 and BIT12 ~ BIT15 for PB GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT13 for PC GPIO port. \n
* It could be BIT0 ~ BIT5 and BIT8 ~ BIT11 for PD GPIO port. \n
* It could be BIT0 ~ BIT3 for PF GPIO port.
* @param[in] u32Mode Operation mode. It could be :
* - \ref GPIO_PMD_INPUT,
* - \ref GPIO_PMD_OUTPUT,
* - \ref GPIO_PMD_OPEN_DRAIN,
* - \ref GPIO_PMD_QUASI
*
* @return None
*
* @details This function is used to set specified GPIO operation mode.
*/
void GPIO_SetMode(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode)
{
uint32_t i;
for(i = 0; i < GPIO_PIN_MAX; i++)
{
if(u32PinMask & (1 << i))
{
port->PMD = (port->PMD & ~(0x3 << (i << 1))) | (u32Mode << (i << 1));
}
}
}
/**
* @brief Enable GPIO interrupt
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32Pin The pin of specified GPIO port. \n
* It could be 10 ~ 15 for PA GPIO port. \n
* It could be 0 ~ 10 and 12 ~ 15 for PB GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 13 for PC GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 11 for PD GPIO port. \n
* It could be 0 ~ 3 for PF GPIO port.
* @param[in] u32IntAttribs The interrupt attribute of specified GPIO pin. It could be :
* - \ref GPIO_INT_RISING
* - \ref GPIO_INT_FALLING
* - \ref GPIO_INT_BOTH_EDGE
* - \ref GPIO_INT_HIGH
* - \ref GPIO_INT_LOW
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
void GPIO_EnableInt(GPIO_T *port, uint32_t u32Pin, uint32_t u32IntAttribs)
{
port->IMD |= (((u32IntAttribs >> 24) & 0xFFUL) << u32Pin);
port->IEN |= ((u32IntAttribs & 0xFFFFFFUL) << u32Pin);
}
/**
* @brief Disable GPIO interrupt
*
* @param[in] port GPIO port. It could be PA, PB, PC, PD or PF.
* @param[in] u32Pin The pin of specified GPIO port. \n
* It could be 10 ~ 15 for PA GPIO port. \n
* It could be 0 ~ 10 and 12 ~ 15 for PB GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 13 for PC GPIO port. \n
* It could be 0 ~ 5 and 8 ~ 11 for PD GPIO port. \n
* It could be 0 ~ 3 for PF GPIO port.
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
void GPIO_DisableInt(GPIO_T *port, uint32_t u32Pin)
{
port->IMD &= ~(1UL << u32Pin);
port->IEN &= ~((0x00010001UL) << u32Pin);
}
/*@}*/ /* end of group GPIO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group GPIO_Driver */
/*@}*/ /* end of group Standard_Driver */
/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,191 @@
/*
Copyright (C) 2019 /u/KeepItUnder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_pal_lld.c
* @brief PLATFORM PAL subsystem low level driver source.
*
* @addtogroup PAL
* @{
*/
#include "hal.h"
#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/* DEBUG
OSAL_IRQ_HANDLER(NUC123_GPIOAB_HANDLER){
OSAL_IRQ_PROLOGUE();
GPIO_TOGGLE(PB4);
GPIO_TOGGLE(PB5);
GPIO_TOGGLE(PB6);
GPIO_TOGGLE(PB7);
GPIO_TOGGLE(PB8);
OSAL_IRQ_EPILOGUE();
}
OSAL_IRQ_HANDLER(NUC123_GPIOCDF_HANDLER){
OSAL_IRQ_PROLOGUE();
GPIO_TOGGLE(PB4);
GPIO_TOGGLE(PB5);
GPIO_TOGGLE(PB6);
GPIO_TOGGLE(PB7);
GPIO_TOGGLE(PB8);
OSAL_IRQ_EPILOGUE();
}
*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief NUC123 I/O ports configuration.
* @details Ports A-D(E, F, G, H) clocks enabled.
*
* @param[in] config the NUC123 ports configuration
*
* @notapi
*/
void _pal_lld_init(const PALConfig *config) {
//(void)config;
/* Turn on GPIO subsystem
* Set all GPIO to Input/HZ
* Clear all GPIO Interrupts
* Set all GPIO Interrupt Modes to Level
* Turn off DeBounce
* Zero all GPIO Outputs (just in case)
*/
GPIOA->PMD = config->PAData.PMD;
GPIOA->OFFD = config->PAData.OFFD;
GPIOA->DMASK = config->PAData.DMASK;
GPIOA->DBEN = config->PAData.DBEN;
GPIOA->IMD = config->PAData.IMD;
GPIOA->IEN = config->PAData.IEN;
GPIOA->ISRC = config->PAData.ISRC;
GPIOA->DOUT = config->PAData.DOUT;
GPIOB->PMD = config->PBData.PMD;
GPIOB->OFFD = config->PBData.OFFD;
GPIOB->DMASK = config->PBData.DMASK;
GPIOB->DBEN = config->PBData.DBEN;
GPIOB->IMD = config->PBData.IMD;
GPIOB->IEN = config->PBData.IEN;
GPIOB->ISRC = config->PBData.ISRC;
GPIOB->DOUT = config->PBData.DOUT;
GPIOC->PMD = config->PCData.PMD;
GPIOC->OFFD = config->PCData.OFFD;
GPIOC->DMASK = config->PCData.DMASK;
GPIOC->DBEN = config->PCData.DBEN;
GPIOC->IMD = config->PCData.IMD;
GPIOC->IEN = config->PCData.IEN;
GPIOC->ISRC = config->PCData.ISRC;
GPIOC->DOUT = config->PCData.DOUT;
GPIOD->PMD = config->PDData.PMD;
GPIOD->OFFD = config->PDData.OFFD;
GPIOD->DMASK = config->PDData.DMASK;
GPIOD->DBEN = config->PDData.DBEN;
GPIOD->IMD = config->PDData.IMD;
GPIOD->IEN = config->PDData.IEN;
GPIOD->ISRC = config->PDData.ISRC;
GPIOD->DOUT = config->PDData.DOUT;
GPIOF->PMD = config->PFData.PMD;
GPIOF->OFFD = config->PFData.OFFD;
GPIOF->DMASK = config->PFData.DMASK;
GPIOF->DBEN = config->PFData.DBEN;
GPIOF->IMD = config->PFData.IMD;
GPIOF->IEN = config->PFData.IEN;
GPIOF->ISRC = config->PFData.ISRC;
GPIOF->DOUT = config->PFData.DOUT;
/* Set DeBounce conditions */
GPIO->DBNCECON = 0x04u;
/* Enable External Crystal Oscillator pins */
SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN;
// SYS->GPD_MFP |= SYS_GPD_MFP_PD10_CLKO;
/* Enable UART1 data pins */
SYS->GPB_MFP |= SYS_GPB_MFP_PB1_UART0_TXD | SYS_GPB_MFP_PB0_UART0_RXD;
}
/**
* @brief Pads mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @notapi
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode) {
uint32_t nucMode;
nucMode = 0;
if (mode == PAL_MODE_INPUT || mode == PAL_MODE_INPUT_PULLUP)
nucMode = GPIO_PMD_INPUT;
else if (mode == PAL_MODE_OUTPUT_OPENDRAIN)
nucMode = GPIO_PMD_OPEN_DRAIN;
else if (mode == PAL_MODE_OUTPUT_PUSHPULL)
nucMode = GPIO_PMD_OUTPUT;
else
nucMode = GPIO_PMD_QUASI;
GPIO_SetMode(port, mask, nucMode);
}
#endif /* HAL_USE_PAL == TRUE */
/** @} */

View File

@ -0,0 +1,466 @@
/*
Copyright (C) 2019 /u/KeepItUnder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_pal_lld.h
* @brief PLATFORM PAL subsystem low level driver header.
*
* @addtogroup PAL
* @{
*/
#ifndef HAL_PAL_LLD_H
#define HAL_PAL_LLD_H
#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
/**
* @name NUC123 specific I/O mode flags
* @{
*/
/**
* @brief NUC123 specific alternate input mode.
*/
#define PAL_MODE_NUC123_ALTERNATE_INPUT 0x0UL
/**
* @brief NUC123 specific alternate push-pull output mode.
*/
#define PAL_MODE_NUC123_ALTERNATE_OUTPUT 0x1UL
/** @} */
/**
* @brief NUC123 specific alternate output mode.
*/
#define PAL_MODE_NUC123_ALTERNATE_OPEN_DRAIN 0x2UL
/** @} */
/**
* @brief NUC123 specific alternate output mode.
*/
#define PAL_MODE_NUC123_ALTERNATE_QUASI 0x3UL
/** @} */
/*
#undef PAL_MODE_RESET
#undef PAL_MODE_UNCONNECTED
#undef PAL_MODE_INPUT
#undef PAL_MODE_INPUT_PULLUP
#undef PAL_MODE_INPUT_PULLDOWN
#undef PAL_MODE_INPUT_ANALOG
#undef PAL_MODE_OUTPUT_PUSHPULL
#undef PAL_MODE_OUTPUT_OPENDRAIN
#define PAL_MODE_RESET 3U
#define PAL_MODE_INPUT 0U
#define PAL_MODE_OUTPUT_PUSHPULL 1U
#define PAL_MODE_OUTPUT_OPENDRAIN 2U
#define PAL_MODE_INPUT_PULLUP 3U
*/
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @name Port related definitions
* @{
*/
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH GPIO_PIN_MAX
/**
* @brief Whole port mask.
* @details This macro specifies all the valid bits into a port.
*/
//#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFU)
#define PAL_WHOLE_PORT ((ioportmask_t)(2^GPIO_PIN_MAX) - 1)
/** @} */
/**
* @name Line handling macros
* @{
*/
/**
* @brief Forms a line identifier.
* @details A port/pad pair are encoded into an @p ioline_t type. The encoding
* of this type is platform-dependent.
*/
#define PAL_LINE(port, pad) \
((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
/**
* @brief Decodes a port identifier from a line identifier.
*/
#define PAL_PORT(line) \
((GPIO_T *)(((uint32_t)(line)) & 0xFFFFFFF0U))
/**
* @brief Decodes a pad identifier from a line identifier.
*/
#define PAL_PAD(line) \
((uint32_t)((uint32_t)(line) & 0x0000000FU))
/**
* @brief Value identifying an invalid line.
*/
#define PAL_NOLINE 0U
/** @} */
/**
* @brief Generic I/O ports static initializer.
* @details An instance of this structure must be passed to @p palInit() at
* system startup time in order to initialized the digital I/O
* subsystem. This represents only the initial setup, specific pads
* or whole ports can be reprogrammed at later time.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/
typedef struct {
/** @brief Port A setup data.*/
GPIO_T PAData;
/** @brief Port B setup data.*/
GPIO_T PBData;
/** @brief Port C setup data.*/
GPIO_T PCData;
/** @brief Port D setup data.*/
GPIO_T PDData;
/** @brief Port F setup data.*/
GPIO_T PFData;
} PALConfig;
/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint32_t ioportmask_t;
/**
* @brief Digital I/O modes.
*/
typedef uint32_t iomode_t;
/**
* @brief Type of an I/O line.
*/
typedef uint32_t ioline_t;
/**
* @brief Port Identifier.
* @details This type can be a scalar or some kind of pointer, do not make
* any assumption about it, use the provided macros when populating
* variables of this type.
*/
typedef GPIO_T * ioportid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief First I/O port identifier.
* @details Low level drivers can define multiple ports, it is suggested to
* use this naming convention.
*/
#define IOPORT1 0
#define GPIOA PA
#define GPIOB PB
#define GPIOC PC
#define GPIOD PD
#define GPIOF PF
/*===========================================================================*/
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in pal_lld.c. */
/*===========================================================================*/
/**
* @brief Low level PAL subsystem initialization.
*
* @param[in] config architecture-dependent ports configuration
*
* @notapi
*/
#define pal_lld_init(config) _pal_lld_init(config)
/**
* @brief Reads the physical I/O port states.
*
* @param[in] port port identifier
* @return The port bits.
*
* @notapi
*/
#define pal_lld_readport(port) (port->PIN)
/**
* @brief Reads the output latch.
* @details The purpose of this function is to read back the latched output
* value.
*
* @param[in] port port identifier
* @return The latched logical states.
*
* @notapi
*/
#define pal_lld_readlatch(port) (port->DOUT)
/**
* @brief Writes a bits mask on a I/O port.
*
* @param[in] port port identifier
* @param[in] bits bits to be written on the specified port
*
* @notapi
*/
#define pal_lld_writeport(port, bits) (port->DOUT = bits)
/**
* @brief Sets a bits mask on a I/O port.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be ORed on the specified port
*
* @notapi
*/
#define pal_lld_setport(port, bits) (port->DOUT |= bits)
/**
* @brief Clears a bits mask on a I/O port.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be cleared on the specified port
*
* @notapi
*/
#define pal_lld_clearport(port, bits) (port->DOUT &= ~bits)
/**
* @brief Toggles a bits mask on a I/O port.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be XORed on the specified port
*
* @notapi
*/
#define pal_lld_toggleport(port, bits) (port->DOUT ^= bits)
/**
* @brief Reads a group of bits.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @return The group logical states.
*
* @notapi
*/
//#define pal_lld_readgroup(port, mask, offset) 0U
/**
* @brief Writes a group of bits.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @param[in] bits bits to be written. Values exceeding the group width
* are masked.
*
* @notapi
*/
#define pal_lld_writegroup(port, mask, offset, bits) \
do { \
uint32_t oldmask = port->DMASK; \
port->DMASK = ~(mask << offset); \
port->DOUT = (bits & mask) << offset; \
port->DMASK = oldmask; \
} while (false)
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
* @note Programming an unknown or unsupported mode is silently ignored.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @param[in] mode group mode
*
* @notapi
*/
#define pal_lld_setgroupmode(port, mask, offset, mode) \
_pal_lld_setgroupmode(port, mask << offset, mode)
/**
* @brief Reads a logical state from an I/O pad.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @return The logical state.
* @retval PAL_LOW low logical state.
* @retval PAL_HIGH high logical state.
*
* @notapi
*/
/**
* @brief Reads a logical state from an I/O pad.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @return The logical state.
* @retval PAL_LOW low logical state.
* @retval PAL_HIGH high logical state.
*
* @notapi
*/
/*#define pal_lld_readpad(port, pad) PAL_LOW*/
#define pal_lld_readpad(port, pad) ((port->PIN & PAL_PORT_BIT(pad)) >> pad)
/**
* @brief Writes a logical state on an output pad.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @param[in] bit logical value, the value must be @p PAL_LOW or
* @p PAL_HIGH
*
* @notapi
*/
/*
#define pal_lld_writepad(port, pad, bit) \
do { \
(void)port; \
(void)pad; \
(void)bit; \
} while (false)
*/
/**
* @brief Sets a pad logical state to @p PAL_HIGH.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*
* @notapi
*/
#define pal_lld_setpad(port, pad) \
(port->DOUT |= PAL_PORT_BIT(pad))
/**
* @brief Clears a pad logical state to @p PAL_LOW.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*
* @notapi
*/
#define pal_lld_clearpad(port, pad) \
(port->DOUT &= ~(0xFFFF0000U | PAL_PORT_BIT(pad)))
/**
* @brief Toggles a pad logical state.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*
* @notapi
*/
#define pal_lld_togglepad(port, pad) \
(port->DOUT ^= PAL_PORT_BIT(pad))
/**
* @brief Pad mode setup.
* @details This function programs a pad with the specified mode.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
* @note Programming an unknown or unsupported mode is silently ignored.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @param[in] mode pad mode
*
* @notapi
*/
#define pal_lld_setpadmode(port, pad, mode) \
_pal_lld_setgroupmode(port, PAL_PORT_BIT(pad), mode)
//GPIO_SetMode(port, PAL_PORT_BIT(pad), mode)
#if !defined(__DOXYGEN__)
extern const PALConfig pal_default_config;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void _pal_lld_init(const PALConfig *config);
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_PAL == TRUE */
#endif /* HAL_PAL_LLD_H */
/** @} */

View File

@ -0,0 +1,2 @@
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/PWMv1/pwm.c
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/PWMv1

View File

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

View File

@ -0,0 +1,3 @@
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/hal_st_lld.c
#PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/timer.c
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1

View File

@ -0,0 +1,351 @@
/*
Copyright (C) 2019 /u/KeepItUnder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file TIMv1/hal_st_lld.c
* @brief ST Driver subsystem low level driver code.
*
* @addtogroup ST
* @{
*/
#include "hal.h"
#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
#if (OSAL_ST_RESOLUTION == 32)
#define ST_ARR_INIT 0xFFFFFFFF
#else
#define ST_ARR_INIT 0x0000FFFF
#endif
#if NUC123_ST_USE_TIMER == 2
#if (OSAL_ST_RESOLUTION == 32) && !NUC123_TIM2_IS_32BITS
#error "TIM2 is not a 32bits timer"
#endif
#if defined(NUC123_TIM2_IS_USED)
#error "ST requires TIM2 but the timer is already used"
#else
#define NUC123_TIM2_IS_USED
#endif
#define ST_HANDLER NUC123_TIM2_HANDLER
#define ST_NUMBER NUC123_TIM2_NUMBER
#define ST_USE_TIMER TIMER2
#elif NUC123_ST_USE_TIMER == 3
#if (OSAL_ST_RESOLUTION == 32) && !NUC123_TIM3_IS_32BITS
#error "TIM3 is not a 32bits timer"
#endif
#if defined(NUC123_TIM3_IS_USED)
#error "ST requires TIM3 but the timer is already used"
#else
#define NUC123_TIM3_IS_USED
#endif
#define ST_HANDLER NUC123_TIM3_HANDLER
#define ST_NUMBER NUC123_TIM3_NUMBER
#define ST_USE_TIMER TIMER3
#elif NUC123_ST_USE_TIMER == 4
#if (OSAL_ST_RESOLUTION == 32) && !NUC123_TIM4_IS_32BITS
#error "TIM4 is not a 32bits timer"
#endif
#if defined(NUC123_TIM4_IS_USED)
#error "ST requires TIM4 but the timer is already used"
#else
#define NUC123_TIM4_IS_USED
#endif
#define ST_HANDLER NUC123_TIM4_HANDLER
#define ST_NUMBER NUC123_TIM4_NUMBER
#define ST_USE_TIMER TIMER4
#else
#error "NUC123_ST_USE_TIMER specifies an unsupported timer"
#endif
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) || defined(__DOXYGEN__)
/**
* @brief System Timer vector.
* @details This interrupt is used for system tick in periodic mode.
*
* @isr
*/
OSAL_IRQ_HANDLER(SysTick_Handler) {
OSAL_IRQ_PROLOGUE();
osalSysLockFromISR();
osalOsTimerHandlerI();
osalSysUnlockFromISR();
/* DEBUG Output to pin PB8 */
//GPIO_TOGGLE(PB8);
//GPIO_TOGGLE(PD10);
//GPIO_TOGGLE(PB14);
//uint16_t quickChange = PB14;
//pal_lld_writepad(GPIOB, 14, ~quickChange);
// if (PB14 == 0)
// palSetLine(B14);
// else
// palClearLine(B14);
//palToggleLine(B14);
OSAL_IRQ_EPILOGUE();
}
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
#if (OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING) || defined(__DOXYGEN__)
/**
* @brief TIM2 interrupt handler.
* @details This interrupt is used for system tick in free running mode.
*
* @isr
*/
OSAL_IRQ_HANDLER(ST_HANDLER) {
OSAL_IRQ_PROLOGUE();
/* Note, under rare circumstances an interrupt can remain latched even if
the timer SR register has been cleared, in those cases the interrupt
is simply ignored.*/
if (TIMER_GetIntFlag(NUC123_ST_TIM)) {
TIMER_ClearIntFlag(NUC123_ST_TIM);
osalSysLockFromISR();
osalOsTimerHandlerI();
osalSysUnlockFromISR();
}
/* DEBUG Output to pin PC13 */
//GPIO_TOGGLE(PB8);
//GPIO_TOGGLE(PD11);
OSAL_IRQ_EPILOGUE();
}
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
/* DEBUG - Catch unused Interrupt Vectors and output to test pins
OSAL_IRQ_HANDLER(Vector7C){
OSAL_IRQ_PROLOGUE();
GPIO_TOGGLE(PB8);
GPIO_TOGGLE(PB11);
OSAL_IRQ_EPILOGUE();
}
OSAL_IRQ_HANDLER(NUC123_TIM3_HANDLER){
OSAL_IRQ_PROLOGUE();
GPIO_TOGGLE(PB4);
GPIO_TOGGLE(PB5);
GPIO_TOGGLE(PB6);
GPIO_TOGGLE(PB7);
GPIO_TOGGLE(PB8);
OSAL_IRQ_EPILOGUE();
}
OSAL_IRQ_HANDLER(NUC123_TIM4_HANDLER){
OSAL_IRQ_PROLOGUE();
GPIO_TOGGLE(PB4);
GPIO_TOGGLE(PB5);
GPIO_TOGGLE(PB6);
GPIO_TOGGLE(PB7);
GPIO_TOGGLE(PB8);
OSAL_IRQ_EPILOGUE();
}
OSAL_IRQ_HANDLER(NUC123_ADC_HANDLER){
OSAL_IRQ_PROLOGUE();
GPIO_TOGGLE(PB4);
GPIO_TOGGLE(PB5);
GPIO_TOGGLE(PB6);
GPIO_TOGGLE(PB7);
GPIO_TOGGLE(PB8);
OSAL_IRQ_EPILOGUE();
}
OSAL_IRQ_HANDLER(NUC123_USB1_HANDLER){
OSAL_IRQ_PROLOGUE();
GPIO_TOGGLE(PB4);
GPIO_TOGGLE(PB5);
GPIO_TOGGLE(PB6);
GPIO_TOGGLE(PB7);
GPIO_TOGGLE(PB8);
OSAL_IRQ_EPILOGUE();
}
OSAL_IRQ_HANDLER(NUC123_PDMA_HANDLER){
OSAL_IRQ_PROLOGUE();
GPIO_TOGGLE(PB4);
GPIO_TOGGLE(PB5);
GPIO_TOGGLE(PB6);
GPIO_TOGGLE(PB7);
GPIO_TOGGLE(PB8);
OSAL_IRQ_EPILOGUE();
}
//OSAL_IRQ_HANDLER(HardFault_Handler){
// OSAL_IRQ_PROLOGUE();
// NVIC_SystemReset();
// OSAL_IRQ_EPILOGUE();
//}
*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level ST driver initialization.
*
* @notapi
*/
void st_lld_init(void) {
//GPIO_SetMode(PB, BIT6, GPIO_PMD_OUTPUT);
//PB6 = 1;
#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
/* Free running counter mode.*/
/* Enabling timer clock.*/
//ST_ENABLE_CLOCK();
//GPIO_SetMode(PB, BIT7, GPIO_PMD_OUTPUT);
//PB7 = 1;
TIMER_Open(ST_USE_TIMER, TIMER_CONTINUOUS_MODE, OSAL_ST_FREQUENCY);
/* Initializing the counter in free running mode.*/
/* NUC123_ST_TIM->PSC = (ST_CLOCK_SRC / OSAL_ST_FREQUENCY) - 1;
NUC123_ST_TIM->ARR = ST_ARR_INIT;
NUC123_ST_TIM->CCMR1 = 0;
NUC123_ST_TIM->CCR[0] = 0;
NUC123_ST_TIM->DIER = 0;
NUC123_ST_TIM->CR2 = 0;
NUC123_ST_TIM->EGR = TIM_EGR_UG;
NUC123_ST_TIM->CR1 = TIM_CR1_CEN;
*/
/* IRQ enabled.*/
nvicEnableVector(ST_NUMBER, NUC123_ST_IRQ_PRIORITY);
TIMER_EnableInt(ST_USE_TIMER);
/* Start the Timer! */
TIMER_Start(ST_USE_TIMER);
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
/* Periodic systick mode, the Cortex-Mx internal systick timer is used
in this mode.*/
// GPIO_SetMode(PB, BIT8, GPIO_PMD_OUTPUT);
// PB8 = 1;
// CLK_EnableSysTick(CLK_CLKSEL0_STCLK_S_HCLK, (NUC123_HCLK / OSAL_ST_FREQUENCY) - 1);
SysTick->LOAD = (NUC123_HCLK / OSAL_ST_FREQUENCY) - 1;
SysTick->VAL = 0;
SysTick->CTRL = (~SysTick_CTRL_CLKSOURCE_Msk) &
(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
/* IRQ enabled.*/
nvicSetSystemHandlerPriority(HANDLER_SYSTICK, NUC123_ST_IRQ_PRIORITY);
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
/* DEBUG */
// TIMER_Open(TIMER3, TIMER_CONTINUOUS_MODE, OSAL_ST_FREQUENCY);
// nvicEnableVector(NUC123_TIM3_NUMBER, 0);
// TIMER_EnableInt(TIMER3);
// TIMER_Start(TIMER3);
// /* Enable peripheral clock */
// CLK_EnableModuleClock(UART0_MODULE);
// CLK_EnableModuleClock(USBD_MODULE);
// CLK_EnableModuleClock(TMR0_MODULE);
// CLK_EnableModuleClock(TMR1_MODULE);
// CLK_EnableModuleClock(TMR2_MODULE);
// CLK_EnableModuleClock(TMR3_MODULE);
// //
// /* Peripheral clock source */
// // CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_PLL, CLK_CLKDIV_UART(1));
// CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0_S_HXT, 0);
// CLK_SetModuleClock(TMR1_MODULE, CLK_CLKSEL1_TMR1_S_HIRC, 0);
// CLK_SetModuleClock(TMR2_MODULE, CLK_CLKSEL1_TMR2_S_HCLK, 0);
// CLK_SetModuleClock(TMR3_MODULE, CLK_CLKSEL1_TMR3_S_LIRC, 0);
}
#else /* OSAL_ST_MODE == OSAL_ST_MODE_NONE!!! */
#error "We can't proceed without an OSAL_ST clock!"
#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */
/** @} */

View File

@ -0,0 +1,200 @@
/*
Copyright (C) 2019 /u/KeepItUnder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_st_lld.h
* @brief ST Driver subsystem low level driver header.
* @details This header is designed to be include-able without having to
* include other files from the HAL.
*
* @addtogroup ST
* @{
*/
#ifndef HAL_ST_LLD_H
#define HAL_ST_LLD_H
#include "mcuconf.h"
//#include "nuc123_tim.h"
/*
* Registry definitions.
*/
#include "nuc123_registry.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief SysTick timer IRQ priority.
*/
#if !defined(NUC123_ST_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define NUC123_ST_IRQ_PRIORITY 8
#endif
/**
* @brief TIMx unit (by number) to be used for free running operations.
* @note You must select a 32 bits timer if a 32 bits @p systick_t type
* is required.
* @note Timers 2, 3 and 4 are supported.
*/
#if !defined(NUC123_ST_USE_TIMER) || defined(__DOXYGEN__)
#define NUC123_ST_USE_TIMER 2
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if NUC123_ST_USE_TIMER == 2
#if !NUC123_HAS_TIM2
#error "TIM2 not present"
#endif
#define NUC123_ST_TIM TIMER1
#elif NUC123_ST_USE_TIMER == 3
#if !NUC123_HAS_TIM3
#error "TIM3 not present"
#endif
#define NUC123_ST_TIM TIMER2
#elif NUC123_ST_USE_TIMER == 4
#if !NUC123_HAS_TIM4
#error "TIM4 not present"
#endif
#define NUC123_ST_TIM TIMER3
#else
#error "NUC123_ST_USE_TIMER specifies an unsupported timer"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void st_lld_init(void);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Driver inline functions. */
/*===========================================================================*/
/**
* @brief Returns the time counter value.
*
* @return The counter value.
*
* @notapi
*/
static inline systime_t st_lld_get_counter(void) {
return (systime_t)NUC123_ST_TIM->TDR;
}
/**
* @brief Starts the alarm.
* @note Makes sure that no spurious alarms are triggered after
* this call.
*
* @param[in] time the time to be set for the first alarm
*
* @notapi
*/
static inline void st_lld_start_alarm(systime_t time) {
//NUC123_ST_TIM->TCMP = (uint32_t)time;
//NUC123_ST_TIM->SR = 0;
//NUC123_ST_TIM->DIER = NUC123_TIM_DIER_CC1IE;
TIMER_Open(NUC123_ST_TIM, TIMER_CONTINUOUS_MODE | TIMER_TCSR_TDR_EN_Msk, TIMER_GetModuleClock(NUC123_ST_TIM));
TIMER_SET_CMP_VALUE(NUC123_ST_TIM, (uint32_t)time);
TIMER_SET_PRESCALE_VALUE(NUC123_ST_TIM, 0);
TIMER_Start(NUC123_ST_TIM);
}
/**
* @brief Stops the alarm interrupt.
*
* @notapi
*/
static inline void st_lld_stop_alarm(void) {
TIMER_DisableInt(NUC123_ST_TIM);
}
/**
* @brief Sets the alarm time.
*
* @param[in] time the time to be set for the next alarm
*
* @notapi
*/
static inline void st_lld_set_alarm(systime_t time) {
TIMER_SET_CMP_VALUE(NUC123_ST_TIM, (uint32_t)time);
}
/**
* @brief Returns the current alarm time.
*
* @return The currently set alarm time.
*
* @notapi
*/
static inline systime_t st_lld_get_alarm(void) {
return (systime_t)NUC123_ST_TIM->TCMPR;
}
/**
* @brief Determines if the alarm is active.
*
* @return The alarm status.
* @retval false if the alarm is not active.
* @retval true is the alarm is active
*
* @notapi
*/
static inline bool st_lld_is_alarm_active(void) {
return (bool)((TIMER_GetIntFlag(NUC123_ST_TIM) & TIMER_IS_ACTIVE(NUC123_ST_TIM)) != 0);
}
#endif /* HAL_ST_LLD_H */
/** @} */

View File

@ -0,0 +1,9 @@
ifeq ($(USE_SMART_BUILD),yes)
ifneq ($(findstring HAL_USE_USB TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/USBv1/hal_usb_lld.c
endif
else
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/USBv1/hal_usb_lld.c
endif
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/USBv1

View File

@ -0,0 +1,570 @@
/*
ChibiOS - Copyright (C) 2017 Frank Zschockelt
ChibiOS - Copyright (C) 2019 /u/KeepItUnder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_usb_lld.c
* @brief NUC123 USB subsystem low level driver source.
*
* @addtogroup USB
* @{
*/
#include "hal.h"
#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief USB1 driver identifier.
*/
#if (NUC123_USB_USE_USB1 == TRUE) || defined(__DOXYGEN__)
USBDriver USBD1;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
uint8_t * const usbd_sram = (uint8_t*)(USBD_BASE + 0x100);
/**
* @brief EP0 state.
*/
/**
* @brief IN EP0 state.
*/
USBInEndpointState ep0_in;
/**
* @brief OUT EP0 state.
*/
USBOutEndpointState ep0_out;
static uint8_t ep0setup_buffer[8];
/**
* @brief EP0 initialization structure.
*/
static const USBEndpointConfig ep0config = {
USB_EP_MODE_TYPE_CTRL,
_usb_ep0setup,
_usb_ep0in,
_usb_ep0out,
0x40,
0x40,
&ep0_in,
&ep0_out,
1,
ep0setup_buffer
};
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
void _toggle_dsq(int ep, uint8_t *dsq)
{
if (*dsq) {
USBD->EP[ep].CFG &= ~USBD_CFG_DSQ_SYNC_Msk;
}
else {
USBD->EP[ep].CFG |= USBD_CFG_DSQ_SYNC_Msk;
}
*dsq = !*dsq;
}
/*===========================================================================*/
/* Driver interrupt handlers and threads. */
/*===========================================================================*/
static void serve_endpoint_irq(USBDriver *usbp,
uint32_t endpoint_mask,
uint32_t epstatus)
{
for (int hwEp = 0; hwEp < USB_MAX_ENDPOINTS; hwEp++) {
if (endpoint_mask & (1 << hwEp)) {
uint32_t bus_status = ((epstatus >> (hwEp*(USBD_EPSTS_EPSTS1_Pos - USBD_EPSTS_EPSTS0_Pos))) & USBD_EPSTS_EPSTS0_Msk) >> USBD_EPSTS_EPSTS0_Pos;
usbep_t ep = (USBD->EP[hwEp].CFG & USBD_CFG_EP_NUM_Msk) >> USBD_CFG_EP_NUM_Pos;
switch (bus_status) {
case 0: /* In ACK */
{
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
iesp->txcnt += USBD->EP[hwEp].MXPLD;
if (iesp->txcnt >= iesp->txsize) {
_usb_isr_invoke_in_cb(usbp, ep);
}
else {
uint32_t txcnt;
if ((iesp->txcnt + usbp->epc[ep]->in_maxsize) > iesp->txsize) {
txcnt = iesp->txsize - iesp->txcnt;
}
else {
txcnt = usbp->epc[ep]->in_maxsize;
}
for (uint32_t n = 0; n < txcnt; n++) {
usbd_sram[(USBD->EP[hwEp].BUFSEG) + n] = iesp->txbuf[iesp->txcnt + n];
}
_toggle_dsq(hwEp, &(iesp->dsq));
USBD->EP[hwEp].MXPLD = txcnt;
}
}
break;
case 0x1: /* In NAK */
break;
case 0x2: /* Out Packet Data 0 ACK */
case 0x6: /* Out Packet Data 1 ACK */
{
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
for (uint32_t n = 0; n < USBD->EP[hwEp].MXPLD; n++) {
oesp->rxbuf[oesp->rxcnt] = usbd_sram[USBD->EP[hwEp].BUFSEG + n];
oesp->rxcnt++;
}
if (oesp->rxcnt == oesp->rxsize) {
_usb_isr_invoke_out_cb(usbp, ep);
}
else {
_toggle_dsq(hwEp, &(oesp->dsq));
if ((oesp->rxcnt + usbp->epc[ep]->out_maxsize) > oesp->rxsize) {
USBD->EP[hwEp].MXPLD = oesp->rxsize - oesp->rxcnt;
}
else {
USBD->EP[hwEp].MXPLD = usbp->epc[ep]->out_maxsize;
}
}
}
break;
case 0x3: /* Setup ACK */
break;
case 0x7: /* Isochronous transfer end */
default:
osalDbgAssert(FALSE, "not supported");
}
}
}
}
static void serve_usb_irq(USBDriver *usbp) {
uint32_t intsts = USBD->INTSTS;
uint32_t epsts = USBD->EPSTS;
if (intsts & USBD_INTSTS_FLDET_STS_Msk) {
USBD->INTSTS |= USBD_INTSTS_FLDET_STS_Msk;
if (USBD->FLDET) {
usbConnectBus(usbp);
}
else {
usbDisconnectBus(usbp);
}
}
if (intsts & USBD_INTSTS_BUS_STS_Msk) {
uint32_t bus_attr = USBD->ATTR;
USBD->INTSTS |= USBD_INTSTS_BUS_STS_Msk;
if (bus_attr & USBD_ATTR_USBRST_Msk) {
_usb_reset(usbp);
}
if (bus_attr & USBD_ATTR_SUSPEND_Msk) {
if (usbp->state == USB_ACTIVE) {
_usb_suspend(usbp);
}
}
if (bus_attr & USBD_ATTR_RESUME_Msk) {
usbConnectBus(usbp);
(usbp)->receiving = 0;
(usbp)->transmitting = 0;
_usb_wakeup(usbp);
}
}
if (intsts & USBD_INTSTS_USB_STS_Msk) {
/* check endpoints first */
serve_endpoint_irq(usbp, (intsts & USBD_INTSTS_EPEVT_Msk) >> USBD_INTSTS_EPEVT_Pos, epsts);
USBD->INTSTS = intsts & USBD_INTSTS_EPEVT_Msk;
/* then handle setup packets */
if (intsts & USBD_INTSTS_SETUP_Msk) {
USBD->INTSTS |= USBD_INTSTS_SETUP_Msk;
USBInEndpointState *iesp = usbp->epc[0]->in_state;
iesp->dsq = 0;
_usb_isr_invoke_setup_cb(usbp, 0);
}
}
if (intsts & USBD_INTSTS_WAKEUP_STS_Msk) {
USBD->INTSTS |= USBD_INTSTS_WAKEUP_STS_Msk;
USBD->ATTR |= USBD_ATTR_PHY_EN_Msk;
}
}
OSAL_IRQ_HANDLER(NUC123_USB1_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_usb_irq(&USBD1);
OSAL_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level USB driver initialization.
*
* @notapi
*/
void usb_lld_init(void) {
#if NUC123_USB_USE_USB1 == TRUE
/* Driver initialization.*/
usbObjectInit(&USBD1);
#endif
}
/**
* @brief Configures and activates the USB peripheral.
*
* @param[in] usbp pointer to the @p USBDriver object
*
* @notapi
*/
void usb_lld_start(USBDriver *usbp) {
if (usbp->state == USB_STOP) {
/* Enables the peripheral.*/
#if NUC123_USB_USE_USB1 == TRUE
if (&USBD1 == usbp) {
uint16_t delay;
/* Enable USB Clock */
UNLOCKREG();
CLK->APBCLK |= CLK_APBCLK_USBD_EN_Msk;
/* Reset USB */
SYS->IPRSTC2 |= SYS_IPRSTC2_USBD_RST_Msk;
for (delay=0x100; delay > 0; delay--);
SYS->IPRSTC2 &= ~SYS_IPRSTC2_USBD_RST_Msk;
LOCKREG();
usbConnectBus(usbp);
USBD->ATTR = (USBD_ATTR_BYTEM_Msk | USBD_ATTR_PWRDN_Msk |
USBD_ATTR_DPPU_EN_Msk |USBD_ATTR_USB_EN_Msk |
USBD_ATTR_PHY_EN_Msk);
USBD->DRVSE0 = 1u;
for (delay=0x100; delay > 0; delay--);
USBD->DRVSE0 = 0u;
USBD->INTSTS = USBD->INTSTS;
nvicEnableVector(NUC123_USB1_NUMBER, NUC123_USB_USB1_IRQ_PRIORITY);
USBD->INTEN = (USBD_INTEN_WAKEUP_EN_Msk |
USBD_INTEN_WAKEUP_IE_Msk |
USBD_INTEN_FLDET_IE_Msk |
USBD_INTEN_USB_IE_Msk |
USBD_INTEN_BUS_IE_Msk);
}
#endif
}
}
/**
* @brief Deactivates the USB peripheral.
*
* @param[in] usbp pointer to the @p USBDriver object
*
* @notapi
*/
void usb_lld_stop(USBDriver *usbp) {
if (usbp->state == USB_READY) {
/* Resets the peripheral.*/
/* Disables the peripheral.*/
#if NUC123_USB_USE_USB1 == TRUE
if (&USBD1 == usbp) {
}
#endif
}
}
/**
* @brief USB low level reset routine.
*
* @param[in] usbp pointer to the @p USBDriver object
*
* @notapi
*/
void usb_lld_reset(USBDriver *usbp) {
/* Post reset initialization.*/
/* EP0 initialization.*/
usbp->epc[0] = &ep0config;
/* NUC123 has 512b SRAM for EP-buffers; the first 8b are reserved for setup packets */
usbp->bufnext = 8;
usbp->epnext = 0;
usb_lld_init_endpoint(usbp, 0);
usbConnectBus(usbp);
USBD->FADDR = 0;
}
/**
* @brief Sets the USB address.
*
* @param[in] usbp pointer to the @p USBDriver object
*
* @notapi
*/
void usb_lld_set_address(USBDriver *usbp) {
USBD->FADDR = usbp->address;
}
uint32_t usb_alloc_buf(USBDriver *usbp, size_t size) {
uint32_t buf;
buf = usbp->bufnext;
usbp->bufnext += size;
osalDbgAssert(usbp->bufnext <= 512, "usb buffer space full");
return buf;
}
/**
* @brief Enables an endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
const USBEndpointConfig *epcp = usbp->epc[ep];
uint8_t hwep;
if (epcp->in_state != NULL) {
hwep = usbp->epnext;
usbp->epnext += 1;
osalDbgAssert(usbp->epnext <= USB_MAX_ENDPOINTS, "No endpoints left");
USBD->EP[hwep].BUFSEG = usb_alloc_buf(usbp, epcp->in_maxsize);
if (epcp->ep_mode == USB_EP_MODE_TYPE_CTRL)
/* 2 == in */
USBD->EP[hwep].CFG = (ep << USBD_CFG_EP_NUM_Pos) | (2 << USBD_CFG_STATE_Pos) | USBD_CFG_CSTALL_Msk;
else
USBD->EP[hwep].CFG = (ep << USBD_CFG_EP_NUM_Pos) | (2 << USBD_CFG_STATE_Pos);
epcp->in_state->hwEp = hwep;
}
if (epcp->out_state != NULL) {
hwep = usbp->epnext;
usbp->epnext += 1;
osalDbgAssert(usbp->epnext <= USB_MAX_ENDPOINTS, "No endpoints left");
USBD->EP[hwep].BUFSEG = usb_alloc_buf(usbp, epcp->out_maxsize);
if (epcp->ep_mode == USB_EP_MODE_TYPE_CTRL)
/* 1 == Out */
USBD->EP[hwep].CFG = (ep << USBD_CFG_EP_NUM_Pos) | (1 << USBD_CFG_STATE_Pos) | USBD_CFG_CSTALL_Msk;
else
USBD->EP[hwep].CFG = (ep << USBD_CFG_EP_NUM_Pos) | (1 << USBD_CFG_STATE_Pos);
epcp->out_state->hwEp = hwep;
}
}
/**
* @brief Disables all the active endpoints except the endpoint zero.
*
* @param[in] usbp pointer to the @p USBDriver object
*
* @notapi
*/
void usb_lld_disable_endpoints(USBDriver *usbp) {
(void)usbp;
for (int i = 0; i < USB_MAX_ENDPOINTS; i++) {
USBD->EP[i].CFGP |= USBD_CFGP_CLRRDY_Msk;
USBD->EP[i].CFG &= ~USBD_CFG_STATE_Msk;
}
}
/**
* @brief Returns the status of an OUT endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
* @return The endpoint status.
* @retval EP_STATUS_DISABLED The endpoint is not active.
* @retval EP_STATUS_STALLED The endpoint is stalled.
* @retval EP_STATUS_ACTIVE The endpoint is active.
*
* @notapi
*/
usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
(void)usbp;
(void)ep;
return EP_STATUS_DISABLED;
}
/**
* @brief Returns the status of an IN endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
* @return The endpoint status.
* @retval EP_STATUS_DISABLED The endpoint is not active.
* @retval EP_STATUS_STALLED The endpoint is stalled.
* @retval EP_STATUS_ACTIVE The endpoint is active.
*
* @notapi
*/
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
return EP_STATUS_DISABLED;
}
/**
* @brief Reads a setup packet from the dedicated packet buffer.
* @details This function must be invoked in the context of the @p setup_cb
* callback in order to read the received setup packet.
* @pre In order to use this function the endpoint must have been
* initialized as a control endpoint.
* @post The endpoint is ready to accept another packet.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
* @param[out] buf buffer where to copy the packet data
*
* @notapi
*/
void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
(void)usbp;
(void)ep;
int i;
for (i = 0; i < 8; i++) {
*buf = usbd_sram[i];
//*buf = ep0setup_buffer[i];
ep0setup_buffer[i] = usbd_sram[i];
buf += 1;
}
}
/**
* @brief Starts a receive operation on an OUT endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
uint32_t rxcnt;
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
if (oesp->rxsize > usbp->epc[ep]->out_maxsize) {
rxcnt = usbp->epc[ep]->out_maxsize;
}
else {
rxcnt = oesp->rxsize;
}
_toggle_dsq(oesp->hwEp, &(oesp->dsq));
USBD->EP[oesp->hwEp].MXPLD = rxcnt;
}
/**
* @brief Starts a transmit operation on an IN endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
uint32_t i, txcnt;
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
if (iesp->txsize > usbp->epc[ep]->in_maxsize) {
txcnt = usbp->epc[ep]->in_maxsize;
}
else {
txcnt = iesp->txsize;
}
for (i = 0; i < txcnt; i++) {
usbd_sram[(USBD->EP[iesp->hwEp].BUFSEG) + i] = iesp->txbuf[i];
}
_toggle_dsq(iesp->hwEp, &(iesp->dsq));
USBD->EP[iesp->hwEp].MXPLD = txcnt;
}
/**
* @brief Brings an OUT endpoint in the stalled state.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
USBD->EP[oesp->hwEp].CFGP |= (USBD_CFGP_SSTALL_Msk | USBD_CFGP_CLRRDY_Msk);
}
/**
* @brief Brings an IN endpoint in the stalled state.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
USBD->EP[iesp->hwEp].CFGP |= (USBD_CFGP_SSTALL_Msk | USBD_CFGP_CLRRDY_Msk);
}
/**
* @brief Brings an OUT endpoint in the active state.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
USBD->EP[oesp->hwEp].CFGP &= ~USBD_CFGP_SSTALL_Msk;
}
/**
* @brief Brings an IN endpoint in the active state.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
USBD->EP[iesp->hwEp].CFGP &= ~USBD_CFGP_SSTALL_Msk;
}
#endif /* HAL_USE_USB == TRUE */
/** @} */

View File

@ -0,0 +1,425 @@
/*
ChibiOS - Copyright (C) 2017 Frank Zschockelt
ChibiOS - Copyright (C) 2019 /u/KeepItUnder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_usb_lld.h
* @brief NUC123 USB subsystem low level driver header.
*
* @addtogroup USB
* @{
*/
#ifndef HAL_USB_LLD_H
#define HAL_USB_LLD_H
#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Maximum endpoint address.
*/
#define USB_MAX_ENDPOINTS 8
/**
* @brief Status stage handling method.
*/
#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW
/**
* @brief The address can be changed immediately upon packet reception.
*/
#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
/**
* @brief Method for set address acknowledge.
*/
#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_SW
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name NUC123 configuration options
* @{
*/
/**
* @brief USB driver enable switch.
* @details If set to @p TRUE the support for USB1 is included.
* @note The default is @p FALSE.
*/
#if !defined(NUC123_USB_USE_USB1) || defined(__DOXYGEN__)
#define NUC123_USB_USE_USB1 FALSE
#endif
/**
* @brief USB interrupt priority level setting.
*/
#if !defined(NUC123_USB_USB1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define NUC123_USB_USB1_IRQ_PRIORITY 2
#endif
/**
* @brief Host wake-up procedure duration.
*/
#if !defined(USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__)
#define USB_HOST_WAKEUP_DURATION 2
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if (USB_HOST_WAKEUP_DURATION < 2) || (USB_HOST_WAKEUP_DURATION > 15)
#error "invalid USB_HOST_WAKEUP_DURATION setting, it must be between 2 and 15"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Type of an IN endpoint state structure.
*/
typedef struct {
/**
* @brief Requested transmit transfer size.
*/
size_t txsize;
/**
* @brief Transmitted bytes so far.
*/
size_t txcnt;
/**
* @brief Pointer to the transmission linear buffer.
*/
const uint8_t *txbuf;
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
thread_reference_t thread;
#endif
/* End of the mandatory fields.*/
uint8_t hwEp;
uint8_t dsq;
} USBInEndpointState;
/**
* @brief Type of an OUT endpoint state structure.
*/
typedef struct {
/**
* @brief Requested receive transfer size.
*/
size_t rxsize;
/**
* @brief Received bytes so far.
*/
size_t rxcnt;
/**
* @brief Pointer to the receive linear buffer.
*/
uint8_t *rxbuf;
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
/**
* @brief Waiting thread.
*/
thread_reference_t thread;
#endif
/* End of the mandatory fields.*/
uint8_t hwEp;
uint8_t dsq;
} USBOutEndpointState;
/**
* @brief Type of an USB endpoint configuration structure.
* @note Platform specific restrictions may apply to endpoints.
*/
typedef struct {
/**
* @brief Type and mode of the endpoint.
*/
uint32_t ep_mode;
/**
* @brief Setup packet notification callback.
* @details This callback is invoked when a setup packet has been
* received.
* @post The application must immediately call @p usbReadPacket() in
* order to access the received packet.
* @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL
* endpoints, it should be set to @p NULL for other endpoint
* types.
*/
usbepcallback_t setup_cb;
/**
* @brief IN endpoint notification callback.
* @details This field must be set to @p NULL if the IN endpoint is not
* used.
*/
usbepcallback_t in_cb;
/**
* @brief OUT endpoint notification callback.
* @details This field must be set to @p NULL if the OUT endpoint is not
* used.
*/
usbepcallback_t out_cb;
/**
* @brief IN endpoint maximum packet size.
* @details This field must be set to zero if the IN endpoint is not
* used.
*/
uint16_t in_maxsize;
/**
* @brief OUT endpoint maximum packet size.
* @details This field must be set to zero if the OUT endpoint is not
* used.
*/
uint16_t out_maxsize;
/**
* @brief @p USBEndpointState associated to the IN endpoint.
* @details This structure maintains the state of the IN endpoint.
*/
USBInEndpointState *in_state;
/**
* @brief @p USBEndpointState associated to the OUT endpoint.
* @details This structure maintains the state of the OUT endpoint.
*/
USBOutEndpointState *out_state;
/* End of the mandatory fields.*/
/**
* @brief Reserved field, not currently used.
* @note Initialize this field to 1 in order to be forward compatible.
*/
uint16_t ep_buffers;
/**
* @brief Pointer to a buffer for setup packets.
* @details Setup packets require a dedicated 8-bytes buffer, set this
* field to @p NULL for non-control endpoints.
*/
uint8_t *setup_buf;
} USBEndpointConfig;
/**
* @brief Type of an USB driver configuration structure.
*/
typedef struct {
/**
* @brief USB events callback.
* @details This callback is invoked when an USB driver event is registered.
*/
usbeventcb_t event_cb;
/**
* @brief Device GET_DESCRIPTOR request callback.
* @note This callback is mandatory and cannot be set to @p NULL.
*/
usbgetdescriptor_t get_descriptor_cb;
/**
* @brief Requests hook callback.
* @details This hook allows to be notified of standard requests or to
* handle non standard requests.
*/
usbreqhandler_t requests_hook_cb;
/**
* @brief Start Of Frame callback.
*/
usbcallback_t sof_cb;
/* End of the mandatory fields.*/
} USBConfig;
/**
* @brief Structure representing an USB driver.
*/
struct USBDriver {
/**
* @brief Driver state.
*/
usbstate_t state;
/**
* @brief Current configuration data.
*/
const USBConfig *config;
/**
* @brief Bit map of the transmitting IN endpoints.
*/
uint16_t transmitting;
/**
* @brief Bit map of the receiving OUT endpoints.
*/
uint16_t receiving;
/**
* @brief Active endpoints configurations.
*/
const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
/**
* @brief Fields available to user, it can be used to associate an
* application-defined handler to an IN endpoint.
* @note The base index is one, the endpoint zero does not have a
* reserved element in this array.
*/
void *in_params[USB_MAX_ENDPOINTS];
/**
* @brief Fields available to user, it can be used to associate an
* application-defined handler to an OUT endpoint.
* @note The base index is one, the endpoint zero does not have a
* reserved element in this array.
*/
void *out_params[USB_MAX_ENDPOINTS];
/**
* @brief Endpoint 0 state.
*/
usbep0state_t ep0state;
/**
* @brief Next position in the buffer to be transferred through endpoint 0.
*/
uint8_t *ep0next;
/**
* @brief Number of bytes yet to be transferred through endpoint 0.
*/
size_t ep0n;
/**
* @brief Endpoint 0 end transaction callback.
*/
usbcallback_t ep0endcb;
/**
* @brief Setup packet buffer.
*/
uint8_t setup[8];
/**
* @brief Current USB device status.
*/
uint16_t status;
/**
* @brief Assigned USB address.
*/
uint8_t address;
/**
* @brief Current USB device configuration.
*/
uint8_t configuration;
/**
* @brief State of the driver when a suspend happened.
*/
usbstate_t saved_state;
#if defined(USB_DRIVER_EXT_FIELDS)
USB_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
uint32_t bufnext;
uint8_t epnext;
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Returns the current frame number.
*
* @param[in] usbp pointer to the @p USBDriver object
* @return The current frame number.
*
* @notapi
*/
#define usb_lld_get_frame_number(usbp) 0
/**
* @brief Returns the exact size of a receive transaction.
* @details The received size can be different from the size specified in
* @p usbStartReceiveI() because the last packet could have a size
* different from the expected one.
* @pre The OUT endpoint must have been configured in transaction mode
* in order to use this function.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
* @return Received data size.
*
* @notapi
*/
#define usb_lld_get_transaction_size(usbp, ep) \
((usbp)->epc[ep]->out_state->rxcnt)
/**
* @brief Connects the USB device.
*
* @api
*/
#define usb_lld_connect_bus(usbp) (USBD->ATTR |= USBD_ATTR_USB_EN_Msk | USBD_ATTR_PHY_EN_Msk)
/**
* @brief Disconnect the USB device.
*
* @api
*/
#define usb_lld_disconnect_bus(usbp) (USBD->ATTR &= ~USBD_ATTR_USB_EN_Msk)
/**
* @brief Start of host wake-up procedure.
*
* @notapi
*/
#define usb_lld_wakeup_host(usbp) \
do{ \
USBD->ATTR |= USBD_ATTR_RWAKEUP_Msk; \
osalThreadSleepMilliseconds(USB_HOST_WAKEUP_DURATION); \
USBD->ATTR &= ~USBD_ATTR_RWAKEUP_Msk; \
} while (false)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if (NUC123_USB_USE_USB1 == TRUE) && !defined(__DOXYGEN__)
extern USBDriver USBD1;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void usb_lld_init(void);
void usb_lld_start(USBDriver *usbp);
void usb_lld_stop(USBDriver *usbp);
void usb_lld_reset(USBDriver *usbp);
void usb_lld_set_address(USBDriver *usbp);
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
void usb_lld_disable_endpoints(USBDriver *usbp);
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep);
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep);
void usb_lld_start_out(USBDriver *usbp, usbep_t ep);
void usb_lld_start_in(USBDriver *usbp, usbep_t ep);
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_USB == TRUE */
#endif /* HAL_USB_LLD_H */
/** @} */

View File

@ -0,0 +1,257 @@
/*
Copyright (C) 2019 /u/KeepItUnder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file NUC123SD4AN0/hal_lld.c
* @brief NUC123SD4AN0 HAL subsystem low level driver source.
*
* @addtogroup HAL
* @{
*/
#include "hal.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
#define NUC123_PLLXTPRE_OFFSET 17 /**< PLLXTPRE offset */
#define NUC123_PLLXTPRE_MASK 0x01 /**< PLLXTPRE mask */
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief CMSIS system core clock variable.
* @note It is declared in system_NUC123SD4AN0.h.
*/
//uint32_t SystemCoreClock = NUC123_HCLK;
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if defined(NUC123_DMA_REQUIRED) || defined(__DOXYGEN__)
#if defined(NUC123_DMA1_CH23_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA1 streams 2 and 3 shared ISR.
* @note It is declared here because this device has a non-standard
* DMA shared IRQ handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(NUC123_DMA1_CH23_HANDLER) {
OSAL_IRQ_PROLOGUE();
/* Check on channel 2.*/
dmaServeInterrupt(NUC123_DMA1_STREAM2);
/* Check on channel 3.*/
dmaServeInterrupt(NUC123_DMA1_STREAM3);
OSAL_IRQ_EPILOGUE();
}
#endif /* defined(NUC123_DMA1_CH23_HANDLER) */
#if defined(NUC123_DMA1_CH4567_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA1 streams 4, 5, 6 and 7 shared ISR.
*
* @isr
*/
OSAL_IRQ_HANDLER(NUC123_DMA1_CH4567_HANDLER) {
OSAL_IRQ_PROLOGUE();
/* Check on channel 4.*/
dmaServeInterrupt(NUC123_DMA1_STREAM4);
/* Check on channel 5.*/
dmaServeInterrupt(NUC123_DMA1_STREAM5);
#if NUC123_DMA1_NUM_CHANNELS > 5
/* Check on channel 6.*/
dmaServeInterrupt(NUC123_DMA1_STREAM6);
#endif
#if NUC123_DMA1_NUM_CHANNELS > 6
/* Check on channel 7.*/
dmaServeInterrupt(NUC123_DMA1_STREAM7);
#endif
OSAL_IRQ_EPILOGUE();
}
#endif /* defined(NUC123_DMA1_CH4567_HANDLER) */
#if defined(NUC123_DMA12_CH23_CH12_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA1 streams 2 and 3, DMA2 streams 1 and 1 shared ISR.
* @note It is declared here because this device has a non-standard
* DMA shared IRQ handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(NUC123_DMA12_CH23_CH12_HANDLER) {
OSAL_IRQ_PROLOGUE();
/* Check on channel 2 of DMA1.*/
dmaServeInterrupt(NUC123_DMA1_STREAM2);
/* Check on channel 3 of DMA1.*/
dmaServeInterrupt(NUC123_DMA1_STREAM3);
/* Check on channel 1 of DMA2.*/
dmaServeInterrupt(NUC123_DMA2_STREAM1);
/* Check on channel 2 of DMA2.*/
dmaServeInterrupt(NUC123_DMA2_STREAM2);
OSAL_IRQ_EPILOGUE();
}
#endif /* defined(NUC123_DMA12_CH23_CH12_HANDLER) */
#if defined(NUC123_DMA12_CH4567_CH345_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA1 streams 4, 5, 6 and 7, DMA2 streams 3, 4 and 5 shared ISR.
* @note It is declared here because this device has a non-standard
* DMA shared IRQ handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(NUC123_DMA12_CH4567_CH345_HANDLER) {
OSAL_IRQ_PROLOGUE();
/* Check on channel 4 of DMA1.*/
dmaServeInterrupt(NUC123_DMA1_STREAM4);
/* Check on channel 5 of DMA1.*/
dmaServeInterrupt(NUC123_DMA1_STREAM5);
/* Check on channel 6 of DMA1.*/
dmaServeInterrupt(NUC123_DMA1_STREAM6);
/* Check on channel 7 of DMA1.*/
dmaServeInterrupt(NUC123_DMA1_STREAM7);
/* Check on channel 3 of DMA2.*/
dmaServeInterrupt(NUC123_DMA2_STREAM3);
/* Check on channel 4 of DMA2.*/
dmaServeInterrupt(NUC123_DMA2_STREAM4);
/* Check on channel 5 of DMA2.*/
dmaServeInterrupt(NUC123_DMA2_STREAM5);
OSAL_IRQ_EPILOGUE();
}
#endif /* defined(NUC123_DMA12_CH4567_CH345_HANDLER) */
#endif /* defined(NUC123_DMA_REQUIRED) */
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*
* @notapi
*/
void hal_lld_init(void) {
/* Reset of all peripherals.*/
// **NUC123TODO
#if defined(NUC123_DMA_REQUIRED)
//dmaInit();
//usbInit();
//uartInit();
//spiInit();
#endif
//usbInit();
}
/**
* @brief NUC123 clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h.
* @note This function should be invoked just after the system reset.
*
* @special
*/
void NUC123_clock_init(void) {
SYS_UnlockReg();
/* Enable XT1_OUT (PF.0) and XT1_IN (PF.1) */
SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN;
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Enable Internal RC 22.1184 MHz clock */
CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);
/* Waiting for Internal RC clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
/* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
/* Enable external XTAL 12 MHz clock */
CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);
/* Waiting for external XTAL clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
/* Set core clock */
CLK_SetCoreClock(FREQ_72MHZ);
SystemCoreClock = NUC123_HCLK;
//CLK_SetSysTickClockSrc(CLK_CLKSEL0_STCLK_S_HCLK_DIV2);
CLK_EnableSysTick(CLK_CLKSEL0_STCLK_S_HCLK_DIV2, (NUC123_HCLK / OSAL_ST_FREQUENCY) - 1);
/* Enable module clock */
//CLK_EnableModuleClock(UART0_MODULE);
CLK_EnableModuleClock(USBD_MODULE);
/* Select module clock source */
//CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
CLK_SetModuleClock(USBD_MODULE, 0, CLK_CLKDIV_USB(3));
/* TEMPORARY!!! */
/* Set GPB multi-function pins for UART0 RXD and TXD */
SYS->GPB_MFP = (SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD);
/* Set PC.13 as CLKO function pin */
//SYS->GPC_MFP = SYS_GPC_MFP_PC13_CLKO;
//SYS->ALT_MFP = SYS_ALT_MFP_PC13_CLKO;
/* Enable CLKO (PC.13) for monitor HCLK. CLKO = HCLK/8 Hz*/
//CLK_EnableCKO(CLK_CLKSEL2_FRQDIV_S_HCLK, 2, 0);
}
/** @} */

View File

@ -0,0 +1,815 @@
/*
Copyright (C) 2019 /u/KeepItUnder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file NUC123SD4AN0/hal_lld.h
* @brief NUC123SD4AN0 HAL subsystem low level driver header.
* @pre This module requires the following macros to be defined in the
* @p board.h file:
* - NUC123_LSECLK.
* - NUC123_LSEDRV.
* - NUC123_LSE_BYPASS (optionally).
* - NUC123_HSECLK.
* - NUC123_HSE_BYPASS (optionally).
* .
* .
*
* @addtogroup HAL
* @{
*/
#ifndef HAL_LLD_H
#define HAL_LLD_H
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name Platform identification macros
* @{
*/
#if defined(NUC123SD4AN0) || defined(__DOXYGEN__)
#define PLATFORM_NAME "NUC123SD4AN0 NUC123 Cortex M0 USB Micro"
#else
#error "NUC123 device unsupported or not specified"
#endif
/** @} */
/**
* @name Absolute Maximum Ratings
* @{
*/
/**
* @brief Maximum system clock frequency.
*/
#define NUC123_SYSCLK_MAX FREQ_72MHZ
/**
* @brief Maximum HSE clock frequency.
*/
#define NUC123_HSECLK_MAX 24000000
/**
* @brief Minimum HSE clock frequency.
*/
#define NUC123_HSECLK_MIN 4000000
/**
* @brief Maximum LSE clock frequency.
*/
#define NUC123_LSECLK_MAX 10000
/**
* @brief Minimum LSE clock frequency.
*/
#define NUC123_LSECLK_MIN 10000
/**
* @brief Maximum PLLs input clock frequency.
*/
#define NUC123_PLLIN_MAX 24000000
/**
* @brief Minimum PLLs input clock frequency.
*/
#define NUC123_PLLIN_MIN 4000000
/**
* @brief Maximum PLL output clock frequency.
*/
#define NUC123_PLLOUT_MAX FREQ_72MHZ
/**
* @brief Minimum PLL output clock frequency.
*/
#define NUC123_PLLOUT_MIN 4000000
/**
* @brief Maximum APB clock frequency.
*/
#define NUC123_PCLK_MAX FREQ_72MHZ
/** @} */
/**
* @name Internal clock sources
* @{
*/
#define NUC123_HSICLK __HIRC /**< High speed internal clock. */
#define NUC123_HSI_69CLK 691200 /**< ~0.69MHz High speed internal clock. */
#define NUC123_HSI1_38CLK 1382400 /**< ~1.375MHz High speed internal clock. */
#define NUC123_HSI2_76CLK 2764800 /**< ~2.75MHz High speed internal clock. */
#define NUC123_HSI5_5CLK 5529600 /**< ~5.5MHz speed internal clock.*/
#define NUC123_HSI11CLK 11059200 /**< ~11MHz speed internal clock.*/
#define NUC123_LSICLK __LIRC /**< Low speed internal clock. */
/** @} */
/**
* @name CLKSEL0 register bits definitions
* @{
*/
#define NUC123_HCLKSRC_HSE (0 << 0) /**< HCLK source is HSE */
#define NUC123_HCLKSRC_PLL_2 (1 << 0) /**< HCLK source is PLL/2 */
#define NUC123_HCLKSRC_PLL (2 << 0) /**< HCLK source is PLL */
#define NUC123_HCLKSRC_LSI (3 << 0) /**< HCLK source is LSI */
#define NUC123_HCLKSRC_HSI (7 << 0) /**< HCLK source is HSI */
#define NUC123_SW_HSE (0 << 3) /**< SYSCLK source is HSE. */
#define NUC123_SW_HSE_2 (1 << 3) /**< SYSCLK source is HSE/2. */
#define NUC123_SW_HCLK_2 (3 << 3) /**< SYSCLK source is HCLK/2. */
#define NUC123_SW_HSI_2 (7 << 3) /**< SYSCLK source is HSI. */
/** @} */
/**
* @name CLKSEL1 register bits definitions
* @{
*/
#define NUC123_WDTSRC_MASK (3 << 0) /**< WDT source mask */
#define NUC123_WDTSRC_HCLK_2048 (2 << 0) /**< WDT source is HCLK/2048 */
#define NUC123_WDTSRC_LSI (3 << 0) /**< WDT source is LSI */
#define NUC123_ADCSRC_MASK (3 << 2) /**< ADC source mask */
#define NUC123_ADCSRC_HSE (0 << 2) /**< ADC source is HSE */
#define NUC123_ADCSRC_PLL (1 << 2) /**< ADC source is PLL */
#define NUC123_ADCSRC_HCLK (2 << 2) /**< ADC source is HCLK */
#define NUC123_ADCSRC_HSI (3 << 2) /**< ADC source is HSI */
#define NUC123_SPI0SRC_MASK (1 << 4) /**< SPI0 source mask */
#define NUC123_SPI0SRC_PLL (0 << 4) /**< SPI0 source is PLL */
#define NUC123_SPI0SRC_HCLK (1 << 4) /**< SPI0 source is HCLK */
#define NUC123_SPI1SRC_MASK (1 << 5) /**< SPI1 source MASK */
#define NUC123_SPI1SRC_PLL (0 << 5) /**< SPI1 source is PLL */
#define NUC123_SPI1SRC_HCLK (1 << 5) /**< SPI1 source is HCLK */
#define NUC123_SPI2SRC_MASK (1 << 6) /**< SPI2 source mask */
#define NUC123_SPI2SRC_PLL (0 << 6) /**< SPI2 source is PLL */
#define NUC123_SPI2SRC_HCLK (1 << 6) /**< SPI2 source is HCLK */
#define NUC123_TMR0SRC_MASK (7 << 8) /**< TMR0 source mask */
#define NUC123_TMR0SRC_HSE (0 << 8) /**< TMR0 source is HSE */
#define NUC123_TMR0SRC_HCLK (2 << 8) /**< TMR0 source is HCLK */
#define NUC123_TMR0SRC_TM0 (3 << 8) /**< TMR0 source is TM0 pin */
#define NUC123_TMR0SRC_LSI (5 << 8) /**< TMR0 source is LSI */
#define NUC123_TMR0SRC_HSI (7 << 8) /**< TMR0 source is HSI */
#define NUC123_TMR1SRC_MASK (7 << 12) /**< TMR1 source mask */
#define NUC123_TMR1SRC_HSE (0 << 12) /**< TMR1 source is HSE */
#define NUC123_TMR1SRC_HCLK (2 << 12) /**< TMR1 source is HCLK */
#define NUC123_TMR1SRC_TM1 (3 << 12) /**< TMR1 source is TM1 pin */
#define NUC123_TMR1SRC_LSI (5 << 12) /**< TMR1 source is LSI */
#define NUC123_TMR1SRC_HSI (7 << 12) /**< TMR1 source is HSI */
#define NUC123_TMR2SRC_MASK (7 << 16) /**< TMR2 source mask */
#define NUC123_TMR2SRC_HSE (0 << 16) /**< TMR2 source is HSE */
#define NUC123_TMR2SRC_HCLK (2 << 16) /**< TMR2 source is HCLK */
#define NUC123_TMR2SRC_TM2 (3 << 16) /**< TMR2 source is TM2 pin */
#define NUC123_TMR2SRC_LSI (5 << 16) /**< TMR2 source is LSI */
#define NUC123_TMR2SRC_HSI (7 << 16) /**< TMR2 source is HSI */
#define NUC123_TMR3SRC_MASK (7 << 20) /**< TMR3 source mask */
#define NUC123_TMR3SRC_HSE (0 << 20) /**< TMR3 source is HSE */
#define NUC123_TMR3SRC_HCLK (2 << 20) /**< TMR3 source is HCLK */
#define NUC123_TMR3SRC_LSI (5 << 20) /**< TMR3 source is LSI */
#define NUC123_TMR3SRC_HSI (7 << 20) /**< TMR3 source is HSI */
#define NUC123_USARTSRC_MASK (3 << 24) /**< UART source mask. */
#define NUC123_USARTSRC_HS3 (0 << 24) /**< UART source is HSE. */
#define NUC123_USARTSRC_PLL (1 << 24) /**< UART source is PLL. */
#define NUC123_USARTSRC_HSI (3 << 24) /**< UART source is HSI. */
#define NUC123_PWM01SRCA_MASK (3 << 28) /**< PWM0/1 source [1:0] mask */
#define NUC123_PWM01SRCA_HSE (0 << 28) /**< PWM0/1 source [1:0] is HSE */
#define NUC123_PWM01SRCA_HCLK (2 << 28) /**< PWM0/1 source [1:0] is HCLK*/
#define NUC123_PWM01SRCA_HSI (3 << 28) /**< PWM0/1 source [1:0] is HSI */
#define NUC123_PWM01SRCA_LSI (3 << 28) /**< PWM0/1 source [1:0] is LSI */
#define NUC123_PWM23SRCA_MASK (3 << 30) /**< PWM2/3 source [1:0] mask */
#define NUC123_PWM23SRCA_HSE (0 << 30) /**< PWM2/3 source [1:0] is HSE */
#define NUC123_PWM23SRCA_HCLK (2 << 30) /**< PWM2/3 source [1:0] is HCLK*/
#define NUC123_PWM23SRCA_HSI (3 << 30) /**< PWM2/3 source [1:0] is HSI */
#define NUC123_PWM23SRCA_LSI (3 << 30) /**< PWM2/3 source [1:0] is LSI */
/** @} */
/**
* @name CLKSEL2 register bits definitions
* @{
*/
#define NUC123_I2SSRC_MASK (3 << 0) /**< I2S clock source mask. */
#define NUC123_I2SSRC_HSE (0 << 0) /**< I2S clock source is HSE. */
#define NUC123_I2SSRC_PLL (1 << 0) /**< I2S clock source is PLL. */
#define NUC123_I2SSRC_HCLK (2 << 0) /**< I2S clock source is HCLK. */
#define NUC123_I2SSRC_HSI (3 << 0) /**< I2S clock source is HSI. */
#define NUC123_FREQDIVSRC_MASK (3 << 2) /**< FRQDIV clock source mask */
#define NUC123_FREQDIVSRC_HSE (0 << 2) /**< FRQDIV clock source is HSE */
#define NUC123_FREQDIVSRC_HCLK (2 << 2) /**< FRQDIV clock source is HCLK*/
#define NUC123_FREQDIVSRC_HSI (3 << 2) /**< FRQDIV clock source is LSI */
#define NUC123_PWM01SRCB_MASK (1 << 8) /**< PWM0/1 source [2] mask */
#define NUC123_PWM01SRCB_HSI (0 << 8) /**< PWM0/1 source [2] is HSI */
#define NUC123_PWM01SRCB_LSI (1 << 8) /**< PWM0/1 source [2] is LSI */
#define NUC123_PWM23SRCB_MASK (1 << 9) /**< PWM2/3 source [2] mask */
#define NUC123_PWM23SRCB_HSI (0 << 9) /**< PWM2/3 source [2] is HSI */
#define NUC123_PWM23SRCB_LSI (1 << 9) /**< PWM2/3 source [2] is LSI */
#define NUC123_WWDTSRC_MASK (3 << 16) /**< WWDT source mask */
#define NUC123_WWDTSRC_HCLK_2048 (2 << 16) /**< WWDT source is HCLK/2048 */
#define NUC123_WWDTSRC_LSI (3 << 16) /**< WWDT source is LSI */
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief Disables the PWR/RCC initialization in the HAL.
*/
#if !defined(NUC123_NO_INIT) || defined(__DOXYGEN__)
#define NUC123_NO_INIT FALSE
#endif
/**
* @brief Enables or disables the HSI clock source.
*/
#if !defined(NUC123_HSI_ENABLED) || defined(__DOXYGEN__)
#define NUC123_HSI_ENABLED TRUE
#endif
/**
* @brief Enables or disables the LSI clock source.
*/
#if !defined(NUC123_LSI_ENABLED) || defined(__DOXYGEN__)
#define NUC123_LSI_ENABLED TRUE
#endif
/**
* @brief Enables or disables the HSE clock source.
*/
#if !defined(NUC123_HSE_ENABLED) || defined(__DOXYGEN__)
#define NUC123_HSE_ENABLED TRUE
#endif
/**
* @brief Enables or disables the LSE clock source.
*/
#if !defined(NUC123_LSE_ENABLED) || defined(__DOXYGEN__)
#define NUC123_LSE_ENABLED FALSE
#endif
/**
* @brief Main clock source selection.
* @note If the selected clock source is not the PLL then the PLL is not
* initialized and started.
* @note The default value is calculated for a 72MHz system clock from
* a 12MHz crystal using the PLL.
*/
#if !defined(NUC123_SW) || defined(__DOXYGEN__)
#define NUC123_SW NUC123_SW_HCLK_2
#endif
/**
* @brief Clock source for the PLL.
* @note This setting has only effect if the PLL is selected as the
* system clock source.
* @note The default value is calculated for a 72MHz system clock from
* a 12MHz crystal using the PLL.
*/
#if !defined(NUC123_PLLSRC) || defined(__DOXYGEN__)
#define NUC123_PLLSRC NUC123_PLLSRC_HSE
#endif
/**
* @brief Crystal PLL pre-divider.
* @note This setting has only effect if the PLL is selected as the
* system clock source.
* @note The default value is calculated for a 72MHz system clock from
* a 21MHz crystal using the PLL.
*/
#if !defined(NUC123_PREDIV_VALUE) || defined(__DOXYGEN__)
#define NUC123_PREDIV_VALUE 1
#endif
/**
* @brief PLL multiplier value.
* @note The allowed range is 2...16.
* @note The default value is calculated for a 72MHz system clock from
* a 12MHz crystal using the PLL.
*/
#if !defined(NUC123_PLLMUL_VALUE) || defined(__DOXYGEN__)
#define NUC123_PLLMUL_VALUE 6
#endif
/**
* @brief AHB prescaler value.
* @note The default value is calculated for a 72MHz system clock from
* a 12MHz crystal using the PLL.
*/
#if !defined(NUC123_HPRE) || defined(__DOXYGEN__)
#define NUC123_HPRE NUC123_HPRE_DIV1
#endif
/**
* @brief APB1 prescaler value.
*/
#if !defined(NUC123_PPRE) || defined(__DOXYGEN__)
#define NUC123_PPRE NUC123_PPRE_DIV1
#endif
/**
* @brief MCO pin setting.
*/
#if !defined(NUC123_MCOSEL) || defined(__DOXYGEN__)
#define NUC123_MCOSEL NUC123_MCOSEL_NOCLOCK
#endif
/**
* @brief MCO divider setting.
*/
#if !defined(NUC123_MCOPRE) || defined(__DOXYGEN__)
#define NUC123_MCOPRE NUC123_MCOPRE_DIV1
#endif
/**
* @brief MCO PLL divider setting.
*/
#if !defined(NUC123_PLLNODIV) || defined(__DOXYGEN__)
#define NUC123_PLLNODIV NUC123_PLLNODIV_DIV2
#endif
/**
* @brief USB Clock source.
*/
#if !defined(NUC123_USBSW) || defined(__DOXYGEN__)
#define NUC123_USBSW NUC123_USBSW_HSI48
#endif
/**
* @brief CEC clock source.
*/
#if !defined(NUC123_CECSW) || defined(__DOXYGEN__)
#define NUC123_CECSW NUC123_CECSW_HSI
#endif
/**
* @brief I2C1 clock source.
*/
#if !defined(NUC123_I2C1SW) || defined(__DOXYGEN__)
#define NUC123_I2C1SW NUC123_I2C1SW_HSI
#endif
/**
* @brief USART1 clock source.
*/
#if !defined(NUC123_USART1SW) || defined(__DOXYGEN__)
#define NUC123_USART1SW NUC123_USART1SW_PCLK
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*
* Configuration-related checks.
*/
#if !defined(NUC123SD4AN0_MCUCONF)
#error "Using a wrong mcuconf.h file, NUC123SD4AN0_MCUCONF not defined"
#endif
/*
* HSI related checks.
*/
#if NUC123_HSI_ENABLED
/*#if NUC123_SW == NUC123_SW_HSE
#error "HSI not enabled, required by NUC123_SW"
#endif
#if NUC123_CECSW == NUC123_CECSW_HSI
#error "HSI not enabled, required by NUC123_CECSW"
#endif
#if NUC123_I2C1SW == NUC123_I2C1SW_HSI
#error "HSI not enabled, required by NUC123_I2C1SW"
#endif
#if NUC123_USART1SW == NUC123_USART1SW_HSI
#error "HSI not enabled, required by NUC123_USART1SW"
#endif
#if (NUC123_SW == NUC123_SW_PLL) && \
(NUC123_PLLSRC == NUC123_PLLSRC_HSI_DIV2) || \
(NUC123_PLLSRC == NUC123_PLLSRC_HSI)
#error "HSI not enabled, required by NUC123_SW and NUC123_PLLSRC"
#endif
#if (NUC123_MCOSEL == NUC123_MCOSEL_HSI) || \
((NUC123_MCOSEL == NUC123_MCOSEL_PLLDIV2) && \
((NUC123_PLLSRC == NUC123_PLLSRC_HSI_DIV2) || \
(NUC123_PLLSRC == NUC123_PLLSRC_HSI)))
#error "HSI not enabled, required by NUC123_MCOSEL"
#endif
*/
#endif /* !NUC123_HSI_ENABLED */
/*
* HSE related checks.
*/
#if NUC123_HSE_ENABLED
#if NUC123_HSECLK == 0
#error "HSE frequency not defined"
#elif (NUC123_HSECLK < NUC123_HSECLK_MIN) || (NUC123_HSECLK > NUC123_HSECLK_MAX)
#error "NUC123_HSECLK outside acceptable range (NUC123_HSECLK_MIN...NUC123_HSECLK_MAX)"
#endif
#else /* !NUC123_HSE_ENABLED */
#if (NUC123_SW == NUC123_SW_HSE) || (NUC123_SW == NUC123_SW_HSE_2)
#error "HSE not enabled, required by NUC123_SW"
#endif
#if (NUC123_SW == NUC123_SW_HCL) && (NUC123_PLLSRC == NUC123_PLLSRC_HSE)
#error "HSE not enabled, required by NUC123_SW and NUC123_PLLSRC"
#endif
#if (NUC123_MCOSEL == NUC123_MCOSEL_HSE) || \
((NUC123_MCOSEL == NUC123_MCOSEL_PLLDIV2) && \
(NUC123_PLLSRC == NUC123_PLLSRC_HSE))
#error "HSE not enabled, required by NUC123_MCOSEL"
#endif
#endif /* !NUC123_HSE_ENABLED */
/*
* LSI related checks.
*/
#if NUC123_LSI_ENABLED
#else /* !NUC123_LSI_ENABLED */
#if NUC123_RTCSEL == NUC123_RTCSEL_LSI
#error "LSI not enabled, required by NUC123_RTCSEL"
#endif
#endif /* !NUC123_LSI_ENABLED */
/*
* LSE related checks.
*/
#if NUC123_LSE_ENABLED
#if (NUC123_LSECLK == 0)
#error "LSE frequency not defined"
#endif
#if (NUC123_LSECLK < NUC123_LSECLK_MIN) || (NUC123_LSECLK > NUC123_LSECLK_MAX)
#error "NUC123_LSECLK outside acceptable range (NUC123_LSECLK_MIN...NUC123_LSECLK_MAX)"
#endif
#if !defined(NUC123_LSEDRV)
#error "NUC123_LSEDRV not defined"
#endif
#if (NUC123_LSEDRV >> 3) > 3
#error "NUC123_LSEDRV outside acceptable range ((0<<3)...(3<<3))"
#endif
#else /* !NUC123_LSE_ENABLED */
#endif /* !NUC123_LSE_ENABLED */
/* PLL activation conditions.*/
#if (NUC123_SW == NUC123_SW_PLL) || \
(NUC123_USBSW == NUC123_USBSW_PCLK) || \
(NUC123_MCOSEL == NUC123_MCOSEL_PLLDIV2) || \
defined(__DOXYGEN__)
/**
* @brief PLL activation flag.
*/
#define NUC123_ACTIVATE_PLL TRUE
#else
#define NUC123_ACTIVATE_PLL FALSE
#endif
/* HSE, HSI prescaler setting check.*/
#if ((NUC123_PREDIV_VALUE >= 1) || (NUC123_PREDIV_VALUE <= 16))
#define NUC123_PREDIV ((NUC123_PREDIV_VALUE - 1) << 0)
#else
#error "invalid NUC123_PREDIV value specified"
#endif
/**
* @brief PLLMUL field.
*/
#if ((NUC123_PLLMUL_VALUE >= 2) && (NUC123_PLLMUL_VALUE <= 16)) || \
defined(__DOXYGEN__)
#define NUC123_PLLMUL ((NUC123_PLLMUL_VALUE - 2) << 18)
#else
#error "invalid NUC123_PLLMUL_VALUE value specified"
#endif
/**
* @brief PLL input clock frequency.
*/
#if (NUC123_PLLSRC == NUC123_PLLSRC_HSE) || defined(__DOXYGEN__)
#define NUC123_PLLCLKIN (NUC123_HSECLK / NUC123_PREDIV_VALUE)
#elif NUC123_PLLSRC == NUC123_PLLSRC_HSI_DIV2
#define NUC123_PLLCLKIN (NUC123_HSICLK / 2)
#elif NUC123_PLLSRC == NUC123_PLLSRC_HSI
#define NUC123_PLLCLKIN (NUC123_HSICLK / NUC123_PREDIV_VALUE)
#else
#error "invalid NUC123_PLLSRC value specified"
#endif
/* PLL input frequency range check.*/
#if (NUC123_PLLCLKIN < NUC123_PLLIN_MIN) || (NUC123_PLLCLKIN > NUC123_PLLIN_MAX)
#error "NUC123_PLLCLKIN outside acceptable range (NUC123_PLLIN_MIN...NUC123_PLLIN_MAX)"
#endif
/**
* @brief PLL output clock frequency.
*/
#define NUC123_PLLCLKOUT (NUC123_PLLCLKIN * NUC123_PLLMUL_VALUE)
/* PLL output frequency range check.
#if (NUC123_PLLCLKOUT < NUC123_PLLOUT_MIN) || (NUC123_PLLCLKOUT > NUC123_PLLOUT_MAX)
#error "NUC123_PLLCLKOUT outside acceptable range (NUC123_PLLOUT_MIN...NUC123_PLLOUT_MAX)"
#endif
*/
/**
* @brief System clock source.
*/
#if (NUC123_SW == NUC123_SW_HSE) || defined(__DOXYGEN__)
#define NUC123_SYSCLK NUC123_HSECLK
#elif (NUC123_SW == NUC123_SW_HSE_2)
#define NUC123_SYSCLK NUC123_HSECLK >> 1
#elif (NUC123_SW == NUC123_SW_HCLK_2)
#define NUC123_SYSCLK FREQ_72MHZ >> 1
#elif (NUC123_SW == NUC123_SW_HSI_2)
#define NUC123_SYSCLK NUC123_HSI11CLK
#else
#error "invalid NUC123_SW value specified"
#endif
/* Check on the system clock.*/
#if NUC123_SYSCLK > NUC123_SYSCLK_MAX
#error "NUC123_SYSCLK above maximum rated frequency (NUC123_SYSCLK_MAX)"
#endif
/**
* @brief AHB frequency.
*
#if (NUC123_HPRE == NUC123_HPRE_DIV1) || defined(__DOXYGEN__)
#define NUC123_HCLK (NUC123_SYSCLK / 1)
#elif NUC123_HPRE == NUC123_HPRE_DIV2
#define NUC123_HCLK (NUC123_SYSCLK / 2)
#elif NUC123_HPRE == NUC123_HPRE_DIV4
#define NUC123_HCLK (NUC123_SYSCLK / 4)
#elif NUC123_HPRE == NUC123_HPRE_DIV8
#define NUC123_HCLK (NUC123_SYSCLK / 8)
#elif NUC123_HPRE == NUC123_HPRE_DIV16
#define NUC123_HCLK (NUC123_SYSCLK / 16)
#elif NUC123_HPRE == NUC123_HPRE_DIV64
#define NUC123_HCLK (NUC123_SYSCLK / 64)
#elif NUC123_HPRE == NUC123_HPRE_DIV128
#define NUC123_HCLK (NUC123_SYSCLK / 128)
#elif NUC123_HPRE == NUC123_HPRE_DIV256
#define NUC123_HCLK (NUC123_SYSCLK / 256)
#elif NUC123_HPRE == NUC123_HPRE_DIV512
#define NUC123_HCLK (NUC123_SYSCLK / 512)
#else
#error "invalid NUC123_HPRE value specified"
#endif
*/
#define NUC123_HCLK (NUC123_SYSCLK / 1)
/* AHB frequency check.*/
#if NUC123_HCLK > NUC123_SYSCLK_MAX
#error "NUC123_HCLK exceeding maximum frequency (NUC123_SYSCLK_MAX)"
#endif
/**
* @brief APB frequency.
*/
#if (NUC123_PPRE == NUC123_PPRE_DIV1) || defined(__DOXYGEN__)
#define NUC123_PCLK (NUC123_HCLK / 1)
#elif NUC123_PPRE == NUC123_PPRE_DIV2
#define NUC123_PCLK (NUC123_HCLK / 2)
#elif NUC123_PPRE == NUC123_PPRE_DIV4
#define NUC123_PCLK (NUC123_HCLK / 4)
#elif NUC123_PPRE == NUC123_PPRE_DIV8
#define NUC123_PCLK (NUC123_HCLK / 8)
#elif NUC123_PPRE == NUC123_PPRE_DIV16
#define NUC123_PCLK (NUC123_HCLK / 16)
#else
#error "invalid NUC123_PPRE value specified"
#endif
/* APB frequency check.*/
#if NUC123_PCLK > NUC123_PCLK_MAX
#error "NUC123_PCLK exceeding maximum frequency (NUC123_PCLK_MAX)"
#endif
/* NUC123_PLLNODIV check.*/
#if (NUC123_PLLNODIV != NUC123_PLLNODIV_DIV2) && \
(NUC123_PLLNODIV != NUC123_PLLNODIV_DIV1)
#error "invalid NUC123_PLLNODIV value specified"
#endif
/**
* @brief MCO clock before divider.
*/
// #if (NUC123_MCOSEL == NUC123_MCOSEL_NOCLOCK) || defined(__DOXYGEN__)
// #define NUC123_MCODIVCLK 0
// #elif NUC123_MCOSEL == NUC123_MCOSEL_HSI14
// #define NUC123_MCODIVCLK NUC123_HSI14CLK
// #elif NUC123_MCOSEL == NUC123_MCOSEL_LSI
// #define NUC123_MCODIVCLK NUC123_LSICLK
// #elif NUC123_MCOSEL == NUC123_MCOSEL_LSE
// #define NUC123_MCODIVCLK NUC123_LSECLK
// #elif NUC123_MCOSEL == NUC123_MCOSEL_SYSCLK
// #define NUC123_MCODIVCLK NUC123_SYSCLK
// #elif NUC123_MCOSEL == NUC123_MCOSEL_HSI
// #define NUC123_MCODIVCLK NUC123_HSICLK
// #elif NUC123_MCOSEL == NUC123_MCOSEL_HSE
// #define NUC123_MCODIVCLK NUC123_HSECLK
// #elif NUC123_MCOSEL == NUC123_MCOSEL_PLLDIV2
// #if NUC123_PLLNODIV == NUC123_PLLNODIV_DIV2
// #define NUC123_MCODIVCLK (NUC123_PLLCLKOUT / 2)
// #else
// #define NUC123_MCODIVCLK (NUC123_PLLCLKOUT / 1)
// #endif
// #elif NUC123_MCOSEL == NUC123_MCOSEL_HSI48
// #define NUC123_MCODIVCLK NUC123_HSI48CLK
// #else
// #error "invalid NUC123_MCOSEL value specified"
// #endif
/**
* @brief MCO output pin clock.
*/
// #if (NUC123_MCOPRE == NUC123_MCOPRE_DIV1) || defined(__DOXYGEN__)
// #define NUC123_MCOCLK NUC123_MCODIVCLK
// #elif (NUC123_MCOPRE == NUC123_MCOPRE_DIV2) && NUC123_HAS_MCO_PREDIV
// #define NUC123_MCOCLK (NUC123_MCODIVCLK / 2)
// #elif (NUC123_MCOPRE == NUC123_MCOPRE_DIV4) && NUC123_HAS_MCO_PREDIV
// #define NUC123_MCOCLK (NUC123_MCODIVCLK / 4)
// #elif (NUC123_MCOPRE == NUC123_MCOPRE_DIV8) && NUC123_HAS_MCO_PREDIV
// #define NUC123_MCOCLK (NUC123_MCODIVCLK / 8)
// #elif (NUC123_MCOPRE == NUC123_MCOPRE_DIV16) && NUC123_HAS_MCO_PREDIV
// #define NUC123_MCOCLK (NUC123_MCODIVCLK / 16)
// #elif !NUC123_HAS_MCO_PREDIV
// #error "MCO_PREDIV not available on this platform. Select NUC123_MCODIVCLK."
// #else
// #error "invalid NUC123_MCOPRE value specified"
// #endif
/**
* @brief USB frequency.
*/
// #if (NUC123_USBSW == NUC123_USBSW_HSI48) || defined(__DOXYGEN__)
// #define NUC123_USBCLK NUC123_HSI48CLK
// #elif NUC123_USBSW == NUC123_USBSW_PCLK
// #define NUC123_USBCLK NUC123_PLLCLKOUT
// #else
// #error "invalid source selected for USB clock"
// #endif
/**
* @brief CEC frequency.
*/
#if (NUC123_CECSW == NUC123_CECSW_HSI) || defined(__DOXYGEN__)
#define NUC123_CECCLK NUC123_HSICLK
#elif NUC123_CECSW == NUC123_CECSW_LSE
#define NUC123_CECCLK NUC123_LSECLK
#elif NUC123_CECSW == NUC123_CECSW_OFF
#define NUC123_CECCLK 0
#else
#error "invalid source selected for CEC clock"
#endif
/**
* @brief I2C1 frequency.
*/
#if (NUC123_I2C1SW == NUC123_I2C1SW_HSI) || defined(__DOXYGEN__)
#define NUC123_I2C1CLK NUC123_HSICLK
#elif NUC123_I2C1SW == NUC123_I2C1SW_SYSCLK
#define NUC123_I2C1CLK NUC123_SYSCLK
#else
#error "invalid source selected for I2C1 clock"
#endif
/**
* @brief USART1 frequency.
*/
#if (NUC123_USART1SW == NUC123_USART1SW_PCLK) || defined(__DOXYGEN__)
#define NUC123_USART1CLK NUC123_PCLK
#elif NUC123_USART1SW == NUC123_USART1SW_SYSCLK
#define NUC123_USART1CLK NUC123_SYSCLK
#elif NUC123_USART1SW == NUC123_USART1SW_LSE
#define NUC123_USART1CLK NUC123_LSECLK
#elif NUC123_USART1SW == NUC123_USART1SW_HSI
#define NUC123_USART1CLK NUC123_HSICLK
#else
#error "invalid source selected for USART1 clock"
#endif
/**
* @brief USART2 frequency.
*/
#define NUC123_USART2CLK NUC123_PCLK
/**
* @brief USART3 frequency.
*/
#define NUC123_USART3CLK NUC123_PCLK
/**
* @brief USART4 frequency.
*/
#define NUC123_UART4CLK NUC123_PCLK
/**
* @brief USART5 frequency.
*/
#define NUC123_UART5CLK NUC123_PCLK
/**
* @brief USART6 frequency.
*/
#define NUC123_USART6CLK NUC123_PCLK
/**
* @brief Timers clock.
*/
#if (NUC123_PPRE == NUC123_PPRE_DIV1) || defined(__DOXYGEN__)
#define NUC123_TIMCLK1 (NUC123_PCLK * 1)
#define NUC123_TIMCLK2 (NUC123_PCLK * 1)
#else
#define NUC123_TIMCLK1 (NUC123_PCLK * 2)
#define NUC123_TIMCLK2 (NUC123_PCLK * 2)
#endif
/**
* @brief Flash settings.
*/
#if (NUC123_HCLK <= 24000000) || defined(__DOXYGEN__)
#define NUC123_FLASHBITS 0x00000010
#else
#define NUC123_FLASHBITS 0x00000011
#endif
/*
* For compatibility with driver assuming a specific PPRE clock.
*/
#define NUC123_PCLK1 NUC123_PCLK
#define NUC123_PCLK2 NUC123_PCLK
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
/* Various helpers.*/
#include "nvic.h"
#include "nuc123_isr.h"
//#include "nuc123_dma.h"
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
void NUC123_clock_init(void);
#ifdef __cplusplus
}
#endif
#endif /* HAL_LLD_H */
/** @} */

View File

@ -0,0 +1,152 @@
/*
Copyright (C) 2019 /u/KeepItUnder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file NUMICRO/nuc123_isr.h
* @brief ISR remapper driver header.
*
* @addtogroup NUC123SD4AN0_ISR
* @{
*/
#ifndef NUC123_ISR_H
#define NUC123_ISR_H
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name ISR names and numbers remapping
* @{
*/
/*
* GPIO units.
*/
#if defined(NUC123SD4AN0)
#define NUC123_GPIOAB_HANDLER Vector50
#define NUC123_GPIOCDF_HANDLER Vector54
#define NUC123_GPIOAB_NUMBER GPAB_IRQn
#define NUC123_GPIOCDF_NUMBER GPCDF_IRQn
#endif
/*
* Special ST unit
*/
#define NUC123_ST_HANDLER Vector3C
#define NUC123_ST_NUMBER SysTick_IRQn
/*
* DMA units.
*/
#define NUC123_PDMA_HANDLER VectorA8
#define NUC123_PDMA_NUMBER PDMA_IRQn
/*
* ADC units.
*/
#define NUC123_ADC_HANDLER VectorB0
#define NUC123_ADC_NUMBER ADC_IRQn
/*
* PWM units.
*/
#define NUC123_PWMA_HANDLER Vector58
#define NUC123_PWMA_NUMBER PWMA_IRQn
/*
* SPI units.
*/
#define NUC123_SPI0_HANDLER Vector78
#define NUC123_SPI1_HANDLER Vector7C
#define NUC123_SPI2_HANDLER Vector80
#define NUC123_SPI0_NUMBER SPI0_IRQn
#define NUC123_SPI1_NUMBER SPI1_IRQn
#define NUC123_SPI2_NUMBER SPI2_IRQn
/*
* I2S units.
*/
#define NUC123_I2C1_HANDLER VectorB8
#define NUC123_I2C1_NUMBER I2S_IRQn
/*
* I2C units.
*/
#define NUC123_I2C1_GLOBAL_HANDLER Vector88
#define NUC123_I2C1_GLOBAL_NUMBER I2C0_IRQn
#define NUC123_I2C2_GLOBAL_HANDLER Vector8C
#define NUC123_I2C2_GLOBAL_NUMBER I2C1_IRQn
/*
* TIM units.
*/
#define NUC123_TIM1_HANDLER Vector60
#define NUC123_TIM2_HANDLER Vector64
#define NUC123_TIM3_HANDLER Vector68
#define NUC123_TIM4_HANDLER Vector6C
#define NUC123_TIM1_NUMBER TMR0_IRQn
#define NUC123_TIM2_NUMBER TMR1_IRQn
#define NUC123_TIM3_NUMBER TMR2_IRQn
#define NUC123_TIM4_NUMBER TMR3_IRQn
/*
* USART units.
*/
#define NUC123_USART1_HANDLER Vector70
#define NUC123_USART2_HANDLER Vector74
#define NUC123_USART1_NUMBER UART0_IRQn
#define NUC123_USART2_NUMBER UART1_IRQn
/*
* USB units.
*/
#define NUC123_USB1_HANDLER Vector9C
#define NUC123_USB1_NUMBER USBD_IRQn
#define USBD_INTSTS_EPEVT_Pos USBD_INTSTS_EPEVT0_Pos
#define USBD_INTSTS_EPEVT_Msk (0xFFul << USBD_INTSTS_EPEVT_Pos)
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#endif /* NUC123_ISR_H */
/** @} */

View File

@ -0,0 +1,263 @@
/*
Copyright (C) 2019 /u/KeepItUnder
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file NUC123SD4AN0/nuc123_registry.h
* @brief NUC123SD4AN0 capabilities registry.
*
* @addtogroup HAL
* @{
*/
#ifndef NUC123_REGISTRY_H
#define NUC123_REGISTRY_H
#if !defined(NUC123SD4AN0) || defined(__DOXYGEN__)
#define NUC123SD4AN0
#endif
/*===========================================================================*/
/* Platform capabilities. */
/*===========================================================================*/
/**
* @name NUC123SD4AN0 capabilities
* @{
*/
/* RCC attributes. */
#define NUC123_HAS_HSI48 FALSE
#define NUC123_HAS_HSI_PREDIV FALSE
#define NUC123_HAS_MCO_PREDIV TRUE
/* ADC attributes.*/
#define NUC123_HAS_ADC1 TRUE
#define NUC123_ADC_SUPPORTS_PRESCALER FALSE
#define NUC123_ADC_SUPPORTS_OVERSAMPLING FALSE
#define NUC123_ADC1_IRQ_SHARED_WITH_EXTI FALSE
#define NUC123_ADC1_HANDLER Vector70
#define NUC123_ADC1_NUMBER Vector70_IRQn
#define NUC123_ADC1_DMA_MSK (NUC123_DMA_STREAM_ID_MSK(1, 1) |\
NUC123_DMA_STREAM_ID_MSK(1, 2))
#define NUC123_ADC1_DMA_CHN 0x00000011
#define NUC123_HAS_ADC2 FALSE
#define NUC123_HAS_ADC3 FALSE
#define NUC123_HAS_ADC4 FALSE
/* CAN attributes.*/
#define NUC123_HAS_CAN1 FALSE
#define NUC123_HAS_CAN2 FALSE
#define NUC123_HAS_CAN3 FALSE
/* DAC attributes.*/
#define NUC123_HAS_DAC1_CH1 FALSE
#define NUC123_HAS_DAC1_CH2 FALSE
#define NUC123_HAS_DAC2_CH1 FALSE
#define NUC123_HAS_DAC2_CH2 FALSE
/* DMA attributes.*/
#define NUC123_ADVANCED_DMA FALSE
#define NUC123_DMA_SUPPORTS_CSELR FALSE
#define NUC123_DMA1_NUM_CHANNELS 6
#define NUC123_DMA2_NUM_CHANNELS 0
#define NUC123_DMA1_CH1_HANDLER Vector64
#define NUC123_DMA1_CH23_HANDLER Vector68
#define NUC123_DMA1_CH4567_HANDLER Vector6C
#define NUC123_DMA1_CH1_NUMBER Vector64_IRQn
#define NUC123_DMA1_CH23_NUMBER Vector68_IRQn
#define NUC123_DMA1_CH4567_NUMBER Vector6C_IRQn
#define NUC123_DMA1_CH2_NUMBER NUC123_DMA1_CH23_NUMBER
#define NUC123_DMA1_CH3_NUMBER NUC123_DMA1_CH23_NUMBER
#define DMA1_CH2_CMASK 0x00000006U
#define DMA1_CH3_CMASK 0x00000006U
#define NUC123_DMA1_CH4_NUMBER NUC123_DMA1_CH4567_NUMBER
#define NUC123_DMA1_CH5_NUMBER NUC123_DMA1_CH4567_NUMBER
#define NUC123_DMA1_CH6_NUMBER NUC123_DMA1_CH4567_NUMBER
#define NUC123_DMA1_CH7_NUMBER NUC123_DMA1_CH4567_NUMBER
#define DMA1_CH4_CMASK 0x00000078U
#define DMA1_CH5_CMASK 0x00000078U
#define DMA1_CH6_CMASK 0x00000078U
#define DMA1_CH7_CMASK 0x00000078U
/* ETH attributes.*/
#define NUC123_HAS_ETH FALSE
/* EXTI attributes.*/
//#define NUC123_EXTI_NUM_LINES 20
//#define NUC123_EXTI_IMR_MASK 0xFFF50000U
/* GPIO attributes.*/
#define NUC123_HAS_GPIOA TRUE
#define NUC123_HAS_GPIOB TRUE
#define NUC123_HAS_GPIOC TRUE
#define NUC123_HAS_GPIOD TRUE
#define NUC123_HAS_GPIOE FALSE
#define NUC123_HAS_GPIOF TRUE
#define NUC123_HAS_GPIOG FALSE
#define NUC123_HAS_GPIOH FALSE
#define NUC123_HAS_GPIOI FALSE
#define NUC123_HAS_GPIOJ FALSE
#define NUC123_HAS_GPIOK FALSE
/* I2C attributes.*/
#define NUC123_HAS_I2C1 TRUE
#define NUC123_I2C1_RX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 3)
#define NUC123_I2C1_RX_DMA_CHN 0x00000200
#define NUC123_I2C1_TX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 2)
#define NUC123_I2C1_TX_DMA_CHN 0x00000020
#define NUC123_HAS_I2C2 TRUE
#define NUC123_I2C2_RX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 5)
#define NUC123_I2C2_RX_DMA_CHN 0x00020000
#define NUC123_I2C2_TX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 4)
#define NUC123_I2C2_TX_DMA_CHN 0x00002000
#define NUC123_HAS_I2C3 FALSE
#define NUC123_HAS_I2C4 FALSE
/* QUADSPI attributes.*/
#define NUC123_HAS_QUADSPI1 FALSE
/* RTC attributes.*/
#define NUC123_HAS_RTC FALSE
#define NUC123_RTC_HAS_SUBSECONDS FALSE
#define NUC123_RTC_HAS_PERIODIC_WAKEUPS FALSE
#define NUC123_RTC_NUM_ALARMS 0
#define NUC123_RTC_HAS_INTERRUPTS FALSE
/* SDIO attributes.*/
#define NUC123_HAS_SDIO FALSE
/* SPI attributes.*/
#define NUC123_HAS_SPI1 TRUE
#define NUC123_SPI1_SUPPORTS_I2S FALSE
#define NUC123_SPI1_RX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 2)
#define NUC123_SPI1_RX_DMA_CHN 0x00000030
#define NUC123_SPI1_TX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 3)
#define NUC123_SPI1_TX_DMA_CHN 0x00000300
#define NUC123_HAS_SPI2 TRUE
#define NUC123_SPI2_SUPPORTS_I2S FALSE
#define NUC123_SPI2_RX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 4)
#define NUC123_SPI2_RX_DMA_CHN 0x00003000
#define NUC123_SPI2_TX_DMA_MSK NUC123_DMA_STREAM_ID_MSK(1, 5)
#define NUC123_SPI2_TX_DMA_CHN 0x00030000
#define NUC123_HAS_SPI3 FALSE
#define NUC123_HAS_SPI4 FALSE
#define NUC123_HAS_SPI5 FALSE
#define NUC123_HAS_SPI6 FALSE
/* TIM attributes.*/
#define NUC123_TIM_MAX_CHANNELS 4
#define NUC123_HAS_TIM1 TRUE
#define NUC123_TIM1_IS_32BITS TRUE
#define NUC123_TIM1_CHANNELS 1
#define NUC123_HAS_TIM2 TRUE
#define NUC123_TIM2_IS_32BITS TRUE
#define NUC123_TIM2_CHANNELS 1
#define NUC123_HAS_TIM3 TRUE
#define NUC123_TIM3_IS_32BITS TRUE
#define NUC123_TIM3_CHANNELS 1
#define NUC123_HAS_TIM4 TRUE
#define NUC123_TIM14_IS_32BITS TRUE
#define NUC123_TIM14_CHANNELS 1
#define NUC123_HAS_TIM5 FALSE
#define NUC123_HAS_TIM6 FALSE
#define NUC123_HAS_TIM7 FALSE
#define NUC123_HAS_TIM8 FALSE
#define NUC123_HAS_TIM9 FALSE
#define NUC123_HAS_TIM10 FALSE
#define NUC123_HAS_TIM11 FALSE
#define NUC123_HAS_TIM12 FALSE
#define NUC123_HAS_TIM13 FALSE
#define NUC123_HAS_TIM14 FALSE
#define NUC123_HAS_TIM15 FALSE
#define NUC123_HAS_TIM16 FALSE
#define NUC123_HAS_TIM17 FALSE
#define NUC123_HAS_TIM18 FALSE
#define NUC123_HAS_TIM19 FALSE
#define NUC123_HAS_TIM20 FALSE
#define NUC123_HAS_TIM21 FALSE
#define NUC123_HAS_TIM22 FALSE
/* USART attributes.*/
/*#define NUC123_HAS_USART1 TRUE
#define NUC123_USART1_RX_DMA_MSK (NUC123_DMA_STREAM_ID_MSK(1, 1) |\
NUC123_DMA_STREAM_ID_MSK(1, 3) |\
NUC123_DMA_STREAM_ID_MSK(1, 5))
#define NUC123_USART1_RX_DMA_CHN 0x00080808
#define NUC123_USART1_TX_DMA_MSK (NUC123_DMA_STREAM_ID_MSK(1, 2) |\
NUC123_DMA_STREAM_ID_MSK(1, 4))
#define NUC123_USART1_TX_DMA_CHN 0x00008080
#define NUC123_HAS_USART2 TRUE
#define NUC123_USART2_RX_DMA_MSK (NUC123_DMA_STREAM_ID_MSK(1, 1) |\
NUC123_DMA_STREAM_ID_MSK(1, 3) |\
NUC123_DMA_STREAM_ID_MSK(1, 5))
#define NUC123_USART2_RX_DMA_CHN 0x00090909
#define NUC123_USART2_TX_DMA_MSK (NUC123_DMA_STREAM_ID_MSK(1, 2) |\
NUC123_DMA_STREAM_ID_MSK(1, 4))
#define NUC123_USART2_TX_DMA_CHN 0x00009090
*/
#define NUC123_HAS_USART1 FALSE
#define NUC123_HAS_USART2 FALSE
#define NUC123_HAS_USART3 FALSE
#define NUC123_HAS_UART4 FALSE
#define NUC123_HAS_UART5 FALSE
#define NUC123_HAS_USART6 FALSE
#define NUC123_HAS_UART7 FALSE
#define NUC123_HAS_UART8 FALSE
#define NUC123_HAS_LPUART1 FALSE
/* USB attributes.*/
#define NUC123_HAS_USB TRUE
#define NUC123_HAS_OTG1 FALSE
#define NUC123_HAS_OTG2 FALSE
/* IWDG attributes.*/
#define NUC123_HAS_IWDG TRUE
#define NUC123_IWDG_IS_WINDOWED TRUE
/* LTDC attributes.*/
#define NUC123_HAS_LTDC FALSE
/* DMA2D attributes.*/
#define NUC123_HAS_DMA2D FALSE
/* FSMC attributes.*/
#define NUC123_HAS_FSMC FALSE
/* CRC attributes.*/
#define NUC123_HAS_CRC TRUE
#define NUC123_CRC_PROGRAMMABLE FALSE
#else
#error "NUC123SD4AN0 device not specified"
/** @} */
#endif /* NUC123_REGISTRY_H */
/** @} */

View File

@ -0,0 +1,22 @@
# Required platform files.
PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
$(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/NUC123SD4AN0/hal_lld.c \
$(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/NUC123SD4AN0/system_NUC123.c
# Required include directories.
PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
$(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/NUC123SD4AN0 \
$(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD
# Optional platform files.
ifeq ($(USE_SMART_BUILD),yes)
HALCONF := $(strip $(shell cat halconf.h | egrep -e "\#define"))
endif
# Drivers compatible with the platform.
include $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/CLKv1/driver.mk
include $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/GPIOv1/driver.mk
include $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/TIMv1/driver.mk
include $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/PWMv1/driver.mk
include $(CHIBIOS_CONTRIB)/os/hal/ports/NUMICRO/LLD/USBv1/driver.mk

View File

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