[NANO] Alpha support

pull/4631/head
MS30 CCChang12 2017-04-13 11:32:51 +08:00
parent cc58a7fb0c
commit 99290462f6
79 changed files with 28823 additions and 1 deletions

View File

@ -768,7 +768,7 @@ extern "C" int errno;
register unsigned char * stack_ptr __asm ("sp");
// Dynamic memory allocation related syscall.
#if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M453)
#if defined(TARGET_NUVOTON)
// Overwrite _sbrk() to support two region model (heap and stack are two distinct regions).
// __wrap__sbrk() is implemented in:
// TARGET_NUMAKER_PFM_NUC472 hal/targets/cmsis/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/TOOLCHAIN_GCC_ARM/retarget.c

View File

@ -0,0 +1,123 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#ifndef MBED_PERIPHERALNAMES_H
#define MBED_PERIPHERALNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
// NOTE: Check all module base addresses (XXX_BASE in BSP) for free bit fields to define module name
// which encodes module base address and module index/subindex.
#define NU_MODSUBINDEX_Pos 0
#define NU_MODSUBINDEX_Msk (0x1Ful << NU_MODSUBINDEX_Pos)
#define NU_MODINDEX_Pos 20
#define NU_MODINDEX_Msk (0xFul << NU_MODINDEX_Pos)
#define NU_MODNAME(MODBASE, INDEX, SUBINDEX) ((MODBASE) | ((INDEX) << NU_MODINDEX_Pos) | ((SUBINDEX) << NU_MODSUBINDEX_Pos))
#define NU_MODBASE(MODNAME) ((MODNAME) & ~(NU_MODINDEX_Msk | NU_MODSUBINDEX_Msk))
#define NU_MODINDEX(MODNAME) (((MODNAME) & NU_MODINDEX_Msk) >> NU_MODINDEX_Pos)
#define NU_MODSUBINDEX(MODNAME) (((MODNAME) & NU_MODSUBINDEX_Msk) >> NU_MODSUBINDEX_Pos)
#if 0
typedef enum {
GPIO_A = (int) NU_MODNAME(GPIOA_BASE, 0, 0),
GPIO_B = (int) NU_MODNAME(GPIOB_BASE, 1, 0),
GPIO_C = (int) NU_MODNAME(GPIOC_BASE, 2, 0),
GPIO_D = (int) NU_MODNAME(GPIOD_BASE, 3, 0),
GPIO_E = (int) NU_MODNAME(GPIOE_BASE, 4, 0),
GPIO_F = (int) NU_MODNAME(GPIOF_BASE, 5, 0)
} GPIOName;
#endif
typedef enum {
ADC_0_0 = (int) NU_MODNAME(ADC_BASE, 0, 0),
ADC_0_1 = (int) NU_MODNAME(ADC_BASE, 0, 1),
ADC_0_2 = (int) NU_MODNAME(ADC_BASE, 0, 2),
ADC_0_3 = (int) NU_MODNAME(ADC_BASE, 0, 3),
ADC_0_4 = (int) NU_MODNAME(ADC_BASE, 0, 4),
ADC_0_5 = (int) NU_MODNAME(ADC_BASE, 0, 5),
ADC_0_6 = (int) NU_MODNAME(ADC_BASE, 0, 6),
ADC_0_7 = (int) NU_MODNAME(ADC_BASE, 0, 7),
ADC_0_8 = (int) NU_MODNAME(ADC_BASE, 0, 8),
ADC_0_9 = (int) NU_MODNAME(ADC_BASE, 0, 9),
ADC_0_10 = (int) NU_MODNAME(ADC_BASE, 0, 10),
ADC_0_11 = (int) NU_MODNAME(ADC_BASE, 0, 11),
} ADCName;
typedef enum {
UART_0 = (int) NU_MODNAME(UART0_BASE, 0, 0),
UART_1 = (int) NU_MODNAME(UART1_BASE, 1, 0),
// FIXME: board-specific
STDIO_UART = UART_0
} UARTName;
typedef enum {
SPI_0 = (int) NU_MODNAME(SPI0_BASE, 0, 0),
SPI_1 = (int) NU_MODNAME(SPI1_BASE, 1, 0),
SPI_2 = (int) NU_MODNAME(SPI2_BASE, 2, 0)
} SPIName;
typedef enum {
I2C_0 = (int) NU_MODNAME(I2C0_BASE, 0, 0),
I2C_1 = (int) NU_MODNAME(I2C1_BASE, 1, 0)
} I2CName;
typedef enum {
PWM_0_0 = (int) NU_MODNAME(PWM0_BASE, 0, 0),
PWM_0_1 = (int) NU_MODNAME(PWM0_BASE, 0, 1),
PWM_0_2 = (int) NU_MODNAME(PWM0_BASE, 0, 2),
PWM_0_3 = (int) NU_MODNAME(PWM0_BASE, 0, 3),
PWM_1_0 = (int) NU_MODNAME(PWM1_BASE, 1, 0),
PWM_1_1 = (int) NU_MODNAME(PWM1_BASE, 1, 1),
PWM_1_2 = (int) NU_MODNAME(PWM1_BASE, 1, 2),
PWM_1_3 = (int) NU_MODNAME(PWM1_BASE, 1, 3),
} PWMName;
typedef enum {
TIMER_0 = (int) NU_MODNAME(TIMER0_BASE, 0, 0),
TIMER_1 = (int) NU_MODNAME(TIMER1_BASE, 0, 0),
TIMER_2 = (int) NU_MODNAME(TIMER2_BASE, 0, 0),
TIMER_3 = (int) NU_MODNAME(TIMER3_BASE, 0, 0),
} TIMERName;
typedef enum {
RTC_0 = (int) NU_MODNAME(RTC_BASE, 0, 0)
} RTCName;
typedef enum {
DMA_0 = (int) NU_MODNAME(VDMA_BASE, 0, 0),
DMA_1 = (int) NU_MODNAME(PDMA1_BASE, 0, 0),
DMA_2 = (int) NU_MODNAME(PDMA2_BASE, 0, 0),
DMA_3 = (int) NU_MODNAME(PDMA3_BASE, 0, 0),
DMA_4 = (int) NU_MODNAME(PDMA4_BASE, 0, 0),
DMA_5 = (int) NU_MODNAME(PDMA5_BASE, 0, 0),
DMA_6 = (int) NU_MODNAME(PDMA6_BASE, 0, 0),
} DMAName;
typedef enum {
I2S_0 = (int) NU_MODNAME(I2S_BASE, 0, 0),
} I2SName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,305 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#include "PeripheralPins.h"
// =====
// Note: Commented lines are alternative possibilities which are not used per default.
// If you change them, you will have also to modify the corresponding xxx_api.c file
// for pwmout, analogin, analogout, ...
// =====
#if 0
//*** GPIO ***
const PinMap PinMap_GPIO[] = {
// GPIO A MFPL
{PA_0, GPIO_A, SYS_GPA_MFPL_PA0MFP_GPIO},
{PA_1, GPIO_A, SYS_GPA_MFPL_PA1MFP_GPIO},
{PA_2, GPIO_A, SYS_GPA_MFPL_PA2MFP_GPIO},
{PA_3, GPIO_A, SYS_GPA_MFPL_PA3MFP_GPIO},
{PA_4, GPIO_A, SYS_GPA_MFPL_PA4MFP_GPIO},
{PA_5, GPIO_A, SYS_GPA_MFPL_PA5MFP_GPIO},
{PA_6, GPIO_A, SYS_GPA_MFPL_PA6MFP_GPIO},
{PA_7, GPIO_A, SYS_GPA_MFPL_PA7MFP_GPIO},
// GPIO A MFPH
{PA_8, GPIO_A, SYS_GPA_MFPH_PA8MFP_GPIO},
{PA_9, GPIO_A, SYS_GPA_MFPH_PA9MFP_GPIO},
{PA_10, GPIO_A, SYS_GPA_MFPH_PA10MFP_GPIO},
{PA_11, GPIO_A, SYS_GPA_MFPH_PA11MFP_GPIO},
{PA_12, GPIO_A, SYS_GPA_MFPH_PA12MFP_GPIO},
{PA_13, GPIO_A, SYS_GPA_MFPH_PA13MFP_GPIO},
{PA_14, GPIO_A, SYS_GPA_MFPH_PA14MFP_GPIO},
{PA_15, GPIO_A, SYS_GPA_MFPH_PA15MFP_GPIO},
// GPIO B MFPL
{PB_0, GPIO_B, SYS_GPB_MFPL_PB0MFP_GPIO},
{PB_1, GPIO_B, SYS_GPB_MFPL_PB1MFP_GPIO},
{PB_2, GPIO_B, SYS_GPB_MFPL_PB2MFP_GPIO},
{PB_3, GPIO_B, SYS_GPB_MFPL_PB3MFP_GPIO},
{PB_4, GPIO_B, SYS_GPB_MFPL_PB4MFP_GPIO},
{PB_5, GPIO_B, SYS_GPB_MFPL_PB5MFP_GPIO},
{PB_6, GPIO_B, SYS_GPB_MFPL_PB6MFP_GPIO},
{PB_7, GPIO_B, SYS_GPB_MFPL_PB7MFP_GPIO},
// GPIO B MFPH
{PB_8, GPIO_B, SYS_GPB_MFPH_PB8MFP_GPIO},
{PB_9, GPIO_B, SYS_GPB_MFPH_PB9MFP_GPIO},
{PB_10, GPIO_B, SYS_GPB_MFPH_PB10MFP_GPIO},
{PB_11, GPIO_B, SYS_GPB_MFPH_PB11MFP_GPIO},
{PB_12, GPIO_B, SYS_GPB_MFPH_PB12MFP_GPIO},
{PB_13, GPIO_B, SYS_GPB_MFPH_PB13MFP_GPIO},
{PB_14, GPIO_B, SYS_GPB_MFPH_PB14MFP_GPIO},
{PB_15, GPIO_B, SYS_GPB_MFPH_PB15MFP_GPIO},
// GPIO C MFPL
{PC_0, GPIO_C, SYS_GPC_MFPL_PC0MFP_GPIO},
{PC_1, GPIO_C, SYS_GPC_MFPL_PC1MFP_GPIO},
{PC_2, GPIO_C, SYS_GPC_MFPL_PC2MFP_GPIO},
{PC_3, GPIO_C, SYS_GPC_MFPL_PC3MFP_GPIO},
{PC_4, GPIO_C, SYS_GPC_MFPL_PC4MFP_GPIO},
{PC_5, GPIO_C, SYS_GPC_MFPL_PC5MFP_GPIO},
{PC_6, GPIO_C, SYS_GPC_MFPL_PC6MFP_GPIO},
{PC_7, GPIO_C, SYS_GPC_MFPL_PC7MFP_GPIO},
// GPIO C MFPH
{PC_8, GPIO_C, SYS_GPC_MFPH_PC8MFP_GPIO},
{PC_9, GPIO_C, SYS_GPC_MFPH_PC9MFP_GPIO},
{PC_10, GPIO_C, SYS_GPC_MFPH_PC10MFP_GPIO},
{PC_11, GPIO_C, SYS_GPC_MFPH_PC11MFP_GPIO},
{PC_12, GPIO_C, SYS_GPC_MFPH_PC12MFP_GPIO},
{PC_13, GPIO_C, SYS_GPC_MFPH_PC13MFP_GPIO},
{PC_14, GPIO_C, SYS_GPC_MFPH_PC14MFP_GPIO},
{PC_15, GPIO_C, SYS_GPC_MFPH_PC15MFP_GPIO},
// GPIO D MFPL
{PD_0, GPIO_D, SYS_GPD_MFPL_PD0MFP_GPIO},
{PD_1, GPIO_D, SYS_GPD_MFPL_PD1MFP_GPIO},
{PD_2, GPIO_D, SYS_GPD_MFPL_PD2MFP_GPIO},
{PD_3, GPIO_D, SYS_GPD_MFPL_PD3MFP_GPIO},
{PD_4, GPIO_D, SYS_GPD_MFPL_PD4MFP_GPIO},
{PD_5, GPIO_D, SYS_GPD_MFPL_PD5MFP_GPIO},
{PD_6, GPIO_D, SYS_GPD_MFPL_PD6MFP_GPIO},
{PD_7, GPIO_D, SYS_GPD_MFPL_PD7MFP_GPIO},
// GPIO D MFPH
{PD_8, GPIO_D, SYS_GPD_MFPH_PD8MFP_GPIO},
{PD_9, GPIO_D, SYS_GPD_MFPH_PD9MFP_GPIO},
{PD_10, GPIO_D, SYS_GPD_MFPH_PD10MFP_GPIO},
{PD_11, GPIO_D, SYS_GPD_MFPH_PD11MFP_GPIO},
{PD_12, GPIO_D, SYS_GPD_MFPH_PD12MFP_GPIO},
{PD_13, GPIO_D, SYS_GPD_MFPH_PD13MFP_GPIO},
{PD_14, GPIO_D, SYS_GPD_MFPH_PD14MFP_GPIO},
{PD_15, GPIO_D, SYS_GPD_MFPH_PD15MFP_GPIO},
// GPIO E MFPL
{PE_0, GPIO_E, SYS_GPE_MFPL_PE0MFP_GPIO},
{PE_1, GPIO_E, SYS_GPE_MFPL_PE1MFP_GPIO},
{PE_2, GPIO_E, SYS_GPE_MFPL_PE2MFP_GPIO},
{PE_3, GPIO_E, SYS_GPE_MFPL_PE3MFP_GPIO},
{PE_4, GPIO_E, SYS_GPE_MFPL_PE4MFP_GPIO},
{PE_5, GPIO_E, SYS_GPE_MFPL_PE5MFP_GPIO},
{PE_6, GPIO_E, SYS_GPE_MFPL_PE6MFP_GPIO},
{PE_7, GPIO_E, SYS_GPE_MFPL_PE7MFP_GPIO},
// GPIO E MFPH
{PE_8, GPIO_E, SYS_GPE_MFPH_PE8MFP_GPIO},
{PE_9, GPIO_E, SYS_GPE_MFPH_PE9MFP_GPIO},
{PE_10, GPIO_E, SYS_GPE_MFPH_PE10MFP_GPIO},
{PE_11, GPIO_E, SYS_GPE_MFPH_PE11MFP_GPIO},
{PE_12, GPIO_E, SYS_GPE_MFPH_PE12MFP_GPIO},
{PE_13, GPIO_E, SYS_GPE_MFPH_PE13MFP_GPIO},
{PE_14, GPIO_E, SYS_GPE_MFPH_PE14MFP_GPIO},
// GPIO F MFPL
{PF_0, GPIO_F, SYS_GPF_MFPL_PF0MFP_GPIO},
{PF_1, GPIO_F, SYS_GPF_MFPL_PF1MFP_GPIO},
{PF_2, GPIO_F, SYS_GPF_MFPL_PF2MFP_GPIO},
{PF_3, GPIO_F, SYS_GPF_MFPL_PF3MFP_GPIO},
{PF_4, GPIO_F, SYS_GPF_MFPL_PF4MFP_GPIO},
{PF_5, GPIO_F, SYS_GPF_MFPL_PF5MFP_GPIO},
};
#endif
//*** ADC ***
const PinMap PinMap_ADC[] = {
{PA_0, ADC_0_0, SYS_PA_L_MFP_PA0_MFP_ADC_CH0},
{PA_1, ADC_0_1, SYS_PA_L_MFP_PA1_MFP_ADC_CH1},
{PA_2, ADC_0_2, SYS_PA_L_MFP_PA2_MFP_ADC_CH2},
{PA_3, ADC_0_3, SYS_PA_L_MFP_PA3_MFP_ADC_CH3},
{PA_4, ADC_0_4, SYS_PA_L_MFP_PA4_MFP_ADC_CH4},
{PA_5, ADC_0_5, SYS_PA_L_MFP_PA5_MFP_ADC_CH5},
{PA_6, ADC_0_6, SYS_PA_L_MFP_PA6_MFP_ADC_CH6},
{PA_7, ADC_0_7, SYS_PA_L_MFP_PA7_MFP_ADC_CH7},
{PD_0, ADC_0_8, SYS_PD_L_MFP_PD0_MFP_ADC_CH8},
{PD_1, ADC_0_9, SYS_PD_L_MFP_PD1_MFP_ADC_CH9},
{PD_2, ADC_0_10, SYS_PD_L_MFP_PD2_MFP_ADC_CH10},
{PD_3, ADC_0_11, SYS_PD_L_MFP_PD3_MFP_ADC_CH11},
{NC, NC, 0}
};
//*** I2C ***
const PinMap PinMap_I2C_SDA[] = {
{PA_8, I2C_0, SYS_PA_H_MFP_PA8_MFP_I2C0_SDA},
{PA_10, I2C_1, SYS_PA_H_MFP_PA10_MFP_I2C1_SDA},
{PA_12, I2C_0, SYS_PA_H_MFP_PA12_MFP_I2C0_SDA},
{PA_4, I2C_0, SYS_PA_L_MFP_PA4_MFP_I2C0_SDA},
{PC_8, I2C_1, SYS_PC_H_MFP_PC8_MFP_I2C1_SDA},
{PC_12, I2C_0, SYS_PC_H_MFP_PC12_MFP_I2C0_SDA},
{PF_4, I2C_0, SYS_PF_L_MFP_PF4_MFP_I2C0_SDA},
{NC, NC, 0}
};
const PinMap PinMap_I2C_SCL[] = {
{PA_5, I2C_0, SYS_PA_L_MFP_PA5_MFP_I2C0_SCL},
{PA_9, I2C_0, SYS_PA_H_MFP_PA9_MFP_I2C0_SCL},
{PA_11, I2C_1, SYS_PA_H_MFP_PA11_MFP_I2C1_SCL},
{PA_13, I2C_0, SYS_PA_H_MFP_PA13_MFP_I2C0_SCL},
{PC_9, I2C_1, SYS_PC_H_MFP_PC9_MFP_I2C1_SCL},
{PC_13, I2C_0, SYS_PC_H_MFP_PC13_MFP_I2C0_SCL},
{PF_5, I2C_0, SYS_PF_L_MFP_PF5_MFP_I2C0_SCL},
{NC, NC, 0}
};
//*** PWM ***
const PinMap PinMap_PWM[] = {
{PA_6, PWM_0_3, SYS_PA_L_MFP_PA6_MFP_PWM0_CH3},
{PA_7, PWM_0_2, SYS_PA_L_MFP_PA7_MFP_PWM0_CH2},
{PA_12, PWM_0_0, SYS_PA_H_MFP_PA12_MFP_PWM0_CH0},
{PA_13, PWM_0_1, SYS_PA_H_MFP_PA13_MFP_PWM0_CH1},
{PA_14, PWM_0_2, SYS_PA_H_MFP_PA14_MFP_PWM0_CH2},
{PA_15, PWM_0_3, SYS_PA_H_MFP_PA15_MFP_PWM0_CH3},
{PB_11, PWM_1_0, SYS_PB_H_MFP_PB11_MFP_PWM1_CH0},
{PC_6, PWM_0_0, SYS_PC_L_MFP_PC6_MFP_PWM0_CH0},
{PC_7, PWM_0_1, SYS_PC_L_MFP_PC7_MFP_PWM0_CH1},
{PC_12, PWM_1_0, SYS_PC_H_MFP_PC12_MFP_PWM1_CH0},
{PC_13, PWM_1_1, SYS_PC_H_MFP_PC13_MFP_PWM1_CH1},
{PC_14, PWM_1_3, SYS_PC_H_MFP_PC14_MFP_PWM1_CH3},
{PC_15, PWM_1_2, SYS_PC_H_MFP_PC15_MFP_PWM1_CH2},
{PE_0, PWM_1_2, SYS_PE_L_MFP_PE0_MFP_PWM1_CH2},
{PE_1, PWM_1_3, SYS_PE_L_MFP_PE1_MFP_PWM1_CH3},
{PE_5, PWM_1_1, SYS_PE_L_MFP_PE5_MFP_PWM1_CH1},
{NC, NC, 0}
};
//*** SERIAL ***
const PinMap PinMap_UART_TX[] = {
{PA_2, UART_1, SYS_PA_L_MFP_PA2_MFP_UART1_RX},
{PA_3, UART_1, SYS_PA_L_MFP_PA3_MFP_UART1_TX},
{PA_15, UART_0, SYS_PA_H_MFP_PA15_MFP_UART0_TX},
{PB_1, UART_0, SYS_PB_L_MFP_PB1_MFP_UART0_TX},
{PB_5, UART_1, SYS_PB_L_MFP_PB5_MFP_UART1_TX},
{PC_11, UART_1, SYS_PC_H_MFP_PC11_MFP_UART1_TX},
{PD_1, UART_1, SYS_PD_L_MFP_PD1_MFP_UART1_TX},
{PE_10, UART_1, SYS_PE_H_MFP_PE10_MFP_UART1_TX},
{NC, NC, 0}
};
const PinMap PinMap_UART_RX[] = {
{PA_2, UART_1, SYS_PA_L_MFP_PA2_MFP_UART1_RX},
{PA_3, UART_1, SYS_PA_L_MFP_PA3_MFP_UART1_TX},
{PA_14, UART_0, SYS_PA_H_MFP_PA14_MFP_UART0_RX},
{PB_0, UART_0, SYS_PB_L_MFP_PB0_MFP_UART0_RX},
{PB_4, UART_1, SYS_PB_L_MFP_PB4_MFP_UART1_RX},
{PC_10, UART_1, SYS_PC_H_MFP_PC10_MFP_UART1_RX},
{PD_0, UART_1, SYS_PD_L_MFP_PD0_MFP_UART1_RX},
{PE_9, UART_1, SYS_PE_H_MFP_PE9_MFP_UART1_RX},
{NC, NC, 0}
};
const PinMap PinMap_UART_RTS[] = {
{PB_2, UART_0, SYS_PB_L_MFP_PB2_MFP_UART0_RTS},
{PB_6, UART_1, SYS_PB_L_MFP_PB6_MFP_UART1_RTS},
{PD_2, UART_1, SYS_PD_L_MFP_PD2_MFP_UART1_RTS},
{PE_11, UART_1, SYS_PE_H_MFP_PE11_MFP_UART1_RTS},
{NC, NC, 0}
};
const PinMap PinMap_UART_CTS[] = {
{PB_3, UART_0, SYS_PB_L_MFP_PB3_MFP_UART0_CTS},
{PB_7, UART_1, SYS_PB_L_MFP_PB7_MFP_UART1_CTS},
{PD_3, UART_1, SYS_PD_L_MFP_PD3_MFP_UART1_CTS},
{PE_12, UART_1, SYS_PE_H_MFP_PE12_MFP_UART1_CTS},
{NC, NC, 0}
};
//*** SPI ***
const PinMap PinMap_SPI_MOSI[] = {
{PA_11, SPI_2, SYS_PA_H_MFP_PA11_MFP_SPI2_MOSI0},
{PB_0, SPI_1, SYS_PB_L_MFP_PB0_MFP_SPI1_MOSI0},
{PB_7, SPI_2, SYS_PB_L_MFP_PB7_MFP_SPI2_MOSI0},
{PB_10, SPI_0, SYS_PB_H_MFP_PB10_MFP_SPI0_MOSI0},
{PC_3, SPI_0, SYS_PC_L_MFP_PC3_MFP_SPI0_MOSI0},
{PC_5, SPI_0, SYS_PC_L_MFP_PC5_MFP_SPI0_MOSI1},
{PC_11, SPI_1, SYS_PC_H_MFP_PC11_MFP_SPI1_MOSI0},
{PC_13, SPI_1, SYS_PC_H_MFP_PC13_MFP_SPI1_MOSI1},
{PD_3, SPI_2, SYS_PD_L_MFP_PD3_MFP_SPI2_MOSI0},
{PD_5, SPI_2, SYS_PD_L_MFP_PD5_MFP_SPI2_MOSI1},
{PE_4, SPI_0, SYS_PE_L_MFP_PE4_MFP_SPI0_MOSI0},
{NC, NC, 0}
};
const PinMap PinMap_SPI_MISO[] = {
{PA_10, SPI_2, SYS_PA_H_MFP_PA10_MFP_SPI2_MISO0},
{PB_1, SPI_1, SYS_PB_L_MFP_PB1_MFP_SPI1_MISO0},
{PB_6, SPI_2, SYS_PB_L_MFP_PB6_MFP_SPI2_MISO0},
{PB_11, SPI_0, SYS_PB_H_MFP_PB11_MFP_SPI0_MISO0},
{PC_2, SPI_0, SYS_PC_L_MFP_PC2_MFP_SPI0_MISO0},
{PC_4, SPI_0, SYS_PC_L_MFP_PC4_MFP_SPI0_MISO1},
{PC_10, SPI_1, SYS_PC_H_MFP_PC10_MFP_SPI1_MISO0},
{PC_12, SPI_1, SYS_PC_H_MFP_PC12_MFP_SPI1_MISO1},
{PD_2, SPI_2, SYS_PD_L_MFP_PD2_MFP_SPI2_MISO0},
{PD_4, SPI_2, SYS_PD_L_MFP_PD4_MFP_SPI2_MISO1},
{PE_3, SPI_0, SYS_PE_L_MFP_PE3_MFP_SPI0_MISO0},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SCLK[] = {
{PA_9, SPI_2, SYS_PA_H_MFP_PA9_MFP_SPI2_SCLK},
{PB_2, SPI_1, SYS_PB_L_MFP_PB2_MFP_SPI1_SCLK},
{PB_5, SPI_2, SYS_PB_L_MFP_PB5_MFP_SPI2_SCLK},
{PC_1, SPI_0, SYS_PC_L_MFP_PC1_MFP_SPI0_SCLK},
{PC_9, SPI_1, SYS_PC_H_MFP_PC9_MFP_SPI1_SCLK},
{PD_1, SPI_2, SYS_PD_L_MFP_PD1_MFP_SPI2_SCLK},
{PE_2, SPI_0, SYS_PE_L_MFP_PE2_MFP_SPI0_SCLK},
{NC, NC, 0}
};
const PinMap PinMap_SPI_SSEL[] = {
{PA_8, SPI_2, SYS_PA_H_MFP_PA8_MFP_SPI2_SS0},
{PB_3, SPI_1, SYS_PB_L_MFP_PB3_MFP_SPI1_SS0},
{PB_4, SPI_2, SYS_PB_L_MFP_PB4_MFP_SPI2_SS0},
{PB_9, SPI_1, SYS_PB_H_MFP_PB9_MFP_SPI1_SS1},
{PB_10, SPI_0, SYS_PB_H_MFP_PB10_MFP_SPI0_SS1},
{PB_14, SPI_2, SYS_PB_H_MFP_PB14_MFP_SPI2_SS1},
{PC_0, SPI_0, SYS_PC_L_MFP_PC0_MFP_SPI0_SS0},
{PC_8, SPI_1, SYS_PC_H_MFP_PC8_MFP_SPI1_SS0},
{PD_0, SPI_2, SYS_PD_L_MFP_PD0_MFP_SPI2_SS0},
{PE_1, SPI_0, SYS_PE_L_MFP_PE1_MFP_SPI0_SS0},
{NC, NC, 0}
};

View File

@ -0,0 +1,64 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#ifndef MBED_PERIPHERALPINS_H
#define MBED_PERIPHERALPINS_H
#include "pinmap.h"
#include "PeripheralNames.h"
#ifdef __cplusplus
extern "C" {
#endif
#if 0
//*** GPIO ***
extern const PinMap PinMap_GPIO[];
#endif
//*** ADC ***
extern const PinMap PinMap_ADC[];
//*** I2C ***
extern const PinMap PinMap_I2C_SDA[];
extern const PinMap PinMap_I2C_SCL[];
//*** PWM ***
extern const PinMap PinMap_PWM[];
//*** SERIAL ***
extern const PinMap PinMap_UART_TX[];
extern const PinMap PinMap_UART_RX[];
extern const PinMap PinMap_UART_RTS[];
extern const PinMap PinMap_UART_CTS[];
//*** SPI ***
extern const PinMap PinMap_SPI_MOSI[];
extern const PinMap PinMap_SPI_MISO[];
extern const PinMap PinMap_SPI_SCLK[];
extern const PinMap PinMap_SPI_SSEL[];
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,143 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#ifndef MBED_PINNAMES_H
#define MBED_PINNAMES_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NU_PININDEX_Pos 0
#define NU_PININDEX_Msk (0xFFul << NU_PININDEX_Pos)
#define NU_PINPORT_Pos 8
#define NU_PINPORT_Msk (0xFul << NU_PINPORT_Pos)
#define NU_PIN_MODINDEX_Pos 12
#define NU_PIN_MODINDEX_Msk (0xFul << NU_PIN_MODINDEX_Pos)
#define NU_PIN_BIND_Pos 16
#define NU_PIN_BIND_Msk (0x1ul << NU_PIN_BIND_Pos)
#define NU_PININDEX(PINNAME) (((unsigned int)(PINNAME) & NU_PININDEX_Msk) >> NU_PININDEX_Pos)
#define NU_PINPORT(PINNAME) (((unsigned int)(PINNAME) & NU_PINPORT_Msk) >> NU_PINPORT_Pos)
#define NU_PIN_BIND(PINNAME) (((unsigned int)(PINNAME) & NU_PIN_BIND_Msk) >> NU_PIN_BIND_Pos)
#define NU_PIN_MODINDEX(PINNAME) (((unsigned int)(PINNAME) & NU_PIN_MODINDEX_Msk) >> NU_PIN_MODINDEX_Pos)
#define NU_PINNAME(PORT, PIN) ((((unsigned int) (PORT)) << (NU_PINPORT_Pos)) | (((unsigned int) (PIN)) << NU_PININDEX_Pos))
#define NU_PINNAME_BIND(PINNAME, modname) NU_PINNAME_BIND_(NU_PINPORT(PINNAME), NU_PININDEX(PINNAME), modname)
#define NU_PINNAME_BIND_(PORT, PIN, modname) ((((unsigned int)(PORT)) << NU_PINPORT_Pos) | (((unsigned int)(PIN)) << NU_PININDEX_Pos) | (NU_MODINDEX(modname) << NU_PIN_MODINDEX_Pos) | NU_PIN_BIND_Msk)
#define NU_PORT_BASE(port) ((GPIO_T *)(((uint32_t) GPIOA_BASE) + 0x40 * port))
#define NU_MFP_POS(pin) ((pin % 8) * 4)
#define NU_MFP_MSK(pin) (0xful << NU_MFP_POS(pin))
// LEGACY
#define NU_PINNAME_TO_PIN(PINNAME) NU_PININDEX(PINNAME)
#define NU_PINNAME_TO_PORT(PINNAME) NU_PINPORT(PINNAME)
#define NU_PINNAME_TO_MODSUBINDEX(PINNAME) NU_PIN_MODINDEX(PINNAME)
#define NU_PORT_N_PIN_TO_PINNAME(PORT, PIN) NU_PINNAME((PORT), (PIN))
typedef enum {
PIN_INPUT,
PIN_OUTPUT
} PinDirection;
typedef enum {
PullNone = 0,
PullDown,
PullUp,
PushPull,
OpenDrain,
Quasi,
PullDefault = PullUp,
} PinMode;
typedef enum {
// Not connected
NC = (int)0xFFFFFFFF,
// Generic naming
PA_0 = NU_PORT_N_PIN_TO_PINNAME(0, 0), PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7, PA_8, PA_9, PA_10, PA_11, PA_12, PA_13, PA_14, PA_15,
PB_0 = NU_PORT_N_PIN_TO_PINNAME(1, 0), PB_1, PB_2, PB_3, PB_4, PB_5, PB_6, PB_7, PB_8, PB_9, PB_10, PB_11, PB_12, PB_13, PB_14, PB_15,
PC_0 = NU_PORT_N_PIN_TO_PINNAME(2, 0), PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_9, PC_10, PC_11, PC_12, PC_13, PC_14, PC_15,
PD_0 = NU_PORT_N_PIN_TO_PINNAME(3, 0), PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9, PD_10, PD_11, PD_12, PD_13, PD_14, PD_15,
PE_0 = NU_PORT_N_PIN_TO_PINNAME(4, 0), PE_1, PE_2, PE_3, PE_4, PE_5, PE_6, PE_7, PE_8, PE_9, PE_10, PE_11, PE_12, PE_13, PE_14, PE_15,
PF_0 = NU_PORT_N_PIN_TO_PINNAME(5, 0), PF_1, PF_2, PF_3, PF_4, PF_5,
// Arduino UNO naming
A0 = PA_0,
A1 = PA_1,
A2 = PA_2,
A3 = PA_3,
A4 = PA_4,
A5 = PA_5,
A6 = PA_6,
A7 = PA_7,
D0 = PC_10,
D1 = PC_11,
D2 = PA_12,
D3 = PA_13,
D4 = PA_14,
D5 = PA_15,
D6 = PC_12,
D7 = PC_13,
D8 = PC_15,
D9 = PC_14,
D10 = PD_6,
D11 = PD_7,
D12 = PD_14,
D13 = PD_15,
D14 = PA_10,
D15 = PA_11,
// FIXME: other board-specific naming
// UART naming
USBTX = PB_1,
USBRX = PB_0,
STDIO_UART_TX = USBTX,
STDIO_UART_RX = USBRX,
// LED naming
#if 0
LED1 = PB_0,
LED2 = PB_1,
LED3 = PE_9,
LED4 = PE_10,
LED5 = PE_11,
LED6 = PD_8,
LED7 = PD_9,
LED8 = PC_7,
#endif
LED1 = PA_12,
LED2 = PA_13,
LED3 = PA_14,
LED4 = LED3,
LED_RED = LED1,
LED_GREEN = LED2,
LED_BLUE = LED3,
// Button naming
SW2 = PE_12,
SW3 = PD_0,
SW4 = PD_1,
} PinName;
#ifdef __cplusplus
}
#endif
#endif // MBED_PINNAMES_H

View File

@ -0,0 +1,36 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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.
*/
#ifndef MBED_PORTNAMES_H
#define MBED_PORTNAMES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
PortA = 0,
PortB = 1,
PortC = 2,
PortD = 3,
PortE = 4,
PortF = 5
} PortName;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,24 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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.
*/
#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H
#define DEVICE_ID_LENGTH 24
#include "objects.h"
#endif

View File

@ -0,0 +1,82 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#include "analogin_api.h"
// NOTE: Ensurce mbed_sdk_init() will get called before C++ global object constructor.
#if defined(__CC_ARM) || defined(__GNUC__)
void mbed_sdk_init_forced(void) __attribute__((constructor(101)));
#elif defined(__ICCARM__)
// FIXME: How to achieve it in IAR?
#endif
void mbed_sdk_init(void)
{
// NOTE: Support singleton semantics to be called from other init functions
static int inited = 0;
if (inited) {
return;
}
inited = 1;
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable HIRC clock (internal OSC 12MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HIRC_EN_Msk);
/* Enable HXT clock (external XTAL 12MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HXT_EN_Msk);
/* Enable LIRC clock (OSC 10KHz) for lp_ticker */
CLK_EnableXtalRC(CLK_PWRCTL_LIRC_EN_Msk);
/* Enable LXT clock (XTAL 32KHz) for RTC */
CLK_EnableXtalRC(CLK_PWRCTL_LXT_EN_Msk);
/* Wait for HIRC clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_HIRC_STB_Msk);
/* Wait for HXT clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_HXT_STB_Msk);
/* Wait for LIRC clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_LIRC_STB_Msk);
/* Wait for LXT clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_LXT_STB_Msk);
/* Set HCLK source form HXT and HCLK source divide 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HXT, CLK_HCLK_CLK_DIVIDER(1));
/* Set HCLK frequency 42MHz */
CLK_SetCoreClock(42000000);
#if DEVICE_ANALOGIN
/* Vref connect to internal */
// SYS->VREFCTL = (SYS->VREFCTL & ~SYS_VREFCTL_VREFCTL_Msk) | SYS_VREFCTL_VREF_3_072V;
#endif
/* Update System Core Clock */
/* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
SystemCoreClockUpdate();
/* Lock protected registers */
SYS_LockReg();
}
void mbed_sdk_init_forced(void)
{
mbed_sdk_init();
}

View File

@ -0,0 +1,131 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#ifndef MBED_OBJECTS_H
#define MBED_OBJECTS_H
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#include "dma_api.h"
#ifdef __cplusplus
extern "C" {
#endif
struct gpio_irq_s {
//IRQn_Type irq_n;
//uint32_t irq_index;
//uint32_t event;
PinName pin;
uint32_t irq_handler;
uint32_t irq_id;
};
struct port_s {
PortName port;
uint32_t mask;
PinDirection direction;
};
struct analogin_s {
ADCName adc;
//PinName pin;
};
struct serial_s {
UARTName uart;
PinName pin_tx;
PinName pin_rx;
uint32_t baudrate;
uint32_t databits;
uint32_t parity;
uint32_t stopbits;
void (*vec)(void);
uint32_t irq_handler;
uint32_t irq_id;
uint32_t ier_msk;
// Async transfer related fields
DMAUsage dma_usage_tx;
DMAUsage dma_usage_rx;
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
void (*irq_handler_tx_async)(void);
void (*irq_handler_rx_async)(void);
};
struct spi_s {
SPIName spi;
PinName pin_miso;
PinName pin_mosi;
PinName pin_sclk;
PinName pin_ssel;
//void (*vec)(void);
// Async transfer related fields
DMAUsage dma_usage;
int dma_chn_id_tx;
int dma_chn_id_rx;
uint32_t event;
//void (*irq_handler_tx_async)(void);
//void (*irq_handler_rx_async)(void);
};
struct i2c_s {
I2CName i2c;
//void (*vec)(void);
int slaveaddr_state;
uint32_t tran_ctrl;
char * tran_beg;
char * tran_pos;
char * tran_end;
int inten;
// Async transfer related fields
DMAUsage dma_usage;
uint32_t event;
int stop;
uint32_t address;
};
struct pwmout_s {
PWMName pwm;
//PinName pin;
uint32_t period_us;
uint32_t pulsewidth_us;
};
struct sleep_s {
uint32_t start_us;
uint32_t end_us;
uint32_t period_us;
int powerdown;
};
#ifdef __cplusplus
}
#endif
#include "gpio_object.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,202 @@
/**************************************************************************//**
* @file adc.c
* @version V1.00
* $Revision: 7 $
* $Date: 14/10/06 6:00p $
* @brief NANO100 series ADC driver source file
*
* @note
* Copyright (C) 2013-2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_ADC_Driver ADC Driver
@{
*/
/** @addtogroup NANO100_ADC_EXPORTED_FUNCTIONS ADC Exported Functions
@{
*/
/**
* @brief This API configures ADC module to be ready for convert the input from selected channel
* @param[in] adc Base address of ADC module
* @param[in] u32InputMode Input mode (single-end/differential). Valid values are:
* - \ref ADC_INPUT_MODE_SINGLE_END
* - \ref ADC_INPUT_MODE_DIFFERENTIAL
* @param[in] u32OpMode Operation mode (single/single cycle/continuous). Valid values are:
* - \ref ADC_OPERATION_MODE_SINGLE
* - \ref ADC_OPERATION_MODE_SINGLE_CYCLE
* - \ref ADC_OPERATION_MODE_CONTINUOUS
* @param[in] u32ChMask Channel enable bit. Each bit corresponds to a input channel. Bit 0 is channel 0, bit 1 is channel 1...
* @return None
* @note This API does not turn on ADC power nor does trigger ADC conversion
*/
void ADC_Open(ADC_T *adc,
uint32_t u32InputMode,
uint32_t u32OpMode,
uint32_t u32ChMask)
{
ADC->CR = (ADC->CR & ~ADC_CR_DIFF_Msk) | u32InputMode;
ADC->CR = (ADC->CR & ~ADC_CR_ADMD_Msk) | u32OpMode;
ADC->CR = (ADC->CR & ~ADC_CR_REFSEL_Msk);
ADC->CHEN = u32ChMask;
return;
}
/**
* @brief Disable ADC module
* @param[in] adc Base address of ADC module
* @return None
*/
void ADC_Close(ADC_T *adc)
{
SYS->IPRST_CTL2 |= SYS_IPRST_CTL2_ADC_RST_Msk;
SYS->IPRST_CTL2 &= ~SYS_IPRST_CTL2_ADC_RST_Msk;
return;
}
/**
* @brief Configure the hardware trigger condition and enable hardware trigger
* @param[in] adc Base address of ADC module
* @param[in] u32Source Decides the hardware trigger source. Valid values are:
* - \ref ADC_TRIGGER_BY_EXT_PIN
* @param[in] u32Param While ADC trigger by external pin, this parameter
* is used to set trigger condition. Valid values are:
* - \ref ADC_LOW_LEVEL_TRIGGER
* - \ref ADC_HIGH_LEVEL_TRIGGER
* - \ref ADC_FALLING_EDGE_TRIGGER
* - \ref ADC_RISING_EDGE_TRIGGER
* @return None
*/
void ADC_EnableHWTrigger(ADC_T *adc,
uint32_t u32Source,
uint32_t u32Param)
{
ADC->CR &= ~(ADC_CR_TRGE_Msk | ADC_CR_TRGCOND_Msk | ADC_CR_TRGS_Msk);
ADC->CR |= u32Source | u32Param | ADC_CR_TRGE_Msk;
return;
}
/**
* @brief Disable hardware trigger ADC function.
* @param[in] adc Base address of ADC module
* @return None
*/
void ADC_DisableHWTrigger(ADC_T *adc)
{
ADC->CR &= ~(ADC_CR_TRGS_Msk | ADC_CR_TRGCOND_Msk | ADC_CR_TRGE_Msk);
return;
}
/**
* @brief Config and enable timer trigger
* @param[in] adc Base address of ADC module
* @param[in] u32Source Decides which timer trigger ADC. Valid values are: 0 ~ 3
* @param[in] u32PDMACnt When timer event occurred, PDMA will transfer u32PDMACnt+1 ADC result
* @return None
*/
void ADC_EnableTimerTrigger(ADC_T *adc,
uint32_t u32Source,
uint32_t u32PDMACnt)
{
ADC->CR &= ~(ADC_CR_TMPDMACNT_Msk | ADC_CR_TMSEL_Msk);
ADC->CR |= (u32PDMACnt << ADC_CR_TMPDMACNT_Pos) | (u32Source << ADC_CR_TMSEL_Pos) | ADC_CR_TMTRGMOD_Msk;
return;
}
/**
* @brief Disable timer trigger ADC function.
* @param[in] adc Base address of ADC module
* @return None
*/
void ADC_DisableTimerTrigger(ADC_T *adc)
{
ADC->CR &= ~ADC_CR_TMTRGMOD_Msk;
return;
}
/**
* @brief Configure the extended sampling time
* @param[in] adc Base address of ADC module
* @param[in] u32ChNum The channel number
* @param[in] u32SampleTime Decides the extend sampling counter. Valid values are 0 ~ 15
* @return None
*/
void ADC_SetExtraSampleTime(ADC_T *adc,
uint32_t u32ChNum,
uint32_t u32SampleTime)
{
if (u32ChNum < 8)
ADC->SMPLCNT0 = (ADC->SMPLCNT0 & ~(ADC_SMPLCNT0_CH0SAMPCNT_Msk << (u32ChNum * 4))) | (u32SampleTime << (u32ChNum * 4));
else if (u32ChNum < 12)
ADC->SMPLCNT1 = (ADC->SMPLCNT1 & ~(ADC_SMPLCNT1_CH8SAMPCNT_Msk << ((u32ChNum - 8) * 4))) | (u32SampleTime << ((u32ChNum - 8 ) * 4));
else
ADC->SMPLCNT1 = (ADC->SMPLCNT1 & ~ADC_SMPLCNT1_INTCHSAMPCNT_Msk) | (u32SampleTime << ADC_SMPLCNT1_INTCHSAMPCNT_Pos);
}
/**
* @brief Enable the interrupt(s) selected by u32Mask parameter.
* @param[in] adc Base address of ADC module
* @param[in] u32Mask The combination of interrupt status bits listed below. Each bit
* corresponds to a interrupt status. This parameter decides which
* interrupts will be enabled.
* - \ref ADC_ADF_INT
* - \ref ADC_CMP0_INT
* - \ref ADC_CMP1_INT
* @return None
*/
void ADC_EnableInt(ADC_T *adc, uint32_t u32Mask)
{
if(u32Mask & ADC_ADF_INT)
ADC->CR |= ADC_CR_ADIE_Msk;
if(u32Mask & ADC_CMP0_INT)
ADC->CMPR0 |= ADC_CMPR_CMPIE_Msk;
if(u32Mask & ADC_CMP1_INT)
ADC->CMPR1 |= ADC_CMPR_CMPIE_Msk;
return;
}
/**
* @brief Disable the interrupt(s) selected by u32Mask parameter.
* @param[in] adc Base address of ADC module
* @param[in] u32Mask The combination of interrupt status bits listed below. Each bit
* corresponds to a interrupt status. This parameter decides which
* interrupts will be disabled.
* - \ref ADC_ADF_INT
* - \ref ADC_CMP0_INT
* - \ref ADC_CMP1_INT
* @return None
*/
void ADC_DisableInt(ADC_T *adc, uint32_t u32Mask)
{
if(u32Mask & ADC_ADF_INT)
ADC->CR &= ~ADC_CR_ADIE_Msk;
if(u32Mask & ADC_CMP0_INT)
ADC->CMPR0 &= ~ADC_CMPR_CMPIE_Msk;
if(u32Mask & ADC_CMP1_INT)
ADC->CMPR1 &= ~ADC_CMPR_CMPIE_Msk;
return;
}
/*@}*/ /* end of group NANO100_ADC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_ADC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013-2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,367 @@
/**************************************************************************//**
* @file adc.h
* @version V1.00
* $Revision: 10 $
* $Date: 15/06/30 2:50p $
* @brief NANO100 series ADC driver header file
*
* @note
* Copyright (C) 2013-2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __ADC_H__
#define __ADC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_ADC_Driver ADC Driver
@{
*/
/** @addtogroup NANO100_ADC_EXPORTED_CONSTANTS ADC Exported Constants
@{
*/
#define ADC_CH_0_MASK (1UL << 0) /*!< ADC channel 0 mask */
#define ADC_CH_1_MASK (1UL << 1) /*!< ADC channel 1 mask */
#define ADC_CH_2_MASK (1UL << 2) /*!< ADC channel 2 mask */
#define ADC_CH_3_MASK (1UL << 3) /*!< ADC channel 3 mask */
#define ADC_CH_4_MASK (1UL << 4) /*!< ADC channel 4 mask */
#define ADC_CH_5_MASK (1UL << 5) /*!< ADC channel 5 mask */
#define ADC_CH_6_MASK (1UL << 6) /*!< ADC channel 6 mask */
#define ADC_CH_7_MASK (1UL << 7) /*!< ADC channel 7 mask */
#define ADC_CH_8_MASK (1UL << 8) /*!< ADC channel 8 mask */
#define ADC_CH_9_MASK (1UL << 9) /*!< ADC channel 9 mask */
#define ADC_CH_10_MASK (1UL << 10) /*!< ADC channel 10 mask */
#define ADC_CH_11_MASK (1UL << 11) /*!< ADC channel 11 mask */
#define ADC_CH_12_MASK (1UL << 12) /*!< ADC channel 12 mask */
#define ADC_CH_13_MASK (1UL << 13) /*!< ADC channel 13 mask */
#define ADC_CH_14_MASK (1UL << 14) /*!< ADC channel 14 mask */
#define ADC_CH_15_MASK (1UL << 15) /*!< ADC channel 15 mask */
#define ADC_CH_16_MASK (1UL << 16) /*!< ADC channel 16 mask */
#define ADC_CH_17_MASK (1UL << 17) /*!< ADC channel 17 mask */
#define ADC_CHEN_Msk (0x3FFFF) /*!< ADC channel 0 ~ 17 mask */
#define ADC_PDMADATA_AD_PDMA_Msk (0xFFF) /*!< ADC PDMA current transfer data */
#define ADC_CMP_LESS_THAN (0UL) /*!< ADC compare condition less than */
#define ADC_CMP_GREATER_OR_EQUAL_TO (ADC_CMPR_CMPCOND_Msk) /*!< ADC compare condition greater or equal to */
#define ADC_TRIGGER_BY_EXT_PIN (0UL) /*!< ADC trigger by STADC (P3.2) pin */
#define ADC_LOW_LEVEL_TRIGGER (0UL << ADC_CR_TRGCOND_Pos) /*!< External pin low level trigger ADC */
#define ADC_HIGH_LEVEL_TRIGGER (1UL << ADC_CR_TRGCOND_Pos) /*!< External pin high level trigger ADC */
#define ADC_FALLING_EDGE_TRIGGER (2UL << ADC_CR_TRGCOND_Pos) /*!< External pin falling edge trigger ADC */
#define ADC_RISING_EDGE_TRIGGER (3UL << ADC_CR_TRGCOND_Pos) /*!< External pin rising edge trigger ADC */
#define ADC_ADF_INT (ADC_SR_ADF_Msk) /*!< ADC convert complete interrupt */
#define ADC_CMP0_INT (ADC_SR_CMPF0_Msk) /*!< ADC comparator 0 interrupt */
#define ADC_CMP1_INT (ADC_SR_CMPF1_Msk) /*!< ADC comparator 1 interrupt */
#define ADC_INPUT_MODE_SINGLE_END (0UL << ADC_CR_DIFF_Pos) /*!< ADC input mode set to single end */
#define ADC_INPUT_MODE_DIFFERENTIAL (1UL << ADC_CR_DIFF_Pos) /*!< ADC input mode set to differential */
#define ADC_OPERATION_MODE_SINGLE (0UL << ADC_CR_ADMD_Pos) /*!< ADC operation mode set to single conversion */
#define ADC_OPERATION_MODE_SINGLE_CYCLE (2UL << ADC_CR_ADMD_Pos) /*!< ADC operation mode set to single cycle scan */
#define ADC_OPERATION_MODE_CONTINUOUS (3UL << ADC_CR_ADMD_Pos) /*!< ADC operation mode set to continuous scan */
#define ADC_DMODE_OUT_FORMAT_UNSIGNED (0UL << ADC_CR_DIFF_Pos) /*!< ADC differential mode output format with unsigned */
#define ADC_DMODE_OUT_FORMAT_2COMPLEMENT (1UL << ADC_CR_DIFF_Pos) /*!< ADC differential mode output format with 2's complement */
#define ADC_RESSEL_6_BIT (0UL << ADC_CR_RESSEL_Pos) /*!< ADC resolution selection set to 6 bit */
#define ADC_RESSEL_8_BIT (1UL << ADC_CR_RESSEL_Pos) /*!< ADC resolution selection set to 8 bit */
#define ADC_RESSEL_10_BIT (2UL << ADC_CR_RESSEL_Pos) /*!< ADC resolution selection set to 10 bit */
#define ADC_RESSEL_12_BIT (3UL << ADC_CR_RESSEL_Pos) /*!< ADC resolution selection set to 12 bit */
#define ADC_REFSEL_POWER (0UL << ADC_CR_REFSEL_Pos) /*!< ADC reference voltage source selection set to power */
#define ADC_REFSEL_INT_VREF (1UL << ADC_CR_REFSEL_Pos) /*!< ADC reference voltage source selection set to Int_VREF */
#define ADC_REFSEL_VREF (2UL << ADC_CR_REFSEL_Pos) /*!< ADC reference voltage source selection set to VREF */
/*@}*/ /* end of group NANO100_ADC_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_ADC_EXPORTED_FUNCTIONS ADC Exported Functions
@{
*/
/**
* @brief Get the latest ADC conversion data
* @param[in] adc Base address of ADC module
* @param[in] u32ChNum Channel number
* @return Latest ADC conversion data
* \hideinitializer
*/
#define ADC_GET_CONVERSION_DATA(adc, u32ChNum) (ADC->RESULT[u32ChNum] & ADC_RESULT_RSLT_Msk)
/**
* @brief Return the user-specified interrupt flags
* @param[in] adc Base address of ADC module
* @param[in] u32Mask The combination of following interrupt status bits. Each bit corresponds to a interrupt status.
* - \ref ADC_ADF_INT
* - \ref ADC_CMP0_INT
* - \ref ADC_CMP1_INT
* @return User specified interrupt flags
* \hideinitializer
*/
#define ADC_GET_INT_FLAG(adc, u32Mask) (ADC->SR & (u32Mask))
/**
* @brief This macro clear the selected interrupt status bits
* @param[in] adc Base address of ADC module
* @param[in] u32Mask The combination of following interrupt status bits. Each bit corresponds to a interrupt status.
* - \ref ADC_ADF_INT
* - \ref ADC_CMP0_INT
* - \ref ADC_CMP1_INT
* @return None
* \hideinitializer
*/
#define ADC_CLR_INT_FLAG(adc, u32Mask) (ADC->SR = (ADC->SR & ~(ADC_SR_ADF_Msk | \
ADC_SR_CMPF0_Msk | \
ADC_SR_CMPF1_Msk)) | (u32Mask))
/**
* @brief Get the busy state of ADC
* @param[in] adc Base address of ADC module
* @return busy state of ADC
* @retval 0 ADC is not busy
* @retval 1 ADC is busy
* \hideinitializer
*/
#define ADC_IS_BUSY(adc) (ADC->SR & ADC_SR_BUSY_Msk ? 1 : 0)
/**
* @brief Check if the ADC conversion data is over written or not
* @param[in] adc Base address of ADC module
* @param[in] u32ChNum Currently not used
* @return Over run state of ADC data
* @retval 0 ADC data is not overrun
* @retval 1 ADC data us overrun
* \hideinitializer
*/
#define ADC_IS_DATA_OVERRUN(adc, u32ChNum) (ADC->RESULT[u32ChNum] & ADC_RESULT_OVERRUN_Msk ? 1 : 0)
/**
* @brief Check if the ADC conversion data is valid or not
* @param[in] adc Base address of ADC module
* @param[in] u32ChNum Currently not used
* @return Valid state of ADC data
* @retval 0 ADC data is not valid
* @retval 1 ADC data us valid
* \hideinitializer
*/
#define ADC_IS_DATA_VALID(adc, u32ChNum) (ADC->RESULT[u32ChNum] & ADC_RESULT_VALID_Msk ? 1 : 0)
/**
* @brief Power down ADC module
* @param[in] adc Base address of ADC module
* @return None
* \hideinitializer
*/
#define ADC_POWER_DOWN(adc) (ADC->CR &= ~ADC_CR_ADEN_Msk)
/**
* @brief Power on ADC module
* @param[in] adc Base address of ADC module
* @return None
* \hideinitializer
*/
#define ADC_POWER_ON(adc) \
do { \
ADC->CR |= ADC_CR_ADEN_Msk; \
while ((!(ADC->SR & ADC_SR_INITRDY_Msk)) || (!(ADC->PWRCTL & ADC_PWRCTL_PWUPRDY_Msk))); \
} while(0)
/**
* @brief Configure the comparator 0 and enable it
* @param[in] adc Base address of ADC module
* @param[in] u32ChNum Specifies the source channel, valid value are from 0 to 7
* @param[in] u32Condition Specifies the compare condition
* - \ref ADC_CMP_LESS_THAN
* - \ref ADC_CMP_GREATER_OR_EQUAL_TO
* @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_CMP_GREATER_OR_EQUAL_TO, 0x800, 10);
* Means ADC will assert comparator 0 flag if channel 5 conversion result is
* greater or equal to 0x800 for 10 times continuously.
* \hideinitializer
*/
#define ADC_ENABLE_CMP0(adc, \
u32ChNum, \
u32Condition, \
u32Data, \
u32MatchCount) (ADC->CMPR0 = ((u32ChNum) << ADC_CMPR_CMPCH_Pos) | \
(u32Condition) | \
((u32Data) << ADC_CMPR_CMPD_Pos) | \
(((u32MatchCount) - 1) << ADC_CMPR_CMPMATCNT_Pos) |\
ADC_CMPR_CMPEN_Msk)
/**
* @brief Disable comparator 0
* @param[in] adc Base address of ADC module
* @return None
* \hideinitializer
*/
#define ADC_DISABLE_CMP0(adc) (ADC->CMPR0 = 0)
/**
* @brief Configure the comparator 1 and enable it
* @param[in] adc Base address of ADC module
* @param[in] u32ChNum Specifies the source channel, valid value are from 0 to 7
* @param[in] u32Condition Specifies the compare condition
* - \ref ADC_CMP_LESS_THAN
* - \ref ADC_CMP_GREATER_OR_EQUAL_TO
* @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_CMP_GREATER_OR_EQUAL_TO, 0x800, 10);
* Means ADC will assert comparator 1 flag if channel 5 conversion result is
* greater or equal to 0x800 for 10 times continuously.
* \hideinitializer
*/
#define ADC_ENABLE_CMP1(adc, \
u32ChNum, \
u32Condition, \
u32Data, \
u32MatchCount) (ADC->CMPR1 = ((u32ChNum) << ADC_CMPR_CMPCH_Pos) | \
(u32Condition) | \
((u32Data) << ADC_CMPR_CMPD_Pos) | \
((u32MatchCount - 1) << ADC_CMPR_CMPMATCNT_Pos) |\
ADC_CMPR_CMPEN_Msk)
/**
* @brief Disable comparator 1
* @param[in] adc Base address of ADC module
* @return None
* \hideinitializer
*/
#define ADC_DISABLE_CMP1(adc) (ADC->CMPR1 = 0)
/**
* @brief Set ADC input channel. Enabled channel will be converted while ADC starts.
* @param[in] adc Base address of 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...
* @return None
* \hideinitializer
*/
#define ADC_SET_INPUT_CHANNEL(adc, u32Mask) (ADC->CHEN = (ADC->CHEN & ~ADC_CHEN_Msk) | (u32Mask))
/**
* @brief Start the A/D conversion.
* @param[in] adc Base address of ADC module
* @return None
* \hideinitializer
*/
#define ADC_START_CONV(adc) (ADC->CR |= ADC_CR_ADST_Msk)
/**
* @brief Stop the A/D conversion.
* @param[in] adc Base address of ADC module
* @return None
* \hideinitializer
*/
#define ADC_STOP_CONV(adc) (ADC->CR &= ~ADC_CR_ADST_Msk)
/**
* @brief Set the output format in differential input mode.
* @param[in] adc Base address of ADC module
* @param[in] u32Format Differential input mode output format. Valid values are:
* - \ref ADC_DMODE_OUT_FORMAT_UNSIGNED
* - \ref ADC_DMODE_OUT_FORMAT_2COMPLEMENT
* @return None
* \hideinitializer
*/
#define ADC_SET_DMOF(adc, u32Format) (ADC->CR = (ADC->CR & ~ADC_CR_DIFF_Msk) | u32Format)
/**
* @brief Set the resolution of conversion result.
* @param[in] adc Base address of ADC module
* @param[in] u32Resolution The resolution of conversion result. Valid values are:
* - \ref ADC_RESSEL_6_BIT
* - \ref ADC_RESSEL_8_BIT
* - \ref ADC_RESSEL_10_BIT
* - \ref ADC_RESSEL_12_BIT
* @return None
* \hideinitializer
*/
#define ADC_SET_RESOLUTION(adc, u32Resolution) (ADC->CR = (ADC->CR & ~ADC_CR_RESSEL_Msk) | u32Resolution)
/**
* @brief Set the reference voltage selection.
* @param[in] adc Base address of ADC module
* @param[in] u32Ref The reference voltage selection. Valid values are:
* - \ref ADC_REFSEL_POWER
* - \ref ADC_REFSEL_INT_VREF
* - \ref ADC_REFSEL_VREF
* @return None
* \hideinitializer
*/
#define ADC_SET_REF_VOLTAGE(adc, u32Ref) (ADC->CR = (ADC->CR & ~ADC_CR_REFSEL_Msk) | u32Ref)
/**
* @brief Set power down mode.
* @param[in] adc Base address of ADC module
* @param[in] u32Mode The power down mode. 0: power down mode, 2: standby mode
* @param[in] u32CalEn Do calibration when power up.
* @return None
* \hideinitializer
*/
#define ADC_SET_POWERDOWN_MODE(adc, u32Mode, u32CalEn) \
ADC->PWRCTL = (ADC->PWRCTL & ~(ADC_PWRCTL_PWDMOD_Msk | ADC_PWRCTL_PWDCALEN_Msk)) \
| (u32Mode << ADC_PWRCTL_PWDMOD_Pos) | (u32CalEn << ADC_PWRCTL_PWDCALEN_Pos)
/**
* @brief Enable PDMA transfer.
* @param[in] adc Base address of ADC module
* @return None
* \hideinitializer
*/
#define ADC_ENABLE_PDMA(adc) (ADC->CR |= ADC_CR_PTEN_Msk)
/**
* @brief Disable PDMA transfer.
* @param[in] adc Base address of ADC module
* @return None
* \hideinitializer
*/
#define ADC_DISABLE_PDMA(adc) (ADC->CR &= ~ADC_CR_PTEN_Msk)
/**
* @brief Get PDMA current transfer data
* @param[in] adc Base address of ADC module
* @return PDMA current transfer data
* \hideinitializer
*/
#define ADC_GET_PDMA_DATA(adc) (ADC->PDMA & ADC_PDMADATA_AD_PDMA_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_EnableTimerTrigger(ADC_T *adc,
uint32_t u32Source,
uint32_t u32PDMACnt);
void ADC_DisableTimerTrigger(ADC_T *adc);
void ADC_SetExtraSampleTime(ADC_T *adc,
uint32_t u32ChNum,
uint32_t u32SampleTime);
void ADC_EnableInt(ADC_T *adc, uint32_t u32Mask);
void ADC_DisableInt(ADC_T *adc, uint32_t u32Mask);
/*@}*/ /* end of group NANO100_ADC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_ADC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__ADC_H__
/*** (C) COPYRIGHT 2013-2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,628 @@
/**************************************************************************//**
* @file clk.c
* @version V1.00
* $Revision: 29 $
* $Date: 15/06/30 3:10p $
* @brief NANO100 series CLK driver source file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_CLK_Driver CLK Driver
@{
*/
/** @addtogroup NANO100_CLK_EXPORTED_FUNCTIONS CLK Exported Functions
@{
*/
/**
* @brief This function disable frequency output function.
* @param None
* @return None
*/
void CLK_DisableCKO(void)
{
/* Disable CKO0 clock source */
CLK->APBCLK &= (~CLK_APBCLK_FDIV_EN_Msk);
}
/**
* @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
* - \ref CLK_CLKSEL2_FRQDIV_S_HXT
* - \ref CLK_CLKSEL2_FRQDIV_S_LXT
* - \ref CLK_CLKSEL2_FRQDIV_S_HCLK
* - \ref CLK_CLKSEL2_FRQDIV_S_HIRC
* @param[in] u32ClkDiv is divider output frequency selection.
* @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)
{
/* CKO = clock source / 2^(u32ClkDiv + 1) */
CLK->FRQDIV = CLK_FRQDIV_FDIV_EN_Msk | u32ClkDiv ;
/* Enable CKO clock source */
CLK->APBCLK |= CLK_APBCLK_FDIV_EN_Msk;
/* Select CKO clock source */
CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_FRQDIV_S_Msk)) | u32ClkSrc;
}
/**
* @brief This function let system enter to Power-down mode.
* @param None
* @return None
*/
void CLK_PowerDown(void)
{
SCB->SCR = SCB_SCR_SLEEPDEEP_Msk;
CLK->PWRCTL |= (CLK_PWRCTL_PD_EN_Msk | CLK_PWRCTL_WK_DLY_Msk );
__WFI();
}
/**
* @brief This function let system enter to Idle mode
* @return None
*/
void CLK_Idle(void)
{
CLK->PWRCTL &= ~(CLK_PWRCTL_PD_EN_Msk );
__WFI();
}
/**
* @brief This function get external high frequency crystal frequency. The frequency unit is Hz.
* @param None
* @return None
*/
uint32_t CLK_GetHXTFreq(void)
{
if(CLK->PWRCTL & CLK_PWRCTL_HXT_EN )
return __HXT;
else
return 0;
}
/**
* @brief This function get external low frequency crystal frequency. The frequency unit is Hz.
* @return LXT frequency
*/
uint32_t CLK_GetLXTFreq(void)
{
if(CLK->PWRCTL & CLK_PWRCTL_LXT_EN )
return __LXT;
else
return 0;
}
/**
* @brief This function get HCLK frequency. The frequency unit is Hz.
* @param None
* @return HCLK frequency
*/
uint32_t CLK_GetHCLKFreq(void)
{
SystemCoreClockUpdate();
return SystemCoreClock;
}
/**
* @brief This function get CPU frequency. The frequency unit is Hz.
* @param None
* @return CPU frequency
*/
uint32_t CLK_GetCPUFreq(void)
{
SystemCoreClockUpdate();
return SystemCoreClock;
}
/**
* @brief This function get PLL frequency. The frequency unit is Hz.
* @param None
* @return PLL frequency
*/
uint32_t CLK_GetPLLClockFreq(void)
{
uint32_t u32Freq =0, u32PLLSrc;
uint32_t u32NO, u32NR, u32IN_DV, u32PllReg;
u32PllReg = CLK->PLLCTL;
if (u32PllReg & CLK_PLLCTL_PD)
return 0; /* PLL is in power down mode */
if (u32PllReg & CLK_PLLCTL_PLL_SRC_Msk)
u32PLLSrc = __HIRC12M;
else
u32PLLSrc = __HXT;
u32NO = (u32PllReg & CLK_PLLCTL_OUT_DV) ? 2: 1;
u32IN_DV = (u32PllReg & CLK_PLLCTL_IN_DV_Msk) >> 8;
if (u32IN_DV == 0)
u32NR = 2;
else if (u32IN_DV == 1)
u32NR = 4;
else if (u32IN_DV == 2)
u32NR = 8;
else
u32NR = 16;
u32Freq = u32PLLSrc * ((u32PllReg & CLK_PLLCTL_FB_DV_Msk) +32) / u32NR / u32NO;
return u32Freq;
}
/**
* @brief This function set HCLK frequency. The frequency unit is Hz. The range of u32Hclk is 24 ~ 42 MHz
* @param[in] u32Hclk is HCLK frequency
* @return None
*/
uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
{
uint32_t u32HIRCSTB;
/* Read HIRC clock source stable flag */
u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB_Msk;
if(u32Hclk==__HIRC12M) {
CLK_EnableXtalRC(CLK_PWRCTL_HIRC_EN_Msk);
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC,CLK_HCLK_CLK_DIVIDER(1));
return SystemCoreClock;
}
if(u32Hclk<FREQ_24MHZ) u32Hclk=FREQ_24MHZ;
if(u32Hclk>FREQ_42MHZ) u32Hclk=FREQ_42MHZ;
if(CLK->PWRCTL & CLK_PWRCTL_HXT_EN)
CLK_EnablePLL(CLK_PLLCTL_PLL_SRC_HXT,u32Hclk*2);
else {
CLK_EnablePLL(CLK_PLLCTL_PLL_SRC_HIRC,u32Hclk*2);
/* Read HIRC clock source stable flag */
u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB_Msk;
}
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL,CLK_HCLK_CLK_DIVIDER(2));
/* Disable HIRC if HIRC is disabled before setting core clock */
if(u32HIRCSTB == 0)
CLK->PWRCTL &= ~CLK_PWRCTL_HIRC_EN_Msk;
return SystemCoreClock;
}
/**
* @brief This function set HCLK clock source and HCLK clock divider
* @param[in] u32ClkSrc is HCLK clock source. Including :
* - \ref CLK_CLKSEL0_HCLK_S_HXT
* - \ref CLK_CLKSEL0_HCLK_S_LXT
* - \ref CLK_CLKSEL0_HCLK_S_PLL
* - \ref CLK_CLKSEL0_HCLK_S_LIRC
* - \ref CLK_CLKSEL0_HCLK_S_HIRC
* @param[in] u32ClkDiv is HCLK clock divider. Including :
* - \ref CLK_HCLK_CLK_DIVIDER(x)
* @return None
*/
void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
{
uint32_t u32HIRCSTB;
/* Read HIRC clock source stable flag */
u32HIRCSTB = CLK->CLKSTATUS & CLK_CLKSTATUS_HIRC_STB_Msk;
/* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */
CLK->PWRCTL |= CLK_PWRCTL_HIRC_EN_Msk;
CLK_WaitClockReady(CLK_CLKSTATUS_HIRC_STB_Msk);
CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLK_S_Msk)) | CLK_CLKSEL0_HCLK_S_HIRC;
CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_HCLK_N_Msk) | u32ClkDiv;
CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_HCLK_S_Msk) | u32ClkSrc;
SystemCoreClockUpdate();
/* Disable HIRC if HIRC is disabled before switching HCLK source */
if(u32HIRCSTB == 0)
CLK->PWRCTL &= ~CLK_CLKSTATUS_HIRC_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 GPIO_MODULE | x | x |
* |\ref DMA_MODULE | x | x |
* |\ref ISP_MODULE | x | x |
* |\ref EBI_MODULE | x | x |
* |\ref SRAM_MODULE | x | x |
* |\ref TICK_MODULE | x | x |
* |\ref SC2_MODULE |\ref CLK_CLKSEL2_SC_S_HXT |\ref CLK_SC2_CLK_DIVIDER(x) |
* |\ref SC2_MODULE |\ref CLK_CLKSEL2_SC_S_PLL |\ref CLK_SC2_CLK_DIVIDER(x) |
* |\ref SC2_MODULE |\ref CLK_CLKSEL2_SC_S_HIRC |\ref CLK_SC2_CLK_DIVIDER(x) |
* |\ref SC1_MODULE |\ref CLK_CLKSEL2_SC_S_HXT |\ref CLK_SC1_CLK_DIVIDER(x) |
* |\ref SC1_MODULE |\ref CLK_CLKSEL2_SC_S_PLL |\ref CLK_SC1_CLK_DIVIDER(x) |
* |\ref SC1_MODULE |\ref CLK_CLKSEL2_SC_S_HIRC |\ref CLK_SC1_CLK_DIVIDER(x) |
* |\ref SC0_MODULE |\ref CLK_CLKSEL2_SC_S_HXT |\ref CLK_SC0_CLK_DIVIDER(x) |
* |\ref SC0_MODULE |\ref CLK_CLKSEL2_SC_S_PLL |\ref CLK_SC0_CLK_DIVIDER(x) |
* |\ref SC0_MODULE |\ref CLK_CLKSEL2_SC_S_HIRC |\ref CLK_SC0_CLK_DIVIDER(x) |
* |\ref I2S_MODULE |\ref CLK_CLKSEL2_I2S_S_HXT |\ref CLK_I2S_CLK_DIVIDER(x) |
* |\ref I2S_MODULE |\ref CLK_CLKSEL2_I2S_S_PLL |\ref CLK_I2S_CLK_DIVIDER(x) |
* |\ref I2S_MODULE |\ref CLK_CLKSEL2_I2S_S_HIRC |\ref CLK_I2S_CLK_DIVIDER(x) |
* |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADC_S_HXT |\ref CLK_ADC_CLK_DIVIDER(x) |
* |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADC_S_LXT |\ref CLK_ADC_CLK_DIVIDER(x) |
* |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADC_S_PLL |\ref CLK_ADC_CLK_DIVIDER(x) |
* |\ref ADC_MODULE |\ref CLK_CLKSEL1_ADC_S_HIRC |\ref CLK_ADC_CLK_DIVIDER(x) |
* |\ref USBD_MODULE | x |\ref CLK_USB_CLK_DIVIDER(x) |
* |\ref PWM1_CH23_MODULE |\ref CLK_CLKSEL2_PWM1_CH23_S_HXT | x |
* |\ref PWM1_CH23_MODULE |\ref CLK_CLKSEL2_PWM1_CH23_S_LXT | x |
* |\ref PWM1_CH23_MODULE |\ref CLK_CLKSEL2_PWM1_CH23_S_HCLK | x |
* |\ref PWM1_CH23_MODULE |\ref CLK_CLKSEL2_PWM1_CH23_S_HIRC | x |
* |\ref PWM1_CH01_MODULE |\ref CLK_CLKSEL2_PWM1_CH01_S_HXT | x |
* |\ref PWM1_CH01_MODULE |\ref CLK_CLKSEL2_PWM1_CH01_S_LXT | x |
* |\ref PWM1_CH01_MODULE |\ref CLK_CLKSEL2_PWM1_CH01_S_HCLK | x |
* |\ref PWM1_CH01_MODULE |\ref CLK_CLKSEL2_PWM1_CH01_S_HIRC | x |
* |\ref LCD_MODULE |\ref CLK_CLKSEL1_LCD_S_LXT | x |
* |\ref PWM0_CH23_MODULE |\ref CLK_CLKSEL1_PWM0_CH23_S_HXT | x |
* |\ref PWM0_CH23_MODULE |\ref CLK_CLKSEL1_PWM0_CH23_S_LXT | x |
* |\ref PWM0_CH23_MODULE |\ref CLK_CLKSEL1_PWM0_CH23_S_HCLK | x |
* |\ref PWM0_CH23_MODULE |\ref CLK_CLKSEL1_PWM0_CH23_S_HIRC | x |
* |\ref PWM0_CH01_MODULE |\ref CLK_CLKSEL1_PWM0_CH01_S_HXT | x |
* |\ref PWM0_CH01_MODULE |\ref CLK_CLKSEL1_PWM0_CH01_S_LXT | x |
* |\ref PWM0_CH01_MODULE |\ref CLK_CLKSEL1_PWM0_CH01_S_HCLK | x |
* |\ref PWM0_CH01_MODULE |\ref CLK_CLKSEL1_PWM0_CH01_S_HIRC | x |
* |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART_S_HXT |\ref CLK_UART_CLK_DIVIDER(x) |
* |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART_S_LXT |\ref CLK_UART_CLK_DIVIDER(x) |
* |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART_S_PLL |\ref CLK_UART_CLK_DIVIDER(x) |
* |\ref UART1_MODULE |\ref CLK_CLKSEL1_UART_S_HIRC |\ref CLK_UART_CLK_DIVIDER(x) |
* |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART_S_HXT |\ref CLK_UART_CLK_DIVIDER(x) |
* |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART_S_LXT |\ref CLK_UART_CLK_DIVIDER(x) |
* |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART_S_PLL |\ref CLK_UART_CLK_DIVIDER(x) |
* |\ref UART0_MODULE |\ref CLK_CLKSEL1_UART_S_HIRC |\ref CLK_UART_CLK_DIVIDER(x) |
* |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2_S_PLL | x |
* |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2_S_HCLK | x |
* |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1_S_PLL | x |
* |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1_S_HCLK | x |
* |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0_S_PLL | x |
* |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0_S_HCLK | x |
* |\ref I2C1_MODULE | x | x |
* |\ref I2C0_MODULE | x | x |
* |\ref FDIV_MODULE |\ref CLK_CLKSEL2_FRQDIV_S_HXT | x |
* |\ref FDIV_MODULE |\ref CLK_CLKSEL2_FRQDIV_S_LXT | x |
* |\ref FDIV_MODULE |\ref CLK_CLKSEL2_FRQDIV_S_HCLK | x |
* |\ref FDIV_MODULE |\ref CLK_CLKSEL2_FRQDIV_S_HIRC | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL2_TMR3_S_HXT | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL2_TMR3_S_LXT | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL2_TMR3_S_LIRC | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL2_TMR3_S_EXT | x |
* |\ref TMR3_MODULE |\ref CLK_CLKSEL2_TMR3_S_HIRC | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL2_TMR2_S_HXT | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL2_TMR2_S_LXT | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL2_TMR2_S_LIRC | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL2_TMR2_S_EXT | x |
* |\ref TMR2_MODULE |\ref CLK_CLKSEL2_TMR2_S_HIRC | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_HXT | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_LXT | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_LIRC | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_EXT | x |
* |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1_S_HIRC | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_HXT | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_LXT | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_LIRC | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_EXT | x |
* |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0_S_HIRC | x |
* |\ref RTC_MODULE | x | x |
* |\ref WDT_MODULE | x | x |
* |
*/
void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
{
uint32_t u32tmp=0,u32sel=0,u32div=0;
if(MODULE_CLKDIV_Msk(u32ModuleIdx)!=MODULE_NoMsk) {
u32div =(uint32_t)&CLK->CLKDIV0+((MODULE_CLKDIV(u32ModuleIdx))*4);
u32tmp = *(volatile uint32_t *)(u32div);
u32tmp = ( u32tmp & ~(MODULE_CLKDIV_Msk(u32ModuleIdx)<<MODULE_CLKDIV_Pos(u32ModuleIdx)) ) | u32ClkDiv;
*(volatile uint32_t *)(u32div) = u32tmp;
}
if(MODULE_CLKSEL_Msk(u32ModuleIdx)!=MODULE_NoMsk) {
u32sel = (uint32_t)&CLK->CLKSEL0+((MODULE_CLKSEL(u32ModuleIdx))*4);
u32tmp = *(volatile uint32_t *)(u32sel);
u32tmp = ( u32tmp & ~(MODULE_CLKSEL_Msk(u32ModuleIdx)<<MODULE_CLKSEL_Pos(u32ModuleIdx)) ) | u32ClkSrc;
*(volatile uint32_t *)(u32sel) = u32tmp;
}
}
/**
* @brief This function enable clock source
* @param[in] u32ClkMask is clock source mask. Including:
* - \ref CLK_PWRCTL_HXT_EN_Msk
* - \ref CLK_PWRCTL_LXT_EN_Msk
* - \ref CLK_PWRCTL_HIRC_EN_Msk
* - \ref CLK_PWRCTL_LIRC_EN_Msk
* @return None
*/
void CLK_EnableXtalRC(uint32_t u32ClkMask)
{
CLK->PWRCTL |= u32ClkMask;
if(u32ClkMask & CLK_PWRCTL_HXT_EN_Msk)
CLK_WaitClockReady(CLK_CLKSTATUS_HXT_STB_Msk);
if(u32ClkMask & CLK_PWRCTL_LXT_EN_Msk)
CLK_WaitClockReady(CLK_CLKSTATUS_LXT_STB_Msk);
if(u32ClkMask & CLK_PWRCTL_HIRC_EN_Msk)
CLK_WaitClockReady(CLK_CLKSTATUS_HIRC_STB_Msk);
if(u32ClkMask & CLK_PWRCTL_LIRC_EN_Msk)
CLK_WaitClockReady(CLK_CLKSTATUS_LIRC_STB_Msk);
}
/**
* @brief This function disable clock source
* @param[in] u32ClkMask is clock source mask. Including:
* - \ref CLK_PWRCTL_HXT_EN_Msk
* - \ref CLK_PWRCTL_LXT_EN_Msk
* - \ref CLK_PWRCTL_HIRC_EN_Msk
* - \ref CLK_PWRCTL_LIRC_EN_Msk
* @return None
*/
void CLK_DisableXtalRC(uint32_t u32ClkMask)
{
CLK->PWRCTL &= ~u32ClkMask;
}
/**
* @brief This function enable module clock
* @param[in] u32ModuleIdx is module index. Including :
* - \ref GPIO_MODULE
* - \ref DMA_MODULE
* - \ref ISP_MODULE
* - \ref EBI_MODULE
* - \ref SRAM_MODULE
* - \ref TICK_MODULE
* - \ref SC2_MODULE
* - \ref SC1_MODULE
* - \ref SC0_MODULE
* - \ref USBD_MODULE
* - \ref I2S_MODULE
* - \ref ADC_MODULE
* - \ref PWM1_CH23_MODULE
* - \ref PWM1_CH01_MODULE
* - \ref PWM0_CH23_MODULE
* - \ref PWM0_CH01_MODULE
* - \ref UART1_MODULE
* - \ref UART0_MODULE
* - \ref SPI2_MODULE
* - \ref SPI1_MODULE
* - \ref SPI0_MODULE
* - \ref I2C1_MODULE
* - \ref I2C0_MODULE
* - \ref FDIV_MODULE
* - \ref TMR3_MODULE
* - \ref TMR2_MODULE
* - \ref TMR1_MODULE
* - \ref TMR0_MODULE
* - \ref RTC_MODULE
* - \ref WDT_MODULE
* - \ref LCD_MODULE
* - \ref DAC_MODULE
* @return None
*/
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
{
*(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) |= 1<<MODULE_IP_EN_Pos(u32ModuleIdx);
}
/**
* @brief This function disable module clock
* @param[in] u32ModuleIdx is module index. Including :
* - \ref GPIO_MODULE
* - \ref DMA_MODULE
* - \ref ISP_MODULE
* - \ref EBI_MODULE
* - \ref SRAM_MODULE
* - \ref TICK_MODULE
* - \ref SC2_MODULE
* - \ref SC1_MODULE
* - \ref SC0_MODULE
* - \ref USBD_MODULE
* - \ref I2S_MODULE
* - \ref ADC_MODULE
* - \ref PWM1_CH23_MODULE
* - \ref PWM1_CH01_MODULE
* - \ref PWM0_CH23_MODULE
* - \ref PWM0_CH01_MODULE
* - \ref UART1_MODULE
* - \ref UART0_MODULE
* - \ref SPI2_MODULE
* - \ref SPI1_MODULE
* - \ref SPI0_MODULE
* - \ref I2C1_MODULE
* - \ref I2C0_MODULE
* - \ref FDIV_MODULE
* - \ref TMR3_MODULE
* - \ref TMR2_MODULE
* - \ref TMR1_MODULE
* - \ref TMR0_MODULE
* - \ref RTC_MODULE
* - \ref WDT_MODULE
* - \ref LCD_MODULE
* - \ref DAC_MODULE
* @return None
*/
void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
{
*(volatile uint32_t *)((uint32_t)&CLK->AHBCLK+(MODULE_APBCLK(u32ModuleIdx)*4)) &= ~(1<<MODULE_IP_EN_Pos(u32ModuleIdx));
}
/**
* @brief This function set PLL frequency
* @param[in] u32PllClkSrc is PLL clock source. Including :
* - \ref CLK_PLLCTL_PLL_SRC_HIRC
* - \ref CLK_PLLCTL_PLL_SRC_HXT
* @param[in] u32PllFreq is PLL frequency
* @return None
*/
uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
{
uint32_t u32ClkSrc,u32NR, u32NF,u32Register;
uint32_t u32NRTable[4]= {2,4,8,16};
int32_t i32NRVal;
if ( u32PllFreq < FREQ_48MHZ)
u32PllFreq=FREQ_48MHZ;
else if(u32PllFreq > FREQ_120MHZ)
u32PllFreq=FREQ_120MHZ;
if(u32PllClkSrc!=CLK_PLLCTL_PLL_SRC_HIRC) {
/* PLL source clock from HXT */
u32Register = (0x0UL<<CLK_PLLCTL_PLL_SRC_Pos);
u32ClkSrc = __HXT;
} else {
/* PLL source clock from HIRC */
u32Register = (0x1UL<<CLK_PLLCTL_PLL_SRC_Pos);
u32ClkSrc =__HIRC12M;
}
u32NF = u32PllFreq / 1000000;
u32NR = u32ClkSrc / 1000000;
if(u32ClkSrc%12==0) {
u32NF=(u32NF/3)*4;
u32NR=(u32NR/3)*4;
}
while( u32NR>16 || u32NF>(0x3F+32) ) {
u32NR = u32NR>>1;
u32NF = u32NF>>1;
}
for(i32NRVal=3; i32NRVal>=0; i32NRVal--)
if(u32NR==u32NRTable[i32NRVal]) break;
CLK->PLLCTL = u32Register | (i32NRVal<<8) | (u32NF - 32) ;
CLK->PLLCTL &= ~CLK_PLLCTL_PD_Msk;
CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk);
return CLK_GetPLLClockFreq();
}
/**
* @brief This function disable PLL
* @param None
* @return None
*/
void CLK_DisablePLL(void)
{
CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
}
/**
* @brief This function execute delay function.
* @param us Delay time. The Max value is 2^24 / CPU Clock(MHz). Ex:
* 50MHz => 335544us, 48MHz => 349525us, 28MHz => 699050us ...
* @return None
* @details Use the SysTick to generate the delay time and the UNIT is in us.
* The SysTick clock source is from HCLK, i.e the same as system core clock.
*/
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);
SysTick->CTRL = 0;
}
/**
* @brief Enable System Tick counter
* @param[in] u32ClkSrc is System Tick clock source. Including:
* - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV8
* - \ref CLK_CLKSEL0_STCLKSEL_HCLK
* @param[in] u32Count is System Tick reload value. It should be 0x1~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)
{
SysTick->CTRL=0;
if( u32ClkSrc== CLK_CLKSEL0_STCLKSEL_HCLK ) /* Set System Tick clock source */
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
else {
SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
}
SysTick->LOAD = u32Count; /* Set System Tick reload value */
SysTick->VAL = 0; /* Clear System Tick current value and counter flag */
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* Set System Tick counter enabled */
}
/**
* @brief Disable System Tick counter
* @return None
* @details This function disable System Tick counter.
*/
void CLK_DisableSysTick(void)
{
SysTick->CTRL = 0; /* Set System Tick counter disabled */
}
/**
* @brief This function check selected clock source status
* @param[in] u32ClkMask is selected clock source. Including
* - \ref CLK_CLKSTATUS_CLK_SW_FAIL_Msk
* - \ref CLK_CLKSTATUS_HIRC_STB_Msk
* - \ref CLK_CLKSTATUS_LIRC_STB_Msk
* - \ref CLK_CLKSTATUS_PLL_STB_Msk
* - \ref CLK_CLKSTATUS_LXT_STB_Msk
* - \ref CLK_CLKSTATUS_HXT_STB_Msk
* @return 0 clock is not stable
* 1 clock is stable
*
* @details To wait for clock ready by specified CLKSTATUS bit or timeout (~5ms)
*/
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
{
int32_t i32TimeOutCnt;
i32TimeOutCnt = __HSI / 200; /* About 5ms */
while((CLK->CLKSTATUS & u32ClkMask) != u32ClkMask) {
if(i32TimeOutCnt-- <= 0)
return 0;
}
return 1;
}
/*@}*/ /* end of group NANO100_CLK_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_CLK_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,367 @@
/**************************************************************************//**
* @file clk.h
* @version V1.00
* $Revision: 20 $
* $Date: 15/07/08 10:00a $
* @brief Nano100 series CLK driver header file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __CLK_H__
#define __CLK_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_CLK_Driver CLK Driver
@{
*/
/** @addtogroup NANO100_CLK_EXPORTED_CONSTANTS CLK Exported Constants
@{
*/
#define FREQ_128MHZ 128000000
#define FREQ_120MHZ 120000000
#define FREQ_48MHZ 48000000
#define FREQ_42MHZ 42000000
#define FREQ_32MHZ 32000000
#define FREQ_24MHZ 24000000
#define FREQ_12MHZ 12000000
/********************* Bit definition of PWRCTL register **********************/
#define CLK_PWRCTL_HXT_EN (0x1UL<<CLK_PWRCTL_HXT_EN_Pos) /*!<Enable high speed crystal */
#define CLK_PWRCTL_LXT_EN (0x1UL<<CLK_PWRCTL_LXT_EN_Pos) /*!<Enable low speed crystal */
#define CLK_PWRCTL_HIRC_EN (0x1UL<<CLK_PWRCTL_HIRC_EN_Pos) /*!<Enable internal high speed oscillator */
#define CLK_PWRCTL_LIRC_EN (0x1UL<<CLK_PWRCTL_LIRC_EN_Pos) /*!<Enable internal low speed oscillator */
#define CLK_PWRCTL_DELY_EN (0x1UL<<CLK_PWRCTL_WK_DLY_Pos) /*!<Enable the wake-up delay counter */
#define CLK_PWRCTL_WAKEINT_EN (0x1UL<<CLK_PWRCTL_PD_WK_IE_Pos) /*!<Enable the wake-up interrupt */
#define CLK_PWRCTL_PWRDOWN_EN (0x1UL<<CLK_PWRCTL_PD_EN_Pos) /*!<Power down enable bit */
#define CLK_PWRCTL_HXT_SELXT (0x1UL<<CLK_PWRCTL_HXT_SELXT_Pos) /*!<High frequency crystal loop back path Enabled */
#define CLK_PWRCTL_HXT_GAIN (0x1UL<<CLK_PWRCTL_HXT_GAIN_Pos) /*!<High frequency crystal Gain control Enabled */
#define CLK_PWRCTL_LXT_SCNT (0x1UL<<CLK_PWRCTL_LXT_SCNT_Pos) /*!<Delay 8192 LXT before LXT output */
/********************* Bit definition of AHBCLK register **********************/
#define CLK_AHBCLK_GPIO_EN (0x1UL<<CLK_AHBCLK_GPIO_EN_Pos) /*!<GPIO clock enable */
#define CLK_AHBCLK_DMA_EN (0x1UL<<CLK_AHBCLK_DMA_EN_Pos) /*!<DMA clock enable */
#define CLK_AHBCLK_ISP_EN (0x1UL<<CLK_AHBCLK_ISP_EN_Pos) /*!<Flash ISP controller clock enable */
#define CLK_AHBCLK_EBI_EN (0x1UL<<CLK_AHBCLK_EBI_EN_Pos) /*!<EBI clock enable */
#define CLK_AHBCLK_SRAM_EN (0x1UL<<CLK_AHBCLK_SRAM_EN_Pos) /*!<SRAM Controller Clock Enable */
#define CLK_AHBCLK_TICK_EN (0x1UL<<CLK_AHBCLK_TICK_EN_Pos) /*!<System Tick Clock Enable */
/********************* Bit definition of APBCLK register **********************/
#define CLK_APBCLK_WDT_EN (0x1UL<<CLK_APBCLK_WDT_EN_Pos) /*!<Watchdog clock enable */
#define CLK_APBCLK_RTC_EN (0x1UL<<CLK_APBCLK_RTC_EN_Pos) /*!<RTC clock enable */
#define CLK_APBCLK_TMR0_EN (0x1UL<<CLK_APBCLK_TMR0_EN_Pos) /*!<Timer 0 clock enable */
#define CLK_APBCLK_TMR1_EN (0x1UL<<CLK_APBCLK_TMR1_EN_Pos) /*!<Timer 1 clock enable */
#define CLK_APBCLK_TMR2_EN (0x1UL<<CLK_APBCLK_TMR2_EN_Pos) /*!<Timer 2 clock enable */
#define CLK_APBCLK_TMR3_EN (0x1UL<<CLK_APBCLK_TMR3_EN_Pos) /*!<Timer 3 clock enable */
#define CLK_APBCLK_FDIV_EN (0x1UL<<CLK_APBCLK_FDIV_EN_Pos) /*!<Frequency Divider Output clock enable */
#define CLK_APBCLK_SC2_EN (0x1UL<<CLK_APBCLK_SC2_EN_Pos) /*!<SmartCard 2 Clock Enable Control */
#define CLK_APBCLK_I2C0_EN (0x1UL<<CLK_APBCLK_I2C0_EN_Pos) /*!<I2C 0 clock enable */
#define CLK_APBCLK_I2C1_EN (0x1UL<<CLK_APBCLK_I2C1_EN_Pos) /*!<I2C 1 clock enable */
#define CLK_APBCLK_SPI0_EN (0x1UL<<CLK_APBCLK_SPI0_EN_Pos) /*!<SPI 0 clock enable */
#define CLK_APBCLK_SPI1_EN (0x1UL<<CLK_APBCLK_SPI1_EN_Pos) /*!<SPI 1 clock enable */
#define CLK_APBCLK_SPI2_EN (0x1UL<<CLK_APBCLK_SPI2_EN_Pos) /*!<SPI 2 clock enable */
#define CLK_APBCLK_UART0_EN (0x1UL<<CLK_APBCLK_UART0_EN_Pos) /*!<UART 0 clock enable */
#define CLK_APBCLK_UART1_EN (0x1UL<<CLK_APBCLK_UART1_EN_Pos) /*!<UART 1 clock enable */
#define CLK_APBCLK_PWM0_CH01_EN (0x1UL<<CLK_APBCLK_PWM0_CH01_EN_Pos) /*!<PWM0 Channel 0 and Channel 1 Clock Enable Control */
#define CLK_APBCLK_PWM0_CH23_EN (0x1UL<<CLK_APBCLK_PWM0_CH23_EN_Pos) /*!<PWM0 Channel 2 and Channel 3 Clock Enable Control */
#define CLK_APBCLK_PWM1_CH01_EN (0x1UL<<CLK_APBCLK_PWM1_CH01_EN_Pos) /*!<PWM1 Channel 0 and Channel 1 Clock Enable Control */
#define CLK_APBCLK_PWM1_CH23_EN (0x1UL<<CLK_APBCLK_PWM1_CH23_EN_Pos) /*!<PWM1 Channel 2 and Channel 3 Clock Enable Control */
#define CLK_APBCLK_DAC_EN (0x1UL<<CLK_APBCLK_DAC_EN_Pos) /*!<DAC Clock Enable Control */
#define CLK_APBCLK_LCD_EN (0x1UL<<CLK_APBCLK_LCD_EN_Pos) /*!<LCD Clock Enable Control */
#define CLK_APBCLK_USBD_EN (0x1UL<<CLK_APBCLK_USBD_EN_Pos) /*!<USB device clock enable */
#define CLK_APBCLK_ADC_EN (0x1UL<<CLK_APBCLK_ADC_EN_Pos) /*!<ADC clock enable */
#define CLK_APBCLK_I2S_EN (0x1UL<<CLK_APBCLK_I2S_EN_Pos) /*!<I2S clock enable */
#define CLK_APBCLK_SC0_EN (0x1UL<<CLK_APBCLK_SC0_EN_Pos) /*!<SmartCard 0 Clock Enable Control */
#define CLK_APBCLK_SC1_EN (0x1UL<<CLK_APBCLK_SC1_EN_Pos) /*!<SmartCard 1 Clock Enable Control */
/********************* Bit definition of CLKSTATUS register **********************/
#define CLK_CLKSTATUS_HXT_STB (0x1UL<<CLK_CLKSTATUS_HXT_STB_Pos) /*!<External high speed crystal clock source stable flag */
#define CLK_CLKSTATUS_LXT_STB (0x1UL<<CLK_CLKSTATUS_LXT_STB_Pos) /*!<External low speed crystal clock source stable flag */
#define CLK_CLKSTATUS_PLL_STB (0x1UL<<CLK_CLKSTATUS_PLL_STB_Pos) /*!<Internal PLL clock source stable flag */
#define CLK_CLKSTATUS_LIRC_STB (0x1UL<<CLK_CLKSTATUS_LIRC_STB_Pos) /*!<Internal low speed oscillator clock source stable flag */
#define CLK_CLKSTATUS_HIRC_STB (0x1UL<<CLK_CLKSTATUS_HIRC_STB_Pos) /*!<Internal high speed oscillator clock source stable flag */
#define CLK_CLKSTATUS_CLK_SW_FAIL (0x1UL<<CLK_CLKSTATUS_CLK_SW_FAIL_Pos) /*!<Clock switch fail flag */
/********************* Bit definition of CLKSEL0 register **********************/
#define CLK_CLKSEL0_HCLK_S_HXT (0UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!<Select HCLK clock source from high speed crystal */
#define CLK_CLKSEL0_HCLK_S_LXT (1UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!<Select HCLK clock source from low speed crystal */
#define CLK_CLKSEL0_HCLK_S_PLL (2UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!<Select HCLK clock source from PLL */
#define CLK_CLKSEL0_HCLK_S_LIRC (3UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!<Select HCLK clock source from low speed oscillator */
#define CLK_CLKSEL0_HCLK_S_HIRC (7UL<<CLK_CLKSEL0_HCLK_S_Pos) /*!<Select HCLK clock source from high speed oscillator */
/********************* Bit definition of CLKSEL1 register **********************/
#define CLK_CLKSEL1_LCD_S_LXT (0x0UL<<CLK_CLKSEL1_LCD_S_Pos) /*!<Select LCD clock source from low speed crystal */
#define CLK_CLKSEL1_TMR1_S_HXT (0x0UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!<Select TMR1 clock source from high speed crystal */
#define CLK_CLKSEL1_TMR1_S_LXT (0x1UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!<Select TMR1 clock source from low speed crystal */
#define CLK_CLKSEL1_TMR1_S_LIRC (0x2UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!<Select TMR1 clock source from low speed oscillator */
#define CLK_CLKSEL1_TMR1_S_EXT (0x3UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!<Select TMR1 clock source from external trigger */
#define CLK_CLKSEL1_TMR1_S_HIRC (0x4UL<<CLK_CLKSEL1_TMR1_S_Pos) /*!<Select TMR1 clock source from high speed oscillator */
#define CLK_CLKSEL1_TMR0_S_HXT (0x0UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!<Select TMR0 clock source from high speed crystal */
#define CLK_CLKSEL1_TMR0_S_LXT (0x1UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!<Select TMR0 clock source from low speed crystal */
#define CLK_CLKSEL1_TMR0_S_LIRC (0x2UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!<Select TMR0 clock source from low speed oscillator */
#define CLK_CLKSEL1_TMR0_S_EXT (0x3UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!<Select TMR0 clock source from external trigger */
#define CLK_CLKSEL1_TMR0_S_HIRC (0x4UL<<CLK_CLKSEL1_TMR0_S_Pos) /*!<Select TMR0 clock source from high speed oscillator */
#define CLK_CLKSEL1_PWM0_CH01_S_HXT (0x0UL<<CLK_CLKSEL1_PWM0_CH01_S_Pos) /*!<Select PWM0_CH01 clock source from high speed crystal */
#define CLK_CLKSEL1_PWM0_CH01_S_LXT (0x1UL<<CLK_CLKSEL1_PWM0_CH01_S_Pos) /*!<Select PWM0_CH01 clock source from low speed crystal */
#define CLK_CLKSEL1_PWM0_CH01_S_HCLK (0x2UL<<CLK_CLKSEL1_PWM0_CH01_S_Pos) /*!<Select PWM0_CH01 clock source from HCLK */
#define CLK_CLKSEL1_PWM0_CH01_S_HIRC (0x3UL<<CLK_CLKSEL1_PWM0_CH01_S_Pos) /*!<Select PWM0_CH01 clock source from high speed oscillator */
#define CLK_CLKSEL1_PWM0_CH23_S_HXT (0x0UL<<CLK_CLKSEL1_PWM0_CH23_S_Pos) /*!<Select PWM0_CH23 clock source from high speed crystal */
#define CLK_CLKSEL1_PWM0_CH23_S_LXT (0x1UL<<CLK_CLKSEL1_PWM0_CH23_S_Pos) /*!<Select PWM0_CH23 clock source from low speed crystal */
#define CLK_CLKSEL1_PWM0_CH23_S_HCLK (0x2UL<<CLK_CLKSEL1_PWM0_CH23_S_Pos) /*!<Select PWM0_CH23 clock source from HCLK */
#define CLK_CLKSEL1_PWM0_CH23_S_HIRC (0x3UL<<CLK_CLKSEL1_PWM0_CH23_S_Pos) /*!<Select PWM0_CH23 clock source from high speed oscillator */
#define CLK_CLKSEL1_ADC_S_HXT (0x0UL<<CLK_CLKSEL1_ADC_S_Pos) /*!<Select ADC clock source from high speed crystal */
#define CLK_CLKSEL1_ADC_S_LXT (0x1UL<<CLK_CLKSEL1_ADC_S_Pos) /*!<Select ADC clock source from low speed crystal */
#define CLK_CLKSEL1_ADC_S_PLL (0x2UL<<CLK_CLKSEL1_ADC_S_Pos) /*!<Select ADC clock source from PLL */
#define CLK_CLKSEL1_ADC_S_HIRC (0x3UL<<CLK_CLKSEL1_ADC_S_Pos) /*!<Select ADC clock source from high speed oscillator */
#define CLK_CLKSEL1_UART_S_HXT (0x0UL<<CLK_CLKSEL1_UART_S_Pos) /*!<Select UART clock source from high speed crystal */
#define CLK_CLKSEL1_UART_S_LXT (0x1UL<<CLK_CLKSEL1_UART_S_Pos) /*!<Select UART clock source from low speed crystal */
#define CLK_CLKSEL1_UART_S_PLL (0x2UL<<CLK_CLKSEL1_UART_S_Pos) /*!<Select UART clock source from PLL */
#define CLK_CLKSEL1_UART_S_HIRC (0x3UL<<CLK_CLKSEL1_UART_S_Pos) /*!<Select UART clock source from high speed oscillator */
/********************* Bit definition of CLKSEL2 register **********************/
#define CLK_CLKSEL2_SPI2_S_PLL (0x0UL<<CLK_CLKSEL2_SPI2_S_Pos) /*!<Select SPI2 clock source from PLL */
#define CLK_CLKSEL2_SPI2_S_HCLK (0x1UL<<CLK_CLKSEL2_SPI2_S_Pos) /*!<Select SPI2 clock source from HCLK */
#define CLK_CLKSEL2_SPI1_S_PLL (0x0UL<<CLK_CLKSEL2_SPI1_S_Pos) /*!<Select SPI1 clock source from PLL */
#define CLK_CLKSEL2_SPI1_S_HCLK (0x1UL<<CLK_CLKSEL2_SPI1_S_Pos) /*!<Select SPI1 clock source from HCLK */
#define CLK_CLKSEL2_SPI0_S_PLL (0x0UL<<CLK_CLKSEL2_SPI0_S_Pos) /*!<Select SPI0 clock source from PLL */
#define CLK_CLKSEL2_SPI0_S_HCLK (0x1UL<<CLK_CLKSEL2_SPI0_S_Pos) /*!<Select SPI0 clock source from HCLK */
#define CLK_CLKSEL2_SC_S_HXT (0x0UL<<CLK_CLKSEL2_SC_S_Pos) /*!<Select SmartCard clock source from HXT */
#define CLK_CLKSEL2_SC_S_PLL (0x1UL<<CLK_CLKSEL2_SC_S_Pos) /*!<Select smartCard clock source from PLL */
#define CLK_CLKSEL2_SC_S_HIRC (0x2UL<<CLK_CLKSEL2_SC_S_Pos) /*!<Select SmartCard clock source from HIRC */
#define CLK_CLKSEL2_I2S_S_HXT (0x0UL<<CLK_CLKSEL2_I2S_S_Pos) /*!<Select I2S clock source from HXT */
#define CLK_CLKSEL2_I2S_S_PLL (0x1UL<<CLK_CLKSEL2_I2S_S_Pos) /*!<Select I2S clock source from PLL */
#define CLK_CLKSEL2_I2S_S_HIRC (0x2UL<<CLK_CLKSEL2_I2S_S_Pos) /*!<Select I2S clock source from HIRC */
#define CLK_CLKSEL2_TMR3_S_HXT (0x0UL<<CLK_CLKSEL2_TMR3_S_Pos) /*!<Select TMR3 clock source from high speed crystal */
#define CLK_CLKSEL2_TMR3_S_LXT (0x1UL<<CLK_CLKSEL2_TMR3_S_Pos) /*!<Select TMR3 clock source from low speed crystal */
#define CLK_CLKSEL2_TMR3_S_LIRC (0x2UL<<CLK_CLKSEL2_TMR3_S_Pos) /*!<Select TMR3 clock source from low speed oscillator */
#define CLK_CLKSEL2_TMR3_S_EXT (0x3UL<<CLK_CLKSEL2_TMR3_S_Pos) /*!<Select TMR3 clock source from external trigger */
#define CLK_CLKSEL2_TMR3_S_HIRC (0x4UL<<CLK_CLKSEL2_TMR3_S_Pos) /*!<Select TMR3 clock source from high speed oscillator */
#define CLK_CLKSEL2_TMR2_S_HXT (0x0UL<<CLK_CLKSEL2_TMR2_S_Pos) /*!<Select TMR2 clock source from high speed crystal */
#define CLK_CLKSEL2_TMR2_S_LXT (0x1UL<<CLK_CLKSEL2_TMR2_S_Pos) /*!<Select TMR2 clock source from low speed crystal */
#define CLK_CLKSEL2_TMR2_S_LIRC (0x2UL<<CLK_CLKSEL2_TMR2_S_Pos) /*!<Select TMR2 clock source from low speed oscillator */
#define CLK_CLKSEL2_TMR2_S_EXT (0x3UL<<CLK_CLKSEL2_TMR2_S_Pos) /*!<Select TMR2 clock source from external trigger */
#define CLK_CLKSEL2_TMR2_S_HIRC (0x4UL<<CLK_CLKSEL2_TMR2_S_Pos) /*!<Select TMR2 clock source from high speed oscillator */
#define CLK_CLKSEL2_PWM1_CH01_S_HXT (0x0UL<<CLK_CLKSEL2_PWM1_CH01_S_Pos) /*!<Select PWM1_CH01 clock source from high speed crystal */
#define CLK_CLKSEL2_PWM1_CH01_S_LXT (0x1UL<<CLK_CLKSEL2_PWM1_CH01_S_Pos) /*!<Select PWM1_CH01 clock source from low speed crystal */
#define CLK_CLKSEL2_PWM1_CH01_S_HCLK (0x2UL<<CLK_CLKSEL2_PWM1_CH01_S_Pos) /*!<Select PWM1_CH01 clock source from HCLK */
#define CLK_CLKSEL2_PWM1_CH01_S_HIRC (0x3UL<<CLK_CLKSEL2_PWM1_CH01_S_Pos) /*!<Select PWM1_CH01 clock source from high speed oscillator */
#define CLK_CLKSEL2_PWM1_CH23_S_HXT (0x0UL<<CLK_CLKSEL2_PWM1_CH23_S_Pos) /*!<Select PWM1_CH23 clock source from high speed crystal */
#define CLK_CLKSEL2_PWM1_CH23_S_LXT (0x1UL<<CLK_CLKSEL2_PWM1_CH23_S_Pos) /*!<Select PWM1_CH23 clock source from low speed crystal */
#define CLK_CLKSEL2_PWM1_CH23_S_HCLK (0x2UL<<CLK_CLKSEL2_PWM1_CH23_S_Pos) /*!<Select PWM1_CH23 clock source from HCLK */
#define CLK_CLKSEL2_PWM1_CH23_S_HIRC (0x3UL<<CLK_CLKSEL2_PWM1_CH23_S_Pos) /*!<Select PWM1_CH23 clock source from high speed oscillator */
#define CLK_CLKSEL2_FRQDIV_S_HXT (0x0UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!<Select FRQDIV clock source from HXT */
#define CLK_CLKSEL2_FRQDIV_S_LXT (0x1UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!<Select FRQDIV clock source from LXT */
#define CLK_CLKSEL2_FRQDIV_S_HCLK (0x2UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!<Select FRQDIV clock source from HCLK */
#define CLK_CLKSEL2_FRQDIV_S_HIRC (0x3UL<<CLK_CLKSEL2_FRQDIV_S_Pos) /*!<Select FRQDIV clock source from HIRC */
/********************* Bit definition of CLKDIV0 register **********************/
#define CLK_HCLK_CLK_DIVIDER(x) (((x-1)<< CLK_CLKDIV0_HCLK_N_Pos) & CLK_CLKDIV0_HCLK_N_Msk) /*!< CLKDIV0 Setting for HCLK clock divider. It could be 1~16 */
#define CLK_USB_CLK_DIVIDER(x) (((x-1)<< CLK_CLKDIV0_USB_N_Pos) & CLK_CLKDIV0_USB_N_Msk) /*!< CLKDIV0 Setting for HCLK clock divider. It could be 1~16 */
#define CLK_UART_CLK_DIVIDER(x) (((x-1)<< CLK_CLKDIV0_UART_N_Pos) & CLK_CLKDIV0_UART_N_Msk) /*!< CLKDIV0 Setting for UART clock divider. It could be 1~16 */
#define CLK_ADC_CLK_DIVIDER(x) (((x-1)<< CLK_CLKDIV0_ADC_N_Pos) & CLK_CLKDIV0_ADC_N_Msk) /*!< CLKDIV0 Setting for ADC clock divider. It could be 1~256 */
#define CLK_SC0_CLK_DIVIDER(x) (((x-1)<< CLK_CLKDIV0_SC0_N_Pos) & CLK_CLKDIV0_SC0_N_Msk) /*!< CLKDIV0 Setting for SmartCard0 clock divider. It could be 1~16 */
#define CLK_I2S_CLK_DIVIDER(x) (((x-1)<< CLK_CLKDIV0_I2S_N_Pos) & CLK_CLKDIV0_I2S_N_Msk) /*!< CLKDIV0 Setting for I2S clock divider. It could be 1~16 */
/********************* Bit definition of CLKDIV1 register **********************/
#define CLK_SC2_CLK_DIVIDER(x) (((x-1)<< CLK_CLKDIV1_SC2_N_Pos ) & CLK_CLKDIV1_SC2_N_Msk) /*!< CLKDIV1 Setting for SmartCard2 clock divider. It could be 1~16 */
#define CLK_SC1_CLK_DIVIDER(x) (((x-1)<< CLK_CLKDIV1_SC1_N_Pos ) & CLK_CLKDIV1_SC1_N_Msk) /*!< CLKDIV1 Setting for SmartCard1 clock divider. It could be 1~16 */
/********************* Bit definition of SysTick register **********************/
#define CLK_CLKSEL0_STCLKSEL_HCLK (1) /*!< Setting systick clock source as external HCLK */
#define CLK_CLKSEL0_STCLKSEL_HCLK_DIV8 (2) /*!< Setting systick clock source as external HCLK/8 */
/********************* Bit definition of PLLCTL register **********************/
#define CLK_PLLCTL_OUT_DV (0x1UL<<CLK_PLLCTL_OUT_DV_Pos) /*!<PLL Output Divider Control */
#define CLK_PLLCTL_PD (0x1UL<<CLK_PLLCTL_PD_Pos) /*!<PLL Power down mode */
#define CLK_PLLCTL_PLL_SRC_HIRC (0x1UL<<CLK_PLLCTL_PLL_SRC_Pos) /*!<PLL clock source from high speed oscillator */
#define CLK_PLLCTL_PLL_SRC_HXT (0x0UL<<CLK_PLLCTL_PLL_SRC_Pos) /*!<PLL clock source from high speed crystal */
#define CLK_PLLCTL_NR_2 0x000 /*!< For PLL input divider is 2 */
#define CLK_PLLCTL_NR_4 0x100 /*!< For PLL input divider is 4 */
#define CLK_PLLCTL_NR_8 0x200 /*!< For PLL input divider is 8 */
#define CLK_PLLCTL_NR_16 0x300 /*!< For PLL input divider is 16 */
#define CLK_PLLCON_NF(x) ((x)-32) /*!< x must be constant and 32 <= x <= 95.) */
#define CLK_PLLCON_NO_1 0x0000UL /*!< For PLL output divider is 1 */
#define CLK_PLLCON_NO_2 0x1000UL /*!< For PLL output divider is 2 */
#if (__HXT == 12000000)
#define CLK_PLLCTL_120MHz_HXT (CLK_PLLCTL_PLL_SRC_HXT | CLK_PLLCON_NO_1 | CLK_PLLCTL_NR_4 | CLK_PLLCON_NF(40) ) /*!< Predefined PLLCTL setting for 120MHz PLL output with 12MHz X'tal */
#define CLK_PLLCTL_96MHz_HXT (CLK_PLLCTL_PLL_SRC_HXT | CLK_PLLCON_NO_1 | CLK_PLLCTL_NR_8 | CLK_PLLCON_NF(64) ) /*!< Predefined PLLCTL setting for 96MHz PLL output with 12MHz X'tal */
#define CLK_PLLCTL_48MHz_HXT (CLK_PLLCTL_PLL_SRC_HXT | CLK_PLLCON_NO_1 | CLK_PLLCTL_NR_16| CLK_PLLCON_NF(64) ) /*!< Predefined PLLCTL setting for 48MHz PLL output with 12MHz X'tal */
#define CLK_PLLCTL_84MHz_HXT (CLK_PLLCTL_PLL_SRC_HXT | CLK_PLLCON_NO_1 | CLK_PLLCTL_NR_8 | CLK_PLLCON_NF(56) ) /*!< Predefined PLLCTL setting for 84MHz PLL output with 12MHz X'tal */
#define CLK_PLLCTL_42MHz_HXT (CLK_PLLCTL_PLL_SRC_HXT | CLK_PLLCON_NO_1 | CLK_PLLCTL_NR_16| CLK_PLLCON_NF(56) ) /*!< Predefined PLLCTL setting for 42MHz PLL output with 12MHz X'tal */
#else
# error "The PLL pre-definitions are only valid when external crystal is 12MHz"
#endif
#define CLK_PLLCTL_120MHz_HIRC (CLK_PLLCTL_PLL_SRC_HIRC | CLK_PLLCON_NO_1 | CLK_PLLCTL_NR_4 | CLK_PLLCON_NF(40) ) /*!< Predefined PLLCTL setting for 120MHz PLL output with 12MHz IRC */
#define CLK_PLLCTL_96MHz_HIRC (CLK_PLLCTL_PLL_SRC_HIRC | CLK_PLLCON_NO_1 | CLK_PLLCTL_NR_8 | CLK_PLLCON_NF(64) ) /*!< Predefined PLLCTL setting for 96MHz PLL output with 12MHz IRC */
#define CLK_PLLCTL_48MHz_HIRC (CLK_PLLCTL_PLL_SRC_HIRC | CLK_PLLCON_NO_1 | CLK_PLLCTL_NR_16| CLK_PLLCON_NF(64) ) /*!< Predefined PLLCTL setting for 48MHz PLL output with 12MHz IRC */
#define CLK_PLLCTL_84MHz_HIRC (CLK_PLLCTL_PLL_SRC_HIRC | CLK_PLLCON_NO_1 | CLK_PLLCTL_NR_8 | CLK_PLLCON_NF(56) ) /*!< Predefined PLLCTL setting for 84MHz PLL output with 12MHz IRC */
#define CLK_PLLCTL_42MHz_HIRC (CLK_PLLCTL_PLL_SRC_HIRC | CLK_PLLCON_NO_1 | CLK_PLLCTL_NR_16| CLK_PLLCON_NF(56) ) /*!< Predefined PLLCTL setting for 42MHz PLL output with 12MHz IRC */
/********************* Bit definition of FRQDIV register **********************/
#define CLK_FRQDIV_EN (0x1UL<<CLK_FRQDIV_FDIV_EN_Pos) /*!<Frequency divider enable bit */
/********************* Bit definition of WK_INTSTS register **********************/
#define CLK_WK_INTSTS_IS (0x1UL<<CLK_WK_INTSTS_PD_WK_IS_Pos) /*!<Wake-up Interrupt Status in chip Power-down Mode */
/********************* Bit definition of MCLKO register **********************/
#define CLK_MCLKO_MCLK_SEL_ISP_CLK (0x00<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output ISP_CLK */
#define CLK_MCLKO_MCLK_SEL_HIRC (0x01<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output HIRC clock */
#define CLK_MCLKO_MCLK_SEL_HXT (0x02<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output HXT clock */
#define CLK_MCLKO_MCLK_SEL_LXT (0x03<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output LXT clock */
#define CLK_MCLKO_MCLK_SEL_LIRC (0x04<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output LIRC clock */
#define CLK_MCLKO_MCLK_SEL_PLLO (0x05<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output PLL input */
#define CLK_MCLKO_MCLK_SEL_PLLI (0x06<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output PLL input */
#define CLK_MCLKO_MCLK_SEL_SYSTICK (0x07<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output system tick */
#define CLK_MCLKO_MCLK_SEL_HCLK (0x08<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output HCLK clock */
#define CLK_MCLKO_MCLK_SEL_PCLK (0x0A<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output PCLK clock */
#define CLK_MCLKO_MCLK_SEL_TMR0 (0x20<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output TMR0 clock */
#define CLK_MCLKO_MCLK_SEL_TMR1 (0x21<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output TMR1 clock */
#define CLK_MCLKO_MCLK_SEL_UART0 (0x22<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output UART0 clock */
#define CLK_MCLKO_MCLK_SEL_USB (0x23<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output USB clock */
#define CLK_MCLKO_MCLK_SEL_ADC (0x24<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output ADC clock */
#define CLK_MCLKO_MCLK_SEL_WDT (0x25<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output WDT clock */
#define CLK_MCLKO_MCLK_SEL_PWM0CH01 (0x26<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output PWM0CH01 clock */
#define CLK_MCLKO_MCLK_SEL_PWM0CH23 (0x27<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output PWM0CH23 clock */
#define CLK_MCLKO_MCLK_SEL_LCD (0x29<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output LCD clock */
#define CLK_MCLKO_MCLK_SEL_TMR2 (0x38<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output TMR2 clock */
#define CLK_MCLKO_MCLK_SEL_TMR3 (0x39<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output TMR3 clock */
#define CLK_MCLKO_MCLK_SEL_UART1 (0x3A<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output UART1 clock */
#define CLK_MCLKO_MCLK_SEL_PWM1CH01 (0x3B<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output PWM1CH01 clock */
#define CLK_MCLKO_MCLK_SEL_PWM1CH23 (0x3C<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output PWM1CH23 clock */
#define CLK_MCLKO_MCLK_SEL_I2S (0x3D<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output I2S clock */
#define CLK_MCLKO_MCLK_SEL_SC0 (0x3E<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output SC0 clock */
#define CLK_MCLKO_MCLK_SEL_SC1 (0x3F<<CLK_MCLKO_MCLK_SEL_Pos) /*!<Select MCLK clock output SC1 clock */
/*---------------------------------------------------------------------------------------------------------*/
/* MODULE constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define MODULE_APBCLK(x) ((x >>31) & 0x1) /*!< Calculate APBCLK offset on MODULE index */
#define MODULE_CLKSEL(x) ((x >>29) & 0x3) /*!< Calculate CLKSEL offset on MODULE index */
#define MODULE_CLKSEL_Msk(x) ((x >>25) & 0xf) /*!< 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 */
#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) & 0x01) << 31) /*!< MODULE index, 0x0:AHBCLK, 0x1:APBCLK */
#define MODULE_CLKSEL_ENC(x) (((x) & 0x03) << 29) /*!< CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1 0x3 CLKSEL2*/
#define MODULE_CLKSEL_Msk_ENC(x) (((x) & 0x0f) << 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 */
/*-------------------------------------------------------------------------------------------------------------------------------*/
/* APBCLK(1) | CLKSEL(2) | CLKSEL_Msk(4) | CLKSEL_Pos(5) | CLKDIV(2) | CLKDIV_Msk(8) | CLKDIV_Pos(5) | IP_EN_Pos(5) */
/*-------------------------------------------------------------------------------------------------------------------------------*/
#define TICK_MODULE ((0UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(1<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_TICK_EN_Pos ) /*!< TICK Module */
#define SRAM_MODULE ((0UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(1<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_SRAM_EN_Pos ) /*!< SRAM Module */
#define EBI_MODULE ((0UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(1<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_EBI_EN_Pos ) /*!< EBI Module */
#define ISP_MODULE ((0UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(1<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_ISP_EN_Pos ) /*!< ISP Module */
#define DMA_MODULE ((0UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_DMA_EN_Pos ) /*!< DMA Module */
#define GPIO_MODULE ((0UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_AHBCLK_GPIO_EN_Pos ) /*!< GPIO Module */
#define SC2_MODULE ((1UL<<31)|(2<<29)|(3<<25) |(18<<20)|(1<<18)|(0xF<<10) |( 4<<5)|CLK_APBCLK_SC2_EN_Pos ) /*!< SmartCard2 Module */
#define SC1_MODULE ((1UL<<31)|(2<<29)|(3<<25) |(18<<20)|(1<<18)|(0xF<<10) |( 0<<5)|CLK_APBCLK_SC1_EN_Pos ) /*!< SmartCard1 Module */
#define SC0_MODULE ((1UL<<31)|(2<<29)|(3<<25) |(18<<20)|(0<<18)|(0xF<<10) |(28<<5)|CLK_APBCLK_SC0_EN_Pos ) /*!< SmartCard0 Module */
#define I2S_MODULE ((1UL<<31)|(2<<29)|(3<<25) |(16<<20)|(0<<18)|(0xF<<10) |(12<<5)|CLK_APBCLK_I2S_EN_Pos ) /*!< I2S Module */
#define ADC_MODULE ((1UL<<31)|(1<<29)|(3<<25) |( 2<<20)|(0<<18)|(0xFF<<10) |(16<<5)|CLK_APBCLK_ADC_EN_Pos ) /*!< ADC Module */
#define USBD_MODULE ((1UL<<31)|(1<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(0xF<<10) |( 4<<5)|CLK_APBCLK_USBD_EN_Pos ) /*!< USBD Module */
#define PWM1_CH23_MODULE ((1UL<<31)|(2<<29)|(3<<25) |( 6<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_PWM1_CH23_EN_Pos) /*!< PWM1 Channel2 and Channel3 Module */
#define PWM1_CH01_MODULE ((1UL<<31)|(2<<29)|(3<<25) |( 4<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_PWM1_CH01_EN_Pos) /*!< PWM1 Channel0 and Channel1 Module */
#define PWM0_CH23_MODULE ((1UL<<31)|(1<<29)|(3<<25) |( 6<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_PWM0_CH23_EN_Pos) /*!< PWM0 Channel2 and Channel3 Module */
#define PWM0_CH01_MODULE ((1UL<<31)|(1<<29)|(3<<25) |( 4<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_PWM0_CH01_EN_Pos) /*!< PWM0 Channel0 and Channel1 Module */
#define UART1_MODULE ((1UL<<31)|(1<<29)|(3<<25) |( 0<<20)|(0<<18)|(0xF<<10) |( 8<<5)|CLK_APBCLK_UART1_EN_Pos ) /*!< UART1 Module */
#define UART0_MODULE ((1UL<<31)|(1<<29)|(3<<25) |( 0<<20)|(0<<18)|(0xF<<10) |( 8<<5)|CLK_APBCLK_UART0_EN_Pos ) /*!< UART0 Module */
#define SPI2_MODULE ((1UL<<31)|(2<<29)|(1<<25) |(22<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_SPI2_EN_Pos ) /*!< SPI0 Module */
#define SPI1_MODULE ((1UL<<31)|(2<<29)|(1<<25) |(21<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_SPI1_EN_Pos ) /*!< SPI1 Module */
#define SPI0_MODULE ((1UL<<31)|(2<<29)|(1<<25) |(20<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_SPI0_EN_Pos ) /*!< SPI0 Module */
#define I2C1_MODULE ((1UL<<31)|(0<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_I2C1_EN_Pos ) /*!< I2C1 Module */
#define I2C0_MODULE ((1UL<<31)|(0<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_I2C0_EN_Pos ) /*!< I2C0 Module */
#define FDIV_MODULE ((1UL<<31)|(2<<29)|(3<<25) |( 2<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_FDIV_EN_Pos ) /*!< Frequency Divider0 Output Module */
#define TMR3_MODULE ((1UL<<31)|(2<<29)|(7<<25) |(12<<20)|(1<<18)|(0xF<<10) |(20<<5)|CLK_APBCLK_TMR3_EN_Pos ) /*!< Timer3 Module */
#define TMR2_MODULE ((1UL<<31)|(2<<29)|(7<<25) |( 8<<20)|(1<<18)|(0xF<<10) |(16<<5)|CLK_APBCLK_TMR2_EN_Pos ) /*!< Timer2 Module */
#define TMR1_MODULE ((1UL<<31)|(1<<29)|(7<<25) |(12<<20)|(1<<18)|(0xF<<10) |(12<<5)|CLK_APBCLK_TMR1_EN_Pos ) /*!< Timer1 Module */
#define TMR0_MODULE ((1UL<<31)|(1<<29)|(7<<25) |( 8<<20)|(1<<18)|(0xF<<10) |( 8<<5)|CLK_APBCLK_TMR0_EN_Pos ) /*!< Timer0 Module */
#define RTC_MODULE ((1UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_RTC_EN_Pos ) /*!< Real-Time-Clock Module */
#define WDT_MODULE ((1UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_WDT_EN_Pos ) /*!< Watchdog Timer Module */
#define LCD_MODULE ((1UL<<31)|(1<<29)|(1<<25) |(18<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_LCD_EN_Pos ) /*!< LCD Module */
#define DAC_MODULE ((1UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_DAC_EN_Pos ) /*!< DAC Module */
/*@}*/ /* end of group NANO100_CLK_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_CLK_EXPORTED_FUNCTIONS CLK Exported Functions
@{
*/
void CLK_DisableCKO(void);
void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv);
void CLK_PowerDown(void);
void CLK_Idle(void);
uint32_t CLK_GetHXTFreq(void);
uint32_t CLK_GetLXTFreq(void);
uint32_t CLK_GetHCLKFreq(void);
uint32_t CLK_GetCPUFreq(void);
uint32_t CLK_GetPLLClockFreq(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_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);
void CLK_SysTickDelay(uint32_t us);
void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count);
void CLK_DisableSysTick(void);
uint32_t CLK_WaitClockReady(uint32_t u32ClkMask);
/*@}*/ /* end of group NANO100_CLK_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_CLK_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__CLK_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,100 @@
/**************************************************************************//**
* @file crc.c
* @version V1.00
* $Revision: 3 $
* $Date: 14/09/29 3:50p $
* @brief Nano100 series CRC driver source file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_CRC_Driver CRC Driver
@{
*/
/** @addtogroup NANO100_CRC_EXPORTED_FUNCTIONS CRC Exported Functions
@{
*/
/**
* @brief CRC Open
*
* @param[in] u32Mode CRC Polynomial Mode \ref CRC_CCITT, \ref CRC_8, \ref CRC_16, \ref CRC_32
* @param[in] u32Attribute Parameter attribute \ref CRC_CHECKSUM_COM, \ref CRC_CHECKSUM_RVS, \ref CRC_WDATA_COM, \ref CRC_WDATA_RVS
* @param[in] u32Seed Seed value
* @param[in] u32DataLen CPU Write Data Length \ref CRC_CPU_WDATA_8, \ref CRC_CPU_WDATA_16, \ref CRC_CPU_WDATA_32
*
* @return None
*
* @details This function enable the CRC channel.
*/
void CRC_Open(uint32_t u32Mode, uint32_t u32Attribute, uint32_t u32Seed, uint32_t u32DataLen)
{
PDMAGCR->GCRCSR |= DMA_GCR_GCRCSR_CRC_CLK_EN_Msk;
PDMACRC->SEED = u32Seed;
PDMACRC->CTL = u32Mode | u32Attribute | u32DataLen | DMA_CRC_CTL_CRCCEN_Msk;
/* When operated in CPU PIO mode, setting RST bit will reload the initial seed value (CRC_SEED register) */
PDMACRC->CTL |= DMA_CRC_CTL_CRC_RST_Msk;
}
/**
* @brief CRC Start DMA transfer
*
* @param[in] u32SrcAddr Source address
* @param[in] u32ByteCount Calculate byte count
*
* @return None
*
* @details This function start DMA transfer.
*/
void CRC_StartDMATransfer(uint32_t u32SrcAddr, uint32_t u32ByteCount)
{
PDMACRC->DMASAR = u32SrcAddr;
PDMACRC->DMABCR = u32ByteCount;
PDMACRC->CTL |= DMA_CRC_CTL_TRIG_EN_Msk;
}
/**
* @brief Get CRC Checksum
*
* @param[in] None
*
* @return Checksum
*
* @details This macro get the CRC checksum
*/
uint32_t CRC_GetChecksum(void)
{
switch (PDMACRC->CTL & DMA_CRC_CTL_CRC_MODE_Msk) {
case CRC_CCITT:
case CRC_16:
return (PDMACRC->CHECKSUM & 0xffff);
case CRC_32:
return (PDMACRC->CHECKSUM);
case CRC_8:
return (PDMACRC->CHECKSUM & 0xff);
default:
return 0;
}
}
/*@}*/ /* end of group NANO100_CRC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_CRC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,158 @@
/**************************************************************************//**
* @file crc.h
* @version V1.00
* $Revision: 2 $
* $Date: 15/06/10 4:50p $
* @brief Nano100 series CRC driver header file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __CRC_H__
#define __CRC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_CRC_Driver CRC Driver
@{
*/
/** @addtogroup NANO100_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 NANO100_CRC_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_CRC_EXPORTED_FUNCTIONS CRC Exported Functions
@{
*/
/**
* @brief Enable CRC Interrupt
*
* @param[in] u32Mask Interrupt mask
*
* @return None
*
* @details This macro enable the interrupts.
*/
#define CRC_ENABLE_INT(u32Mask) (PDMACRC->DMAIER |= (u32Mask))
/**
* @brief Disable CRC Interrupt
*
* @param[in] u32Mask Interrupt mask
*
* @return None
*
* @details This macro disable the interrupts.
*/
#define CRC_DISABLE_INT(u32Mask) (PDMACRC->DMAIER &= ~(u32Mask))
/**
* @brief Get CRC Interrupt Flag
*
* @param[in] None
*
* @return Interrupt Flag
*
* @details This macro gets the interrupt flag.
*/
#define CRC_GET_INT_FLAG() ((uint32_t)(PDMACRC->DMAISR))
/**
* @brief Clear CRC Interrupt Flag
*
* @param[in] u32Mask Interrupt mask
*
* @return None
*
* @details This macro clear the interrupt flag.
*/
#define CRC_CLR_INT_FLAG(u32Mask) (PDMACRC->DMAISR |= (u32Mask))
/**
* @brief Set CRC seed value
*
* @param[in] u32Seed Seed value
*
* @return None
*
* @details This macro set seed value.
*/
#define CRC_SET_SEED(u32Seed) { PDMACRC->SEED = (u32Seed); PDMACRC->CTL |= DMA_CRC_CTL_CRC_RST_Msk; }
/**
* @brief Get CRC Seed value
*
* @param[in] None
*
* @return Seed Value
*
* @details This macro gets the seed value.
*/
#define CRC_GET_SEED() ((uint32_t)(PDMACRC->SEED))
/**
* @brief CRC write data
*
* @param[in] u32Data write data
*
* @return None
*
* @details This macro write CRC data.
*/
#define CRC_WRITE_DATA(u32Data) (PDMACRC->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 NANO100_CRC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_CRC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__CRC_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,114 @@
/**************************************************************************//**
* @file dac.c
* @version V1.00
* $Revision: 4 $
* $Date: 14/09/08 12:31p $
* @brief NANO100 series DAC driver source file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NANO100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_DAC_Driver DAC Driver
@{
*/
/** @addtogroup NANO100_DAC_EXPORTED_FUNCTIONS DAC Exported Functions
@{
*/
/**
* @brief This function make a DAC channel ready to convert.
* @param[in] dac Base address of DAC module.
* @param[in] u32Ch DAC channel number, could be 0 or 1
* @param[in] u32TrgSrc Decides the trigger source of specified DAC channel. Valid options are:
* - \ref DAC_WRITE_DAT_TRIGGER
* - \ref DAC_PDMA_TRIGGER
* - \ref DAC_TIMER0_TRIGGER
* - \ref DAC_TIMER1_TRIGGER
* - \ref DAC_TIMER2_TRIGGER
* - \ref DAC_TIMER3_TRIGGER
* @return None
* @note This API also set DAC stable time to 2uc according to current PCLK
*/
void DAC_Open(DAC_T *dac, uint32_t u32Ch, uint32_t u32TrgSrc)
{
uint32_t u32Delay;
// DAC needs 6 us to stable after power on
u32Delay = CLK_GetHCLKFreq() * 6 / 1000000;
if(u32Delay == 0)
u32Delay++;
if(u32Ch == 0)
DAC->CTL0 = (u32Delay << DAC_CTL_DACPWONSTBCNT_Pos) | u32TrgSrc | DAC_CTL_DACEN_Msk;
else
DAC->CTL1 = (u32Delay << DAC_CTL_DACPWONSTBCNT_Pos) | u32TrgSrc | DAC_CTL_DACEN_Msk;
// DAC needs 2 us to stable after convert.
u32Delay = CLK_GetHCLKFreq() * 2 / 1000000;
if(u32Delay == 0)
u32Delay++;
DAC->COMCTL = (DAC->COMCTL & ~DAC_COMCTL_WAITDACCONV_Msk) | u32Delay;
}
/**
* @brief Disable DAC analog power.
* @param[in] dac Base address of DAC module.
* @param[in] u32Ch DAC channel number, could be 0 or 1
* @return None
* @details Disable DAC analog power for saving power consumption.
*/
void DAC_Close(DAC_T *dac, uint32_t u32Ch)
{
if(u32Ch == 0) {
DAC->CTL0 &= ~DAC_CTL_DACEN_Msk;
} else {
DAC->CTL1 &= ~DAC_CTL_DACEN_Msk;
}
}
/**
* @brief Set delay time for DAC to become stable.
* @param[in] dac Base address of DAC module.
* @param[in] u32Delay Decides the DAC conversion settling time, Valid values are between 1~0xFF.
* @return Success or failed
* @retval 0 Success
* @retval -1 Failed, the new setting will cause stable time less than 2us. So new setting is not applied.
* @details For example, DAC controller clock speed is 12MHz and DAC conversion settling time is 3 us,
* u32Delay should be given the value 3 * 12 = 36.
* @note User needs to write appropriate value to meet DAC conversion settling time base on
* PCLK (APB clock) speed. Minimum delay is 2 us.
* @note This setting is shared by both DAC channels.
*/
int DAC_SetDelayTime(DAC_T *dac, uint32_t u32Delay)
{
uint32_t u32Dly;
// DAC needs 2 us to stable after DAC convert, calculate minimal setting
u32Dly = CLK_GetHCLKFreq() * 2 / 1000000;
if(u32Dly == 0)
u32Dly++;
if(u32Delay < u32Dly) // return error id stable time is shorter than 2us
return -1;
DAC->COMCTL = (DAC->COMCTL & ~DAC_COMCTL_WAITDACCONV_Msk) | u32Delay;
return 0;
}
/*@}*/ /* end of group NANO100_DAC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_DAC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,179 @@
/******************************************************************************
* @file dac.h
* @version V1.00
* $Revision: 4 $
* $Date: 14/09/08 12:31p $
* @brief NANO100 series DAC driver header file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __DAC_H__
#define __DAC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_DAC_Driver DAC Driver
@{
*/
/** @addtogroup NANO100_DAC_EXPORTED_CONSTANTS DAC Exported Constants
@{
*/
#define DAC_WRITE_DAT_TRIGGER (0UL << DAC_CTL_DACLSEL_Pos) ///< Write DACx_DAT trigger \hideinitializer
#define DAC_PDMA_TRIGGER (1UL << DAC_CTL_DACLSEL_Pos) ///< PDMA trigger \hideinitializer
#define DAC_TIMER0_TRIGGER (2UL << DAC_CTL_DACLSEL_Pos) ///< Timer 0 trigger \hideinitializer
#define DAC_TIMER1_TRIGGER (3UL << DAC_CTL_DACLSEL_Pos) ///< Timer 1 trigger \hideinitializer
#define DAC_TIMER2_TRIGGER (4UL << DAC_CTL_DACLSEL_Pos) ///< Timer 2 trigger \hideinitializer
#define DAC_TIMER3_TRIGGER (5UL << DAC_CTL_DACLSEL_Pos) ///< Timer 3 trigger \hideinitializer
#define DAC_REFSEL_POWER (0UL << DAC_COMCTL_REFSEL_Pos) ///< DAC reference voltage source selection set to power \hideinitializer
#define DAC_REFSEL_INT_VREF (1UL << DAC_COMCTL_REFSEL_Pos) ///< DAC reference voltage source selection set to Int_VREF \hideinitializer
#define DAC_REFSEL_VREF (2UL << DAC_COMCTL_REFSEL_Pos) ///< DAC reference voltage source selection set to VREF \hideinitializer
/*@}*/ /* end of group NANO100_DAC_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_DAC_EXPORTED_FUNCTIONS DAC Exported Functions
@{
*/
/**
* @brief Write data for conversion.
* @param[in] dac Base address of DAC module.
* @param[in] u32Ch DAC channel number, could be 0 or 1
* @param[in] u32Data Decides the data for conversion, valid range are between 0~0xFFF.
* @return None
* \hideinitializer
*/
#define DAC_WRITE_DATA(dac, u32Ch, u32Data) do {\
if(u32Ch) {\
DAC->DATA1 = u32Data;\
} else {\
DAC->DATA0 = u32Data;\
}\
}while(0)
/**
* @brief Enable DAC group mode
* @param[in] dac Base address of DAC module.
* @return None
* \hideinitializer
*/
#define DAC_ENABLE_GROUP_MODE(dac) (DAC->COMCTL |= DAC_COMCTL_DAC01GRP_Msk)
/**
* @brief Disable DAC group mode
* @param[in] dac Base address of DAC module.
* @return None
* \hideinitializer
*/
#define DAC_DISABLE_GROUP_MODE(dac) (DAC->COMCTL &= ~DAC_COMCTL_DAC01GRP_Msk)
/**
* @brief Get the busy state of DAC.
* @param[in] dac Base address of DAC module.
* @param[in] u32Ch DAC channel number, could be 0 or 1
* @return If DAC is able to convert or not.
* @retval 0 DAC is in idle state.
* @retval 1 DAC is in busy state, or DAC is not in ready state.
* @details If this macro returns 1, DAC is \b not in ready state. Ether DAC is busy or not in ready state.
* \hideinitializer
*/
#define DAC_IS_BUSY(dac, u32Ch) (inp32(DAC_BASE + 0x8 + 0x10 * (u32Ch)) & DAC_STS_BUSY_Msk ? 1 : 0)
/**
* @brief Get the interrupt flag of specified channel.
* @param[in] dac Base address of DAC module.
* @param[in] u32Ch DAC channel number, could be 0 or 1
* @return Returns the interrupt flag of selected channel.
* @retval 0 DAC interrupt flag is not set.
* @retval 1 DAC interrupt flag is set.
* \hideinitializer
*/
#define DAC_GET_INT_FLAG(dac, u32Ch) (inp32(DAC_BASE + 0x8 + 0x10 * (u32Ch)) & DAC_STS_DACIFG_Msk ? 1 : 0)
/**
* @brief This macro clear the interrupt status bit of specified channel.
* @param[in] dac Base address of DAC module.
* @param[in] u32Ch DAC channel number, could be 0 or 1
* @return None
* \hideinitializer
*/
#define DAC_CLR_INT_FLAG(dac, u32Ch) do {\
if(u32Ch)\
DAC->STS1 = DAC_STS_DACIFG_Msk;\
else\
DAC->STS0 = DAC_STS_DACIFG_Msk;\
}while(0)
/**
* @brief Set the DAC reference voltage. This setting affects both DAC channel
* @param[in] dac Base address of DAC module
* @param[in] u32Ref The reference voltage selection. Valid values are:
* - \ref DAC_REFSEL_POWER
* - \ref DAC_REFSEL_INT_VREF
* - \ref DAC_REFSEL_VREF
* @return None
* \hideinitializer
*/
#define DAC_SET_REF_VOLTAGE(dac, u32Ref) (DAC->COMCTL = ((DAC->COMCTL) & ~DAC_COMCTL_REFSEL_Msk) | u32Ref)
/**
* @brief This macro enable the interrupt of specified channel.
* @param[in] dac Base address of DAC module.
* @param[in] u32Ch DAC channel number, could be 0 or 1
* @return None
* \hideinitializer
*/
#define DAC_ENABLE_INT(dac, u32Ch) do {\
if(u32Ch)\
DAC->CTL1 |= DAC_CTL_DACIE_Msk;\
else\
DAC->CTL0 |= DAC_CTL_DACIE_Msk;\
}while(0)
/**
* @brief This macro disable the interrupt of specified channel.
* @param[in] dac Base address of DAC module.
* @param[in] u32Ch DAC channel number, could be 0 or 1
* @return None
* \hideinitializer
*/
#define DAC_DISABLE_INT(dac, u32Ch) do {\
if(u32Ch)\
DAC->CTL1 &= ~DAC_CTL_DACIE_Msk;\
else\
DAC->CTL0 &= ~DAC_CTL_DACIE_Msk;\
}while(0)
void DAC_Open(DAC_T *dac, uint32_t u32Ch, uint32_t u32TrgSrc);
void DAC_Close(DAC_T *dac, uint32_t u32Ch);
int DAC_SetDelayTime(DAC_T *dac, uint32_t u32Delay);
/*@}*/ /* end of group NANO100_DAC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_DAC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__DAC_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,152 @@
/****************************************************************************//**
* @file ebi.c
* @version V0.10
* $Revision: 3 $
* $Date: 14/02/05 10:36a $
* @brief NANO100 series EBI driver source file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
//#include "ebi.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_EBI_Driver EBI Driver
@{
*/
/** @addtogroup NANO100_EBI_EXPORTED_FUNCTIONS EBI Exported Functions
@{
*/
/**
* @brief Initialize and enable EBI
* @param[in] u32Bank argument is reserved in NANO100 series.
* @param[in] u32DataWidth Data bus width. Valid values are:
* - \ref EBI_BUSWIDTH_8BIT
* - \ref EBI_BUSWIDTH_16BIT
* @param[in] u32TimingClass Default timing configuration. Valid values are:
* - \ref EBI_TIMING_FASTEST
* - \ref EBI_TIMING_VERYFAST
* - \ref EBI_TIMING_FAST
* - \ref EBI_TIMING_NORMAL
* - \ref EBI_TIMING_SLOW
* - \ref EBI_TIMING_VERYSLOW
* - \ref EBI_TIMING_SLOWEST
* @param[in] u32BusMode argument is reserved in NANO100 series.
* @param[in] u32CSActiveLevel argument is reserved in NANO100 series.
* @return none
*/
void EBI_Open(uint32_t u32Bank, uint32_t u32DataWidth, uint32_t u32TimingClass, uint32_t u32BusMode, uint32_t u32CSActiveLevel)
{
EBI->EBICON = 0;
if (u32DataWidth == EBI_BUSWIDTH_8BIT)
EBI->EBICON &= ~EBI_EBICON_ExtBW16_Msk;
else
EBI->EBICON |= EBI_EBICON_ExtBW16_Msk;
EBI->EBICON &= ~(EBI_EBICON_ExttALE_Msk | EBI_EBICON_MCLKDIV_Msk);
switch (u32TimingClass) {
case EBI_TIMING_FASTEST:
EBI->EBICON |= (0 << EBI_EBICON_ExttALE_Pos);
EBI->EBICON |= (EBI_MCLKDIV_1 << EBI_EBICON_MCLKDIV_Pos);
EBI->EXTIME = 0;
break;
case EBI_TIMING_VERYFAST:
EBI->EBICON |= (1 << EBI_EBICON_ExttALE_Pos);
EBI->EBICON |= (EBI_MCLKDIV_2 << EBI_EBICON_MCLKDIV_Pos);
EBI->EXTIME = (4 << EBI_EXTIME_ExttACC_Pos) | (1 << EBI_EXTIME_ExttAHD_Pos) |
(2 << EBI_EXTIME_ExtIW2X_Pos) | (2 << EBI_EXTIME_ExtIR2W_Pos) |
(2 << EBI_EXTIME_ExtIR2R_Pos);
break;
case EBI_TIMING_FAST:
EBI->EBICON |= (2 << EBI_EBICON_ExttALE_Pos);
EBI->EBICON |= (EBI_MCLKDIV_4 << EBI_EBICON_MCLKDIV_Pos);
EBI->EXTIME = (8 << EBI_EXTIME_ExttACC_Pos) | (2 << EBI_EXTIME_ExttAHD_Pos) |
(4 << EBI_EXTIME_ExtIW2X_Pos) | (4 << EBI_EXTIME_ExtIR2W_Pos) |
(4 << EBI_EXTIME_ExtIR2R_Pos);
break;
case EBI_TIMING_NORMAL:
EBI->EBICON |= (3 << EBI_EBICON_ExttALE_Pos);
EBI->EBICON |= (EBI_MCLKDIV_8 << EBI_EBICON_MCLKDIV_Pos);
EBI->EXTIME = (16 << EBI_EXTIME_ExttACC_Pos) | (3 << EBI_EXTIME_ExttAHD_Pos) |
(8 << EBI_EXTIME_ExtIW2X_Pos) | (8 << EBI_EXTIME_ExtIR2W_Pos) |
(8 << EBI_EXTIME_ExtIR2R_Pos);
break;
case EBI_TIMING_SLOW:
EBI->EBICON |= (4 << EBI_EBICON_ExttALE_Pos);
EBI->EBICON |= (EBI_MCLKDIV_16 << EBI_EBICON_MCLKDIV_Pos);
EBI->EXTIME = (20 << EBI_EXTIME_ExttACC_Pos) | (4 << EBI_EXTIME_ExttAHD_Pos) |
(12 << EBI_EXTIME_ExtIW2X_Pos) | (12 << EBI_EXTIME_ExtIR2W_Pos) |
(12 << EBI_EXTIME_ExtIR2R_Pos);
break;
case EBI_TIMING_VERYSLOW:
EBI->EBICON |= (5 << EBI_EBICON_ExttALE_Pos);
EBI->EBICON |= (EBI_MCLKDIV_32 << EBI_EBICON_MCLKDIV_Pos);
EBI->EXTIME = (26 << EBI_EXTIME_ExttACC_Pos) | (5 << EBI_EXTIME_ExttAHD_Pos) |
(14 << EBI_EXTIME_ExtIW2X_Pos) | (14 << EBI_EXTIME_ExtIR2W_Pos) |
(14 << EBI_EXTIME_ExtIR2R_Pos);
break;
case EBI_TIMING_SLOWEST:
EBI->EBICON |= (6 << EBI_EBICON_ExttALE_Pos);
EBI->EBICON |= (EBI_MCLKDIV_32 << EBI_EBICON_MCLKDIV_Pos);
EBI->EXTIME = (31 << EBI_EXTIME_ExttACC_Pos) | (7 << EBI_EXTIME_ExttAHD_Pos) |
(15 << EBI_EXTIME_ExtIW2X_Pos) | (15 << EBI_EXTIME_ExtIR2W_Pos) |
(15 << EBI_EXTIME_ExtIR2R_Pos);
break;
}
EBI->EBICON |= EBI_EBICON_MCLKEN_Msk | EBI_EBICON_ExtEN_Msk;
}
/**
* @brief Disable EBI
* @param[in] u32Bank argument is reserved in NANO100 series.
* @return none
*/
void EBI_Close(uint8_t u32Bank)
{
EBI->EBICON = 0;
EBI->EXTIME = 0;
}
/**
* @brief Set EBI bus timings
* @param[in] u32Bank argument is reserved in NANO100 series.
* @param[in] u32TimingConfig The new EBI timing settings. This value will be written to EXTIME register.
* @param[in] u32MclkDiv Divider for MCLK. Valid values are:
* - \ref EBI_MCLKDIV_1
* - \ref EBI_MCLKDIV_2
* - \ref EBI_MCLKDIV_4
* - \ref EBI_MCLKDIV_8
* - \ref EBI_MCLKDIV_16
* - \ref EBI_MCLKDIV_32
* @return none
*/
void EBI_SetBusTiming(uint32_t u32Bank, uint32_t u32TimingConfig, uint32_t u32MclkDiv)
{
EBI->EXTIME = u32TimingConfig;
EBI->EBICON = (EBI->EBICON & ~EBI_EBICON_MCLKDIV_Msk) | (u32MclkDiv << EBI_EBICON_MCLKDIV_Pos);
}
/*@}*/ /* end of group NANO100_EBI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_EBI_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,150 @@
/**************************************************************************//**
* @file ebi.h
* @version V1.00
* $Revision: 4 $
* $Date: 14/09/30 4:21p $
* @brief Nano100 Series Flash Memory Controller Driver Header File
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __EBI_H__
#define __EBI_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_EBI_Driver EBI Driver
@{
*/
/** @addtogroup NANO100_EBI_EXPORTED_CONSTANTS EBI Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Define Base Address */
/*---------------------------------------------------------------------------------------------------------*/
#define EBI_BASE_ADDR 0x60000000 /*!< EBI base address */
#define EBI_MAX_SIZE 0x20000 /*!< Maximum size of EBI bank */
#define EBI_TIMEOUT_COUNT 0x10000 /*!< Time-out value */
/* Constants for EBI data bus width */
#define EBI_BUSWIDTH_8BIT 8 /*!< EBI bus width is 8-bit */
#define EBI_BUSWIDTH_16BIT 16 /*!< EBI bus width is 16-bit */
/*---------------------------------------------------------------------------------------------------------*/
/* EBI MCLK divider */
/*---------------------------------------------------------------------------------------------------------*/
#define EBI_MCLKDIV_1 0 /*!< MCLK divided by 1 */
#define EBI_MCLKDIV_2 1 /*!< MCLK divided by 2 */
#define EBI_MCLKDIV_4 2 /*!< MCLK divided by 4 */
#define EBI_MCLKDIV_8 3 /*!< MCLK divided by 8 */
#define EBI_MCLKDIV_16 4 /*!< MCLK divided by 16 */
#define EBI_MCLKDIV_32 5 /*!< MCLK divided by 32 */
/*---------------------------------------------------------------------------------------------------------*/
/* EBI timing setting */
/*---------------------------------------------------------------------------------------------------------*/
#define EBI_TIMING_FASTEST 0x0 /*!< EBI timing is the fastest */
#define EBI_TIMING_VERYFAST 0x1 /*!< EBI timing is the very fast */
#define EBI_TIMING_FAST 0x2 /*!< EBI timing is the fast */
#define EBI_TIMING_NORMAL 0x3 /*!< EBI timing is the normal */
#define EBI_TIMING_SLOW 0x4 /*!< EBI timing is the slow */
#define EBI_TIMING_VERYSLOW 0x5 /*!< EBI timing is the very slow */
#define EBI_TIMING_SLOWEST 0x6 /*!< EBI timing is the slowest */
/*@}*/ /* end of group NANO100_EBI_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_EBI_EXPORTED_FUNCTIONS EBI Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* EBI access macros */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief Read one byte data from EBI.
* @param[in] Addr EBI offset address.
* @return Byte data read from EBI.
* \hideinitializer
*/
#define EBI_READ_DATA8(Addr) *((volatile unsigned char *)(EBI_BASE_ADDR+Addr))
/**
* @brief Write one byte data to EBI.
* @param[in] Addr EBI offset address.
* @param[in] Data Byte data to be written.
* @return None
* \hideinitializer
*/
#define EBI_WRITE_DATA8(Addr, Data) *((volatile unsigned char *)(EBI_BASE_ADDR+Addr))=Data
/**
* @brief Read a half-word data from EBI.
* @param[in] Addr EBI offset address.
* @return Half-word data read from EBI.
* \hideinitializer
*/
#define EBI_READ_DATA16(Addr) *((volatile unsigned short *)(EBI_BASE_ADDR+Addr))
/**
* @brief Write a half-word data to EBI.
* @param[in] Addr EBI offset address.
* @param[in] Data Half-word data to be written.
* @return None
* \hideinitializer
*/
#define EBI_WRITE_DATA16(Addr, Data) *((volatile unsigned short *)(EBI_BASE_ADDR+Addr))=Data
/**
* @brief Read a word data from EBI.
* @param[in] Addr EBI offset address.
* @return Word data read from EBI.
* \hideinitializer
*/
#define EBI_READ_DATA32(Addr) *((volatile unsigned int *)(EBI_BASE_ADDR+Addr))
/**
* @brief Write a word data to EBI.
* @param[in] Addr EBI offset address.
* @param[in] Data Word data to be written.
* @return None
* \hideinitializer
*/
#define EBI_WRITE_DATA32(Addr, Data) *((volatile unsigned int *)(EBI_BASE_ADDR+Addr))=Data
/*---------------------------------------------------------------------------------------------------------*/
/* Functions */
/*---------------------------------------------------------------------------------------------------------*/
void EBI_Open(uint32_t u32Bank, uint32_t u32DataWidth, uint32_t u32TimingClass, uint32_t u32BusMode, uint32_t u32CSActiveLevel);
void EBI_Close(uint8_t u32Bank);
void EBI_SetBusTiming(uint32_t u32Bank, uint32_t u32TimingConfig, uint32_t u32MclkDiv);
/*@}*/ /* end of group NANO100_EBI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_EBI_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif // __EBI_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,269 @@
/**************************************************************************//**
* @file fmc.c
* @version V1.00
* $Revision: 8 $
* $Date: 15/06/12 3:17p $
* @brief NANO100 series FMC driver source file
*
* @note
* Copyright (C) 2015 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
//* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_FMC_Driver FMC Driver
@{
*/
/** @addtogroup NANO100_FMC_EXPORTED_FUNCTIONS FMC Exported Functions
@{
*/
/**
* @brief Disable FMC ISP function.
* @return None
*/
void FMC_Close(void)
{
FMC->ISPCON &= ~FMC_ISPCON_ISPEN_Msk;
}
/**
* @brief Execute ISP command to erase a flash page. The page size is 512 bytes.
* @param[in] u32PageAddr Address of the flash page to be erased.
* It must be a 512-byte aligned address.
* @return ISP page erase success or not.
* @retval 0 Success
* @retval -1 Erase failed
*/
int32_t FMC_Erase(uint32_t u32PageAddr)
{
FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE;
FMC->ISPADR = u32PageAddr;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ;
if (FMC->ISPCON & FMC_ISPCON_ISPFF_Msk) {
FMC->ISPCON |= FMC_ISPCON_ISPFF_Msk;
return -1;
}
return 0;
}
/**
* @brief Get the current boot source.
* @return The current boot source.
* @retval 0 Is boot from APROM.
* @retval 1 Is boot from LDROM.
*/
int32_t FMC_GetBootSource (void)
{
if (FMC->ISPCON & FMC_ISPCON_BS_Msk)
return 1;
else
return 0;
}
/**
* @brief Enable FMC ISP function
* @return None
*/
void FMC_Open(void)
{
FMC->ISPCON |= FMC_ISPCON_ISPEN_Msk;
}
/**
* @brief Execute ISP command to read a word from flash.
* @param[in] u32Addr Address of the flash location to be read.
* It must be a word aligned address.
* @return The word data read from specified flash address.
*/
uint32_t FMC_Read(uint32_t u32Addr)
{
FMC->ISPCMD = FMC_ISPCMD_READ;
FMC->ISPADR = u32Addr;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ;
return FMC->ISPDAT;
}
/**
* @brief Read company ID.
* @return The company ID.
*/
uint32_t FMC_ReadCID(void)
{
FMC->ISPCMD = FMC_ISPCMD_READ_CID;
FMC->ISPADR = 0x0;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ;
return FMC->ISPDAT;
}
/**
* @brief Read product ID.
* @return The product ID.
*/
uint32_t FMC_ReadPID(void)
{
FMC->ISPCMD = FMC_ISPCMD_READ_PID;
FMC->ISPADR = 0x04;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ;
return FMC->ISPDAT;
}
/**
* @brief This function reads one of the four UCID.
* @param[in] u32Index Index of the UCID to read. u32Index must be 0, 1, 2, or 3.
* @return The UCID.
*/
uint32_t FMC_ReadUCID(uint32_t u32Index)
{
FMC->ISPCMD = FMC_ISPCMD_READ_UID;
FMC->ISPADR = (0x04 * u32Index) + 0x10;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ;
return FMC->ISPDAT;
}
/**
* @brief This function reads one of the three UID.
* @param[in] u32Index Index of the UID to read. u32Index must be 0, 1, or 2.
* @return The UID.
*/
uint32_t FMC_ReadUID(uint32_t u32Index)
{
FMC->ISPCMD = FMC_ISPCMD_READ_UID;
FMC->ISPADR = 0x04 * u32Index;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ;
return FMC->ISPDAT;
}
/**
* @brief Get the base address of Data Flash if enabled.
* @return Base address of Data Flash
*/
uint32_t FMC_ReadDataFlashBaseAddr(void)
{
return FMC->DFBADR;
}
/**
* @brief This function will force re-map assigned flash page to CPU address 0x0.
* @param[in] u32PageAddr Address of the page to be mapped to CPU address 0x0.
* @return None
*/
void FMC_SetVectorPageAddr(uint32_t u32PageAddr)
{
FMC->ISPCMD = FMC_ISPCMD_VECMAP;
FMC->ISPADR = u32PageAddr;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ;
}
/**
* @brief Obtain the current vector page address setting.
* @return The vector page address.
*/
uint32_t FMC_GetVectorPageAddr(void)
{
return (FMC->ISPSTA & 0x0FFFFF00ul);
}
/**
* @brief Execute ISP command to program a word to flash.
* @param[in] u32Addr Address of the flash location to be programmed.
* It must be a word aligned address.
* @param[in] u32Data The word data to be programmed.
* @return None
*/
void FMC_Write(uint32_t u32Addr, uint32_t u32Data)
{
FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
FMC->ISPADR = u32Addr;
FMC->ISPDAT = u32Data;
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
while (FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ;
}
/**
* @brief Execute ISP command to read User Configuration.
* @param[out] u32Config A two-word array.
* u32Config[0] holds CONFIG0, while u32Config[1] holds CONFIG1.
* @param[in] u32Count Avaliable word count in u32Config.
* @return Success or not.
* @retval 0 Success.
* @retval -1 Invalid parameter.
*/
int32_t FMC_ReadConfig(uint32_t *u32Config, uint32_t u32Count)
{
u32Config[0] = FMC_Read(FMC_CONFIG_BASE);
if (u32Count < 2)
return -1;
u32Config[1] = FMC_Read(FMC_CONFIG_BASE+4);
return 0;
}
/**
* @brief Execute ISP command to write User Configuration.
* @param[in] u32Config A two-word array.
* u32Config[0] holds CONFIG0, while u32Config[1] holds CONFIG1.
* @param[in] u32Count Avaliable word count in u32Config.
* @return Success or not.
* @retval 0 Success.
* @retval -1 Invalid parameter.
*/
int32_t FMC_WriteConfig(uint32_t *u32Config, uint32_t u32Count)
{
FMC_ENABLE_CFG_UPDATE();
FMC_Erase(FMC_CONFIG_BASE);
FMC_Write(FMC_CONFIG_BASE, u32Config[0]);
FMC_Write(FMC_CONFIG_BASE+4, u32Config[1]);
FMC_DISABLE_CFG_UPDATE();
return 0;
}
/*@}*/ /* end of group NANO100_FMC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_FMC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,201 @@
/**************************************************************************//**
* @file fmc.h
* @version V1.00
* $Revision: 5 $
* $Date: 15/06/12 2:11p $
* @brief Nano100B Series Flash Memory Controller Driver Header File
*
* @note
* Copyright (C) 2015 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#ifndef __FMC_H__
#define __FMC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_FMC_Driver FMC Driver
@{
*/
/** @addtogroup NANO100_FMC_EXPORTED_CONSTANTS FMC Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Define Base Address */
/*---------------------------------------------------------------------------------------------------------*/
#define FMC_APROM_BASE 0x00000000UL /*!< APROM Base Address */
#define FMC_APROM_END 0x0001EC00UL /*!< APROM End Address */
#define FMC_LDROM_BASE 0x00100000UL /*!< LDROM Base Address */
#define FMC_LDROM_END 0x00101000UL /*!< LDROM End Address */
#define FMC_CONFIG_BASE 0x00300000UL /*!< User Configuration Address */
#define FMC_FLASH_PAGE_SIZE 0x200 /*!< Flash Page Size (512 bytes) */
#define FMC_LDROM_SIZE 0x1000 /*!< LDROM Size (4 Kbytes) */
/*---------------------------------------------------------------------------------------------------------*/
/* ISPCMD constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define FMC_ISPCMD_READ 0x00 /*!< ISP Command: Read flash word */
#define FMC_ISPCMD_PROGRAM 0x21 /*!< ISP Command: Write flash word */
#define FMC_ISPCMD_PAGE_ERASE 0x22 /*!< ISP Command: Page Erase Flash */
#define FMC_ISPCMD_READ_CID 0x0B /*!< ISP Command: Read Company ID */
#define FMC_ISPCMD_READ_PID 0x0C /*!< ISP Command: Read Product ID */
#define FMC_ISPCMD_READ_UID 0x04 /*!< ISP Command: Read Unique ID */
#define FMC_ISPCMD_VECMAP 0x2E /*!< ISP Command: Vector Page Remap */
#define IS_BOOT_FROM_APROM 0 /*!< Is booting from APROM */
#define IS_BOOT_FROM_LDROM 1 /*!< Is booting from LDROM */
/*@}*/ /* end of group NANO100_FMC_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_FMC_EXPORTED_FUNCTIONS FMC Exported Functions
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Macros */
/*---------------------------------------------------------------------------------------------------------*/
/**
* @brief This macro selects booting from APROM.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_SET_APROM_BOOT() (FMC->ISPCON &= ~FMC_ISPCON_BS_Msk)
/**
* @brief This macro selects booting from LDROM.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_SET_LDROM_BOOT() (FMC->ISPCON |= FMC_ISPCON_BS_Msk)
/**
* @brief This macro enables APROM update function.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_ENABLE_AP_UPDATE() (FMC->ISPCON |= FMC_ISPCON_APUEN_Msk)
/**
* @brief This macro disables APROM update function.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_DISABLE_AP_UPDATE() (FMC->ISPCON &= ~FMC_ISPCON_APUEN_Msk)
/**
* @brief This macro enables User Configuration update function.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_ENABLE_CFG_UPDATE() (FMC->ISPCON |= FMC_ISPCON_CFGUEN_Msk)
/**
* @brief This macro disables User Configuration update function.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_DISABLE_CFG_UPDATE() (FMC->ISPCON &= ~FMC_ISPCON_CFGUEN_Msk)
/**
* @brief This macro enables LDROM update function.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_ENABLE_LD_UPDATE() (FMC->ISPCON |= FMC_ISPCON_LDUEN_Msk)
/**
* @brief This macro disables LDROM update function.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_DISABLE_LD_UPDATE() (FMC->ISPCON &= ~FMC_ISPCON_LDUEN_Msk)
/**
* @brief This macro enables ISP function.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_ENABLE_ISP() (FMC->ISPCON |= FMC_ISPCON_ISPEN_Msk)
/**
* @brief This macro disables ISP function.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_DISABLE_ISP() (FMC->ISPCON &= ~FMC_ISPCON_ISPEN_Msk)
/**
* @brief This macro gets ISP fail flag value.
* @param None
* @return ISP fail flag value.
* \hideinitializer
*/
#define FMC_GET_FAIL_FLAG() ((FMC->ISPCON & FMC_ISPCON_ISPFF_Msk) ? 1 : 0)
/**
* @brief This macro clears ISP fail flag.
* @param None
* @return None
* \hideinitializer
*/
#define FMC_CLR_FAIL_FLAG() (FMC->ISPCON |= FMC_ISPCON_ISPFF_Msk)
/*---------------------------------------------------------------------------------------------------------*/
/* Functions */
/*---------------------------------------------------------------------------------------------------------*/
extern void FMC_Close(void);
extern int32_t FMC_Erase(uint32_t u32PageAddr);
extern int32_t FMC_GetBootSource(void);
extern void FMC_Open(void);
extern uint32_t FMC_Read(uint32_t u32Addr);
extern uint32_t FMC_ReadCID(void);
extern uint32_t FMC_ReadPID(void);
extern uint32_t FMC_ReadUCID(uint32_t u32Index);
extern uint32_t FMC_ReadUID(uint32_t u32Index);
extern uint32_t FMC_ReadDataFlashBaseAddr(void);
extern void FMC_SetVectorPageAddr(uint32_t u32PageAddr);
extern uint32_t FMC_GetVectorPageAddr(void);
extern void FMC_Write(uint32_t u32Addr, uint32_t u32Data);
extern int32_t FMC_ReadConfig(uint32_t *u32Config, uint32_t u32Count);
extern int32_t FMC_WriteConfig(uint32_t *u32Config, uint32_t u32Count);
/*@}*/ /* end of group NANO100_FMC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_FMC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif // __FMC_H__
/*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,93 @@
/**************************************************************************//**
* @file gpio.c
* @version V1.00
* $Revision: 3 $
* $Date: 14/09/29 3:50p $
* @brief Nano100 series GPIO driver source file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_GPIO_Driver GPIO Driver
@{
*/
/** @addtogroup NANO100_GPIO_EXPORTED_FUNCTIONS GPIO Exported Functions
@{
*/
/**
* @brief Set GPIO operation mode
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified GPIO port.
* @param[in] u32Mode Operation mode. \ref GPIO_PMD_INPUT, \ref GPIO_PMD_OUTPUT, \ref GPIO_PMD_OPEN_DRAIN
*
* @return None
*
* @details This function is used to set specified GPIO operation mode.
*/
void GPIO_SetMode(GPIO_T *gpio, uint32_t u32PinMask, uint32_t u32Mode)
{
uint32_t i;
for (i=0; i<GPIO_PIN_MAX; i++) {
if (u32PinMask & (1 << i)) {
gpio->PMD = (gpio->PMD & ~(0x3 << (i << 1))) | (u32Mode << (i << 1));
}
}
}
/**
* @brief Enable GPIO interrupt
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32Pin The pin of specified GPIO port. It could be 0 ~ 15
* @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.
*/
void GPIO_EnableInt(GPIO_T *gpio, uint32_t u32Pin, uint32_t u32IntAttribs)
{
gpio->IMD |= (((u32IntAttribs >> 24) & 0xFFUL) << u32Pin);
gpio->IER |= ((u32IntAttribs & 0xFFFFFFUL) << u32Pin);
}
/**
* @brief Disable GPIO interrupt
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32Pin The pin of specified GPIO port. It could be 0 ~ 15
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
void GPIO_DisableInt(GPIO_T *gpio, uint32_t u32Pin)
{
gpio->IMD &= ~(1UL << u32Pin);
gpio->IER &= ~((0x00010001UL) << u32Pin);
}
/*@}*/ /* end of group NANO100_GPIO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_GPIO_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,443 @@
/**************************************************************************//**
* @file gpio.h
* @version V1.00
* $Revision: 7 $
* $Date: 14/12/01 10:30a $
* @brief Nano100 series GPIO driver header file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __GPIO_H__
#define __GPIO_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_GPIO_Driver GPIO Driver
@{
*/
/** @addtogroup NANO100_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 */
/*---------------------------------------------------------------------------------------------------------*/
/* 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_ICLK_ON 0x00000020UL /*!< DBNCECON setting for all IO pins edge detection circuit is always active after reset */
#define GPIO_ICLK_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_IRC10K 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 internal HCLK */
#define GPIO_DBCLKSEL_1 0x00000000UL /*!< DBNCECON setting for sampling cycle = 1 clocks */
#define GPIO_DBCLKSEL_2 0x00000001UL /*!< DBNCECON setting for sampling cycle = 2 clocks */
#define GPIO_DBCLKSEL_4 0x00000002UL /*!< DBNCECON setting for sampling cycle = 4 clocks */
#define GPIO_DBCLKSEL_8 0x00000003UL /*!< DBNCECON setting for sampling cycle = 8 clocks */
#define GPIO_DBCLKSEL_16 0x00000004UL /*!< DBNCECON setting for sampling cycle = 16 clocks */
#define GPIO_DBCLKSEL_32 0x00000005UL /*!< DBNCECON setting for sampling cycle = 32 clocks */
#define GPIO_DBCLKSEL_64 0x00000006UL /*!< DBNCECON setting for sampling cycle = 64 clocks */
#define GPIO_DBCLKSEL_128 0x00000007UL /*!< DBNCECON setting for sampling cycle = 128 clocks */
#define GPIO_DBCLKSEL_256 0x00000008UL /*!< DBNCECON setting for sampling cycle = 256 clocks */
#define GPIO_DBCLKSEL_512 0x00000009UL /*!< DBNCECON setting for sampling cycle = 512 clocks */
#define GPIO_DBCLKSEL_1024 0x0000000AUL /*!< DBNCECON setting for sampling cycle = 1024 clocks */
#define GPIO_DBCLKSEL_2048 0x0000000BUL /*!< DBNCECON setting for sampling cycle = 2048 clocks */
#define GPIO_DBCLKSEL_4096 0x0000000CUL /*!< DBNCECON setting for sampling cycle = 4096 clocks */
#define GPIO_DBCLKSEL_8192 0x0000000DUL /*!< DBNCECON setting for sampling cycle = 8192 clocks */
#define GPIO_DBCLKSEL_16384 0x0000000EUL /*!< DBNCECON setting for sampling cycle = 16384 clocks */
#define GPIO_DBCLKSEL_32768 0x0000000FUL /*!< DBNCECON setting for sampling cycle = 32768 clocks */
/** Define GPIO Pin Data Input/Output. It could be used to control each I/O pin by pin address mapping.
* Example 1:
*
* PA0 = 1;
*
* It is used to set PA0 to high;
*
* Example 2:
*
* if (PA0)
* PA0 = 0;
*
* If PA0 pin status is high, then set PA0 data output to low.
*/
#define GPIO_PIN_ADDR(port, pin) (*((volatile uint32_t *)((GPIO_PIN_DATA_BASE+(0x40*(port))) + ((pin)<<2))))
#define PA0 GPIO_PIN_ADDR(0, 0) /*!< Specify PA0 Pin Data Input/Output */
#define PA1 GPIO_PIN_ADDR(0, 1) /*!< Specify PA1 Pin Data Input/Output */
#define PA2 GPIO_PIN_ADDR(0, 2) /*!< Specify PA2 Pin Data Input/Output */
#define PA3 GPIO_PIN_ADDR(0, 3) /*!< Specify PA3 Pin Data Input/Output */
#define PA4 GPIO_PIN_ADDR(0, 4) /*!< Specify PA4 Pin Data Input/Output */
#define PA5 GPIO_PIN_ADDR(0, 5) /*!< Specify PA5 Pin Data Input/Output */
#define PA6 GPIO_PIN_ADDR(0, 6) /*!< Specify PA6 Pin Data Input/Output */
#define PA7 GPIO_PIN_ADDR(0, 7) /*!< Specify PA7 Pin Data Input/Output */
#define PA8 GPIO_PIN_ADDR(0, 8) /*!< Specify PA8 Pin Data Input/Output */
#define PA9 GPIO_PIN_ADDR(0, 9) /*!< Specify PA9 Pin Data Input/Output */
#define PA10 GPIO_PIN_ADDR(0, 10) /*!< Specify PA10 Pin Data Input/Output */
#define PA11 GPIO_PIN_ADDR(0, 11) /*!< Specify PA11 Pin Data Input/Output */
#define PA12 GPIO_PIN_ADDR(0, 12) /*!< Specify PA12 Pin Data Input/Output */
#define PA13 GPIO_PIN_ADDR(0, 13) /*!< Specify PA13 Pin Data Input/Output */
#define PA14 GPIO_PIN_ADDR(0, 14) /*!< Specify PA14 Pin Data Input/Output */
#define PA15 GPIO_PIN_ADDR(0, 15) /*!< Specify PA15 Pin Data Input/Output */
#define PB0 GPIO_PIN_ADDR(1, 0) /*!< Specify PB0 Pin Data Input/Output */
#define PB1 GPIO_PIN_ADDR(1, 1) /*!< Specify PB1 Pin Data Input/Output */
#define PB2 GPIO_PIN_ADDR(1, 2) /*!< Specify PB2 Pin Data Input/Output */
#define PB3 GPIO_PIN_ADDR(1, 3) /*!< Specify PB3 Pin Data Input/Output */
#define PB4 GPIO_PIN_ADDR(1, 4) /*!< Specify PB4 Pin Data Input/Output */
#define PB5 GPIO_PIN_ADDR(1, 5) /*!< Specify PB5 Pin Data Input/Output */
#define PB6 GPIO_PIN_ADDR(1, 6) /*!< Specify PB6 Pin Data Input/Output */
#define PB7 GPIO_PIN_ADDR(1, 7) /*!< Specify PB7 Pin Data Input/Output */
#define PB8 GPIO_PIN_ADDR(1, 8) /*!< Specify PB8 Pin Data Input/Output */
#define PB9 GPIO_PIN_ADDR(1, 9) /*!< Specify PB9 Pin Data Input/Output */
#define PB10 GPIO_PIN_ADDR(1, 10) /*!< Specify PB10 Pin Data Input/Output */
#define PB11 GPIO_PIN_ADDR(1, 11) /*!< Specify PB11 Pin Data Input/Output */
#define PB12 GPIO_PIN_ADDR(1, 12) /*!< Specify PB12 Pin Data Input/Output */
#define PB13 GPIO_PIN_ADDR(1, 13) /*!< Specify PB13 Pin Data Input/Output */
#define PB14 GPIO_PIN_ADDR(1, 14) /*!< Specify PB14 Pin Data Input/Output */
#define PB15 GPIO_PIN_ADDR(1, 15) /*!< Specify PB15 Pin Data Input/Output */
#define PC0 GPIO_PIN_ADDR(2, 0) /*!< Specify PC0 Pin Data Input/Output */
#define PC1 GPIO_PIN_ADDR(2, 1) /*!< Specify PC1 Pin Data Input/Output */
#define PC2 GPIO_PIN_ADDR(2, 2) /*!< Specify PC2 Pin Data Input/Output */
#define PC3 GPIO_PIN_ADDR(2, 3) /*!< Specify PC3 Pin Data Input/Output */
#define PC4 GPIO_PIN_ADDR(2, 4) /*!< Specify PC4 Pin Data Input/Output */
#define PC5 GPIO_PIN_ADDR(2, 5) /*!< Specify PC5 Pin Data Input/Output */
#define PC6 GPIO_PIN_ADDR(2, 6) /*!< Specify PC6 Pin Data Input/Output */
#define PC7 GPIO_PIN_ADDR(2, 7) /*!< Specify PC7 Pin Data Input/Output */
#define PC8 GPIO_PIN_ADDR(2, 8) /*!< Specify PC8 Pin Data Input/Output */
#define PC9 GPIO_PIN_ADDR(2, 9) /*!< Specify PC9 Pin Data Input/Output */
#define PC10 GPIO_PIN_ADDR(2, 10) /*!< Specify PC10 Pin Data Input/Output */
#define PC11 GPIO_PIN_ADDR(2, 11) /*!< Specify PC11 Pin Data Input/Output */
#define PC12 GPIO_PIN_ADDR(2, 12) /*!< Specify PC12 Pin Data Input/Output */
#define PC13 GPIO_PIN_ADDR(2, 13) /*!< Specify PC13 Pin Data Input/Output */
#define PC14 GPIO_PIN_ADDR(2, 14) /*!< Specify PC14 Pin Data Input/Output */
#define PC15 GPIO_PIN_ADDR(2, 15) /*!< Specify PC15 Pin Data Input/Output */
#define PD0 GPIO_PIN_ADDR(3, 0) /*!< Specify PD0 Pin Data Input/Output */
#define PD1 GPIO_PIN_ADDR(3, 1) /*!< Specify PD1 Pin Data Input/Output */
#define PD2 GPIO_PIN_ADDR(3, 2) /*!< Specify PD2 Pin Data Input/Output */
#define PD3 GPIO_PIN_ADDR(3, 3) /*!< Specify PD3 Pin Data Input/Output */
#define PD4 GPIO_PIN_ADDR(3, 4) /*!< Specify PD4 Pin Data Input/Output */
#define PD5 GPIO_PIN_ADDR(3, 5) /*!< Specify PD5 Pin Data Input/Output */
#define PD6 GPIO_PIN_ADDR(3, 6) /*!< Specify PD6 Pin Data Input/Output */
#define PD7 GPIO_PIN_ADDR(3, 7) /*!< Specify PD7 Pin Data Input/Output */
#define PD8 GPIO_PIN_ADDR(3, 8) /*!< Specify PD8 Pin Data Input/Output */
#define PD9 GPIO_PIN_ADDR(3, 9) /*!< Specify PD9 Pin Data Input/Output */
#define PD10 GPIO_PIN_ADDR(3, 10) /*!< Specify PD10 Pin Data Input/Output */
#define PD11 GPIO_PIN_ADDR(3, 11) /*!< Specify PD11 Pin Data Input/Output */
#define PD12 GPIO_PIN_ADDR(3, 12) /*!< Specify PD12 Pin Data Input/Output */
#define PD13 GPIO_PIN_ADDR(3, 13) /*!< Specify PD13 Pin Data Input/Output */
#define PD14 GPIO_PIN_ADDR(3, 14) /*!< Specify PD14 Pin Data Input/Output */
#define PD15 GPIO_PIN_ADDR(3, 15) /*!< Specify PD15 Pin Data Input/Output */
#define PE0 GPIO_PIN_ADDR(4, 0) /*!< Specify PE0 Pin Data Input/Output */
#define PE1 GPIO_PIN_ADDR(4, 1) /*!< Specify PE1 Pin Data Input/Output */
#define PE2 GPIO_PIN_ADDR(4, 2) /*!< Specify PE2 Pin Data Input/Output */
#define PE3 GPIO_PIN_ADDR(4, 3) /*!< Specify PE3 Pin Data Input/Output */
#define PE4 GPIO_PIN_ADDR(4, 4) /*!< Specify PE4 Pin Data Input/Output */
#define PE5 GPIO_PIN_ADDR(4, 5) /*!< Specify PE5 Pin Data Input/Output */
#define PE6 GPIO_PIN_ADDR(4, 6) /*!< Specify PE6 Pin Data Input/Output */
#define PE7 GPIO_PIN_ADDR(4, 7) /*!< Specify PE7 Pin Data Input/Output */
#define PE8 GPIO_PIN_ADDR(4, 8) /*!< Specify PE8 Pin Data Input/Output */
#define PE9 GPIO_PIN_ADDR(4, 9) /*!< Specify PE9 Pin Data Input/Output */
#define PE10 GPIO_PIN_ADDR(4, 10) /*!< Specify PE10 Pin Data Input/Output */
#define PE11 GPIO_PIN_ADDR(4, 11) /*!< Specify PE11 Pin Data Input/Output */
#define PE12 GPIO_PIN_ADDR(4, 12) /*!< Specify PE12 Pin Data Input/Output */
#define PE13 GPIO_PIN_ADDR(4, 13) /*!< Specify PE13 Pin Data Input/Output */
#define PE14 GPIO_PIN_ADDR(4, 14) /*!< Specify PE14 Pin Data Input/Output */
#define PE15 GPIO_PIN_ADDR(4, 15) /*!< Specify PE15 Pin Data Input/Output */
#define PF0 GPIO_PIN_ADDR(5, 0) /*!< Specify PF0 Pin Data Input/Output */
#define PF1 GPIO_PIN_ADDR(5, 1) /*!< Specify PF1 Pin Data Input/Output */
#define PF2 GPIO_PIN_ADDR(5, 2) /*!< Specify PF2 Pin Data Input/Output */
#define PF3 GPIO_PIN_ADDR(5, 3) /*!< Specify PF3 Pin Data Input/Output */
#define PF4 GPIO_PIN_ADDR(5, 4) /*!< Specify PF4 Pin Data Input/Output */
#define PF5 GPIO_PIN_ADDR(5, 5) /*!< Specify PF5 Pin Data Input/Output */
/*@}*/ /* end of group NANO100_GPIO_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_GPIO_EXPORTED_FUNCTIONS GPIO Exported Functions
@{
*/
/**
* @brief Clear GPIO Pin Interrupt Flag
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified GPIO port
*
* @return None
*
* @details Clear the interrupt status of specified GPIO pin.
*/
#define GPIO_CLR_INT_FLAG(gpio, u32PinMask) ((gpio)->ISRC = u32PinMask)
/**
* @brief Disable Pin De-bounce Function
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified GPIO port
*
* @return None
*
* @details Disable the interrupt de-bounce function of specified GPIO pin.
*/
#define GPIO_DISABLE_DEBOUNCE(gpio, u32PinMask) ((gpio)->DBEN &= ~u32PinMask)
/**
* @brief Enable Pin De-bounce Function
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified GPIO port
*
* @return None
*
* @details Enable the interrupt de-bounce function of specified GPIO pin.
*/
#define GPIO_ENABLE_DEBOUNCE(gpio, u32PinMask) ((gpio)->DBEN |= u32PinMask)
/**
* @brief Disable I/O Digital Input Path
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified GPIO port
*
* @return None
*
* @details Disable I/O digital input path of specified GPIO pin.
*/
#define GPIO_DISABLE_DIGITAL_PATH(gpio, u32PinMask) ((gpio)->OFFD |= (u32PinMask << 16))
/**
* @brief Enable I/O Digital Input Path
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified GPIO port
*
* @return None
*
* @details Enable I/O digital input path of specified GPIO pin.
*/
#define GPIO_ENABLE_DIGITAL_PATH(gpio, u32PinMask) ((gpio)->OFFD &= ~(u32PinMask << 16))
/**
* @brief Disable I/O DOUT mask
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified GPIO port
*
* @return None
*
* @details Disable I/O DOUT mask of specified GPIO pin.
*/
#define GPIO_DISABLE_DOUT_MASK(gpio, u32PinMask) ((gpio)->DMASK &= ~u32PinMask)
/**
* @brief Enable I/O DOUT mask
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified GPIO port
*
* @return None
*
* @details Enable I/O DOUT mask of specified GPIO pin.
*/
#define GPIO_ENABLE_DOUT_MASK(gpio, u32PinMask) ((gpio)->DMASK |= u32PinMask)
/**
* @brief Get GPIO Pin Interrupt Flag
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified 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(gpio, u32PinMask) ((gpio)->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 or \ref GPIO_DBCLKSRC_IRC10K
* @param[in] u32ClkSel The de-bounce sampling cycle selection. It could be \n
* \ref GPIO_DBCLKSEL_1, \ref GPIO_DBCLKSEL_2, \ref GPIO_DBCLKSEL_4, \ref GPIO_DBCLKSEL_8, \n
* \ref GPIO_DBCLKSEL_16, \ref GPIO_DBCLKSEL_32, \ref GPIO_DBCLKSEL_64, \ref GPIO_DBCLKSEL_128, \n
* \ref GPIO_DBCLKSEL_256, \ref GPIO_DBCLKSEL_512, \ref GPIO_DBCLKSEL_1024, \ref GPIO_DBCLKSEL_2048, \n
* \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: \ref GPIO_SET_DEBOUNCE_TIME(\ref GPIO_DBCLKSRC_IRC10K, \ref 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 (2^4)*(1/(10*1000)) s = 16*0.0001 s = 1600 us,
* and system will sampling interrupt input once per 1600 us.
*/
#define GPIO_SET_DEBOUNCE_TIME(u32ClkSrc, u32ClkSel) (GPIO->DBNCECON = (GP_DBNCECON_DBCLK_ON_Msk | u32ClkSrc | u32ClkSel))
/**
* @brief Get GPIO Port IN Data
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
*
* @retval The specified port data
*
* @details Get the PIN register of specified GPIO port.
*/
#define GPIO_GET_IN_DATA(gpio) ((gpio)->PIN)
/**
* @brief Set GPIO Port OUT Data
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32Data GPIO port data
*
* @retval None
*
* @details Set the Data into specified GPIO port.
*/
#define GPIO_SET_OUT_DATA(gpio, u32Data) ((gpio)->DOUT = (u32Data))
/**
* @brief Disable Pin Pull-up resistor Function
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified GPIO port
*
* @return None
*
* @details Disable the Pull-up resistor function of specified GPIO pin.
*/
#define GPIO_DISABLE_PULL_UP(gpio, u32PinMask) ((gpio)->PUEN &= ~u32PinMask)
/**
* @brief Enable Pin Pull-up resistor Function
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32PinMask The single or multiple pins of specified GPIO port
*
* @return None
*
* @details Enable the Pull-up resistor function of specified GPIO pin.
*/
#define GPIO_ENABLE_PULL_UP(gpio, u32PinMask) ((gpio)->PUEN |= u32PinMask)
/**
* @brief Toggle Specified GPIO pin
*
* @param[in] u32Pin Pxy
*
* @retval None
*
* @details Toggle the specified GPIO pint.
*/
#define GPIO_TOGGLE(u32Pin) ((u32Pin) ^= 1)
/**
* @brief Enable External GPIO interrupt 0
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32Pin The pin of specified 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] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32Pin The pin of specified GPIO port. It could be 0 ~ 15
*
* @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] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32Pin The pin of specified 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_EnableEINT1 GPIO_EnableInt
/**
* @brief Disable External GPIO interrupt 1
*
* @param[in] gpio GPIO port. It could be \ref PA, \ref PB, \ref PC, \ref PD, \ref PE or \ref PF
* @param[in] u32Pin The pin of specified GPIO port. It could be 0 ~ 15
*
* @return None
*
* @details This function is used to enable specified GPIO pin interrupt.
*/
#define GPIO_DisableEINT1 GPIO_DisableInt
void GPIO_SetMode(GPIO_T *gpio, uint32_t u32PinMask, uint32_t u32Mode);
void GPIO_EnableInt(GPIO_T *gpio, uint32_t u32Pin, uint32_t u32IntAttribs);
void GPIO_DisableInt(GPIO_T *gpio, uint32_t u32Pin);
/*@}*/ /* end of group NANO100_GPIO_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_GPIO_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__GPIO_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,296 @@
/****************************************************************************//**
* @file i2c.c
* @version V0.10
* $Revision: 7 $
* $Date: 15/06/05 5:04p $
* @brief NANO100 series I2C driver source file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "nano100series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_I2C_Driver I2C Driver
@{
*/
/** @addtogroup NANO100_I2C_EXPORTED_FUNCTIONS I2C Exported Functions
@{
*/
/**
* @brief This function make I2C module be ready and set the wanted bus clock.
* @param[in] i2c is the base address of I2C module.
* @param[in] u32BusClock is the target bus speed of I2C module.
* @return Actual I2C bus clock frequency.
*/
uint32_t I2C_Open(I2C_T *i2c, uint32_t u32BusClock)
{
uint32_t u32Div;
u32Div = (uint32_t) (((SystemCoreClock * 10)/(u32BusClock * 4) + 5) / 10 - 1); /* Compute proper divider for I2C clock */
i2c->DIV = u32Div;
/* Enable I2C */
i2c->CON |= I2C_CON_IPEN_Msk;
return ( SystemCoreClock / ((u32Div+1)<<2) );
}
/**
* @brief This function closes the I2C module.
* @param[in] i2c is the base address of I2C module.
* @return none
*/
void I2C_Close(I2C_T *i2c)
{
/* Reset I2C */
if((uint32_t)i2c == I2C0_BASE) {
SYS->IPRST_CTL2 |= SYS_IPRST_CTL2_I2C0_RST_Msk;
SYS->IPRST_CTL2 &= ~SYS_IPRST_CTL2_I2C0_RST_Msk;
} else {
SYS->IPRST_CTL2 |= SYS_IPRST_CTL2_I2C1_RST_Msk;
SYS->IPRST_CTL2 &= ~SYS_IPRST_CTL2_I2C1_RST_Msk;
}
/* Disable I2C */
i2c->CON &= ~I2C_CON_IPEN_Msk;
}
/**
* @brief This function clears the timeout flag.
* @param[in] i2c is the base address of I2C module.
* @return none
*/
void I2C_ClearTimeoutFlag(I2C_T *i2c)
{
i2c->INTSTS |= I2C_INTSTS_TIF_Msk;
}
/**
* @brief This function sets the control bit of the I2C module.
* @param[in] i2c is the base address of I2C module.
* @param[in] u8Start sets START bit to I2C module.
* @param[in] u8Stop sets STOP bit to I2C module.
* @param[in] u8Si sets SI bit to I2C module.
* @param[in] u8Ack sets ACK bit to I2C module.
* @return none
*/
void I2C_Trigger(I2C_T *i2c, uint8_t u8Start, uint8_t u8Stop, uint8_t u8Si, uint8_t u8Ack)
{
uint32_t u32Reg = 0;
uint32_t u32Val = i2c->CON & ~(I2C_STA | I2C_STO | I2C_AA);
if (u8Start)
u32Reg |= I2C_STA;
if (u8Stop)
u32Reg |= I2C_STO;
if (u8Si)
u32Reg |= I2C_SI;
if (u8Ack)
u32Reg |= I2C_AA;
i2c->CON = u32Val | u32Reg;
}
/**
* @brief This function disables the interrupt of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return none
*/
void I2C_DisableInt(I2C_T *i2c)
{
i2c->CON &= ~I2C_CON_INTEN_Msk;
}
/**
* @brief This function enables the interrupt (EI bit) of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return none
*/
void I2C_EnableInt(I2C_T *i2c)
{
i2c->CON |= I2C_CON_INTEN_Msk;
}
/**
* @brief This function returns the real bus clock of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return Actual I2C bus clock frequency.
*/
uint32_t I2C_GetBusClockFreq(I2C_T *i2c)
{
uint32_t u32Divider = i2c->DIV;
return ( SystemCoreClock / ((u32Divider+1)<<2) );
}
/**
* @brief This function sets bus frequency of I2C module.
* @param[in] i2c is the base address of I2C module.
* @param[in] u32BusClock is the target bus speed of I2C module.
* @return Actual I2C bus clock frequency.
*/
uint32_t I2C_SetBusClockFreq(I2C_T *i2c, uint32_t u32BusClock)
{
uint32_t u32Div;
u32Div = (uint32_t) (((SystemCoreClock * 10)/(u32BusClock * 4) + 5) / 10 - 1); /* Compute proper divider for I2C clock */
i2c->DIV = u32Div;
return ( SystemCoreClock / ((u32Div+1)<<2) );
}
/**
* @brief This function gets the interrupt flag of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return Interrupt flag.
* @retval 0 Flag is not set.
* @retval 1 Flag is set.
*/
uint32_t I2C_GetIntFlag(I2C_T *i2c)
{
return ( (i2c->INTSTS & I2C_INTSTS_INTSTS_Msk) == I2C_INTSTS_INTSTS_Msk ? 1:0 );
}
/**
* @brief This function clears the interrupt flag of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return none
*/
void I2C_ClearIntFlag(I2C_T *i2c)
{
i2c->INTSTS |= I2C_INTSTS_INTSTS_Msk;
}
/**
* @brief This function returns the status of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return I2C status
*/
uint32_t I2C_GetStatus(I2C_T *i2c)
{
return ( i2c->STATUS );
}
/**
* @brief This function returns the data stored in data register of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return Data.
*/
uint32_t I2C_GetData(I2C_T *i2c)
{
return ( i2c->DATA );
}
/**
* @brief This function writes the data to data register of I2C module.
* @param[in] i2c is the base address of I2C module.
* @param[in] u8Data is the data which will be write to data register of I2C module.
* @return none
*/
void I2C_SetData(I2C_T *i2c, uint8_t u8Data)
{
i2c->DATA = u8Data;
}
/**
* @brief Configure slave address and enable GC mode.
* @param[in] i2c is the base address of I2C module.
* @param[in] u8SlaveNo is the set number of salve address.
* @param[in] u8SlaveAddr is the slave address.
* @param[in] u8GCMode GC mode enable or not. Valid values are:
* - \ref I2C_GCMODE_ENABLE
* - \ref I2C_GCMODE_DISABLE
* @return none
*/
void I2C_SetSlaveAddr(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddr, uint8_t u8GCMode)
{
switch (u8SlaveNo) {
case 0:
i2c->SADDR0 = (u8SlaveAddr << 1) | u8GCMode;
break;
case 1:
i2c->SADDR1 = (u8SlaveAddr << 1) | u8GCMode;
break;
}
}
/**
* @brief Configure the mask of slave address. The corresponding address bit is "Don't Care".
* @param[in] i2c is the base address of I2C module.
* @param[in] u8SlaveNo is the set number of salve address.
* @param[in] u8SlaveAddrMask is the slave address mask.
* @return none
*/
void I2C_SetSlaveAddrMask(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddrMask)
{
switch (u8SlaveNo) {
case 0:
i2c->SAMASK0 = u8SlaveAddrMask << 1;
break;
case 1:
i2c->SAMASK1 = u8SlaveAddrMask << 1;
break;
}
}
/**
* @brief This function enables timeout function and configures DIV4 function to support long timeout.
* @param[in] i2c is the base address of I2C module.
* @param[in] u8LongTimeout Enable timeout counter input clock is divide by 4.
* @return none
*/
void I2C_EnableTimeout(I2C_T *i2c, uint8_t u8LongTimeout)
{
if(u8LongTimeout)
i2c->TOUT |= I2C_TOUT_DIV4_Msk;
else
i2c->TOUT &= ~I2C_TOUT_DIV4_Msk;
i2c->TOUT |= I2C_TOUT_TOUTEN_Msk;
}
/**
* @brief This function disables timeout function.
* @param[in] i2c is the base address of I2C module.
* @return none
*/
void I2C_DisableTimeout(I2C_T *i2c)
{
i2c->TOUT &= ~I2C_TOUT_TOUTEN_Msk;
}
/**
* @brief This function enables the wakeup function of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return none
*/
void I2C_EnableWakeup(I2C_T *i2c)
{
i2c->WKUPCON |= I2C_WKUPCON_WKUPEN_Msk;
}
/**
* @brief This function disables the wakeup function of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return none
*/
void I2C_DisableWakeup(I2C_T *i2c)
{
i2c->WKUPCON &= ~I2C_WKUPCON_WKUPEN_Msk;
}
/*@}*/ /* end of group NANO100_I2C_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_I2C_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,181 @@
/****************************************************************************//**
* @file i2c.h
* @version V1.00
* $Revision: 5 $
* $Date: 15/06/05 5:06p $
* @brief Nano100 series I2C driver header file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __I2C_H__
#define __I2C_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_I2C_Driver I2C Driver
@{
*/
/** @addtogroup NANO100_I2C_EXPORTED_CONSTANTS I2C Exported Constants
@{
*/
#define I2C_STA 0x08 /*!< I2C START bit value */
#define I2C_STO 0x04 /*!< I2C STOP bit value*/
#define I2C_SI 0x10 /*!< I2C SI bit value */
#define I2C_AA 0x02 /*!< I2C ACK bit value */
#define I2C_GCMODE_ENABLE 1 /*!< Enable I2C GC Mode */
#define I2C_GCMODE_DISABLE 0 /*!< Disable I2C GC Mode */
/*@}*/ /* end of group NANO100_I2C_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_I2C_EXPORTED_FUNCTIONS I2C Exported Functions
@{
*/
/**
* @brief This macro sets the I2C control register at one time.
* @param[in] i2c is the base address of I2C module.
* @param[in] u8Ctrl is the register value of I2C control register.
* @return none
* \hideinitializer
*/
#define I2C_SET_CONTROL_REG(i2c, u8Ctrl) ( (i2c)->CON = ((i2c)->CON & ~0x1e) | u8Ctrl )
/**
* @brief This macro only set START bit to the control register of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return none
* \hideinitializer
*/
#define I2C_START(i2c) ( (i2c)->CON = ((i2c)->CON & ~I2C_CON_I2C_STS_Msk) | I2C_CON_START_Msk )
/**
* @brief This macro only set STOP bit to the control register of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return none
* \hideinitializer
*/
static __INLINE void I2C_STOP(I2C_T *i2c)
{
i2c->CON |= (I2C_CON_I2C_STS_Msk | I2C_CON_STOP_Msk);
while(i2c->CON & I2C_CON_STOP_Msk);
}
/**
* @brief This macro will return when I2C module is ready.
* @param[in] i2c is the base address of I2C module.
* @return none
* \hideinitializer
*/
static __INLINE void I2C_WAIT_READY(I2C_T *i2c)
{
while(!(i2c->INTSTS & I2C_INTSTS_INTSTS_Msk));
i2c->INTSTS |= I2C_INTSTS_INTSTS_Msk;
}
/**
* @brief This macro returns the data stored in data register of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return Data.
* \hideinitializer
*/
#define I2C_GET_DATA(i2c) ( (i2c)->DATA )
/**
* @brief This macro writes the data to data register of I2C module.
* @param[in] i2c is the base address of I2C module.
* @param[in] u8Data is the data which will be write to data register of I2C module.
* @return none
* \hideinitializer
*/
#define I2C_SET_DATA(i2c, u8Data) ( (i2c)->DATA = u8Data )
/**
* @brief This macro returns the status of I2C module.
* @param[in] i2c is the base address of I2C module.
* @return Status.
* \hideinitializer
*/
#define I2C_GET_STATUS(i2c) ( (i2c)->STATUS )
/**
* @brief This macro returns timeout flag.
* @param[in] i2c is the base address of I2C module.
* @return Status.
* @retval 0 Flag is not set.
* @retval 1 Flag is set.
* \hideinitializer
*/
#define I2C_GET_TIMEOUT_FLAG(i2c) ( ((i2c)->INTSTS & I2C_INTSTS_TIF_Msk) == I2C_INTSTS_TIF_Msk ? 1:0 )
/**
* @brief This macro clears timeout flag.
* @param[in] i2c is the base address of I2C module.
* @return none
* \hideinitializer
*/
#define I2C_CLEAR_TIMEOUT_FLAG(i2c) ( (i2c)->INTSTS |= I2C_INTSTS_TIF_Msk )
/**
* @brief This macro returns wakeup flag.
* @param[in] i2c is the base address of I2C module.
* @return Status.
* @retval 0 Flag is not set.
* @retval 1 Flag is set.
* \hideinitializer
*/
#define I2C_GET_WAKEUP_FLAG(i2c) ( ((i2c)->WKUPSTS & I2C_WKUPSTS_WKUPIF_Msk) == I2C_WKUPSTS_WKUPIF_Msk ? 1:0 )
/**
* @brief This macro clears wakeup flag.
* @param[in] i2c is the base address of I2C module.
* @return none
* \hideinitializer
*/
#define I2C_CLEAR_WAKEUP_FLAG(i2c) ( (i2c)->WKUPSTS |= I2C_WKUPSTS_WKUPIF_Msk )
uint32_t I2C_Open(I2C_T *i2c, uint32_t u32BusClock);
void I2C_Close(I2C_T *i2c);
void I2C_ClearTimeoutFlag(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);
void I2C_ClearIntFlag(I2C_T *i2c);
uint32_t I2C_GetStatus(I2C_T *i2c);
uint32_t I2C_GetData(I2C_T *i2c);
void I2C_SetData(I2C_T *i2c, uint8_t u8Data);
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);
/*@}*/ /* end of group NANO100_I2C_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_I2C_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__I2C_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,204 @@
/**************************************************************************//**
* @file i2s.c
* @version V1.00
* $Revision: 4 $
* $Date: 15/06/08 4:58p $
* @brief Nano100 series I2S driver header file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_I2S_Driver I2S Driver
@{
*/
/** @addtogroup NANO100_I2S_EXPORTED_FUNCTIONS I2S Exported Functions
@{
*/
/// @cond HIDDEN_SYMBOLS
/**
* @brief This function is used to get I2S source clock frequency.
* @param[in] i2s is the base address of I2S module.
* @return I2S source clock frequency (Hz).
*/
static uint32_t I2S_GetSourceClockFreq(I2S_T *i2s)
{
uint32_t u32Freq, u32ClkSrcSel;
// get I2S selection clock source
u32ClkSrcSel = CLK->CLKSEL2 & CLK_CLKSEL2_I2S_S_Msk;
switch (u32ClkSrcSel) {
case CLK_CLKSEL2_I2S_S_HXT:
u32Freq = __HXT;
break;
case CLK_CLKSEL2_I2S_S_PLL:
u32Freq = CLK_GetPLLClockFreq();
break;
case CLK_CLKSEL2_I2S_S_HIRC:
u32Freq = __HIRC;
break;
default:
u32Freq = __HIRC;
break;
}
return u32Freq;
}
/// @endcond /* HIDDEN_SYMBOLS */
/**
* @brief This function configures some parameters of I2S interface for general purpose use.
* The sample rate may not be used from the parameter, it depends on system's clock settings,
* but real sample rate used by system will be returned for reference.
* @param[in] i2s is the base address of I2S module.
* @param[in] u32MasterSlave I2S operation mode. Valid values are:
* - \ref I2S_MODE_MASTER
* - \ref I2S_MODE_SLAVE
* @param[in] u32SampleRate Sample rate
* @param[in] u32WordWidth Data length. Valid values are:
* - \ref I2S_DATABIT_8
* - \ref I2S_DATABIT_16
* - \ref I2S_DATABIT_24
* - \ref I2S_DATABIT_32
* @param[in] u32Channels: Audio format. Valid values are:
* - \ref I2S_MONO
* - \ref I2S_STEREO
* @param[in] u32DataFormat: Data format. Valid values are:
* - \ref I2S_FORMAT_I2S
* - \ref I2S_FORMAT_MSB
* @param[in] u32AudioInterface: Audio interface. Valid values are:
* - \ref I2S_I2S
* @return Real sample rate.
*/
uint32_t I2S_Open(I2S_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat, uint32_t u32AudioInterface)
{
uint8_t u8Divider;
uint32_t u32BitRate, u32SrcClk;
SYS->IPRST_CTL2 |= SYS_IPRST_CTL2_I2S_RST_Msk;
SYS->IPRST_CTL2 &= ~SYS_IPRST_CTL2_I2S_RST_Msk;
i2s->CTRL = u32MasterSlave | u32WordWidth | u32Channels | u32DataFormat | u32AudioInterface | I2S_FIFO_TX_LEVEL_WORD_4 | I2S_FIFO_RX_LEVEL_WORD_4;
u32SrcClk = I2S_GetSourceClockFreq(i2s);
u32BitRate = u32SampleRate * (((u32WordWidth>>4) & 0x3) + 1) * 16;
u8Divider = ((u32SrcClk/u32BitRate) >> 1) - 1;
i2s->CLKDIV = (i2s->CLKDIV & ~I2S_CLKDIV_BCLK_DIV_Msk) | (u8Divider << 8);
//calculate real sample rate
u32BitRate = u32SrcClk / (2*(u8Divider+1));
u32SampleRate = u32BitRate / ((((u32WordWidth>>4) & 0x3) + 1) * 16);
i2s->CTRL |= I2S_CTRL_I2SEN_Msk;
return u32SampleRate;
}
/**
* @brief Disable I2S function and I2S clock.
* @param[in] i2s is the base address of I2S module.
* @return none
*/
void I2S_Close(I2S_T *i2s)
{
i2s->CTRL &= ~I2S_CTRL_I2SEN_Msk;
}
/**
* @brief This function enables the interrupt according to the mask parameter.
* @param[in] i2s is the base address of I2S module.
* @param[in] u32Mask is the combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt bit.
* @return none
*/
void I2S_EnableInt(I2S_T *i2s, uint32_t u32Mask)
{
i2s->INTEN |= u32Mask;
}
/**
* @brief This function disables the interrupt according to the mask parameter.
* @param[in] i2s is the base address of I2S module.
* @param[in] u32Mask is the combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt bit.
* @return none
*/
void I2S_DisableInt(I2S_T *i2s, uint32_t u32Mask)
{
i2s->INTEN &= ~u32Mask;
}
/**
* @brief Enable MCLK .
* @param[in] i2s is the base address of I2S module.
* @param[in] u32BusClock is the target MCLK clock
* @return Actual MCLK clock
*/
uint32_t I2S_EnableMCLK(I2S_T *i2s, uint32_t u32BusClock)
{
uint8_t u8Divider;
uint32_t u32SrcClk, u32Reg;
u32SrcClk = I2S_GetSourceClockFreq(i2s);
if (u32BusClock == u32SrcClk)
u8Divider = 0;
else
u8Divider = (u32SrcClk/u32BusClock) >> 1;
i2s->CLKDIV = (i2s->CLKDIV & ~I2S_CLKDIV_MCLK_DIV_Msk) | u8Divider;
i2s->CTRL |= I2S_CTRL_MCLKEN_Msk;
u32Reg = i2s->CLKDIV & I2S_CLKDIV_MCLK_DIV_Msk;
if (u32Reg == 0)
return u32SrcClk;
else
return ((u32SrcClk >> 1) / u32Reg);
}
/**
* @brief Disable MCLK .
* @param[in] i2s is the base address of I2S module.
* @return none
*/
void I2S_DisableMCLK(I2S_T *i2s)
{
i2s->CTRL &= ~I2S_CTRL_MCLKEN_Msk;
}
/**
* @brief Configure FIFO threshold setting.
* @param[in] i2s The pointer of the specified I2S module.
* @param[in] u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 7.
* @param[in] u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 7.
* @return None
* @details Set TX FIFO threshold and RX FIFO threshold configurations.
*/
void I2S_SetFIFO(I2S_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
{
i2s->CTRL = (i2s->CTRL & ~(I2S_CTRL_TXTH_Msk | I2S_CTRL_RXTH_Msk) |
(u32TxThreshold << I2S_CTRL_TXTH_Pos) |
(u32RxThreshold << I2S_CTRL_RXTH_Pos));
}
/*@}*/ /* end of group NANO100_I2S_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_I2S_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,296 @@
/**************************************************************************//**
* @file i2s.h
* @version V1.00
* $Revision: 5 $
* $Date: 15/06/08 4:59p $
* @brief Nano100 series I2S driver header file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __I2S_H__
#define __I2S_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_I2S_Driver I2S Driver
@{
*/
/** @addtogroup NANO100_I2S_EXPORTED_CONSTANTS I2S Exported Constants
@{
*/
#define I2S_DATABIT_8 (0 << I2S_CTRL_WORDWIDTH_Pos) /*!< I2S data width is 8-bit */
#define I2S_DATABIT_16 (1 << I2S_CTRL_WORDWIDTH_Pos) /*!< I2S data width is 16-bit */
#define I2S_DATABIT_24 (2 << I2S_CTRL_WORDWIDTH_Pos) /*!< I2S data width is 24-bit */
#define I2S_DATABIT_32 (3 << I2S_CTRL_WORDWIDTH_Pos) /*!< I2S data width is 32-bit */
/* Audio Format */
#define I2S_MONO I2S_CTRL_MONO_Msk /*!< Mono channel */
#define I2S_STEREO 0 /*!< Stereo channel */
/* I2S Data Format */
#define I2S_FORMAT_MSB I2S_CTRL_FORMAT_Msk /*!< MSB data format */
#define I2S_FORMAT_I2S 0 /*!< I2S data format */
/* I2S Interface */
#define I2S_I2S 0 /*!< I2S interface is selected */
/* I2S Operation mode */
#define I2S_MODE_SLAVE I2S_CTRL_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_CTRL_TXTH_Pos) /*!< TX threshold is 1 word */
#define I2S_FIFO_TX_LEVEL_WORD_2 (2 << I2S_CTRL_TXTH_Pos) /*!< TX threshold is 2 words */
#define I2S_FIFO_TX_LEVEL_WORD_3 (3 << I2S_CTRL_TXTH_Pos) /*!< TX threshold is 3 words */
#define I2S_FIFO_TX_LEVEL_WORD_4 (4 << I2S_CTRL_TXTH_Pos) /*!< TX threshold is 4 words */
#define I2S_FIFO_TX_LEVEL_WORD_5 (5 << I2S_CTRL_TXTH_Pos) /*!< TX threshold is 5 words */
#define I2S_FIFO_TX_LEVEL_WORD_6 (6 << I2S_CTRL_TXTH_Pos) /*!< TX threshold is 6 words */
#define I2S_FIFO_TX_LEVEL_WORD_7 (7 << I2S_CTRL_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_CTRL_RXTH_Pos) /*!< RX threshold is 2 words */
#define I2S_FIFO_RX_LEVEL_WORD_3 (2 << I2S_CTRL_RXTH_Pos) /*!< RX threshold is 3 words */
#define I2S_FIFO_RX_LEVEL_WORD_4 (3 << I2S_CTRL_RXTH_Pos) /*!< RX threshold is 4 words */
#define I2S_FIFO_RX_LEVEL_WORD_5 (4 << I2S_CTRL_RXTH_Pos) /*!< RX threshold is 5 words */
#define I2S_FIFO_RX_LEVEL_WORD_6 (5 << I2S_CTRL_RXTH_Pos) /*!< RX threshold is 6 words */
#define I2S_FIFO_RX_LEVEL_WORD_7 (6 << I2S_CTRL_RXTH_Pos) /*!< RX threshold is 7 words */
#define I2S_FIFO_RX_LEVEL_WORD_8 (7 << I2S_CTRL_RXTH_Pos) /*!< RX threshold is 8 words */
/* I2S Record Channel */
#define I2S_MONO_RIGHT 0 /*!< Record mono right channel */
#define I2S_MONO_LEFT I2S_CTRL_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 NANO100_I2S_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_I2S_EXPORTED_FUNCTIONS I2S Exported Functions
@{
*/
/**
* @brief Enable zero cross detect function.
* @param[in] i2s is the base address of I2S module.
* @param[in] u32ChMask is the mask for left or right channel. Valid values are:
* - \ref I2S_RIGHT
* - \ref I2S_LEFT
* @return none
* \hideinitializer
*/
static __INLINE void I2S_ENABLE_TX_ZCD(I2S_T *i2s, uint32_t u32ChMask)
{
if(u32ChMask == I2S_RIGHT)
i2s->CTRL |= I2S_CTRL_RCHZCEN_Msk;
else
i2s->CTRL |= I2S_CTRL_LCHZCEN_Msk;
}
/**
* @brief Disable zero cross detect function.
* @param[in] i2s is the base address of I2S module.
* @param[in] u32ChMask is the mask for left or right channel. Valid values are:
* - \ref I2S_RIGHT
* - \ref I2S_LEFT
* @return none
* \hideinitializer
*/
static __INLINE void I2S_DISABLE_TX_ZCD(I2S_T *i2s, uint32_t u32ChMask)
{
if(u32ChMask == I2S_RIGHT)
i2s->CTRL &= ~I2S_CTRL_RCHZCEN_Msk;
else
i2s->CTRL &= ~I2S_CTRL_LCHZCEN_Msk;
}
/**
* @brief Enable I2S Tx DMA function. I2S requests DMA to transfer data to Tx FIFO.
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_ENABLE_TXDMA(i2s) ( (i2s)->CTRL |= I2S_CTRL_TXDMA_Msk )
/**
* @brief Disable I2S Tx DMA function. I2S requests DMA to transfer data to Tx FIFO.
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_DISABLE_TXDMA(i2s) ( (i2s)->CTRL &= ~I2S_CTRL_TXDMA_Msk )
/**
* @brief Enable I2S Rx DMA function. I2S requests DMA to transfer data from Rx FIFO.
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_ENABLE_RXDMA(i2s) ( (i2s)->CTRL |= I2S_CTRL_RXDMA_Msk )
/**
* @brief Disable I2S Rx DMA function. I2S requests DMA to transfer data from Rx FIFO.
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_DISABLE_RXDMA(i2s) ( (i2s)->CTRL &= ~I2S_CTRL_RXDMA_Msk )
/**
* @brief Enable I2S Tx function .
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_ENABLE_TX(i2s) ( (i2s)->CTRL |= I2S_CTRL_TXEN_Msk )
/**
* @brief Disable I2S Tx function .
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_DISABLE_TX(i2s) ( (i2s)->CTRL &= ~I2S_CTRL_TXEN_Msk )
/**
* @brief Enable I2S Rx function .
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_ENABLE_RX(i2s) ( (i2s)->CTRL |= I2S_CTRL_RXEN_Msk )
/**
* @brief Disable I2S Rx function .
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_DISABLE_RX(i2s) ( (i2s)->CTRL &= ~I2S_CTRL_RXEN_Msk )
/**
* @brief Enable Tx Mute function .
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_ENABLE_TX_MUTE(i2s) ( (i2s)->CTRL |= I2S_CTRL_MUTE_Msk )
/**
* @brief Disable Tx Mute function .
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_DISABLE_TX_MUTE(i2s) ( (i2s)->CTRL &= ~I2S_CTRL_MUTE_Msk )
/**
* @brief Clear Tx FIFO. Internal pointer is reset to FIFO start point.
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_CLR_TX_FIFO(i2s) ( (i2s)->CTRL |= I2S_CTRL_CLR_TXFIFO_Msk )
/**
* @brief Clear Rx FIFO. Internal pointer is reset to FIFO start point.
* @param[in] i2s is the base address of I2S module.
* @return none
* \hideinitializer
*/
#define I2S_CLR_RX_FIFO(i2s) ( (i2s)->CTRL |= I2S_CTRL_CLR_RXFIFO_Msk )
/**
* @brief This function sets the recording source channel when mono mode is used.
* @param[in] i2s is the base address of I2S module.
* @param[in] u32Ch left or right channel. Valid values are:
* - \ref I2S_MONO_LEFT
* - \ref I2S_MONO_RIGHT
* @return none
* \hideinitializer
*/
#define I2S_SET_MONO_RX_CHANNEL(i2s, u32Ch) ( u32Ch == I2S_MONO_LEFT ? ((i2s)->CTRL |= I2S_CTRL_RXLCH_Msk) : ((i2s)->CTRL &= ~I2S_CTRL_RXLCH_Msk) )
/**
* @brief Write data to I2S Tx FIFO.
* @param[in] i2s is the base address of I2S module.
* @param[in] u32Data The data written to FIFO.
* @return none
* \hideinitializer
*/
#define I2S_WRITE_TX_FIFO(i2s, u32Data) ( (i2s)->TXFIFO = u32Data )
/**
* @brief Read Rx FIFO.
* @param[in] i2s is the base address of I2S module.
* @return Data in Rx FIFO.
* \hideinitializer
*/
#define I2S_READ_RX_FIFO(i2s) ( (i2s)->RXFIFO )
/**
* @brief This function gets the interrupt flag according to the mask parameter.
* @param[in] i2s is the base address of I2S module.
* @param[in] u32Mask is the mask for the all interrupt flags.
* @return The masked bit value of interrupt flag.
* \hideinitializer
*/
#define I2S_GET_INT_FLAG(i2s, u32Mask) ((i2s)->STATUS & (u32Mask))
/**
* @brief This function clears the interrupt flag according to the mask parameter.
* @param[in] i2s is the base address of I2S module.
* @param[in] u32Mask is the mask for the all interrupt flags.
* @return none
* \hideinitializer
*/
#define I2S_CLR_INT_FLAG(i2s, u32Mask) ( (i2s)->STATUS |= (u32Mask) )
/**
* @brief Get transmit FIFO level
* @param[in] i2s is the base address of I2S module.
* @return FIFO level
* \hideinitializer
*/
#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 is the base address of I2S module.
* @return FIFO level
* \hideinitializer
*/
#define I2S_GET_RX_FIFO_LEVEL(i2s) ((((i2s)->STATUS & I2S_STATUS_RX_LEVEL_Msk) >> I2S_STATUS_RX_LEVEL_Pos) & 0xF)
uint32_t I2S_Open(I2S_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat, uint32_t u32AudioInterface);
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);
void I2S_SetFIFO(I2S_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold);
/*@}*/ /* end of group NANO100_I2S_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_I2S_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__I2S_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,434 @@
/**************************************************************************//**
* @file lcd.c
* @version V1.00
* $Revision: 9 $
* $Date: 15/07/06 2:08p $
* @brief Nano100 series LCD driver header file
* The LCD driver can directly drives a LCD glass by creating the ac
* segment and common voltage signals automatically. It can support
* static, 1/2 duty, 1/3 duty, 1/4 duty, 1/5 duty, 1/6 duty LCD glass with up to 34
* segments with 6 COM or 36 segments with 4 COM.
*
* @note
* Copyright (C) 2013~2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_LCD_Driver LCD Driver
@{
*/
/// @cond HIDDEN_SYMBOLS
/** @addtogroup NANO100_LCD_EXPORTED_VARIABLES LCD Exported Variables
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Global file scope (static) variables */
/*---------------------------------------------------------------------------------------------------------*/
double g_LCDFreq;
static uint32_t g_LCDFrameRate; /* src:32768Hz, COM:4, FREQ Div:64, frame-rate 64Hz */
/* src:10240Hz, COM:4, FREQ Div:32, frame-rate 40Hz */
/*@}*/ /* end of group NANO100_LCD_EXPORTED_VARIABLES */
/// @endcond /* HIDDEN_SYMBOLS */
/** @addtogroup NANO100_LCD_EXPORTED_FUNCTIONS LCD Exported Functions
@{
*/
/**
* @brief Enables a segment on the LCD display
*
* @param[in] u32Com COM number
* @param[in] u32Seg Segment number
* @param[in] u32OnFlag 1: segment display
* 0: segment not display
*
* @return None
*
*/
void LCD_SetPixel(uint32_t u32Com, uint32_t u32Seg, uint32_t u32OnFlag)
{
int32_t memnum = u32Seg / 4;
int32_t seg_shift = 8*(u32Seg-(4*memnum));
if(u32OnFlag) {
if(memnum==0) {
LCD->MEM_0 |= (1<<u32Com)<<seg_shift;
} else if(memnum==1) {
LCD->MEM_1 |= (1<<u32Com)<<seg_shift;
} else if(memnum==2) {
LCD->MEM_2 |= (1<<u32Com)<<seg_shift;
} else if(memnum==3) {
LCD->MEM_3 |= (1<<u32Com)<<seg_shift;
} else if(memnum==4) {
LCD->MEM_4 |= (1<<u32Com)<<seg_shift;
} else if(memnum==5) {
LCD->MEM_5 |= (1<<u32Com)<<seg_shift;
} else if(memnum==6) {
LCD->MEM_6 |= (1<<u32Com)<<seg_shift;
} else if(memnum==7) {
LCD->MEM_7 |= (1<<u32Com)<<seg_shift;
} else if(memnum==8) {
LCD->MEM_8 |= (1<<u32Com)<<seg_shift;
} else if(memnum==9) {
LCD->MEM_9 |= (1<<u32Com)<<seg_shift;
}
} else {
if(memnum==0) {
LCD->MEM_0 &= ~((1<<u32Com)<<seg_shift);
} else if(memnum==1) {
LCD->MEM_1 &= ~((1<<u32Com)<<seg_shift);
} else if(memnum==2) {
LCD->MEM_2 &= ~((1<<u32Com)<<seg_shift);
} else if(memnum==3) {
LCD->MEM_3 &= ~((1<<u32Com)<<seg_shift);
} else if(memnum==4) {
LCD->MEM_4 &= ~((1<<u32Com)<<seg_shift);
} else if(memnum==5) {
LCD->MEM_5 &= ~((1<<u32Com)<<seg_shift);
} else if(memnum==6) {
LCD->MEM_6 &= ~((1<<u32Com)<<seg_shift);
} else if(memnum==7) {
LCD->MEM_7 &= ~((1<<u32Com)<<seg_shift);
} else if(memnum==8) {
LCD->MEM_8 &= ~((1<<u32Com)<<seg_shift);
} else if(memnum==9) {
LCD->MEM_9 &= ~((1<<u32Com)<<seg_shift);
}
}
if(CyclesPerUs > 0)
SysTick->LOAD = 300 * CyclesPerUs;
else
SysTick->LOAD = 15;
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);
}
/**
* @brief LCD Enable/Disable all segments
*
* @param[in] u32OnOff 1: Enable all segments
* 0: Disable all segment
*
* @return None
*
*/
void LCD_SetAllPixels(uint32_t u32OnOff)
{
uint32_t u32SetValue;
if(u32OnOff) {
u32SetValue = 0xFFFFFFFF;
} else {
u32SetValue = 0x00000000;
}
LCD->MEM_0 = u32SetValue;
LCD->MEM_1 = u32SetValue;
LCD->MEM_2 = u32SetValue;
LCD->MEM_3 = u32SetValue;
LCD->MEM_4 = u32SetValue;
LCD->MEM_5 = u32SetValue;
LCD->MEM_6 = u32SetValue;
LCD->MEM_7 = u32SetValue;
LCD->MEM_8 = u32SetValue;
if(CyclesPerUs > 0)
SysTick->LOAD = 300 * CyclesPerUs;
else
SysTick->LOAD = 15;
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);
}
/**
* @brief Set Frame Count and Enable frame count
*
* @param[in] u32Count Frame count value
*
*
* @return real frame count value.
*
*/
uint32_t LCD_EnableFrameCounter(uint32_t u32Count)
{
uint32_t div = 1; // default prediv == LCD_FCPRESC_DIV1
LCD->FCR = 0x00;
LCD->FCSTS |= LCD_FCSTS_FCSTS_Msk; // clear fcsts flag
if(u32Count == 0) return 0;
if(u32Count > 0x3F) { // top value max. 63 = 0x3F
div = u32Count/64;
if(div > 3) {
div = 8;
LCD->FCR = LCD->FCR & ~LCD_FCR_PRESCL_Msk | LCD_FCPRESC_DIV8;
} else if(div > 1) {
div = 4;
LCD->FCR = LCD->FCR & ~LCD_FCR_PRESCL_Msk | LCD_FCPRESC_DIV4;
} else {
div = 2;
LCD->FCR = LCD->FCR & ~LCD_FCR_PRESCL_Msk | LCD_FCPRESC_DIV2;
}
u32Count = (u32Count+(div/2))/div;
} else {
div = 1;
LCD->FCR = LCD->FCR & ~LCD_FCR_PRESCL_Msk | LCD_FCPRESC_DIV1;
}
LCD->FCR = LCD->FCR & ~LCD_FCR_FCV_Msk | (u32Count << LCD_FCR_FCV_Pos);
u32Count = u32Count*div;
LCD->FCR |= LCD_FCR_FCEN_Msk; // enable LCD frame count
return u32Count;
}
/**
* @brief Disable frame count function
*
* @param None
*
* @return None
*
*/
void LCD_DisableFrameCounter(void)
{
LCD->FCR = 0x00; // disable LCD frame count
if( LCD->FCSTS & LCD_FCSTS_FCSTS_Msk) // clear status flag
LCD->FCSTS = LCD_FCSTS_FCSTS_Msk;
}
/**
* @brief LCD Initialization routine.
*
* @param[in] u32DrivingType LCD driving type: \ref LCD_C_TYPE / \ref LCD_EXTERNAL_R_TYPE / \ref LCD_INTERNAL_R_TYPE / \ref LCD_EXTERNAL_C_TYPE
* @param[in] u32ComNum LCD Com number: 1 ~6
* @param[in] u32BiasLevel LCD bias level: \ref LCD_BIAS_STATIC / \ref LCD_BIAS_HALF / \ref LCD_BIAS_THIRD
* @param[in] u32FramerateDiv LCD frequency divider: \ref LCD_FREQ_DIV32 / \ref LCD_FREQ_DIV64 / \ref LCD_FREQ_DIV96 / \ref LCD_FREQ_DIV128 /
* \ref LCD_FREQ_DIV192/ \ref LCD_FREQ_DIV256 / \ref LCD_FREQ_DIV384 / \ref LCD_FREQ_DIV512
* @param[in] u32DrivingVol LCD charge pump driving voltage: \ref LCD_CPVOl_2_6V / \ref LCD_CPVOl_2_7V / \ref LCD_CPVOl_2_8V / \ref LCD_CPVOl_2_9V /
* \ref LCD_CPVOl_3V / \ref LCD_CPVOl_3_1V / \ref LCD_CPVOl_3_2V / \ref LCD_CPVOl_3_3V
*
* @return LCD frame rate.
*
*/
uint32_t LCD_Open(uint32_t u32DrivingType, uint32_t u32ComNum, uint32_t u32BiasLevel, uint32_t u32FramerateDiv, uint32_t u32DrivingVol)
{
uint32_t clkdiv, muldiv;
uint32_t lcd_freq_div[] = {32, 64, 96, 128, 192, 256, 384, 512};
uint32_t multiplex_freq_div[] = {2, 4, 6, 8, 10, 12};
uint32_t u32clk_src;
/* IP reset */
SYS->IPRST_CTL2 |= SYS_IPRST_CTL2_LCD_RST_Msk;
SYS->IPRST_CTL2 &= ~SYS_IPRST_CTL2_LCD_RST_Msk;
LCD_DisableDisplay();
/* Turn all segments off */
LCD_SetAllPixels(0);
switch(u32DrivingType) {
case LCD_C_TYPE:
case LCD_EXTERNAL_C_TYPE:
LCD->DISPCTL &= ~LCD_DISPCTL_BV_SEL_Msk; // internal source for charge pump
LCD->DISPCTL = LCD->DISPCTL & ~LCD_DISPCTL_CPUMP_FREQ_Msk | (LCD_CPUMP_DIV1);
LCD->DISPCTL = LCD->DISPCTL & ~LCD_DISPCTL_CPUMP_VOL_SET_Msk | (u32DrivingVol);
LCD->DISPCTL &= ~LCD_DISPCTL_IBRL_EN_Msk;
LCD->DISPCTL |= LCD_DISPCTL_CPUMP_EN_Msk; // enable charge pump
break;
case LCD_EXTERNAL_R_TYPE:
case LCD_INTERNAL_R_TYPE:
LCD->DISPCTL &= ~LCD_DISPCTL_CPUMP_EN_Msk;
LCD->DISPCTL |= LCD_DISPCTL_BV_SEL_Msk;
LCD->DISPCTL &= ~LCD_DISPCTL_IBRL_EN_Msk;
LCD->DISPCTL |= (u32DrivingType == LCD_INTERNAL_R_TYPE)?LCD_DISPCTL_IBRL_EN_Msk:0;
break;
};
LCD->CTL &= ~LCD_CTL_FREQ_Msk;
LCD->CTL |= u32FramerateDiv;
LCD->CTL = (LCD->CTL & ~LCD_CTL_MUX_Msk) | ((u32ComNum - 1) << LCD_CTL_MUX_Pos);
LCD->DISPCTL = LCD->DISPCTL & ~LCD_DISPCTL_BIAS_SEL_Msk | u32BiasLevel;
if((CLK->CLKSEL1 & CLK_CLKSEL1_LCD_S_Msk) == 0)
u32clk_src = 32 * 1024;
else
u32clk_src = 10 * 1024;
clkdiv = (LCD->CTL & LCD_CTL_FREQ_Msk) >> LCD_CTL_FREQ_Pos;
muldiv = (LCD->CTL & LCD_CTL_MUX_Msk) >> LCD_CTL_MUX_Pos;
g_LCDFreq = (double)u32clk_src / lcd_freq_div[clkdiv];
g_LCDFrameRate = (uint32_t)g_LCDFreq / multiplex_freq_div[muldiv];
return g_LCDFrameRate;
}
/**
* @brief The function is used to disable LCD controller.
*
* @param None
*
* @return None
*
*/
void LCD_Close(void)
{
LCD_DisableDisplay();
}
/**
* @brief Enable Blink function in LCD controller
*
* @param[in] u32ms Blinking display time(unit: ms).
*
* @return Real blinking delay time(ms).
*
*/
uint32_t LCD_EnableBlink(uint32_t u32ms)
{
uint32_t prescale=LCD_FCPRESC_DIV1, div=1;
uint32_t framecount;
if((1000/u32ms) > g_LCDFrameRate) u32ms = (1000/g_LCDFrameRate);
framecount = (uint32_t) (u32ms / (1000/g_LCDFrameRate)) ;
if(framecount > 0x3F) {
for(div=2; div<=8; div*=2) {
framecount = (uint32_t) (u32ms / (1000/(g_LCDFrameRate/div)) );
if( framecount <= 0x40 )
break;
}
if(div==2) prescale = LCD_FCPRESC_DIV2;
else if(div==4) prescale = LCD_FCPRESC_DIV4;
else if(div==8) prescale = LCD_FCPRESC_DIV8;
else return 0;
} else if(framecount == 0) {
framecount = 1;
}
LCD->FCR = LCD->FCR & ~LCD_FCR_PRESCL_Msk | prescale;
LCD->FCR = LCD->FCR & ~LCD_FCR_FCV_Msk | ((framecount - 1) << LCD_FCR_FCV_Pos);
LCD->FCR |= LCD_FCR_FCEN_Msk;
/* Enable Blink LCD */
LCD->CTL |= LCD_CTL_BLINK_Msk;
return ( (framecount*1000)/(g_LCDFrameRate/div) );
}
/**
* @brief Disable Blink function in LCD controller
*
* @param None
*
* @return None
*
*/
void LCD_DisableBlink(void)
{
/* Disable Blink LCD */
LCD->CTL &= ~LCD_CTL_BLINK_Msk;
/* Disable frame count */
LCD->FCR = 0x00; // disable LCD frame count
if( LCD->FCSTS & LCD_FCSTS_FCSTS_Msk) // clear status flag
LCD->FCSTS = LCD_FCSTS_FCSTS_Msk;
}
/**
* @brief This function is used to enable LCD interrupt
*
* @param[in] IntSrc Interrupt Source: \ref LCD_FRAMECOUNT_INT / \ref LCD_POWERDOWN_INT / \ref LCD_ALL_INT
*
* @return None
*
*/
void LCD_EnableInt(uint32_t IntSrc)
{
if((IntSrc & LCD_FRAMECOUNT_INT) == LCD_FRAMECOUNT_INT ) {
LCD->FCR |= LCD_FCR_FCEN_Msk;
}
if((IntSrc & LCD_POWERDOWN_INT) == LCD_POWERDOWN_INT ) {
LCD->CTL |= LCD_CTL_PDINT_EN_Msk;
}
}
/**
* @brief This function is used to disable LCD specified interrupt
*
* @param[in] IntSrc Interrupt Source: \ref LCD_FRAMECOUNT_INT / \ref LCD_POWERDOWN_INT / \ref LCD_ALL_INT
*
* @return None
*
*/
void LCD_DisableInt(uint32_t IntSrc)
{
if((IntSrc & LCD_FRAMECOUNT_INT) == LCD_FRAMECOUNT_INT ) {
LCD->FCR &= ~LCD_FCR_FCEN_Msk;
LCD->FCSTS = LCD_FCSTS_FCSTS_Msk;
}
if((IntSrc & LCD_POWERDOWN_INT) == LCD_POWERDOWN_INT ) {
LCD->CTL &= ~LCD_CTL_PDINT_EN_Msk;
LCD->FCSTS = LCD_FCSTS_PDSTS_Msk;
}
}
/*@}*/ /* end of group NANO100_LCD_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_LCD_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013~2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,225 @@
/****************************************************************************//**
* @file lcd.h
* @version V1.00
* $Revision: 5 $
* $Date: 15/06/26 1:30p $
* @brief Nano100 series I2C driver header file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __LCD_H__
#define __LCD_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
//#include <stdbool.h>
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_LCD_Driver LCD Driver
@{
*/
/** @addtogroup NANO100_LCD_EXPORTED_CONSTANTS LCD Exported Constants
@{
*/
/// @cond
/*---------------------------------------------------------------------------------------------------------*/
/* Macro, type and constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
/// @endcond
#define LCD_FREQ_DIV32 ((uint32_t) 0x00000000) /*!< Clock source (32 or 10KHz) divide by 32 */
#define LCD_FREQ_DIV64 ((uint32_t) 0x00000010) /*!< Clock source (32 or 10KHz) divide by 64 */
#define LCD_FREQ_DIV96 ((uint32_t) 0x00000020) /*!< Clock source (32 or 10KHz) divide by 96 */
#define LCD_FREQ_DIV128 ((uint32_t) 0x00000030) /*!< Clock source (32 or 10KHz) divide by 128 */
#define LCD_FREQ_DIV192 ((uint32_t) 0x00000040) /*!< Clock source (32 or 10KHz) divide by 192 */
#define LCD_FREQ_DIV256 ((uint32_t) 0x00000050) /*!< Clock source (32 or 10KHz) divide by 256 */
#define LCD_FREQ_DIV384 ((uint32_t) 0x00000060) /*!< Clock source (32 or 10KHz) divide by 384 */
#define LCD_FREQ_DIV512 ((uint32_t) 0x00000070) /*!< Clock source (32 or 10KHz) divide by 512 */
#define LCD_MUX_STATIC ((uint32_t) 0x00000000) /*!< Static multiplexing */
#define LCD_MUX_ONE_SECOND ((uint32_t) 0x00000002) /*!< Duplex multiplexing */
#define LCD_MUX_ONE_THIRD ((uint32_t) 0x00000004) /*!< Triplex multiplexing */
#define LCD_MUX_ONE_FOURTH ((uint32_t) 0x00000006) /*!< Quadruplex multiplexing */
#define LCD_MUX_ONE_FIFTH ((uint32_t) 0x00000008) /*!< 1/5 duty */
#define LCD_MUX_ONE_SIXTH ((uint32_t) 0x0000000A) /*!< 1/6 duty */
#define LCD_BIAS_STATIC ((uint32_t) 0x00000000) /*!< Static bias */
#define LCD_BIAS_HALF ((uint32_t) 0x00000002) /*!< 1/2 bias */
#define LCD_BIAS_THIRD ((uint32_t) 0x00000004) /*!< 1/3 bias */
#define LCD_CPUMP_DIV1 ((uint32_t) 0x00000000) /*!< Clock source (32 or 10KHz) divide by 1 and is used by analog component */
#define LCD_CPUMP_DIV2 ((uint32_t) 0x00000800) /*!< Clock source (32 or 10KHz) divide by 2 */
#define LCD_CPUMP_DIV4 ((uint32_t) 0x00001000) /*!< Clock source (32 or 10KHz) divide by 4 */
#define LCD_CPUMP_DIV8 ((uint32_t) 0x00001800) /*!< Clock source (32 or 10KHz) divide by 8 */
#define LCD_CPUMP_DIV16 ((uint32_t) 0x00002000) /*!< Clock source (32 or 10KHz) divide by 16 */
#define LCD_CPUMP_DIV32 ((uint32_t) 0x00002800) /*!< Clock source (32 or 10KHz) divide by 32 */
#define LCD_CPUMP_DIV64 ((uint32_t) 0x00003000) /*!< Clock source (32 or 10KHz) divide by 64 */
#define LCD_CPUMP_DIV128 ((uint32_t) 0x00003800) /*!< Clock source (32 or 10KHz) divide by 128 */
#define LCD_CPVOl_2_6V ((uint32_t) 0x00000000) /*!< Set charge pump voltage to 2.6 V */
#define LCD_CPVOl_2_7V ((uint32_t) 0x00000100) /*!< Set charge pump voltage to 2.7 V */
#define LCD_CPVOl_2_8V ((uint32_t) 0x00000200) /*!< Set charge pump voltage to 2.8 V */
#define LCD_CPVOl_2_9V ((uint32_t) 0x00000300) /*!< Set charge pump voltage to 2.9 V */
#define LCD_CPVOl_3V ((uint32_t) 0x00000400) /*!< Set charge pump voltage to 3 V */
#define LCD_CPVOl_3_1V ((uint32_t) 0x00000500) /*!< Set charge pump voltage to 3.1 V */
#define LCD_CPVOl_3_2V ((uint32_t) 0x00000600) /*!< Set charge pump voltage to 3.2 V */
#define LCD_CPVOl_3_3V ((uint32_t) 0x00000700) /*!< Set charge pump voltage to 3.3 V */
#define LCD_FCPRESC_DIV1 ((uint32_t) 0x00000000) /*!< Set pre-scale divider value to 1 */
#define LCD_FCPRESC_DIV2 ((uint32_t) 0x00000004) /*!< Set pre-scale divider value to 2 */
#define LCD_FCPRESC_DIV4 ((uint32_t) 0x00000008) /*!< Set pre-scale divider value to 4 */
#define LCD_FCPRESC_DIV8 ((uint32_t) 0x0000000C) /*!< Set pre-scale divider value to 8 */
#define LCD_FRAMECOUNT_INT ((uint32_t) 0x00000001) /*!< Indicate frame count interrupt */
#define LCD_POWERDOWN_INT ((uint32_t) 0x00000002) /*!< Indicate power down interrupt */
#define LCD_ALL_INT ((uint32_t) 0x00000003) /*!< Indicate frame count & power down interrupt */
#define ERR_LCD_CAL_BLINK_FAIL 0xFFFF0000 /*!< Specifies that overflow to calculate the blinking frequency */
/*@}*/ /* end of group NANO100_LCD_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_LCD_EXPORTED_STRUCTS LCD Exported Structs
@{
*/
typedef enum {
LCD_C_TYPE = 0, /*!< Select LCD C-Type */
LCD_EXTERNAL_R_TYPE = 1, /*!< Select LCD External R-Type */
LCD_INTERNAL_R_TYPE = 2, /*!< Select LCD Internal R-Type */
LCD_EXTERNAL_C_TYPE = 3 /*!< Select LCD External C-Type */
} LCD_PanelType;
/*@}*/ /* end of group NANO100_LCD_EXPORTED_STRUCTS */
/** @addtogroup NANO100_LCD_EXPORTED_FUNCTIONS LCD Exported Functions
@{
*/
/**
* @brief Get LCD Power Down interrupt flag.
*
* @param None
*
* @return LCD Power Down interrupt Flag.
*/
#define LCD_GET_PD_INT_FLAG() ((LCD->FCSTS & LCD_FCSTS_PDSTS_Msk) >> LCD_FCSTS_PDSTS_Pos)
/**
* @brief Clear LCD Power Down interrupt flag.
*
* @param None
*
* @return None.
*/
#define LCD_CLR_PD_INT_FLAG() (LCD->FCSTS = LCD_FCSTS_PDSTS_Msk)
/**
* @brief Get LCD Frame Count interrupt flag.
*
* @param None
*
* @return LCD Frame Count interrupt Flag.
*/
#define LCD_GET_FRAME_CNT_INT_FLAG() ((LCD->FCSTS & LCD_FCSTS_FCSTS_Msk) >> LCD_FCSTS_FCSTS_Pos)
/**
* @brief Clear LCD Frame Count interrupt flag.
*
* @param None
*
* @return None.
*/
#define LCD_CLR_FRAME_CNT_INT_FLAG() (LCD->FCSTS = LCD_FCSTS_FCSTS_Msk)
/**
* @brief Enable LCD Power Down Display function.
*
* @param None
*
* @return None.
*/
#define LCD_ENABLE_PD_DISPLAY() (LCD->CTL |= LCD_CTL_PDDISP_EN_Msk)
/**
* @brief Disable LCD Power Down Display function.
*
* @param None
*
* @return None.
*/
#define LCD_DISABLE_PD_DISPLAY() (LCD->CTL &= ~LCD_CTL_PDDISP_EN_Msk)
uint32_t LCD_EnableFrameCounter(uint32_t u32Count);
void LCD_DisableFrameCounter(void);
uint32_t LCD_EnableBlink(uint32_t u32ms);
void LCD_DisableBlink(void);
void LCD_EnableInt(uint32_t IntSrc);
void LCD_DisableInt(uint32_t IntSrc);
uint32_t LCD_Open(uint32_t u32DrivingType, uint32_t u32ComNum, uint32_t u32BiasLevel, uint32_t u32FramerateDiv, uint32_t u32DrivingVol);
void LCD_SetPixel(uint32_t u32Com, uint32_t u32Seg, uint32_t u32OnFlag);
void LCD_SetAllPixels(uint32_t u32OnOff);
void LCD_Close(void);
/**
* @brief Enable LCD controller
*
* @param None
*
* @return None
*
*/
static __INLINE void LCD_EnableDisplay(void)
{
/* Enable LCD */
LCD->CTL |= LCD_CTL_EN_Msk;
}
/**
* @brief Disable LCD controller
*
* @param None
*
* @return None
*
*/
static __INLINE void LCD_DisableDisplay(void)
{
/* Enable LCD */
LCD->CTL &= ~LCD_CTL_EN_Msk;
}
/*@}*/ /* end of group NANO100_LCD_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_LCD_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __LCD_H__ */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,241 @@
/**************************************************************************//**
* @file pdma.c
* @version V1.00
* $Revision: 5 $
* $Date: 14/09/29 3:50p $
* @brief Nano100 series PDMA driver source file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_PDMA_Driver PDMA Driver
@{
*/
/** @addtogroup NANO100_PDMA_EXPORTED_FUNCTIONS PDMA Exported Functions
@{
*/
/**
* @brief PDMA Open
*
* @param[in] u32Mask Channel enable bits
*
* @return None
*
* @details This function enable the PDMA channels.
*/
void PDMA_Open(uint32_t u32Mask)
{
PDMAGCR->GCRCSR |= (u32Mask << 8);
}
/**
* @brief PDMA Close
*
* @param[in] None
*
* @return None
*
* @details This function disable all PDMA channels.
*/
void PDMA_Close(void)
{
PDMAGCR->GCRCSR = 0;
}
/**
* @brief Set PDMA Transfer Count
*
* @param[in] u32Ch The selected channel
* @param[in] u32Width Data width. \ref PDMA_WIDTH_8, \ref PDMA_WIDTH_16, or \ref PDMA_WIDTH_32
* @param[in] u32TransCount Transfer count
*
* @return None
*
* @details This function set the selected channel data width and transfer count.
*/
void PDMA_SetTransferCnt(uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA1_BASE + (0x100 * (u32Ch-1)));
pdma->CSR = (pdma->CSR & ~PDMA_CSR_APB_TWS_Msk) | u32Width;
switch (u32Width) {
case PDMA_WIDTH_32:
pdma->BCR = (u32TransCount << 2);
break;
case PDMA_WIDTH_8:
pdma->BCR = u32TransCount;
break;
case PDMA_WIDTH_16:
pdma->BCR = (u32TransCount << 1);
break;
default:
;
}
}
/**
* @brief Set PDMA Transfer Address
*
* @param[in] u32Ch The selected channel
* @param[in] u32SrcAddr Source address
* @param[in] u32SrcCtrl Source control attribute. \ref PDMA_SAR_INC, \ref PDMA_SAR_FIX, or \ref PDMA_SAR_WRA
* @param[in] u32DstAddr destination address
* @param[in] u32DstCtrl destination control attribute. \ref PDMA_DAR_INC, \ref PDMA_DAR_FIX, or \ref PDMA_DAR_WRA
*
* @return None
*
* @details This function set the selected channel source/destination address and attribute.
*/
void PDMA_SetTransferAddr(uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA1_BASE + (0x100 * (u32Ch-1)));
pdma->SAR = u32SrcAddr;
pdma->DAR = u32DstAddr;
pdma->CSR = (pdma->CSR & ~(PDMA_CSR_SAD_SEL_Msk|PDMA_CSR_DAD_SEL_Msk)) | (u32SrcCtrl | u32DstCtrl);
}
/**
* @brief Set PDMA Transfer Mode
*
* @param[in] u32Ch The selected channel
* @param[in] u32Peripheral The selected peripheral.
* \ref PDMA_SPI0_TX, \ref PDMA_SPI1_TX, \ref PDMA_UART0_TX, \ref PDMA_UART1_TX, \ref PDMA_USB_TX,
* \ref PDMA_I2S_TX, \ref PDMA_DAC0_TX, \ref PDMA_DAC1_TX, \ref PDMA_SPI2_TX, \ref PDMA_TMR0,
* \ref PDMA_TMR1, \ref PDMA_TMR2, \ref PDMA_TMR3, \ref PDMA_SPI0_RX, \ref PDMA_SPI1_RX,
* \ref PDMA_UART0_RX, \ref PDMA_UART1_RX, \ref PDMA_USB_RX, \ref PDMA_I2S_RX, \ref PDMA_ADC,
* \ref PDMA_SPI2_RX, \ref PDMA_PWM0_CH0, \ref PDMA_PWM0_CH2, \ref PDMA_PWM1_CH0, \ref PDMA_PWM1_CH2,
* \ref PDMA_MEM
* @param[in] u32ScatterEn Scatter-gather mode enable
* @param[in] u32DescAddr Scatter-gather descriptor address
*
* @return None
*
* @details This function set the selected channel transfer mode. Include peripheral setting.
*/
void PDMA_SetTransferMode(uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA1_BASE + (0x100 * (u32Ch-1)));
switch (u32Ch) {
case 1:
PDMAGCR->DSSR0 = (PDMAGCR->DSSR0 & ~DMA_GCR_DSSR0_CH1_SEL_Msk) | (u32Peripheral << DMA_GCR_DSSR0_CH1_SEL_Pos);
break;
case 2:
PDMAGCR->DSSR0 = (PDMAGCR->DSSR0 & ~DMA_GCR_DSSR0_CH2_SEL_Msk) | (u32Peripheral << DMA_GCR_DSSR0_CH2_SEL_Pos);
break;
case 3:
PDMAGCR->DSSR0 = (PDMAGCR->DSSR0 & ~DMA_GCR_DSSR0_CH3_SEL_Msk) | (u32Peripheral << DMA_GCR_DSSR0_CH3_SEL_Pos);
break;
case 4:
PDMAGCR->DSSR1 = (PDMAGCR->DSSR1 & ~DMA_GCR_DSSR1_CH4_SEL_Msk) | u32Peripheral;
break;
default:
;
}
if (u32Peripheral == PDMA_MEM)
pdma->CSR &= ~PDMA_CSR_MODE_SEL_Msk;
else if (u32Peripheral & 0x10)
pdma->CSR = (pdma->CSR & ~PDMA_CSR_MODE_SEL_Msk) | 0x4; /* IP to memory */
else
pdma->CSR = (pdma->CSR & ~PDMA_CSR_MODE_SEL_Msk) | 0x8; /* memory to IP */
}
/**
* @brief Set PDMA Timeout
*
* @param[in] u32Ch The selected channel
* @param[in] u32OnOff Enable/disable time out function
* @param[in] u32TimeOutCnt Timeout count
*
* @return None
*
* @details This function set the timeout count.
*/
void PDMA_SetTimeOut(uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA1_BASE + (0x100 * (u32Ch-1)));
pdma->TCR = (pdma->TCR & ~PDMA_TCR_PDMA_TCR_Msk) | u32TimeOutCnt;
pdma->CSR = (pdma->CSR & ~PDMA_CSR_TO_EN_Msk) | (u32OnOff << PDMA_CSR_TO_EN_Pos);
}
/**
* @brief Trigger PDMA
*
* @param[in] u32Ch The selected channel
*
* @return None
*
* @details This function trigger the selected channel.
*/
void PDMA_Trigger(uint32_t u32Ch)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA1_BASE + (0x100 * (u32Ch-1)));
pdma->CSR |= (PDMA_CSR_TRIG_EN_Msk | PDMA_CSR_PDMACEN_Msk);
}
/**
* @brief Enable Interrupt
*
* @param[in] u32Ch The selected channel
* @param[in] u32Mask The Interrupt Type
*
* @return None
*
* @details This function enable the selected channel interrupt.
*/
void PDMA_EnableInt(uint32_t u32Ch, uint32_t u32Mask)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA1_BASE + (0x100 * (u32Ch-1)));
pdma->IER |= u32Mask;
}
/**
* @brief Disable Interrupt
*
* @param[in] u32Ch The selected channel
* @param[in] u32Mask The Interrupt Type
*
* @return None
*
* @details This function disable the selected channel interrupt.
*/
void PDMA_DisableInt(uint32_t u32Ch, uint32_t u32Mask)
{
PDMA_T *pdma;
pdma = (PDMA_T *)((uint32_t) PDMA1_BASE + (0x100 * (u32Ch-1)));
pdma->IER &= ~u32Mask;
}
/*@}*/ /* end of group NANO100_PDMA_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_PDMA_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,219 @@
/**************************************************************************//**
* @file pdma.h
* @version V1.00
* $Revision: 9 $
* $Date: 15/06/10 4:52p $
* @brief Nano100 series PDMA driver header file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __PDMA_H__
#define __PDMA_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_PDMA_Driver PDMA Driver
@{
*/
/** @addtogroup NANO100_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_SAR_WRA 0x00000030UL /*!<DMA SAR wrap around */
#define PDMA_DAR_INC 0x00000000UL /*!<DMA DAR increment */
#define PDMA_DAR_FIX 0x00000080UL /*!<DMA DAR fix address */
#define PDMA_DAR_WRA 0x000000C0UL /*!<DMA DAR wrap around */
/*---------------------------------------------------------------------------------------------------------*/
/* 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_UART0_TX 0x00000002UL /*!<DMA Connect to UART0 TX */
#define PDMA_UART1_TX 0x00000003UL /*!<DMA Connect to UART1 TX */
#define PDMA_USB_TX 0x00000004UL /*!<DMA Connect to USB TX */
#define PDMA_I2S_TX 0x00000005UL /*!<DMA Connect to I2S TX */
#define PDMA_DAC0_TX 0x00000006UL /*!<DMA Connect to DAC0 TX */
#define PDMA_DAC1_TX 0x00000007UL /*!<DMA Connect to DAC1 TX */
#define PDMA_SPI2_TX 0x00000008UL /*!<DMA Connect to SPI2 TX */
#define PDMA_TMR0 0x00000009UL /*!<DMA Connect to TMR0 */
#define PDMA_TMR1 0x0000000AUL /*!<DMA Connect to TMR1 */
#define PDMA_TMR2 0x0000000BUL /*!<DMA Connect to TMR2 */
#define PDMA_TMR3 0x0000000CUL /*!<DMA Connect to TMR3 */
#define PDMA_SPI0_RX 0x00000010UL /*!<DMA Connect to SPI0 RX */
#define PDMA_SPI1_RX 0x00000011UL /*!<DMA Connect to SPI1 RX */
#define PDMA_UART0_RX 0x00000012UL /*!<DMA Connect to UART0 RX */
#define PDMA_UART1_RX 0x00000013UL /*!<DMA Connect to UART1 RX */
#define PDMA_USB_RX 0x00000014UL /*!<DMA Connect to USB RX */
#define PDMA_I2S_RX 0x00000015UL /*!<DMA Connect to I2S RX */
#define PDMA_ADC 0x00000016UL /*!<DMA Connect to I2S1 RX */
#define PDMA_SPI2_RX 0x00000018UL /*!<DMA Connect to SPI2 RX */
#define PDMA_PWM0_CH0 0x00000019UL /*!<DMA Connect to PWM0 CH0 */
#define PDMA_PWM0_CH2 0x0000001AUL /*!<DMA Connect to PWM0 CH2 */
#define PDMA_PWM1_CH0 0x0000001BUL /*!<DMA Connect to PWM1 CH0 */
#define PDMA_PWM1_CH2 0x0000001CUL /*!<DMA Connect to PWM1 CH2 */
#define PDMA_MEM 0x0000001FUL /*!<DMA Connect to Memory */
/*@}*/ /* end of group NANO100_PDMA_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_PDMA_EXPORTED_FUNCTIONS PDMA Exported Functions
@{
*/
/**
* @brief Get PDMA Interrupt Status
*
* @param[in] None
*
* @return None
*
* @details This macro gets the interrupt status.
* \hideinitializer
*/
#define PDMA_GET_INT_STATUS() ((uint32_t)(PDMAGCR->GCRISR))
/**
* @brief Get PDMA Channel Interrupt Status
*
* @param[in] u32Ch Selected DMA channel
*
* @return Interrupt Status
*
* @details This macro gets the channel interrupt status.
* \hideinitializer
*/
#define PDMA_GET_CH_INT_STS(u32Ch) (*((__IO uint32_t *)((uint32_t)&PDMA1->ISR + (uint32_t)((u32Ch-1)*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.
* \hideinitializer
*/
#define PDMA_CLR_CH_INT_FLAG(u32Ch, u32Mask) (*((__IO uint32_t *)((uint32_t)&PDMA1->ISR + (uint32_t)((u32Ch-1)*0x100))) = (u32Mask))
/**
* @brief Check Channel Status
*
* @param[in] u32Ch The selected channel
*
* @return 0 = idle
* @return 1 = busy
*
* @details Check the selected channel is busy or not.
* \hideinitializer
*/
#define PDMA_IS_CH_BUSY(u32Ch) ((*((__IO uint32_t *)((uint32_t)&PDMA1->CSR +(uint32_t)((u32Ch-1)*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.
* \hideinitializer
*/
#define PDMA_SET_SRC_ADDR(u32Ch, u32Addr) (*((__IO uint32_t *)((uint32_t)&PDMA1->SAR + (uint32_t)((u32Ch-1)*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.
* \hideinitializer
*/
#define PDMA_SET_DST_ADDR(u32Ch, u32Addr) (*((__IO uint32_t *)((uint32_t)&PDMA1->DAR + (uint32_t)((u32Ch-1)*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) \
do{\
if (((uint32_t)*((__IO uint32_t *)((uint32_t)&PDMA1->CSR + (uint32_t)((u32Ch-1)*0x100))) & PDMA_CSR_APB_TWS_Msk) == PDMA_WIDTH_32) \
*((__IO uint32_t *)((uint32_t)&PDMA1->BCR + (uint32_t)((u32Ch-1)*0x100))) = ((u32Count) << 2); \
else if (((uint32_t)*((__IO uint32_t *)((uint32_t)&PDMA1->CSR + (uint32_t)((u32Ch-1)*0x100))) & PDMA_CSR_APB_TWS_Msk) == PDMA_WIDTH_8) \
*((__IO uint32_t *)((uint32_t)&PDMA1->BCR + (uint32_t)((u32Ch-1)*0x100))) = (u32Count); \
else if (((uint32_t)*((__IO uint32_t *)((uint32_t)&PDMA1->CSR + (uint32_t)((u32Ch-1)*0x100))) & PDMA_CSR_APB_TWS_Msk) == PDMA_WIDTH_16) \
*((__IO uint32_t *)((uint32_t)&PDMA1->BCR + (uint32_t)((u32Ch-1)*0x100))) = ((u32Count) << 1); \
}while(0)
/**
* @brief Stop the channel
*
* @param[in] u32Ch The selected channel
*
* @return None
*
* @details This macro stop the selected channel.
* \hideinitializer
*/
#define PDMA_STOP(u32Ch) (*((__IO uint32_t *)((uint32_t)&PDMA1->CSR + (uint32_t)((u32Ch-1)*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_SetTimeOut(uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt);
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 group NANO100_PDMA_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_PDMA_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__PDMA_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,522 @@
/**************************************************************************//**
* @file PWM.c
* @version V1.00
* $Revision: 14 $
* $Date: 14/09/04 11:58a $
* @brief NANO100 series PWM driver source file
*
* @note
* Copyright (C) 2013-2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_PWM_Driver PWM Driver
@{
*/
/** @addtogroup NANO100_PWM_EXPORTED_FUNCTIONS PWM Exported Functions
@{
*/
/**
* @brief This function config PWM generator and get the nearest frequency in edge aligned auto-reload mode
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32Frequency Target generator frequency
* @param[in] u32DutyCycle Target generator duty cycle percentage. Valid range are between 0 ~ 100. 10 means 10%, 20 means 20%...
* @return Nearest frequency clock in nano second
* @note Since every two channels, (0 & 1), (2 & 3), (4 & 5), 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 i;
uint32_t u32ClkSrc;
uint32_t u32PWM_Clock = SystemCoreClock;
uint8_t u8Divider = 1, u8Prescale = 0xFF;
uint16_t u16CNR = 0xFFFF;
if(pwm == PWM0)
u32ClkSrc = (CLK->CLKSEL1 & (CLK_CLKSEL1_PWM0_CH01_S_Msk << (u32ChannelNum & 2))) >> (CLK_CLKSEL1_PWM0_CH01_S_Pos + (u32ChannelNum & 2));
else
u32ClkSrc = (CLK->CLKSEL2 & (CLK_CLKSEL2_PWM1_CH01_S_Msk << (u32ChannelNum & 2))) >> (CLK_CLKSEL2_PWM1_CH01_S_Pos + (u32ChannelNum & 2));
switch (u32ClkSrc) {
case 0:
u32PWM_Clock = __HXT;
break;
case 1:
u32PWM_Clock = __LXT;
break;
case 2:
u32PWM_Clock = SystemCoreClock;
break;
case 3:
u32PWM_Clock = __HIRC12M;
break;
}
for(; u8Divider < 17; u8Divider <<= 1) { // clk divider could only be 1, 2, 4, 8, 16
i = (u32PWM_Clock / 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 = u32PWM_Clock / (u8Prescale * u8Divider * u16CNR);
u8Prescale -= 1;
u16CNR -= 1;
// convert to real register value
if(u8Divider == 1)
u8Divider = 4;
else if (u8Divider == 2)
u8Divider = 0;
else if (u8Divider == 4)
u8Divider = 1;
else if (u8Divider == 8)
u8Divider = 2;
else // 16
u8Divider = 3;
// every two channels share a prescaler
while((pwm->INTSTS & PWM_INTSTS_PRESSYNC_Msk ) == PWM_INTSTS_PRESSYNC_Msk);
pwm->PRES = (pwm->PRES & ~(PWM_PRES_CP01_Msk << ((u32ChannelNum >> 1) * 8))) | (u8Prescale << ((u32ChannelNum >> 1) * 8));
pwm->CLKSEL = (pwm->CLKSEL & ~(PWM_CLKSEL_CLKSEL0_Msk << (4 * u32ChannelNum))) | (u8Divider << (4 * u32ChannelNum));
pwm->CTL |= (PWM_CTL_CH0MOD_Msk << (u32ChannelNum * 8));
while((pwm->INTSTS & (PWM_INTSTS_DUTY0SYNC_Msk << u32ChannelNum)) == (PWM_INTSTS_DUTY0SYNC_Msk << u32ChannelNum));
if(u32DutyCycle == 0)
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) &= ~PWM_DUTY_CM_Msk;
else {
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) &= ~PWM_DUTY_CM_Msk;
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) |= ((u32DutyCycle * (u16CNR + 1) / 100 - 1) << PWM_DUTY_CM_Pos);
}
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) &= ~PWM_DUTY_CN_Msk;
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) |= u16CNR;
return(i);
}
/**
* @brief This function config PWM capture and get the nearest unit time
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32UnitTimeNsec Unit time of counter
* @param[in] u32CaptureEdge Condition to latch the counter
* @return Nearest unit time in nano second
* @note Since every two channels, (0 & 1), (2 & 3), (4 & 5), shares a prescaler. Call this API to configure PWM frequency may affect
* existing frequency of other channel.
*/
uint32_t PWM_ConfigCaptureChannel (PWM_T *pwm,
uint32_t u32ChannelNum,
uint32_t u32UnitTimeNsec,
uint32_t u32CaptureEdge)
{
uint32_t i;
uint32_t u32ClkSrc;
uint32_t u32PWM_Clock = SystemCoreClock;
uint8_t u8Divider = 1, u8Prescale = 0xFF;
uint16_t u16CNR = 0xFFFF;
if(pwm == PWM0)
u32ClkSrc = (CLK->CLKSEL1 & (CLK_CLKSEL1_PWM0_CH01_S_Msk << (u32ChannelNum & 2))) >> (CLK_CLKSEL1_PWM0_CH01_S_Pos + (u32ChannelNum & 2));
else
u32ClkSrc = (CLK->CLKSEL2 & (CLK_CLKSEL2_PWM1_CH01_S_Msk << (u32ChannelNum & 2))) >> (CLK_CLKSEL2_PWM1_CH01_S_Pos + (u32ChannelNum & 2));
switch (u32ClkSrc) {
case 0:
u32PWM_Clock = __HXT;
break;
case 1:
u32PWM_Clock = __LXT;
break;
case 2:
u32PWM_Clock = SystemCoreClock;
break;
case 3:
u32PWM_Clock = __HIRC12M;
break;
}
for(; u8Divider < 17; u8Divider <<= 1) { // clk divider could only be 1, 2, 4, 8, 16
i = ((long long)(u32PWM_Clock / u8Divider) * u32UnitTimeNsec) / 1000000000;
// If target value is larger than 0xFF, need to use a larger divider
if(i > (0xFF))
continue;
u8Prescale = i;
// u8Prescale must at least be 2, otherwise the output stop
if(u8Prescale < 3)
u8Prescale = 2;
break;
}
// Store return value here 'cos we're gonna change u8Divider & u8Prescale & u16CNR to the real value to fill into register
i = (long long) (u8Prescale * u8Divider) * 1000000000 / u32PWM_Clock;
u8Prescale -= 1;
u16CNR -= 1;
// convert to real register value
if(u8Divider == 1)
u8Divider = 4;
else if (u8Divider == 2)
u8Divider = 0;
else if (u8Divider == 4)
u8Divider = 1;
else if (u8Divider == 8)
u8Divider = 2;
else // 16
u8Divider = 3;
// every two channels share a prescaler
while((pwm->INTSTS & PWM_INTSTS_PRESSYNC_Msk ) == PWM_INTSTS_PRESSYNC_Msk);
pwm->PRES = (pwm->PRES & ~(PWM_PRES_CP01_Msk << ((u32ChannelNum >> 1) * 8))) | (u8Prescale << ((u32ChannelNum >> 1) * 8));
pwm->CLKSEL = (pwm->CLKSEL & ~(PWM_CLKSEL_CLKSEL0_Msk << (4 * u32ChannelNum))) | (u8Divider << (4 * u32ChannelNum));
pwm->CTL |= (PWM_CTL_CH0MOD_Msk << (u32ChannelNum * 8));
while((pwm->INTSTS & (PWM_INTSTS_DUTY0SYNC_Msk << u32ChannelNum)) == (PWM_INTSTS_DUTY0SYNC_Msk << u32ChannelNum));
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) &= ~PWM_DUTY_CN_Msk;
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) |= u16CNR;
return(i);
}
/**
* @brief This function start PWM module
* @param[in] pwm The base address of PWM module
* @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
*/
void PWM_Start (PWM_T *pwm, uint32_t u32ChannelMask)
{
uint8_t i;
uint32_t u32Mask = 0;
for (i = 0; i < PWM_CHANNEL_NUM; i++) {
if ( u32ChannelMask & (1 << i))
u32Mask |= (PWM_CTL_CH0EN_Msk << (i * 8));
}
pwm->CTL |= u32Mask;
}
/**
* @brief This function stop PWM module
* @param[in] pwm The base address of PWM module
* @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
*/
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 *) (&pwm->DUTY0 + 3 * i) &= ~PWM_DUTY_CN_Msk;
}
}
}
/**
* @brief This function stop PWM generation immediately by clear channel enable bit
* @param[in] pwm The base address of PWM module
* @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
*/
void PWM_ForceStop (PWM_T *pwm, uint32_t u32ChannelMask)
{
uint32_t i;
for (i = 0; i < PWM_CHANNEL_NUM; i++) {
if ( u32ChannelMask & (1 << i))
pwm->CTL &= ~(PWM_CTL_CH0EN_Msk << (i * 8));
}
}
/**
* @brief This function enables PWM capture of selected channels
* @param[in] pwm The base address of PWM module
* @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
*/
void PWM_EnableCapture (PWM_T *pwm, uint32_t u32ChannelMask)
{
uint8_t i;
uint32_t u32Mask = 0;
for (i = 0; i < PWM_CHANNEL_NUM; i++) {
if ( u32ChannelMask & (1 << i)) {
u32Mask |= ((PWM_CAPCTL_CAPCH0EN_Msk | PWM_CAPCTL_CAPCH0PADEN_Msk) << (i * 8));
}
}
pwm->CAPCTL |= u32Mask;
}
/**
* @brief This function disables PWM capture of selected channels
* @param[in] pwm The base address of PWM module
* @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
*/
void PWM_DisableCapture (PWM_T *pwm, uint32_t u32ChannelMask)
{
uint8_t i;
uint32_t u32CTLMask = 0;
uint32_t u32CAPCTLMask = 0;
for (i = 0; i < PWM_CHANNEL_NUM; i++) {
if ( u32ChannelMask & (1 << i)) {
u32CTLMask |= (PWM_CTL_CH0EN_Msk << (i * 8));
u32CAPCTLMask |= ((PWM_CAPCTL_CAPCH0EN_Msk | PWM_CAPCTL_CAPCH0PADEN_Msk) << (i * 8));
}
}
pwm->CTL &= ~u32CTLMask;
pwm->CAPCTL &= ~u32CAPCTLMask;
}
/**
* @brief This function enables PWM output generation of selected channels
* @param[in] pwm The base address of PWM module
* @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
*/
void PWM_EnableOutput (PWM_T *pwm, uint32_t u32ChannelMask)
{
pwm->OE |= u32ChannelMask;
}
/**
* @brief This function disables PWM output generation of selected channels
* @param[in] pwm The base address of PWM module
* @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
*/
void PWM_DisableOutput (PWM_T *pwm, uint32_t u32ChannelMask)
{
pwm->OE &= ~u32ChannelMask;
}
/**
* @brief This function enable Dead zone of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @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
*/
void PWM_EnableDeadZone (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration)
{
// every two channels shares the same setting
u32ChannelNum >>= 1;
// set duration
pwm->PRES = (pwm->PRES & ~(PWM_PRES_DZ01_Msk << (8 * u32ChannelNum))) | ((u32Duration << PWM_PRES_DZ01_Pos ) << (8 * u32ChannelNum));
// enable dead zone
pwm->CTL |= (PWM_CTL_DZEN01_Msk << u32ChannelNum);
}
/**
* @brief This function disable Dead zone of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return None
*/
void PWM_DisableDeadZone (PWM_T *pwm, uint32_t u32ChannelNum)
{
// every two channels shares the same setting
u32ChannelNum >>= 1;
// enable dead zone
pwm->CTL &= ~(PWM_CTL_DZEN01_Msk << u32ChannelNum);
}
/**
* @brief This function enable capture interrupt of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32Edge Capture interrupt type. It could be either
* - \ref PWM_RISING_LATCH_INT_ENABLE
* - \ref PWM_FALLING_LATCH_INT_ENABLE
* - \ref PWM_RISING_FALLING_LATCH_INT_ENABLE
* @return None
*/
void PWM_EnableCaptureInt (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
// enable capture interrupt
pwm->CAPINTEN |= (u32Edge << (u32ChannelNum * 8));
}
/**
* @brief This function disable capture interrupt of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32Edge Capture interrupt type. It could be either
* - \ref PWM_RISING_LATCH_INT_ENABLE
* - \ref PWM_FALLING_LATCH_INT_ENABLE
* - \ref PWM_RISING_FALLING_LATCH_INT_ENABLE
* @return None
*/
void PWM_DisableCaptureInt (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
// disable capture interrupt
pwm->CAPINTEN &= ~(u32Edge << (u32ChannelNum * 8));
}
/**
* @brief This function clear capture interrupt flag of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32Edge Capture interrupt type. It could be either
* - \ref PWM_RISING_LATCH_INT_FLAG
* - \ref PWM_FALLING_LATCH_INT_FLAG
* - \ref PWM_RISING_FALLING_LATCH_INT_FLAG
* @return None
*/
void PWM_ClearCaptureIntFlag (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge)
{
// disable capture interrupt flag
pwm->CAPINTSTS = (u32Edge + 1) << (u32ChannelNum * 8);
}
/**
* @brief This function get capture interrupt flag of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return Capture interrupt flag of specified channel
* @retval 0 Capture interrupt did not occurred
* @retval PWM_RISING_LATCH_INT_FLAG Rising edge latch interrupt occurred
* @retval PWM_FALLING_LATCH_INT_FLAG Falling edge latch interrupt occurred
* @retval PWM_RISING_FALLING_LATCH_INT_FLAG Rising and falling edge latch interrupt occurred
*/
uint32_t PWM_GetCaptureIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
{
return ((pwm->CAPINTSTS >> (u32ChannelNum * 8)) & (PWM_RISING_FALLING_LATCH_INT_FLAG));
}
/**
* @brief This function enable period interrupt of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32IntPeriodType This parameter is not used
* @return None
* @note All channels share the same period interrupt type setting.
*/
void PWM_EnablePeriodInt (PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType)
{
// enable period interrupt
pwm->INTEN |= (PWM_INTEN_TMIE0_Msk << u32ChannelNum);
}
/**
* @brief This function disable period interrupt of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return None
*/
void PWM_DisablePeriodInt (PWM_T *pwm, uint32_t u32ChannelNum)
{
pwm->INTEN &= ~(PWM_INTEN_TMIE0_Msk << u32ChannelNum);
}
/**
* @brief This function clear period interrupt of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return None
*/
void PWM_ClearPeriodIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
{
// write 1 clear
pwm->INTSTS = (PWM_INTSTS_TMINT0_Msk << u32ChannelNum);
}
/**
* @brief This function get period interrupt of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return Period interrupt flag of specified channel
* @retval 0 Period interrupt did not occurred
* @retval 1 Period interrupt occurred
*/
uint32_t PWM_GetPeriodIntFlag (PWM_T *pwm, uint32_t u32ChannelNum)
{
return ((pwm->INTSTS & (PWM_INTSTS_TMINT0_Msk << u32ChannelNum)) ? 1 : 0);
}
/**
* @brief This function enable capture PDMA of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are 0 and 2
* @param[in] u32RisingFirst Order of captured data transferred by PDMA. It could be either
* - \ref PWM_CAP_PDMA_RFORDER_R
* - \ref PWM_CAP_PDMA_RFORDER_F
* @param[in] u32Mode Captured data transferred by PDMA interrupt type. It could be either
* - \ref PWM_RISING_LATCH_PDMA_ENABLE
* - \ref PWM_FALLING_LATCH_PDMA_ENABLE
* - \ref PWM_RISING_FALLING_LATCH_PDMA_ENABLE
* @return None
*/
void PWM_EnablePDMA(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32RisingFirst, uint32_t u32Mode)
{
if (u32ChannelNum == 0)
pwm->CAPCTL = (pwm->CAPCTL & ~(PWM_CAPCTL_PDMACAPMOD0_Msk | PWM_CAPCTL_CH0RFORDER_Msk)) | u32Mode | u32RisingFirst | PWM_CAPCTL_CH0PDMAEN_Msk;
else
pwm->CAPCTL = (pwm->CAPCTL & ~(PWM_CAPCTL_PDMACAPMOD2_Msk | PWM_CAPCTL_CH2RFORDER_Msk)) | (u32Mode << 16)| (u32RisingFirst << 16)| PWM_CAPCTL_CH2PDMAEN_Msk;
}
/**
* @brief This function disable capture PDMA of selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are 0 and 2
* @return None
*/
void PWM_DisablePDMA(PWM_T *pwm, uint32_t u32ChannelNum)
{
if (u32ChannelNum == 0)
pwm->CAPCTL &= ~PWM_CAPCTL_CH0PDMAEN_Msk;
else
pwm->CAPCTL &= ~PWM_CAPCTL_CH2PDMAEN_Msk;
}
/*@}*/ /* end of group NANO100_PWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_PWM_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013-2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,204 @@
/**************************************************************************//**
* @file pwm.h
* @version V1.00
* $Revision: 12 $
* $Date: 15/06/30 2:52p $
* @brief NANO100 series PWM driver header file
*
* @note
* Copyright (C) 2013-2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __PWM_H__
#define __PWM_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_PWM_Driver PWM Driver
@{
*/
/** @addtogroup NANO100_PWM_EXPORTED_CONSTANTS PWM Exported Constants
@{
*/
#define PWM_CHANNEL_NUM (4) /*!< PWM channel number \hideinitializer */
#define PWM_CH0 (0UL) /*!< PWM channel 0 \hideinitializer */
#define PWM_CH1 (1UL) /*!< PWM channel 1 \hideinitializer */
#define PWM_CH2 (2UL) /*!< PWM channel 2 \hideinitializer */
#define PWM_CH3 (3UL) /*!< PWM channel 3 \hideinitializer */
#define PWM_CH_0_MASK (1UL) /*!< PWM channel 0 mask \hideinitializer */
#define PWM_CH_1_MASK (2UL) /*!< PWM channel 1 mask \hideinitializer */
#define PWM_CH_2_MASK (4UL) /*!< PWM channel 2 mask \hideinitializer */
#define PWM_CH_3_MASK (8UL) /*!< PWM channel 3 mask \hideinitializer */
#define PWM_CLK_DIV_1 (4UL) /*!< PWM clock divide by 1 \hideinitializer */
#define PWM_CLK_DIV_2 (0UL) /*!< PWM clock divide by 2 \hideinitializer */
#define PWM_CLK_DIV_4 (1UL) /*!< PWM clock divide by 4 \hideinitializer */
#define PWM_CLK_DIV_8 (2UL) /*!< PWM clock divide by 8 \hideinitializer */
#define PWM_CLK_DIV_16 (3UL) /*!< PWM clock divide by 16 \hideinitializer */
#define PWM_EDGE_ALIGNED (0UL) /*!< PWM working in edge aligned type \hideinitializer */
#define PWM_CENTER_ALIGNED (1UL) /*!< PWM working in center aligned type \hideinitializer */
#define PWM_RISING_LATCH_INT_ENABLE (1UL) /*!< PWM rising latch interrupt enable \hideinitializer */
#define PWM_FALLING_LATCH_INT_ENABLE (2UL) /*!< PWM falling latch interrupt enable \hideinitializer */
#define PWM_RISING_FALLING_LATCH_INT_ENABLE (3UL) /*!< PWM rising latch interrupt enable \hideinitializer */
#define PWM_RISING_LATCH_INT_FLAG (2UL) /*!< PWM rising latch condition happened \hideinitializer */
#define PWM_FALLING_LATCH_INT_FLAG (4UL) /*!< PWM falling latch condition happened \hideinitializer */
#define PWM_RISING_FALLING_LATCH_INT_FLAG (6UL) /*!< PWM rising latch condition happened \hideinitializer */
#define PWM_RISING_LATCH_PDMA_ENABLE (0x10UL) /*!< PWM rising latch PDMA enable \hideinitializer */
#define PWM_FALLING_LATCH_PDMA_ENABLE (0x20UL) /*!< PWM falling latch PDMA enable \hideinitializer */
#define PWM_RISING_FALLING_LATCH_PDMA_ENABLE (0x30UL) /*!< PWM rising and falling latch PDMA enable \hideinitializer */
#define PWM_CAP_PDMA_RFORDER_R (0x1000UL) /*!< PWM captured data transferred by PDMA is rising latch first \hideinitializer */
#define PWM_CAP_PDMA_RFORDER_F (0UL) /*!< PWM captured data transferred by PDMA is falling latch first \hideinitializer */
/*@}*/ /* end of group NANO100_PWM_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_PWM_EXPORTED_FUNCTIONS PWM Exported Functions
@{
*/
/**
* @brief This macro enable output inverter of specified channel(s)
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel
* Bit 0 represents channel 0, bit 1 represents channel 1...
* @return None
* \hideinitializer
*/
#define PWM_ENABLE_OUTPUT_INVERTER(pwm, u32ChannelMask)\
do { \
uint8_t i; \
(pwm)->CTL &= ~(PWM_CTL_CH0INV_Msk | PWM_CTL_CH1INV_Msk | PWM_CTL_CH2INV_Msk | PWM_CTL_CH3INV_Msk);\
for (i = 0; i < PWM_CHANNEL_NUM; i++) { \
if ( (u32ChannelMask) & (1 << i)) { \
(pwm)->CTL |= (PWM_CTL_CH0INV_Msk << (i * 8)); \
} \
} \
}while(0)
/**
* @brief This macro get captured rising data
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return None
* \hideinitializer
*/
#define PWM_GET_CAPTURE_RISING_DATA(pwm, u32ChannelNum) (*(__IO uint32_t *) (&pwm->CRL0 + 2 * u32ChannelNum))
/**
* @brief This macro get captured falling data
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @return None
* \hideinitializer
*/
#define PWM_GET_CAPTURE_FALLING_DATA(pwm, u32ChannelNum) (*(__IO uint32_t *) (&pwm->CFL0 + 2 * u32ChannelNum))
/**
* @brief This macro set the prescaler of the selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32Prescaler Clock prescaler of specified channel. Valid values are between 1 ~ 0xFF
* @return None
* @note Every even channel N, and channel (N + 1) share a prescaler. So if channel 0 prescaler changed,
* channel 1 will also be affected.
* \hideinitializer
*/
#define PWM_SET_PRESCALER(pwm, u32ChannelNum, u32Prescaler) \
(pwm->PRES = (pwm->PRES & ~(PWM_PRES_CP01_Msk << (((u32ChannelNum) >> 1) * 8))) | ((u32Prescaler) << (((u32ChannelNum) >> 1) * 8)))
/**
* @brief This macro set the divider of the selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @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
* \hideinitializer
*/
#define PWM_SET_DIVIDER(pwm, u32ChannelNum, u32Divider) \
(pwm->CLKSEL = (pwm->CLKSEL & ~(PWM_CLKSEL_CLKSEL0_Msk << (4 * u32ChannelNum))) | (u32Divider << (4 * u32ChannelNum)))
/**
* @brief This macro set the duty of the selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32CMR Duty of specified channel. Valid values are between 0~0xFFFF
* @return None
* @note This new setting will take effect on next PWM period
* \hideinitializer
*/
#define PWM_SET_CMR(pwm, u32ChannelNum, u32CMR) \
do { \
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) &= ~PWM_DUTY_CM_Msk; \
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) |= (u32CMR << PWM_DUTY_CM_Pos); \
}while(0)
/**
* @brief This macro set the period of the selected channel
* @param[in] pwm The base address of PWM module
* @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5
* @param[in] u32CNR Period of specified channel. Valid values are between 0~0xFFFF
* @return None
* @note This new setting will take effect on next PWM period
* @note PWM counter will stop if period length set to 0
* \hideinitializer
*/
#define PWM_SET_CNR(pwm, u32ChannelNum, u32CNR) \
do { \
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) &= ~PWM_DUTY_CN_Msk; \
*(__IO uint32_t *) (&pwm->DUTY0 + 3 * u32ChannelNum) |= u32CNR; \
} while(0)
uint32_t PWM_ConfigOutputChannel(PWM_T *pwm,
uint32_t u32ChannelNum,
uint32_t u32Frequency,
uint32_t u32DutyCycle);
uint32_t PWM_ConfigCaptureChannel (PWM_T *pwm,
uint32_t u32ChannelNum,
uint32_t u32UnitTimeNsec,
uint32_t u32CaptureEdge);
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_EnableCapture(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_DisableCapture(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_EnableOutput(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_DisableOutput(PWM_T *pwm, uint32_t u32ChannelMask);
void PWM_EnableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration);
void PWM_DisableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_EnableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge);
void PWM_DisableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge);
void PWM_ClearCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge);
uint32_t PWM_GetCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_EnablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType);
void PWM_DisablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_ClearPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum);
uint32_t PWM_GetPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum);
void PWM_EnablePDMA(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32RisingFirst, uint32_t u32Mode);
void PWM_DisablePDMA(PWM_T *pwm, uint32_t u32ChannelNum);
/*@}*/ /* end of group NANO100_PWM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_PWM_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__PWM_H__
/*** (C) COPYRIGHT 2013-2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,806 @@
/**************************************************************************//**
* @file rtc.c
* @version V1.00
* $Revision: 11 $
* $Date: 15/06/26 1:26p $
* @brief Nano100 series RTC driver source file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "Nano100Series.h"
/*---------------------------------------------------------------------------------------------------------*/
/* Includes of local headers */
/*---------------------------------------------------------------------------------------------------------*/
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_RTC_Driver RTC Driver
@{
*/
/// @cond HIDDEN_SYMBOLS
/*---------------------------------------------------------------------------------------------------------*/
/* Macro, type and constant definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define RTC_GLOBALS
/*---------------------------------------------------------------------------------------------------------*/
/* Global file scope (static) variables */
/*---------------------------------------------------------------------------------------------------------*/
static volatile uint32_t g_u32Reg, g_u32Reg1,g_u32hiYear,g_u32loYear,g_u32hiMonth,g_u32loMonth,g_u32hiDay,g_u32loDay;
static volatile uint32_t g_u32hiHour,g_u32loHour,g_u32hiMin,g_u32loMin,g_u32hiSec,g_u32loSec;
/// @endcond HIDDEN_SYMBOLS
/** @addtogroup NANO100_RTC_EXPORTED_FUNCTIONS RTC Exported Functions
@{
*/
/**
* @brief Set Frequency Compensation Data
*
* @param[in] i32FrequencyX100 Specify the RTC clock X100, ex: 3277365 means 32773.65.
*
* @return None
*
*/
void RTC_32KCalibration(int32_t i32FrequencyX100)
{
int32_t i32RegInt,i32RegFra ;
/* Compute Integer and Fraction for RTC register*/
i32RegInt = (i32FrequencyX100/100) - RTC_FCR_REFERENCE;
i32RegFra = (((i32FrequencyX100%100)) * 60) / 100;
/* Judge Integer part is reasonable */
if ( (i32RegInt < 0) | (i32RegInt > 15) ) {
return;
}
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
RTC->FCR = (uint32_t)((i32RegInt<<8) | i32RegFra);
}
/**
* @brief This function is used to write initial key to let RTC start count and set current time.
*
*
* @param[in] sPt \n
* Specify the time property and current time. Null pointer for using default starting time. It includes: \n
* u32Year: Year value. \n
* u32Month: Month value. \n
* u32Day: Day value. \n
* u32DayOfWeek: Day of week. [ \ref RTC_SUNDAY / \ref RTC_MONDAY / \ref RTC_TUESDAY /
* \ref RTC_WEDNESDAY / \ref RTC_THURSDAY / \ref RTC_FRIDAY /
* \ref RTC_SATURDAY] \n
* u32Hour: Hour value. \n
* u32Minute: Minute value. \n
* u32Second: Second value. \n
* u32TimeScale: [ \ref RTC_CLOCK_12 / \ref RTC_CLOCK_24] \n
* u8AmPm: [ \ref RTC_AM / \ref RTC_PM] \n
*
* @return None
*
*/
void RTC_Open (S_RTC_TIME_DATA_T *sPt)
{
uint32_t u32Reg;
volatile int32_t i32delay=1000;
RTC->INIR = RTC_INIT_KEY;
if(RTC->INIR != 0x1) {
RTC->INIR = RTC_INIT_KEY;
while(RTC->INIR != 0x1);
}
if(sPt == NULL)
return;
/*-----------------------------------------------------------------------------------------------------*/
/* Second, set RTC 24/12 hour setting */
/*-----------------------------------------------------------------------------------------------------*/
if (sPt->u32TimeScale == RTC_CLOCK_12) {
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
RTC->TSSR &= ~RTC_TSSR_24H_12H_Msk;
/*-------------------------------------------------------------------------------------------------*/
/* important, range of 12-hour PM mode is 21 upto 32 */
/*-------------------------------------------------------------------------------------------------*/
if (sPt->u32AmPm == RTC_PM)
sPt->u32Hour += 20;
} else {
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
RTC->TSSR |= RTC_TSSR_24H_12H_Msk;
}
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC Calender Loading */
/*-----------------------------------------------------------------------------------------------------*/
u32Reg = ((sPt->u32Year - RTC_YEAR2000) / 10) << 20;
u32Reg |= (((sPt->u32Year - RTC_YEAR2000) % 10) << 16);
u32Reg |= ((sPt->u32Month / 10) << 12);
u32Reg |= ((sPt->u32Month % 10) << 8);
u32Reg |= ((sPt->u32Day / 10) << 4);
u32Reg |= (sPt->u32Day % 10);
g_u32Reg = u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
RTC->CLR = (uint32_t)g_u32Reg;
/*-----------------------------------------------------------------------------------------------------*/
/* Set RTC Time Loading */
/*-----------------------------------------------------------------------------------------------------*/
u32Reg = ((sPt->u32Hour / 10) << 20);
u32Reg |= ((sPt->u32Hour % 10) << 16);
u32Reg |= ((sPt->u32Minute / 10) << 12);
u32Reg |= ((sPt->u32Minute % 10) << 8);
u32Reg |= ((sPt->u32Second / 10) << 4);
u32Reg |= (sPt->u32Second % 10);
g_u32Reg = u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
RTC->TLR = (uint32_t)g_u32Reg;
RTC->DWR = sPt->u32DayOfWeek;
/* Waiting for RTC settings stable */
while(i32delay--);
}
/**
* @brief Read current date/time from RTC setting
*
* @param[out] sPt \n
* Specify the time property and current time. It includes: \n
* u32Year: Year value \n
* u32Month: Month value \n
* u32Day: Day value \n
* u32DayOfWeek: Day of week \n
* u32Hour: Hour value \n
* u32Minute: Minute value \n
* u32Second: Second value \n
* u32TimeScale: \ref RTC_CLOCK_12 / \ref RTC_CLOCK_24 \n
* u8AmPm: \ref RTC_AM / \ref RTC_PM \n
*
* @return None
*
*/
void RTC_GetDateAndTime(S_RTC_TIME_DATA_T *sPt)
{
uint32_t u32Tmp;
sPt->u32TimeScale = RTC->TSSR & RTC_TSSR_24H_12H_Msk; /* 12/24-hour */
sPt->u32DayOfWeek = RTC->DWR & RTC_DWR_DWR_Msk; /* Day of week */
g_u32hiYear = (RTC->CLR & RTC_CLR_10YEAR_Msk) >> RTC_CLR_10YEAR_Pos;
g_u32loYear = (RTC->CLR & RTC_CLR_1YEAR_Msk) >> RTC_CLR_1YEAR_Pos;
g_u32hiMonth = (RTC->CLR & RTC_CLR_10MON_Msk) >> RTC_CLR_10MON_Pos;
g_u32loMonth = (RTC->CLR & RTC_CLR_1MON_Msk) >> RTC_CLR_1MON_Pos;
g_u32hiDay = (RTC->CLR & RTC_CLR_10DAY_Msk) >> RTC_CLR_10DAY_Pos;
g_u32loDay = (RTC->CLR & RTC_CLR_1DAY_Msk);
g_u32hiHour = (RTC->TLR & RTC_TLR_10HR_Msk) >> RTC_TLR_10HR_Pos;
g_u32loHour = (RTC->TLR & RTC_TLR_1HR_Msk) >> RTC_TLR_1HR_Pos;
g_u32hiMin = (RTC->TLR & RTC_TLR_10MIN_Msk) >> RTC_TLR_10MIN_Pos;
g_u32loMin = (RTC->TLR & RTC_TLR_1MIN_Msk) >> RTC_TLR_1MIN_Pos;
g_u32hiSec = (RTC->TLR & RTC_TLR_10SEC_Msk) >> RTC_TLR_10SEC_Pos;
g_u32loSec = (RTC->TLR & RTC_TLR_1SEC_Msk);
u32Tmp = (g_u32hiYear * 10); /* Compute to 20XX year */
u32Tmp += g_u32loYear;
sPt->u32Year = u32Tmp + RTC_YEAR2000;
u32Tmp = (g_u32hiMonth * 10); /* Compute 0~12 month */
sPt->u32Month = u32Tmp + g_u32loMonth;
u32Tmp = (g_u32hiDay * 10); /* Compute 0~31 day */
sPt->u32Day = u32Tmp + g_u32loDay;
if (sPt->u32TimeScale == RTC_CLOCK_12) { /* Compute12/24 hour */
u32Tmp = (g_u32hiHour * 10);
u32Tmp+= g_u32loHour;
sPt->u32Hour = u32Tmp; /* AM: 1~12. PM: 21~32. */
if (sPt->u32Hour >= 21) {
sPt->u32AmPm = RTC_PM;
sPt->u32Hour -= 20;
} else {
sPt->u32AmPm = RTC_AM;
}
u32Tmp = (g_u32hiMin * 10);
u32Tmp+= g_u32loMin;
sPt->u32Minute = u32Tmp;
u32Tmp = (g_u32hiSec * 10);
u32Tmp+= g_u32loSec;
sPt->u32Second = u32Tmp;
} else {
u32Tmp = (g_u32hiHour * 10);
u32Tmp += g_u32loHour;
sPt->u32Hour = u32Tmp;
u32Tmp = (g_u32hiMin * 10);
u32Tmp += g_u32loMin;
sPt->u32Minute = u32Tmp;
u32Tmp = (g_u32hiSec * 10);
u32Tmp += g_u32loSec;
sPt->u32Second = u32Tmp;
}
}
/**
* @brief Read alarm date/time from RTC setting
*
* @param[out] sPt \n
* Specify the time property and current time. It includes: \n
* u32Year: Year value \n
* u32Month: Month value \n
* u32Day: Day value \n
* u32DayOfWeek: Day of week \n
* u32Hour: Hour value \n
* u32Minute: Minute value \n
* u32Second: Second value \n
* u32TimeScale: \ref RTC_CLOCK_12 / \ref RTC_CLOCK_24 \n
* u8AmPm: \ref RTC_AM / \ref RTC_PM \n
*
* @return None
*
*/
void RTC_GetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt)
{
uint32_t u32Tmp;
sPt->u32TimeScale = RTC->TSSR & RTC_TSSR_24H_12H_Msk; /* 12/24-hour */
sPt->u32DayOfWeek = RTC->DWR & RTC_DWR_DWR_Msk; /* Day of week */
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
g_u32hiYear = (RTC->CAR & RTC_CAR_10YEAR_Msk) >> RTC_CAR_10YEAR_Pos;
g_u32loYear = (RTC->CAR & RTC_CAR_1YEAR_Msk) >> RTC_CAR_1YEAR_Pos;
g_u32hiMonth = (RTC->CAR & RTC_CAR_10MON_Msk) >> RTC_CAR_10MON_Pos;
g_u32loMonth = (RTC->CAR & RTC_CAR_1MON_Msk) >> RTC_CAR_1MON_Pos;
g_u32hiDay = (RTC->CAR & RTC_CAR_10DAY_Msk) >> RTC_CAR_10DAY_Pos;
g_u32loDay = (RTC->CAR & RTC_CAR_1DAY_Msk);
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
g_u32hiHour = (RTC->TAR & RTC_TAR_10HR_Msk) >> RTC_TAR_10HR_Pos;
g_u32loHour = (RTC->TAR & RTC_TAR_1HR_Msk) >> RTC_TAR_1HR_Pos;
g_u32hiMin = (RTC->TAR & RTC_TAR_10MIN_Msk) >> RTC_TAR_10MIN_Pos;
g_u32loMin = (RTC->TAR & RTC_TAR_1MIN_Msk) >> RTC_TAR_1MIN_Pos;
g_u32hiSec = (RTC->TAR & RTC_TAR_10SEC_Msk) >> RTC_TAR_10SEC_Pos;
g_u32loSec = (RTC->TAR & RTC_TAR_1SEC_Msk);
u32Tmp = (g_u32hiYear * 10); /* Compute to 20XX year */
u32Tmp += g_u32loYear;
sPt->u32Year = u32Tmp + RTC_YEAR2000;
u32Tmp = (g_u32hiMonth * 10); /* Compute 0~12 month */
sPt->u32Month = u32Tmp + g_u32loMonth;
u32Tmp = (g_u32hiDay * 10); /* Compute 0~31 day */
sPt->u32Day = u32Tmp + g_u32loDay;
if (sPt->u32TimeScale == RTC_CLOCK_12) { /* Compute12/24 hour */
u32Tmp = (g_u32hiHour * 10);
u32Tmp += g_u32loHour;
sPt->u32Hour = u32Tmp; /* AM: 1~12. PM: 21~32. */
if (sPt->u32Hour >= 21) {
sPt->u32AmPm = RTC_PM;
sPt->u32Hour -= 20;
} else {
sPt->u32AmPm = RTC_AM;
}
u32Tmp = (g_u32hiMin * 10);
u32Tmp += g_u32loMin;
sPt->u32Minute = u32Tmp;
u32Tmp = (g_u32hiSec * 10);
u32Tmp += g_u32loSec;
sPt->u32Second = u32Tmp;
} else {
u32Tmp = (g_u32hiHour * 10);
u32Tmp += g_u32loHour;
sPt->u32Hour = u32Tmp;
u32Tmp = (g_u32hiMin * 10);
u32Tmp+= g_u32loMin;
sPt->u32Minute = u32Tmp;
u32Tmp = (g_u32hiSec * 10);
u32Tmp += g_u32loSec;
sPt->u32Second = u32Tmp;
}
}
/**
* @brief This function is used to update date/time to RTC.
*
* @param[in] sPt \n
* Specify the time property and current time. It includes: \n
* u32Year: Year value. \n
* u32Month: Month value. \n
* u32Day: Day value. \n
* u32DayOfWeek: Day of week. [ \ref RTC_SUNDAY / \ref RTC_MONDAY / \ref RTC_TUESDAY /
* \ref RTC_WEDNESDAY / \ref RTC_THURSDAY / \ref RTC_FRIDAY /
* \ref RTC_SATURDAY] \n
* u32Hour: Hour value. \n
* u32Minute: Minute value. \n
* u32Second: Second value. \n
* u32TimeScale: [ \ref RTC_CLOCK_12 / \ref RTC_CLOCK_24] \n
* u8AmPm: [ \ref RTC_AM / \ref RTC_PM] \n
*
*
* @return None
*
*
*/
void RTC_SetDateAndTime(S_RTC_TIME_DATA_T *sPt)
{
uint32_t u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
if (sPt->u32TimeScale == RTC_CLOCK_12) {
RTC->TSSR &= ~RTC_TSSR_24H_12H_Msk;
/*-----------------------------------------------------------------------------------------*/
/* important, range of 12-hour PM mode is 21 upto 32 */
/*-----------------------------------------------------------------------------------------*/
if (sPt->u32AmPm == RTC_PM)
sPt->u32Hour += 20;
} else {
RTC->TSSR |= RTC_TSSR_24H_12H_Msk;
}
RTC->DWR = sPt->u32DayOfWeek & RTC_DWR_DWR_Msk;
u32Reg = ((sPt->u32Year - RTC_YEAR2000) / 10) << 20;
u32Reg |= (((sPt->u32Year - RTC_YEAR2000) % 10) << 16);
u32Reg |= ((sPt->u32Month / 10) << 12);
u32Reg |= ((sPt->u32Month % 10) << 8);
u32Reg |= ((sPt->u32Day / 10) << 4);
u32Reg |= (sPt->u32Day % 10);
g_u32Reg = u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
RTC->CLR = (uint32_t)g_u32Reg;
u32Reg = ((sPt->u32Hour / 10) << 20);
u32Reg |= ((sPt->u32Hour % 10) << 16);
u32Reg |= ((sPt->u32Minute / 10) << 12);
u32Reg |= ((sPt->u32Minute % 10) << 8);
u32Reg |= ((sPt->u32Second / 10) << 4);
u32Reg |= (sPt->u32Second % 10);
g_u32Reg = u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
RTC->TLR = (uint32_t)g_u32Reg;
}
/**
* @brief This function is used to set alarm date/time to RTC.
*
* @param[in] sPt \n
* Specify the time property and current time. It includes: \n
* u32Year: Year value. \n
* u32Month: Month value. \n
* u32Day: Day value. \n
* u32DayOfWeek: Day of week. [ \ref RTC_SUNDAY / \ref RTC_MONDAY / \ref RTC_TUESDAY /
* \ref RTC_WEDNESDAY / \ref RTC_THURSDAY / \ref RTC_FRIDAY /
* \ref RTC_SATURDAY] \n
* u32Hour: Hour value. \n
* u32Minute: Minute value. \n
* u32Second: Second value. \n
* u32TimeScale: [ \ref RTC_CLOCK_12 / \ref RTC_CLOCK_24] \n
* u8AmPm: [ \ref RTC_AM / \ref RTC_PM] \n
*
* @return None
*
*/
void RTC_SetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt)
{
uint32_t u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
if (sPt->u32TimeScale == RTC_CLOCK_12) {
RTC->TSSR &= ~RTC_TSSR_24H_12H_Msk;
/*-----------------------------------------------------------------------------------------*/
/* important, range of 12-hour PM mode is 21 upto 32 */
/*-----------------------------------------------------------------------------------------*/
if (sPt->u32AmPm == RTC_PM)
sPt->u32Hour += 20;
} else {
RTC->TSSR |= RTC_TSSR_24H_12H_Msk;
}
RTC->DWR = sPt->u32DayOfWeek & RTC_DWR_DWR_Msk;
u32Reg = ((sPt->u32Year - RTC_YEAR2000) / 10) << 20;
u32Reg |= (((sPt->u32Year - RTC_YEAR2000) % 10) << 16);
u32Reg |= ((sPt->u32Month / 10) << 12);
u32Reg |= ((sPt->u32Month % 10) << 8);
u32Reg |= ((sPt->u32Day / 10) << 4);
u32Reg |= (sPt->u32Day % 10);
g_u32Reg = u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
RTC->CAR = (uint32_t)g_u32Reg;
u32Reg = ((sPt->u32Hour / 10) << 20);
u32Reg |= ((sPt->u32Hour % 10) << 16);
u32Reg |= ((sPt->u32Minute / 10) << 12);
u32Reg |= ((sPt->u32Minute % 10) << 8);
u32Reg |= ((sPt->u32Second / 10) << 4);
u32Reg |= (sPt->u32Second % 10);
g_u32Reg = u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
RTC->TAR = (uint32_t)g_u32Reg;
}
/**
* @brief This function is used to update date to RTC
*
* @param[in] u32Year The Year Calendar Digit of Alarm Setting
* @param[in] u32Month The Month Calendar Digit of Alarm Setting
* @param[in] u32Day The Day Calendar Digit of Alarm Setting
* @param[in] u32DayOfWeek The Day of Week. [ \ref RTC_SUNDAY / \ref RTC_MONDAY / \ref RTC_TUESDAY /
* \ref RTC_WEDNESDAY / \ref RTC_THURSDAY / \ref RTC_FRIDAY /
* \ref RTC_SATURDAY]
*
* @return None
*
*/
void RTC_SetDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day, uint32_t u32DayOfWeek)
{
__IO uint32_t u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
RTC->DWR = u32DayOfWeek & RTC_DWR_DWR_Msk;
u32Reg = ((u32Year - RTC_YEAR2000) / 10) << 20;
u32Reg |= (((u32Year - RTC_YEAR2000) % 10) << 16);
u32Reg |= ((u32Month / 10) << 12);
u32Reg |= ((u32Month % 10) << 8);
u32Reg |= ((u32Day / 10) << 4);
u32Reg |= (u32Day % 10);
g_u32Reg = u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
RTC->CLR = (uint32_t)g_u32Reg;
}
/**
* @brief This function is used to update time to RTC.
*
* @param[in] u32Hour The Hour Time Digit of Alarm Setting.
* @param[in] u32Minute The Minute Time Digit of Alarm Setting
* @param[in] u32Second The Second Time Digit of Alarm Setting
* @param[in] u32TimeMode The 24-Hour / 12-Hour Time Scale Selection. [ \ref RTC_CLOCK_12 / \ref RTC_CLOCK_24]
* @param[in] u32AmPm 12-hour time scale with AM and PM indication. Only Time Scale select 12-hour used. [ \ref RTC_AM / \ref RTC_PM]
*
* @return None
*
*/
void RTC_SetTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm)
{
__IO uint32_t u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
if (u32TimeMode == RTC_CLOCK_12) {
RTC->TSSR &= ~RTC_TSSR_24H_12H_Msk;
if (u32AmPm == RTC_PM) /* important, range of 12-hour PM mode is 21 upto 32 */
u32Hour += 20;
} else if(u32TimeMode == RTC_CLOCK_24) {
RTC->TSSR |= RTC_TSSR_24H_12H_Msk;
}
u32Reg = ((u32Hour / 10) << 20);
u32Reg |= ((u32Hour % 10) << 16);
u32Reg |= ((u32Minute / 10) << 12);
u32Reg |= ((u32Minute % 10) << 8);
u32Reg |= ((u32Second / 10) << 4);
u32Reg |= (u32Second % 10);
g_u32Reg = u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk));
RTC->TLR = (uint32_t)g_u32Reg;
}
/**
* @brief This function is used to set alarm date to RTC
*
* @param[in] u32Year The Year Calendar Digit of Alarm Setting
* @param[in] u32Month The Month Calendar Digit of Alarm Setting
* @param[in] u32Day The Day Calendar Digit of Alarm Setting
*
* @return None
*
*/
void RTC_SetAlarmDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day)
{
__IO uint32_t u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
u32Reg = ((u32Year - RTC_YEAR2000) / 10) << 20;
u32Reg |= (((u32Year - RTC_YEAR2000) % 10) << 16);
u32Reg |= ((u32Month / 10) << 12);
u32Reg |= ((u32Month % 10) << 8);
u32Reg |= ((u32Day / 10) << 4);
u32Reg |= (u32Day % 10);
g_u32Reg = u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
RTC->CAR = (uint32_t)g_u32Reg;
}
/**
* @brief This function is used to set alarm date to RTC
*
* @param[in] u32Hour The Hour Time Digit of Alarm Setting.
* @param[in] u32Minute The Month Calendar Digit of Alarm Setting
* @param[in] u32Second The Day Calendar Digit of Alarm Setting
* @param[in] u32TimeMode The 24-Hour / 12-Hour Time Scale Selection. [ \ref RTC_CLOCK_12 / \ref RTC_CLOCK_24]
* @param[in] u32AmPm 12-hour time scale with AM and PM indication. Only Time Scale select 12-hour used. [ \ref RTC_AM / \ref RTC_PM]
*
* @return None
*
*/
void RTC_SetAlarmTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm)
{
__IO uint32_t u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
if (u32TimeMode == RTC_CLOCK_12) {
RTC->TSSR &= ~RTC_TSSR_24H_12H_Msk;
if (u32AmPm == RTC_PM) /* important, range of 12-hour PM mode is 21 upto 32 */
u32Hour += 20;
} else if(u32TimeMode == RTC_CLOCK_24) {
RTC->TSSR |= RTC_TSSR_24H_12H_Msk;
}
u32Reg = ((u32Hour / 10) << 20);
u32Reg |= ((u32Hour % 10) << 16);
u32Reg |= ((u32Minute / 10) << 12);
u32Reg |= ((u32Minute % 10) << 8);
u32Reg |= ((u32Second / 10) << 4);
u32Reg |= (u32Second % 10);
g_u32Reg = u32Reg;
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
RTC->TAR = (uint32_t)g_u32Reg;
}
/**
* @brief This function is used to enable tamper detection function and set tamper control register, interrupt.
*
* @param[in] u32PinCondition set tamper detection condition: 1=Falling detect, 0=Rising detect
*
* @return None
*
*/
void RTC_EnableTamperDetection(uint32_t u32PinCondition)
{
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
/* detection edge select */
if(u32PinCondition)
RTC->SPRCTL |= RTC_SPRCTL_SNOOPEDGE_Msk;
else
RTC->SPRCTL &= ~RTC_SPRCTL_SNOOPEDGE_Msk;
while(!(RTC->SPRCTL & RTC_SPRCTL_SPRRDY_Msk));
/* enable snooper pin event detection */
RTC->SPRCTL |= RTC_SPRCTL_SNOOPEN_Msk;
while(!(RTC->SPRCTL & RTC_SPRCTL_SPRRDY_Msk));
}
/**
* @brief This function is used to disable tamper detection function.
*
* @param None
*
* @return None
*
*/
void RTC_DisableTamperDetection(void)
{
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
RTC->SPRCTL &= ~RTC_SPRCTL_SNOOPEN_Msk;
}
/**
* @brief This function is used to get day of week.
*
* @param None
*
* @return Day of week
*
*/
uint32_t RTC_GetDayOfWeek(void)
{
return (RTC->DWR & RTC_DWR_DWR_Msk);
}
/**
* @brief The function is used to set time tick period for periodic time tick Interrupt.
*
* @param[in] u32TickSelection
* It is used to set the RTC time tick period for Periodic Time Tick Interrupt request.
* It consists of: \n
* \ref RTC_TICK_1_SEC : Time tick is 1 second \n
* \ref RTC_TICK_1_2_SEC : Time tick is 1/2 second \n
* \ref RTC_TICK_1_4_SEC : Time tick is 1/4 second \n
* \ref RTC_TICK_1_8_SEC : Time tick is 1/8 second \n
* \ref RTC_TICK_1_16_SEC : Time tick is 1/16 second \n
* \ref RTC_TICK_1_32_SEC : Time tick is 1/32 second \n
* \ref RTC_TICK_1_64_SEC : Time tick is 1/64 second \n
* \ref RTC_TICK_1_128_SEC : Time tick is 1/128 second
*
* @return None
*
*/
void RTC_SetTickPeriod(uint32_t u32TickSelection)
{
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
RTC->TTR = RTC->TTR & ~RTC_TTR_TTR_Msk | u32TickSelection;
}
/**
* @brief The function is used to enable specified interrupt.
*
* @param[in] u32IntFlagMask The structure of interrupt source. It consists of: \n
* \ref RTC_RIER_AIER_Msk : Alarm interrupt \n
* \ref RTC_RIER_TIER_Msk : Tick interrupt \n
* \ref RTC_RIER_SNOOPIER_Msk : Snooper Pin Event Detection Interrupt\n
*
* @return None
*
*/
void RTC_EnableInt(uint32_t u32IntFlagMask)
{
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
RTC->RIER |= u32IntFlagMask;
}
/**
* @brief The function is used to disable specified interrupt.
*
* @param[in] u32IntFlagMask The structure of interrupt source. It consists of: \n
* \ref RTC_RIER_AIER_Msk : Alarm interrupt \n
* \ref RTC_RIER_TIER_Msk : Tick interrupt \n
* \ref RTC_RIER_SNOOPIER_Msk : Snooper Pin Event Detection Interrupt\n
*
* @return None
*
*/
void RTC_DisableInt(uint32_t u32IntFlagMask)
{
RTC->AER = RTC_WRITE_KEY;
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
if(u32IntFlagMask & RTC_RIER_TIER_Msk) {
RTC->RIER &= ~RTC_RIER_TIER_Msk;
RTC->RIIR = RTC_RIIR_TIF_Msk;
}
if(u32IntFlagMask & RTC_RIER_AIER_Msk) {
RTC->RIER &= ~RTC_RIER_AIER_Msk;
RTC->RIIR = RTC_RIIR_AIF_Msk;
}
if(u32IntFlagMask & RTC_RIER_SNOOPIER_Msk) {
RTC->RIER &= ~RTC_RIER_SNOOPIER_Msk;
RTC->RIIR = RTC_RIIR_SNOOPIF_Msk;
}
}
/**
* @brief Disable RTC clock.
*
* @return None
*
*/
void RTC_Close (void)
{
CLK->APBCLK &= ~CLK_APBCLK_RTC_EN_Msk;
}
/*@}*/ /* end of group NANO100_RTC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_RTC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,252 @@
/**************************************************************************//**
* @file rtc.h
* @version V1.00
* $Revision: 7 $
* $Date: 15/06/26 1:34p $
* @brief Nano100 series RTC driver header file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __RTC_H__
#define __RTC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_RTC_Driver RTC Driver
@{
*/
/** @addtogroup NANO100_RTC_EXPORTED_CONSTANTS RTC Exported Constants
@{
*/
#define RTC_INIT_KEY 0xA5EB1357 /*!< RTC Access Key */
#define RTC_WRITE_KEY 0xA965 /*!< RTC Access Key */
#define RTC_WAIT_COUNT 0xFFFFFFFF /*!< Initial Time Out Value */
#define RTC_YEAR2000 2000 /*!< RTC Reference */
#define RTC_FCR_REFERENCE 32761 /*!< RTC Reference */
#define RTC_CLOCK_12 0 /*!< RTC 12 Hour */
#define RTC_CLOCK_24 1 /*!< RTC 24 Hour */
#define RTC_AM 1 /*!< RTC AM */
#define RTC_PM 2 /*!< RTC PM */
#define RTC_TICK_1_SEC ((uint32_t) 0x00000000) /*!< Time tick is 1 second */
#define RTC_TICK_1_2_SEC ((uint32_t) 0x00000001) /*!< Time tick is 1/2 second */
#define RTC_TICK_1_4_SEC ((uint32_t) 0x00000002) /*!< Time tick is 1/4 second */
#define RTC_TICK_1_8_SEC ((uint32_t) 0x00000003) /*!< Time tick is 1/8 second */
#define RTC_TICK_1_16_SEC ((uint32_t) 0x00000004) /*!< Time tick is 1/16 second */
#define RTC_TICK_1_32_SEC ((uint32_t) 0x00000005) /*!< Time tick is 1/32 second */
#define RTC_TICK_1_64_SEC ((uint32_t) 0x00000006) /*!< Time tick is 1/64 second */
#define RTC_TICK_1_128_SEC ((uint32_t) 0x00000007) /*!< Time tick is 1/128 second */
#define RTC_SUNDAY ((uint32_t) 0x00000000) /*!< Day of week is sunday */
#define RTC_MONDAY ((uint32_t) 0x00000001) /*!< Day of week is monday */
#define RTC_TUESDAY ((uint32_t) 0x00000002) /*!< Day of week is tuesday */
#define RTC_WEDNESDAY ((uint32_t) 0x00000003) /*!< Day of week is wednesday */
#define RTC_THURSDAY ((uint32_t) 0x00000004) /*!< Day of week is thursday */
#define RTC_FRIDAY ((uint32_t) 0x00000005) /*!< Day of week is friday */
#define RTC_SATURDAY ((uint32_t) 0x00000006) /*!< Day of week is saturday */
#define RTC_SNOOPER_RISING 0 /*!< Snooper Active Rising Edge */
#define RTC_SNOOPER_FALLING 1 /*!< Snooper Active Falling Edge */
/*@}*/ /* end of group NANO100_RTC_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_RTC_EXPORTED_STRUCTS RTC Exported Structs
@{
*/
/**
* @brief RTC define Time Data Struct
*/
typedef struct {
uint32_t u32Year; /*!< Year value */
uint32_t u32Month; /*!< Month value */
uint32_t u32Day; /*!< Day value */
uint32_t u32DayOfWeek; /*!< Day of week value */
uint32_t u32Hour; /*!< Hour value */
uint32_t u32Minute; /*!< Minute value */
uint32_t u32Second; /*!< Second value */
uint32_t u32TimeScale; /*!< 12-Hour, 24-Hour */
uint32_t u32AmPm; /*!< Only Time Scale select 12-hr used */
} S_RTC_TIME_DATA_T;
/*@}*/ /* end of group NANO100_RTC_EXPORTED_STRUCTS */
/** @addtogroup NANO100_RTC_EXPORTED_FUNCTIONS RTC Exported Functions
@{
*/
/**
* @brief Read spare register
*
* @param[in] u32RegNum The spare register number(0~23)
*
* @return Spare register content.
*
*/
#define RTC_READ_SPARE_REGISTER(u32RegNum) (RTC->SPR[u32RegNum])
/**
* @brief Write spare register
*
* @param[in] u32RegNum The spare register number(0~23)
* @param[in] u32RegValue The spare register value
*
* @return None
*
*/
#define RTC_WRITE_SPARE_REGISTER(u32RegNum, u32RegValue) (RTC->SPR[u32RegNum] = u32RegValue)
/**
* @brief According to current time, return this year is leap year or not
*
* @param None
*
* @return 0 = This year is not a leap year. \n
* 1 = This year is a leap year.
*
*/
#define RTC_IS_LEAP_YEAR() ((RTC->LIR & (RTC_LIR_LIR_Msk))?1:0)
/**
* @brief Clear alarm interrupt status.
*
* @param None
*
* @return None
*
*/
#define RTC_CLEAR_ALARM_INT_FLAG() (RTC->RIIR = RTC_RIIR_AIF_Msk)
/**
* @brief Clear tick interrupt status.
*
* @param None
*
* @return None
*
*/
#define RTC_CLEAR_TICK_INT_FLAG() (RTC->RIIR = RTC_RIIR_TIF_Msk)
/**
* @brief Clear tamper detect pin status.
*
* @param[in] u32PinNum tamper detect pin number.
*
* @return None
*
*/
#define RTC_CLEAR_TAMPER_FLAG(u32PinNum) (RTC->RIIR = RTC_RIIR_SNOOPIF_Msk)
/**
* @brief Get alarm interrupt status.
*
* @param None
*
* @return Alarm interrupt status
*
*/
#define RTC_GET_ALARM_INT_FLAG() ((RTC->RIIR & RTC_RIIR_AIF_Msk) >> RTC_RIIR_AIF_Pos)
/**
* @brief Get alarm interrupt status.
*
* @param None
*
* @return Alarm interrupt status
*
*/
#define RTC_GET_TICK_INT_FLAG() ((RTC->RIIR & RTC_RIIR_TIF_Msk) >> RTC_RIIR_TIF_Pos)
/**
* @brief Get tamper detect pin status.
*
* @param None
*
* @return 1: Snooper Pin Event Detected \n
* 0: Snooper Pin Event Never Detected
*
*/
#define RTC_GET_TAMPER_FLAG() ( (RTC->RIIR & RTC_RIIR_SNOOPIF_Msk) >> RTC_RIIR_SNOOPIF_Pos)
/**
* @brief Enable Timer tick wakeup function.
*
* @param None
*
* @return None
*
*/
#define RTC_ENABLE_TICK_WAKEUP() (RTC->TTR |= RTC_TTR_TWKE_Msk);
/**
* @brief Disable Timer tick wakeup function.
*
* @param None
*
* @return None
*
*/
#define RTC_DISABLE_TICK_WAKEUP() (RTC->TTR &= ~RTC_TTR_TWKE_Msk);
void RTC_Open(S_RTC_TIME_DATA_T *sPt);
void RTC_Close(void);
void RTC_32KCalibration(int32_t i32FrequencyX100);
void RTC_SetTickPeriod(uint32_t u32TickSelection);
void RTC_EnableInt(uint32_t u32IntFlagMask);
void RTC_DisableInt(uint32_t u32IntFlagMask);
uint32_t RTC_GetDayOfWeek(void);
void RTC_DisableTamperDetection(void);
void RTC_EnableTamperDetection(uint32_t u32PinCondition);
void RTC_SetAlarmTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm);
void RTC_SetAlarmDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day);
void RTC_SetTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm);
void RTC_SetDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day, uint32_t u32DayOfWeek);
void RTC_SetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt);
void RTC_SetDateAndTime(S_RTC_TIME_DATA_T *sPt);
void RTC_GetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt);
void RTC_GetDateAndTime(S_RTC_TIME_DATA_T *sPt);
/*@}*/ /* end of group NANO100_RTC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_RTC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif /* __RTC_H__ */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

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

View File

@ -0,0 +1,265 @@
/**************************************************************************//**
* @file sc.h
* @version V1.00
* $Revision: 7 $
* $Date: 15/07/31 7:26p $
* @brief Nano100 series Smartcard (SC) driver header file
*
* @note
* Copyright (C) 2013~2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __SC_H__
#define __SC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_SC_Driver SC Driver
@{
*/
/** @addtogroup NANO100_SC_EXPORTED_CONSTANTS SC Exported Constants
@{
*/
#define SC_INTERFACE_NUM 3 /*!< Smartcard interface numbers */
#define SC_PIN_STATE_HIGH 1 /*!< Smartcard pin status high */
#define SC_PIN_STATE_LOW 0 /*!< Smartcard pin status low */
#define SC_PIN_STATE_IGNORE 0xFFFFFFFF /*!< Ignore pin status */
#define SC_CLK_ON 1 /*!< Smartcard clock on */
#define SC_CLK_OFF 0 /*!< Smartcard clock off */
#define SC_TMR_MODE_0 (0ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 0, down count */
#define SC_TMR_MODE_1 (1ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 1, down count, start after detect start bit */
#define SC_TMR_MODE_2 (2ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 2, down count, start after receive start bit */
#define SC_TMR_MODE_3 (3ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 3, down count, use for activation, only timer 0 support this mode */
#define SC_TMR_MODE_4 (4ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 4, down count with reload after timeout */
#define SC_TMR_MODE_5 (5ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 5, down count, start after detect start bit, reload after timeout */
#define SC_TMR_MODE_6 (6ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 6, down count, start after receive start bit, reload after timeout */
#define SC_TMR_MODE_7 (7ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 7, down count, start and reload after detect start bit */
#define SC_TMR_MODE_8 (8ul << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 8, up count */
#define SC_TMR_MODE_F (0xF << SC_TMR0_MODE_Pos) /*!<Timer Operation Mode 15, down count, reload after detect start bit */
/*@}*/ /* end of group NANO100_SC_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_SC_EXPORTED_FUNCTIONS SC Exported Functions
@{
*/
/**
* @brief This macro enable smartcard interrupt
* @param[in] sc Base address of smartcard module
* @param[in] u32Mask Interrupt mask to be enabled. A combination of
* - \ref SC_IER_ACON_ERR_IE_Msk
* - \ref SC_IER_RTMR_IE_Msk
* - \ref SC_IER_INIT_IE_Msk
* - \ref SC_IER_CD_IE_Msk
* - \ref SC_IER_BGT_IE_Msk
* - \ref SC_IER_TMR2_IE_Msk
* - \ref SC_IER_TMR1_IE_Msk
* - \ref SC_IER_TMR0_IE_Msk
* - \ref SC_IER_TERR_IE_Msk
* - \ref SC_IER_TBE_IE_Msk
* - \ref SC_IER_RDA_IE_Msk
* @return None
* \hideinitializer
*/
#define SC_ENABLE_INT(sc, u32Mask) ((sc)->IER |= (u32Mask))
/**
* @brief This macro disable smartcard interrupt
* @param[in] sc Base address of smartcard module
* @param[in] u32Mask Interrupt mask to be disabled. A combination of
* - \ref SC_IER_ACON_ERR_IE_Msk
* - \ref SC_IER_RTMR_IE_Msk
* - \ref SC_IER_INIT_IE_Msk
* - \ref SC_IER_CD_IE_Msk
* - \ref SC_IER_BGT_IE_Msk
* - \ref SC_IER_TMR2_IE_Msk
* - \ref SC_IER_TMR1_IE_Msk
* - \ref SC_IER_TMR0_IE_Msk
* - \ref SC_IER_TERR_IE_Msk
* - \ref SC_IER_TBE_IE_Msk
* - \ref SC_IER_RDA_IE_Msk
* @return None
* \hideinitializer
*/
#define SC_DISABLE_INT(sc, u32Mask) ((sc)->IER &= ~(u32Mask))
/**
* @brief This macro set VCC pin state of smartcard interface
* @param[in] sc Base address of smartcard module
* @param[in] u32State Pin state of VCC pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW
* @return None
* \hideinitializer
*/
#define SC_SET_VCC_PIN(sc, u32State) \
do {\
uint32_t reg = (sc)->PINCSR;\
if(((reg & (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)) == 0) ||\
((reg & (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)) == (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)))\
reg &= ~SC_PINCSR_POW_EN_Msk;\
else\
reg |= SC_PINCSR_POW_EN_Msk;\
if(u32State)\
(sc)->PINCSR = reg | SC_PINCSR_POW_EN_Msk;\
else\
(sc)->PINCSR = reg & ~SC_PINCSR_POW_EN_Msk;\
}while(0)
/**
* @brief This macro turns CLK output on or off
* @param[in] sc Base address of smartcard module
* @param[in] u32OnOff Clock on or off for selected smartcard module, valid values are \ref SC_CLK_ON and \ref SC_CLK_OFF
* @return None
* \hideinitializer
*/
#define SC_SET_CLK_PIN(sc, u32OnOff)\
do {\
uint32_t reg = (sc)->PINCSR;\
if(((reg & (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)) == 0) ||\
((reg & (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)) == (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)))\
reg &= ~SC_PINCSR_POW_EN_Msk;\
else\
reg |= SC_PINCSR_POW_EN_Msk;\
if(u32OnOff)\
(sc)->PINCSR = reg | SC_PINCSR_CLK_KEEP_Msk;\
else\
(sc)->PINCSR = reg & ~SC_PINCSR_CLK_KEEP_Msk;\
}while(0)
/**
* @brief This macro set I/O pin state of smartcard interface
* @param[in] sc Base address of smartcard module
* @param[in] u32State Pin state of I/O pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW
* @return None
* \hideinitializer
*/
#define SC_SET_IO_PIN(sc, u32State)\
do {\
uint32_t reg = (sc)->PINCSR;\
if(((reg & (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)) == 0) ||\
((reg & (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)) == (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)))\
reg &= ~SC_PINCSR_POW_EN_Msk;\
else\
reg |= SC_PINCSR_POW_EN_Msk;\
if(u32State)\
(sc)->PINCSR = reg | SC_PINCSR_SC_DATA_O_Msk;\
else\
(sc)->PINCSR = reg & ~SC_PINCSR_SC_DATA_O_Msk;\
}while(0)
/**
* @brief This macro set RST pin state of smartcard interface
* @param[in] sc Base address of smartcard module
* @param[in] u32State Pin state of RST pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW
* @return None
* \hideinitializer
*/
#define SC_SET_RST_PIN(sc, u32State)\
do {\
uint32_t reg = (sc)->PINCSR;\
if(((reg & (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)) == 0) ||\
((reg & (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)) == (SC_PINCSR_POW_EN_Msk | SC_PINCSR_POW_INV_Msk)))\
reg &= ~SC_PINCSR_POW_EN_Msk;\
else\
reg |= SC_PINCSR_POW_EN_Msk;\
if(u32State)\
(sc)->PINCSR = reg | SC_PINCSR_SC_RST_Msk;\
else\
(sc)->PINCSR = reg & ~SC_PINCSR_SC_RST_Msk;\
}while(0)
/**
* @brief This macro read one byte from smartcard module receive FIFO
* @param[in] sc Base address of smartcard module
* @return[in] One byte read from receive FIFO
* \hideinitializer
*/
#define SC_READ(sc) ((char)((sc)->RBR))
/**
* @brief This macro write one byte to smartcard module transmit FIFO
* @param[in] sc Base address of smartcard module
* @param[in] u8Data Data to write to transmit FIFO
* @return None
* \hideinitializer
*/
#define SC_WRITE(sc, u8Data) ((sc)->THR = (u8Data))
/**
* @brief This macro set smartcard stop bit length
* @param[in] sc Base address of smartcard module
* @param[in] u32Len Stop bit length, ether 1 or 2.
* @return None
* @details Stop bit length must be 1 for T = 1 protocol and 2 for T = 0 protocol.
* \hideinitializer
*/
#define SC_SET_STOP_BIT_LEN(sc, u32Len) ((sc)->CTL = ((sc)->CTL & ~SC_CTL_SLEN_Msk) | (u32Len == 1 ? SC_CTL_SLEN_Msk : 0))
/**
* @brief Enable/Disable Tx error retry, and set Tx error retry count
* @param[in] sc Base address of smartcard module
* @param[in] u32Count The number of times of Tx error retry count, between 0~8. 0 means disable Tx error retry
* @return None
*/
__STATIC_INLINE void SC_SetTxRetry(SC_T *sc, uint32_t u32Count)
{
if(u32Count == 0) { // disable Tx error retry
sc->CTL &= ~(SC_CTL_TX_ERETRY_Msk | SC_CTL_TX_ERETRY_EN_Msk);
} else {
sc->CTL = (sc->CTL & ~SC_CTL_TX_ERETRY_Msk) | ((u32Count - 1) << SC_CTL_TX_ERETRY_Pos) | SC_CTL_TX_ERETRY_EN_Msk;
}
}
/**
* @brief Enable/Disable Rx error retry, and set Rx error retry count
* @param[in] sc Base address of smartcard module
* @param[in] u32Count The number of times of Rx error retry count, between 0~8. 0 means disable Rx error retry
* @return None
*/
__STATIC_INLINE void SC_SetRxRetry(SC_T *sc, uint32_t u32Count)
{
if(u32Count == 0) { // disable Rx error retry
sc->CTL &= ~(SC_CTL_RX_ERETRY_Msk | SC_CTL_RX_ERETRY_EN_Msk);
} else {
sc->CTL = (sc->CTL & ~SC_CTL_RX_ERETRY_Msk) | ((u32Count - 1) << SC_CTL_RX_ERETRY_Pos) | SC_CTL_RX_ERETRY_EN_Msk;
}
}
uint32_t SC_IsCardInserted(SC_T *sc);
void SC_ClearFIFO(SC_T *sc);
void SC_Close(SC_T *sc);
void SC_Open(SC_T *sc, uint32_t u32CardDet, uint32_t u32PWR);
void SC_ResetReader(SC_T *sc);
void SC_SetBlockGuardTime(SC_T *sc, uint32_t u32BGT);
void SC_SetCharGuardTime(SC_T *sc, uint32_t u32CGT);
void SC_StopAllTimer(SC_T *sc);
void SC_StartTimer(SC_T *sc, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount);
void SC_StopTimer(SC_T *sc, uint32_t u32TimerNum);
/*@}*/ /* end of group NANO100_SC_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_SC_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__SC_H__
/*** (C) COPYRIGHT 2013~2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,192 @@
/**************************************************************************//**
* @file scuart.c
* @version V1.00
* $Revision: 5 $
* $Date: 15/05/14 11:14a $
* @brief Nano100 series Smartcard UART mode (SCUART) driver source file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_SCUART_Driver SCUART Driver
@{
*/
/** @addtogroup NANO100_SCUART_EXPORTED_FUNCTIONS SCUART Exported Functions
@{
*/
/**
* @brief The function is used to disable smartcard interface UART mode.
* @param sc The base address of smartcard module.
* @return None
*/
void SCUART_Close(SC_T* sc)
{
sc->IER = 0;
sc->UACTL = 0;
sc->CTL = 0;
}
/// @cond HIDDEN_SYMBOLS
/**
* @brief This function returns module clock of specified SC interface
* @param[in] sc The base address of smartcard module.
* @return Module clock of specified SC interface
*/
static uint32_t SCUART_GetClock(SC_T *sc)
{
uint32_t u32ClkSrc = (CLK->CLKSEL2 & CLK_CLKSEL2_SC_S_Msk) >> CLK_CLKSEL2_SC_S_Pos;
uint32_t u32Clk;
// Get smartcard module clock
if(u32ClkSrc == 0)
u32Clk = __HXT;
else if(u32ClkSrc == 1)
u32Clk = CLK_GetPLLClockFreq();
else
u32Clk = __HIRC12M;
if(sc == SC0)
u32Clk /= ((CLK->CLKDIV0 & CLK_CLKDIV0_SC0_N_Msk) >> CLK_CLKDIV0_SC0_N_Pos) + 1;
else if(sc == SC1)
u32Clk /= (CLK->CLKDIV1 & CLK_CLKDIV1_SC1_N_Msk) + 1;
else // SC2
u32Clk /= ((CLK->CLKDIV1 & CLK_CLKDIV1_SC2_N_Msk) >> CLK_CLKDIV1_SC2_N_Pos) + 1;
return u32Clk;
}
/// @endcond HIDDEN_SYMBOLS
/**
* @brief This function use to enable smartcard module UART mode and set baudrate.
* @param[in] sc The base address of smartcard module.
* @param[in] u32baudrate Target baudrate of smartcard module.
* @return Actual baudrate of smartcard mode
* @note This function configures character width to 8 bits, 1 stop bit, and no parity.
* And can use \ref SCUART_SetLineConfig function to update these settings
*/
uint32_t SCUART_Open(SC_T* sc, uint32_t u32baudrate)
{
uint32_t u32Clk = SCUART_GetClock(sc), u32Div;
// Calculate divider for target baudrate
u32Div = (u32Clk + (u32baudrate >> 1) - 1) / u32baudrate - 1;
sc->CTL = SC_CTL_SC_CEN_Msk | SC_CTL_SLEN_Msk; // Enable smartcard interface and stop bit = 1
sc->UACTL = SCUART_CHAR_LEN_8 | SCUART_PARITY_NONE | SC_UACTL_UA_MODE_EN_Msk; // Enable UART mode, disable parity and 8 bit per character
sc->ETUCR = u32Div;
return(u32Clk / (u32Div + 1));
}
/**
* @brief The function is used to read Rx data from RX FIFO.
* @param[in] sc The base address of smartcard module.
* @param[in] pu8RxBuf The buffer to store receive the data
* @param[in] u32ReadBytes Target number of characters to receive
* @return Actual character number reads to buffer
* @note This function does not block and return immediately if there's no data available
*/
uint32_t SCUART_Read(SC_T* sc, uint8_t *pu8RxBuf, uint32_t u32ReadBytes)
{
uint32_t u32Count;
for(u32Count = 0; u32Count < u32ReadBytes; u32Count++) {
if(SCUART_GET_RX_EMPTY(sc)) { // no data available
break;
}
pu8RxBuf[u32Count] = SCUART_READ(sc); // get data from FIFO
}
return u32Count;
}
/**
* @brief This function use to config smartcard UART mode line setting.
* @param[in] sc The base address of smartcard module.
* @param[in] u32Baudrate Target baudrate of smartcard module. If this value is 0, UART baudrate will not change.
* @param[in] u32DataWidth The data length, could be
* - \ref SCUART_CHAR_LEN_5
* - \ref SCUART_CHAR_LEN_6
* - \ref SCUART_CHAR_LEN_7
* - \ref SCUART_CHAR_LEN_8
* @param[in] u32Parity The parity setting, could be
* - \ref SCUART_PARITY_NONE
* - \ref SCUART_PARITY_ODD
* - \ref SCUART_PARITY_EVEN
* @param[in] u32StopBits The stop bit length, could be
* - \ref SCUART_STOP_BIT_1
* - \ref SCUART_STOP_BIT_2
* @return Actual baudrate of smartcard
*/
uint32_t SCUART_SetLineConfig(SC_T* sc, uint32_t u32Baudrate, uint32_t u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits)
{
uint32_t u32Clk = SCUART_GetClock(sc), u32Div;
if(u32Baudrate == 0) { // keep original baudrate setting
u32Div = sc->ETUCR & SC_ETUCR_ETU_RDIV_Msk;
} else {
// Calculate divider for target baudrate
u32Div = (u32Clk + (u32Baudrate >> 1) - 1)/ u32Baudrate - 1;
sc->ETUCR = u32Div;
}
sc->CTL = u32StopBits | SC_CTL_SC_CEN_Msk; // Set stop bit
sc->UACTL = u32Parity | u32DataWidth | SC_UACTL_UA_MODE_EN_Msk; // Set character width and parity
return(u32Clk / (u32Div + 1));
}
/**
* @brief This function use to set receive timeout count.
* @param[in] sc The base address of smartcard module.
* @param[in] u32TOC Rx timeout counter, using baudrate as counter unit. Valid range are 0~0x1FF,
* set this value to 0 will disable timeout counter
* @return None
* @details The time-out counter resets and starts counting whenever the RX buffer received a
* new data word. Once the counter decrease to 1 and no new data is received or CPU
* does not read any data from FIFO, a receiver time-out interrupt will be generated.
*/
void SCUART_SetTimeoutCnt(SC_T* sc, uint32_t u32TOC)
{
sc->RFTMR = u32TOC;
}
/**
* @brief This function is to write data into transmit FIFO to send data out.
* @param[in] sc The base address of smartcard module.
* @param[in] pu8TxBuf The buffer containing data to send to transmit FIFO.
* @param[in] u32WriteBytes Number of data to send.
* @return None
* @note This function blocks until all data write into FIFO
*/
void SCUART_Write(SC_T* sc,uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
{
uint32_t u32Count;
for(u32Count = 0; u32Count != u32WriteBytes; u32Count++) {
while(SCUART_GET_TX_FULL(sc)); // Wait 'til FIFO not full
sc->THR = pu8TxBuf[u32Count]; // Write 1 byte to FIFO
}
}
/*@}*/ /* end of group NANO100_SCUART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_SCUART_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,260 @@
/**************************************************************************//**
* @file sc.h
* @version V1.00
* $Revision: 3 $
* $Date: 14/05/20 7:57p $
* @brief Nano100 series Smartcard UART mode (SCUART) driver header file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __SCUART_H__
#define __SCUART_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_SCUART_Driver SCUART Driver
@{
*/
/** @addtogroup NANO100_SCUART_EXPORTED_CONSTANTS SCUART Exported Constants
@{
*/
#define SCUART_CHAR_LEN_5 (0x3ul << SC_UACTL_DATA_LEN_Pos) /*!< Set SCUART word length to 5 bits */
#define SCUART_CHAR_LEN_6 (0x2ul << SC_UACTL_DATA_LEN_Pos) /*!< Set SCUART word length to 6 bits */
#define SCUART_CHAR_LEN_7 (0x1ul << SC_UACTL_DATA_LEN_Pos) /*!< Set SCUART word length to 7 bits */
#define SCUART_CHAR_LEN_8 (0) /*!< Set SCUART word length to 8 bits */
#define SCUART_PARITY_NONE (SC_UACTL_PBDIS_Msk) /*!< Set SCUART transfer with no parity */
#define SCUART_PARITY_ODD (SC_UACTL_OPE_Msk) /*!< Set SCUART transfer with odd parity */
#define SCUART_PARITY_EVEN (0) /*!< Set SCUART transfer with even parity */
#define SCUART_STOP_BIT_1 (SC_CTL_SLEN_Msk) /*!< Set SCUART transfer with one stop bit */
#define SCUART_STOP_BIT_2 (0) /*!< Set SCUART transfer with two stop bits */
/*@}*/ /* end of group NANO100_SCUART_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_SCUART_EXPORTED_FUNCTIONS SCUART Exported Functions
@{
*/
/* TX Macros */
/**
* @brief Write Data to Tx data register
* @param[in] sc The base address of smartcard module.
* @param[in] u8Data Data byte to transmit
* @return None
* \hideinitializer
*/
#define SCUART_WRITE(sc, u8Data) ((sc)->THR = (u8Data))
/**
* @brief Get TX FIFO empty flag status from register
* @param[in] sc The base address of smartcard module
* @return Transmit FIFO empty status
* @retval 0 Transmit FIFO is not empty
* @retval SC_TRSR_TX_EMPTY_F_Msk Transmit FIFO is empty
* \hideinitializer
*/
#define SCUART_GET_TX_EMPTY(sc) ((sc)->TRSR & SC_TRSR_TX_EMPTY_F_Msk)
/**
* @brief Get TX FIFO full flag status from register
* @param[in] sc The base address of smartcard module
* @return Transmit FIFO full status
* @retval 0 Transmit FIFO is not full
* @retval SC_TRSR_TX_FULL_F_Msk Transmit FIFO is full
* \hideinitializer
*/
#define SCUART_GET_TX_FULL(sc) ((sc)->TRSR & SC_TRSR_TX_FULL_F_Msk)
/**
* @brief Wait specified smartcard port transmission complete
* @param[in] sc The base address of smartcard module
* @return None
* @note This Macro blocks until transmit complete.
* \hideinitializer
*/
#define SCUART_WAIT_TX_EMPTY(sc) while((sc)->TRSR & SC_TRSR_TX_ATV_Msk)
/**
* @brief Check specified smartcard port transmit FIFO is full or not
* @param[in] sc The base address of smartcard module
* @return Transmit FIFO full status
* @retval 0 Transmit FIFO is not full
* @retval 1 Transmit FIFO is full
* \hideinitializer
*/
#define SCUART_IS_TX_FULL(sc) ((sc)->TRSR & SC_TRSR_TX_FULL_F_Msk ? 1 : 0)
/**
* @brief Check specified smartcard port transmission is over
* @param[in] sc The base address of smartcard module
* @return Transmit complete status
* @retval 0 Transmit is not complete
* @retval 1 Transmit complete
* \hideinitializer
*/
#define SCUART_IS_TX_EMPTY(sc) ((sc)->TRSR & SC_TRSR_TX_ATV_Msk ? 0 : 1)
/* RX Macros */
/**
* @brief Read Rx data register
* @param[in] sc The base address of smartcard module
* @return The oldest data byte in RX FIFO
* \hideinitializer
*/
#define SCUART_READ(sc) ((sc)->RBR)
/**
* @brief Get RX FIFO empty flag status from register
* @param[in] sc The base address of smartcard module
* @return Receive FIFO empty status
* @retval 0 Receive FIFO is not empty
* @retval SC_TRSR_RX_EMPTY_F_Msk Receive FIFO is empty
* \hideinitializer
*/
#define SCUART_GET_RX_EMPTY(sc) ((sc)->TRSR & SC_TRSR_RX_EMPTY_F_Msk)
/**
* @brief Get RX FIFO full flag status from register
* @param[in] sc The base address of smartcard module
* @return Receive FIFO full status
* @retval 0 Receive FIFO is not full
* @retval SC_TRSR_TX_FULL_F_Msk Receive FIFO is full
* \hideinitializer
*/
#define SCUART_GET_RX_FULL(sc) ((sc)->TRSR & SC_TRSR_RX_FULL_F_Msk)
/**
* @brief Check if receive data number in FIFO reach FIFO trigger level or not
* @param[in] sc The base address of smartcard module
* @return Receive FIFO data status
* @retval 0 The number of bytes in receive FIFO is less than trigger level
* @retval 1 The number of bytes in receive FIFO equals or larger than trigger level
* @note If receive trigger level is \b not 1 byte, this macro return 0 does not necessary indicates there is no data in FIFO
* \hideinitializer
*/
#define SCUART_IS_RX_READY(sc) ((sc)->ISR & SC_ISR_RDA_IS_Msk ? 1 : 0)
/**
* @brief Check specified smartcard port receive FIFO is full or not
* @param[in] sc The base address of smartcard module
* @return Receive FIFO full status
* @retval 0 Receive FIFO is not full
* @retval 1 Receive FIFO is full
* \hideinitializer
*/
#define SCUART_IS_RX_FULL(sc) ((sc)->TRSR & SC_TRSR_RX_FULL_F_Msk ? 1 : 0)
/* Interrupt Macros */
/**
* @brief Enable specified interrupts
* @param[in] sc The base address of smartcard module
* @param[in] u32Mask Interrupt masks to enable, a combination of following bits
* - \ref SC_IER_RTMR_IE_Msk
* - \ref SC_IER_TERR_IE_Msk
* - \ref SC_IER_TBE_IE_Msk
* - \ref SC_IER_RDA_IE_Msk
* @return None
* \hideinitializer
*/
#define SCUART_ENABLE_INT(sc, u32Mask) ((sc)->IER |= (u32Mask))
/**
* @brief Disable specified interrupts
* @param[in] sc The base address of smartcard module
* @param[in] u32Mask Interrupt masks to disable, a combination of following bits
* - \ref SC_IER_RTMR_IE_Msk
* - \ref SC_IER_TERR_IE_Msk
* - \ref SC_IER_TBE_IE_Msk
* - \ref SC_IER_RDA_IE_Msk
* @return None
* \hideinitializer
*/
#define SCUART_DISABLE_INT(sc, u32Mask) ((sc)->IER &= ~(u32Mask))
/**
* @brief Get specified interrupt flag/status
* @param[in] sc The base address of smartcard module
* @param[in] u32Type Interrupt flag/status to check, could be one of following value
* - \ref SC_ISR_RTMR_IS_Msk
* - \ref SC_ISR_TERR_IS_Msk
* - \ref SC_ISR_TBE_IS_Msk
* - \ref SC_ISR_RDA_IS_Msk
* @return The status of specified interrupt
* @retval 0 Specified interrupt does not happened
* @retval 1 Specified interrupt happened
* \hideinitializer
*/
#define SCUART_GET_INT_FLAG(sc, u32Type) ((sc)->ISR & u32Type ? 1 : 0)
/**
* @brief Clear specified interrupt flag/status
* @param[in] sc The base address of smartcard module
* @param[in] u32Type Interrupt flag/status to clear, could be the combination of following values
* - \ref SC_ISR_RTMR_IS_Msk
* - \ref SC_ISR_TERR_IS_Msk
* - \ref SC_ISR_TBE_IS_Msk
* @return None
* \hideinitializer
*/
#define SCUART_CLR_INT_FLAG(sc, u32Type) ((sc)->ISR = u32Type)
/**
* @brief Get receive error flag/status
* @param[in] sc The base address of smartcard module
* @return Current receive error status, could one of following errors:
* @retval SC_TRSR_RX_EPA_F_Msk Parity error
* @retval SC_TRSR_RX_EFR_F_Msk Frame error
* @retval SC_TRSR_RX_EBR_F_Msk Break error
* \hideinitializer
*/
#define SCUART_GET_ERR_FLAG(sc) ((sc)->TRSR & (SC_TRSR_RX_EPA_F_Msk | SC_TRSR_RX_EFR_F_Msk | SC_TRSR_RX_EBR_F_Msk))
/**
* @brief Clear specified receive error flag/status
* @param[in] sc The base address of smartcard module
* @param[in] u32Mask Receive error flag/status to clear, combination following values
* - \ref SC_TRSR_RX_EPA_F_Msk
* - \ref SC_TRSR_RX_EFR_F_Msk
* - \ref SC_TRSR_RX_EBR_F_Msk
* @return None
* \hideinitializer
*/
#define SCUART_CLR_ERR_FLAG(sc, u32Mask) ((sc)->TRSR = u32Mask)
void SCUART_Close(SC_T* sc);
uint32_t SCUART_Open(SC_T* sc, uint32_t u32baudrate);
uint32_t SCUART_Read(SC_T* sc, uint8_t *pu8RxBuf, uint32_t u32ReadBytes);
uint32_t SCUART_SetLineConfig(SC_T* sc, uint32_t u32Baudrate, uint32_t u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits);
void SCUART_SetTimeoutCnt(SC_T* sc, uint32_t u32TOC);
void SCUART_Write(SC_T* sc,uint8_t *pu8TxBuf, uint32_t u32WriteBytes);
/*@}*/ /* end of group NANO100_SCUART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_SCUART_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__SCUART_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,321 @@
/****************************************************************************//**
* @file spi.c
* @version V0.10
* $Revision: 7 $
* $Date: 15/05/28 1:33p $
* @brief NANO100 series SPI driver source file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "nano100series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_SPI_Driver SPI Driver
@{
*/
/** @addtogroup NANO100_SPI_EXPORTED_FUNCTIONS SPI Exported Functions
@{
*/
/**
* @brief This function make SPI module be ready to transfer.
* By default, the SPI transfer sequence is MSB first and
* the automatic slave select function is disabled. In
* Slave mode, the u32BusClock must be NULL and the SPI clock
* divider setting will be 0.
* @param[in] spi is the base address of SPI module.
* @param[in] u32MasterSlave decides the SPI module is operating in master mode or in slave mode. Valid values are:
* - \ref SPI_MASTER
* - \ref SPI_SLAVE
* @param[in] u32SPIMode decides the transfer timing. Valid values are:
* - \ref SPI_MODE_0
* - \ref SPI_MODE_1
* - \ref SPI_MODE_2
* - \ref SPI_MODE_3
* @param[in] u32DataWidth decides the data width of a SPI transaction.
* @param[in] u32BusClock is the expected frequency of SPI bus clock in Hz.
* @return Actual frequency of SPI peripheral clock.
*/
uint32_t SPI_Open(SPI_T *spi,
uint32_t u32MasterSlave,
uint32_t u32SPIMode,
uint32_t u32DataWidth,
uint32_t u32BusClock)
{
if(u32DataWidth == 32)
u32DataWidth = 0;
spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_TX_BIT_LEN_Pos) | (u32SPIMode);
return ( SPI_SetBusClock(spi, u32BusClock) );
}
/**
* @brief Reset SPI module and disable SPI peripheral clock.
* @param[in] spi is the base address of SPI module.
* @return none
*/
void SPI_Close(SPI_T *spi)
{
/* Reset SPI */
if(spi == SPI0) {
SYS->IPRST_CTL2 |= SYS_IPRST_CTL2_SPI0_RST_Msk;
SYS->IPRST_CTL2 &= ~SYS_IPRST_CTL2_SPI0_RST_Msk;
} else if(spi == SPI1) {
SYS->IPRST_CTL2 |= SYS_IPRST_CTL2_SPI1_RST_Msk;
SYS->IPRST_CTL2 &= ~SYS_IPRST_CTL2_SPI1_RST_Msk;
} else {
SYS->IPRST_CTL2 |= SYS_IPRST_CTL2_SPI2_RST_Msk;
SYS->IPRST_CTL2 &= ~SYS_IPRST_CTL2_SPI2_RST_Msk;
}
}
/**
* @brief Clear Rx FIFO buffer.
* @param[in] spi is the base address of SPI module.
* @return none
*/
void SPI_ClearRxFIFO(SPI_T *spi)
{
spi->FFCTL |= SPI_FFCTL_RX_CLR_Msk;
}
/**
* @brief Clear Tx FIFO buffer.
* @param[in] spi is the base address of SPI module.
* @return none
*/
void SPI_ClearTxFIFO(SPI_T *spi)
{
spi->FFCTL |= SPI_FFCTL_TX_CLR_Msk;
}
/**
* @brief Disable the automatic slave select function.
* @param[in] spi is the base address of SPI module.
* @return none
*/
void SPI_DisableAutoSS(SPI_T *spi)
{
spi->SSR &= ~SPI_SSR_AUTOSS_Msk;
}
/**
* @brief Enable the automatic slave select function. Only available in Master mode.
* @param[in] spi is the base address of SPI module.
* @param[in] u32SSPinMask specifies slave select pins. (SPI_SS)
* @param[in] u32ActiveLevel specifies the active level of slave select signal. Valid values are:
* - \ref SPI_SS0_ACTIVE_HIGH
* - \ref SPI_SS0_ACTIVE_LOW
* - \ref SPI_SS1_ACTIVE_HIGH
* - \ref SPI_SS1_ACTIVE_LOW
* @return none
*/
void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
{
spi->SSR = (spi->SSR & ~(SPI_SSR_SS_LVL_Msk | SPI_SSR_SSR_Msk)) | (u32SSPinMask | u32ActiveLevel) | SPI_SSR_AUTOSS_Msk;
}
/**
* @brief Set the SPI bus clock. Only available in Master mode.
* @param[in] spi is the base address of SPI module.
* @param[in] u32BusClock is the expected frequency of SPI bus clock.
* @return Actual frequency of SPI peripheral clock.
*/
uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock)
{
uint32_t u32ClkSrc, u32Div = 0;
if(spi == SPI0) {
if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0_S_Msk) == CLK_CLKSEL2_SPI0_S_HCLK)
u32ClkSrc = CLK_GetHCLKFreq();
else
u32ClkSrc = CLK_GetPLLClockFreq();
} else if(spi == SPI1) {
if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1_S_Msk) == CLK_CLKSEL2_SPI1_S_HCLK)
u32ClkSrc = CLK_GetHCLKFreq();
else
u32ClkSrc = CLK_GetPLLClockFreq();
} else {
if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2_S_Msk) == CLK_CLKSEL2_SPI2_S_HCLK)
u32ClkSrc = CLK_GetHCLKFreq();
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
if(u32BusClock > u32ClkSrc)
u32BusClock = u32ClkSrc;
if(u32BusClock != 0 ) {
u32Div = (u32ClkSrc / u32BusClock) - 1;
if(u32Div > SPI_CLKDIV_DIVIDER1_Msk)
u32Div = SPI_CLKDIV_DIVIDER1_Msk;
} else
u32Div = 0;
spi->CLKDIV = (spi->CLKDIV & ~SPI_CLKDIV_DIVIDER1_Msk) | u32Div;
return ( u32ClkSrc / (u32Div+1) );
}
/**
* @brief Enable FIFO mode with user-specified Tx FIFO threshold and Rx FIFO threshold configurations.
* @param[in] spi is the base address of SPI module.
* @param[in] u32TxThreshold decides the Tx FIFO threshold.
* @param[in] u32RxThreshold decides the Rx FIFO threshold.
* @return none
*/
void SPI_EnableFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
{
spi->FFCTL = (spi->FFCTL & ~(SPI_FFCTL_TX_THRESHOLD_Msk | SPI_FFCTL_RX_THRESHOLD_Msk) |
(u32TxThreshold << SPI_FFCTL_TX_THRESHOLD_Pos) |
(u32RxThreshold << SPI_FFCTL_RX_THRESHOLD_Pos));
spi->CTL |= SPI_CTL_FIFOM_Msk;
}
/**
* @brief Disable FIFO mode.
* @param[in] spi is the base address of SPI module.
* @return none
*/
void SPI_DisableFIFO(SPI_T *spi)
{
spi->CTL &= ~SPI_CTL_FIFOM_Msk;
}
/**
* @brief Get the actual frequency of SPI bus clock. Only available in Master mode.
* @param[in] spi is the base address of SPI module.
* @return Actual SPI bus clock frequency.
*/
uint32_t SPI_GetBusClock(SPI_T *spi)
{
uint32_t u32Div;
uint32_t u32ClkSrc;
if(spi == SPI0) {
if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0_S_Msk) == CLK_CLKSEL2_SPI0_S_HCLK)
u32ClkSrc = CLK_GetHCLKFreq();
else
u32ClkSrc = CLK_GetPLLClockFreq();
} else if(spi == SPI1) {
if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1_S_Msk) == CLK_CLKSEL2_SPI1_S_HCLK)
u32ClkSrc = CLK_GetHCLKFreq();
else
u32ClkSrc = CLK_GetPLLClockFreq();
} else {
if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2_S_Msk) == CLK_CLKSEL2_SPI2_S_HCLK)
u32ClkSrc = CLK_GetHCLKFreq();
else
u32ClkSrc = CLK_GetPLLClockFreq();
}
u32Div = spi->CLKDIV & SPI_CLKDIV_DIVIDER1_Msk;
return (u32ClkSrc / (u32Div + 1));
}
/**
* @brief Enable FIFO related interrupts specified by u32Mask parameter.
* @param[in] spi is the base address of SPI module.
* @param[in] u32Mask is the combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt bit.
* This parameter decides which interrupts will be enabled. Valid values are:
* - \ref SPI_IE_MASK
* - \ref SPI_SSTA_INTEN_MASK
* - \ref SPI_FIFO_TX_INTEN_MASK
* - \ref SPI_FIFO_RX_INTEN_MASK
* - \ref SPI_FIFO_RXOVR_INTEN_MASK
* - \ref SPI_FIFO_TIMEOUT_INTEN_MASK
* @return none
*/
void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask)
{
if((u32Mask & SPI_IE_MASK) == SPI_IE_MASK)
spi->CTL |= SPI_CTL_INTEN_Msk;
if((u32Mask & SPI_SSTA_INTEN_MASK) == SPI_SSTA_INTEN_MASK)
spi->SSR |= SPI_SSR_SSTA_INTEN_Msk;
if((u32Mask & SPI_FIFO_TX_INTEN_MASK) == SPI_FIFO_TX_INTEN_MASK)
spi->FFCTL |= SPI_FFCTL_TX_INTEN_Msk;
if((u32Mask & SPI_FIFO_RX_INTEN_MASK) == SPI_FIFO_RX_INTEN_MASK)
spi->FFCTL |= SPI_FFCTL_RX_INTEN_Msk;
if((u32Mask & SPI_FIFO_RXOVR_INTEN_MASK) == SPI_FIFO_RXOVR_INTEN_MASK)
spi->FFCTL |= SPI_FFCTL_RXOVR_INTEN_Msk;
if((u32Mask & SPI_FIFO_TIMEOUT_INTEN_MASK) == SPI_FIFO_TIMEOUT_INTEN_MASK)
spi->FFCTL |= SPI_FFCTL_TIMEOUT_EN_Msk;
}
/**
* @brief Disable FIFO related interrupts specified by u32Mask parameter.
* @param[in] spi is the base address of SPI module.
* @param[in] u32Mask is the combination of all related interrupt enable bits.
* Each bit corresponds to a interrupt bit.
* This parameter decides which interrupts will be enabled. Valid values are:
* - \ref SPI_IE_MASK
* - \ref SPI_SSTA_INTEN_MASK
* - \ref SPI_FIFO_TX_INTEN_MASK
* - \ref SPI_FIFO_RX_INTEN_MASK
* - \ref SPI_FIFO_RXOVR_INTEN_MASK
* - \ref SPI_FIFO_TIMEOUT_INTEN_MASK
* @return none
*/
void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask)
{
if((u32Mask & SPI_IE_MASK) == SPI_IE_MASK)
spi->CTL &= ~SPI_CTL_INTEN_Msk;
if((u32Mask & SPI_SSTA_INTEN_MASK) == SPI_SSTA_INTEN_MASK)
spi->SSR &= ~SPI_SSR_SSTA_INTEN_Msk;
if((u32Mask & SPI_FIFO_TX_INTEN_MASK) == SPI_FIFO_TX_INTEN_MASK)
spi->FFCTL &= ~SPI_FFCTL_TX_INTEN_Msk;
if((u32Mask & SPI_FIFO_RX_INTEN_MASK) == SPI_FIFO_RX_INTEN_MASK)
spi->FFCTL &= ~SPI_FFCTL_RX_INTEN_Msk;
if((u32Mask & SPI_FIFO_RXOVR_INTEN_MASK) == SPI_FIFO_RXOVR_INTEN_MASK)
spi->FFCTL &= ~SPI_FFCTL_RXOVR_INTEN_Msk;
if((u32Mask & SPI_FIFO_TIMEOUT_INTEN_MASK) == SPI_FIFO_TIMEOUT_INTEN_MASK)
spi->FFCTL &= ~SPI_FFCTL_TIMEOUT_EN_Msk;
}
/**
* @brief Enable wake-up function.
* @param[in] spi is the base address of SPI module.
* @return none
*/
void SPI_EnableWakeup(SPI_T *spi)
{
spi->CTL |= SPI_CTL_WKEUP_EN_Msk;
}
/**
* @brief Disable wake-up function.
* @param[in] spi is the base address of SPI module.
* @return none
*/
void SPI_DisableWakeup(SPI_T *spi)
{
spi->CTL &= ~SPI_CTL_WKEUP_EN_Msk;
}
/*@}*/ /* end of group NANO100_SPI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_SPI_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,386 @@
/****************************************************************************//**
* @file spi.h
* @version V1.00
* $Revision: 8 $
* $Date: 15/06/08 5:03p $
* @brief NANO100 series SPI driver header file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __SPI_H__
#define __SPI_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_SPI_Driver SPI Driver
@{
*/
/** @addtogroup NANO100_SPI_EXPORTED_CONSTANTS SPI Exported Constants
@{
*/
#define SPI_MODE_0 (SPI_CTL_TX_NEG_Msk) /*!< CLKP=0; RX_NEG=0; TX_NEG=1 */
#define SPI_MODE_1 (SPI_CTL_RX_NEG_Msk) /*!< CLKP=0; RX_NEG=1; TX_NEG=0 */
#define SPI_MODE_2 (SPI_CTL_CLKP_Msk | SPI_CTL_RX_NEG_Msk) /*!< CLKP=1; RX_NEG=1; TX_NEG=0 */
#define SPI_MODE_3 (SPI_CTL_CLKP_Msk | SPI_CTL_TX_NEG_Msk) /*!< CLKP=1; RX_NEG=0; TX_NEG=1 */
#define SPI_SLAVE (SPI_CTL_SLAVE_Msk) /*!< Set as slave */
#define SPI_MASTER (0x0) /*!< Set as master */
#define SPI_SS0 (0x1) /*!< Set SS0 */
#define SPI_SS0_ACTIVE_HIGH (SPI_SSR_SS_LVL_Msk) /*!< SS0 active high */
#define SPI_SS0_ACTIVE_LOW (0x0) /*!< SS0 active low */
#define SPI_SS1 (0x2) /*!< Set SS1 */
#define SPI_SS1_ACTIVE_HIGH (SPI_SSR_SS_LVL_Msk) /*!< SS1 active high */
#define SPI_SS1_ACTIVE_LOW (0x0) /*!< SS1 active low */
#define SPI_IE_MASK (0x01) /*!< Interrupt enable mask */
#define SPI_SSTA_INTEN_MASK (0x04) /*!< Slave 3-Wire mode start interrupt enable mask */
#define SPI_FIFO_TX_INTEN_MASK (0x08) /*!< FIFO TX interrupt mask */
#define SPI_FIFO_RX_INTEN_MASK (0x10) /*!< FIFO RX interrupt mask */
#define SPI_FIFO_RXOVR_INTEN_MASK (0x20) /*!< FIFO RX overrun interrupt mask */
#define SPI_FIFO_TIMEOUT_INTEN_MASK (0x40) /*!< FIFO timeout interrupt mask */
/*@}*/ /* end of group NANO100_SPI_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_SPI_EXPORTED_FUNCTIONS SPI Exported Functions
@{
*/
/**
* @brief Abort the current transfer in slave 3-wire mode.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_ABORT_3WIRE_TRANSFER(spi) ( (spi)->SSR |= SPI_SSR_SLV_ABORT_Msk )
/**
* @brief Clear the slave 3-wire mode start interrupt flag.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#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 is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_CLR_UNIT_TRANS_INT_FLAG(spi) ( (spi)->STATUS = SPI_STATUS_INTSTS_Msk )
/**
* @brief Disable slave 3-wire mode.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_DISABLE_3WIRE_MODE(spi) ( (spi)->SSR &= ~SPI_SSR_NOSLVSEL_Msk )
/**
* @brief Enable slave 3-wire mode.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_ENABLE_3WIRE_MODE(spi) ( (spi)->SSR |= SPI_SSR_NOSLVSEL_Msk )
/**
* @brief Get the count of available data in RX FIFO.
* @param[in] spi is the base address of SPI module.
* @return The count of available data in RX FIFO.
* \hideinitializer
*/
#define SPI_GET_RX_FIFO_COUNT(spi) ( (((spi)->STATUS & SPI_STATUS_RX_FIFO_CNT_Msk) >> SPI_STATUS_RX_FIFO_CNT_Pos) & 0xf )
/**
* @brief Get the Rx FIFO empty flag.
* @param[in] spi is the base address of SPI module.
* @return Rx FIFO flag
* @retval 0 Rx FIFO is not empty
* @retval 1 Rx FIFO is empty
* \hideinitializer
*/
#define SPI_GET_RX_FIFO_EMPTY_FLAG(spi) ( ((spi)->STATUS & SPI_STATUS_RX_EMPTY_Msk) == SPI_STATUS_RX_EMPTY_Msk ? 1:0)
/**
* @brief Get the Tx FIFO empty flag.
* @param[in] spi is the base address of SPI module.
* @return Tx FIFO flag
* @retval 0 Tx FIFO is not empty
* @retval 1 Tx FIFO is empty
* \hideinitializer
*/
#define SPI_GET_TX_FIFO_EMPTY_FLAG(spi) ( ((spi)->STATUS & SPI_STATUS_TX_EMPTY_Msk) == SPI_STATUS_TX_EMPTY_Msk ? 1:0)
/**
* @brief Get the Tx FIFO full flag.
* @param[in] spi is the base address of SPI module.
* @return Tx FIFO flag
* @retval 0 Tx FIFO is not full
* @retval 1 Tx FIFO is full
* \hideinitializer
*/
#define SPI_GET_TX_FIFO_FULL_FLAG(spi) ( ((spi)->STATUS & SPI_STATUS_TX_FULL_Msk) == SPI_STATUS_TX_FULL_Msk ? 1:0)
/**
* @brief Get the datum read from RX0 FIFO.
* @param[in] spi is the base address of SPI module.
* @return Data in Rx0 register.
* \hideinitializer
*/
#define SPI_READ_RX0(spi) ( (spi)->RX0 )
/**
* @brief Get the datum read from RX1 FIFO.
* @param[in] spi is the base address of SPI module.
* @return Data in Rx1 register.
*/
#define SPI_READ_RX1(spi) ( (spi)->RX1 )
/**
* @brief Write datum to TX0 register.
* @param[in] spi is the base address of SPI module.
* @param[in] u32TxData is the datum which user attempt to transfer through SPI bus.
* @return none
* \hideinitializer
*/
#define SPI_WRITE_TX0(spi, u32TxData) ( (spi)->TX0 = u32TxData )
/**
* @brief Write datum to TX1 register.
* @param[in] spi is the base address of SPI module.
* @param[in] u32TxData is the datum which user attempt to transfer through SPI bus.
* @return none
* \hideinitializer
*/
#define SPI_WRITE_TX1(spi, u32TxData) ( (spi)->TX1 = u32TxData )
/**
* @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.
* \hideinitializer
*/
#define SPI_SET_SS0_HIGH(spi) ((spi)->SSR = ((spi)->SSR & ~(SPI_SSR_AUTOSS_Msk|SPI_SSR_SS_LVL_Msk|SPI_SS0)))
/**
* @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.
* \hideinitializer
*/
#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 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.
* \hideinitializer
*/
#define SPI_SET_SS1_HIGH(spi) ((spi)->SSR = ((spi)->SSR & ~(SPI_SSR_AUTOSS_Msk|SPI_SSR_SS_LVL_Msk|SPI_SS1)))
/**
* @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.
* \hideinitializer
*/
#define SPI_SET_SS1_LOW(spi) ((spi)->SSR = ((spi)->SSR & ~(SPI_SSR_AUTOSS_Msk|SPI_SSR_SS_LVL_Msk|SPI_SS1)) | SPI_SS1)
/**
* @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 Enable byte reorder function.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_ENABLE_BYTE_REORDER(spi) ( (spi)->CTL |= SPI_CTL_REORDER_Msk )
/**
* @brief Disable byte reorder function.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_DISABLE_BYTE_REORDER(spi) ( (spi)->CTL &= ~SPI_CTL_REORDER_Msk )
/**
* @brief Set the length of suspend interval.
* @param[in] spi is the base address of SPI module.
* @param[in] u32SuspCycle decides the length of suspend interval.
* @return none
* \hideinitializer
*/
#define SPI_SET_SUSPEND_CYCLE(spi, u32SuspCycle) ( (spi)->CTL = ((spi)->CTL & ~SPI_CTL_SP_CYCLE_Msk) | (u32SuspCycle << SPI_CTL_SP_CYCLE_Pos) )
/**
* @brief Set the SPI transfer sequence with LSB first.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_SET_LSB_FIRST(spi) ( (spi)->CTL |= SPI_CTL_LSB_Msk )
/**
* @brief Set the SPI transfer sequence with MSB first.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_SET_MSB_FIRST(spi) ( (spi)->CTL &= ~SPI_CTL_LSB_Msk )
/**
* @brief Set the data width of a SPI transaction.
* @param[in] spi is the base address of SPI module.
* @param[in] u32Width is the data width (from 8-32 bits).
* @return none
* \hideinitializer
*/
static __INLINE void SPI_SET_DATA_WIDTH(SPI_T *spi, uint32_t u32Width)
{
if(u32Width == 32)
u32Width = 0;
spi->CTL = (spi->CTL & ~SPI_CTL_TX_BIT_LEN_Msk) | (u32Width << SPI_CTL_TX_BIT_LEN_Pos);
}
/**
* @brief Get the SPI busy state.
* @param[in] spi is the base address of SPI module.
* @return SPI busy status
* @retval 0 SPI module is not busy
* @retval 1 SPI module is busy
* \hideinitializer
*/
#define SPI_IS_BUSY(spi) ( ((spi)->CTL & SPI_CTL_GO_BUSY_Msk) == SPI_CTL_GO_BUSY_Msk ? 1:0)
/**
* @brief Set the GO_BUSY bit to trigger SPI transfer.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_TRIGGER(spi) ( (spi)->CTL |= SPI_CTL_GO_BUSY_Msk )
/**
* @brief Disable SPI Dual IO function.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_DISABLE_DUAL_MODE(spi) ( (spi)->CTL &= ~SPI_CTL_DUAL_IO_EN_Msk )
/**
* @brief Enable Dual IO function and set SPI Dual IO direction to input.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_ENABLE_DUAL_INPUT_MODE(spi) ( (spi)->CTL = ((spi)->CTL & ~SPI_CTL_DUAL_IO_DIR_Msk) | SPI_CTL_DUAL_IO_EN_Msk )
/**
* @brief Enable Dual IO function and set SPI Dual IO direction to output.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_ENABLE_DUAL_OUTPUT_MODE(spi) ( (spi)->CTL |= (SPI_CTL_DUAL_IO_DIR_Msk | SPI_CTL_DUAL_IO_EN_Msk) )
/**
* @brief Trigger RX PDMA transfer.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_TRIGGER_RX_PDMA(spi) ( (spi)->DMA |= SPI_DMA_RX_DMA_EN_Msk )
/**
* @brief Trigger TX PDMA transfer.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_TRIGGER_TX_PDMA(spi) ( (spi)->DMA |= SPI_DMA_TX_DMA_EN_Msk )
/**
* @brief Enable 2-bit transfer mode.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_ENABLE_2BIT_MODE(spi) ( (spi)->CTL |= SPI_CTL_TWOB_Msk )
/**
* @brief Disable 2-bit transfer mode.
* @param[in] spi is the base address of SPI module.
* @return none
* \hideinitializer
*/
#define SPI_DISABLE_2BIT_MODE(spi) ( (spi)->CTL &= ~SPI_CTL_TWOB_Msk )
/**
* @brief Get the status register value.
* @param[in] spi is the base address of SPI module.
* @return status value.
* \hideinitializer
*/
#define SPI_GET_STATUS(spi) ( (spi)->STATUS )
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);
void SPI_EnableWakeup(SPI_T *spi);
void SPI_DisableWakeup(SPI_T *spi);
/*@}*/ /* end of group NANO100_SPI_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_SPI_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__SPI_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,198 @@
/**************************************************************************//**
* @file sys.c
* @version V1.00
* $Revision: 8 $
* $Date: 15/06/17 4:49p $
* @brief NANO100 series SYS driver source file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_SYS_Driver SYS Driver
@{
*/
/** @addtogroup NANO100_SYS_EXPORTED_FUNCTIONS SYS Exported Functions
@{
*/
/**
* @brief This function clear the selected system reset source
* @param[in] u32Src is system reset source
* @return None
*/
void SYS_ClearResetSrc(uint32_t u32Src)
{
SYS->RST_SRC |= u32Src;
}
/**
* @brief This function get Brown-out detector output status
* @param None
* @return 0: System voltage is higher than BOD_VL setting or BOD_EN is 0.
* 1: System voltage is lower than BOD_VL setting.
* Note : If the BOD_EN is 0, this function always return 0.
*/
uint32_t SYS_GetBODStatus()
{
return (SYS->BODSTS);
}
/**
* @brief This function get the system reset source register value
* @param None
* @return Reset source
*/
uint32_t SYS_GetResetSrc(void)
{
return (SYS->RST_SRC);
}
/**
* @brief This function check register write-protection bit setting
* @param None
* @return 0: Write-protection function is disabled.
* 1: Write-protection function is enabled.
*/
uint32_t SYS_IsRegLocked(void)
{
return !(SYS->RegLockAddr & SYS_RegLockAddr_RegUnLock_Msk);
}
/**
* @brief This function get product ID.
* @param None
* @return Product ID
*/
uint32_t SYS_ReadPDID(void)
{
return SYS->PDID;
}
/**
* @brief This function reset chip.
* @param None
* @return None
*/
void SYS_ResetChip(void)
{
SYS->IPRST_CTL1 |= SYS_IPRST_CTL1_CHIP_RST_Msk;
}
/**
* @brief This function reset CPU.
* @param None
* @return None
*/
void SYS_ResetCPU(void)
{
SYS->IPRST_CTL1 |= SYS_IPRST_CTL1_CPU_RST_Msk;
}
/**
* @brief This function reset selected modules.
* @param[in] u32ModuleIndex is module index. Including :
* - \ref CHIP_RST
* - \ref CPU_RST
* - \ref DMA_RST
* - \ref EBI_RST
* - \ref SC1_RST
* - \ref SC0_RST
* - \ref I2S_RST
* - \ref ADC_RST
* - \ref USBD_RST
* - \ref DAC_RST
* - \ref PWM1_RST
* - \ref PWM0_RST
* - \ref UART1_RST
* - \ref UART0_RST
* - \ref SPI2_RST
* - \ref SPI1_RST
* - \ref SPI0_RST
* - \ref I2C1_RST
* - \ref I2C0_RST
* - \ref TMR3_RST
* - \ref TMR2_RST
* - \ref TMR1_RST
* - \ref TMR0_RST
* - \ref GPIO_RST
* @return None
*/
void SYS_ResetModule(uint32_t u32ModuleIndex)
{
*(volatile uint32_t *)((uint32_t)&(SYS->IPRST_CTL1) + (u32ModuleIndex>>24)) |= 1<<(u32ModuleIndex & 0x00ffffff);
*(volatile uint32_t *)((uint32_t)&(SYS->IPRST_CTL1) + (u32ModuleIndex>>24)) &= ~(1<<(u32ModuleIndex & 0x00ffffff));
}
/**
* @brief This function configure BOD function.
* Configure BOD reset or interrupt mode and set Brown-out voltage level.
* Enable Brown-out function
* @param[in] i32Mode is reset or interrupt mode. Including :
* - \ref SYS_BODCTL_BOD25_RST_EN_Msk or \ref SYS_BODCTL_BOD25_INT_EN_Msk
* - \ref SYS_BODCTL_BOD20_RST_EN_Msk or \ref SYS_BODCTL_BOD20_INT_EN_Msk
* - \ref SYS_BODCTL_BOD17_RST_EN_Msk or \ref SYS_BODCTL_BOD17_INT_EN_Msk
* @param[in] u32BODLevel is Brown-out voltage level. Including :
* - \ref SYS_BODCTL_BOD25_EN_Msk
* - \ref SYS_BODCTL_BOD20_EN_Msk
* - \ref SYS_BODCTL_BOD17_EN_Msk
*
* @return None
*/
void SYS_EnableBOD(int32_t i32Mode, uint32_t u32BODLevel)
{
SYS->BODCTL = (SYS->BODCTL & ~0xFFF) | (i32Mode | u32BODLevel);
}
/**
* @brief This function disable BOD function.
* @param None
* @return None
*/
void SYS_DisableBOD(void)
{
SYS->BODCTL = SYS->BODCTL & ~(SYS_BODCTL_BOD25_EN_Msk | SYS_BODCTL_BOD20_EN_Msk | SYS_BODCTL_BOD17_EN_Msk);
}
/**
* @brief This function enable HIRC trim function.
* @param[in] u32TrimSel is trim frequency selection. Including :
* - \ref SYS_IRCTRIMCTL_TRIM_11_0592M
* - \ref SYS_IRCTRIMCTL_TRIM_12M
* - \ref SYS_IRCTRIMCTL_TRIM_12_288M
* @param[in] u32TrimEnInt is HIRC trim interrupt selection. Including :
* - \ref SYS_IRCTRIMIEN_FAIL_EN
* - \ref SYS_IRCTRIMIEN_32KERR_EN
* - \ref SYS_IRCTRIMIEN_DISABLE
* @return None
*/
void SYS_EnableIRCTrim(uint32_t u32TrimSel,uint32_t u32TrimEnInt)
{
SYS->IRCTRIMIEN = (SYS->IRCTRIMIEN & ~(SYS_IRCTRIMIEN_TRIM_FAIL_IEN_Msk|SYS_IRCTRIMIEN_32K_ERR_IEN_Msk)) | u32TrimEnInt;
SYS->IRCTRIMCTL = (SYS->IRCTRIMCTL & ~SYS_IRCTRIMCTL_TRIM_SEL_Msk)|u32TrimSel;
}
/**
* @brief This function disable HIRC trim function.
* @param None
* @return None
*/
void SYS_DisableIRCTrim(void)
{
SYS->IRCTRIMCTL = 0;
}
/*@}*/ /* end of group NANO100_SYS_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_SYS_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,872 @@
/**************************************************************************//**
* @file sys.h
* @version V1.00
* $Revision: 17 $
* $Date: 15/06/24 1:11p $
* @brief Nano100 Series system control header file.
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __SYS_H__
#define __SYS_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_SYS_Driver SYS Driver
@{
*/
/** @addtogroup NANO100_SYS_EXPORTED_CONSTANTS SYS Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* Module Reset Control Resister constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
#define CHIP_RST ((0x0<<24) | SYS_IPRST_CTL1_CPU_RST_Pos ) /*!< CPU reset is one of the SYS_ResetModule parameter */
#define CPU_RST ((0x0<<24) | SYS_IPRST_CTL1_CHIP_RST_Pos ) /*!< CHIP reset is one of the SYS_ResetModule parameter */
#define DMA_RST ((0x0<<24) | SYS_IPRST_CTL1_DMA_RST_Pos ) /*!< DMA reset is one of the SYS_ResetModule parameter */
#define EBI_RST ((0x0<<24) | SYS_IPRST_CTL1_EBI_RST_Pos ) /*!< EBI reset is one of the SYS_ResetModule parameter */
#define SC1_RST ((0x4<<24) | SYS_IPRST_CTL2_SC1_RST_Pos ) /*!< SmartCard1 reset is one of the SYS_ResetModule parameter */
#define SC0_RST ((0x4<<24) | SYS_IPRST_CTL2_SC0_RST_Pos ) /*!< SmartCard0 reset is one of the SYS_ResetModule parameter */
#define I2S_RST ((0x4<<24) | SYS_IPRST_CTL2_I2S_RST_Pos ) /*!< I2S reset is one of the SYS_ResetModule parameter */
#define ADC_RST ((0x4<<24) | SYS_IPRST_CTL2_ADC_RST_Pos ) /*!< ADC reset is one of the SYS_ResetModule parameter */
#define USBD_RST ((0x4<<24) | SYS_IPRST_CTL2_USBD_RST_Pos ) /*!< USBD reset is one of the SYS_ResetModule parameter */
#define DAC_RST ((0x4<<24) | SYS_IPRST_CTL2_DAC_RST_Pos ) /*!< DAC reset is one of the SYS_ResetModule parameter */
#define PWM1_RST ((0x4<<24) | SYS_IPRST_CTL2_PWM1_RST_Pos ) /*!< PWM1 reset is one of the SYS_ResetModule parameter */
#define PWM0_RST ((0x4<<24) | SYS_IPRST_CTL2_PWM0_RST_Pos ) /*!< PWM0 reset is one of the SYS_ResetModule parameter */
#define UART1_RST ((0x4<<24) | SYS_IPRST_CTL2_UART1_RST_Pos ) /*!< UART1 reset is one of the SYS_ResetModule parameter */
#define UART0_RST ((0x4<<24) | SYS_IPRST_CTL2_UART0_RST_Pos ) /*!< UART0 reset is one of the SYS_ResetModule parameter */
#define SPI2_RST ((0x4<<24) | SYS_IPRST_CTL2_SPI2_RST_Pos ) /*!< SPI2 reset is one of the SYS_ResetModule parameter */
#define SPI1_RST ((0x4<<24) | SYS_IPRST_CTL2_SPI1_RST_Pos ) /*!< SPI1 reset is one of the SYS_ResetModule parameter */
#define SPI0_RST ((0x4<<24) | SYS_IPRST_CTL2_SPI0_RST_Pos ) /*!< SPI0 reset is one of the SYS_ResetModule parameter */
#define I2C1_RST ((0x4<<24) | SYS_IPRST_CTL2_I2C1_RST_Pos ) /*!< I2C1 reset is one of the SYS_ResetModule parameter */
#define I2C0_RST ((0x4<<24) | SYS_IPRST_CTL2_I2C0_RST_Pos ) /*!< I2C0 reset is one of the SYS_ResetModule parameter */
#define TMR3_RST ((0x4<<24) | SYS_IPRST_CTL2_TMR3_RST_Pos ) /*!< Timer3 reset is one of the SYS_ResetModule parameter */
#define TMR2_RST ((0x4<<24) | SYS_IPRST_CTL2_TMR2_RST_Pos ) /*!< Timer2 reset is one of the SYS_ResetModule parameter */
#define TMR1_RST ((0x4<<24) | SYS_IPRST_CTL2_TMR1_RST_Pos ) /*!< Timer1 reset is one of the SYS_ResetModule parameter */
#define TMR0_RST ((0x4<<24) | SYS_IPRST_CTL2_TMR0_RST_Pos ) /*!< Timer0 reset is one of the SYS_ResetModule parameter */
#define GPIO_RST ((0x4<<24) | SYS_IPRST_CTL2_GPIO_RST_Pos ) /*!< GPIO reset is one of the SYS_ResetModule parameter */
/*---------------------------------------------------------------------------------------------------------*/
/* Multi-Function constant definitions. */
/*---------------------------------------------------------------------------------------------------------*/
/********************* Bit definition of VREFCTL register **********************/
#define SYS_VREFCTL_BGP_EN SYS_VREFCTL_BGP_EN_Msk /*!<Band-gap Enable */
#define SYS_VREFCTL_REG_EN SYS_VREFCTL_REG_EN_Msk /*!<Regulator Enable */
#define SYS_VREFCTL_SEL25 SYS_VREFCTL_SEL25_Msk /*!<Regulator Output Voltage 2.5V */
#define SYS_VREFCTL_EXTMODE SYS_VREFCTL_EXT_MODE_Msk /*!<Regulator External Mode */
/********************* Bit definition of IRCTRIMCTL register **********************/
#define SYS_IRCTRIMCTL_TRIM_11_0592M (0x1UL<<SYS_IRCTRIMCTL_TRIM_SEL_Pos) /*!<Trim HIRC to 11.0592 MHz */
#define SYS_IRCTRIMCTL_TRIM_12M (0x2UL<<SYS_IRCTRIMCTL_TRIM_SEL_Pos) /*!<Trim HIRC to 12 MHz */
#define SYS_IRCTRIMCTL_TRIM_12_288M (0x3UL<<SYS_IRCTRIMCTL_TRIM_SEL_Pos) /*!<Trim HIRC to 12.288 MHz */
#define SYS_IRCTRIMCTL_LOOP_4CLK (0x0UL<<SYS_IRCTRIMCTL_TRIM_LOOP_Pos) /*!<Based on average difference in 4 x 32.768 kHz clock */
#define SYS_IRCTRIMCTL_LOOP_8CLK (0x1UL<<SYS_IRCTRIMCTL_TRIM_LOOP_Pos) /*!<Based on average difference in 8 x 32.768 kHz clock */
#define SYS_IRCTRIMCTL_LOOP_16CLK (0x2UL<<SYS_IRCTRIMCTL_TRIM_LOOP_Pos) /*!<Based on average difference in 16 x 32.768 kHz clock */
#define SYS_IRCTRIMCTL_LOOP_32CLK (0x3UL<<SYS_IRCTRIMCTL_TRIM_LOOP_Pos) /*!<Based on average difference in 32 x 32.768 kHz clock */
#define SYS_IRCTRIMCTL_RETRY_64 (0x0UL<<SYS_IRCTRIMCTL_TRIM_RETRY_CNT_Pos) /*!<Trim retry count limitation is 64 */
#define SYS_IRCTRIMCTL_RETRY_128 (0x1UL<<SYS_IRCTRIMCTL_TRIM_RETRY_CNT_Pos) /*!<Trim retry count limitation is 128 */
#define SYS_IRCTRIMCTL_RETRY_256 (0x2UL<<SYS_IRCTRIMCTL_TRIM_RETRY_CNT_Pos) /*!<Trim retry count limitation is 256 */
#define SYS_IRCTRIMCTL_RETRY_512 (0x3UL<<SYS_IRCTRIMCTL_TRIM_RETRY_CNT_Pos) /*!<Trim retry count limitation is 512 */
/********************* Bit definition of IRCTRIMIEN register **********************/
#define SYS_IRCTRIMIEN_DISABLE ((uint32_t)0x00000000) /*!<Trim failure interrupt disable */
#define SYS_IRCTRIMIEN_FAIL_EN SYS_IRCTRIMIEN_TRIM_FAIL_IEN_Msk /*!<Trim failure interrupt enable */
#define SYS_IRCTRIMIEN_32KERR_EN SYS_IRCTRIMIEN_32K_ERR_IEN_Msk /*!<32.768 kHz Clock Error Interrupt Enable */
/********************* Bit definition of IRCTRIMINT register **********************/
#define SYS_IRCTRIMINT_FREQLOCK SYS_IRCTRIMINT_FREQ_LOCK_Msk /*!<HIRC frequency lock status */
#define SYS_IRCTRIMINT_FAIL_INT SYS_IRCTRIMINT_TRIM_FAIL_INT_Msk /*!<Trim failure interrupt status */
#define SYS_IRCTRIMINT_32KERR_INT SYS_IRCTRIMINT_32K_ERR_INT_Msk /*!<32.768 kHz Clock Error Interrupt Status */
/********************* Bit definition of PA_L_MFP register **********************/
#define SYS_PA_L_MFP_PA7_MFP_GPA7 (0UL<<SYS_PA_L_MFP_PA7_MFP_Pos) /*!<PA7 Pin Function - GPIOA[7] */
#define SYS_PA_L_MFP_PA7_MFP_ADC_CH7 (1UL<<SYS_PA_L_MFP_PA7_MFP_Pos) /*!<PA7 Pin Function - ADC input channel 7 */
#define SYS_PA_L_MFP_PA7_MFP_EBI_AD6 (2UL<<SYS_PA_L_MFP_PA7_MFP_Pos) /*!<PA7 Pin Function - EBI AD[6] */
#define SYS_PA_L_MFP_PA7_MFP_TMR2_CAP (3UL<<SYS_PA_L_MFP_PA7_MFP_Pos) /*!<PA7 Pin Function - Timer 2 capture event */
#define SYS_PA_L_MFP_PA7_MFP_SC2_DAT (4UL<<SYS_PA_L_MFP_PA7_MFP_Pos) /*!<PA7 Pin Function - SmartCard 2 data pin */
#define SYS_PA_L_MFP_PA7_MFP_PWM0_CH2 (5UL<<SYS_PA_L_MFP_PA7_MFP_Pos) /*!<PA7 Pin Function - PWM0 Channel 2 */
#define SYS_PA_L_MFP_PA7_MFP_LCD_S36 (7UL<<SYS_PA_L_MFP_PA7_MFP_Pos) /*!<PA7 Pin Function - LCD SEG 36 */
#define SYS_PA_L_MFP_PA6_MFP_GPA6 (0UL<<SYS_PA_L_MFP_PA6_MFP_Pos) /*!<PA6 Pin Function - GPIOA[6] */
#define SYS_PA_L_MFP_PA6_MFP_ADC_CH6 (1UL<<SYS_PA_L_MFP_PA6_MFP_Pos) /*!<PA6 Pin Function - ADC input channel 6 */
#define SYS_PA_L_MFP_PA6_MFP_EBI_AD7 (2UL<<SYS_PA_L_MFP_PA6_MFP_Pos) /*!<PA6 Pin Function - EBI AD[7] */
#define SYS_PA_L_MFP_PA6_MFP_TMR3_CAP (3UL<<SYS_PA_L_MFP_PA6_MFP_Pos) /*!<PA6 Pin Function - Timer 3 Capture event */
#define SYS_PA_L_MFP_PA6_MFP_SC2_CLK (4UL<<SYS_PA_L_MFP_PA6_MFP_Pos) /*!<PA6 Pin Function - SmartCard 2 clock */
#define SYS_PA_L_MFP_PA6_MFP_PWM0_CH3 (5UL<<SYS_PA_L_MFP_PA6_MFP_Pos) /*!<PA6 Pin Function - PWM0 Channel 3 */
#define SYS_PA_L_MFP_PA6_MFP_LCD_S37 (7UL<<SYS_PA_L_MFP_PA6_MFP_Pos) /*!<PA6 Pin Function - LCD SEG 37 */
#define SYS_PA_L_MFP_PA6_MFP_LCD_S19 (7UL<<SYS_PA_L_MFP_PA6_MFP_Pos) /*!<PA6 Pin Function - LCD SEG 19 */
#define SYS_PA_L_MFP_PA5_MFP_GPA5 (0UL<<SYS_PA_L_MFP_PA5_MFP_Pos) /*!<PA5 Pin Function - GPIOA[5] */
#define SYS_PA_L_MFP_PA5_MFP_ADC_CH5 (1UL<<SYS_PA_L_MFP_PA5_MFP_Pos) /*!<PA5 Pin Function - ADC input channel 5 */
#define SYS_PA_L_MFP_PA5_MFP_EBI_AD8 (2UL<<SYS_PA_L_MFP_PA5_MFP_Pos) /*!<PA5 Pin Function - EBI AD[8] */
#define SYS_PA_L_MFP_PA5_MFP_SC2_RST (4UL<<SYS_PA_L_MFP_PA5_MFP_Pos) /*!<PA5 Pin Function - SmartCard2 RST */
#define SYS_PA_L_MFP_PA5_MFP_I2C0_SCL (5UL<<SYS_PA_L_MFP_PA5_MFP_Pos) /*!<PA5 Pin Function - I2C0 clock */
#define SYS_PA_L_MFP_PA5_MFP_LCD_S38 (7UL<<SYS_PA_L_MFP_PA5_MFP_Pos) /*!<PA5 Pin Function - LCD SEG 38 */
#define SYS_PA_L_MFP_PA5_MFP_LCD_S20 (7UL<<SYS_PA_L_MFP_PA5_MFP_Pos) /*!<PA5 Pin Function - LCD SEG 20 */
#define SYS_PA_L_MFP_PA4_MFP_GPA4 (0UL<<SYS_PA_L_MFP_PA4_MFP_Pos) /*!<PA4 Pin Function - GPIOA[4] */
#define SYS_PA_L_MFP_PA4_MFP_ADC_CH4 (1UL<<SYS_PA_L_MFP_PA4_MFP_Pos) /*!<PA4 Pin Function - ADC input channel 4 */
#define SYS_PA_L_MFP_PA4_MFP_EBI_AD9 (2UL<<SYS_PA_L_MFP_PA4_MFP_Pos) /*!<PA4 Pin Function - EBI AD[9] */
#define SYS_PA_L_MFP_PA4_MFP_SC2_PWR (4UL<<SYS_PA_L_MFP_PA4_MFP_Pos) /*!<PA4 Pin Function - SmartCard 2 power */
#define SYS_PA_L_MFP_PA4_MFP_I2C0_SDA (5UL<<SYS_PA_L_MFP_PA4_MFP_Pos) /*!<PA4 Pin Function - I2C0 DATA */
#define SYS_PA_L_MFP_PA4_MFP_LCD_S39 (7UL<<SYS_PA_L_MFP_PA4_MFP_Pos) /*!<PA4 Pin Function - LCD SEG 39 */
#define SYS_PA_L_MFP_PA4_MFP_LCD_S21 (7UL<<SYS_PA_L_MFP_PA4_MFP_Pos) /*!<PA4 Pin Function - LCD SEG 21 */
#define SYS_PA_L_MFP_PA3_MFP_GPA3 (0UL<<SYS_PA_L_MFP_PA3_MFP_Pos) /*!<PA3 Pin Function - GPIOA[3] */
#define SYS_PA_L_MFP_PA3_MFP_ADC_CH3 (1UL<<SYS_PA_L_MFP_PA3_MFP_Pos) /*!<PA3 Pin Function - ADC input channel 3 */
#define SYS_PA_L_MFP_PA3_MFP_EBI_AD10 (2UL<<SYS_PA_L_MFP_PA3_MFP_Pos) /*!<PA3 Pin Function - EBI AD[10] */
#define SYS_PA_L_MFP_PA3_MFP_UART1_TX (5UL<<SYS_PA_L_MFP_PA3_MFP_Pos) /*!<PA3 Pin Function - UART 1 RX */
#define SYS_PA_L_MFP_PA3_MFP_LCD_S22 (7UL<<SYS_PA_L_MFP_PA3_MFP_Pos) /*!<PA3 Pin Function - LCD SEG 22 */
#define SYS_PA_L_MFP_PA2_MFP_GPA2 (0UL<<SYS_PA_L_MFP_PA2_MFP_Pos) /*!<PA2 Pin Function - GPIOA[2] */
#define SYS_PA_L_MFP_PA2_MFP_ADC_CH2 (1UL<<SYS_PA_L_MFP_PA2_MFP_Pos) /*!<PA2 Pin Function - ADC input channel 2 */
#define SYS_PA_L_MFP_PA2_MFP_EBI_AD11 (2UL<<SYS_PA_L_MFP_PA2_MFP_Pos) /*!<PA2 Pin Function - EBI AD[11] */
#define SYS_PA_L_MFP_PA2_MFP_UART1_RX (5UL<<SYS_PA_L_MFP_PA2_MFP_Pos) /*!<PA2 Pin Function - UART1 TX */
#define SYS_PA_L_MFP_PA2_MFP_LCD_S23 (7UL<<SYS_PA_L_MFP_PA2_MFP_Pos) /*!<PA2 Pin Function - LCD SEG 23 */
#define SYS_PA_L_MFP_PA1_MFP_GPA1 (0UL<<SYS_PA_L_MFP_PA1_MFP_Pos) /*!<PA1 Pin Function - GPIOA[1] */
#define SYS_PA_L_MFP_PA1_MFP_ADC_CH1 (1UL<<SYS_PA_L_MFP_PA1_MFP_Pos) /*!<PA1 Pin Function - ADC input channel 1 */
#define SYS_PA_L_MFP_PA1_MFP_EBI_AD12 (2UL<<SYS_PA_L_MFP_PA1_MFP_Pos) /*!<PA1 Pin Function - EBI AD[12] */
#define SYS_PA_L_MFP_PA0_MFP_GPA0 (0UL<<SYS_PA_L_MFP_PA0_MFP_Pos) /*!<PA0 Pin Function - GPIOA[0] */
#define SYS_PA_L_MFP_PA0_MFP_ADC_CH0 (1UL<<SYS_PA_L_MFP_PA0_MFP_Pos) /*!<PA0 Pin Function - ADC input channel 0 */
#define SYS_PA_L_MFP_PA0_MFP_SC2_CD (4UL<<SYS_PA_L_MFP_PA0_MFP_Pos) /*!<PA0 Pin Function - SmartCard 2 card detect */
/********************* Bit definition of PA_H_MFP register **********************/
#define SYS_PA_H_MFP_PA15_MFP_GPA15 (0UL<<SYS_PA_H_MFP_PA15_MFP_Pos) /*!<PA15 Pin Function - GPIOA[15] */
#define SYS_PA_H_MFP_PA15_MFP_PWM0_CH3 (1UL<<SYS_PA_H_MFP_PA15_MFP_Pos) /*!<PA15 Pin Function - PWM0 Channel 3 */
#define SYS_PA_H_MFP_PA15_MFP_I2S_MCLK (2UL<<SYS_PA_H_MFP_PA15_MFP_Pos) /*!<PA15 Pin Function - I2S MCLK */
#define SYS_PA_H_MFP_PA15_MFP_TMR3_CAP (3UL<<SYS_PA_H_MFP_PA15_MFP_Pos) /*!<PA15 Pin Function - Timer3 capture event */
#define SYS_PA_H_MFP_PA15_MFP_SC0_PWR (4UL<<SYS_PA_H_MFP_PA15_MFP_Pos) /*!<PA15 Pin Function - SmartCard 0 power */
#define SYS_PA_H_MFP_PA15_MFP_UART0_TX (6UL<<SYS_PA_H_MFP_PA15_MFP_Pos) /*!<PA15 Pin Function - UART0 TX */
#define SYS_PA_H_MFP_PA15_MFP_LCD_S27 (7UL<<SYS_PA_H_MFP_PA15_MFP_Pos) /*!<PA15 Pin Function - LCD SEG 27 */
#define SYS_PA_H_MFP_PA14_MFP_GPA14 (0UL<<SYS_PA_H_MFP_PA14_MFP_Pos) /*!<PA14 Pin Function - GPIOA[14] */
#define SYS_PA_H_MFP_PA14_MFP_PWM0_CH2 (1UL<<SYS_PA_H_MFP_PA14_MFP_Pos) /*!<PA14 Pin Function - PWM0 Channel 2 */
#define SYS_PA_H_MFP_PA14_MFP_EBI_AD15 (2UL<<SYS_PA_H_MFP_PA14_MFP_Pos) /*!<PA14 Pin Function - EBI AD[15] */
#define SYS_PA_H_MFP_PA14_MFP_TMR2_CAP (3UL<<SYS_PA_H_MFP_PA14_MFP_Pos) /*!<PA14 Pin Function - Timer2 capture event */
#define SYS_PA_H_MFP_PA14_MFP_UART0_RX (6UL<<SYS_PA_H_MFP_PA14_MFP_Pos) /*!<PA14 Pin Function - UART0 RX */
#define SYS_PA_H_MFP_PA14_MFP_LCD_S26 (7UL<<SYS_PA_H_MFP_PA14_MFP_Pos) /*!<PA14 Pin Function - LCD SEG 26 */
#define SYS_PA_H_MFP_PA13_MFP_GPA13 (0UL<<SYS_PA_H_MFP_PA13_MFP_Pos) /*!<PA13 Pin Function - GPIOA[13] */
#define SYS_PA_H_MFP_PA13_MFP_PWM0_CH1 (1UL<<SYS_PA_H_MFP_PA13_MFP_Pos) /*!<PA13 Pin Function - PWM0 Channel 1 */
#define SYS_PA_H_MFP_PA13_MFP_EBI_AD14 (2UL<<SYS_PA_H_MFP_PA13_MFP_Pos) /*!<PA13 Pin Function - EBI AD[14] */
#define SYS_PA_H_MFP_PA13_MFP_TMR1_CAP (3UL<<SYS_PA_H_MFP_PA13_MFP_Pos) /*!<PA13 Pin Function - Timer1 capture event */
#define SYS_PA_H_MFP_PA13_MFP_I2C0_SCL (5UL<<SYS_PA_H_MFP_PA13_MFP_Pos) /*!<PA13 Pin Function - I2C0 clock */
#define SYS_PA_H_MFP_PA13_MFP_LCD_S25 (7UL<<SYS_PA_H_MFP_PA13_MFP_Pos) /*!<PA13 Pin Function - LCD SEG 25 */
#define SYS_PA_H_MFP_PA12_MFP_GPA12 (0UL<<SYS_PA_H_MFP_PA12_MFP_Pos) /*!<PA12 Pin Function - GPIOA[12] */
#define SYS_PA_H_MFP_PA12_MFP_PWM0_CH0 (1UL<<SYS_PA_H_MFP_PA12_MFP_Pos) /*!<PA12 Pin Function - PWM0 Channel 0 */
#define SYS_PA_H_MFP_PA12_MFP_EBI_AD13 (2UL<<SYS_PA_H_MFP_PA12_MFP_Pos) /*!<PA12 Pin Function - EBI AD[13] */
#define SYS_PA_H_MFP_PA12_MFP_TMR0_CAP (3UL<<SYS_PA_H_MFP_PA12_MFP_Pos) /*!<PA12 Pin Function - Timer0 capture event */
#define SYS_PA_H_MFP_PA12_MFP_I2C0_SDA (5UL<<SYS_PA_H_MFP_PA12_MFP_Pos) /*!<PA12 Pin Function - I2C0 DATA */
#define SYS_PA_H_MFP_PA12_MFP_LCD_S24 (7UL<<SYS_PA_H_MFP_PA12_MFP_Pos) /*!<PA12 Pin Function - LCD SEG 24 */
#define SYS_PA_H_MFP_PA11_MFP_GPA11 (0UL<<SYS_PA_H_MFP_PA11_MFP_Pos) /*!<PA11 Pin Function - GPIOA[11] */
#define SYS_PA_H_MFP_PA11_MFP_I2C1_SCL (1UL<<SYS_PA_H_MFP_PA11_MFP_Pos) /*!<PA11 Pin Function - I2C1 clock */
#define SYS_PA_H_MFP_PA11_MFP_EBI_NRE (2UL<<SYS_PA_H_MFP_PA11_MFP_Pos) /*!<PA11 Pin Function - EBI nRE */
#define SYS_PA_H_MFP_PA11_MFP_SC0_RST (3UL<<SYS_PA_H_MFP_PA11_MFP_Pos) /*!<PA11 Pin Function - SmartCard0 RST */
#define SYS_PA_H_MFP_PA11_MFP_SPI2_MOSI0 (4UL<<SYS_PA_H_MFP_PA11_MFP_Pos) /*!<PA11 Pin Function - SPI2 MOSI[0] */
#define SYS_PA_H_MFP_PA11_MFP_LCD_S23 (7UL<<SYS_PA_H_MFP_PA11_MFP_Pos) /*!<PA11 Pin Function - LCD SEG 23 */
#define SYS_PA_H_MFP_PA11_MFP_LCD_S9 (7UL<<SYS_PA_H_MFP_PA11_MFP_Pos) /*!<PA11 Pin Function - LCD SEG 9 */
#define SYS_PA_H_MFP_PA10_MFP_GPA10 (0UL<<SYS_PA_H_MFP_PA10_MFP_Pos) /*!<PA10 Pin Function - GPIOA[10] */
#define SYS_PA_H_MFP_PA10_MFP_I2C1_SDA (1UL<<SYS_PA_H_MFP_PA10_MFP_Pos) /*!<PA10 Pin Function - I2C1 DATA */
#define SYS_PA_H_MFP_PA10_MFP_EBI_NWE (2UL<<SYS_PA_H_MFP_PA10_MFP_Pos) /*!<PA10 Pin Function - EBI nWE */
#define SYS_PA_H_MFP_PA10_MFP_SC0_PWR (3UL<<SYS_PA_H_MFP_PA10_MFP_Pos) /*!<PA10 Pin Function - SmartCard0 Power */
#define SYS_PA_H_MFP_PA10_MFP_SPI2_MISO0 (4UL<<SYS_PA_H_MFP_PA10_MFP_Pos) /*!<PA10 Pin Function - SPI2 MISO[0] */
#define SYS_PA_H_MFP_PA10_MFP_LCD_S22 (7UL<<SYS_PA_H_MFP_PA10_MFP_Pos) /*!<PA10 Pin Function - LCD SEG 22 */
#define SYS_PA_H_MFP_PA10_MFP_LCD_S8 (7UL<<SYS_PA_H_MFP_PA10_MFP_Pos) /*!<PA10 Pin Function - LCD SEG 8 */
#define SYS_PA_H_MFP_PA9_MFP_GPA9 (0UL<<SYS_PA_H_MFP_PA9_MFP_Pos) /*!<PA9 Pin Function - GPIOA[9] */
#define SYS_PA_H_MFP_PA9_MFP_I2C0_SCL (1UL<<SYS_PA_H_MFP_PA9_MFP_Pos) /*!<PA9 Pin Function - I2C0 clock */
#define SYS_PA_H_MFP_PA9_MFP_SC0_DAT (3UL<<SYS_PA_H_MFP_PA9_MFP_Pos) /*!<PA9 Pin Function - SmartCard0 DATA */
#define SYS_PA_H_MFP_PA9_MFP_SPI2_SCLK (4UL<<SYS_PA_H_MFP_PA9_MFP_Pos) /*!<PA9 Pin Function - SPI2 SCLK */
#define SYS_PA_H_MFP_PA9_MFP_LCD_S21 (7UL<<SYS_PA_H_MFP_PA9_MFP_Pos) /*!<PA9 Pin Function - LCD SEG 21 */
#define SYS_PA_H_MFP_PA9_MFP_LCD_S7 (7UL<<SYS_PA_H_MFP_PA9_MFP_Pos) /*!<PA9 Pin Function - LCD SEG 7 */
#define SYS_PA_H_MFP_PA8_MFP_GPA8 (0UL<<SYS_PA_H_MFP_PA8_MFP_Pos) /*!<PA8 Pin Function - GPIOA[8] */
#define SYS_PA_H_MFP_PA8_MFP_I2C0_SDA (1UL<<SYS_PA_H_MFP_PA8_MFP_Pos) /*!<PA8 Pin Function - I2C0 DATA */
#define SYS_PA_H_MFP_PA8_MFP_SC0_CLK (3UL<<SYS_PA_H_MFP_PA8_MFP_Pos) /*!<PA8 Pin Function - SmartCard0 clock */
#define SYS_PA_H_MFP_PA8_MFP_SPI2_SS0 (4UL<<SYS_PA_H_MFP_PA8_MFP_Pos) /*!<PA8 Pin Function - SPI2 1st chip selection */
#define SYS_PA_H_MFP_PA8_MFP_LCD_S20 (7UL<<SYS_PA_H_MFP_PA8_MFP_Pos) /*!<PA8 Pin Function - LCD SEG 20 */
#define SYS_PA_H_MFP_PA8_MFP_LCD_S6 (7UL<<SYS_PA_H_MFP_PA8_MFP_Pos) /*!<PA8 Pin Function - LCD SEG 6 */
/********************* Bit definition of PB_L_MFP register **********************/
#define SYS_PB_L_MFP_PB7_MFP_GPB7 (0UL<<SYS_PB_L_MFP_PB7_MFP_Pos) /*!<PB7 Pin Function - GPIOB[7] */
#define SYS_PB_L_MFP_PB7_MFP_UART1_CTS (1UL<<SYS_PB_L_MFP_PB7_MFP_Pos) /*!<PB7 Pin Function - UART1 CTSn */
#define SYS_PB_L_MFP_PB7_MFP_EBI_NCS (2UL<<SYS_PB_L_MFP_PB7_MFP_Pos) /*!<PB7 Pin Function - EBI nCS */
#define SYS_PB_L_MFP_PB7_MFP_SPI2_MOSI0 (4UL<<SYS_PB_L_MFP_PB7_MFP_Pos) /*!<PB7 Pin Function - SPI2 MOSI[0] */
#define SYS_PB_L_MFP_PB7_MFP_LCD_S10 (7UL<<SYS_PB_L_MFP_PB7_MFP_Pos) /*!<PB7 Pin Function - LCD SEG 10 */
#define SYS_PB_L_MFP_PB7_MFP_LCD_S2 (7UL<<SYS_PB_L_MFP_PB7_MFP_Pos) /*!<PB7 Pin Function - LCD SEG 2 */
#define SYS_PB_L_MFP_PB6_MFP_GPB6 (0UL<<SYS_PB_L_MFP_PB6_MFP_Pos) /*!<PB6 Pin Function - GPIOB[6] */
#define SYS_PB_L_MFP_PB6_MFP_UART1_RTS (1UL<<SYS_PB_L_MFP_PB6_MFP_Pos) /*!<PB6 Pin Function - UART1 RTSn */
#define SYS_PB_L_MFP_PB6_MFP_EBI_ALE (2UL<<SYS_PB_L_MFP_PB6_MFP_Pos) /*!<PB6 Pin Function - EBI ALE */
#define SYS_PB_L_MFP_PB6_MFP_SPI2_MISO0 (4UL<<SYS_PB_L_MFP_PB6_MFP_Pos) /*!<PB6 Pin Function - SPI2 MISO[0] */
#define SYS_PB_L_MFP_PB6_MFP_LCD_S11 (7UL<<SYS_PB_L_MFP_PB6_MFP_Pos) /*!<PB6 Pin Function - LCD SEG 11 */
#define SYS_PB_L_MFP_PB6_MFP_LCD_S3 (7UL<<SYS_PB_L_MFP_PB6_MFP_Pos) /*!<PB6 Pin Function - LCD SEG 3 */
#define SYS_PB_L_MFP_PB5_MFP_GPB5 (0UL<<SYS_PB_L_MFP_PB5_MFP_Pos) /*!<PB5 Pin Function - GPIOB[5] */
#define SYS_PB_L_MFP_PB5_MFP_UART1_TX (1UL<<SYS_PB_L_MFP_PB5_MFP_Pos) /*!<PB5 Pin Function - UART1 TX */
#define SYS_PB_L_MFP_PB5_MFP_SC0_RST (3UL<<SYS_PB_L_MFP_PB5_MFP_Pos) /*!<PB5 Pin Function - SmartCard0 RST */
#define SYS_PB_L_MFP_PB5_MFP_SPI2_SCLK (4UL<<SYS_PB_L_MFP_PB5_MFP_Pos) /*!<PB5 Pin Function - SPI2 SCLK */
#define SYS_PB_L_MFP_PB5_MFP_LCD_S12 (7UL<<SYS_PB_L_MFP_PB5_MFP_Pos) /*!<PB5 Pin Function - LCD SEG 12 */
#define SYS_PB_L_MFP_PB5_MFP_LCD_S4 (7UL<<SYS_PB_L_MFP_PB5_MFP_Pos) /*!<PB5 Pin Function - LCD SEG 4 */
#define SYS_PB_L_MFP_PB4_MFP_GPB4 (0UL<<SYS_PB_L_MFP_PB4_MFP_Pos) /*!<PB4 Pin Function - GPIOB[4] */
#define SYS_PB_L_MFP_PB4_MFP_UART1_RX (1UL<<SYS_PB_L_MFP_PB4_MFP_Pos) /*!<PB4 Pin Function - UART1 RX */
#define SYS_PB_L_MFP_PB4_MFP_SC0_CD (3UL<<SYS_PB_L_MFP_PB4_MFP_Pos) /*!<PB4 Pin Function - SmartCard0 card detection */
#define SYS_PB_L_MFP_PB4_MFP_SPI2_SS0 (4UL<<SYS_PB_L_MFP_PB4_MFP_Pos) /*!<PB4 Pin Function - SPI2 chip selection 0 */
#define SYS_PB_L_MFP_PB4_MFP_LCD_S13 (7UL<<SYS_PB_L_MFP_PB4_MFP_Pos) /*!<PB4 Pin Function - LCD SEG 13 */
#define SYS_PB_L_MFP_PB4_MFP_LCD_S5 (7UL<<SYS_PB_L_MFP_PB4_MFP_Pos) /*!<PB4 Pin Function - LCD SEG 5 */
#define SYS_PB_L_MFP_PB3_MFP_GPB3 (0UL<<SYS_PB_L_MFP_PB3_MFP_Pos) /*!<PB3 Pin Function - GPIOB[3] */
#define SYS_PB_L_MFP_PB3_MFP_UART0_CTS (1UL<<SYS_PB_L_MFP_PB3_MFP_Pos) /*!<PB3 Pin Function - UART0 CTSn */
#define SYS_PB_L_MFP_PB3_MFP_EBI_NWRH (2UL<<SYS_PB_L_MFP_PB3_MFP_Pos) /*!<PB3 Pin Function - EBI nWRH */
#define SYS_PB_L_MFP_PB3_MFP_SPI1_SS0 (3UL<<SYS_PB_L_MFP_PB3_MFP_Pos) /*!<PB3 Pin Function - SPI1 chip selection 0 */
#define SYS_PB_L_MFP_PB3_MFP_LCD_S4 (7UL<<SYS_PB_L_MFP_PB3_MFP_Pos) /*!<PB3 Pin Function - LCD SEG 4 */
#define SYS_PB_L_MFP_PB3_MFP_LCD_COM2 (7UL<<SYS_PB_L_MFP_PB3_MFP_Pos) /*!<PB3 Pin Function - LCD COM 2 */
#define SYS_PB_L_MFP_PB2_MFP_GPB2 (0UL<<SYS_PB_L_MFP_PB2_MFP_Pos) /*!<PB2 Pin Function - GPIOB[2] */
#define SYS_PB_L_MFP_PB2_MFP_UART0_RTS (1UL<<SYS_PB_L_MFP_PB2_MFP_Pos) /*!<PB2 Pin Function - UART0 RTSn */
#define SYS_PB_L_MFP_PB2_MFP_EBI_NWRL (2UL<<SYS_PB_L_MFP_PB2_MFP_Pos) /*!<PB2 Pin Function - EBI nWRL */
#define SYS_PB_L_MFP_PB2_MFP_SPI1_SCLK (3UL<<SYS_PB_L_MFP_PB2_MFP_Pos) /*!<PB2 Pin Function - SPI1 SCLK */
#define SYS_PB_L_MFP_PB2_MFP_LCD_S5 (7UL<<SYS_PB_L_MFP_PB2_MFP_Pos) /*!<PB2 Pin Function - LCD SEG 5 */
#define SYS_PB_L_MFP_PB2_MFP_LCD_COM3 (7UL<<SYS_PB_L_MFP_PB2_MFP_Pos) /*!<PB2 Pin Function - LCD COM 3 */
#define SYS_PB_L_MFP_PB1_MFP_GPB1 (0UL<<SYS_PB_L_MFP_PB1_MFP_Pos) /*!<PB1 Pin Function - GPIOB[1] */
#define SYS_PB_L_MFP_PB1_MFP_UART0_TX (1UL<<SYS_PB_L_MFP_PB1_MFP_Pos) /*!<PB1 Pin Function - UART0 TX */
#define SYS_PB_L_MFP_PB1_MFP_SPI1_MISO0 (3UL<<SYS_PB_L_MFP_PB1_MFP_Pos) /*!<PB1 Pin Function - SPI1 MISO[0] */
#define SYS_PB_L_MFP_PB1_MFP_LCD_S6 (7UL<<SYS_PB_L_MFP_PB1_MFP_Pos) /*!<PB1 Pin Function - LCD SEG 6 */
#define SYS_PB_L_MFP_PB1_MFP_LCD_S0 (7UL<<SYS_PB_L_MFP_PB1_MFP_Pos) /*!<PB1 Pin Function - LCD SEG 0 */
#define SYS_PB_L_MFP_PB0_MFP_GPB0 (0UL<<SYS_PB_L_MFP_PB0_MFP_Pos) /*!<PB0 Pin Function - GPIOB[0] */
#define SYS_PB_L_MFP_PB0_MFP_UART0_RX (1UL<<SYS_PB_L_MFP_PB0_MFP_Pos) /*!<PB0 Pin Function - UART0 RX */
#define SYS_PB_L_MFP_PB0_MFP_SPI1_MOSI0 (3UL<<SYS_PB_L_MFP_PB0_MFP_Pos) /*!<PB0 Pin Function - SPI1 MOSI[0] */
#define SYS_PB_L_MFP_PB0_MFP_LCD_S7 (7UL<<SYS_PB_L_MFP_PB0_MFP_Pos) /*!<PB0 Pin Function - LCD SEG 7 */
#define SYS_PB_L_MFP_PB0_MFP_LCD_S1 (7UL<<SYS_PB_L_MFP_PB0_MFP_Pos) /*!<PB0 Pin Function - LCD SEG 1 */
/********************* Bit definition of PB_H_MFP register **********************/
#define SYS_PB_H_MFP_PB15_MFP_GPB15 (0UL<<SYS_PB_H_MFP_PB15_MFP_Pos) /*!<PB15 Pin Function - GPIOB[15] */
#define SYS_PB_H_MFP_PB15_MFP_EXT_INT1 (1UL<<SYS_PB_H_MFP_PB15_MFP_Pos) /*!<PB15 Pin Function - External interrupt 1 */
#define SYS_PB_H_MFP_PB15_MFP_SNOOPER (3UL<<SYS_PB_H_MFP_PB15_MFP_Pos) /*!<PB15 Pin Function - Snooper pin */
#define SYS_PB_H_MFP_PB15_MFP_SC1_CD (4UL<<SYS_PB_H_MFP_PB15_MFP_Pos) /*!<PB15 Pin Function - SmartCard1 card detect */
#define SYS_PB_H_MFP_PB15_MFP_LCD_S31 (7UL<<SYS_PB_H_MFP_PB15_MFP_Pos) /*!<PB15 Pin Function - LCD SEG 31 */
#define SYS_PB_H_MFP_PB15_MFP_LCD_S14 (7UL<<SYS_PB_H_MFP_PB15_MFP_Pos) /*!<PB15 Pin Function - LCD SEG 14 */
#define SYS_PB_H_MFP_PB14_MFP_GPB14 (0UL<<SYS_PB_H_MFP_PB14_MFP_Pos) /*!<PB14 Pin Function - GPIOB[14] */
#define SYS_PB_H_MFP_PB14_MFP_EXT_INT0 (1UL<<SYS_PB_H_MFP_PB14_MFP_Pos) /*!<PB14 Pin Function - External interrupt 0 */
#define SYS_PB_H_MFP_PB14_MFP_SC2_CD (3UL<<SYS_PB_H_MFP_PB14_MFP_Pos) /*!<PB14 Pin Function - SmartCard 2 card detect */
#define SYS_PB_H_MFP_PB14_MFP_SPI2_SS1 (4UL<<SYS_PB_H_MFP_PB14_MFP_Pos) /*!<PB14 Pin Function - SPI2 2nd chip selection */
#define SYS_PB_H_MFP_PB14_MFP_LCD_S26 (7UL<<SYS_PB_H_MFP_PB14_MFP_Pos) /*!<PB14 Pin Function - LCD SEG 26 */
#define SYS_PB_H_MFP_PB14_MFP_LCD_S12 (7UL<<SYS_PB_H_MFP_PB14_MFP_Pos) /*!<PB14 Pin Function - LCD SEG 12 */
#define SYS_PB_H_MFP_PB13_MFP_GPB13 (0UL<<SYS_PB_H_MFP_PB13_MFP_Pos) /*!<PB13 Pin Function - GPIOB[13] */
#define SYS_PB_H_MFP_PB13_MFP_EBI_AD1 (2UL<<SYS_PB_H_MFP_PB13_MFP_Pos) /*!<PB13 Pin Function - EBI AD[1] */
#define SYS_PB_H_MFP_PB13_MFP_LCD_S25 (7UL<<SYS_PB_H_MFP_PB13_MFP_Pos) /*!<PB13 Pin Function - LCD SEG 25 */
#define SYS_PB_H_MFP_PB13_MFP_LCD_S11 (7UL<<SYS_PB_H_MFP_PB13_MFP_Pos) /*!<PB13 Pin Function - LCD SEG 11 */
#define SYS_PB_H_MFP_PB12_MFP_GPB12 (0UL<<SYS_PB_H_MFP_PB12_MFP_Pos) /*!<PB12 Pin Function - GPIOB[12] */
#define SYS_PB_H_MFP_PB12_MFP_EBI_AD0 (2UL<<SYS_PB_H_MFP_PB12_MFP_Pos) /*!<PB12 Pin Function - EBI AD[0] */
#define SYS_PB_H_MFP_PB12_MFP_CKO (4UL<<SYS_PB_H_MFP_PB12_MFP_Pos) /*!<PB12 Pin Function - CKO */
#define SYS_PB_H_MFP_PB12_MFP_LCD_S24 (7UL<<SYS_PB_H_MFP_PB12_MFP_Pos) /*!<PB12 Pin Function - LCD SEG 24 */
#define SYS_PB_H_MFP_PB12_MFP_LCD_S10 (7UL<<SYS_PB_H_MFP_PB12_MFP_Pos) /*!<PB12 Pin Function - LCD SEG 10 */
#define SYS_PB_H_MFP_PB11_MFP_GPB11 (0UL<<SYS_PB_H_MFP_PB11_MFP_Pos) /*!<PB11 Pin Function - GPIOB[11] */
#define SYS_PB_H_MFP_PB11_MFP_PWM1_CH0 (1UL<<SYS_PB_H_MFP_PB11_MFP_Pos) /*!<PB11 Pin Function - PWM1 Channel 0 */
#define SYS_PB_H_MFP_PB11_MFP_TMR3_EXT (2UL<<SYS_PB_H_MFP_PB11_MFP_Pos) /*!<PB11 Pin Function - Timer3 external event input */
#define SYS_PB_H_MFP_PB11_MFP_TMR3_TOGGLE_OUT (2UL<<SYS_PB_H_MFP_PB11_MFP_Pos) /*!<PB11 Pin Function - Timer3 toggle output */
#define SYS_PB_H_MFP_PB11_MFP_SC2_DAT (4UL<<SYS_PB_H_MFP_PB11_MFP_Pos) /*!<PB11 Pin Function - SmartCard2 DATA */
#define SYS_PB_H_MFP_PB11_MFP_SPI0_MISO0 (5UL<<SYS_PB_H_MFP_PB11_MFP_Pos) /*!<PB11 Pin Function - SPI 0 MISO[0] */
#define SYS_PB_H_MFP_PB11_MFP_LCD_V1 (7UL<<SYS_PB_H_MFP_PB11_MFP_Pos) /*!<PB11 Pin Function - LCD V1 */
#define SYS_PB_H_MFP_PB10_MFP_GPB10 (0UL<<SYS_PB_H_MFP_PB10_MFP_Pos) /*!<PB10 Pin Function - GPIOB[10] */
#define SYS_PB_H_MFP_PB10_MFP_SPI0_SS1 (1UL<<SYS_PB_H_MFP_PB10_MFP_Pos) /*!<PB10 Pin Function - SPI0 chip selection 1 */
#define SYS_PB_H_MFP_PB10_MFP_TMR2_EXT (2UL<<SYS_PB_H_MFP_PB10_MFP_Pos) /*!<PB10 Pin Function - Timer2 external event input */
#define SYS_PB_H_MFP_PB10_MFP_TMR2_TOGGLE_OUT (2UL<<SYS_PB_H_MFP_PB10_MFP_Pos) /*!<PB10 Pin Function - Timer2 toggle output */
#define SYS_PB_H_MFP_PB10_MFP_SC2_CLK (4UL<<SYS_PB_H_MFP_PB10_MFP_Pos) /*!<PB10 Pin Function - SmartCard2 clock */
#define SYS_PB_H_MFP_PB10_MFP_SPI0_MOSI0 (5UL<<SYS_PB_H_MFP_PB10_MFP_Pos) /*!<PB10 Pin Function - SPI0 MOSI[0] */
#define SYS_PB_H_MFP_PB10_MFP_LCD_V2 (7UL<<SYS_PB_H_MFP_PB10_MFP_Pos) /*!<PB10 Pin Function - LCD V2 */
#define SYS_PB_H_MFP_PB9_MFP_GPB9 (0UL<<SYS_PB_H_MFP_PB9_MFP_Pos) /*!<PB9 Pin Function - GPIOB[9] */
#define SYS_PB_H_MFP_PB9_MFP_SPI1_SS1 (1UL<<SYS_PB_H_MFP_PB9_MFP_Pos) /*!<PB9 Pin Function - SPI1 chip selection 1 */
#define SYS_PB_H_MFP_PB9_MFP_TMR1_EXT (2UL<<SYS_PB_H_MFP_PB9_MFP_Pos) /*!<PB9 Pin Function - Timer1 external event input */
#define SYS_PB_H_MFP_PB9_MFP_TMR1_TOGGLE_OUT (2UL<<SYS_PB_H_MFP_PB9_MFP_Pos) /*!<PB9 Pin Function - Timer1 toggle output */
#define SYS_PB_H_MFP_PB9_MFP_SC2_RST (4UL<<SYS_PB_H_MFP_PB9_MFP_Pos) /*!<PB9 Pin Function - SmartCard2 RST */
#define SYS_PB_H_MFP_PB9_MFP_EXT_INT0 (5UL<<SYS_PB_H_MFP_PB9_MFP_Pos) /*!<PB9 Pin Function - External interrupt 0 */
#define SYS_PB_H_MFP_PB9_MFP_LCD_V3 (7UL<<SYS_PB_H_MFP_PB9_MFP_Pos) /*!<PB9 Pin Function - LCD V3 */
#define SYS_PB_H_MFP_PB8_MFP_GPB8 (0UL<<SYS_PB_H_MFP_PB8_MFP_Pos) /*!<PB8 Pin Function - GPIOB[8] */
#define SYS_PB_H_MFP_PB8_MFP_ADC_EXT (1UL<<SYS_PB_H_MFP_PB8_MFP_Pos) /*!<PB8 Pin Function - ADC external trigger */
#define SYS_PB_H_MFP_PB8_MFP_TMR0_EXT (2UL<<SYS_PB_H_MFP_PB8_MFP_Pos) /*!<PB8 Pin Function - Timer0 external event input */
#define SYS_PB_H_MFP_PB8_MFP_TMR0_TOGGLE_OUT (2UL<<SYS_PB_H_MFP_PB8_MFP_Pos) /*!<PB8 Pin Function - Timer0 toggle output */
#define SYS_PB_H_MFP_PB8_MFP_EXT_INT0 (3UL<<SYS_PB_H_MFP_PB8_MFP_Pos) /*!<PB8 Pin Function - External interrupt 0 */
#define SYS_PB_H_MFP_PB8_MFP_SC2_PWR (4UL<<SYS_PB_H_MFP_PB8_MFP_Pos) /*!<PB8 Pin Function - SmartCard 2 power */
#define SYS_PB_H_MFP_PB8_MFP_LCD_S30 (7UL<<SYS_PB_H_MFP_PB8_MFP_Pos) /*!<PB8 Pin Function - LCD SEG 30 */
#define SYS_PB_H_MFP_PB8_MFP_LCD_S13 (7UL<<SYS_PB_H_MFP_PB8_MFP_Pos) /*!<PB8 Pin Function - LCD SEG 13 */
/********************* Bit definition of PC_L_MFP register **********************/
#define SYS_PC_L_MFP_PC7_MFP_GPC7 (0UL<<SYS_PC_L_MFP_PC7_MFP_Pos) /*!<PC7 Pin Function - GPIOC[7] */
#define SYS_PC_L_MFP_PC7_MFP_DA_OUT1 (1UL<<SYS_PC_L_MFP_PC7_MFP_Pos) /*!<PC7 Pin Function - DA out1 */
#define SYS_PC_L_MFP_PC7_MFP_EBI_AD5 (2UL<<SYS_PC_L_MFP_PC7_MFP_Pos) /*!<PC7 Pin Function - EBI AD[5] */
#define SYS_PC_L_MFP_PC7_MFP_TMR1_CAP (3UL<<SYS_PC_L_MFP_PC7_MFP_Pos) /*!<PC7 Pin Function - Timer1 capture event */
#define SYS_PC_L_MFP_PC7_MFP_PWM0_CH1 (5UL<<SYS_PC_L_MFP_PC7_MFP_Pos) /*!<PC7 Pin Function - PWM0 Channel 1 */
#define SYS_PC_L_MFP_PC7_MFP_LCD_S17 (7UL<<SYS_PC_L_MFP_PC7_MFP_Pos) /*!<PC7 Pin Function - LCD SEG 17 */
#define SYS_PC_L_MFP_PC6_MFP_GPC6 (0UL<<SYS_PC_L_MFP_PC6_MFP_Pos) /*!<PC6 Pin Function - GPIOC[6] */
#define SYS_PC_L_MFP_PC6_MFP_DA_OUT0 (1UL<<SYS_PC_L_MFP_PC6_MFP_Pos) /*!<PC6 Pin Function - DA out0 */
#define SYS_PC_L_MFP_PC6_MFP_EBI_AD4 (2UL<<SYS_PC_L_MFP_PC6_MFP_Pos) /*!<PC6 Pin Function - EBI AD[4] */
#define SYS_PC_L_MFP_PC6_MFP_TMR0_CAP (3UL<<SYS_PC_L_MFP_PC6_MFP_Pos) /*!<PC6 Pin Function - Timer0 Capture event */
#define SYS_PC_L_MFP_PC6_MFP_SC1_CD (4UL<<SYS_PC_L_MFP_PC6_MFP_Pos) /*!<PC6 Pin Function - SmartCard1 card detection */
#define SYS_PC_L_MFP_PC6_MFP_PWM0_CH0 (5UL<<SYS_PC_L_MFP_PC6_MFP_Pos) /*!<PC6 Pin Function - PWM0 Channel 0 */
#define SYS_PC_L_MFP_PC5_MFP_GPC5 (0UL<<SYS_PC_L_MFP_PC5_MFP_Pos) /*!<PC5 Pin Function - GPIOC[5] */
#define SYS_PC_L_MFP_PC5_MFP_SPI0_MOSI1 (1UL<<SYS_PC_L_MFP_PC5_MFP_Pos) /*!<PC5 Pin Function - SPI0 MOSI[1] */
#define SYS_PC_L_MFP_PC5_MFP_LCD_COM3 (7UL<<SYS_PC_L_MFP_PC5_MFP_Pos) /*!<PC5 Pin Function - LCD COM 3 */
#define SYS_PC_L_MFP_PC4_MFP_GPC4 (0UL<<SYS_PC_L_MFP_PC4_MFP_Pos) /*!<PC4 Pin Function - GPIOC[4] */
#define SYS_PC_L_MFP_PC4_MFP_SPI0_MISO1 (1UL<<SYS_PC_L_MFP_PC4_MFP_Pos) /*!<PC4 Pin Function - SPI0 MISO[1] */
#define SYS_PC_L_MFP_PC4_MFP_LCD_COM2 (7UL<<SYS_PC_L_MFP_PC4_MFP_Pos) /*!<PC4 Pin Function - LCD COM 2 */
#define SYS_PC_L_MFP_PC3_MFP_GPC3 (0UL<<SYS_PC_L_MFP_PC3_MFP_Pos) /*!<PC3 Pin Function - GPIOC[3] */
#define SYS_PC_L_MFP_PC3_MFP_SPI0_MOSI0 (1UL<<SYS_PC_L_MFP_PC3_MFP_Pos) /*!<PC3 Pin Function - SPI0 MOSI[0] */
#define SYS_PC_L_MFP_PC3_MFP_I2S_DOUT (2UL<<SYS_PC_L_MFP_PC3_MFP_Pos) /*!<PC3 Pin Function - I2S Dout */
#define SYS_PC_L_MFP_PC3_MFP_SC1_RST (4UL<<SYS_PC_L_MFP_PC3_MFP_Pos) /*!<PC3 Pin Function - SmartCard1 RST */
#define SYS_PC_L_MFP_PC3_MFP_LCD_COM1 (7UL<<SYS_PC_L_MFP_PC3_MFP_Pos) /*!<PC3 Pin Function - LCD COM 1 */
#define SYS_PC_L_MFP_PC2_MFP_GPC2 (0UL<<SYS_PC_L_MFP_PC2_MFP_Pos) /*!<PC2 Pin Function - GPIOC[2] */
#define SYS_PC_L_MFP_PC2_MFP_SPI0_MISO0 (1UL<<SYS_PC_L_MFP_PC2_MFP_Pos) /*!<PC2 Pin Function - SPI0 MISO[0] */
#define SYS_PC_L_MFP_PC2_MFP_I2S_DIN (2UL<<SYS_PC_L_MFP_PC2_MFP_Pos) /*!<PC2 Pin Function - I2S Din */
#define SYS_PC_L_MFP_PC2_MFP_SC1_PWR (4UL<<SYS_PC_L_MFP_PC2_MFP_Pos) /*!<PC2 Pin Function - SmartCard1 Power */
#define SYS_PC_L_MFP_PC2_MFP_LCD_COM0 (7UL<<SYS_PC_L_MFP_PC2_MFP_Pos) /*!<PC2 Pin Function - LCD COM 0 */
#define SYS_PC_L_MFP_PC1_MFP_GPC1 (0UL<<SYS_PC_L_MFP_PC1_MFP_Pos) /*!<PC1 Pin Function - GPIOC[1] */
#define SYS_PC_L_MFP_PC1_MFP_SPI0_SCLK (1UL<<SYS_PC_L_MFP_PC1_MFP_Pos) /*!<PC1 Pin Function - SPI0 SCLK */
#define SYS_PC_L_MFP_PC1_MFP_I2S_BCLK (2UL<<SYS_PC_L_MFP_PC1_MFP_Pos) /*!<PC1 Pin Function - I2S BCLK */
#define SYS_PC_L_MFP_PC1_MFP_SC1_DAT (4UL<<SYS_PC_L_MFP_PC1_MFP_Pos) /*!<PC1 Pin Function - SmartCard1 DATA */
#define SYS_PC_L_MFP_PC1_MFP_LCD_DH2 (7UL<<SYS_PC_L_MFP_PC1_MFP_Pos) /*!<PC1 Pin Function - LCD DH2 */
#define SYS_PC_L_MFP_PC0_MFP_GPC0 (0UL<<SYS_PC_L_MFP_PC0_MFP_Pos) /*!<PC0 Pin Function - GPIOC[0] */
#define SYS_PC_L_MFP_PC0_MFP_SPI0_SS0 (1UL<<SYS_PC_L_MFP_PC0_MFP_Pos) /*!<PC0 Pin Function - SPI0 chip selection 0 */
#define SYS_PC_L_MFP_PC0_MFP_I2S_WS (2UL<<SYS_PC_L_MFP_PC0_MFP_Pos) /*!<PC0 Pin Function - I2S WS */
#define SYS_PC_L_MFP_PC0_MFP_SC1_CLK (4UL<<SYS_PC_L_MFP_PC0_MFP_Pos) /*!<PC0 Pin Function - SmartCard1 clock */
#define SYS_PC_L_MFP_PC0_MFP_LCD_DH1 (7UL<<SYS_PC_L_MFP_PC0_MFP_Pos) /*!<PC0 Pin Function - LCD DH1 */
/********************* Bit definition of PC_H_MFP register **********************/
#define SYS_PC_H_MFP_PC15_MFP_GPC15 (0UL<<SYS_PC_H_MFP_PC15_MFP_Pos) /*!<PC15 Pin Function - GPIOC[15] */
#define SYS_PC_H_MFP_PC15_MFP_EBI_AD3 (2UL<<SYS_PC_H_MFP_PC15_MFP_Pos) /*!<PC15 Pin Function - EBI AD[3] */
#define SYS_PC_H_MFP_PC15_MFP_TMR0_CAP (3UL<<SYS_PC_H_MFP_PC15_MFP_Pos) /*!<PC15 Pin Function - Timer0 capture event */
#define SYS_PC_H_MFP_PC15_MFP_PWM1_CH2 (4UL<<SYS_PC_H_MFP_PC15_MFP_Pos) /*!<PC15 Pin Function - PWM1 Channel 2 */
#define SYS_PC_H_MFP_PC15_MFP_LCD_S33 (7UL<<SYS_PC_H_MFP_PC15_MFP_Pos) /*!<PC15 Pin Function - LCD SEG 33 */
#define SYS_PC_H_MFP_PC15_MFP_LCD_S16 (7UL<<SYS_PC_H_MFP_PC15_MFP_Pos) /*!<PC15 Pin Function - LCD SEG 16 */
#define SYS_PC_H_MFP_PC14_MFP_GPC14 (0UL<<SYS_PC_H_MFP_PC14_MFP_Pos) /*!<PC14 Pin Function - GPIOC[14] */
#define SYS_PC_H_MFP_PC14_MFP_EBI_AD2 (2UL<<SYS_PC_H_MFP_PC14_MFP_Pos) /*!<PC14 Pin Function - EBI AD[2] */
#define SYS_PC_H_MFP_PC14_MFP_PWM1_CH3 (4UL<<SYS_PC_H_MFP_PC14_MFP_Pos) /*!<PC14 Pin Function - PWM1 Channel 3 */
#define SYS_PC_H_MFP_PC14_MFP_LCD_S32 (7UL<<SYS_PC_H_MFP_PC14_MFP_Pos) /*!<PC14 Pin Function - LCD SEG 32 */
#define SYS_PC_H_MFP_PC14_MFP_LCD_S15 (7UL<<SYS_PC_H_MFP_PC14_MFP_Pos) /*!<PC14 Pin Function - LCD SEG 15 */
#define SYS_PC_H_MFP_PC13_MFP_GPC13 (0UL<<SYS_PC_H_MFP_PC13_MFP_Pos) /*!<PC13 Pin Function - GPIOC[13] */
#define SYS_PC_H_MFP_PC13_MFP_SPI1_MOSI1 (1UL<<SYS_PC_H_MFP_PC13_MFP_Pos) /*!<PC13 Pin Function - SPI1 MOSI[1] */
#define SYS_PC_H_MFP_PC13_MFP_PWM1_CH1 (2UL<<SYS_PC_H_MFP_PC13_MFP_Pos) /*!<PC13 Pin Function - PWM1 Channel 1 */
#define SYS_PC_H_MFP_PC13_MFP_SNOOPER (4UL<<SYS_PC_H_MFP_PC13_MFP_Pos) /*!<PC13 Pin Function - Snooper pin */
#define SYS_PC_H_MFP_PC13_MFP_EXT_INT1 (5UL<<SYS_PC_H_MFP_PC13_MFP_Pos) /*!<PC13 Pin Function - External interrupt 1 */
#define SYS_PC_H_MFP_PC13_MFP_I2C0_SCL (6UL<<SYS_PC_H_MFP_PC13_MFP_Pos) /*!<PC13 Pin Function - I2C0 clock */
#define SYS_PC_H_MFP_PC12_MFP_GPC12 (0UL<<SYS_PC_H_MFP_PC12_MFP_Pos) /*!<PC12 Pin Function - GPIOC[12] */
#define SYS_PC_H_MFP_PC12_MFP_SPI1_MISO1 (1UL<<SYS_PC_H_MFP_PC12_MFP_Pos) /*!<PC12 Pin Function - SPI1 MISO[1] */
#define SYS_PC_H_MFP_PC12_MFP_PWM1_CH0 (2UL<<SYS_PC_H_MFP_PC12_MFP_Pos) /*!<PC12 Pin Function - PWM1 Channel 0 */
#define SYS_PC_H_MFP_PC12_MFP_EXT_INT0 (5UL<<SYS_PC_H_MFP_PC12_MFP_Pos) /*!<PC12 Pin Function - External interrupt 0 */
#define SYS_PC_H_MFP_PC12_MFP_I2C0_SDA (6UL<<SYS_PC_H_MFP_PC12_MFP_Pos) /*!<PC12 Pin Function - I2C0 DATA */
#define SYS_PC_H_MFP_PC11_MFP_GPC11 (0UL<<SYS_PC_H_MFP_PC11_MFP_Pos) /*!<PC11 Pin Function - GPIOC[11] */
#define SYS_PC_H_MFP_PC11_MFP_SPI1_MOSI0 (1UL<<SYS_PC_H_MFP_PC11_MFP_Pos) /*!<PC11 Pin Function - SPI1 MOSI[0] */
#define SYS_PC_H_MFP_PC11_MFP_UART1_TX (5UL<<SYS_PC_H_MFP_PC11_MFP_Pos) /*!<PC11 Pin Function - UART1 TX */
#define SYS_PC_H_MFP_PC11_MFP_LCD_S31 (7UL<<SYS_PC_H_MFP_PC11_MFP_Pos) /*!<PC11 Pin Function - LCD SEG 31 */
#define SYS_PC_H_MFP_PC10_MFP_GPC10 (0UL<<SYS_PC_H_MFP_PC10_MFP_Pos) /*!<PC10 Pin Function - GPIOC[10] */
#define SYS_PC_H_MFP_PC10_MFP_SPI1_MISO0 (1UL<<SYS_PC_H_MFP_PC10_MFP_Pos) /*!<PC10 Pin Function - SPI1 MISO[0] */
#define SYS_PC_H_MFP_PC10_MFP_UART1_RX (5UL<<SYS_PC_H_MFP_PC10_MFP_Pos) /*!<PC10 Pin Function - UART1 RX */
#define SYS_PC_H_MFP_PC10_MFP_LCD_S30 (7UL<<SYS_PC_H_MFP_PC10_MFP_Pos) /*!<PC10 Pin Function - LCD SEG 30 */
#define SYS_PC_H_MFP_PC9_MFP_GPC9 (0UL<<SYS_PC_H_MFP_PC9_MFP_Pos) /*!<PC9 Pin Function - GPIOC[9] */
#define SYS_PC_H_MFP_PC9_MFP_SPI1_SCLK (1UL<<SYS_PC_H_MFP_PC9_MFP_Pos) /*!<PC9 Pin Function - SPI1 SCLK */
#define SYS_PC_H_MFP_PC9_MFP_I2C1_SCL (5UL<<SYS_PC_H_MFP_PC9_MFP_Pos) /*!<PC9 Pin Function - I2C1 clock */
#define SYS_PC_H_MFP_PC9_MFP_LCD_S29 (7UL<<SYS_PC_H_MFP_PC9_MFP_Pos) /*!<PC9 Pin Function - LCD SEG 29 */
#define SYS_PC_H_MFP_PC8_MFP_GPC8 (0UL<<SYS_PC_H_MFP_PC8_MFP_Pos) /*!<PC8 Pin Function - GPIOC[8] */
#define SYS_PC_H_MFP_PC8_MFP_SPI1_SS0 (1UL<<SYS_PC_H_MFP_PC8_MFP_Pos) /*!<PC8 Pin Function - SPI1 SS[0] */
#define SYS_PC_H_MFP_PC8_MFP_EBI_XCLK (2UL<<SYS_PC_H_MFP_PC8_MFP_Pos) /*!<PC8 Pin Function - EBI XCLK */
#define SYS_PC_H_MFP_PC8_MFP_I2C1_SDA (5UL<<SYS_PC_H_MFP_PC8_MFP_Pos) /*!<PC8 Pin Function - I2C1 DATA */
#define SYS_PC_H_MFP_PC8_MFP_LCD_S28 (7UL<<SYS_PC_H_MFP_PC8_MFP_Pos) /*!<PC8 Pin Function - LCD SEG 28 */
/********************* Bit definition of PD_L_MFP register **********************/
#define SYS_PD_L_MFP_PD7_MFP_GPD7 (0UL<<SYS_PD_L_MFP_PD7_MFP_Pos) /*!<PD7 Pin Function - GPIOD[7] */
#define SYS_PD_L_MFP_PD7_MFP_LCD_S2 (7UL<<SYS_PD_L_MFP_PD7_MFP_Pos) /*!<PD7 Pin Function - LCD SEG 2 */
#define SYS_PD_L_MFP_PD6_MFP_GPD6 (0UL<<SYS_PD_L_MFP_PD6_MFP_Pos) /*!<PD6 Pin Function - GPIOD[6] */
#define SYS_PD_L_MFP_PD6_MFP_LCD_S3 (7UL<<SYS_PD_L_MFP_PD6_MFP_Pos) /*!<PD6 Pin Function - LCD SEG 3 */
#define SYS_PD_L_MFP_PD5_MFP_GPD5 (0UL<<SYS_PD_L_MFP_PD5_MFP_Pos) /*!<PD5 Pin Function - GPIOD[5] */
#define SYS_PD_L_MFP_PD5_MFP_I2S_DOUT (2UL<<SYS_PD_L_MFP_PD5_MFP_Pos) /*!<PD5 Pin Function - I2S Dout */
#define SYS_PD_L_MFP_PD5_MFP_SPI2_MOSI1 (3UL<<SYS_PD_L_MFP_PD5_MFP_Pos) /*!<PD5 Pin Function - SPI2 MOSI[1] */
#define SYS_PD_L_MFP_PD5_MFP_LCD_S34 (7UL<<SYS_PD_L_MFP_PD5_MFP_Pos) /*!<PD5 Pin Function - LCD SEG 34 */
#define SYS_PD_L_MFP_PD4_MFP_GPD4 (0UL<<SYS_PD_L_MFP_PD4_MFP_Pos) /*!<PD4 Pin Function - GPIOD[4] */
#define SYS_PD_L_MFP_PD4_MFP_I2S_DIN (2UL<<SYS_PD_L_MFP_PD4_MFP_Pos) /*!<PD4 Pin Function - I2S Din */
#define SYS_PD_L_MFP_PD4_MFP_SPI2_MISO1 (3UL<<SYS_PD_L_MFP_PD4_MFP_Pos) /*!<PD4 Pin Function - SPI2 MISO[1] */
#define SYS_PD_L_MFP_PD4_MFP_SC1_CD (4UL<<SYS_PD_L_MFP_PD4_MFP_Pos) /*!<PD4 Pin Function - SmartCard1 card detection */
#define SYS_PD_L_MFP_PD4_MFP_LCD_S35 (7UL<<SYS_PD_L_MFP_PD4_MFP_Pos) /*!<PD4 Pin Function - LCD SEG 35 */
#define SYS_PD_L_MFP_PD3_MFP_GPD3 (0UL<<SYS_PD_L_MFP_PD3_MFP_Pos) /*!<PD3 Pin Function - GPIOD[3] */
#define SYS_PD_L_MFP_PD3_MFP_UART1_CTS (1UL<<SYS_PD_L_MFP_PD3_MFP_Pos) /*!<PD3 Pin Function - UART1 CTSn */
#define SYS_PD_L_MFP_PD3_MFP_I2S_BCLK (2UL<<SYS_PD_L_MFP_PD3_MFP_Pos) /*!<PD3 Pin Function - I2S BCLK */
#define SYS_PD_L_MFP_PD3_MFP_SPI2_MOSI0 (3UL<<SYS_PD_L_MFP_PD3_MFP_Pos) /*!<PD3 Pin Function - SPI2 MOSI[0] */
#define SYS_PD_L_MFP_PD3_MFP_SC1_RST (4UL<<SYS_PD_L_MFP_PD3_MFP_Pos) /*!<PD3 Pin Function - SmartCard1 reset */
#define SYS_PD_L_MFP_PD3_MFP_ADC_CH11 (5UL<<SYS_PD_L_MFP_PD3_MFP_Pos) /*!<PD3 Pin Function - ADC input channel 11 */
#define SYS_PD_L_MFP_PD2_MFP_GPD2 (0UL<<SYS_PD_L_MFP_PD2_MFP_Pos) /*!<PD2 Pin Function - GPIOD[2] */
#define SYS_PD_L_MFP_PD2_MFP_UART1_RTS (1UL<<SYS_PD_L_MFP_PD2_MFP_Pos) /*!<PD2 Pin Function - UART1 RTSn */
#define SYS_PD_L_MFP_PD2_MFP_I2S_WS (2UL<<SYS_PD_L_MFP_PD2_MFP_Pos) /*!<PD2 Pin Function - I2S WS */
#define SYS_PD_L_MFP_PD2_MFP_SPI2_MISO0 (3UL<<SYS_PD_L_MFP_PD2_MFP_Pos) /*!<PD2 Pin Function - SPI2 MISO[0] */
#define SYS_PD_L_MFP_PD2_MFP_SC1_PWR (4UL<<SYS_PD_L_MFP_PD2_MFP_Pos) /*!<PD2 Pin Function - SmartCard1 power */
#define SYS_PD_L_MFP_PD2_MFP_ADC_CH10 (5UL<<SYS_PD_L_MFP_PD2_MFP_Pos) /*!<PD2 Pin Function - ADC input channel 10 */
#define SYS_PD_L_MFP_PD1_MFP_GPD1 (0UL<<SYS_PD_L_MFP_PD1_MFP_Pos) /*!<PD1 Pin Function - GPIOD[1] */
#define SYS_PD_L_MFP_PD1_MFP_UART1_TX (1UL<<SYS_PD_L_MFP_PD1_MFP_Pos) /*!<PD1 Pin Function - UART1 TX */
#define SYS_PD_L_MFP_PD1_MFP_SPI2_SCLK (3UL<<SYS_PD_L_MFP_PD1_MFP_Pos) /*!<PD1 Pin Function - SPI2 SCLK */
#define SYS_PD_L_MFP_PD1_MFP_SC1_DAT (4UL<<SYS_PD_L_MFP_PD1_MFP_Pos) /*!<PD1 Pin Function - SmartCard1 DATA */
#define SYS_PD_L_MFP_PD1_MFP_ADC_CH9 (5UL<<SYS_PD_L_MFP_PD1_MFP_Pos) /*!<PD1 Pin Function - ADC input channel 9 */
#define SYS_PD_L_MFP_PD0_MFP_GPD0 (0UL<<SYS_PD_L_MFP_PD0_MFP_Pos) /*!<PD0 Pin Function - GPIOD[0] */
#define SYS_PD_L_MFP_PD0_MFP_UART1_RX (1UL<<SYS_PD_L_MFP_PD0_MFP_Pos) /*!<PD0 Pin Function - UART1 RX */
#define SYS_PD_L_MFP_PD0_MFP_SPI2_SS0 (3UL<<SYS_PD_L_MFP_PD0_MFP_Pos) /*!<PD0 Pin Function - SPI2 chip selection 0 */
#define SYS_PD_L_MFP_PD0_MFP_SC1_CLK (4UL<<SYS_PD_L_MFP_PD0_MFP_Pos) /*!<PD0 Pin Function - SmartCard1 clock */
#define SYS_PD_L_MFP_PD0_MFP_ADC_CH8 (5UL<<SYS_PD_L_MFP_PD0_MFP_Pos) /*!<PD0 Pin Function - ADC input channel 8 */
/********************* Bit definition of PD_H_MFP register **********************/
#define SYS_PD_H_MFP_PD15_MFP_GPD15 (0UL<<SYS_PD_H_MFP_PD15_MFP_Pos) /*!<PD15 Pin Function - GPIOD[15] */
#define SYS_PD_H_MFP_PD15_MFP_LCD_S0 (7UL<<SYS_PD_H_MFP_PD15_MFP_Pos) /*!<PD15 Pin Function - LCD SEG 0 */
#define SYS_PD_H_MFP_PD14_MFP_GPD14 (0UL<<SYS_PD_H_MFP_PD14_MFP_Pos) /*!<PD14 Pin Function - GPIOD[14] */
#define SYS_PD_H_MFP_PD14_MFP_LCD_S1 (7UL<<SYS_PD_H_MFP_PD14_MFP_Pos) /*!<PD14 Pin Function - LCD SEG 1 */
#define SYS_PD_H_MFP_PD13_MFP_GPD13 (0UL<<SYS_PD_H_MFP_PD13_MFP_Pos) /*!<PD13 Pin Function - GPIOD[13] */
#define SYS_PD_H_MFP_PD13_MFP_LCD_S14 (7UL<<SYS_PD_H_MFP_PD13_MFP_Pos) /*!<PD13 Pin Function - LCD SEG 14 */
#define SYS_PD_H_MFP_PD12_MFP_GPD12 (0UL<<SYS_PD_H_MFP_PD12_MFP_Pos) /*!<PD12 Pin Function - GPIOD[12] */
#define SYS_PD_H_MFP_PD12_MFP_LCD_S15 (7UL<<SYS_PD_H_MFP_PD12_MFP_Pos) /*!<PD12 Pin Function - LCD SEG 15 */
#define SYS_PD_H_MFP_PD11_MFP_GPD11 (0UL<<SYS_PD_H_MFP_PD11_MFP_Pos) /*!<PD11 Pin Function - GPIOD[11] */
#define SYS_PD_H_MFP_PD11_MFP_LCD_S16 (7uL<<SYS_PD_H_MFP_PD11_MFP_Pos) /*!<PD11 Pin Function - LCD SEG 16 */
#define SYS_PD_H_MFP_PD10_MFP_GPD10 (0UL<<SYS_PD_H_MFP_PD10_MFP_Pos) /*!<PD10 Pin Function - GPIOD[10] */
#define SYS_PD_H_MFP_PD10_MFP_LCD_S17 (7UL<<SYS_PD_H_MFP_PD10_MFP_Pos) /*!<PD10 Pin Function - LCD SEG 17 */
#define SYS_PD_H_MFP_PD9_MFP_GPD9 (0UL<<SYS_PD_H_MFP_PD9_MFP_Pos) /*!<PD9 Pin Function - GPIOD[9] */
#define SYS_PD_H_MFP_PD9_MFP_LCD_S18 (7UL<<SYS_PD_H_MFP_PD9_MFP_Pos) /*!<PD9 Pin Function - LCD SEG 18 */
#define SYS_PD_H_MFP_PD8_MFP_GPD8 (0UL<<SYS_PD_H_MFP_PD8_MFP_Pos) /*!<PD8 Pin Function - GPIOD[8] */
#define SYS_PD_H_MFP_PD8_MFP_LCD_S19 (7UL<<SYS_PD_H_MFP_PD8_MFP_Pos) /*!<PD8 Pin Function - LCD SEG 19 */
/********************* Bit definition of PE_L_MFP register **********************/
#define SYS_PE_L_MFP_PE7_MFP_GPE7 (0UL<<SYS_PE_L_MFP_PE7_MFP_Pos) /*!<PE7 Pin Function - GPIOE[7] */
#define SYS_PE_L_MFP_PE7_MFP_LCD_S8 (7UL<<SYS_PE_L_MFP_PE7_MFP_Pos) /*!<PE7 Pin Function - LCD SEG 8 */
#define SYS_PE_L_MFP_PE6_MFP_GPE6 (0UL<<SYS_PE_L_MFP_PE6_MFP_Pos) /*!<PE6 Pin Function - GPIOE[6] */
#define SYS_PE_L_MFP_PE5_MFP_GPE5 (0UL<<SYS_PE_L_MFP_PE5_MFP_Pos) /*!<PE5 Pin Function - GPIOE[5] */
#define SYS_PE_L_MFP_PE5_MFP_PWM1_CH1 (1UL<<SYS_PE_L_MFP_PE5_MFP_Pos) /*!<PE5 Pin Function - PWM1 Channel 1 */
#define SYS_PE_L_MFP_PE4_MFP_GPE4 (0UL<<SYS_PE_L_MFP_PE4_MFP_Pos) /*!<PE4 Pin Function - GPIOE[4] */
#define SYS_PE_L_MFP_PE4_MFP_SPI0_MOSI0 (6UL<<SYS_PE_L_MFP_PE4_MFP_Pos) /*!<PE4 Pin Function - SPI0 MOSI[0] */
#define SYS_PE_L_MFP_PE3_MFP_GPE3 (0UL<<SYS_PE_L_MFP_PE3_MFP_Pos) /*!<PE3 Pin Function - GPIOE[3] */
#define SYS_PE_L_MFP_PE3_MFP_SPI0_MISO0 (6UL<<SYS_PE_L_MFP_PE3_MFP_Pos) /*!<PE3 Pin Function - SPI0 MISO[0] */
#define SYS_PE_L_MFP_PE2_MFP_GPE2 (0UL<<SYS_PE_L_MFP_PE2_MFP_Pos) /*!<PE2 Pin Function - GPIOE[2] */
#define SYS_PE_L_MFP_PE2_MFP_SPI0_SCLK (6UL<<SYS_PE_L_MFP_PE2_MFP_Pos) /*!<PE2 Pin Function - SPI0 SCLK */
#define SYS_PE_L_MFP_PE1_MFP_GPE1 (0UL<<SYS_PE_L_MFP_PE1_MFP_Pos) /*!<PE1 Pin Function - GPIOE[1] */
#define SYS_PE_L_MFP_PE1_MFP_PWM1_CH3 (1UL<<SYS_PE_L_MFP_PE1_MFP_Pos) /*!<PE1 Pin Function - PWM1 Channel 3 */
#define SYS_PE_L_MFP_PE1_MFP_SPI0_SS0 (6UL<<SYS_PE_L_MFP_PE1_MFP_Pos) /*!<PE1 Pin Function - SPI0 chip selection 0 */
#define SYS_PE_L_MFP_PE0_MFP_GPE0 (0UL<<SYS_PE_L_MFP_PE0_MFP_Pos) /*!<PE0 Pin Function - GPIOE[0] */
#define SYS_PE_L_MFP_PE0_MFP_PWM1_CH2 (1UL<<SYS_PE_L_MFP_PE0_MFP_Pos) /*!<PE0 Pin Function - PWM1 Channel 2 */
#define SYS_PE_L_MFP_PE0_MFP_I2S_MCLK (2UL<<SYS_PE_L_MFP_PE0_MFP_Pos) /*!<PE0 Pin Function - I2S MCLK */
/********************* Bit definition of PE_H_MFP register **********************/
#define SYS_PE_H_MFP_PE15_MFP_GPE15 (0UL<<SYS_PE_H_MFP_PE15_MFP_Pos) /*!<PE15 Pin Function - GPIOE[15] */
#define SYS_PE_H_MFP_PE15_MFP_LCD_S29 (7UL<<SYS_PE_H_MFP_PE15_MFP_Pos) /*!<PE15 Pin Function - LCD SEG 29 */
#define SYS_PE_H_MFP_PE14_MFP_GPE14 (0UL<<SYS_PE_H_MFP_PE14_MFP_Pos) /*!<PE14 Pin Function - GPIOE[14] */
#define SYS_PE_H_MFP_PE14_MFP_LCD_S28 (7UL<<SYS_PE_H_MFP_PE14_MFP_Pos) /*!<PE14 Pin Function - LCD SEG 28 */
#define SYS_PE_H_MFP_PE13_MFP_GPE13 (0UL<<SYS_PE_H_MFP_PE13_MFP_Pos) /*!<PE13 Pin Function - GPIOE[13] */
#define SYS_PE_H_MFP_PE13_MFP_LCD_S27 (7UL<<SYS_PE_H_MFP_PE13_MFP_Pos) /*!<PE13 Pin Function - LCD SEG 27 */
#define SYS_PE_H_MFP_PE12_MFP_GPE12 (0UL<<SYS_PE_H_MFP_PE12_MFP_Pos) /*!<PE12 Pin Function - GPIOE[12] */
#define SYS_PE_H_MFP_PE12_MFP_UART1_CTS (7UL<<SYS_PE_H_MFP_PE12_MFP_Pos) /*!<PE12 Pin Function - UART1 CTSn */
#define SYS_PE_H_MFP_PE11_MFP_GPE11 (0UL<<SYS_PE_H_MFP_PE11_MFP_Pos) /*!<PE11 Pin Function - GPIOE[11] */
#define SYS_PE_H_MFP_PE11_MFP_UART1_RTS (7UL<<SYS_PE_H_MFP_PE11_MFP_Pos) /*!<PE11 Pin Function - UART1 RTSn */
#define SYS_PE_H_MFP_PE10_MFP_GPE10 (0UL<<SYS_PE_H_MFP_PE10_MFP_Pos) /*!<PE10 Pin Function - GPIOE[10] */
#define SYS_PE_H_MFP_PE10_MFP_UART1_TX (7UL<<SYS_PE_H_MFP_PE10_MFP_Pos) /*!<PE10 Pin Function - UART1 TX */
#define SYS_PE_H_MFP_PE9_MFP_GPE9 (0UL<<SYS_PE_H_MFP_PE9_MFP_Pos) /*!<PE9 Pin Function - GPIOE[9] */
#define SYS_PE_H_MFP_PE9_MFP_UART1_RX (7UL<<SYS_PE_H_MFP_PE9_MFP_Pos) /*!<PE9 Pin Function - UART1 RX */
#define SYS_PE_H_MFP_PE8_MFP_GPE8 (0UL<<SYS_PE_H_MFP_PE8_MFP_Pos) /*!<PE8 Pin Function - GPIOA[8] */
#define SYS_PE_H_MFP_PE8_MFP_LCD_S9 (7UL<<SYS_PE_H_MFP_PE8_MFP_Pos) /*!<PE8 Pin Function - LCD SEG 9 */
/********************* Bit definition of PF_L_MFP register **********************/
#define SYS_PF_L_MFP_PF5_MFP_GPF5 (0UL<<SYS_PF_L_MFP_PF5_MFP_Pos) /*!<PF5 Pin Function - GPIOF[5] */
#define SYS_PF_L_MFP_PF5_MFP_I2C0_SCL (1UL<<SYS_PF_L_MFP_PF5_MFP_Pos) /*!<PF5 Pin Function - I2C0 clock */
#define SYS_PF_L_MFP_PF4_MFP_GPF4 (0UL<<SYS_PF_L_MFP_PF4_MFP_Pos) /*!<PF4 Pin Function - GPIOF[4] */
#define SYS_PF_L_MFP_PF4_MFP_I2C0_SDA (1UL<<SYS_PF_L_MFP_PF4_MFP_Pos) /*!<PF4 Pin Function - I2C0 DATA */
#define SYS_PF_L_MFP_PF3_MFP_GPF3 (0UL<<SYS_PF_L_MFP_PF3_MFP_Pos) /*!<PF3 Pin Function - GPIOF[3] */
#define SYS_PF_L_MFP_PF3_MFP_HXT_IN (7UL<<SYS_PF_L_MFP_PF3_MFP_Pos) /*!<PF3 Pin Function - HXT IN */
#define SYS_PF_L_MFP_PF2_MFP_GPF2 (0UL<<SYS_PF_L_MFP_PF2_MFP_Pos) /*!<PF2 Pin Function - GPIOF[2] */
#define SYS_PF_L_MFP_PF2_MFP_HXT_OUT (7UL<<SYS_PF_L_MFP_PF2_MFP_Pos) /*!<PF2 Pin Function - HXT OUT */
#define SYS_PF_L_MFP_PF1_MFP_GPF1 (0UL<<SYS_PF_L_MFP_PF1_MFP_Pos) /*!<PF1 Pin Function - GPIOF[1] */
#define SYS_PF_L_MFP_PF1_MFP_CKO (4UL<<SYS_PF_L_MFP_PF1_MFP_Pos) /*!<PF1 Pin Function - CKO */
#define SYS_PF_L_MFP_PF1_MFP_EXT_INT1 (5UL<<SYS_PF_L_MFP_PF1_MFP_Pos) /*!<PF1 Pin Function - External interrupt 1 */
#define SYS_PF_L_MFP_PF1_MFP_ICE_CLK (7UL<<SYS_PF_L_MFP_PF1_MFP_Pos) /*!<PF1 Pin Function - ICE CLOCK */
#define SYS_PF_L_MFP_PF0_MFP_GPF0 (0UL<<SYS_PF_L_MFP_PF0_MFP_Pos) /*!<PF0 Pin Function - GPIOF[0] */
#define SYS_PF_L_MFP_PF0_MFP_EXT_INT0 (5UL<<SYS_PF_L_MFP_PF0_MFP_Pos) /*!<PF0 Pin Function - External interrupt 0 */
#define SYS_PF_L_MFP_PF0_MFP_ICE_DAT (7UL<<SYS_PF_L_MFP_PF0_MFP_Pos) /*!<PF0 Pin Function - ICE DATA */
/*@}*/ /* end of group NANO100_SYS_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_SYS_EXPORTED_FUNCTIONS SYS Exported Functions
@{
*/
/**
* @brief Clear Brown-out detector interrupt flag
* @param None
* @return None
* @details This macro clear Brown-out detector interrupt flag.
*/
#define SYS_CLEAR_BOD_INT_FLAG() (SYS->BODSTS |= SYS_BODSTS_BOD_INT_Msk)
/**
* @brief Disable Brown-out 2.5V detector function
* @param None
* @return None
* @details This macro disable Brown-out 2.5V detector function.
*/
#define SYS_DISABLE_BOD25() (SYS->BODCTL &= ~SYS_BODCTL_BOD25_EN_Msk)
/**
* @brief Enable Brown-out 2.5V detector function
* @param None
* @return None
* @details This macro enable Brown-out 2.5V detector function.
*/
#define SYS_ENABLE_BOD25() (SYS->BODCTL |= SYS_BODCTL_BOD25_EN_Msk)
/**
* @brief Disable Brown-out 2.0V detector function
* @param None
* @return None
* @details This macro disable Brown-out 2.0V detector function.
*/
#define SYS_DISABLE_BOD20() (SYS->BODCTL &= ~SYS_BODCTL_BOD20_EN_Msk)
/**
* @brief Enable Brown-out 2.0V detector function
* @param None
* @return None
* @details This macro enable Brown-out 2.0V detector function.
*/
#define SYS_ENABLE_BOD20() (SYS->BODCTL |= SYS_BODCTL_BOD20_EN_Msk)
/**
* @brief Disable Brown-out 1.7V detector function
* @param None
* @return None
* @details This macro disable Brown-out 1.7V detector function.
*/
#define SYS_DISABLE_BOD17() (SYS->BODCTL &= ~SYS_BODCTL_BOD17_EN_Msk)
/**
* @brief Enable Brown-out 1.7V detector function
* @param None
* @return None
* @details This macro enable Brown-out 1.7V detector function.
*/
#define SYS_ENABLE_BOD17() (SYS->BODCTL |= SYS_BODCTL_BOD17_EN_Msk)
/**
* @brief Get Brown-out detector interrupt flag
* @param None
* @retval 0 Brown-out detect interrupt flag is not set.
* @retval >=1 Brown-out detect interrupt flag is set.
* @details This macro get Brown-out detector interrupt flag.
*/
#define SYS_GET_BOD_INT_FLAG() (SYS->BODSTS & SYS_BODSTS_BOD_INT_Msk)
/**
* @brief Get Brown-out 2.5V detector status
* @param None
* @retval 0 System voltage is higher than 2.5V setting or BOD_EN is 0.
* @retval >=1 System voltage is lower than 2.5V setting.
* @details This macro get Brown-out detector output status.
* If the BOD_EN is 0, this function always return 0.
*/
#define SYS_GET_BOD25_OUTPUT() (SYS->BODSTS & SYS_BODSTS_BOD25_drop_Msk)
/**
* @brief Get Brown-out 2.0V detector status
* @param None
* @retval 0 System voltage is higher than 2.0V setting or BOD_EN is 0.
* @retval >=1 System voltage is lower than 2.0V setting.
* @details This macro get Brown-out detector output status.
* If the BOD_EN is 0, this function always return 0.
*/
#define SYS_GET_BOD20_OUTPUT() (SYS->BODSTS & SYS_BODSTS_BOD20_drop_Msk)
/**
* @brief Get Brown-out 1.7V detector status
* @param None
* @retval 0 System voltage is higher than 1.7V setting or BOD_EN is 0.
* @retval >=1 System voltage is lower than 1.7V setting.
* @details This macro get Brown-out detector output status.
* If the BOD_EN is 0, this function always return 0.
*/
#define SYS_GET_BOD17_OUTPUT() (SYS->BODSTS & SYS_BODSTS_BOD17_drop_Msk)
/**
* @brief Disable Brown-out 2.5V detector interrupt function
* @param None
* @return None
* @details This macro enable Brown-out detector interrupt function.
*/
#define SYS_DISABLE_BOD25_RST() (SYS->BODCTL &= ~SYS_BODCTL_BOD25_RST_EN_Msk)
/**
* @brief Enable Brown-out 2.5V detector reset function
* @param None
* @return None
* @details This macro enable Brown-out detect reset function.
*/
#define SYS_ENABLE_BOD25_RST() (SYS->BODCTL |= SYS_BODCTL_BOD25_RST_EN_Msk)
/**
* @brief Disable Brown-out 2.0V detector interrupt function
* @param None
* @return None
* @details This macro enable Brown-out detector interrupt function.
*/
#define SYS_DISABLE_BOD20_RST() (SYS->BODCTL &= ~SYS_BODCTL_BOD20_RST_EN_Msk)
/**
* @brief Enable Brown-out 2.0V detector reset function
* @param None
* @return None
* @details This macro enable Brown-out detect reset function.
*/
#define SYS_ENABLE_BOD20_RST() (SYS->BODCTL |= SYS_BODCTL_BOD20_RST_EN_Msk)
/**
* @brief Disable Brown-out 1.7V detector interrupt function
* @param None
* @return None
* @details This macro enable Brown-out detector interrupt function.
*/
#define SYS_DISABLE_BOD17_RST() (SYS->BODCTL &= ~SYS_BODCTL_BOD17_RST_EN_Msk)
/**
* @brief Enable Brown-out 1.7V detector reset function
* @param None
* @return None
* @details This macro enable Brown-out detect reset function.
*/
#define SYS_ENABLE_BOD17_RST() (SYS->BODCTL |= SYS_BODCTL_BOD17_RST_EN_Msk)
/**
* @brief Get reset source is from Brown-out detector reset
* @param None
* @retval 0 Previous reset source is not from Brown-out detector reset
* @retval >=1 Previous reset source is from Brown-out detector reset
* @details This macro get previous reset source is from Brown-out detect reset or not.
*/
#define SYS_IS_BOD_RST() (SYS->RST_SRC & SYS_RST_SRC_RSTS_BOD_Msk)
/**
* @brief Get reset source is from CPU reset
* @param None
* @retval 0 Previous reset source is not from CPU reset
* @retval >=1 Previous reset source is from CPU reset
* @details This macro get previous reset source is from CPU reset.
*/
#define SYS_IS_CPU_RST() (SYS->RST_SRC & SYS_RST_SRC_RSTS_CPU_Msk)
/**
* @brief Get reset source is from Power-on Reset
* @param None
* @retval 0 Previous reset source is not from Power-on Reset
* @retval >=1 Previous reset source is from Power-on Reset
* @details This macro get previous reset source is from Power-on Reset.
*/
#define SYS_IS_POR_RST() (SYS->RST_SRC & SYS_RST_SRC_RSTS_POR_Msk)
/**
* @brief Get reset source is from reset pin reset
* @param None
* @retval 0 Previous reset source is not from reset pin reset
* @retval >=1 Previous reset source is from reset pin reset
* @details This macro get previous reset source is from reset pin reset.
*/
#define SYS_IS_RSTPIN_RST() (SYS->RST_SRC & SYS_RST_SRC_RSTS_PAD_Msk)
/**
* @brief Get reset source is from system reset
* @param None
* @retval 0 Previous reset source is not from system reset
* @retval >=1 Previous reset source is from system reset
* @details This macro get previous reset source is from system reset.
*/
#define SYS_IS_SYSTEM_RST() (SYS->RST_SRC & SYS_RST_SRC_RSTS_SYS_Msk)
/**
* @brief Get reset source is from window watch dog reset
* @param None
* @retval 0 Previous reset source is not from window watch dog reset
* @retval >=1 Previous reset source is from window watch dog reset
* @details This macro get previous reset source is from window watch dog reset.
*/
#define SYS_IS_WDT_RST() (SYS->RST_SRC & SYS_RST_SRC_RSTS_WDT_Msk)
/**
* @brief Disable Power-on Reset function
* @param None
* @return None
* @details This macro disable Power-on Reset function.
*/
#define SYS_DISABLE_POR() (SYS->PORCTL = 0x5AA5)
/**
* @brief Enable Power-on Reset function
* @param None
* @return None
* @details This macro enable Power-on Reset function.
*/
#define SYS_ENABLE_POR() (SYS->PORCTL = 0)
/**
* @brief Clear reset source flag
* @param[in] u32RstSrc is reset source. Including:
* - \ref SYS_RST_SRC_RSTS_POR_Msk
* - \ref SYS_RST_SRC_RSTS_PAD_Msk
* - \ref SYS_RST_SRC_RSTS_WDT_Msk
* - \ref SYS_RST_SRC_RSTS_BOD_Msk
* - \ref SYS_RST_SRC_RSTS_SYS_Msk
* - \ref SYS_RST_SRC_RSTS_CPU_Msk
* @return None
* @details This macro clear reset source flag.
*/
#define SYS_CLEAR_RST_SOURCE(u32RstSrc) (SYS->RST_SRC = u32RstSrc )
/**
* @brief Get HIRC trim status
* @param None
* @retval BIT0 HIRC Frequency Lock
* @retval BIT1 Trim Failure Interrupt
* @retval BIT2 LXT Clock error
* @details This macro get HIRC trim interrupt status register.
*/
#define SYS_GET_IRCTRIM_INT_FLAG() (SYS->IRCTRIMINT)
/**
* @brief Clear HIRC trim flag
* @param[in] u32IRCTrimFlg is HIRC trim flags. Including:
* - \ref SYS_IRCTRIMINT_FAIL_INT
* - \ref SYS_IRCTRIMINT_32KERR_INT
* @return None
* @details This macro clear HIRC trim flag.
*/
#define SYS_CLEAR_IRCTRIM_INT_FLAG(u32IRCTrimFlg) (SYS->IRCTRIMINT = u32IRCTrimFlg )
/**
* @brief Disable register write-protection function
* @param None
* @return None
* @details This function disable register write-protection function.
* To unlock the protected register to allow write access.
*/
__STATIC_INLINE void SYS_UnlockReg(void)
{
while(SYS->RegLockAddr != SYS_RegLockAddr_RegUnLock_Msk) {
SYS->RegLockAddr = 0x59;
SYS->RegLockAddr = 0x16;
SYS->RegLockAddr = 0x88;
}
}
/**
* @brief Enable register write-protection function
* @param None
* @return None
* @details This function is used to enable register write-protection function.
* To lock the protected register to forbid write access.
*/
__STATIC_INLINE void SYS_LockReg(void)
{
SYS->RegLockAddr = 0;
}
void SYS_ClearResetSrc(uint32_t u32Src);
uint32_t SYS_GetBODStatus(void);
uint32_t SYS_GetResetSrc(void);
uint32_t SYS_IsRegLocked(void);
uint32_t SYS_ReadPDID(void);
void SYS_ResetChip(void);
void SYS_ResetCPU(void);
void SYS_ResetModule(uint32_t u32ModuleIndex);
void SYS_EnableBOD(int32_t i32Mode, uint32_t u32BODLevel);
void SYS_DisableBOD(void);
void SYS_EnableIRCTrim(uint32_t u32TrimSel,uint32_t u32TrimEnInt);
void SYS_DisableIRCTrim(void);
/*@}*/ /* end of group NANO100_SYS_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_SYS_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__SYS_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,284 @@
/**************************************************************************//**
* @file timer.c
* @version V1.00
* $Revision: 11 $
* $Date: 15/06/23 5:15p $
* @brief Nano100 series TIMER driver source file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_TIMER_Driver TIMER Driver
@{
*/
/** @addtogroup NANO100_TIMER_EXPORTED_FUNCTIONS TIMER Exported Functions
@{
*/
/**
* @brief This API is used to configure timer to operate in specified mode
* and frequency. If timer cannot work in target frequency, a closest
* frequency will be chose and returned.
* @param[in] timer The base address of Timer module
* @param[in] u32Mode Operation mode. Possible options are
* - \ref TIMER_ONESHOT_MODE
* - \ref TIMER_PERIODIC_MODE
* - \ref TIMER_TOGGLE_MODE
* - \ref TIMER_CONTINUOUS_MODE
* @param[in] u32Freq Target working frequency
* @return Real Timer working frequency
* @note After calling this API, Timer is \b NOT running yet. But could start timer running be calling
* \ref TIMER_Start macro or program registers directly
*/
uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
{
uint32_t u32Clk = TIMER_GetModuleClock(timer);
uint32_t u32Cmpr = 0, u32Prescale = 0;
// Fastest possible timer working freq is u32Clk / 2. While cmpr = 2, pre-scale = 0
if(u32Freq > (u32Clk / 2)) {
u32Cmpr = 2;
} else {
if(u32Clk >= 0x2000000) {
u32Prescale = 3; // real prescaler value is 4
u32Clk >>= 2;
} else if(u32Clk >= 0x1000000) {
u32Prescale = 1; // real prescaler value is 2
u32Clk >>= 1;
}
u32Cmpr = u32Clk / u32Freq;
}
timer->CMPR = u32Cmpr;
timer->PRECNT = u32Prescale;
timer->CTL = u32Mode;
return(u32Clk / (u32Cmpr * (u32Prescale + 1)));
}
/**
* @brief This API stops Timer counting and disable the Timer interrupt function
* @param[in] timer The base address of Timer module
* @return None
*/
void TIMER_Close(TIMER_T *timer)
{
timer->CTL = 0;
timer->IER = 0;
}
/**
* @brief This API is used to create a delay loop for u32usec micro seconds
* @param[in] timer The base address of Timer module
* @param[in] u32Usec Delay period in micro seconds with 10 usec every step. Valid values are between 10~1000000 (10 micro second ~ 1 second)
* @return None
* @note This API overwrites the register setting of the timer used to count the delay time.
* @note This API use polling mode. So there is no need to enable interrupt for the timer module used to generate delay
*/
void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec)
{
uint32_t u32Clk = TIMER_GetModuleClock(timer);
uint32_t u32Prescale = 0, delay = SystemCoreClock / u32Clk;
long long u64Cmpr;
// Clear current timer configuration
timer->CTL = 0;
if(u32Clk == 10000) { // min delay is 100us if timer clock source is LIRC 10k
u32Usec = ((u32Usec + 99) / 100) * 100;
} else { // 10 usec every step
u32Usec = ((u32Usec + 9) / 10) * 10;
}
if(u32Clk >= 0x2000000) {
u32Prescale = 3; // real prescaler value is 4
u32Clk >>= 2;
} else if(u32Clk >= 0x1000000) {
u32Prescale = 1; // real prescaler value is 2
u32Clk >>= 1;
}
// u32Usec * u32Clk might overflow if using uint32_t
u64Cmpr = ((long long)u32Usec * (long long)u32Clk) / (long long)1000000;
timer->CMPR = (uint32_t)u64Cmpr;
timer->PRECNT = u32Prescale;
timer->CTL = TIMER_CTL_TMR_EN_Msk; // one shot mode
// When system clock is faster than timer clock, it is possible timer active bit cannot set in time while we check it.
// And the while loop below return immediately, so put a tiny delay here allowing timer start counting and raise active flag.
for(; delay > 0; delay--) {
__NOP();
}
while(timer->CTL & TIMER_CTL_TMR_ACT_Msk);
}
/**
* @brief This API is used to enable timer capture function with specified mode and capture edge
* @param[in] timer The base address of Timer module
* @param[in] u32CapMode Timer capture mode. Could be
* - \ref TIMER_CAPTURE_FREE_COUNTING_MODE
* - \ref TIMER_CAPTURE_TRIGGER_COUNTING_MODE
* - \ref TIMER_CAPTURE_COUNTER_RESET_MODE
* @param[in] u32Edge Timer capture edge. Possible values are
* - \ref TIMER_CAPTURE_FALLING_EDGE
* - \ref TIMER_CAPTURE_RISING_EDGE
* - \ref TIMER_CAPTURE_FALLING_THEN_RISING_EDGE
* - \ref TIMER_CAPTURE_RISING_THEN_FALLING_EDGE
* @return None
* @note Timer frequency should be configured separately by using \ref TIMER_Open API, or program registers directly
*/
void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge)
{
timer->CTL = (timer->CTL & ~(TIMER_CTL_TCAP_MODE_Msk |
TIMER_CTL_TCAP_CNT_MODE_Msk |
TIMER_CTL_TCAP_EDGE_Msk)) |
u32CapMode | u32Edge | TIMER_CTL_TCAP_EN_Msk;
}
/**
* @brief This API is used to disable the Timer capture function
* @param[in] timer The base address of Timer module
* @return None
*/
void TIMER_DisableCapture(TIMER_T *timer)
{
timer->CTL &= ~TIMER_CTL_TCAP_EN_Msk;
}
/**
* @brief This function is used to enable the Timer counter function with specify detection edge
* @param[in] timer The base address of Timer module
* @param[in] u32Edge Detection edge of counter pin. Could be ether
* - \ref TIMER_COUNTER_RISING_EDGE, or
* - \ref TIMER_COUNTER_FALLING_EDGE
* @return None
* @note Timer compare value should be configured separately by using \ref TIMER_SET_CMP_VALUE macro or program registers directly
*/
void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge)
{
timer->CTL = (timer->CTL & ~TIMER_CTL_EVENT_EDGE_Msk) | u32Edge;
timer->CTL |= TIMER_CTL_EVENT_EN_Msk;
}
/**
* @brief This API is used to disable the Timer event counter function.
* @param[in] timer The base address of Timer module
* @return None
*/
void TIMER_DisableEventCounter(TIMER_T *timer)
{
timer->CTL &= ~TIMER_CTL_EVENT_EN_Msk;
}
/**
* @brief This API is used to get the clock frequency of Timer
* @param[in] timer The base address of Timer module
* @return Timer clock frequency
* @note This API cannot return correct clock rate if timer source is external clock input.
*/
uint32_t TIMER_GetModuleClock(TIMER_T *timer)
{
uint32_t u32Src;
const uint32_t au32Clk[] = {__HXT, __LXT, __LIRC, 0}; // we don't know actual clock if external pin is clock source, set to 0 here
if(timer == TIMER0)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0_S_Msk) >> CLK_CLKSEL1_TMR0_S_Pos;
else if(timer == TIMER1)
u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1_S_Msk) >> CLK_CLKSEL1_TMR1_S_Pos;
else if(timer == TIMER2)
u32Src = (CLK->CLKSEL2 & CLK_CLKSEL2_TMR2_S_Msk) >> CLK_CLKSEL2_TMR2_S_Pos;
else // Timer 3
u32Src = (CLK->CLKSEL2 & CLK_CLKSEL2_TMR3_S_Msk) >> CLK_CLKSEL2_TMR3_S_Pos;
if(u32Src < 4)
return au32Clk[u32Src];
else
return __HIRC;
}
/**
* @brief This function is used to enable the Timer frequency counter function
* @param[in] timer The base address of Timer module. Can be \ref TIMER0 or \ref TIMER2
* @param[in] u32DropCount This parameter has no effect in Nano100 series BSP
* @param[in] u32Timeout This parameter has no effect in Nano100 series BSP
* @param[in] u32EnableInt Enable interrupt assertion after capture complete or not. Valid values are TRUE and FALSE
* @return None
* @details This function is used to calculate input event frequency. After enable
* this function, a pair of timers, TIMER0 and TIMER1, or TIMER2 and TIMER3
* will be configured for this function. The mode used to calculate input
* event frequency is mentioned as "Inter Timer Trigger Mode" in Technical
* Reference Manual
*/
void TIMER_EnableFreqCounter(TIMER_T *timer,
uint32_t u32DropCount,
uint32_t u32Timeout,
uint32_t u32EnableInt)
{
TIMER_T *t; // store the timer base to configure compare value
t = (timer == TIMER0) ? TIMER1 : TIMER3;
t->CMPR = 0xFFFFFF;
t->IER = u32EnableInt ? TIMER_IER_TCAP_IE_Msk : 0;
timer->CTL = TIMER_CTL_INTR_TRG_EN_Msk | TIMER_CTL_TMR_EN_Msk;
return;
}
/**
* @brief This function is used to disable the Timer frequency counter function.
* @param[in] timer The base address of Timer module
* @return None
*/
void TIMER_DisableFreqCounter(TIMER_T *timer)
{
timer->CTL &= ~TIMER_CTL_INTR_TRG_EN_Msk;
}
/**
* @brief This function is used to select the interrupt source used to trigger other modules.
* @param[in] timer The base address of Timer module
* @param[in] u32Src Selects the interrupt source to trigger other modules. Could be:
* - \ref TIMER_TIMEOUT_TRIGGER
* - \ref TIMER_CAPTURE_TRIGGER
* @return None
*/
void TIMER_SetTriggerSource(TIMER_T *timer, uint32_t u32Src)
{
timer->CTL = (timer->CTL & ~TIMER_CTL_CAP_TRG_EN_Msk) | u32Src;
}
/**
* @brief This function is used to set modules trigger by timer interrupt
* @param[in] timer The base address of Timer module
* @param[in] u32Mask The mask of modules (ADC, DAC and PDMA) trigger by timer. Is the combination of
* - \ref TIMER_CTL_PDMA_TEEN_Msk,
* - \ref TIMER_CTL_ADC_TEEN_Msk, and
* - \ref TIMER_CTL_DAC_TEEN_Msk,
* @return None
*/
void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask)
{
timer->CTL = (timer->CTL & ~(TIMER_CTL_PDMA_TEEN_Msk | TIMER_CTL_DAC_TEEN_Msk | TIMER_CTL_ADC_TEEN_Msk)) | u32Mask;
}
/*@}*/ /* end of group NANO100_TIMER_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_TIMER_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,325 @@
/**************************************************************************//**
* @file timer.h
* @version V1.00
* $Revision: 6 $
* $Date: 14/08/29 7:56p $
* @brief Nano100 series TIMER driver header file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __TIMER_H__
#define __TIMER_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_TIMER_Driver TIMER Driver
@{
*/
/** @addtogroup NANO100_TIMER_EXPORTED_CONSTANTS TIMER Exported Constants
@{
*/
#define TIMER_ONESHOT_MODE (0UL) /*!< Timer working in one shot mode */
#define TIMER_PERIODIC_MODE (1UL << TIMER_CTL_MODE_SEL_Pos) /*!< Timer working in periodic mode */
#define TIMER_TOGGLE_MODE (2UL << TIMER_CTL_MODE_SEL_Pos) /*!< Timer working in toggle mode */
#define TIMER_CONTINUOUS_MODE (3UL << TIMER_CTL_MODE_SEL_Pos) /*!< Timer working in continuous mode */
#define TIMER_CAPTURE_FREE_COUNTING_MODE (0UL) /*!< Free counting mode */
#define TIMER_CAPTURE_TRIGGER_COUNTING_MODE (TIMER_CTL_TCAP_CNT_MODE_Msk) /*!< Trigger counting mode */
#define TIMER_CAPTURE_COUNTER_RESET_MODE (TIMER_CTL_TCAP_MODE_Msk) /*!< Counter reset mode */
#define TIMER_CAPTURE_FALLING_EDGE (0UL) /*!< Falling edge trigger timer capture */
#define TIMER_CAPTURE_RISING_EDGE (1UL << TIMER_CTL_TCAP_EDGE_Pos) /*!< Rising edge trigger timer capture */
#define TIMER_CAPTURE_FALLING_THEN_RISING_EDGE (2UL << TIMER_CTL_TCAP_EDGE_Pos) /*!< Falling edge then rising edge trigger timer capture */
#define TIMER_CAPTURE_RISING_THEN_FALLING_EDGE (3UL << TIMER_CTL_TCAP_EDGE_Pos) /*!< Rising edge then falling edge trigger timer capture */
#define TIMER_COUNTER_RISING_EDGE (TIMER_CTL_EVENT_EDGE_Msk) /*!< Counter increase on rising edge */
#define TIMER_COUNTER_FALLING_EDGE (0UL) /*!< Counter increase on falling edge */
#define TIMER_TIMEOUT_TRIGGER (0UL) /*!< Timer timeout trigger other modules */
#define TIMER_CAPTURE_TRIGGER (TIMER_CTL_CAP_TRG_EN_Msk) /*!< Timer capture trigger other modules */
/*@}*/ /* end of group NANO100_TIMER_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_TIMER_EXPORTED_FUNCTIONS TIMER Exported Functions
@{
*/
/**
* @brief This macro is used to set new Timer compared value
* @param[in] timer The base address of Timer module
* @param[in] u32Value Timer compare value. Valid values are between 2 to 0xFFFFFF
* @return None
* \hideinitializer
*/
#define TIMER_SET_CMP_VALUE(timer, u32Value) ((timer)->CMPR = (u32Value))
/**
* @brief This macro is used to set new Timer prescale value
* @param[in] timer The base address of Timer module
* @param[in] u32Value Timer prescale value. Valid values are between 0 to 0xFF
* @return None
* @note Clock input is divided by (prescale + 1) before it is fed into timer
* \hideinitializer
*/
#define TIMER_SET_PRESCALE_VALUE(timer, u32Value) ((timer)->PRECNT = (u32Value))
/**
* @brief This macro is used to check if specify Timer is inactive or active
* @return timer is activate or inactivate
* @retval 0 Timer 24-bit up counter is inactive
* @retval 1 Timer 24-bit up counter is active
* \hideinitializer
*/
#define TIMER_IS_ACTIVE(timer) ((timer)->CTL & TIMER_CTL_TMR_ACT_Msk ? 1 : 0)
/**
* @brief This function is used to start Timer counting
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_Start(TIMER_T *timer)
{
timer->CTL |= TIMER_CTL_TMR_EN_Msk;
}
/**
* @brief This function is used to stop Timer counting
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_Stop(TIMER_T *timer)
{
timer->CTL &= ~TIMER_CTL_TMR_EN_Msk;
}
/**
* @brief This function is used to enable the Timer wake-up function
* @param[in] timer The base address of Timer module
* @return None
* @note To wake the system from power down mode, timer clock source must be ether LXT or LIRC
*/
__STATIC_INLINE void TIMER_EnableWakeup(TIMER_T *timer)
{
timer->CTL |= TIMER_CTL_WAKE_EN_Msk;
}
/**
* @brief This function is used to disable the Timer wake-up function
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_DisableWakeup(TIMER_T *timer)
{
timer->CTL &= ~TIMER_CTL_WAKE_EN_Msk;
}
/**
* @brief This function is used to enable the capture pin detection de-bounce function.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_EnableCaptureDebounce(TIMER_T *timer)
{
timer->CTL |= TIMER_CTL_TCAP_DEB_EN_Msk;
}
/**
* @brief This function is used to disable the capture pin detection de-bounce function.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_DisableCaptureDebounce(TIMER_T *timer)
{
timer->CTL &= ~TIMER_CTL_TCAP_DEB_EN_Msk;
}
/**
* @brief This function is used to enable the counter pin detection de-bounce function.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_EnableEventCounterDebounce(TIMER_T *timer)
{
timer->CTL |= TIMER_CTL_EVNT_DEB_EN_Msk;
}
/**
* @brief This function is used to disable the counter pin detection de-bounce function.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_DisableEventCounterDebounce(TIMER_T *timer)
{
timer->CTL &= ~TIMER_CTL_EVNT_DEB_EN_Msk;
}
/**
* @brief This function is used to enable the Timer time-out interrupt function.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_EnableInt(TIMER_T *timer)
{
timer->IER |= TIMER_IER_TMR_IE_Msk;
}
/**
* @brief This function is used to disable the Timer time-out interrupt function.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_DisableInt(TIMER_T *timer)
{
timer->IER &= ~TIMER_IER_TMR_IE_Msk;
}
/**
* @brief This function is used to enable the Timer capture trigger interrupt function.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_EnableCaptureInt(TIMER_T *timer)
{
timer->IER |= TIMER_IER_TCAP_IE_Msk;
}
/**
* @brief This function is used to disable the Timer capture trigger interrupt function.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_DisableCaptureInt(TIMER_T *timer)
{
timer->IER &= ~TIMER_IER_TCAP_IE_Msk;
}
/**
* @brief This function indicates Timer time-out interrupt occurred or not.
* @param[in] timer The base address of Timer module
* @return Timer time-out interrupt occurred or not
* @retval 0 Timer time-out interrupt did not occur
* @retval 1 Timer time-out interrupt occurred
*/
__STATIC_INLINE uint32_t TIMER_GetIntFlag(TIMER_T *timer)
{
return(timer->ISR & TIMER_ISR_TMR_IS_Msk ? 1 : 0);
}
/**
* @brief This function clears the Timer time-out interrupt flag.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_ClearIntFlag(TIMER_T *timer)
{
timer->ISR = TIMER_ISR_TMR_IS_Msk;
}
/**
* @brief This function indicates Timer capture interrupt occurred or not.
* @param[in] timer The base address of Timer module
* @return Timer capture interrupt occurred or not
* @retval 0 Timer capture interrupt did not occur
* @retval 1 Timer capture interrupt occurred
*/
__STATIC_INLINE uint32_t TIMER_GetCaptureIntFlag(TIMER_T *timer)
{
return(timer->ISR & TIMER_ISR_TCAP_IS_Msk ? 1 : 0);
}
/**
* @brief This function clears the Timer capture interrupt flag.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_ClearCaptureIntFlag(TIMER_T *timer)
{
timer->ISR = TIMER_ISR_TCAP_IS_Msk;
}
/**
* @brief This function indicates Timer has waked up system or not.
* @param[in] timer The base address of Timer module
* @return Timer has waked up system or not
* @retval 0 Timer did not wake up system
* @retval 1 Timer wake up system
*/
__STATIC_INLINE uint32_t TIMER_GetWakeupFlag(TIMER_T *timer)
{
return (timer->ISR & TIMER_ISR_TMR_WAKE_STS_Msk ? 1 : 0);
}
/**
* @brief This function clears the Timer wakeup interrupt flag.
* @param[in] timer The base address of Timer module
* @return None
*/
__STATIC_INLINE void TIMER_ClearWakeupFlag(TIMER_T *timer)
{
timer->ISR = TIMER_ISR_TMR_WAKE_STS_Msk;
}
/**
* @brief This function gets the Timer capture data.
* @param[in] timer The base address of Timer module
* @return Timer capture data value
*/
__STATIC_INLINE uint32_t TIMER_GetCaptureData(TIMER_T *timer)
{
return timer->TCAP;
}
/**
* @brief This function reports the current timer counter value.
* @param[in] timer The base address of Timer module
* @return Timer counter value
*/
__STATIC_INLINE uint32_t TIMER_GetCounter(TIMER_T *timer)
{
return timer->DR;
}
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);
void TIMER_EnableFreqCounter(TIMER_T *timer,
uint32_t u32DropCount,
uint32_t u32Timeout,
uint32_t u32EnableInt);
void TIMER_DisableFreqCounter(TIMER_T *timer);
void TIMER_SetTriggerSource(TIMER_T *timer, uint32_t u32Src);
void TIMER_SetTriggerTarget(TIMER_T *timer, uint32_t u32Mask);
/*@}*/ /* end of group NANO100_TIMER_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_TIMER_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__TIMER_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,408 @@
/**************************************************************************//**
* @file uart.c
* @version V1.00
* $Revision: 11 $
* $Date: 15/06/26 1:28p $
* @brief Nano100 series Smartcard UART mode (UART) driver source file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_UART_Driver UART Driver
@{
*/
/** @addtogroup NANO100_UART_EXPORTED_FUNCTIONS UART Exported Functions
@{
*/
/// @cond HIDDEN_SYMBOLS
extern uint32_t SysGet_PLLClockFreq(void);
/// @endcond /* HIDDEN_SYMBOLS */
/**
* @brief The function is used to clear UART specified interrupt flag.
*
* @param[in] uart The base address of UART module.
* @param[in] u32InterruptFlag The specified interrupt of UART module..
*
* @return None
*/
void UART_ClearIntFlag(UART_T* uart , uint32_t u32InterruptFlag)
{
if(u32InterruptFlag & UART_ISR_RLS_IS_Msk) { /* clear Receive Line Status Interrupt */
uart->FSR |= UART_FSR_BI_F_Msk | UART_FSR_FE_F_Msk | UART_FSR_FE_F_Msk;
uart->TRSR |= UART_TRSR_RS485_ADDET_F_Msk;
}
if(u32InterruptFlag & UART_ISR_MODEM_IS_Msk) /* clear Modem Interrupt */
uart->MCSR |= UART_MCSR_DCT_F_Msk;
if(u32InterruptFlag & UART_ISR_BUF_ERR_IS_Msk) { /* clear Buffer Error Interrupt */
uart->FSR |= UART_FSR_RX_OVER_F_Msk | UART_FSR_TX_OVER_F_Msk;
}
if(u32InterruptFlag & UART_ISR_WAKE_IS_Msk) { /* clear wake up Interrupt */
uart->ISR |= UART_ISR_WAKE_IS_Msk;
}
if(u32InterruptFlag & UART_ISR_ABAUD_IS_Msk) { /* clear auto-baud rate Interrupt */
uart->TRSR |= UART_TRSR_ABAUD_TOUT_F_Msk | UART_TRSR_ABAUD_F_Msk;
}
if(u32InterruptFlag & UART_ISR_LIN_IS_Msk) { /* clear LIN break Interrupt */
uart->TRSR |= UART_TRSR_LIN_TX_F_Msk | UART_TRSR_LIN_RX_F_Msk | UART_TRSR_BIT_ERR_F_Msk;
}
}
/**
* @brief The function is used to disable UART.
*
* @param[in] uart The base address of UART module.
*
* @return None
*/
void UART_Close(UART_T* uart)
{
uart->IER = 0;
}
/**
* @brief The function is used to disable UART auto flow control.
*
* @param[in] uart The base address of UART module.
*
* @return None
*/
void UART_DisableFlowCtrl(UART_T* uart)
{
uart->CTL &= ~(UART_CTL_AUTO_RTS_EN_Msk | UART_CTL_AUTO_CTS_EN_Msk);
}
/**
* @brief The function is used to disable UART specified interrupt and disable NVIC UART IRQ.
*
* @param[in] uart The base address of UART module.
* @param[in] u32InterruptFlag The specified interrupt of UART module.
* - \ref UART_IER_LIN_IE_Msk : LIN interrupt
* - \ref UART_IER_ABAUD_IE_Msk : Auto baudrate interrupt
* - \ref UART_IER_WAKE_IE_Msk : Wakeup interrupt
* - \ref UART_IER_ABAUD_IE_Msk : Auto Baud-rate interrupt
* - \ref UART_IER_BUF_ERR_IE_Msk : Buffer Error interrupt
* - \ref UART_IER_RTO_IE_Msk : Rx time-out interrupt
* - \ref UART_IER_MODEM_IE_Msk : Modem interrupt
* - \ref UART_IER_RLS_IE_Msk : Rx Line status interrupt
* - \ref UART_IER_THRE_IE_Msk : Tx empty interrupt
* - \ref UART_IER_RDA_IE_Msk : Rx ready interrupt
*
* @return None
*/
void UART_DisableInt(UART_T* uart, uint32_t u32InterruptFlag )
{
uart->IER &= ~ u32InterruptFlag;
}
/**
* @brief The function is used to Enable UART auto flow control.
*
* @param[in] uart The base address of UART module.
*
* @return None
*/
void UART_EnableFlowCtrl(UART_T* uart )
{
uart->MCSR |= UART_MCSR_LEV_RTS_Msk | UART_MCSR_LEV_CTS_Msk;
uart->CTL |= UART_CTL_AUTO_RTS_EN_Msk | UART_CTL_AUTO_CTS_EN_Msk;
}
/**
* @brief The function is used to enable UART specified interrupt and disable NVIC UART IRQ.
*
* @param[in] uart The base address of UART module.
* @param[in] u32InterruptFlag The specified interrupt of UART module:
* - \ref UART_IER_LIN_IE_Msk : LIN interrupt
* - \ref UART_IER_ABAUD_IE_Msk : Auto baudrate interrupt
* - \ref UART_IER_WAKE_IE_Msk : Wakeup interrupt
* - \ref UART_IER_ABAUD_IE_Msk : Auto Baud-rate interrupt
* - \ref UART_IER_BUF_ERR_IE_Msk : Buffer Error interrupt
* - \ref UART_IER_RTO_IE_Msk : Rx time-out interrupt
* - \ref UART_IER_MODEM_IE_Msk : Modem interrupt
* - \ref UART_IER_RLS_IE_Msk : Rx Line status interrupt
* - \ref UART_IER_THRE_IE_Msk : Tx empty interrupt
* - \ref UART_IER_RDA_IE_Msk : Rx ready interrupt
*
* @return None
*/
void UART_EnableInt(UART_T* uart, uint32_t u32InterruptFlag )
{
uart->IER |= u32InterruptFlag;
}
/**
* @brief This function use to enable UART function and set baud-rate.
*
* @param[in] uart The base address of UART module.
* @param[in] u32baudrate The baudrate of UART module.
*
* @return None
*/
void UART_Open(UART_T* uart, uint32_t u32baudrate)
{
uint8_t u8UartClkSrcSel;
uint32_t u32ClkTbl[4] = {__HXT, __LXT, 0, __HIRC12M};
uint32_t u32Baud_Div;
uint32_t u32SrcFreq;
uint32_t u32SrcFreqDiv;
u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART_S_Msk) >> CLK_CLKSEL1_UART_S_Pos;
u32SrcFreq = u32ClkTbl[u8UartClkSrcSel];
u32SrcFreqDiv = (((CLK->CLKDIV0 & CLK_CLKDIV0_UART_N_Msk) >> CLK_CLKDIV0_UART_N_Pos) + 1);
if(u32SrcFreq == 0) {
u32SrcFreq = SysGet_PLLClockFreq() / u32SrcFreqDiv;
} else {
u32SrcFreq = u32SrcFreq / u32SrcFreqDiv;
}
uart->FUN_SEL = UART_FUNC_SEL_UART;
uart->TLCTL = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1 |
UART_TLCTL_RFITL_1BYTE | UART_TLCTL_RTS_TRI_LEV_1BYTE;
if(u32baudrate != 0) {
u32Baud_Div = UART_BAUD_MODE0_DIVIDER(u32SrcFreq, u32baudrate);
if(u32Baud_Div > 0xFFFF)
uart->BAUD = (UART_BAUD_MODE1 | UART_BAUD_MODE1_DIVIDER(u32SrcFreq, u32baudrate));
else
uart->BAUD = (UART_BAUD_MODE0 | u32Baud_Div);
}
}
/**
* @brief The function is used to read Rx data from RX FIFO and the data will be stored in pu8RxBuf.
*
* @param[in] uart The base address of UART module.
* @param[out] pu8RxBuf The buffer to receive the data of receive FIFO.
* @param[in] u32ReadBytes The the read bytes number of data.
*
* @return u32Count: Receive byte count
*
*/
uint32_t UART_Read(UART_T* uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes)
{
uint32_t u32Count, u32delayno;
for(u32Count=0; u32Count < u32ReadBytes; u32Count++) {
u32delayno = 0;
while(uart->FSR & UART_FSR_RX_EMPTY_F_Msk) { /* Check RX empty => failed */
u32delayno++;
if( u32delayno >= 0x40000000 )
return FALSE;
}
pu8RxBuf[u32Count] = uart->RBR; /* Get Data from UART RX */
}
return u32Count;
}
/**
* @brief This function use to config UART line setting.
*
* @param[in] uart The base address of UART module.
* @param[in] u32baudrate The register value of baudrate of UART module.
* if u32baudrate = 0, UART baudrate will not change.
* @param[in] u32data_width The data length of UART module.
* @param[in] u32parity The parity setting (odd/even/none) of UART module.
* @param[in] u32stop_bits The stop bit length (1/1.5 bit) of UART module.
*
* @return None
*/
void UART_SetLine_Config(UART_T* uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits)
{
uint8_t u8UartClkSrcSel;
uint32_t u32ClkTbl[4] = {__HXT, __LXT, 0, __HIRC12M};
uint32_t u32Baud_Div = 0;
uint32_t u32SrcFreq;
uint32_t u32SrcFreqDiv;
u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART_S_Msk) >> CLK_CLKSEL1_UART_S_Pos;
u32SrcFreq = u32ClkTbl[u8UartClkSrcSel];
u32SrcFreqDiv = (((CLK->CLKDIV0 & CLK_CLKDIV0_UART_N_Msk) >> CLK_CLKDIV0_UART_N_Pos) + 1);
if(u32SrcFreq == 0) {
u32SrcFreq = SysGet_PLLClockFreq() / u32SrcFreqDiv;
} else {
u32SrcFreq = u32SrcFreq / u32SrcFreqDiv;
}
if(u32baudrate != 0) {
u32Baud_Div = UART_BAUD_MODE0_DIVIDER(u32SrcFreq, u32baudrate);
if(u32Baud_Div > 0xFFFF)
uart->BAUD = (UART_BAUD_MODE1 | UART_BAUD_MODE1_DIVIDER(u32SrcFreq, u32baudrate));
else
uart->BAUD = (UART_BAUD_MODE0 | u32Baud_Div);
}
uart->TLCTL = u32data_width | u32parity | u32stop_bits;
}
/**
* @brief This function use to set Rx timeout count.
*
* @param[in] uart The base address of UART module.
* @param[in] u32TOC Rx timeout counter.
*
* @return None
*/
void UART_SetTimeoutCnt(UART_T* uart, uint32_t u32TOC)
{
uart->TMCTL = (uart->TMCTL & ~UART_TMCTL_TOIC_Msk)| (u32TOC);
uart->IER |= UART_IER_RTO_IE_Msk;
}
/**
* @brief The function is used to configure IrDA relative settings. It consists of TX or RX mode and baudrate.
*
* @param[in] uart The base address of UART module.
* @param[in] u32Buadrate The baudrate of UART module.
* @param[in] u32Direction The direction(transmit:1/receive:0) of UART module in IrDA mode.
*
* @return None
*/
void UART_SelectIrDAMode(UART_T* uart, uint32_t u32Buadrate, uint32_t u32Direction)
{
uint8_t u8UartClkSrcSel;
uint32_t u32ClkTbl[4] = {__HXT, __LXT, 0, __HIRC12M};
uint32_t u32SrcFreq;
uint32_t u32SrcFreqDiv;
u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UART_S_Msk) >> CLK_CLKSEL1_UART_S_Pos;
u32SrcFreq = u32ClkTbl[u8UartClkSrcSel];
u32SrcFreqDiv = (((CLK->CLKDIV0 & CLK_CLKDIV0_UART_N_Msk) >> CLK_CLKDIV0_UART_N_Pos) + 1);
if(u32SrcFreq == 0) {
u32SrcFreq = SysGet_PLLClockFreq() / u32SrcFreqDiv;
} else {
u32SrcFreq = u32SrcFreq / u32SrcFreqDiv;
}
uart->BAUD = UART_BAUD_MODE1 | UART_BAUD_MODE1_DIVIDER(u32SrcFreq, u32Buadrate);
uart->IRCR &= ~UART_IRCR_INV_TX_Msk;
uart->IRCR |= UART_IRCR_INV_RX_Msk;
uart->IRCR = u32Direction ? uart->IRCR | UART_IRCR_TX_SELECT_Msk : uart->IRCR &~ UART_IRCR_TX_SELECT_Msk;
uart->FUN_SEL = (0x2 << UART_FUN_SEL_FUN_SEL_Pos);
}
/**
* @brief The function is used to set RS485 relative setting.
*
* @param[in] uart The base address of UART module.
* @param[in] u32Mode The operation mode( \ref UART_ALT_CTL_RS485_NMM_Msk / \ref UART_ALT_CTL_RS485_AUD_Msk / \ref UART_ALT_CTL_RS485_AAD_Msk).
* @param[in] u32Addr The RS485 address.
*
* @return None
*/
void UART_SelectRS485Mode(UART_T* uart, uint32_t u32Mode, uint32_t u32Addr)
{
uart->FUN_SEL = UART_FUNC_SEL_RS485;
uart->ALT_CTL = 0;
uart->ALT_CTL |= u32Mode | (u32Addr << UART_ALT_CTL_ADDR_PID_MATCH_Pos);
}
/**
* @brief Select and configure LIN function
*
* @param[in] uart The pointer of the specified UART module.
* @param[in] u32Mode The LIN direction :
* - UART_ALT_CTL_LIN_TX_EN_Msk
* - UART_ALT_CTL_LIN_RX_EN_Msk
* - (UART_ALT_CTL_LIN_TX_EN_Msk|UART_ALT_CTL_LIN_RX_EN_Msk)
* @param[in] u32BreakLength The breakfield length.
*
* @return None
*
* @details The function is used to set LIN relative setting.
*/
void UART_SelectLINMode(UART_T* uart, uint32_t u32Mode, uint32_t u32BreakLength)
{
/* Select LIN function mode */
uart->FUN_SEL = UART_FUNC_SEL_LIN;
/* Select LIN function setting : Tx enable, Rx enable and break field length */
uart->FUN_SEL = UART_FUNC_SEL_LIN;
uart->ALT_CTL &= ~(UART_ALT_CTL_LIN_TX_BCNT_Msk | UART_ALT_CTL_LIN_RX_EN_Msk | UART_ALT_CTL_LIN_TX_EN_Msk);
uart->ALT_CTL |= u32BreakLength & UART_ALT_CTL_LIN_TX_BCNT_Msk;
uart->ALT_CTL |= u32Mode;
}
/**
* @brief The function is to write data into TX buffer to transmit data by UART.
*
* @param[in] uart The base address of UART module.
* @param[in] pu8TxBuf The buffer to send the data to UART transmission FIFO.
* @param[in] u32WriteBytes The byte number of data.
*
* @return u32Count: transfer byte count
*/
uint32_t UART_Write(UART_T* uart,uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
{
uint32_t u32Count, u32delayno;
for(u32Count=0; u32Count != u32WriteBytes; u32Count++) {
u32delayno = 0;
while((uart->FSR & UART_FSR_TX_EMPTY_F_Msk) == 0) { /* Wait Tx empty and Time-out manner */
u32delayno++;
if( u32delayno >= 0x40000000 )
return FALSE;
}
uart->THR = pu8TxBuf[u32Count]; /* Send UART Data from buffer */
}
return u32Count;
}
/*@}*/ /* end of group NANO100_UART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_UART_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,379 @@
/**************************************************************************//**
* @file uart.h
* @version V1.00
* $Revision: 9 $
* $Date: 15/06/26 1:36p $
* @brief Nano100 Series uart control header file.
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __UART_H__
#define __UART_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_UART_Driver UART Driver
@{
*/
/** @addtogroup NANO100_UART_EXPORTED_CONSTANTS UART Exported Constants
@{
*/
/*---------------------------------------------------------------------------------------------------------*/
/* UA_LCR constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_WORD_LEN_5 (0) /*!< UART_TLCTL setting to set UART word length to 5 bits */
#define UART_WORD_LEN_6 (1) /*!< UART_TLCTL setting to set UART word length to 6 bits */
#define UART_WORD_LEN_7 (2) /*!< UART_TLCTL setting to set UART word length to 7 bits */
#define UART_WORD_LEN_8 (3) /*!< UART_TLCTL setting to set UART word length to 8 bits */
#define UART_PARITY_NONE (0x0 << UART_TLCTL_PBE_Pos) /*!< UART_TLCTL setting to set UART as no parity */
#define UART_PARITY_ODD (0x1 << UART_TLCTL_PBE_Pos) /*!< UART_TLCTL setting to set UART as odd parity */
#define UART_PARITY_EVEN (0x3 << UART_TLCTL_PBE_Pos) /*!< UART_TLCTL setting to set UART as even parity */
#define UART_PARITY_MARK (0x5 << UART_TLCTL_PBE_Pos) /*!< UART_TLCTL setting to keep parity bit as '1' */
#define UART_PARITY_SPACE (0x7 << UART_TLCTL_PBE_Pos) /*!< UART_TLCTL setting to keep parity bit as '0' */
#define UART_STOP_BIT_1 (0x0 << UART_TLCTL_NSB_Pos) /*!< UART_TLCTL setting for one stop bit */
#define UART_STOP_BIT_1_5 (0x1 << UART_TLCTL_NSB_Pos) /*!< UART_TLCTL setting for 1.5 stop bit when 5-bit word length */
#define UART_STOP_BIT_2 (0x1 << UART_TLCTL_NSB_Pos) /*!< UART_TLCTL setting for two stop bit when 6, 7, 8-bit word length */
#define UART_TLCTL_RFITL_1BYTE (0x0 << UART_TLCTL_RFITL_Pos) /*!< UART_TLCTL setting to set RX FIFO Trigger Level to 1 bit */
#define UART_TLCTL_RFITL_4BYTES (0x1 << UART_TLCTL_RFITL_Pos) /*!< UART_TLCTL setting to set RX FIFO Trigger Level to 4 bits */
#define UART_TLCTL_RFITL_8BYTES (0x2 << UART_TLCTL_RFITL_Pos) /*!< UART_TLCTL setting to set RX FIFO Trigger Level to 8 bits */
#define UART_TLCTL_RFITL_14BYTES (0x3 << UART_TLCTL_RFITL_Pos) /*!< UART_TLCTL setting to set RX FIFO Trigger Level to 14 bits */
#define UART_TLCTL_RTS_TRI_LEV_1BYTE (0x0 << UART_TLCTL_RTS_TRI_LEV_Pos) /*!< UART_TLCTL setting to set RTS Trigger Level to 1 bit */
#define UART_TLCTL_RTS_TRI_LEV_4BYTES (0x1 << UART_TLCTL_RTS_TRI_LEV_Pos) /*!< UART_TLCTL setting to set RTS Trigger Level to 4 bits */
#define UART_TLCTL_RTS_TRI_LEV_8BYTES (0x2 << UART_TLCTL_RTS_TRI_LEV_Pos) /*!< UART_TLCTL setting to set RTS Trigger Level to 8 bits */
#define UART_TLCTL_RTS_TRI_LEV_14BYTES (0x3 << UART_TLCTL_RTS_TRI_LEV_Pos) /*!< UART_TLCTL setting to set RTS Trigger Level to 14 bits */
/*---------------------------------------------------------------------------------------------------------*/
/* UART RTS LEVEL TRIGGER constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_RTS_IS_HIGH_LEV_TRG (0x1 << UART_MCSR_LEV_RTS_Pos) /*!< Set RTS is High Level Trigger */
#define UART_RTS_IS_LOW_LEV_TRG (0x0 << UART_MCSR_LEV_RTS_Pos) /*!< Set RTS is Low Level Trigger */
/*---------------------------------------------------------------------------------------------------------*/
/* UA_FUNC_SEL constants definitions */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_FUNC_SEL_UART (0x0 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UART_FUN_SEL setting to set UART Function (Default) */
#define UART_FUNC_SEL_LIN (0x1 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UART_FUN_SEL setting to set LIN Function */
#define UART_FUNC_SEL_IrDA (0x2 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UART_FUN_SEL setting to set IrDA Function */
#define UART_FUNC_SEL_RS485 (0x3 << UART_FUN_SEL_FUN_SEL_Pos) /*!< UART_FUN_SEL setting to set RS485 Function */
/*@}*/ /* end of group NANO100_UART_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_UART_EXPORTED_FUNCTIONS UART Exported Functions
@{
*/
/**
* @brief Calculate UART baudrate mode0 divider
*
* @param None
*
* @return UART baudrate mode0 register setting value
*
*/
#define UART_BAUD_MODE0 (0)
/**
* @brief Calculate UART baudrate mode0 divider
*
* @param None
*
* @return UART baudrate mode1 register setting value
*
*/
#define UART_BAUD_MODE1 (UART_BAUD_DIV_16_EN_Msk)
/**
* @brief Calculate UART baudrate mode0 divider
*
* @param[in] u32SrcFreq UART clock frequency
* @param[in] u32BaudRate Baudrate of UART module
*
* @return UART baudrate mode1 divider
*
*/
#define UART_BAUD_MODE1_DIVIDER(u32SrcFreq, u32BaudRate) (((u32SrcFreq + (u32BaudRate*8)) / u32BaudRate >> 4)-1)
/**
* @brief Calculate UART baudrate mode2 divider
*
* @param[in] u32SrcFreq UART clock frequency
* @param[in] u32BaudRate Baudrate of UART module
*
* @return UART baudrate mode0 divider
*/
#define UART_BAUD_MODE0_DIVIDER(u32SrcFreq, u32BaudRate) (((u32SrcFreq + (u32BaudRate/2)) / u32BaudRate)-1)
/**
* @brief Write Data to Tx data register
*
* @param[in] uart The base address of UART module.
* @param[in] u8Data Data byte to transmit
*
* @return None
*/
#define UART_WRITE(uart, u8Data) (uart->THR = (u8Data))
/**
* @brief Read Rx data register
*
* @param[in] uart The base address of UART module.
*
* @return The oldest data byte in RX FIFO
*/
#define UART_READ(uart) (uart->RBR)
/**
* @brief Get Tx empty register value.
*
* @param[in] uart The base address of UART module
*
* @return Tx empty register value.
*/
#define UART_GET_TX_EMPTY(uart) (uart->FSR & UART_FSR_TX_EMPTY_F_Msk)
/**
* @brief Get Rx empty register value.
*
* @param[in] uart The base address of UART module
*
* @return Rx empty register value.
*/
#define UART_GET_RX_EMPTY(uart) (uart->FSR & UART_FSR_RX_EMPTY_F_Msk)
/**
* @brief Check specified uart port transmission is over.
*
* @param[in] uart The base address of UART module
*
* @return TE_Flag.
*/
#define UART_IS_TX_EMPTY(uart) ((uart->FSR & UART_FSR_TE_F_Msk) >> UART_FSR_TE_F_Pos)
/**
* @brief Wait specified uart port transmission is over
*
* @param[in] uart The base address of UART module
*
* @return None
*/
#define UART_WAIT_TX_EMPTY(uart) while(!(((uart->FSR) & UART_FSR_TX_EMPTY_F_Msk) >> UART_FSR_TX_EMPTY_F_Pos))
/**
* @brief Check RDA_IF is set or not
*
* @param[in] uart The base address of UART module
*
* @return
* 0 : The number of bytes in the RX FIFO is less than the RFITL
* 1 : The number of bytes in the RX FIFO equals or larger than RFITL
*/
#define UART_IS_RX_READY(uart) ((uart->ISR & UART_ISR_RDA_IS_Msk)>>UART_ISR_RDA_IS_Pos)
/**
* @brief Check TX FIFO is full or not
*
* @param[in] uart The base address of UART module
*
* @return
* 1 = TX FIFO is full
* 0 = TX FIFO is not full
*/
#define UART_IS_TX_FULL(uart) ((uart->FSR & UART_FSR_TX_FULL_F_Msk)>>UART_FSR_TX_FULL_F_Pos)
/**
* @brief Check RX FIFO is full or not
*
* @param[in] uart The base address of UART module
*
* @return
* 1 = RX FIFO is full
* 0 = RX FIFO is not full
*
*/
#define UART_IS_RX_FULL(uart) ((uart->FSR & UART_FSR_RX_FULL_F_Msk)>>UART_FSR_RX_FULL_F_Pos)
/**
* @brief Get Tx full register value
*
* @param[in] uart The base address of UART module
*
* @return Tx full register value
*/
#define UART_GET_TX_FULL(uart) (uart->FSR & UART_FSR_TX_FULL_F_Msk)
/**
* @brief Get Rx full register value
*
* @param[in] uart The base address of UART module
*
* @return Rx full register value
*/
#define UART_GET_RX_FULL(uart) (uart->FSR & UART_FSR_RX_FULL_F_Msk)
/**
* @brief Enable specified interrupt
*
* @param[in] uart The base address of UART module
* @param[in] u32eIntSel Interrupt type select
* - \ref UART_IER_LIN_IE_Msk : LIN interrupt
* - \ref UART_IER_ABAUD_IE_Msk : Auto baudrate interrupt
* - \ref UART_IER_WAKE_IE_Msk : Wakeup interrupt
* - \ref UART_IER_BUF_ERR_IE_Msk : Buffer Error interrupt
* - \ref UART_IER_RTO_IE_Msk : Rx time-out interrupt
* - \ref UART_IER_MODEM_IE_Msk : Modem interrupt
* - \ref UART_IER_RLS_IE_Msk : Rx Line status interrupt
* - \ref UART_IER_THRE_IE_Msk : Tx empty interrupt
* - \ref UART_IER_RDA_IE_Msk : Rx ready interrupt
*
* @return None
*/
#define UART_ENABLE_INT(uart, u32eIntSel) (uart->IER |= (u32eIntSel))
/**
* @brief Disable specified interrupt
*
* @param[in] uart The base address of UART module
* @param[in] u32eIntSel Interrupt type select
* - \ref UART_IER_LIN_IE_Msk : LIN interrupt
* - \ref UART_IER_ABAUD_IE_Msk : Auto baudrate interrupt
* - \ref UART_IER_WAKE_IE_Msk : Wakeup interrupt
* - \ref UART_IER_BUF_ERR_IE_Msk : Buffer Error interrupt
* - \ref UART_IER_RTO_IE_Msk : Rx time-out interrupt
* - \ref UART_IER_MODEM_IE_Msk : Modem interrupt
* - \ref UART_IER_RLS_IE_Msk : Rx Line status interrupt
* - \ref UART_IER_THRE_IE_Msk : Tx empty interrupt
* - \ref UART_IER_RDA_IE_Msk : Rx ready interrupt
* @return None
*/
#define UART_DISABLE_INT(uart, u32eIntSel) (uart->IER &= ~ (u32eIntSel))
/**
* @brief Get specified interrupt flag/status
*
* @param[in] uart The base address of UART module
* @param[in] u32eIntTypeFlag Interrupt Type Flag,should be
* - \ref UART_ISR_LIN_IS_Msk : LIN interrupt flag
* - \ref UART_ISR_ABAUD_IS_Msk : Auto baudrate interrupt flag
* - \ref UART_ISR_WAKE_IS_Msk : Wakeup interrupt flag
* - \ref UART_ISR_BUF_ERR_IS_Msk : Buffer Error interrupt flag
* - \ref UART_ISR_RTO_IS_Msk : Rx time-out interrupt flag
* - \ref UART_ISR_MODEM_IS_Msk : Modem interrupt flag
* - \ref UART_ISR_RLS_IS_Msk : Rx Line status interrupt flag
* - \ref UART_ISR_THRE_IS_Msk : Tx empty interrupt flag
* - \ref UART_ISR_RDA_IS_Msk : Rx ready interrupt flag
*
* @return
* 0 = The specified interrupt is not happened.
* 1 = The specified interrupt is happened.
*/
#define UART_GET_INT_FLAG(uart,u32eIntTypeFlag) ((uart->ISR & (u32eIntTypeFlag))?1:0)
/**
* @brief Set RTS pin is low
*
* @param[in] uart The base address of UART module
* @return None
*/
__INLINE void UART_CLEAR_RTS(UART_T* uart)
{
uart->MCSR |= UART_MCSR_LEV_RTS_Msk;
}
/**
* @brief Set RTS pin is high
*
* @param[in] uart The base address of UART module
* @return None
*/
__INLINE void UART_SET_RTS(UART_T* uart)
{
uart->MCSR &= ~UART_MCSR_LEV_RTS_Msk;
}
/**
* @brief Clear RS-485 Address Byte Detection Flag
*
* @param[in] uart The base address of UART module
* @return None
*/
#define UART_RS485_CLEAR_ADDR_FLAG(uart) (uart->TRSR |= UART_TRSR_RS485_ADDET_F_Msk)
/**
* @brief Get RS-485 Address Byte Detection Flag
*
* @param[in] uart The base address of UART module
* @return RS-485 Address Byte Detection Flag
*/
#define UART_RS485_GET_ADDR_FLAG(uart) ((uart->TRSR & UART_TRSR_RS485_ADDET_F_Msk) >> UART_TRSR_RS485_ADDET_F_Pos)
void UART_ClearIntFlag(UART_T* uart , uint32_t u32InterruptFlag);
void UART_Close(UART_T* uart );
void UART_DisableFlowCtrl(UART_T* uart );
void UART_DisableInt(UART_T* uart, uint32_t u32InterruptFlag );
void UART_EnableFlowCtrl(UART_T* uart );
void UART_EnableInt(UART_T* uart, uint32_t u32InterruptFlag );
void UART_Open(UART_T* uart, uint32_t u32baudrate);
uint32_t UART_Read(UART_T* uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes);
void UART_SetLine_Config(UART_T* uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits);
void UART_SetTimeoutCnt(UART_T* uart, uint32_t u32TOC);
void UART_SelectIrDAMode(UART_T* uart, uint32_t u32Buadrate, uint32_t u32Direction);
void UART_SelectRS485Mode(UART_T* uart, uint32_t u32Mode, uint32_t u32Addr);
void UART_SelectLINMode(UART_T* uart, uint32_t u32Mode, uint32_t u32BreakLength);
uint32_t UART_Write(UART_T* uart,uint8_t *pu8TxBuf, uint32_t u32WriteBytes);
/*@}*/ /* end of group NANO100_UART_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_UART_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__UART_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,526 @@
/******************************************************************************
* @file usbd.c
* @brief NANO100 series USBD driver Sample file
* @version 2.0.0
* @date 20, September, 2014
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
/*!<Includes */
#include <string.h>
#include "nano100Series.h"
/*--------------------------------------------------------------------------*/
/* Global variables for Control Pipe */
uint8_t g_usbd_SetupPacket[8] = {0};
volatile uint8_t g_usbd_RemoteWakeupEn = 0; /*!< Remote wake up function enable flag */
/**
* @cond HIDDEN_SYMBOLS
*/
static volatile uint8_t *g_usbd_CtrlInPointer = 0;
static volatile uint32_t g_usbd_CtrlInSize = 0;
static volatile uint8_t *g_usbd_CtrlOutPointer = 0;
static volatile uint32_t g_usbd_CtrlOutSize = 0;
static volatile uint32_t g_usbd_CtrlOutSizeLimit = 0;
static volatile uint32_t g_usbd_UsbAddr = 0;
static volatile uint32_t g_usbd_CtrlMaxPktSize = 8;
static volatile uint32_t g_usbd_UsbAltInterface = 0;
volatile uint32_t g_usbd_UsbConfig = 0;
/**
* @endcond
*/
S_USBD_INFO_T *g_usbd_sInfo;
VENDOR_REQ g_usbd_pfnVendorRequest = NULL;
CLASS_REQ g_usbd_pfnClassRequest = NULL;
SET_INTERFACE_REQ g_usbd_pfnSetInterface = NULL;
uint32_t g_u32EpStallLock = 0; /*!< Bit map flag to lock specified EP when SET_FEATURE */
/**
* @brief USBD Initial, Enable clock and reset USB.
* @param[in] param Descriptor
* @param[in] pfnClassReq Class Request Callback Function
* @param[in] pfnSetInterface SetInterface Request Callback Function
* @retval None.
*/
void USBD_Open(S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface)
{
g_usbd_sInfo = param;
g_usbd_pfnClassRequest = pfnClassReq;
g_usbd_pfnSetInterface = pfnSetInterface;
/* get EP0 maximum packet size */
g_usbd_CtrlMaxPktSize = g_usbd_sInfo->gu8DevDesc[7];
/* Initial USB engine */
USBD->CTL = 0x29f;
USBD->PDMA |= USBD_PDMA_BYTEM_Msk;
/* Force SE0, and then clear it to connect*/
USBD_SET_SE0();
}
/**
* @brief USBD Start
*
* @param None
*
* @return None
*
* @details This function is used to start transfer
*/
void USBD_Start(void)
{
/* Enable USB-related interrupts. */
USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP);
CLK_SysTickDelay(100000);
USBD_CLR_SE0();
}
/**
* @brief Get Setup Packet
*
* @param[in] buf Buffer pointer to store setup packet
*
* @return None
*
* @details This function is used to get Setup packet.
*/
void USBD_GetSetupPacket(uint8_t *buf)
{
USBD_MemCopy(buf, g_usbd_SetupPacket, 8);
}
/**
* @brief Process Setup Packet
*
* @param None
*
* @return None
*
* @details This function is used to process Setup packet.
*/
void USBD_ProcessSetupPacket(void)
{
// Setup packet process
USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8);
switch (g_usbd_SetupPacket[0] & 0x60) { /* request type */
case REQ_STANDARD: { // Standard
USBD_StandardRequest();
break;
}
case REQ_CLASS: { // Class
if (g_usbd_pfnClassRequest != NULL) {
g_usbd_pfnClassRequest();
}
break;
}
case REQ_VENDOR: { // Vendor
if (g_usbd_pfnVendorRequest != NULL) {
g_usbd_pfnVendorRequest();
}
break;
}
default: { // reserved
/* Setup error, stall the device */
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
break;
}
}
}
/**
* @brief Get Descriptor request
*
* @param None
*
* @return None
*
* @details This function is used to process GetDescriptor request.
*/
void USBD_GetDescriptor(void)
{
uint32_t u32Len;
u32Len = 0;
u32Len = g_usbd_SetupPacket[7];
u32Len <<= 8;
u32Len += g_usbd_SetupPacket[6];
switch (g_usbd_SetupPacket[3]) {
// Get Device Descriptor
case DESC_DEVICE: {
u32Len = Minimum(u32Len, LEN_DEVICE);
USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8DevDesc, u32Len);
USBD_PrepareCtrlOut(0,0);
break;
}
// Get Configuration Descriptor
case DESC_CONFIG: {
uint32_t u32TotalLen;
u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3];
u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8);
u32Len = Minimum(u32Len, u32TotalLen);
USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8ConfigDesc, u32Len);
USBD_PrepareCtrlOut(0,0);
break;
}
// Get HID Descriptor
case DESC_HID: {
/* CV3.0 HID Class Descriptor Test,
Need to indicate index of the HID Descriptor within gu8ConfigDescriptor, specifically HID Composite device. */
uint32_t u32ConfigDescOffset; // u32ConfigDescOffset is configuration descriptor offset (HID descriptor start index)
u32Len = Minimum(u32Len, LEN_HID);
u32ConfigDescOffset = g_usbd_sInfo->gu32ConfigHidDescIdx[g_usbd_SetupPacket[4]];
USBD_PrepareCtrlIn((uint8_t *)&g_usbd_sInfo->gu8ConfigDesc[u32ConfigDescOffset], u32Len);
USBD_PrepareCtrlOut(0,0);
break;
}
// Get Report Descriptor
case DESC_HID_RPT: {
u32Len = Minimum(u32Len, g_usbd_sInfo->gu32HidReportSize[g_usbd_SetupPacket[4]]);
USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8HidReportDesc[g_usbd_SetupPacket[4]], u32Len);
USBD_PrepareCtrlOut(0,0);
break;
}
// Get String Descriptor
case DESC_STRING: {
// Get String Descriptor
if(g_usbd_SetupPacket[2] < 4) {
u32Len = Minimum(u32Len, g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]][0]);
USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]], u32Len);
USBD_PrepareCtrlOut(0, 0);
} else {
// Not support. Reply STALL.
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
}
break;
}
default:
// Not support. Reply STALL.
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
break;
}
}
/**
* @brief Process USB standard request
*
* @param None
*
* @return None
*
* @details This function is used to process USB Standard Request.
*/
void USBD_StandardRequest(void)
{
/* clear global variables for new request */
g_usbd_CtrlInPointer = 0;
g_usbd_CtrlInSize = 0;
if (g_usbd_SetupPacket[0] & 0x80) { /* request data transfer direction */
// Device to host
switch (g_usbd_SetupPacket[1]) {
case GET_CONFIGURATION: {
// Return current configuration setting
/* Data stage */
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbConfig;
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 1);
/* Status stage */
USBD_PrepareCtrlOut(0,0);
break;
}
case GET_DESCRIPTOR: {
USBD_GetDescriptor();
break;
}
case GET_INTERFACE: {
// Return current interface setting
/* Data stage */
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbAltInterface;
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 1);
/* Status stage */
USBD_PrepareCtrlOut(0,0);
break;
}
case GET_STATUS: {
// Device
if(g_usbd_SetupPacket[0] == 0x80) {
uint8_t u8Tmp;
u8Tmp = 0;
if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x40) u8Tmp |= 1; // Self-Powered/Bus-Powered.
if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x20) u8Tmp |= (g_usbd_RemoteWakeupEn << 1); // Remote wake up
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = u8Tmp;
}
// Interface
else if (g_usbd_SetupPacket[0] == 0x81)
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0;
// Endpoint
else if (g_usbd_SetupPacket[0] == 0x82) {
uint8_t ep = g_usbd_SetupPacket[4] & 0xF;
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = USBD_GetStall(ep)? 1 : 0;
}
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0) + 1) = 0;
/* Data stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 2);
/* Status stage */
USBD_PrepareCtrlOut(0,0);
break;
}
default: {
/* Setup error, stall the device */
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
break;
}
}
} else {
// Host to device
switch (g_usbd_SetupPacket[1]) {
case CLEAR_FEATURE: {
if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) {
int32_t epNum, i;
/* EP number stall is not allow to be clear in MSC class "Error Recovery Test".
a flag: g_u32EpStallLock is added to support it */
epNum = g_usbd_SetupPacket[4] & 0xF;
for(i = 0; i < USBD_MAX_EP; i++) {
if(((USBD->EP[i].CFG & 0xF) == epNum) && ((g_u32EpStallLock & (1 << i)) == 0))
USBD->EP[i].CFG &= ~(USBD_CFG_SSTALL_Msk | USBD_CFG_DSQ_SYNC_Msk);
}
} else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP)
g_usbd_RemoteWakeupEn = 0;
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
break;
}
case SET_ADDRESS: {
g_usbd_UsbAddr = g_usbd_SetupPacket[2];
// DATA IN for end of setup
/* Status Stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
break;
}
case SET_CONFIGURATION: {
g_usbd_UsbConfig = g_usbd_SetupPacket[2];
if (g_usbd_UsbConfig == 0) {
int volatile i;
/* Reset PID DATA0 */
for (i=2; i<USBD_MAX_EP; i++)
USBD->EP[i].CFG &= ~USBD_CFG_DSQ_SYNC_Msk;
}
// DATA IN for end of setup
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
break;
}
case SET_FEATURE: {
if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT)
USBD_SetStall(g_usbd_SetupPacket[4] & 0xF);
else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP)
g_usbd_RemoteWakeupEn = 1;
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
break;
}
case SET_INTERFACE: {
g_usbd_UsbAltInterface = g_usbd_SetupPacket[2];
if (g_usbd_pfnSetInterface != NULL)
g_usbd_pfnSetInterface(g_usbd_UsbAltInterface);
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
break;
}
default: {
/* Setup error, stall the device */
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
break;
}
}
}
}
/**
* @brief Prepare Control IN transaction
*
* @param[in] pu8Buf Control IN data pointer
* @param[in] u32Size IN transfer size
*
* @return None
*
* @details This function is used to prepare Control IN transfer
*/
void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size)
{
if(u32Size > g_usbd_CtrlMaxPktSize) {
// Data size > MXPLD
g_usbd_CtrlInPointer = pu8Buf + g_usbd_CtrlMaxPktSize;
g_usbd_CtrlInSize = u32Size - g_usbd_CtrlMaxPktSize;
USBD_SET_DATA1(EP0);
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, g_usbd_CtrlMaxPktSize);
USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize);
} else {
// Data size <= MXPLD
g_usbd_CtrlInPointer = 0;
g_usbd_CtrlInSize = 0;
USBD_SET_DATA1(EP0);
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, u32Size);
USBD_SET_PAYLOAD_LEN(EP0, u32Size);
}
}
/**
* @brief Start Control IN transfer
*
* @param None
*
* @return None
*
* @details This function is used to start Control IN
*/
void USBD_CtrlIn(void)
{
if(g_usbd_CtrlInSize) {
// Process remained data
if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize) {
// Data size > MXPLD
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize);
USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize);
g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize;
g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize;
} else {
// Data size <= MXPLD
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlInSize);
USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlInSize);
g_usbd_CtrlInPointer = 0;
g_usbd_CtrlInSize = 0;
}
} else {
// In ACK for Set address
if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == SET_ADDRESS)) {
if((USBD_GET_ADDR() != g_usbd_UsbAddr) && (USBD_GET_ADDR() == 0)) {
USBD_SET_ADDR(g_usbd_UsbAddr);
}
}
// No more data for IN token
USBD_SET_PAYLOAD_LEN(EP0, 0);
}
}
/**
* @brief Prepare Control OUT transaction
*
* @param[in] pu8Buf Control OUT data pointer
* @param[in] u32Size OUT transfer size
*
* @return None
*
* @details This function is used to prepare Control OUT transfer
*/
void USBD_PrepareCtrlOut(uint8_t *pu8Buf, uint32_t u32Size)
{
g_usbd_CtrlOutPointer = pu8Buf;
g_usbd_CtrlOutSize = 0;
g_usbd_CtrlOutSizeLimit = u32Size;
USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize);
}
/**
* @brief Start Control OUT transfer
*
* @param None
*
* @return None
*
* @details This function is used to start Control OUT
*/
void USBD_CtrlOut(void)
{
uint32_t u32Size;
if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit) {
u32Size = USBD_GET_PAYLOAD_LEN(EP1);
USBD_MemCopy((uint8_t *)g_usbd_CtrlOutPointer, (uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1), u32Size);
g_usbd_CtrlOutPointer += u32Size;
g_usbd_CtrlOutSize += u32Size;
}
}
/**
* @brief Clear all software flags
*
* @param None
*
* @return None
*
* @details This function is used to clear all software control flag
*/
void USBD_SwReset(void)
{
int i;
// Reset all variables for protocol
g_usbd_CtrlInPointer = 0;
g_usbd_CtrlInSize = 0;
g_usbd_CtrlOutPointer = 0;
g_usbd_CtrlOutSize = 0;
g_usbd_CtrlOutSizeLimit = 0;
memset(g_usbd_SetupPacket, 0, 8);
/* Reset PID DATA0 */
for (i=0; i<USBD_MAX_EP; i++)
USBD->EP[i].CFG &= ~USBD_CFG_DSQ_SYNC_Msk;
// Reset USB device address
USBD_SET_ADDR(0);
}
/**
* @brief USBD Set Vendor Request
*
* @param[in] pfnVendorReq Vendor Request Callback Function
*
* @return None
*
* @details This function is used to set USBD vendor request callback function
*/
void USBD_SetVendorRequest(VENDOR_REQ pfnVendorReq)
{
g_usbd_pfnVendorRequest = pfnVendorReq;
}
void USBD_LockEpStall(uint32_t u32EpBitmap)
{
g_u32EpStallLock = u32EpBitmap;
}

View File

@ -0,0 +1,507 @@
/******************************************************************************
* @file usbd.h
* @brief NANO100 series USB driver header file
* @version 2.0.0
* @date 20, September, 2014
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef __USBD_H__
#define __USBD_H__
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_USBD_Driver USBD Driver
@{
*/
/** @addtogroup NANO100_USBD_EXPORTED_STRUCTS USBD Exported Structs
@{
*/
typedef struct s_usbd_info {
uint8_t *gu8DevDesc; /*!< Device descriptor */
uint8_t *gu8ConfigDesc; /*!< Config descriptor */
uint8_t **gu8StringDesc; /*!< Pointer for USB String Descriptor pointers */
uint8_t **gu8HidReportDesc; /*!< Pointer for HID Report descriptor */
uint32_t *gu32HidReportSize; /*!< Pointer for HID Report descriptor Size */
uint32_t *gu32ConfigHidDescIdx; /*!< Pointer for HID Descriptor start index */
} S_USBD_INFO_T;
/// @cond HIDDEN_SYMBOLS
extern S_USBD_INFO_T gsInfo;
/// @endcond /* HIDDEN_SYMBOLS */
/*@}*/ /* end of group NANO100_USBD_EXPORTED_STRUCTS */
/** @addtogroup NANO100_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 */
/// @cond HIDDEN_SYMBOLS
extern volatile uint32_t g_usbd_UsbConfig;
/*!<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
/// @endcond
#define USBD_WAKEUP_EN USBD_CTL_WAKEUP_EN_Msk /*!< USB Wake-up Enable */
#define USBD_DRVSE0 USBD_CTL_DRVSE0_Msk /*!< Drive SE0 */
#define USBD_DPPU_EN USBD_CTL_DPPU_EN_Msk /*!< USB D+ Pull-up Enable */
#define USBD_PWRDN USBD_CTL_PWRDB_Msk /*!< PHY Turn-On */
#define USBD_PHY_EN USBD_CTL_PHY_EN_Msk /*!< PHY Enable */
#define USBD_USB_EN USBD_CTL_USB_EN_Msk /*!< USB Enable */
#define USBD_INT_BUS USBD_INTEN_BUSEVT_IE_Msk /*!< USB Bus Event Interrupt */
#define USBD_INT_USB USBD_INTEN_USBEVT_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 /*!< USB Wake-up Interrupt */
#define USBD_INTSTS_WAKEUP USBD_INTSTS_WKEUP_STS_Msk /*!< USB Wakeup Interrupt Status */
#define USBD_INTSTS_FLDET USBD_INTSTS_FLD_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_BUSSTS_USBRST_Msk /*!< USB Bus Reset */
#define USBD_STATE_SUSPEND USBD_BUSSTS_SUSPEND_Msk /*!< USB Bus Suspend */
#define USBD_STATE_RESUME USBD_BUSSTS_RESUME_Msk /*!< USB Bus Resume */
#define USBD_STATE_TIMEOUT USBD_BUSSTS_TIMEOUT_Msk /*!< USB Bus Timeout */
#define USBD_CFG_SSTALL USBD_CFG_SSTALL_Msk /*!< Set Stall */
#define USBD_CFG_CSTALL USBD_CFG_CSTALL_Msk /*!< Clear Stall */
#define USBD_CFG_EPMODE_DISABLE (0ul << USBD_CFG_EPMODE_Pos)/*!< Endpoint Disable */
#define USBD_CFG_EPMODE_OUT (1ul << USBD_CFG_EPMODE_Pos)/*!< Out Endpoint */
#define USBD_CFG_EPMODE_IN (2ul << USBD_CFG_EPMODE_Pos)/*!< In Endpoint */
#define USBD_CFG_TYPE_ISO (1ul << USBD_CFG_ISOCH_Pos) /*!< Isochronous */
/*@}*/ /* end of group NANO100_USBD_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_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 USBD engine
* @param None
* @retval None
*/
#define USBD_ENABLE_USB() ((uint32_t)(USBD->CTL |= 0xF))
/**
* @brief Disable USBD engine
* @param None
* @retval None
*/
#define USBD_DISABLE_USB() ((uint32_t)(USBD->CTL &= ~USBD_USB_EN))
/**
* @brief Enable USBD PHY
* @param None
* @retval None
*/
#define USBD_ENABLE_PHY() ((uint32_t)(USBD->CTL |= USBD_PHY_EN))
/**
* @brief Disable USBD PHY
* @param None
* @retval None
*/
#define USBD_DISABLE_PHY() ((uint32_t)(USBD->CTL &= ~USBD_PHY_EN))
/**
* @brief Force USB PHY Transceiver to Drive SE0
* @param None
* @retval None
*/
#define USBD_SET_SE0() ((uint32_t)(USBD->CTL |= USBD_DRVSE0))
/**
* @brief Release SE0
* @param None
* @retval None
*/
#define USBD_CLR_SE0() ((uint32_t)(USBD->CTL &= ~USBD_DRVSE0))
/**
* @brief Set USBD address
* @param[in] addr host assign address number
* @retval None
*/
#define USBD_SET_ADDR(addr) (USBD->FADDR = (addr))
/**
* @brief Get USBD address
* @param None
* @retval USBD address
*/
#define USBD_GET_ADDR() ((uint32_t)(USBD->FADDR))
/**
* @brief Enable USBD interrupt
* @param[in] intr interrupt mask
* @retval None
*/
#define USBD_ENABLE_INT(intr) (USBD->INTEN |= (intr))
/**
* @brief Get USBD interrupt flag
* @param None
* @retval interrupt status
*/
#define USBD_GET_INT_FLAG() ((uint32_t)(USBD->INTSTS))
/**
* @brief Clear USBD interrupt
* @param[in] flag interrupt flag
* @retval None
*/
#define USBD_CLR_INT_FLAG(flag) (USBD->INTSTS = flag)
/**
* @brief Get USBD Endpoint status
* @param None
* @retval endpoint status
*/
#define USBD_GET_EP_FLAG() ((uint32_t)(USBD->EPSTS))
/**
* @brief Get USBD bus state
* @param None
* @retval bus status
*/
#define USBD_GET_BUS_STATE() ((uint32_t)(USBD->BUSSTS & 0xf))
/**
* @brief check cable connect state
* @param None
* @retval connect / disconnect
*/
#define USBD_IS_ATTACHED() ((uint32_t)(USBD->BUSSTS & USBD_BUSSTS_FLDET_Msk))
/**
* @brief Stop USB endpoint transaction
* @param[in] ep endpoint
* @retval None
*/
#define USBD_STOP_TRANSACTION(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) |= USBD_CFG_CLRRDY_Msk)
/**
* @brief Set USB data1 token
* @param[in] ep endpoint
* @retval None
*/
#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 token
* @param[in] ep endpoint
* @retval None
*/
#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 endpoint
* @param[in] size IN transfer length
* @retval None
*/
#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 endpoint
* @retval received data length
*/
#define USBD_GET_PAYLOAD_LEN(ep) ((uint32_t)*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].MXPLD + (uint32_t)((ep) << 4))))
/**
* @brief config endpoint
* @param[in] ep endpoint
* @param[in] config config value
* @retval None
*/
#define USBD_CONFIG_EP(ep, config) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) = (config))
/**
* @brief Set buffer for USB endpoint
* @param[in] ep endpoint
* @param[in] offset buffer offset
* @retval None
*/
#define USBD_SET_EP_BUF_ADDR(ep, offset) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].BUFSEG + (uint32_t)((ep) << 4))) = (offset))
/**
* @brief Get buffer for USB endpoint
* @param[in] ep endpoint
* @retval buffer offset
*/
#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.
*
* @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].CFG + (uint32_t)((ep) << 4))) |= USBD_CFG_SSTALL_Msk)
/**
* @brief Clear USB endpoint stall state
*
* @param[in] ep The USB endpoint ID.
*
* @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].CFG + (uint32_t)((ep) << 4))) &= ~USBD_CFG_SSTALL_Msk)
/**
* @brief Get USB endpoint stall state
*
* @param[in] ep The USB endpoint ID.
*
* @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].CFG + (uint32_t)((ep) << 4))) & USBD_CFG_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 return STALL token.
*/
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) {
*((__IO uint32_t *) (u32CfgAddr)) = (u32Cfg | USBD_CFG_SSTALL);
break;
}
}
}
/**
* @brief Clear USB endpoint stall state
*
* @param[in] epnum USB endpoint number
* @return None
*
* @details Clear USB endpoint stall state, endpoint will return 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) {
*((__IO uint32_t *) (u32CfgAddr)) = (u32Cfg & ~USBD_CFG_SSTALL);
break;
}
}
}
/**
* @brief Get USB endpoint stall state
*
* @param[in] epnum USB endpoint number
* @retval 0 USB endpoint is not stalled.
* @retval non-0 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)
break;
}
return (u32Cfg & USBD_CFG_SSTALL);
}
/*--------------------------------------------------------------------*/
extern volatile uint8_t g_usbd_RemoteWakeupEn;
typedef void (*VENDOR_REQ)(void); /*!<USB Vendor request callback function */
typedef void (*CLASS_REQ)(void); /*!<USB Class request callback function */
typedef void (*SET_INTERFACE_REQ)(uint32_t u32AltInterface); /*!<USB Standard request "Set Interface" callback function */
/*--------------------------------------------------------------------*/
void USBD_Open(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_LockEpStall(uint32_t u32EpBitmap);
/*@}*/ /* end of group NANO100_USBD_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_USBD_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#endif //__USBD_H__
/*** (C) COPYRIGHT 2013~2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,65 @@
/**************************************************************************//**
* @file wdt.c
* @version V1.00
* $Revision: 2 $
* $Date: 15/03/18 5:37p $
* @brief Nano100 series WDT driver source file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_WDT_Driver WDT Driver
@{
*/
/** @addtogroup NANO100_WDT_EXPORTED_FUNCTIONS WDT Exported Functions
@{
*/
/**
* @brief This function make WDT module start counting with different time-out interval
* @param[in] u32TimeoutInterval Time-out interval period of WDT module. Valid values are:
* - \ref WDT_TIMEOUT_2POW4
* - \ref WDT_TIMEOUT_2POW6
* - \ref WDT_TIMEOUT_2POW8
* - \ref WDT_TIMEOUT_2POW10
* - \ref WDT_TIMEOUT_2POW12
* - \ref WDT_TIMEOUT_2POW14
* - \ref WDT_TIMEOUT_2POW16
* - \ref WDT_TIMEOUT_2POW18
* @param[in] u32ResetDelay Reset delay period while WDT time-out happened. Valid values are:
* - \ref WDT_RESET_DELAY_3CLK
* - \ref WDT_RESET_DELAY_18CLK
* - \ref WDT_RESET_DELAY_130CLK
* - \ref WDT_RESET_DELAY_1026CLK
* @param[in] u32EnableReset Enable WDT reset system function. Valid values are TRUE and FALSE
* @param[in] u32EnableWakeup Enable WDT wake-up system function. Valid values are TRUE and FALSE
* @return None
*/
void WDT_Open(uint32_t u32TimeoutInterval,
uint32_t u32ResetDelay,
uint32_t u32EnableReset,
uint32_t u32EnableWakeup)
{
WDT->CTL = u32TimeoutInterval | u32ResetDelay | WDT_CTL_WTE_Msk |
(u32EnableReset << WDT_CTL_WTRE_Pos) |
(u32EnableWakeup << WDT_CTL_WTWKE_Pos);
return;
}
/*@}*/ /* end of group NANO100_WDT_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_WDT_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,161 @@
/**************************************************************************//**
* @file wdt.h
* @version V1.00
* $Revision: 4 $
* $Date: 14/08/29 7:56p $
* @brief Nano100 series WDT driver header file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __WDT_H__
#define __WDT_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_WDT_Driver WDT Driver
@{
*/
/** @addtogroup NANO100_WDT_EXPORTED_CONSTANTS WDT Exported Constants
@{
*/
#define WDT_TIMEOUT_2POW4 (0UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^4 * WDT clocks */
#define WDT_TIMEOUT_2POW6 (1UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^6 * WDT clocks */
#define WDT_TIMEOUT_2POW8 (2UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^8 * WDT clocks */
#define WDT_TIMEOUT_2POW10 (3UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^10 * WDT clocks */
#define WDT_TIMEOUT_2POW12 (4UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^12 * WDT clocks */
#define WDT_TIMEOUT_2POW14 (5UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^14 * WDT clocks */
#define WDT_TIMEOUT_2POW16 (6UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^16 * WDT clocks */
#define WDT_TIMEOUT_2POW18 (7UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^18 * WDT clocks */
#define WDT_RESET_DELAY_3CLK (3UL << WDT_CTL_WTRDSEL_Pos) /*!< WDT setting reset delay to 3 WDT clocks */
#define WDT_RESET_DELAY_18CLK (2UL << WDT_CTL_WTRDSEL_Pos) /*!< WDT setting reset delay to 18 WDT clocks */
#define WDT_RESET_DELAY_130CLK (1UL << WDT_CTL_WTRDSEL_Pos) /*!< WDT setting reset delay to 130 WDT clocks */
#define WDT_RESET_DELAY_1026CLK (0UL << WDT_CTL_WTRDSEL_Pos) /*!< WDT setting reset delay to 1026 WDT clocks */
/*@}*/ /* end of group NANO100_WDT_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_WDT_EXPORTED_FUNCTIONS WDT Exported Functions
@{
*/
/**
* @brief This macro clear WDT time-out reset system flag.
* @param None
* @return None
* \hideinitializer
*/
#define WDT_CLEAR_RESET_FLAG() (WDT->ISR = WDT_ISR_RST_IS_Msk)
/**
* @brief This macro clear WDT time-out interrupt flag.
* @param None
* @return None
* \hideinitializer
*/
#define WDT_CLEAR_TIMEOUT_INT_FLAG() (WDT->ISR = WDT_ISR_IS_Msk)
/**
* @brief This macro clear WDT time-out wake-up system flag.
* @param None
* @return None
* \hideinitializer
*/
#define WDT_CLEAR_TIMEOUT_WAKEUP_FLAG() (WDT->ISR = WDT_ISR_WAKE_IS_Msk)
/**
* @brief This macro indicate WDT time-out to reset system or not.
* @return WDT reset system or not
* @retval 0 WDT did not cause system reset
* @retval 1 WDT caused system reset
* \hideinitializer
*/
#define WDT_GET_RESET_FLAG() (WDT->ISR & WDT_ISR_RST_IS_Msk ? 1 : 0)
/**
* @brief This macro indicate WDT time-out interrupt occurred or not.
* @return WDT time-out interrupt occurred or not
* @retval 0 WDT time-out interrupt did not occur
* @retval 1 WDT time-out interrupt occurred
* \hideinitializer
*/
#define WDT_GET_TIMEOUT_INT_FLAG() (WDT->ISR & WDT_ISR_IS_Msk ? 1 : 0)
/**
* @brief This macro indicate WDT time-out waked system up or not
* @return WDT time-out waked system up or not
* @retval 0 WDT did not wake up system
* @retval 1 WDT waked up system
* \hideinitializer
*/
#define WDT_GET_TIMEOUT_WAKEUP_FLAG() (WDT->ISR & WDT_ISR_WAKE_IS_Msk ? 1 : 0)
/**
* @brief This macro is used to reset 18-bit WDT counter.
* @details If WDT is activated and enabled to reset system, software must reset WDT counter
* before WDT time-out plus reset delay reached. Or WDT generate a reset signal.
* \hideinitializer
*/
#define WDT_RESET_COUNTER() (WDT->CTL |= WDT_CTL_WTR_Msk)
/**
* @brief This function stops WDT counting and disable WDT module
* @param None
* @return None
*/
__STATIC_INLINE void WDT_Close(void)
{
WDT->CTL = 0;
return;
}
/**
* @brief This function enables the WDT time-out interrupt
* @param None
* @return None
*/
__STATIC_INLINE void WDT_EnableInt(void)
{
WDT->IER = WDT_IER_IE_Msk;
return;
}
/**
* @brief This function disables the WDT time-out interrupt
* @param None
* @return None
*/
__STATIC_INLINE void WDT_DisableInt(void)
{
WDT->IER = 0;
return;
}
void WDT_Open(uint32_t u32TimeoutInterval,
uint32_t u32ResetDelay,
uint32_t u32EnableReset,
uint32_t u32EnableWakeup);
/*@}*/ /* end of group NANO100_WDT_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_WDT_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__WDT_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,66 @@
/**************************************************************************//**
* @file wwdt.c
* @version V1.00
* $Revision: 3 $
* $Date: 14/08/29 7:57p $
* @brief Nano100 series WWDT driver source file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_WWDT_Driver WWDT Driver
@{
*/
/** @addtogroup NANO100_WWDT_EXPORTED_FUNCTIONS WWDT Exported Functions
@{
*/
/**
* @brief This function make WWDT module start counting with different counter period and compared window value
* @param[in] u32PreScale Prescale period for the WWDT counter period. Valid values are:
* - \ref WWDT_PRESCALER_1
* - \ref WWDT_PRESCALER_2
* - \ref WWDT_PRESCALER_4
* - \ref WWDT_PRESCALER_8
* - \ref WWDT_PRESCALER_16
* - \ref WWDT_PRESCALER_32
* - \ref WWDT_PRESCALER_64
* - \ref WWDT_PRESCALER_128
* - \ref WWDT_PRESCALER_192
* - \ref WWDT_PRESCALER_256
* - \ref WWDT_PRESCALER_384
* - \ref WWDT_PRESCALER_512
* - \ref WWDT_PRESCALER_768
* - \ref WWDT_PRESCALER_1024
* - \ref WWDT_PRESCALER_1536
* - \ref WWDT_PRESCALER_2048
* @param[in] u32CmpValue Window compared value. Valid values are between 0x0 to 0x3F
* @param[in] u32EnableInt Enable WWDT interrupt or not. Valid values are TRUE and FALSE
* @return None
* @note Application can call this function can only once after boot up
*/
void WWDT_Open(uint32_t u32PreScale, uint32_t u32CmpValue, uint32_t u32EnableInt)
{
WWDT->IER = u32EnableInt;
WWDT->CR = u32PreScale | (u32CmpValue << WWDT_CR_WINCMP_Pos) | WWDT_CR_WWDTEN_Msk;
return;
}
/*@}*/ /* end of group NANO100_WDT_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_WDT_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,125 @@
/**************************************************************************//**
* @file wwdt.h
* @version V1.00
* $Revision: 2 $
* $Date: 14/01/14 5:38p $
* @brief Nano100 series WWDT driver header file
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __WWDT_H__
#define __WWDT_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup NANO100_Device_Driver NANO100 Device Driver
@{
*/
/** @addtogroup NANO100_WWDT_Driver WWDT Driver
@{
*/
/** @addtogroup NANO100_WWDT_EXPORTED_CONSTANTS WWDT Exported Constants
@{
*/
#define WWDT_PRESCALER_1 (0UL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 1 */
#define WWDT_PRESCALER_2 (1UL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 2 */
#define WWDT_PRESCALER_4 (2UL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 4 */
#define WWDT_PRESCALER_8 (3UL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 8 */
#define WWDT_PRESCALER_16 (4UL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 16 */
#define WWDT_PRESCALER_32 (5UL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 32 */
#define WWDT_PRESCALER_64 (6UL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 64 */
#define WWDT_PRESCALER_128 (7UL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 128 */
#define WWDT_PRESCALER_192 (8UL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 192 */
#define WWDT_PRESCALER_256 (9UL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 256 */
#define WWDT_PRESCALER_384 (0xAUL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 384 */
#define WWDT_PRESCALER_512 (0xBUL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 512 */
#define WWDT_PRESCALER_768 (0xCUL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 768 */
#define WWDT_PRESCALER_1024 (0xDUL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 1024 */
#define WWDT_PRESCALER_1536 (0xEUL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 1536 */
#define WWDT_PRESCALER_2048 (0xFUL << WWDT_CR_PERIODSEL_Pos) /*!< WWDT setting prescaler to 2048 */
#define WWDT_RELOAD_WORD (0x00005AA5) /*!< Fill this value to RLD register to reload WWDT counter */
/*@}*/ /* end of group NANO100_WWDT_EXPORTED_CONSTANTS */
/** @addtogroup NANO100_WWDT_EXPORTED_FUNCTIONS WWDT Exported Functions
@{
*/
/**
* @brief This macro clear WWDT time-out reset system flag.
* @param None
* @return None
* \hideinitializer
*/
#define WWDT_CLEAR_RESET_FLAG() (WWDT->STS = WWDT_STS_RF_Msk)
/**
* @brief This macro clears WWDT compare match interrupt flag.
* @param None
* @return None
* \hideinitializer
*/
#define WWDT_CLEAR_INT_FLAG() (WWDT->STS = WWDT_STS_IF_Msk)
/**
* @brief This macro is use to get WWDT time-out reset system flag.
* @return WWDT reset system or not
* @retval 0 WWDT did not cause system reset
* @retval 1 WWDT caused system reset
* \hideinitializer
*/
#define WWDT_GET_RESET_FLAG() (WWDT->STS & WWDT_STS_RF_Msk ? 1 : 0)
/**
* @brief This macro is used to indicate WWDT compare match interrupt flag.
* @return WWDT compare match interrupt occurred or not
* @retval 0 WWDT compare match interrupt did not occur
* @retval 1 WWDT compare match interrupt occurred
* \hideinitializer
*/
#define WWDT_GET_INT_FLAG() (WWDT->STS & WWDT_STS_IF_Msk ? 1 : 0)
/**
* @brief This macro to reflects current WWDT counter value
* @param None
* @return Return current WWDT counter value
* \hideinitializer
*/
#define WWDT_GET_COUNTER() (WWDT->VAL)
/**
* @brief This macro is used to reload the WWDT counter value to 0x3F.
* @param None
* @return None
* @details After WWDT enabled, application must reload WWDT counter while
* current counter is less than compare value and larger than 0,
* otherwise WWDT will cause system reset.
* \hideinitializer
*/
#define WWDT_RELOAD_COUNTER() (WWDT->RLD = WWDT_RELOAD_WORD)
void WWDT_Open(uint32_t u32PreScale, uint32_t u32CmpValue, uint32_t u32EnableInt);
/*@}*/ /* end of group NANO100_WWDT_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group NANO100_WWDT_Driver */
/*@}*/ /* end of group NANO100_Device_Driver */
#ifdef __cplusplus
}
#endif
#endif //__WWDT_H__
/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,28 @@
LR_IROM1 0x00000000 {
ER_IROM1 0x00000000 { ; load address = execution address
*(RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
;UVISOR AlignExpr(+0, 16) { ; 16 byte-aligned
; uvisor-lib.a (+RW +ZI)
;}
ARM_LIB_STACK 0x20000000 EMPTY 0x800 {
}
;ER_IRAMVEC 0x20000800 EMPTY (4*(16 + 32)) { ; Reserve for vectors
;}
RW_IRAM1 AlignExpr(+0, 16) { ; 16 byte-aligned
.ANY (+RW +ZI)
}
ARM_LIB_HEAP AlignExpr(+0, 16) EMPTY (0x20000000 + 0x4000 - AlignExpr(ImageLimit(RW_IRAM1), 16)) {
}
}
ScatterAssert(LoadLimit(LR_IROM1) <= 0x00020000) ; 128 KB APROM
ScatterAssert(ImageLimit(ARM_LIB_HEAP) <= 0x20004000) ; 16 KB SRAM

View File

@ -0,0 +1,28 @@
/* mbed Microcontroller Library - stackheap
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* Setup a fixed single stack/heap memory model,
* between the top of the RW/ZI region and the stackpointer
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <rt_misc.h>
#include <stdint.h>
extern char Image$$ARM_LIB_STACK$$ZI$$Limit[];
extern char Image$$ARM_LIB_HEAP$$Base[];
extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[];
extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
struct __initial_stackheap r;
r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit;
return r;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,28 @@
LR_IROM1 0x00000000 {
ER_IROM1 0x00000000 { ; load address = execution address
*(RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
;UVISOR AlignExpr(+0, 16) { ; 16 byte-aligned
; uvisor-lib.a (+RW +ZI)
;}
ARM_LIB_STACK 0x20000000 EMPTY 0x800 {
}
;ER_IRAMVEC 0x20000800 EMPTY (4*(16 + 32)) { ; Reserve for vectors
;}
RW_IRAM1 AlignExpr(+0, 16) { ; 16 byte-aligned
.ANY (+RW +ZI)
}
ARM_LIB_HEAP AlignExpr(+0, 16) EMPTY (0x20000000 + 0x4000 - AlignExpr(ImageLimit(RW_IRAM1), 16)) {
}
}
ScatterAssert(LoadLimit(LR_IROM1) <= 0x00020000) ; 128 KB APROM
ScatterAssert(ImageLimit(ARM_LIB_HEAP) <= 0x20004000) ; 16 KB SRAM

View File

@ -0,0 +1,28 @@
/* mbed Microcontroller Library - stackheap
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* Setup a fixed single stack/heap memory model,
* between the top of the RW/ZI region and the stackpointer
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <rt_misc.h>
#include <stdint.h>
extern char Image$$ARM_LIB_STACK$$ZI$$Limit[];
extern char Image$$ARM_LIB_HEAP$$Base[];
extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[];
extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
struct __initial_stackheap r;
r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit;
return r;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,255 @@
/*
* Nuvoton NANO130 GCC linker script file
*/
StackSize = 0x800;
MEMORY
{
VECTORS (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000400
FLASH (rx) : ORIGIN = 0x00000400, LENGTH = 0x00020000 - 0x00000400
RAM_INTERN (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000 - 0x00000000
}
/**
* Must match cmsis_nvic.h
*/
__vector_size = 4 * (16 + 32);
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
.isr_vector :
{
__vector_table = .;
KEEP(*(.vector_table))
. = ALIGN(4);
} > VECTORS
/* ensure that uvisor bss is at the beginning of memory */
.uvisor.bss (NOLOAD):
{
. = ALIGN(32);
__uvisor_bss_start = .;
/* protected uvisor main bss */
. = ALIGN(32);
__uvisor_bss_main_start = .;
KEEP(*(.keep.uvisor.bss.main))
. = ALIGN(32);
__uvisor_bss_main_end = .;
/* protected uvisor secure boxes bss */
. = ALIGN(32);
__uvisor_bss_boxes_start = .;
KEEP(*(.keep.uvisor.bss.boxes))
. = ALIGN(32);
__uvisor_bss_boxes_end = .;
/* Ensure log2(size) alignment of the uvisor region, to ensure that the region can be effectively protected by the MPU. */
. = ALIGN(1 << LOG2CEIL(__uvisor_bss_boxes_end - __uvisor_bss_start));
__uvisor_bss_end = .;
} > RAM_INTERN
.text :
{
/* uVisor code and data */
. = ALIGN(4);
__uvisor_main_start = .;
*(.uvisor.main)
__uvisor_main_end = .;
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > FLASH
/* .stack section doesn't contains any symbols. It is only
* used for linker to reserve space for the main stack section
* WARNING: .stack should come immediately after the last secure memory
* section. This provides stack overflow detection. */
.stack (NOLOAD):
{
__StackLimit = .;
*(.stack*);
. += StackSize - (. - __StackLimit);
} > RAM_INTERN
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ADDR(.stack) + SIZEOF(.stack);
__StackLimit = ADDR(.stack);
PROVIDE(__stack = __StackTop);
/* Relocate vector table in SRAM */
/* .isr_vector.reloc (NOLOAD) :
{
. = ALIGN(1 << LOG2CEIL(__vector_size));
PROVIDE(__start_vector_table__ = .);
. += __vector_size;
PROVIDE(__end_vector_table__ = .);
} > RAM_INTERN
*/
.data :
{
PROVIDE( __etext = LOADADDR(.data) );
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
/* All data end */
. = ALIGN(32);
__data_end__ = .;
} >RAM_INTERN AT>FLASH
/* uvisor configuration data */
.uvisor.secure :
{
. = ALIGN(32);
__uvisor_secure_start = .;
/* uvisor secure boxes configuration tables */
. = ALIGN(32);
__uvisor_cfgtbl_start = .;
KEEP(*(.keep.uvisor.cfgtbl))
. = ALIGN(32);
__uvisor_cfgtbl_end = .;
/* pointers to uvisor secure boxes configuration tables */
/* note: no further alignment here, we need to have the exact list of pointers */
__uvisor_cfgtbl_ptr_start = .;
KEEP(*(.keep.uvisor.cfgtbl_ptr_first))
KEEP(*(.keep.uvisor.cfgtbl_ptr))
__uvisor_cfgtbl_ptr_end = .;
/* the following symbols are kept for backward compatibility and will be soon
* deprecated; applications actively using uVisor (__uvisor_mode == UVISOR_ENABLED)
* will need to use uVisor 0.8.x or above, or the security assertions will halt the
* system */
/************************/
__uvisor_data_src = .;
__uvisor_data_start = .;
__uvisor_data_end = .;
/************************/
. = ALIGN(32);
__uvisor_secure_end = .;
} >FLASH
.uninitialized (NOLOAD):
{
. = ALIGN(32);
__uninitialized_start = .;
*(.uninitialized)
KEEP(*(.keep.uninitialized))
. = ALIGN(32);
__uninitialized_end = .;
} > RAM_INTERN
.bss (NOLOAD):
{
__bss_start__ = .;
*(.bss*)
*(COMMON)
__bss_end__ = .;
} > RAM_INTERN
.heap (NOLOAD):
{
__end__ = .;
end = __end__;
*(.heap*);
. += (ORIGIN(RAM_INTERN) + LENGTH(RAM_INTERN) - .);
__HeapLimit = .;
} > RAM_INTERN
PROVIDE(__heap_size = SIZEOF(.heap));
PROVIDE(__mbed_sbrk_start = ADDR(.heap));
PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap));
/* Provide physical memory boundaries for uVisor. */
__uvisor_flash_start = ORIGIN(VECTORS);
__uvisor_flash_end = ORIGIN(FLASH) + LENGTH(FLASH);
__uvisor_sram_start = ORIGIN(RAM_INTERN);
__uvisor_sram_end = ORIGIN(RAM_INTERN) + LENGTH(RAM_INTERN);
}

View File

@ -0,0 +1,40 @@
/******************************************************************************
* @file startup_NUC472_442.c
* @version V0.10
* $Revision: 11 $
* $Date: 15/09/02 10:02a $
* @brief CMSIS Cortex-M4 Core Peripheral Access Layer Source File for NUC472/442 MCU
*
* @note
* Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "NANO100Series.h"
#include <errno.h>
#include "nu_miscutil.h"
extern uint32_t __mbed_sbrk_start;
extern uint32_t __mbed_krbs_start;
#define NU_HEAP_ALIGN 32
/**
* The default implementation of _sbrk() (in common/retarget.cpp) for GCC_ARM requires one-region model (heap and stack share one region), which doesn't
* fit two-region model (heap and stack are two distinct regions), for example, NUMAKER-PFM-NUC472 locates heap on external SRAM. Define __wrap__sbrk() to
* override the default _sbrk(). It is expected to get called through gcc hooking mechanism ('-Wl,--wrap,_sbrk') or in _sbrk().
*/
void *__wrap__sbrk(int incr)
{
static uint32_t heap_ind = (uint32_t) &__mbed_sbrk_start;
uint32_t heap_ind_old = NU_ALIGN_UP(heap_ind, NU_HEAP_ALIGN);
uint32_t heap_ind_new = NU_ALIGN_UP(heap_ind_old + incr, NU_HEAP_ALIGN);
if (heap_ind_new > &__mbed_krbs_start) {
errno = ENOMEM;
return (void *) -1;
}
heap_ind = heap_ind_new;
return (void *) heap_ind_old;
}

View File

@ -0,0 +1,36 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x00020000;
define symbol __ICFEDIT_region_IRAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_IRAM_end__ = 0x20004000;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__ = 0x2000;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region IRAM_region = mem:[from __ICFEDIT_region_IRAM_start__ to __ICFEDIT_region_IRAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
/* NOTE: Vector table base requires to be aligned to the power of vector table size. Give a safe value here. */
/*define block IRAMVEC with alignment = 1024, size = 4 * (16 + 32) { };*/
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place at start of IRAM_region { block CSTACK };
place in IRAM_region { block IRAMVEC };
place in IRAM_region { readwrite };
place in IRAM_region { block HEAP };

View File

@ -0,0 +1,33 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#ifndef MBED_CMSIS_H
#define MBED_CMSIS_H
#include "NANO100Series.h"
#include "cmsis_nvic.h"
// Support linker-generated symbol as start of relocated vector table.
#if defined(__CC_ARM)
extern uint32_t Image$$ER_IRAMVEC$$ZI$$Base;
#elif defined(__ICCARM__)
#elif defined(__GNUC__)
extern uint32_t __start_vector_table__;
#endif
#endif

View File

@ -0,0 +1,32 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#include "cmsis_nvic.h"
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
{
//static volatile uint32_t *vectors = (uint32_t *) NVIC_RAM_VECTOR_ADDRESS;
// Put the vectors in SRAM
//vectors[IRQn + 16] = vector;
}
uint32_t NVIC_GetVector(IRQn_Type IRQn)
{
uint32_t *vectors = (uint32_t*) NVIC_FLASH_VECTOR_ADDRESS;
// Return the vector
return vectors[IRQn + 16];
}

View File

@ -0,0 +1,63 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H
#include "cmsis.h"
#define NVIC_USER_IRQ_OFFSET 16
#define NVIC_USER_IRQ_NUMBER 32
#define NVIC_NUM_VECTORS (NVIC_USER_IRQ_OFFSET + NVIC_USER_IRQ_NUMBER)
#if defined(__CC_ARM)
# define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) &Image$$ER_IRAMVEC$$ZI$$Base)
#elif defined(__ICCARM__)
# pragma section = "IRAMVEC"
# define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) __section_begin("IRAMVEC"))
#elif defined(__GNUC__)
# define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) &__start_vector_table__)
#endif
#define NVIC_FLASH_VECTOR_ADDRESS 0
#ifdef __cplusplus
extern "C" {
#endif
/** Set the ISR for IRQn
*
* Sets an Interrupt Service Routine vector for IRQn; if the feature is available, the vector table is relocated to SRAM
* the first time this function is called
* @param[in] IRQn The Interrupt Request number for which a vector will be registered
* @param[in] vector The ISR vector to register for IRQn
*/
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
/** Get the ISR registered for IRQn
*
* Reads the Interrupt Service Routine currently registered for IRQn
* @param[in] IRQn The Interrupt Request number the vector of which will be read
* @return Returns the ISR registered for IRQn
*/
uint32_t NVIC_GetVector(IRQn_Type IRQn);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,398 @@
/******************************************************************************
* @file startup_Nano100Series.c
* @version V1.00
* $Revision: 4 $
* $Date: 15/06/08 5:12p $
* @brief CMSIS ARM Cortex-M0 Core Device Startup File
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include "Nano100Series.h"
/* Suppress warning messages */
#if defined(__CC_ARM)
// Suppress warning message: extended constant initialiser used
#pragma diag_suppress 1296
#elif defined(__ICCARM__)
#elif defined(__GNUC__)
#endif
/* Macro Definitions */
#if defined(__CC_ARM)
#define WEAK __attribute__ ((weak))
#define ALIAS(f) __attribute__ ((weak, alias(#f)))
#define WEAK_ALIAS_FUNC(FUN, FUN_ALIAS) \
void FUN(void) __attribute__ ((weak, alias(#FUN_ALIAS)));
#elif defined(__ICCARM__)
//#define STRINGIFY(x) #x
//#define _STRINGIFY(x) STRINGIFY(x)
#define WEAK_ALIAS_FUNC(FUN, FUN_ALIAS) \
void FUN(void); \
_Pragma(_STRINGIFY(_WEAK_ALIAS_FUNC(FUN, FUN_ALIAS)))
#define _WEAK_ALIAS_FUNC(FUN, FUN_ALIAS) weak __WEAK_ALIAS_FUNC(FUN, FUN_ALIAS)
#define __WEAK_ALIAS_FUNC(FUN, FUN_ALIAS) FUN##=##FUN_ALIAS
#elif defined(__GNUC__)
#define WEAK __attribute__ ((weak))
#define ALIAS(f) __attribute__ ((weak, alias(#f)))
#define WEAK_ALIAS_FUNC(FUN, FUN_ALIAS) \
void FUN(void) __attribute__ ((weak, alias(#FUN_ALIAS)));
#endif
/* Initialize segments */
#if defined(__CC_ARM)
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
extern void __main(void);
#elif defined(__ICCARM__)
void __iar_program_start(void);
#elif defined(__GNUC__)
extern uint32_t __StackTop;
extern uint32_t __etext;
extern uint32_t __data_start__;
extern uint32_t __data_end__;
extern uint32_t __bss_start__;
extern uint32_t __bss_end__;
extern void uvisor_init(void);
//#if defined(TOOLCHAIN_GCC_ARM)
//extern void _start(void);
//#endif
extern void software_init_hook(void) __attribute__((weak));
extern void __libc_init_array(void);
extern int main(void);
#endif
/* Default empty handler */
void Default_Handler(void);
void Default_Handler_1(void);
/* Reset handler */
void Reset_Handler(void);
/* Cortex-M0 core handlers */
WEAK_ALIAS_FUNC(NMI_Handler, Default_Handler) // NMI Handler
WEAK_ALIAS_FUNC(HardFault_Handler, Default_Handler_a) // Hard Fault Handler
WEAK_ALIAS_FUNC(SVC_Handler, Default_Handler) // SVCall Handler
WEAK_ALIAS_FUNC(PendSV_Handler, Default_Handler) // PendSV Handler
WEAK_ALIAS_FUNC(SysTick_Handler, Default_Handler) // SysTick Handler
/* Peripherals handlers */
WEAK_ALIAS_FUNC(BOD_IRQHandler, Default_Handler_0) // Brownout low voltage detected interrupt
WEAK_ALIAS_FUNC(WDT_IRQHandler, Default_Handler_1) // Watch Dog Timer interrupt
WEAK_ALIAS_FUNC(EINT0_IRQHandler, Default_Handler_2) // External signal interrupt from PB.14 pin
WEAK_ALIAS_FUNC(EINT1_IRQHandler, Default_Handler_3) // External signal interrupt from PB.15 pin
WEAK_ALIAS_FUNC(GPABC_IRQHandler, Default_Handler_4) // External interrupt from PA[15:0]/PB[15:0]/PC[15:0]
WEAK_ALIAS_FUNC(GPDEF_IRQHandler, Default_Handler_5) // External interrupt from PD[15:0]/PE[15:0]/PF[7:0]
WEAK_ALIAS_FUNC(PWM0_IRQHandler, Default_Handler_6) // PWM 0 interrupt
WEAK_ALIAS_FUNC(PWM1_IRQHandler, Default_Handler_7) // PWM 1 interrupt
WEAK_ALIAS_FUNC(TMR0_IRQHandler, Default_Handler_8) // Timer 0 interrupt
WEAK_ALIAS_FUNC(TMR1_IRQHandler, Default_Handler_9) // Timer 1 interrupt
WEAK_ALIAS_FUNC(TMR2_IRQHandler, Default_Handler_10) // Timer 2 interrupt
WEAK_ALIAS_FUNC(TMR3_IRQHandler, Default_Handler_11) // Timer 3 interrupt
WEAK_ALIAS_FUNC(UART0_IRQHandler, Default_Handler_12) // UART0 interrupt
WEAK_ALIAS_FUNC(UART1_IRQHandler, Default_Handler_13) // UART1 interrupt
WEAK_ALIAS_FUNC(SPI0_IRQHandler, Default_Handler_14) // SPI0 interrupt
WEAK_ALIAS_FUNC(SPI1_IRQHandler, Default_Handler_15) // SPI1 interrupt
WEAK_ALIAS_FUNC(SPI2_IRQHandler, Default_Handler_16) // SPI2 interrupt
WEAK_ALIAS_FUNC(HIRC_IRQHandler, Default_Handler_17) // HIRC interrupt
WEAK_ALIAS_FUNC(I2C0_IRQHandler, Default_Handler_18) // I2C0 interrupt
WEAK_ALIAS_FUNC(I2C1_IRQHandler, Default_Handler_19) // I2C1 interrupt
WEAK_ALIAS_FUNC(SC2_IRQHandler, Default_Handler_20) // SC2 interrupt
WEAK_ALIAS_FUNC(SC0_IRQHandler, Default_Handler_21) // SC0 interrupt
WEAK_ALIAS_FUNC(SC1_IRQHandler, Default_Handler_22) // SC1 interrupt
WEAK_ALIAS_FUNC(USBD_IRQHandler, Default_Handler_23) // USB FS Device interrupt
// Reserved
WEAK_ALIAS_FUNC(LCD_IRQHandler, Default_Handler_25) // LCD interrupt
WEAK_ALIAS_FUNC(PDMA_IRQHandler, Default_Handler_26) // PDMA interrupt
WEAK_ALIAS_FUNC(I2S_IRQHandler, Default_Handler_27) // I2S interrupt
WEAK_ALIAS_FUNC(PDWU_IRQHandler, Default_Handler_28) // Power Down Wake up interrupt
WEAK_ALIAS_FUNC(ADC_IRQHandler, Default_Handler_29) // ADC interrupt
WEAK_ALIAS_FUNC(DAC_IRQHandler, Default_Handler_30) // DAC interrupt
WEAK_ALIAS_FUNC(RTC_IRQHandler, Default_Handler_31) // Real time clock interrupt
/* Vector table */
#if defined(__CC_ARM)
__attribute__ ((section("RESET")))
const uint32_t __vector_handlers[] = {
#elif defined(__ICCARM__)
extern uint32_t CSTACK$$Limit;
const uint32_t __vector_table[] @ ".intvec" = {
#elif defined(__GNUC__)
__attribute__ ((section(".vector_table")))
const uint32_t __vector_handlers[] = {
#endif
/* Configure Initial Stack Pointer, using linker-generated symbols */
#if defined(__CC_ARM)
(uint32_t) &Image$$ARM_LIB_STACK$$ZI$$Limit,
#elif defined(__ICCARM__)
//(uint32_t) __sfe("CSTACK"),
(uint32_t) &CSTACK$$Limit,
#elif defined(__GNUC__)
(uint32_t) &__StackTop,
#endif
(uint32_t) Reset_Handler, // Reset Handler
(uint32_t) NMI_Handler, // NMI Handler
(uint32_t) HardFault_Handler, // Hard Fault Handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
(uint32_t) SVC_Handler, // SVCall Handler
0, // Reserved
0, // Reserved
(uint32_t) PendSV_Handler, // PendSV Handler
(uint32_t) SysTick_Handler, // SysTick Handler
/* External Interrupts */
(uint32_t) BOD_IRQHandler, // Brownout low voltage detected interrupt
(uint32_t) WDT_IRQHandler, // Watch Dog Timer interrupt
(uint32_t) EINT0_IRQHandler, // External signal interrupt from PB.14 pin
(uint32_t) EINT1_IRQHandler, // External signal interrupt from PB.15 pin
(uint32_t) GPABC_IRQHandler, // External interrupt from PA[15:0]/PB[15:0]/PC[15:0]
(uint32_t) GPDEF_IRQHandler, // External interrupt from PD[15:0]/PE[15:0]/PF[7:0]
(uint32_t) PWM0_IRQHandler, // PWM 0 interrupt
(uint32_t) PWM1_IRQHandler, // PWM 1 interrupt
(uint32_t) TMR0_IRQHandler, // Timer 0 interrupt
(uint32_t) TMR1_IRQHandler, // Timer 1 interrupt
(uint32_t) TMR2_IRQHandler, // Timer 2 interrupt
(uint32_t) TMR3_IRQHandler, // Timer 3 interrupt
(uint32_t) UART0_IRQHandler, // UART0 interrupt
(uint32_t) UART1_IRQHandler, // UART1 interrupt
(uint32_t) SPI0_IRQHandler, // SPI0 interrupt
(uint32_t) SPI1_IRQHandler, // SPI1 interrupt
(uint32_t) SPI2_IRQHandler, // SPI2 interrupt
(uint32_t) HIRC_IRQHandler, // HIRC interrupt
(uint32_t) I2C0_IRQHandler, // I2C0 interrupt
(uint32_t) I2C1_IRQHandler, // I2C1 interrupt
(uint32_t) SC2_IRQHandler, // SC2 interrupt
(uint32_t) SC0_IRQHandler, // SC0 interrupt
(uint32_t) SC1_IRQHandler, // SC1 interrupt
(uint32_t) USBD_IRQHandler, // USB FS Device interrupt
(uint32_t) Default_Handler, // Reserved
(uint32_t) LCD_IRQHandler, // LCD interrupt
(uint32_t) PDMA_IRQHandler, // PDMA interrupt
(uint32_t) I2S_IRQHandler, // I2S interrupt
(uint32_t) PDWU_IRQHandler, // Power Down Wake up interrupt
(uint32_t) ADC_IRQHandler, // ADC interrupt
(uint32_t) DAC_IRQHandler, // DAC interrupt
(uint32_t) RTC_IRQHandler, // Real time clock interrupt
};
/**
* \brief This is the code that gets called on processor reset.
*/
void Reset_Handler(void)
{
/* Disable register write-protection function */
SYS_UnlockReg();
/* Disable Power-on Reset function */
SYS_DISABLE_POR();
/* Enable register write-protection function */
SYS_LockReg();
/**
* Because EBI (external SRAM) init is done in SystemInit(), SystemInit() must be called at the very start.
*/
//SystemInit();
#if defined(__CC_ARM)
__main();
#elif defined(__ICCARM__)
__iar_program_start();
#elif defined(__GNUC__)
uint32_t *src_ind = (uint32_t *) &__etext;
uint32_t *dst_ind = (uint32_t *) &__data_start__;
uint32_t *dst_end = (uint32_t *) &__data_end__;
/* Move .data section from ROM to RAM */
if (src_ind != dst_ind) {
for (; dst_ind < dst_end;) {
*dst_ind ++ = *src_ind ++;
}
}
/* Initialize .bss section to zero */
dst_ind = (uint32_t *) &__bss_start__;
dst_end = (uint32_t *) &__bss_end__;
if (dst_ind != dst_end) {
for (; dst_ind < dst_end;) {
*dst_ind ++ = 0;
}
}
//uvisor_init();
if (software_init_hook) {
/**
* Give control to the RTOS via software_init_hook() which will also call __libc_init_array().
* Assume software_init_hook() is defined in libraries/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h.
*/
software_init_hook();
}
else {
__libc_init_array();
main();
}
#endif
/* Infinite loop */
while (1);
}
/**
* \brief Default interrupt handler for unused IRQs.
*/
void Default_Handler(void)
{
while (1);
}
void Default_Handler_a(void)
{
while (1);
}
void Default_Handler_0(void)
{
while (1);
}
void Default_Handler_1(void)
{
while (1);
}
void Default_Handler_2(void)
{
while (1);
}
void Default_Handler_3(void)
{
while (1);
}
void Default_Handler_4(void)
{
while (1);
}
void Default_Handler_5(void)
{
while (1);
}
void Default_Handler_6(void)
{
while (1);
}
void Default_Handler_7(void)
{
while (1);
}
void Default_Handler_8(void)
{
while (1);
}
void Default_Handler_9(void)
{
while (1);
}
void Default_Handler_10(void)
{
while (1);
}
void Default_Handler_11(void)
{
while (1);
}
void Default_Handler_12(void)
{
while (1);
}
void Default_Handler_13(void)
{
while (1);
}
void Default_Handler_14(void)
{
while (1);
}
void Default_Handler_15(void)
{
while (1);
}
void Default_Handler_16(void)
{
while (1);
}
void Default_Handler_17(void)
{
while (1);
}
void Default_Handler_18(void)
{
while (1);
}
void Default_Handler_19(void)
{
while (1);
}
void Default_Handler_20(void)
{
while (1);
}
void Default_Handler_21(void)
{
while (1);
}
void Default_Handler_22(void)
{
while (1);
}
void Default_Handler_23(void)
{
while (1);
}
void Default_Handler_24(void)
{
while (1);
}
void Default_Handler_25(void)
{
while (1);
}
void Default_Handler_26(void)
{
while (1);
}
void Default_Handler_27(void)
{
while (1);
}
void Default_Handler_28(void)
{
while (1);
}
void Default_Handler_29(void)
{
while (1);
}
void Default_Handler_30(void)
{
while (1);
}
void Default_Handler_31(void)
{
while (1);
}

View File

@ -0,0 +1,126 @@
/******************************************************************************
* @file system_Nano100Series.c
* @version V1.00
* $Revision: 4 $
* $Date: 14/01/29 4:09p $
* @brief Nano100 series system clock init code and assert handler
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdint.h>
#include "Nano100Series.h"
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = __HSI; /*!< System Clock Frequency (Core Clock) */
uint32_t CyclesPerUs = (__HSI / 1000000); /*!< Cycles per micro second */
/**
* @brief Calculate current PLL clock frequency.
* @param None.
* @return PLL clock frequency. The clock UNIT is in Hz.
*/
uint32_t SysGet_PLLClockFreq(void)
{
uint32_t u32Freq =0, u32PLLSrc;
uint32_t u32NO, u32NR, u32IN_DV, u32PllReg;
u32PllReg = CLK->PLLCTL;
if (u32PllReg & CLK_PLLCTL_PD)
return 0; /* PLL is in power down mode */
if (u32PllReg & CLK_PLLCTL_PLL_SRC_Msk)
u32PLLSrc = __HIRC12M;
else
u32PLLSrc = __HXT;
u32NO = (u32PllReg & CLK_PLLCTL_OUT_DV) ? 2: 1;
u32IN_DV = (u32PllReg & CLK_PLLCTL_IN_DV_Msk) >> 8;
if (u32IN_DV == 0)
u32NR = 2;
else if (u32IN_DV == 1)
u32NR = 4;
else if (u32IN_DV == 2)
u32NR = 8;
else
u32NR = 16;
u32Freq = u32PLLSrc * ((u32PllReg & CLK_PLLCTL_FB_DV_Msk) +32) / u32NR / u32NO;
return u32Freq;
}
/**
* @brief Get current HCLK clock frequency.
* @param None.
* @return HCLK clock frequency. The clock UNIT is in Hz.
*/
uint32_t SysGet_HCLKFreq(void)
{
uint32_t u32Freqout, u32AHBDivider, u32ClkSel;
u32ClkSel = CLK->CLKSEL0 & CLK_CLKSEL0_HCLK_S_Msk;
if (u32ClkSel == CLK_CLKSEL0_HCLK_S_HXT) { /* external HXT crystal clock */
u32Freqout = __HXT;
} else if(u32ClkSel == CLK_CLKSEL0_HCLK_S_LXT) { /* external LXT crystal clock */
u32Freqout = __LXT;
} else if(u32ClkSel == CLK_CLKSEL0_HCLK_S_PLL) { /* PLL clock */
u32Freqout = SysGet_PLLClockFreq();
} else if(u32ClkSel == CLK_CLKSEL0_HCLK_S_LIRC) { /* internal LIRC oscillator clock */
u32Freqout = __LIRC;
} else { /* internal HIRC oscillator clock */
u32Freqout = __HIRC12M;
}
u32AHBDivider = (CLK->CLKDIV0 & CLK_CLKDIV0_HCLK_N_Msk) + 1 ;
return (u32Freqout/u32AHBDivider);
}
/**
* @brief This function is used to update the variable SystemCoreClock
* and must be called whenever the core clock is changed.
* @param None.
* @retval None.
*/
void SystemCoreClockUpdate (void)
{
SystemCoreClock = SysGet_HCLKFreq();
CyclesPerUs = (SystemCoreClock + 500000) / 1000000;
}
#if USE_ASSERT
/**
* @brief Assert Error Message
*
* @param[in] file the source file name
* @param[in] line line number
*
* @return None
*
* @details The function prints the source file name and line number where
* the ASSERT_PARAM() error occurs, and then stops in an infinite loop.
*/
void AssertError(uint8_t * file, uint32_t line)
{
printf("[%s] line %d : wrong parameters.\r\n", file, line);
/* Infinite loop */
while(1) ;
}
#endif
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,56 @@
/**************************************************************************//**
* @file system_Nano100Series.h
* @version V1.00
* $Revision: 2 $
* $Date: 14/01/07 7:35p $
* @brief Nano100 series system clock definition file
*
* @note
* Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __SYSTEM_NANO100SERIES_H__
#define __SYSTEM_NANO100SERIES_H__
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------
Define SYSCLK
*----------------------------------------------------------------------------*/
#define __HXT (12000000UL)
#define __LXT (32768UL)
#define __HIRC12M (12000000UL)
#define __LIRC (10000UL)
#define __HIRC __HIRC12M
#define __HSI (__HIRC12M) /* Factory Default is internal 12MHz */
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
extern uint32_t CyclesPerUs; /*!< Cycles per micro second */
/**
* Update SystemCoreClock variable
*
* @param None
* @return None
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from CPU registers.
*/
extern void SystemCoreClockUpdate (void);
extern uint32_t SysGet_PLLClockFreq(void);
#ifdef __cplusplus
}
#endif
#endif //__SYSTEM_NANO100SERIES_H__
/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/

View File

@ -0,0 +1,41 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2016 Nuvoton
*
* 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.
*/
#ifndef MBED_DMA_H
#define MBED_DMA_H
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DMA_CAP_NONE (0 << 0)
#define DMA_EVENT_ABORT (1 << 0)
#define DMA_EVENT_TRANSFER_DONE (1 << 1)
#define DMA_EVENT_TIMEOUT (1 << 2)
#define DMA_EVENT_ALL (DMA_EVENT_ABORT | DMA_EVENT_TRANSFER_DONE | DMA_EVENT_TIMEOUT)
#define DMA_EVENT_MASK DMA_EVENT_ALL
void dma_set_handler(int channelid, uint32_t handler, uint32_t id, uint32_t event);
PDMA_T *dma_modbase(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,86 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#include "gpio_api.h"
#include "mbed_assert.h"
#include "pinmap.h"
#include "mbed_error.h"
#include "PeripheralPins.h"
uint32_t gpio_set(PinName pin)
{
if (pin == (PinName) NC) {
return 0;
}
uint32_t pin_index = NU_PINNAME_TO_PIN(pin);
#if 1
pin_function(pin, 0 << NU_MFP_POS(pin_index));
#else
pinmap_pinout(pin, PinMap_GPIO);
#endif
return (uint32_t)(1 << pin_index); // Return the pin mask
}
void gpio_init(gpio_t *obj, PinName pin)
{
obj->pin = pin;
if (obj->pin == (PinName) NC) {
return;
}
obj->mask = gpio_set(pin);
}
void gpio_mode(gpio_t *obj, PinMode mode)
{
if (obj->pin == (PinName) NC) {
return;
}
pin_mode(obj->pin, mode);
}
void gpio_dir(gpio_t *obj, PinDirection direction)
{
if (obj->pin == (PinName) NC) {
return;
}
uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin);
uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin);
GPIO_T *gpio_base = NU_PORT_BASE(port_index);
uint32_t mode_intern = GPIO_PMD_INPUT;
switch (direction) {
case PIN_INPUT:
mode_intern = GPIO_PMD_INPUT;
break;
case PIN_OUTPUT:
mode_intern = GPIO_PMD_OUTPUT;
break;
default:
return;
}
GPIO_SetMode(gpio_base, 1 << pin_index, mode_intern);
}

View File

@ -0,0 +1,241 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#include "gpio_irq_api.h"
#if DEVICE_INTERRUPTIN
#include "gpio_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "PeripheralPins.h"
#include "nu_bitutil.h"
#define NU_MAX_PIN_PER_PORT 16
struct nu_gpio_irq_var {
gpio_irq_t * obj_arr[NU_MAX_PIN_PER_PORT];
//IRQn_Type irq_n;
uint32_t gpio_n;
void (*vec)(void);
};
void GPABC_IRQHandler(void);
void GPDEF_IRQHandler(void);
static void gpio_irq(struct nu_gpio_irq_var *var);
//EINT0_IRQn
static struct nu_gpio_irq_var gpio_irq_var_arr[] = {
{{NULL}, 0, GPABC_IRQHandler},
{{NULL}, 1, GPABC_IRQHandler},
{{NULL}, 2, GPABC_IRQHandler},
{{NULL}, 3, GPDEF_IRQHandler},
{{NULL}, 4, GPDEF_IRQHandler},
{{NULL}, 5, GPDEF_IRQHandler}
};
#define NU_MAX_PORT (sizeof (gpio_irq_var_arr) / sizeof (gpio_irq_var_arr[0]))
#ifndef MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE
#define MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE 0
#endif
#ifndef MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE_LIST
#define MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE_LIST NC
#endif
static PinName gpio_irq_debounce_arr[] = {
MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE_LIST
};
#ifndef MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE
#define MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCLKSRC_IRC10K
#endif
#ifndef MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE
#define MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCLKSEL_16
#endif
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
{
if (pin == NC) {
return -1;
}
uint32_t pin_index = NU_PINNAME_TO_PIN(pin);
uint32_t port_index = NU_PINNAME_TO_PORT(pin);
if (pin_index >= NU_MAX_PIN_PER_PORT || port_index >= NU_MAX_PORT) {
return -1;
}
obj->pin = pin;
obj->irq_handler = (uint32_t) handler;
obj->irq_id = id;
GPIO_T *gpio_base = NU_PORT_BASE(port_index);
//gpio_set(pin);
{
#if MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_ENABLE
// Suppress compiler warning
(void) gpio_irq_debounce_arr;
// Configure de-bounce clock source and sampling cycle time
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index);
#else
// Enable de-bounce if the pin is in the de-bounce enable list
// De-bounce defaults to disabled.
GPIO_DISABLE_DEBOUNCE(gpio_base, 1 << pin_index);
PinName *debounce_pos = gpio_irq_debounce_arr;
PinName *debounce_end = gpio_irq_debounce_arr + sizeof (gpio_irq_debounce_arr) / sizeof (gpio_irq_debounce_arr[0]);
for (; debounce_pos != debounce_end && *debounce_pos != NC; debounce_pos ++) {
uint32_t pin_index_debunce = NU_PINNAME_TO_PIN(*debounce_pos);
uint32_t port_index_debounce = NU_PINNAME_TO_PORT(*debounce_pos);
if (pin_index == pin_index_debunce &&
port_index == port_index_debounce) {
// Configure de-bounce clock source and sampling cycle time
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_NANO100_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index);
break;
}
}
#endif
}
struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index;
var->obj_arr[pin_index] = obj;
// NOTE: InterruptIn requires IRQ enabled by default.
gpio_irq_enable(obj);
return 0;
}
void gpio_irq_free(gpio_irq_t *obj)
{
uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin);
uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin);
struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index;
NVIC_DisableIRQ((var->gpio_n < 3) ? GPABC_IRQn : GPDEF_IRQn);
NU_PORT_BASE(port_index)->IER = 0;
MBED_ASSERT(pin_index < NU_MAX_PIN_PER_PORT);
var->obj_arr[pin_index] = NULL;
}
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin);
uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin);
GPIO_T *gpio_base = NU_PORT_BASE(port_index);
switch (event) {
case IRQ_RISE:
if (enable) {
GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_RISING);
}
else {
gpio_base->IER &= ~(GPIO_INT_RISING << pin_index);
}
break;
case IRQ_FALL:
if (enable) {
GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_FALLING);
}
else {
gpio_base->IER &= ~(GPIO_INT_FALLING << pin_index);
}
break;
}
}
void gpio_irq_enable(gpio_irq_t *obj)
{
//uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin);
uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin);
struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index;
NVIC_SetVector((var->gpio_n < 3) ? GPABC_IRQn : GPDEF_IRQn, (uint32_t) var->vec);
NVIC_EnableIRQ((var->gpio_n < 3) ? GPABC_IRQn : GPDEF_IRQn);
}
void gpio_irq_disable(gpio_irq_t *obj)
{
//uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin);
uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin);
struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index;
NVIC_DisableIRQ((var->gpio_n < 3) ? GPABC_IRQn : GPDEF_IRQn);
}
void GPABC_IRQHandler(void)
{
if (PA->ISRC)
gpio_irq(gpio_irq_var_arr + 0);
if (PB->ISRC)
gpio_irq(gpio_irq_var_arr + 1);
if (PC->ISRC)
gpio_irq(gpio_irq_var_arr + 2);
}
void GPDEF_IRQHandler(void)
{
if (PD->ISRC)
gpio_irq(gpio_irq_var_arr + 3);
if (PE->ISRC)
gpio_irq(gpio_irq_var_arr + 4);
if (PF->ISRC)
gpio_irq(gpio_irq_var_arr + 5);
}
static void gpio_irq(struct nu_gpio_irq_var *var)
{
uint32_t port_index = var->gpio_n;
GPIO_T *gpio_base = NU_PORT_BASE(port_index);
uint32_t isrc = gpio_base->ISRC;
uint32_t ier = gpio_base->IER;
while (isrc) {
int pin_index = nu_ctz(isrc);
gpio_irq_t *obj = var->obj_arr[pin_index];
if (ier & (GPIO_INT_RISING << pin_index)) {
if (GPIO_PIN_ADDR(port_index, pin_index)) {
if (obj->irq_handler) {
((gpio_irq_handler) obj->irq_handler)(obj->irq_id, IRQ_RISE);
}
}
}
if (ier & (GPIO_INT_FALLING << pin_index)) {
if (! GPIO_PIN_ADDR(port_index, pin_index)) {
if (obj->irq_handler) {
((gpio_irq_handler) obj->irq_handler)(obj->irq_id, IRQ_FALL);
}
}
}
isrc &= ~(1 << pin_index);
}
// Clear all interrupt flags
gpio_base->ISRC = gpio_base->ISRC;
}
#endif

View File

@ -0,0 +1,57 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#ifndef MBED_GPIO_OBJECT_H
#define MBED_GPIO_OBJECT_H
#include "mbed_assert.h"
#include "cmsis.h"
#include "PortNames.h"
#include "PeripheralNames.h"
#include "PinNames.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
PinName pin;
uint32_t mask;
} gpio_t;
static inline void gpio_write(gpio_t *obj, int value)
{
MBED_ASSERT(obj->pin != (PinName)NC);
uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin);
uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin);
GPIO_PIN_ADDR(port_index, pin_index) = value ? 1 : 0;
}
static inline int gpio_read(gpio_t *obj)
{
MBED_ASSERT(obj->pin != (PinName)NC);
uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin);
uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin);
return (GPIO_PIN_ADDR(port_index, pin_index) ? 1 : 0);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,22 @@
{
"name": "NANO100",
"config": {
"gpio-irq-debounce-enable": {
"help": "Enable GPIO IRQ debounce",
"value": 0
},
"gpio-irq-debounce-enable-list": {
"help": "Comma separated pin list to enable GPIO IRQ debounce",
"value": "NC"
},
"gpio-irq-debounce-clock-source": {
"help": "Select GPIO IRQ debounce clock source: GPIO_DBCLKSRC_HCLK or GPIO_DBCLKSRC_IRC10K",
"value": "GPIO_DBCLKSRC_IRC10K"
},
"gpio-irq-debounce-sample-rate": {
"help": "Select GPIO IRQ debounce sample rate: GPIO_DBCLKSEL_1, GPIO_DBCLKSEL_2, GPIO_DBCLKSEL_4, ..., or GPIO_DBCLKSEL_32768",
"value": "GPIO_DBCLKSEL_16"
}
}
}

View File

@ -0,0 +1,83 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#include "mbed_assert.h"
#include "pinmap.h"
#include "PortNames.h"
#include "mbed_error.h"
/**
* Configure pin multi-function
*/
void pin_function(PinName pin, int data)
{
MBED_ASSERT(pin != (PinName)NC);
uint32_t pin_index = NU_PINNAME_TO_PIN(pin);
uint32_t port_index = NU_PINNAME_TO_PORT(pin);
__IO uint32_t *Px_x_MFP = ((__IO uint32_t *) &SYS->PA_L_MFP) + port_index * 2 + (pin_index / 8);
//uint32_t MFP_Pos = NU_MFP_POS(pin_index);
uint32_t MFP_Msk = NU_MFP_MSK(pin_index);
// E.g.: SYS->PA_L_MFP = (SYS->PA_L_MFP & (~SYS_PA_L_MFP_PA0_MFP_Msk) ) | SYS_PA_L_MFP_PA0_MFP_SC0_CD ;
*Px_x_MFP = (*Px_x_MFP & (~MFP_Msk)) | data;
// [TODO] Disconnect JTAG-DP + SW-DP signals.
// Warning: Need to reconnect under reset
//if ((pin == PA_13) || (pin == PA_14)) {
//
//}
//if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) {
//
//}
}
/**
* Configure pin pull-up/pull-down
*/
void pin_mode(PinName pin, PinMode mode)
{
MBED_ASSERT(pin != (PinName)NC);
uint32_t pin_index = NU_PINNAME_TO_PIN(pin);
uint32_t port_index = NU_PINNAME_TO_PORT(pin);
GPIO_T *gpio_base = NU_PORT_BASE(port_index);
uint32_t mode_intern = GPIO_PMD_INPUT;
switch (mode) {
case PullUp:
mode_intern = GPIO_PMD_INPUT;
break;
case PullDown:
case PullNone:
// NOTE: Not support
return;
case PushPull:
mode_intern = GPIO_PMD_OUTPUT;
break;
case OpenDrain:
mode_intern = GPIO_PMD_OPEN_DRAIN;
break;
case Quasi:
// NOTE: Not support
break;
}
GPIO_SetMode(gpio_base, 1 << pin_index, mode_intern);
}

View File

@ -0,0 +1,99 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#include "port_api.h"
#include "gpio_api.h"
#include "pinmap.h"
#include "mbed_error.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT || DEVICE_PORTINOUT
PinName port_pin(PortName port, int pin_n)
{
return (PinName) NU_PORT_N_PIN_TO_PINNAME(port, pin_n);
}
void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
{
obj->port = port;
obj->mask = mask;
obj->direction = dir;
uint32_t i;
obj->direction = dir;
for (i = 0; i < GPIO_PIN_MAX; i++) {
if (obj->mask & (1 << i)) {
gpio_set(port_pin(port, i));
}
}
port_dir(obj, dir);
}
void port_dir(port_t *obj, PinDirection dir)
{
uint32_t i;
obj->direction = dir;
for (i = 0; i < GPIO_PIN_MAX; i++) {
if (obj->mask & (1 << i)) {
if (dir == PIN_OUTPUT) {
GPIO_SetMode(NU_PORT_BASE(obj->port), 1 << i, GPIO_PMD_OUTPUT);
} else { // PIN_INPUT
GPIO_SetMode(NU_PORT_BASE(obj->port), 1 << i, GPIO_PMD_INPUT);
}
}
}
}
void port_mode(port_t *obj, PinMode mode)
{
uint32_t i;
for (i = 0; i < GPIO_PIN_MAX; i++) {
if (obj->mask & (1 << i)) {
pin_mode(port_pin(obj->port, i), mode);
}
}
}
void port_write(port_t *obj, int value)
{
uint32_t i;
uint32_t port_index = obj->port;
for (i = 0; i < GPIO_PIN_MAX; i++) {
if (obj->mask & (1 << i)) {
GPIO_PIN_ADDR(port_index, i) = (value & obj->mask) ? 1 : 0;
}
}
}
int port_read(port_t *obj)
{
uint32_t i;
uint32_t port_index = obj->port;
int value = 0;
for (i = 0; i < GPIO_PIN_MAX; i++) {
if (obj->mask & (1 << i)) {
value = value | (GPIO_PIN_ADDR(port_index, i) << i);
}
}
return value;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,208 @@
/* mbed Microcontroller Library
* Copyright (c) 2015-2017 Nuvoton
*
* 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.
*/
#include "us_ticker_api.h"
#include "sleep_api.h"
#include "mbed_assert.h"
#include "nu_modutil.h"
#include "nu_miscutil.h"
#include "mbed_critical.h"
// us_ticker tick = us = timestamp
#define US_PER_TICK 1
#define US_PER_SEC (1000 * 1000)
#define TMR0HIRES_CLK_PER_SEC (1000 * 1000)
#define TMR1HIRES_CLK_PER_SEC (1000 * 1000)
#define US_PER_TMR0HIRES_CLK (US_PER_SEC / TMR0HIRES_CLK_PER_SEC)
#define US_PER_TMR1HIRES_CLK (US_PER_SEC / TMR1HIRES_CLK_PER_SEC)
#define US_PER_TMR0HIRES_INT (1000 * 1000 * 10)
#define TMR0HIRES_CLK_PER_TMR0HIRES_INT ((uint32_t) ((uint64_t) US_PER_TMR0HIRES_INT * TMR0HIRES_CLK_PER_SEC / US_PER_SEC))
void TMR0_IRQHandler(void);
void TMR1_IRQHandler(void);
static void us_ticker_arm_cd(void);
static int us_ticker_inited = 0;
static volatile uint32_t counter_major = 0;
static volatile uint32_t cd_major_minor_us = 0;
static volatile uint32_t cd_minor_us = 0;
// NOTE: Choose clock source of timer:
// 1. HIRC: Be the most accurate but might cause unknown HardFault.
// 2. HXT: Less accurate and cannot pass mbed-drivers test.
// NOTE: TIMER_0 for normal counter, TIMER_1 for countdown.
static const struct nu_modinit_s timer0hires_modinit = {TIMER_0, TMR0_MODULE, CLK_CLKSEL1_TMR0_S_HXT, 0, TMR0_RST, TMR0_IRQn, (void *) TMR0_IRQHandler};
static const struct nu_modinit_s timer1hires_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1_S_HXT, 0, TMR1_RST, TMR1_IRQn, (void *) TMR1_IRQHandler};
#define TMR_CMP_MIN 2
#define TMR_CMP_MAX 0xFFFFFFu
void us_ticker_init(void)
{
if (us_ticker_inited) {
return;
}
counter_major = 0;
cd_major_minor_us = 0;
cd_minor_us = 0;
us_ticker_inited = 1;
// Reset IP
SYS_ResetModule(timer0hires_modinit.rsetidx);
SYS_ResetModule(timer1hires_modinit.rsetidx);
// Select IP clock source
CLK_SetModuleClock(timer0hires_modinit.clkidx, timer0hires_modinit.clksrc, timer0hires_modinit.clkdiv);
CLK_SetModuleClock(timer1hires_modinit.clkidx, timer1hires_modinit.clksrc, timer1hires_modinit.clkdiv);
// Enable IP clock
CLK_EnableModuleClock(timer0hires_modinit.clkidx);
CLK_EnableModuleClock(timer1hires_modinit.clkidx);
// Timer for normal counter
uint32_t clk_timer0 = TIMER_GetModuleClock((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname));
uint32_t prescale_timer0 = clk_timer0 / TMR0HIRES_CLK_PER_SEC - 1;
MBED_ASSERT((prescale_timer0 != (uint32_t) -1) && prescale_timer0 <= 127);
MBED_ASSERT((clk_timer0 % TMR0HIRES_CLK_PER_SEC) == 0);
uint32_t cmp_timer0 = TMR0HIRES_CLK_PER_TMR0HIRES_INT;
MBED_ASSERT(cmp_timer0 >= TMR_CMP_MIN && cmp_timer0 <= TMR_CMP_MAX);
((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname))->CTL = TIMER_PERIODIC_MODE;
((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname))->PRECNT = prescale_timer0;
((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname))->CMPR = cmp_timer0;
NVIC_SetVector(timer0hires_modinit.irq_n, (uint32_t) timer0hires_modinit.var);
NVIC_SetVector(timer1hires_modinit.irq_n, (uint32_t) timer1hires_modinit.var);
NVIC_EnableIRQ(timer0hires_modinit.irq_n);
NVIC_EnableIRQ(timer1hires_modinit.irq_n);
TIMER_EnableInt((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname));
TIMER_Start((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname));
}
uint32_t us_ticker_read()
{
if (! us_ticker_inited) {
us_ticker_init();
}
TIMER_T * timer0_base = (TIMER_T *) NU_MODBASE(timer0hires_modinit.modname);
do {
uint32_t major_minor_us;
uint32_t minor_us;
// NOTE: As TIMER_DR = TIMER_CMPR and counter_major has increased by one, TIMER_DR doesn't change to 0 for one tick time.
// NOTE: As TIMER_DR = TIMER_CMPR or TIMER_DR = 0, counter_major (ISR) may not sync with TIMER_DR. So skip and fetch stable one at the cost of 1 clock delay on this read.
do {
core_util_critical_section_enter();
// NOTE: Order of reading minor_us/carry here is significant.
minor_us = TIMER_GetCounter(timer0_base) * US_PER_TMR0HIRES_CLK;
uint32_t carry = (timer0_base->ISR & TIMER_ISR_TMR_IS_Msk) ? 1 : 0;
// When TIMER_DR approaches TIMER_CMPR and will wrap soon, we may get carry but TIMER_DR not wrapped. Hanlde carefully carry == 1 && TIMER_DR is near TIMER_CMPR.
if (carry && minor_us > (US_PER_TMR0HIRES_INT / 2)) {
major_minor_us = (counter_major + 1) * US_PER_TMR0HIRES_INT;
}
else {
major_minor_us = (counter_major + carry) * US_PER_TMR0HIRES_INT + minor_us;
}
core_util_critical_section_exit();
}
while (minor_us == 0 || minor_us == US_PER_TMR0HIRES_INT);
return (major_minor_us / US_PER_TICK);
}
while (0);
}
void us_ticker_disable_interrupt(void)
{
TIMER_DisableInt((TIMER_T *) NU_MODBASE(timer1hires_modinit.modname));
}
void us_ticker_clear_interrupt(void)
{
TIMER_ClearIntFlag((TIMER_T *) NU_MODBASE(timer1hires_modinit.modname));
}
void us_ticker_set_interrupt(timestamp_t timestamp)
{
TIMER_Stop((TIMER_T *) NU_MODBASE(timer1hires_modinit.modname));
int delta = (int) (timestamp - us_ticker_read());
if (delta > 0) {
cd_major_minor_us = delta * US_PER_TICK;
us_ticker_arm_cd();
}
else {
cd_major_minor_us = cd_minor_us = 0;
/**
* This event was in the past. Set the interrupt as pending, but don't process it here.
* This prevents a recurive loop under heavy load which can lead to a stack overflow.
*/
NVIC_SetPendingIRQ(timer1hires_modinit.irq_n);
}
}
void TMR0_IRQHandler(void)
{
TIMER_ClearIntFlag((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname));
counter_major ++;
}
void TMR1_IRQHandler(void)
{
TIMER_ClearIntFlag((TIMER_T *) NU_MODBASE(timer1hires_modinit.modname));
cd_major_minor_us = (cd_major_minor_us > cd_minor_us) ? (cd_major_minor_us - cd_minor_us) : 0;
if (cd_major_minor_us == 0) {
// NOTE: us_ticker_set_interrupt() may get called in us_ticker_irq_handler();
us_ticker_irq_handler();
}
else {
us_ticker_arm_cd();
}
}
static void us_ticker_arm_cd(void)
{
TIMER_T * timer1_base = (TIMER_T *) NU_MODBASE(timer1hires_modinit.modname);
cd_minor_us = cd_major_minor_us;
// Reset Timer's pre-scale counter, internal 24-bit up-counter and TMR_CTL [TMR_EN] bit
timer1_base->CTL |= TIMER_CTL_SW_RST_Msk;
// One-shot mode, Clock = 1 MHz
uint32_t clk_timer1 = TIMER_GetModuleClock((TIMER_T *) NU_MODBASE(timer1hires_modinit.modname));
uint32_t prescale_timer1 = clk_timer1 / TMR1HIRES_CLK_PER_SEC - 1;
MBED_ASSERT((prescale_timer1 != (uint32_t) -1) && prescale_timer1 <= 127);
MBED_ASSERT((clk_timer1 % TMR1HIRES_CLK_PER_SEC) == 0);
timer1_base->CTL &= ~TIMER_CTL_MODE_SEL_Msk;
timer1_base->CTL |= TIMER_ONESHOT_MODE;
timer1_base->PRECNT = prescale_timer1;
uint32_t cmp_timer1 = cd_minor_us / US_PER_TMR1HIRES_CLK;
cmp_timer1 = NU_CLAMP(cmp_timer1, TMR_CMP_MIN, TMR_CMP_MAX);
timer1_base->CMPR = cmp_timer1;
TIMER_EnableInt(timer1_base);
TIMER_Start(timer1_base);
}

View File

@ -89,6 +89,42 @@
#error "no toolchain defined"
#endif
#elif defined(TARGET_NUMAKER_PFM_NANO130)
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
#ifndef OS_CLOCK
#define OS_CLOCK 42000000
#endif
#if defined(__CC_ARM)
extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Base[];
extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Length[];
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Length[];
#define HEAP_START ((unsigned char*) Image$$ARM_LIB_HEAP$$ZI$$Base)
#define HEAP_SIZE ((uint32_t) Image$$ARM_LIB_HEAP$$ZI$$Length)
#define ISR_STACK_START ((unsigned char*)Image$$ARM_LIB_STACK$$ZI$$Base)
#define ISR_STACK_SIZE ((uint32_t)Image$$ARM_LIB_STACK$$ZI$$Length)
#elif defined(__GNUC__)
extern uint32_t __StackTop[];
extern uint32_t __StackLimit[];
extern uint32_t __end__[];
extern uint32_t __HeapLimit[];
#define HEAP_START ((unsigned char*)__end__)
#define HEAP_SIZE ((uint32_t)((uint32_t)__HeapLimit - (uint32_t)HEAP_START))
#define ISR_STACK_START ((unsigned char*)__StackLimit)
#define ISR_STACK_SIZE ((uint32_t)((uint32_t)__StackTop - (uint32_t)__StackLimit))
#elif defined(__ICCARM__)
/* No region declarations needed */
#else
#error "no toolchain defined"
#endif
#endif
#endif // MBED_MBED_RTX_H

View File

@ -2625,6 +2625,18 @@
"release_versions": ["2", "5"],
"device_name": "M453VG6AE"
},
"NUMAKER_PFM_NANO130": {
"core": "Cortex-M0",
"default_toolchain": "ARM",
"extra_labels": ["NUVOTON", "NANO100", "NUMAKER_PFM_NANO130"],
"is_disk_virtual": true,
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"],
"inherits": ["Target"],
"progen": {"target": "numaker-pfm-nano130"},
"device_has": ["INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES"],
"release_versions": ["5"],
"device_name": "NANO130KE3BN"
},
"HI2110": {
"inherits": ["Target"],
"core": "Cortex-M0",

View File

@ -162,6 +162,10 @@ class ARM(mbedToolchain):
cmd.extend(self.get_dep_option(object))
# Remove '.\' from relative path names of source files. For example, '.\mbed-os\platform\retarget.cpp' will truncate to 'mbed-os\platform\retarget.cpp'.
if source.startswith('.\\'):
source = source[2:]
cmd.extend(["-o", object, source])
# Call cmdline hook