From 0351d2686f63500b25fa1013873982d6033713a4 Mon Sep 17 00:00:00 2001 From: a74589669 <290198252@qq.com> Date: Sun, 2 Jun 2019 00:22:17 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=87=E7=94=A8=E5=BA=93=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E6=9D=A5=E5=AE=9E=E7=8E=B0=EF=BC=8C=E4=B8=8D=E4=BE=9D=E8=B5=96?= =?UTF-8?q?keil=E8=87=AA=E5=B8=A6=E7=9A=84pack=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StdDriver/inc/acmp.h | 333 +++++ StdDriver/inc/can.h | 175 +++ StdDriver/inc/clk.h | 489 ++++++++ StdDriver/inc/crc.h | 112 ++ StdDriver/inc/dac.h | 245 ++++ StdDriver/inc/eadc.h | 569 +++++++++ StdDriver/inc/ebi.h | 235 ++++ StdDriver/inc/fmc.h | 605 +++++++++ StdDriver/inc/gpio.h | 439 +++++++ StdDriver/inc/i2c.h | 413 +++++++ StdDriver/inc/otg.h | 260 ++++ StdDriver/inc/pdma.h | 300 +++++ StdDriver/inc/pwm.h | 555 +++++++++ StdDriver/inc/rtc.h | 272 +++++ StdDriver/inc/sc.h | 269 ++++ StdDriver/inc/scuart.h | 279 +++++ StdDriver/inc/spi.h | 630 ++++++++++ StdDriver/inc/sys.h | 970 +++++++++++++++ StdDriver/inc/timer.h | 415 +++++++ StdDriver/inc/tk.h | 302 +++++ StdDriver/inc/uart.h | 460 +++++++ StdDriver/inc/usbd.h | 657 ++++++++++ StdDriver/inc/wdt.h | 201 +++ StdDriver/inc/wwdt.h | 148 +++ StdDriver/src/acmp.c | 84 ++ StdDriver/src/can.c | 1098 +++++++++++++++++ StdDriver/src/clk.c | 751 ++++++++++++ StdDriver/src/crc.c | 93 ++ StdDriver/src/dac.c | 94 ++ StdDriver/src/eadc.c | 159 +++ StdDriver/src/ebi.c | 178 +++ StdDriver/src/fmc.c | 320 +++++ StdDriver/src/gpio.c | 102 ++ StdDriver/src/i2c.c | 642 ++++++++++ StdDriver/src/pdma.c | 389 ++++++ StdDriver/src/pwm.c | 1351 ++++++++++++++++++++ StdDriver/src/retarget.c | 674 ++++++++++ StdDriver/src/rtc.c | 789 ++++++++++++ StdDriver/src/sc.c | 299 +++++ StdDriver/src/scuart.c | 223 ++++ StdDriver/src/spi.c | 1154 ++++++++++++++++++ StdDriver/src/sys.c | 213 ++++ StdDriver/src/timer.c | 292 +++++ StdDriver/src/tk.c | 265 ++++ StdDriver/src/uart.c | 512 ++++++++ StdDriver/src/usbd.c | 728 +++++++++++ StdDriver/src/usbd.c.new | 723 +++++++++++ StdDriver/src/wdt.c | 71 ++ StdDriver/src/wwdt.c | 71 ++ stepper/Listings/stepper.map | 1556 +++++++++++++++--------- stepper/Objects/stepper.axf | Bin 619268 -> 630744 bytes stepper/Objects/stepper.lnp | 19 +- stepper/RTE/_Target_1/RTE_Components.h | 18 - stepper/stepper.uvoptx | 154 ++- stepper/stepper.uvprojx | 107 +- 55 files changed, 21805 insertions(+), 657 deletions(-) create mode 100644 StdDriver/inc/acmp.h create mode 100644 StdDriver/inc/can.h create mode 100644 StdDriver/inc/clk.h create mode 100644 StdDriver/inc/crc.h create mode 100644 StdDriver/inc/dac.h create mode 100644 StdDriver/inc/eadc.h create mode 100644 StdDriver/inc/ebi.h create mode 100644 StdDriver/inc/fmc.h create mode 100644 StdDriver/inc/gpio.h create mode 100644 StdDriver/inc/i2c.h create mode 100644 StdDriver/inc/otg.h create mode 100644 StdDriver/inc/pdma.h create mode 100644 StdDriver/inc/pwm.h create mode 100644 StdDriver/inc/rtc.h create mode 100644 StdDriver/inc/sc.h create mode 100644 StdDriver/inc/scuart.h create mode 100644 StdDriver/inc/spi.h create mode 100644 StdDriver/inc/sys.h create mode 100644 StdDriver/inc/timer.h create mode 100644 StdDriver/inc/tk.h create mode 100644 StdDriver/inc/uart.h create mode 100644 StdDriver/inc/usbd.h create mode 100644 StdDriver/inc/wdt.h create mode 100644 StdDriver/inc/wwdt.h create mode 100644 StdDriver/src/acmp.c create mode 100644 StdDriver/src/can.c create mode 100644 StdDriver/src/clk.c create mode 100644 StdDriver/src/crc.c create mode 100644 StdDriver/src/dac.c create mode 100644 StdDriver/src/eadc.c create mode 100644 StdDriver/src/ebi.c create mode 100644 StdDriver/src/fmc.c create mode 100644 StdDriver/src/gpio.c create mode 100644 StdDriver/src/i2c.c create mode 100644 StdDriver/src/pdma.c create mode 100644 StdDriver/src/pwm.c create mode 100644 StdDriver/src/retarget.c create mode 100644 StdDriver/src/rtc.c create mode 100644 StdDriver/src/sc.c create mode 100644 StdDriver/src/scuart.c create mode 100644 StdDriver/src/spi.c create mode 100644 StdDriver/src/sys.c create mode 100644 StdDriver/src/timer.c create mode 100644 StdDriver/src/tk.c create mode 100644 StdDriver/src/uart.c create mode 100644 StdDriver/src/usbd.c create mode 100644 StdDriver/src/usbd.c.new create mode 100644 StdDriver/src/wdt.c create mode 100644 StdDriver/src/wwdt.c diff --git a/StdDriver/inc/acmp.h b/StdDriver/inc/acmp.h new file mode 100644 index 0000000..67857f4 --- /dev/null +++ b/StdDriver/inc/acmp.h @@ -0,0 +1,333 @@ +/**************************************************************************//** + * @file ACMP.h + * @version V0.10 + * $Revision: 10 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 Series ACMP Driver Header File + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + * + ******************************************************************************/ +#ifndef __ACMP_H__ +#define __ACMP_H__ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Include related headers */ +/*---------------------------------------------------------------------------------------------------------*/ +#include "M451Series.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup ACMP_Driver ACMP Driver + @{ +*/ + + +/** @addtogroup ACMP_EXPORTED_CONSTANTS ACMP Exported Constants + @{ +*/ + + + +/*---------------------------------------------------------------------------------------------------------*/ +/* ACMP_CTL constant definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define ACMP_CTL_FILTSEL_OFF (0UL << 13) /*!< ACMP_CTL setting for filter function disabled. */ +#define ACMP_CTL_FILTSEL_1PCLK (1UL << 13) /*!< ACMP_CTL setting for 1 PCLK filter count. */ +#define ACMP_CTL_FILTSEL_2PCLK (2UL << 13) /*!< ACMP_CTL setting for 2 PCLK filter count. */ +#define ACMP_CTL_FILTSEL_4PCLK (3UL << 13) /*!< ACMP_CTL setting for 4 PCLK filter count. */ +#define ACMP_CTL_FILTSEL_8PCLK (4UL << 13) /*!< ACMP_CTL setting for 8 PCLK filter count. */ +#define ACMP_CTL_FILTSEL_16PCLK (5UL << 13) /*!< ACMP_CTL setting for 16 PCLK filter count. */ +#define ACMP_CTL_FILTSEL_32PCLK (6UL << 13) /*!< ACMP_CTL setting for 32 PCLK filter count. */ +#define ACMP_CTL_FILTSEL_64PCLK (7UL << 13) /*!< ACMP_CTL setting for 64 PCLK filter count. */ +#define ACMP_CTL_INTPOL_RF (0UL << 8) /*!< ACMP_CTL setting for selecting rising edge and falling edge as interrupt condition. */ +#define ACMP_CTL_INTPOL_R (1UL << 8) /*!< ACMP_CTL setting for selecting rising edge as interrupt condition. */ +#define ACMP_CTL_INTPOL_F (2UL << 8) /*!< ACMP_CTL setting for selecting falling edge as interrupt condition. */ +#define ACMP_CTL_POSSEL_P0 (0UL << 6) /*!< ACMP_CTL setting for selecting ACMPx_P0 pin as the source of ACMP V+. */ +#define ACMP_CTL_POSSEL_P1 (1UL << 6) /*!< ACMP_CTL setting for selecting ACMPx_P1 pin as the source of ACMP V+. */ +#define ACMP_CTL_POSSEL_P2 (2UL << 6) /*!< ACMP_CTL setting for selecting ACMPx_P2 pin as the source of ACMP V+. */ +#define ACMP_CTL_POSSEL_P3 (3UL << 6) /*!< ACMP_CTL setting for selecting ACMPx_P3 pin as the source of ACMP V+. */ +#define ACMP_CTL_NEGSEL_PIN (0UL << 4) /*!< ACMP_CTL setting for selecting the voltage of ACMP negative input pin as the source of ACMP V-. */ +#define ACMP_CTL_NEGSEL_CRV (1UL << 4) /*!< ACMP_CTL setting for selecting internal comparator reference voltage as the source of ACMP V-. */ +#define ACMP_CTL_NEGSEL_VBG (2UL << 4) /*!< ACMP_CTL setting for selecting internal Band-gap voltage as the source of ACMP V-. */ +#define ACMP_CTL_NEGSEL_DAC (3UL << 4) /*!< ACMP_CTL setting for selecting DAC output voltage as the source of ACMP V-. */ +#define ACMP_CTL_HYSTERESIS_ENABLE (1UL << 2) /*!< ACMP_CTL setting for enabling the hysteresis function. */ +#define ACMP_CTL_HYSTERESIS_DISABLE (0UL << 2) /*!< ACMP_CTL setting for disabling the hysteresis function. */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* ACMP_VREF constant definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define ACMP_VREF_CRVSSEL_VDDA (0UL << 6) /*!< ACMP_VREF setting for selecting analog supply voltage VDDA as the CRV source voltage */ +#define ACMP_VREF_CRVSSEL_INTVREF (1UL << 6) /*!< ACMP_VREF setting for selecting internal reference voltage as the CRV source voltage */ + + +/*@}*/ /* end of group ACMP_EXPORTED_CONSTANTS */ + + +/** @addtogroup ACMP_EXPORTED_FUNCTIONS ACMP Exported Functions + @{ +*/ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Define Macros and functions */ +/*---------------------------------------------------------------------------------------------------------*/ + + +/** + * @brief This macro is used to enable output inverse function + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will set ACMPOINV bit of ACMP_CTL register to enable output inverse function. + */ +#define ACMP_ENABLE_OUTPUT_INVERSE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] |= ACMP_CTL_ACMPOINV_Msk) + +/** + * @brief This macro is used to disable output inverse function + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will clear ACMPOINV bit of ACMP_CTL register to disable output inverse function. + */ +#define ACMP_DISABLE_OUTPUT_INVERSE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] &= ~ACMP_CTL_ACMPOINV_Msk) + +/** + * @brief This macro is used to select ACMP negative input source + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @param[in] u32Src is comparator negative input selection. Including: + * - \ref ACMP_CTL_NEGSEL_PIN + * - \ref ACMP_CTL_NEGSEL_CRV + * - \ref ACMP_CTL_NEGSEL_VBG + * - \ref ACMP_CTL_NEGSEL_DAC + * @return None + * @details This macro will set NEGSEL (ACMP_CTL[5:4]) to determine the source of negative input. + */ +#define ACMP_SET_NEG_SRC(acmp, u32ChNum, u32Src) ((acmp)->CTL[(u32ChNum)%2] = ((acmp)->CTL[(u32ChNum)%2] & ~ACMP_CTL_NEGSEL_Msk) | (u32Src)) + +/** + * @brief This macro is used to enable hysteresis function + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will set HYSEN bit of ACMP_CTL register to enable hysteresis function. + */ +#define ACMP_ENABLE_HYSTERESIS(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] |= ACMP_CTL_HYSEN_Msk) + +/** + * @brief This macro is used to disable hysteresis function + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will clear HYSEN bit of ACMP_CTL register to disable hysteresis function. + */ +#define ACMP_DISABLE_HYSTERESIS(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] &= ~ACMP_CTL_HYSEN_Msk) + +/** + * @brief This macro is used to enable interrupt + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will set ACMPIE bit of ACMP_CTL register to enable interrupt function. + * If wake-up function is enabled, the wake-up interrupt will be enabled as well. + */ +#define ACMP_ENABLE_INT(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] |= ACMP_CTL_ACMPIE_Msk) + +/** + * @brief This macro is used to disable interrupt + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will clear ACMPIE bit of ACMP_CTL register to disable interrupt function. + */ +#define ACMP_DISABLE_INT(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] &= ~ACMP_CTL_ACMPIE_Msk) + +/** + * @brief This macro is used to enable ACMP + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will set ACMPEN bit of ACMP_CTL register to enable analog comparator. + */ +#define ACMP_ENABLE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] |= ACMP_CTL_ACMPEN_Msk) + +/** + * @brief This macro is used to disable ACMP + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will clear ACMPEN bit of ACMP_CTL register to disable analog comparator. + */ +#define ACMP_DISABLE(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] &= ~ACMP_CTL_ACMPEN_Msk) + +/** + * @brief This macro is used to get ACMP output value + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return ACMP output value + * @details This macro will return the ACMP output value. + */ +#define ACMP_GET_OUTPUT(acmp, u32ChNum) (((acmp)->STATUS & (ACMP_STATUS_ACMPO0_Msk<<((u32ChNum)%2)))?1:0) + +/** + * @brief This macro is used to get ACMP interrupt flag + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return ACMP interrupt occurred (1) or not (0) + * @details This macro will return the ACMP interrupt flag. + */ +#define ACMP_GET_INT_FLAG(acmp, u32ChNum) (((acmp)->STATUS & (ACMP_STATUS_ACMPIF0_Msk<<((u32ChNum)%2)))?1:0) + +/** + * @brief This macro is used to clear ACMP interrupt flag + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will write 1 to ACMPIFn bit of ACMP_STATUS register to clear interrupt flag. + */ +#define ACMP_CLR_INT_FLAG(acmp, u32ChNum) ((acmp)->STATUS = (ACMP_STATUS_ACMPIF0_Msk<<((u32ChNum)%2))) + +/** + * @brief This macro is used to clear ACMP wake-up interrupt flag + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will write 1 to WKIFn bit of ACMP_STATUS register to clear interrupt flag. + */ +#define ACMP_CLR_WAKEUP_INT_FLAG(acmp, u32ChNum) ((acmp)->STATUS = (ACMP_STATUS_WKIF0_Msk<<((u32ChNum)%2))) + +/** + * @brief This macro is used to enable ACMP wake-up function + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will set WKEN (ACMP_CTL[16]) to enable ACMP wake-up function. + */ +#define ACMP_ENABLE_WAKEUP(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] |= ACMP_CTL_WKEN_Msk) + +/** + * @brief This macro is used to disable ACMP wake-up function + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will clear WKEN (ACMP_CTL[16]) to disable ACMP wake-up function. + */ +#define ACMP_DISABLE_WAKEUP(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] &= ~ACMP_CTL_WKEN_Msk) + +/** + * @brief This macro is used to select ACMP positive input pin + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @param[in] u32Pin Comparator positive pin selection. Including: + * - \ref ACMP_CTL_POSSEL_P0 + * - \ref ACMP_CTL_POSSEL_P1 + * - \ref ACMP_CTL_POSSEL_P2 + * - \ref ACMP_CTL_POSSEL_P3 + * @return None + * @details This macro will set POSSEL (ACMP_CTL[7:6]) to determine the comparator positive input pin. + */ +#define ACMP_SELECT_P(acmp, u32ChNum, u32Pin) ((acmp)->CTL[(u32ChNum)%2] = ((acmp)->CTL[(u32ChNum)%2] & ~ACMP_CTL_POSSEL_Msk) | (u32Pin)) + +/** + * @brief This macro is used to enable ACMP filter function + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will set OUTSEL (ACMP_CTL[12]) to enable output filter function. + */ +#define ACMP_ENABLE_FILTER(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] |= ACMP_CTL_OUTSEL_Msk) + +/** + * @brief This macro is used to disable ACMP filter function + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @return None + * @details This macro will clear OUTSEL (ACMP_CTL[12]) to disable output filter function. + */ +#define ACMP_DISABLE_FILTER(acmp, u32ChNum) ((acmp)->CTL[(u32ChNum)%2] &= ~ACMP_CTL_OUTSEL_Msk) + +/** + * @brief This macro is used to set ACMP filter function + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @param[in] u32Cnt is comparator filter count setting. + * - \ref ACMP_CTL_FILTSEL_OFF + * - \ref ACMP_CTL_FILTSEL_1PCLK + * - \ref ACMP_CTL_FILTSEL_2PCLK + * - \ref ACMP_CTL_FILTSEL_4PCLK + * - \ref ACMP_CTL_FILTSEL_8PCLK + * - \ref ACMP_CTL_FILTSEL_16PCLK + * - \ref ACMP_CTL_FILTSEL_32PCLK + * - \ref ACMP_CTL_FILTSEL_64PCLK + * @return None + * @details When ACMP output filter function is enabled, the output sampling count is determined by FILTSEL (ACMP_CTL[15:13]). + */ +#define ACMP_SET_FILTER(acmp, u32ChNum, u32Cnt) ((acmp)->CTL[(u32ChNum)%2] = ((acmp)->CTL[(u32ChNum)%2] & ~ACMP_CTL_FILTSEL_Msk) | (u32Cnt)) + +/** + * @brief This macro is used to select comparator reference voltage + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32Level The comparator reference voltage setting. + * The formula is: + * comparator reference voltage = CRV source voltage x (1/6 + u32Level/24) + * The range of u32Level is 0 ~ 15. + * @return None + * @details When CRV is selected as ACMP negative input source, the CRV level is determined by CRVCTL (ACMP_VREF[3:0]). + */ +#define ACMP_CRV_SEL(acmp, u32Level) ((acmp)->VREF = ((acmp)->VREF & ~ACMP_VREF_CRVCTL_Msk) | ((u32Level)<VREF = ((acmp)->VREF & ~ACMP_VREF_CRVSSEL_Msk) | (u32Src)) + +/** + * @brief This macro is used to select ACMP interrupt condition + * @param[in] acmp The pointer of the specified ACMP module + * @param[in] u32ChNum The ACMP number + * @param[in] u32Cond Comparator interrupt condition selection. Including: + * - \ref ACMP_CTL_INTPOL_RF + * - \ref ACMP_CTL_INTPOL_R + * - \ref ACMP_CTL_INTPOL_F + * @return None + * @details The ACMP output interrupt condition can be rising edge, falling edge or any edge. + */ +#define ACMP_SELECT_INT_COND(acmp, u32ChNum, u32Cond) ((acmp)->CTL[(u32ChNum)%2] = ((acmp)->CTL[(u32ChNum)%2] & ~ACMP_CTL_INTPOL_Msk) | (u32Cond)) + + + +/* Function prototype declaration */ +void ACMP_Open(ACMP_T *, uint32_t u32ChNum, uint32_t u32NegSrc, uint32_t u32HysteresisEn); +void ACMP_Close(ACMP_T *, uint32_t u32ChNum); + + + +/*@}*/ /* end of group ACMP_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group ACMP_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + + +#endif //__ACMP_H__ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/can.h b/StdDriver/inc/can.h new file mode 100644 index 0000000..7f661c3 --- /dev/null +++ b/StdDriver/inc/can.h @@ -0,0 +1,175 @@ +/**************************************************************************//** + * @file can.h + * @version V2.00 + * $Revision: 9 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 Series CAN Driver Header File + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + * + ******************************************************************************/ +#ifndef __CAN_H__ +#define __CAN_H__ + +#include "M451Series.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup CAN_Driver CAN Driver + @{ +*/ + +/** @addtogroup CAN_EXPORTED_CONSTANTS CAN Exported Constants + @{ +*/ +/*---------------------------------------------------------------------------------------------------------*/ +/* CAN Test Mode Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define CAN_NORMAL_MODE 0 +#define CAN_BASIC_MODE 1 + +/*---------------------------------------------------------------------------------------------------------*/ +/* Message ID Type Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define CAN_STD_ID 0 +#define CAN_EXT_ID 1 + +/*---------------------------------------------------------------------------------------------------------*/ +/* Message Frame Type Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define CAN_REMOTE_FRAME 0 +#define CAN_DATA_FRAME 1 + +/*---------------------------------------------------------------------------------------------------------*/ +/* CAN message structure */ +/*---------------------------------------------------------------------------------------------------------*/ +typedef struct +{ + uint32_t IdType; + uint32_t FrameType; + uint32_t Id; + uint8_t DLC; + uint8_t Data[8]; +} STR_CANMSG_T; + +/*---------------------------------------------------------------------------------------------------------*/ +/* CAN mask message structure */ +/*---------------------------------------------------------------------------------------------------------*/ +typedef struct +{ + uint8_t u8Xtd; + uint8_t u8Dir; + uint32_t u32Id; + uint8_t u8IdType; +} STR_CANMASK_T; + +#define MSG(id) (id) + + +/*@}*/ /* end of group CAN_EXPORTED_CONSTANTS */ + + +/** @addtogroup CAN_EXPORTED_FUNCTIONS CAN Exported Functions + @{ +*/ + +/** + * @brief Get interrupt status. + * + * @param[in] can The base address of can module. + * + * @return CAN module status register value. + * + * @details Status Interrupt is generated by bits BOff (CAN_STATUS[7]), EWarn (CAN_STATUS[6]), + * EPass (CAN_STATUS[5]), RxOk (CAN_STATUS[4]), TxOk (CAN_STATUS[3]), and LEC (CAN_STATUS[2:0]). + */ +#define CAN_GET_INT_STATUS(can) ((can)->STATUS) + +/** + * @brief Get specified interrupt pending status. + * + * @param[in] can The base address of can module. + * + * @return The source of the interrupt. + * + * @details If several interrupts are pending, the CAN Interrupt Register will point to the pending interrupt + * with the highest priority, disregarding their chronological order. + */ +#define CAN_GET_INT_PENDING_STATUS(can) ((can)->IIDR) + +/** + * @brief Disable wake-up function. + * + * @param[in] can The base address of can module. + * + * @return None + * + * @details The macro is used to disable wake-up function. + */ +#define CAN_DISABLE_WAKEUP(can) ((can)->WU_EN = 0) + +/** + * @brief Enable wake-up function. + * + * @param[in] can The base address of can module. + * + * @return None + * + * @details User can wake-up system when there is a falling edge in the CAN_Rx pin. + */ +#define CAN_ENABLE_WAKEUP(can) ((can)->WU_EN = CAN_WUEN_WAKUP_EN_Msk) + +/** + * @brief Get specified Message Object new data into bit value. + * + * @param[in] can The base address of can module. + * @param[in] u32MsgNum Specified Message Object number, valid value are from 0 to 31. + * + * @return Specified Message Object new data into bit value. + * + * @details The NewDat bit (CAN_IFn_MCON[15]) of a specific Message Object can be set/reset by the software through the IFn Message Interface Registers + * or by the Message Handler after reception of a Data Frame or after a successful transmission. + */ +#define CAN_GET_NEW_DATA_IN_BIT(can, u32MsgNum) ((u32MsgNum) < 16 ? (can)->NDAT1 & (1 << (u32MsgNum)) : (can)->NDAT2 & (1 << ((u32MsgNum)-16))) + + +/*---------------------------------------------------------------------------------------------------------*/ +/* Define CAN functions prototype */ +/*---------------------------------------------------------------------------------------------------------*/ +uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate); +uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode); +void CAN_Close(CAN_T *tCAN); +void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum); +void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask); +void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask); +int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg); +int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg); +int32_t CAN_SetMultiRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32MsgCount, uint32_t u32IDType, uint32_t u32ID); +int32_t CAN_SetRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID); +int32_t CAN_SetRxMsgAndMsk(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID, uint32_t u32IDMask); +int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg); +int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum); + + +/*@}*/ /* end of group CAN_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group CAN_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__CAN_H__ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/clk.h b/StdDriver/inc/clk.h new file mode 100644 index 0000000..6dc8846 --- /dev/null +++ b/StdDriver/inc/clk.h @@ -0,0 +1,489 @@ +/****************************************************************************** + * @file CLK.h + * @version V3.0 + * $Revision 1 $ + * $Date: 17/07/20 1:52p $ + * @brief M451 Series CLK Header File + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. + ******************************************************************************/ +#ifndef __CLK_H__ +#define __CLK_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup CLK_Driver CLK Driver + @{ +*/ + +/** @addtogroup CLK_EXPORTED_CONSTANTS CLK Exported Constants + @{ +*/ + + +#define FREQ_25MHZ 25000000 +#define FREQ_50MHZ 50000000 +#define FREQ_72MHZ 72000000 +#define FREQ_125MHZ 125000000 +#define FREQ_200MHZ 200000000 +#define FREQ_250MHZ 250000000 +#define FREQ_500MHZ 500000000 + + +/*---------------------------------------------------------------------------------------------------------*/ +/* CLKSEL0 constant definitions. (Write-protection) */ +/*---------------------------------------------------------------------------------------------------------*/ +#define CLK_CLKSEL0_HCLKSEL_HXT (0x00UL< 250MHz is preferred.) */ +#define CLK_PLLCTL_NR(x) (((x)-2)<<9) /*!< x must be constant and 2 <= x <= 33. 1.6MHz < FIN/NR < 16MHz */ + +#define CLK_PLLCTL_NO_1 0x0000UL /*!< For output divider is 1 */ +#define CLK_PLLCTL_NO_2 0x4000UL /*!< For output divider is 2 */ +#define CLK_PLLCTL_NO_4 0xC000UL /*!< For output divider is 4 */ + +#define CLK_PLLCTL_72MHz_HXT (CLK_PLLCTL_PLLSRC_HXT | CLK_PLLCTL_NR(2) | CLK_PLLCTL_NF( 48) | CLK_PLLCTL_NO_4) /*!< Predefined PLLCTL setting for 72MHz PLL output with HXT(12MHz X'tal) */ +#define CLK_PLLCTL_144MHz_HXT (CLK_PLLCTL_PLLSRC_HXT | CLK_PLLCTL_NR(2) | CLK_PLLCTL_NF( 48) | CLK_PLLCTL_NO_2) /*!< Predefined PLLCTL setting for 144MHz PLL output with HXT(12MHz X'tal) */ +#define CLK_PLLCTL_72MHz_HIRC (CLK_PLLCTL_PLLSRC_HIRC | CLK_PLLCTL_NR(4) | CLK_PLLCTL_NF( 52) | CLK_PLLCTL_NO_4) /*!< Predefined PLLCTL setting for 71.8848MHz PLL output with HIRC(22.1184MHz IRC) */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* MODULE constant definitions. */ +/*---------------------------------------------------------------------------------------------------------*/ + +/* APBCLK(31:30)|CLKSEL(29:28)|CLKSEL_Msk(27:25) |CLKSEL_Pos(24:20)|CLKDIV(19:18)|CLKDIV_Msk(17:10)|CLKDIV_Pos(9:5)|IP_EN_Pos(4:0) */ + +#define MODULE_APBCLK(x) (((x) >>30) & 0x3) /*!< Calculate AHBCLK/APBCLK offset on MODULE index, 0x0:AHBCLK, 0x1:APBCLK0, 0x2:APBCLK1 */ +#define MODULE_CLKSEL(x) (((x) >>28) & 0x3) /*!< Calculate CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2, 0x3:CLKSEL3 */ +#define MODULE_CLKSEL_Msk(x) (((x) >>25) & 0x7) /*!< Calculate CLKSEL mask offset on MODULE index */ +#define MODULE_CLKSEL_Pos(x) (((x) >>20) & 0x1f) /*!< Calculate CLKSEL position offset on MODULE index */ +#define MODULE_CLKDIV(x) (((x) >>18) & 0x3) /*!< Calculate APBCLK CLKDIV on MODULE index, 0x0:CLKDIV, 0x1:CLKDIV1 */ +#define MODULE_CLKDIV_Msk(x) (((x) >>10) & 0xff) /*!< Calculate CLKDIV mask offset on MODULE index */ +#define MODULE_CLKDIV_Pos(x) (((x) >>5 ) & 0x1f) /*!< Calculate CLKDIV position offset on MODULE index */ +#define MODULE_IP_EN_Pos(x) (((x) >>0 ) & 0x1f) /*!< Calculate APBCLK offset on MODULE index */ +#define MODULE_NoMsk 0x0 /*!< Not mask on MODULE index */ +#define NA MODULE_NoMsk /*!< Not Available */ + +#define MODULE_APBCLK_ENC(x) (((x) & 0x03) << 30) /*!< MODULE index, 0x0:AHBCLK, 0x1:APBCLK0, 0x2:APBCLK1 */ +#define MODULE_CLKSEL_ENC(x) (((x) & 0x03) << 28) /*!< CLKSEL offset on MODULE index, 0x0:CLKSEL0, 0x1:CLKSEL1, 0x2:CLKSEL2, 0x3:CLKSEL3 */ +#define MODULE_CLKSEL_Msk_ENC(x) (((x) & 0x07) << 25) /*!< CLKSEL mask offset on MODULE index */ +#define MODULE_CLKSEL_Pos_ENC(x) (((x) & 0x1f) << 20) /*!< CLKSEL position offset on MODULE index */ +#define MODULE_CLKDIV_ENC(x) (((x) & 0x03) << 18) /*!< APBCLK CLKDIV on MODULE index, 0x0:CLKDIV, 0x1:CLKDIV1 */ +#define MODULE_CLKDIV_Msk_ENC(x) (((x) & 0xff) << 10) /*!< CLKDIV mask offset on MODULE index */ +#define MODULE_CLKDIV_Pos_ENC(x) (((x) & 0x1f) << 5) /*!< CLKDIV position offset on MODULE index */ +#define MODULE_IP_EN_Pos_ENC(x) (((x) & 0x1f) << 0) /*!< AHBCLK/APBCLK offset on MODULE index */ + + +//AHBCLK +#define PDMA_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_PDMACKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PDMA Module */ + +#define ISP_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_ISPCKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< ISP Module */ + +#define EBI_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_EBICKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< EBI Module */ + +#define USBH_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_USBHCKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC(4)) /*!< USBH Module */ + +#define CRC_MODULE (MODULE_APBCLK_ENC( 0)|MODULE_IP_EN_Pos_ENC(CLK_AHBCLK_CRCCKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< CRC Module */ + + +//APBCLK0 +#define WDT_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_WDTCKEN_Pos) |\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 0)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< WDT Module */ + +#define WWDT_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_WDTCKEN_Pos) |\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(30)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< WWDT Module */ + +#define RTC_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_RTCCKEN_Pos) |\ + MODULE_CLKSEL_ENC( 3)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 8)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< RTC Module */ + +#define TMR0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_TMR0CKEN_Pos) |\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC( 8)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR0 Module */ + +#define TMR1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_TMR1CKEN_Pos) |\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(12)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR1 Module */ + +#define TMR2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_TMR2CKEN_Pos) |\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(16)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR2 Module */ + +#define TMR3_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_TMR3CKEN_Pos) |\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 7)|MODULE_CLKSEL_Pos_ENC(20)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TMR3 Module */ + +#define CLKO_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_CLKOCKEN_Pos) |\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(28)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< CLKO Module */ + +#define ACMP01_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_ACMP01CKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< ACMP01 Module */ + +#define I2C0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_I2C0CKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2C0 Module */ + +#define I2C1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_I2C1CKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< I2C1 Module */ + +#define SPI0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_SPI0CKEN_Pos) |\ + MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 2)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI0 Module */ + +#define SPI1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_SPI1CKEN_Pos) |\ + MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 4)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI1 Module */ + +#define SPI2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_SPI2CKEN_Pos) |\ + MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 6)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< SPI2 Module */ + +#define UART0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_UART0CKEN_Pos)|\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\ + MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART0 Module */ + +#define UART1_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_UART1CKEN_Pos)|\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\ + MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART1 Module */ + +#define UART2_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_UART2CKEN_Pos)|\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\ + MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART2 Module */ + +#define UART3_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_UART3CKEN_Pos)|\ + MODULE_CLKSEL_ENC( 1)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC(24)|\ + MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC( 8)) /*!< UART3 Module */ + +#define CAN0_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_CAN0CKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< CAN0 Module */ + +#define OTG_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_OTGCKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC(4)) /*!< OTG Module */ + +#define USBD_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_USBDCKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0x0F)|MODULE_CLKDIV_Pos_ENC(4)) /*!< USBD Module */ + +#define EADC_MODULE (MODULE_APBCLK_ENC( 1)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK0_EADCCKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC( 0)|MODULE_CLKDIV_Msk_ENC(0xFF)|MODULE_CLKDIV_Pos_ENC(16)) /*!< EADC Module */ + + +//APBCLK1 +#define SC0_MODULE (MODULE_APBCLK_ENC( 2UL)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_SC0CKEN_Pos) |\ + MODULE_CLKSEL_ENC( 3)|MODULE_CLKSEL_Msk_ENC( 3)|MODULE_CLKSEL_Pos_ENC( 0)|\ + MODULE_CLKDIV_ENC( 1)|MODULE_CLKDIV_Msk_ENC(0xFF)|MODULE_CLKDIV_Pos_ENC( 0)) /*!< SC0 Module */ + +#define DAC_MODULE (MODULE_APBCLK_ENC( 2UL)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_DACCKEN_Pos) |\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< DAC Module */ + +#define PWM0_MODULE (MODULE_APBCLK_ENC( 2UL)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_PWM0CKEN_Pos)|\ + MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 0)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM0 Module */ + +#define PWM1_MODULE (MODULE_APBCLK_ENC( 2UL)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_PWM1CKEN_Pos)|\ + MODULE_CLKSEL_ENC( 2)|MODULE_CLKSEL_Msk_ENC( 1)|MODULE_CLKSEL_Pos_ENC( 1)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< PWM1 Module */ + +#define TK_MODULE (MODULE_APBCLK_ENC( 2UL)|MODULE_IP_EN_Pos_ENC(CLK_APBCLK1_TKCKEN_Pos)|\ + MODULE_CLKSEL_ENC(NA)|MODULE_CLKSEL_Msk_ENC(NA)|MODULE_CLKSEL_Pos_ENC(NA)|\ + MODULE_CLKDIV_ENC(NA)|MODULE_CLKDIV_Msk_ENC(NA)|MODULE_CLKDIV_Pos_ENC(NA)) /*!< TK Module */ + + +/*@}*/ /* end of group CLK_EXPORTED_CONSTANTS */ + + +/** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions + @{ +*/ + + +/** + * @brief Get PLL clock frequency + * @param None + * @return PLL frequency + * @details This function get PLL frequency. The frequency unit is Hz. + */ +__STATIC_INLINE uint32_t CLK_GetPLLClockFreq(void) +{ + uint32_t u32PllFreq = 0, u32PllReg; + uint32_t u32FIN, u32NF, u32NR, u32NO; + uint8_t au8NoTbl[4] = {1, 2, 2, 4}; + + u32PllReg = CLK->PLLCTL; + + if(u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk)) + return 0; /* PLL is in power down mode or fix low */ + + if(u32PllReg & CLK_PLLCTL_PLLSRC_HIRC) + u32FIN = __HIRC; /* PLL source clock from HIRC */ + else + u32FIN = __HXT; /* PLL source clock from HXT */ + + if(u32PllReg & CLK_PLLCTL_BP_Msk) + return u32FIN; /* PLL is in bypass mode */ + + /* PLL is output enabled in normal work mode */ + u32NO = au8NoTbl[((u32PllReg & CLK_PLLCTL_OUTDIV_Msk) >> CLK_PLLCTL_OUTDIV_Pos)]; + u32NF = ((u32PllReg & CLK_PLLCTL_FBDIV_Msk) >> CLK_PLLCTL_FBDIV_Pos) + 2; + u32NR = ((u32PllReg & CLK_PLLCTL_INDIV_Msk) >> CLK_PLLCTL_INDIV_Pos) + 2; + + /* u32FIN is shifted 2 bits to avoid overflow */ + u32PllFreq = (((u32FIN >> 2) * u32NF) / (u32NR * u32NO) << 2); + + return u32PllFreq; +} + +/** + * @brief This function execute delay function. + * @param us Delay time. The Max value is 2^24 / CPU Clock(MHz). Ex: + * 72MHz => 233016us, 50MHz => 335544us, + 48MHz => 349525us, 28MHz => 699050us ... + * @return None + * @details Use the SysTick to generate the delay time and the unit is in us. + * The SysTick clock source is from HCLK, i.e the same as system core clock. + */ +__STATIC_INLINE void CLK_SysTickDelay(uint32_t us) +{ + SysTick->LOAD = us * CyclesPerUs; + SysTick->VAL = (0x00); + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; + + /* Waiting for down-count to zero */ + while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0); + + /* Disable SysTick counter */ + SysTick->CTRL = 0; +} + +/** + * @brief This function execute long delay function. + * @param[in] us Delay time. + * @return None + * @details Use the SysTick to generate the long delay time and the UNIT is in us. + * The SysTick clock source is from HCLK, i.e the same as system core clock. + * User can use SystemCoreClockUpdate() to calculate CyclesPerUs automatically before using this function. + */ + +__STATIC_INLINE void CLK_SysTickLongDelay(uint32_t us) +{ + uint32_t delay; + + /* It should <= 233016us for each delay loop */ + delay = 233016UL; + + do + { + if(us > delay) + { + us -= delay; + } + else + { + delay = us; + us = 0UL; + } + + SysTick->LOAD = delay * CyclesPerUs; + SysTick->VAL = (0x0UL); + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; + + /* Waiting for down-count to zero */ + while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0UL); + + /* Disable SysTick counter */ + SysTick->CTRL = 0UL; + + }while(us > 0UL); + +} + + +void CLK_DisableCKO(void); +void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En); +void CLK_PowerDown(void); +void CLK_Idle(void); +uint32_t CLK_GetHXTFreq(void); +uint32_t CLK_GetLXTFreq(void); +uint32_t CLK_GetHCLKFreq(void); +uint32_t CLK_GetPCLK0Freq(void); +uint32_t CLK_GetPCLK1Freq(void); +uint32_t CLK_GetCPUFreq(void); +uint32_t CLK_SetCoreClock(uint32_t u32Hclk); +void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv); +void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv); +void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc); +void CLK_EnableXtalRC(uint32_t u32ClkMask); +void CLK_DisableXtalRC(uint32_t u32ClkMask); +void CLK_EnableModuleClock(uint32_t u32ModuleIdx); +void CLK_DisableModuleClock(uint32_t u32ModuleIdx); +uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq); +void CLK_DisablePLL(void); +uint32_t CLK_WaitClockReady(uint32_t u32ClkMask); +void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count); +void CLK_DisableSysTick(void); + + + +/*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group CLK_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__CLK_H__ diff --git a/StdDriver/inc/crc.h b/StdDriver/inc/crc.h new file mode 100644 index 0000000..4c8c333 --- /dev/null +++ b/StdDriver/inc/crc.h @@ -0,0 +1,112 @@ +/**************************************************************************//** + * @file crc.h + * @version V3.00 + * $Revision: 6 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series CRC driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __CRC_H__ +#define __CRC_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup CRC_Driver CRC Driver + @{ +*/ + +/** @addtogroup CRC_EXPORTED_CONSTANTS CRC Exported Constants + @{ +*/ +/*---------------------------------------------------------------------------------------------------------*/ +/* CRC Polynomial Mode Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define CRC_CCITT 0x00000000UL /*!SEED = (u32Seed); CRC->CTL |= CRC_CTL_CRCRST_Msk; } + +/** + * @brief Get CRC Seed Value + * + * @param None + * + * @return CRC seed value + * + * @details This macro gets the current CRC seed value. + */ +#define CRC_GET_SEED() (CRC->SEED) + +/** + * @brief CRC Write Data + * + * @param[in] u32Data Write data + * + * @return None + * + * @details User can write data directly to CRC Write Data Register(CRC_DAT) by this macro to perform CRC operation. + */ +#define CRC_WRITE_DATA(u32Data) (CRC->DAT = (u32Data)) + +void CRC_Open(uint32_t u32Mode, uint32_t u32Attribute, uint32_t u32Seed, uint32_t u32DataLen); +uint32_t CRC_GetChecksum(void); + +/*@}*/ /* end of group CRC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group CRC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__CRC_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/dac.h b/StdDriver/inc/dac.h new file mode 100644 index 0000000..c0914a3 --- /dev/null +++ b/StdDriver/inc/dac.h @@ -0,0 +1,245 @@ +/****************************************************************************** + * @file dac.h + * @version V0.10 + * $Revision: 12 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series DAC driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#ifndef __DAC_H__ +#define __DAC_H__ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Include related headers */ +/*---------------------------------------------------------------------------------------------------------*/ +#include "M451Series.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup DAC_Driver DAC Driver + @{ +*/ + + +/** @addtogroup DAC_EXPORTED_CONSTANTS DAC Exported Constants + @{ +*/ + +/*---------------------------------------------------------------------------------------------------------*/ +/* DAC_CTL Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define DAC_CTL_LALIGN_RIGHT_ALIGN (0UL<SWTRG = DAC_SWTRG_SWTRG_Msk) + +/** + * @brief Enable DAC data left-aligned. + * @param[in] dac Base address of DAC module. + * @return None + * @details User has to load data into DAC_DAT[15:4] bits. DAC_DAT[31:16] and DAC_DAT[3:0] are ignored in DAC conversion. + */ +#define DAC_ENABLE_LEFT_ALIGN(dac) ((dac)->CTL |= DAC_CTL_LALIGN_Msk) + +/** + * @brief Enable DAC data right-aligned. + * @param[in] dac Base address of DAC module. + * @return None + * @details User has to load data into DAC_DAT[11:0] bits, DAC_DAT[31:12] are ignored in DAC conversion. + */ +#define DAC_ENABLE_RIGHT_ALIGN(dac) ((dac)->CTL &= ~DAC_CTL_LALIGN_Msk) + +/** + * @brief Enable output voltage buffer. + * @param[in] dac Base address of DAC module. + * @return None + * @details The DAC integrates a voltage output buffer that can be used to reduce output impedance and + * drive external loads directly without having to add an external operational amplifier. + */ +#define DAC_ENABLE_BYPASS_BUFFER(dac) ((dac)->CTL |= DAC_CTL_BYPASS_Msk) + +/** + * @brief Disable output voltage buffer. + * @param[in] dac Base address of DAC module. + * @return None + * @details This macro is used to disable output voltage buffer. + */ +#define DAC_DISABLE_BYPASS_BUFFER(dac) ((dac)->CTL &= ~DAC_CTL_BYPASS_Msk) + +/** + * @brief Enable the interrupt. + * @param[in] dac Base address of DAC module. + * @param[in] u32Ch Not used in M451 Series DAC. + * @return None + * @details This macro is used to enable DAC interrupt. + */ +#define DAC_ENABLE_INT(dac, u32Ch) ((dac)->CTL |= DAC_CTL_DACIEN_Msk) + +/** + * @brief Disable the interrupt. + * @param[in] dac Base address of DAC module. + * @param[in] u32Ch Not used in M451 Series DAC. + * @return None + * @details This macro is used to disable DAC interrupt. + */ +#define DAC_DISABLE_INT(dac, u32Ch) ((dac)->CTL &= ~DAC_CTL_DACIEN_Msk) + +/** + * @brief Enable DMA under-run interrupt. + * @param[in] dac Base address of DAC module. + * @return None + * @details This macro is used to enable DMA under-run interrupt. + */ +#define DAC_ENABLE_DMAUDR_INT(dac) ((dac)->CTL |= DAC_CTL_DMAURIEN_Msk) + +/** + * @brief Disable DMA under-run interrupt. + * @param[in] dac Base address of DAC module. + * @return None + * @details This macro is used to disable DMA under-run interrupt. + */ +#define DAC_DISABLE_DMAUDR_INT(dac) ((dac)->CTL &= ~DAC_CTL_DMAURIEN_Msk) + +/** + * @brief Enable PDMA mode. + * @param[in] dac Base address of DAC module. + * @return None + * @details DAC DMA request is generated when a hardware trigger event occurs while DMAEN (DAC_CTL[2]) is set. + */ +#define DAC_ENABLE_PDMA(dac) ((dac)->CTL |= DAC_CTL_DMAEN_Msk) + +/** + * @brief Disable PDMA mode. + * @param[in] dac Base address of DAC module. + * @return None + * @details This macro is used to disable DMA mode. + */ +#define DAC_DISABLE_PDMA(dac) ((dac)->CTL &= ~DAC_CTL_DMAEN_Msk) + +/** + * @brief Write data for conversion. + * @param[in] dac Base address of DAC module. + * @param[in] u32Ch Not used in M451 Series DAC. + * @param[in] u32Data Decides the data for conversion, valid range are between 0~0xFFF. + * @return None + * @details 12 bit left alignment: user has to load data into DAC_DAT[15:4] bits. + * 12 bit right alignment: user has to load data into DAC_DAT[11:0] bits. + */ +#define DAC_WRITE_DATA(dac, u32Ch, u32Data) ((dac)->DAT = (u32Data)) + +/** + * @brief Read DAC 12-bit holding data. + * @param[in] dac Base address of DAC module. + * @param[in] u32Ch Not used in M451 Series DAC. + * @return Return DAC 12-bit holding data. + * @details This macro is used to read DAC_DAT register. + */ +#define DAC_READ_DATA(dac, u32Ch) ((dac)->DAT) + +/** + * @brief Get the busy state of DAC. + * @param[in] dac Base address of DAC module. + * @param[in] u32Ch Not used in M451 Series DAC. + * @retval 0 Idle state. + * @retval 1 Busy state. + * @details This macro is used to read BUSY bit (DAC_STATUS[8]) to get busy state. + */ +#define DAC_IS_BUSY(dac, u32Ch) (((dac)->STATUS & DAC_STATUS_BUSY_Msk) >> DAC_STATUS_BUSY_Pos) + +/** + * @brief Get the interrupt flag. + * @param[in] dac Base address of DAC module. + * @param[in] u32Ch Not used in M451 Series DAC. + * @retval 0 DAC is in conversion state. + * @retval 1 DAC conversion finish. + * @details This macro is used to read FINISH bit (DAC_STATUS[0]) to get DAC conversion complete finish flag. + */ +#define DAC_GET_INT_FLAG(dac, u32Ch) ((dac)->STATUS & DAC_STATUS_FINISH_Msk) + +/** + * @brief Get the DMA under-run flag. + * @param[in] dac Base address of DAC module. + * @retval 0 No DMA under-run error condition occurred. + * @retval 1 DMA under-run error condition occurred. + * @details This macro is used to read DMAUDR bit (DAC_STATUS[1]) to get DMA under-run state. + */ +#define DAC_GET_DMAUDR_FLAG(dac) (((dac)->STATUS & DAC_STATUS_DMAUDR_Msk) >> DAC_STATUS_DMAUDR_Pos) + +/** + * @brief This macro clear the interrupt status bit. + * @param[in] dac Base address of DAC module. + * @param[in] u32Ch Not used in M451 Series DAC. + * @return None + * @details User writes FINISH bit (DAC_STATUS[0]) to clear DAC conversion complete finish flag. + */ +#define DAC_CLR_INT_FLAG(dac, u32Ch) ((dac)->STATUS = DAC_STATUS_FINISH_Msk) + +/** + * @brief This macro clear the DMA under-run flag. + * @param[in] dac Base address of DAC module. + * @return None + * @details User writes DMAUDR bit (DAC_STATUS[1]) to clear DMA under-run flag. + */ +#define DAC_CLR_DMAUDR_FLAG(dac) ((dac)->STATUS = DAC_STATUS_DMAUDR_Msk) + +void DAC_Open(DAC_T *dac, uint32_t u32Ch, uint32_t u32TrgSrc); +void DAC_Close(DAC_T *dac, uint32_t u32Ch); +float DAC_SetDelayTime(DAC_T *dac, uint32_t u16Delay); + +/*@}*/ /* end of group DAC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group DAC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__DAC_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/eadc.h b/StdDriver/inc/eadc.h new file mode 100644 index 0000000..9751d57 --- /dev/null +++ b/StdDriver/inc/eadc.h @@ -0,0 +1,569 @@ +/****************************************************************************** + * @file eadc.h + * @version V0.10 + * $Revision: 18 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series EADC driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#ifndef __EADC_H__ +#define __EADC_H__ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Include related headers */ +/*---------------------------------------------------------------------------------------------------------*/ +#include "M451Series.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup EADC_Driver EADC Driver + @{ +*/ + +/** @addtogroup EADC_EXPORTED_CONSTANTS EADC Exported Constants + @{ +*/ + +/*---------------------------------------------------------------------------------------------------------*/ +/* EADC_CTL Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define EADC_CTL_DIFFEN_SINGLE_END (0UL<CTL |= EADC_CTL_ADRST_Msk) + +/** + * @brief Enable PDMA transfer. + * @param[in] eadc The pointer of the specified EADC module. + * @return None + * @details When A/D conversion is completed, the converted data is loaded into EADC_DATn (n: 0 ~ 18) register, + * user can enable this bit to generate a PDMA data transfer request. + * @note When set PDMAEN bit (EADC_CTL[11]), user must set ADINTENn (EADC_CTL[5:2], n=0~3) = 0 to disable interrupt. + */ +#define EADC_ENABLE_PDMA(eadc) ((eadc)->CTL |= EADC_CTL_PDMAEN_Msk) + +/** + * @brief Disable PDMA transfer. + * @param[in] eadc The pointer of the specified EADC module. + * @return None + * @details This macro is used to disable PDMA transfer. + */ +#define EADC_DISABLE_PDMA(eadc) ((eadc)->CTL &= (~EADC_CTL_PDMAEN_Msk)) + +/** + * @brief Enable double buffer mode. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 3. + * @return None + * @details The ADC controller supports a double buffer mode in sample module 0~3. + * If user enable DBMEN (EADC_SCTLn[23], n=0~3), the double buffer mode will enable. + */ +#define EADC_ENABLE_DOUBLE_BUFFER(eadc, u32ModuleNum) ((eadc)->SCTL[(u32ModuleNum)] |= EADC_SCTL_DBMEN_Msk) + +/** + * @brief Disable double buffer mode. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 3. + * @return None + * @details Sample has one sample result register. + */ +#define EADC_DISABLE_DOUBLE_BUFFER(eadc, u32ModuleNum) ((eadc)->SCTL[(u32ModuleNum)] &= ~EADC_SCTL_DBMEN_Msk) + +/** + * @brief Set ADIFn at A/D end of conversion. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15. + * @return None + * @details The A/D converter generates ADIFn (EADC_STATUS2[3:0], n=0~3) at the start of conversion. + */ +#define EADC_ENABLE_INT_POSITION(eadc, u32ModuleNum) ((eadc)->SCTL[(u32ModuleNum)] |= EADC_SCTL_INTPOS_Msk) + +/** + * @brief Set ADIFn at A/D start of conversion. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15. + * @return None + * @details The A/D converter generates ADIFn (EADC_STATUS2[3:0], n=0~3) at the end of conversion. + */ +#define EADC_DISABLE_INT_POSITION(eadc, u32ModuleNum) ((eadc)->SCTL[(u32ModuleNum)] &= ~EADC_SCTL_INTPOS_Msk) + +/** + * @brief Enable the interrupt. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32Mask Decides the combination of interrupt status bits. Each bit corresponds to a interrupt status. + * This parameter decides which interrupts will be enabled. Bit 0 is ADCIEN0, bit 1 is ADCIEN1..., bit 3 is ADCIEN3. + * @return None + * @details The A/D converter generates a conversion end ADIFn (EADC_STATUS2[n]) upon the end of specific sample module A/D conversion. + * If ADCIENn bit (EADC_CTL[n+2]) is set then conversion end interrupt request ADINTn is generated (n=0~3). + */ +#define EADC_ENABLE_INT(eadc, u32Mask) ((eadc)->CTL |= ((u32Mask) << EADC_CTL_ADCIEN0_Pos)) + +/** + * @brief Disable the interrupt. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32Mask Decides the combination of interrupt status bits. Each bit corresponds to a interrupt status. + * This parameter decides which interrupts will be disabled. Bit 0 is ADCIEN0, bit 1 is ADCIEN1..., bit 3 is ADCIEN3. + * @return None + * @details Specific sample module A/D ADINT0 interrupt function Disabled. + */ +#define EADC_DISABLE_INT(eadc, u32Mask) ((eadc)->CTL &= ~((u32Mask) << EADC_CTL_ADCIEN0_Pos)) + +/** + * @brief Enable the sample module interrupt. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32IntSel Decides which interrupt source will be used, valid value are from 0 to 3. + * @param[in] u32ModuleMask the combination of sample module interrupt status bits. Each bit corresponds to a sample module interrupt status. + * This parameter decides which sample module interrupts will be enabled, valid range are between 1~0x7FFFF. + * @return None + * @details There are 4 ADC interrupts ADINT0~3, and each of these interrupts has its own interrupt vector address. + */ +#define EADC_ENABLE_SAMPLE_MODULE_INT(eadc, u32IntSel, u32ModuleMask) ((eadc)->INTSRC[(u32IntSel)] |= (u32ModuleMask)) + +/** + * @brief Disable the sample module interrupt. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32IntSel Decides which interrupt source will be used, valid value are from 0 to 3. + * @param[in] u32ModuleMask the combination of sample module interrupt status bits. Each bit corresponds to a sample module interrupt status. + * This parameter decides which sample module interrupts will be disabled, valid range are between 1~0x7FFFF. + * @return None + * @details There are 4 ADC interrupts ADINT0~3, and each of these interrupts has its own interrupt vector address. + */ +#define EADC_DISABLE_SAMPLE_MODULE_INT(eadc, u32IntSel, u32ModuleMask) ((eadc)->INTSRC[(u32IntSel)] &= ~(u32ModuleMask)) + +/** + * @brief Set the input mode output format. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32Format Decides the output format. Valid values are: + * - \ref EADC_CTL_DMOF_STRAIGHT_BINARY :Select the straight binary format as the output format of the conversion result. + * - \ref EADC_CTL_DMOF_TWOS_COMPLEMENT :Select the 2's complement format as the output format of the conversion result. + * @return None + * @details The macro is used to set A/D input mode output format. + */ +#define EADC_SET_DMOF(eadc, u32Format) ((eadc)->CTL = ((eadc)->CTL & ~EADC_CTL_DMOF_Msk) | (u32Format)) + +/** + * @brief Start the A/D conversion. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleMask The combination of sample module. Each bit corresponds to a sample module. + * This parameter decides which sample module will be conversion, valid range are between 1~0x7FFFF. + * Bit 0 is sample module 0, bit 1 is sample module 1..., bit 18 is sample module 18. + * @return None + * @details After write EADC_SWTRG register to start ADC conversion, the EADC_PENDSTS register will show which SAMPLE will conversion. + */ +#define EADC_START_CONV(eadc, u32ModuleMask) ((eadc)->SWTRG = (u32ModuleMask)) + +/** + * @brief Cancel the conversion for sample module. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleMask The combination of sample module. Each bit corresponds to a sample module. + * This parameter decides which sample module will stop the conversion, valid range are between 1~0x7FFFF. + * Bit 0 is sample module 0, bit 1 is sample module 1..., bit 18 is sample module18. + * @return None + * @details If user want to disable the conversion of the sample module, user can write EADC_PENDSTS register to clear it. + */ +#define EADC_STOP_CONV(eadc, u32ModuleMask) ((eadc)->PENDSTS = (u32ModuleMask)) + +/** + * @brief Get the conversion pending flag. + * @param[in] eadc The pointer of the specified EADC module. + * @return Return the conversion pending sample module. + * @details This STPFn(EADC_PENDSTS[18:0]) bit remains 1 during pending state, when the respective ADC conversion is end, + * the STPFn (n=0~18) bit is automatically cleared to 0. + */ +#define EADC_GET_PENDING_CONV(eadc) ((eadc)->PENDSTS) + +/** + * @brief Get the conversion data of the user-specified sample module. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 18. + * @return Return the conversion data of the user-specified sample module. + * @details This macro is used to read RESULT bit (EADC_DATn[15:0], n=0~18) field to get conversion data. + */ +#define EADC_GET_CONV_DATA(eadc, u32ModuleNum) ((eadc)->DAT[(u32ModuleNum)] & EADC_DAT_RESULT_Msk) + +/** + * @brief Get the data overrun flag of the user-specified sample module. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleMask The combination of data overrun status bits. Each bit corresponds to a data overrun status, valid range are between 1~0x7FFFF. + * @return Return the data overrun flag of the user-specified sample module. + * @details This macro is used to read OV bit (EADC_STATUS0[31:16], EADC_STATUS1[18:16]) field to get data overrun status. + */ +#define EADC_GET_DATA_OVERRUN_FLAG(eadc, u32ModuleMask) ((((eadc)->STATUS0 >> EADC_STATUS0_OV_Pos) | ((eadc)->STATUS1 & EADC_STATUS1_OV_Msk)) & (u32ModuleMask)) + +/** + * @brief Get the data valid flag of the user-specified sample module. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleMask The combination of data valid status bits. Each bit corresponds to a data valid status, valid range are between 1~0x7FFFF. + * @return Return the data valid flag of the user-specified sample module. + * @details This macro is used to read VALID bit (EADC_STATUS0[15:0], EADC_STATUS1[1:0]) field to get data overrun status. + */ +#define EADC_GET_DATA_VALID_FLAG(eadc, u32ModuleMask) ((((eadc)->STATUS0 & EADC_STATUS0_VALID_Msk) | (((eadc)->STATUS1 & EADC_STATUS1_VALID_Msk) << 16)) & (u32ModuleMask)) + +/** + * @brief Get the double data of the user-specified sample module. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 18. + * @return Return the double data of the user-specified sample module. + * @details This macro is used to read RESULT bit (EADC_DDATn[15:0], n=0~3) field to get conversion data. + */ +#define EADC_GET_DOUBLE_DATA(eadc, u32ModuleNum) ((eadc)->DDAT[(u32ModuleNum)] & EADC_DDAT_RESULT_Msk) + +/** + * @brief Get the user-specified interrupt flags. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32Mask The combination of interrupt status bits. Each bit corresponds to a interrupt status. + * Bit 0 is ADIF0, bit 1 is ADIF1..., bit 3 is ADIF3. + * Bit 4 is ADCMPF0, bit 5 is ADCMPF1..., bit 7 is ADCMPF3. + * @return Return the user-specified interrupt flags. + * @details This macro is used to get the user-specified interrupt flags. + */ +#define EADC_GET_INT_FLAG(eadc, u32Mask) ((eadc)->STATUS2 & (u32Mask)) + +/** + * @brief Get the user-specified sample module overrun flags. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleMask The combination of sample module overrun status bits. Each bit corresponds to a sample module overrun status, valid range are between 1~0x7FFFF. + * @return Return the user-specified sample module overrun flags. + * @details This macro is used to get the user-specified sample module overrun flags. + */ +#define EADC_GET_SAMPLE_MODULE_OV_FLAG(eadc, u32ModuleMask) ((eadc)->OVSTS & (u32ModuleMask)) + +/** + * @brief Clear the selected interrupt status bits. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32Mask The combination of compare interrupt status bits. Each bit corresponds to a compare interrupt status. + * Bit 0 is ADIF0, bit 1 is ADIF1..., bit 3 is ADIF3. + * Bit 4 is ADCMPF0, bit 5 is ADCMPF1..., bit 7 is ADCMPF3. + * @return None + * @details This macro is used to clear clear the selected interrupt status bits. + */ +#define EADC_CLR_INT_FLAG(eadc, u32Mask) ((eadc)->STATUS2 = (u32Mask)) + +/** + * @brief Clear the selected sample module overrun status bits. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleMask The combination of sample module overrun status bits. Each bit corresponds to a sample module overrun status. + * Bit 0 is SPOVF0, bit 1 is SPOVF1..., bit 18 is SPOVF18. + * @return None + * @details This macro is used to clear the selected sample module overrun status bits. + */ +#define EADC_CLR_SAMPLE_MODULE_OV_FLAG(eadc, u32ModuleMask) ((eadc)->OVSTS = (u32ModuleMask)) + +/** + * @brief Check all sample module A/D result data register overrun flags. + * @param[in] eadc The pointer of the specified EADC module. + * @retval 0 None of sample module data register overrun flag is set to 1. + * @retval 1 Any one of sample module data register overrun flag is set to 1. + * @details The AOV bit (EADC_STATUS2[27]) will keep 1 when any one of sample module data register overrun flag OVn (EADC_DATn[16]) is set to 1. + */ +#define EADC_IS_DATA_OV(eadc) (((eadc)->STATUS2 & EADC_STATUS2_AOV_Msk) >> EADC_STATUS2_AOV_Pos) + +/** + * @brief Check all sample module A/D result data register valid flags. + * @param[in] eadc The pointer of the specified EADC module. + * @retval 0 None of sample module data register valid flag is set to 1. + * @retval 1 Any one of sample module data register valid flag is set to 1. + * @details The AVALID bit (EADC_STATUS2[26]) will keep 1 when any one of sample module data register valid flag VALIDn (EADC_DATn[17]) is set to 1. + */ +#define EADC_IS_DATA_VALID(eadc) (((eadc)->STATUS2 & EADC_STATUS2_AVALID_Msk) >> EADC_STATUS2_AVALID_Pos) + +/** + * @brief Check all A/D sample module start of conversion overrun flags. + * @param[in] eadc The pointer of the specified EADC module. + * @retval 0 None of sample module event overrun flag is set to 1. + * @retval 1 Any one of sample module event overrun flag is set to 1. + * @details The STOVF bit (EADC_STATUS2[25]) will keep 1 when any one of sample module event overrun flag SPOVFn (EADC_OVSTS[n]) is set to 1. + */ +#define EADC_IS_SAMPLE_MODULE_OV(eadc) (((eadc)->STATUS2 & EADC_STATUS2_STOVF_Msk) >> EADC_STATUS2_STOVF_Pos) + +/** + * @brief Check all A/D interrupt flag overrun bits. + * @param[in] eadc The pointer of the specified EADC module. + * @retval 0 None of ADINT interrupt flag is overwritten to 1. + * @retval 1 Any one of ADINT interrupt flag is overwritten to 1. + * @details The ADOVIF bit (EADC_STATUS2[24]) will keep 1 when any one of ADINT interrupt flag ADOVIFn (EADC_STATUS2[11:8]) is overwritten to 1. + */ +#define EADC_IS_INT_FLAG_OV(eadc) (((eadc)->STATUS2 & EADC_STATUS2_ADOVIF_Msk) >> EADC_STATUS2_ADOVIF_Pos) + +/** + * @brief Get the busy state of EADC. + * @param[in] eadc The pointer of the specified EADC module. + * @retval 0 Idle state. + * @retval 1 Busy state. + * @details This macro is used to read BUSY bit (EADC_STATUS2[23]) to get busy state. + */ +#define EADC_IS_BUSY(eadc) (((eadc)->STATUS2 & EADC_STATUS2_BUSY_Msk) >> EADC_STATUS2_BUSY_Pos) + +/** + * @brief Configure the comparator 0 and enable it. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum specifies the compare sample module, valid value are from 0 to 18. + * @param[in] u32Condition specifies the compare condition. Valid values are: + * - \ref EADC_CMP_CMPCOND_LESS_THAN :The compare condition is "less than the compare value" + * - \ref EADC_CMP_CMPCOND_GREATER_OR_EQUAL :The compare condition is "greater than or equal to the compare value + * @param[in] u16CMPData specifies the compare value, valid range are between 0~0xFFF. + * @param[in] u32MatchCount specifies the match count setting, valid range are between 0~0xF. + * @return None + * @details For example, ADC_ENABLE_CMP0(EADC, 5, ADC_ADCMPR_CMPCOND_GREATER_OR_EQUAL, 0x800, 10, EADC_CMP_CMPWEN_DISABLE, EADC_CMP_ADCMPIE_ENABLE); + * Means EADC will assert comparator 0 flag if sample module 5 conversion result is greater or + * equal to 0x800 for 10 times continuously, and a compare interrupt request is generated. + */ +#define EADC_ENABLE_CMP0(eadc,\ + u32ModuleNum,\ + u32Condition,\ + u16CMPData,\ + u32MatchCount) ((eadc)->CMP[0] |=(((u32ModuleNum) << EADC_CMP_CMPSPL_Pos)|\ + (u32Condition) |\ + ((u16CMPData) << EADC_CMP_CMPDAT_Pos)| \ + (((u32MatchCount) - 1) << EADC_CMP_CMPMCNT_Pos)|\ + EADC_CMP_ADCMPEN_Msk)) + +/** + * @brief Configure the comparator 1 and enable it. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum specifies the compare sample module, valid value are from 0 to 18. + * @param[in] u32Condition specifies the compare condition. Valid values are: + * - \ref EADC_CMP_CMPCOND_LESS_THAN :The compare condition is "less than the compare value" + * - \ref EADC_CMP_CMPCOND_GREATER_OR_EQUAL :The compare condition is "greater than or equal to the compare value + * @param[in] u16CMPData specifies the compare value, valid range are between 0~0xFFF. + * @param[in] u32MatchCount specifies the match count setting, valid range are between 0~0xF. + * @return None + * @details For example, ADC_ENABLE_CMP1(EADC, 5, ADC_ADCMPR_CMPCOND_GREATER_OR_EQUAL, 0x800, 10, EADC_CMP_ADCMPIE_ENABLE); + * Means EADC will assert comparator 1 flag if sample module 5 conversion result is greater or + * equal to 0x800 for 10 times continuously, and a compare interrupt request is generated. + */ +#define EADC_ENABLE_CMP1(eadc,\ + u32ModuleNum,\ + u32Condition,\ + u16CMPData,\ + u32MatchCount) ((eadc)->CMP[1] |=(((u32ModuleNum) << EADC_CMP_CMPSPL_Pos)|\ + (u32Condition) |\ + ((u16CMPData) << EADC_CMP_CMPDAT_Pos)| \ + (((u32MatchCount) - 1) << EADC_CMP_CMPMCNT_Pos)|\ + EADC_CMP_ADCMPEN_Msk)) + +/** + * @brief Configure the comparator 2 and enable it. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum specifies the compare sample module, valid value are from 0 to 18. + * @param[in] u32Condition specifies the compare condition. Valid values are: + * - \ref EADC_CMP_CMPCOND_LESS_THAN :The compare condition is "less than the compare value" + * - \ref EADC_CMP_CMPCOND_GREATER_OR_EQUAL :The compare condition is "greater than or equal to the compare value + * @param[in] u16CMPData specifies the compare value, valid range are between 0~0xFFF. + * @param[in] u32MatchCount specifies the match count setting, valid range are between 0~0xF. + * @return None + * @details For example, ADC_ENABLE_CMP2(EADC, 5, ADC_ADCMPR_CMPCOND_GREATER_OR_EQUAL, 0x800, 10, EADC_CMP_CMPWEN_DISABLE, EADC_CMP_ADCMPIE_ENABLE); + * Means EADC will assert comparator 2 flag if sample module 5 conversion result is greater or + * equal to 0x800 for 10 times continuously, and a compare interrupt request is generated. + */ +#define EADC_ENABLE_CMP2(eadc,\ + u32ModuleNum,\ + u32Condition,\ + u16CMPData,\ + u32MatchCount) ((eadc)->CMP[2] |=(((u32ModuleNum) << EADC_CMP_CMPSPL_Pos)|\ + (u32Condition) |\ + ((u16CMPData) << EADC_CMP_CMPDAT_Pos)| \ + (((u32MatchCount) - 1) << EADC_CMP_CMPMCNT_Pos)|\ + EADC_CMP_ADCMPEN_Msk)) + +/** + * @brief Configure the comparator 3 and enable it. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum specifies the compare sample module, valid value are from 0 to 18. + * @param[in] u32Condition specifies the compare condition. Valid values are: + * - \ref EADC_CMP_CMPCOND_LESS_THAN :The compare condition is "less than the compare value" + * - \ref EADC_CMP_CMPCOND_GREATER_OR_EQUAL :The compare condition is "greater than or equal to the compare value + * @param[in] u16CMPData specifies the compare value, valid range are between 0~0xFFF. + * @param[in] u32MatchCount specifies the match count setting, valid range are between 1~0xF. + * @return None + * @details For example, ADC_ENABLE_CMP3(EADC, 5, ADC_ADCMPR_CMPCOND_GREATER_OR_EQUAL, 0x800, 10, EADC_CMP_ADCMPIE_ENABLE); + * Means EADC will assert comparator 3 flag if sample module 5 conversion result is greater or + * equal to 0x800 for 10 times continuously, and a compare interrupt request is generated. + */ +#define EADC_ENABLE_CMP3(eadc,\ + u32ModuleNum,\ + u32Condition,\ + u16CMPData,\ + u32MatchCount) ((eadc)->CMP[3] |=(((u32ModuleNum) << EADC_CMP_CMPSPL_Pos)|\ + (u32Condition) |\ + ((u16CMPData) << EADC_CMP_CMPDAT_Pos)| \ + (((u32MatchCount) - 1) << EADC_CMP_CMPMCNT_Pos)|\ + EADC_CMP_ADCMPEN_Msk)) + +/** + * @brief Enable the compare window mode. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32CMP Specifies the compare register, valid value are 0 and 2. + * @return None + * @details ADCMPF0 (EADC_STATUS2[4]) will be set when both EADC_CMP0 and EADC_CMP1 compared condition matched. + */ +#define EADC_ENABLE_CMP_WINDOW_MODE(eadc, u32CMP) ((eadc)->CMP[(u32CMP)] |= EADC_CMP_CMPWEN_Msk) + +/** + * @brief Disable the compare window mode. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32CMP Specifies the compare register, valid value are 0 and 2. + * @return None + * @details ADCMPF2 (EADC_STATUS2[6]) will be set when both EADC_CMP2 and EADC_CMP3 compared condition matched. + */ +#define EADC_DISABLE_CMP_WINDOW_MODE(eadc, u32CMP) ((eadc)->CMP[(u32CMP)] &= ~EADC_CMP_CMPWEN_Msk) + +/** + * @brief Enable the compare interrupt. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32CMP Specifies the compare register, valid value are from 0 to 3. + * @return None + * @details If the compare function is enabled and the compare condition matches the setting of CMPCOND (EADC_CMPn[2], n=0~3) + * and CMPMCNT (EADC_CMPn[11:8], n=0~3), ADCMPFn (EADC_STATUS2[7:4], n=0~3) will be asserted, in the meanwhile, + * if ADCMPIE is set to 1, a compare interrupt request is generated. + */ +#define EADC_ENABLE_CMP_INT(eadc, u32CMP) ((eadc)->CMP[(u32CMP)] |= EADC_CMP_ADCMPIE_Msk) + +/** + * @brief Disable the compare interrupt. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32CMP Specifies the compare register, valid value are from 0 to 3. + * @return None + * @details This macro is used to disable the compare interrupt. + */ +#define EADC_DISABLE_CMP_INT(eadc, u32CMP) ((eadc)->CMP[(u32CMP)] &= ~EADC_CMP_ADCMPIE_Msk) + +/** + * @brief Disable comparator 0. + * @param[in] eadc The pointer of the specified EADC module. + * @return None + * @details This macro is used to disable comparator 0. + */ +#define EADC_DISABLE_CMP0(eadc) ((eadc)->CMP[0] = 0) + +/** + * @brief Disable comparator 1. + * @param[in] eadc The pointer of the specified EADC module. + * @return None + * @details This macro is used to disable comparator 1. + */ +#define EADC_DISABLE_CMP1(eadc) ((eadc)->CMP[1] = 0) + +/** + * @brief Disable comparator 2. + * @param[in] eadc The pointer of the specified EADC module. + * @return None + * @details This macro is used to disable comparator 2. + */ +#define EADC_DISABLE_CMP2(eadc) ((eadc)->CMP[2] = 0) + +/** + * @brief Disable comparator 3. + * @param[in] eadc The pointer of the specified EADC module. + * @return None + * @details This macro is used to disable comparator 3. + */ +#define EADC_DISABLE_CMP3(eadc) ((eadc)->CMP[3] = 0) + +/*---------------------------------------------------------------------------------------------------------*/ +/* Define EADC functions prototype */ +/*---------------------------------------------------------------------------------------------------------*/ +void EADC_Open(EADC_T *eadc, uint32_t u32InputMode); +void EADC_Close(EADC_T *eadc); +void EADC_ConfigSampleModule(EADC_T *eadc, uint32_t u32ModuleNum, uint32_t u32TriggerSource, uint32_t u32Channel); +void EADC_SetTriggerDelayTime(EADC_T *eadc, uint32_t u32ModuleNum, uint32_t u32TriggerDelayTime, uint32_t u32DelayClockDivider); +void EADC_SetInternalSampleTime(EADC_T *eadc, uint32_t u32SampleTime); +void EADC_SetExtendSampleTime(EADC_T *eadc, uint32_t u32ModuleNum, uint32_t u32ExtendSampleTime); + +/*@}*/ /* end of group EADC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group EADC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__EADC_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/ebi.h b/StdDriver/inc/ebi.h new file mode 100644 index 0000000..36af7ff --- /dev/null +++ b/StdDriver/inc/ebi.h @@ -0,0 +1,235 @@ +/**************************************************************************//** + * @file ebi.h + * @version V3.00 + * $Revision: 8 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series EBI driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __EBI_H__ +#define __EBI_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup EBI_Driver EBI Driver + @{ +*/ + +/** @addtogroup EBI_EXPORTED_CONSTANTS EBI Exported Constants + @{ +*/ +/*---------------------------------------------------------------------------------------------------------*/ +/* Miscellaneous Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define EBI_BANK0_BASE_ADDR 0x60000000UL /*!< EBI bank0 base address */ +#define EBI_BANK1_BASE_ADDR 0x60100000UL /*!< EBI bank1 base address */ +#define EBI_MAX_SIZE 0x00100000UL /*!< Maximum EBI size for each bank is 1 MB */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Constants for EBI bank number */ +/*---------------------------------------------------------------------------------------------------------*/ +#define EBI_BANK0 0 /*!< EBI bank 0 */ +#define EBI_BANK1 1 /*!< EBI bank 1 */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* 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 */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Constants for EBI CS Active Level */ +/*---------------------------------------------------------------------------------------------------------*/ +#define EBI_CS_ACTIVE_LOW 0 /*!< EBI CS active level is low */ +#define EBI_CS_ACTIVE_HIGH 1 /*!< EBI CS active level is high */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Constants for EBI MCLK divider and Timing */ +/*---------------------------------------------------------------------------------------------------------*/ +#define EBI_MCLKDIV_1 0x0UL /*!< EBI output clock(MCLK) is HCLK/1 */ +#define EBI_MCLKDIV_2 0x1UL /*!< EBI output clock(MCLK) is HCLK/2 */ +#define EBI_MCLKDIV_4 0x2UL /*!< EBI output clock(MCLK) is HCLK/4 */ +#define EBI_MCLKDIV_8 0x3UL /*!< EBI output clock(MCLK) is HCLK/8 */ +#define EBI_MCLKDIV_16 0x4UL /*!< EBI output clock(MCLK) is HCLK/16 */ +#define EBI_MCLKDIV_32 0x5UL /*!< EBI output clock(MCLK) is HCLK/32 */ + +#define EBI_TIMING_FASTEST 0x0UL /*!< EBI timing is the fastest */ +#define EBI_TIMING_VERYFAST 0x1UL /*!< EBI timing is very fast */ +#define EBI_TIMING_FAST 0x2UL /*!< EBI timing is fast */ +#define EBI_TIMING_NORMAL 0x3UL /*!< EBI timing is normal */ +#define EBI_TIMING_SLOW 0x4UL /*!< EBI timing is slow */ +#define EBI_TIMING_VERYSLOW 0x5UL /*!< EBI timing is very slow */ +#define EBI_TIMING_SLOWEST 0x6UL /*!< EBI timing is the slowest */ + +/*@}*/ /* end of group EBI_EXPORTED_CONSTANTS */ + + +/** @addtogroup EBI_EXPORTED_FUNCTIONS EBI Exported Functions + @{ +*/ + +/** + * @brief Read 8-bit data on EBI bank0 + * + * @param[in] u32Addr The data address on EBI bank0. + * + * @return 8-bit Data + * + * @details This macro is used to read 8-bit data from specify address on EBI bank0. + */ +#define EBI0_READ_DATA8(u32Addr) (*((volatile unsigned char *)(EBI_BANK0_BASE_ADDR+(u32Addr)))) + +/** + * @brief Write 8-bit data to EBI bank0 + * + * @param[in] u32Addr The data address on EBI bank0. + * @param[in] u32Data Specify data to be written. + * + * @return None + * + * @details This macro is used to write 8-bit data to specify address on EBI bank0. + */ +#define EBI0_WRITE_DATA8(u32Addr, u32Data) (*((volatile unsigned char *)(EBI_BANK0_BASE_ADDR+(u32Addr))) = (u32Data)) + +/** + * @brief Read 16-bit data on EBI bank0 + * + * @param[in] u32Addr The data address on EBI bank0. + * + * @return 16-bit Data + * + * @details This macro is used to read 16-bit data from specify address on EBI bank0. + */ +#define EBI0_READ_DATA16(u32Addr) (*((volatile unsigned short *)(EBI_BANK0_BASE_ADDR+(u32Addr)))) + +/** + * @brief Write 16-bit data to EBI bank0 + * + * @param[in] u32Addr The data address on EBI bank0. + * @param[in] u32Data Specify data to be written. + * + * @return None + * + * @details This macro is used to write 16-bit data to specify address on EBI bank0. + */ +#define EBI0_WRITE_DATA16(u32Addr, u32Data) (*((volatile unsigned short *)(EBI_BANK0_BASE_ADDR+(u32Addr))) = (u32Data)) + +/** + * @brief Read 32-bit data on EBI bank0 + * + * @param[in] u32Addr The data address on EBI bank0. + * + * @return 32-bit Data + * + * @details This macro is used to read 32-bit data from specify address on EBI bank0. + */ +#define EBI0_READ_DATA32(u32Addr) (*((volatile unsigned int *)(EBI_BANK0_BASE_ADDR+(u32Addr)))) + +/** + * @brief Write 32-bit data to EBI bank0 + * + * @param[in] u32Addr The data address on EBI bank0. + * @param[in] u32Data Specify data to be written. + * + * @return None + * + * @details This macro is used to write 32-bit data to specify address on EBI bank0. + */ +#define EBI0_WRITE_DATA32(u32Addr, u32Data) (*((volatile unsigned int *)(EBI_BANK0_BASE_ADDR+(u32Addr))) = (u32Data)) + +/** + * @brief Read 8-bit data on EBI bank1 + * + * @param[in] u32Addr The data address on EBI bank1. + * + * @return 8-bit Data + * + * @details This macro is used to read 8-bit data from specify address on EBI bank1. + */ +#define EBI1_READ_DATA8(u32Addr) (*((volatile unsigned char *)(EBI_BANK1_BASE_ADDR+(u32Addr)))) + +/** + * @brief Write 8-bit data to EBI bank1 + * + * @param[in] u32Addr The data address on EBI bank1. + * @param[in] u32Data Specify data to be written. + * + * @return None + * + * @details This macro is used to write 8-bit data to specify address on EBI bank1. + */ +#define EBI1_WRITE_DATA8(u32Addr, u32Data) (*((volatile unsigned char *)(EBI_BANK1_BASE_ADDR+(u32Addr))) = (u32Data)) + +/** + * @brief Read 16-bit data on EBI bank1 + * + * @param[in] u32Addr The data address on EBI bank1. + * + * @return 16-bit Data + * + * @details This macro is used to read 16-bit data from specify address on EBI bank1. + */ +#define EBI1_READ_DATA16(u32Addr) (*((volatile unsigned short *)(EBI_BANK1_BASE_ADDR+(u32Addr)))) + +/** + * @brief Write 16-bit data to EBI bank1 + * + * @param[in] u32Addr The data address on EBI bank1. + * @param[in] u32Data Specify data to be written. + * + * @return None + * + * @details This macro is used to write 16-bit data to specify address on EBI bank1. + */ +#define EBI1_WRITE_DATA16(u32Addr, u32Data) (*((volatile unsigned short *)(EBI_BANK1_BASE_ADDR+(u32Addr))) = (u32Data)) + +/** + * @brief Read 32-bit data on EBI bank1 + * + * @param[in] u32Addr The data address on EBI bank1. + * + * @return 32-bit Data + * + * @details This macro is used to read 32-bit data from specify address on EBI bank1. + */ +#define EBI1_READ_DATA32(u32Addr) (*((volatile unsigned int *)(EBI_BANK1_BASE_ADDR+(u32Addr)))) + +/** + * @brief Write 32-bit data to EBI bank1 + * + * @param[in] u32Addr The data address on EBI bank1. + * @param[in] u32Data Specify data to be written. + * + * @return None + * + * @details This macro is used to write 32-bit data to specify address on EBI bank1. + */ +#define EBI1_WRITE_DATA32(u32Addr, u32Data) (*((volatile unsigned int *)(EBI_BANK1_BASE_ADDR+(u32Addr))) = (u32Data)) + +void EBI_Open(uint32_t u32Bank, uint32_t u32DataWidth, uint32_t u32TimingClass, uint32_t u32BusMode, uint32_t u32CSActiveLevel); +void EBI_Close(uint32_t u32Bank); +void EBI_SetBusTiming(uint32_t u32Bank, uint32_t u32TimingConfig, uint32_t u32MclkDiv); + +/*@}*/ /* end of group EBI_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group EBI_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__EBI_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/fmc.h b/StdDriver/inc/fmc.h new file mode 100644 index 0000000..994c0b3 --- /dev/null +++ b/StdDriver/inc/fmc.h @@ -0,0 +1,605 @@ +/**************************************************************************//** + * @file FMC.h + * @version V2.1 + * $Revision: 19 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 Series Flash Memory Controller Driver Header File + * + * @note + * Copyright (C) 2011~2015 Nuvoton Technology Corp. All rights reserved. + * + ******************************************************************************/ +#ifndef __FMC_H__ +#define __FMC_H__ + +#include "M451Series.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup FMC_Driver FMC Driver + @{ +*/ + +/** @addtogroup FMC_EXPORTED_CONSTANTS FMC Exported Constants + @{ +*/ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Global constant definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define ISBEN 0 + +/*---------------------------------------------------------------------------------------------------------*/ +/* Define Base Address */ +/*---------------------------------------------------------------------------------------------------------*/ +#define FMC_APROM_BASE 0x00000000UL /*!< APROM Base Address */ +#define FMC_LDROM_BASE 0x00100000UL /*!< LDROM Base Address */ +#define FMC_SPROM_BASE 0x00200000UL /*!< SPROM Base Address */ +#define FMC_CONFIG_BASE 0x00300000UL /*!< CONFIG Base Address */ + +#define FMC_CONFIG0_ADDR (FMC_CONFIG_BASE) /*!< CONFIG 0 Address */ +#define FMC_CONFIG1_ADDR (FMC_CONFIG_BASE + 4) /*!< CONFIG 1 Address */ + + +#define FMC_FLASH_PAGE_SIZE 0x800 /*!< Flash Page Size (2048 Bytes) */ +#define FMC_LDROM_SIZE 0x1000 /*!< LDROM Size (4 kBytes) */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* ISPCTL constant definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define FMC_ISPCTL_BS_LDROM 0x2 /*!< ISPCTL setting to select to boot from LDROM */ +#define FMC_ISPCTL_BS_APROM 0x0 /*!< ISPCTL setting to select to boot from APROM */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* ISPCMD constant definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define FMC_ISPCMD_READ 0x00 /*!< ISP Command: Read Flash */ +#define FMC_ISPCMD_PROGRAM 0x21 /*!< ISP Command: 32-bit Program Flash */ +#define FMC_ISPCMD_WRITE_8 0x61 /*!< ISP Command: 64-bit program Flash */ +#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_UID 0x04 /*!< ISP Command: Read Unique ID */ +#define FMC_ISPCMD_READ_DID 0x0C /*!< ISP Command: Read Device ID */ +#define FMC_ISPCMD_VECMAP 0x2E /*!< ISP Command: Set vector mapping */ +#define FMC_ISPCMD_CHECKSUM 0x0D /*!< ISP Command: Read Checksum */ +#define FMC_ISPCMD_CAL_CHECKSUM 0x2D /*!< ISP Command: Run Check Calculation */ +#define FMC_ISPCMD_MULTI_PROG 0x27 /*!< ISP Command: Flash Multi-Word Program */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* FTCTL constant definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define FMC_FTCTL_OPTIMIZE_DISABLE 0x00 /*!< Frequency Optimize Mode disable */ +#define FMC_FTCTL_OPTIMIZE_12MHZ 0x01 /*!< Frequency Optimize Mode <= 12Mhz */ +#define FMC_FTCTL_OPTIMIZE_36MHZ 0x02 /*!< Frequency Optimize Mode <= 36Mhz */ +#define FMC_FTCTL_OPTIMIZE_60MHZ 0x04 /*!< Frequency Optimize Mode <= 60Mhz */ +#define FMC_FTCTL_OPTIMIZE_72MHZ 0x05 /*!< Frequency Optimize Mode <= 72Mhz */ + +/*@}*/ /* end of group FMC_EXPORTED_CONSTANTS */ + +/** @addtogroup FMC_EXPORTED_FUNCTIONS FMC Exported Functions + @{ +*/ + +/*---------------------------------------------------------------------------------------------------------*/ +/* FMC Macro Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +/** + * @brief Enable ISP Function + * + * @param None + * + * @return None + * + * @details This function will set ISPEN bit of ISPCTL control register to enable ISP function. + * + */ +#define FMC_ENABLE_ISP() (FMC->ISPCTL |= FMC_ISPCTL_ISPEN_Msk) /*!< Enable ISP Function */ + +/** + * @brief Disable ISP Function + * + * @param None + * + * @return None + * + * @details This function will clear ISPEN bit of ISPCTL control register to disable ISP function. + * + */ +#define FMC_DISABLE_ISP() (FMC->ISPCTL &= ~FMC_ISPCTL_ISPEN_Msk) /*!< Disable ISP Function */ + +/** + * @brief Enable LDROM Update Function + * + * @param None + * + * @return None + * + * @details This function will set LDUEN bit of ISPCTL control register to enable LDROM update function. + * User needs to set LDUEN bit before they can update LDROM. + * + */ +#define FMC_ENABLE_LD_UPDATE() (FMC->ISPCTL |= FMC_ISPCTL_LDUEN_Msk) /*!< Enable LDROM Update Function */ + +/** + * @brief Disable LDROM Update Function + * + * @param None + * + * @return None + * + * @details This function will set ISPEN bit of ISPCTL control register to disable LDROM update function. + * + */ +#define FMC_DISABLE_LD_UPDATE() (FMC->ISPCTL &= ~FMC_ISPCTL_LDUEN_Msk) /*!< Disable LDROM Update Function */ + +/** + * @brief Enable User Configuration Update Function + * + * @param None + * + * @return None + * + * @details This function will set CFGUEN bit of ISPCTL control register to enable User Configuration update function. + * User needs to set CFGUEN bit before they can update User Configuration area. + * + */ +#define FMC_ENABLE_CFG_UPDATE() (FMC->ISPCTL |= FMC_ISPCTL_CFGUEN_Msk) /*!< Enable CONFIG Update Function */ + +/** + * @brief Disable User Configuration Update Function + * + * @param None + * + * @return None + * + * @details This function will clear CFGUEN bit of ISPCTL control register to disable User Configuration update function. + * + */ +#define FMC_DISABLE_CFG_UPDATE() (FMC->ISPCTL &= ~FMC_ISPCTL_CFGUEN_Msk) /*!< Disable CONFIG Update Function */ + + +/** + * @brief Enable APROM Update Function + * + * @param None + * + * @return None + * + * @details This function will set APUEN bit of ISPCTL control register to enable APROM update function. + * User needs to set APUEN bit before they can update APROM in APROM boot mode. + * + */ +#define FMC_ENABLE_AP_UPDATE() (FMC->ISPCTL |= FMC_ISPCTL_APUEN_Msk) /*!< Enable APROM Update Function */ + +/** + * @brief Disable APROM Update Function + * + * @param None + * + * @return None + * + * @details This function will clear APUEN bit of ISPCTL control register to disable APROM update function. + * + */ +#define FMC_DISABLE_AP_UPDATE() (FMC->ISPCTL &= ~FMC_ISPCTL_APUEN_Msk) /*!< Disable APROM Update Function */ + +/** + * @brief Next Booting Selection function + * + * @param[in] x Booting from APROM(0)/LDROM(1) + * + * @return None + * + * @details This function will set MCU next booting from LDROM/APROM. + * + * @note When use this macro, the Boot Loader booting selection MBS(CONFIG0[5]) must be set. + * + */ +#define FMC_SELECT_NEXT_BOOT(x) (FMC->ISPCTL = (FMC->ISPCTL & ~FMC_ISPCTL_BS_Msk) | ((x) << FMC_ISPCTL_BS_Pos)) /*!< Select Next Booting, x = 0 or 1 */ + +/** + * @brief Get MCU Booting Status + * + * @param None + * + * @return None + * + * @details This function will get status of chip next booting from LDROM/APROM. + * + */ +#define FMC_GET_BOOT_STATUS() ((FMC->ISPCTL & FMC_ISPCTL_BS_Msk)?1:0) /*!< Get MCU Booting Status */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* inline functions */ +/*---------------------------------------------------------------------------------------------------------*/ +/** + * @brief Program 32-bit data into specified address of flash + * + * @param[in] u32Addr Flash address include APROM, LDROM, Data Flash, and CONFIG + * @param[in] u32Data 32-bit Data to program + * + * @return None + * + * @details To program word data into Flash include APROM, LDROM, Data Flash, and CONFIG. + * The corresponding functions in CONFIG are listed in FMC section of Technical Reference Manual. + * + */ +static __INLINE void FMC_Write(uint32_t u32Addr, uint32_t u32Data) +{ + FMC->ISPCMD = FMC_ISPCMD_PROGRAM; + FMC->ISPADDR = u32Addr; + FMC->ISPDAT = u32Data; + FMC->ISPTRG = 0x1; +#if ISBEN + __ISB(); +#endif + while(FMC->ISPTRG); +} + +/** + * @brief Program 64-bit data into specified address of flash + * + * @param[in] u32Addr Flash address include APROM, LDROM, Data Flash, and CONFIG + * @param[in] u32Data0 32-bit Data to program + * @param[in] u32Data1 32-bit Data to program + * + * @return None + * + * @details To program two words data into Flash include APROM, LDROM, Data Flash, and CONFIG. + * The corresponding functions in CONFIG are listed in FMC section of Technical Reference Manual. + * + */ +static __INLINE void FMC_Write8(uint32_t u32Addr, uint32_t u32Data0, uint32_t u32Data1) +{ + FMC->ISPCMD = FMC_ISPCMD_WRITE_8; + FMC->ISPADDR = u32Addr; + FMC->MPDAT0 = u32Data0; + FMC->MPDAT1 = u32Data1; + FMC->ISPTRG = 0x1; +#if ISBEN + __ISB(); +#endif + while(FMC->ISPTRG); +} + + +/** + * @brief Read 32-bit Data from specified address of flash + * + * @param[in] u32Addr Flash address include APROM, LDROM, Data Flash, and CONFIG + * + * @return The data of specified address + * + * @details To read word data from Flash include APROM, LDROM, Data Flash, and CONFIG. + * + */ +static __INLINE uint32_t FMC_Read(uint32_t u32Addr) +{ + FMC->ISPCMD = FMC_ISPCMD_READ; + FMC->ISPADDR = u32Addr; + FMC->ISPDAT = 0; + FMC->ISPTRG = 0x1; +#if ISBEN + __ISB(); +#endif + while(FMC->ISPTRG); + + return FMC->ISPDAT; +} + +/** + * @brief Flash page erase + * + * @param[in] u32Addr Flash address including APROM, LDROM, Data Flash, and CONFIG + * + * @details To do flash page erase. The target address could be APROM, LDROM, Data Flash, or CONFIG. + * The page size is 2048 bytes. + * + * @retval 0 Success + * @retval -1 Erase failed + * + */ +static __INLINE int32_t FMC_Erase(uint32_t u32Addr) +{ + FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE; + FMC->ISPADDR = u32Addr; + FMC->ISPTRG = 0x1; +#if ISBEN + __ISB(); +#endif + while(FMC->ISPTRG); + + /* Check ISPFF flag to know whether erase OK or fail. */ + if(FMC->ISPCTL & FMC_ISPCTL_ISPFF_Msk) + { + FMC->ISPCTL |= FMC_ISPCTL_ISPFF_Msk; + return -1; + } + return 0; +} + +/** + * @brief Read Unique ID + * + * @param[in] u8Index UID index. 0 = UID[31:0], 1 = UID[63:32], 2 = UID[95:64] + * + * @return The 32-bit unique ID data of specified UID index. + * + * @details To read out 96-bit Unique ID. + * + */ +static __INLINE uint32_t FMC_ReadUID(uint8_t u8Index) +{ + FMC->ISPCMD = FMC_ISPCMD_READ_UID; + FMC->ISPADDR = (u8Index << 2); + FMC->ISPDAT = 0; + FMC->ISPTRG = 0x1; +#if ISBEN + __ISB(); +#endif + while(FMC->ISPTRG); + + return FMC->ISPDAT; +} + +/** + * @brief Read company ID + * + * @param None + * + * @return The company ID (32-bit) + * + * @details The company ID of Nuvoton is fixed to be 0xDA + * + */ +static __INLINE uint32_t FMC_ReadCID(void) +{ + FMC->ISPCMD = FMC_ISPCMD_READ_CID; /* Set ISP Command Code */ + FMC->ISPADDR = 0x0; /* Must keep 0x0 when read CID */ + FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */ +#if ISBEN + __ISB(); +#endif /* To make sure ISP/CPU be Synchronized */ + while(FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk) ; /* Waiting for ISP Done */ + + return FMC->ISPDAT; +} + +/** + * @brief Read product ID + * + * @param None + * + * @return The product ID (32-bit) + * + * @details This function is used to read product ID. + * + */ +static __INLINE uint32_t FMC_ReadPID(void) +{ + FMC->ISPCMD = FMC_ISPCMD_READ_DID; /* Set ISP Command Code */ + FMC->ISPADDR = 0x04; /* Must keep 0x4 when read PID */ + FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */ +#if ISBEN + __ISB(); +#endif /* To make sure ISP/CPU be Synchronized */ + while(FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk); /* Waiting for ISP Done */ + + return FMC->ISPDAT; +} + +/** + * @brief To read UCID + * + * @param[in] u32Index Index of the UCID to read. u32Index must be 0, 1, 2, or 3. + * + * @return The UCID of specified index + * + * @details This function is used to read unique chip ID (UCID). + * + */ +static __INLINE uint32_t FMC_ReadUCID(uint32_t u32Index) +{ + FMC->ISPCMD = FMC_ISPCMD_READ_UID; /* Set ISP Command Code */ + FMC->ISPADDR = (0x04 * u32Index) + 0x10; /* The UCID is at offset 0x10 with word alignment. */ + FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk; /* Trigger to start ISP procedure */ +#if ISBEN + __ISB(); +#endif /* To make sure ISP/CPU be Synchronized */ + while(FMC->ISPTRG & FMC_ISPTRG_ISPGO_Msk); /* Waiting for ISP Done */ + + return FMC->ISPDAT; +} + +/** + * @brief Set vector mapping address + * + * @param[in] u32PageAddr The page address to remap to address 0x0. The address must be page alignment. + * + * @return To set VECMAP to remap specified page address to 0x0. + * + * @details This function is used to set VECMAP to map specified page to vector page (0x0). + * + * @note + * VECMAP only valid when new IAP function is enabled. (CBS = 10'b or 00'b) + * + */ +static __INLINE void FMC_SetVectorPageAddr(uint32_t u32PageAddr) +{ + FMC->ISPCMD = FMC_ISPCMD_VECMAP; /* Set ISP Command Code */ + FMC->ISPADDR = u32PageAddr; /* The address of specified page which will be map to address 0x0. It must be page alignment. */ + FMC->ISPTRG = 0x1; /* Trigger to start ISP procedure */ +#if ISBEN + __ISB(); +#endif /* To make sure ISP/CPU be Synchronized */ + while(FMC->ISPTRG); /* Waiting for ISP Done */ +} + +/** + * @brief Get current vector mapping address. + * + * @param None + * + * @return The current vector mapping address. + * + * @details To get VECMAP value which is the page address for remapping to vector page (0x0). + * + * @note + * VECMAP only valid when new IAP function is enabled. (CBS = 10'b or 00'b) + * + */ +static __INLINE uint32_t FMC_GetVECMAP(void) +{ + return (FMC->ISPSTS & FMC_ISPSTS_VECMAP_Msk); +} + +/** + * @brief Get Flash Checksum + * + * @param[in] u32Addr Specific flash start address + * @param[in] i32Size Specific a size of Flash area + * + * @return A checksum value of a flash block. + * + * @details To get VECMAP value which is the page address for remapping to vector page (0x0). + * + */ +static __INLINE uint32_t FMC_GetCheckSum(uint32_t u32Addr, int32_t i32Size) +{ + FMC->ISPCMD = FMC_ISPCMD_CAL_CHECKSUM; + FMC->ISPADDR = u32Addr; + FMC->ISPDAT = i32Size; + FMC->ISPTRG = 0x1; +#if ISBEN + __ISB(); +#endif + while(FMC->ISPTRG); + + FMC->ISPCMD = FMC_ISPCMD_CHECKSUM; + FMC->ISPTRG = 0x1; + while(FMC->ISPTRG); + + return FMC->ISPDAT; +} + +/** + * @brief Program Multi-Word data into specified address of flash + * + * @param[in] u32Addr Flash address include APROM, LDROM, Data Flash, and CONFIG + * @param[in] pu32Buf A data pointer is point to a data buffer start address; + * + * @return None + * + * @details To program multi-words data into Flash include APROM, LDROM, Data Flash, and CONFIG. + * The corresponding functions in CONFIG are listed in FMC section of Technical Reference Manual. + * + */ +static __INLINE void FMC_Write256(uint32_t u32Addr, uint32_t *pu32Buf) +{ + int32_t i, idx; + volatile uint32_t *pu32IspData; + //int32_t i32Err; + + //i32Err = 0; + idx = 0; + FMC->ISPCMD = FMC_ISPCMD_MULTI_PROG; + FMC->ISPADDR = u32Addr; + +retrigger: + + //if(i32Err) + // printf("idx=%d ISPADDR = 0x%08x\n",idx, FMC->ISPADDR); + + FMC->MPDAT0 = pu32Buf[idx + 0]; + FMC->MPDAT1 = pu32Buf[idx + 1]; + FMC->MPDAT2 = pu32Buf[idx + 2]; + FMC->MPDAT3 = pu32Buf[idx + 3]; + + + + FMC->ISPTRG = 0x1; + + pu32IspData = &FMC->MPDAT0; + idx += 4; + + for(i = idx; i < 256 / 4; i += 4) // Max data length is 256 bytes (256/4 words) + { + + __set_PRIMASK(1); // Mask interrupt to avoid status check coherence error + do + { + if((FMC->MPSTS & FMC_MPSTS_MPBUSY_Msk) == 0) + { + __set_PRIMASK(0); + //printf("%d %x\n", i, FMC->MPADDR); + FMC->ISPADDR = FMC->MPADDR & (~0xful); + idx = (FMC->ISPADDR - u32Addr) / 4; + //i32Err = -1; + goto retrigger; + } + } + while(FMC->MPSTS & (3 << FMC_MPSTS_D0_Pos)); + + // Update new data for D0 + pu32IspData[0] = pu32Buf[i ]; + pu32IspData[1] = pu32Buf[i + 1]; + + do + { + if((FMC->MPSTS & FMC_MPSTS_MPBUSY_Msk) == 0) + { + __set_PRIMASK(0); + //printf("%d %x\n", i, FMC->MPADDR); + FMC->ISPADDR = FMC->MPADDR & (~0xful); + idx = (FMC->ISPADDR - u32Addr) / 4; + //i32Err = -1; + goto retrigger; + } + } + while(FMC->MPSTS & (3 << FMC_MPSTS_D2_Pos)); + + // Update new data for D2 + pu32IspData[2] = pu32Buf[i + 2]; + pu32IspData[3] = pu32Buf[i + 3]; + __set_PRIMASK(0); + } + + while(FMC->ISPSTS & FMC_ISPSTS_ISPBUSY_Msk); +} + +void FMC_Open(void); +void FMC_Close(void); +void FMC_EnableAPUpdate(void); +void FMC_DisableAPUpdate(void); +void FMC_EnableConfigUpdate(void); +void FMC_DisableConfigUpdate(void); +void FMC_EnableLDUpdate(void); +void FMC_DisableLDUpdate(void); +int32_t FMC_ReadConfig(uint32_t *u32Config, uint32_t u32Count); +int32_t FMC_WriteConfig(uint32_t *u32Config, uint32_t u32Count); +void FMC_SetBootSource(int32_t i32BootSrc); +int32_t FMC_GetBootSource(void); +uint32_t FMC_ReadDataFlashBaseAddr(void); +void FMC_EnableFreqOptimizeMode(uint32_t u32Mode); +void FMC_DisableFreqOptimizeMode(void); +/*@}*/ /* end of group FMC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group FMC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/StdDriver/inc/gpio.h b/StdDriver/inc/gpio.h new file mode 100644 index 0000000..37ca98f --- /dev/null +++ b/StdDriver/inc/gpio.h @@ -0,0 +1,439 @@ +/**************************************************************************//** + * @file GPIO.h + * @version V3.00 + * $Revision: 21 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series GPIO driver header file + * + * @note + * Copyright (C) 2011~2015 Nuvoton Technology Corp. All rights reserved. + * + ******************************************************************************/ +#ifndef __GPIO_H__ +#define __GPIO_H__ + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup GPIO_Driver GPIO Driver + @{ +*/ + +/** @addtogroup GPIO_EXPORTED_CONSTANTS GPIO Exported Constants + @{ +*/ + + +#define GPIO_PIN_MAX 16 /*!< Specify Maximum Pins of Each GPIO Port */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* GPIO_MODE Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define GPIO_MODE_INPUT 0x0UL /*!< Input Mode */ +#define GPIO_MODE_OUTPUT 0x1UL /*!< Output Mode */ +#define GPIO_MODE_OPEN_DRAIN 0x2UL /*!< Open-Drain Mode */ +#define GPIO_MODE_QUASI 0x3UL /*!< Quasi-bidirectional Mode */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* GPIO Interrupt Type Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define GPIO_INT_RISING 0x00010000UL /*!< Interrupt enable by Input Rising Edge */ +#define GPIO_INT_FALLING 0x00000001UL /*!< Interrupt enable by Input Falling Edge */ +#define GPIO_INT_BOTH_EDGE 0x00010001UL /*!< Interrupt enable by both Rising Edge and Falling Edge */ +#define GPIO_INT_HIGH 0x01010000UL /*!< Interrupt enable by Level-High */ +#define GPIO_INT_LOW 0x01000001UL /*!< Interrupt enable by Level-Level */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* GPIO_INTTYPE Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define GPIO_INTTYPE_EDGE 0UL /*!< GPIO_INTTYPE Setting for Edge Trigger Mode */ +#define GPIO_INTTYPE_LEVEL 1UL /*!< GPIO_INTTYPE Setting for Edge Level Mode */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* GPIO_DBCTL Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define GPIO_DBCTL_ICLK_ON 0x00000020UL /*!< GPIO_DBCTL setting for all IO pins edge detection circuit is always active after reset */ +#define GPIO_DBCTL_ICLK_OFF 0x00000000UL /*!< GPIO_DBCTL setting for edge detection circuit is active only if IO pin corresponding GPIOx_IEN bit is set to 1 */ + +#define GPIO_DBCTL_DBCLKSRC_LIRC 0x00000010UL /*!< GPIO_DBCTL setting for de-bounce counter clock source is the internal 10 kHz */ +#define GPIO_DBCTL_DBCLKSRC_HCLK 0x00000000UL /*!< GPIO_DBCTL setting for de-bounce counter clock source is the HCLK */ + +#define GPIO_DBCTL_DBCLKSEL_1 0x00000000UL /*!< GPIO_DBCTL setting for sampling cycle = 1 clocks */ +#define GPIO_DBCTL_DBCLKSEL_2 0x00000001UL /*!< GPIO_DBCTL setting for sampling cycle = 2 clocks */ +#define GPIO_DBCTL_DBCLKSEL_4 0x00000002UL /*!< GPIO_DBCTL setting for sampling cycle = 4 clocks */ +#define GPIO_DBCTL_DBCLKSEL_8 0x00000003UL /*!< GPIO_DBCTL setting for sampling cycle = 8 clocks */ +#define GPIO_DBCTL_DBCLKSEL_16 0x00000004UL /*!< GPIO_DBCTL setting for sampling cycle = 16 clocks */ +#define GPIO_DBCTL_DBCLKSEL_32 0x00000005UL /*!< GPIO_DBCTL setting for sampling cycle = 32 clocks */ +#define GPIO_DBCTL_DBCLKSEL_64 0x00000006UL /*!< GPIO_DBCTL setting for sampling cycle = 64 clocks */ +#define GPIO_DBCTL_DBCLKSEL_128 0x00000007UL /*!< GPIO_DBCTL setting for sampling cycle = 128 clocks */ +#define GPIO_DBCTL_DBCLKSEL_256 0x00000008UL /*!< GPIO_DBCTL setting for sampling cycle = 256 clocks */ +#define GPIO_DBCTL_DBCLKSEL_512 0x00000009UL /*!< GPIO_DBCTL setting for sampling cycle = 512 clocks */ +#define GPIO_DBCTL_DBCLKSEL_1024 0x0000000AUL /*!< GPIO_DBCTL setting for sampling cycle = 1024 clocks */ +#define GPIO_DBCTL_DBCLKSEL_2048 0x0000000BUL /*!< GPIO_DBCTL setting for sampling cycle = 2048 clocks */ +#define GPIO_DBCTL_DBCLKSEL_4096 0x0000000CUL /*!< GPIO_DBCTL setting for sampling cycle = 4096 clocks */ +#define GPIO_DBCTL_DBCLKSEL_8192 0x0000000DUL /*!< GPIO_DBCTL setting for sampling cycle = 8192 clocks */ +#define GPIO_DBCTL_DBCLKSEL_16384 0x0000000EUL /*!< GPIO_DBCTL setting for sampling cycle = 16384 clocks */ +#define GPIO_DBCTL_DBCLKSEL_32768 0x0000000FUL /*!< GPIO_DBCTL setting for sampling cycle = 32768 clocks */ + + +/* Define GPIO Pin Data Input/Output. It could be used to control each I/O pin by pin address mapping. + Example 1: + + PA0 = 1; + + It is used to set GPIO PA.0 to high; + + Example 2: + + if (PA0) + PA0 = 0; + + If GPIO PA.0 pin status is high, then set GPIO PA.0 data output to low. + */ +#define GPIO_PIN_DATA(port, pin) (*((volatile uint32_t *)((GPIO_PIN_DATA_BASE+(0x40*(port))) + ((pin)<<2)))) +#define PA0 GPIO_PIN_DATA(0, 0 ) /*!< Specify PA.0 Pin Data Input/Output */ +#define PA1 GPIO_PIN_DATA(0, 1 ) /*!< Specify PA.1 Pin Data Input/Output */ +#define PA2 GPIO_PIN_DATA(0, 2 ) /*!< Specify PA.2 Pin Data Input/Output */ +#define PA3 GPIO_PIN_DATA(0, 3 ) /*!< Specify PA.3 Pin Data Input/Output */ +#define PA4 GPIO_PIN_DATA(0, 4 ) /*!< Specify PA.4 Pin Data Input/Output */ +#define PA5 GPIO_PIN_DATA(0, 5 ) /*!< Specify PA.5 Pin Data Input/Output */ +#define PA6 GPIO_PIN_DATA(0, 6 ) /*!< Specify PA.6 Pin Data Input/Output */ +#define PA7 GPIO_PIN_DATA(0, 7 ) /*!< Specify PA.7 Pin Data Input/Output */ +#define PA8 GPIO_PIN_DATA(0, 8 ) /*!< Specify PA.8 Pin Data Input/Output */ +#define PA9 GPIO_PIN_DATA(0, 9 ) /*!< Specify PA.9 Pin Data Input/Output */ +#define PA10 GPIO_PIN_DATA(0, 10) /*!< Specify PA.10 Pin Data Input/Output */ +#define PA11 GPIO_PIN_DATA(0, 11) /*!< Specify PA.11 Pin Data Input/Output */ +#define PA12 GPIO_PIN_DATA(0, 12) /*!< Specify PA.12 Pin Data Input/Output */ +#define PA13 GPIO_PIN_DATA(0, 13) /*!< Specify PA.13 Pin Data Input/Output */ +#define PA14 GPIO_PIN_DATA(0, 14) /*!< Specify PA.14 Pin Data Input/Output */ +#define PA15 GPIO_PIN_DATA(0, 15) /*!< Specify PA.15 Pin Data Input/Output */ +#define PB0 GPIO_PIN_DATA(1, 0 ) /*!< Specify PB.0 Pin Data Input/Output */ +#define PB1 GPIO_PIN_DATA(1, 1 ) /*!< Specify PB.1 Pin Data Input/Output */ +#define PB2 GPIO_PIN_DATA(1, 2 ) /*!< Specify PB.2 Pin Data Input/Output */ +#define PB3 GPIO_PIN_DATA(1, 3 ) /*!< Specify PB.3 Pin Data Input/Output */ +#define PB4 GPIO_PIN_DATA(1, 4 ) /*!< Specify PB.4 Pin Data Input/Output */ +#define PB5 GPIO_PIN_DATA(1, 5 ) /*!< Specify PB.5 Pin Data Input/Output */ +#define PB6 GPIO_PIN_DATA(1, 6 ) /*!< Specify PB.6 Pin Data Input/Output */ +#define PB7 GPIO_PIN_DATA(1, 7 ) /*!< Specify PB.7 Pin Data Input/Output */ +#define PB8 GPIO_PIN_DATA(1, 8 ) /*!< Specify PB.8 Pin Data Input/Output */ +#define PB9 GPIO_PIN_DATA(1, 9 ) /*!< Specify PB.9 Pin Data Input/Output */ +#define PB10 GPIO_PIN_DATA(1, 10) /*!< Specify PB.10 Pin Data Input/Output */ +#define PB11 GPIO_PIN_DATA(1, 11) /*!< Specify PB.11 Pin Data Input/Output */ +#define PB12 GPIO_PIN_DATA(1, 12) /*!< Specify PB.12 Pin Data Input/Output */ +#define PB13 GPIO_PIN_DATA(1, 13) /*!< Specify PB.13 Pin Data Input/Output */ +#define PB14 GPIO_PIN_DATA(1, 14) /*!< Specify PB.14 Pin Data Input/Output */ +#define PB15 GPIO_PIN_DATA(1, 15) /*!< Specify PB.15 Pin Data Input/Output */ +#define PC0 GPIO_PIN_DATA(2, 0 ) /*!< Specify PC.0 Pin Data Input/Output */ +#define PC1 GPIO_PIN_DATA(2, 1 ) /*!< Specify PC.1 Pin Data Input/Output */ +#define PC2 GPIO_PIN_DATA(2, 2 ) /*!< Specify PC.2 Pin Data Input/Output */ +#define PC3 GPIO_PIN_DATA(2, 3 ) /*!< Specify PC.3 Pin Data Input/Output */ +#define PC4 GPIO_PIN_DATA(2, 4 ) /*!< Specify PC.4 Pin Data Input/Output */ +#define PC5 GPIO_PIN_DATA(2, 5 ) /*!< Specify PC.5 Pin Data Input/Output */ +#define PC6 GPIO_PIN_DATA(2, 6 ) /*!< Specify PC.6 Pin Data Input/Output */ +#define PC7 GPIO_PIN_DATA(2, 7 ) /*!< Specify PC.7 Pin Data Input/Output */ +#define PC8 GPIO_PIN_DATA(2, 8 ) /*!< Specify PC.8 Pin Data Input/Output */ +#define PC9 GPIO_PIN_DATA(2, 9 ) /*!< Specify PC.9 Pin Data Input/Output */ +#define PC10 GPIO_PIN_DATA(2, 10) /*!< Specify PC.10 Pin Data Input/Output */ +#define PC11 GPIO_PIN_DATA(2, 11) /*!< Specify PC.11 Pin Data Input/Output */ +#define PC12 GPIO_PIN_DATA(2, 12) /*!< Specify PC.12 Pin Data Input/Output */ +#define PC13 GPIO_PIN_DATA(2, 13) /*!< Specify PC.13 Pin Data Input/Output */ +#define PC14 GPIO_PIN_DATA(2, 14) /*!< Specify PC.14 Pin Data Input/Output */ +#define PC15 GPIO_PIN_DATA(2, 15) /*!< Specify PC.15 Pin Data Input/Output */ +#define PD0 GPIO_PIN_DATA(3, 0 ) /*!< Specify PD.0 Pin Data Input/Output */ +#define PD1 GPIO_PIN_DATA(3, 1 ) /*!< Specify PD.1 Pin Data Input/Output */ +#define PD2 GPIO_PIN_DATA(3, 2 ) /*!< Specify PD.2 Pin Data Input/Output */ +#define PD3 GPIO_PIN_DATA(3, 3 ) /*!< Specify PD.3 Pin Data Input/Output */ +#define PD4 GPIO_PIN_DATA(3, 4 ) /*!< Specify PD.4 Pin Data Input/Output */ +#define PD5 GPIO_PIN_DATA(3, 5 ) /*!< Specify PD.5 Pin Data Input/Output */ +#define PD6 GPIO_PIN_DATA(3, 6 ) /*!< Specify PD.6 Pin Data Input/Output */ +#define PD7 GPIO_PIN_DATA(3, 7 ) /*!< Specify PD.7 Pin Data Input/Output */ +#define PD8 GPIO_PIN_DATA(3, 8 ) /*!< Specify PD.8 Pin Data Input/Output */ +#define PD9 GPIO_PIN_DATA(3, 9 ) /*!< Specify PD.9 Pin Data Input/Output */ +#define PD10 GPIO_PIN_DATA(3, 10) /*!< Specify PD.10 Pin Data Input/Output */ +#define PD11 GPIO_PIN_DATA(3, 11) /*!< Specify PD.11 Pin Data Input/Output */ +#define PD12 GPIO_PIN_DATA(3, 12) /*!< Specify PD.12 Pin Data Input/Output */ +#define PD13 GPIO_PIN_DATA(3, 13) /*!< Specify PD.13 Pin Data Input/Output */ +#define PD14 GPIO_PIN_DATA(3, 14) /*!< Specify PD.14 Pin Data Input/Output */ +#define PD15 GPIO_PIN_DATA(3, 15) /*!< Specify PD.15 Pin Data Input/Output */ +#define PE0 GPIO_PIN_DATA(4, 0 ) /*!< Specify PE.0 Pin Data Input/Output */ +#define PE1 GPIO_PIN_DATA(4, 1 ) /*!< Specify PE.1 Pin Data Input/Output */ +#define PE2 GPIO_PIN_DATA(4, 2 ) /*!< Specify PE.2 Pin Data Input/Output */ +#define PE3 GPIO_PIN_DATA(4, 3 ) /*!< Specify PE.3 Pin Data Input/Output */ +#define PE4 GPIO_PIN_DATA(4, 4 ) /*!< Specify PE.4 Pin Data Input/Output */ +#define PE5 GPIO_PIN_DATA(4, 5 ) /*!< Specify PE.5 Pin Data Input/Output */ +#define PE6 GPIO_PIN_DATA(4, 6 ) /*!< Specify PE.6 Pin Data Input/Output */ +#define PE7 GPIO_PIN_DATA(4, 7 ) /*!< Specify PE.7 Pin Data Input/Output */ +#define PE8 GPIO_PIN_DATA(4, 8 ) /*!< Specify PE.8 Pin Data Input/Output */ +#define PE9 GPIO_PIN_DATA(4, 9 ) /*!< Specify PE.9 Pin Data Input/Output */ +#define PE10 GPIO_PIN_DATA(4, 10) /*!< Specify PE.10 Pin Data Input/Output */ +#define PE11 GPIO_PIN_DATA(4, 11) /*!< Specify PE.11 Pin Data Input/Output */ +#define PE12 GPIO_PIN_DATA(4, 12) /*!< Specify PE.12 Pin Data Input/Output */ +#define PE13 GPIO_PIN_DATA(4, 13) /*!< Specify PE.13 Pin Data Input/Output */ +#define PE14 GPIO_PIN_DATA(4, 14) /*!< Specify PE.14 Pin Data Input/Output */ +#define PF0 GPIO_PIN_DATA(5, 0 ) /*!< Specify PF.0 Pin Data Input/Output */ +#define PF1 GPIO_PIN_DATA(5, 1 ) /*!< Specify PF.1 Pin Data Input/Output */ +#define PF2 GPIO_PIN_DATA(5, 2 ) /*!< Specify PF.2 Pin Data Input/Output */ +#define PF3 GPIO_PIN_DATA(5, 3 ) /*!< Specify PF.3 Pin Data Input/Output */ +#define PF4 GPIO_PIN_DATA(5, 4 ) /*!< Specify PF.4 Pin Data Input/Output */ +#define PF5 GPIO_PIN_DATA(5, 5 ) /*!< Specify PF.5 Pin Data Input/Output */ +#define PF6 GPIO_PIN_DATA(5, 6 ) /*!< Specify PF.6 Pin Data Input/Output */ +#define PF7 GPIO_PIN_DATA(5, 7 ) /*!< Specify PF.7 Pin Data Input/Output */ + + +/*@}*/ /* end of group GPIO_EXPORTED_CONSTANTS */ + + +/** @addtogroup GPIO_EXPORTED_FUNCTIONS GPIO Exported Functions + @{ +*/ + +/** + * @brief Clear GPIO Pin Interrupt Flag + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32PinMask The single or multiple pins of specified GPIO port. + * It could be BIT0 ~ BIT15 for PA, PB, PC and PD. + * It could be BIT0 ~ BIT14 for PE. + * It could be BIT0 ~ BIT7 for PF. + * + * @return None + * + * @details Clear the interrupt status of specified GPIO pin. + */ +#define GPIO_CLR_INT_FLAG(port, u32PinMask) ((port)->INTSRC = (u32PinMask)) + +/** + * @brief Disable Pin De-bounce Function + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32PinMask The single or multiple pins of specified GPIO port. + * It could be BIT0 ~ BIT15 for PA, PB, PC and PD. + * It could be BIT0 ~ BIT14 for PE. + * It could be BIT0 ~ BIT7 for PF. + * + * @return None + * + * @details Disable the interrupt de-bounce function of specified GPIO pin. + */ +#define GPIO_DISABLE_DEBOUNCE(port, u32PinMask) ((port)->DBEN &= ~(u32PinMask)) + +/** + * @brief Enable Pin De-bounce Function + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32PinMask The single or multiple pins of specified GPIO port. + * It could be BIT0 ~ BIT15 for PA, PB, PC and PD. + * It could be BIT0 ~ BIT14 for PE. + * It could be BIT0 ~ BIT7 for PF. + * @return None + * + * @details Enable the interrupt de-bounce function of specified GPIO pin. + */ +#define GPIO_ENABLE_DEBOUNCE(port, u32PinMask) ((port)->DBEN |= (u32PinMask)) + +/** + * @brief Disable I/O Digital Input Path + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32PinMask The single or multiple pins of specified GPIO port. + * It could be BIT0 ~ BIT15 for PA, PB, PC and PD. + * It could be BIT0 ~ BIT14 for PE. + * It could be BIT0 ~ BIT7 for PF. + * + * @return None + * + * @details Disable I/O digital input path of specified GPIO pin. + */ +#define GPIO_DISABLE_DIGITAL_PATH(port, u32PinMask) ((port)->DINOFF |= ((u32PinMask)<<16)) + +/** + * @brief Enable I/O Digital Input Path + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32PinMask The single or multiple pins of specified GPIO port. + * It could be BIT0 ~ BIT15 for PA, PB, PC and PD. + * It could be BIT0 ~ BIT14 for PE. + * It could be BIT0 ~ BIT7 for PF. + * + * @return None + * + * @details Enable I/O digital input path of specified GPIO pin. + */ +#define GPIO_ENABLE_DIGITAL_PATH(port, u32PinMask) ((port)->DINOFF &= ~((u32PinMask)<<16)) + +/** + * @brief Disable I/O DOUT mask + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32PinMask The single or multiple pins of specified GPIO port. + * It could be BIT0 ~ BIT15 for PA, PB, PC and PD. + * It could be BIT0 ~ BIT14 for PE. + * It could be BIT0 ~ BIT7 for PF. + * + * @return None + * + * @details Disable I/O DOUT mask of specified GPIO pin. + */ +#define GPIO_DISABLE_DOUT_MASK(port, u32PinMask) ((port)->DATMSK &= ~(u32PinMask)) + +/** + * @brief Enable I/O DOUT mask + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32PinMask The single or multiple pins of specified GPIO port. + * It could be BIT0 ~ BIT15 for PA, PB, PC and PD. + * It could be BIT0 ~ BIT14 for PE. + * It could be BIT0 ~ BIT7 for PF. + * + * @return None + * + * @details Enable I/O DOUT mask of specified GPIO pin. + */ +#define GPIO_ENABLE_DOUT_MASK(port, u32PinMask) ((port)->DATMSK |= (u32PinMask)) + +/** + * @brief Get GPIO Pin Interrupt Flag + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32PinMask The single or multiple pins of specified GPIO port. + * It could be BIT0 ~ BIT15 for PA, PB, PC and PD. + * It could be BIT0 ~ BIT14 for PE. + * It could be BIT0 ~ BIT7 for PF. + * + * @retval 0 No interrupt at specified GPIO pin + * @retval 1 The specified GPIO pin generate an interrupt + * + * @details Get the interrupt status of specified GPIO pin. + */ +#define GPIO_GET_INT_FLAG(port, u32PinMask) ((port)->INTSRC & (u32PinMask)) + +/** + * @brief Set De-bounce Sampling Cycle Time + * + * @param[in] u32ClkSrc The de-bounce counter clock source. It could be GPIO_DBCTL_DBCLKSRC_HCLK or GPIO_DBCTL_DBCLKSRC_LIRC. + * @param[in] u32ClkSel The de-bounce sampling cycle selection. It could be + * - \ref GPIO_DBCTL_DBCLKSEL_1 + * - \ref GPIO_DBCTL_DBCLKSEL_2 + * - \ref GPIO_DBCTL_DBCLKSEL_4 + * - \ref GPIO_DBCTL_DBCLKSEL_8 + * - \ref GPIO_DBCTL_DBCLKSEL_16 + * - \ref GPIO_DBCTL_DBCLKSEL_32 + * - \ref GPIO_DBCTL_DBCLKSEL_64 + * - \ref GPIO_DBCTL_DBCLKSEL_128 + * - \ref GPIO_DBCTL_DBCLKSEL_256 + * - \ref GPIO_DBCTL_DBCLKSEL_512 + * - \ref GPIO_DBCTL_DBCLKSEL_1024 + * - \ref GPIO_DBCTL_DBCLKSEL_2048 + * - \ref GPIO_DBCTL_DBCLKSEL_4096 + * - \ref GPIO_DBCTL_DBCLKSEL_8192 + * - \ref GPIO_DBCTL_DBCLKSEL_16384 + * - \ref GPIO_DBCTL_DBCLKSEL_32768 + * + * @return None + * + * @details Set the interrupt de-bounce sampling cycle time based on the debounce counter clock source. \n + * Example: _GPIO_SET_DEBOUNCE_TIME(GPIO_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_4). \n + * It's meaning the De-debounce counter clock source is internal 10 KHz and sampling cycle selection is 4. \n + * Then the target de-bounce sampling cycle time is (4)*(1/(10*1000)) s = 4*0.0001 s = 400 us, + * and system will sampling interrupt input once per 00 us. + */ +#define GPIO_SET_DEBOUNCE_TIME(u32ClkSrc, u32ClkSel) (GPIO->DBCTL = (GPIO_DBCTL_ICLKON_Msk | (u32ClkSrc) | (u32ClkSel))) + +/** + * @brief Get GPIO Port IN Data + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * + * @return The specified port data + * + * @details Get the PIN register of specified GPIO port. + */ +#define GPIO_GET_IN_DATA(port) ((port)->PIN) + +/** + * @brief Set GPIO Port OUT Data + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32Data GPIO port data. + * + * @return None + * + * @details Set the Data into specified GPIO port. + */ +#define GPIO_SET_OUT_DATA(port, u32Data) ((port)->DOUT = (u32Data)) + +/** + * @brief Toggle Specified GPIO pin + * + * @param[in] u32Pin Pxy + * + * @return None + * + * @details Toggle the specified GPIO pint. + */ +#define GPIO_TOGGLE(u32Pin) ((u32Pin) ^= 1) + + +/** +* @brief Enable External GPIO interrupt +* +* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. +* @param[in] u32Pin The pin of specified GPIO port. +* It could be 0 ~ 15 for PA, PB, PC and PD GPIO port. +* It could be 0 ~ 14 for PE GPIO port. +* It could be 0 ~ 7 for PF GPIO port. +* @param[in] u32IntAttribs The interrupt attribute of specified GPIO pin. It could be \n +* GPIO_INT_RISING, GPIO_INT_FALLING, GPIO_INT_BOTH_EDGE, GPIO_INT_HIGH, GPIO_INT_LOW. +* +* @return None +* +* @details This function is used to enable specified GPIO pin interrupt. +*/ +#define GPIO_EnableEINT GPIO_EnableInt + +/** +* @brief Disable External GPIO interrupt +* +* @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. +* @param[in] u32Pin The pin of specified GPIO port. +* It could be 0 ~ 15 for PA, PB, PC and PD GPIO port. +* It could be 0 ~ 14 for PE GPIO port. +* It could be 0 ~ 7 for PF GPIO port. +* +* @return None +* +* @details This function is used to enable specified GPIO pin interrupt. +*/ +#define GPIO_DisableEINT GPIO_DisableInt + + +void GPIO_SetMode(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode); +void GPIO_EnableInt(GPIO_T *port, uint32_t u32Pin, uint32_t u32IntAttribs); +void GPIO_DisableInt(GPIO_T *port, uint32_t u32Pin); + + +/*@}*/ /* end of group GPIO_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group GPIO_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + + +#ifdef __cplusplus +} +#endif + +#endif // __GPIO_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/i2c.h b/StdDriver/inc/i2c.h new file mode 100644 index 0000000..775946c --- /dev/null +++ b/StdDriver/inc/i2c.h @@ -0,0 +1,413 @@ +/**************************************************************************//** + * @file I2C.h + * @version V3.0 + * $Revision: 19 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 Series I2C Driver Header File + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + * + ******************************************************************************/ +#ifndef __I2C_H__ +#define __I2C_H__ + +#include "M451Series.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup I2C_Driver I2C Driver + @{ +*/ + +/** @addtogroup I2C_EXPORTED_CONSTANTS I2C Exported Constants + @{ +*/ + +/*---------------------------------------------------------------------------------------------------------*/ +/* I2C_CTL constant definitions. */ +/*---------------------------------------------------------------------------------------------------------*/ +#define I2C_CTL_STA_SI 0x28UL /*!< I2C_CTL setting for I2C control bits. It would set STA and SI bits */ +#define I2C_CTL_STA_SI_AA 0x2CUL /*!< I2C_CTL setting for I2C control bits. It would set STA, SI and AA bits */ +#define I2C_CTL_STO_SI 0x18UL /*!< I2C_CTL setting for I2C control bits. It would set STO and SI bits */ +#define I2C_CTL_STO_SI_AA 0x1CUL /*!< I2C_CTL setting for I2C control bits. It would set STO, SI and AA bits */ +#define I2C_CTL_SI 0x08UL /*!< I2C_CTL setting for I2C control bits. It would set SI bit */ +#define I2C_CTL_SI_AA 0x0CUL /*!< I2C_CTL setting for I2C control bits. It would set SI and AA bits */ +#define I2C_CTL_STA 0x20UL /*!< I2C_CTL setting for I2C control bits. It would set STA bit */ +#define I2C_CTL_STO 0x10UL /*!< I2C_CTL setting for I2C control bits. It would set STO bit */ +#define I2C_CTL_AA 0x04UL /*!< I2C_CTL setting for I2C control bits. It would set AA bit */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* I2C GCMode constant definitions. */ +/*---------------------------------------------------------------------------------------------------------*/ +#define I2C_GCMODE_ENABLE 1 /*!< Enable I2C GC Mode */ +#define I2C_GCMODE_DISABLE 0 /*!< Disable I2C GC Mode */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* I2C SMBUS constant definitions. */ +/*---------------------------------------------------------------------------------------------------------*/ +#define I2C_SMBH_ENABLE 1 /*!< Enable SMBus Host Mode enable */ +#define I2C_SMBD_ENABLE 0 /*!< Enable SMBus Device Mode enable */ +#define I2C_PECTX_ENABLE 1 /*!< Enable SMBus Packet Error Check Transmit function */ +#define I2C_PECTX_DISABLE 0 /*!< Disable SMBus Packet Error Check Transmit function */ + +/*@}*/ /* end of group I2C_EXPORTED_CONSTANTS */ + +/** @addtogroup I2C_EXPORTED_FUNCTIONS I2C Exported Functions + @{ +*/ +/** + * @brief The macro is used to set I2C bus condition at One Time + * + * @param[in] i2c Specify I2C port + * @param[in] u8Ctrl A byte writes to I2C control register + * + * @return None + * + * @details Set I2C_CTL register to control I2C bus conditions of START, STOP, SI, ACK. + */ +#define I2C_SET_CONTROL_REG(i2c, u8Ctrl) ((i2c)->CTL = ((i2c)->CTL & ~0x3c) | (u8Ctrl)) + +/** + * @brief The macro is used to set START condition of I2C Bus + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details Set the I2C bus START condition in I2C_CTL register. + */ +#define I2C_START(i2c) ((i2c)->CTL = ((i2c)->CTL & ~I2C_CTL_SI_Msk) | I2C_CTL_STA_Msk) + +/** + * @brief The macro is used to wait I2C bus status get ready + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details When a new status is presented of I2C bus, the SI flag will be set in I2C_CTL register. + */ +#define I2C_WAIT_READY(i2c) while(!((i2c)->CTL & I2C_CTL_SI_Msk)) + +/** + * @brief The macro is used to Read I2C Bus Data Register + * + * @param[in] i2c Specify I2C port + * + * @return A byte of I2C data register + * + * @details I2C controller read data from bus and save it in I2CDAT register. + */ +#define I2C_GET_DATA(i2c) ((i2c)->DAT) + +/** + * @brief Write a Data to I2C Data Register + * + * @param[in] i2c Specify I2C port + * @param[in] u8Data A byte that writes to data register + * + * @return None + * + * @details When write a data to I2C_DAT register, the I2C controller will shift it to I2C bus. + */ +#define I2C_SET_DATA(i2c, u8Data) ((i2c)->DAT = (u8Data)) + +/** + * @brief Get I2C Bus status code + * + * @param[in] i2c Specify I2C port + * + * @return I2C status code + * + * @details To get this status code to monitor I2C bus event. + */ +#define I2C_GET_STATUS(i2c) ((i2c)->STATUS) + +/** + * @brief Get Time-out flag from I2C Bus + * + * @param[in] i2c Specify I2C port + * + * @retval 0 I2C Bus time-out is not happened + * @retval 1 I2C Bus time-out is happened + * + * @details When I2C bus occurs time-out event, the time-out flag will be set. + */ +#define I2C_GET_TIMEOUT_FLAG(i2c) ( ((i2c)->TOCTL & I2C_TOCTL_TOIF_Msk) == I2C_TOCTL_TOIF_Msk ? 1:0 ) + +/** + * @brief To get wake-up flag from I2C Bus + * + * @param[in] i2c Specify I2C port + * + * @retval 0 Chip is not woken-up from power-down mode + * @retval 1 Chip is woken-up from power-down mode + * + * @details I2C bus occurs wake-up event, wake-up flag will be set. + */ +#define I2C_GET_WAKEUP_FLAG(i2c) ( ((i2c)->WKSTS & I2C_WKSTS_WKIF_Msk) == I2C_WKSTS_WKIF_Msk ? 1:0 ) + +/** + * @brief To clear wake-up flag + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details If wake-up flag is set, use this macro to clear it. + */ +#define I2C_CLEAR_WAKEUP_FLAG(i2c) ((i2c)->WKSTS = I2C_WKSTS_WKIF_Msk) + +/** + * @brief To get SMBus Status + * + * @param[in] i2c Specify I2C port + * + * @return SMBus status + * + * @details To get the Bus Management status of I2C_BUSSTS register + * + */ +#define I2C_SMBUS_GET_STATUS(i2c) ((i2c)->BUSSTS) + +/** + * @brief Get SMBus CRC value + * + * @param[in] i2c Specify I2C port + * + * @return Packet error check byte value + * + * @details The CRC check value after a transmission or a reception by count by using CRC8 + * + */ +#define I2C_SMBUS_GET_PEC_VALUE(i2c) ((i2c)->PKTCRC) + +/** + * @brief Set SMBus Bytes number of Transmission or reception + * + * @param[in] i2c Specify I2C port + * @param[in] u32PktSize Transmit / Receive bytes + * + * @return None + * + * @details The transmission or receive byte number in one transaction when PECEN is set. The maximum is 255 bytes. + * + */ +#define I2C_SMBUS_SET_PACKET_BYTE_COUNT(i2c, u32PktSize) ((i2c)->PKTSIZE = (u32PktSize)) + +/** + * @brief Enable SMBus Alert function + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details Device Mode(BMHEN=0): If ALERTEN(I2C_BUSCTL[4]) is set, the Alert pin will pull lo, and reply ACK when get ARP from host + * Host Mode(BMHEN=1): If ALERTEN(I2C_BUSCTL[4]) is set, the Alert pin is supported to receive alert state(Lo trigger) + * + */ +#define I2C_SMBUS_ENABLE_ALERT(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_ALERTEN_Msk) + +/** + * @brief Disable SMBus Alert pin function + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details Device Mode(BMHEN=0): If ALERTEN(I2C_BUSCTL[4]) is clear, the Alert pin will pull hi, and reply NACK when get ARP from host + * Host Mode(BMHEN=1): If ALERTEN(I2C_BUSCTL[4]) is clear, the Alert pin is not supported to receive alert state(Lo trigger) + * + */ +#define I2C_SMBUS_DISABLE_ALERT(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_ALERTEN_Msk) + +/** + * @brief Set SMBus SUSCON pin is output mode + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details This function to set SUSCON(I2C_BUSCTL[6]) pin is output mode. + * + * + */ +#define I2C_SMBUS_SET_SUSCON_OUT(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_SCTLOEN_Msk) + +/** + * @brief Set SMBus SUSCON pin is input mode + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details This function to set SUSCON(I2C_BUSCTL[6]) pin is input mode. + * + * + */ +#define I2C_SMBUS_SET_SUSCON_IN(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_SCTLOEN_Msk) + +/** + * @brief Set SMBus SUSCON pin output high state + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details This function to set SUSCON(I2C_BUSCTL[6]) pin is output hi state. + * + */ +#define I2C_SMBUS_SET_SUSCON_HIGH(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_SCTLOSTS_Msk) + + +/** + * @brief Set SMBus SUSCON pin output low state + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details This function to set SUSCON(I2C_BUSCTL[6]) pin is output lo state. + * + */ +#define I2C_SMBUS_SET_SUSCON_LOW(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_SCTLOSTS_Msk) + +/** + * @brief Enable SMBus Acknowledge control by manual + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details The 9th bit can response the ACK or NACK according the received data by user. When the byte is received, SCLK line stretching to low between the 8th and 9th SCLK pulse. + * + */ +#define I2C_SMBUS_ACK_MANUAL(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_ACKMEN_Msk) + +/** + * @brief Disable SMBus Acknowledge control by manual + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details Disable acknowledge response control by user. + * + */ +#define I2C_SMBUS_ACK_AUTO(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_ACKMEN_Msk) + +/** + * @brief Enable SMBus Acknowledge manual interrupt + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details This function is used to enable SMBUS acknowledge manual interrupt on the 9th clock cycle when SMBUS=1 and ACKMEN=1 + * + */ +#define I2C_SMBUS_9THBIT_INT_ENABLE(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_ACKM9SI_Msk) + +/** + * @brief Disable SMBus Acknowledge manual interrupt + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details This function is used to disable SMBUS acknowledge manual interrupt on the 9th clock cycle when SMBUS=1 and ACKMEN=1 + * + */ +#define I2C_SMBUS_9THBIT_INT_DISABLE(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_ACKM9SI_Msk) + +/** + * @brief Enable SMBus PEC clear at REPEAT START + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details This function is used to enable the condition of REAEAT START can clear the PEC calculation. + * + */ +#define I2C_SMBUS_RST_PEC_AT_START_ENABLE(i2c) ((i2c)->BUSCTL |= I2C_BUSCTL_PECCLR_Msk) + +/** + * @brief Disable SMBus PEC clear at Repeat START + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details This function is used to disable the condition of Repeat START can clear the PEC calculation. + * + */ +#define I2C_SMBUS_RST_PEC_AT_START_DISABLE(i2c) ((i2c)->BUSCTL &= ~I2C_BUSCTL_PECCLR_Msk) + +/*---------------------------------------------------------------------------------------------------------*/ +/* inline functions */ +/*---------------------------------------------------------------------------------------------------------*/ +/** + * @brief The macro is used to set STOP condition of I2C Bus + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details Set the I2C bus STOP condition in I2C_CTL register. + */ +static __INLINE void I2C_STOP(I2C_T *i2c) +{ + + (i2c)->CTL |= (I2C_CTL_SI_Msk | I2C_CTL_STO_Msk); + while(i2c->CTL & I2C_CTL_STO_Msk); +} + +void I2C_ClearTimeoutFlag(I2C_T *i2c); +void I2C_Close(I2C_T *i2c); +void I2C_Trigger(I2C_T *i2c, uint8_t u8Start, uint8_t u8Stop, uint8_t u8Si, uint8_t u8Ack); +void I2C_DisableInt(I2C_T *i2c); +void I2C_EnableInt(I2C_T *i2c); +uint32_t I2C_GetBusClockFreq(I2C_T *i2c); +uint32_t I2C_GetIntFlag(I2C_T *i2c); +uint32_t I2C_GetStatus(I2C_T *i2c); +uint32_t I2C_Open(I2C_T *i2c, uint32_t u32BusClock); +uint8_t I2C_GetData(I2C_T *i2c); +void I2C_SetSlaveAddr(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddr, uint8_t u8GCMode); +void I2C_SetSlaveAddrMask(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddrMask); +uint32_t I2C_SetBusClockFreq(I2C_T *i2c, uint32_t u32BusClock); +void I2C_EnableTimeout(I2C_T *i2c, uint8_t u8LongTimeout); +void I2C_DisableTimeout(I2C_T *i2c); +void I2C_EnableWakeup(I2C_T *i2c); +void I2C_DisableWakeup(I2C_T *i2c); +void I2C_SetData(I2C_T *i2c, uint8_t u8Data); + +uint32_t I2C_SMBusGetStatus(I2C_T *i2c); +void I2C_SMBusClearInterruptFlag(I2C_T *i2c, uint8_t u8ClrSMBusIntFlag); +void I2C_SMBusSetPacketByteCount(I2C_T *i2c, uint32_t u32PktSize); +void I2C_SMBusOpen(I2C_T *i2c, uint8_t u8HostDevice); +void I2C_SMBusClose(I2C_T *i2c); +void I2C_SMBusPECTxEnable(I2C_T *i2c, uint8_t u8PECTxEn); +uint8_t I2C_SMBusGetPECValue(I2C_T *i2c); +void I2C_SMBusIdleTimeout(I2C_T *i2c, uint32_t us, uint32_t u32Hclk); +void I2C_SMBusTimeout(I2C_T *i2c, uint32_t ms, uint32_t u32Pclk); +void I2C_SMBusClockLoTimeout(I2C_T *i2c, uint32_t ms, uint32_t u32Pclk); +/*@}*/ /* end of group I2C_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group I2C_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif +#endif //__I2C_H__ diff --git a/StdDriver/inc/otg.h b/StdDriver/inc/otg.h new file mode 100644 index 0000000..4137650 --- /dev/null +++ b/StdDriver/inc/otg.h @@ -0,0 +1,260 @@ +/**************************************************************************//** + * @file otg.h + * @version V0.10 + * $Revision: 3 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 Series OTG Driver Header File + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + * + ******************************************************************************/ +#ifndef __OTG_H__ +#define __OTG_H__ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Include related headers */ +/*---------------------------------------------------------------------------------------------------------*/ +#include "M451Series.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup OTG_Driver OTG Driver + @{ +*/ + + +/** @addtogroup OTG_EXPORTED_CONSTANTS OTG Exported Constants + @{ +*/ + + + +/*---------------------------------------------------------------------------------------------------------*/ +/* OTG constant definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define OTG_VBUS_EN_ACTIVE_HIGH (0UL) /*!< USB VBUS power switch enable signal is active high. */ +#define OTG_VBUS_EN_ACTIVE_LOW (1UL) /*!< USB VBUS power switch enable signal is active low. */ +#define OTG_VBUS_ST_VALID_HIGH (0UL) /*!< USB VBUS power switch valid status is high. */ +#define OTG_VBUS_ST_VALID_LOW (1UL) /*!< USB VBUS power switch valid status is low. */ + + +/*@}*/ /* end of group OTG_EXPORTED_CONSTANTS */ + + +/** @addtogroup OTG_EXPORTED_FUNCTIONS OTG Exported Functions + @{ +*/ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Define Macros and functions */ +/*---------------------------------------------------------------------------------------------------------*/ + + +/** + * @brief This macro is used to enable OTG function + * @param None + * @return None + * @details This macro will set OTGEN bit of OTG_CTL register to enable OTG function. + */ +#define OTG_ENABLE() (OTG->CTL |= OTG_CTL_OTGEN_Msk) + +/** + * @brief This macro is used to disable OTG function + * @param None + * @return None + * @details This macro will clear OTGEN bit of OTG_CTL register to disable OTG function. + */ +#define OTG_DISABLE() (OTG->CTL &= ~OTG_CTL_OTGEN_Msk) + +/** + * @brief This macro is used to enable USB PHY + * @param None + * @return None + * @details When the USB role is selected as OTG device, use this macro to enable USB PHY. + * This macro will set OTGPHYEN bit of OTG_PHYCTL register to enable USB PHY. + */ +#define OTG_ENABLE_PHY() (OTG->PHYCTL |= OTG_PHYCTL_OTGPHYEN_Msk) + +/** + * @brief This macro is used to disable USB PHY + * @param None + * @return None + * @details This macro will clear OTGPHYEN bit of OTG_PHYCTL register to disable USB PHY. + */ +#define OTG_DISABLE_PHY() (OTG->PHYCTL &= ~OTG_PHYCTL_OTGPHYEN_Msk) + +/** + * @brief This macro is used to enable ID detection function + * @param None + * @return None + * @details This macro will set IDDETEN bit of OTG_PHYCTL register to enable ID detection function. + */ +#define OTG_ENABLE_ID_DETECT() (OTG->PHYCTL |= OTG_PHYCTL_IDDETEN_Msk) + +/** + * @brief This macro is used to disable ID detection function + * @param None + * @return None + * @details This macro will clear IDDETEN bit of OTG_PHYCTL register to disable ID detection function. + */ +#define OTG_DISABLE_ID_DETECT() (OTG->PHYCTL &= ~OTG_PHYCTL_IDDETEN_Msk) + +/** + * @brief This macro is used to enable OTG wake-up function + * @param None + * @return None + * @details This macro will set WKEN bit of OTG_CTL register to enable OTG wake-up function. + */ +#define OTG_ENABLE_WAKEUP() (OTG->CTL |= OTG_CTL_WKEN_Msk) + +/** + * @brief This macro is used to disable OTG wake-up function + * @param None + * @return None + * @details This macro will clear WKEN bit of OTG_CTL register to disable OTG wake-up function. + */ +#define OTG_DISABLE_WAKEUP() (OTG->CTL &= ~OTG_CTL_WKEN_Msk) + +/** + * @brief This macro is used to set the polarity of USB_VBUS_EN pin + * @param[in] u32Pol The polarity selection. Valid values are listed below. + * - \ref OTG_VBUS_EN_ACTIVE_HIGH + * - \ref OTG_VBUS_EN_ACTIVE_LOW + * @return None + * @details This macro is used to set the polarity of external USB VBUS power switch enable signal. + */ +#define OTG_SET_VBUS_EN_POL(u32Pol) (OTG->PHYCTL = (OTG->PHYCTL & (~OTG_PHYCTL_VBENPOL_Msk)) | ((u32Pol)<PHYCTL = (OTG->PHYCTL & (~OTG_PHYCTL_VBSTSPOL_Msk)) | ((u32Pol)<INTEN |= (u32Mask)) + +/** + * @brief This macro is used to disable OTG related interrupts + * @param[in] u32Mask The combination of interrupt source. Each bit corresponds to a interrupt source. Valid values are listed below. + * - \ref OTG_INTEN_ROLECHGIEN_Msk + * - \ref OTG_INTEN_VBEIEN_Msk + * - \ref OTG_INTEN_SRPFIEN_Msk + * - \ref OTG_INTEN_HNPFIEN_Msk + * - \ref OTG_INTEN_GOIDLEIEN_Msk + * - \ref OTG_INTEN_IDCHGIEN_Msk + * - \ref OTG_INTEN_PDEVIEN_Msk + * - \ref OTG_INTEN_HOSTIEN_Msk + * - \ref OTG_INTEN_BVLDCHGIEN_Msk + * - \ref OTG_INTEN_AVLDCHGIEN_Msk + * - \ref OTG_INTEN_VBCHGIEN_Msk + * - \ref OTG_INTEN_SECHGIEN_Msk + * - \ref OTG_INTEN_SRPDETIEN_Msk + * @return None + * @details This macro will disable OTG related interrupts specified by u32Mask parameter. + */ +#define OTG_DISABLE_INT(u32Mask) (OTG->INTEN &= ~(u32Mask)) + +/** + * @brief This macro is used to get OTG related interrupt flags + * @param[in] u32Mask The combination of interrupt source. Each bit corresponds to a interrupt source. Valid values are listed below. + * - \ref OTG_INTSTS_ROLECHGIF_Msk + * - \ref OTG_INTSTS_VBEIF_Msk + * - \ref OTG_INTSTS_SRPFIF_Msk + * - \ref OTG_INTSTS_HNPFIF_Msk + * - \ref OTG_INTSTS_GOIDLEIF_Msk + * - \ref OTG_INTSTS_IDCHGIF_Msk + * - \ref OTG_INTSTS_PDEVIF_Msk + * - \ref OTG_INTSTS_HOSTIF_Msk + * - \ref OTG_INTSTS_BVLDCHGIF_Msk + * - \ref OTG_INTSTS_AVLDCHGIF_Msk + * - \ref OTG_INTSTS_VBCHGIF_Msk + * - \ref OTG_INTSTS_SECHGIF_Msk + * - \ref OTG_INTSTS_SRPDETIF_Msk + * @return Interrupt flags of selected sources. + * @details This macro will return OTG related interrupt flags specified by u32Mask parameter. + */ +#define OTG_GET_INT_FLAG(u32Mask) (OTG->INTSTS & (u32Mask)) + +/** + * @brief This macro is used to clear OTG related interrupt flags + * @param[in] u32Mask The combination of interrupt source. Each bit corresponds to a interrupt source. Valid values are listed below. + * - \ref OTG_INTSTS_ROLECHGIF_Msk + * - \ref OTG_INTSTS_VBEIF_Msk + * - \ref OTG_INTSTS_SRPFIF_Msk + * - \ref OTG_INTSTS_HNPFIF_Msk + * - \ref OTG_INTSTS_GOIDLEIF_Msk + * - \ref OTG_INTSTS_IDCHGIF_Msk + * - \ref OTG_INTSTS_PDEVIF_Msk + * - \ref OTG_INTSTS_HOSTIF_Msk + * - \ref OTG_INTSTS_BVLDCHGIF_Msk + * - \ref OTG_INTSTS_AVLDCHGIF_Msk + * - \ref OTG_INTSTS_VBCHGIF_Msk + * - \ref OTG_INTSTS_SECHGIF_Msk + * - \ref OTG_INTSTS_SRPDETIF_Msk + * @return None + * @details This macro will clear OTG related interrupt flags specified by u32Mask parameter. + */ +#define OTG_CLR_INT_FLAG(u32Mask) (OTG->INTSTS = (u32Mask)) + +/** + * @brief This macro is used to get OTG related status + * @param[in] u32Mask The combination of user specified source. Valid values are listed below. + * - \ref OTG_STATUS_OVERCUR_Msk + * - \ref OTG_STATUS_IDSTS_Msk + * - \ref OTG_STATUS_SESSEND_Msk + * - \ref OTG_STATUS_BVLD_Msk + * - \ref OTG_STATUS_AVLD_Msk + * - \ref OTG_STATUS_VBUSVLD_Msk + * @return The user specified status. + * @details This macro will return OTG related status specified by u32Mask parameter. + */ +#define OTG_GET_STATUS(u32Mask) (OTG->STATUS & (u32Mask)) + + + +/*@}*/ /* end of group OTG_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group OTG_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + + +#endif //__OTG_H__ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/pdma.h b/StdDriver/inc/pdma.h new file mode 100644 index 0000000..200b196 --- /dev/null +++ b/StdDriver/inc/pdma.h @@ -0,0 +1,300 @@ +/**************************************************************************//** + * @file pdma.h + * @version V1.00 + * $Revision: 16 $ + * $Date: 17/01/09 2:30p $ + * @brief M451 series PDMA driver header file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __PDMA_H__ +#define __PDMA_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup PDMA_Driver PDMA Driver + @{ +*/ + +/** @addtogroup PDMA_EXPORTED_CONSTANTS PDMA Exported Constants + @{ +*/ +#define PDMA_CH_MAX 12UL /*!< Specify Maximum Channels of PDMA \hideinitializer */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Operation Mode Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PDMA_OP_STOP 0x00000000UL /*!INTSTS)) + +/** + * @brief Get Transfer Done Interrupt Status + * + * @param[in] None + * + * @return None + * + * @details Get the transfer done Interrupt status. + */ +#define PDMA_GET_TD_STS() ((uint32_t)(PDMA->TDSTS)) + +/** + * @brief Clear Transfer Done Interrupt Status + * + * @param[in] u32Mask The channel mask + * + * @return None + * + * @details Clear the transfer done Interrupt status. + */ +#define PDMA_CLR_TD_FLAG(u32Mask) ((uint32_t)(PDMA->TDSTS = (u32Mask))) + +/** + * @brief Get Target Abort Interrupt Status + * + * @param[in] None + * + * @return None + * + * @details Get the target abort Interrupt status. + */ +#define PDMA_GET_ABORT_STS() ((uint32_t)(PDMA->ABTSTS)) + +/** + * @brief Clear Target Abort Interrupt Status + * + * @param[in] u32Mask The channel mask + * + * @return None + * + * @details Clear the target abort Interrupt status. + */ +#define PDMA_CLR_ABORT_FLAG(u32Mask) ((uint32_t)(PDMA->ABTSTS = (u32Mask))) + +/** + * @brief Get Scatter-Gather Table Empty Interrupt Status + * + * @param[in] None + * + * @return None + * + * @details Get the scatter-gather table empty Interrupt status. + */ +#define PDMA_GET_EMPTY_STS() ((uint32_t)(PDMA->SCATSTS)) + +/** + * @brief Clear Scatter-Gather Table Empty Interrupt Status + * + * @param[in] u32Mask The channel mask + * + * @return None + * + * @details Clear the scatter-gather table empty Interrupt status. + */ +#define PDMA_CLR_EMPTY_FLAG(u32Mask) ((uint32_t)(PDMA->SCATSTS = (u32Mask))) + +/** + * @brief Clear Timeout Interrupt Status + * + * @param[in] u32Ch The selected channel + * + * @return None + * + * @details Clear the selected channel timeout interrupt status. + * @note This function is only supported in M45xD/M45xC. + */ +#define PDMA_CLR_TMOUT_FLAG(u32Ch) ((uint32_t)(PDMA->INTSTS = (1 << ((u32Ch) + 8)))) + +/** + * @brief Check Channel Status + * + * @param[in] u32Ch The selected channel + * + * @retval 0 Idle state + * @retval 1 Busy state + * + * @details Check the selected channel is busy or not. + */ +#define PDMA_IS_CH_BUSY(u32Ch) ((uint32_t)(PDMA->TRGSTS & (1 << (u32Ch)))? 1 : 0) + +/** + * @brief Set Source Address + * + * @param[in] u32Ch The selected channel + * @param[in] u32Addr The selected address + * + * @return None + * + * @details This macro set the selected channel source address. + */ +#define PDMA_SET_SRC_ADDR(u32Ch, u32Addr) ((uint32_t)(PDMA->DSCT[(u32Ch)].SA = (u32Addr))) + +/** + * @brief Set Destination Address + * + * @param[in] u32Ch The selected channel + * @param[in] u32Addr The selected address + * + * @return None + * + * @details This macro set the selected channel destination address. + */ +#define PDMA_SET_DST_ADDR(u32Ch, u32Addr) ((uint32_t)(PDMA->DSCT[(u32Ch)].DA = (u32Addr))) + +/** + * @brief Set Transfer Count + * + * @param[in] u32Ch The selected channel + * @param[in] u32TransCount Transfer Count + * + * @return None + * + * @details This macro set the selected channel transfer count. + */ +#define PDMA_SET_TRANS_CNT(u32Ch, u32TransCount) ((uint32_t)(PDMA->DSCT[(u32Ch)].CTL=(PDMA->DSCT[(u32Ch)].CTL&~PDMA_DSCT_CTL_TXCNT_Msk)|(((u32TransCount)-1) << PDMA_DSCT_CTL_TXCNT_Pos))) + +/** + * @brief Set Scatter-gather descriptor Address + * + * @param[in] u32Ch The selected channel + * @param[in] u32Addr The descriptor address + * + * @return None + * + * @details This macro set the selected channel scatter-gather descriptor address. + */ +#define PDMA_SET_SCATTER_DESC(u32Ch, u32Addr) ((uint32_t)(PDMA->DSCT[(u32Ch)].NEXT = (u32Addr) - (PDMA->SCATBA))) + +/** + * @brief Stop the channel + * + * @param[in] u32Ch The selected channel + * + * @return None + * + * @details This macro stop the selected channel. + */ +#define PDMA_STOP(u32Ch) ((uint32_t)(PDMA->STOP = (1 << (u32Ch)))) + +/*---------------------------------------------------------------------------------------------------------*/ +/* Define PWM functions prototype */ +/*---------------------------------------------------------------------------------------------------------*/ +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 u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr); +void PDMA_SetBurstType(uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize); +void PDMA_EnableTimeout(uint32_t u32Mask); +void PDMA_DisableTimeout(uint32_t u32Mask); +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 PDMA_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group PDMA_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__PDMA_H__ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/pwm.h b/StdDriver/inc/pwm.h new file mode 100644 index 0000000..4f38239 --- /dev/null +++ b/StdDriver/inc/pwm.h @@ -0,0 +1,555 @@ +/**************************************************************************//** + * @file pwm.h + * @version V1.00 + * $Revision: 26 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series PWM driver header file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __PWM_H__ +#define __PWM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup PWM_Driver PWM Driver + @{ +*/ + +/** @addtogroup PWM_EXPORTED_CONSTANTS PWM Exported Constants + @{ +*/ +#define PWM_CHANNEL_NUM (6) /*!< PWM channel number */ +#define PWM_CH_0_MASK (0x1UL) /*!< PWM channel 0 mask \hideinitializer */ +#define PWM_CH_1_MASK (0x2UL) /*!< PWM channel 1 mask \hideinitializer */ +#define PWM_CH_2_MASK (0x4UL) /*!< PWM channel 2 mask \hideinitializer */ +#define PWM_CH_3_MASK (0x8UL) /*!< PWM channel 3 mask \hideinitializer */ +#define PWM_CH_4_MASK (0x10UL) /*!< PWM channel 4 mask \hideinitializer */ +#define PWM_CH_5_MASK (0x20UL) /*!< PWM channel 5 mask \hideinitializer */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Counter Type Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_UP_COUNTER (0UL) /*!< Up counter type */ +#define PWM_DOWN_COUNTER (1UL) /*!< Down counter type */ +#define PWM_UP_DOWN_COUNTER (2UL) /*!< Up-Down counter type */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Aligned Type Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_EDGE_ALIGNED (1UL) /*!< PWM working in edge aligned type(down count) */ +#define PWM_CENTER_ALIGNED (2UL) /*!< PWM working in center aligned type */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Output Level Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_OUTPUT_NOTHING (0UL) /*!< PWM output nothing */ +#define PWM_OUTPUT_LOW (1UL) /*!< PWM output low */ +#define PWM_OUTPUT_HIGH (2UL) /*!< PWM output high */ +#define PWM_OUTPUT_TOGGLE (3UL) /*!< PWM output toggle */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Trigger Source Select Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_TRIGGER_ADC_EVEN_ZERO_POINT (0UL) /*!< PWM trigger ADC while counter of even channel matches zero point */ +#define PWM_TRIGGER_ADC_EVEN_PERIOD_POINT (1UL) /*!< PWM trigger ADC while counter of even channel matches period point */ +#define PWM_TRIGGER_ADC_EVEN_ZERO_OR_PERIOD_POINT (2UL) /*!< PWM trigger ADC while counter of even channel matches zero or period point */ +#define PWM_TRIGGER_ADC_EVEN_COMPARE_UP_COUNT_POINT (3UL) /*!< PWM trigger ADC while counter of even channel matches up count to comparator point */ +#define PWM_TRIGGER_ADC_EVEN_COMPARE_DOWN_COUNT_POINT (4UL) /*!< PWM trigger ADC while counter of even channel matches down count to comparator point */ +#define PWM_TRIGGER_ADC_ODD_ZERO_POINT (5UL) /*!< PWM trigger ADC while counter of odd channel matches zero point */ +#define PWM_TRIGGER_ADC_ODD_PERIOD_POINT (6UL) /*!< PWM trigger ADC while counter of odd channel matches period point */ +#define PWM_TRIGGER_ADC_ODD_ZERO_OR_PERIOD_POINT (7UL) /*!< PWM trigger ADC while counter of odd channel matches zero or period point */ +#define PWM_TRIGGER_ADC_ODD_COMPARE_UP_COUNT_POINT (8UL) /*!< PWM trigger ADC while counter of odd channel matches up count to comparator point */ +#define PWM_TRIGGER_ADC_ODD_COMPARE_DOWN_COUNT_POINT (9UL) /*!< PWM trigger ADC while counter of odd channel matches down count to comparator point */ +#define PWM_TRIGGER_ADC_CH_0_FREE_COMPARE_UP_COUNT_POINT (10UL) /*!< PWM trigger ADC while counter of channel 0 matches up count to free comparator point */ +#define PWM_TRIGGER_ADC_CH_0_FREE_COMPARE_DOWN_COUNT_POINT (11UL) /*!< PWM trigger ADC while counter of channel 0 matches down count to free comparator point */ +#define PWM_TRIGGER_ADC_CH_2_FREE_COMPARE_UP_COUNT_POINT (12UL) /*!< PWM trigger ADC while counter of channel 2 matches up count to free comparator point */ +#define PWM_TRIGGER_ADC_CH_2_FREE_COMPARE_DOWN_COUNT_POINT (13UL) /*!< PWM trigger ADC while counter of channel 2 matches down count to free comparator point */ +#define PWM_TRIGGER_ADC_CH_4_FREE_COMPARE_UP_COUNT_POINT (14UL) /*!< PWM trigger ADC while counter of channel 4 matches up count to free comparator point */ +#define PWM_TRIGGER_ADC_CH_4_FREE_COMPARE_DOWN_COUNT_POINT (15UL) /*!< PWM trigger ADC while counter of channel 4 matches down count to free comparator point */ + +#define PWM_TRIGGER_DAC_ZERO_POINT (0x1UL) /*!< PWM trigger ADC while counter down count to 0 \hideinitializer */ +#define PWM_TRIGGER_DAC_PERIOD_POINT (0x100UL) /*!< PWM trigger ADC while counter matches (PERIOD + 1) \hideinitializer */ +#define PWM_TRIGGER_DAC_COMPARE_UP_COUNT_POINT (0x10000UL) /*!< PWM trigger ADC while counter up count to CMPDAT \hideinitializer */ +#define PWM_TRIGGER_DAC_COMPARE_DOWN_COUNT_POINT (0x1000000UL) /*!< PWM trigger ADC while counter down count to CMPDAT \hideinitializer */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Fail brake Control Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_FB_EDGE_ACMP0 (PWM_BRKCTL0_1_CPO0EBEN_Msk) /*!< Comparator 0 as edge-detect fault brake source */ +#define PWM_FB_EDGE_ACMP1 (PWM_BRKCTL0_1_CPO1EBEN_Msk) /*!< Comparator 1 as edge-detect fault brake source */ +#define PWM_FB_EDGE_BKP0 (PWM_BRKCTL0_1_BRKP0EEN_Msk) /*!< BKP0 pin as edge-detect fault brake source */ +#define PWM_FB_EDGE_BKP1 (PWM_BRKCTL0_1_BRKP1EEN_Msk) /*!< BKP1 pin as edge-detect fault brake source */ +#define PWM_FB_EDGE_SYS_CSS (PWM_BRKCTL0_1_SYSEBEN_Msk | PWM_FAILBRK_CSSBRKEN_Msk) /*!< System fail condition: clock security system detection as edge-detect fault brake source */ +#define PWM_FB_EDGE_SYS_BOD (PWM_BRKCTL0_1_SYSEBEN_Msk | PWM_FAILBRK_BODBRKEN_Msk) /*!< System fail condition: brown-out detection as edge-detect fault brake source */ +#define PWM_FB_EDGE_SYS_RAM (PWM_BRKCTL0_1_SYSEBEN_Msk | PWM_FAILBRK_RAMBRKEN_Msk) /*!< System fail condition: SRAM parity error detection as edge-detect fault brake source */ +#define PWM_FB_EDGE_SYS_COR (PWM_BRKCTL0_1_SYSEBEN_Msk | PWM_FAILBRK_CORBRKEN_Msk) /*!< System fail condition: core lockup detection as edge-detect fault brake source */ + +#define PWM_FB_LEVEL_ACMP0 (PWM_BRKCTL0_1_CPO0LBEN_Msk) /*!< Comparator 0 as level-detect fault brake source */ +#define PWM_FB_LEVEL_ACMP1 (PWM_BRKCTL0_1_CPO1LBEN_Msk) /*!< Comparator 1 as level-detect fault brake source */ +#define PWM_FB_LEVEL_BKP0 (PWM_BRKCTL0_1_BRKP0LEN_Msk) /*!< BKP0 pin as level-detect fault brake source */ +#define PWM_FB_LEVEL_BKP1 (PWM_BRKCTL0_1_BRKP1LEN_Msk) /*!< BKP1 pin as level-detect fault brake source */ +#define PWM_FB_LEVEL_SYS_CSS (PWM_BRKCTL0_1_SYSLBEN_Msk | PWM_FAILBRK_CSSBRKEN_Msk) /*!< System fail condition: clock security system detection as level-detect fault brake source */ +#define PWM_FB_LEVEL_SYS_BOD (PWM_BRKCTL0_1_SYSLBEN_Msk | PWM_FAILBRK_BODBRKEN_Msk) /*!< System fail condition: brown-out detection as level-detect fault brake source */ +#define PWM_FB_LEVEL_SYS_RAM (PWM_BRKCTL0_1_SYSLBEN_Msk | PWM_FAILBRK_RAMBRKEN_Msk) /*!< System fail condition: SRAM parity error detection as level-detect fault brake source */ +#define PWM_FB_LEVEL_SYS_COR (PWM_BRKCTL0_1_SYSLBEN_Msk | PWM_FAILBRK_CORBRKEN_Msk) /*!< System fail condition: core lockup detection as level-detect fault brake source */ + +#define PWM_FB_EDGE (0UL) /*!< edge-detect fault brake */ +#define PWM_FB_LEVEL (8UL) /*!< level-detect fault brake */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Capture Control Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_CAPTURE_INT_RISING_LATCH (1UL) /*!< PWM capture interrupt if channel has rising transition */ +#define PWM_CAPTURE_INT_FALLING_LATCH (0x100UL) /*!< PWM capture interrupt if channel has falling transition */ + +#define PWM_CAPTURE_PDMA_RISING_LATCH (0x2UL) /*!< PWM capture rising latched data transfer by PDMA */ +#define PWM_CAPTURE_PDMA_FALLING_LATCH (0x4UL) /*!< PWM capture falling latched data transfer by PDMA */ +#define PWM_CAPTURE_PDMA_RISING_FALLING_LATCH (0x6UL) /*!< PWM capture rising and falling latched data transfer by PDMA */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Duty Interrupt Type Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_DUTY_INT_DOWN_COUNT_MATCH_CMP (PWM_INTEN0_CMPDIEN0_Msk) /*!< PWM duty interrupt triggered if down count match comparator */ +#define PWM_DUTY_INT_UP_COUNT_MATCH_CMP (PWM_INTEN0_CMPUIEN0_Msk) /*!< PWM duty interrupt triggered if up down match comparator */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Interrupt Flag Accumulator Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_IFA_EVEN_ZERO_POINT (0UL) /*!< PWM counter equal to zero in even channel \hideinitializer */ +#define PWM_IFA_EVEN_PERIOD_POINT (1UL) /*!< PWM counter equal to period in even channel \hideinitializer */ +#define PWM_IFA_EVEN_COMPARE_UP_COUNT_POINT (2UL) /*!< PWM counter up count to comparator value in even channel \hideinitializer */ +#define PWM_IFA_EVEN_COMPARE_DOWN_COUNT_POINT (3UL) /*!< PWM counter down count to comparator value in even channel \hideinitializer */ +#define PWM_IFA_ODD_ZERO_POINT (4UL) /*!< PWM counter equal to zero in odd channel \hideinitializer */ +#define PWM_IFA_ODD_PERIOD_POINT (5UL) /*!< PWM counter equal to period in odd channel \hideinitializer */ +#define PWM_IFA_ODD_COMPARE_UP_COUNT_POINT (6UL) /*!< PWM counter up count to comparator value in odd channel \hideinitializer */ +#define PWM_IFA_ODD_COMPARE_DOWN_COUNT_POINT (7UL) /*!< PWM counter down count to comparator value in odd channel \hideinitializer */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Load Mode Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_LOAD_MODE_IMMEDIATE (PWM_CTL0_IMMLDEN0_Msk) /*!< PWM immediately load mode \hideinitializer */ +#define PWM_LOAD_MODE_WINDOW (PWM_CTL0_WINLDEN0_Msk) /*!< PWM window load mode \hideinitializer */ +#define PWM_LOAD_MODE_CENTER (PWM_CTL0_CTRLD0_Msk) /*!< PWM center load mode \hideinitializer */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Synchronize Control Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_SYNC_OUT_FROM_SYNCIN_SWSYNC (0UL) /*!< Synchronize source from SYNC_IN or SWSYNC \hideinitializer */ +#define PWM_SYNC_OUT_FROM_COUNT_TO_ZERO (1UL) /*!< Synchronize source from counter equal to 0 \hideinitializer */ +#define PWM_SYNC_OUT_FROM_COUNT_TO_COMPARATOR (2UL) /*!< Synchronize source from counter equal to CMPDAT1, CMPDAT3, CMPDAT5 \hideinitializer */ +#define PWM_SYNC_OUT_DISABLE (3UL) /*!< SYNC_OUT will not be generated \hideinitializer */ +#define PWM_PHS_DIR_DECREMENT (0UL) /*!< PWM counter count decrement \hideinitializer */ +#define PWM_PHS_DIR_INCREMENT (1UL) /*!< PWM counter count increment \hideinitializer */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Noise Filter Clock Divide Select Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_NF_CLK_DIV_1 (0UL) /*!< Noise filter clock is HCLK divide by 1 \hideinitializer */ +#define PWM_NF_CLK_DIV_2 (1UL) /*!< Noise filter clock is HCLK divide by 2 \hideinitializer */ +#define PWM_NF_CLK_DIV_4 (2UL) /*!< Noise filter clock is HCLK divide by 4 \hideinitializer */ +#define PWM_NF_CLK_DIV_8 (3UL) /*!< Noise filter clock is HCLK divide by 8 \hideinitializer */ +#define PWM_NF_CLK_DIV_16 (4UL) /*!< Noise filter clock is HCLK divide by 16 \hideinitializer */ +#define PWM_NF_CLK_DIV_32 (5UL) /*!< Noise filter clock is HCLK divide by 32 \hideinitializer */ +#define PWM_NF_CLK_DIV_64 (6UL) /*!< Noise filter clock is HCLK divide by 64 \hideinitializer */ +#define PWM_NF_CLK_DIV_128 (7UL) /*!< Noise filter clock is HCLK divide by 128 \hideinitializer */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Clock Source Select Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PWM_CLKSRC_PWM_CLK (0UL) /*!< PWM Clock source selects to PWM0_CLK or PWM1_CLK \hideinitializer */ +#define PWM_CLKSRC_TIMER0 (1UL) /*!< PWM Clock source selects to TIMER0 overflow \hideinitializer */ +#define PWM_CLKSRC_TIMER1 (2UL) /*!< PWM Clock source selects to TIMER1 overflow \hideinitializer */ +#define PWM_CLKSRC_TIMER2 (3UL) /*!< PWM Clock source selects to TIMER2 overflow \hideinitializer */ +#define PWM_CLKSRC_TIMER3 (4UL) /*!< PWM Clock source selects to TIMER3 overflow \hideinitializer */ + + +/*@}*/ /* end of group PWM_EXPORTED_CONSTANTS */ + + +/** @addtogroup PWM_EXPORTED_FUNCTIONS PWM Exported Functions + @{ +*/ + +/** + * @brief This macro enable complementary mode + * @param[in] pwm The pointer of the specified PWM module + * @return None + * @details This macro is used to enable complementary mode of PWM module. + * \hideinitializer + */ +#define PWM_ENABLE_COMPLEMENTARY_MODE(pwm) ((pwm)->CTL1 = (pwm)->CTL1 | PWM_CTL1_OUTMODEn_Msk) + +/** + * @brief This macro disable complementary mode, and enable independent mode. + * @param[in] pwm The pointer of the specified PWM module + * @return None + * @details This macro is used to disable complementary mode of PWM module. + * \hideinitializer + */ +#define PWM_DISABLE_COMPLEMENTARY_MODE(pwm) ((pwm)->CTL1 = (pwm)->CTL1 & ~PWM_CTL1_OUTMODEn_Msk) + +/** + * @brief This macro enable group mode + * @param[in] pwm The pointer of the specified PWM module + * @return None + * @details This macro is used to enable group mode of PWM module. + * \hideinitializer + */ +#define PWM_ENABLE_GROUP_MODE(pwm) ((pwm)->CTL0 = (pwm)->CTL0 | PWM_CTL0_GROUPEN_Msk) + +/** + * @brief This macro disable group mode + * @param[in] pwm The pointer of the specified PWM module + * @return None + * @details This macro is used to disable group mode of PWM module. + * \hideinitializer + */ +#define PWM_DISABLE_GROUP_MODE(pwm) ((pwm)->CTL0 = (pwm)->CTL0 & ~PWM_CTL0_GROUPEN_Msk) + +/** + * @brief Enable timer synchronous mode of specified channel(s) + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel + * Bit 0 represents channel 0, bit 1 represents channel 1... + * @return None + * @details This macro is used to enable timer synchronous mode of specified channel(s). + * \hideinitializer + */ +#define PWM_ENABLE_TIMER_SYNC(pwm, u32ChannelMask) ((pwm)->SSCTL |= (u32ChannelMask)) + +/** + * @brief Disable timer synchronous mode of specified channel(s) + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel + * Bit 0 represents channel 0, bit 1 represents channel 1... + * @return None + * @details This macro is used to disable timer synchronous mode of specified channel(s). + * \hideinitializer + */ +#define PWM_DISABLE_TIMER_SYNC(pwm, u32ChannelMask) \ + do{ \ + int i;\ + for(i = 0; i < 6; i++) { \ + if((u32ChannelMask) & (1 << i)) \ + (pwm)->SSCTL &= ~(1UL << i); \ + } \ + }while(0) + +/** + * @brief This macro enable output inverter of specified channel(s) + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel + * Bit 0 represents channel 0, bit 1 represents channel 1... + * @return None + * @details This macro is used to enable output inverter of specified channel(s). + * \hideinitializer + */ +#define PWM_ENABLE_OUTPUT_INVERTER(pwm, u32ChannelMask) ((pwm)->POLCTL = (u32ChannelMask)) + +/** + * @brief This macro get captured rising data + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This macro is used to get captured rising data of specified channel. + * \hideinitializer + */ +#define PWM_GET_CAPTURE_RISING_DATA(pwm, u32ChannelNum) (*(__IO uint32_t *) (&((pwm)->RCAPDAT0) + 2 * (u32ChannelNum))) + +/** + * @brief This macro get captured falling data + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This macro is used to get captured falling data of specified channel. + * \hideinitializer + */ +#define PWM_GET_CAPTURE_FALLING_DATA(pwm, u32ChannelNum) (*(__IO uint32_t *) (&((pwm)->FCAPDAT0) + 2 * (u32ChannelNum))) + +/** + * @brief This macro mask output logic to high or low + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel + * Bit 0 represents channel 0, bit 1 represents channel 1... + * @param[in] u32LevelMask Output logic to high or low + * @return None + * @details This macro is used to mask output logic to high or low of specified channel(s). + * @note If u32ChannelMask parameter is 0, then mask function will be disabled. + * \hideinitializer + */ +#define PWM_MASK_OUTPUT(pwm, u32ChannelMask, u32LevelMask) \ + { \ + (pwm)->MSKEN = (u32ChannelMask); \ + (pwm)->MSK = (u32LevelMask); \ + } + +/** + * @brief This macro set the prescaler of the selected channel + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32Prescaler Clock prescaler of specified channel. Valid values are between 1 ~ 0xFFF + * @return None + * @details This macro is used to set the prescaler of specified channel. + * @note Every even channel N, and channel (N + 1) share a prescaler. So if channel 0 prescaler changed, + * channel 1 will also be affected. + * \hideinitializer + */ +#define PWM_SET_PRESCALER(pwm, u32ChannelNum, u32Prescaler) (*(__IO uint32_t *) (&((pwm)->CLKPSC0_1) + ((u32ChannelNum) >> 1)) = (u32Prescaler)) + +/** + * @brief This macro set the comparator of the selected channel + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32CMR Comparator of specified channel. Valid values are between 0~0xFFFF + * @return None + * @details This macro is used to set the comparator of specified channel. + * @note This new setting will take effect on next PWM period. + * \hideinitializer + */ +#define PWM_SET_CMR(pwm, u32ChannelNum, u32CMR) ((pwm)->CMPDAT[(u32ChannelNum)]= (u32CMR)) + +/** + * @brief This macro set the free trigger comparator of the selected channel + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32FTCMR Free trigger comparator of specified channel. Valid values are between 0~0xFFFF + * @return None + * @details This macro is used to set the free trigger comparator of specified channel. + * @note This new setting will take effect on next PWM period. + * \hideinitializer + */ +#define PWM_SET_FTCMR(pwm, u32ChannelNum, u32FTCMR) (*(__IO uint32_t *) (&((pwm)->FTCMPDAT0_1) + ((u32ChannelNum) >> 1)) = (u32FTCMR)) + +/** + * @brief This macro set the period of the selected channel + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32CNR Period of specified channel. Valid values are between 0~0xFFFF + * @return None + * @details This macro is used to set the period of specified channel. + * @note This new setting will take effect on next PWM period. + * @note PWM counter will stop if period length set to 0. + * \hideinitializer + */ +#define PWM_SET_CNR(pwm, u32ChannelNum, u32CNR) ((pwm)->PERIOD[(u32ChannelNum)] = (u32CNR)) + +/** + * @brief This macro set the PWM aligned type + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel + * Bit 0 represents channel 0, bit 1 represents channel 1... + * @param[in] u32AlignedType PWM aligned type, valid values are: + * - \ref PWM_EDGE_ALIGNED + * - \ref PWM_CENTER_ALIGNED + * @return None + * @details This macro is used to set the PWM aligned type of specified channel(s). + * \hideinitializer + */ +#define PWM_SET_ALIGNED_TYPE(pwm, u32ChannelMask, u32AlignedType) \ + do{ \ + int i; \ + for(i = 0; i < 6; i++) { \ + if((u32ChannelMask) & (1 << i)) \ + (pwm)->CTL1 = (((pwm)->CTL1 & ~(3UL << (2 * i))) | ((u32AlignedType) << ( 2 * i))); \ + } \ + }while(0) + +/** + * @brief Set load window of window loading mode for specified channel(s) + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel + * Bit 0 represents channel 0, bit 1 represents channel 1... + * @return None + * @details This macro is used to set load window of window loading mode for specified channel(s). + * \hideinitializer + */ +#define PWM_SET_LOAD_WINDOW(pwm, u32ChannelMask) ((pwm)->LOAD |= (u32ChannelMask)) + +/** + * @brief Trigger synchronous event from specified channel(s) + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelNum PWM channel number. Valid values are 0, 2, 4 + * Bit 0 represents channel 0, bit 1 represents channel 2 and bit 2 represents channel 4 + * @return None + * @details This macro is used to trigger synchronous event from specified channel(s). + * \hideinitializer + */ +#define PWM_TRIGGER_SYNC(pwm, u32ChannelNum) ((pwm)->SWSYNC |= (1 << ((u32ChannelNum) >> 1))) + +/** + * @brief Clear counter of specified channel(s) + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel + * Bit 0 represents channel 0, bit 1 represents channel 1... + * @return None + * @details This macro is used to clear counter of specified channel(s). + * \hideinitializer + */ +#define PWM_CLR_COUNTER(pwm, u32ChannelMask) ((pwm)->CNTCLR |= (u32ChannelMask)) + +/** + * @brief Set output level at zero, compare up, period(center) and compare down of specified channel(s) + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel + * Bit 0 represents channel 0, bit 1 represents channel 1... + * @param[in] u32ZeroLevel output level at zero point, valid values are: + * - \ref PWM_OUTPUT_NOTHING + * - \ref PWM_OUTPUT_LOW + * - \ref PWM_OUTPUT_HIGH + * - \ref PWM_OUTPUT_TOGGLE + * @param[in] u32CmpUpLevel output level at compare up point, valid values are: + * - \ref PWM_OUTPUT_NOTHING + * - \ref PWM_OUTPUT_LOW + * - \ref PWM_OUTPUT_HIGH + * - \ref PWM_OUTPUT_TOGGLE + * @param[in] u32PeriodLevel output level at period(center) point, valid values are: + * - \ref PWM_OUTPUT_NOTHING + * - \ref PWM_OUTPUT_LOW + * - \ref PWM_OUTPUT_HIGH + * - \ref PWM_OUTPUT_TOGGLE + * @param[in] u32CmpDownLevel output level at compare down point, valid values are: + * - \ref PWM_OUTPUT_NOTHING + * - \ref PWM_OUTPUT_LOW + * - \ref PWM_OUTPUT_HIGH + * - \ref PWM_OUTPUT_TOGGLE + * @return None + * @details This macro is used to Set output level at zero, compare up, period(center) and compare down of specified channel(s). + * \hideinitializer + */ +#define PWM_SET_OUTPUT_LEVEL(pwm, u32ChannelMask, u32ZeroLevel, u32CmpUpLevel, u32PeriodLevel, u32CmpDownLevel) \ + do{ \ + int i; \ + for(i = 0; i < 6; i++) { \ + if((u32ChannelMask) & (1 << i)) { \ + (pwm)->WGCTL0 = (((pwm)->WGCTL0 & ~(3UL << (2 * i))) | ((u32ZeroLevel) << (2 * i))); \ + (pwm)->WGCTL0 = (((pwm)->WGCTL0 & ~(3UL << (PWM_WGCTL0_PRDPCTLn_Pos + (2 * i)))) | ((u32PeriodLevel) << (PWM_WGCTL0_PRDPCTLn_Pos + (2 * i)))); \ + (pwm)->WGCTL1 = (((pwm)->WGCTL1 & ~(3UL << (2 * i))) | ((u32CmpUpLevel) << (2 * i))); \ + (pwm)->WGCTL1 = (((pwm)->WGCTL1 & ~(3UL << (PWM_WGCTL1_CMPDCTLn_Pos + (2 * i)))) | ((u32CmpDownLevel) << (PWM_WGCTL1_CMPDCTLn_Pos + (2 * i)))); \ + } \ + } \ + }while(0) + +/** + * @brief Trigger brake event from specified channel(s) + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel + * Bit 0 represents channel 0, bit 1 represents channel 2 and bit 2 represents channel 4 + * @param[in] u32BrakeType Type of brake trigger. PWM_FB_EDGE of this macro is only supported in M45xD/M45xC. + * - \ref PWM_FB_EDGE + * - \ref PWM_FB_LEVEL + * @return None + * @details This macro is used to trigger brake event from specified channel(s). + * \hideinitializer + */ +#define PWM_TRIGGER_BRAKE(pwm, u32ChannelMask, u32BrakeType) ((pwm)->SWBRK |= ((u32ChannelMask) << (u32BrakeType))) + +/** + * @brief Set Dead zone clock source + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32AfterPrescaler Dead zone clock source is from prescaler output. Valid values are TRUE (after prescaler) or FALSE (before prescaler). + * @return None + * @details This macro is used to set Dead zone clock source. Every two channels share the same setting. + * @note The write-protection function should be disabled before using this function. + * @note This function is only supported in M45xD/M45xC. + * \hideinitializer + */ +#define PWM_SET_DEADZONE_CLK_SRC(pwm, u32ChannelNum, u32AfterPrescaler) \ + (*(__IO uint32_t *) (&((pwm)->DTCTL0_1) + ((u32ChannelNum) >> 1)) = (*(__IO uint32_t *) (&((pwm)->DTCTL0_1) + ((u32ChannelNum) >> 1)) & ~PWM_DTCTL0_1_DTCKSEL_Msk) | \ + ((u32AfterPrescaler) << PWM_DTCTL0_1_DTCKSEL_Pos)) + +/*---------------------------------------------------------------------------------------------------------*/ +/* Define PWM functions prototype */ +/*---------------------------------------------------------------------------------------------------------*/ +uint32_t PWM_ConfigCaptureChannel(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32UnitTimeNsec, uint32_t u32CaptureEdge); +uint32_t PWM_ConfigOutputChannel(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Frequency, uint32_t u32DutyCycle); +void PWM_Start(PWM_T *pwm, uint32_t u32ChannelMask); +void PWM_Stop(PWM_T *pwm, uint32_t u32ChannelMask); +void PWM_ForceStop(PWM_T *pwm, uint32_t u32ChannelMask); +void PWM_EnableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition); +void PWM_DisableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_ClearADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition); +uint32_t PWM_GetADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_EnableDACTrigger(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition); +void PWM_DisableDACTrigger(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_ClearDACTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition); +uint32_t PWM_GetDACTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_EnableFaultBrake(PWM_T *pwm, uint32_t u32ChannelMask, uint32_t u32LevelMask, uint32_t u32BrakeSource); +void PWM_EnableCapture(PWM_T *pwm, uint32_t u32ChannelMask); +void PWM_DisableCapture(PWM_T *pwm, uint32_t u32ChannelMask); +void PWM_EnableOutput(PWM_T *pwm, uint32_t u32ChannelMask); +void PWM_DisableOutput(PWM_T *pwm, uint32_t u32ChannelMask); +void PWM_EnablePDMA(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32RisingFirst, uint32_t u32Mode); +void PWM_DisablePDMA(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_EnableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration); +void PWM_DisableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_EnableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge); +void PWM_DisableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge); +void PWM_ClearCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge); +uint32_t PWM_GetCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_EnableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType); +void PWM_DisableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_ClearDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum); +uint32_t PWM_GetDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_EnableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource); +void PWM_DisableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource); +void PWM_ClearFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource); +uint32_t PWM_GetFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource); +void PWM_EnablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType); +void PWM_DisablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_ClearPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum); +uint32_t PWM_GetPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_EnableZeroInt(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_DisableZeroInt(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_ClearZeroIntFlag(PWM_T *pwm, uint32_t u32ChannelNum); +uint32_t PWM_GetZeroIntFlag(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_EnableAcc(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntFlagCnt, uint32_t u32IntAccSrc); +void PWM_DisableAcc(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_EnableAccInt(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_DisableAccInt(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_ClearAccInt(PWM_T *pwm, uint32_t u32ChannelNum); +uint32_t PWM_GetAccInt(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_ClearFTDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum); +uint32_t PWM_GetFTDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_EnableLoadMode(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32LoadMode); +void PWM_DisableLoadMode(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32LoadMode); +void PWM_ConfigSyncPhase(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32SyncSrc, uint32_t u32Direction, uint32_t u32StartPhase); +void PWM_EnableSyncPhase(PWM_T *pwm, uint32_t u32ChannelMask); +void PWM_DisableSyncPhase(PWM_T *pwm, uint32_t u32ChannelMask); +void PWM_EnableSyncNoiseFilter(PWM_T *pwm, uint32_t u32ClkCnt, uint32_t u32ClkDivSel); +void PWM_DisableSyncNoiseFilter(PWM_T *pwm); +void PWM_EnableSyncPinInverse(PWM_T *pwm); +void PWM_DisableSyncPinInverse(PWM_T *pwm); +void PWM_SetClockSource(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32ClkSrcSel); +void PWM_EnableBrakeNoiseFilter(PWM_T *pwm, uint32_t u32BrakePinNum, uint32_t u32ClkCnt, uint32_t u32ClkDivSel); +void PWM_DisableBrakeNoiseFilter(PWM_T *pwm, uint32_t u32BrakePinNum); +void PWM_EnableBrakePinInverse(PWM_T *pwm, uint32_t u32BrakePinNum); +void PWM_DisableBrakePinInverse(PWM_T *pwm, uint32_t u32BrakePinNum); +void PWM_SetBrakePinSource(PWM_T *pwm, uint32_t u32BrakePinNum, uint32_t u32SelAnotherModule); +uint32_t PWM_GetWrapAroundFlag(PWM_T *pwm, uint32_t u32ChannelNum); +void PWM_ClearWrapAroundFlag(PWM_T *pwm, uint32_t u32ChannelNum); + + +/*@}*/ /* end of group PWM_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group PWM_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__PWM_H__ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/rtc.h b/StdDriver/inc/rtc.h new file mode 100644 index 0000000..fd0c442 --- /dev/null +++ b/StdDriver/inc/rtc.h @@ -0,0 +1,272 @@ +/**************************************************************************//** + * @file rtc.h + * @version V3.00 + * $Revision: 10 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series RTC driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __RTC_H__ +#define __RTC_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup RTC_Driver RTC Driver + @{ +*/ + +/** @addtogroup RTC_EXPORTED_CONSTANTS RTC Exported Constants + @{ +*/ +/*---------------------------------------------------------------------------------------------------------*/ +/* RTC Initial Keyword Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define RTC_INIT_KEY 0xA5EB1357UL /*!< RTC Initiation Key to make RTC leaving reset state */ +#define RTC_WRITE_KEY 0x0000A965UL /*!< RTC Register Access Enable Key to enable RTC read/write accessible and kept 1024 RTC clock */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* RTC Time Attribute Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define RTC_CLOCK_12 0 /*!< RTC as 12-hour time scale with AM and PM indication */ +#define RTC_CLOCK_24 1 /*!< RTC as 24-hour time scale */ +#define RTC_AM 1 /*!< RTC as AM indication */ +#define RTC_PM 2 /*!< RTC as PM indication */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* RTC Tick Period Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define RTC_TICK_1_SEC 0x0UL /*!< RTC time tick period is 1 second */ +#define RTC_TICK_1_2_SEC 0x1UL /*!< RTC time tick period is 1/2 second */ +#define RTC_TICK_1_4_SEC 0x2UL /*!< RTC time tick period is 1/4 second */ +#define RTC_TICK_1_8_SEC 0x3UL /*!< RTC time tick period is 1/8 second */ +#define RTC_TICK_1_16_SEC 0x4UL /*!< RTC time tick period is 1/16 second */ +#define RTC_TICK_1_32_SEC 0x5UL /*!< RTC time tick period is 1/32 second */ +#define RTC_TICK_1_64_SEC 0x6UL /*!< RTC time tick period is 1/64 second */ +#define RTC_TICK_1_128_SEC 0x7UL /*!< RTC time tick period is 1/128 second */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* RTC Day of Week Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define RTC_SUNDAY 0x0UL /*!< Day of the Week is Sunday */ +#define RTC_MONDAY 0x1UL /*!< Day of the Week is Monday */ +#define RTC_TUESDAY 0x2UL /*!< Day of the Week is Tuesday */ +#define RTC_WEDNESDAY 0x3UL /*!< Day of the Week is Wednesday */ +#define RTC_THURSDAY 0x4UL /*!< Day of the Week is Thursday */ +#define RTC_FRIDAY 0x5UL /*!< Day of the Week is Friday */ +#define RTC_SATURDAY 0x6UL /*!< Day of the Week is Saturday */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* RTC Snooper Detection Mode Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define RTC_SNOOPER_LOW_LEVEL 0x0UL /*!< Snooper pin detected is low-level trigger */ +#define RTC_SNOOPER_HIGH_LEVEL 0x2UL /*!< Snooper pin detected is high-level trigger */ +#define RTC_SNOOPER_FALLING_EDGE 0x8UL /*!< Snooper pin detected is falling-edge trigger */ +#define RTC_SNOOPER_RISING_EDGE 0xAUL /*!< Snooper pin detected is rising-edge trigger */ +#define RTC_SNOOPER_DETECT_Msk 0xAUL /*!< Snooper pin detected mask bits */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* RTC Miscellaneous Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define RTC_WAIT_COUNT 0xFFFFFFFF /*!< Initial Time-out Value */ +#define RTC_YEAR2000 2000 /*!< RTC Reference for compute year data */ +#define RTC_FCR_REFERENCE 32761 /*!< RTC Reference for frequency compensation */ + +/*@}*/ /* end of group RTC_EXPORTED_CONSTANTS */ + + +/** @addtogroup RTC_EXPORTED_STRUCTS RTC Exported Structs + @{ +*/ +/** + * @details RTC define Time Data Struct + */ +typedef struct +{ + uint32_t u32Year; /*!< Year value */ + uint32_t u32Month; /*!< Month value */ + uint32_t u32Day; /*!< Day value */ + uint32_t u32DayOfWeek; /*!< Day of week value */ + uint32_t u32Hour; /*!< Hour value */ + uint32_t u32Minute; /*!< Minute value */ + uint32_t u32Second; /*!< Second value */ + uint32_t u32TimeScale; /*!< 12-Hour, 24-Hour */ + uint32_t u32AmPm; /*!< Only Time Scale select 12-hr used */ +} S_RTC_TIME_DATA_T; + +/*@}*/ /* end of group RTC_EXPORTED_STRUCTS */ + + +/** @addtogroup RTC_EXPORTED_FUNCTIONS RTC Exported Functions + @{ +*/ + +/** + * @brief Indicate is Leap Year or not + * + * @param None + * + * @retval 0 This year is not a leap year + * @retval 1 This year is a leap year + * + * @details According to current date, return this year is leap year or not. + */ +#define RTC_IS_LEAP_YEAR() (RTC->LEAPYEAR & RTC_LEAPYEAR_LEAPYEAR_Msk ? 1:0) + +/** + * @brief Clear RTC Alarm Interrupt Flag + * + * @param None + * + * @return None + * + * @details This macro is used to clear RTC alarm interrupt flag. + */ +#define RTC_CLEAR_ALARM_INT_FLAG() (RTC->INTSTS = (RTC->INTSTS & ~(RTC_INTSTS_TICKIF_Msk | RTC_INTSTS_SNPDIF_Msk)) | RTC_INTSTS_ALMIF_Msk) + +/** + * @brief Clear RTC Tick Interrupt Flag + * + * @param None + * + * @return None + * + * @details This macro is used to clear RTC tick interrupt flag. + */ +#define RTC_CLEAR_TICK_INT_FLAG() (RTC->INTSTS = (RTC->INTSTS & ~(RTC_INTSTS_ALMIF_Msk | RTC_INTSTS_SNPDIF_Msk)) | RTC_INTSTS_TICKIF_Msk) + +/** + * @brief Clear RTC Snooper Interrupt Flag + * + * @param None + * + * @return None + * + * @details This macro is used to clear RTC snooper pin interrupt flag. + */ +#define RTC_CLEAR_SNOOPER_INT_FLAG() (RTC->INTSTS = (RTC->INTSTS & ~(RTC_INTSTS_ALMIF_Msk | RTC_INTSTS_TICKIF_Msk)) | RTC_INTSTS_SNPDIF_Msk) + +/** + * @brief Get RTC Alarm Interrupt Flag + * + * @param None + * + * @retval 0 RTC alarm interrupt did not occur + * @retval 1 RTC alarm interrupt occurred + * + * @details This macro indicates RTC alarm interrupt occurred or not. + */ +#define RTC_GET_ALARM_INT_FLAG() ((RTC->INTSTS & RTC_INTSTS_ALMIF_Msk)? 1:0) + +/** + * @brief Get RTC Time Tick Interrupt Flag + * + * @param None + * + * @retval 0 RTC time tick interrupt did not occur + * @retval 1 RTC time tick interrupt occurred + * + * @details This macro indicates RTC time tick interrupt occurred or not. + */ +#define RTC_GET_TICK_INT_FLAG() ((RTC->INTSTS & RTC_INTSTS_TICKIF_Msk)? 1:0) + +/** + * @brief Get RTC Snooper Interrupt Flag + * + * @param None + * + * @retval 0 RTC snooper pin interrupt did not occur + * @retval 1 RTC snooper pin interrupt occurred + * + * @details This macro indicates RTC snooper pin interrupt occurred or not. + */ +#define RTC_GET_SNPPOER_INT_FLAG() ((RTC->INTSTS & RTC_INTSTS_SNPDIF_Msk)? 1:0) + +/** + * @brief Read Spare Register + * + * @param[in] u32RegNum The spare register number, 0~19. + * + * @return Spare register content + * + * @details Read the specify spare register content. + * @note The returned value is valid only when SPRRDY(SPRCTL[7] SPR Register Ready) bit is set. \n + * And its controlled by RTC Access Enable Register. + */ +#define RTC_READ_SPARE_REGISTER(u32RegNum) (RTC->SPR[(u32RegNum)]) + +/** + * @brief Write Spare Register + * + * @param[in] u32RegNum The spare register number, 0~19. + * @param[in] u32RegValue The spare register value. + * + * @return None + * + * @details Write specify data to spare register. + * @note This macro is effect only when SPRRDY(SPRCTL[7] SPR Register Ready) bit is set. \n + * And its controlled by RTC Access Enable Register(RTC_RWEN). + */ +#define RTC_WRITE_SPARE_REGISTER(u32RegNum, u32RegValue) (RTC->SPR[(u32RegNum)] = (u32RegValue)) + +/** + * @brief Wait RTC Access Enable + * + * @param None + * + * @return None + * + * @details This function is used to enable the maximum RTC read/write accessible time. + */ +static __INLINE void RTC_WaitAccessEnable(void) +{ + /* To wait RWENF bit is cleared and enable RWENF bit (Access Enable bit) again */ + while((RTC->RWEN & RTC_RWEN_RWENF_Msk) == RTC_RWEN_RWENF_Msk); + RTC->RWEN = RTC_WRITE_KEY; + + /* To wait RWENF bit is set and user can access the protected-register of RTC from now on */ + while((RTC->RWEN & RTC_RWEN_RWENF_Msk) == 0x0); +} + +void RTC_Open(S_RTC_TIME_DATA_T *sPt); +void RTC_Close(void); +void RTC_32KCalibration(int32_t i32FrequencyX100); +void RTC_GetDateAndTime(S_RTC_TIME_DATA_T *sPt); +void RTC_GetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt); +void RTC_SetDateAndTime(S_RTC_TIME_DATA_T *sPt); +void RTC_SetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt); +void RTC_SetDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day, uint32_t u32DayOfWeek); +void RTC_SetTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm); +void RTC_SetAlarmDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day); +void RTC_SetAlarmTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm); +uint32_t RTC_GetDayOfWeek(void); +void RTC_SetTickPeriod(uint32_t u32TickSelection); +void RTC_EnableInt(uint32_t u32IntFlagMask); +void RTC_DisableInt(uint32_t u32IntFlagMask); +void RTC_EnableSpareAccess(void); +void RTC_DisableSpareRegister(void); +void RTC_EnableSnooperDetection(uint32_t u32PinCondition); +void RTC_DisableSnooperDetection(void); + +/*@}*/ /* end of group RTC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group RTC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__RTC_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/sc.h b/StdDriver/inc/sc.h new file mode 100644 index 0000000..295e872 --- /dev/null +++ b/StdDriver/inc/sc.h @@ -0,0 +1,269 @@ +/**************************************************************************//** + * @file sc.h + * @version V3.00 + * $Revision: 13 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series Smartcard (SC) driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __SC_H__ +#define __SC_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup SC_Driver SC Driver + @{ +*/ + +/** @addtogroup SC_EXPORTED_CONSTANTS SC Exported Constants + @{ +*/ +#define SC_INTERFACE_NUM 1 /*!< Smartcard interface numbers */ /* M451 series has only one SC interface */ +#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_TMRCTL0_OPMODE_Pos) /*!INTEN |= (u32Mask)) + +/** + * @brief Disable smartcard interrupt. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32Mask Interrupt mask to be disabled. A combination of + * - \ref SC_INTEN_ACERRIEN_Msk + * - \ref SC_INTEN_RXTOIF_Msk + * - \ref SC_INTEN_INITIEN_Msk + * - \ref SC_INTEN_CDIEN_Msk + * - \ref SC_INTEN_BGTIEN_Msk + * - \ref SC_INTEN_TMR2IEN_Msk + * - \ref SC_INTEN_TMR1IEN_Msk + * - \ref SC_INTEN_TMR0IEN_Msk + * - \ref SC_INTEN_TERRIEN_Msk + * - \ref SC_INTEN_TBEIEN_Msk + * - \ref SC_INTEN_RDAIEN_Msk + * @return None + * @details The macro is used to disable Auto-convention error interrupt, Receiver buffer time-out interrupt, Initial end interrupt, + * Card detect interrupt, Block guard time interrupt, Timer2 interrupt, Timer1 interrupt, Timer0 interrupt, + * Transfer error interrupt, Transmit buffer empty interrupt or Receive data reach trigger level interrupt. + * \hideinitializer + */ +#define SC_DISABLE_INT(sc, u32Mask) ((sc)->INTEN &= ~(u32Mask)) + +/** + * @brief This macro set VCC pin state of smartcard interface. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32State Pin state of VCC pin, valid parameters are: + * \ref SC_PIN_STATE_HIGH :Smartcard pin status high. + * \ref SC_PIN_STATE_LOW :Smartcard pin status low. + * @return None + * @details User can set PWREN (SC_PINCTL[0]) and PWRINV (SC_PINCTL[11])to decide SC_PWR pin is in high or low level. + * \hideinitializer + */ +#define SC_SET_VCC_PIN(sc, u32State) \ + do {\ + while((sc)->PINCTL & SC_PINCTL_SYNC_Msk);\ + if(u32State)\ + (sc)->PINCTL |= SC_PINCTL_PWREN_Msk;\ + else\ + (sc)->PINCTL &= ~SC_PINCTL_PWREN_Msk;\ + }while(0) + + +/** + * @brief Set CLK output status. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32OnOff Clock on or off for selected smartcard module, valid values are: + * \ref SC_CLK_ON :Smartcard clock on. + * \ref SC_CLK_OFF :Smartcard clock off. + * @return None + * @details User can set CLKKEEP (SC_PINCTL[6]) to decide SC_CLK pin always keeps free running or not. + * \hideinitializer + */ +#define SC_SET_CLK_PIN(sc, u32OnOff)\ + do {\ + while((sc)->PINCTL & SC_PINCTL_SYNC_Msk);\ + if(u32OnOff)\ + (sc)->PINCTL |= SC_PINCTL_CLKKEEP_Msk;\ + else\ + (sc)->PINCTL &= ~(SC_PINCTL_CLKKEEP_Msk);\ + }while(0) + +/** + * @brief Set I/O pin state. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32State Pin state of I/O pin, valid parameters are: + * \ref SC_PIN_STATE_HIGH :Smartcard pin status high. + * \ref SC_PIN_STATE_LOW :Smartcard pin status low. + * @return None + * @details User can set SCDOUT(SC_PINCTL[9]) to decide SCDOUT pin to high or low. + * \hideinitializer + */ +#define SC_SET_IO_PIN(sc, u32State)\ + do {\ + while((sc)->PINCTL & SC_PINCTL_SYNC_Msk);\ + if(u32State)\ + (sc)->PINCTL |= SC_PINCTL_SCDOUT_Msk;\ + else\ + (sc)->PINCTL &= ~SC_PINCTL_SCDOUT_Msk;\ + }while(0) + +/** + * @brief Set RST pin state. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32State Pin state of RST pin, valid parameters are: + * \ref SC_PIN_STATE_HIGH :Smartcard pin status high. + * \ref SC_PIN_STATE_LOW :Smartcard pin status low. + * @return None + * @details User can set SCRST(SC_PINCTL[1]) to decide SCRST pin to high or low. + * \hideinitializer + */ +#define SC_SET_RST_PIN(sc, u32State)\ + do {\ + while((sc)->PINCTL & SC_PINCTL_SYNC_Msk);\ + if(u32State)\ + (sc)->PINCTL |= SC_PINCTL_SCRST_Msk;\ + else\ + (sc)->PINCTL &= ~SC_PINCTL_SCRST_Msk;\ + }while(0) + +/** + * @brief Read one byte from smartcard module receive FIFO. + * @param[in] sc The pointer of smartcard module. + * @return One byte read from receive FIFO. + * @details By reading DAT register, the SC will return an 8-bit received data. + * \hideinitializer + */ +#define SC_READ(sc) ((char)((sc)->DAT)) + +/** + * @brief Write one byte to smartcard module transmit FIFO. + * @param[in] sc The pointer of smartcard module. + * @param[in] u8Data Data to write to transmit FIFO. + * @return None + * @details By writing data to DAT register, the SC will send out an 8-bit data. + * \hideinitializer + */ +#define SC_WRITE(sc, u8Data) ((sc)->DAT = (u8Data)) + +/** + * @brief This macro set smartcard stop bit length. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32Len Stop bit length, ether 1 or 2. + * @return None + * @details Stop bit length must be 1 for T = 1 protocol and 2 for T = 0 protocol. + * \hideinitializer + */ +#define SC_SET_STOP_BIT_LEN(sc, u32Len) ((sc)->CTL = ((sc)->CTL & ~SC_CTL_NSB_Msk) | ((u32Len) == 1 ? SC_CTL_NSB_Msk : 0)) + +/** + * @brief Enable/Disable Tx error retry, and set Tx error retry count. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32Count The number of times of Tx error retry count, between 0~8. 0 means disable Tx error retry. + * @return None + * @details This macro enable/disable transmitter retry function when parity error has occurred, and set error retry count. + */ +__STATIC_INLINE void SC_SetTxRetry(SC_T *sc, uint32_t u32Count) +{ + while((sc)->CTL & SC_CTL_SYNC_Msk); + if(u32Count == 0) { // disable Tx error retry + (sc)->CTL &= ~(SC_CTL_TXRTY_Msk | SC_CTL_TXRTYEN_Msk); + } else { + (sc)->CTL = ((sc)->CTL & ~SC_CTL_TXRTY_Msk) | ((u32Count - 1) << SC_CTL_TXRTY_Pos) | SC_CTL_TXRTYEN_Msk; + } +} + +/** + * @brief Enable/Disable Rx error retry, and set Rx error retry count. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32Count The number of times of Rx error retry count, between 0~8. 0 means disable Rx error retry. + * @return None + * @details This macro enable/disable receiver retry function when parity error has occurred, and set error retry count. + */ +__STATIC_INLINE void SC_SetRxRetry(SC_T *sc, uint32_t u32Count) +{ + while((sc)->CTL & SC_CTL_SYNC_Msk); + if(u32Count == 0) { // disable Rx error retry + (sc)->CTL &= ~(SC_CTL_RXRTY_Msk | SC_CTL_RXRTYEN_Msk); + } else { + (sc)->CTL = ((sc)->CTL & ~SC_CTL_RXRTY_Msk) | ((u32Count - 1) << SC_CTL_RXRTY_Pos) | SC_CTL_RXRTYEN_Msk; + } +} + + +uint32_t SC_IsCardInserted(SC_T *sc); +void SC_ClearFIFO(SC_T *sc); +void SC_Close(SC_T *sc); +void SC_Open(SC_T *sc, uint32_t u32CardDet, uint32_t u32PWR); +void SC_ResetReader(SC_T *sc); +void SC_SetBlockGuardTime(SC_T *sc, uint32_t u32BGT); +void SC_SetCharGuardTime(SC_T *sc, uint32_t u32CGT); +void SC_StopAllTimer(SC_T *sc); +void SC_StartTimer(SC_T *sc, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount); +void SC_StopTimer(SC_T *sc, uint32_t u32TimerNum); + + +/*@}*/ /* end of group SC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group SC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__SC_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ + diff --git a/StdDriver/inc/scuart.h b/StdDriver/inc/scuart.h new file mode 100644 index 0000000..0ab13ab --- /dev/null +++ b/StdDriver/inc/scuart.h @@ -0,0 +1,279 @@ +/**************************************************************************//** + * @file sc.h + * @version V3.00 + * $Revision: 7 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series Smartcard UART mode (SCUART) driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __SCUART_H__ +#define __SCUART_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup SCUART_Driver SCUART Driver + @{ +*/ + +/** @addtogroup SCUART_EXPORTED_CONSTANTS SCUART Exported Constants + @{ +*/ +#define SCUART_CHAR_LEN_5 (0x3ul << SC_UARTCTL_WLS_Pos) /*!< Set SCUART word length to 5 bits */ +#define SCUART_CHAR_LEN_6 (0x2ul << SC_UARTCTL_WLS_Pos) /*!< Set SCUART word length to 6 bits */ +#define SCUART_CHAR_LEN_7 (0x1ul << SC_UARTCTL_WLS_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_UARTCTL_PBOFF_Msk) /*!< Set SCUART transfer with no parity */ +#define SCUART_PARITY_ODD (SC_UARTCTL_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_NSB_Msk) /*!< Set SCUART transfer with one stop bit */ +#define SCUART_STOP_BIT_2 (0) /*!< Set SCUART transfer with two stop bits */ + + +/*@}*/ /* end of group SCUART_EXPORTED_CONSTANTS */ + + +/** @addtogroup SCUART_EXPORTED_FUNCTIONS SCUART Exported Functions + @{ +*/ + +/* TX Macros */ +/** + * @brief Write Data to Tx data register. + * @param[in] sc The pointer of smartcard module. + * @param[in] u8Data Data byte to transmit. + * @return None + * @details By writing data to DAT register, the SC will send out an 8-bit data. + * \hideinitializer + */ +#define SCUART_WRITE(sc, u8Data) ((sc)-> DAT = (u8Data)) + +/** + * @brief Get TX FIFO empty flag status from register. + * @param[in] sc The pointer of smartcard module. + * @return Transmit FIFO empty status. + * @retval 0 Transmit FIFO is not empty. + * @retval SC_STATUS_TXEMPTY_Msk Transmit FIFO is empty. + * @details When the last byte of TX buffer has been transferred to Transmitter Shift Register, hardware sets TXEMPTY bit (SC_STATUS[9]) high. + * It will be cleared when writing data into DAT (SC_DAT[7:0]). + * \hideinitializer + */ +#define SCUART_GET_TX_EMPTY(sc) ((sc)->STATUS & SC_STATUS_TXEMPTY_Msk) + +/** + * @brief Get TX FIFO full flag status from register. + * @param[in] sc The pointer of smartcard module. + * @retval 0 Transmit FIFO is not full. + * @retval SC_STATUS_TXFULL_Msk Transmit FIFO is full. + * @details TXFULL(SC_STATUS[10]) is set when TX pointer is equal to 4, otherwise is cleared by hardware. + * \hideinitializer + */ +#define SCUART_GET_TX_FULL(sc) ((sc)->STATUS & SC_STATUS_TXFULL_Msk) + +/** + * @brief Wait specified smartcard port transmission complete. + * @param[in] sc The pointer of smartcard module. + * @return None + * @details TXACT (SC_STATUS[31]) is cleared automatically when TX transfer is finished or the last byte transmission has completed. + * @note This macro blocks until transmit complete. + * \hideinitializer + */ +#define SCUART_WAIT_TX_EMPTY(sc) while((sc)->STATUS & SC_STATUS_TXACT_Msk) + +/** + * @brief Check specified smartcard port transmit FIFO is full or not. + * @param[in] sc The pointer of smartcard module. + * @retval 0 Transmit FIFO is not full. + * @retval 1 Transmit FIFO is full. + * @details TXFULL(SC_STATUS[10]) indicates TX buffer full or not. + * This is set when TX pointer is equal to 4, otherwise is cleared by hardware. + * \hideinitializer + */ +#define SCUART_IS_TX_FULL(sc) ((sc)->STATUS & SC_STATUS_TXFULL_Msk ? 1 : 0) + +/** + * @brief Check specified smartcard port transmission is over. + * @param[in] sc The pointer of smartcard module. + * @retval 0 Transmit is not complete. + * @retval 1 Transmit complete. + * @details TXACT (SC_STATUS[31]) is set by hardware when TX transfer is in active and the STOP bit of the last byte has been transmitted. + * \hideinitializer + */ +#define SCUART_IS_TX_EMPTY(sc) ((sc)->STATUS & SC_STATUS_TXACT_Msk ? 0 : 1) + + +/* RX Macros */ + +/** + * @brief Read Rx data register. + * @param[in] sc The pointer of smartcard module. + * @return The oldest data byte in RX FIFO. + * @details By reading DAT register, the SC will return an 8-bit received data. + * \hideinitializer + */ +#define SCUART_READ(sc) ((sc)->DAT) + +/** + * @brief Get RX FIFO empty flag status from register. + * @param[in] sc The pointer of smartcard module. + * @retval 0 Receive FIFO is not empty. + * @retval SC_STATUS_RXEMPTY_Msk Receive FIFO is empty. + * @details When the last byte of Rx buffer has been read by CPU, hardware sets RXEMPTY(SC_STATUS[1]) high. + * It will be cleared when SC receives any new data. + * \hideinitializer + */ +#define SCUART_GET_RX_EMPTY(sc) ((sc)->STATUS & SC_STATUS_RXEMPTY_Msk) + + +/** + * @brief Get RX FIFO full flag status from register. + * @param[in] sc The pointer of smartcard module. + * @retval 0 Receive FIFO is not full. + * @retval SC_STATUS_TXFULL_Msk Receive FIFO is full. + * @details RXFULLF(SC_STATUS[2]) is set when RX pointer is equal to 4, otherwise it is cleared by hardware. + * \hideinitializer + */ +#define SCUART_GET_RX_FULL(sc) ((sc)->STATUS & SC_STATUS_RXFULL_Msk) + +/** + * @brief Check if receive data number in FIFO reach FIFO trigger level or not. + * @param[in] sc The pointer of smartcard module. + * @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. + * @details RDAIF(SC_INTSTS[0]) is used for received data reaching trigger level RXTRGLV (SC_CTL[7:6]) interrupt status flag. + * @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)->INTSTS & SC_INTSTS_RDAIF_Msk ? 1 : 0) + +/** + * @brief Check specified smartcard port receive FIFO is full or not. + * @param[in] sc The pointer of smartcard module. + * @retval 0 Receive FIFO is not full. + * @retval 1 Receive FIFO is full. + * @details RXFULLF(SC_STATUS[2]) is set when RX pointer is equal to 4, otherwise it is cleared by hardware. + * \hideinitializer + */ +#define SCUART_IS_RX_FULL(sc) ((sc)->STATUS & SC_STATUS_RXFULL_Msk ? 1 : 0) + +/* Interrupt Macros */ + +/** + * @brief Enable specified interrupts. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32Mask Interrupt masks to enable, a combination of following bits. + * - \ref SC_INTEN_RXTOIF_Msk + * - \ref SC_INTEN_TERRIEN_Msk + * - \ref SC_INTEN_TBEIEN_Msk + * - \ref SC_INTEN_RDAIEN_Msk + * @return None + * @details The macro is used to enable receiver buffer time-out interrupt, transfer error interrupt, + * transmit buffer empty interrupt or receive data reach trigger level interrupt. + * \hideinitializer + */ +#define SCUART_ENABLE_INT(sc, u32Mask) ((sc)->INTEN |= (u32Mask)) + +/** + * @brief Disable specified interrupts. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32Mask Interrupt masks to disable, a combination of following bits. + * - \ref SC_INTEN_RXTOIF_Msk + * - \ref SC_INTEN_TERRIEN_Msk + * - \ref SC_INTEN_TBEIEN_Msk + * - \ref SC_INTEN_RDAIEN_Msk + * @return None + * @details The macro is used to disable receiver buffer time-out interrupt, transfer error interrupt, + * transmit buffer empty interrupt or receive data reach trigger level interrupt. + * \hideinitializer + */ +#define SCUART_DISABLE_INT(sc, u32Mask) ((sc)->INTEN &= ~(u32Mask)) + +/** + * @brief Get specified interrupt flag/status. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32Type Interrupt flag/status to check, could be one of following value: + * - \ref SC_INTSTS_RBTOIF_Msk + * - \ref SC_INTSTS_TERRIF_Msk + * - \ref SC_INTSTS_TBEIF_Msk + * - \ref SC_INTSTS_RDAIF_Msk + * @return The status of specified interrupt. + * @retval 0 Specified interrupt does not happened. + * @retval 1 Specified interrupt happened. + * @details The macro is used to get receiver buffer time-out interrupt status, transfer error interrupt status, + * transmit buffer empty interrupt status or receive data reach interrupt status. + * \hideinitializer + */ +#define SCUART_GET_INT_FLAG(sc, u32Type) ((sc)->INTSTS & (u32Type) ? 1 : 0) + +/** + * @brief Clear specified interrupt flag/status. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32Type Interrupt flag/status to clear, could be the combination of following values: + * - \ref SC_INTSTS_RBTOIF_Msk + * - \ref SC_INTSTS_TERRIF_Msk + * - \ref SC_INTSTS_TBEIF_Msk + * @return None + * @details The macro is used to clear receiver buffer time-out interrupt flag, transfer error interrupt flag or + * transmit buffer empty interrupt flag. + * \hideinitializer + */ +#define SCUART_CLR_INT_FLAG(sc, u32Type) ((sc)->INTSTS = (u32Type)) + +/** + * @brief Get receive error flag/status. + * @param[in] sc The pointer of smartcard module. + * @return Current receive error status, could one of following errors: + * @retval SC_STATUS_PEF_Msk Parity error. + * @retval SC_STATUS_FEF_Msk Frame error. + * @retval SC_STATUS_BEF_Msk Break error. + * @details The macro is used to get receiver parity error status, receiver frame error status or + * receiver break error status. + * \hideinitializer + */ +#define SCUART_GET_ERR_FLAG(sc) ((sc)->STATUS & (SC_STATUS_PEF_Msk | SC_STATUS_FEF_Msk | SC_STATUS_BEF_Msk)) + +/** + * @brief Clear specified receive error flag/status. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32Mask Receive error flag/status to clear, combination following values: + * - \ref SC_STATUS_PEF_Msk + * - \ref SC_STATUS_FEF_Msk + * - \ref SC_STATUS_BEF_Msk + * @return None + * @details The macro is used to clear receiver parity error flag, receiver frame error flag or + * receiver break error flag. + * \hideinitializer + */ +#define SCUART_CLR_ERR_FLAG(sc, u32Mask) ((sc)->STATUS = (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 SCUART_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group SCUART_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__SCUART_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/spi.h b/StdDriver/inc/spi.h new file mode 100644 index 0000000..02d2469 --- /dev/null +++ b/StdDriver/inc/spi.h @@ -0,0 +1,630 @@ +/****************************************************************************** + * @file spi.h + * @version V0.10 + * $Revision: 17 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series SPI driver header file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#ifndef __SPI_H__ +#define __SPI_H__ + +/*---------------------------------------------------------------------------------------------------------*/ +/* Include related headers */ +/*---------------------------------------------------------------------------------------------------------*/ +#include "M451Series.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup SPI_Driver SPI Driver + @{ +*/ + +/** @addtogroup SPI_EXPORTED_CONSTANTS SPI Exported Constants + @{ +*/ + +#define SPI_MODE_0 (SPI_CTL_TXNEG_Msk) /*!< CLKPOL=0; RXNEG=0; TXNEG=1 */ +#define SPI_MODE_1 (SPI_CTL_RXNEG_Msk) /*!< CLKPOL=0; RXNEG=1; TXNEG=0 */ +#define SPI_MODE_2 (SPI_CTL_CLKPOL_Msk | SPI_CTL_RXNEG_Msk) /*!< CLKPOL=1; RXNEG=1; TXNEG=0 */ +#define SPI_MODE_3 (SPI_CTL_CLKPOL_Msk | SPI_CTL_TXNEG_Msk) /*!< CLKPOL=1; RXNEG=0; TXNEG=1 */ + +#define SPI_SLAVE (SPI_CTL_SLAVE_Msk) /*!< Set as slave */ +#define SPI_MASTER (0x0) /*!< Set as master */ + +#define SPI_SS (SPI_SSCTL_SS_Msk) /*!< Set SS */ +#define SPI_SS_ACTIVE_HIGH (SPI_SSCTL_SSACTPOL_Msk) /*!< SS active high */ +#define SPI_SS_ACTIVE_LOW (0x0) /*!< SS active low */ + +/* SPI Interrupt Mask */ +#define SPI_UNIT_INT_MASK (0x001) /*!< Unit transfer interrupt mask */ +#define SPI_SSACT_INT_MASK (0x002) /*!< Slave selection signal active interrupt mask */ +#define SPI_SSINACT_INT_MASK (0x004) /*!< Slave selection signal inactive interrupt mask */ +#define SPI_SLVUR_INT_MASK (0x008) /*!< Slave under run interrupt mask */ +#define SPI_SLVBE_INT_MASK (0x010) /*!< Slave bit count error interrupt mask */ +#define SPI_SLVTO_INT_MASK (0x020) /*!< Slave time-out interrupt mask */ +#define SPI_TXUF_INT_MASK (0x040) /*!< Slave TX underflow interrupt mask */ +#define SPI_FIFO_TXTH_INT_MASK (0x080) /*!< FIFO TX threshold interrupt mask */ +#define SPI_FIFO_RXTH_INT_MASK (0x100) /*!< FIFO RX threshold interrupt mask */ +#define SPI_FIFO_RXOV_INT_MASK (0x200) /*!< FIFO RX overrun interrupt mask */ +#define SPI_FIFO_RXTO_INT_MASK (0x400) /*!< FIFO RX time-out interrupt mask */ + +/* SPI Status Mask */ +#define SPI_BUSY_MASK (0x01) /*!< Busy status mask */ +#define SPI_RX_EMPTY_MASK (0x02) /*!< RX empty status mask */ +#define SPI_RX_FULL_MASK (0x04) /*!< RX full status mask */ +#define SPI_TX_EMPTY_MASK (0x08) /*!< TX empty status mask */ +#define SPI_TX_FULL_MASK (0x10) /*!< TX full status mask */ +#define SPI_TXRX_RESET_MASK (0x20) /*!< TX or RX reset status mask */ +#define SPI_SPIEN_STS_MASK (0x40) /*!< SPIEN status mask */ +#define SPI_SSLINE_STS_MASK (0x80) /*!< SPIn_SS line status mask */ + + +/* I2S Data Width */ +#define I2S_DATABIT_8 (0 << SPI_I2SCTL_WDWIDTH_Pos) /*!< I2S data width is 8-bit */ +#define I2S_DATABIT_16 (1 << SPI_I2SCTL_WDWIDTH_Pos) /*!< I2S data width is 16-bit */ +#define I2S_DATABIT_24 (2 << SPI_I2SCTL_WDWIDTH_Pos) /*!< I2S data width is 24-bit */ +#define I2S_DATABIT_32 (3 << SPI_I2SCTL_WDWIDTH_Pos) /*!< I2S data width is 32-bit */ + +/* I2S Audio Format */ +#define I2S_MONO SPI_I2SCTL_MONO_Msk /*!< Monaural channel */ +#define I2S_STEREO 0 /*!< Stereo channel */ + +/* I2S Data Format */ +#define I2S_FORMAT_I2S (0<STATUS = SPI_STATUS_UNITIF_Msk) + +/** + * @brief Disable 2-bit Transfer mode. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear TWOBIT bit of SPI_CTL register to disable 2-bit Transfer mode. + */ +#define SPI_DISABLE_2BIT_MODE(spi) ((spi)->CTL &= ~SPI_CTL_TWOBIT_Msk) + +/** + * @brief Disable Slave 3-wire mode. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear SLV3WIRE bit of SPI_SSCTL register to disable Slave 3-wire mode. + */ +#define SPI_DISABLE_3WIRE_MODE(spi) ((spi)->SSCTL &= ~SPI_SSCTL_SLV3WIRE_Msk) + +/** + * @brief Disable Dual I/O mode. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear DUALIOEN bit of SPI_CTL register to disable Dual I/O mode. + */ +#define SPI_DISABLE_DUAL_MODE(spi) ((spi)->CTL &= ~SPI_CTL_DUALIOEN_Msk) + +/** + * @brief Disable Quad I/O mode. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear QUADIOEN bit of SPI_CTL register to disable Quad I/O mode. + */ +#define SPI_DISABLE_QUAD_MODE(spi) ((spi)->CTL &= ~SPI_CTL_QUADIOEN_Msk) + +/** + * @brief Enable 2-bit Transfer mode. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Set TWOBIT bit of SPI_CTL register to enable 2-bit Transfer mode. + */ +#define SPI_ENABLE_2BIT_MODE(spi) ((spi)->CTL |= SPI_CTL_TWOBIT_Msk) + +/** + * @brief Enable Slave 3-wire mode. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Set SLV3WIRE bit of SPI_SSCTL register to enable Slave 3-wire mode. + */ +#define SPI_ENABLE_3WIRE_MODE(spi) ((spi)->SSCTL |= SPI_SSCTL_SLV3WIRE_Msk) + +/** + * @brief Enable Dual input mode. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear QDIODIR bit and set DUALIOEN bit of SPI_CTL register to enable Dual input mode. + */ +#define SPI_ENABLE_DUAL_INPUT_MODE(spi) ((spi)->CTL = ((spi)->CTL & (~SPI_CTL_QDIODIR_Msk)) | SPI_CTL_DUALIOEN_Msk) + +/** + * @brief Enable Dual output mode. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Set QDIODIR bit and DUALIOEN bit of SPI_CTL register to enable Dual output mode. + */ +#define SPI_ENABLE_DUAL_OUTPUT_MODE(spi) ((spi)->CTL |= (SPI_CTL_QDIODIR_Msk | SPI_CTL_DUALIOEN_Msk)) + +/** + * @brief Enable Quad input mode. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear QDIODIR bit and set QUADIOEN bit of SPI_CTL register to enable Quad input mode. + */ +#define SPI_ENABLE_QUAD_INPUT_MODE(spi) ((spi)->CTL = ((spi)->CTL & (~SPI_CTL_QDIODIR_Msk)) | SPI_CTL_QUADIOEN_Msk) + +/** + * @brief Enable Quad output mode. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Set QDIODIR bit and QUADIOEN bit of SPI_CTL register to enable Quad output mode. + */ +#define SPI_ENABLE_QUAD_OUTPUT_MODE(spi) ((spi)->CTL |= (SPI_CTL_QDIODIR_Msk | SPI_CTL_QUADIOEN_Msk)) + +/** + * @brief Trigger RX PDMA function. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Set RXPDMAEN bit of SPI_PDMACTL register to enable RX PDMA transfer function. + */ +#define SPI_TRIGGER_RX_PDMA(spi) ((spi)->PDMACTL |= SPI_PDMACTL_RXPDMAEN_Msk) + +/** + * @brief Trigger TX PDMA function. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Set TXPDMAEN bit of SPI_PDMACTL register to enable TX PDMA transfer function. + */ +#define SPI_TRIGGER_TX_PDMA(spi) ((spi)->PDMACTL |= SPI_PDMACTL_TXPDMAEN_Msk) + +/** + * @brief Disable RX PDMA transfer. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear RXPDMAEN bit of SPI_PDMACTL register to disable RX PDMA transfer function. + */ +#define SPI_DISABLE_RX_PDMA(spi) ( (spi)->PDMACTL &= ~SPI_PDMACTL_RXPDMAEN_Msk ) + +/** + * @brief Disable TX PDMA transfer. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear TXPDMAEN bit of SPI_PDMACTL register to disable TX PDMA transfer function. + */ +#define SPI_DISABLE_TX_PDMA(spi) ( (spi)->PDMACTL &= ~SPI_PDMACTL_TXPDMAEN_Msk ) + +/** + * @brief Get the count of available data in RX FIFO. + * @param[in] spi The pointer of the specified SPI module. + * @return The count of available data in RX FIFO. + * @details Read RXCNT (SPI_STATUS[27:24]) to get the count of available data in RX FIFO. + */ +#define SPI_GET_RX_FIFO_COUNT(spi) (((spi)->STATUS & SPI_STATUS_RXCNT_Msk) >> SPI_STATUS_RXCNT_Pos) + +/** + * @brief Get the RX FIFO empty flag. + * @param[in] spi The pointer of the specified SPI module. + * @retval 0 RX FIFO is not empty. + * @retval 1 RX FIFO is empty. + * @details Read RXEMPTY bit of SPI_STATUS register to get the RX FIFO empty flag. + */ +#define SPI_GET_RX_FIFO_EMPTY_FLAG(spi) (((spi)->STATUS & SPI_STATUS_RXEMPTY_Msk)>>SPI_STATUS_RXEMPTY_Pos) + +/** + * @brief Get the TX FIFO empty flag. + * @param[in] spi The pointer of the specified SPI module. + * @retval 0 TX FIFO is not empty. + * @retval 1 TX FIFO is empty. + * @details Read TXEMPTY bit of SPI_STATUS register to get the TX FIFO empty flag. + */ +#define SPI_GET_TX_FIFO_EMPTY_FLAG(spi) (((spi)->STATUS & SPI_STATUS_TXEMPTY_Msk)>>SPI_STATUS_TXEMPTY_Pos) + +/** + * @brief Get the TX FIFO full flag. + * @param[in] spi The pointer of the specified SPI module. + * @retval 0 TX FIFO is not full. + * @retval 1 TX FIFO is full. + * @details Read TXFULL bit of SPI_STATUS register to get the TX FIFO full flag. + */ +#define SPI_GET_TX_FIFO_FULL_FLAG(spi) (((spi)->STATUS & SPI_STATUS_TXFULL_Msk)>>SPI_STATUS_TXFULL_Pos) + +/** + * @brief Get the datum read from RX register. + * @param[in] spi The pointer of the specified SPI module. + * @return Data in RX register. + * @details Read SPI_RX register to get the received datum. + */ +#define SPI_READ_RX(spi) ((spi)->RX) + +/** + * @brief Write datum to TX register. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32TxData The datum which user attempt to transfer through SPI bus. + * @return None. + * @details Write u32TxData to SPI_TX register. + */ +#define SPI_WRITE_TX(spi, u32TxData) ((spi)->TX = (u32TxData)) + +/** + * @brief Set SPIn_SS pin to high state. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Disable automatic slave selection function and set SPIn_SS pin to high state. + */ +#define SPI_SET_SS_HIGH(spi) ((spi)->SSCTL = ((spi)->SSCTL & (~SPI_SSCTL_AUTOSS_Msk)) | (SPI_SSCTL_SSACTPOL_Msk | SPI_SSCTL_SS_Msk)) + +/** + * @brief Set SPIn_SS pin to low state. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Disable automatic slave selection function and set SPIn_SS pin to low state. + */ +#define SPI_SET_SS_LOW(spi) ((spi)->SSCTL = ((spi)->SSCTL & (~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SSACTPOL_Msk))) | SPI_SSCTL_SS_Msk) + +/** + * @brief Enable Byte Reorder function. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Enable Byte Reorder function. The suspend interval depends on the setting of SUSPITV (SPI_CTL[7:4]). + */ +#define SPI_ENABLE_BYTE_REORDER(spi) ((spi)->CTL |= SPI_CTL_REORDER_Msk) + +/** + * @brief Disable Byte Reorder function. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear REORDER bit field of SPI_CTL register to disable Byte Reorder function. + */ +#define SPI_DISABLE_BYTE_REORDER(spi) ((spi)->CTL &= ~SPI_CTL_REORDER_Msk) + +/** + * @brief Set the length of suspend interval. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32SuspCycle Decides the length of suspend interval. It could be 0 ~ 15. + * @return None. + * @details Set the length of suspend interval according to u32SuspCycle. + * The length of suspend interval is ((u32SuspCycle + 0.5) * the length of one SPI bus clock cycle). + */ +#define SPI_SET_SUSPEND_CYCLE(spi, u32SuspCycle) ((spi)->CTL = ((spi)->CTL & ~SPI_CTL_SUSPITV_Msk) | ((u32SuspCycle) << SPI_CTL_SUSPITV_Pos)) + +/** + * @brief Set the SPI transfer sequence with LSB first. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Set LSB bit of SPI_CTL register to set the SPI transfer sequence with LSB first. + */ +#define SPI_SET_LSB_FIRST(spi) ((spi)->CTL |= SPI_CTL_LSB_Msk) + +/** + * @brief Set the SPI transfer sequence with MSB first. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear LSB bit of SPI_CTL register to set the SPI transfer sequence with MSB first. + */ +#define SPI_SET_MSB_FIRST(spi) ((spi)->CTL &= ~SPI_CTL_LSB_Msk) + +/** + * @brief Set the data width of a SPI transaction. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32Width The bit width of one transaction. + * @return None. + * @details The data width can be 8 ~ 32 bits. + */ +#define SPI_SET_DATA_WIDTH(spi, u32Width) ((spi)->CTL = ((spi)->CTL & ~SPI_CTL_DWIDTH_Msk) | (((u32Width)&0x1F) << SPI_CTL_DWIDTH_Pos)) + +/** + * @brief Get the SPI busy state. + * @param[in] spi The pointer of the specified SPI module. + * @retval 0 SPI controller is not busy. + * @retval 1 SPI controller is busy. + * @details This macro will return the busy state of SPI controller. + */ +#define SPI_IS_BUSY(spi) ( ((spi)->STATUS & SPI_STATUS_BUSY_Msk)>>SPI_STATUS_BUSY_Pos ) + +/** + * @brief Enable SPI controller. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Set SPIEN (SPI_CTL[0]) to enable SPI controller. + */ +#define SPI_ENABLE(spi) ((spi)->CTL |= SPI_CTL_SPIEN_Msk) + +/** + * @brief Disable SPI controller. + * @param[in] spi The pointer of the specified SPI module. + * @return None. + * @details Clear SPIEN (SPI_CTL[0]) to disable SPI controller. + */ +#define SPI_DISABLE(spi) ((spi)->CTL &= ~SPI_CTL_SPIEN_Msk) + + +/** + * @brief Enable zero cross detection function. + * @param[in] i2s The pointer of the specified I2S module. + * @param[in] u32ChMask The mask for left or right channel. Valid values are: + * - \ref I2S_RIGHT + * - \ref I2S_LEFT + * @return None + * @details This function will set RZCEN or LZCEN bit of SPI_I2SCTL register to enable zero cross detection function. + */ +static __INLINE void I2S_ENABLE_TX_ZCD(SPI_T *i2s, uint32_t u32ChMask) +{ + if(u32ChMask == I2S_RIGHT) + i2s->I2SCTL |= SPI_I2SCTL_RZCEN_Msk; + else + i2s->I2SCTL |= SPI_I2SCTL_LZCEN_Msk; +} + +/** + * @brief Disable zero cross detection function. + * @param[in] i2s The pointer of the specified I2S module. + * @param[in] u32ChMask The mask for left or right channel. Valid values are: + * - \ref I2S_RIGHT + * - \ref I2S_LEFT + * @return None + * @details This function will clear RZCEN or LZCEN bit of SPI_I2SCTL register to disable zero cross detection function. + */ +static __INLINE void I2S_DISABLE_TX_ZCD(SPI_T *i2s, uint32_t u32ChMask) +{ + if(u32ChMask == I2S_RIGHT) + i2s->I2SCTL &= ~SPI_I2SCTL_RZCEN_Msk; + else + i2s->I2SCTL &= ~SPI_I2SCTL_LZCEN_Msk; +} + +/** + * @brief Enable I2S TX DMA function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will set TXPDMAEN bit of SPI_PDMACTL register to transmit data with PDMA. + */ +#define I2S_ENABLE_TXDMA(i2s) ( (i2s)->PDMACTL |= SPI_PDMACTL_TXPDMAEN_Msk ) + +/** + * @brief Disable I2S TX DMA function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will clear TXPDMAEN bit of SPI_PDMACTL register to disable TX DMA function. + */ +#define I2S_DISABLE_TXDMA(i2s) ( (i2s)->PDMACTL &= ~SPI_PDMACTL_TXPDMAEN_Msk ) + +/** + * @brief Enable I2S RX DMA function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will set RXPDMAEN bit of SPI_PDMACTL register to receive data with PDMA. + */ +#define I2S_ENABLE_RXDMA(i2s) ( (i2s)->PDMACTL |= SPI_PDMACTL_RXPDMAEN_Msk ) + +/** + * @brief Disable I2S RX DMA function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will clear RXPDMAEN bit of SPI_PDMACTL register to disable RX DMA function. + */ +#define I2S_DISABLE_RXDMA(i2s) ( (i2s)->PDMACTL &= ~SPI_PDMACTL_RXPDMAEN_Msk ) + +/** + * @brief Enable I2S TX function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will set TXEN bit of SPI_I2SCTL register to enable I2S TX function. + */ +#define I2S_ENABLE_TX(i2s) ( (i2s)->I2SCTL |= SPI_I2SCTL_TXEN_Msk ) + +/** + * @brief Disable I2S TX function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will clear TXEN bit of SPI_I2SCTL register to disable I2S TX function. + */ +#define I2S_DISABLE_TX(i2s) ( (i2s)->I2SCTL &= ~SPI_I2SCTL_TXEN_Msk ) + +/** + * @brief Enable I2S RX function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will set RXEN bit of SPI_I2SCTL register to enable I2S RX function. + */ +#define I2S_ENABLE_RX(i2s) ( (i2s)->I2SCTL |= SPI_I2SCTL_RXEN_Msk ) + +/** + * @brief Disable I2S RX function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will clear RXEN bit of SPI_I2SCTL register to disable I2S RX function. + */ +#define I2S_DISABLE_RX(i2s) ( (i2s)->I2SCTL &= ~SPI_I2SCTL_RXEN_Msk ) + +/** + * @brief Enable TX Mute function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will set MUTE bit of SPI_I2SCTL register to enable I2S TX mute function. + */ +#define I2S_ENABLE_TX_MUTE(i2s) ( (i2s)->I2SCTL |= SPI_I2SCTL_MUTE_Msk ) + +/** + * @brief Disable TX Mute function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will clear MUTE bit of SPI_I2SCTL register to disable I2S TX mute function. + */ +#define I2S_DISABLE_TX_MUTE(i2s) ( (i2s)->I2SCTL &= ~SPI_I2SCTL_MUTE_Msk ) + +/** + * @brief Clear TX FIFO. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will clear TX FIFO. The internal TX FIFO pointer will be reset to FIFO start point. + */ +#define I2S_CLR_TX_FIFO(i2s) ( (i2s)->FIFOCTL |= SPI_FIFOCTL_TXFBCLR_Msk ) + +/** + * @brief Clear RX FIFO. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details This macro will clear RX FIFO. The internal RX FIFO pointer will be reset to FIFO start point. + */ +#define I2S_CLR_RX_FIFO(i2s) ( (i2s)->FIFOCTL |= SPI_FIFOCTL_RXFBCLR_Msk ) + +/** + * @brief This function sets the recording source channel when mono mode is used. + * @param[in] i2s The pointer of the specified I2S module. + * @param[in] u32Ch left or right channel. Valid values are: + * - \ref I2S_MONO_LEFT + * - \ref I2S_MONO_RIGHT + * @return None + * @details This function selects the recording source channel of monaural mode. + */ +static __INLINE void I2S_SET_MONO_RX_CHANNEL(SPI_T *i2s, uint32_t u32Ch) +{ + u32Ch == I2S_MONO_LEFT ? + (i2s->I2SCTL |= SPI_I2SCTL_RXLCH_Msk) : + (i2s->I2SCTL &= ~SPI_I2SCTL_RXLCH_Msk); +} + +/** + * @brief Write data to I2S TX FIFO. + * @param[in] i2s The pointer of the specified I2S module. + * @param[in] u32Data The value written to TX FIFO. + * @return None + * @details This macro will write a value to TX FIFO. + */ +#define I2S_WRITE_TX_FIFO(i2s, u32Data) ( (i2s)->TX = (u32Data) ) + +/** + * @brief Read RX FIFO. + * @param[in] i2s The pointer of the specified I2S module. + * @return The value read from RX FIFO. + * @details This function will return a value read from RX FIFO. + */ +#define I2S_READ_RX_FIFO(i2s) ( (i2s)->RX ) + +/** + * @brief Get the interrupt flag. + * @param[in] i2s The pointer of the specified I2S module. + * @param[in] u32Mask The mask value for all interrupt flags. + * @return The interrupt flags specified by the u32mask parameter. + * @details This macro will return the combination interrupt flags of SPI_I2SSTS register. The flags are specified by the u32mask parameter. + */ +#define I2S_GET_INT_FLAG(i2s, u32Mask) ( (i2s)->I2SSTS & (u32Mask) ) + +/** + * @brief Clear the interrupt flag. + * @param[in] i2s The pointer of the specified I2S module. + * @param[in] u32Mask The mask value for all interrupt flags. + * @return None + * @details This macro will clear the interrupt flags specified by the u32mask parameter. + * @note Except TX and RX FIFO threshold interrupt flags, the other interrupt flags can be cleared by writing 1 to itself. + */ +#define I2S_CLR_INT_FLAG(i2s, u32Mask) ( (i2s)->I2SSTS = (u32Mask) ) + +/** + * @brief Get transmit FIFO level + * @param[in] i2s The pointer of the specified I2S module. + * @return TX FIFO level + * @details This macro will return the number of available words in TX FIFO. + */ +#define I2S_GET_TX_FIFO_LEVEL(i2s) ( ((i2s)->I2SSTS & SPI_I2SSTS_TXCNT_Msk) >> SPI_I2SSTS_TXCNT_Pos ) + +/** + * @brief Get receive FIFO level + * @param[in] i2s The pointer of the specified I2S module. + * @return RX FIFO level + * @details This macro will return the number of available words in RX FIFO. + */ +#define I2S_GET_RX_FIFO_LEVEL(i2s) ( ((i2s)->I2SSTS & SPI_I2SSTS_RXCNT_Msk) >> SPI_I2SSTS_RXCNT_Pos ) + + + +/* Function prototype declaration */ +uint32_t SPI_Open(SPI_T *spi, uint32_t u32MasterSlave, uint32_t u32SPIMode, uint32_t u32DataWidth, uint32_t u32BusClock); +void SPI_Close(SPI_T *spi); +void SPI_ClearRxFIFO(SPI_T *spi); +void SPI_ClearTxFIFO(SPI_T *spi); +void SPI_DisableAutoSS(SPI_T *spi); +void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel); +uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock); +void SPI_SetFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold); +uint32_t SPI_GetBusClock(SPI_T *spi); +void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask); +void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask); +uint32_t SPI_GetIntFlag(SPI_T *spi, uint32_t u32Mask); +void SPI_ClearIntFlag(SPI_T *spi, uint32_t u32Mask); +uint32_t SPI_GetStatus(SPI_T *spi, uint32_t u32Mask); + +uint32_t I2S_Open(SPI_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat); +void I2S_Close(SPI_T *i2s); +void I2S_EnableInt(SPI_T *i2s, uint32_t u32Mask); +void I2S_DisableInt(SPI_T *i2s, uint32_t u32Mask); +uint32_t I2S_EnableMCLK(SPI_T *i2s, uint32_t u32BusClock); +void I2S_DisableMCLK(SPI_T *i2s); +void I2S_SetFIFO(SPI_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold); + + +/*@}*/ /* end of group SPI_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group SPI_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__SPI_H__ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/sys.h b/StdDriver/inc/sys.h new file mode 100644 index 0000000..28b4a26 --- /dev/null +++ b/StdDriver/inc/sys.h @@ -0,0 +1,970 @@ +/**************************************************************************//** + * @file SYS.h + * @version V3.0 + * $Revision 1 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 Series SYS Header File + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. + ******************************************************************************/ + +#ifndef __SYS_H__ +#define __SYS_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup SYS_Driver SYS Driver + @{ +*/ + +/** @addtogroup SYS_EXPORTED_CONSTANTS SYS Exported Constants + @{ +*/ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* Module Reset Control Resister constant definitions. */ +/*---------------------------------------------------------------------------------------------------------*/ +#define PDMA_RST ((0x0<<24) | SYS_IPRST0_PDMARST_Pos ) /*!< Reset PDMA */ +#define EBI_RST ((0x0<<24) | SYS_IPRST0_EBIRST_Pos ) /*!< Reset EBI */ +#define USBH_RST ((0x0<<24) | SYS_IPRST0_USBHRST_Pos ) /*!< Reset USBH */ +#define CRC_RST ((0x0<<24) | SYS_IPRST0_CRCRST_Pos ) /*!< Reset CRC */ + +#define GPIO_RST ((0x4<<24) | SYS_IPRST1_GPIORST_Pos ) /*!< Reset GPIO */ +#define TMR0_RST ((0x4<<24) | SYS_IPRST1_TMR0RST_Pos ) /*!< Reset TMR0 */ +#define TMR1_RST ((0x4<<24) | SYS_IPRST1_TMR1RST_Pos ) /*!< Reset TMR1 */ +#define TMR2_RST ((0x4<<24) | SYS_IPRST1_TMR2RST_Pos ) /*!< Reset TMR2 */ +#define TMR3_RST ((0x4<<24) | SYS_IPRST1_TMR3RST_Pos ) /*!< Reset TMR3 */ +#define ACMP01_RST ((0x4<<24) | SYS_IPRST1_ACMP01RST_Pos ) /*!< Reset ACMP01 */ +#define I2C0_RST ((0x4<<24) | SYS_IPRST1_I2C0RST_Pos ) /*!< Reset I2C0 */ +#define I2C1_RST ((0x4<<24) | SYS_IPRST1_I2C1RST_Pos ) /*!< Reset I2C1 */ +#define SPI0_RST ((0x4<<24) | SYS_IPRST1_SPI0RST_Pos ) /*!< Reset SPI0 */ +#define SPI1_RST ((0x4<<24) | SYS_IPRST1_SPI1RST_Pos ) /*!< Reset SPI1 */ +#define SPI2_RST ((0x4<<24) | SYS_IPRST1_SPI2RST_Pos ) /*!< Reset SPI2 */ +#define UART0_RST ((0x4<<24) | SYS_IPRST1_UART0RST_Pos ) /*!< Reset UART0 */ +#define UART1_RST ((0x4<<24) | SYS_IPRST1_UART1RST_Pos ) /*!< Reset UART1 */ +#define UART2_RST ((0x4<<24) | SYS_IPRST1_UART2RST_Pos ) /*!< Reset UART2 */ +#define UART3_RST ((0x4<<24) | SYS_IPRST1_UART3RST_Pos ) /*!< Reset UART3 */ +#define CAN0_RST ((0x4<<24) | SYS_IPRST1_CAN0RST_Pos ) /*!< Reset CAN0 */ +#define OTG_RST ((0x4<<24) | SYS_IPRST1_OTGRST_Pos ) /*!< Reset OTG */ +#define USBD_RST ((0x4<<24) | SYS_IPRST1_USBDRST_Pos ) /*!< Reset USBD */ +#define EADC_RST ((0x4<<24) | SYS_IPRST1_EADCRST_Pos ) /*!< Reset EADC */ + +#define SC0_RST ((0x8<<24) | SYS_IPRST2_SC0RST_Pos ) /*!< Reset SC0 */ +#define DAC_RST ((0x8<<24) | SYS_IPRST2_DACRST_Pos ) /*!< Reset DAC */ +#define PWM0_RST ((0x8<<24) | SYS_IPRST2_PWM0RST_Pos ) /*!< Reset PWM0 */ +#define PWM1_RST ((0x8<<24) | SYS_IPRST2_PWM1RST_Pos ) /*!< Reset PWM1 */ +#define TK_RST ((0x8<<24) | SYS_IPRST2_TKRST_Pos ) /*!< Reset TK */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* Brown Out Detector Threshold Voltage Selection constant definitions. */ +/*---------------------------------------------------------------------------------------------------------*/ +#define SYS_BODCTL_BOD_RST_EN (1UL<GPA_MFPL = (SYS->GPA_MFPL & (~SYS_GPA_MFPL_PA0MFP_Msk) ) | SYS_GPA_MFPL_PA0_MFP_SC0_CLK ; + +*/ +//PA0 MFP +#define SYS_GPA_MFPL_PA0MFP_GPIO (0ul << SYS_GPA_MFPL_PA0MFP_Pos) /*!< GPA_MFPL PA0 setting for GPIO*/ +#define SYS_GPA_MFPL_PA0MFP_UART1_nCTS (1ul << SYS_GPA_MFPL_PA0MFP_Pos) /*!< GPA_MFPL PA0 setting for UART1_nCTS*/ +#define SYS_GPA_MFPL_PA0MFP_UART1_TXD (3ul << SYS_GPA_MFPL_PA0MFP_Pos) /*!< GPA_MFPL PA0 setting for UART1_TXD*/ +#define SYS_GPA_MFPL_PA0MFP_CAN0_RXD (4ul << SYS_GPA_MFPL_PA0MFP_Pos) /*!< GPA_MFPL PA0 setting for CAN0_RXD*/ +#define SYS_GPA_MFPL_PA0MFP_SC0_CLK (5ul << SYS_GPA_MFPL_PA0MFP_Pos) /*!< GPA_MFPL PA0 setting for SC0_CLK*/ +#define SYS_GPA_MFPL_PA0MFP_PWM1_CH5 (6ul << SYS_GPA_MFPL_PA0MFP_Pos) /*!< GPA_MFPL PA0 setting for PWM1_CH5*/ +#define SYS_GPA_MFPL_PA0MFP_EBI_AD0 (7ul << SYS_GPA_MFPL_PA0MFP_Pos) /*!< GPA_MFPL PA0 setting for EBI_AD0*/ +#define SYS_GPA_MFPL_PA0MFP_INT0 (8ul << SYS_GPA_MFPL_PA0MFP_Pos) /*!< GPA_MFPL PA0 setting for INT0*/ +#define SYS_GPA_MFPL_PA0MFP_SPI1_I2SMCLK (9ul << SYS_GPA_MFPL_PA0MFP_Pos) /*!< GPA_MFPL PA0 setting for SPI1_I2SMCLK*/ + +//PA1 MFP +#define SYS_GPA_MFPL_PA1MFP_GPIO (0ul << SYS_GPA_MFPL_PA1MFP_Pos) /*!< GPA_MFPL PA1 setting for GPIO*/ +#define SYS_GPA_MFPL_PA1MFP_UART1_nRTS (1ul << SYS_GPA_MFPL_PA1MFP_Pos) /*!< GPA_MFPL PA1 setting for UART1_nRTS*/ +#define SYS_GPA_MFPL_PA1MFP_UART1_RXD (3ul << SYS_GPA_MFPL_PA1MFP_Pos) /*!< GPA_MFPL PA1 setting for UART1_RXD*/ +#define SYS_GPA_MFPL_PA1MFP_CAN0_TXD (4ul << SYS_GPA_MFPL_PA1MFP_Pos) /*!< GPA_MFPL PA1 setting for CAN0_TXD*/ +#define SYS_GPA_MFPL_PA1MFP_SC0_DAT (5ul << SYS_GPA_MFPL_PA1MFP_Pos) /*!< GPA_MFPL PA1 setting for SC0_DAT*/ +#define SYS_GPA_MFPL_PA1MFP_PWM1_CH4 (6ul << SYS_GPA_MFPL_PA1MFP_Pos) /*!< GPA_MFPL PA1 setting for PWM1_CH4*/ +#define SYS_GPA_MFPL_PA1MFP_EBI_AD1 (7ul << SYS_GPA_MFPL_PA1MFP_Pos) /*!< GPA_MFPL PA1 setting for EBI_AD1*/ +#define SYS_GPA_MFPL_PA1MFP_STADC (10ul << SYS_GPA_MFPL_PA1MFP_Pos) /*!< GPA_MFPL PA1 setting for STADC*/ + +//PA2 MFP +#define SYS_GPA_MFPL_PA2MFP_GPIO (0ul << SYS_GPA_MFPL_PA2MFP_Pos) /*!< GPA_MFPL PA2 setting for GPIO*/ +#define SYS_GPA_MFPL_PA2MFP_USB_VBUS_EN (1ul << SYS_GPA_MFPL_PA2MFP_Pos) /*!< GPA_MFPL PA2 setting for USB_VBUS_EN*/ +#define SYS_GPA_MFPL_PA2MFP_UART0_TXD (2ul << SYS_GPA_MFPL_PA2MFP_Pos) /*!< GPA_MFPL PA2 setting for UART0_TXD*/ +#define SYS_GPA_MFPL_PA2MFP_UART0_nCTS (3ul << SYS_GPA_MFPL_PA2MFP_Pos) /*!< GPA_MFPL PA2 setting for UART0_nCTS*/ +#define SYS_GPA_MFPL_PA2MFP_I2C0_SDA (4ul << SYS_GPA_MFPL_PA2MFP_Pos) /*!< GPA_MFPL PA2 setting for I2C0_SDA*/ +#define SYS_GPA_MFPL_PA2MFP_SC0_RST (5ul << SYS_GPA_MFPL_PA2MFP_Pos) /*!< GPA_MFPL PA2 setting for SC0_RST*/ +#define SYS_GPA_MFPL_PA2MFP_PWM1_CH3 (6ul << SYS_GPA_MFPL_PA2MFP_Pos) /*!< GPA_MFPL PA2 setting for PWM1_CH3*/ +#define SYS_GPA_MFPL_PA2MFP_EBI_AD2 (7ul << SYS_GPA_MFPL_PA2MFP_Pos) /*!< GPA_MFPL PA2 setting for EBI_AD2*/ + +//PA3 MFP +#define SYS_GPA_MFPL_PA3MFP_GPIO (0ul << SYS_GPA_MFPL_PA3MFP_Pos) /*!< GPA_MFPL PA3 setting for GPIO*/ +#define SYS_GPA_MFPL_PA3MFP_USB_VBUS_ST (1ul << SYS_GPA_MFPL_PA3MFP_Pos) /*!< GPA_MFPL PA3 setting for USB_VBUS_ST*/ +#define SYS_GPA_MFPL_PA3MFP_UART0_RXD (2ul << SYS_GPA_MFPL_PA3MFP_Pos) /*!< GPA_MFPL PA3 setting for UART0_RXD*/ +#define SYS_GPA_MFPL_PA3MFP_UART0_nRTS (3ul << SYS_GPA_MFPL_PA3MFP_Pos) /*!< GPA_MFPL PA3 setting for UART0_nRTS*/ +#define SYS_GPA_MFPL_PA3MFP_I2C0_SCL (4ul << SYS_GPA_MFPL_PA3MFP_Pos) /*!< GPA_MFPL PA3 setting for I2C0_SCL*/ +#define SYS_GPA_MFPL_PA3MFP_SC0_PWR (5ul << SYS_GPA_MFPL_PA3MFP_Pos) /*!< GPA_MFPL PA3 setting for SC0_PWR*/ +#define SYS_GPA_MFPL_PA3MFP_PWM1_CH2 (6ul << SYS_GPA_MFPL_PA3MFP_Pos) /*!< GPA_MFPL PA3 setting for PWM1_CH2*/ +#define SYS_GPA_MFPL_PA3MFP_EBI_AD3 (7ul << SYS_GPA_MFPL_PA3MFP_Pos) /*!< GPA_MFPL PA3 setting for EBI_AD3*/ + +//PA4 MFP +#define SYS_GPA_MFPL_PA4MFP_GPIO (0ul << SYS_GPA_MFPL_PA4MFP_Pos) /*!< GPA_MFPL PA4 setting for GPIO*/ +#define SYS_GPA_MFPL_PA4MFP_SPI1_SS (2ul << SYS_GPA_MFPL_PA4MFP_Pos) /*!< GPA_MFPL PA4 setting for SPI1_SS*/ +#define SYS_GPA_MFPL_PA4MFP_EBI_AD4 (7ul << SYS_GPA_MFPL_PA4MFP_Pos) /*!< GPA_MFPL PA4 setting for EBI_AD4*/ + +//PA5 MFP +#define SYS_GPA_MFPL_PA5MFP_GPIO (0ul << SYS_GPA_MFPL_PA5MFP_Pos) /*!< GPA_MFPL PA5 setting for GPIO*/ +#define SYS_GPA_MFPL_PA5MFP_SPI1_MOSI (2ul << SYS_GPA_MFPL_PA5MFP_Pos) /*!< GPA_MFPL PA5 setting for SPI1_MOSI*/ +#define SYS_GPA_MFPL_PA5MFP_T2_EXT (3ul << SYS_GPA_MFPL_PA5MFP_Pos) /*!< GPA_MFPL PA5 setting for T2_EXT*/ +#define SYS_GPA_MFPL_PA5MFP_EBI_AD5 (7ul << SYS_GPA_MFPL_PA5MFP_Pos) /*!< GPA_MFPL PA5 setting for EBI_AD5*/ + +//PA6 MFP +#define SYS_GPA_MFPL_PA6MFP_GPIO (0ul << SYS_GPA_MFPL_PA6MFP_Pos) /*!< GPA_MFPL PA6 setting for GPIO*/ +#define SYS_GPA_MFPL_PA6MFP_SPI1_MISO (2ul << SYS_GPA_MFPL_PA6MFP_Pos) /*!< GPA_MFPL PA6 setting for SPI1_MISO*/ +#define SYS_GPA_MFPL_PA6MFP_T1_EXT (3ul << SYS_GPA_MFPL_PA6MFP_Pos) /*!< GPA_MFPL PA6 setting for T1_EXT*/ +#define SYS_GPA_MFPL_PA6MFP_EBI_AD6 (7ul << SYS_GPA_MFPL_PA6MFP_Pos) /*!< GPA_MFPL PA6 setting for EBI_AD6*/ + +//PA7 MFP +#define SYS_GPA_MFPL_PA7MFP_GPIO (0ul << SYS_GPA_MFPL_PA7MFP_Pos) /*!< GPA_MFPL PA7 setting for GPIO*/ +#define SYS_GPA_MFPL_PA7MFP_SPI1_CLK (2ul << SYS_GPA_MFPL_PA7MFP_Pos) /*!< GPA_MFPL PA7 setting for SPI1_CLK*/ +#define SYS_GPA_MFPL_PA7MFP_T0_EXT (3ul << SYS_GPA_MFPL_PA7MFP_Pos) /*!< GPA_MFPL PA7 setting for T0_EXT*/ +#define SYS_GPA_MFPL_PA7MFP_EBI_AD7 (7ul << SYS_GPA_MFPL_PA7MFP_Pos) /*!< GPA_MFPL PA7 setting for EBI_AD7*/ + +//PA8 MFP +#define SYS_GPA_MFPH_PA8MFP_GPIO (0ul << SYS_GPA_MFPH_PA8MFP_Pos) /*!< GPA_MFPH PA8 setting for GPIO*/ +#define SYS_GPA_MFPH_PA8MFP_UART3_TXD (3ul << SYS_GPA_MFPH_PA8MFP_Pos) /*!< GPA_MFPH PA8 setting for UART3_TXD*/ + +//PA9 MFP +#define SYS_GPA_MFPH_PA9MFP_GPIO (0ul << SYS_GPA_MFPH_PA9MFP_Pos) /*!< GPA_MFPH PA9 setting for GPIO*/ +#define SYS_GPA_MFPH_PA9MFP_UART3_RXD (3ul << SYS_GPA_MFPH_PA9MFP_Pos) /*!< GPA_MFPH PA9 setting for UART3_RXD*/ + +//PA10 MFP +#define SYS_GPA_MFPH_PA10MFP_GPIO (0ul << SYS_GPA_MFPH_PA10MFP_Pos) /*!< GPA_MFPH PA10 setting for GPIO*/ +#define SYS_GPA_MFPH_PA10MFP_UART3_nCTS (3ul << SYS_GPA_MFPH_PA10MFP_Pos) /*!< GPA_MFPH PA10 setting for UART3_nCTS*/ + +//PA11 MFP +#define SYS_GPA_MFPH_PA11MFP_GPIO (0ul << SYS_GPA_MFPH_PA11MFP_Pos) /*!< GPA_MFPH PA11 setting for GPIO*/ +#define SYS_GPA_MFPH_PA11MFP_UART3_nRTS (3ul << SYS_GPA_MFPH_PA11MFP_Pos) /*!< GPA_MFPH PA11 setting for UART3_nRTS*/ + +//PA12 MFP +#define SYS_GPA_MFPH_PA12MFP_GPIO (0ul << SYS_GPA_MFPH_PA12MFP_Pos) /*!< GPA_MFPH PA12 setting for GPIO*/ +#define SYS_GPA_MFPH_PA12MFP_SPI1_I2SMCLK (2ul << SYS_GPA_MFPH_PA12MFP_Pos) /*!< GPA_MFPH PA12 setting for SPI1_I2SMCLK*/ +#define SYS_GPA_MFPH_PA12MFP_CAN0_TXD (4ul << SYS_GPA_MFPH_PA12MFP_Pos) /*!< GPA_MFPH PA12 setting for CAN0_TXD*/ + +//PA13 MFP +#define SYS_GPA_MFPH_PA13MFP_GPIO (0ul << SYS_GPA_MFPH_PA13MFP_Pos) /*!< GPA_MFPH PA13 setting for GPIO*/ +#define SYS_GPA_MFPH_PA13MFP_CAN0_RXD (4ul << SYS_GPA_MFPH_PA13MFP_Pos) /*!< GPA_MFPH PA13 setting for CAN0_RXD*/ + +//PA14 MFP +#define SYS_GPA_MFPH_PA14MFP_GPIO (0ul << SYS_GPA_MFPH_PA14MFP_Pos) /*!< GPA_MFPH PA14 setting for GPIO*/ +#define SYS_GPA_MFPH_PA14MFP_UART2_nCTS (3ul << SYS_GPA_MFPH_PA14MFP_Pos) /*!< GPA_MFPH PA14 setting for UART2_nCTS*/ +#define SYS_GPA_MFPH_PA14MFP_I2C0_SMBAL (4ul << SYS_GPA_MFPH_PA14MFP_Pos) /*!< GPA_MFPH PA14 setting for I2C0_SMBAL*/ + +//PA15 MFP +#define SYS_GPA_MFPH_PA15MFP_GPIO (0ul << SYS_GPA_MFPH_PA15MFP_Pos) /*!< GPA_MFPH PA15 setting for GPIO*/ +#define SYS_GPA_MFPH_PA15MFP_UART2_nRTS (3ul << SYS_GPA_MFPH_PA15MFP_Pos) /*!< GPA_MFPH PA15 setting for UART2_nRTS*/ +#define SYS_GPA_MFPH_PA15MFP_I2C0_SMBSUS (4ul << SYS_GPA_MFPH_PA15MFP_Pos) /*!< GPA_MFPH PA15 setting for I2C0_SMBSUS*/ + +//PB0 MFP +#define SYS_GPB_MFPL_PB0MFP_GPIO (0ul << SYS_GPB_MFPL_PB0MFP_Pos) /*!< GPB_MFPL PB0 setting for GPIO*/ +#define SYS_GPB_MFPL_PB0MFP_EADC_CH0 (1ul << SYS_GPB_MFPL_PB0MFP_Pos) /*!< GPB_MFPL PB0 setting for EADC_CH0*/ +#define SYS_GPB_MFPL_PB0MFP_SPI0_MOSI1 (2ul << SYS_GPB_MFPL_PB0MFP_Pos) /*!< GPB_MFPL PB0 setting for SPI0_MOSI1*/ +#define SYS_GPB_MFPL_PB0MFP_UART2_RXD (3ul << SYS_GPB_MFPL_PB0MFP_Pos) /*!< GPB_MFPL PB0 setting for UART2_RXD*/ +#define SYS_GPB_MFPL_PB0MFP_T2 (4ul << SYS_GPB_MFPL_PB0MFP_Pos) /*!< GPB_MFPL PB0 setting for T2*/ +#define SYS_GPB_MFPL_PB0MFP_DAC (5ul << SYS_GPB_MFPL_PB0MFP_Pos) /*!< GPB_MFPL PB0 setting for DAC*/ +#define SYS_GPB_MFPL_PB0MFP_EBI_nWRL (7ul << SYS_GPB_MFPL_PB0MFP_Pos) /*!< GPB_MFPL PB0 setting for EBI_nWRL*/ +#define SYS_GPB_MFPL_PB0MFP_INT1 (8ul << SYS_GPB_MFPL_PB0MFP_Pos) /*!< GPB_MFPL PB0 setting for INT1*/ + +//PB1 MFP +#define SYS_GPB_MFPL_PB1MFP_GPIO (0ul << SYS_GPB_MFPL_PB1MFP_Pos) /*!< GPB_MFPL PB1 setting for GPIO*/ +#define SYS_GPB_MFPL_PB1MFP_EADC_CH1 (1ul << SYS_GPB_MFPL_PB1MFP_Pos) /*!< GPB_MFPL PB1 setting for EADC_CH1*/ +#define SYS_GPB_MFPL_PB1MFP_SPI0_MISO1 (2ul << SYS_GPB_MFPL_PB1MFP_Pos) /*!< GPB_MFPL PB1 setting for SPI0_MISO1*/ +#define SYS_GPB_MFPL_PB1MFP_UART2_TXD (3ul << SYS_GPB_MFPL_PB1MFP_Pos) /*!< GPB_MFPL PB1 setting for UART2_TXD*/ +#define SYS_GPB_MFPL_PB1MFP_T3 (4ul << SYS_GPB_MFPL_PB1MFP_Pos) /*!< GPB_MFPL PB1 setting for T3*/ +#define SYS_GPB_MFPL_PB1MFP_SC0_RST (5ul << SYS_GPB_MFPL_PB1MFP_Pos) /*!< GPB_MFPL PB1 setting for SC0_RST*/ +#define SYS_GPB_MFPL_PB1MFP_PWM0_SYNC_OUT (6ul << SYS_GPB_MFPL_PB1MFP_Pos) /*!< GPB_MFPL PB1 setting for PWM0_SYNC_OUT*/ +#define SYS_GPB_MFPL_PB1MFP_EBI_nWRH (7ul << SYS_GPB_MFPL_PB1MFP_Pos) /*!< GPB_MFPL PB1 setting for EBI_nWRH*/ + +//PB2 MFP +#define SYS_GPB_MFPL_PB2MFP_GPIO (0ul << SYS_GPB_MFPL_PB2MFP_Pos) /*!< GPB_MFPL PB2 setting for GPIO*/ +#define SYS_GPB_MFPL_PB2MFP_EADC_CH2 (1ul << SYS_GPB_MFPL_PB2MFP_Pos) /*!< GPB_MFPL PB2 setting for EADC_CH2*/ +#define SYS_GPB_MFPL_PB2MFP_SPI0_CLK (2ul << SYS_GPB_MFPL_PB2MFP_Pos) /*!< GPB_MFPL PB2 setting for SPI0_CLK*/ +#define SYS_GPB_MFPL_PB2MFP_SPI1_CLK (3ul << SYS_GPB_MFPL_PB2MFP_Pos) /*!< GPB_MFPL PB2 setting for SPI1_CLK*/ +#define SYS_GPB_MFPL_PB2MFP_UART1_RXD (4ul << SYS_GPB_MFPL_PB2MFP_Pos) /*!< GPB_MFPL PB2 setting for UART1_RXD*/ +#define SYS_GPB_MFPL_PB2MFP_SC0_CD (5ul << SYS_GPB_MFPL_PB2MFP_Pos) /*!< GPB_MFPL PB2 setting for SC0_CD*/ +#define SYS_GPB_MFPL_PB2MFP_UART3_RXD (9ul << SYS_GPB_MFPL_PB2MFP_Pos) /*!< GPB_MFPL PB2 setting for UART3_RXD*/ +#define SYS_GPB_MFPL_PB2MFP_T2_EXT (11ul << SYS_GPB_MFPL_PB2MFP_Pos) /*!< GPB_MFPL PB2 setting for T2_EXT*/ + +//PB3 +#define SYS_GPB_MFPL_PB3MFP_GPIO (0ul << SYS_GPB_MFPL_PB3MFP_Pos) /*!< GPB_MFPL PB3 setting for GPIO*/ +#define SYS_GPB_MFPL_PB3MFP_EADC_CH3 (1ul << SYS_GPB_MFPL_PB3MFP_Pos) /*!< GPB_MFPL PB3 setting for EADC_CH3*/ +#define SYS_GPB_MFPL_PB3MFP_SPI0_MISO0 (2ul << SYS_GPB_MFPL_PB3MFP_Pos) /*!< GPB_MFPL PB3 setting for SPI0_MISO0*/ +#define SYS_GPB_MFPL_PB3MFP_SPI1_MISO (3ul << SYS_GPB_MFPL_PB3MFP_Pos) /*!< GPB_MFPL PB3 setting for SPI1_MISO*/ +#define SYS_GPB_MFPL_PB3MFP_UART1_TXD (4ul << SYS_GPB_MFPL_PB3MFP_Pos) /*!< GPB_MFPL PB3 setting for UART1_TXD*/ +#define SYS_GPB_MFPL_PB3MFP_UART3_TXD (9ul << SYS_GPB_MFPL_PB3MFP_Pos) /*!< GPB_MFPL PB3 setting for UART3_TXD*/ +#define SYS_GPB_MFPL_PB3MFP_T0_EXT (11ul << SYS_GPB_MFPL_PB3MFP_Pos) /*!< GPB_MFPL PB3 setting for T0_EXT*/ + +//PB4 +#define SYS_GPB_MFPL_PB4MFP_GPIO (0ul << SYS_GPB_MFPL_PB4MFP_Pos) /*!< GPB_MFPL PB4 setting for GPIO*/ +#define SYS_GPB_MFPL_PB4MFP_EADC_CH4 (1ul << SYS_GPB_MFPL_PB4MFP_Pos) /*!< GPB_MFPL PB4 setting for EADC_CH4*/ +#define SYS_GPB_MFPL_PB4MFP_SPI0_SS (2ul << SYS_GPB_MFPL_PB4MFP_Pos) /*!< GPB_MFPL PB4 setting for SPI0_SS*/ +#define SYS_GPB_MFPL_PB4MFP_SPI1_SS (3ul << SYS_GPB_MFPL_PB4MFP_Pos) /*!< GPB_MFPL PB4 setting for SPI1_SS*/ +#define SYS_GPB_MFPL_PB4MFP_UART1_nCTS (4ul << SYS_GPB_MFPL_PB4MFP_Pos) /*!< GPB_MFPL PB4 setting for UART1_nCTS*/ +#define SYS_GPB_MFPL_PB4MFP_ACMP0_N (5ul << SYS_GPB_MFPL_PB4MFP_Pos) /*!< GPB_MFPL PB4 setting for ACMP0_N*/ +#define SYS_GPB_MFPL_PB4MFP_EBI_AD7 (7ul << SYS_GPB_MFPL_PB4MFP_Pos) /*!< GPB_MFPL PB4 setting for EBI_AD7*/ +#define SYS_GPB_MFPL_PB4MFP_UART2_TXD (9ul << SYS_GPB_MFPL_PB4MFP_Pos) /*!< GPB_MFPL PB4 setting for UART2_TXD*/ +#define SYS_GPB_MFPL_PB4MFP_T1_EXT (11ul << SYS_GPB_MFPL_PB4MFP_Pos) /*!< GPB_MFPL PB4 setting for T1_EXT*/ + +//PB5 +#define SYS_GPB_MFPL_PB5MFP_GPIO (0ul << SYS_GPB_MFPL_PB5MFP_Pos) /*!< GPB_MFPL PB5 setting for GPIO*/ +#define SYS_GPB_MFPL_PB5MFP_EADC_CH13 (1ul << SYS_GPB_MFPL_PB5MFP_Pos) /*!< GPB_MFPL PB5 setting for EADC_CH13*/ +#define SYS_GPB_MFPL_PB5MFP_SPI0_MOSI0 (2ul << SYS_GPB_MFPL_PB5MFP_Pos) /*!< GPB_MFPL PB5 setting for SPI0_MOSI0*/ +#define SYS_GPB_MFPL_PB5MFP_SPI1_MOSI (3ul << SYS_GPB_MFPL_PB5MFP_Pos) /*!< GPB_MFPL PB5 setting for SPI1_MOSI*/ +#define SYS_GPB_MFPL_PB5MFP_TK3 (4ul << SYS_GPB_MFPL_PB5MFP_Pos) /*!< GPB_MFPL PB5 setting for TK3*/ +#define SYS_GPB_MFPL_PB5MFP_ACMP0_P2 (5ul << SYS_GPB_MFPL_PB5MFP_Pos) /*!< GPB_MFPL PB5 setting for ACMP0_P2*/ +#define SYS_GPB_MFPL_PB5MFP_EBI_AD6 (7ul << SYS_GPB_MFPL_PB5MFP_Pos) /*!< GPB_MFPL PB5 setting for EBI_AD6*/ +#define SYS_GPB_MFPL_PB5MFP_UART2_RXD (9ul << SYS_GPB_MFPL_PB5MFP_Pos) /*!< GPB_MFPL PB5 setting for UART2_RXD*/ + +//PB6 +#define SYS_GPB_MFPL_PB6MFP_GPIO (0ul << SYS_GPB_MFPL_PB6MFP_Pos) /*!< GPB_MFPL PB6 setting for GPIO*/ +#define SYS_GPB_MFPL_PB6MFP_EADC_CH14 (1ul << SYS_GPB_MFPL_PB6MFP_Pos) /*!< GPB_MFPL PB6 setting for EADC_CH14*/ +#define SYS_GPB_MFPL_PB6MFP_SPI0_MISO0 (2ul << SYS_GPB_MFPL_PB6MFP_Pos) /*!< GPB_MFPL PB6 setting for SPI0_MISO0*/ +#define SYS_GPB_MFPL_PB6MFP_SPI1_MISO (3ul << SYS_GPB_MFPL_PB6MFP_Pos) /*!< GPB_MFPL PB6 setting for SPI1_MISO*/ +#define SYS_GPB_MFPL_PB6MFP_TK4 (4ul << SYS_GPB_MFPL_PB6MFP_Pos) /*!< GPB_MFPL PB6 setting for TK4*/ +#define SYS_GPB_MFPL_PB6MFP_ACMP0_P1 (5ul << SYS_GPB_MFPL_PB6MFP_Pos) /*!< GPB_MFPL PB6 setting for ACMP0_P1*/ +#define SYS_GPB_MFPL_PB6MFP_EBI_AD5 (7ul << SYS_GPB_MFPL_PB6MFP_Pos) /*!< GPB_MFPL PB6 setting for EBI_AD5*/ + +//PB7 +#define SYS_GPB_MFPL_PB7MFP_GPIO (0ul << SYS_GPB_MFPL_PB7MFP_Pos) /*!< GPB_MFPL PB7 setting for GPIO*/ +#define SYS_GPB_MFPL_PB7MFP_EADC_CH15 (1ul << SYS_GPB_MFPL_PB7MFP_Pos) /*!< GPB_MFPL PB7 setting for EADC_CH15*/ +#define SYS_GPB_MFPL_PB7MFP_SPI0_CLK (2ul << SYS_GPB_MFPL_PB7MFP_Pos) /*!< GPB_MFPL PB7 setting for SPI0_CLK*/ +#define SYS_GPB_MFPL_PB7MFP_SPI1_CLK (3ul << SYS_GPB_MFPL_PB7MFP_Pos) /*!< GPB_MFPL PB7 setting for SPI1_CLK*/ +#define SYS_GPB_MFPL_PB7MFP_TK5 (4ul << SYS_GPB_MFPL_PB7MFP_Pos) /*!< GPB_MFPL PB7 setting for TK5*/ +#define SYS_GPB_MFPL_PB7MFP_ACMP0_P0 (5ul << SYS_GPB_MFPL_PB7MFP_Pos) /*!< GPB_MFPL PB7 setting for ACMP0_P0*/ +#define SYS_GPB_MFPL_PB7MFP_EBI_AD4 (7ul << SYS_GPB_MFPL_PB7MFP_Pos) /*!< GPB_MFPL PB7 setting for EBI_AD4*/ +#define SYS_GPB_MFPL_PB7MFP_STADC (10ul << SYS_GPB_MFPL_PB7MFP_Pos) /*!< GPB_MFPL PB7 setting for STADC*/ + +//PB8 +#define SYS_GPB_MFPH_PB8MFP_GPIO (0ul << SYS_GPB_MFPH_PB8MFP_Pos) /*!< GPB_MFPH PB8 setting for GPIO*/ +#define SYS_GPB_MFPH_PB8MFP_EADC_CH5 (1ul << SYS_GPB_MFPH_PB8MFP_Pos) /*!< GPB_MFPH PB8 setting for EADC_CH5*/ +#define SYS_GPB_MFPH_PB8MFP_UART1_nRTS (4ul << SYS_GPB_MFPH_PB8MFP_Pos) /*!< GPB_MFPH PB8 setting for UART1_nRTS*/ +#define SYS_GPB_MFPH_PB8MFP_PWM0_CH2 (6ul << SYS_GPB_MFPH_PB8MFP_Pos) /*!< GPB_MFPH PB8 setting for PWM0_CH2*/ + +//PB9 +#define SYS_GPB_MFPH_PB9MFP_GPIO (0ul << SYS_GPB_MFPH_PB9MFP_Pos) /*!< GPB_MFPH PB9 setting for GPIO*/ +#define SYS_GPB_MFPH_PB9MFP_EADC_CH6 (1ul << SYS_GPB_MFPH_PB9MFP_Pos) /*!< GPB_MFPH PB9 setting for EADC_CH6*/ + +//PB10 +#define SYS_GPB_MFPH_PB10MFP_GPIO (0ul << SYS_GPB_MFPH_PB10MFP_Pos) /*!< GPB_MFPH_ PB10 setting for GPIO*/ +#define SYS_GPB_MFPH_PB10MFP_EADC_CH7 (1ul << SYS_GPB_MFPH_PB10MFP_Pos) /*!< GPB_MFPH_ PB10 setting for EADC_CH7*/ + +//PB11 +#define SYS_GPB_MFPH_PB11MFP_GPIO (0ul << SYS_GPB_MFPH_PB11MFP_Pos) /*!< GPB_MFPH_ PB11 setting for GPIO*/ +#define SYS_GPB_MFPH_PB11MFP_EADC_CH8 (1ul << SYS_GPB_MFPH_PB11MFP_Pos) /*!< GPB_MFPH_ PB11 setting for EADC_CH8*/ +#define SYS_GPB_MFPH_PB11MFP_TK0 (4ul << SYS_GPB_MFPH_PB11MFP_Pos) /*!< GPB_MFPH_ PB11 setting for TK0*/ + +//PB12 +#define SYS_GPB_MFPH_PB12MFP_GPIO (0ul << SYS_GPB_MFPH_PB12MFP_Pos) /*!< GPB_MFPH_ PB12 setting for GPIO*/ +#define SYS_GPB_MFPH_PB12MFP_EADC_CH9 (1ul << SYS_GPB_MFPH_PB12MFP_Pos) /*!< GPB_MFPH_ PB12 setting for EADC_CH9*/ +#define SYS_GPB_MFPH_PB12MFP_TK1 (4ul << SYS_GPB_MFPH_PB12MFP_Pos) /*!< GPB_MFPH_ PB12 setting for TK1*/ + +//PB13 +#define SYS_GPB_MFPH_PB13MFP_GPIO (0ul << SYS_GPB_MFPH_PB13MFP_Pos) /*!< GPB_MFPH PB13 setting for GPIO*/ +#define SYS_GPB_MFPH_PB13MFP_EADC_CH10 (1ul << SYS_GPB_MFPH_PB13MFP_Pos) /*!< GPB_MFPH PB13 setting for EADC_CH10*/ + +//PB14 +#define SYS_GPB_MFPH_PB14MFP_GPIO (0ul << SYS_GPB_MFPH_PB14MFP_Pos) /*!< GPB_MFPH PB14 setting for GPIO*/ +#define SYS_GPB_MFPH_PB14MFP_EADC_CH11 (1ul << SYS_GPB_MFPH_PB14MFP_Pos) /*!< GPB_MFPH PB14 setting for EADC_CH11*/ + +//PB15 +#define SYS_GPB_MFPH_PB15MFP_GPIO (0ul << SYS_GPB_MFPH_PB15MFP_Pos) /*!< GPB_MFPH PB15 setting for GPIO*/ +#define SYS_GPB_MFPH_PB15MFP_EADC_CH12 (1ul << SYS_GPB_MFPH_PB15MFP_Pos) /*!< GPB_MFPH PB15 setting for EADC_CH12*/ +#define SYS_GPB_MFPH_PB15MFP_TK2 (4ul << SYS_GPB_MFPH_PB15MFP_Pos) /*!< GPB_MFPH PB15 setting for TK2*/ +#define SYS_GPB_MFPH_PB15MFP_ACMP0_P3 (5ul << SYS_GPB_MFPH_PB15MFP_Pos) /*!< GPB_MFPH PB15 setting for ACMP0_P3*/ +#define SYS_GPB_MFPH_PB15MFP_EBI_nCS1 (7ul << SYS_GPB_MFPH_PB15MFP_Pos) /*!< GPB_MFPH PB15 setting for EBI_nCS1*/ + +//PC0 +#define SYS_GPC_MFPL_PC0MFP_GPIO (0ul << SYS_GPC_MFPL_PC0MFP_Pos) /*!< GPC_MFPL PC0 setting for GPIO*/ +#define SYS_GPC_MFPL_PC0MFP_SPI2_CLK (2ul << SYS_GPC_MFPL_PC0MFP_Pos) /*!< GPC_MFPL PC0 setting for SPI2_CLK*/ +#define SYS_GPC_MFPL_PC0MFP_UART2_nCTS (3ul << SYS_GPC_MFPL_PC0MFP_Pos) /*!< GPC_MFPL PC0 setting for UART2_nCTS*/ +#define SYS_GPC_MFPL_PC0MFP_CAN0_TXD (4ul << SYS_GPC_MFPL_PC0MFP_Pos) /*!< GPC_MFPL PC0 setting for CAN0_TXD*/ +#define SYS_GPC_MFPL_PC0MFP_PWM0_CH0 (6ul << SYS_GPC_MFPL_PC0MFP_Pos) /*!< GPC_MFPL PC0 setting for PWM0_CH0*/ +#define SYS_GPC_MFPL_PC0MFP_EBI_AD8 (7ul << SYS_GPC_MFPL_PC0MFP_Pos) /*!< GPC_MFPL PC0 setting for EBI_AD8*/ +#define SYS_GPC_MFPL_PC0MFP_INT2 (8ul << SYS_GPC_MFPL_PC0MFP_Pos) /*!< GPC_MFPL PC0 setting for INT2*/ +#define SYS_GPC_MFPL_PC0MFP_UART3_TXD (9ul << SYS_GPC_MFPL_PC0MFP_Pos) /*!< GPC_MFPL PC0 setting for UART3_TXD*/ +#define SYS_GPC_MFPL_PC0MFP_T3_EXT (11ul << SYS_GPC_MFPL_PC0MFP_Pos) /*!< GPC_MFPL PC0 setting for T3_EXT*/ + +//PC1 +#define SYS_GPC_MFPL_PC1MFP_GPIO (0ul << SYS_GPC_MFPL_PC1MFP_Pos) /*!< GPC_MFPL PC1 setting for GPIO*/ +#define SYS_GPC_MFPL_PC1MFP_CLKO (1ul << SYS_GPC_MFPL_PC1MFP_Pos) /*!< GPC_MFPL PC1 setting for CLKO*/ +#define SYS_GPC_MFPL_PC1MFP_STDAC (2ul << SYS_GPC_MFPL_PC1MFP_Pos) /*!< GPC_MFPL PC1 setting for STDAC*/ +#define SYS_GPC_MFPL_PC1MFP_UART2_nRTS (3ul << SYS_GPC_MFPL_PC1MFP_Pos) /*!< GPC_MFPL PC1 setting for UART2_nRTS*/ +#define SYS_GPC_MFPL_PC1MFP_CAN0_RXD (4ul << SYS_GPC_MFPL_PC1MFP_Pos) /*!< GPC_MFPL PC1 setting for CAN0_RXD*/ +#define SYS_GPC_MFPL_PC1MFP_PWM0_CH1 (6ul << SYS_GPC_MFPL_PC1MFP_Pos) /*!< GPC_MFPL PC1 setting for PWM0_CH1*/ +#define SYS_GPC_MFPL_PC1MFP_EBI_AD9 (7ul << SYS_GPC_MFPL_PC1MFP_Pos) /*!< GPC_MFPL PC1 setting for EBI_AD9*/ +#define SYS_GPC_MFPL_PC1MFP_UART3_RXD (9ul << SYS_GPC_MFPL_PC1MFP_Pos) /*!< GPC_MFPL PC1 setting for UART3_RXD*/ + +//PC2 +#define SYS_GPC_MFPL_PC2MFP_GPIO (0ul << SYS_GPC_MFPL_PC2MFP_Pos) /*!< GPC_MFPL PC2 setting for GPIO*/ +#define SYS_GPC_MFPL_PC2MFP_SPI2_SS (2ul << SYS_GPC_MFPL_PC2MFP_Pos) /*!< GPC_MFPL PC2 setting for SPI2_SS*/ +#define SYS_GPC_MFPL_PC2MFP_UART2_TXD (3ul << SYS_GPC_MFPL_PC2MFP_Pos) /*!< GPC_MFPL PC2 setting for UART2_TXD*/ +#define SYS_GPC_MFPL_PC2MFP_ACMP1_O (5ul << SYS_GPC_MFPL_PC2MFP_Pos) /*!< GPC_MFPL PC2 setting for ACMP1_O*/ +#define SYS_GPC_MFPL_PC2MFP_PWM0_CH2 (6ul << SYS_GPC_MFPL_PC2MFP_Pos) /*!< GPC_MFPL PC2 setting for PWM0_CH2*/ +#define SYS_GPC_MFPL_PC2MFP_EBI_AD10 (7ul << SYS_GPC_MFPL_PC2MFP_Pos) /*!< GPC_MFPL PC2 setting for EBI_AD10*/ + +//PC3 +#define SYS_GPC_MFPL_PC3MFP_GPIO (0ul << SYS_GPC_MFPL_PC3MFP_Pos) /*!< GPC_MFPL PC3 setting for GPIO*/ +#define SYS_GPC_MFPL_PC3MFP_SPI2_MOSI (2ul << SYS_GPC_MFPL_PC3MFP_Pos) /*!< GPC_MFPL PC3 setting for SPI2_MOSI*/ +#define SYS_GPC_MFPL_PC3MFP_UART2_RXD (3ul << SYS_GPC_MFPL_PC3MFP_Pos) /*!< GPC_MFPL PC3 setting for UART2_RXD*/ +#define SYS_GPC_MFPL_PC3MFP_USB_VBUS_ST (4ul << SYS_GPC_MFPL_PC3MFP_Pos) /*!< GPC_MFPL PC3 setting for USB_VBUS_ST*/ +#define SYS_GPC_MFPL_PC3MFP_PWM0_CH3 (6ul << SYS_GPC_MFPL_PC3MFP_Pos) /*!< GPC_MFPL PC3 setting for PWM0_CH3*/ +#define SYS_GPC_MFPL_PC3MFP_EBI_AD11 (7ul << SYS_GPC_MFPL_PC3MFP_Pos) /*!< GPC_MFPL PC3 setting for EBI_AD11*/ + +//PC4 +#define SYS_GPC_MFPL_PC4MFP_GPIO (0ul << SYS_GPC_MFPL_PC4MFP_Pos) /*!< GPC_MFPL PC4 setting for GPIO*/ +#define SYS_GPC_MFPL_PC4MFP_SPI2_MISO (2ul << SYS_GPC_MFPL_PC4MFP_Pos) /*!< GPC_MFPL PC4 setting for SPI2_MISO*/ +#define SYS_GPC_MFPL_PC4MFP_I2C1_SCL (3ul << SYS_GPC_MFPL_PC4MFP_Pos) /*!< GPC_MFPL PC4 setting for I2C1_SCL*/ +#define SYS_GPC_MFPL_PC4MFP_USB_VBUS_EN (4ul << SYS_GPC_MFPL_PC4MFP_Pos) /*!< GPC_MFPL PC4 setting for USB_VBUS_EN*/ +#define SYS_GPC_MFPL_PC4MFP_PWM0_CH4 (6ul << SYS_GPC_MFPL_PC4MFP_Pos) /*!< GPC_MFPL PC4 setting for PWM0_CH4*/ +#define SYS_GPC_MFPL_PC4MFP_EBI_AD12 (7ul << SYS_GPC_MFPL_PC4MFP_Pos) /*!< GPC_MFPL PC4 setting for EBI_AD12*/ + +//PC5 +#define SYS_GPC_MFPL_PC5MFP_GPIO (0ul << SYS_GPC_MFPL_PC5MFP_Pos) /*!< GPC_MFPL PC5 setting for GPIO*/ +#define SYS_GPC_MFPL_PC5MFP_SPI2_I2SMCLK (2ul << SYS_GPC_MFPL_PC5MFP_Pos) /*!< GPC_MFPL PC5 setting for SPI2_I2SMCLK*/ +#define SYS_GPC_MFPL_PC5MFP_PWM0_CH5 (6ul << SYS_GPC_MFPL_PC5MFP_Pos) /*!< GPC_MFPL PC5 setting for PWM0_CH5*/ +#define SYS_GPC_MFPL_PC5MFP_EBI_AD13 (7ul << SYS_GPC_MFPL_PC5MFP_Pos) /*!< GPC_MFPL PC5 setting for EBI_AD13*/ + +//PC6 +#define SYS_GPC_MFPL_PC6MFP_GPIO (0ul << SYS_GPC_MFPL_PC6MFP_Pos) /*!< GPC_MFPL PC6 setting for GPIO*/ +#define SYS_GPC_MFPL_PC6MFP_I2C1_SMBAL (3ul << SYS_GPC_MFPL_PC6MFP_Pos) /*!< GPC_MFPL PC6 setting for I2C1_SMBAL*/ +#define SYS_GPC_MFPL_PC6MFP_ACMP1_O (5ul << SYS_GPC_MFPL_PC6MFP_Pos) /*!< GPC_MFPL PC6 setting for ACMP1_O*/ +#define SYS_GPC_MFPL_PC6MFP_PWM1_CH0 (6ul << SYS_GPC_MFPL_PC6MFP_Pos) /*!< GPC_MFPL PC6 setting for PWM1_CH0*/ +#define SYS_GPC_MFPL_PC6MFP_EBI_AD14 (7ul << SYS_GPC_MFPL_PC6MFP_Pos) /*!< GPC_MFPL PC6 setting for EBI_AD14*/ +#define SYS_GPC_MFPL_PC6MFP_UART0_TXD (9ul << SYS_GPC_MFPL_PC6MFP_Pos) /*!< GPC_MFPL PC6 setting for UART0_TXD*/ + +//PC7 +#define SYS_GPC_MFPL_PC7MFP_GPIO (0ul << SYS_GPC_MFPL_PC7MFP_Pos) /*!< GPC_MFPL PC7 setting for GPIO*/ +#define SYS_GPC_MFPL_PC7MFP_I2C1_SMBSUS (3ul << SYS_GPC_MFPL_PC7MFP_Pos) /*!< GPC_MFPL PC7 setting for I2C1_SMBSUS*/ +#define SYS_GPC_MFPL_PC7MFP_PWM1_CH1 (6ul << SYS_GPC_MFPL_PC7MFP_Pos) /*!< GPC_MFPL PC7 setting for PWM1_CH1*/ +#define SYS_GPC_MFPL_PC7MFP_EBI_AD15 (7ul << SYS_GPC_MFPL_PC7MFP_Pos) /*!< GPC_MFPL PC7 setting for EBI_AD15*/ +#define SYS_GPC_MFPL_PC7MFP_UART0_RXD (9ul << SYS_GPC_MFPL_PC7MFP_Pos) /*!< GPC_MFPL PC7 setting for UART0_RXD*/ + +//PC8 +#define SYS_GPC_MFPH_PC8MFP_GPIO (0ul << SYS_GPC_MFPH_PC8MFP_Pos) /*!< GPC_MFPH_ PC8 setting for GPIO*/ +#define SYS_GPC_MFPH_PC8MFP_TK7 (4ul << SYS_GPC_MFPH_PC8MFP_Pos) /*!< GPC_MFPH_ PC8 setting for TK7*/ + +//PC9 +#define SYS_GPC_MFPH_PC9MFP_GPIO (0ul << SYS_GPC_MFPH_PC9MFP_Pos) /*!< GPC_MFPH PC9 setting for GPIO*/ +#define SYS_GPC_MFPH_PC9MFP_SPI2_I2SMCLK (2ul << SYS_GPC_MFPH_PC9MFP_Pos) /*!< GPC_MFPH PC9 setting for SPI2_I2SMCLK*/ +#define SYS_GPC_MFPH_PC9MFP_PWM1_CH0 (6ul << SYS_GPC_MFPH_PC9MFP_Pos) /*!< GPC_MFPH PC9 setting for PWM1_CH0*/ + +//PC10 +#define SYS_GPC_MFPH_PC10MFP_GPIO (0ul << SYS_GPC_MFPH_PC10MFP_Pos) /*!< GPC_MFPH PC10 setting for GPIO*/ +#define SYS_GPC_MFPH_PC10MFP_SPI2_MOSI (2ul << SYS_GPC_MFPH_PC10MFP_Pos) /*!< GPC_MFPH PC10 setting for SPI2_MOSI*/ +#define SYS_GPC_MFPH_PC10MFP_PWM1_CH1 (6ul << SYS_GPC_MFPH_PC10MFP_Pos) /*!< GPC_MFPH PC10 setting for PWM1_CH1*/ + +//PC11 +#define SYS_GPC_MFPH_PC11MFP_GPIO (0ul << SYS_GPC_MFPH_PC11MFP_Pos) /*!< GPC_MFPH PC11 setting for GPIO*/ +#define SYS_GPC_MFPH_PC11MFP_SPI2_MISO (2ul << SYS_GPC_MFPH_PC11MFP_Pos) /*!< GPC_MFPH PC11 setting for SPI2_MISO*/ +#define SYS_GPC_MFPH_PC11MFP_PWM1_CH2 (6ul << SYS_GPC_MFPH_PC11MFP_Pos) /*!< GPC_MFPH PC11 setting for PWM1_CH2*/ + +//PC12 +#define SYS_GPC_MFPH_PC12MFP_GPIO (0ul << SYS_GPC_MFPH_PC12MFP_Pos) /*!< GPC_MFPH PC12 setting for GPIO*/ +#define SYS_GPC_MFPH_PC12MFP_SPI2_CLK (2ul << SYS_GPC_MFPH_PC12MFP_Pos) /*!< GPC_MFPH PC12 setting for SPI2_CLK*/ +#define SYS_GPC_MFPH_PC12MFP_PWM1_CH3 (6ul << SYS_GPC_MFPH_PC12MFP_Pos) /*!< GPC_MFPH PC12 setting for PWM1_CH3*/ + +//PC13 +#define SYS_GPC_MFPH_PC13MFP_GPIO (0ul << SYS_GPC_MFPH_PC13MFP_Pos) /*!< GPC_MFPH PC13 setting for GPIO*/ +#define SYS_GPC_MFPH_PC13MFP_SPI2_SS (2ul << SYS_GPC_MFPH_PC13MFP_Pos) /*!< GPC_MFPH PC13 setting for SPI2_SS*/ +#define SYS_GPC_MFPH_PC13MFP_PWM1_CH4 (6ul << SYS_GPC_MFPH_PC13MFP_Pos) /*!< GPC_MFPH PC13 setting for PWM1_CH4*/ + +//PC14 +#define SYS_GPC_MFPH_PC14MFP_GPIO (0ul << SYS_GPC_MFPH_PC14MFP_Pos) /*!< GPC_MFPH PC14 setting for GPIO*/ +#define SYS_GPC_MFPH_PC14MFP_PWM1_CH5 (6ul << SYS_GPC_MFPH_PC14MFP_Pos) /*!< GPC_MFPH PC14 setting for PWM1_CH5*/ + +//PC15 +#define SYS_GPC_MFPH_PC15MFP_GPIO (0ul << SYS_GPC_MFPH_PC15MFP_Pos) /*!< GPC_MFPH PC15 setting for GPIO*/ +#define SYS_GPC_MFPH_PC15MFP_PWM1_CH0 (6ul << SYS_GPC_MFPH_PC15MFP_Pos) /*!< GPC_MFPH PC15 setting for PWM1_CH0*/ + +//PD0 +#define SYS_GPD_MFPL_PD0MFP_GPIO (0ul << SYS_GPD_MFPL_PD0MFP_Pos) /*!< GPD_MFPL PD0 setting for GPIO*/ +#define SYS_GPD_MFPL_PD0MFP_EADC_CH6 (1ul << SYS_GPD_MFPL_PD0MFP_Pos) /*!< GPD_MFPL PD0 setting for EADC_CH6*/ +#define SYS_GPD_MFPL_PD0MFP_SPI1_I2SMCLK (2ul << SYS_GPD_MFPL_PD0MFP_Pos) /*!< GPD_MFPL PD0 setting for SPI1_I2SMCLK*/ +#define SYS_GPD_MFPL_PD0MFP_UART0_RXD (3ul << SYS_GPD_MFPL_PD0MFP_Pos) /*!< GPD_MFPL PD0 setting for UART0_RXD*/ +#define SYS_GPD_MFPL_PD0MFP_TK6 (4ul << SYS_GPD_MFPL_PD0MFP_Pos) /*!< GPD_MFPL PD0 setting for TK6*/ +#define SYS_GPD_MFPL_PD0MFP_ACMP1_N (5ul << SYS_GPD_MFPL_PD0MFP_Pos) /*!< GPD_MFPL PD0 setting for ACMP1_N*/ +#define SYS_GPD_MFPL_PD0MFP_INT3 (8ul << SYS_GPD_MFPL_PD0MFP_Pos) /*!< GPD_MFPL PD0 setting for INT3*/ +#define SYS_GPD_MFPL_PD0MFP_T3 (11ul << SYS_GPD_MFPL_PD0MFP_Pos) /*!< GPD_MFPL PD0 setting for T3*/ + +//PD1 +#define SYS_GPD_MFPL_PD1MFP_GPIO (0ul << SYS_GPD_MFPL_PD1MFP_Pos) /*!< GPD_MFPL PD1 setting for GPIO*/ +#define SYS_GPD_MFPL_PD1MFP_EADC_CH11 (1ul << SYS_GPD_MFPL_PD1MFP_Pos) /*!< GPD_MFPL PD1 setting for EADC_CH11*/ +#define SYS_GPD_MFPL_PD1MFP_PWM0_SYNC_IN (2ul << SYS_GPD_MFPL_PD1MFP_Pos) /*!< GPD_MFPL PD1 setting for PWM0_SYNC_IN*/ +#define SYS_GPD_MFPL_PD1MFP_UART0_TXD (3ul << SYS_GPD_MFPL_PD1MFP_Pos) /*!< GPD_MFPL PD1 setting for UART0_TXD*/ +#define SYS_GPD_MFPL_PD1MFP_TK10 (4ul << SYS_GPD_MFPL_PD1MFP_Pos) /*!< GPD_MFPL PD1 setting for TK10*/ +#define SYS_GPD_MFPL_PD1MFP_ACMP1_P2 (5ul << SYS_GPD_MFPL_PD1MFP_Pos) /*!< GPD_MFPL PD1 setting for ACMP1_P2*/ +#define SYS_GPD_MFPL_PD1MFP_T0 (6ul << SYS_GPD_MFPL_PD1MFP_Pos) /*!< GPD_MFPL PD1 setting for T0*/ +#define SYS_GPD_MFPL_PD1MFP_EBI_nRD (7ul << SYS_GPD_MFPL_PD1MFP_Pos) /*!< GPD_MFPL PD1 setting for EBI_nRD*/ + +//PD2 +#define SYS_GPD_MFPL_PD2MFP_GPIO (0ul << SYS_GPD_MFPL_PD2MFP_Pos) /*!< GPD_MFPL PD2 setting for GPIO*/ +#define SYS_GPD_MFPL_PD2MFP_STADC (1ul << SYS_GPD_MFPL_PD2MFP_Pos) /*!< GPD_MFPL PD2 setting for STADC*/ +#define SYS_GPD_MFPL_PD2MFP_T0_EXT (3ul << SYS_GPD_MFPL_PD2MFP_Pos) /*!< GPD_MFPL PD2 setting for T0_EXT*/ +#define SYS_GPD_MFPL_PD2MFP_TK11 (4ul << SYS_GPD_MFPL_PD2MFP_Pos) /*!< GPD_MFPL PD2 setting for TK11*/ +#define SYS_GPD_MFPL_PD2MFP_ACMP1_P1 (5ul << SYS_GPD_MFPL_PD2MFP_Pos) /*!< GPD_MFPL PD2 setting for ACMP1_P1*/ +#define SYS_GPD_MFPL_PD2MFP_PWM0_BRAKE0 (6ul << SYS_GPD_MFPL_PD2MFP_Pos) /*!< GPD_MFPL PD2 setting for PWM0_BRAKE0*/ +#define SYS_GPD_MFPL_PD2MFP_EBI_nWR (7ul << SYS_GPD_MFPL_PD2MFP_Pos) /*!< GPD_MFPL PD2 setting for EBI_nWR*/ +#define SYS_GPD_MFPL_PD2MFP_INT0 (8ul << SYS_GPD_MFPL_PD2MFP_Pos) /*!< GPD_MFPL PD2 setting for INT0*/ + +//PD3 +#define SYS_GPD_MFPL_PD3MFP_GPIO (0ul << SYS_GPD_MFPL_PD3MFP_Pos) /*!< GPD_MFPL PD3 setting for GPIO*/ +#define SYS_GPD_MFPL_PD3MFP_T2 (1ul << SYS_GPD_MFPL_PD3MFP_Pos) /*!< GPD_MFPL PD3 setting for T2*/ +#define SYS_GPD_MFPL_PD3MFP_T1_EXT (3ul << SYS_GPD_MFPL_PD3MFP_Pos) /*!< GPD_MFPL PD3 setting for T1_EXT*/ +#define SYS_GPD_MFPL_PD3MFP_TK12 (4ul << SYS_GPD_MFPL_PD3MFP_Pos) /*!< GPD_MFPL PD3 setting for TK12*/ +#define SYS_GPD_MFPL_PD3MFP_ACMP1_P0 (5ul << SYS_GPD_MFPL_PD3MFP_Pos) /*!< GPD_MFPL PD3 setting for ACMP1_P0*/ +#define SYS_GPD_MFPL_PD3MFP_PWM0_BRAKE1 (6ul << SYS_GPD_MFPL_PD3MFP_Pos) /*!< GPD_MFPL PD3 setting for PWM0_BRAKE1*/ +#define SYS_GPD_MFPL_PD3MFP_EBI_MCLK (7ul << SYS_GPD_MFPL_PD3MFP_Pos) /*!< GPD_MFPL PD3 setting for EBI_MCLK*/ +#define SYS_GPD_MFPL_PD3MFP_INT1 (8ul << SYS_GPD_MFPL_PD3MFP_Pos) /*!< GPD_MFPL PD3 setting for INT1*/ + +//PD4 +#define SYS_GPD_MFPL_PD4MFP_GPIO (0ul << SYS_GPD_MFPL_PD4MFP_Pos) /*!< GPD_MFPL PD4 setting for GPIO*/ +#define SYS_GPD_MFPL_PD4MFP_SPI1_CLK (2ul << SYS_GPD_MFPL_PD4MFP_Pos) /*!< GPD_MFPL PD4 setting for SPI1_CLK*/ +#define SYS_GPD_MFPL_PD4MFP_I2C0_SDA (3ul << SYS_GPD_MFPL_PD4MFP_Pos) /*!< GPD_MFPL PD4 setting for I2C0_SDA*/ +#define SYS_GPD_MFPL_PD4MFP_TK13 (4ul << SYS_GPD_MFPL_PD4MFP_Pos) /*!< GPD_MFPL PD4 setting for TK13*/ +#define SYS_GPD_MFPL_PD4MFP_PWM0_BRAKE0 (5ul << SYS_GPD_MFPL_PD4MFP_Pos) /*!< GPD_MFPL PD4 setting for PWM0_BRAKE0*/ +#define SYS_GPD_MFPL_PD4MFP_T0 (6ul << SYS_GPD_MFPL_PD4MFP_Pos) /*!< GPD_MFPL PD4 setting for T0*/ + +//PD5 +#define SYS_GPD_MFPL_PD5MFP_GPIO (0ul << SYS_GPD_MFPL_PD5MFP_Pos) /*!< GPD_MFPL PD5 setting for GPIO*/ +#define SYS_GPD_MFPL_PD5MFP_CLKO (1ul << SYS_GPD_MFPL_PD5MFP_Pos) /*!< GPD_MFPL PD5 setting for CLKO*/ +#define SYS_GPD_MFPL_PD5MFP_SPI1_MISO (2ul << SYS_GPD_MFPL_PD5MFP_Pos) /*!< GPD_MFPL PD5 setting for SPI1_MISO*/ +#define SYS_GPD_MFPL_PD5MFP_I2C0_SCL (3ul << SYS_GPD_MFPL_PD5MFP_Pos) /*!< GPD_MFPL PD5 setting for I2C0_SCL*/ +#define SYS_GPD_MFPL_PD5MFP_TK14 (4ul << SYS_GPD_MFPL_PD5MFP_Pos) /*!< GPD_MFPL PD5 setting for TK14*/ +#define SYS_GPD_MFPL_PD5MFP_PWM0_BRAKE1 (5ul << SYS_GPD_MFPL_PD5MFP_Pos) /*!< GPD_MFPL PD5 setting for PWM0_BRAKE1*/ +#define SYS_GPD_MFPL_PD5MFP_T1 (6ul << SYS_GPD_MFPL_PD5MFP_Pos) /*!< GPD_MFPL PD5 setting for T1*/ + +//PD6 +#define SYS_GPD_MFPL_PD6MFP_GPIO (0ul << SYS_GPD_MFPL_PD6MFP_Pos) /*!< GPD_MFPL PD6 setting for GPIO*/ +#define SYS_GPD_MFPL_PD6MFP_CLKO (1ul << SYS_GPD_MFPL_PD6MFP_Pos) /*!< GPD_MFPL PD6 setting for CLKO*/ +#define SYS_GPD_MFPL_PD6MFP_SPI1_SS (2ul << SYS_GPD_MFPL_PD6MFP_Pos) /*!< GPD_MFPL PD6 setting for SPI1_SS*/ +#define SYS_GPD_MFPL_PD6MFP_UART0_RXD (3ul << SYS_GPD_MFPL_PD6MFP_Pos) /*!< GPD_MFPL PD6 setting for UART0_RXD*/ +#define SYS_GPD_MFPL_PD6MFP_TK16 (4ul << SYS_GPD_MFPL_PD6MFP_Pos) /*!< GPD_MFPL PD6 setting for TK16*/ +#define SYS_GPD_MFPL_PD6MFP_ACMP0_O (5ul << SYS_GPD_MFPL_PD6MFP_Pos) /*!< GPD_MFPL PD6 setting for ACMP0_O*/ +#define SYS_GPD_MFPL_PD6MFP_PWM0_CH5 (6ul << SYS_GPD_MFPL_PD6MFP_Pos) /*!< GPD_MFPL PD6 setting for PWM0_CH5*/ +#define SYS_GPD_MFPL_PD6MFP_EBI_nWR (7ul << SYS_GPD_MFPL_PD6MFP_Pos) /*!< GPD_MFPL PD6 setting for EBI_nWR*/ + +//PD7 +#define SYS_GPD_MFPL_PD7MFP_GPIO (0ul << SYS_GPD_MFPL_PD7MFP_Pos) /*!< GPD_MFPL PD7 setting for GPIO*/ +#define SYS_GPD_MFPL_PD7MFP_PWM0_SYNC_IN (3ul << SYS_GPD_MFPL_PD7MFP_Pos) /*!< GPD_MFPL PD7 setting for PWM0_SYNC_IN*/ +#define SYS_GPD_MFPL_PD7MFP_T1 (4ul << SYS_GPD_MFPL_PD7MFP_Pos) /*!< GPD_MFPL PD7 setting for T1*/ +#define SYS_GPD_MFPL_PD7MFP_ACMP0_O (5ul << SYS_GPD_MFPL_PD7MFP_Pos) /*!< GPD_MFPL PD7 setting for ACMP0_O*/ +#define SYS_GPD_MFPL_PD7MFP_PWM0_CH5 (6ul << SYS_GPD_MFPL_PD7MFP_Pos) /*!< GPD_MFPL PD7 setting for PWM0_CH5*/ +#define SYS_GPD_MFPL_PD7MFP_EBI_nRD (7ul << SYS_GPD_MFPL_PD7MFP_Pos) /*!< GPD_MFPL PD7 setting for EBI_nRD*/ + +//PD8 +#define SYS_GPD_MFPH_PD8MFP_GPIO (0ul << SYS_GPD_MFPH_PD8MFP_Pos) /*!< GPD_MFPH PD8 setting for GPIO*/ +#define SYS_GPD_MFPH_PD8MFP_EADC_CH7 (1ul << SYS_GPD_MFPH_PD8MFP_Pos) /*!< GPD_MFPH PD8 setting for EADC_CH7*/ +#define SYS_GPD_MFPH_PD8MFP_TK8 (4ul << SYS_GPD_MFPH_PD8MFP_Pos) /*!< GPD_MFPH PD8 setting for TK8*/ +#define SYS_GPD_MFPH_PD8MFP_EBI_nCS0 (7ul << SYS_GPD_MFPH_PD8MFP_Pos) /*!< GPD_MFPH PD8 setting for EBI_nCS0*/ + +//PD9 +#define SYS_GPD_MFPH_PD9MFP_GPIO (0ul << SYS_GPD_MFPH_PD9MFP_Pos) /*!< GPD_MFPH PD9 setting for GPIO*/ +#define SYS_GPD_MFPH_PD9MFP_EADC_CH10 (1ul << SYS_GPD_MFPH_PD9MFP_Pos) /*!< GPD_MFPH PD9 setting for EADC_CH10*/ +#define SYS_GPD_MFPH_PD9MFP_TK9 (4ul << SYS_GPD_MFPH_PD9MFP_Pos) /*!< GPD_MFPH PD9 setting for TK9*/ +#define SYS_GPD_MFPH_PD9MFP_ACMP1_P3 (5ul << SYS_GPD_MFPH_PD9MFP_Pos) /*!< GPD_MFPH PD9 setting for ACMP1_P3*/ +#define SYS_GPD_MFPH_PD9MFP_EBI_ALE (7ul << SYS_GPD_MFPH_PD9MFP_Pos) /*!< GPD_MFPH PD9 setting for EBI_ALE*/ + +//PD10 +#define SYS_GPD_MFPH_PD10MFP_GPIO (0ul << SYS_GPD_MFPH_PD10MFP_Pos) /*!< GPD_MFPH PD10 setting for GPIO*/ +#define SYS_GPD_MFPH_PD10MFP_T2 (4ul << SYS_GPD_MFPH_PD10MFP_Pos) /*!< GPD_MFPH PD10 setting for T2*/ + +//PD11 +#define SYS_GPD_MFPH_PD11MFP_GPIO (0ul << SYS_GPD_MFPH_PD11MFP_Pos) /*!< GPD_MFPH PD11 setting for GPIO*/ +#define SYS_GPD_MFPH_PD11MFP_T3 (4ul << SYS_GPD_MFPH_PD11MFP_Pos) /*!< GPD_MFPH PD11 setting for T3*/ + +//PD12 +#define SYS_GPD_MFPH_PD12MFP_GPIO (0ul << SYS_GPD_MFPH_PD12MFP_Pos) /*!< GPD_MFPH PD12 setting for GPIO*/ +#define SYS_GPD_MFPH_PD12MFP_SPI2_SS (2ul << SYS_GPD_MFPH_PD12MFP_Pos) /*!< GPD_MFPH PD12 setting for SPI2_SS*/ +#define SYS_GPD_MFPH_PD12MFP_UART3_TXD (3ul << SYS_GPD_MFPH_PD12MFP_Pos) /*!< GPD_MFPH PD12 setting for UART3_TXD*/ +#define SYS_GPD_MFPH_PD12MFP_PWM1_CH0 (6ul << SYS_GPD_MFPH_PD12MFP_Pos) /*!< GPD_MFPH PD12 setting for PWM1_CH0*/ +#define SYS_GPD_MFPH_PD12MFP_EBI_ADR16 (7ul << SYS_GPD_MFPH_PD12MFP_Pos) /*!< GPD_MFPH PD12 setting for EBI_ADR16*/ + +//PD13 +#define SYS_GPD_MFPH_PD13MFP_GPIO (0ul << SYS_GPD_MFPH_PD13MFP_Pos) /*!< GPD_MFPH PD13 setting for GPIO*/ +#define SYS_GPD_MFPH_PD13MFP_SPI2_MOSI (2ul << SYS_GPD_MFPH_PD13MFP_Pos) /*!< GPD_MFPH PD13 setting for SPI2_MOSI*/ +#define SYS_GPD_MFPH_PD13MFP_UART3_RXD (3ul << SYS_GPD_MFPH_PD13MFP_Pos) /*!< GPD_MFPH PD13 setting for UART3_RXD*/ +#define SYS_GPD_MFPH_PD13MFP_PWM1_CH1 (6ul << SYS_GPD_MFPH_PD13MFP_Pos) /*!< GPD_MFPH PD13 setting for PWM1_CH1*/ +#define SYS_GPD_MFPH_PD13MFP_EBI_ADR17 (7ul << SYS_GPD_MFPH_PD13MFP_Pos) /*!< GPD_MFPH PD13 setting for EBI_ADR17*/ + +//PD14 +#define SYS_GPD_MFPH_PD14MFP_GPIO (0ul << SYS_GPD_MFPH_PD14MFP_Pos) /*!< GPD_MFPH_ PD14 setting for GPIO*/ +#define SYS_GPD_MFPH_PD14MFP_SPI2_MISO (2ul << SYS_GPD_MFPH_PD14MFP_Pos) /*!< GPD_MFPH_ PD14 setting for SPI2_MISO*/ +#define SYS_GPD_MFPH_PD14MFP_UART3_nCTS (3ul << SYS_GPD_MFPH_PD14MFP_Pos) /*!< GPD_MFPH_ PD14 setting for UART3_nCTS*/ +#define SYS_GPD_MFPH_PD14MFP_PWM1_CH2 (6ul << SYS_GPD_MFPH_PD14MFP_Pos) /*!< GPD_MFPH_ PD14 setting for PWM1_CH2*/ +#define SYS_GPD_MFPH_PD14MFP_EBI_ADR18 (7ul << SYS_GPD_MFPH_PD14MFP_Pos) /*!< GPD_MFPH_ PD14 setting for EBI_ADR18*/ + +//PD15 +#define SYS_GPD_MFPH_PD15MFP_GPIO (0ul << SYS_GPD_MFPH_PD15MFP_Pos) /*!< GPD_MFPH_ PD15 setting for GPIO*/ +#define SYS_GPD_MFPH_PD15MFP_SPI2_CLK (2ul << SYS_GPD_MFPH_PD15MFP_Pos) /*!< GPD_MFPH_ PD15 setting for SPI2_CLK*/ +#define SYS_GPD_MFPH_PD15MFP_UART3_nRTS (3ul << SYS_GPD_MFPH_PD15MFP_Pos) /*!< GPD_MFPH_ PD15 setting for UART3_nRTS*/ +#define SYS_GPD_MFPH_PD15MFP_PWM1_CH3 (6ul << SYS_GPD_MFPH_PD15MFP_Pos) /*!< GPD_MFPH_ PD15 setting for PWM1_CH3*/ +#define SYS_GPD_MFPH_PD15MFP_EBI_ADR19 (7ul << SYS_GPD_MFPH_PD15MFP_Pos) /*!< GPD_MFPH_ PD15 setting for EBI_ADR19*/ + +//PE0 +#define SYS_GPE_MFPL_PE0MFP_GPIO (0ul << SYS_GPE_MFPL_PE0MFP_Pos) /*!< GPE_MFPL PE0 setting for GPIO*/ +#define SYS_GPE_MFPL_PE0MFP_SPI2_CLK (2ul << SYS_GPE_MFPL_PE0MFP_Pos) /*!< GPE_MFPL PE0 setting for SPI2_CLK*/ +#define SYS_GPE_MFPL_PE0MFP_I2C1_SDA (3ul << SYS_GPE_MFPL_PE0MFP_Pos) /*!< GPE_MFPL PE0 setting for I2C1_SDA*/ +#define SYS_GPE_MFPL_PE0MFP_T2_EXT (4ul << SYS_GPE_MFPL_PE0MFP_Pos) /*!< GPE_MFPL PE0 setting for T2_EXT*/ +#define SYS_GPE_MFPL_PE0MFP_SC0_CD (5ul << SYS_GPE_MFPL_PE0MFP_Pos) /*!< GPE_MFPL PE0 setting for SC0_CD*/ +#define SYS_GPE_MFPL_PE0MFP_PWM0_CH0 (6ul << SYS_GPE_MFPL_PE0MFP_Pos) /*!< GPE_MFPL PE0 setting for PWM0_CH0*/ +#define SYS_GPE_MFPL_PE0MFP_EBI_nCS1 (7ul << SYS_GPE_MFPL_PE0MFP_Pos) /*!< GPE_MFPL PE0 setting for EBI_nCS1*/ +#define SYS_GPE_MFPL_PE0MFP_INT4 (8ul << SYS_GPE_MFPL_PE0MFP_Pos) /*!< GPE_MFPL PE0 setting for INT4*/ + +//PE1 +#define SYS_GPE_MFPL_PE1MFP_GPIO (0ul << SYS_GPE_MFPL_PE1MFP_Pos) /*!< GPE_MFPL PE1 setting for GPIO*/ +#define SYS_GPE_MFPL_PE1MFP_T3_EXT (3ul << SYS_GPE_MFPL_PE1MFP_Pos) /*!< GPE_MFPL PE1 setting for T3_EXT*/ +#define SYS_GPE_MFPL_PE1MFP_SC0_CD (5ul << SYS_GPE_MFPL_PE1MFP_Pos) /*!< GPE_MFPL PE1 setting for SC0_CD*/ +#define SYS_GPE_MFPL_PE1MFP_PWM0_CH1 (6ul << SYS_GPE_MFPL_PE1MFP_Pos) /*!< GPE_MFPL PE1 setting for PWM0_CH1*/ + +//PE2 +#define SYS_GPE_MFPL_PE2MFP_GPIO (0ul << SYS_GPE_MFPL_PE2MFP_Pos) /*!< GPE_MFPL PE2 setting for GPIO*/ +#define SYS_GPE_MFPL_PE2MFP_PWM1_CH1 (6ul << SYS_GPE_MFPL_PE2MFP_Pos) /*!< GPE_MFPL PE2 setting for PWM1_CH1*/ + +//PE3 +#define SYS_GPE_MFPL_PE3MFP_GPIO (0ul << SYS_GPE_MFPL_PE3MFP_Pos) /*!< GPE_MFPL PE3 setting for GPIO*/ +#define SYS_GPE_MFPL_PE3MFP_SPI1_MOSI (2ul << SYS_GPE_MFPL_PE3MFP_Pos) /*!< GPE_MFPL PE3 setting for SPI1_MOSI*/ +#define SYS_GPE_MFPL_PE3MFP_TK15 (4ul << SYS_GPE_MFPL_PE3MFP_Pos) /*!< GPE_MFPL PE3 setting for TK15*/ +#define SYS_GPE_MFPL_PE3MFP_PWM0_CH3 (6ul << SYS_GPE_MFPL_PE3MFP_Pos) /*!< GPE_MFPL PE3 setting for PWM0_CH3*/ + +//PE4 +#define SYS_GPE_MFPL_PE4MFP_GPIO (0ul << SYS_GPE_MFPL_PE4MFP_Pos) /*!< GPE_MFPL PE4 setting for GPIO*/ +#define SYS_GPE_MFPL_PE4MFP_I2C1_SCL (3ul << SYS_GPE_MFPL_PE4MFP_Pos) /*!< GPE_MFPL PE4 setting for I2C1_SCL*/ +#define SYS_GPE_MFPL_PE4MFP_SC0_PWR (5ul << SYS_GPE_MFPL_PE4MFP_Pos) /*!< GPE_MFPL PE4 setting for SC0_PWR*/ +#define SYS_GPE_MFPL_PE4MFP_PWM1_BRAKE0 (6ul << SYS_GPE_MFPL_PE4MFP_Pos) /*!< GPE_MFPL PE4 setting for PWM1_BRAKE0*/ +#define SYS_GPE_MFPL_PE4MFP_EBI_nCS0 (7ul << SYS_GPE_MFPL_PE4MFP_Pos) /*!< GPE_MFPL PE4 setting for EBI_nCS0*/ +#define SYS_GPE_MFPL_PE4MFP_INT0 (8ul << SYS_GPE_MFPL_PE4MFP_Pos) /*!< GPE_MFPL PE4 setting for INT0*/ + +//PE5 +#define SYS_GPE_MFPL_PE5MFP_GPIO (0ul << SYS_GPE_MFPL_PE5MFP_Pos) /*!< GPE_MFPL PE5 setting for GPIO*/ +#define SYS_GPE_MFPL_PE5MFP_I2C1_SDA (3ul << SYS_GPE_MFPL_PE5MFP_Pos) /*!< GPE_MFPL PE5 setting for I2C1_SDA*/ +#define SYS_GPE_MFPL_PE5MFP_SC0_RST (5ul << SYS_GPE_MFPL_PE5MFP_Pos) /*!< GPE_MFPL PE5 setting for SC0_RST*/ +#define SYS_GPE_MFPL_PE5MFP_PWM1_BRAKE1 (6ul << SYS_GPE_MFPL_PE5MFP_Pos) /*!< GPE_MFPL PE5 setting for PWM1_BRAKE1*/ +#define SYS_GPE_MFPL_PE5MFP_EBI_ALE (7ul << SYS_GPE_MFPL_PE5MFP_Pos) /*!< GPE_MFPL PE5 setting for EBI_ALE*/ +#define SYS_GPE_MFPL_PE5MFP_INT1 (8ul << SYS_GPE_MFPL_PE5MFP_Pos) /*!< GPE_MFPL PE5 setting for INT1*/ + +//PE6 +#define SYS_GPE_MFPL_PE6MFP_GPIO (0ul << SYS_GPE_MFPL_PE6MFP_Pos) /*!< GPE_MFPL PE6 setting for GPIO*/ +#define SYS_GPE_MFPL_PE6MFP_T3_EXT (3ul << SYS_GPE_MFPL_PE6MFP_Pos) /*!< GPE_MFPL PE6 setting for T3_EXT*/ + +//PE7 +#define SYS_GPE_MFPL_PE7MFP_GPIO (0ul << SYS_GPE_MFPL_PE7MFP_Pos) /*!< GPE_MFPL PE7 setting for GPIO*/ + +//PE8 +#define SYS_GPE_MFPH_PE8MFP_GPIO (0ul << SYS_GPE_MFPH_PE8MFP_Pos) /*!< GPE_MFPH PE8 setting for GPIO*/ +#define SYS_GPE_MFPH_PE8MFP_UART1_TXD (1ul << SYS_GPE_MFPH_PE8MFP_Pos) /*!< GPE_MFPH PE8 setting for UART1_TXD*/ +#define SYS_GPE_MFPH_PE8MFP_SPI0_MISO1 (2ul << SYS_GPE_MFPH_PE8MFP_Pos) /*!< GPE_MFPH PE8 setting for SPI0_MISO1*/ +#define SYS_GPE_MFPH_PE8MFP_I2C1_SCL (4ul << SYS_GPE_MFPH_PE8MFP_Pos) /*!< GPE_MFPH PE8 setting for I2C1_SCL*/ +#define SYS_GPE_MFPH_PE8MFP_SC0_PWR (5ul << SYS_GPE_MFPH_PE8MFP_Pos) /*!< GPE_MFPH PE8 setting for SC0_PWR*/ +#define SYS_GPE_MFPH_PE8MFP_CLKO (9ul << SYS_GPE_MFPH_PE8MFP_Pos) /*!< GPE_MFPH PE8 setting for CLKO*/ +#define SYS_GPE_MFPH_PE8MFP_PWM0_BRAKE0 (10ul << SYS_GPE_MFPH_PE8MFP_Pos) /*!< GPE_MFPH PE8 setting for PWM0_BRAKE0*/ +#define SYS_GPE_MFPH_PE8MFP_T1 (11ul << SYS_GPE_MFPH_PE8MFP_Pos) /*!< GPE_MFPH PE8 setting for T1*/ + +//PE9 +#define SYS_GPE_MFPH_PE9MFP_GPIO (0ul << SYS_GPE_MFPH_PE9MFP_Pos) /*!< GPE_MFPH PE9 setting for GPIO*/ +#define SYS_GPE_MFPH_PE9MFP_UART1_RXD (1ul << SYS_GPE_MFPH_PE9MFP_Pos) /*!< GPE_MFPH PE9 setting for UART1_RXD*/ +#define SYS_GPE_MFPH_PE9MFP_SPI0_MOSI1 (2ul << SYS_GPE_MFPH_PE9MFP_Pos) /*!< GPE_MFPH PE9 setting for SPI0_MOSI1*/ +#define SYS_GPE_MFPH_PE9MFP_I2C1_SDA (4ul << SYS_GPE_MFPH_PE9MFP_Pos) /*!< GPE_MFPH PE9 setting for I2C1_SDA*/ +#define SYS_GPE_MFPH_PE9MFP_SC0_RST (5ul << SYS_GPE_MFPH_PE9MFP_Pos) /*!< GPE_MFPH PE9 setting for SC0_RST*/ +#define SYS_GPE_MFPH_PE9MFP_SPI1_I2SMCLK (9ul << SYS_GPE_MFPH_PE9MFP_Pos) /*!< GPE_MFPH PE9 setting for SPI1_I2SMCLK*/ +#define SYS_GPE_MFPH_PE9MFP_PWM1_BRAKE1 (10ul << SYS_GPE_MFPH_PE9MFP_Pos) /*!< GPE_MFPH PE9 setting for PWM1_BRAKE1*/ +#define SYS_GPE_MFPH_PE9MFP_T2 (11ul << SYS_GPE_MFPH_PE9MFP_Pos) /*!< GPE_MFPH PE9 setting for T2*/ + +//PE10 +#define SYS_GPE_MFPH_PE10MFP_GPIO (0ul << SYS_GPE_MFPH_PE10MFP_Pos) /*!< GPE_MFPH PE10 setting for GPIO*/ +#define SYS_GPE_MFPH_PE10MFP_SPI1_MISO (1ul << SYS_GPE_MFPH_PE10MFP_Pos) /*!< GPE_MFPH PE10 setting for SPI1_MISO*/ +#define SYS_GPE_MFPH_PE10MFP_SPI0_MISO0 (2ul << SYS_GPE_MFPH_PE10MFP_Pos) /*!< GPE_MFPH PE10 setting for SPI0_MISO0*/ +#define SYS_GPE_MFPH_PE10MFP_UART1_nCTS (3ul << SYS_GPE_MFPH_PE10MFP_Pos) /*!< GPE_MFPH PE10 setting for UART1_nCTS*/ +#define SYS_GPE_MFPH_PE10MFP_I2C0_SMBAL (4ul << SYS_GPE_MFPH_PE10MFP_Pos) /*!< GPE_MFPH PE10 setting for I2C0_SMBAL*/ +#define SYS_GPE_MFPH_PE10MFP_SC0_DAT (5ul << SYS_GPE_MFPH_PE10MFP_Pos) /*!< GPE_MFPH PE10 setting for SC0_DAT*/ +#define SYS_GPE_MFPH_PE10MFP_UART3_TXD (9ul << SYS_GPE_MFPH_PE10MFP_Pos) /*!< GPE_MFPH PE10 setting for UART3_TXD*/ +#define SYS_GPE_MFPH_PE10MFP_I2C1_SCL (11ul << SYS_GPE_MFPH_PE10MFP_Pos) /*!< GPE_MFPH PE10 setting for I2C1_SCL*/ + +//PE11 +#define SYS_GPE_MFPH_PE11MFP_GPIO (0ul << SYS_GPE_MFPH_PE11MFP_Pos) /*!< GPE_MFPH PE11 setting for GPIO*/ +#define SYS_GPE_MFPH_PE11MFP_SPI1_MOSI (1ul << SYS_GPE_MFPH_PE11MFP_Pos) /*!< GPE_MFPH PE11 setting for SPI1_MOSI*/ +#define SYS_GPE_MFPH_PE11MFP_SPI0_MOSI0 (2ul << SYS_GPE_MFPH_PE11MFP_Pos) /*!< GPE_MFPH PE11 setting for SPI0_MOSI0*/ +#define SYS_GPE_MFPH_PE11MFP_UART1_nRTS (3ul << SYS_GPE_MFPH_PE11MFP_Pos) /*!< GPE_MFPH PE11 setting for UART1_nRTS*/ +#define SYS_GPE_MFPH_PE11MFP_I2C0_SMBSUS (4ul << SYS_GPE_MFPH_PE11MFP_Pos) /*!< GPE_MFPH PE11 setting for I2C0_SMBSUS*/ +#define SYS_GPE_MFPH_PE11MFP_SC0_CLK (5ul << SYS_GPE_MFPH_PE11MFP_Pos) /*!< GPE_MFPH PE11 setting for SC0_CLK*/ +#define SYS_GPE_MFPH_PE11MFP_UART3_RXD (9ul << SYS_GPE_MFPH_PE11MFP_Pos) /*!< GPE_MFPH PE11 setting for UART3_RXD*/ +#define SYS_GPE_MFPH_PE11MFP_I2C1_SDA (11ul << SYS_GPE_MFPH_PE11MFP_Pos) /*!< GPE_MFPH PE11 setting for I2C1_SDA*/ + +//PE12 +#define SYS_GPE_MFPH_PE12MFP_GPIO (0ul << SYS_GPE_MFPH_PE12MFP_Pos) /*!< GPE_MFPH PE12 setting for GPIO*/ +#define SYS_GPE_MFPH_PE12MFP_SPI1_SS (1ul << SYS_GPE_MFPH_PE12MFP_Pos) /*!< GPE_MFPH PE12 setting for SPI1_SS*/ +#define SYS_GPE_MFPH_PE12MFP_SPI0_SS (2ul << SYS_GPE_MFPH_PE12MFP_Pos) /*!< GPE_MFPH PE12 setting for SPI0_SS*/ +#define SYS_GPE_MFPH_PE12MFP_UART1_TXD (3ul << SYS_GPE_MFPH_PE12MFP_Pos) /*!< GPE_MFPH PE12 setting for UART1_TXD*/ +#define SYS_GPE_MFPH_PE12MFP_I2C0_SCL (4ul << SYS_GPE_MFPH_PE12MFP_Pos) /*!< GPE_MFPH PE12 setting for I2C0_SCL*/ + +//PE13 +#define SYS_GPE_MFPH_PE13MFP_GPIO (0ul << SYS_GPE_MFPH_PE13MFP_Pos) /*!< GPE_MFPH PE13 setting for GPIO*/ +#define SYS_GPE_MFPH_PE13MFP_SPI1_CLK (1ul << SYS_GPE_MFPH_PE13MFP_Pos) /*!< GPE_MFPH PE13 setting for SPI1_CLK*/ +#define SYS_GPE_MFPH_PE13MFP_SPI0_CLK (2ul << SYS_GPE_MFPH_PE13MFP_Pos) /*!< GPE_MFPH PE13 setting for SPI0_CLK*/ +#define SYS_GPE_MFPH_PE13MFP_UART1_RXD (3ul << SYS_GPE_MFPH_PE13MFP_Pos) /*!< GPE_MFPH PE13 setting for UART1_RXD*/ +#define SYS_GPE_MFPH_PE13MFP_I2C0_SDA (4ul << SYS_GPE_MFPH_PE13MFP_Pos) /*!< GPE_MFPH PE13 setting for I2C0_SDA*/ + +//PE14 +#define SYS_GPE_MFPH_PE14MFP_GPIO (0ul << SYS_GPE_MFPH_PE14MFP_Pos) /*!< GPE_MFPH PE14 setting for GPIO*/ + +//PF0 +#define SYS_GPF_MFPL_PF0MFP_GPIO (0ul << SYS_GPF_MFPL_PF0MFP_Pos) /*!< GPF_MFPL PF0 setting for GPIO*/ +#define SYS_GPF_MFPL_PF0MFP_X32_OUT (1ul << SYS_GPF_MFPL_PF0MFP_Pos) /*!< GPF_MFPL PF0 setting for X32_OUT*/ +#define SYS_GPF_MFPL_PF0MFP_INT5 (8ul << SYS_GPF_MFPL_PF0MFP_Pos) /*!< GPF_MFPL PF0 setting for INT5*/ + +//PF1 +#define SYS_GPF_MFPL_PF1MFP_GPIO (0ul << SYS_GPF_MFPL_PF1MFP_Pos) /*!< GPF_MFPL PF1 setting for GPIO*/ +#define SYS_GPF_MFPL_PF1MFP_X32_IN (1ul << SYS_GPF_MFPL_PF1MFP_Pos) /*!< GPF_MFPL PF1 setting for X32_IN*/ + +//PF2 +#define SYS_GPF_MFPL_PF2MFP_GPIO (0ul << SYS_GPF_MFPL_PF2MFP_Pos) /*!< GPF_MFPL PF2 setting for GPIO*/ +#define SYS_GPF_MFPL_PF2MFP_TAMPER (1ul << SYS_GPF_MFPL_PF2MFP_Pos) /*!< GPF_MFPL PF2 setting for TAMPER*/ + +//PF3 +#define SYS_GPF_MFPL_PF3MFP_GPIO (0ul << SYS_GPF_MFPL_PF3MFP_Pos) /*!< GPF_MFPL PF3 setting for GPIO*/ +#define SYS_GPF_MFPL_PF3MFP_XT1_OUT (1ul << SYS_GPF_MFPL_PF3MFP_Pos) /*!< GPF_MFPL PF3 setting for XT1_OUT*/ +#define SYS_GPF_MFPL_PF3MFP_I2C1_SCL (3ul << SYS_GPF_MFPL_PF3MFP_Pos) /*!< GPF_MFPL PF3 setting for I2C1_SCL*/ + +//PF4 +#define SYS_GPF_MFPL_PF4MFP_GPIO (0ul << SYS_GPF_MFPL_PF4MFP_Pos) /*!< GPF_MFPL PF4 setting for GPIO*/ +#define SYS_GPF_MFPL_PF4MFP_XT1_IN (1ul << SYS_GPF_MFPL_PF4MFP_Pos) /*!< GPF_MFPL PF4 setting for XT1_IN*/ +#define SYS_GPF_MFPL_PF4MFP_I2C1_SDA (3ul << SYS_GPF_MFPL_PF4MFP_Pos) /*!< GPF_MFPL PF4 setting for I2C1_SDA*/ + +//PF5 +#define SYS_GPF_MFPL_PF5MFP_GPIO (0ul << SYS_GPF_MFPL_PF5MFP_Pos) /*!< GPF_MFPL PF5 setting for GPIO*/ +#define SYS_GPF_MFPL_PF5MFP_ICE_CLK (1ul << SYS_GPF_MFPL_PF5MFP_Pos) /*!< GPF_MFPL PF5 setting for ICE_CLK*/ + +//PF6 +#define SYS_GPF_MFPL_PF6MFP_GPIO (0ul << SYS_GPF_MFPL_PF6MFP_Pos) /*!< GPF_MFPL PF6 setting for GPIO*/ +#define SYS_GPF_MFPL_PF6MFP_ICE_DAT (1ul << SYS_GPF_MFPL_PF6MFP_Pos) /*!< GPF_MFPL PF6 setting for ICE_DAT*/ + +//PF7 +#define SYS_GPF_MFPL_PF7MFP_GPIO (0ul << SYS_GPF_MFPL_PF7MFP_Pos) /*!< GPF_MFPL PF7 setting for GPIO*/ + + +/*@}*/ /* end of group SYS_EXPORTED_CONSTANTS */ + + +/** @addtogroup 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->BODCTL |= SYS_BODCTL_BODIF_Msk) + +/** + * @brief Set Brown-out detector function to normal mode + * @param None + * @return None + * @details This macro set Brown-out detector to normal mode. + * The register write-protection function should be disabled before using this macro. + */ +#define SYS_CLEAR_BOD_LPM() (SYS->BODCTL &= ~SYS_BODCTL_BODLPM_Msk) + +/** + * @brief Disable Brown-out detector function + * @param None + * @return None + * @details This macro disable Brown-out detector function. + * The register write-protection function should be disabled before using this macro. + */ +#define SYS_DISABLE_BOD() (SYS->BODCTL &= ~SYS_BODCTL_BODEN_Msk) + +/** + * @brief Enable Brown-out detector function + * @param None + * @return None + * @details This macro enable Brown-out detector function. + * The register write-protection function should be disabled before using this macro. + */ +#define SYS_ENABLE_BOD() (SYS->BODCTL |= SYS_BODCTL_BODEN_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->BODCTL & SYS_BODCTL_BODIF_Msk) + +/** + * @brief Get Brown-out detector status + * @param None + * @retval 0 System voltage is higher than BOD threshold voltage setting or BOD function is disabled. + * @retval >=1 System voltage is lower than BOD threshold voltage setting. + * @details This macro get Brown-out detector output status. + * If the BOD function is disabled, this function always return 0. + */ +#define SYS_GET_BOD_OUTPUT() (SYS->BODCTL & SYS_BODCTL_BODOUT_Msk) + +/** + * @brief Enable Brown-out detector interrupt function + * @param None + * @return None + * @details This macro enable Brown-out detector interrupt function. + * The register write-protection function should be disabled before using this macro. + */ +#define SYS_DISABLE_BOD_RST() (SYS->BODCTL &= ~SYS_BODCTL_BODRSTEN_Msk) + +/** + * @brief Enable Brown-out detector reset function + * @param None + * @return None + * @details This macro enable Brown-out detect reset function. + * The register write-protection function should be disabled before using this macro. + */ +#define SYS_ENABLE_BOD_RST() (SYS->BODCTL |= SYS_BODCTL_BODRSTEN_Msk) + +/** + * @brief Set Brown-out detector function low power mode + * @param None + * @return None + * @details This macro set Brown-out detector to low power mode. + * The register write-protection function should be disabled before using this macro. + */ +#define SYS_SET_BOD_LPM() (SYS->BODCTL |= SYS_BODCTL_BODLPM_Msk) + +/** + * @brief Set Brown-out detector voltage level + * @param[in] u32Level is Brown-out voltage level. Including : + * - \ref SYS_BODCTL_BODVL_4_5V + * - \ref SYS_BODCTL_BODVL_3_7V + * - \ref SYS_BODCTL_BODVL_2_7V + * - \ref SYS_BODCTL_BODVL_2_2V + * @return None + * @details This macro set Brown-out detector voltage level. + * The write-protection function should be disabled before using this macro. + */ +#define SYS_SET_BOD_LEVEL(u32Level) (SYS->BODCTL = (SYS->BODCTL & ~SYS_BODCTL_BODVL_Msk) | (u32Level)) + +/** + * @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->RSTSTS & SYS_RSTSTS_BODRF_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->RSTSTS & SYS_RSTSTS_CPURF_Msk) + +/** + * @brief Get reset source is from LVR Reset + * @param None + * @retval 0 Previous reset source is not from Low-Voltage-Reset + * @retval >=1 Previous reset source is from Low-Voltage-Reset + * @details This macro get previous reset source is from Low-Voltage-Reset. + */ +#define SYS_IS_LVR_RST() (SYS->RSTSTS & SYS_RSTSTS_LVRF_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->RSTSTS & SYS_RSTSTS_PORF_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->RSTSTS & SYS_RSTSTS_PINRF_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->RSTSTS & SYS_RSTSTS_SYSRF_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->RSTSTS & SYS_RSTSTS_WDTRF_Msk) + +/** + * @brief Disable Low-Voltage-Reset function + * @param None + * @return None + * @details This macro disable Low-Voltage-Reset function. + * The register write-protection function should be disabled before using this macro. + */ +#define SYS_DISABLE_LVR() (SYS->BODCTL &= ~SYS_BODCTL_LVREN_Msk) + +/** + * @brief Enable Low-Voltage-Reset function + * @param None + * @return None + * @details This macro enable Low-Voltage-Reset function. + * The register write-protection function should be disabled before using this macro. + */ +#define SYS_ENABLE_LVR() (SYS->BODCTL |= SYS_BODCTL_LVREN_Msk) + +/** + * @brief Disable Power-on Reset function + * @param None + * @return None + * @details This macro disable Power-on Reset function. + * The register write-protection function should be disabled before using this macro. + */ +#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. + * The register write-protection function should be disabled before using this macro. + */ +#define SYS_ENABLE_POR() (SYS->PORCTL = 0) + +/** + * @brief Clear reset source flag + * @param[in] u32RstSrc is reset source. Including : + * - \ref SYS_RSTSTS_PORF_Msk + * - \ref SYS_RSTSTS_PINRF_Msk + * - \ref SYS_RSTSTS_WDTRF_Msk + * - \ref SYS_RSTSTS_LVRF_Msk + * - \ref SYS_RSTSTS_BODRF_Msk + * - \ref SYS_RSTSTS_SYSRF_Msk + * - \ref SYS_RSTSTS_CPURF_Msk + * - \ref SYS_RSTSTS_CPULKRF_Msk + * @return None + * @details This macro clear reset source flag. + */ +#define SYS_CLEAR_RST_SOURCE(u32RstSrc) ((SYS->RSTSTS) = (u32RstSrc) ) + + +/*---------------------------------------------------------------------------------------------------------*/ +/* static inline functions */ +/*---------------------------------------------------------------------------------------------------------*/ + + +/** + * @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) +{ + do + { + SYS->REGLCTL = 0x59; + SYS->REGLCTL = 0x16; + SYS->REGLCTL = 0x88; + } + while(SYS->REGLCTL == 0); +} + +/** + * @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->REGLCTL = 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); + + +/*@}*/ /* end of group SYS_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group SYS_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + + +#ifdef __cplusplus +} +#endif + +#endif //__SYS_H__ diff --git a/StdDriver/inc/timer.h b/StdDriver/inc/timer.h new file mode 100644 index 0000000..de11f67 --- /dev/null +++ b/StdDriver/inc/timer.h @@ -0,0 +1,415 @@ +/**************************************************************************//** + * @file timer.h + * @version V3.00 + * $Revision: 10 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series Timer driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup TIMER_Driver TIMER Driver + @{ +*/ + +/** @addtogroup TIMER_EXPORTED_CONSTANTS TIMER Exported Constants + @{ +*/ +/*---------------------------------------------------------------------------------------------------------*/ +/* TIMER Operation Mode, External Counter and Capture Mode Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define TIMER_ONESHOT_MODE (0UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in one-shot mode */ +#define TIMER_PERIODIC_MODE (1UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in periodic mode */ +#define TIMER_TOGGLE_MODE (2UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in toggle-output mode */ +#define TIMER_CONTINUOUS_MODE (3UL << TIMER_CTL_OPMODE_Pos) /*!< Timer working in continuous counting mode */ +#define TIMER_TOUT_PIN_FROM_TX (0UL << TIMER_CTL_TGLPINSEL_Pos) /*!< Timer toggle-output pin is from Tx pin */ +#define TIMER_TOUT_PIN_FROM_TX_EXT (1UL << TIMER_CTL_TGLPINSEL_Pos) /*!< Timer toggle-output pin is from Tx_EXT pin */ +#define TIMER_CAPTURE_FREE_COUNTING_MODE (0UL << TIMER_EXTCTL_CAPFUNCS_Pos) /*!< Timer capture event to get timer counter value */ +#define TIMER_CAPTURE_COUNTER_RESET_MODE (1UL << TIMER_EXTCTL_CAPFUNCS_Pos) /*!< Timer capture event to reset timer counter */ +#define TIMER_CAPTURE_FALLING_EDGE (0UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< Falling edge detection to trigger timer capture */ +#define TIMER_CAPTURE_RISING_EDGE (1UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< Rising edge detection to trigger timer capture */ +#define TIMER_CAPTURE_FALLING_AND_RISING_EDGE (2UL << TIMER_EXTCTL_CAPEDGE_Pos) /*!< Both falling and rising edge detection to trigger timer capture */ +#define TIMER_COUNTER_FALLING_EDGE (0UL << TIMER_EXTCTL_CNTPHASE_Pos) /*!< Counter increase on falling edge detection */ +#define TIMER_COUNTER_RISING_EDGE (1UL << TIMER_EXTCTL_CNTPHASE_Pos) /*!< Counter increase on rising edge detection */ + +/*@}*/ /* end of group TIMER_EXPORTED_CONSTANTS */ + + +/** @addtogroup TIMER_EXPORTED_FUNCTIONS TIMER Exported Functions + @{ +*/ + +/** + * @brief Set Timer Compared Value + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * @param[in] u32Value Timer compare value. Valid values are between 2 to 0xFFFFFF. + * + * @return None + * + * @details This macro is used to set timer compared value to adjust timer time-out interval. + * @note 1. Never write 0x0 or 0x1 in this field, or the core will run into unknown state. \n + * 2. If update timer compared value in continuous counting mode, timer counter value will keep counting continuously. \n + * But if timer is operating at other modes, the timer up counter will restart counting and start from 0. + */ +#define TIMER_SET_CMP_VALUE(timer, u32Value) ((timer)->CMP = (u32Value)) + +/** + * @brief Set Timer Prescale Value + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * @param[in] u32Value Timer prescale value. Valid values are between 0 to 0xFF. + * + * @return None + * + * @details This macro is used to set timer prescale value and timer source clock will be divided by (prescale + 1) \n + * before it is fed into timer. + */ +#define TIMER_SET_PRESCALE_VALUE(timer, u32Value) ((timer)->CTL = ((timer)->CTL & ~TIMER_CTL_PSC_Msk) | (u32Value)) + +/** + * @brief Check specify Timer Status + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @retval 0 Timer 24-bit up counter is inactive + * @retval 1 Timer 24-bit up counter is active + * + * @details This macro is used to check if specify Timer counter is inactive or active. + */ +#define TIMER_IS_ACTIVE(timer) (((timer)->CTL & TIMER_CTL_ACTSTS_Msk)? 1 : 0) + +/** + * @brief Select Toggle-output Pin + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * @param[in] u32ToutSel Toggle-output pin selection, valid values are: + * - \ref TIMER_TOUT_PIN_FROM_TX + * - \ref TIMER_TOUT_PIN_FROM_TX_EXT + * + * @return None + * + * @details This macro is used to select timer toggle-output pin is output on Tx or Tx_EXT pin. + */ +#define TIMER_SELECT_TOUT_PIN(timer, u32ToutSel) ((timer)->CTL = ((timer)->CTL & ~TIMER_CTL_TGLPINSEL_Msk) | (u32ToutSel)) + +/** + * @brief Start Timer Counting + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to start Timer counting. + */ +static __INLINE void TIMER_Start(TIMER_T *timer) +{ + timer->CTL |= TIMER_CTL_CNTEN_Msk; +} + +/** + * @brief Stop Timer Counting + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to stop/suspend Timer counting. + */ +static __INLINE void TIMER_Stop(TIMER_T *timer) +{ + timer->CTL &= ~TIMER_CTL_CNTEN_Msk; +} + +/** + * @brief Enable Timer Interrupt Wake-up Function + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to enable the timer interrupt wake-up function and interrupt source could be time-out interrupt, \n + * counter event interrupt or capture trigger interrupt. + * @note To wake the system from Power-down mode, timer clock source must be ether LXT or LIRC. + */ +static __INLINE void TIMER_EnableWakeup(TIMER_T *timer) +{ + timer->CTL |= TIMER_CTL_WKEN_Msk; +} + +/** + * @brief Disable Timer Wake-up Function + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to disable the timer interrupt wake-up function. + */ +static __INLINE void TIMER_DisableWakeup(TIMER_T *timer) +{ + timer->CTL &= ~TIMER_CTL_WKEN_Msk; +} + +/** + * @brief Enable Capture Pin De-bounce + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to enable the detect de-bounce function of capture pin. + */ +static __INLINE void TIMER_EnableCaptureDebounce(TIMER_T *timer) +{ + timer->EXTCTL |= TIMER_EXTCTL_CAPDBEN_Msk; +} + +/** + * @brief Disable Capture Pin De-bounce + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to disable the detect de-bounce function of capture pin. + */ +static __INLINE void TIMER_DisableCaptureDebounce(TIMER_T *timer) +{ + timer->EXTCTL &= ~TIMER_EXTCTL_CAPDBEN_Msk; +} + +/** + * @brief Enable Counter Pin De-bounce + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to enable the detect de-bounce function of counter pin. + */ +static __INLINE void TIMER_EnableEventCounterDebounce(TIMER_T *timer) +{ + timer->EXTCTL |= TIMER_EXTCTL_CNTDBEN_Msk; +} + +/** + * @brief Disable Counter Pin De-bounce + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to disable the detect de-bounce function of counter pin. + */ +static __INLINE void TIMER_DisableEventCounterDebounce(TIMER_T *timer) +{ + timer->EXTCTL &= ~TIMER_EXTCTL_CNTDBEN_Msk; +} + +/** + * @brief Enable Timer Time-out Interrupt + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to enable the timer time-out interrupt function. + */ +static __INLINE void TIMER_EnableInt(TIMER_T *timer) +{ + timer->CTL |= TIMER_CTL_INTEN_Msk; +} + +/** + * @brief Disable Timer Time-out Interrupt + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to disable the timer time-out interrupt function. + */ +static __INLINE void TIMER_DisableInt(TIMER_T *timer) +{ + timer->CTL &= ~TIMER_CTL_INTEN_Msk; +} + +/** + * @brief Enable Capture Trigger Interrupt + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to enable the timer capture trigger interrupt function. + */ +static __INLINE void TIMER_EnableCaptureInt(TIMER_T *timer) +{ + timer->EXTCTL |= TIMER_EXTCTL_CAPIEN_Msk; +} + +/** + * @brief Disable Capture Trigger Interrupt + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function is used to disable the timer capture trigger interrupt function. + */ +static __INLINE void TIMER_DisableCaptureInt(TIMER_T *timer) +{ + timer->EXTCTL &= ~TIMER_EXTCTL_CAPIEN_Msk; +} + +/** + * @brief Get Timer Time-out Interrupt Flag + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @retval 0 Timer time-out interrupt did not occur + * @retval 1 Timer time-out interrupt occurred + * + * @details This function indicates timer time-out interrupt occurred or not. + */ +static __INLINE uint32_t TIMER_GetIntFlag(TIMER_T *timer) +{ + return ((timer->INTSTS & TIMER_INTSTS_TIF_Msk) ? 1 : 0); +} + +/** + * @brief Clear Timer Time-out Interrupt Flag + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function clears timer time-out interrupt flag to 0. + */ +static __INLINE void TIMER_ClearIntFlag(TIMER_T *timer) +{ + timer->INTSTS = (timer->INTSTS & ~TIMER_INTSTS_TWKF_Msk) | TIMER_INTSTS_TIF_Msk; +} + +/** + * @brief Get Timer Capture Interrupt Flag + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @retval 0 Timer capture interrupt did not occur + * @retval 1 Timer capture interrupt occurred + * + * @details This function indicates timer capture trigger interrupt occurred or not. + */ +static __INLINE uint32_t TIMER_GetCaptureIntFlag(TIMER_T *timer) +{ + return timer->EINTSTS; +} + +/** + * @brief Clear Timer Capture Interrupt Flag + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function clears timer capture trigger interrupt flag to 0. + */ +static __INLINE void TIMER_ClearCaptureIntFlag(TIMER_T *timer) +{ + timer->EINTSTS = TIMER_EINTSTS_CAPIF_Msk; +} + +/** + * @brief Get Timer Wake-up Flag + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @retval 0 Timer does not cause CPU wake-up + * @retval 1 Timer interrupt event cause CPU wake-up + * + * @details This function indicates timer interrupt event has waked up system or not. + */ +static __INLINE uint32_t TIMER_GetWakeupFlag(TIMER_T *timer) +{ + return (timer->INTSTS & TIMER_INTSTS_TWKF_Msk ? 1 : 0); +} + +/** + * @brief Clear Timer Wake-up Flag + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This function clears the timer wake-up system flag to 0. + */ +static __INLINE void TIMER_ClearWakeupFlag(TIMER_T *timer) +{ + timer->INTSTS = (timer->INTSTS & ~TIMER_INTSTS_TIF_Msk) | TIMER_INTSTS_TWKF_Msk; +} + +/** + * @brief Get Capture value + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return 24-bit Capture Value + * + * @details This function reports the current 24-bit timer capture value. + */ +static __INLINE uint32_t TIMER_GetCaptureData(TIMER_T *timer) +{ + return timer->CAP; +} + +/** + * @brief Get Counter value + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return 24-bit Counter Value + * + * @details This function reports the current 24-bit timer counter value. + */ +static __INLINE uint32_t TIMER_GetCounter(TIMER_T *timer) +{ + return timer->CNT; +} + +uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq); +void TIMER_Close(TIMER_T *timer); +void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec); +void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge); +void TIMER_DisableCapture(TIMER_T *timer); +void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge); +void TIMER_DisableEventCounter(TIMER_T *timer); +uint32_t TIMER_GetModuleClock(TIMER_T *timer); + +/*@}*/ /* end of group TIMER_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group TIMER_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__TIMER_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/tk.h b/StdDriver/inc/tk.h new file mode 100644 index 0000000..ccbbadf --- /dev/null +++ b/StdDriver/inc/tk.h @@ -0,0 +1,302 @@ +/**************************************************************************//** + * @file tk.h + * @version V1.00 + * $Revision: 6 $ + * $Date: 15/08/24 4:52p $ + * @brief M451 Series TK Driver Header File + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + * + ******************************************************************************/ +#ifndef __TK_H__ +#define __TK_H__ + +#include "M451Series.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup TK_Driver TK Driver + @{ +*/ + +/** @addtogroup TK_EXPORTED_CONSTANTS TK Exported Constants + @{ +*/ + +#define TK_SCAN_MODE_SINGLE (0UL) /*!< Touch key single scan mode */ +#define TK_SCAN_MODE_PERIODIC (TK_CTL_TMRTRGEN_Msk) /*!< Touch key periodic scan mode */ +#define TK_SCAN_MODE_ALL_KEY (TK_REFCTL_SCANALL_Msk) /*!< Touch key all keys scan mode */ +#define TK_SCAN_MODE_PERIODIC_ALL_KEY (TK_CTL_TMRTRGEN_Msk | TK_REFCTL_SCANALL_Msk) /*!< Touch key periodic with all keys scan mode */ + +#define TK_SENSE_PULSE_1 (0UL << TK_REFCTL_SENPTCTL_Pos) /*!< Touch key sensing pulse width is 1us */ +#define TK_SENSE_PULSE_2 (1UL << TK_REFCTL_SENPTCTL_Pos) /*!< Touch key sensing pulse width is 2us */ +#define TK_SENSE_PULSE_4 (2UL << TK_REFCTL_SENPTCTL_Pos) /*!< Touch key sensing pulse width is 4us */ +#define TK_SENSE_PULSE_8 (3UL << TK_REFCTL_SENPTCTL_Pos) /*!< Touch key sensing pulse width is 8us */ + +#define TK_SENSE_CNT_128 (0UL << TK_REFCTL_SENTCTL_Pos) /*!< Touch key sensing count is 128 */ +#define TK_SENSE_CNT_255 (1UL << TK_REFCTL_SENTCTL_Pos) /*!< Touch key sensing count is 255 */ +#define TK_SENSE_CNT_511 (2UL << TK_REFCTL_SENTCTL_Pos) /*!< Touch key sensing count is 511 */ +#define TK_SENSE_CNT_1023 (3UL << TK_REFCTL_SENTCTL_Pos) /*!< Touch key sensing count is 1023 */ + +#define TK_AVCCH_1_DIV_16 (0UL << TK_CTL_AVCCHSEL_Pos) /*!< Touch key AVCCH voltage is 1/16 VDD */ +#define TK_AVCCH_1_DIV_8 (1UL << TK_CTL_AVCCHSEL_Pos) /*!< Touch key AVCCH voltage is 1/8 VDD */ +#define TK_AVCCH_3_DIV_16 (2UL << TK_CTL_AVCCHSEL_Pos) /*!< Touch key AVCCH voltage is 3/16 VDD */ +#define TK_AVCCH_1_DIV_4 (3UL << TK_CTL_AVCCHSEL_Pos) /*!< Touch key AVCCH voltage is 1/4 VDD */ +#define TK_AVCCH_5_DIV_16 (4UL << TK_CTL_AVCCHSEL_Pos) /*!< Touch key AVCCH voltage is 5/16 VDD */ +#define TK_AVCCH_3_DIV_8 (5UL << TK_CTL_AVCCHSEL_Pos) /*!< Touch key AVCCH voltage is 3/8 VDD */ +#define TK_AVCCH_7_DIV_16 (6UL << TK_CTL_AVCCHSEL_Pos) /*!< Touch key AVCCH voltage is 7/16 VDD */ +#define TK_AVCCH_1_DIV_2 (7UL << TK_CTL_AVCCHSEL_Pos) /*!< Touch key AVCCH voltage is 1/2 VDD */ + +#define TK_CAP_BANK_POL_SEL_GND (0UL << TK_POLCTL_CBPOLSEL_Pos) /*!< Touch key capacitor bank polarity is GND */ +#define TK_CAP_BANK_POL_SEL_AVCCH (1UL << TK_POLCTL_CBPOLSEL_Pos) /*!< Touch key capacitor bank polarity is AVCCH */ +#define TK_CAP_BANK_POL_SEL_VDD (2UL << TK_POLCTL_CBPOLSEL_Pos) /*!< Touch key capacitor bank polarity is VDD */ + +#define TK_TKn_POL_SEL_GND (0UL) /*!< Touch key polarity is GND */ +#define TK_TKn_POL_SEL_AVCCH (1UL) /*!< Touch key polarity is AVCCH */ +#define TK_TKn_POL_SEL_VDD (2UL) /*!< Touch key polarity is VDD */ + +#define TK_INT_EN_SCAN_COMPLETE (TK_INTEN_SCINTEN_Msk) /*!< Touch key enable scan complete interrupt */ +#define TK_INT_EN_SCAN_COMPLETE_EDGE_TH (TK_INTEN_SCTHIEN_Msk) /*!< Touch key enable scan complete with threshold interrupt of edge trigger mode */ +#define TK_INT_EN_SCAN_COMPLETE_LEVEL_TH (TK_INTEN_THIMOD_Msk | TK_INTEN_SCTHIEN_Msk) /*!< Touch key enable scan complete with threshold interrupt of level trigger mode */ + +#define TK_INT_SCAN_COMPLETE (TK_STATUS_SCIF_Msk) /*!< Touch key scan complete interrupt */ +#define TK_INT_SCAN_COMPLETE_TH_ALL (0x1FFFF02UL) /*!< Touch key scan complete or all touch keys threshold control interrupt */ +#define TK_INT_SCAN_TH_ALL (0x1FFFF00UL) /*!< ALL Touch key threshold control interrupt */ +#define TK_INT_SCAN_TH_TK0 (TK_STATUS_TKIF0_Msk) /*!< Touch key 0 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK1 (TK_STATUS_TKIF1_Msk) /*!< Touch key 1 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK2 (TK_STATUS_TKIF2_Msk) /*!< Touch key 2 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK3 (TK_STATUS_TKIF3_Msk) /*!< Touch key 3 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK4 (TK_STATUS_TKIF4_Msk) /*!< Touch key 4 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK5 (TK_STATUS_TKIF5_Msk) /*!< Touch key 5 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK6 (TK_STATUS_TKIF6_Msk) /*!< Touch key 6 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK7 (TK_STATUS_TKIF7_Msk) /*!< Touch key 7 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK8 (TK_STATUS_TKIF8_Msk) /*!< Touch key 8 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK9 (TK_STATUS_TKIF9_Msk) /*!< Touch key 9 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK10 (TK_STATUS_TKIF10_Msk) /*!< Touch key 10 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK11 (TK_STATUS_TKIF11_Msk) /*!< Touch key 11 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK12 (TK_STATUS_TKIF12_Msk) /*!< Touch key 12 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK13 (TK_STATUS_TKIF13_Msk) /*!< Touch key 13 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK14 (TK_STATUS_TKIF14_Msk) /*!< Touch key 14 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK15 (TK_STATUS_TKIF15_Msk) /*!< Touch key 15 threshold control interrupt */ +#define TK_INT_SCAN_TH_TK16 (TK_STATUS_TKIF16_Msk) /*!< Touch key 16 threshold control interrupt */ + + +/*@}*/ /* end of group TK_EXPORTED_CONSTANTS */ + + +/** @addtogroup TK_EXPORTED_FUNCTIONS TK Exported Functions + @{ +*/ + +/** + * @brief Enable scan key(s) + * @param[in] u32Mask Combination of enabled scan keys. Each bit corresponds to a touch key. + * Bit 0 represents touch key 0, bit 1 represents touch key 1... + * @return None + * @note Touch key 16 is the default reference key, so touch key 16 is enabled. + * \hideinitializer + */ +#define TK_ENABLE_SCAN_KEY(u32Mask) (TK->CTL |= (u32Mask)) + +/** + * @brief Disable scan key(s) + * @param[in] u32Mask Combination of disabled scan keys. Each bit corresponds to a touch key. + * Bit 0 represents touch key 0, bit 1 represents touch key 1... + * @return None + * \hideinitializer + */ +#define TK_DISABLE_SCAN_KEY(u32Mask) (TK->CTL &= ~(u32Mask)) + +/** + * @brief Enable reference key(s) + * @param[in] u32Mask Combination of enabled reference keys. Each bit corresponds to a touch key. + * Bit 0 represents touch key 0, bit 1 represents touch key 1... + * @return None + * @note Touch key 16 is the default reference key, so touch key 16 is enabled. + * \hideinitializer + */ +#define TK_ENABLE_REF_KEY(u32Mask) (TK->REFCTL |= (u32Mask)) + +/** + * @brief Disable reference key(s) + * @param[in] u32Mask Combination of disabled reference keys. Each bit corresponds to a touch key. + * Bit 0 represents touch key 0, bit 1 represents touch key 1... + * @return None + * @note It must enable a reference key and touch key 16 is the default reference key. + * If no any one touch key as reference key except touch key 16, then reference Touch key 16 can't be disable. + * \hideinitializer + */ +#define TK_DISABLE_REF_KEY(u32Mask) (TK->REFCTL &= ~(u32Mask)) + +/** + * @brief Initiate enabled key(s) scan immediately. + * @param None + * @return None + * \hideinitializer + */ +#define TK_START_SCAN() (TK->CTL |= TK_CTL_SCAN_Msk) + +/** + * @brief Set touch key Sensing pulse width. + * @param[in] u32PulseWidth Sensing pulse width. + * - \ref TK_SENSE_PULSE_1 + * - \ref TK_SENSE_PULSE_2 + * - \ref TK_SENSE_PULSE_4 + * - \ref TK_SENSE_PULSE_8 + * @return None + * \hideinitializer + */ +#define TK_SET_PULSE_WIDTH(u32PulseWidth) (TK->REFCTL = (TK->REFCTL & ~TK_REFCTL_SENPTCTL_Msk) | (u32PulseWidth)) + +/** + * @brief Set touch key Sensing count. + * @param[in] u32SenseCnt Sensing count. + * - \ref TK_SENSE_CNT_128 + * - \ref TK_SENSE_CNT_255 + * - \ref TK_SENSE_CNT_511 + * - \ref TK_SENSE_CNT_1023 + * @return None + * \hideinitializer + */ +#define TK_SET_SENSING_CNT(u32SenseCnt) (TK->REFCTL = (TK->REFCTL & ~TK_REFCTL_SENTCTL_Msk) | (u32SenseCnt)) + + +/** + * @brief Set touch key AVCCH voltage. + * @param[in] u32AVCCHSel voltage selection. + * - \ref TK_AVCCH_1_DIV_16 + * - \ref TK_AVCCH_1_DIV_8 + * - \ref TK_AVCCH_3_DIV_16 + * - \ref TK_AVCCH_1_DIV_4 + * - \ref TK_AVCCH_5_DIV_16 + * - \ref TK_AVCCH_3_DIV_8 + * - \ref TK_AVCCH_7_DIV_16 + * - \ref TK_AVCCH_1_DIV_2 + * @return None + * \hideinitializer + */ +#define TK_SET_AVCCH(u32AVCCHSel) (TK->CTL = (TK->CTL & ~TK_CTL_AVCCHSEL_Msk) | (u32AVCCHSel)) + +/** + * @brief Get touch key complement capacitor bank data. + * @param[in] u32TKNum Touch key number. The valid value is 0~16. + * @return Complement capacitor bank data + * \hideinitializer + */ +#define TK_GET_COMP_CAP_BANK_DATA(u32TKNum) (((*(__IO uint32_t *) (&(TK->CCBDAT0) + ((u32TKNum) >> 2))) >> ((u32TKNum) % 4 * 8) & TK_CCBDAT0_CCBDAT0_Msk)) + +/** + * @brief Get touch key sensing result data. + * @param[in] u32TKNum Touch key number. The valid value is 0~16. + * @return Sensing result data + * \hideinitializer + */ +#define TK_GET_SENSE_DATA(u32TKNum) (((*(__IO uint32_t *) (&(TK->DAT0) + ((u32TKNum) >> 2))) >> ((u32TKNum) % 4 * 8) & TK_DAT0_TKDAT0_Msk)) + +/** + * @brief Get touch key busy status. + * @param None + * @retval 0 Touch key is scan completed or stopped. + * @retval 1 Touch key is busy. + * \hideinitializer + */ +#define TK_IS_BUSY() ((TK->STATUS & TK_STATUS_BUSY_Msk) ? 1: 0) + +/** + * @brief Get touch key interrupt flag. + * @param[in] u32Mask Interrupt flag type selection. + * - \ref TK_INT_SCAN_COMPLETE + * - \ref TK_INT_SCAN_COMPLETE_TH_ALL + * - \ref TK_INT_SCAN_TH_ALL + * - \ref TK_INT_SCAN_TH_TK0 + * - \ref TK_INT_SCAN_TH_TK1 + * - \ref TK_INT_SCAN_TH_TK2 + * - \ref TK_INT_SCAN_TH_TK3 + * - \ref TK_INT_SCAN_TH_TK4 + * - \ref TK_INT_SCAN_TH_TK5 + * - \ref TK_INT_SCAN_TH_TK6 + * - \ref TK_INT_SCAN_TH_TK7 + * - \ref TK_INT_SCAN_TH_TK8 + * - \ref TK_INT_SCAN_TH_TK9 + * - \ref TK_INT_SCAN_TH_TK10 + * - \ref TK_INT_SCAN_TH_TK11 + * - \ref TK_INT_SCAN_TH_TK12 + * - \ref TK_INT_SCAN_TH_TK13 + * - \ref TK_INT_SCAN_TH_TK14 + * - \ref TK_INT_SCAN_TH_TK15 + * - \ref TK_INT_SCAN_TH_TK16 + * @retval 0 Touch key has no interrupt. + * @retval 1 Touch key is scan completed or threshold control event occurs. + * \hideinitializer + */ +#define TK_GET_INT_STATUS(u32Mask) ((TK->STATUS & (u32Mask)) ? 1: 0) + +/** + * @brief Clear touch key interrupt flag. + * @param[in] u32Mask Interrupt flag type selection. + * - \ref TK_INT_SCAN_COMPLETE + * - \ref TK_INT_SCAN_COMPLETE_TH_ALL + * - \ref TK_INT_SCAN_TH_ALL + * - \ref TK_INT_SCAN_TH_TK0 + * - \ref TK_INT_SCAN_TH_TK1 + * - \ref TK_INT_SCAN_TH_TK2 + * - \ref TK_INT_SCAN_TH_TK3 + * - \ref TK_INT_SCAN_TH_TK4 + * - \ref TK_INT_SCAN_TH_TK5 + * - \ref TK_INT_SCAN_TH_TK6 + * - \ref TK_INT_SCAN_TH_TK7 + * - \ref TK_INT_SCAN_TH_TK8 + * - \ref TK_INT_SCAN_TH_TK9 + * - \ref TK_INT_SCAN_TH_TK10 + * - \ref TK_INT_SCAN_TH_TK11 + * - \ref TK_INT_SCAN_TH_TK12 + * - \ref TK_INT_SCAN_TH_TK13 + * - \ref TK_INT_SCAN_TH_TK14 + * - \ref TK_INT_SCAN_TH_TK15 + * - \ref TK_INT_SCAN_TH_TK16 + * @return None + * \hideinitializer + */ +#define TK_CLR_INT_FLAG(u32Mask) (TK->STATUS = (u32Mask)) + + +/*---------------------------------------------------------------------------------------------------------*/ +/* Define TK functions prototype */ +/*---------------------------------------------------------------------------------------------------------*/ +void TK_Open(void); +void TK_Close(void); +void TK_SetScanMode(uint32_t u32Mode); +void TK_ConfigSensitivity(uint32_t u32PulseWidth, uint32_t u32SenseCnt, uint32_t u32AVCCHSel); +void TK_SetCapBankPol(uint32_t u32CapBankPolSel); +void TK_EnableTkPolarity(uint32_t u32Mask); +void TK_DisableTkPolarity(uint32_t u32Mask); +void TK_SetCompCapBankData(uint32_t u32TKNum, uint32_t u32CapData); +void TK_SetTkPol(uint32_t u32Mask, uint32_t u32PolSel); +void TK_SetRefKeyCapBankData(uint32_t u32CapData); +void TK_SetScanThreshold(uint32_t u32TKNum, uint32_t u32HighLevel, uint32_t u32LowLevel); +void TK_EnableInt(uint32_t u32Msk); +void TK_DisableInt(uint32_t u32Msk); + + +/*@}*/ /* end of group TK_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group TK_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__TK_H__ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/uart.h b/StdDriver/inc/uart.h new file mode 100644 index 0000000..071f4ff --- /dev/null +++ b/StdDriver/inc/uart.h @@ -0,0 +1,460 @@ +/****************************************************************************** + * @file uart.h + * @version V3.00 + * $Revision: 36 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series UART driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#ifndef __UART_H__ +#define __UART_H__ + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup UART_Driver UART Driver + @{ +*/ + +/** @addtogroup UART_EXPORTED_CONSTANTS UART Exported Constants + @{ +*/ + +/*---------------------------------------------------------------------------------------------------------*/ +/* UART FIFO size constants definitions */ +/*---------------------------------------------------------------------------------------------------------*/ + +#define UART0_FIFO_SIZE 16 /*!< UART0 supports separated receive/transmit 16/16 bytes entry FIFO */ +#define UART1_FIFO_SIZE 16 /*!< UART1 supports separated receive/transmit 16/16 bytes entry FIFO */ +#define UART2_FIFO_SIZE 16 /*!< UART2 supports separated receive/transmit 16/16 bytes entry FIFO */ +#define UART3_FIFO_SIZE 16 /*!< UART3 supports separated receive/transmit 16/16 bytes entry FIFO */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* UART_FIFO constants definitions */ +/*---------------------------------------------------------------------------------------------------------*/ + +#define UART_FIFO_RFITL_1BYTE (0x0 << UART_FIFO_RFITL_Pos) /*!< UART_FIFO setting to set RX FIFO Trigger Level to 1 byte */ +#define UART_FIFO_RFITL_4BYTES (0x1 << UART_FIFO_RFITL_Pos) /*!< UART_FIFO setting to set RX FIFO Trigger Level to 4 bytes */ +#define UART_FIFO_RFITL_8BYTES (0x2 << UART_FIFO_RFITL_Pos) /*!< UART_FIFO setting to set RX FIFO Trigger Level to 8 bytes */ +#define UART_FIFO_RFITL_14BYTES (0x3 << UART_FIFO_RFITL_Pos) /*!< UART_FIFO setting to set RX FIFO Trigger Level to 14 bytes */ + +#define UART_FIFO_RTSTRGLV_1BYTE (0x0 << UART_FIFO_RTSTRGLV_Pos) /*!< UART_FIFO setting to set RTS Trigger Level to 1 byte */ +#define UART_FIFO_RTSTRGLV_4BYTES (0x1 << UART_FIFO_RTSTRGLV_Pos) /*!< UART_FIFO setting to set RTS Trigger Level to 4 bytes */ +#define UART_FIFO_RTSTRGLV_8BYTES (0x2 << UART_FIFO_RTSTRGLV_Pos) /*!< UART_FIFO setting to set RTS Trigger Level to 8 bytes */ +#define UART_FIFO_RTSTRGLV_14BYTES (0x3 << UART_FIFO_RTSTRGLV_Pos) /*!< UART_FIFO setting to set RTS Trigger Level to 14 bytes */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* UART_LINE constants definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define UART_WORD_LEN_5 (0) /*!< UART_LINE setting to set UART word length to 5 bits */ +#define UART_WORD_LEN_6 (1) /*!< UART_LINE setting to set UART word length to 6 bits */ +#define UART_WORD_LEN_7 (2) /*!< UART_LINE setting to set UART word length to 7 bits */ +#define UART_WORD_LEN_8 (3) /*!< UART_LINE setting to set UART word length to 8 bits */ + +#define UART_PARITY_NONE (0x0 << UART_LINE_PBE_Pos) /*!< UART_LINE setting to set UART as no parity */ +#define UART_PARITY_ODD (0x1 << UART_LINE_PBE_Pos) /*!< UART_LINE setting to set UART as odd parity */ +#define UART_PARITY_EVEN (0x3 << UART_LINE_PBE_Pos) /*!< UART_LINE setting to set UART as even parity */ +#define UART_PARITY_MARK (0x5 << UART_LINE_PBE_Pos) /*!< UART_LINE setting to keep parity bit as '1' */ +#define UART_PARITY_SPACE (0x7 << UART_LINE_PBE_Pos) /*!< UART_LINE setting to keep parity bit as '0' */ + +#define UART_STOP_BIT_1 (0x0 << UART_LINE_NSB_Pos) /*!< UART_LINE setting for one stop bit */ +#define UART_STOP_BIT_1_5 (0x1 << UART_LINE_NSB_Pos) /*!< UART_LINE setting for 1.5 stop bit when 5-bit word length */ +#define UART_STOP_BIT_2 (0x1 << UART_LINE_NSB_Pos) /*!< UART_LINE setting for two stop bit when 6, 7, 8-bit word length */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* UART RTS ACTIVE LEVEL constants definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define UART_RTS_IS_LOW_LEV_ACTIVE (0x1 << UART_MODEM_RTSACTLV_Pos) /*!< Set RTS is Low Level Active */ +#define UART_RTS_IS_HIGH_LEV_ACTIVE (0x0 << UART_MODEM_RTSACTLV_Pos) /*!< Set RTS is High Level Active */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* UART_IRDA constants definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define UART_IRDA_TXEN (0x1 << UART_IRDA_TXEN_Pos) /*!< Set IrDA function Tx mode */ +#define UART_IRDA_RXEN (0x0 << UART_IRDA_TXEN_Pos) /*!< Set IrDA function Rx mode */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* UART_FUNCSEL constants definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define UART_FUNCSEL_UART (0x0 << UART_FUNCSEL_FUNCSEL_Pos) /*!< UART_FUNCSEL setting to set UART Function (Default) */ +#define UART_FUNCSEL_LIN (0x1 << UART_FUNCSEL_FUNCSEL_Pos) /*!< UART_FUNCSEL setting to set LIN Function */ +#define UART_FUNCSEL_IrDA (0x2 << UART_FUNCSEL_FUNCSEL_Pos) /*!< UART_FUNCSEL setting to set IrDA Function */ +#define UART_FUNCSEL_RS485 (0x3 << UART_FUNCSEL_FUNCSEL_Pos) /*!< UART_FUNCSEL setting to set RS485 Function */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* UART_LINCTL constants definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define UART_LINCTL_BRKFL(x) (((x)-1) << UART_LINCTL_BRKFL_Pos) /*!< UART_LINCTL setting to set LIN Break Field Length, x = 10 ~ 15, default value is 12 */ +#define UART_LINCTL_BSL(x) (((x)-1) << UART_LINCTL_BSL_Pos) /*!< UART_LINCTL setting to set LIN Break/Sync Delimiter Length, x = 1 ~ 4 */ +#define UART_LINCTL_HSEL_BREAK (0x0UL << UART_LINCTL_HSEL_Pos) /*!< UART_LINCTL setting to set LIN Header Select to break field */ +#define UART_LINCTL_HSEL_BREAK_SYNC (0x1UL << UART_LINCTL_HSEL_Pos) /*!< UART_LINCTL setting to set LIN Header Select to break field and sync field */ +#define UART_LINCTL_HSEL_BREAK_SYNC_ID (0x2UL << UART_LINCTL_HSEL_Pos) /*!< UART_LINCTL setting to set LIN Header Select to break field, sync field and ID field*/ +#define UART_LINCTL_PID(x) ((x) << UART_LINCTL_PID_Pos) /*!< UART_LINCTL setting to set LIN PID value */ + + +/*---------------------------------------------------------------------------------------------------------*/ +/* UART BAUDRATE MODE constants definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define UART_BAUD_MODE0 (0) /*!< Set UART Baudrate Mode is Mode0 */ +#define UART_BAUD_MODE2 (UART_BAUD_BAUDM1_Msk | UART_BAUD_BAUDM0_Msk) /*!< Set UART Baudrate Mode is Mode2 */ + + +/*@}*/ /* end of group UART_EXPORTED_CONSTANTS */ + + +/** @addtogroup UART_EXPORTED_FUNCTIONS UART Exported Functions + @{ +*/ + + +/** + * @brief Calculate UART baudrate mode0 divider + * + * @param[in] u32SrcFreq UART clock frequency + * @param[in] u32BaudRate Baudrate of UART module + * + * @return UART baudrate mode0 divider + * + * @details This macro calculate UART baudrate mode0 divider. + */ +#define UART_BAUD_MODE0_DIVIDER(u32SrcFreq, u32BaudRate) ((((u32SrcFreq) + ((u32BaudRate)*8)) / (u32BaudRate) >> 4)-2) + + +/** + * @brief Calculate UART baudrate mode2 divider + * + * @param[in] u32SrcFreq UART clock frequency + * @param[in] u32BaudRate Baudrate of UART module + * + * @return UART baudrate mode2 divider + * + * @details This macro calculate UART baudrate mode2 divider. + */ +#define UART_BAUD_MODE2_DIVIDER(u32SrcFreq, u32BaudRate) ((((u32SrcFreq) + ((u32BaudRate)/2)) / (u32BaudRate))-2) + + +/** + * @brief Write UART data + * + * @param[in] uart The pointer of the specified UART module + * @param[in] u8Data Data byte to transmit. + * + * @return None + * + * @details This macro write Data to Tx data register. + */ +#define UART_WRITE(uart, u8Data) ((uart)->DAT = (u8Data)) + + +/** + * @brief Read UART data + * + * @param[in] uart The pointer of the specified UART module + * + * @return The oldest data byte in RX FIFO. + * + * @details This macro read Rx data register. + */ +#define UART_READ(uart) ((uart)->DAT) + + +/** + * @brief Get Tx empty + * + * @param[in] uart The pointer of the specified UART module + * + * @retval 0 Tx FIFO is not empty + * @retval >=1 Tx FIFO is empty + * + * @details This macro get Transmitter FIFO empty register value. + */ +#define UART_GET_TX_EMPTY(uart) ((uart)->FIFOSTS & UART_FIFOSTS_TXEMPTY_Msk) + + +/** + * @brief Get Rx empty + * + * @param[in] uart The pointer of the specified UART module + * + * @retval 0 Rx FIFO is not empty + * @retval >=1 Rx FIFO is empty + * + * @details This macro get Receiver FIFO empty register value. + */ +#define UART_GET_RX_EMPTY(uart) ((uart)->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) + + +/** + * @brief Check specified uart port transmission is over. + * + * @param[in] uart The pointer of the specified UART module + * + * @retval 0 Tx transmission is not over + * @retval 1 Tx transmission is over + * + * @details This macro return Transmitter Empty Flag register bit value. + * It indicates if specified uart port transmission is over nor not. + */ +#define UART_IS_TX_EMPTY(uart) (((uart)->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk) >> UART_FIFOSTS_TXEMPTYF_Pos) + + +/** + * @brief Wait specified uart port transmission is over + * + * @param[in] uart The pointer of the specified UART module + * + * @return None + * + * @details This macro wait specified uart port transmission is over. + */ +#define UART_WAIT_TX_EMPTY(uart) while(!((((uart)->FIFOSTS) & UART_FIFOSTS_TXEMPTYF_Msk) >> UART_FIFOSTS_TXEMPTYF_Pos)) + + +/** + * @brief Check RX is ready or not + * + * @param[in] uart The pointer of the specified UART module + * + * @retval 0 The number of bytes in the RX FIFO is less than the RFITL + * @retval 1 The number of bytes in the RX FIFO equals or larger than RFITL + * + * @details This macro check receive data available interrupt flag is set or not. + */ +#define UART_IS_RX_READY(uart) (((uart)->INTSTS & UART_INTSTS_RDAIF_Msk)>>UART_INTSTS_RDAIF_Pos) + + +/** + * @brief Check TX FIFO is full or not + * + * @param[in] uart The pointer of the specified UART module + * + * @retval 1 TX FIFO is full + * @retval 0 TX FIFO is not full + * + * @details This macro check TX FIFO is full or not. + */ +#define UART_IS_TX_FULL(uart) (((uart)->FIFOSTS & UART_FIFOSTS_TXFULL_Msk)>>UART_FIFOSTS_TXFULL_Pos) + + +/** + * @brief Check RX FIFO is full or not + * + * @param[in] uart The pointer of the specified UART module + * + * @retval 1 RX FIFO is full + * @retval 0 RX FIFO is not full + * + * @details This macro check RX FIFO is full or not. + */ +#define UART_IS_RX_FULL(uart) (((uart)->FIFOSTS & UART_FIFOSTS_RXFULL_Msk)>>UART_FIFOSTS_RXFULL_Pos) + + +/** + * @brief Get Tx full register value + * + * @param[in] uart The pointer of the specified UART module + * + * @retval 0 Tx FIFO is not full. + * @retval >=1 Tx FIFO is full. + * + * @details This macro get Tx full register value. + */ +#define UART_GET_TX_FULL(uart) ((uart)->FIFOSTS & UART_FIFOSTS_TXFULL_Msk) + + +/** + * @brief Get Rx full register value + * + * @param[in] uart The pointer of the specified UART module + * + * @retval 0 Rx FIFO is not full. + * @retval >=1 Rx FIFO is full. + * + * @details This macro get Rx full register value. + */ +#define UART_GET_RX_FULL(uart) ((uart)->FIFOSTS & UART_FIFOSTS_RXFULL_Msk) + + +/** + * @brief Enable specified UART interrupt + * + * @param[in] uart The pointer of the specified UART module + * @param[in] u32eIntSel Interrupt type select + * - \ref UART_INTEN_ABRIEN_Msk : Auto baud rate interrupt + * - \ref UART_INTEN_WKCTSIEN_Msk : CTS wakeup interrupt + * - \ref UART_INTEN_WKDATIEN_Msk : Data wakeup interrupt + * - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt + * - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt + * - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt + * - \ref UART_INTEN_MODEMIEN_Msk : Modem interrupt + * - \ref UART_INTEN_RLSIEN_Msk : Rx Line status interrupt + * - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt + * - \ref UART_INTEN_RDAIEN_Msk : Rx ready interrupt + * + * @return None + * + * @details This macro enable specified UART interrupt. + */ +#define UART_ENABLE_INT(uart, u32eIntSel) ((uart)->INTEN |= (u32eIntSel)) + + +/** + * @brief Disable specified UART interrupt + * + * @param[in] uart The pointer of the specified UART module + * @param[in] u32eIntSel Interrupt type select + * - \ref UART_INTEN_ABRIEN_Msk : Auto baud rate interrupt + * - \ref UART_INTEN_WKCTSIEN_Msk : CTS wakeup interrupt + * - \ref UART_INTEN_WKDATIEN_Msk : Data wakeup interrupt + * - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt + * - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt + * - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt + * - \ref UART_INTEN_MODEMIEN_Msk : Modem status interrupt + * - \ref UART_INTEN_RLSIEN_Msk : Receive Line status interrupt + * - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt + * - \ref UART_INTEN_RDAIEN_Msk : Rx ready interrupt + * + * @return None + * + * @details This macro enable specified UART interrupt. + */ +#define UART_DISABLE_INT(uart, u32eIntSel) ((uart)->INTEN &= ~ (u32eIntSel)) + + +/** + * @brief Get specified interrupt flag/status + * + * @param[in] uart The pointer of the specified UART module + * @param[in] u32eIntTypeFlag Interrupt Type Flag, should be + * - \ref UART_INTSTS_HWBUFEINT_Msk : In DMA Mode, Buffer Error Interrupt Indicator + * - \ref UART_INTSTS_HWTOINT_Msk : In DMA Mode, Time-out Interrupt Indicator + * - \ref UART_INTSTS_HWMODINT_Msk : In DMA Mode, MODEM Status Interrupt Indicator + * - \ref UART_INTSTS_HWRLSINT_Msk : In DMA Mode, Receive Line Status Interrupt Indicator + * - \ref UART_INTSTS_HWBUFEIF_Msk : In DMA Mode, Buffer Error Interrupt Flag + * - \ref UART_INTSTS_HWTOIF_Msk : In DMA Mode, Time-out Interrupt Flag + * - \ref UART_INTSTS_HWMODIF_Msk : In DMA Mode, MODEM Interrupt Flag + * - \ref UART_INTSTS_HWRLSIF_Msk : In DMA Mode, Receive Line Status Flag + * - \ref UART_INTSTS_LININT_Msk : LIN Bus Interrupt Indicator + * - \ref UART_INTSTS_BUFERRINT_Msk : Buffer Error Interrupt Indicator + * - \ref UART_INTSTS_RXTOINT_Msk : Time-out Interrupt Indicator + * - \ref UART_INTSTS_MODEMINT_Msk : Modem Status Interrupt Indicator + * - \ref UART_INTSTS_RLSINT_Msk : Receive Line Status Interrupt Indicator + * - \ref UART_INTSTS_THREINT_Msk : Transmit Holding Register Empty Interrupt Indicator + * - \ref UART_INTSTS_RDAINT_Msk : Receive Data Available Interrupt Indicator + * - \ref UART_INTSTS_LINIF_Msk : LIN Bus Flag + * - \ref UART_INTSTS_BUFERRIF_Msk : Buffer Error Interrupt Flag + * - \ref UART_INTSTS_RXTOIF_Msk : Rx Time-out Interrupt Flag + * - \ref UART_INTSTS_MODEMIF_Msk : Modem Interrupt Flag + * - \ref UART_INTSTS_RLSIF_Msk : Receive Line Status Interrupt Flag + * - \ref UART_INTSTS_THREIF_Msk : Tx Empty Interrupt Flag + * - \ref UART_INTSTS_RDAIF_Msk : Rx Ready Interrupt Flag + * + * @retval 0 The specified interrupt is not happened. + * 1 The specified interrupt is happened. + * + * @details This macro get specified interrupt flag or interrupt indicator status. + */ +#define UART_GET_INT_FLAG(uart,u32eIntTypeFlag) (((uart)->INTSTS & (u32eIntTypeFlag))?1:0) + + +/** + * @brief Set RTS pin to low + * + * @param[in] uart The pointer of the specified UART module + * + * @return None + * + * @details This macro set RTS pin to low. + */ +__STATIC_INLINE void UART_CLEAR_RTS(UART_T* uart) +{ + uart->MODEM |= UART_MODEM_RTSACTLV_Msk; + uart->MODEM &= ~UART_MODEM_RTS_Msk; +} + + +/** + * @brief Set RTS pin to high + * + * @param[in] uart The pointer of the specified UART module + * + * @return None + * + * @details This macro set RTS pin to high. + */ +__STATIC_INLINE void UART_SET_RTS(UART_T* uart) +{ + uart->MODEM |= UART_MODEM_RTSACTLV_Msk | UART_MODEM_RTS_Msk; +} + + +/** + * @brief Clear RS-485 Address Byte Detection Flag + * + * @param[in] uart The pointer of the specified UART module + * + * @return None + * + * @details This macro clear RS-485 address byte detection flag. + */ +#define UART_RS485_CLEAR_ADDR_FLAG(uart) ((uart)->FIFOSTS = UART_FIFOSTS_ADDRDETF_Msk) + + +/** + * @brief Get RS-485 Address Byte Detection Flag + * + * @param[in] uart The pointer of the specified UART module + * + * @retval 0 Receiver detects a data that is not an address bit. + * @retval 1 Receiver detects a data that is an address bit. + * + * @details This macro get RS-485 address byte detection flag. + */ +#define UART_RS485_GET_ADDR_FLAG(uart) (((uart)->FIFOSTS & UART_FIFOSTS_ADDRDETF_Msk) >> UART_FIFOSTS_ADDRDETF_Pos) + + +void UART_ClearIntFlag(UART_T* uart , uint32_t u32InterruptFlag); +void UART_Close(UART_T* uart); +void UART_DisableFlowCtrl(UART_T* uart); +void UART_DisableInt(UART_T* uart, uint32_t u32InterruptFlag); +void UART_EnableFlowCtrl(UART_T* uart); +void UART_EnableInt(UART_T* uart, uint32_t u32InterruptFlag); +void UART_Open(UART_T* uart, uint32_t u32baudrate); +uint32_t UART_Read(UART_T* uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes); +void UART_SetLine_Config(UART_T* uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits); +void UART_SetTimeoutCnt(UART_T* uart, uint32_t u32TOC); +void UART_SelectIrDAMode(UART_T* uart, uint32_t u32Buadrate, uint32_t u32Direction); +void UART_SelectRS485Mode(UART_T* uart, uint32_t u32Mode, uint32_t u32Addr); +void UART_SelectLINMode(UART_T* uart, uint32_t u32Mode, uint32_t u32BreakLength); +uint32_t UART_Write(UART_T* uart, uint8_t *pu8TxBuf, uint32_t u32WriteBytes); + + + + +/*@}*/ /* end of group UART_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group UART_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__UART_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/usbd.h b/StdDriver/inc/usbd.h new file mode 100644 index 0000000..3943b84 --- /dev/null +++ b/StdDriver/inc/usbd.h @@ -0,0 +1,657 @@ +/****************************************************************************** + * @file usbd.h + * @brief M451 series USB driver header file + * @version 2.0.0 + * @date 10, January, 2014 + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + ******************************************************************************/ +#ifndef __USBD_H__ +#define __USBD_H__ + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup USBD_Driver USBD Driver + @{ +*/ + +/** @addtogroup USBD_EXPORTED_STRUCTS USBD Exported Structs + @{ +*/ +typedef struct s_usbd_info +{ + const uint8_t *gu8DevDesc; /*!< Pointer for USB Device Descriptor */ + const uint8_t *gu8ConfigDesc; /*!< Pointer for USB Configuration Descriptor */ + const uint8_t **gu8StringDesc; /*!< Pointer for USB String Descriptor pointers */ + const uint8_t **gu8HidReportDesc; /*!< Pointer for USB HID Report Descriptor */ + const uint32_t *gu32HidReportSize; /*!< Pointer for HID Report descriptor Size */ + const uint32_t *gu32ConfigHidDescIdx; /*!< Pointer for HID Descriptor start index */ + +} S_USBD_INFO_T; + +extern const S_USBD_INFO_T gsInfo; + +/*@}*/ /* end of group USBD_EXPORTED_STRUCTS */ + + + + +/** @addtogroup USBD_EXPORTED_CONSTANTS USBD Exported Constants + @{ +*/ +#define USBD_BUF_BASE (USBD_BASE+0x100) +#define USBD_MAX_EP 8 + +#define EP0 0 /*!< Endpoint 0 */ +#define EP1 1 /*!< Endpoint 1 */ +#define EP2 2 /*!< Endpoint 2 */ +#define EP3 3 /*!< Endpoint 3 */ +#define EP4 4 /*!< Endpoint 4 */ +#define EP5 5 /*!< Endpoint 5 */ +#define EP6 6 /*!< Endpoint 6 */ +#define EP7 7 /*!< Endpoint 7 */ + + +/*! b, then return a. Otherwise, return b. + */ +#define Maximum(a,b) ((a)>(b) ? (a) : (b)) + + +/** + * @brief Compare two input numbers and return minimum one + * + * @param[in] a First number to be compared + * @param[in] b Second number to be compared + * + * @return Minimum value between a and b + * + * @details If a < b, then return a. Otherwise, return b. + */ +#define Minimum(a,b) ((a)<(b) ? (a) : (b)) + + +/** + * @brief Enable USB + * + * @param None + * + * @return None + * + * @details To set USB ATTR control register to enable USB and PHY. + * + */ +#define USBD_ENABLE_USB() ((uint32_t)(USBD->ATTR |= (USBD_USB_EN|USBD_PHY_EN))) + +/** + * @brief Disable USB + * + * @param None + * + * @return None + * + * @details To set USB ATTR control register to disable USB. + * + */ +#define USBD_DISABLE_USB() ((uint32_t)(USBD->ATTR &= ~USBD_USB_EN)) + +/** + * @brief Enable USB PHY + * + * @param None + * + * @return None + * + * @details To set USB ATTR control register to enable USB PHY. + * + */ +#define USBD_ENABLE_PHY() ((uint32_t)(USBD->ATTR |= USBD_PHY_EN)) + +/** + * @brief Disable USB PHY + * + * @param None + * + * @return None + * + * @details To set USB ATTR control register to disable USB PHY. + * + */ +#define USBD_DISABLE_PHY() ((uint32_t)(USBD->ATTR &= ~USBD_PHY_EN)) + +/** + * @brief Enable SE0. Force USB PHY transceiver to drive SE0. + * + * @param None + * + * @return None + * + * @details Set DRVSE0 bit of USB_DRVSE0 register to enable software-disconnect function. Force USB PHY transceiver to drive SE0 to bus. + * + */ +#define USBD_SET_SE0() ((uint32_t)(USBD->SE0 |= USBD_DRVSE0)) + +/** + * @brief Disable SE0 + * + * @param None + * + * @return None + * + * @details Clear DRVSE0 bit of USB_DRVSE0 register to disable software-disconnect function. + * + */ +#define USBD_CLR_SE0() ((uint32_t)(USBD->SE0 &= ~USBD_DRVSE0)) + +/** + * @brief Set USB device address + * + * @param[in] addr The USB device address. + * + * @return None + * + * @details Write USB device address to USB_FADDR register. + * + */ +#define USBD_SET_ADDR(addr) (USBD->FADDR = (addr)) + +/** + * @brief Get USB device address + * + * @param None + * + * @return USB device address + * + * @details Read USB_FADDR register to get USB device address. + * + */ +#define USBD_GET_ADDR() ((uint32_t)(USBD->FADDR)) + +/** + * @brief Enable USB interrupt function + * + * @param[in] intr The combination of the specified interrupt enable bits. + * Each bit corresponds to a interrupt enable bit. + * This parameter decides which interrupts will be enabled. + * (USBD_INT_WAKEUP, USBD_INT_FLDET, USBD_INT_USB, USBD_INT_BUS) + * + * @return None + * + * @details Enable USB related interrupt functions specified by intr parameter. + * + */ +#define USBD_ENABLE_INT(intr) (USBD->INTEN |= (intr)) + +/** + * @brief Get interrupt status + * + * @param None + * + * @return The value of USB_INTSTS register + * + * @details Return all interrupt flags of USB_INTSTS register. + * + */ +#define USBD_GET_INT_FLAG() ((uint32_t)(USBD->INTSTS)) + +/** + * @brief Clear USB interrupt flag + * + * @param[in] flag The combination of the specified interrupt flags. + * Each bit corresponds to a interrupt source. + * This parameter decides which interrupt flags will be cleared. + * (USBD_INTSTS_WAKEUP, USBD_INTSTS_FLDET, USBD_INTSTS_BUS, USBD_INTSTS_USB) + * + * @return None + * + * @details Clear USB related interrupt flags specified by flag parameter. + * + */ +#define USBD_CLR_INT_FLAG(flag) (USBD->INTSTS = (flag)) + +/** + * @brief Get endpoint status + * + * @param None + * + * @return The value of USB_EPSTS register. + * + * @details Return all endpoint status. + * + */ +#define USBD_GET_EP_FLAG() ((uint32_t)(USBD->EPSTS)) + +/** + * @brief Get USB bus state + * + * @param None + * + * @return The value of USB_ATTR[3:0]. + * Bit 0 indicates USB bus reset status. + * Bit 1 indicates USB bus suspend status. + * Bit 2 indicates USB bus resume status. + * Bit 3 indicates USB bus time-out status. + * + * @details Return USB_ATTR[3:0] for USB bus events. + * + */ +#define USBD_GET_BUS_STATE() ((uint32_t)(USBD->ATTR & 0xf)) + +/** + * @brief Check cable connection state + * + * @param None + * + * @retval 0 USB cable is not attached. + * @retval 1 USB cable is attached. + * + * @details Check the connection state by FLDET bit of USB_FLDET register. + * + */ +#define USBD_IS_ATTACHED() ((uint32_t)(USBD->VBUSDET & USBD_VBUSDET_VBUSDET_Msk)) + +/** + * @brief Stop USB transaction of the specified endpoint ID + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 hardware endpoint ID. This parameter could be 0 ~ 7. + * + * @return None + * + * @details Write 1 to CLRRDY bit of USB_CFGPx register to stop USB transaction of the specified endpoint ID. + * + */ +#define USBD_STOP_TRANSACTION(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) |= USBD_CFGP_CLRRDY_Msk) + +/** + * @brief Set USB DATA1 PID for the specified endpoint ID + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 hardware endpoint ID. This parameter could be 0 ~ 7. + * + * @return None + * + * @details Set DSQ_SYNC bit of USB_CFGx register to specify the DATA1 PID for the following IN token transaction. + * Base on this setting, hardware will toggle PID between DATA0 and DATA1 automatically for IN token transactions. + * + */ +#define USBD_SET_DATA1(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) |= USBD_CFG_DSQSYNC_Msk) + +/** + * @brief Set USB DATA0 PID for the specified endpoint ID + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 hardware endpoint ID. This parameter could be 0 ~ 7. + * + * @return None + * + * @details Clear DSQ_SYNC bit of USB_CFGx register to specify the DATA0 PID for the following IN token transaction. + * Base on this setting, hardware will toggle PID between DATA0 and DATA1 automatically for IN token transactions. + * + */ +#define USBD_SET_DATA0(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) &= (~USBD_CFG_DSQSYNC_Msk)) + +/** + * @brief Set USB payload size (IN data) + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 hardware endpoint ID. This parameter could be 0 ~ 7. + * + * @param[in] size The transfer length. + * + * @return None + * + * @details This macro will write the transfer length to USB_MXPLDx register for IN data transaction. + * + */ +#define USBD_SET_PAYLOAD_LEN(ep, size) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].MXPLD + (uint32_t)((ep) << 4))) = (size)) + +/** + * @brief Get USB payload size (OUT data) + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 endpoint ID. This parameter could be 0 ~ 7. + * + * @return The value of USB_MXPLDx register. + * + * @details Get the data length of OUT data transaction by reading USB_MXPLDx register. + * + */ +#define USBD_GET_PAYLOAD_LEN(ep) ((uint32_t)*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].MXPLD + (uint32_t)((ep) << 4)))) + +/** + * @brief Configure endpoint + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 hardware endpoint ID. This parameter could be 0 ~ 7. + * + * @param[in] config The USB configuration. + * + * @return None + * + * @details This macro will write config parameter to USB_CFGx register of specified endpoint ID. + * + */ +#define USBD_CONFIG_EP(ep, config) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFG + (uint32_t)((ep) << 4))) = (config)) + +/** + * @brief Set USB endpoint buffer + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 hardware endpoint ID. This parameter could be 0 ~ 7. + * + * @param[in] offset The SRAM offset. + * + * @return None + * + * @details This macro will set the SRAM offset for the specified endpoint ID. + * + */ +#define USBD_SET_EP_BUF_ADDR(ep, offset) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].BUFSEG + (uint32_t)((ep) << 4))) = (offset)) + +/** + * @brief Get the offset of the specified USB endpoint buffer + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 hardware endpoint ID. This parameter could be 0 ~ 7. + * + * @return The offset of the specified endpoint buffer. + * + * @details This macro will return the SRAM offset of the specified endpoint ID. + * + */ +#define USBD_GET_EP_BUF_ADDR(ep) ((uint32_t)*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].BUFSEG + (uint32_t)((ep) << 4)))) + +/** + * @brief Set USB endpoint stall state + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 hardware endpoint ID. This parameter could be 0 ~ 7. + * + * @return None + * + * @details Set USB endpoint stall state for the specified endpoint ID. Endpoint will respond STALL token automatically. + * + */ +#define USBD_SET_EP_STALL(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) |= USBD_CFGP_SSTALL_Msk) + +/** + * @brief Clear USB endpoint stall state + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 hardware endpoint ID. This parameter could be 0 ~ 7. + * + * @return None + * + * @details Clear USB endpoint stall state for the specified endpoint ID. Endpoint will respond ACK/NAK token. + */ +#define USBD_CLR_EP_STALL(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) &= ~USBD_CFGP_SSTALL_Msk) + +/** + * @brief Get USB endpoint stall state + * + * @param[in] ep The USB endpoint ID. M451 Series supports 8 hardware endpoint ID. This parameter could be 0 ~ 7. + * + * @retval 0 USB endpoint is not stalled. + * @retval Others USB endpoint is stalled. + * + * @details Get USB endpoint stall state of the specified endpoint ID. + * + */ +#define USBD_GET_EP_STALL(ep) (*((__IO uint32_t *) ((uint32_t)&USBD->EP[0].CFGP + (uint32_t)((ep) << 4))) & USBD_CFGP_SSTALL_Msk) + +/** + * @brief To support byte access between USB SRAM and system SRAM + * + * @param[in] dest Destination pointer. + * + * @param[in] src Source pointer. + * + * @param[in] size Byte count. + * + * @return None + * + * @details This function will copy the number of data specified by size and src parameters to the address specified by dest parameter. + * + */ +static __INLINE void USBD_MemCopy(uint8_t *dest, uint8_t *src, int32_t size) +{ + while(size--) *dest++ = *src++; +} + + +/** + * @brief Set USB endpoint stall state + * + * @param[in] epnum USB endpoint number + * + * @return None + * + * @details Set USB endpoint stall state. Endpoint will respond STALL token automatically. + * + */ +static __INLINE void USBD_SetStall(uint8_t epnum) +{ + uint32_t u32CfgAddr; + uint32_t u32Cfg; + int i; + + for(i = 0; i < USBD_MAX_EP; i++) + { + u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */ + u32Cfg = *((__IO uint32_t *)(u32CfgAddr)); + + if((u32Cfg & 0xf) == epnum) + { + u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */ + u32Cfg = *((__IO uint32_t *)(u32CfgAddr)); + + *((__IO uint32_t *)(u32CfgAddr)) = (u32Cfg | USBD_CFGP_SSTALL); + break; + } + } +} + +/** + * @brief Clear USB endpoint stall state + * + * @param[in] epnum USB endpoint number + * + * @return None + * + * @details Clear USB endpoint stall state. Endpoint will respond ACK/NAK token. + */ +static __INLINE void USBD_ClearStall(uint8_t epnum) +{ + uint32_t u32CfgAddr; + uint32_t u32Cfg; + int i; + + for(i = 0; i < USBD_MAX_EP; i++) + { + u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */ + u32Cfg = *((__IO uint32_t *)(u32CfgAddr)); + + if((u32Cfg & 0xf) == epnum) + { + u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */ + u32Cfg = *((__IO uint32_t *)(u32CfgAddr)); + + *((__IO uint32_t *)(u32CfgAddr)) = (u32Cfg & ~USBD_CFGP_SSTALL); + break; + } + } +} + +/** + * @brief Get USB endpoint stall state + * + * @param[in] epnum USB endpoint number + * + * @retval 0 USB endpoint is not stalled. + * @retval Others USB endpoint is stalled. + * + * @details Get USB endpoint stall state. + * + */ +static __INLINE uint32_t USBD_GetStall(uint8_t epnum) +{ + uint32_t u32CfgAddr; + uint32_t u32Cfg; + int i; + + for(i = 0; i < USBD_MAX_EP; i++) + { + u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFG; /* USBD_CFG0 */ + u32Cfg = *((__IO uint32_t *)(u32CfgAddr)); + + if((u32Cfg & 0xf) == epnum) + { + u32CfgAddr = (uint32_t)(i << 4) + (uint32_t)&USBD->EP[0].CFGP; /* USBD_CFGP0 */ + break; + } + } + + return ((*((__IO uint32_t *)(u32CfgAddr))) & USBD_CFGP_SSTALL); +} + + +extern volatile uint8_t g_usbd_RemoteWakeupEn; + + +typedef void (*VENDOR_REQ)(void); /*!< Functional pointer type definition for Vendor class */ +typedef void (*CLASS_REQ)(void); /*!< Functional pointer type declaration for USB class request callback handler */ +typedef void (*SET_INTERFACE_REQ)(void); /*!< Functional pointer type declaration for USB set interface request callback handler */ +typedef void (*SET_CONFIG_CB)(void); /*!< Functional pointer type declaration for USB set configuration request callback handler */ + + +/*--------------------------------------------------------------------*/ +void USBD_Open(const S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface); +void USBD_Start(void); +void USBD_GetSetupPacket(uint8_t *buf); +void USBD_ProcessSetupPacket(void); +void USBD_StandardRequest(void); +void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size); +void USBD_CtrlIn(void); +void USBD_PrepareCtrlOut(uint8_t *pu8Buf, uint32_t u32Size); +void USBD_CtrlOut(void); +void USBD_SwReset(void); +void USBD_SetVendorRequest(VENDOR_REQ pfnVendorReq); +void USBD_SetConfigCallback(SET_CONFIG_CB pfnSetConfigCallback); +void USBD_LockEpStall(uint32_t u32EpBitmap); + +/*@}*/ /* end of group USBD_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group USBD_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + + +#endif //__USBD_H__ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/wdt.h b/StdDriver/inc/wdt.h new file mode 100644 index 0000000..3c22721 --- /dev/null +++ b/StdDriver/inc/wdt.h @@ -0,0 +1,201 @@ +/**************************************************************************//** + * @file wdt.h + * @version V3.00 + * $Revision: 7 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series WDT driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __WDT_H__ +#define __WDT_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup WDT_Driver WDT Driver + @{ +*/ + +/** @addtogroup WDT_EXPORTED_CONSTANTS WDT Exported Constants + @{ +*/ +/*---------------------------------------------------------------------------------------------------------*/ +/* WDT Time-out Interval Period Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define WDT_TIMEOUT_2POW4 (0UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^4 * WDT clocks */ +#define WDT_TIMEOUT_2POW6 (1UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^6 * WDT clocks */ +#define WDT_TIMEOUT_2POW8 (2UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^8 * WDT clocks */ +#define WDT_TIMEOUT_2POW10 (3UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^10 * WDT clocks */ +#define WDT_TIMEOUT_2POW12 (4UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^12 * WDT clocks */ +#define WDT_TIMEOUT_2POW14 (5UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^14 * WDT clocks */ +#define WDT_TIMEOUT_2POW16 (6UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^16 * WDT clocks */ +#define WDT_TIMEOUT_2POW18 (7UL << WDT_CTL_TOUTSEL_Pos) /*!< Setting WDT time-out interval to 2^18 * WDT clocks */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* WDT Reset Delay Period Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define WDT_RESET_DELAY_1026CLK (0UL << WDT_ALTCTL_RSTDSEL_Pos) /*!< Setting WDT reset delay period to 1026 * WDT clocks */ +#define WDT_RESET_DELAY_130CLK (1UL << WDT_ALTCTL_RSTDSEL_Pos) /*!< Setting WDT reset delay period to 130 * WDT clocks */ +#define WDT_RESET_DELAY_18CLK (2UL << WDT_ALTCTL_RSTDSEL_Pos) /*!< Setting WDT reset delay period to 18 * WDT clocks */ +#define WDT_RESET_DELAY_3CLK (3UL << WDT_ALTCTL_RSTDSEL_Pos) /*!< Setting WDT reset delay period to 3 * WDT clocks */ + +/*@}*/ /* end of group WDT_EXPORTED_CONSTANTS */ + + +/** @addtogroup WDT_EXPORTED_FUNCTIONS WDT Exported Functions + @{ +*/ + +/** + * @brief Clear WDT Reset System Flag + * + * @param None + * + * @return None + * + * @details This macro clears WDT time-out reset system flag. + */ +#define WDT_CLEAR_RESET_FLAG() (WDT->CTL = (WDT->CTL & ~(WDT_CTL_IF_Msk | WDT_CTL_WKF_Msk)) | WDT_CTL_RSTF_Msk) + +/** + * @brief Clear WDT Time-out Interrupt Flag + * + * @param None + * + * @return None + * + * @details This macro clears WDT time-out interrupt flag. + */ +#define WDT_CLEAR_TIMEOUT_INT_FLAG() (WDT->CTL = (WDT->CTL & ~(WDT_CTL_RSTF_Msk | WDT_CTL_WKF_Msk)) | WDT_CTL_IF_Msk) + +/** + * @brief Clear WDT Wake-up Flag + * + * @param None + * + * @return None + * + * @details This macro clears WDT time-out wake-up system flag. + */ +#define WDT_CLEAR_TIMEOUT_WAKEUP_FLAG() (WDT->CTL = (WDT->CTL & ~(WDT_CTL_RSTF_Msk | WDT_CTL_IF_Msk)) | WDT_CTL_WKF_Msk) + +/** + * @brief Get WDT Time-out Reset Flag + * + * @param None + * + * @retval 0 WDT time-out reset system did not occur + * @retval 1 WDT time-out reset system occurred + * + * @details This macro indicates system has been reset by WDT time-out reset or not. + */ +#define WDT_GET_RESET_FLAG() ((WDT->CTL & WDT_CTL_RSTF_Msk)? 1 : 0) + +/** + * @brief Get WDT Time-out Interrupt Flag + * + * @param None + * + * @retval 0 WDT time-out interrupt did not occur + * @retval 1 WDT time-out interrupt occurred + * + * @details This macro indicates WDT time-out interrupt occurred or not. + */ +#define WDT_GET_TIMEOUT_INT_FLAG() ((WDT->CTL & WDT_CTL_IF_Msk)? 1 : 0) + +/** + * @brief Get WDT Time-out Wake-up Flag + * + * @param None + * + * @retval 0 WDT time-out interrupt does not cause CPU wake-up + * @retval 1 WDT time-out interrupt event cause CPU wake-up + * + * @details This macro indicates WDT time-out interrupt event has waked up system or not. + */ +#define WDT_GET_TIMEOUT_WAKEUP_FLAG() ((WDT->CTL & WDT_CTL_WKF_Msk)? 1 : 0) + +/** + * @brief Reset WDT Counter + * + * @param None + * + * @return None + * + * @details This macro is used to reset the internal 18-bit WDT up counter value. + * @note If WDT is activated and time-out reset system function is enabled also, user should \n + * reset the 18-bit WDT up counter value to avoid generate WDT time-out reset signal to \n + * reset system before the WDT time-out reset delay period expires. + */ +#define WDT_RESET_COUNTER() (WDT->CTL = (WDT->CTL & ~(WDT_CTL_IF_Msk | WDT_CTL_WKF_Msk | WDT_CTL_RSTF_Msk)) | WDT_CTL_RSTCNT_Msk) + +/** + * @brief Stop WDT Counting + * + * @param None + * + * @return None + * + * @details This function will stop WDT counting and disable WDT module. + */ +static __INLINE void WDT_Close(void) +{ + WDT->CTL = 0; + return; +} + +/** + * @brief Enable WDT Time-out Interrupt + * + * @param None + * + * @return None + * + * @details This function will enable the WDT time-out interrupt function. + */ +static __INLINE void WDT_EnableInt(void) +{ + WDT->CTL |= WDT_CTL_INTEN_Msk; + return; +} + +/** + * @brief Disable WDT Time-out Interrupt + * + * @param None + * + * @return None + * + * @details This function will disable the WDT time-out interrupt function. + */ +static __INLINE void WDT_DisableInt(void) +{ + // Do not touch another write 1 clear bits + WDT->CTL &= ~(WDT_CTL_INTEN_Msk | WDT_CTL_RSTF_Msk | WDT_CTL_IF_Msk | WDT_CTL_WKF_Msk); + return; +} + +void WDT_Open(uint32_t u32TimeoutInterval, uint32_t u32ResetDelay, uint32_t u32EnableReset, uint32_t u32EnableWakeup); + +/*@}*/ /* end of group WDT_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group WDT_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__WDT_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/inc/wwdt.h b/StdDriver/inc/wwdt.h new file mode 100644 index 0000000..56e8a83 --- /dev/null +++ b/StdDriver/inc/wwdt.h @@ -0,0 +1,148 @@ +/**************************************************************************//** + * @file wwdt.h + * @version V3.00 + * $Revision: 7 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series WWDT driver header file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#ifndef __WWDT_H__ +#define __WWDT_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup WWDT_Driver WWDT Driver + @{ +*/ + +/** @addtogroup WWDT_EXPORTED_CONSTANTS WWDT Exported Constants + @{ +*/ +/*---------------------------------------------------------------------------------------------------------*/ +/* WWDT Prescale Period Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define WWDT_PRESCALER_1 (0 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 1 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_2 (1 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 2 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_4 (2 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 4 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_8 (3 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 8 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_16 (4 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 16 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_32 (5 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 32 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_64 (6 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 64 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_128 (7 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 128 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_192 (8 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 192 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_256 (9 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 256 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_384 (10 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 384 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_512 (11 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 512 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_768 (12 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 768 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_1024 (13 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 1024 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_1536 (14 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 1536 * (64*WWDT_CLK) */ +#define WWDT_PRESCALER_2048 (15 << WWDT_CTL_PSCSEL_Pos) /*!< Select max time-out period to 2048 * (64*WWDT_CLK) */ + +/*---------------------------------------------------------------------------------------------------------*/ +/* WWDT Reload Counter Keyword Constant Definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define WWDT_RELOAD_WORD (0x00005AA5) /*!< Fill this value to WWDT_RLDCNT register to reload WWDT counter */ + +/*@}*/ /* end of group WWDT_EXPORTED_CONSTANTS */ + + +/** @addtogroup WWDT_EXPORTED_FUNCTIONS WWDT Exported Functions + @{ +*/ + +/** + * @brief Clear WWDT Reset System Flag + * + * @param None + * + * @return None + * + * @details This macro is used to clear WWDT time-out reset system flag. + */ +#define WWDT_CLEAR_RESET_FLAG() (WWDT->STATUS = (WWDT->STATUS & ~WWDT_STATUS_WWDTIF_Msk) | WWDT_STATUS_WWDTRF_Msk) + +/** + * @brief Clear WWDT Compared Match Interrupt Flag + * + * @param None + * + * @return None + * + * @details This macro is used to clear WWDT compared match interrupt flag. + */ +#define WWDT_CLEAR_INT_FLAG() (WWDT->STATUS = (WWDT->STATUS & ~WWDT_STATUS_WWDTRF_Msk) | WWDT_STATUS_WWDTIF_Msk) + +/** + * @brief Get WWDT Reset System Flag + * + * @param None + * + * @retval 0 WWDT time-out reset system did not occur + * @retval 1 WWDT time-out reset system occurred + * + * @details This macro is used to indicate system has been reset by WWDT time-out reset or not. + */ +#define WWDT_GET_RESET_FLAG() ((WWDT->STATUS & WWDT_STATUS_WWDTRF_Msk)? 1 : 0) + +/** + * @brief Get WWDT Compared Match Interrupt Flag + * + * @param None + * + * @retval 0 WWDT compare match interrupt did not occur + * @retval 1 WWDT compare match interrupt occurred + * + * @details This macro is used to indicate WWDT counter value matches CMPDAT value or not. + */ +#define WWDT_GET_INT_FLAG() ((WWDT->STATUS & WWDT_STATUS_WWDTIF_Msk)? 1 : 0) + +/** + * @brief Get WWDT Counter + * + * @param None + * + * @return WWDT Counter Value + * + * @details This macro reflects the current WWDT counter value. + */ +#define WWDT_GET_COUNTER() (WWDT->CNT) + +/** + * @brief Reload WWDT Counter + * + * @param None + * + * @return None + * + * @details This macro is used to reload the WWDT counter value to 0x3F. + * @note User can only write WWDT_RLDCNT register to reload WWDT counter value when current WWDT counter value \n + * between 0 and CMPDAT value. If user writes WWDT_RLDCNT when current WWDT counter value is larger than CMPDAT, \n + * WWDT reset signal will generate immediately to reset system. + */ +#define WWDT_RELOAD_COUNTER() (WWDT->RLDCNT = WWDT_RELOAD_WORD) + +void WWDT_Open(uint32_t u32PreScale, uint32_t u32CmpValue, uint32_t u32EnableInt); + +/*@}*/ /* end of group WWDT_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group WWDT_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +#endif //__WWDT_H__ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/acmp.c b/StdDriver/src/acmp.c new file mode 100644 index 0000000..6b5edd1 --- /dev/null +++ b/StdDriver/src/acmp.c @@ -0,0 +1,84 @@ +/**************************************************************************//** + * @file acmp.c + * @version V3.00 + * $Revision: 4 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series Analog Comparator(ACMP) driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ + +#include "M451Series.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup ACMP_Driver ACMP Driver + @{ +*/ + + +/** @addtogroup ACMP_EXPORTED_FUNCTIONS ACMP Exported Functions + @{ +*/ + + +/** + * @brief Configure the specified ACMP module + * + * @param[in] Acmp The pointer of the specified ACMP module + * @param[in] u32ChNum Comparator number. + * @param[in] u32NegSrc Comparator negative input selection. Including: + * - \ref ACMP_CTL_NEGSEL_PIN + * - \ref ACMP_CTL_NEGSEL_CRV + * - \ref ACMP_CTL_NEGSEL_VBG + * - \ref ACMP_CTL_NEGSEL_DAC + * @param[in] u32HysteresisEn The hysteresis function option. Including: + * - \ref ACMP_CTL_HYSTERESIS_ENABLE + * - \ref ACMP_CTL_HYSTERESIS_DISABLE + * + * @return None + * + * @details Configure hysteresis function, select the source of negative input and enable analog comparator. + */ +void ACMP_Open(ACMP_T *Acmp, uint32_t u32ChNum, uint32_t u32NegSrc, uint32_t u32HysteresisEn) +{ + Acmp->CTL[u32ChNum] = (Acmp->CTL[u32ChNum] & (~(ACMP_CTL_NEGSEL_Msk | ACMP_CTL_HYSEN_Msk))) | (u32NegSrc | u32HysteresisEn | ACMP_CTL_ACMPEN_Msk); +} + +/** + * @brief Close analog comparator + * + * @param[in] Acmp The pointer of the specified ACMP module + * @param[in] u32ChNum Comparator number. + * + * @return None + * + * @details This function will clear ACMPEN bit of ACMP_CTL register to disable analog comparator. + */ +void ACMP_Close(ACMP_T *Acmp, uint32_t u32ChNum) +{ + Acmp->CTL[u32ChNum] &= (~ACMP_CTL_ACMPEN_Msk); +} + + + +/*@}*/ /* end of group ACMP_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group ACMP_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ + diff --git a/StdDriver/src/can.c b/StdDriver/src/can.c new file mode 100644 index 0000000..d907ea6 --- /dev/null +++ b/StdDriver/src/can.c @@ -0,0 +1,1098 @@ +/**************************************************************************//** + * @file can.c + * @version V2.00 + * $Revision: 9 $ + * $Date: 2/19/16 2:26p $ + * @brief M451 series CAN driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup CAN_Driver CAN Driver + @{ +*/ + +/** @addtogroup CAN_EXPORTED_FUNCTIONS CAN Exported Functions + @{ +*/ + +/// @cond HIDDEN_SYMBOLS + +#if defined(CAN1) +static uint8_t gu8LockCanIf[2][2] = {0}; // The chip has two CANs. +#elif defined(CAN0) || defined(CAN) +static uint8_t gu8LockCanIf[1][2] = {0}; // The chip only has one CAN. +#endif + +#define RETRY_COUNTS (0x10000000) + +#define TSEG1_MIN 2ul +#define TSEG1_MAX 16ul +#define TSEG2_MIN 1ul +#define TSEG2_MAX 8ul +#define BRP_MIN 1ul +#define BRP_MAX 1024ul /* 6-bit BRP field + 4-bit BRPE field*/ +#define SJW_MAX 4ul +#define BRP_INC 1ul + + +static int can_update_spt(int sampl_pt, int tseg, int *tseg1, int *tseg2); + + + +//#define DEBUG_PRINTF printf +#define DEBUG_PRINTF(...) + + + +static int can_update_spt(int sampl_pt, int tseg, int *tseg1, int *tseg2) +{ + *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000; + if (*tseg2 < TSEG2_MIN) { + *tseg2 = TSEG2_MIN; + } else { + } + + if (*tseg2 > TSEG2_MAX) { + *tseg2 = TSEG2_MAX; + } else { + } + + *tseg1 = tseg - *tseg2; + if (*tseg1 > TSEG1_MAX) { + *tseg1 = TSEG1_MAX; + *tseg2 = tseg - *tseg1; + } else { + } + + return 1000 * (tseg + 1 - *tseg2) / (tseg + 1); +} + + +/** + * @brief Check if any interface is available then lock it for usage. + * @param[in] tCAN The pointer to CAN module base address. + * @retval 0 IF0 is free + * @retval 1 IF1 is free + * @retval 2 No IF is free + * @details Search the first free message interface, starting from 0. If a interface is + * available, set a flag to lock the interface. + */ +static uint32_t LockIF(CAN_T *tCAN) +{ + uint32_t u32CanNo; + uint32_t u32FreeIfNo; + uint32_t u32IntMask; + +#if defined(CAN1) + u32CanNo = (tCAN == CAN1) ? 1 : 0; +#else // defined(CAN0) || defined(CAN) + u32CanNo = 0; +#endif + + u32FreeIfNo = 2; + + /* Disable CAN interrupt */ + u32IntMask = tCAN->CON & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk); + tCAN->CON = tCAN->CON & ~(CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk); + + /* Check interface 1 is available or not */ + if((tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0) + { + if(gu8LockCanIf[u32CanNo][0] == FALSE) + { + gu8LockCanIf[u32CanNo][0] = TRUE; + u32FreeIfNo = 0; + } + } + + /* Or check interface 2 is available or not */ + if(u32FreeIfNo == 2 && (tCAN->IF[1].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0) + { + if(gu8LockCanIf[u32CanNo][1] == FALSE) + { + gu8LockCanIf[u32CanNo][1] = TRUE; + u32FreeIfNo = 1; + } + } + + /* Enable CAN interrupt */ + tCAN->CON |= u32IntMask; + + return u32FreeIfNo; +} + +/** + * @brief Check if any interface is available in a time limitation then lock it for usage. + * @param[in] tCAN The pointer to CAN module base address. + * @retval 0 IF0 is free + * @retval 1 IF1 is free + * @retval 2 No IF is free + * @details Search the first free message interface, starting from 0. If no interface is + * it will try again until time out. If a interface is available, set a flag to + * lock the interface. + */ +static uint32_t LockIF_TL(CAN_T *tCAN) +{ + uint32_t u32Count; + uint32_t u32FreeIfNo; + + for(u32Count = 0; u32Count < RETRY_COUNTS; u32Count++) + { + if((u32FreeIfNo = LockIF(tCAN)) != 2) + return u32FreeIfNo; + } + + return u32FreeIfNo; +} + +/** + * @brief Release locked interface. + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32Info The interface number, 0 or 1. + * @return none + * @details Release the locked interface. + */ +static void ReleaseIF(CAN_T *tCAN, uint32_t u32IfNo) +{ + uint32_t u32IntMask; + uint32_t u32CanNo; + + if(u32IfNo >= 2) + return; + +#if defined(CAN1) + u32CanNo = (tCAN == CAN1) ? 1 : 0; +#else // defined(CAN0) || defined(CAN) + u32CanNo = 0; +#endif + + /* Disable CAN interrupt */ + u32IntMask = tCAN->CON & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk); + tCAN->CON = tCAN->CON & ~(CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk); + + gu8LockCanIf[u32CanNo][u32IfNo] = FALSE; + + /* Enable CAN interrupt */ + tCAN->CON |= u32IntMask; +} + +/** + * @brief Enter initialization mode + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] Following values can be used. + * \ref CAN_CON_DAR_Msk Disable automatic retransmission. + * \ref CAN_CON_EIE_Msk Enable error interrupt. + * \ref CAN_CON_SIE_Msk Enable status interrupt. + * \ref CAN_CON_IE_Msk CAN interrupt. + * @return None + * @details This function is used to set CAN to enter initialization mode and enable access bit timing + * register. After bit timing configuration ready, user must call CAN_LeaveInitMode() + * to leave initialization mode and lock bit timing register to let new configuration + * take effect. + */ +void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask) +{ + tCAN->CON = u8Mask | (CAN_CON_INIT_Msk | CAN_CON_CCE_Msk); +} + + +/** + * @brief Leave initialization mode + * @param[in] tCAN The pointer to CAN module base address. + * @return None + * @details This function is used to set CAN to leave initialization mode to let + * bit timing configuration take effect after configuration ready. + */ +void CAN_LeaveInitMode(CAN_T *tCAN) +{ + tCAN->CON &= (~(CAN_CON_INIT_Msk | CAN_CON_CCE_Msk)); + while(tCAN->CON & CAN_CON_INIT_Msk); /* Check INIT bit is released */ +} + +/** + * @brief Wait message into message buffer in basic mode. + * @param[in] tCAN The pointer to CAN module base address. + * @return None + * @details This function is used to wait message into message buffer in basic mode. Please notice the + * function is polling NEWDAT bit of MCON register by while loop and it is used in basic mode. + */ +void CAN_WaitMsg(CAN_T *tCAN) +{ + tCAN->STATUS = 0x0; /* clr status */ + + while(1) + { + if(tCAN->IF[1].MCON & CAN_IF_MCON_NEWDAT_Msk) /* check new data */ + { + DEBUG_PRINTF("New Data IN\n"); + break; + } + + if(tCAN->STATUS & CAN_STATUS_RXOK_Msk) + DEBUG_PRINTF("Rx OK\n"); + + if(tCAN->STATUS & CAN_STATUS_LEC_Msk) + { + DEBUG_PRINTF("Error\n"); + } + } +} + +/** + * @brief Get current bit rate + * @param[in] tCAN The pointer to CAN module base address. + * @return Current Bit-Rate (kilo bit per second) + * @details Return current CAN bit rate according to the user bit-timing parameter settings + */ +uint32_t CAN_GetCANBitRate(CAN_T *tCAN) +{ + uint8_t u8Tseg1, u8Tseg2; + uint32_t u32Bpr; + + u8Tseg1 = (tCAN->BTIME & CAN_BTIME_TSEG1_Msk) >> CAN_BTIME_TSEG1_Pos; + u8Tseg2 = (tCAN->BTIME & CAN_BTIME_TSEG2_Msk) >> CAN_BTIME_TSEG2_Pos; + u32Bpr = (tCAN->BTIME & CAN_BTIME_BRP_Msk) | (tCAN->BRPE << 6); + + return (SystemCoreClock / (u32Bpr + 1) / (u8Tseg1 + u8Tseg2 + 3)); +} + +/** + * @brief Switch the CAN into test mode. + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u8TestMask Specifies the configuration in test modes + * \ref CAN_TEST_BASIC_Msk Enable basic mode of test mode + * \ref CAN_TEST_SILENT_Msk Enable silent mode of test mode + * \ref CAN_TEST_LBACK_Msk Enable Loop Back Mode of test mode + * \ref CAN_TEST_TX0_Msk / \ref CAN_TEST_TX1_Msk Control CAN_TX pin bit field + * @return None + * @details Switch the CAN into test mode. There are four test mode (BASIC/SILENT/LOOPBACK/ + * LOOPBACK combined SILENT/CONTROL_TX_PIN)could be selected. After setting test mode,user + * must call CAN_LeaveInitMode() to let the setting take effect. + */ +void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask) +{ + tCAN->CON |= CAN_CON_TEST_Msk; + tCAN->TEST = u8TestMask; +} + + +/** + * @brief Leave the test mode + * @param[in] tCAN The pointer to CAN module base address. + * @return None + * @details This function is used to Leave the test mode (switch into normal mode). + */ +void CAN_LeaveTestMode(CAN_T *tCAN) +{ + tCAN->CON |= CAN_CON_TEST_Msk; + tCAN->TEST &= ~(CAN_TEST_LBACK_Msk | CAN_TEST_SILENT_Msk | CAN_TEST_BASIC_Msk); + tCAN->CON &= (~CAN_CON_TEST_Msk); +} + +/** + * @brief Get the waiting status of a received message. + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31. + * @retval non-zero The corresponding message object has a new data bit is set. + * @retval 0 No message object has new data. + * @details This function is used to get the waiting status of a received message. + */ +uint32_t CAN_IsNewDataReceived(CAN_T *tCAN, uint8_t u8MsgObj) +{ + return (u8MsgObj < 16 ? tCAN->NDAT1 & (1 << u8MsgObj) : tCAN->NDAT2 & (1 << (u8MsgObj - 16))); +} + + +/** + * @brief Send CAN message in BASIC mode of test mode + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] pCanMsg Pointer to the message structure containing data to transmit. + * @return TRUE: Transmission OK + * FALSE: Check busy flag of interface 0 is timeout + * @details The function is used to send CAN message in BASIC mode of test mode. Before call the API, + * the user should be call CAN_EnterTestMode(CAN_TEST_BASIC) and let CAN controller enter + * basic mode of test mode. Please notice IF1 Registers used as Tx Buffer in basic mode. + */ +int32_t CAN_BasicSendMsg(CAN_T *tCAN, STR_CANMSG_T* pCanMsg) +{ + uint32_t i = 0; + while(tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk); + + tCAN->STATUS &= (~CAN_STATUS_TXOK_Msk); + + if(pCanMsg->IdType == CAN_STD_ID) + { + /* standard ID*/ + tCAN->IF[0].ARB1 = 0; + tCAN->IF[0].ARB2 = (((pCanMsg->Id) & 0x7FF) << 2) ; + } + else + { + /* extended ID*/ + tCAN->IF[0].ARB1 = (pCanMsg->Id) & 0xFFFF; + tCAN->IF[0].ARB2 = ((pCanMsg->Id) & 0x1FFF0000) >> 16 | CAN_IF_ARB2_XTD_Msk; + + } + + if(pCanMsg->FrameType) + tCAN->IF[0].ARB2 |= CAN_IF_ARB2_DIR_Msk; + else + tCAN->IF[0].ARB2 &= (~CAN_IF_ARB2_DIR_Msk); + + tCAN->IF[0].MCON = (tCAN->IF[0].MCON & (~CAN_IF_MCON_DLC_Msk)) | pCanMsg->DLC; + tCAN->IF[0].DAT_A1 = ((uint16_t)pCanMsg->Data[1] << 8) | pCanMsg->Data[0]; + tCAN->IF[0].DAT_A2 = ((uint16_t)pCanMsg->Data[3] << 8) | pCanMsg->Data[2]; + tCAN->IF[0].DAT_B1 = ((uint16_t)pCanMsg->Data[5] << 8) | pCanMsg->Data[4]; + tCAN->IF[0].DAT_B2 = ((uint16_t)pCanMsg->Data[7] << 8) | pCanMsg->Data[6]; + + /* request transmission*/ + tCAN->IF[0].CREQ &= (~CAN_IF_CREQ_BUSY_Msk); + if(tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) + { + DEBUG_PRINTF("Cannot clear busy for sending ...\n"); + return FALSE; + } + + tCAN->IF[0].CREQ |= CAN_IF_CREQ_BUSY_Msk; // sending + + for(i = 0; i < 0xFFFFF; i++) + { + if((tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0) + break; + } + + if(i >= 0xFFFFF) + { + DEBUG_PRINTF("Cannot send out...\n"); + return FALSE; + } + + return TRUE; +} + +/** + * @brief Get a message information in BASIC mode. + * + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] pCanMsg Pointer to the message structure where received data is copied. + * + * @return FALSE No any message received. + * TRUE Receive a message success. + * + */ +int32_t CAN_BasicReceiveMsg(CAN_T *tCAN, STR_CANMSG_T* pCanMsg) +{ + + if((tCAN->IF[1].MCON & CAN_IF_MCON_NEWDAT_Msk) == 0) /* In basic mode, receive data always save in IF2 */ + { + return FALSE; + } + + tCAN->STATUS &= (~CAN_STATUS_RXOK_Msk); + + tCAN->IF[1].CMASK = CAN_IF_CMASK_ARB_Msk + | CAN_IF_CMASK_CONTROL_Msk + | CAN_IF_CMASK_DATAA_Msk + | CAN_IF_CMASK_DATAB_Msk; + + if((tCAN->IF[1].ARB2 & CAN_IF_ARB2_XTD_Msk) == 0) + { + /* standard ID*/ + pCanMsg->IdType = CAN_STD_ID; + pCanMsg->Id = (tCAN->IF[1].ARB2 >> 2) & 0x07FF; + + } + else + { + /* extended ID*/ + pCanMsg->IdType = CAN_EXT_ID; + pCanMsg->Id = (tCAN->IF[1].ARB2 & 0x1FFF) << 16; + pCanMsg->Id |= (uint32_t)tCAN->IF[1].ARB1; + } + + pCanMsg->FrameType = !((tCAN->IF[1].ARB2 & CAN_IF_ARB2_DIR_Msk) >> CAN_IF_ARB2_DIR_Pos); + + pCanMsg->DLC = tCAN->IF[1].MCON & CAN_IF_MCON_DLC_Msk; + pCanMsg->Data[0] = tCAN->IF[1].DAT_A1 & CAN_IF_DAT_A1_DATA0_Msk; + pCanMsg->Data[1] = (tCAN->IF[1].DAT_A1 & CAN_IF_DAT_A1_DATA1_Msk) >> CAN_IF_DAT_A1_DATA1_Pos; + pCanMsg->Data[2] = tCAN->IF[1].DAT_A2 & CAN_IF_DAT_A2_DATA2_Msk; + pCanMsg->Data[3] = (tCAN->IF[1].DAT_A2 & CAN_IF_DAT_A2_DATA3_Msk) >> CAN_IF_DAT_A2_DATA3_Pos; + pCanMsg->Data[4] = tCAN->IF[1].DAT_B1 & CAN_IF_DAT_B1_DATA4_Msk; + pCanMsg->Data[5] = (tCAN->IF[1].DAT_B1 & CAN_IF_DAT_B1_DATA5_Msk) >> CAN_IF_DAT_B1_DATA5_Pos; + pCanMsg->Data[6] = tCAN->IF[1].DAT_B2 & CAN_IF_DAT_B2_DATA6_Msk; + pCanMsg->Data[7] = (tCAN->IF[1].DAT_B2 & CAN_IF_DAT_B2_DATA7_Msk) >> CAN_IF_DAT_B2_DATA7_Pos; + + return TRUE; +} + +/** + * @brief Set Rx message object, include ID mask. + * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31. + * @param[in] u8idType Specifies the identifier type of the frames that will be transmitted + * This parameter can be one of the following values: + * \ref CAN_STD_ID (standard ID, 11-bit) + * \ref CAN_EXT_ID (extended ID, 29-bit) + * @param[in] u32id Specifies the identifier used for acceptance filtering. + * @param[in] u32idmask Specifies the identifier mask + * @param[in] u8singleOrFifoLast Specifies the end-of-buffer indicator. + * This parameter can be one of the following values: + * TRUE: for a single receive object or a FIFO receive object that is the last one of the FIFO. + * FALSE: for a FIFO receive object that is not the last one. + * @retval TRUE SUCCESS + * @retval FALSE No useful interface + * @details The function is used to configure a receive message object. + */ +int32_t CAN_SetRxMsgObjAndMsk(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint32_t u32idmask, uint8_t u8singleOrFifoLast) +{ + uint8_t u8MsgIfNum; + + /* Get and lock a free interface */ + if((u8MsgIfNum = LockIF_TL(tCAN)) == 2) + return FALSE; + + /* Command Setting */ + tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk | + CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk; + + if(u8idType == CAN_STD_ID) /* According STD/EXT ID format,Configure Mask and Arbitration register */ + { + tCAN->IF[u8MsgIfNum].ARB1 = 0; + tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | (u32id & 0x7FF) << 2; + tCAN->IF[u8MsgIfNum].MASK1 = 0; + tCAN->IF[u8MsgIfNum].MASK2 = CAN_IF_MASK2_MXTD_Msk | CAN_IF_MASK2_MDIR_Msk | (u32idmask & 0x7FF) << 2; + } + else + { + tCAN->IF[u8MsgIfNum].ARB1 = u32id & 0xFFFF; + tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | CAN_IF_ARB2_XTD_Msk | (u32id & 0x1FFF0000) >> 16; + tCAN->IF[u8MsgIfNum].MASK1 = u32idmask & 0xFFFF; + tCAN->IF[u8MsgIfNum].MASK2 = CAN_IF_MASK2_MXTD_Msk | CAN_IF_MASK2_MDIR_Msk | (u32idmask & 0x1FFF0000) >> 16; + } + + //tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk; + tCAN->IF[u8MsgIfNum].MCON = CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk; + if(u8singleOrFifoLast) + tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_EOB_Msk; + else + tCAN->IF[u8MsgIfNum].MCON &= (~CAN_IF_MCON_EOB_Msk); + + tCAN->IF[u8MsgIfNum].DAT_A1 = 0; + tCAN->IF[u8MsgIfNum].DAT_A2 = 0; + tCAN->IF[u8MsgIfNum].DAT_B1 = 0; + tCAN->IF[u8MsgIfNum].DAT_B2 = 0; + + tCAN->IF[u8MsgIfNum].CREQ = 1 + u8MsgObj; + ReleaseIF(tCAN, u8MsgIfNum); + + return TRUE; +} + +/** + * @brief Set Rx message object + * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31. + * @param[in] u8idType Specifies the identifier type of the frames that will be transmitted + * This parameter can be one of the following values: + * \ref CAN_STD_ID (standard ID, 11-bit) + * \ref CAN_EXT_ID (extended ID, 29-bit) + * @param[in] u32id Specifies the identifier used for acceptance filtering. + * @param[in] u8singleOrFifoLast Specifies the end-of-buffer indicator. + * This parameter can be one of the following values: + * TRUE: for a single receive object or a FIFO receive object that is the last one of the FIFO. + * FALSE: for a FIFO receive object that is not the last one. + * @retval TRUE SUCCESS + * @retval FALSE No useful interface + * @details The function is used to configure a receive message object. + */ +int32_t CAN_SetRxMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast) +{ + uint8_t u8MsgIfNum; + + /* Get and lock a free interface */ + if((u8MsgIfNum = LockIF_TL(tCAN)) == 2) + return FALSE; + + /* Command Setting */ + tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk | + CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk; + + if(u8idType == CAN_STD_ID) /* According STD/EXT ID format,Configure Mask and Arbitration register */ + { + tCAN->IF[u8MsgIfNum].ARB1 = 0; + tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | (u32id & 0x7FF) << 2; + } + else + { + tCAN->IF[u8MsgIfNum].ARB1 = u32id & 0xFFFF; + tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | CAN_IF_ARB2_XTD_Msk | (u32id & 0x1FFF0000) >> 16; + } + + //tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk; + tCAN->IF[u8MsgIfNum].MCON = CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk; + if(u8singleOrFifoLast) + tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_EOB_Msk; + else + tCAN->IF[u8MsgIfNum].MCON &= (~CAN_IF_MCON_EOB_Msk); + + tCAN->IF[u8MsgIfNum].DAT_A1 = 0; + tCAN->IF[u8MsgIfNum].DAT_A2 = 0; + tCAN->IF[u8MsgIfNum].DAT_B1 = 0; + tCAN->IF[u8MsgIfNum].DAT_B2 = 0; + + tCAN->IF[u8MsgIfNum].CREQ = 1 + u8MsgObj; + ReleaseIF(tCAN, u8MsgIfNum); + + return TRUE; +} + +/** + * @brief Gets the message + * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31. + * @param[in] u8Release Specifies the message release indicator. + * This parameter can be one of the following values: + * TRUE: the message object is released when getting the data. + * FALSE:the message object is not released. + * @param[in] pCanMsg Pointer to the message structure where received data is copied. + * @retval TRUE Success + * @retval FALSE No any message received + * @details Gets the message, if received. + */ +int32_t CAN_ReadMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8Release, STR_CANMSG_T* pCanMsg) +{ + uint8_t u8MsgIfNum; + + if(!CAN_IsNewDataReceived(tCAN, u8MsgObj)) + return FALSE; + + /* Get and lock a free interface */ + if((u8MsgIfNum = LockIF_TL(tCAN)) == 2) + return FALSE; + + tCAN->STATUS &= (~CAN_STATUS_RXOK_Msk); + + /* read the message contents*/ + tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_MASK_Msk + | CAN_IF_CMASK_ARB_Msk + | CAN_IF_CMASK_CONTROL_Msk + | CAN_IF_CMASK_CLRINTPND_Msk + | (u8Release ? CAN_IF_CMASK_TXRQSTNEWDAT_Msk : 0) + | CAN_IF_CMASK_DATAA_Msk + | CAN_IF_CMASK_DATAB_Msk; + + tCAN->IF[u8MsgIfNum].CREQ = 1 + u8MsgObj; + + while(tCAN->IF[u8MsgIfNum].CREQ & CAN_IF_CREQ_BUSY_Msk) + { + /*Wait*/ + } + + if((tCAN->IF[u8MsgIfNum].ARB2 & CAN_IF_ARB2_XTD_Msk) == 0) + { + /* standard ID*/ + pCanMsg->IdType = CAN_STD_ID; + pCanMsg->Id = (tCAN->IF[u8MsgIfNum].ARB2 & CAN_IF_ARB2_ID_Msk) >> 2; + } + else + { + /* extended ID*/ + pCanMsg->IdType = CAN_EXT_ID; + pCanMsg->Id = (((tCAN->IF[u8MsgIfNum].ARB2) & 0x1FFF) << 16) | tCAN->IF[u8MsgIfNum].ARB1; + } + + pCanMsg->DLC = tCAN->IF[u8MsgIfNum].MCON & CAN_IF_MCON_DLC_Msk; + pCanMsg->Data[0] = tCAN->IF[u8MsgIfNum].DAT_A1 & CAN_IF_DAT_A1_DATA0_Msk; + pCanMsg->Data[1] = (tCAN->IF[u8MsgIfNum].DAT_A1 & CAN_IF_DAT_A1_DATA1_Msk) >> CAN_IF_DAT_A1_DATA1_Pos; + pCanMsg->Data[2] = tCAN->IF[u8MsgIfNum].DAT_A2 & CAN_IF_DAT_A2_DATA2_Msk; + pCanMsg->Data[3] = (tCAN->IF[u8MsgIfNum].DAT_A2 & CAN_IF_DAT_A2_DATA3_Msk) >> CAN_IF_DAT_A2_DATA3_Pos; + pCanMsg->Data[4] = tCAN->IF[u8MsgIfNum].DAT_B1 & CAN_IF_DAT_B1_DATA4_Msk; + pCanMsg->Data[5] = (tCAN->IF[u8MsgIfNum].DAT_B1 & CAN_IF_DAT_B1_DATA5_Msk) >> CAN_IF_DAT_B1_DATA5_Pos; + pCanMsg->Data[6] = tCAN->IF[u8MsgIfNum].DAT_B2 & CAN_IF_DAT_B2_DATA6_Msk; + pCanMsg->Data[7] = (tCAN->IF[u8MsgIfNum].DAT_B2 & CAN_IF_DAT_B2_DATA7_Msk) >> CAN_IF_DAT_B2_DATA7_Pos; + + ReleaseIF(tCAN, u8MsgIfNum); + return TRUE; +} + +/// @endcond HIDDEN_SYMBOLS + + +/** + * @brief Set bus baud-rate. + * + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32BaudRate The target CAN baud-rate. The range of u32BaudRate is 1Kbps~1000Kbps. + * + * @return u32CurrentBitRate Real baud-rate value. + * + * @details The function is used to set bus timing parameter according current clock and target baud-rate. + */ +uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate) +{ + long rate; + long best_error = 1000000000, error = 0; + int best_tseg = 0, best_brp = 0, brp = 0; + int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0; + int spt_error = 1000, spt = 0, sampl_pt; + uint64_t clock_freq = (uint64_t)0; + uint32_t sjw = (uint32_t)1; + + CAN_EnterInitMode(tCAN, (uint8_t) 0); + + SystemCoreClockUpdate(); + clock_freq = CLK_GetPCLK0Freq(); + + if(u32BaudRate > (uint32_t)1000000) + { + u32BaudRate = (uint32_t)1000000; + } + + /* Use CIA recommended sample points */ + if(u32BaudRate > (uint32_t)800000) + { + sampl_pt = (int)750; + } + else if(u32BaudRate > (uint32_t)500000) + { + sampl_pt = (int)800; + } + else + { + sampl_pt = (int)875; + } + + /* tseg even = round down, odd = round up */ + for(tseg = (TSEG1_MAX + TSEG2_MAX) * 2ul + 1ul; tseg >= (TSEG1_MIN + TSEG2_MIN) * 2ul; tseg--) + { + tsegall = 1ul + tseg / 2ul; + /* Compute all possible tseg choices (tseg=tseg1+tseg2) */ + brp = clock_freq / (tsegall * u32BaudRate) + tseg % 2; + /* chose brp step which is possible in system */ + brp = (brp / BRP_INC) * BRP_INC; + + if((brp < BRP_MIN) || (brp > BRP_MAX)) + { + continue; + } + rate = clock_freq / (brp * tsegall); + + error = u32BaudRate - rate; + + /* tseg brp biterror */ + if(error < 0) + { + error = -error; + } + if(error > best_error) + { + continue; + } + best_error = error; + if(error == 0) + { + spt = can_update_spt(sampl_pt, tseg / 2, &tseg1, &tseg2); + error = sampl_pt - spt; + if(error < 0) + { + error = -error; + } + if(error > spt_error) + { + continue; + } + spt_error = error; + } + best_tseg = tseg / 2; + best_brp = brp; + + if(error == 0) + { + break; + } + } + + spt = can_update_spt(sampl_pt, best_tseg, &tseg1, &tseg2); + + /* check for sjw user settings */ + /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ + if(sjw > SJW_MAX) + { + sjw = SJW_MAX; + } + /* bt->sjw must not be higher than tseg2 */ + if(tseg2 < sjw) + { + sjw = tseg2; + } + + /* real bit-rate */ + u32BaudRate = clock_freq / (best_brp * (tseg1 + tseg2 + 1)); + + tCAN->BTIME = ((uint32_t)(tseg2 - 1ul) << CAN_BTIME_TSEG2_Pos) | ((uint32_t)(tseg1 - 1ul) << CAN_BTIME_TSEG1_Pos) | + ((uint32_t)(best_brp - 1ul) & CAN_BTIME_BRP_Msk) | (sjw << CAN_BTIME_SJW_Pos); + tCAN->BRPE = ((uint32_t)(best_brp - 1ul) >> 6) & 0x0Ful; + + /* printf("\n bitrate = %d \n", CAN_GetCANBitRate(tCAN)); */ + + CAN_LeaveInitMode(tCAN); + + return u32BaudRate; +} + +/** + * @brief The function is used to disable all CAN interrupt. + * + * @param[in] tCAN The pointer to CAN module base address. + * + * @return None + * + * @details No Status Change Interrupt and Error Status Interrupt will be generated. + */ +void CAN_Close(CAN_T *tCAN) +{ + CAN_DisableInt(tCAN, (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk)); +} + +/** + * @brief Set CAN operation mode and target baud-rate. + * + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32BaudRate The target CAN baud-rate. The range of u32BaudRate is 1Kbps~1000Kbps. + * @param[in] u32Mode The CAN operation mode. Valid values are: + * - \ref CAN_NORMAL_MODE Normal operation. + * - \ref CAN_BASIC_MODE Basic mode. + * @return u32CurrentBitRate Real baud-rate value. + * + * @details Set bus timing parameter according current clock and target baud-rate. + * In Basic mode, IF1 Registers used as Tx Buffer, IF2 Registers used as Rx Buffer. + */ +uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode) +{ + uint32_t u32CurrentBitRate; + + u32CurrentBitRate = CAN_SetBaudRate(tCAN, u32BaudRate); + + if(u32Mode == CAN_BASIC_MODE) + CAN_EnterTestMode(tCAN, CAN_TEST_BASIC_Msk); + + return u32CurrentBitRate; +} + +/** + * @brief The function is used to configure a transmit object. + * + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31. + * @param[in] pCanMsg Pointer to the message structure where received data is copied. + * + * @retval FALSE No useful interface. + * @retval TRUE Config message object success. + * + * @details The two sets of interface registers (IF1 and IF2) control the software access to the Message RAM. + * They buffer the data to be transferred to and from the RAM, avoiding conflicts between software accesses and message reception/transmission. + */ +int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg) +{ + uint8_t u8MsgIfNum; + + if((u8MsgIfNum = LockIF_TL(tCAN)) == 2) + return FALSE; + + /* update the contents needed for transmission*/ + tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk | + CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk; + + if(pCanMsg->IdType == CAN_STD_ID) + { + /* standard ID*/ + tCAN->IF[u8MsgIfNum].ARB1 = 0; + tCAN->IF[u8MsgIfNum].ARB2 = (((pCanMsg->Id) & 0x7FF) << 2) | CAN_IF_ARB2_DIR_Msk | CAN_IF_ARB2_MSGVAL_Msk; + } + else + { + /* extended ID*/ + tCAN->IF[u8MsgIfNum].ARB1 = (pCanMsg->Id) & 0xFFFF; + tCAN->IF[u8MsgIfNum].ARB2 = ((pCanMsg->Id) & 0x1FFF0000) >> 16 | + CAN_IF_ARB2_DIR_Msk | CAN_IF_ARB2_XTD_Msk | CAN_IF_ARB2_MSGVAL_Msk; + } + + if(pCanMsg->FrameType) + tCAN->IF[u8MsgIfNum].ARB2 |= CAN_IF_ARB2_DIR_Msk; + else + tCAN->IF[u8MsgIfNum].ARB2 &= (~CAN_IF_ARB2_DIR_Msk); + + tCAN->IF[u8MsgIfNum].DAT_A1 = ((uint16_t)pCanMsg->Data[1] << 8) | pCanMsg->Data[0]; + tCAN->IF[u8MsgIfNum].DAT_A2 = ((uint16_t)pCanMsg->Data[3] << 8) | pCanMsg->Data[2]; + tCAN->IF[u8MsgIfNum].DAT_B1 = ((uint16_t)pCanMsg->Data[5] << 8) | pCanMsg->Data[4]; + tCAN->IF[u8MsgIfNum].DAT_B2 = ((uint16_t)pCanMsg->Data[7] << 8) | pCanMsg->Data[6]; + + tCAN->IF[u8MsgIfNum].MCON = CAN_IF_MCON_NEWDAT_Msk | pCanMsg->DLC | CAN_IF_MCON_TXIE_Msk | CAN_IF_MCON_EOB_Msk; + tCAN->IF[u8MsgIfNum].CREQ = 1 + u32MsgNum; + + ReleaseIF(tCAN, u8MsgIfNum); + return TRUE; +} + +/** + * @brief Set transmit request bit. + * + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31. + * + * @return TRUE: Start transmit message. + * + * @details If a transmission is requested by programming bit TxRqst/NewDat (IFn_CMASK[2]), the TxRqst (IFn_MCON[8]) will be ignored. + */ +int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum) +{ + uint8_t u8MsgIfNum; + + if((u8MsgIfNum = LockIF_TL(tCAN)) == 2) + return FALSE; + + tCAN->STATUS &= (~CAN_STATUS_TXOK_Msk); + + /* read the message contents*/ + tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_CLRINTPND_Msk + | CAN_IF_CMASK_TXRQSTNEWDAT_Msk; + + tCAN->IF[u8MsgIfNum].CREQ = 1 + u32MsgNum; + + while(tCAN->IF[u8MsgIfNum].CREQ & CAN_IF_CREQ_BUSY_Msk) + { + /*Wait*/ + } + tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_TXRQSTNEWDAT_Msk; + tCAN->IF[u8MsgIfNum].CREQ = 1 + u32MsgNum; + + ReleaseIF(tCAN, u8MsgIfNum); + return TRUE; +} + +/** + * @brief Enable CAN interrupt. + * + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32Mask Interrupt Mask. Valid values are: + * - \ref CAN_CON_IE_Msk Module interrupt enable. + * - \ref CAN_CON_SIE_Msk Status change interrupt enable. + * - \ref CAN_CON_EIE_Msk Error interrupt enable. + * + * @return None + * + * @details The application software has two possibilities to follow the source of a message interrupt. + * First, it can follow the IntId in the Interrupt Register and second it can poll the Interrupt Pending Register. + */ +void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask) +{ + tCAN->CON = (tCAN->CON & ~(CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk)) | + (u32Mask & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk)); +} + +/** + * @brief Disable CAN interrupt. + * + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32Mask Interrupt Mask. Valid values are: + * - CAN_CON_IE_Msk: Module interrupt enable. + * - CAN_CON_SIE_Msk: Status change interrupt enable. + * - CAN_CON_EIE_Msk: Error interrupt enable. + * + * @return None + * + * @details The interrupt remains active until the Interrupt Register is back to value zero (the cause of the interrupt is reset) or until IE is reset. + */ +void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask) +{ + tCAN->CON = tCAN->CON & ~((u32Mask & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk))); +} + + +/** + * @brief The function is used to configure a receive message object. + * + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31. + * @param[in] u32IDType Specifies the identifier type of the frames that will be transmitted. Valid values are: + * - \ref CAN_STD_ID The 11-bit identifier. + * - \ref CAN_EXT_ID The 29-bit identifier. + * @param[in] u32ID Specifies the identifier used for acceptance filtering. + * + * @retval FALSE No useful interface. + * @retval TRUE Configure a receive message object success. + * + * @details If the RxIE bit (CAN_IFn_MCON[10]) is set, the IntPnd bit (CAN_IFn_MCON[13]) + * will be set when a received Data Frame is accepted and stored in the Message Object. + */ +int32_t CAN_SetRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID) +{ + uint32_t u32TimeOutCount = 0; + + while(CAN_SetRxMsgObj(tCAN, u32MsgNum, u32IDType, u32ID, TRUE) == FALSE) + { + if(++u32TimeOutCount >= RETRY_COUNTS) return FALSE; + } + + return TRUE; +} + +/** + * @brief The function is used to configure a receive message object. + * + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31. + * @param[in] u32IDType Specifies the identifier type of the frames that will be transmitted. Valid values are: + * - \ref CAN_STD_ID The 11-bit identifier. + * - \ref CAN_EXT_ID The 29-bit identifier. + * @param[in] u32ID Specifies the identifier used for acceptance filtering. + * @param[in] u32IDMask Specifies the identifier mask used for acceptance filtering. + * + * @retval FALSE No useful interface. + * @retval TRUE Configure a receive message object success. + * + * @details If the RxIE bit (CAN_IFn_MCON[10]) is set, the IntPnd bit (CAN_IFn_MCON[13]) + * will be set when a received Data Frame is accepted and stored in the Message Object. + */ +int32_t CAN_SetRxMsgAndMsk(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID, uint32_t u32IDMask) +{ + uint32_t u32TimeOutCount = 0; + + while(CAN_SetRxMsgObjAndMsk(tCAN, u32MsgNum, u32IDType, u32ID, u32IDMask, TRUE) == FALSE) + { + if(++u32TimeOutCount >= RETRY_COUNTS) return FALSE; + } + + return TRUE; +} + +/** + * @brief The function is used to configure several receive message objects. + * + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32MsgNum The starting MSG RAM number, from 0 to 31. + * @param[in] u32MsgCount the number of MSG RAM of the FIFO. + * @param[in] u32IDType Specifies the identifier type of the frames that will be transmitted. Valid values are: + * - \ref CAN_STD_ID The 11-bit identifier. + * - \ref CAN_EXT_ID The 29-bit identifier. + * @param[in] u32ID Specifies the identifier used for acceptance filtering. + * + * @retval FALSE No useful interface. + * @retval TRUE Configure receive message objects success. + * + * @details The Interface Registers avoid conflict between the CPU accesses to the Message RAM and CAN message reception + * and transmission by buffering the data to be transferred. + */ +int32_t CAN_SetMultiRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32MsgCount, uint32_t u32IDType, uint32_t u32ID) +{ + uint32_t i = 0; + uint32_t u32TimeOutCount; + uint32_t u32EOB_Flag = 0; + + for(i = 1; i < u32MsgCount; i++) + { + u32TimeOutCount = 0; + + u32MsgNum += (i - 1); + + if(i == u32MsgCount) u32EOB_Flag = 1; + + while(CAN_SetRxMsgObj(tCAN, u32MsgNum, u32IDType, u32ID, u32EOB_Flag) == FALSE) + { + if(++u32TimeOutCount >= RETRY_COUNTS) return FALSE; + } + } + + return TRUE; +} + + +/** + * @brief Send CAN message. + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31. + * @param[in] pCanMsg Pointer to the message structure where received data is copied. + * + * @retval FALSE 1. When operation in basic mode: Transmit message time out. \n + * 2. When operation in normal mode: No useful interface. \n + * @retval TRUE Transmit Message success. + * + * @details The receive/transmit priority for the Message Objects is attached to the message number. + * Message Object 1 has the highest priority, while Message Object 32 has the lowest priority. + */ +int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg) +{ + if((tCAN->CON & CAN_CON_TEST_Msk) && (tCAN->TEST & CAN_TEST_BASIC_Msk)) + { + return (CAN_BasicSendMsg(tCAN, pCanMsg)); + } + else + { + if(CAN_SetTxMsg(tCAN, u32MsgNum, pCanMsg) == FALSE) + return FALSE; + CAN_TriggerTxMsg(tCAN, u32MsgNum); + } + + return TRUE; +} + + +/** + * @brief Gets the message, if received. + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31. + * @param[in] pCanMsg Pointer to the message structure where received data is copied. + * + * @retval FALSE No any message received. + * @retval TRUE Receive Message success. + * + * @details The Interface Registers avoid conflict between the CPU accesses to the Message RAM and CAN message reception + * and transmission by buffering the data to be transferred. + */ +int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg) +{ + if((tCAN->CON & CAN_CON_TEST_Msk) && (tCAN->TEST & CAN_TEST_BASIC_Msk)) + { + return (CAN_BasicReceiveMsg(tCAN, pCanMsg)); + } + else + { + return CAN_ReadMsgObj(tCAN, u32MsgNum, TRUE, pCanMsg); + } +} + +/** + * @brief Clear interrupt pending bit. + * @param[in] tCAN The pointer to CAN module base address. + * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31. + * + * @return None + * + * @details An interrupt remains pending until the application software has cleared it. + */ +void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum) +{ + uint32_t u32MsgIfNum; + + if((u32MsgIfNum = LockIF_TL(tCAN)) == 2) + u32MsgIfNum = 0; + + tCAN->IF[u32MsgIfNum].CMASK = CAN_IF_CMASK_CLRINTPND_Msk | CAN_IF_CMASK_TXRQSTNEWDAT_Msk; + tCAN->IF[u32MsgIfNum].CREQ = 1 + u32MsgNum; + + ReleaseIF(tCAN, u32MsgIfNum); +} + + +/*@}*/ /* end of group CAN_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group CAN_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ + diff --git a/StdDriver/src/clk.c b/StdDriver/src/clk.c new file mode 100644 index 0000000..3231816 --- /dev/null +++ b/StdDriver/src/clk.c @@ -0,0 +1,751 @@ +/**************************************************************************//** + * @file clk.c + * @version V3.00 + * $Revision: 37 $ + * $Date: 16/07/07 3:46p $ + * @brief M451 series CLK driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ + +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup CLK_Driver CLK Driver + @{ +*/ + +/** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions + @{ +*/ + +/** + * @brief Disable clock divider output function + * @param None + * @return None + * @details This function disable clock divider output function. + */ +void CLK_DisableCKO(void) +{ + /* Disable CKO clock source */ + CLK_DisableModuleClock(CLKO_MODULE); +} + +/** + * @brief This function enable clock divider output module clock, + * enable clock divider output function and set frequency selection. + * @param[in] u32ClkSrc is frequency divider function clock source. Including : + * - \ref CLK_CLKSEL1_CLKOSEL_HXT + * - \ref CLK_CLKSEL1_CLKOSEL_LXT + * - \ref CLK_CLKSEL1_CLKOSEL_HCLK + * - \ref CLK_CLKSEL1_CLKOSEL_HIRC + * @param[in] u32ClkDiv is divider output frequency selection. It could be 0~15. + * @param[in] u32ClkDivBy1En is clock divided by one enabled. + * @return None + * @details Output selected clock to CKO. The output clock frequency is divided by u32ClkDiv. \n + * The formula is: \n + * CKO frequency = (Clock source frequency) / 2^(u32ClkDiv + 1) \n + * This function is just used to set CKO clock. + * User must enable I/O for CKO clock output pin by themselves. \n + */ +void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En) +{ + /* CKO = clock source / 2^(u32ClkDiv + 1) */ + CLK->CLKOCTL = CLK_CLKOCTL_CLKOEN_Msk | u32ClkDiv | (u32ClkDivBy1En << CLK_CLKOCTL_DIV1EN_Pos); + + /* Enable CKO clock source */ + CLK_EnableModuleClock(CLKO_MODULE); + + /* Select CKO clock source */ + CLK_SetModuleClock(CLKO_MODULE, u32ClkSrc, 0); +} + +/** + * @brief Enter to Power-down mode + * @param None + * @return None + * @details This function is used to let system enter to Power-down mode. \n + * The register write-protection function should be disabled before using this function. + */ +void CLK_PowerDown(void) +{ + /* Set the processor uses deep sleep as its low power mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* Set system Power-down enabled and Power-down entry condition */ + CLK->PWRCTL |= (CLK_PWRCTL_PDEN_Msk | CLK_PWRCTL_PDWTCPU_Msk); + + /* Chip enter Power-down mode after CPU run WFI instruction */ + __WFI(); +} + +/** + * @brief Enter to Idle mode + * @param None + * @return None + * @details This function let system enter to Idle mode. \n + * The register write-protection function should be disabled before using this function. + */ +void CLK_Idle(void) +{ + /* Set the processor uses sleep as its low power mode */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + /* Set chip in idle mode because of WFI command */ + CLK->PWRCTL &= ~CLK_PWRCTL_PDEN_Msk; + + /* Chip enter idle mode after CPU run WFI instruction */ + __WFI(); +} + +/** + * @brief Get external high speed crystal clock frequency + * @param None + * @return External high frequency crystal frequency + * @details This function get external high frequency crystal frequency. The frequency unit is Hz. + */ +uint32_t CLK_GetHXTFreq(void) +{ + if(CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk) + return __HXT; + else + return 0; +} + + +/** + * @brief Get external low speed crystal clock frequency + * @param None + * @return External low speed crystal clock frequency + * @details This function get external low frequency crystal frequency. The frequency unit is Hz. + */ +uint32_t CLK_GetLXTFreq(void) +{ + if(CLK->PWRCTL & CLK_PWRCTL_LXTEN_Msk) + return __LXT; + else + return 0; +} + +/** + * @brief Get PCLK0 frequency + * @param None + * @return PCLK0 frequency + * @details This function get PCLK0 frequency. The frequency unit is Hz. + */ +uint32_t CLK_GetPCLK0Freq(void) +{ + SystemCoreClockUpdate(); + if(CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) + return SystemCoreClock / 2; + else + return SystemCoreClock; +} + + +/** + * @brief Get PCLK1 frequency + * @param None + * @return PCLK1 frequency + * @details This function get PCLK1 frequency. The frequency unit is Hz. + */ +uint32_t CLK_GetPCLK1Freq(void) +{ + SystemCoreClockUpdate(); + if(CLK->CLKSEL0 & CLK_CLKSEL0_PCLK1SEL_Msk) + return SystemCoreClock / 2; + else + return SystemCoreClock; +} + + +/** + * @brief Get HCLK frequency + * @param None + * @return HCLK frequency + * @details This function get HCLK frequency. The frequency unit is Hz. + */ +uint32_t CLK_GetHCLKFreq(void) +{ + SystemCoreClockUpdate(); + return SystemCoreClock; +} + + +/** + * @brief Get CPU frequency + * @param None + * @return CPU frequency + * @details This function get CPU frequency. The frequency unit is Hz. + */ +uint32_t CLK_GetCPUFreq(void) +{ + SystemCoreClockUpdate(); + return SystemCoreClock; +} + + +/** + * @brief Set HCLK frequency + * @param[in] u32Hclk is HCLK frequency. The range of u32Hclk is 25 MHz ~ 72 MHz. + * @return HCLK frequency + * @details This function is used to set HCLK frequency. The frequency unit is Hz. \n + * It would configure PLL frequency to 50MHz ~ 144MHz, + * set HCLK clock divider as 2 and switch HCLK clock source to PLL. \n + * The register write-protection function should be disabled before using this function. + */ +uint32_t CLK_SetCoreClock(uint32_t u32Hclk) +{ + uint32_t u32HIRCSTB; + + /* Read HIRC clock source stable flag */ + u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk; + + /* The range of u32Hclk is 25 MHz ~ 72 MHz */ + if(u32Hclk > FREQ_72MHZ) + u32Hclk = FREQ_72MHZ; + if(u32Hclk < FREQ_25MHZ) + u32Hclk = FREQ_25MHZ; + + /* Switch HCLK clock source to HIRC clock for safe */ + CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk; + CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); + CLK->CLKSEL0 |= CLK_CLKSEL0_HCLKSEL_Msk; + CLK->CLKDIV0 &= (~CLK_CLKDIV0_HCLKDIV_Msk); + + /* Configure PLL setting if HXT clock is stable */ + if(CLK->STATUS & CLK_STATUS_HXTSTB_Msk) + u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HXT, (u32Hclk << 1)); + + /* Configure PLL setting if HXT clock is not stable */ + else + { + u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HIRC, (u32Hclk << 1)); + + /* Read HIRC clock source stable flag */ + u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk; + } + + /* Select HCLK clock source to PLL, + Select HCLK clock source divider as 2 + and update system core clock + */ + CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(2)); + + /* Disable HIRC if HIRC is disabled before setting core clock */ + if(u32HIRCSTB == 0) + CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk; + + /* Return actually HCLK frequency is PLL frequency divide 2 */ + return u32Hclk >> 1; +} + +/** + * @brief This function set HCLK clock source and HCLK clock divider + * @param[in] u32ClkSrc is HCLK clock source. Including : + * - \ref CLK_CLKSEL0_HCLKSEL_HXT + * - \ref CLK_CLKSEL0_HCLKSEL_LXT + * - \ref CLK_CLKSEL0_HCLKSEL_PLL + * - \ref CLK_CLKSEL0_HCLKSEL_LIRC + * - \ref CLK_CLKSEL0_HCLKSEL_HIRC + * @param[in] u32ClkDiv is HCLK clock divider. Including : + * - \ref CLK_CLKDIV0_HCLK(x) + * @return None + * @details This function set HCLK clock source and HCLK clock divider. \n + * The register write-protection function should be disabled before using this function. + */ +void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv) +{ + uint32_t u32HIRCSTB; + + /* Read HIRC clock source stable flag */ + u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk; + + /* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */ + CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk; + CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); + CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | CLK_CLKSEL0_HCLKSEL_HIRC; + + /* Apply new Divider */ + CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_HCLKDIV_Msk)) | u32ClkDiv; + + /* Switch HCLK to new HCLK source */ + CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | u32ClkSrc; + + /* Update System Core Clock */ + SystemCoreClockUpdate(); + + /* Disable HIRC if HIRC is disabled before switching HCLK source */ + if(u32HIRCSTB == 0) + CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk; +} + +/** + * @brief This function set selected module clock source and module clock divider + * @param[in] u32ModuleIdx is module index. + * @param[in] u32ClkSrc is module clock source. + * @param[in] u32ClkDiv is module clock divider. + * @return None + * @details Valid parameter combinations listed in following table: + * + * |Module index |Clock source |Divider | + * | :---------------- | :----------------------------------- | :---------------------- | + * |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDTSEL_LXT | x | + * |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDTSEL_HCLK_DIV2048 | x | + * |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDTSEL_LIRC | x | + * |\ref RTC_MODULE |\ref CLK_CLKSEL3_RTCSEL_LXT | x | + * |\ref RTC_MODULE |\ref CLK_CLKSEL3_RTCSEL_LIRC | x | + * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_HXT | x | + * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_LXT | x | + * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_PCLK0 | x | + * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_EXT_TRG | x | + * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_LIRC | x | + * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_HIRC | x | + * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_HXT | x | + * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_LXT | x | + * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_PCLK0 | x | + * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_EXT_TRG | x | + * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_LIRC | x | + * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_HIRC | x | + * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_HXT | x | + * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_LXT | x | + * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_PCLK1 | x | + * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_EXT_TRG | x | + * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_LIRC | x | + * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_HIRC | x | + * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_HXT | x | + * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_LXT | x | + * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_PCLK1 | x | + * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_EXT_TRG | x | + * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_LIRC | x | + * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_HIRC | x | + * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_HXT | x | + * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_LXT | x | + * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_HCLK | x | + * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_HIRC | x | + * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_HXT | x | + * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_PLL | x | + * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_PCLK0 | x | + * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_HIRC | x | + * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_HXT | x | + * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_PLL | x | + * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_PCLK1 | x | + * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_HIRC | x | + * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_HXT | x | + * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_PLL | x | + * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_PCLK0 | x | + * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_HIRC | x | + * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UARTSEL_HXT |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UARTSEL_PLL |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UARTSEL_LXT |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UARTSEL_HIRC |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UARTSEL_HXT |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UARTSEL_PLL |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UARTSEL_LXT |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UARTSEL_HIRC |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART2_MODULE |\ref CLK_CLKSEL1_UARTSEL_HXT |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART2_MODULE |\ref CLK_CLKSEL1_UARTSEL_PLL |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART2_MODULE |\ref CLK_CLKSEL1_UARTSEL_LXT |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART2_MODULE |\ref CLK_CLKSEL1_UARTSEL_HIRC |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART3_MODULE |\ref CLK_CLKSEL1_UARTSEL_HXT |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART3_MODULE |\ref CLK_CLKSEL1_UARTSEL_LXT |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART3_MODULE |\ref CLK_CLKSEL1_UARTSEL_PLL |\ref CLK_CLKDIV0_UART(x) | + * |\ref UART3_MODULE |\ref CLK_CLKSEL1_UARTSEL_HIRC |\ref CLK_CLKDIV0_UART(x) | + * |\ref USBH_MODULE | x |\ref CLK_CLKDIV0_USB(x) | + * |\ref USBD_MODULE | x |\ref CLK_CLKDIV0_USB(x) | + * |\ref OTG_MODULE | x |\ref CLK_CLKDIV0_USB(x) | + * |\ref EADC_MODULE | x |\ref CLK_CLKDIV0_EADC(x) | + * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_HXT |\ref CLK_CLKDIV1_SC0(x) | + * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_PLL |\ref CLK_CLKDIV1_SC0(x) | + * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_PCLK0 |\ref CLK_CLKDIV1_SC0(x) | + * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_HIRC |\ref CLK_CLKDIV1_SC0(x) | + * |\ref PWM0_MODULE |\ref CLK_CLKSEL2_PWM0SEL_PLL | x | + * |\ref PWM0_MODULE |\ref CLK_CLKSEL2_PWM0SEL_PCLK0 | x | + * |\ref PWM1_MODULE |\ref CLK_CLKSEL2_PWM1SEL_PLL | x | + * |\ref PWM1_MODULE |\ref CLK_CLKSEL2_PWM1SEL_PCLK1 | x | + * |\ref WWDT_MODULE |\ref CLK_CLKSEL1_WWDTSEL_HCLK_DIV2048 | x | + * |\ref WWDT_MODULE |\ref CLK_CLKSEL1_WWDTSEL_LIRC | x | + */ +void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv) +{ + uint32_t u32sel = 0, u32div = 0; + + if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk) + { + /* Get clock divider control register address */ + u32div = (uint32_t)&CLK->CLKDIV0 + ((MODULE_CLKDIV(u32ModuleIdx)) * 4); + /* Apply new divider */ + M32(u32div) = (M32(u32div) & (~(MODULE_CLKDIV_Msk(u32ModuleIdx) << MODULE_CLKDIV_Pos(u32ModuleIdx)))) | u32ClkDiv; + } + + if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk) + { + /* Get clock select control register address */ + u32sel = (uint32_t)&CLK->CLKSEL0 + ((MODULE_CLKSEL(u32ModuleIdx)) * 4); + /* Set new clock selection setting */ + M32(u32sel) = (M32(u32sel) & (~(MODULE_CLKSEL_Msk(u32ModuleIdx) << MODULE_CLKSEL_Pos(u32ModuleIdx)))) | u32ClkSrc; + } +} + + +/** + * @brief Set SysTick clock source + * @param[in] u32ClkSrc is module clock source. Including: + * - \ref CLK_CLKSEL0_STCLKSEL_HXT + * - \ref CLK_CLKSEL0_STCLKSEL_LXT + * - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2 + * - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2 + * - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2 + * @return None + * @details This function set SysTick clock source. \n + * The register write-protection function should be disabled before using this function. + */ +void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc) +{ + CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc; + +} + +/** + * @brief Enable clock source + * @param[in] u32ClkMask is clock source mask. Including : + * - \ref CLK_PWRCTL_HXTEN_Msk + * - \ref CLK_PWRCTL_LXTEN_Msk + * - \ref CLK_PWRCTL_HIRCEN_Msk + * - \ref CLK_PWRCTL_LIRCEN_Msk + * @return None + * @details This function enable clock source. \n + * The register write-protection function should be disabled before using this function. + */ +void CLK_EnableXtalRC(uint32_t u32ClkMask) +{ + CLK->PWRCTL |= u32ClkMask; +} + +/** + * @brief Disable clock source + * @param[in] u32ClkMask is clock source mask. Including : + * - \ref CLK_PWRCTL_HXTEN_Msk + * - \ref CLK_PWRCTL_LXTEN_Msk + * - \ref CLK_PWRCTL_HIRCEN_Msk + * - \ref CLK_PWRCTL_LIRCEN_Msk + * @return None + * @details This function disable clock source. \n + * The register write-protection function should be disabled before using this function. + */ +void CLK_DisableXtalRC(uint32_t u32ClkMask) +{ + CLK->PWRCTL &= ~u32ClkMask; +} + +/** + * @brief Enable module clock + * @param[in] u32ModuleIdx is module index. Including : + * - \ref PDMA_MODULE + * - \ref ISP_MODULE + * - \ref EBI_MODULE + * - \ref USBH_MODULE + * - \ref CRC_MODULE + * - \ref WDT_MODULE + * - \ref WWDT_MODULE + * - \ref RTC_MODULE + * - \ref TMR0_MODULE + * - \ref TMR1_MODULE + * - \ref TMR2_MODULE + * - \ref TMR3_MODULE + * - \ref CLKO_MODULE + * - \ref ACMP01_MODULE + * - \ref I2C0_MODULE + * - \ref I2C1_MODULE + * - \ref SPI0_MODULE + * - \ref SPI1_MODULE + * - \ref SPI2_MODULE + * - \ref UART0_MODULE + * - \ref UART1_MODULE + * - \ref UART2_MODULE + * - \ref UART3_MODULE + * - \ref CAN0_MODULE + * - \ref OTG_MODULE + * - \ref USBD_MODULE + * - \ref EADC_MODULE + * - \ref SC0_MODULE + * - \ref DAC_MODULE + * - \ref PWM0_MODULE + * - \ref PWM1_MODULE + * - \ref TK_MODULE + * @return None + * @details This function is used to enable module clock. + */ +void CLK_EnableModuleClock(uint32_t u32ModuleIdx) +{ + *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK + (MODULE_APBCLK(u32ModuleIdx) * 4)) |= 1 << MODULE_IP_EN_Pos(u32ModuleIdx); +} + +/** + * @brief Disable module clock + * @param[in] u32ModuleIdx is module index. Including : + * - \ref PDMA_MODULE + * - \ref ISP_MODULE + * - \ref EBI_MODULE + * - \ref USBH_MODULE + * - \ref CRC_MODULE + * - \ref WDT_MODULE + * - \ref WWDT_MODULE + * - \ref RTC_MODULE + * - \ref TMR0_MODULE + * - \ref TMR1_MODULE + * - \ref TMR2_MODULE + * - \ref TMR3_MODULE + * - \ref CLKO_MODULE + * - \ref ACMP01_MODULE + * - \ref I2C0_MODULE + * - \ref I2C1_MODULE + * - \ref SPI0_MODULE + * - \ref SPI1_MODULE + * - \ref SPI2_MODULE + * - \ref UART0_MODULE + * - \ref UART1_MODULE + * - \ref UART2_MODULE + * - \ref UART3_MODULE + * - \ref CAN0_MODULE + * - \ref OTG_MODULE + * - \ref USBD_MODULE + * - \ref EADC_MODULE + * - \ref SC0_MODULE + * - \ref DAC_MODULE + * - \ref PWM0_MODULE + * - \ref PWM1_MODULE + * - \ref TK_MODULE + * @return None + * @details This function is used to disable module clock. + */ +void CLK_DisableModuleClock(uint32_t u32ModuleIdx) +{ + *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK + (MODULE_APBCLK(u32ModuleIdx) * 4)) &= ~(1 << MODULE_IP_EN_Pos(u32ModuleIdx)); +} + + +/** + * @brief Set PLL frequency + * @param[in] u32PllClkSrc is PLL clock source. Including : + * - \ref CLK_PLLCTL_PLLSRC_HXT + * - \ref CLK_PLLCTL_PLLSRC_HIRC + * @param[in] u32PllFreq is PLL frequency. + * @return PLL frequency + * @details This function is used to configure PLLCTL register to set specified PLL frequency. \n + * The register write-protection function should be disabled before using this function. + */ +uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq) +{ + uint32_t u32PllSrcClk, u32NR, u32NF, u32NO, u32CLK_SRC; + uint32_t u32Tmp, u32Tmp2, u32Tmp3, u32Min, u32MinNF, u32MinNR; + + /* Disable PLL first to avoid unstable when setting PLL */ + CLK_DisablePLL(); + + /* PLL source clock is from HXT */ + if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT) + { + /* Enable HXT clock */ + CLK->PWRCTL |= CLK_PWRCTL_HXTEN_Msk; + + /* Wait for HXT clock ready */ + CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk); + + /* Select PLL source clock from HXT */ + u32CLK_SRC = CLK_PLLCTL_PLLSRC_HXT; + u32PllSrcClk = __HXT; + + /* u32NR start from 2 */ + u32NR = 2; + } + + /* PLL source clock is from HIRC */ + else + { + /* Enable HIRC clock */ + CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk; + + /* Wait for HIRC clock ready */ + CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); + + /* Select PLL source clock from HIRC */ + u32CLK_SRC = CLK_PLLCTL_PLLSRC_HIRC; + u32PllSrcClk = __HIRC; + + /* u32NR start from 4 when FIN = 22.1184MHz to avoid calculation overflow */ + u32NR = 4; + } + + /* Select "NO" according to request frequency */ + if((u32PllFreq <= FREQ_500MHZ) && (u32PllFreq > FREQ_250MHZ)) + { + u32NO = 0; + } + else if((u32PllFreq <= FREQ_250MHZ) && (u32PllFreq > FREQ_125MHZ)) + { + u32NO = 1; + u32PllFreq = u32PllFreq << 1; + } + else if((u32PllFreq <= FREQ_125MHZ) && (u32PllFreq >= FREQ_50MHZ)) + { + u32NO = 3; + u32PllFreq = u32PllFreq << 2; + } + else + { + /* Wrong frequency request. Just return default setting. */ + goto lexit; + } + + /* Find best solution */ + u32Min = (uint32_t) - 1; + u32MinNR = 0; + u32MinNF = 0; + for(; u32NR <= 33; u32NR++) + { + u32Tmp = u32PllSrcClk / u32NR; + if((u32Tmp > 1600000) && (u32Tmp < 16000000)) + { + for(u32NF = 2; u32NF <= 513; u32NF++) + { + u32Tmp2 = u32Tmp * u32NF; + if((u32Tmp2 >= 200000000) && (u32Tmp2 <= 500000000)) + { + u32Tmp3 = (u32Tmp2 > u32PllFreq) ? u32Tmp2 - u32PllFreq : u32PllFreq - u32Tmp2; + if(u32Tmp3 < u32Min) + { + u32Min = u32Tmp3; + u32MinNR = u32NR; + u32MinNF = u32NF; + + /* Break when get good results */ + if(u32Min == 0) + break; + } + } + } + } + } + + /* Enable and apply new PLL setting. */ + CLK->PLLCTL = u32CLK_SRC | (u32NO << 14) | ((u32MinNR - 2) << 9) | (u32MinNF - 2); + + /* Wait for PLL clock stable */ + CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk); + + /* Return actual PLL output clock frequency */ + return u32PllSrcClk / ((u32NO + 1) * u32MinNR) * u32MinNF; + +lexit: + + /* Apply default PLL setting and return */ + if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT) + CLK->PLLCTL = CLK_PLLCTL_72MHz_HXT; /* 72MHz */ + else + CLK->PLLCTL = CLK_PLLCTL_72MHz_HIRC; /* 71.8848MHz */ + + /* Wait for PLL clock stable */ + CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk); + + return CLK_GetPLLClockFreq(); + +} + +/** + * @brief Disable PLL + * @param None + * @return None + * @details This function set PLL in Power-down mode. \n + * The register write-protection function should be disabled before using this function. + */ +void CLK_DisablePLL(void) +{ + CLK->PLLCTL |= CLK_PLLCTL_PD_Msk; +} + + +/** + * @brief This function check selected clock source status + * @param[in] u32ClkMask is selected clock source. Including : + * - \ref CLK_STATUS_HXTSTB_Msk + * - \ref CLK_STATUS_LXTSTB_Msk + * - \ref CLK_STATUS_HIRCSTB_Msk + * - \ref CLK_STATUS_LIRCSTB_Msk + * - \ref CLK_STATUS_PLLSTB_Msk + * @retval 0 clock is not stable + * @retval 1 clock is stable + * @details To wait for clock ready by specified clock source stable flag or timeout (~300ms) + */ +uint32_t CLK_WaitClockReady(uint32_t u32ClkMask) +{ + int32_t i32TimeOutCnt = 2160000; + + while((CLK->STATUS & u32ClkMask) != u32ClkMask) + { + if(i32TimeOutCnt-- <= 0) + return 0; + } + + return 1; +} + +/** + * @brief Enable System Tick counter + * @param[in] u32ClkSrc is System Tick clock source. Including: + * - \ref CLK_CLKSEL0_STCLKSEL_HXT + * - \ref CLK_CLKSEL0_STCLKSEL_LXT + * - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2 + * - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2 + * - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2 + * - \ref CLK_CLKSEL0_STCLKSEL_HCLK + * @param[in] u32Count is System Tick reload value. It could be 0~0xFFFFFF. + * @return None + * @details This function set System Tick clock source, reload value, enable System Tick counter and interrupt. \n + * The register write-protection function should be disabled before using this function. + */ +void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count) +{ + /* Set System Tick counter disabled */ + SysTick->CTRL = 0; + + /* Set System Tick clock source */ + if( u32ClkSrc == CLK_CLKSEL0_STCLKSEL_HCLK ) + SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk; + else + CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc; + + /* Set System Tick reload value */ + SysTick->LOAD = u32Count; + + /* Clear System Tick current value and counter flag */ + SysTick->VAL = 0; + + /* Set System Tick interrupt enabled and counter enabled */ + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; +} + +/** + * @brief Disable System Tick counter + * @param None + * @return None + * @details This function disable System Tick counter. + */ +void CLK_DisableSysTick(void) +{ + /* Set System Tick counter disabled */ + SysTick->CTRL = 0; +} + + +/*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group CLK_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/crc.c b/StdDriver/src/crc.c new file mode 100644 index 0000000..346a6a5 --- /dev/null +++ b/StdDriver/src/crc.c @@ -0,0 +1,93 @@ +/**************************************************************************//** + * @file crc.c + * @version V3.00 + * $Revision: 7 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series CRC driver source file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup CRC_Driver CRC Driver + @{ +*/ + +/** @addtogroup CRC_EXPORTED_FUNCTIONS CRC Exported Functions + @{ +*/ + +/** + * @brief CRC Open + * + * @param[in] u32Mode CRC operation polynomial mode. Valid values are: + * - \ref CRC_CCITT + * - \ref CRC_8 + * - \ref CRC_16 + * - \ref CRC_32 + * @param[in] u32Attribute CRC operation data attribute. Valid values are combined with: + * - \ref CRC_CHECKSUM_COM + * - \ref CRC_CHECKSUM_RVS + * - \ref CRC_WDATA_COM + * - \ref CRC_WDATA_RVS + * @param[in] u32Seed Seed value. + * @param[in] u32DataLen CPU Write Data Length. Valid values are: + * - \ref CRC_CPU_WDATA_8 + * - \ref CRC_CPU_WDATA_16 + * - \ref CRC_CPU_WDATA_32 + * + * @return None + * + * @details This function will enable the CRC controller by specify CRC operation mode, attribute, initial seed and write data length. \n + * After that, user can start to perform CRC calculate by calling CRC_WRITE_DATA macro or CRC_DAT register directly. + */ +void CRC_Open(uint32_t u32Mode, uint32_t u32Attribute, uint32_t u32Seed, uint32_t u32DataLen) +{ + CRC->SEED = u32Seed; + CRC->CTL = u32Mode | u32Attribute | u32DataLen | CRC_CTL_CRCEN_Msk; + + /* Setting CRCRST bit will reload the initial seed value(CRC_SEED register) to CRC controller */ + CRC->CTL |= CRC_CTL_CRCRST_Msk; +} + +/** + * @brief Get CRC Checksum + * + * @param[in] None + * + * @return Checksum Result + * + * @details This macro gets the CRC checksum result by current CRC polynomial mode. + */ +uint32_t CRC_GetChecksum(void) +{ + switch(CRC->CTL & CRC_CTL_CRCMODE_Msk) + { + case CRC_CCITT: + case CRC_16: + return (CRC->CHECKSUM & 0xFFFF); + + case CRC_32: + return (CRC->CHECKSUM); + + case CRC_8: + return (CRC->CHECKSUM & 0xFF); + + default: + return 0; + } +} + +/*@}*/ /* end of group CRC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group CRC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/dac.c b/StdDriver/src/dac.c new file mode 100644 index 0000000..4baffbd --- /dev/null +++ b/StdDriver/src/dac.c @@ -0,0 +1,94 @@ +/**************************************************************************//** + * @file dac.c + * @version V2.00 + * $Revision: 8 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series DAC driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup DAC_Driver DAC Driver + @{ +*/ + +/** @addtogroup DAC_EXPORTED_FUNCTIONS DAC Exported Functions + @{ +*/ + +/** + * @brief This function make DAC module be ready to convert. + * @param[in] dac Base address of DAC module. + * @param[in] u32Ch Not used in M451 Series DAC. + * @param[in] u32TrgSrc Decides the trigger source. Valid values are: + * - \ref DAC_WRITE_DAT_TRIGGER :Write DAC_DAT trigger + * - \ref DAC_SOFTWARE_TRIGGER :Software trigger + * - \ref DAC_LOW_LEVEL_TRIGGER :STDAC pin low level trigger + * - \ref DAC_HIGH_LEVEL_TRIGGER :STDAC pin high level trigger + * - \ref DAC_FALLING_EDGE_TRIGGER :STDAC pin falling edge trigger + * - \ref DAC_RISING_EDGE_TRIGGER :STDAC pin rising edge trigger + * - \ref DAC_TIMER0_TRIGGER :Timer 0 trigger + * - \ref DAC_TIMER1_TRIGGER :Timer 1 trigger + * - \ref DAC_TIMER2_TRIGGER :Timer 2 trigger + * - \ref DAC_TIMER3_TRIGGER :Timer 3 trigger + * - \ref DAC_PWM0_TRIGGER :PWM0 trigger + * - \ref DAC_PWM1_TRIGGER :PWM1 trigger + * @return None + * @details The DAC conversion can be started by writing DAC_DAT, software trigger or hardware trigger. + * When TRGEN (DAC_CTL[4]) is 0, the data conversion is started by writing DAC_DAT register. + * When TRGEN (DAC_CTL[4]) is 1, the data conversion is started by SWTRG (DAC_SWTRG[0]) is set to 1, + * external STDAC pin, timer event, or PWM timer event. + */ +void DAC_Open(DAC_T *dac, + uint32_t u32Ch, + uint32_t u32TrgSrc) +{ + dac->CTL &= ~(DAC_CTL_ETRGSEL_Msk | DAC_CTL_TRGSEL_Msk | DAC_CTL_TRGEN_Msk); + + dac->CTL |= (u32TrgSrc | DAC_CTL_DACEN_Msk); +} + +/** + * @brief Disable DAC analog power. + * @param[in] dac Base address of DAC module. + * @param[in] u32Ch Not used in M451 Series DAC. + * @return None + * @details Disable DAC analog power for saving power consumption. + */ +void DAC_Close(DAC_T *dac, uint32_t u32Ch) +{ + dac->CTL &= (~DAC_CTL_DACEN_Msk); +} + +/** + * @brief Set delay time for DAC to become stable. + * @param[in] dac Base address of DAC module. + * @param[in] u32Delay Decides the DAC conversion settling time, the range is from 0~(1023/PCLK*1000000) micro seconds. + * @return Real DAC conversion settling time (micro second). + * @details For example, DAC controller clock speed is 72MHz and DAC conversion setting time is 1 us, SETTLET (DAC_TCTL[9:0]) value must be greater than 0x48. + * @note User needs to write appropriate value to meet DAC conversion settling time base on PCLK (APB clock) speed. + */ +float DAC_SetDelayTime(DAC_T *dac, uint32_t u32Delay) +{ + SystemCoreClockUpdate(); + + dac->TCTL = ((SystemCoreClock * u32Delay / 1000000) & 0x3FF); + + return ((dac->TCTL) * 1000000 / SystemCoreClock); +} + + + +/*@}*/ /* end of group DAC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group DAC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/eadc.c b/StdDriver/src/eadc.c new file mode 100644 index 0000000..741e51d --- /dev/null +++ b/StdDriver/src/eadc.c @@ -0,0 +1,159 @@ +/**************************************************************************//** + * @file eadc.c + * @version V2.00 + * $Revision: 8 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series EADC driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup EADC_Driver EADC Driver + @{ +*/ + +/** @addtogroup EADC_EXPORTED_FUNCTIONS EADC Exported Functions + @{ +*/ + +/** + * @brief This function make EADC_module be ready to convert. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32InputMode Decides the input mode. + * - \ref EADC_CTL_DIFFEN_SINGLE_END :Single end input mode. + * - \ref EADC_CTL_DIFFEN_DIFFERENTIAL :Differential input type. + * @return None + * @details This function is used to set analog input mode and enable A/D Converter. + * Before starting A/D conversion function, ADCEN bit (EADC_CTL[0]) should be set to 1. + * @note + */ +void EADC_Open(EADC_T *eadc, uint32_t u32InputMode) +{ + eadc->CTL &= (~EADC_CTL_DIFFEN_Msk); + + eadc->CTL |= (u32InputMode | EADC_CTL_ADCEN_Msk); +} + +/** + * @brief Disable EADC_module. + * @param[in] eadc The pointer of the specified EADC module.. + * @return None + * @details Clear ADCEN bit (EADC_CTL[0]) to disable A/D converter analog circuit power consumption. + */ +void EADC_Close(EADC_T *eadc) +{ + eadc->CTL &= ~EADC_CTL_ADCEN_Msk; +} + +/** + * @brief Configure the sample control logic module. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15. + * @param[in] u32TriggerSrc Decides the trigger source. Valid values are: + * - \ref EADC_SOFTWARE_TRIGGER : Disable trigger + * - \ref EADC_FALLING_EDGE_TRIGGER : STADC pin falling edge trigger + * - \ref EADC_RISING_EDGE_TRIGGER : STADC pin rising edge trigger + * - \ref EADC_FALLING_RISING_EDGE_TRIGGER : STADC pin both falling and rising edge trigger + * - \ref EADC_ADINT0_TRIGGER : ADC ADINT0 interrupt EOC pulse trigger + * - \ref EADC_ADINT1_TRIGGER : ADC ADINT1 interrupt EOC pulse trigger + * - \ref EADC_TIMER0_TRIGGER : Timer0 overflow pulse trigger + * - \ref EADC_TIMER1_TRIGGER : Timer1 overflow pulse trigger + * - \ref EADC_TIMER2_TRIGGER : Timer2 overflow pulse trigger + * - \ref EADC_TIMER3_TRIGGER : Timer3 overflow pulse trigger + * - \ref EADC_PWM0TG0_TRIGGER : PWM0TG0 trigger + * - \ref EADC_PWM0TG1_TRIGGER : PWM0TG1 trigger + * - \ref EADC_PWM0TG2_TRIGGER : PWM0TG2 trigger + * - \ref EADC_PWM0TG3_TRIGGER : PWM0TG3 trigger + * - \ref EADC_PWM0TG4_TRIGGER : PWM0TG4 trigger + * - \ref EADC_PWM0TG5_TRIGGER : PWM0TG5 trigger + * - \ref EADC_PWM1TG0_TRIGGER : PWM1TG0 trigger + * - \ref EADC_PWM1TG1_TRIGGER : PWM1TG1 trigger + * - \ref EADC_PWM1TG2_TRIGGER : PWM1TG2 trigger + * - \ref EADC_PWM1TG3_TRIGGER : PWM1TG3 trigger + * - \ref EADC_PWM1TG4_TRIGGER : PWM1TG4 trigger + * - \ref EADC_PWM1TG5_TRIGGER : PWM1TG5 trigger + * @param[in] u32Channel Specifies the sample module channel, valid value are from 0 to 15. + * @return None + * @details Each of ADC control logic modules 0~15 which is configurable for ADC converter channel EADC_CH0~15 and trigger source. + * sample module 16~18 is fixed for ADC channel 16, 17, 18 input sources as band-gap voltage, temperature sensor, and battery power (VBAT). + */ +void EADC_ConfigSampleModule(EADC_T *eadc, \ + uint32_t u32ModuleNum, \ + uint32_t u32TriggerSrc, \ + uint32_t u32Channel) +{ + eadc->SCTL[u32ModuleNum] &= ~(EADC_SCTL_EXTFEN_Msk | EADC_SCTL_EXTREN_Msk | EADC_SCTL_TRGSEL_Msk | EADC_SCTL_CHSEL_Msk); + eadc->SCTL[u32ModuleNum] |= (u32TriggerSrc | u32Channel); +} + + +/** + * @brief Set trigger delay time. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15. + * @param[in] u32TriggerDelayTime Decides the trigger delay time, valid range are between 0~0xFF. + * @param[in] u32DelayClockDivider Decides the trigger delay clock divider. Valid values are: + * - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_1 : Trigger delay clock frequency is ADC_CLK/1 + * - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_2 : Trigger delay clock frequency is ADC_CLK/2 + * - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_4 : Trigger delay clock frequency is ADC_CLK/4 + * - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_16 : Trigger delay clock frequency is ADC_CLK/16 + * @return None + * @details User can configure the trigger delay time by setting TRGDLYCNT (EADC_SCTLn[15:8], n=0~15) and TRGDLYDIV (EADC_SCTLn[7:6], n=0~15). + * Trigger delay time = (u32TriggerDelayTime) x Trigger delay clock period. + */ +void EADC_SetTriggerDelayTime(EADC_T *eadc, \ + uint32_t u32ModuleNum, \ + uint32_t u32TriggerDelayTime, \ + uint32_t u32DelayClockDivider) +{ + eadc->SCTL[u32ModuleNum] &= ~(EADC_SCTL_TRGDLYDIV_Msk | EADC_SCTL_TRGDLYCNT_Msk); + eadc->SCTL[u32ModuleNum] |= ((u32TriggerDelayTime << EADC_SCTL_TRGDLYCNT_Pos) | u32DelayClockDivider); +} + +/** + * @brief Set ADC internal sample time. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32SampleTime Decides the internal sampling time, the range is from 1~8 ADC clock. Valid value are from 1 to 8. + * @return None + * @details When A/D operation at high ADC clock rate, the sampling time of analog input voltage may not enough + * if the analog channel has heavy loading to cause fully charge time is longer. + * User can set SMPTSEL (EADC_CTL[18:16]) to select the sampling cycle in ADC. + */ +void EADC_SetInternalSampleTime(EADC_T *eadc, uint32_t u32SampleTime) +{ + eadc->CTL &= ~EADC_CTL_SMPTSEL_Msk; + + eadc->CTL |= (u32SampleTime - 1) << EADC_CTL_SMPTSEL_Pos; + +} + +/** + * @brief Set ADC extend sample time. + * @param[in] eadc The pointer of the specified EADC module. + * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 18. + * @param[in] u32ExtendSampleTime Decides the extend sampling time, the range is from 0~255 ADC clock. Valid value are from 0 to 0xFF. + * @return None + * @details When A/D converting at high conversion rate, the sampling time of analog input voltage may not enough if input channel loading is heavy, + * user can extend A/D sampling time after trigger source is coming to get enough sampling time. + */ +void EADC_SetExtendSampleTime(EADC_T *eadc, uint32_t u32ModuleNum, uint32_t u32ExtendSampleTime) +{ + eadc->SCTL[u32ModuleNum] &= ~EADC_SCTL_EXTSMPT_Msk; + + eadc->SCTL[u32ModuleNum] |= (u32ExtendSampleTime << EADC_SCTL_EXTSMPT_Pos); + +} + +/*@}*/ /* end of group EADC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group EADC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/ebi.c b/StdDriver/src/ebi.c new file mode 100644 index 0000000..e4d7b7c --- /dev/null +++ b/StdDriver/src/ebi.c @@ -0,0 +1,178 @@ +/**************************************************************************//** + * @file ebi.c + * @version V3.00 + * $Revision: 9 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series EBI driver source file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup EBI_Driver EBI Driver + @{ +*/ + +/** @addtogroup EBI_EXPORTED_FUNCTIONS EBI Exported Functions + @{ +*/ + +/** + * @brief Initialize EBI for specify Bank + * + * @param[in] u32Bank Bank number for EBI. Valid values are: + * - \ref EBI_BANK0 + * - \ref EBI_BANK1 + * @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 Enable EBI separate mode. This parameter is current not used. + * @param[in] u32CSActiveLevel CS is active High/Low. Valid values are: + * - \ref EBI_CS_ACTIVE_HIGH + * - \ref EBI_CS_ACTIVE_LOW + * + * @return none + * + * @details This function is used to open specify EBI bank with different bus width, timing setting and \n + * active level of CS pin to access EBI device. + * @note Write Buffer Enable(WBUFEN) and Extend Time Of ALE(TALE) are only available in EBI bank0 control register. + */ +void EBI_Open(uint32_t u32Bank, uint32_t u32DataWidth, uint32_t u32TimingClass, uint32_t u32BusMode, uint32_t u32CSActiveLevel) +{ + volatile uint32_t *pu32EBICTL = (uint32_t *)((uint32_t)&EBI->CTL0 + (u32Bank * 0x10)); + volatile uint32_t *pu32EBITCTL = (uint32_t *)((uint32_t)&EBI->TCTL0 + (u32Bank * 0x10)); + + if(u32DataWidth == EBI_BUSWIDTH_8BIT) + *pu32EBICTL &= ~EBI_CTL0_DW16_Msk; + else + *pu32EBICTL |= EBI_CTL0_DW16_Msk; + + switch(u32TimingClass) + { + case EBI_TIMING_FASTEST: + *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL0_MCLKDIV_Msk | EBI_CTL0_TALE_Msk)) | + (EBI_MCLKDIV_1 << EBI_CTL0_MCLKDIV_Pos) | + (u32CSActiveLevel << EBI_CTL0_CSPOLINV_Pos) | EBI_CTL0_EN_Msk; + *pu32EBITCTL = 0x0; + break; + + case EBI_TIMING_VERYFAST: + *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL0_MCLKDIV_Msk | EBI_CTL0_TALE_Msk)) | + (EBI_MCLKDIV_1 << EBI_CTL0_MCLKDIV_Pos) | + (u32CSActiveLevel << EBI_CTL0_CSPOLINV_Pos) | EBI_CTL0_EN_Msk | + (0x3 << EBI_CTL0_TALE_Pos) ; + *pu32EBITCTL = 0x03003318; + break; + + case EBI_TIMING_FAST: + *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL0_MCLKDIV_Msk | EBI_CTL0_TALE_Msk)) | + (EBI_MCLKDIV_2 << EBI_CTL0_MCLKDIV_Pos) | + (u32CSActiveLevel << EBI_CTL0_CSPOLINV_Pos) | EBI_CTL0_EN_Msk; + *pu32EBITCTL = 0x0; + break; + + case EBI_TIMING_NORMAL: + *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL0_MCLKDIV_Msk | EBI_CTL0_TALE_Msk)) | + (EBI_MCLKDIV_2 << EBI_CTL0_MCLKDIV_Pos) | + (u32CSActiveLevel << EBI_CTL0_CSPOLINV_Pos) | EBI_CTL0_EN_Msk | + (0x3 << EBI_CTL0_TALE_Pos) ; + *pu32EBITCTL = 0x03003318; + break; + + case EBI_TIMING_SLOW: + *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL0_MCLKDIV_Msk | EBI_CTL0_TALE_Msk)) | + (EBI_MCLKDIV_2 << EBI_CTL0_MCLKDIV_Pos) | + (u32CSActiveLevel << EBI_CTL0_CSPOLINV_Pos) | EBI_CTL0_EN_Msk | + (0x7 << EBI_CTL0_TALE_Pos) ; + *pu32EBITCTL = 0x07007738; + break; + + case EBI_TIMING_VERYSLOW: + *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL0_MCLKDIV_Msk | EBI_CTL0_TALE_Msk)) | + (EBI_MCLKDIV_4 << EBI_CTL0_MCLKDIV_Pos) | + (u32CSActiveLevel << EBI_CTL0_CSPOLINV_Pos) | EBI_CTL0_EN_Msk | + (0x7 << EBI_CTL0_TALE_Pos) ; + *pu32EBITCTL = 0x07007738; + break; + + case EBI_TIMING_SLOWEST: + *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL0_MCLKDIV_Msk | EBI_CTL0_TALE_Msk)) | + (EBI_MCLKDIV_8 << EBI_CTL0_MCLKDIV_Pos) | + (u32CSActiveLevel << EBI_CTL0_CSPOLINV_Pos) | EBI_CTL0_EN_Msk | + (0x7 << EBI_CTL0_TALE_Pos) ; + *pu32EBITCTL = 0x07007738; + break; + + default: + *pu32EBICTL &= ~EBI_CTL0_EN_Msk; + break; + } +} + +/** + * @brief Disable EBI on specify Bank + * + * @param[in] u32Bank Bank number for EBI. Valid values are: + * - \ref EBI_BANK0 + * - \ref EBI_BANK1 + * + * @return none + * + * @details This function is used to close specify EBI function. + */ +void EBI_Close(uint32_t u32Bank) +{ + volatile uint32_t *pu32EBICTL = (uint32_t *)((uint32_t)&EBI->CTL0 + (u32Bank * 0x10)); + + *pu32EBICTL &= ~EBI_CTL0_EN_Msk; +} + +/** + * @brief Set EBI Bus Timing for specify Bank + * + * @param[in] u32Bank Bank number for EBI. Valid values are: + * - \ref EBI_BANK0 + * - \ref EBI_BANK1 + * @param[in] u32TimingConfig Configure EBI timing settings, includes TACC, TAHD, W2X and R2R setting. + * @param[in] u32MclkDiv Divider for MCLK. Valid values are: + * - \ref EBI_MCLKDIV_1 + * - \ref EBI_MCLKDIV_2 + * - \ref EBI_MCLKDIV_4 + * - \ref EBI_MCLKDIV_8 + * - \ref EBI_MCLKDIV_16 + * - \ref EBI_MCLKDIV_32 + * + * @return none + * + * @details This function is used to configure specify EBI bus timing for access EBI device. + */ +void EBI_SetBusTiming(uint32_t u32Bank, uint32_t u32TimingConfig, uint32_t u32MclkDiv) +{ + volatile uint32_t *pu32EBICTL = (uint32_t *)((uint32_t)&EBI->CTL0 + (u32Bank * 0x10)); + volatile uint32_t *pu32EBITCTL = (uint32_t *)((uint32_t)&EBI->TCTL0 + (u32Bank * 0x10)); + + *pu32EBICTL = (*pu32EBICTL & ~EBI_CTL0_MCLKDIV_Msk) | (u32MclkDiv << EBI_CTL0_MCLKDIV_Pos); + *pu32EBITCTL = u32TimingConfig; +} + +/*@}*/ /* end of group EBI_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group EBI_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/fmc.c b/StdDriver/src/fmc.c new file mode 100644 index 0000000..01fcb84 --- /dev/null +++ b/StdDriver/src/fmc.c @@ -0,0 +1,320 @@ +/**************************************************************************//** + * @file fmc.c + * @version V3.00 + * $Revision: 7 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series FMC driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ + +//* Includes ------------------------------------------------------------------*/ +#include +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup FMC_Driver FMC Driver + @{ +*/ + + +/** @addtogroup FMC_EXPORTED_FUNCTIONS FMC Exported Functions + @{ +*/ + + +/** + * @brief Set boot source from LDROM or APROM after next software reset + * + * @param[in] i32BootSrc + * 1: Boot from LDROM, + * 0: Boot from APROM + * + * @return None + * + * @details This function is used to switch APROM boot or LDROM boot. User need to call + * FMC_SetBootSource to select boot source first, then use CPU reset or + * System Reset Request to reset system. + * + */ +void FMC_SetBootSource(int32_t i32BootSrc) +{ + if(i32BootSrc) + FMC->ISPCTL |= FMC_ISPCTL_BS_Msk; /* Boot from LDROM */ + else + FMC->ISPCTL &= ~FMC_ISPCTL_BS_Msk;/* Boot from APROM */ +} + + +/** + * @brief Disable ISP Functions + * + * @param None + * + * @return None + * + * @details This function will clear ISPEN bit of ISPCTL to disable ISP function + * + */ +void FMC_Close(void) +{ + FMC->ISPCTL &= ~FMC_ISPCTL_ISPEN_Msk; +} + + +/** + * @brief Disable APROM update function + * + * @param None + * + * @return None + * + * @details Disable APROM update function will forbid APROM programming when boot form APROM. + * APROM update is default to be disable. + * + */ +void FMC_DisableAPUpdate(void) +{ + FMC->ISPCTL &= ~FMC_ISPCTL_APUEN_Msk; +} + + +/** + * @brief Disable User Configuration update function + * + * @param None + * + * @return None + * + * @details Disable User Configuration update function will forbid User Configuration programming. + * User Configuration update is default to be disable. + */ +void FMC_DisableConfigUpdate(void) +{ + FMC->ISPCTL &= ~FMC_ISPCTL_CFGUEN_Msk; +} + + +/** + * @brief Disable LDROM update function + * + * @param None + * + * @return None + + * @details Disable LDROM update function will forbid LDROM programming. + * LDROM update is default to be disable. + */ +void FMC_DisableLDUpdate(void) +{ + FMC->ISPCTL &= ~FMC_ISPCTL_LDUEN_Msk; +} + + +/** + * @brief Enable APROM update function + * + * @param None + * + * @return None + * + * @details Enable APROM to be able to program when boot from APROM. + * + */ +void FMC_EnableAPUpdate(void) +{ + FMC->ISPCTL |= FMC_ISPCTL_APUEN_Msk; +} + + +/** + * @brief Enable User Configuration update function + * + * @param None + * + * @return None + * + * @details Enable User Configuration to be able to program. + * + */ +void FMC_EnableConfigUpdate(void) +{ + FMC->ISPCTL |= FMC_ISPCTL_CFGUEN_Msk; +} + + +/** + * @brief Enable LDROM update function + * + * @param None + * + * @return None + * + * @details Enable LDROM to be able to program. + * + */ +void FMC_EnableLDUpdate(void) +{ + FMC->ISPCTL |= FMC_ISPCTL_LDUEN_Msk; +} + + +/** + * @brief Get the current boot source + * + * @param None + * + * @retval 0 This chip is currently booting from APROM + * @retval 1 This chip is currently booting from LDROM + * + * @note This function only show the boot source. + * User need to read ISPSTA register to know if IAP mode supported or not in relative boot. + */ +int32_t FMC_GetBootSource(void) +{ + if(FMC->ISPCTL & FMC_ISPCTL_BS_Msk) + return 1; + else + return 0; +} + + +/** + * @brief Enable FMC ISP function + * + * @param None + * + * @return None + * + * @details ISPEN bit of ISPCTL must be set before we can use ISP commands. + * Therefore, To use all FMC function APIs, user needs to call FMC_Open() first to enable ISP functions. + * + * @note ISP functions are write-protected. user also needs to unlock it by calling SYS_UnlockReg() before using all ISP functions. + * + */ +void FMC_Open(void) +{ + FMC->ISPCTL |= FMC_ISPCTL_ISPEN_Msk; +} + +/** + * @brief Get the base address of Data Flash if enabled. + * + * @param None + * + * @return The base address of Data Flash + * + * @details This function is used to return the base address of Data Flash. + * + */ +uint32_t FMC_ReadDataFlashBaseAddr(void) +{ + return FMC->DFBA; +} + + +/** + * @brief Read the User Configuration words. + * + * @param[out] u32Config The word buffer to store the User Configuration data. + * @param[in] u32Count The word count to be read. + * + * @retval 0 Success + * @retval -1 Failed + * + * @details This function is used to read the settings of user configuration. + * if u32Count = 1, Only CONFIG0 will be returned to the buffer specified by u32Config. + * if u32Count = 2, Both CONFIG0 and CONFIG1 will be returned. + */ +int32_t FMC_ReadConfig(uint32_t *u32Config, uint32_t u32Count) +{ + int32_t i; + + for(i = 0; i < u32Count; i++) + u32Config[i] = FMC_Read(FMC_CONFIG_BASE + i * 4); + + return 0; +} + + +/** + * @brief Write User Configuration + * + * @param[in] u32Config The word buffer to store the User Configuration data. + * @param[in] u32Count The word count to program to User Configuration. + * + * @retval 0 Success + * @retval -1 Failed + * + * @details User must enable User Configuration update before writing it. + * User must erase User Configuration before writing it. + * User Configuration is also be page erase. User needs to backup necessary data + * before erase User Configuration. + */ +int32_t FMC_WriteConfig(uint32_t *u32Config, uint32_t u32Count) +{ + int32_t i; + + for(i = 0; i < u32Count; i++) + { + FMC_Write(FMC_CONFIG_BASE + i * 4, u32Config[i]); + if(FMC_Read(FMC_CONFIG_BASE + i * 4) != u32Config[i]) + return -1; + } + + return 0; +} + +/** + * @brief Enable Flash Access Frequency Optimization Mode + * + * @param[in] u32Mode Optimize flash access cycle mode + * - \ref FMC_FTCTL_OPTIMIZE_DISABLE + * - \ref FMC_FTCTL_OPTIMIZE_12MHZ + * - \ref FMC_FTCTL_OPTIMIZE_36MHZ + * - \ref FMC_FTCTL_OPTIMIZE_60MHZ + * - \ref FMC_FTCTL_OPTIMIZE_72MHZ + * + * @return None + * + * @details This function will set FOM bit fields of FTCTL register to set flash access frequency optimization mode. + * + * @note The flash optimization mode (FOM) bits are write protect. + * + */ +void FMC_EnableFreqOptimizeMode(uint32_t u32Mode) +{ + FMC->FTCTL &= ~FMC_FTCTL_FOM_Msk; + FMC->FTCTL |= (u32Mode << FMC_FTCTL_FOM_Pos); +} + +/** + * @brief Disable Flash Access Frequency Optimization Mode + * + * @param None + * + * @return None + * + * @details This function will clear FOM bit fields of FTCTL register to disable flash access frequency optimization mode. + * + * @note The flash optimization mode (FOM) bits are write protect. + * + */ +void FMC_DisableFreqOptimizeMode(void) +{ + FMC->FTCTL &= ~FMC_FTCTL_FOM_Msk; +} + +/*@}*/ /* end of group FMC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group FMC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ + + diff --git a/StdDriver/src/gpio.c b/StdDriver/src/gpio.c new file mode 100644 index 0000000..7300e4e --- /dev/null +++ b/StdDriver/src/gpio.c @@ -0,0 +1,102 @@ +/**************************************************************************//** + * @file gpio.c + * @version V3.00 + * $Revision: 6 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series GPIO driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ + +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup GPIO_Driver GPIO Driver + @{ +*/ + +/** @addtogroup GPIO_EXPORTED_FUNCTIONS GPIO Exported Functions + @{ +*/ + +/** + * @brief Set GPIO operation mode + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32PinMask The single or multiple pins of specified GPIO port. + * It could be BIT0 ~ BIT15 for PA, PB, PC and PD GPIO port. + * It could be BIT0 ~ BIT14 for PE GPIO port. + * It could be BIT0 ~ BIT7 for PF GPIO port. + * @param[in] u32Mode Operation mode. It could be \n + * GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_OPEN_DRAIN, GPIO_MODE_QUASI. + * + * @return None + * + * @details This function is used to set specified GPIO operation mode. + */ +void GPIO_SetMode(GPIO_T *port, uint32_t u32PinMask, uint32_t u32Mode) +{ + uint32_t i; + + for(i = 0; i < GPIO_PIN_MAX; i++) + { + if(u32PinMask & (1 << i)) + { + port->MODE = (port->MODE & ~(0x3 << (i << 1))) | (u32Mode << (i << 1)); + } + } +} + +/** + * @brief Enable GPIO interrupt + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32Pin The pin of specified GPIO port. + * It could be 0 ~ 15 for PA, PB, PC and PD GPIO port. + * It could be 0 ~ 14 for PE GPIO port. + * It could be 0 ~ 7 for PF GPIO port. + * @param[in] u32IntAttribs The interrupt attribute of specified GPIO pin. It could be \n + * GPIO_INT_RISING, GPIO_INT_FALLING, GPIO_INT_BOTH_EDGE, GPIO_INT_HIGH, GPIO_INT_LOW. + * + * @return None + * + * @details This function is used to enable specified GPIO pin interrupt. + */ +void GPIO_EnableInt(GPIO_T *port, uint32_t u32Pin, uint32_t u32IntAttribs) +{ + port->INTTYPE |= (((u32IntAttribs >> 24) & 0xFFUL) << u32Pin); + port->INTEN |= ((u32IntAttribs & 0xFFFFFFUL) << u32Pin); +} + + +/** + * @brief Disable GPIO interrupt + * + * @param[in] port GPIO port. It could be PA, PB, PC, PD, PE or PF. + * @param[in] u32Pin The pin of specified GPIO port. + * It could be 0 ~ 15 for PA, PB, PC and PD GPIO port. + * It could be 0 ~ 14 for PE GPIO port. + * It could be 0 ~ 7 for PF GPIO port. + * + * @return None + * + * @details This function is used to enable specified GPIO pin interrupt. + */ +void GPIO_DisableInt(GPIO_T *port, uint32_t u32Pin) +{ + port->INTTYPE &= ~(1UL << u32Pin); + port->INTEN &= ~((0x00010001UL) << u32Pin); +} + + +/*@}*/ /* end of group GPIO_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group GPIO_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/i2c.c b/StdDriver/src/i2c.c new file mode 100644 index 0000000..38b8ae0 --- /dev/null +++ b/StdDriver/src/i2c.c @@ -0,0 +1,642 @@ +/**************************************************************************//** + * @file i2c.c + * @version V3.00 + * $Revision: 23 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series I2C driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + *****************************************************************************/ +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup I2C_Driver I2C Driver + @{ +*/ + + +/** @addtogroup I2C_EXPORTED_FUNCTIONS I2C Exported Functions + @{ +*/ + +/** + * @brief Enable specify I2C Controller and set Clock Divider + * + * @param[in] i2c Specify I2C port + * @param[in] u32BusClock The target I2C bus clock in Hz + * + * @return Actual I2C bus clock frequency + * + * @details The function enable the specify I2C Controller and set proper Clock Divider + * in I2C CLOCK DIVIDED REGISTER (I2CLK) according to the target I2C Bus clock. + * I2C Bus clock = PCLK / (4*(divider+1). + * + */ +uint32_t I2C_Open(I2C_T *i2c, uint32_t u32BusClock) +{ + uint32_t u32Div; + uint32_t u32Pclk; + + if(i2c == I2C1) + { + u32Pclk = CLK_GetPCLK1Freq(); + } + else + { + u32Pclk = CLK_GetPCLK0Freq(); + } + + u32Div = (uint32_t)(((u32Pclk * 10u) / (u32BusClock * 4u) + 5u) / 10u - 1u); /* Compute proper divider for I2C clock */ + i2c->CLKDIV = u32Div; + + /* Enable I2C */ + i2c->CTL |= I2C_CTL_I2CEN_Msk; + + return (u32Pclk / ((u32Div + 1u) << 2u)); +} + +/** + * @brief Disable specify I2C Controller + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details Reset I2C Controller and disable specify I2C port. + * + */ + +void I2C_Close(I2C_T *i2c) +{ + /* Reset I2C Controller */ + if(i2c == I2C0) + { + SYS->IPRST1 |= SYS_IPRST1_I2C0RST_Msk; + SYS->IPRST1 &= ~SYS_IPRST1_I2C0RST_Msk; + } + else if(i2c == I2C1) + { + SYS->IPRST1 |= SYS_IPRST1_I2C1RST_Msk; + SYS->IPRST1 &= ~SYS_IPRST1_I2C1RST_Msk; + } + + /* Disable I2C */ + i2c->CTL &= ~I2C_CTL_I2CEN_Msk; +} + +/** + * @brief Clear Time-out Counter flag + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details When Time-out flag will be set, use this function to clear I2C Bus Time-out counter flag . + * + */ +void I2C_ClearTimeoutFlag(I2C_T *i2c) +{ + i2c->TOCTL |= I2C_TOCTL_TOIF_Msk; +} + +/** + * @brief Set Control bit of I2C Controller + * + * @param[in] i2c Specify I2C port + * @param[in] u8Start Set I2C START condition + * @param[in] u8Stop Set I2C STOP condition + * @param[in] u8Si Clear SI flag + * @param[in] u8Ack Set I2C ACK bit + * + * @return None + * + * @details The function set I2C Control bit of I2C Bus protocol. + * + */ +void I2C_Trigger(I2C_T *i2c, uint8_t u8Start, uint8_t u8Stop, uint8_t u8Si, uint8_t u8Ack) +{ + uint32_t u32Reg = 0; + + if(u8Start) + u32Reg |= I2C_CTL_STA; + if(u8Stop) + u32Reg |= I2C_CTL_STO; + if(u8Si) + u32Reg |= I2C_CTL_SI; + if(u8Ack) + u32Reg |= I2C_CTL_AA; + + i2c->CTL = (i2c->CTL & ~0x3C) | u32Reg; +} + +/** + * @brief Disable Interrupt of I2C Controller + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details The function is used for disable I2C interrupt + * + */ +void I2C_DisableInt(I2C_T *i2c) +{ + i2c->CTL &= ~I2C_CTL_INTEN_Msk; +} + +/** + * @brief Enable Interrupt of I2C Controller + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details The function is used for enable I2C interrupt + * + */ +void I2C_EnableInt(I2C_T *i2c) +{ + i2c->CTL |= I2C_CTL_INTEN_Msk; +} + +/** + * @brief Get I2C Bus Clock + * + * @param[in] i2c Specify I2C port + * + * @return The actual I2C Bus clock in Hz + * + * @details To get the actual I2C Bus Clock frequency. + */ +uint32_t I2C_GetBusClockFreq(I2C_T *i2c) +{ + uint32_t u32Divider = i2c->CLKDIV; + uint32_t u32Pclk; + + if(i2c == I2C1) + { + u32Pclk = CLK_GetPCLK1Freq(); + } + else + { + u32Pclk = CLK_GetPCLK0Freq(); + } + + return (u32Pclk / ((u32Divider + 1u) << 2u)); +} + +/** + * @brief Set I2C Bus Clock + * + * @param[in] i2c Specify I2C port + * @param[in] u32BusClock The target I2C Bus Clock in Hz + * + * @return The actual I2C Bus Clock in Hz + * + * @details To set the actual I2C Bus Clock frequency. + */ +uint32_t I2C_SetBusClockFreq(I2C_T *i2c, uint32_t u32BusClock) +{ + uint32_t u32Div; + uint32_t u32Pclk; + + if(i2c == I2C1) + { + u32Pclk = CLK_GetPCLK1Freq(); + } + else + { + u32Pclk = CLK_GetPCLK0Freq(); + } + + u32Div = (uint32_t)(((u32Pclk * 10u) / (u32BusClock * 4u) + 5u) / 10u - 1u); /* Compute proper divider for I2C clock */ + i2c->CLKDIV = u32Div; + + return (u32Pclk / ((u32Div + 1u) << 2u)); +} + +/** + * @brief Get Interrupt Flag + * + * @param[in] i2c Specify I2C port + * + * @return I2C interrupt flag status + * + * @details To get I2C Bus interrupt flag. + */ +uint32_t I2C_GetIntFlag(I2C_T *i2c) +{ + return ((i2c->CTL & I2C_CTL_SI_Msk) == I2C_CTL_SI_Msk ? 1 : 0); +} + +/** + * @brief Get I2C Bus Status Code + * + * @param[in] i2c Specify I2C port + * + * @return I2C Status Code + * + * @details To get I2C Bus Status Code. + */ +uint32_t I2C_GetStatus(I2C_T *i2c) +{ + return (i2c->STATUS); +} + +/** + * @brief Read a Byte from I2C Bus + * + * @param[in] i2c Specify I2C port + * + * @return I2C Data + * + * @details To read a bytes data from specify I2C port. + */ +uint8_t I2C_GetData(I2C_T *i2c) +{ + return (i2c->DAT); +} + +/** + * @brief Send a byte to I2C Bus + * + * @param[in] i2c Specify I2C port + * @param[in] u8Data The data to send to I2C bus + * + * @return None + * + * @details This function is used to write a byte to specified I2C port + */ +void I2C_SetData(I2C_T *i2c, uint8_t u8Data) +{ + i2c->DAT = u8Data; +} + +/** + * @brief Set 7-bit Slave Address and GC Mode + * + * @param[in] i2c Specify I2C port + * @param[in] u8SlaveNo Set the number of I2C address register (0~3) + * @param[in] u8SlaveAddr 7-bit slave address + * @param[in] u8GCMode Enable/Disable GC mode (I2C_GCMODE_ENABLE / I2C_GCMODE_DISABLE) + * + * @return None + * + * @details This function is used to set 7-bit slave addresses in I2C SLAVE ADDRESS REGISTER (I2CADDR0~3) + * and enable GC Mode. + * + */ +void I2C_SetSlaveAddr(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddr, uint8_t u8GCMode) +{ + switch(u8SlaveNo) + { + case 1: + i2c->ADDR1 = (u8SlaveAddr << 1) | u8GCMode; + break; + case 2: + i2c->ADDR2 = (u8SlaveAddr << 1) | u8GCMode; + break; + case 3: + i2c->ADDR3 = (u8SlaveAddr << 1) | u8GCMode; + break; + case 0: + default: + i2c->ADDR0 = (u8SlaveAddr << 1) | u8GCMode; + break; + } +} + +/** + * @brief Configure the mask bits of 7-bit Slave Address + * + * @param[in] i2c Specify I2C port + * @param[in] u8SlaveNo Set the number of I2C address mask register (0~3) + * @param[in] u8SlaveAddrMask A byte for slave address mask + * + * @return None + * + * @details This function is used to set 7-bit slave addresses. + * + */ +void I2C_SetSlaveAddrMask(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddrMask) +{ + switch(u8SlaveNo) + { + case 1: + i2c->ADDRMSK1 = u8SlaveAddrMask << 1; + break; + case 2: + i2c->ADDRMSK2 = u8SlaveAddrMask << 1; + break; + case 3: + i2c->ADDRMSK3 = u8SlaveAddrMask << 1; + break; + case 0: + default: + i2c->ADDRMSK0 = u8SlaveAddrMask << 1; + break; + } +} + +/** + * @brief Enable Time-out Counter Function and support Long Time-out + * + * @param[in] i2c Specify I2C port + * @param[in] u8LongTimeout Configure DIV4 to enable Long Time-out (0/1) + * + * @return None + * + * @details This function enable Time-out Counter function and configure DIV4 to support Long + * Time-out. + * + */ +void I2C_EnableTimeout(I2C_T *i2c, uint8_t u8LongTimeout) +{ + if(u8LongTimeout) + i2c->TOCTL |= I2C_TOCTL_TOCDIV4_Msk; + else + i2c->TOCTL &= ~I2C_TOCTL_TOCDIV4_Msk; + + i2c->TOCTL |= I2C_TOCTL_TOCEN_Msk; +} + +/** + * @brief Disable Time-out Counter Function + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details To disable Time-out Counter function in I2CTOC register. + * + */ +void I2C_DisableTimeout(I2C_T *i2c) +{ + i2c->TOCTL &= ~I2C_TOCTL_TOCEN_Msk; +} + +/** + * @brief Enable I2C Wake-up Function + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details To enable Wake-up function of I2C Wake-up control register. + * + */ +void I2C_EnableWakeup(I2C_T *i2c) +{ + i2c->WKCTL |= I2C_WKCTL_WKEN_Msk; +} + +/** + * @brief Disable I2C Wake-up Function + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details To disable Wake-up function of I2C Wake-up control register. + * + */ +void I2C_DisableWakeup(I2C_T *i2c) +{ + i2c->WKCTL &= ~I2C_WKCTL_WKEN_Msk; +} + +/** + * @brief To get SMBus Status + * + * @param[in] i2c Specify I2C port + * + * @return SMBus status + * + * @details To get the Bus Management status of I2C_BUSSTS register + * + */ +uint32_t I2C_SMBusGetStatus(I2C_T *i2c) +{ + return (i2c->BUSSTS); +} + +/** + * @brief Clear SMBus Interrupt Flag + * + * @param[in] i2c Specify I2C port + * @param[in] u8SMBusIntFlag Specify SMBus interrupt flag + * + * @return None + * + * @details To clear flags of I2C_BUSSTS status register if interrupt set. + * + */ +void I2C_SMBusClearInterruptFlag(I2C_T *i2c, uint8_t u8SMBusIntFlag) +{ + i2c->BUSSTS |= u8SMBusIntFlag; +} + +/** + * @brief Set SMBus Bytes Counts of Transmission or Reception + * + * @param[in] i2c Specify I2C port + * @param[in] u32PktSize Transmit / Receive bytes + * + * @return None + * + * @details The transmission or receive byte number in one transaction when PECEN is set. The maximum is 255 bytes. + * + */ +void I2C_SMBusSetPacketByteCount(I2C_T *i2c, uint32_t u32PktSize) +{ + i2c->PKTSIZE = u32PktSize; +} + +/** + * @brief Init SMBus Host/Device Mode + * + * @param[in] i2c Specify I2C port + * @param[in] u8HostDevice Init SMBus port mode(I2C_SMBH_ENABLE(1)/I2C_SMBD_ENABLE(0)) + * + * @return None + * + * @details Using SMBus communication must specify the port is a Host or a Device. + * + */ +void I2C_SMBusOpen(I2C_T *i2c, uint8_t u8HostDevice) +{ + /* Clear BMHEN, BMDEN of BUSCTL Register */ + i2c->BUSCTL &= ~(I2C_BUSCTL_BMHEN_Msk | I2C_BUSCTL_BMDEN_Msk); + + /* Set SMBus Host/Device Mode, and enable Bus Management*/ + if(u8HostDevice == I2C_SMBH_ENABLE) + i2c->BUSCTL |= (I2C_BUSCTL_BMHEN_Msk | I2C_BUSCTL_BUSEN_Msk); + else + i2c->BUSCTL |= (I2C_BUSCTL_BMDEN_Msk | I2C_BUSCTL_BUSEN_Msk); +} + +/** + * @brief Disable SMBus function + * + * @param[in] i2c Specify I2C port + * + * @return None + * + * @details Disable all SMBus function include Bus disable, CRC check, Acknowledge by manual, Host/Device Mode. + * + */ +void I2C_SMBusClose(I2C_T *i2c) +{ + + i2c->BUSCTL = 0x00; +} + +/** + * @brief Enable SMBus PEC Transmit Function + * + * @param[in] i2c Specify I2C port + * @param[in] u8PECTxEn CRC transmit enable(PECTX_ENABLE) or disable(PECTX_DISABLE) + * + * @return None + * + * @details When enable CRC check function, the Host or Device needs to transmit CRC byte. + * + */ +void I2C_SMBusPECTxEnable(I2C_T *i2c, uint8_t u8PECTxEn) +{ + i2c->BUSCTL &= ~I2C_BUSCTL_PECTXEN_Msk; + + if(u8PECTxEn) + i2c->BUSCTL |= (I2C_BUSCTL_PECEN_Msk | I2C_BUSCTL_PECTXEN_Msk); + else + i2c->BUSCTL |= I2C_BUSCTL_PECEN_Msk; +} + +/** + * @brief Get SMBus CRC value + * + * @param[in] i2c Specify I2C port + * + * @return A byte is packet error check value + * + * @details The CRC check value after a transmission or a reception by count by using CRC8 + * + */ +uint8_t I2C_SMBusGetPECValue(I2C_T *i2c) +{ + return i2c->PKTCRC; +} + +/** + * @brief Calculate Time-out of SMBus idle period + * + * @param[in] i2c Specify I2C port + * @param[in] us Time-out length(us) + * @param[in] u32Hclk I2C peripheral clock frequency + * + * @return None + * + * @details This function is used to set SMBus Time-out length when bus is in Idle state. + * + */ + +void I2C_SMBusIdleTimeout(I2C_T *i2c, uint32_t us, uint32_t u32Hclk) +{ + uint32_t u32Div, u32Hclk_kHz; + + i2c->BUSCTL |= I2C_BUSCTL_TIDLE_Msk; + u32Hclk_kHz = u32Hclk / 1000; + u32Div = (((us * u32Hclk_kHz) / 1000) >> 2) - 1; + if(u32Div > 255) + { + i2c->BUSTOUT = 0xFF; + } + else + { + i2c->BUSTOUT = u32Div; + } + +} + +/** + * @brief Calculate Time-out of SMBus active period + * + * @param[in] i2c Specify I2C port + * @param[in] ms Time-out length(ms) + * @param[in] u32Pclk peripheral clock frequency + * + * @return None + * + * @details This function is used to set SMBus Time-out length when bus is in active state. + * Time-out length is calculate the SCL line "one clock" pull low timing. + * + */ + +void I2C_SMBusTimeout(I2C_T *i2c, uint32_t ms, uint32_t u32Pclk) +{ + uint32_t u32Div, u32Pclk_kHz; + + i2c->BUSCTL &= ~I2C_BUSCTL_TIDLE_Msk; + + /* DIV4 disabled */ + i2c->TOCTL &= ~I2C_TOCTL_TOCEN_Msk; + u32Pclk_kHz = u32Pclk / 1000; + u32Div = ((ms * u32Pclk_kHz) / (16 * 1024)) - 1; + if(u32Div <= 0xFF) + { + i2c->BUSTOUT = u32Div; + return; + } + + /* DIV4 enabled */ + i2c->TOCTL |= I2C_TOCTL_TOCEN_Msk; + + i2c->BUSTOUT = (((ms * u32Pclk_kHz) / (16 * 1024 * 4)) - 1) & 0xFF; //The max value is 255 +} + +/** + * @brief Calculate Cumulative Clock low Time-out of SMBus active period + * + * @param[in] i2c Specify I2C port + * @param[in] ms Time-out length(ms) + * @param[in] u32Pclk peripheral clock frequency + * + * @return None + * + * @details This function is used to set SMBus Time-out length when bus is in Active state. + * Time-out length is calculate the SCL line "clocks" low cumulative timing. + * + */ + +void I2C_SMBusClockLoTimeout(I2C_T *i2c, uint32_t ms, uint32_t u32Pclk) +{ + uint32_t u32Div, u32Pclk_kHz; + + i2c->BUSCTL &= ~I2C_BUSCTL_TIDLE_Msk; + + /* DIV4 disabled */ + i2c->TOCTL &= ~I2C_TOCTL_TOCEN_Msk; + u32Pclk_kHz = u32Pclk / 1000; + u32Div = ((ms * u32Pclk_kHz) / (16 * 1024)) - 1; + if(u32Div <= 0xFF) + { + i2c->CLKTOUT = u32Div; + return; + } + + /* DIV4 enabled */ + i2c->TOCTL |= I2C_TOCTL_TOCEN_Msk; + i2c->CLKTOUT = (((ms * u32Pclk_kHz) / (16 * 1024 * 4)) - 1) & 0xFF; //The max value is 255 +} + +/*@}*/ /* end of group I2C_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group I2C_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/pdma.c b/StdDriver/src/pdma.c new file mode 100644 index 0000000..53f4420 --- /dev/null +++ b/StdDriver/src/pdma.c @@ -0,0 +1,389 @@ +/**************************************************************************//** + * @file pdma.c + * @version V1.00 + * $Revision: 12 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series PDMA driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + + +static uint8_t u32ChSelect[PDMA_CH_MAX]; + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup PDMA_Driver PDMA Driver + @{ +*/ + + +/** @addtogroup PDMA_EXPORTED_FUNCTIONS PDMA Exported Functions + @{ +*/ + +/** + * @brief PDMA Open + * + * @param[in] u32Mask Channel enable bits. + * + * @return None + * + * @details This function enable the PDMA channels. + */ +void PDMA_Open(uint32_t u32Mask) +{ + int volatile i; + + for(i = 0; i < PDMA_CH_MAX; i++) + { + PDMA->DSCT[i].CTL = 0; + u32ChSelect[i] = 0x1f; + } + + PDMA->CHCTL |= u32Mask; +} + +/** + * @brief PDMA Close + * + * @param None + * + * @return None + * + * @details This function disable all PDMA channels. + */ +void PDMA_Close(void) +{ + PDMA->CHCTL = 0; +} + +/** + * @brief Set PDMA Transfer Count + * + * @param[in] u32Ch The selected channel + * @param[in] u32Width Data width. Valid values are + * - \ref PDMA_WIDTH_8 + * - \ref PDMA_WIDTH_16 + * - \ref PDMA_WIDTH_32 + * @param[in] u32TransCount Transfer count + * + * @return None + * + * @details This function set the selected channel data width and transfer count. + */ +void PDMA_SetTransferCnt(uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount) +{ + PDMA->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXCNT_Msk | PDMA_DSCT_CTL_TXWIDTH_Msk); + PDMA->DSCT[u32Ch].CTL |= (u32Width | ((u32TransCount - 1) << PDMA_DSCT_CTL_TXCNT_Pos)); +} + +/** + * @brief Set PDMA Transfer Address + * + * @param[in] u32Ch The selected channel + * @param[in] u32SrcAddr Source address + * @param[in] u32SrcCtrl Source control attribute. Valid values are + * - \ref PDMA_SAR_INC + * - \ref PDMA_SAR_FIX + * @param[in] u32DstAddr destination address + * @param[in] u32DstCtrl destination control attribute. Valid values are + * - \ref PDMA_DAR_INC + * - \ref PDMA_DAR_FIX + * + * @return None + * + * @details This function set the selected channel source/destination address and attribute. + */ +void PDMA_SetTransferAddr(uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl) +{ + PDMA->DSCT[u32Ch].SA = u32SrcAddr; + PDMA->DSCT[u32Ch].DA = u32DstAddr; + PDMA->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_SAINC_Msk | PDMA_DSCT_CTL_DAINC_Msk); + PDMA->DSCT[u32Ch].CTL |= (u32SrcCtrl | u32DstCtrl); +} + +/** + * @brief Set PDMA Transfer Mode + * + * @param[in] u32Ch The selected channel + * @param[in] u32Peripheral The selected peripheral. Valid values are + * - \ref PDMA_SPI0_TX + * - \ref PDMA_SPI1_TX + * - \ref PDMA_SPI2_TX + * - \ref PDMA_UART0_TX + * - \ref PDMA_UART1_TX + * - \ref PDMA_UART2_TX + * - \ref PDMA_UART3_TX + * - \ref PDMA_DAC_TX + * - \ref PDMA_ADC_RX + * - \ref PDMA_PWM0_P1_RX + * - \ref PDMA_PWM0_P2_RX + * - \ref PDMA_PWM0_P3_RX + * - \ref PDMA_PWM1_P1_RX + * - \ref PDMA_PWM1_P2_RX + * - \ref PDMA_PWM1_P3_RX + * - \ref PDMA_SPI0_RX + * - \ref PDMA_SPI1_RX + * - \ref PDMA_SPI2_RX + * - \ref PDMA_UART0_RX + * - \ref PDMA_UART1_RX + * - \ref PDMA_UART2_RX + * - \ref PDMA_UART3_RX + * - \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) +{ + u32ChSelect[u32Ch] = u32Peripheral; + switch(u32Ch) + { + case 0: + PDMA->REQSEL0_3 = (PDMA->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC0_Msk) | u32Peripheral; + break; + case 1: + PDMA->REQSEL0_3 = (PDMA->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC1_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC1_Pos); + break; + case 2: + PDMA->REQSEL0_3 = (PDMA->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC2_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC2_Pos); + break; + case 3: + PDMA->REQSEL0_3 = (PDMA->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC3_Msk) | (u32Peripheral << PDMA_REQSEL0_3_REQSRC3_Pos); + break; + case 4: + PDMA->REQSEL4_7 = (PDMA->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC4_Msk) | u32Peripheral; + break; + case 5: + PDMA->REQSEL4_7 = (PDMA->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC5_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC5_Pos); + break; + case 6: + PDMA->REQSEL4_7 = (PDMA->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC6_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC6_Pos); + break; + case 7: + PDMA->REQSEL4_7 = (PDMA->REQSEL4_7 & ~PDMA_REQSEL4_7_REQSRC7_Msk) | (u32Peripheral << PDMA_REQSEL4_7_REQSRC7_Pos); + break; + case 8: + PDMA->REQSEL8_11 = (PDMA->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC8_Msk) | u32Peripheral; + break; + case 9: + PDMA->REQSEL8_11 = (PDMA->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC9_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC9_Pos); + break; + case 10: + PDMA->REQSEL8_11 = (PDMA->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC10_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC10_Pos); + break; + case 11: + PDMA->REQSEL8_11 = (PDMA->REQSEL8_11 & ~PDMA_REQSEL8_11_REQSRC11_Msk) | (u32Peripheral << PDMA_REQSEL8_11_REQSRC11_Pos); + break; + default: + ; + } + + if(u32ScatterEn) + { + PDMA->DSCT[u32Ch].CTL = (PDMA->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_SCATTER; + PDMA->DSCT[u32Ch].NEXT = u32DescAddr - (PDMA->SCATBA); + } + else + PDMA->DSCT[u32Ch].CTL = (PDMA->DSCT[u32Ch].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | PDMA_OP_BASIC; +} + +/** + * @brief Set PDMA Burst Type and Size + * + * @param[in] u32Ch The selected channel + * @param[in] u32BurstType Burst mode or single mode. Valid values are + * - \ref PDMA_REQ_SINGLE + * - \ref PDMA_REQ_BURST + * @param[in] u32BurstSize Set the size of burst mode. Valid values are + * - \ref PDMA_BURST_128 + * - \ref PDMA_BURST_64 + * - \ref PDMA_BURST_32 + * - \ref PDMA_BURST_16 + * - \ref PDMA_BURST_8 + * - \ref PDMA_BURST_4 + * - \ref PDMA_BURST_2 + * - \ref PDMA_BURST_1 + * + * @return None + * + * @details This function set the selected channel burst type and size. + */ +void PDMA_SetBurstType(uint32_t u32Ch, uint32_t u32BurstType, uint32_t u32BurstSize) +{ + PDMA->DSCT[u32Ch].CTL &= ~(PDMA_DSCT_CTL_TXTYPE_Msk | PDMA_DSCT_CTL_BURSIZE_Msk); + PDMA->DSCT[u32Ch].CTL |= (u32BurstType | u32BurstSize); +} + +/** + * @brief Enable timeout function + * + * @param[in] u32Mask Channel enable bits. + * + * @return None + * + * @details This function enable timeout function of the selected channel(s). + * @note This function is only supported in M45xD/M45xC. + */ +void PDMA_EnableTimeout(uint32_t u32Mask) +{ + PDMA->TOUTEN |= u32Mask; +} + +/** + * @brief Disable timeout function + * + * @param[in] u32Mask Channel enable bits. + * + * @return None + * + * @details This function disable timeout function of the selected channel(s). + * @note This function is only supported in M45xD/M45xC. + */ +void PDMA_DisableTimeout(uint32_t u32Mask) +{ + PDMA->TOUTEN &= ~u32Mask; +} + +/** + * @brief Set PDMA Timeout Count + * + * @param[in] u32Ch The selected channel + * @param[in] u32OnOff Enable/disable time out function + * @param[in] u32TimeOutCnt Timeout count + * + * @return None + * + * @details This function set the timeout count. + * @note This function is only supported in M45xD/M45xC. + */ +void PDMA_SetTimeOut(uint32_t u32Ch, uint32_t u32OnOff, uint32_t u32TimeOutCnt) +{ + switch(u32Ch) + { + case 0: + PDMA->TOC0_1 = (PDMA->TOC0_1 & ~PDMA_TOC0_1_TOC0_Msk) | u32TimeOutCnt; + break; + case 1: + PDMA->TOC0_1 = (PDMA->TOC0_1 & ~PDMA_TOC0_1_TOC1_Msk) | (u32TimeOutCnt << PDMA_TOC0_1_TOC1_Pos); + break; + case 2: + PDMA->TOC2_3 = (PDMA->TOC2_3 & ~PDMA_TOC2_3_TOC2_Msk) | u32TimeOutCnt; + break; + case 3: + PDMA->TOC2_3 = (PDMA->TOC2_3 & ~PDMA_TOC2_3_TOC3_Msk) | (u32TimeOutCnt << PDMA_TOC2_3_TOC3_Pos); + break; + case 4: + PDMA->TOC4_5 = (PDMA->TOC4_5 & ~PDMA_TOC4_5_TOC4_Msk) | u32TimeOutCnt; + break; + case 5: + PDMA->TOC4_5 = (PDMA->TOC4_5 & ~PDMA_TOC4_5_TOC5_Msk) | (u32TimeOutCnt << PDMA_TOC4_5_TOC5_Pos); + break; + case 6: + PDMA->TOC6_7 = (PDMA->TOC6_7 & ~PDMA_TOC6_7_TOC6_Msk) | u32TimeOutCnt; + break; + case 7: + PDMA->TOC6_7 = (PDMA->TOC6_7 & ~PDMA_TOC6_7_TOC7_Msk) | (u32TimeOutCnt << PDMA_TOC6_7_TOC7_Pos); + break; + + default: + ; + } +} + +/** + * @brief Trigger PDMA + * + * @param[in] u32Ch The selected channel + * + * @return None + * + * @details This function trigger the selected channel. + */ +void PDMA_Trigger(uint32_t u32Ch) +{ + if(u32ChSelect[u32Ch] == PDMA_MEM) + PDMA->SWREQ = (1 << u32Ch); +} + +/** + * @brief Enable Interrupt + * + * @param[in] u32Ch The selected channel + * @param[in] u32Mask The Interrupt Type. Valid values are + * - \ref PDMA_INT_TRANS_DONE + * - \ref PDMA_INT_TEMPTY + * - \ref PDMA_INT_TIMEOUT + * + * @return None + * + * @details This function enable the selected channel interrupt. + * @note PDMA_INT_TIMEOUT is only supported in M45xD/M45xC. + */ +void PDMA_EnableInt(uint32_t u32Ch, uint32_t u32Mask) +{ + switch(u32Mask) + { + case PDMA_INT_TRANS_DONE: + PDMA->INTEN |= (1 << u32Ch); + break; + case PDMA_INT_TEMPTY: + PDMA->DSCT[u32Ch].CTL &= ~PDMA_DSCT_CTL_TBINTDIS_Msk; + break; + case PDMA_INT_TIMEOUT: + PDMA->TOUTIEN |= (1 << u32Ch); + break; + + default: + ; + } +} + +/** + * @brief Disable Interrupt + * + * @param[in] u32Ch The selected channel + * @param[in] u32Mask The Interrupt Type. Valid values are + * - \ref PDMA_INT_TRANS_DONE + * - \ref PDMA_INT_TEMPTY + * - \ref PDMA_INT_TIMEOUT + * + * @return None + * + * @details This function disable the selected channel interrupt. + * @note PDMA_INT_TIMEOUT is only supported in M45xD/M45xC. + */ +void PDMA_DisableInt(uint32_t u32Ch, uint32_t u32Mask) +{ + switch(u32Mask) + { + case PDMA_INT_TRANS_DONE: + PDMA->INTEN &= ~(1 << u32Ch); + break; + case PDMA_INT_TEMPTY: + PDMA->DSCT[u32Ch].CTL |= PDMA_DSCT_CTL_TBINTDIS_Msk; + break; + case PDMA_INT_TIMEOUT: + PDMA->TOUTIEN &= ~(1 << u32Ch); + break; + + default: + ; + } +} + +/*@}*/ /* end of group PDMA_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group PDMA_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/pwm.c b/StdDriver/src/pwm.c new file mode 100644 index 0000000..897fc21 --- /dev/null +++ b/StdDriver/src/pwm.c @@ -0,0 +1,1351 @@ +/**************************************************************************//** + * @file pwm.c + * @version V3.00 + * $Revision: 21 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series PWM driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup PWM_Driver PWM Driver + @{ +*/ + + +/** @addtogroup PWM_EXPORTED_FUNCTIONS PWM Exported Functions + @{ +*/ + +/** + * @brief Configure PWM capture and get the nearest unit time. + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32UnitTimeNsec The unit time of counter + * @param[in] u32CaptureEdge The condition to latch the counter. This parameter is not used + * @return The nearest unit time in nano second. + * @details This function is used to Configure PWM capture and get the nearest unit time. + */ +uint32_t PWM_ConfigCaptureChannel(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32UnitTimeNsec, uint32_t u32CaptureEdge) +{ + uint32_t u32Src; + uint32_t u32PWMClockSrc; + uint32_t u32NearestUnitTimeNsec; + uint16_t u16Prescale = 1, u16CNR = 0xFFFF; + + if(pwm == PWM0) + u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_PWM0SEL_Msk; + else//(pwm == PWM1) + u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_PWM1SEL_Msk; + + if(u32Src == 0) + { + //clock source is from PLL clock + u32PWMClockSrc = CLK_GetPLLClockFreq(); + } + else + { + //clock source is from PCLK + SystemCoreClockUpdate(); + u32PWMClockSrc = SystemCoreClock; + } + + u32PWMClockSrc /= 1000; + for(u16Prescale = 1; u16Prescale <= 0x1000; u16Prescale++) + { + u32NearestUnitTimeNsec = (1000000 * u16Prescale) / u32PWMClockSrc; + if(u32NearestUnitTimeNsec < u32UnitTimeNsec) + { + if(u16Prescale == 0x1000) //limit to the maximum unit time(nano second) + break; + if(!((1000000 * (u16Prescale + 1) > (u32NearestUnitTimeNsec * u32PWMClockSrc)))) + break; + continue; + } + break; + } + + // convert to real register value + // every two channels share a prescaler + PWM_SET_PRESCALER(pwm, u32ChannelNum, --u16Prescale); + + // set PWM to down count type(edge aligned) + (pwm)->CTL1 = ((pwm)->CTL1 & ~(PWM_CTL1_CNTTYPE0_Msk << (2 * u32ChannelNum))) | (1UL << (2 * u32ChannelNum)); + // set PWM to auto-reload mode + (pwm)->CTL1 &= ~(PWM_CTL1_CNTMODE0_Msk << u32ChannelNum); + PWM_SET_CNR(pwm, u32ChannelNum, u16CNR); + + return (u32NearestUnitTimeNsec); +} + +/** + * @brief This function Configure PWM generator and get the nearest frequency in edge aligned auto-reload mode + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @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), shares a prescaler. Call this API to configure PWM frequency may affect + * existing frequency of other channel. + */ +uint32_t PWM_ConfigOutputChannel(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Frequency, uint32_t u32DutyCycle) +{ + uint32_t u32Src; + uint32_t u32PWMClockSrc; + uint32_t i; + uint16_t u16Prescale = 1, u16CNR = 0xFFFF; + + if(pwm == PWM0) + u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_PWM0SEL_Msk; + else//(pwm == PWM1) + u32Src = CLK->CLKSEL2 & CLK_CLKSEL2_PWM1SEL_Msk; + + if(u32Src == 0) + { + //clock source is from PLL clock + u32PWMClockSrc = CLK_GetPLLClockFreq(); + } + else + { + //clock source is from PCLK + SystemCoreClockUpdate(); + u32PWMClockSrc = SystemCoreClock; + } + + for(u16Prescale = 1; u16Prescale < 0xFFF; u16Prescale++)//prescale could be 0~0xFFF + { + i = (u32PWMClockSrc / u32Frequency) / u16Prescale; + // If target value is larger than CNR, need to use a larger prescaler + if(i > (0x10000)) + continue; + + u16CNR = i; + break; + } + // Store return value here 'cos we're gonna change u16Prescale & u16CNR to the real value to fill into register + i = u32PWMClockSrc / (u16Prescale * u16CNR); + + // convert to real register value + // every two channels share a prescaler + PWM_SET_PRESCALER(pwm, u32ChannelNum, --u16Prescale); + // set PWM to down count type(edge aligned) + (pwm)->CTL1 = ((pwm)->CTL1 & ~(PWM_CTL1_CNTTYPE0_Msk << (2 * u32ChannelNum))) | (1UL << (2 * u32ChannelNum)); + // set PWM to auto-reload mode + (pwm)->CTL1 &= ~(PWM_CTL1_CNTMODE0_Msk << u32ChannelNum); + + PWM_SET_CNR(pwm, u32ChannelNum, --u16CNR); + if(u32DutyCycle) + { + PWM_SET_CMR(pwm, u32ChannelNum, u32DutyCycle * (u16CNR + 1) / 100 - 1); + (pwm)->WGCTL0 &= ~((PWM_WGCTL0_PRDPCTL0_Msk | PWM_WGCTL0_ZPCTL0_Msk) << (u32ChannelNum * 2)); + (pwm)->WGCTL0 |= (PWM_OUTPUT_LOW << (u32ChannelNum * 2 + PWM_WGCTL0_PRDPCTL0_Pos)); + (pwm)->WGCTL1 &= ~((PWM_WGCTL1_CMPDCTL0_Msk | PWM_WGCTL1_CMPUCTL0_Msk) << (u32ChannelNum * 2)); + (pwm)->WGCTL1 |= (PWM_OUTPUT_HIGH << (u32ChannelNum * 2 + PWM_WGCTL1_CMPDCTL0_Pos)); + } + else + { + PWM_SET_CMR(pwm, u32ChannelNum, 0); + (pwm)->WGCTL0 &= ~((PWM_WGCTL0_PRDPCTL0_Msk | PWM_WGCTL0_ZPCTL0_Msk) << (u32ChannelNum * 2)); + (pwm)->WGCTL0 |= (PWM_OUTPUT_LOW << (u32ChannelNum * 2 + PWM_WGCTL0_ZPCTL0_Pos)); + (pwm)->WGCTL1 &= ~((PWM_WGCTL1_CMPDCTL0_Msk | PWM_WGCTL1_CMPUCTL0_Msk) << (u32ChannelNum * 2)); + (pwm)->WGCTL1 |= (PWM_OUTPUT_HIGH << (u32ChannelNum * 2 + PWM_WGCTL1_CMPDCTL0_Pos)); + } + + return(i); +} + +/** + * @brief Start PWM module + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel. + * Bit 0 is channel 0, bit 1 is channel 1... + * @return None + * @details This function is used to start PWM module. + */ +void PWM_Start(PWM_T *pwm, uint32_t u32ChannelMask) +{ + (pwm)->CNTEN |= u32ChannelMask; +} + +/** + * @brief Stop PWM module + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel. + * Bit 0 is channel 0, bit 1 is channel 1... + * @return None + * @details This function is used to stop PWM module. + */ +void PWM_Stop(PWM_T *pwm, uint32_t u32ChannelMask) +{ + uint32_t i; + for(i = 0; i < PWM_CHANNEL_NUM; i ++) + { + if(u32ChannelMask & (1 << i)) + { + (pwm)->PERIOD[i] = 0; + } + } +} + +/** + * @brief Stop PWM generation immediately by clear channel enable bit + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel. + * Bit 0 is channel 0, bit 1 is channel 1... + * @return None + * @details This function is used to stop PWM generation immediately by clear channel enable bit. + */ +void PWM_ForceStop(PWM_T *pwm, uint32_t u32ChannelMask) +{ + (pwm)->CNTEN &= ~u32ChannelMask; +} + +/** + * @brief Enable selected channel to trigger EADC + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32Condition The condition to trigger EADC. Combination of following conditions: + * - \ref PWM_TRIGGER_ADC_EVEN_ZERO_POINT + * - \ref PWM_TRIGGER_ADC_EVEN_PERIOD_POINT + * - \ref PWM_TRIGGER_ADC_EVEN_ZERO_OR_PERIOD_POINT + * - \ref PWM_TRIGGER_ADC_EVEN_COMPARE_UP_COUNT_POINT + * - \ref PWM_TRIGGER_ADC_EVEN_COMPARE_DOWN_COUNT_POINT + * - \ref PWM_TRIGGER_ADC_ODD_ZERO_POINT + * - \ref PWM_TRIGGER_ADC_ODD_PERIOD_POINT + * - \ref PWM_TRIGGER_ADC_ODD_ZERO_OR_PERIOD_POINT + * - \ref PWM_TRIGGER_ADC_ODD_COMPARE_UP_COUNT_POINT + * - \ref PWM_TRIGGER_ADC_ODD_COMPARE_DOWN_COUNT_POINT + * - \ref PWM_TRIGGER_ADC_CH_0_FREE_COMPARE_UP_COUNT_POINT + * - \ref PWM_TRIGGER_ADC_CH_0_FREE_COMPARE_DOWN_COUNT_POINT + * - \ref PWM_TRIGGER_ADC_CH_2_FREE_COMPARE_UP_COUNT_POINT + * - \ref PWM_TRIGGER_ADC_CH_2_FREE_COMPARE_DOWN_COUNT_POINT + * - \ref PWM_TRIGGER_ADC_CH_4_FREE_COMPARE_UP_COUNT_POINT + * - \ref PWM_TRIGGER_ADC_CH_4_FREE_COMPARE_DOWN_COUNT_POINT + * @return None + * @details This function is used to enable selected channel to trigger EADC. + */ +void PWM_EnableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition) +{ + if(u32ChannelNum < 4) + { + (pwm)->EADCTS0 &= ~((PWM_EADCTS0_TRGSEL0_Msk) << (u32ChannelNum * 8)); + (pwm)->EADCTS0 |= ((PWM_EADCTS0_TRGEN0_Msk | u32Condition) << (u32ChannelNum * 8)); + } + else + { + (pwm)->EADCTS1 &= ~((PWM_EADCTS1_TRGSEL4_Msk) << ((u32ChannelNum - 4) * 8)); + (pwm)->EADCTS1 |= ((PWM_EADCTS1_TRGEN4_Msk | u32Condition) << ((u32ChannelNum - 4) * 8)); + } +} + +/** + * @brief Disable selected channel to trigger EADC + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to disable selected channel to trigger EADC. + */ +void PWM_DisableADCTrigger(PWM_T *pwm, uint32_t u32ChannelNum) +{ + if(u32ChannelNum < 4) + { + (pwm)->EADCTS0 &= ~(PWM_EADCTS0_TRGEN0_Msk << (u32ChannelNum * 8)); + } + else + { + (pwm)->EADCTS1 &= ~(PWM_EADCTS1_TRGEN4_Msk << ((u32ChannelNum - 4) * 8)); + } +} + +/** + * @brief Clear selected channel trigger EADC flag + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32Condition This parameter is not used + * @return None + * @details This function is used to clear selected channel trigger EADC flag. + */ +void PWM_ClearADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition) +{ + (pwm)->STATUS = (PWM_STATUS_ADCTRGF0_Msk << u32ChannelNum); +} + +/** + * @brief Get selected channel trigger EADC flag + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @retval 0 The specified channel trigger EADC to start of conversion flag is not set + * @retval 1 The specified channel trigger EADC to start of conversion flag is set + * @details This function is used to get PWM trigger EADC to start of conversion flag for specified channel. + */ +uint32_t PWM_GetADCTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + return (((pwm)->STATUS & (PWM_STATUS_ADCTRGF0_Msk << u32ChannelNum)) ? 1 : 0); +} + +/** + * @brief Enable selected channel to trigger DAC + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32Condition The condition to trigger DAC. Combination of following conditions: + * - \ref PWM_TRIGGER_DAC_ZERO_POINT + * - \ref PWM_TRIGGER_DAC_PERIOD_POINT + * - \ref PWM_TRIGGER_DAC_COMPARE_UP_COUNT_POINT + * - \ref PWM_TRIGGER_DAC_COMPARE_DOWN_COUNT_POINT + * @return None + * @details This function is used to enable selected channel to trigger DAC. + */ +void PWM_EnableDACTrigger(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition) +{ + (pwm)->DACTRGEN |= (u32Condition << u32ChannelNum); +} + +/** + * @brief Disable selected channel to trigger DAC + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to disable selected channel to trigger DAC. + */ +void PWM_DisableDACTrigger(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->DACTRGEN &= ~((PWM_TRIGGER_DAC_ZERO_POINT | PWM_TRIGGER_DAC_PERIOD_POINT | PWM_TRIGGER_DAC_COMPARE_UP_COUNT_POINT | \ + PWM_TRIGGER_DAC_COMPARE_DOWN_COUNT_POINT) << u32ChannelNum); +} + +/** + * @brief Clear selected channel trigger DAC flag + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. This parameter is not used + * @param[in] u32Condition The condition to trigger DAC. This parameter is not used + * @return None + * @details This function is used to clear selected channel trigger DAC flag. + */ +void PWM_ClearDACTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Condition) +{ + (pwm)->STATUS = PWM_STATUS_DACTRGF_Msk; +} + +/** + * @brief Get selected channel trigger DAC flag + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. This parameter is not used + * @retval 0 The specified channel trigger DAC to start of conversion flag is not set + * @retval 1 The specified channel trigger DAC to start of conversion flag is set + * @details This function is used to get selected channel trigger DAC flag. + */ +uint32_t PWM_GetDACTriggerFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + return (((pwm)->STATUS & PWM_STATUS_DACTRGF_Msk) ? 1 : 0); +} + +/** + * @brief This function enable fault brake of selected channel(s) + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel. + * @param[in] u32LevelMask Output high or low while fault brake occurs, each bit represent the level of a channel + * while fault brake occurs. Bit 0 represents channel 0, bit 1 represents channel 1... + * @param[in] u32BrakeSource Fault brake source, could be one of following source + * - \ref PWM_FB_EDGE_ACMP0 + * - \ref PWM_FB_EDGE_ACMP1 + * - \ref PWM_FB_EDGE_BKP0 + * - \ref PWM_FB_EDGE_BKP1 + * - \ref PWM_FB_EDGE_SYS_CSS + * - \ref PWM_FB_EDGE_SYS_BOD + * - \ref PWM_FB_EDGE_SYS_RAM + * - \ref PWM_FB_EDGE_SYS_COR + * - \ref PWM_FB_LEVEL_ACMP0 + * - \ref PWM_FB_LEVEL_ACMP1 + * - \ref PWM_FB_LEVEL_BKP0 + * - \ref PWM_FB_LEVEL_BKP1 + * - \ref PWM_FB_LEVEL_SYS_CSS + * - \ref PWM_FB_LEVEL_SYS_BOD + * - \ref PWM_FB_LEVEL_SYS_RAM + * - \ref PWM_FB_LEVEL_SYS_COR + * @return None + * @details This function is used to enable fault brake of selected channel(s). + * The write-protection function should be disabled before using this function. + */ +void PWM_EnableFaultBrake(PWM_T *pwm, uint32_t u32ChannelMask, uint32_t u32LevelMask, uint32_t u32BrakeSource) +{ + uint32_t i; + for(i = 0; i < PWM_CHANNEL_NUM; i ++) + { + if(u32ChannelMask & (1 << i)) + { + if((u32BrakeSource == PWM_FB_EDGE_SYS_CSS) || (u32BrakeSource == PWM_FB_EDGE_SYS_BOD) || \ + (u32BrakeSource == PWM_FB_EDGE_SYS_RAM) || (u32BrakeSource == PWM_FB_EDGE_SYS_COR) || \ + (u32BrakeSource == PWM_FB_LEVEL_SYS_CSS) || (u32BrakeSource == PWM_FB_LEVEL_SYS_BOD) || \ + (u32BrakeSource == PWM_FB_LEVEL_SYS_RAM) || (u32BrakeSource == PWM_FB_LEVEL_SYS_COR)) + { + *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= (u32BrakeSource & (PWM_BRKCTL0_1_SYSEBEN_Msk | PWM_BRKCTL0_1_SYSLBEN_Msk)); + (pwm)->FAILBRK |= (u32BrakeSource & 0xF); + } + else + { + *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= u32BrakeSource; + } + } + + if(u32LevelMask & (1 << i)) + { + if(i % 2 == 0) + { + //set brake action as high level for even channel + *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) &= ~PWM_BRKCTL0_1_BRKAEVEN_Msk; + *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= ((3UL) << PWM_BRKCTL0_1_BRKAEVEN_Pos); + } + else + { + //set brake action as high level for odd channel + *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) &= ~PWM_BRKCTL0_1_BRKAODD_Msk; + *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= ((3UL) << PWM_BRKCTL0_1_BRKAODD_Pos); + } + } + else + { + if(i % 2 == 0) + { + //set brake action as low level for even channel + *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) &= ~PWM_BRKCTL0_1_BRKAEVEN_Msk; + *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= ((2UL) << PWM_BRKCTL0_1_BRKAEVEN_Pos); + } + else + { + //set brake action as low level for odd channel + *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) &= ~PWM_BRKCTL0_1_BRKAODD_Msk; + *(__IO uint32_t *)(&((pwm)->BRKCTL0_1) + (i >> 1)) |= ((2UL) << PWM_BRKCTL0_1_BRKAODD_Pos); + } + } + } + +} + +/** + * @brief Enable capture of selected channel(s) + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel. + * Bit 0 is channel 0, bit 1 is channel 1... + * @return None + * @details This function is used to enable capture of selected channel(s). + */ +void PWM_EnableCapture(PWM_T *pwm, uint32_t u32ChannelMask) +{ + (pwm)->CAPINEN |= u32ChannelMask; + (pwm)->CAPCTL |= u32ChannelMask; +} + +/** + * @brief Disable capture of selected channel(s) + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel. + * Bit 0 is channel 0, bit 1 is channel 1... + * @return None + * @details This function is used to disable capture of selected channel(s). + */ +void PWM_DisableCapture(PWM_T *pwm, uint32_t u32ChannelMask) +{ + (pwm)->CAPINEN &= ~u32ChannelMask; + (pwm)->CAPCTL &= ~u32ChannelMask; +} + +/** + * @brief Enables PWM output generation of selected channel(s) + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel. + * Set bit 0 to 1 enables channel 0 output, set bit 1 to 1 enables channel 1 output... + * @return None + * @details This function is used to enable PWM output generation of selected channel(s). + */ +void PWM_EnableOutput(PWM_T *pwm, uint32_t u32ChannelMask) +{ + (pwm)->POEN |= u32ChannelMask; +} + +/** + * @brief Disables PWM output generation of selected channel(s) + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel + * Set bit 0 to 1 disables channel 0 output, set bit 1 to 1 disables channel 1 output... + * @return None + * @details This function is used to disable PWM output generation of selected channel(s). + */ +void PWM_DisableOutput(PWM_T *pwm, uint32_t u32ChannelMask) +{ + (pwm)->POEN &= ~u32ChannelMask; +} + +/** + * @brief Enables PDMA transfer of selected channel for PWM capture + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. + * @param[in] u32RisingFirst The capture order is rising, falling first. Every two channels share the same setting. Valid values are TRUE and FALSE. + * @param[in] u32Mode Captured data transferred by PDMA interrupt type. It could be either + * - \ref PWM_CAPTURE_PDMA_RISING_LATCH + * - \ref PWM_CAPTURE_PDMA_FALLING_LATCH + * - \ref PWM_CAPTURE_PDMA_RISING_FALLING_LATCH + * @return None + * @details This function is used to enable PDMA transfer of selected channel(s) for PWM capture. + * @note This function can only selects even or odd channel of pairs to do PDMA transfer. + */ +void PWM_EnablePDMA(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32RisingFirst, uint32_t u32Mode) +{ + uint32_t u32IsOddCh; + u32IsOddCh = u32ChannelNum % 2; + (pwm)->PDMACTL = ((pwm)->PDMACTL & ~((PWM_PDMACTL_CHSEL0_1_Msk | PWM_PDMACTL_CAPORD0_1_Msk | PWM_PDMACTL_CAPMOD0_1_Msk) << ((u32ChannelNum >> 1) * 8))) | \ + (((u32IsOddCh << PWM_PDMACTL_CHSEL0_1_Pos) | (u32RisingFirst << PWM_PDMACTL_CAPORD0_1_Pos) | \ + u32Mode | PWM_PDMACTL_CHEN0_1_Msk) << ((u32ChannelNum >> 1) * 8)); +} + +/** + * @brief Disables PDMA transfer of selected channel for PWM capture + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. + * @return None + * @details This function is used to enable PDMA transfer of selected channel(s) for PWM capture. + */ +void PWM_DisablePDMA(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->PDMACTL &= ~(PWM_PDMACTL_CHEN0_1_Msk << ((u32ChannelNum >> 1) * 8)); +} + +/** + * @brief Enable Dead zone of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @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~0xFFF, but 0 means there is no Dead zone. + * @return None + * @details This function is used to enable Dead zone of selected channel. + * The write-protection function should be disabled before using this function. + * @note Every two channels share the same setting. + */ +void PWM_EnableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Duration) +{ + // every two channels share the same setting + *(__IO uint32_t *)(&((pwm)->DTCTL0_1) + (u32ChannelNum >> 1)) &= ~PWM_DTCTL0_1_DTCNT_Msk; + *(__IO uint32_t *)(&((pwm)->DTCTL0_1) + (u32ChannelNum >> 1)) |= PWM_DTCTL0_1_DTEN_Msk | u32Duration; +} + +/** + * @brief Disable Dead zone of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to disable Dead zone of selected channel. + * The write-protection function should be disabled before using this function. + */ +void PWM_DisableDeadZone(PWM_T *pwm, uint32_t u32ChannelNum) +{ + // every two channels shares the same setting + *(__IO uint32_t *)(&((pwm)->DTCTL0_1) + (u32ChannelNum >> 1)) &= ~PWM_DTCTL0_1_DTEN_Msk; +} + +/** + * @brief Enable capture interrupt of selected channel. + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32Edge Rising or falling edge to latch counter. + * - \ref PWM_CAPTURE_INT_RISING_LATCH + * - \ref PWM_CAPTURE_INT_FALLING_LATCH + * @return None + * @details This function is used to enable capture interrupt of selected channel. + */ +void PWM_EnableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge) +{ + (pwm)->CAPIEN |= (u32Edge << u32ChannelNum); +} + +/** + * @brief Disable capture interrupt of selected channel. + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32Edge Rising or falling edge to latch counter. + * - \ref PWM_CAPTURE_INT_RISING_LATCH + * - \ref PWM_CAPTURE_INT_FALLING_LATCH + * @return None + * @details This function is used to disable capture interrupt of selected channel. + */ +void PWM_DisableCaptureInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge) +{ + (pwm)->CAPIEN &= ~(u32Edge << u32ChannelNum); +} + +/** + * @brief Clear capture interrupt of selected channel. + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32Edge Rising or falling edge to latch counter. + * - \ref PWM_CAPTURE_INT_RISING_LATCH + * - \ref PWM_CAPTURE_INT_FALLING_LATCH + * @return None + * @details This function is used to clear capture interrupt of selected channel. + */ +void PWM_ClearCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32Edge) +{ + (pwm)->CAPIF = (u32Edge << u32ChannelNum); +} + +/** + * @brief Get capture interrupt of selected channel. + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @retval 0 No capture interrupt + * @retval 1 Rising edge latch interrupt + * @retval 2 Falling edge latch interrupt + * @retval 3 Rising and falling latch interrupt + * @details This function is used to get capture interrupt of selected channel. + */ +uint32_t PWM_GetCaptureIntFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + return (((((pwm)->CAPIF & (PWM_CAPIF_CFLIF0_Msk << u32ChannelNum)) ? 1 : 0) << 1) | \ + (((pwm)->CAPIF & (PWM_CAPIF_CRLIF0_Msk << u32ChannelNum)) ? 1 : 0)); +} +/** + * @brief Enable duty interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32IntDutyType Duty interrupt type, could be either + * - \ref PWM_DUTY_INT_DOWN_COUNT_MATCH_CMP + * - \ref PWM_DUTY_INT_UP_COUNT_MATCH_CMP + * @return None + * @details This function is used to enable duty interrupt of selected channel. + */ +void PWM_EnableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntDutyType) +{ + (pwm)->INTEN0 |= (u32IntDutyType << u32ChannelNum); +} + +/** + * @brief Disable duty interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to disable duty interrupt of selected channel. + */ +void PWM_DisableDutyInt(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->INTEN0 &= ~((PWM_DUTY_INT_DOWN_COUNT_MATCH_CMP | PWM_DUTY_INT_UP_COUNT_MATCH_CMP) << u32ChannelNum); +} + +/** + * @brief Clear duty interrupt flag of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to clear duty interrupt flag of selected channel. + */ +void PWM_ClearDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->INTSTS0 = (PWM_INTSTS0_CMPUIF0_Msk | PWM_INTSTS0_CMPDIF0_Msk) << u32ChannelNum; +} + +/** + * @brief Get duty interrupt flag of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return Duty interrupt flag of specified channel + * @retval 0 Duty interrupt did not occur + * @retval 1 Duty interrupt occurred + * @details This function is used to get duty interrupt flag of selected channel. + */ +uint32_t PWM_GetDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + return ((((pwm)->INTSTS0 & ((PWM_INTSTS0_CMPDIF0_Msk | PWM_INTSTS0_CMPUIF0_Msk) << u32ChannelNum))) ? 1 : 0); +} + +/** + * @brief This function enable fault brake interrupt + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32BrakeSource Fault brake source. + * - \ref PWM_FB_EDGE + * - \ref PWM_FB_LEVEL + * @return None + * @details This function is used to enable fault brake interrupt. + * The write-protection function should be disabled before using this function. + * @note Every two channels share the same setting. + */ +void PWM_EnableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource) +{ + (pwm)->INTEN1 |= (0x7 << u32BrakeSource); +} + +/** + * @brief This function disable fault brake interrupt + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32BrakeSource Fault brake source. + * - \ref PWM_FB_EDGE + * - \ref PWM_FB_LEVEL + * @return None + * @details This function is used to disable fault brake interrupt. + * The write-protection function should be disabled before using this function. + * @note Every two channels share the same setting. + */ +void PWM_DisableFaultBrakeInt(PWM_T *pwm, uint32_t u32BrakeSource) +{ + (pwm)->INTEN1 &= ~(0x7 << u32BrakeSource); +} + +/** + * @brief This function clear fault brake interrupt of selected source + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32BrakeSource Fault brake source. + * - \ref PWM_FB_EDGE + * - \ref PWM_FB_LEVEL + * @return None + * @details This function is used to clear fault brake interrupt of selected source. + * The write-protection function should be disabled before using this function. + */ +void PWM_ClearFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource) +{ + (pwm)->INTSTS1 = (0x3f << u32BrakeSource); +} + +/** + * @brief This function get fault brake interrupt flag of selected source + * @param[in] pwm The pointer of the specified PWM module + * @param[in] u32BrakeSource Fault brake source, could be either + * - \ref PWM_FB_EDGE + * - \ref PWM_FB_LEVEL + * @return Fault brake interrupt flag of specified source + * @retval 0 Fault brake interrupt did not occurred + * @retval 1 Fault brake interrupt occurred + * @details This function is used to get fault brake interrupt flag of selected source. + */ +uint32_t PWM_GetFaultBrakeIntFlag(PWM_T *pwm, uint32_t u32BrakeSource) +{ + return (((pwm)->INTSTS1 & (0x3f << u32BrakeSource)) ? 1 : 0); +} + +/** + * @brief Enable period interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32IntPeriodType Period interrupt type. This parameter is not used. + * @return None + * @details This function is used to enable period interrupt of selected channel. + */ +void PWM_EnablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntPeriodType) +{ + (pwm)->INTEN0 |= (PWM_INTEN0_PIEN0_Msk << u32ChannelNum); +} + +/** + * @brief Disable period interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to disable period interrupt of selected channel. + */ +void PWM_DisablePeriodInt(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->INTEN0 &= ~(PWM_INTEN0_PIEN0_Msk << u32ChannelNum); +} + +/** + * @brief Clear period interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to clear period interrupt of selected channel. + */ +void PWM_ClearPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->INTSTS0 = (PWM_INTSTS0_PIF0_Msk << u32ChannelNum); +} + +/** + * @brief Get period interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @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 occur + * @retval 1 Period interrupt occurred + * @details This function is used to get period interrupt of selected channel. + */ +uint32_t PWM_GetPeriodIntFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + return ((((pwm)->INTSTS0 & (PWM_INTSTS0_PIF0_Msk << u32ChannelNum))) ? 1 : 0); +} + +/** + * @brief Enable zero interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to enable zero interrupt of selected channel. + */ +void PWM_EnableZeroInt(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->INTEN0 |= (PWM_INTEN0_ZIEN0_Msk << u32ChannelNum); +} + +/** + * @brief Disable zero interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to disable zero interrupt of selected channel. + */ +void PWM_DisableZeroInt(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->INTEN0 &= ~(PWM_INTEN0_ZIEN0_Msk << u32ChannelNum); +} + +/** + * @brief Clear zero interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to clear zero interrupt of selected channel. + */ +void PWM_ClearZeroIntFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->INTSTS0 = (PWM_INTSTS0_ZIF0_Msk << u32ChannelNum); +} + +/** + * @brief Get zero interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return Zero interrupt flag of specified channel + * @retval 0 Zero interrupt did not occur + * @retval 1 Zero interrupt occurred + * @details This function is used to get zero interrupt of selected channel. + */ +uint32_t PWM_GetZeroIntFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + return ((((pwm)->INTSTS0 & (PWM_INTSTS0_ZIF0_Msk << u32ChannelNum))) ? 1 : 0); +} + +/** + * @brief Enable interrupt flag accumulator of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32IntFlagCnt Interrupt flag counter. Valid values are between 0~15. + * @param[in] u32IntAccSrc Interrupt flag accumulator source selection. + * - \ref PWM_IFA_EVEN_ZERO_POINT + * - \ref PWM_IFA_EVEN_PERIOD_POINT + * - \ref PWM_IFA_EVEN_COMPARE_UP_COUNT_POINT + * - \ref PWM_IFA_EVEN_COMPARE_DOWN_COUNT_POINT + * - \ref PWM_IFA_ODD_ZERO_POINT + * - \ref PWM_IFA_ODD_PERIOD_POINT + * - \ref PWM_IFA_ODD_COMPARE_UP_COUNT_POINT + * - \ref PWM_IFA_ODD_COMPARE_DOWN_COUNT_POINT + * @return None + * @details This function is used to enable interrupt flag accumulator of selected channel. + * @note Every two channels share the same setting. + */ +void PWM_EnableAcc(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32IntFlagCnt, uint32_t u32IntAccSrc) +{ + (pwm)->IFA = ((pwm)->IFA & ~((PWM_IFA_IFCNT0_1_Msk | PWM_IFA_IFSEL0_1_Msk) << ((u32ChannelNum >> 1) * 8))) | \ + ((PWM_IFA_IFAEN0_1_Msk | (u32IntAccSrc << PWM_IFA_IFSEL0_1_Pos) | u32IntFlagCnt) << ((u32ChannelNum >> 1) * 8)); +} + +/** + * @brief Disable interrupt flag accumulator of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to Disable interrupt flag accumulator of selected channel. + * @note Every two channels share the same setting. + */ +void PWM_DisableAcc(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->IFA = (pwm)->IFA & ~(PWM_IFA_IFAEN0_1_Msk << ((u32ChannelNum >> 1) * 8)); +} + +/** + * @brief Enable interrupt flag accumulator interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to enable interrupt flag accumulator interrupt of selected channel. + * @note Every two channels share the same setting. + */ +void PWM_EnableAccInt(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->INTEN0 |= (PWM_INTEN0_IFAIEN0_1_Msk << ((u32ChannelNum >> 1) * 8)); +} + +/** + * @brief Disable interrupt flag accumulator interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to disable interrupt flag accumulator interrupt of selected channel. + * @note Every two channels share the same setting. + */ +void PWM_DisableAccInt(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->INTEN0 &= ~(PWM_INTEN0_IFAIEN0_1_Msk << ((u32ChannelNum >> 1) * 8)); +} + +/** + * @brief Clear interrupt flag accumulator interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to clear interrupt flag accumulator interrupt of selected channel. + * @note Every two channels share the same setting. + */ +void PWM_ClearAccInt(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->INTSTS0 = (PWM_INTSTS0_IFAIF0_1_Msk << ((u32ChannelNum >> 1) * 8)); +} + +/** + * @brief Get interrupt flag accumulator interrupt of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @retval 0 Accumulator interrupt did not occur + * @retval 1 Accumulator interrupt occurred + * @details This function is used to Get interrupt flag accumulator interrupt of selected channel. + * @note Every two channels share the same setting. + */ +uint32_t PWM_GetAccInt(PWM_T *pwm, uint32_t u32ChannelNum) +{ + return (((pwm)->INTSTS0 & (PWM_INTSTS0_IFAIF0_1_Msk << ((u32ChannelNum >> 1) * 8))) ? 1 : 0); +} + +/** + * @brief Clear free trigger duty interrupt flag of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to clear free trigger duty interrupt flag of selected channel. + */ +void PWM_ClearFTDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->FTCI = ((PWM_FTCI_FTCMU0_Msk | PWM_FTCI_FTCMD0_Msk) << (u32ChannelNum >> 1)); +} + +/** + * @brief Get free trigger duty interrupt flag of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return Duty interrupt flag of specified channel + * @retval 0 Free trigger duty interrupt did not occur + * @retval 1 Free trigger duty interrupt occurred + * @details This function is used to get free trigger duty interrupt flag of selected channel. + */ +uint32_t PWM_GetFTDutyIntFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + return (((pwm)->FTCI & ((PWM_FTCI_FTCMU0_Msk | PWM_FTCI_FTCMD0_Msk) << (u32ChannelNum >> 1))) ? 1 : 0); +} + +/** + * @brief Enable load mode of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32LoadMode PWM counter loading mode. + * - \ref PWM_LOAD_MODE_IMMEDIATE + * - \ref PWM_LOAD_MODE_WINDOW + * - \ref PWM_LOAD_MODE_CENTER + * @return None + * @details This function is used to enable load mode of selected channel. + */ +void PWM_EnableLoadMode(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32LoadMode) +{ + (pwm)->CTL0 |= (u32LoadMode << u32ChannelNum); +} + +/** + * @brief Disable load mode of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32LoadMode PWM counter loading mode. + * - \ref PWM_LOAD_MODE_IMMEDIATE + * - \ref PWM_LOAD_MODE_WINDOW + * - \ref PWM_LOAD_MODE_CENTER + * @return None + * @details This function is used to disable load mode of selected channel. + */ +void PWM_DisableLoadMode(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32LoadMode) +{ + (pwm)->CTL0 &= ~(u32LoadMode << u32ChannelNum); +} + +/** + * @brief Configure synchronization phase of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32SyncSrc PWM synchronize source selection. + * - \ref PWM_SYNC_OUT_FROM_SYNCIN_SWSYNC + * - \ref PWM_SYNC_OUT_FROM_COUNT_TO_ZERO + * - \ref PWM_SYNC_OUT_FROM_COUNT_TO_COMPARATOR + * - \ref PWM_SYNC_OUT_DISABLE + * @param[in] u32Direction Phase direction. Control PWM counter count decrement or increment after synchronizing. + * - \ref PWM_PHS_DIR_DECREMENT + * - \ref PWM_PHS_DIR_INCREMENT + * @param[in] u32StartPhase Synchronous start phase value. Valid values are between 0~65535. + * @return None + * @details This function is used to configure synchronization phase of selected channel. + * @note Every two channels share the same setting. + */ +void PWM_ConfigSyncPhase(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32SyncSrc, uint32_t u32Direction, uint32_t u32StartPhase) +{ + // every two channels shares the same setting + u32ChannelNum >>= 1; + (pwm)->SYNC = (((pwm)->SYNC & ~((PWM_SYNC_SINSRC0_Msk << (u32ChannelNum << 1)) | (PWM_SYNC_PHSDIR0_Msk << u32ChannelNum))) | \ + (u32Direction << PWM_SYNC_PHSDIR0_Pos << u32ChannelNum) | (u32SyncSrc << PWM_SYNC_SINSRC0_Pos) << (u32ChannelNum << 1)); + *(__IO uint32_t *)(&((pwm)->PHS0_1) + u32ChannelNum) = u32StartPhase; +} + + +/** + * @brief Enable SYNC phase of selected channel(s) + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel. + * Bit 0 is channel 0, bit 1 is channel 1... + * @return None + * @details This function is used to enable SYNC phase of selected channel(s). + * @note Every two channels share the same setting. + */ +void PWM_EnableSyncPhase(PWM_T *pwm, uint32_t u32ChannelMask) +{ + uint32_t i; + for(i = 0; i < PWM_CHANNEL_NUM; i ++) + { + if(u32ChannelMask & (1 << i)) + { + (pwm)->SYNC |= (PWM_SYNC_PHSEN0_Msk << (i >> 1)); + } + } +} + +/** + * @brief Disable SYNC phase of selected channel(s) + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelMask Combination of enabled channels. Each bit corresponds to a channel. + * Bit 0 is channel 0, bit 1 is channel 1... + * @return None + * @details This function is used to disable SYNC phase of selected channel(s). + * @note Every two channels share the same setting. + */ +void PWM_DisableSyncPhase(PWM_T *pwm, uint32_t u32ChannelMask) +{ + uint32_t i; + for(i = 0; i < PWM_CHANNEL_NUM; i ++) + { + if(u32ChannelMask & (1 << i)) + { + (pwm)->SYNC &= ~(PWM_SYNC_PHSEN0_Msk << (i >> 1)); + } + } +} + +/** + * @brief Enable PWM SYNC_IN noise filter function + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ClkCnt SYNC Edge Detector Filter Count. This controls the counter number of edge detector. + * The valid value is 0~7. + * @param[in] u32ClkDivSel SYNC Edge Detector Filter Clock Selection. + * - \ref PWM_NF_CLK_DIV_1 + * - \ref PWM_NF_CLK_DIV_2 + * - \ref PWM_NF_CLK_DIV_4 + * - \ref PWM_NF_CLK_DIV_8 + * - \ref PWM_NF_CLK_DIV_16 + * - \ref PWM_NF_CLK_DIV_32 + * - \ref PWM_NF_CLK_DIV_64 + * - \ref PWM_NF_CLK_DIV_128 + * @return None + * @details This function is used to enable PWM SYNC_IN noise filter function. + */ +void PWM_EnableSyncNoiseFilter(PWM_T *pwm, uint32_t u32ClkCnt, uint32_t u32ClkDivSel) +{ + (pwm)->SYNC = ((pwm)->SYNC & ~(PWM_SYNC_SFLTCNT_Msk | PWM_SYNC_SFLTCSEL_Msk)) | \ + ((u32ClkCnt << PWM_SYNC_SFLTCNT_Pos) | (u32ClkDivSel << PWM_SYNC_SFLTCSEL_Pos) | PWM_SYNC_SNFLTEN_Msk); +} + +/** + * @brief Disable PWM SYNC_IN noise filter function + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @return None + * @details This function is used to Disable PWM SYNC_IN noise filter function. + */ +void PWM_DisableSyncNoiseFilter(PWM_T *pwm) +{ + (pwm)->SYNC &= ~PWM_SYNC_SNFLTEN_Msk; +} + +/** + * @brief Enable PWM SYNC input pin inverse function + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @return None + * @details This function is used to enable PWM SYNC input pin inverse function. + */ +void PWM_EnableSyncPinInverse(PWM_T *pwm) +{ + (pwm)->SYNC |= PWM_SYNC_SINPINV_Msk; +} + +/** + * @brief Disable PWM SYNC input pin inverse function + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @return None + * @details This function is used to Disable PWM SYNC input pin inverse function. + */ +void PWM_DisableSyncPinInverse(PWM_T *pwm) +{ + (pwm)->SYNC &= ~PWM_SYNC_SINPINV_Msk; +} + +/** + * @brief Set PWM clock source + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @param[in] u32ClkSrcSel PWM external clock source. + * - \ref PWM_CLKSRC_PWM_CLK + * - \ref PWM_CLKSRC_TIMER0 + * - \ref PWM_CLKSRC_TIMER1 + * - \ref PWM_CLKSRC_TIMER2 + * - \ref PWM_CLKSRC_TIMER3 + * @return None + * @details This function is used to set PWM clock source. + * @note Every two channels share the same setting. + */ +void PWM_SetClockSource(PWM_T *pwm, uint32_t u32ChannelNum, uint32_t u32ClkSrcSel) +{ + (pwm)->CLKSRC = (pwm)->CLKSRC & ~(PWM_CLKSRC_ECLKSRC0_Msk << ((u32ChannelNum >> 1) * PWM_CLKSRC_ECLKSRC2_Pos)) | \ + (u32ClkSrcSel << ((u32ChannelNum >> 1) * PWM_CLKSRC_ECLKSRC2_Pos)); +} + +/** + * @brief Enable PWM brake noise filter function + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32BrakePinNum Brake pin selection. Valid values are 0 or 1. + * @param[in] u32ClkCnt SYNC Edge Detector Filter Count. This controls the counter number of edge detector + * @param[in] u32ClkDivSel SYNC Edge Detector Filter Clock Selection. + * - \ref PWM_NF_CLK_DIV_1 + * - \ref PWM_NF_CLK_DIV_2 + * - \ref PWM_NF_CLK_DIV_4 + * - \ref PWM_NF_CLK_DIV_8 + * - \ref PWM_NF_CLK_DIV_16 + * - \ref PWM_NF_CLK_DIV_32 + * - \ref PWM_NF_CLK_DIV_64 + * - \ref PWM_NF_CLK_DIV_128 + * @return None + * @details This function is used to enable PWM brake noise filter function. + */ +void PWM_EnableBrakeNoiseFilter(PWM_T *pwm, uint32_t u32BrakePinNum, uint32_t u32ClkCnt, uint32_t u32ClkDivSel) +{ + (pwm)->BNF = ((pwm)->BNF & ~((PWM_BNF_BRK0FCNT_Msk | PWM_BNF_BRK0NFSEL_Msk) << (u32BrakePinNum * PWM_BNF_BRK1NFEN_Pos))) | \ + (((u32ClkCnt << PWM_BNF_BRK0FCNT_Pos) | (u32ClkDivSel << PWM_BNF_BRK0NFSEL_Pos) | PWM_BNF_BRK0NFEN_Msk) << (u32BrakePinNum * PWM_BNF_BRK1NFEN_Pos)); +} + +/** + * @brief Disable PWM brake noise filter function + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32BrakePinNum Brake pin selection. Valid values are 0 or 1. + * @return None + * @details This function is used to disable PWM brake noise filter function. + */ +void PWM_DisableBrakeNoiseFilter(PWM_T *pwm, uint32_t u32BrakePinNum) +{ + (pwm)->BNF &= ~(PWM_BNF_BRK0NFEN_Msk << (u32BrakePinNum * PWM_BNF_BRK1NFEN_Pos)); +} + +/** + * @brief Enable PWM brake pin inverse function + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32BrakePinNum Brake pin selection. Valid values are 0 or 1. + * @return None + * @details This function is used to enable PWM brake pin inverse function. + */ +void PWM_EnableBrakePinInverse(PWM_T *pwm, uint32_t u32BrakePinNum) +{ + (pwm)->BNF |= (PWM_BNF_BRK0PINV_Msk << (u32BrakePinNum * PWM_BNF_BRK1NFEN_Pos)); +} + +/** + * @brief Disable PWM brake pin inverse function + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32BrakePinNum Brake pin selection. Valid values are 0 or 1. + * @return None + * @details This function is used to disable PWM brake pin inverse function. + */ +void PWM_DisableBrakePinInverse(PWM_T *pwm, uint32_t u32BrakePinNum) +{ + (pwm)->BNF &= ~(PWM_BNF_BRK0PINV_Msk << (u32BrakePinNum * PWM_BNF_BRK1NFEN_Pos)); +} + +/** + * @brief Set PWM brake pin source + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32BrakePinNum Brake pin selection. Valid values are 0 or 1. + * @param[in] u32SelAnotherModule Select to another module. Valid values are TRUE or FALSE. + * @return None + * @details This function is used to set PWM brake pin source. + * @note This function is only supported in M45xD/M45xC. + */ +void PWM_SetBrakePinSource(PWM_T *pwm, uint32_t u32BrakePinNum, uint32_t u32SelAnotherModule) +{ + (pwm)->BNF = ((pwm)->BNF & ~(PWM_BNF_BK0SRC_Msk << (u32BrakePinNum * 8))) | (u32SelAnotherModule << (PWM_BNF_BK0SRC_Pos + u32BrakePinNum * 8)); +} + +/** + * @brief Get the time-base counter reached its maximum value flag of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return Count to max interrupt flag of specified channel + * @retval 0 Count to max interrupt did not occur + * @retval 1 Count to max interrupt occurred + * @details This function is used to get the time-base counter reached its maximum value flag of selected channel. + */ +uint32_t PWM_GetWrapAroundFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + return (((pwm)->STATUS & (PWM_STATUS_CNTMAXF0_Msk << u32ChannelNum)) ? 1 : 0); +} + +/** + * @brief Clear the time-base counter reached its maximum value flag of selected channel + * @param[in] pwm The pointer of the specified PWM module + * - PWM0 : PWM Group 0 + * - PWM1 : PWM Group 1 + * @param[in] u32ChannelNum PWM channel number. Valid values are between 0~5 + * @return None + * @details This function is used to clear the time-base counter reached its maximum value flag of selected channel. + */ +void PWM_ClearWrapAroundFlag(PWM_T *pwm, uint32_t u32ChannelNum) +{ + (pwm)->STATUS = (PWM_STATUS_CNTMAXF0_Msk << u32ChannelNum); +} + + +/*@}*/ /* end of group PWM_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group PWM_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/retarget.c b/StdDriver/src/retarget.c new file mode 100644 index 0000000..a31f927 --- /dev/null +++ b/StdDriver/src/retarget.c @@ -0,0 +1,674 @@ +/**************************************************************************//** + * @file retarget.c + * @version V3.00 + * $Revision: 14 $ + * $Date: 15/11/02 9:02a $ + * @brief M451 Series Debug Port and Semihost Setting Source File + * + * @note + * Copyright (C) 2011~2015 Nuvoton Technology Corp. All rights reserved. + * + ******************************************************************************/ + + +#include +#include "M451Series.h" + +#if defined ( __CC_ARM ) +#if (__ARMCC_VERSION < 400000) +#else +/* Insist on keeping widthprec, to avoid X propagation by benign code in C-lib */ +#pragma import _printf_widthprec +#endif +#endif + +/*---------------------------------------------------------------------------------------------------------*/ +/* Global variables */ +/*---------------------------------------------------------------------------------------------------------*/ +#if !(defined(__ICCARM__) && (__VER__ >= 6010000)) +struct __FILE +{ + int handle; /* Add whatever you need here */ +}; +#endif +FILE __stdout; +FILE __stdin; + +enum { r0, r1, r2, r3, r12, lr, pc, psr}; + +/** + * @brief Helper function to dump register while hard fault occurred + * @param[in] stack pointer points to the dumped registers in SRAM + * @return None + * @details This function is implement to print r0, r1, r2, r3, r12, lr, pc, psr + */ +static void stackDump(uint32_t stack[]) +{ + printf("r0 = 0x%x\n", stack[r0]); + printf("r1 = 0x%x\n", stack[r1]); + printf("r2 = 0x%x\n", stack[r2]); + printf("r3 = 0x%x\n", stack[r3]); + printf("r12 = 0x%x\n", stack[r12]); + printf("lr = 0x%x\n", stack[lr]); + printf("pc = 0x%x\n", stack[pc]); + printf("psr = 0x%x\n", stack[psr]); +} + +/** + * @brief Hard fault handler + * @param[in] stack pointer points to the dumped registers in SRAM + * @return None + * @details Replace while(1) at the end of this function with chip reset if WDT is not enabled for end product + */ +void Hard_Fault_Handler(uint32_t stack[]) +{ + printf("In Hard Fault Handler\n"); + + stackDump(stack); + // Replace while(1) with chip reset if WDT is not enabled for end product + while(1); + //SYS->IPRST0 = SYS_IPRST0_CHIPRST_Msk; +} + + + +/*---------------------------------------------------------------------------------------------------------*/ +/* Routine to write a char */ +/*---------------------------------------------------------------------------------------------------------*/ + +#if defined(DEBUG_ENABLE_SEMIHOST) +/* The static buffer is used to speed up the semihost */ +static char g_buf[16]; +static char g_buf_len = 0; + +# if defined(__ICCARM__) + +void SH_End(void) +{ + asm("MOVS R0,#1 \n" //; Set return value to 1 + "BX lr \n" //; Return + ); +} + +void SH_ICE(void) +{ + asm("CMP R2,#0 \n" + "BEQ SH_End \n" + "STR R0,[R2] \n" //; Save the return value to *pn32Out_R0 + ); +} + +/** + * + * @brief The function to process semihosted command + * @param[in] n32In_R0 : semihost register 0 + * @param[in] n32In_R1 : semihost register 1 + * @param[out] pn32Out_R0: semihost register 0 + * @retval 0: No ICE debug + * @retval 1: ICE debug + * + */ +int32_t SH_DoCommand(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0) +{ + asm("BKPT 0xAB \n" //; This instruction will cause ICE trap or system HardFault + "B SH_ICE \n" + "SH_HardFault: \n" //; Captured by HardFault + "MOVS R0,#0 \n" //; Set return value to 0 + "BX lr \n" //; Return + ); + + return 1; //; Return 1 when it is trap by ICE +} + +/** + * @brief Get LR value and branch to Hard_Fault_Handler function + * @param None + * @return None + * @details This function is use to get LR value and branch to Hard_Fault_Handler function. + */ +void Get_LR_and_Branch(void) +{ + asm("MOV R1, LR \n" //; LR current value + "B Hard_Fault_Handler \n" + ); +} + +/** + * @brief Get MSP value and branch to Get_LR_and_Branch function + * @param None + * @return None + * @details This function is use to get stack pointer value and branch to Get_LR_and_Branch function. + */ +void Stack_Use_MSP(void) +{ + asm("MRS R0, MSP \n" //; read MSP + "B Get_LR_and_Branch \n" + ); +} + +/** + * @brief Get stack pointer value and branch to Get_LR_and_Branch function + * @param None + * @return None + * @details This function is use to get stack pointer value and branch to Get_LR_and_Branch function. + */ +void HardFault_Handler_Ret(void) +{ + asm("MOVS r0, #4 \n" + "MOV r1, LR \n" + "TST r0, r1 \n" //; check LR bit 2 + "BEQ Stack_Use_MSP \n" //; stack use MSP + "MRS R0, PSP \n" //; stack use PSP, read PSP + "B Get_LR_and_Branch \n" + ); +} + +/** + * @brief This function is implemented to support semihost + * @param None + * @returns None + * @details This function is implement to support semihost message print. + * + */ +void SP_Read_Ready(void) +{ + asm("LDR R1, [R0, #24] \n" //; Get previous PC + "LDRH R3, [R1] \n" //; Get instruction + "LDR R2, [pc, #8] \n" //; The special BKPT instruction + "CMP R3, R2 \n" //; Test if the instruction at previous PC is BKPT + "BNE HardFault_Handler_Ret \n" //; Not BKPT + "ADDS R1, #4 \n" //; Skip BKPT and next line + "STR R1, [R0, #24] \n" //; Save previous PC + "BX lr \n" //; Return + "DCD 0xBEAB \n" //; BKPT instruction code + "B HardFault_Handler_Ret \n" + ); +} + +/** + * @brief Get stack pointer value and branch to Get_LR_and_Branch function + * @param None + * @return None + * @details This function is use to get stack pointer value and branch to Get_LR_and_Branch function. + */ +void SP_is_PSP(void) +{ + asm( + "MRS R0, PSP \n" //; stack use PSP, read PSP + "B Get_LR_and_Branch \n" + + ); +} + +/** + * @brief This HardFault handler is implemented to support semihost + * + * @param None + * + * @returns None + * + * @details This function is implement to support semihost message print. + * + */ +void HardFault_Handler (void) +{ + asm("MOV R0, lr \n" + "LSLS R0, #29 \n" //; Check bit 2 + "BMI SP_is_PSP \n" //; previous stack is PSP + "MRS R0, MSP \n" //; previous stack is MSP, read MSP + "B SP_Read_Ready \n" + ); + + while(1); +} + +# else + +/** + * @brief This HardFault handler is implemented to support semihost + * @param None + * @returns None + * @details This function is implement to support semihost message print. + * + */ +__asm int32_t HardFault_Handler(void) +{ + MOV R0, LR + LSLS R0, #29 //; Check bit 2 + BMI SP_is_PSP //; previous stack is PSP + MRS R0, MSP //; previous stack is MSP, read MSP + B SP_Read_Ready +SP_is_PSP + MRS R0, PSP //; Read PSP + +SP_Read_Ready + LDR R1, [R0, #24] //; Get previous PC + LDRH R3, [R1] //; Get instruction + LDR R2, =0xBEAB //; The special BKPT instruction + CMP R3, R2 //; Test if the instruction at previous PC is BKPT + BNE HardFault_Handler_Ret //; Not BKPT + + ADDS R1, #4 //; Skip BKPT and next line + STR R1, [R0, #24] //; Save previous PC + + BX LR //; Return +HardFault_Handler_Ret + + /* TODO: Implement your own hard fault handler here. */ + MOVS r0, #4 + MOV r1, LR + TST r0, r1 //; check LR bit 2 + BEQ Stack_Use_MSP //; stack use MSP + MRS R0, PSP ;stack use PSP //; stack use PSP, read PSP + B Get_LR_and_Branch +Stack_Use_MSP + MRS R0, MSP ; stack use MSP //; read MSP +Get_LR_and_Branch + MOV R1, LR ; LR current value //; LR current value + LDR R2,=__cpp(Hard_Fault_Handler) //; branch to Hard_Fault_Handler + BX R2 + + B . + + ALIGN +} + +/** + * + * @brief The function to process semihosted command + * @param[in] n32In_R0 : semihost register 0 + * @param[in] n32In_R1 : semihost register 1 + * @param[out] pn32Out_R0: semihost register 0 + * @retval 0: No ICE debug + * @retval 1: ICE debug + * + */ +__asm int32_t SH_DoCommand(int32_t n32In_R0, int32_t n32In_R1, int32_t *pn32Out_R0) +{ + BKPT 0xAB //; Wait ICE or HardFault + //; ICE will step over BKPT directly + //; HardFault will step BKPT and the next line + B SH_ICE + +SH_HardFault //; Captured by HardFault + MOVS R0, #0 //; Set return value to 0 + BX lr //; Return + +SH_ICE //; Captured by ICE + //; Save return value + CMP R2, #0 + BEQ SH_End + STR R0, [R2] //; Save the return value to *pn32Out_R0 + +SH_End + MOVS R0, #1 //; Set return value to 1 + BX lr //; Return +} +#endif + +#else + +# if defined(__ICCARM__) + +void Get_LR_and_Branch(void) +{ + asm("MOV R1, LR \n" //; LR current value + "B Hard_Fault_Handler \n" + ); +} + +void Stack_Use_MSP(void) +{ + asm("MRS R0, MSP \n" //; read MSP + "B Get_LR_and_Branch \n" + ); +} + +/** + * @brief This HardFault handler is implemented to show r0, r1, r2, r3, r12, lr, pc, psr + * + * @param None + * + * @returns None + * + * @details This function is implement to print r0, r1, r2, r3, r12, lr, pc, psr. + * + */ +void HardFault_Handler(void) +{ + asm("MOVS r0, #4 \n" + "MOV r1, LR \n" + "TST r0, r1 \n" //; check LR bit 2 + "BEQ Stack_Use_MSP \n" //; stack use MSP + "MRS R0, PSP \n" //; stack use PSP, read PSP + "B Get_LR_and_Branch \n" + ); + + while(1); +} + +# else + +/** + * @brief This HardFault handler is implemented to show r0, r1, r2, r3, r12, lr, pc, psr + * + * @param None + * + * @return None + * + * @details The function extracts the location of stack frame and passes it to Hard_Fault_Handler function as a pointer + * + */ +__asm int32_t HardFault_Handler(void) +{ + MOVS r0, #4 + MOV r1, LR + TST r0, r1 //; check LR bit 2 + BEQ Stack_Use_MSP //; stack use MSP + MRS R0, PSP //; stack use PSP, read PSP + B Get_LR_and_Branch +Stack_Use_MSP + MRS R0, MSP //; read MSP +Get_LR_and_Branch + MOV R1, LR //; LR current value + LDR R2,=__cpp(Hard_Fault_Handler) //; branch to Hard_Fault_Handler + BX R2 +} + +#endif + +#endif + + +/** + * @brief Routine to send a char + * + * @param[in] ch Character to send to debug port. + * + * @returns Send value from UART debug port + * + * @details Send a target char to UART debug port . + */ +#ifndef NONBLOCK_PRINTF +void SendChar_ToUART(int ch) +{ + while(DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXFULL_Msk); + + DEBUG_PORT->DAT = ch; + if(ch == '\n') + { + while(DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXFULL_Msk); + DEBUG_PORT->DAT = '\r'; + } +} + +#else +/* Non-block implement of send char */ +#define BUF_SIZE 2048 +void SendChar_ToUART(int ch) +{ + static uint8_t u8Buf[BUF_SIZE] = {0}; + static int32_t i32Head = 0; + static int32_t i32Tail = 0; + int32_t i32Tmp; + + /* Only flush the data in buffer to UART when ch == 0 */ + if(ch) + { + // Push char + i32Tmp = i32Head+1; + if(i32Tmp > BUF_SIZE) i32Tmp = 0; + if(i32Tmp != i32Tail) + { + u8Buf[i32Head] = ch; + i32Head = i32Tmp; + } + + if(ch == '\n') + { + i32Tmp = i32Head+1; + if(i32Tmp > BUF_SIZE) i32Tmp = 0; + if(i32Tmp != i32Tail) + { + u8Buf[i32Head] = '\r'; + i32Head = i32Tmp; + } + } + } + else + { + if(i32Tail == i32Head) + return; + } + + // pop char + do + { + i32Tmp = i32Tail + 1; + if(i32Tmp > BUF_SIZE) i32Tmp = 0; + + if((DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXFULL_Msk) == 0) + { + DEBUG_PORT->DAT = u8Buf[i32Tail]; + i32Tail = i32Tmp; + } + else + break; // FIFO full + }while(i32Tail != i32Head); +} +#endif + +/** + * @brief Routine to send a char + * + * @param[in] ch Character to send to debug port. + * + * @returns Send value from UART debug port or semihost + * + * @details Send a target char to UART debug port or semihost. + */ +void SendChar(int ch) +{ +#if defined(DEBUG_ENABLE_SEMIHOST) + g_buf[g_buf_len++] = ch; + g_buf[g_buf_len] = '\0'; + if(g_buf_len + 1 >= sizeof(g_buf) || ch == '\n' || ch == '\0') + { + /* Send the char */ + if(SH_DoCommand(0x04, (int)g_buf, NULL) != 0) + { + g_buf_len = 0; + return; + } + else + { + g_buf_len = 0; + } + } +#else + SendChar_ToUART(ch); +#endif +} + +/** + * @brief Routine to get a char + * + * @param None + * + * @returns Get value from UART debug port or semihost + * + * @details Wait UART debug port or semihost to input a char. + */ +char GetChar(void) +{ +#ifdef DEBUG_ENABLE_SEMIHOST +# if defined (__CC_ARM) + int nRet; + while(SH_DoCommand(0x101, 0, &nRet) != 0) + { + if(nRet != 0) + { + SH_DoCommand(0x07, 0, &nRet); + return (char)nRet; + } + } +# else + int nRet; + while(SH_DoCommand(0x7, 0, &nRet) != 0) + { + if(nRet != 0) + return (char)nRet; + } +# endif + return (0); +#else + + while(1) + { + if((DEBUG_PORT->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) == 0) + { + return (DEBUG_PORT->DAT); + } + } + +#endif +} + +/** + * @brief Check any char input from UART + * + * @param None + * + * @retval 1: No any char input + * @retval 0: Have some char input + * + * @details Check UART RSR RX EMPTY or not to determine if any char input from UART + */ + +int kbhit(void) +{ + return !((DEBUG_PORT->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) == 0); +} +/** + * @brief Check if debug message finished + * + * @param None + * + * @retval 1: Message is finished + * @retval 0: Message is transmitting. + * + * @details Check if message finished (FIFO empty of debug port) + */ + +int IsDebugFifoEmpty(void) +{ + return ((DEBUG_PORT->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk) != 0); +} + +/** + * @brief C library retargetting + * + * @param[in] ch Character to send to debug port. + * + * @returns None + * + * @details Check if message finished (FIFO empty of debug port) + */ + +void _ttywrch(int ch) +{ + SendChar(ch); + return; +} + + +/** + * @brief Write character to stream + * + * @param[in] ch Character to be written. The character is passed as its int promotion. + * @param[in] stream Pointer to a FILE object that identifies the stream where the character is to be written. + * + * @returns If there are no errors, the same character that has been written is returned. + * If an error occurs, EOF is returned and the error indicator is set (see ferror). + * + * @details Writes a character to the stream and advances the position indicator.\n + * The character is written at the current position of the stream as indicated \n + * by the internal position indicator, which is then advanced one character. + * + * @note The above descriptions are copied from http://www.cplusplus.com/reference/clibrary/cstdio/fputc/. + * + * + */ + +int fputc(int ch, FILE *stream) +{ + SendChar(ch); + return ch; +} + + +/** + * @brief Get character from UART debug port or semihosting input + * + * @param[in] stream Pointer to a FILE object that identifies the stream on which the operation is to be performed. + * + * @returns The character read from UART debug port or semihosting + * + * @details For get message from debug port or semihosting. + * + */ + +int fgetc(FILE *stream) +{ + return (GetChar()); +} + +/** + * @brief Check error indicator + * + * @param[in] stream Pointer to a FILE object that identifies the stream. + * + * @returns If the error indicator associated with the stream was set, the function returns a nonzero value. + * Otherwise, it returns a zero value. + * + * @details Checks if the error indicator associated with stream is set, returning a value different + * from zero if it is. This indicator is generally set by a previous operation on the stream that failed. + * + * @note The above descriptions are copied from http://www.cplusplus.com/reference/clibrary/cstdio/ferror/. + * + */ + +int ferror(FILE *stream) +{ + return EOF; +} + +#ifdef DEBUG_ENABLE_SEMIHOST +# ifdef __ICCARM__ +void __exit(int return_code) +{ + + /* Check if link with ICE */ + if(SH_DoCommand(0x18, 0x20026, NULL) == 0) + { + /* Make sure all message is print out */ + while(IsDebugFifoEmpty() == 0); + } +label: + goto label; /* endless loop */ +} +# else +void _sys_exit(int return_code) +{ + + /* Check if link with ICE */ + if(SH_DoCommand(0x18, 0x20026, NULL) == 0) + { + /* Make sure all message is print out */ + while(IsDebugFifoEmpty() == 0); + } +label: + goto label; /* endless loop */ +} +# endif +#endif diff --git a/StdDriver/src/rtc.c b/StdDriver/src/rtc.c new file mode 100644 index 0000000..3489e4e --- /dev/null +++ b/StdDriver/src/rtc.c @@ -0,0 +1,789 @@ +/**************************************************************************//** + * @file rtc.c + * @version V3.00 + * $Revision: 7 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series RTC driver source file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + + +/// @cond HIDDEN_SYMBOLS + +/*---------------------------------------------------------------------------------------------------------*/ +/* Macro, type and constant definitions */ +/*---------------------------------------------------------------------------------------------------------*/ +#define RTC_GLOBALS + +/*---------------------------------------------------------------------------------------------------------*/ +/* Global file scope (static) variables */ +/*---------------------------------------------------------------------------------------------------------*/ +static volatile uint32_t g_u32hiYear, g_u32loYear, g_u32hiMonth, g_u32loMonth, g_u32hiDay, g_u32loDay; +static volatile uint32_t g_u32hiHour, g_u32loHour, g_u32hiMin, g_u32loMin, g_u32hiSec, g_u32loSec; + +/// @endcond HIDDEN_SYMBOLS + + + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup RTC_Driver RTC Driver + @{ +*/ + +/** @addtogroup RTC_EXPORTED_FUNCTIONS RTC Exported Functions + @{ +*/ + +/** + * @brief Initialize RTC module and start counting + * + * @param[in] sPt Specify the time property and current date and time. It includes: \n + * u32Year: Year value, range between 2000 ~ 2099. \n + * u32Month: Month value, range between 1 ~ 12. \n + * u32Day: Day value, range between 1 ~ 31. \n + * u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY / + * RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY / + * RTC_SATURDAY] \n + * u32Hour: Hour value, range between 0 ~ 23. \n + * u32Minute: Minute value, range between 0 ~ 59. \n + * u32Second: Second value, range between 0 ~ 59. \n + * u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n + * u8AmPm: [RTC_AM / RTC_PM] \n + * + * @return None + * + * @details This function is used to: \n + * 1. Write initial key to let RTC start count. \n + * 2. Input parameter indicates start date/time. \n + * 3. User has to make sure that parameters of RTC date/time are reasonable. \n + * @note Null pointer for using default starting date/time. + */ +void RTC_Open(S_RTC_TIME_DATA_T *sPt) +{ + RTC->INIT = RTC_INIT_KEY; + + if(RTC->INIT != RTC_INIT_ACTIVE_Msk) + { + RTC->INIT = RTC_INIT_KEY; + while(RTC->INIT != RTC_INIT_ACTIVE_Msk); + } + + if(sPt == 0) + return ; + + /* Set RTC date and time */ + RTC_SetDateAndTime(sPt); + + /* Waiting for RTC settings stable */ + while((RTC->RWEN & RTC_RWEN_RWENF_Msk) == RTC_RWEN_RWENF_Msk); +} + +/** + * @brief Disable RTC Clock + * + * @param None + * + * @return None + * + * @details This API will disable RTC peripheral clock and stops RTC counting. + */ +void RTC_Close(void) +{ + CLK->APBCLK0 &= ~CLK_APBCLK0_RTCCKEN_Msk; +} + +/** + * @brief Set 32k Frequency Compensation Data + * + * @param[in] i32FrequencyX100 Specify the RTC clock X100, ex: 3277365 means 32773.65. + * + * @return None + * + * @details This API is used to compensate the 32 kHz frequency by current LXT frequency for RTC application. + */ +void RTC_32KCalibration(int32_t i32FrequencyX100) +{ + int32_t i32RegInt, i32RegFra; + + /* Compute integer and fraction for RTC FCR register */ + i32RegInt = (i32FrequencyX100 / 100) - RTC_FCR_REFERENCE; + i32RegFra = (((i32FrequencyX100 % 100)) * 60) / 100; + + /* Judge Integer part is reasonable */ + if((i32RegInt < 0) | (i32RegInt > 15)) + { + return ; + } + + RTC_WaitAccessEnable(); + RTC->FREQADJ = (uint32_t)((i32RegInt << 8) | i32RegFra); +} + +/** + * @brief Get Current RTC Date and Time + * + * @param[out] sPt The returned pointer is specified the current RTC value. It includes: \n + * u32Year: Year value \n + * u32Month: Month value \n + * u32Day: Day value \n + * u32DayOfWeek: Day of week \n + * u32Hour: Hour value \n + * u32Minute: Minute value \n + * u32Second: Second value \n + * u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n + * u8AmPm: [RTC_AM / RTC_PM] \n + * + * @return None + * + * @details This API is used to get the current RTC date and time value. + */ +void RTC_GetDateAndTime(S_RTC_TIME_DATA_T *sPt) +{ + uint32_t u32Tmp; + + sPt->u32TimeScale = RTC->CLKFMT & RTC_CLKFMT_24HEN_Msk; /* 12/24-hour */ + sPt->u32DayOfWeek = RTC->WEEKDAY & RTC_WEEKDAY_WEEKDAY_Msk; /* Day of the week */ + + /* Get [Date digit] data */ + g_u32hiYear = (RTC->CAL & RTC_CAL_TENYEAR_Msk) >> RTC_CAL_TENYEAR_Pos; + g_u32loYear = (RTC->CAL & RTC_CAL_YEAR_Msk) >> RTC_CAL_YEAR_Pos; + g_u32hiMonth = (RTC->CAL & RTC_CAL_TENMON_Msk) >> RTC_CAL_TENMON_Pos; + g_u32loMonth = (RTC->CAL & RTC_CAL_MON_Msk) >> RTC_CAL_MON_Pos; + g_u32hiDay = (RTC->CAL & RTC_CAL_TENDAY_Msk) >> RTC_CAL_TENDAY_Pos; + g_u32loDay = (RTC->CAL & RTC_CAL_DAY_Msk) >> RTC_CAL_DAY_Pos; + + /* Get [Time digit] data */ + g_u32hiHour = (RTC->TIME & RTC_TIME_TENHR_Msk) >> RTC_TIME_TENHR_Pos; + g_u32loHour = (RTC->TIME & RTC_TIME_HR_Msk) >> RTC_TIME_HR_Pos; + g_u32hiMin = (RTC->TIME & RTC_TIME_TENMIN_Msk) >> RTC_TIME_TENMIN_Pos; + g_u32loMin = (RTC->TIME & RTC_TIME_MIN_Msk) >> RTC_TIME_MIN_Pos; + g_u32hiSec = (RTC->TIME & RTC_TIME_TENSEC_Msk) >> RTC_TIME_TENSEC_Pos; + g_u32loSec = (RTC->TIME & RTC_TIME_SEC_Msk) >> RTC_TIME_SEC_Pos; + + /* Compute to 20XX year */ + u32Tmp = (g_u32hiYear * 10); + u32Tmp += g_u32loYear; + sPt->u32Year = u32Tmp + RTC_YEAR2000; + + /* Compute 0~12 month */ + u32Tmp = (g_u32hiMonth * 10); + sPt->u32Month = u32Tmp + g_u32loMonth; + + /* Compute 0~31 day */ + u32Tmp = (g_u32hiDay * 10); + sPt->u32Day = u32Tmp + g_u32loDay; + + /* Compute 12/24 hour */ + if(sPt->u32TimeScale == RTC_CLOCK_12) + { + u32Tmp = (g_u32hiHour * 10); + u32Tmp += g_u32loHour; + sPt->u32Hour = u32Tmp; /* AM: 1~12. PM: 21~32. */ + + if(sPt->u32Hour >= 21) + { + sPt->u32AmPm = RTC_PM; + sPt->u32Hour -= 20; + } + else + { + sPt->u32AmPm = RTC_AM; + } + + u32Tmp = (g_u32hiMin * 10); + u32Tmp += g_u32loMin; + sPt->u32Minute = u32Tmp; + + u32Tmp = (g_u32hiSec * 10); + u32Tmp += g_u32loSec; + sPt->u32Second = u32Tmp; + } + else + { + u32Tmp = (g_u32hiHour * 10); + u32Tmp += g_u32loHour; + sPt->u32Hour = u32Tmp; + + u32Tmp = (g_u32hiMin * 10); + u32Tmp += g_u32loMin; + sPt->u32Minute = u32Tmp; + + u32Tmp = (g_u32hiSec * 10); + u32Tmp += g_u32loSec; + sPt->u32Second = u32Tmp; + } +} + +/** + * @brief Get RTC Alarm Date and Time + * + * @param[out] sPt The returned pointer is specified the RTC alarm value. It includes: \n + * u32Year: Year value \n + * u32Month: Month value \n + * u32Day: Day value \n + * u32DayOfWeek: Day of week \n + * u32Hour: Hour value \n + * u32Minute: Minute value \n + * u32Second: Second value \n + * u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n + * u8AmPm: [RTC_AM / RTC_PM] \n + * + * @return None + * + * @details This API is used to get the RTC alarm date and time setting. + */ +void RTC_GetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt) +{ + uint32_t u32Tmp; + + sPt->u32TimeScale = RTC->CLKFMT & RTC_CLKFMT_24HEN_Msk; /* 12/24-hour */ + sPt->u32DayOfWeek = RTC->WEEKDAY & RTC_WEEKDAY_WEEKDAY_Msk; /* Day of the week */ + + /* Get alarm [Date digit] data */ + RTC_WaitAccessEnable(); + g_u32hiYear = (RTC->CALM & RTC_CALM_TENYEAR_Msk) >> RTC_CALM_TENYEAR_Pos; + g_u32loYear = (RTC->CALM & RTC_CALM_YEAR_Msk) >> RTC_CALM_YEAR_Pos; + g_u32hiMonth = (RTC->CALM & RTC_CALM_TENMON_Msk) >> RTC_CALM_TENMON_Pos; + g_u32loMonth = (RTC->CALM & RTC_CALM_MON_Msk) >> RTC_CALM_MON_Pos; + g_u32hiDay = (RTC->CALM & RTC_CALM_TENDAY_Msk) >> RTC_CALM_TENDAY_Pos; + g_u32loDay = (RTC->CALM & RTC_CALM_DAY_Msk) >> RTC_CALM_DAY_Pos; + + /* Get alarm [Time digit] data */ + RTC_WaitAccessEnable(); + g_u32hiHour = (RTC->TALM & RTC_TALM_TENHR_Msk) >> RTC_TALM_TENHR_Pos; + g_u32loHour = (RTC->TALM & RTC_TALM_HR_Msk) >> RTC_TALM_HR_Pos; + g_u32hiMin = (RTC->TALM & RTC_TALM_TENMIN_Msk) >> RTC_TALM_TENMIN_Pos; + g_u32loMin = (RTC->TALM & RTC_TALM_MIN_Msk) >> RTC_TALM_MIN_Pos; + g_u32hiSec = (RTC->TALM & RTC_TALM_TENSEC_Msk) >> RTC_TALM_TENSEC_Pos; + g_u32loSec = (RTC->TALM & RTC_TALM_SEC_Msk) >> RTC_TALM_SEC_Pos; + + /* Compute to 20XX year */ + u32Tmp = (g_u32hiYear * 10); + u32Tmp += g_u32loYear; + sPt->u32Year = u32Tmp + RTC_YEAR2000; + + /* Compute 0~12 month */ + u32Tmp = (g_u32hiMonth * 10); + sPt->u32Month = u32Tmp + g_u32loMonth; + + /* Compute 0~31 day */ + u32Tmp = (g_u32hiDay * 10); + sPt->u32Day = u32Tmp + g_u32loDay; + + /* Compute 12/24 hour */ + if(sPt->u32TimeScale == RTC_CLOCK_12) + { + u32Tmp = (g_u32hiHour * 10); + u32Tmp += g_u32loHour; + sPt->u32Hour = u32Tmp; /* AM: 1~12. PM: 21~32. */ + + if(sPt->u32Hour >= 21) + { + sPt->u32AmPm = RTC_PM; + sPt->u32Hour -= 20; + } + else + { + sPt->u32AmPm = RTC_AM; + } + + u32Tmp = (g_u32hiMin * 10); + u32Tmp += g_u32loMin; + sPt->u32Minute = u32Tmp; + + u32Tmp = (g_u32hiSec * 10); + u32Tmp += g_u32loSec; + sPt->u32Second = u32Tmp; + + } + else + { + u32Tmp = (g_u32hiHour * 10); + u32Tmp += g_u32loHour; + sPt->u32Hour = u32Tmp; + + u32Tmp = (g_u32hiMin * 10); + u32Tmp += g_u32loMin; + sPt->u32Minute = u32Tmp; + + u32Tmp = (g_u32hiSec * 10); + u32Tmp += g_u32loSec; + sPt->u32Second = u32Tmp; + } +} + +/** + * @brief Update Current RTC Date and Time + * + * @param[in] sPt Specify the time property and current date and time. It includes: \n + * u32Year: Year value, range between 2000 ~ 2099. \n + * u32Month: Month value, range between 1 ~ 12. \n + * u32Day: Day value, range between 1 ~ 31. \n + * u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY / + * RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY / + * RTC_SATURDAY] \n + * u32Hour: Hour value, range between 0 ~ 23. \n + * u32Minute: Minute value, range between 0 ~ 59. \n + * u32Second: Second value, range between 0 ~ 59. \n + * u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n + * u8AmPm: [RTC_AM / RTC_PM] \n + * + * @return None + * + * @details This API is used to update current date and time to RTC. + */ +void RTC_SetDateAndTime(S_RTC_TIME_DATA_T *sPt) +{ + uint32_t u32RegCAL, u32RegTIME; + + if(sPt == 0) + return ; + + /*-----------------------------------------------------------------------------------------------------*/ + /* Set RTC 24/12 hour setting and Day of the Week */ + /*-----------------------------------------------------------------------------------------------------*/ + RTC_WaitAccessEnable(); + if(sPt->u32TimeScale == RTC_CLOCK_12) + { + RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk; + + /*-------------------------------------------------------------------------------------------------*/ + /* Important, range of 12-hour PM mode is 21 up to 32 */ + /*-------------------------------------------------------------------------------------------------*/ + if(sPt->u32AmPm == RTC_PM) + sPt->u32Hour += 20; + } + else + { + RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk; + } + + /* Set Day of the Week */ + RTC->WEEKDAY = sPt->u32DayOfWeek; + + /*-----------------------------------------------------------------------------------------------------*/ + /* Set RTC Current Date and Time */ + /*-----------------------------------------------------------------------------------------------------*/ + u32RegCAL = ((sPt->u32Year - RTC_YEAR2000) / 10) << 20; + u32RegCAL |= (((sPt->u32Year - RTC_YEAR2000) % 10) << 16); + u32RegCAL |= ((sPt->u32Month / 10) << 12); + u32RegCAL |= ((sPt->u32Month % 10) << 8); + u32RegCAL |= ((sPt->u32Day / 10) << 4); + u32RegCAL |= (sPt->u32Day % 10); + + u32RegTIME = ((sPt->u32Hour / 10) << 20); + u32RegTIME |= ((sPt->u32Hour % 10) << 16); + u32RegTIME |= ((sPt->u32Minute / 10) << 12); + u32RegTIME |= ((sPt->u32Minute % 10) << 8); + u32RegTIME |= ((sPt->u32Second / 10) << 4); + u32RegTIME |= (sPt->u32Second % 10); + + /*-----------------------------------------------------------------------------------------------------*/ + /* Set RTC Calender and Time Loading */ + /*-----------------------------------------------------------------------------------------------------*/ + RTC_WaitAccessEnable(); + RTC->CAL = (uint32_t)u32RegCAL; + RTC->TIME = (uint32_t)u32RegTIME; +} + +/** + * @brief Update RTC Alarm Date and Time + * + * @param[in] sPt Specify the time property and alarm date and time. It includes: \n + * u32Year: Year value, range between 2000 ~ 2099. \n + * u32Month: Month value, range between 1 ~ 12. \n + * u32Day: Day value, range between 1 ~ 31. \n + * u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY / + * RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY / + * RTC_SATURDAY] \n + * u32Hour: Hour value, range between 0 ~ 23. \n + * u32Minute: Minute value, range between 0 ~ 59. \n + * u32Second: Second value, range between 0 ~ 59. \n + * u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24] \n + * u8AmPm: [RTC_AM / RTC_PM] \n + * + * @return None + * + * @details This API is used to update alarm date and time setting to RTC. + */ +void RTC_SetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt) +{ + uint32_t u32RegCALM, u32RegTALM; + + if(sPt == 0) + return ; + + /*-----------------------------------------------------------------------------------------------------*/ + /* Set RTC 24/12 hour setting and Day of the Week */ + /*-----------------------------------------------------------------------------------------------------*/ + RTC_WaitAccessEnable(); + if(sPt->u32TimeScale == RTC_CLOCK_12) + { + RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk; + + /*-------------------------------------------------------------------------------------------------*/ + /* Important, range of 12-hour PM mode is 21 up to 32 */ + /*-------------------------------------------------------------------------------------------------*/ + if(sPt->u32AmPm == RTC_PM) + sPt->u32Hour += 20; + } + else + { + RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk; + } + + /* Set Day of the Week */ + RTC->WEEKDAY = sPt->u32DayOfWeek; + + /*-----------------------------------------------------------------------------------------------------*/ + /* Set RTC Alarm Date and Time */ + /*-----------------------------------------------------------------------------------------------------*/ + u32RegCALM = ((sPt->u32Year - RTC_YEAR2000) / 10) << 20; + u32RegCALM |= (((sPt->u32Year - RTC_YEAR2000) % 10) << 16); + u32RegCALM |= ((sPt->u32Month / 10) << 12); + u32RegCALM |= ((sPt->u32Month % 10) << 8); + u32RegCALM |= ((sPt->u32Day / 10) << 4); + u32RegCALM |= (sPt->u32Day % 10); + + u32RegTALM = ((sPt->u32Hour / 10) << 20); + u32RegTALM |= ((sPt->u32Hour % 10) << 16); + u32RegTALM |= ((sPt->u32Minute / 10) << 12); + u32RegTALM |= ((sPt->u32Minute % 10) << 8); + u32RegTALM |= ((sPt->u32Second / 10) << 4); + u32RegTALM |= (sPt->u32Second % 10); + + RTC_WaitAccessEnable(); + RTC->CALM = (uint32_t)u32RegCALM; + RTC->TALM = (uint32_t)u32RegTALM; +} + +/** + * @brief Update RTC Current Date + * + * @param[in] u32Year The year calendar digit of current RTC setting. + * @param[in] u32Month The month calendar digit of current RTC setting. + * @param[in] u32Day The day calendar digit of current RTC setting. + * @param[in] u32DayOfWeek The Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY / + * RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY / + * RTC_SATURDAY] + * + * @return None + * + * @details This API is used to update current date to RTC. + */ +void RTC_SetDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day, uint32_t u32DayOfWeek) +{ + uint32_t u32RegCAL; + + u32RegCAL = ((u32Year - RTC_YEAR2000) / 10) << 20; + u32RegCAL |= (((u32Year - RTC_YEAR2000) % 10) << 16); + u32RegCAL |= ((u32Month / 10) << 12); + u32RegCAL |= ((u32Month % 10) << 8); + u32RegCAL |= ((u32Day / 10) << 4); + u32RegCAL |= (u32Day % 10); + + RTC_WaitAccessEnable(); + + /* Set Day of the Week */ + RTC->WEEKDAY = u32DayOfWeek & RTC_WEEKDAY_WEEKDAY_Msk; + + /* Set RTC Calender Loading */ + RTC->CAL = (uint32_t)u32RegCAL; +} + +/** + * @brief Update RTC Current Time + * + * @param[in] u32Hour The hour time digit of current RTC setting. + * @param[in] u32Minute The minute time digit of current RTC setting. + * @param[in] u32Second The second time digit of current RTC setting. + * @param[in] u32TimeMode The 24-Hour / 12-Hour Time Scale Selection. [RTC_CLOCK_12 / RTC_CLOCK_24] + * @param[in] u32AmPm 12-hour time scale with AM and PM indication. Only Time Scale select 12-hour used. [RTC_AM / RTC_PM] + * + * @return None + * + * @details This API is used to update current time to RTC. + */ +void RTC_SetTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm) +{ + uint32_t u32RegTIME; + + /* Important, range of 12-hour PM mode is 21 up to 32 */ + if((u32TimeMode == RTC_CLOCK_12) && (u32AmPm == RTC_PM)) + u32Hour += 20; + + u32RegTIME = ((u32Hour / 10) << 20); + u32RegTIME |= ((u32Hour % 10) << 16); + u32RegTIME |= ((u32Minute / 10) << 12); + u32RegTIME |= ((u32Minute % 10) << 8); + u32RegTIME |= ((u32Second / 10) << 4); + u32RegTIME |= (u32Second % 10); + + /*-----------------------------------------------------------------------------------------------------*/ + /* Set RTC 24/12 hour setting and Day of the Week */ + /*-----------------------------------------------------------------------------------------------------*/ + RTC_WaitAccessEnable(); + if(u32TimeMode == RTC_CLOCK_12) + { + RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk; + } + else + { + RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk; + } + + RTC->TIME = (uint32_t)u32RegTIME; +} + +/** + * @brief Update RTC Alarm Date + * + * @param[in] u32Year The year calendar digit of RTC alarm setting. + * @param[in] u32Month The month calendar digit of RTC alarm setting. + * @param[in] u32Day The day calendar digit of RTC alarm setting. + * + * @return None + * + * @details This API is used to update alarm date setting to RTC. + */ +void RTC_SetAlarmDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day) +{ + uint32_t u32RegCALM; + + u32RegCALM = ((u32Year - RTC_YEAR2000) / 10) << 20; + u32RegCALM |= (((u32Year - RTC_YEAR2000) % 10) << 16); + u32RegCALM |= ((u32Month / 10) << 12); + u32RegCALM |= ((u32Month % 10) << 8); + u32RegCALM |= ((u32Day / 10) << 4); + u32RegCALM |= (u32Day % 10); + + RTC_WaitAccessEnable(); + + /* Set RTC Alarm Date */ + RTC->CALM = (uint32_t)u32RegCALM; +} + +/** + * @brief Update RTC Alarm Time + * + * @param[in] u32Hour The hour time digit of RTC alarm setting. + * @param[in] u32Minute The minute time digit of RTC alarm setting. + * @param[in] u32Second The second time digit of RTC alarm setting. + * @param[in] u32TimeMode The 24-Hour / 12-Hour Time Scale Selection. [RTC_CLOCK_12 / RTC_CLOCK_24] + * @param[in] u32AmPm 12-hour time scale with AM and PM indication. Only Time Scale select 12-hour used. [RTC_AM / RTC_PM] + * + * @return None + * + * @details This API is used to update alarm time setting to RTC. + */ +void RTC_SetAlarmTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm) +{ + uint32_t u32RegTALM; + + /* Important, range of 12-hour PM mode is 21 up to 32 */ + if((u32TimeMode == RTC_CLOCK_12) && (u32AmPm == RTC_PM)) + u32Hour += 20; + + u32RegTALM = ((u32Hour / 10) << 20); + u32RegTALM |= ((u32Hour % 10) << 16); + u32RegTALM |= ((u32Minute / 10) << 12); + u32RegTALM |= ((u32Minute % 10) << 8); + u32RegTALM |= ((u32Second / 10) << 4); + u32RegTALM |= (u32Second % 10); + + /*-----------------------------------------------------------------------------------------------------*/ + /* Set RTC 24/12 hour setting and Day of the Week */ + /*-----------------------------------------------------------------------------------------------------*/ + RTC_WaitAccessEnable(); + if(u32TimeMode == RTC_CLOCK_12) + { + RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk; + } + else + { + RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk; + } + + /* Set RTC Alarm Time */ + RTC->TALM = (uint32_t)u32RegTALM; +} + +/** + * @brief Get Day of the Week + * + * @param None + * + * @retval 0 Sunday + * @retval 1 Monday + * @retval 2 Tuesday + * @retval 3 Wednesday + * @retval 4 Thursday + * @retval 5 Friday + * @retval 6 Saturday + * + * @details This API is used to get day of the week of current RTC date. + */ +uint32_t RTC_GetDayOfWeek(void) +{ + return (RTC->WEEKDAY & RTC_WEEKDAY_WEEKDAY_Msk); +} + +/** + * @brief Set RTC Tick Period Time + * + * @param[in] u32TickSelection It is used to set the RTC tick period time for Periodic Time Tick request. \n + * It consists of: \n + * RTC_TICK_1_SEC: Time tick is 1 second \n + * RTC_TICK_1_2_SEC: Time tick is 1/2 second \n + * RTC_TICK_1_4_SEC: Time tick is 1/4 second \n + * RTC_TICK_1_8_SEC: Time tick is 1/8 second \n + * RTC_TICK_1_16_SEC: Time tick is 1/16 second \n + * RTC_TICK_1_32_SEC: Time tick is 1/32 second \n + * RTC_TICK_1_64_SEC: Time tick is 1/64 second \n + * RTC_TICK_1_128_SEC: Time tick is 1/128 second + * + * @return None + * + * @details This API is used to set RTC tick period time for each tick interrupt. + */ +void RTC_SetTickPeriod(uint32_t u32TickSelection) +{ + RTC_WaitAccessEnable(); + + RTC->TICK = (RTC->TICK & ~RTC_TICK_TICK_Msk) | u32TickSelection; +} + +/** + * @brief Enable RTC Interrupt + * + * @param[in] u32IntFlagMask Specify the interrupt source. It consists of: \n + * RTC_INTEN_ALMIEN_Msk: Alarm interrupt \n + * RTC_INTEN_TICKIEN_Msk: Tick interrupt \n + * RTC_INTEN_SNPDIEN_Msk: Snooper Pin Event Detection interrupt \n + * + * @return None + * + * @details This API is used to enable the specify RTC interrupt function. + */ +void RTC_EnableInt(uint32_t u32IntFlagMask) +{ + RTC->INTEN |= u32IntFlagMask; +} + +/** + * @brief Disable RTC Interrupt + * + * @param[in] u32IntFlagMask Specify the interrupt source. It consists of: \n + * RTC_INTEN_ALMIEN_Msk: Alarm interrupt \n + * RTC_INTEN_TICKIEN_Msk: Tick interrupt \n + * RTC_INTEN_SNPDIEN_Msk: Snooper Pin Event Detection interrupt \n + * + * @return None + * + * @details This API is used to disable the specify RTC interrupt function. + */ +void RTC_DisableInt(uint32_t u32IntFlagMask) +{ + if(u32IntFlagMask & RTC_INTEN_ALMIEN_Msk) + { + RTC->INTEN &= ~RTC_INTEN_ALMIEN_Msk; + RTC->INTSTS = RTC_INTSTS_ALMIF_Msk; + } + + if(u32IntFlagMask & RTC_INTEN_TICKIEN_Msk) + { + RTC->INTEN &= ~RTC_INTEN_TICKIEN_Msk; + RTC->INTSTS = RTC_INTSTS_TICKIF_Msk; + } + + if(u32IntFlagMask & RTC_INTEN_SNPDIEN_Msk) + { + RTC->INTEN &= ~RTC_INTEN_SNPDIEN_Msk; + RTC->INTSTS = RTC_INTSTS_SNPDIF_Msk; + } +} + +/** + * @brief Enable Spare Registers Access + * + * @param None + * + * @return None + * + * @details This API is used to enable the spare registers 0~19 can be accessed. + */ +void RTC_EnableSpareAccess(void) +{ + RTC_WaitAccessEnable(); + + RTC->SPRCTL |= RTC_SPRCTL_SPRRWEN_Msk; + + while(!(RTC->SPRCTL & RTC_SPRCTL_SPRRWRDY_Msk)); +} + +/** + * @brief Disable Spare Register + * + * @param None + * + * @return None + * + * @details This API is used to disable the spare register 0~19 cannot be accessed. + */ +void RTC_DisableSpareRegister(void) +{ + RTC_WaitAccessEnable(); + + RTC->SPRCTL &= ~RTC_SPRCTL_SPRRWEN_Msk; +} + +/** + * @brief Enable Snooper Pin Detect + * + * @param[in] u32PinCondition Snooper pin trigger condition. Possible options are + * - \ref RTC_SNOOPER_LOW_LEVEL + * - \ref RTC_SNOOPER_HIGH_LEVEL + * - \ref RTC_SNOOPER_FALLING_EDGE + * - \ref RTC_SNOOPER_RISING_EDGE + * + * @return None + * + * @details This API is used to enable the snooper pin detect function with specify trigger condition. + */ +void RTC_EnableSnooperDetection(uint32_t u32PinCondition) +{ + RTC_WaitAccessEnable(); + + RTC->SPRCTL = ((RTC->SPRCTL & ~RTC_SNOOPER_DETECT_Msk) | u32PinCondition) | RTC_SPRCTL_SNPDEN_Msk; +} + +/** + * @brief Disable Snooper Pin Detect + * + * @param None + * + * @return None + * + * @details This API is used to disable the snooper pin detect function. + */ +void RTC_DisableSnooperDetection(void) +{ + RTC_WaitAccessEnable(); + + RTC->SPRCTL &= ~RTC_SPRCTL_SNPDEN_Msk; +} + +/*@}*/ /* end of group RTC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group RTC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/sc.c b/StdDriver/src/sc.c new file mode 100644 index 0000000..85aa2bb --- /dev/null +++ b/StdDriver/src/sc.c @@ -0,0 +1,299 @@ +/**************************************************************************//** + * @file sc.c + * @version V3.00 + * $Revision: 9 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series Smartcard(SC) driver source file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.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}; + +/// @endcond HIDDEN_SYMBOLS + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup SC_Driver SC Driver + @{ +*/ + + +/** @addtogroup SC_EXPORTED_FUNCTIONS SC Exported Functions + @{ +*/ + +/** + * @brief This function indicates specified smartcard slot status. + * @param[in] sc The pointer of smartcard module. + * @retval TRUE Card insert. + * @retval FALSE Card remove. + * @details This function is used to check if specified smart card slot is presented. + */ +uint32_t SC_IsCardInserted(SC_T *sc) +{ + // put conditions into two variable to remove IAR compilation warning + uint32_t cond1 = ((sc->STATUS & SC_STATUS_CDPINSTS_Msk) >> SC_STATUS_CDPINSTS_Pos); + uint32_t cond2 = ((sc->CTL & SC_CTL_CDLV_Msk) >> SC_CTL_CDLV_Pos); + + if(sc == SC0 && u32CardStateIgnore[0] == 1) + return TRUE; +#if 0 /* M451 series has only one SC interface */ + else if(sc == SC1 && u32CardStateIgnore[1] == 1) + return TRUE; + else if(sc == SC2 && u32CardStateIgnore[2] == 1) + return TRUE; + else if(sc == SC3 && u32CardStateIgnore[3] == 1) + return TRUE; + else if(sc == SC4 && u32CardStateIgnore[4] == 1) + return TRUE; + else if(sc == SC5 && u32CardStateIgnore[5] == 1) + return TRUE; +#endif + else if(cond1 != cond2) + return FALSE; + else + return TRUE; +} + +/** + * @brief Reset the Tx/Rx FIFO. + * @param[in] sc The pointer of smartcard module. + * @return None + * @details This function reset both transmit and receive FIFO of specified smartcard module. + */ +void SC_ClearFIFO(SC_T *sc) +{ + sc->ALTCTL |= (SC_ALTCTL_TXRST_Msk | SC_ALTCTL_RXRST_Msk); +} + +/** + * @brief This function disable specified smartcard module. + * @param[in] sc The pointer of smartcard module. + * @return None + * @details SC will force all transition to IDLE state. + */ +void SC_Close(SC_T *sc) +{ + sc->INTEN = 0; + sc->PINCTL = 0; + sc->ALTCTL = 0; + sc->CTL = 0; +} + +/** + * @brief This function initialized smartcard module. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32CD Card detect polarity, select the CD pin state which indicates card insert. Could be: + * -\ref SC_PIN_STATE_HIGH. + * -\ref SC_PIN_STATE_LOW. + * -\ref SC_PIN_STATE_IGNORE, no card detect pin, always assumes card present. + * @param[in] u32PWR Power on polarity, select the PWR pin state which could set smartcard VCC to high level. Could be: + * -\ref SC_PIN_STATE_HIGH. + * -\ref SC_PIN_STATE_LOW. + * @return None + * @details Initialization process configures smartcard and enables engine clock. + */ +void SC_Open(SC_T *sc, uint32_t u32CD, uint32_t u32PWR) +{ + uint32_t u32Reg = 0, u32Intf; + + if(sc == SC0) + u32Intf = 0; +#if 0 /* M451 series has only one SC interface */ + else if(sc == SC1) + u32Intf = 1; + else if(sc == SC2) + u32Intf = 2; + else if(sc == SC3) + u32Intf = 3; + else if(sc == SC4) + u32Intf = 4; + else if(sc == SC5) + u32Intf = 5; +#endif + else + return ; + + if(u32CD != SC_PIN_STATE_IGNORE) { + u32Reg = u32CD ? 0: SC_CTL_CDLV_Msk; + u32CardStateIgnore[u32Intf] = 0; + } else { + u32CardStateIgnore[u32Intf] = 1; + } + while(sc->PINCTL & SC_PINCTL_SYNC_Msk); + sc->PINCTL = u32PWR ? 0 : SC_PINCTL_PWRINV_Msk; + while(sc->CTL & SC_CTL_SYNC_Msk); + sc->CTL = SC_CTL_SCEN_Msk | u32Reg; +} + +/** + * @brief This function reset specified smartcard module to its default state for activate smartcard. + * @param[in] sc The pointer of smartcard module. + * @return None + * @details Reset the Tx/Rx FIFO & clock & initial default parameter. + */ +void SC_ResetReader(SC_T *sc) +{ + uint32_t u32Intf; + + if(sc == SC0) + u32Intf = 0; +#if 0 /* M451 series has only one SC interface */ + else if(sc == SC1) + u32Intf = 1; + else if(sc == SC2) + u32Intf = 2; + else if(sc == SC3) + u32Intf = 3; + else if(sc == SC4) + u32Intf = 4; + else if(sc == SC5) + u32Intf = 5; +#endif + else + return ; + + // Reset FIFO, enable auto de-activation while card removal + sc->ALTCTL |= (SC_ALTCTL_TXRST_Msk | SC_ALTCTL_RXRST_Msk | SC_ALTCTL_ADACEN_Msk); + // Set Rx trigger level to 1 character, longest card detect debounce period, disable error retry (EMV ATR does not use error retry) + while(sc->CTL & SC_CTL_SYNC_Msk); + sc->CTL &= ~(SC_CTL_RXTRGLV_Msk | SC_CTL_CDDBSEL_Msk | SC_CTL_TXRTY_Msk | SC_CTL_RXRTY_Msk); + // Enable auto convention, and all three smartcard internal timers + sc->CTL |= SC_CTL_AUTOCEN_Msk | SC_CTL_TMRSEL_Msk; + // Disable Rx timeout + sc->RXTOUT = 0; + // 372 clocks per ETU by default + sc->ETUCTL = 371; + + /* Enable necessary interrupt for smartcard operation */ + if(u32CardStateIgnore[u32Intf]) // Do not enable card detect interrupt if card present state ignore + sc->INTEN = (SC_INTEN_RDAIEN_Msk | + SC_INTEN_TERRIEN_Msk | + SC_INTEN_TMR0IEN_Msk | + SC_INTEN_TMR1IEN_Msk | + SC_INTEN_TMR2IEN_Msk | + SC_INTEN_BGTIEN_Msk | + SC_INTEN_ACERRIEN_Msk); + else + sc->INTEN = (SC_INTEN_RDAIEN_Msk | + SC_INTEN_TERRIEN_Msk | + SC_INTEN_TMR0IEN_Msk | + SC_INTEN_TMR1IEN_Msk | + SC_INTEN_TMR2IEN_Msk | + SC_INTEN_BGTIEN_Msk | + SC_INTEN_ACERRIEN_Msk | + SC_INTEN_CDIEN_Msk); + + return; +} + +/** + * @brief Set Block Guard Time. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32BGT Block guard time using ETU as unit, valid range are between 1 ~ 32. + * @return None + * @details This function block guard time (BGT) of specified smartcard module. + */ +void SC_SetBlockGuardTime(SC_T *sc, uint32_t u32BGT) +{ + sc->CTL = (sc->CTL & ~SC_CTL_BGT_Msk) | ((u32BGT - 1) << SC_CTL_BGT_Pos); +} + +/** + * @brief Set character guard time. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32CGT Character guard time using ETU as unit, valid range are between 11 ~ 267. + * @return None + * @details This function character guard time (CGT) of specified smartcard module. + * @note Before using this API, user should set the correct stop bit length first. + */ +void SC_SetCharGuardTime(SC_T *sc, uint32_t u32CGT) +{ + u32CGT -= sc->CTL & SC_CTL_NSB_Msk ? 11 : 12; + sc->EGT = u32CGT; +} + +/** + * @brief Stop all Timer counting. + * @param[in] sc The pointer of smartcard module. + * @return None + * @details This function stop all smartcard timer of specified smartcard module. + * @note This function stop the timers within smartcard module, \b not timer module. + */ +void SC_StopAllTimer(SC_T *sc) +{ + sc->ALTCTL &= ~(SC_ALTCTL_CNTEN0_Msk | SC_ALTCTL_CNTEN1_Msk | SC_ALTCTL_CNTEN2_Msk); +} + +/** + * @brief This function configure and start a smartcard timer of specified smartcard module. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32TimerNum Timer(s) to start. Valid values are 0, 1, 2. + * @param[in] u32Mode Timer operating mode, valid values are: + * - \ref SC_TMR_MODE_0 + * - \ref SC_TMR_MODE_1 + * - \ref SC_TMR_MODE_2 + * - \ref SC_TMR_MODE_3 + * - \ref SC_TMR_MODE_4 + * - \ref SC_TMR_MODE_5 + * - \ref SC_TMR_MODE_6 + * - \ref SC_TMR_MODE_7 + * - \ref SC_TMR_MODE_8 + * - \ref SC_TMR_MODE_F + * @param[in] u32ETUCount Timer timeout duration, ETU based. For timer 0, valid range are between 1~0x1000000ETUs. + * For timer 1 and timer 2, valid range are between 1 ~ 0x100 ETUs. + * @return None + * @details Enable Timer starting, counter will count when condition match. + * @note This function start the timer within smartcard module, \b not timer module. + * @note Depend on the timer operating mode, timer may not start counting immediately. + */ +void SC_StartTimer(SC_T *sc, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount) +{ + uint32_t reg = u32Mode | (SC_TMRCTL0_CNT_Msk & (u32ETUCount - 1)); + + if(u32TimerNum == 0) { + sc->TMRCTL0 = reg; + sc->ALTCTL |= SC_ALTCTL_CNTEN0_Msk; + } else if(u32TimerNum == 1) { + sc->TMRCTL1 = reg; + sc->ALTCTL |= SC_ALTCTL_CNTEN1_Msk; + } else { // timer 2 + sc->TMRCTL2 = reg; + sc->ALTCTL |= SC_ALTCTL_CNTEN2_Msk; + } +} + +/** + * @brief Stop Timer counting. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32TimerNum Timer(s) to stop. Valid values are 0, 1, 2. + * @return None + * @details This function stop a smartcard timer of specified smartcard module. + * @note This function stop the timer within smartcard module, \b not timer module. + */ +void SC_StopTimer(SC_T *sc, uint32_t u32TimerNum) +{ + if(u32TimerNum == 0) + sc->ALTCTL &= ~SC_ALTCTL_CNTEN0_Msk; + else if(u32TimerNum == 1) + sc->ALTCTL &= ~SC_ALTCTL_CNTEN1_Msk; + else // timer 2 + sc->ALTCTL &= ~SC_ALTCTL_CNTEN2_Msk; +} + + + +/*@}*/ /* end of group SC_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group SC_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/scuart.c b/StdDriver/src/scuart.c new file mode 100644 index 0000000..aca419e --- /dev/null +++ b/StdDriver/src/scuart.c @@ -0,0 +1,223 @@ +/**************************************************************************//** + * @file scuart.c + * @version V3.00 + * $Revision: 8 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series Smartcard UART mode (SCUART) driver source file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup SCUART_Driver SCUART Driver + @{ +*/ + + +/** @addtogroup SCUART_EXPORTED_FUNCTIONS SCUART Exported Functions + @{ +*/ + +/** + * @brief Disable smartcard uart interface. + * @param sc The pointer of smartcard module. + * @return None + * @details The function is used to disable smartcard interface UART mode. + */ +void SCUART_Close(SC_T* sc) +{ + sc->INTEN = 0; + sc->UARTCTL = 0; + sc->CTL = 0; + +} + +/// @cond HIDDEN_SYMBOLS +/** + * @brief This function returns module clock of specified SC interface + * @param[in] sc The pointer of smartcard module. + * @return Module clock of specified SC interface + */ +static uint32_t SCUART_GetClock(SC_T *sc) +{ + uint32_t u32ClkSrc, u32Num, u32Clk; + + if(sc == SC0) + u32Num = 0; +#if 0 /* M451 series has only one SC interface */ + else if(sc == SC1) + u32Num = 1; + else if(sc == SC2) + u32Num = 2; + else if(sc == SC3) + u32Num = 3; + else if(sc == SC4) + u32Num = 4; + else if(sc == SC5) + u32Intf = 5; +#endif + else + return FALSE; + + u32ClkSrc = (CLK->CLKSEL3 >> (2 * u32Num)) & CLK_CLKSEL3_SC0SEL_Msk; + + // Get smartcard module clock + if(u32ClkSrc == 0) + u32Clk = __HXT; + else if(u32ClkSrc == 1) + u32Clk = CLK_GetPLLClockFreq(); + else if(u32ClkSrc == 2) { + SystemCoreClockUpdate(); + if(CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) + u32Clk = SystemCoreClock / 2; + else + u32Clk = SystemCoreClock; + } else + u32Clk = __HIRC; + +#if 0 /* M451 series has only one SC interface */ + if(u32Num < 4) { + u32Clk /= (((CLK->CLKDIV1 >> (8 * u32Num)) & CLK_CLKDIV1_SC0DIV_Msk) + 1); + } else { + u32Clk /= (((CLK->CLKDIV2 >> (8 * (u32Num - 4))) & CLK_CLKDIV2_SC4DIV_Msk) + 1); + } +#else + u32Clk /= (((CLK->CLKDIV1 >> (8 * u32Num)) & CLK_CLKDIV1_SC0DIV_Msk) + 1); +#endif + + return u32Clk; +} +/// @endcond HIDDEN_SYMBOLS + +/** + * @brief Enable smartcard uart interface. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32baudrate Target baudrate of smartcard module. + * @return Actual baudrate of smartcard mode. + * @details This function use to enable smartcard module UART mode and set baudrate. + * @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_SCEN_Msk | SC_CTL_NSB_Msk; // Enable smartcard interface and stop bit = 1 + sc->UARTCTL = SCUART_CHAR_LEN_8 | SCUART_PARITY_NONE | SC_UARTCTL_UARTEN_Msk; // Enable UART mode, disable parity and 8 bit per character + sc->ETUCTL = u32Div; + + return(u32Clk / (u32Div+1)); +} + +/** + * @brief Read data from smartcard UART interface. + * @param[in] sc The pointer 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. + * @details The function is used to read Rx data from RX FIFO. + * @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 pointer of smartcard module. + * @param[in] u32Baudrate Target baudrate of smartcard module. If this value is 0, UART baudrate will not change. + * @param[in] u32DataWidth The data length, could be: + * - \ref SCUART_CHAR_LEN_5 + * - \ref SCUART_CHAR_LEN_6 + * - \ref SCUART_CHAR_LEN_7 + * - \ref SCUART_CHAR_LEN_8 + * @param[in] u32Parity The parity setting, could be: + * - \ref SCUART_PARITY_NONE + * - \ref SCUART_PARITY_ODD + * - \ref SCUART_PARITY_EVEN + * @param[in] u32StopBits The stop bit length, could be: + * - \ref SCUART_STOP_BIT_1 + * - \ref SCUART_STOP_BIT_2 + * @return Actual baudrate of smartcard. + * @details Smartcard UART mode is operated in LIN data frame. + */ +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->ETUCTL & SC_ETUCTL_ETURDIV_Msk; + } else { + // Calculate divider for target baudrate + u32Div = (u32Clk + (u32Baudrate >> 1) - 1) / u32Baudrate - 1; + sc->ETUCTL = u32Div; + } + + sc->CTL = u32StopBits | SC_CTL_SCEN_Msk; // Set stop bit + sc->UARTCTL = u32Parity | u32DataWidth | SC_UARTCTL_UARTEN_Msk; // Set character width and parity + + return(u32Clk / (u32Div+1)); +} + +/** + * @brief This function use to set receive timeout count. + * @param[in] sc The pointer of smartcard module. + * @param[in] u32TOC Rx timeout counter, using baudrate as counter unit. Valid range are 0~0x1FF, + * set this value to 0 will disable timeout counter. + * @return None + * @details The time-out counter resets and starts counting whenever the RX buffer received a + * new data word. Once the counter decrease to 1 and no new data is received or CPU + * does not read any data from FIFO, a receiver time-out interrupt will be generated. + */ +void SCUART_SetTimeoutCnt(SC_T* sc, uint32_t u32TOC) +{ + sc->RXTOUT = u32TOC; +} + + +/** + * @brief Write data to smartcard UART interface. + * @param[in] sc The pointer 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 + * @details This function is to write data into transmit FIFO to send data out. + * @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->DAT = pu8TxBuf[u32Count]; // Write 1 byte to FIFO + } +} + + +/*@}*/ /* end of group SCUART_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group SCUART_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/spi.c b/StdDriver/src/spi.c new file mode 100644 index 0000000..9e7cb10 --- /dev/null +++ b/StdDriver/src/spi.c @@ -0,0 +1,1154 @@ +/**************************************************************************//** + * @file spi.c + * @version V3.00 + * $Revision: 11 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series SPI driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup SPI_Driver SPI Driver + @{ +*/ + + +/** @addtogroup SPI_EXPORTED_FUNCTIONS SPI Exported Functions + @{ +*/ + +/** + * @brief This function make SPI module be ready to transfer. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32MasterSlave Decides the SPI module is operating in master mode or in slave mode. (SPI_SLAVE, SPI_MASTER) + * @param[in] u32SPIMode Decides the transfer timing. (SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, SPI_MODE_3) + * @param[in] u32DataWidth Decides the data width of a SPI transaction. + * @param[in] u32BusClock The expected frequency of SPI bus clock in Hz. + * @return Actual frequency of SPI peripheral clock. + * @details By default, the SPI transfer sequence is MSB first, the slave selection signal is active low and the automatic + * slave selection function is disabled. + * In Slave mode, the u32BusClock shall be NULL and the SPI clock divider setting will be 0. + * The actual clock rate may be different from the target SPI clock rate. + * For example, if the SPI source clock rate is 12MHz and the target SPI bus clock rate is 7MHz, the + * actual SPI clock rate will be 6MHz. + * @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value. + * @note If u32BusClock >= system clock frequency, SPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0. + * @note If u32BusClock >= SPI peripheral clock source, DIVIDER will be set to 0. + * @note In slave mode, the SPI peripheral clock rate will be equal to APB clock rate. + */ +uint32_t SPI_Open(SPI_T *spi, + uint32_t u32MasterSlave, + uint32_t u32SPIMode, + uint32_t u32DataWidth, + uint32_t u32BusClock) +{ + uint32_t u32ClkSrc = 0, u32Div, u32HCLKFreq; + + if((spi == SPI1) || (spi == SPI2)) + /* Disable I2S mode */ + spi->I2SCTL &= ~SPI_I2SCTL_I2SEN_Msk; + + if(u32DataWidth == 32) + u32DataWidth = 0; + + /* Get system clock frequency */ + u32HCLKFreq = CLK_GetHCLKFreq(); + + if(u32MasterSlave == SPI_MASTER) + { + /* Default setting: slave selection signal is active low; disable automatic slave selection function. */ + spi->SSCTL = SPI_SS_ACTIVE_LOW; + + /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */ + spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk; + + if(u32BusClock >= u32HCLKFreq) + { + /* Select PCLK as the clock source of SPI */ + if(spi == SPI0) + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK0; + else if(spi == SPI1) + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK1; + else + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK0; + } + + /* Check clock source of SPI */ + if(spi == SPI0) + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT) + u32ClkSrc = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL) + u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK0) + { + /* Clock source is PCLK0 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) == CLK_CLKSEL0_PCLK0SEL_HCLK_DIV2) + u32ClkSrc = (u32HCLKFreq / 2); + else + u32ClkSrc = u32HCLKFreq; + } + else + u32ClkSrc = __HIRC; /* Clock source is HIRC */ + } + else if(spi == SPI1) + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT) + u32ClkSrc = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL) + u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK1) + { + /* Clock source is PCLK1 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK1SEL_Msk) == CLK_CLKSEL0_PCLK1SEL_HCLK_DIV2) + u32ClkSrc = (u32HCLKFreq / 2); + else + u32ClkSrc = u32HCLKFreq; + } + else + u32ClkSrc = __HIRC; /* Clock source is HIRC */ + } + else + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_HXT) + u32ClkSrc = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PLL) + u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PCLK0) + { + /* Clock source is PCLK0 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) == CLK_CLKSEL0_PCLK0SEL_HCLK_DIV2) + u32ClkSrc = (u32HCLKFreq / 2); + else + u32ClkSrc = u32HCLKFreq; + } + else + u32ClkSrc = __HIRC; /* Clock source is HIRC */ + } + + if(u32BusClock >= u32HCLKFreq) + { + /* Set DIVIDER = 0 */ + spi->CLKDIV = 0; + /* Return master peripheral clock rate */ + return u32ClkSrc; + } + else if(u32BusClock >= u32ClkSrc) + { + /* Set DIVIDER = 0 */ + spi->CLKDIV = 0; + /* Return master peripheral clock rate */ + return u32ClkSrc; + } + else if(u32BusClock == 0) + { + /* Set DIVIDER to the maximum value 0xFF. f_spi = f_spi_clk_src / (DIVIDER + 1) */ + spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk; + /* Return master peripheral clock rate */ + return (u32ClkSrc / (0xFF + 1)); + } + else + { + u32Div = (((u32ClkSrc * 10) / u32BusClock + 5) / 10) - 1; /* Round to the nearest integer */ + if(u32Div > 0xFF) + { + u32Div = 0xFF; + spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk; + /* Return master peripheral clock rate */ + return (u32ClkSrc / (0xFF + 1)); + } + else + { + spi->CLKDIV = (spi->CLKDIV & (~SPI_CLKDIV_DIVIDER_Msk)) | (u32Div << SPI_CLKDIV_DIVIDER_Pos); + /* Return master peripheral clock rate */ + return (u32ClkSrc / (u32Div + 1)); + } + } + } + else /* For slave mode, force the SPI peripheral clock rate to equal APB clock rate. */ + { + /* Default setting: slave selection signal is low level active. */ + spi->SSCTL = SPI_SS_ACTIVE_LOW; + + /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */ + spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk; + + /* Set DIVIDER = 0 */ + spi->CLKDIV = 0; + + /* Select PCLK as the clock source of SPI */ + if(spi == SPI0) + { + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK0; + /* Return slave peripheral clock rate */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) == CLK_CLKSEL0_PCLK0SEL_HCLK_DIV2) + return (u32HCLKFreq / 2); + else + return u32HCLKFreq; + } + else if(spi == SPI1) + { + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK1; + /* Return slave peripheral clock rate */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK1SEL_Msk) == CLK_CLKSEL0_PCLK1SEL_HCLK_DIV2) + return (u32HCLKFreq / 2); + else + return u32HCLKFreq; + } + else + { + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK0; + /* Return slave peripheral clock rate */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) == CLK_CLKSEL0_PCLK0SEL_HCLK_DIV2) + return (u32HCLKFreq / 2); + else + return u32HCLKFreq; + } + } +} + +/** + * @brief Disable SPI controller. + * @param[in] spi The pointer of the specified SPI module. + * @return None + * @details This function will reset SPI controller. + */ +void SPI_Close(SPI_T *spi) +{ + if(spi == SPI0) + { + /* Reset SPI */ + SYS->IPRST1 |= SYS_IPRST1_SPI0RST_Msk; + SYS->IPRST1 &= ~SYS_IPRST1_SPI0RST_Msk; + } + else if(spi == SPI1) + { + /* Reset SPI */ + SYS->IPRST1 |= SYS_IPRST1_SPI1RST_Msk; + SYS->IPRST1 &= ~SYS_IPRST1_SPI1RST_Msk; + } + else + { + /* Reset SPI */ + SYS->IPRST1 |= SYS_IPRST1_SPI2RST_Msk; + SYS->IPRST1 &= ~SYS_IPRST1_SPI2RST_Msk; + } +} + +/** + * @brief Clear RX FIFO buffer. + * @param[in] spi The pointer of the specified SPI module. + * @return None + * @details This function will clear SPI RX FIFO buffer. The RXEMPTY (SPI_STATUS[8]) will be set to 1. + */ +void SPI_ClearRxFIFO(SPI_T *spi) +{ + spi->FIFOCTL |= SPI_FIFOCTL_RXFBCLR_Msk; +} + +/** + * @brief Clear TX FIFO buffer. + * @param[in] spi The pointer of the specified SPI module. + * @return None + * @details This function will clear SPI TX FIFO buffer. The TXEMPTY (SPI_STATUS[16]) will be set to 1. + * @note The TX shift register will not be cleared. + */ +void SPI_ClearTxFIFO(SPI_T *spi) +{ + spi->FIFOCTL |= SPI_FIFOCTL_TXFBCLR_Msk; +} + +/** + * @brief Disable the automatic slave selection function. + * @param[in] spi The pointer of the specified SPI module. + * @return None + * @details This function will disable the automatic slave selection function and set slave selection signal to inactive state. + */ +void SPI_DisableAutoSS(SPI_T *spi) +{ + spi->SSCTL &= ~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SS_Msk); +} + +/** + * @brief Enable the automatic slave selection function. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32SSPinMask Specifies slave selection pins. (SPI_SS) + * @param[in] u32ActiveLevel Specifies the active level of slave selection signal. (SPI_SS_ACTIVE_HIGH, SPI_SS_ACTIVE_LOW) + * @return None + * @details This function will enable the automatic slave selection function. Only available in Master mode. + * The slave selection pin and the active level will be set in this function. + */ +void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel) +{ + spi->SSCTL = (spi->SSCTL & (~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SSACTPOL_Msk | SPI_SSCTL_SS_Msk))) | (u32SSPinMask | u32ActiveLevel | SPI_SSCTL_AUTOSS_Msk); +} + +/** + * @brief Set the SPI bus clock. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32BusClock The expected frequency of SPI bus clock in Hz. + * @return Actual frequency of SPI bus clock. + * @details This function is only available in Master mode. The actual clock rate may be different from the target SPI bus clock rate. + * For example, if the SPI source clock rate is 12MHz and the target SPI bus clock rate is 7MHz, the actual SPI bus clock + * rate will be 6MHz. + * @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value. + * @note If u32BusClock >= system clock frequency, SPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0. + * @note If u32BusClock >= SPI peripheral clock source, DIVIDER will be set to 0. + */ +uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock) +{ + uint32_t u32ClkSrc, u32HCLKFreq; + uint32_t u32Div; + + /* Get system clock frequency */ + u32HCLKFreq = CLK_GetHCLKFreq(); + + if(u32BusClock >= u32HCLKFreq) + { + /* Select PCLK as the clock source of SPI */ + if(spi == SPI0) + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK0; + else if(spi == SPI1) + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK1; + else + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK0; + } + + /* Check clock source of SPI */ + if(spi == SPI0) + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT) + u32ClkSrc = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL) + u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK0) + { + /* Clock source is PCLK0 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) == CLK_CLKSEL0_PCLK0SEL_HCLK_DIV2) + u32ClkSrc = (u32HCLKFreq / 2); + else + u32ClkSrc = u32HCLKFreq; + } + else + u32ClkSrc = __HIRC; /* Clock source is HIRC */ + } + else if(spi == SPI1) + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT) + u32ClkSrc = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL) + u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK1) + { + /* Clock source is PCLK1 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK1SEL_Msk) == CLK_CLKSEL0_PCLK1SEL_HCLK_DIV2) + u32ClkSrc = (u32HCLKFreq / 2); + else + u32ClkSrc = u32HCLKFreq; + } + else + u32ClkSrc = __HIRC; /* Clock source is HIRC */ + } + else + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_HXT) + u32ClkSrc = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PLL) + u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PCLK0) + { + /* Clock source is PCLK0 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) == CLK_CLKSEL0_PCLK0SEL_HCLK_DIV2) + u32ClkSrc = (u32HCLKFreq / 2); + else + u32ClkSrc = u32HCLKFreq; + } + else + u32ClkSrc = __HIRC; /* Clock source is HIRC */ + } + + if(u32BusClock >= u32HCLKFreq) + { + /* Set DIVIDER = 0 */ + spi->CLKDIV = 0; + /* Return master peripheral clock rate */ + return u32ClkSrc; + } + else if(u32BusClock >= u32ClkSrc) + { + /* Set DIVIDER = 0 */ + spi->CLKDIV = 0; + /* Return master peripheral clock rate */ + return u32ClkSrc; + } + else if(u32BusClock == 0) + { + /* Set DIVIDER to the maximum value 0xFF. f_spi = f_spi_clk_src / (DIVIDER + 1) */ + spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk; + /* Return master peripheral clock rate */ + return (u32ClkSrc / (0xFF + 1)); + } + else + { + u32Div = (((u32ClkSrc * 10) / u32BusClock + 5) / 10) - 1; /* Round to the nearest integer */ + if(u32Div > 0xFF) + { + u32Div = 0xFF; + spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk; + /* Return master peripheral clock rate */ + return (u32ClkSrc / (0xFF + 1)); + } + else + { + spi->CLKDIV = (spi->CLKDIV & (~SPI_CLKDIV_DIVIDER_Msk)) | (u32Div << SPI_CLKDIV_DIVIDER_Pos); + /* Return master peripheral clock rate */ + return (u32ClkSrc / (u32Div + 1)); + } + } +} + +/** + * @brief Configure FIFO threshold setting. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32TxThreshold Decides the TX FIFO threshold. For SPI0, it could be 0 ~ 7. For SPI1 and SPI2, it could be 0 ~ 3. + * @param[in] u32RxThreshold Decides the RX FIFO threshold. For SPI0, it could be 0 ~ 7. For SPI1 and SPI2, it could be 0 ~ 3. + * @return None + * @details Set TX FIFO threshold and RX FIFO threshold configurations. + */ +void SPI_SetFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold) +{ + spi->FIFOCTL = (spi->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk) | + (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) | + (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos)); +} + +/** + * @brief Get the actual frequency of SPI bus clock. Only available in Master mode. + * @param[in] spi The pointer of the specified SPI module. + * @return Actual SPI bus clock frequency in Hz. + * @details This function will calculate the actual SPI bus clock rate according to the SPInSEL and DIVIDER settings. Only available in Master mode. + */ +uint32_t SPI_GetBusClock(SPI_T *spi) +{ + uint32_t u32Div; + uint32_t u32ClkSrc, u32HCLKFreq; + + /* Get DIVIDER setting */ + u32Div = (spi->CLKDIV & SPI_CLKDIV_DIVIDER_Msk) >> SPI_CLKDIV_DIVIDER_Pos; + + /* Get system clock frequency */ + u32HCLKFreq = CLK_GetHCLKFreq(); + + /* Check clock source of SPI */ + if(spi == SPI0) + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT) + u32ClkSrc = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL) + u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK0) + { + /* Clock source is PCLK0 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) == CLK_CLKSEL0_PCLK0SEL_HCLK_DIV2) + u32ClkSrc = (u32HCLKFreq / 2); + else + u32ClkSrc = u32HCLKFreq; + } + else + u32ClkSrc = __HIRC; /* Clock source is HIRC */ + } + else if(spi == SPI1) + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT) + u32ClkSrc = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL) + u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK1) + { + /* Clock source is PCLK1 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK1SEL_Msk) == CLK_CLKSEL0_PCLK1SEL_HCLK_DIV2) + u32ClkSrc = (u32HCLKFreq / 2); + else + u32ClkSrc = u32HCLKFreq; + } + else + u32ClkSrc = __HIRC; /* Clock source is HIRC */ + } + else + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_HXT) + u32ClkSrc = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PLL) + u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PCLK0) + { + /* Clock source is PCLK0 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) == CLK_CLKSEL0_PCLK0SEL_HCLK_DIV2) + u32ClkSrc = (u32HCLKFreq / 2); + else + u32ClkSrc = u32HCLKFreq; + } + else + u32ClkSrc = __HIRC; /* Clock source is HIRC */ + } + + /* Return SPI bus clock rate */ + return (u32ClkSrc / (u32Div + 1)); +} + +/** + * @brief Enable interrupt function. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32Mask The combination of all related interrupt enable bits. + * Each bit corresponds to a interrupt enable bit. + * This parameter decides which interrupts will be enabled. It is combination of: + * - \ref SPI_UNIT_INT_MASK + * - \ref SPI_SSACT_INT_MASK + * - \ref SPI_SSINACT_INT_MASK + * - \ref SPI_SLVUR_INT_MASK + * - \ref SPI_SLVBE_INT_MASK + * - \ref SPI_SLVTO_INT_MASK + * - \ref SPI_TXUF_INT_MASK + * - \ref SPI_FIFO_TXTH_INT_MASK + * - \ref SPI_FIFO_RXTH_INT_MASK + * - \ref SPI_FIFO_RXOV_INT_MASK + * - \ref SPI_FIFO_RXTO_INT_MASK + * + * @return None + * @details Enable SPI related interrupts specified by u32Mask parameter. + */ +void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask) +{ + /* Enable unit transfer interrupt flag */ + if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK) + spi->CTL |= SPI_CTL_UNITIEN_Msk; + + /* Enable slave selection signal active interrupt flag */ + if((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK) + spi->SSCTL |= SPI_SSCTL_SSACTIEN_Msk; + + /* Enable slave selection signal inactive interrupt flag */ + if((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK) + spi->SSCTL |= SPI_SSCTL_SSINAIEN_Msk; + + /* Enable slave TX under run interrupt flag */ + if((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK) + spi->SSCTL |= SPI_SSCTL_SLVURIEN_Msk; + + /* Enable slave bit count error interrupt flag */ + if((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK) + spi->SSCTL |= SPI_SSCTL_SLVBEIEN_Msk; + + /* Enable slave time-out interrupt flag */ + if((u32Mask & SPI_SLVTO_INT_MASK) == SPI_SLVTO_INT_MASK) + spi->SSCTL |= SPI_SSCTL_SLVTOIEN_Msk; + + /* Enable slave TX underflow interrupt flag */ + if((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK) + spi->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk; + + /* Enable TX threshold interrupt flag */ + if((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK) + spi->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk; + + /* Enable RX threshold interrupt flag */ + if((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK) + spi->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk; + + /* Enable RX overrun interrupt flag */ + if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK) + spi->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk; + + /* Enable RX time-out interrupt flag */ + if((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK) + spi->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk; +} + +/** + * @brief Disable interrupt function. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32Mask The combination of all related interrupt enable bits. + * Each bit corresponds to a interrupt bit. + * This parameter decides which interrupts will be disabled. It is combination of: + * - \ref SPI_UNIT_INT_MASK + * - \ref SPI_SSACT_INT_MASK + * - \ref SPI_SSINACT_INT_MASK + * - \ref SPI_SLVUR_INT_MASK + * - \ref SPI_SLVBE_INT_MASK + * - \ref SPI_SLVTO_INT_MASK + * - \ref SPI_TXUF_INT_MASK + * - \ref SPI_FIFO_TXTH_INT_MASK + * - \ref SPI_FIFO_RXTH_INT_MASK + * - \ref SPI_FIFO_RXOV_INT_MASK + * - \ref SPI_FIFO_RXTO_INT_MASK + * + * @return None + * @details Disable SPI related interrupts specified by u32Mask parameter. + */ +void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask) +{ + /* Disable unit transfer interrupt flag */ + if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK) + spi->CTL &= ~SPI_CTL_UNITIEN_Msk; + + /* Disable slave selection signal active interrupt flag */ + if((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK) + spi->SSCTL &= ~SPI_SSCTL_SSACTIEN_Msk; + + /* Disable slave selection signal inactive interrupt flag */ + if((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK) + spi->SSCTL &= ~SPI_SSCTL_SSINAIEN_Msk; + + /* Disable slave TX under run interrupt flag */ + if((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK) + spi->SSCTL &= ~SPI_SSCTL_SLVURIEN_Msk; + + /* Disable slave bit count error interrupt flag */ + if((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK) + spi->SSCTL &= ~SPI_SSCTL_SLVBEIEN_Msk; + + /* Disable slave time-out interrupt flag */ + if((u32Mask & SPI_SLVTO_INT_MASK) == SPI_SLVTO_INT_MASK) + spi->SSCTL &= ~SPI_SSCTL_SLVTOIEN_Msk; + + /* Disable slave TX underflow interrupt flag */ + if((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK) + spi->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk; + + /* Disable TX threshold interrupt flag */ + if((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK) + spi->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk; + + /* Disable RX threshold interrupt flag */ + if((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK) + spi->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk; + + /* Disable RX overrun interrupt flag */ + if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK) + spi->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk; + + /* Disable RX time-out interrupt flag */ + if((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK) + spi->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk; +} + +/** + * @brief Get interrupt flag. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32Mask The combination of all related interrupt sources. + * Each bit corresponds to a interrupt source. + * This parameter decides which interrupt flags will be read. It is combination of: + * - \ref SPI_UNIT_INT_MASK + * - \ref SPI_SSACT_INT_MASK + * - \ref SPI_SSINACT_INT_MASK + * - \ref SPI_SLVUR_INT_MASK + * - \ref SPI_SLVBE_INT_MASK + * - \ref SPI_SLVTO_INT_MASK + * - \ref SPI_TXUF_INT_MASK + * - \ref SPI_FIFO_TXTH_INT_MASK + * - \ref SPI_FIFO_RXTH_INT_MASK + * - \ref SPI_FIFO_RXOV_INT_MASK + * - \ref SPI_FIFO_RXTO_INT_MASK + * + * @return Interrupt flags of selected sources. + * @details Get SPI related interrupt flags specified by u32Mask parameter. + */ +uint32_t SPI_GetIntFlag(SPI_T *spi, uint32_t u32Mask) +{ + uint32_t u32IntFlag = 0; + + /* Check unit transfer interrupt flag */ + if((u32Mask & SPI_UNIT_INT_MASK) && (spi->STATUS & SPI_STATUS_UNITIF_Msk)) + u32IntFlag |= SPI_UNIT_INT_MASK; + + /* Check slave selection signal active interrupt flag */ + if((u32Mask & SPI_SSACT_INT_MASK) && (spi->STATUS & SPI_STATUS_SSACTIF_Msk)) + u32IntFlag |= SPI_SSACT_INT_MASK; + + /* Check slave selection signal inactive interrupt flag */ + if((u32Mask & SPI_SSINACT_INT_MASK) && (spi->STATUS & SPI_STATUS_SSINAIF_Msk)) + u32IntFlag |= SPI_SSINACT_INT_MASK; + + /* Check slave TX under run interrupt flag */ + if((u32Mask & SPI_SLVUR_INT_MASK) && (spi->STATUS & SPI_STATUS_SLVURIF_Msk)) + u32IntFlag |= SPI_SLVUR_INT_MASK; + + /* Check slave bit count error interrupt flag */ + if((u32Mask & SPI_SLVBE_INT_MASK) && (spi->STATUS & SPI_STATUS_SLVBEIF_Msk)) + u32IntFlag |= SPI_SLVBE_INT_MASK; + + /* Check slave time-out interrupt flag */ + if((u32Mask & SPI_SLVTO_INT_MASK) && (spi->STATUS & SPI_STATUS_SLVTOIF_Msk)) + u32IntFlag |= SPI_SLVTO_INT_MASK; + + /* Check slave TX underflow interrupt flag */ + if((u32Mask & SPI_TXUF_INT_MASK) && (spi->STATUS & SPI_STATUS_TXUFIF_Msk)) + u32IntFlag |= SPI_TXUF_INT_MASK; + + /* Check TX threshold interrupt flag */ + if((u32Mask & SPI_FIFO_TXTH_INT_MASK) && (spi->STATUS & SPI_STATUS_TXTHIF_Msk)) + u32IntFlag |= SPI_FIFO_TXTH_INT_MASK; + + /* Check RX threshold interrupt flag */ + if((u32Mask & SPI_FIFO_RXTH_INT_MASK) && (spi->STATUS & SPI_STATUS_RXTHIF_Msk)) + u32IntFlag |= SPI_FIFO_RXTH_INT_MASK; + + /* Check RX overrun interrupt flag */ + if((u32Mask & SPI_FIFO_RXOV_INT_MASK) && (spi->STATUS & SPI_STATUS_RXOVIF_Msk)) + u32IntFlag |= SPI_FIFO_RXOV_INT_MASK; + + /* Check RX time-out interrupt flag */ + if((u32Mask & SPI_FIFO_RXTO_INT_MASK) && (spi->STATUS & SPI_STATUS_RXTOIF_Msk)) + u32IntFlag |= SPI_FIFO_RXTO_INT_MASK; + + return u32IntFlag; +} + +/** + * @brief Clear interrupt flag. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32Mask The combination of all related interrupt sources. + * Each bit corresponds to a interrupt source. + * This parameter decides which interrupt flags will be cleared. It could be the combination of: + * - \ref SPI_UNIT_INT_MASK + * - \ref SPI_SSACT_INT_MASK + * - \ref SPI_SSINACT_INT_MASK + * - \ref SPI_SLVUR_INT_MASK + * - \ref SPI_SLVBE_INT_MASK + * - \ref SPI_SLVTO_INT_MASK + * - \ref SPI_TXUF_INT_MASK + * - \ref SPI_FIFO_RXOV_INT_MASK + * - \ref SPI_FIFO_RXTO_INT_MASK + * + * @return None + * @details Clear SPI related interrupt flags specified by u32Mask parameter. + */ +void SPI_ClearIntFlag(SPI_T *spi, uint32_t u32Mask) +{ + if(u32Mask & SPI_UNIT_INT_MASK) + spi->STATUS = SPI_STATUS_UNITIF_Msk; /* Clear unit transfer interrupt flag */ + + if(u32Mask & SPI_SSACT_INT_MASK) + spi->STATUS = SPI_STATUS_SSACTIF_Msk; /* Clear slave selection signal active interrupt flag */ + + if(u32Mask & SPI_SSINACT_INT_MASK) + spi->STATUS = SPI_STATUS_SSINAIF_Msk; /* Clear slave selection signal inactive interrupt flag */ + + if(u32Mask & SPI_SLVUR_INT_MASK) + spi->STATUS = SPI_STATUS_SLVURIF_Msk; /* Clear slave TX under run interrupt flag */ + + if(u32Mask & SPI_SLVBE_INT_MASK) + spi->STATUS = SPI_STATUS_SLVBEIF_Msk; /* Clear slave bit count error interrupt flag */ + + if(u32Mask & SPI_SLVTO_INT_MASK) + spi->STATUS = SPI_STATUS_SLVTOIF_Msk; /* Clear slave time-out interrupt flag */ + + if(u32Mask & SPI_TXUF_INT_MASK) + spi->STATUS = SPI_STATUS_TXUFIF_Msk; /* Clear slave TX underflow interrupt flag */ + + if(u32Mask & SPI_FIFO_RXOV_INT_MASK) + spi->STATUS = SPI_STATUS_RXOVIF_Msk; /* Clear RX overrun interrupt flag */ + + if(u32Mask & SPI_FIFO_RXTO_INT_MASK) + spi->STATUS = SPI_STATUS_RXTOIF_Msk; /* Clear RX time-out interrupt flag */ +} + +/** + * @brief Get SPI status. + * @param[in] spi The pointer of the specified SPI module. + * @param[in] u32Mask The combination of all related sources. + * Each bit corresponds to a source. + * This parameter decides which flags will be read. It is combination of: + * - \ref SPI_BUSY_MASK + * - \ref SPI_RX_EMPTY_MASK + * - \ref SPI_RX_FULL_MASK + * - \ref SPI_TX_EMPTY_MASK + * - \ref SPI_TX_FULL_MASK + * - \ref SPI_TXRX_RESET_MASK + * - \ref SPI_SPIEN_STS_MASK + * - \ref SPI_SSLINE_STS_MASK + * + * @return Flags of selected sources. + * @details Get SPI related status specified by u32Mask parameter. + */ +uint32_t SPI_GetStatus(SPI_T *spi, uint32_t u32Mask) +{ + uint32_t u32Flag = 0; + + /* Check busy status */ + if((u32Mask & SPI_BUSY_MASK) && (spi->STATUS & SPI_STATUS_BUSY_Msk)) + u32Flag |= SPI_BUSY_MASK; + + /* Check RX empty flag */ + if((u32Mask & SPI_RX_EMPTY_MASK) && (spi->STATUS & SPI_STATUS_RXEMPTY_Msk)) + u32Flag |= SPI_RX_EMPTY_MASK; + + /* Check RX full flag */ + if((u32Mask & SPI_RX_FULL_MASK) && (spi->STATUS & SPI_STATUS_RXFULL_Msk)) + u32Flag |= SPI_RX_FULL_MASK; + + /* Check TX empty flag */ + if((u32Mask & SPI_TX_EMPTY_MASK) && (spi->STATUS & SPI_STATUS_TXEMPTY_Msk)) + u32Flag |= SPI_TX_EMPTY_MASK; + + /* Check TX full flag */ + if((u32Mask & SPI_TX_FULL_MASK) && (spi->STATUS & SPI_STATUS_TXFULL_Msk)) + u32Flag |= SPI_TX_FULL_MASK; + + /* Check TX/RX reset flag */ + if((u32Mask & SPI_TXRX_RESET_MASK) && (spi->STATUS & SPI_STATUS_TXRXRST_Msk)) + u32Flag |= SPI_TXRX_RESET_MASK; + + /* Check SPIEN flag */ + if((u32Mask & SPI_SPIEN_STS_MASK) && (spi->STATUS & SPI_STATUS_SPIENSTS_Msk)) + u32Flag |= SPI_SPIEN_STS_MASK; + + /* Check SPIn_SS line status */ + if((u32Mask & SPI_SSLINE_STS_MASK) && (spi->STATUS & SPI_STATUS_SSLINE_Msk)) + u32Flag |= SPI_SSLINE_STS_MASK; + + return u32Flag; +} + + +/** + * @brief This function is used to get I2S source clock frequency. + * @param[in] i2s The pointer of the specified I2S module. + * @return I2S source clock frequency (Hz). + * @details Return the source clock frequency according to the setting of SPI1SEL (CLKSEL2[5:4]) or SPI2SEL (CLKSEL2[7:6]). + * @note Only SPI1 and SPI2 support I2S mode. + */ +static uint32_t I2S_GetSourceClockFreq(SPI_T *i2s) +{ + uint32_t u32Freq, u32HCLKFreq; + + if(i2s == SPI1) + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT) + u32Freq = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL) + u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK1) + { + /* Get system clock frequency */ + u32HCLKFreq = CLK_GetHCLKFreq(); + /* Clock source is PCLK1 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK1SEL_Msk) == CLK_CLKSEL0_PCLK1SEL_HCLK_DIV2) + u32Freq = (u32HCLKFreq / 2); + else + u32Freq = u32HCLKFreq; + } + else + u32Freq = __HIRC; /* Clock source is HIRC */ + } + else + { + if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_HXT) + u32Freq = __HXT; /* Clock source is HXT */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PLL) + u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */ + else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI2SEL_Msk) == CLK_CLKSEL2_SPI2SEL_PCLK0) + { + /* Get system clock frequency */ + u32HCLKFreq = CLK_GetHCLKFreq(); + /* Clock source is PCLK0 */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) == CLK_CLKSEL0_PCLK0SEL_HCLK_DIV2) + u32Freq = (u32HCLKFreq / 2); + else + u32Freq = u32HCLKFreq; + } + else + u32Freq = __HIRC; /* Clock source is HIRC */ + } + + return u32Freq; +} + +/** + * @brief This function configures some parameters of I2S interface for general purpose use. + * @param[in] i2s The pointer of the specified I2S module. + * @param[in] u32MasterSlave I2S operation mode. Valid values are listed below. + * - \ref I2S_MODE_MASTER + * - \ref I2S_MODE_SLAVE + * @param[in] u32SampleRate Sample rate + * @param[in] u32WordWidth Data length. Valid values are listed below. + * - \ref I2S_DATABIT_8 + * - \ref I2S_DATABIT_16 + * - \ref I2S_DATABIT_24 + * - \ref I2S_DATABIT_32 + * @param[in] u32Channels Audio format. Valid values are listed below. + * - \ref I2S_MONO + * - \ref I2S_STEREO + * @param[in] u32DataFormat Data format. Valid values are listed below. + * - \ref I2S_FORMAT_I2S + * - \ref I2S_FORMAT_MSB + * - \ref I2S_FORMAT_PCMA + * - \ref I2S_FORMAT_PCMB + * @return Real sample rate of master mode or peripheral clock rate of slave mode. + * @details This function will reset SPI/I2S controller and configure I2S controller according to the input parameters. + * Set TX and RX FIFO threshold to middle value. Both the TX and RX functions will be enabled. + * The actual sample rate may be different from the target sample rate. The real sample rate will be returned for reference. + * @note Only SPI1 and SPI2 support I2S mode. + * @note In slave mode, the SPI peripheral clock rate will be equal to APB clock rate. + */ +uint32_t I2S_Open(SPI_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat) +{ + uint32_t u32Divider; + uint32_t u32BitRate, u32SrcClk; + uint32_t u32HCLKFreq; + + /* Reset SPI/I2S */ + if(i2s == SPI1) + { + SYS->IPRST1 |= SYS_IPRST1_SPI1RST_Msk; + SYS->IPRST1 &= ~SYS_IPRST1_SPI1RST_Msk; + } + else + { + SYS->IPRST1 |= SYS_IPRST1_SPI2RST_Msk; + SYS->IPRST1 &= ~SYS_IPRST1_SPI2RST_Msk; + } + + /* Configure I2S controller */ + i2s->I2SCTL = u32MasterSlave | u32WordWidth | u32Channels | u32DataFormat; + /* Set TX and RX FIFO threshold to middle value */ + i2s->FIFOCTL = I2S_FIFO_TX_LEVEL_WORD_2 | I2S_FIFO_RX_LEVEL_WORD_2; + + if(u32MasterSlave == SPI_MASTER) + { + /* Get the source clock rate */ + u32SrcClk = I2S_GetSourceClockFreq(i2s); + + /* Calculate the bit clock rate */ + u32BitRate = u32SampleRate * ((u32WordWidth >> SPI_I2SCTL_WDWIDTH_Pos) + 1) * 16; + u32Divider = (((((u32SrcClk * 10) / u32BitRate) >> 1) + 5) / 10) - 1; /* Round to the nearest integer */ + /* Set BCLKDIV setting */ + i2s->I2SCLK = (i2s->I2SCLK & ~SPI_I2SCLK_BCLKDIV_Msk) | (u32Divider << SPI_I2SCLK_BCLKDIV_Pos); + + /* Calculate bit clock rate */ + u32BitRate = u32SrcClk / ((u32Divider + 1) * 2); + /* Calculate real sample rate */ + u32SampleRate = u32BitRate / (((u32WordWidth >> SPI_I2SCTL_WDWIDTH_Pos) + 1) * 16); + + /* Enable TX function, RX function and I2S mode. */ + i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk); + + /* Return the real sample rate */ + return u32SampleRate; + } + else + { + /* Set BCLKDIV = 0 */ + i2s->I2SCLK &= ~SPI_I2SCLK_BCLKDIV_Msk; + /* Get system clock frequency */ + u32HCLKFreq = CLK_GetHCLKFreq(); + + if(i2s == SPI1) + { + /* Set the peripheral clock rate to equal APB clock rate */ + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK1; + /* Enable TX function, RX function and I2S mode. */ + i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk); + /* Return slave peripheral clock rate */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK1SEL_Msk) == CLK_CLKSEL0_PCLK1SEL_HCLK_DIV2) + return (u32HCLKFreq / 2); + else + return u32HCLKFreq; + } + else + { + /* Set the peripheral clock rate to equal APB clock rate */ + CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK0; + /* Enable TX function, RX function and I2S mode. */ + i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk); + /* Return slave peripheral clock rate */ + if((CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk) == CLK_CLKSEL0_PCLK0SEL_HCLK_DIV2) + return (u32HCLKFreq / 2); + else + return u32HCLKFreq; + } + } +} + +/** + * @brief Disable I2S function. + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details Disable I2S function. + * @note Only SPI1 and SPI2 support I2S mode. + */ +void I2S_Close(SPI_T *i2s) +{ + i2s->I2SCTL &= ~SPI_I2SCTL_I2SEN_Msk; +} + +/** + * @brief Enable interrupt function. + * @param[in] i2s The pointer of the specified I2S module. + * @param[in] u32Mask The combination of all related interrupt enable bits. + * Each bit corresponds to a interrupt source. Valid values are listed below. + * - \ref I2S_FIFO_TXTH_INT_MASK + * - \ref I2S_FIFO_RXTH_INT_MASK + * - \ref I2S_FIFO_RXOV_INT_MASK + * - \ref I2S_FIFO_RXTO_INT_MASK + * - \ref I2S_TXUF_INT_MASK + * - \ref I2S_RIGHT_ZC_INT_MASK + * - \ref I2S_LEFT_ZC_INT_MASK + * @return None + * @details This function enables the interrupt according to the u32Mask parameter. + * @note Only SPI1 and SPI2 support I2S mode. + */ +void I2S_EnableInt(SPI_T *i2s, uint32_t u32Mask) +{ + /* Enable TX threshold interrupt flag */ + if((u32Mask & I2S_FIFO_TXTH_INT_MASK) == I2S_FIFO_TXTH_INT_MASK) + i2s->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk; + + /* Enable RX threshold interrupt flag */ + if((u32Mask & I2S_FIFO_RXTH_INT_MASK) == I2S_FIFO_RXTH_INT_MASK) + i2s->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk; + + /* Enable RX overrun interrupt flag */ + if((u32Mask & I2S_FIFO_RXOV_INT_MASK) == I2S_FIFO_RXOV_INT_MASK) + i2s->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk; + + /* Enable RX time-out interrupt flag */ + if((u32Mask & I2S_FIFO_RXTO_INT_MASK) == I2S_FIFO_RXTO_INT_MASK) + i2s->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk; + + /* Enable TX underflow interrupt flag */ + if((u32Mask & I2S_TXUF_INT_MASK) == I2S_TXUF_INT_MASK) + i2s->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk; + + /* Enable right channel zero cross interrupt flag */ + if((u32Mask & I2S_RIGHT_ZC_INT_MASK) == I2S_RIGHT_ZC_INT_MASK) + i2s->I2SCTL |= SPI_I2SCTL_RZCIEN_Msk; + + /* Enable left channel zero cross interrupt flag */ + if((u32Mask & I2S_LEFT_ZC_INT_MASK) == I2S_LEFT_ZC_INT_MASK) + i2s->I2SCTL |= SPI_I2SCTL_LZCIEN_Msk; +} + +/** + * @brief Disable interrupt function. + * @param[in] i2s The pointer of the specified I2S module. + * @param[in] u32Mask The combination of all related interrupt enable bits. + * Each bit corresponds to a interrupt source. Valid values are listed below. + * - \ref I2S_FIFO_TXTH_INT_MASK + * - \ref I2S_FIFO_RXTH_INT_MASK + * - \ref I2S_FIFO_RXOV_INT_MASK + * - \ref I2S_FIFO_RXTO_INT_MASK + * - \ref I2S_TXUF_INT_MASK + * - \ref I2S_RIGHT_ZC_INT_MASK + * - \ref I2S_LEFT_ZC_INT_MASK + * @return None + * @details This function disables the interrupt according to the u32Mask parameter. + * @note Only SPI1 and SPI2 support I2S mode. + */ +void I2S_DisableInt(SPI_T *i2s, uint32_t u32Mask) +{ + /* Disable TX threshold interrupt flag */ + if((u32Mask & I2S_FIFO_TXTH_INT_MASK) == I2S_FIFO_TXTH_INT_MASK) + i2s->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk; + + /* Disable RX threshold interrupt flag */ + if((u32Mask & I2S_FIFO_RXTH_INT_MASK) == I2S_FIFO_RXTH_INT_MASK) + i2s->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk; + + /* Disable RX overrun interrupt flag */ + if((u32Mask & I2S_FIFO_RXOV_INT_MASK) == I2S_FIFO_RXOV_INT_MASK) + i2s->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk; + + /* Disable RX time-out interrupt flag */ + if((u32Mask & I2S_FIFO_RXTO_INT_MASK) == I2S_FIFO_RXTO_INT_MASK) + i2s->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk; + + /* Disable TX underflow interrupt flag */ + if((u32Mask & I2S_TXUF_INT_MASK) == I2S_TXUF_INT_MASK) + i2s->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk; + + /* Disable right channel zero cross interrupt flag */ + if((u32Mask & I2S_RIGHT_ZC_INT_MASK) == I2S_RIGHT_ZC_INT_MASK) + i2s->I2SCTL &= ~SPI_I2SCTL_RZCIEN_Msk; + + /* Disable left channel zero cross interrupt flag */ + if((u32Mask & I2S_LEFT_ZC_INT_MASK) == I2S_LEFT_ZC_INT_MASK) + i2s->I2SCTL &= ~SPI_I2SCTL_LZCIEN_Msk; +} + +/** + * @brief Enable master clock (MCLK). + * @param[in] i2s The pointer of the specified I2S module. + * @param[in] u32BusClock The target MCLK clock rate. + * @return Actual MCLK clock rate + * @details Set the master clock rate according to u32BusClock parameter and enable master clock output. + * The actual master clock rate may be different from the target master clock rate. The real master clock rate will be returned for reference. + * @note Only SPI1 and SPI2 support I2S mode. + */ +uint32_t I2S_EnableMCLK(SPI_T *i2s, uint32_t u32BusClock) +{ + uint32_t u32Divider; + uint32_t u32SrcClk; + + u32SrcClk = I2S_GetSourceClockFreq(i2s); + if(u32BusClock == u32SrcClk) + u32Divider = 0; + else + { + u32Divider = (u32SrcClk / u32BusClock) >> 1; + /* MCLKDIV is a 6-bit width configuration. The maximum value is 0x3F. */ + if(u32Divider > 0x3F) + u32Divider = 0x3F; + } + + /* Write u32Divider to MCLKDIV (SPI_I2SCLK[5:0]) */ + i2s->I2SCLK = (i2s->I2SCLK & ~SPI_I2SCLK_MCLKDIV_Msk) | (u32Divider << SPI_I2SCLK_MCLKDIV_Pos); + + /* Enable MCLK output */ + i2s->I2SCTL |= SPI_I2SCTL_MCLKEN_Msk; + + if(u32Divider == 0) + return u32SrcClk; /* If MCLKDIV=0, master clock rate is equal to the source clock rate. */ + else + return ((u32SrcClk >> 1) / u32Divider); /* If MCLKDIV>0, master clock rate = source clock rate / (MCLKDIV * 2) */ +} + +/** + * @brief Disable master clock (MCLK). + * @param[in] i2s The pointer of the specified I2S module. + * @return None + * @details Clear MCLKEN bit of SPI_I2SCTL register to disable master clock output. + * @note Only SPI1 and SPI2 support I2S mode. + */ +void I2S_DisableMCLK(SPI_T *i2s) +{ + i2s->I2SCTL &= ~SPI_I2SCTL_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 ~ 3. + * @param[in] u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 3. + * @return None + * @details Set TX FIFO threshold and RX FIFO threshold configurations. + */ +void I2S_SetFIFO(SPI_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold) +{ + i2s->FIFOCTL = (i2s->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk) | + (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) | + (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos)); +} + +/*@}*/ /* end of group SPI_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group SPI_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/sys.c b/StdDriver/src/sys.c new file mode 100644 index 0000000..bc127c7 --- /dev/null +++ b/StdDriver/src/sys.c @@ -0,0 +1,213 @@ +/**************************************************************************//** + * @file sys.c + * @version V3.00 + * $Revision: 12 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series SYS driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ + +#include "M451Series.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup SYS_Driver SYS Driver + @{ +*/ + + +/** @addtogroup SYS_EXPORTED_FUNCTIONS SYS Exported Functions + @{ +*/ + +/** + * @brief Clear reset source + * @param[in] u32Src is system reset source. Including : + * - \ref SYS_RSTSTS_CPURF_Msk + * - \ref SYS_RSTSTS_SYSRF_Msk + * - \ref SYS_RSTSTS_BODRF_Msk + * - \ref SYS_RSTSTS_LVRF_Msk + * - \ref SYS_RSTSTS_WDTRF_Msk + * - \ref SYS_RSTSTS_PINRF_Msk + * - \ref SYS_RSTSTS_PORF_Msk + * @return None + * @details This function clear the selected system reset source. + */ +void SYS_ClearResetSrc(uint32_t u32Src) +{ + SYS->RSTSTS |= u32Src; +} + +/** + * @brief Get Brown-out detector output status + * @param None + * @retval 0 System voltage is higher than BOD_VL setting or BOD_EN is 0. + * @retval 1 System voltage is lower than BOD_VL setting. + * @details This function get Brown-out detector output status. + */ +uint32_t SYS_GetBODStatus(void) +{ + return ((SYS->BODCTL & SYS_BODCTL_BODOUT_Msk) >> SYS_BODCTL_BODOUT_Pos); +} + +/** + * @brief Get reset status register value + * @param None + * @return Reset source + * @details This function get the system reset status register value. + */ +uint32_t SYS_GetResetSrc(void) +{ + return (SYS->RSTSTS); +} + +/** + * @brief Check if register is locked nor not + * @param None + * @retval 0 Write-protection function is disabled. + * 1 Write-protection function is enabled. + * @details This function check register write-protection bit setting. + */ +uint32_t SYS_IsRegLocked(void) +{ + return !(SYS->REGLCTL & 0x1); +} + +/** + * @brief Get product ID + * @param None + * @return Product ID + * @details This function get product ID. + */ +uint32_t SYS_ReadPDID(void) +{ + return SYS->PDID; +} + +/** + * @brief Reset chip with chip reset + * @param None + * @return None + * @details This function reset chip with chip reset. + * The register write-protection function should be disabled before using this function. + */ +void SYS_ResetChip(void) +{ + SYS->IPRST0 |= SYS_IPRST0_CHIPRST_Msk; +} + +/** + * @brief Reset chip with CPU reset + * @param None + * @return None + * @details This function reset CPU with CPU reset. + * The register write-protection function should be disabled before using this function. + */ +void SYS_ResetCPU(void) +{ + SYS->IPRST0 |= SYS_IPRST0_CPURST_Msk; +} + +/** + * @brief Reset selected module + * @param[in] u32ModuleIndex is module index. Including : + * - \ref PDMA_RST + * - \ref EBI_RST + * - \ref USBH_RST + * - \ref CRC_RST + * - \ref GPIO_RST + * - \ref TMR0_RST + * - \ref TMR1_RST + * - \ref TMR2_RST + * - \ref TMR3_RST + * - \ref ACMP01_RST + * - \ref I2C0_RST + * - \ref I2C1_RST + * - \ref SPI0_RST + * - \ref SPI1_RST + * - \ref SPI2_RST + * - \ref UART0_RST + * - \ref UART1_RST + * - \ref UART2_RST + * - \ref UART3_RST + * - \ref CAN0_RST + * - \ref OTG_RST + * - \ref USBD_RST + * - \ref EADC_RST + * - \ref SC0_RST + * - \ref DAC_RST + * - \ref PWM0_RST + * - \ref PWM1_RST + * - \ref TK_RST + * @return None + * @details This function reset selected module. + */ +void SYS_ResetModule(uint32_t u32ModuleIndex) +{ + /* Generate reset signal to the corresponding module */ + *(volatile uint32_t *)((uint32_t)&SYS->IPRST0 + (u32ModuleIndex >> 24)) |= 1 << (u32ModuleIndex & 0x00ffffff); + + /* Release corresponding module from reset state */ + *(volatile uint32_t *)((uint32_t)&SYS->IPRST0 + (u32ModuleIndex >> 24)) &= ~(1 << (u32ModuleIndex & 0x00ffffff)); +} + +/** + * @brief Enable and configure Brown-out detector function + * @param[in] i32Mode is reset or interrupt mode. Including : + * - \ref SYS_BODCTL_BOD_RST_EN + * - \ref SYS_BODCTL_BOD_INTERRUPT_EN + * @param[in] u32BODLevel is Brown-out voltage level. Including : + * - \ref SYS_BODCTL_BODVL_4_5V + * - \ref SYS_BODCTL_BODVL_3_7V + * - \ref SYS_BODCTL_BODVL_2_7V + * - \ref SYS_BODCTL_BODVL_2_2V + * @return None + * @details This function configure Brown-out detector reset or interrupt mode, enable Brown-out function and set Brown-out voltage level. + * The register write-protection function should be disabled before using this function. + */ +void SYS_EnableBOD(int32_t i32Mode, uint32_t u32BODLevel) +{ + /* Enable Brown-out Detector function */ + SYS->BODCTL |= SYS_BODCTL_BODEN_Msk; + + /* Enable Brown-out interrupt or reset function */ + SYS->BODCTL = (SYS->BODCTL & ~SYS_BODCTL_BODRSTEN_Msk) | i32Mode; + + /* Select Brown-out Detector threshold voltage */ + SYS->BODCTL = (SYS->BODCTL & ~SYS_BODCTL_BODVL_Msk) | u32BODLevel; +} + +/** + * @brief Disable Brown-out detector function + * @param None + * @return None + * @details This function disable Brown-out detector function. + * The register write-protection function should be disabled before using this function. + */ +void SYS_DisableBOD(void) +{ + SYS->BODCTL &= ~SYS_BODCTL_BODEN_Msk; +} + + + +/*@}*/ /* end of group SYS_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group SYS_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/timer.c b/StdDriver/src/timer.c new file mode 100644 index 0000000..db8ce42 --- /dev/null +++ b/StdDriver/src/timer.c @@ -0,0 +1,292 @@ +/**************************************************************************//** + * @file timer.c + * @version V3.00 + * $Revision: 6 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series Timer driver source file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup TIMER_Driver TIMER Driver + @{ +*/ + +/** @addtogroup TIMER_EXPORTED_FUNCTIONS TIMER Exported Functions + @{ +*/ + +/** + * @brief Open Timer with Operate Mode and Frequency + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * @param[in] u32Mode Operation mode. Possible options are + * - \ref TIMER_ONESHOT_MODE + * - \ref TIMER_PERIODIC_MODE + * - \ref TIMER_TOGGLE_MODE + * - \ref TIMER_CONTINUOUS_MODE + * @param[in] u32Freq Target working frequency + * + * @return Real timer working frequency + * + * @details This API is used to configure timer to operate in specified mode and frequency. + * If timer cannot work in target frequency, a closest frequency will be chose and returned. + * @note After calling this API, Timer is \b NOT running yet. But could start timer running be calling + * \ref TIMER_Start macro or program registers directly. + */ +uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq) +{ + uint32_t u32Clk = TIMER_GetModuleClock(timer); + uint32_t u32Cmpr = 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 > 64000000) + { + u32Prescale = 7; // real prescaler value is 8 + u32Clk >>= 3; + } + else if(u32Clk > 32000000) + { + u32Prescale = 3; // real prescaler value is 4 + u32Clk >>= 2; + } + else if(u32Clk > 16000000) + { + u32Prescale = 1; // real prescaler value is 2 + u32Clk >>= 1; + } + + u32Cmpr = u32Clk / u32Freq; + } + + timer->CTL = u32Mode | u32Prescale; + timer->CMP = u32Cmpr; + + return(u32Clk / (u32Cmpr * (u32Prescale + 1))); +} + +/** + * @brief Stop Timer Counting + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This API stops timer counting and disable all timer interrupt function. + */ +void TIMER_Close(TIMER_T *timer) +{ + timer->CTL = 0; + timer->EXTCTL = 0; +} + +/** + * @brief Create a specify Delay Time + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * @param[in] u32Usec Delay period in micro seconds. Valid values are between 100~1000000 (100 micro second ~ 1 second). + * + * @return None + * + * @details This API is used to create a delay loop for u32usec micro seconds by using timer one-shot mode. + * @note This API overwrites the register setting of the timer used to count the delay time. + * @note This API use polling mode. So there is no need to enable interrupt for the timer module used to generate delay. + */ +void TIMER_Delay(TIMER_T *timer, uint32_t u32Usec) +{ + uint32_t u32Clk = TIMER_GetModuleClock(timer); + uint32_t u32Prescale = 0, delay = (SystemCoreClock / u32Clk) + 1; + uint32_t u32Cmpr, u32NsecPerTick; + + // Clear current timer configuration/ + timer->CTL = 0; + timer->EXTCTL = 0; + + if(u32Clk <= 1000000) // min delay is 1000 us if timer clock source is <= 1 MHz + { + if(u32Usec < 1000) + u32Usec = 1000; + if(u32Usec > 1000000) + u32Usec = 1000000; + } + else + { + if(u32Usec < 100) + u32Usec = 100; + if(u32Usec > 1000000) + u32Usec = 1000000; + } + + if(u32Clk <= 1000000) + { + u32Prescale = 0; + u32NsecPerTick = 1000000000 / u32Clk; + u32Cmpr = (u32Usec * 1000) / u32NsecPerTick; + } + else + { + if(u32Clk > 64000000) + { + u32Prescale = 7; // real prescaler value is 8 + u32Clk >>= 3; + } + else if(u32Clk > 32000000) + { + u32Prescale = 3; // real prescaler value is 4 + u32Clk >>= 2; + } + else if(u32Clk > 16000000) + { + u32Prescale = 1; // real prescaler value is 2 + u32Clk >>= 1; + } + + if(u32Usec < 250) + { + u32Cmpr = (u32Usec * u32Clk) / 1000000; + } + else + { + u32NsecPerTick = 1000000000 / u32Clk; + u32Cmpr = (u32Usec * 1000) / u32NsecPerTick; + } + } + + timer->CMP = u32Cmpr; + timer->CTL = TIMER_CTL_CNTEN_Msk | TIMER_ONESHOT_MODE | u32Prescale; + + // When system clock is faster than timer clock, it is possible timer active bit cannot set in time while we check it. + // And the while loop below return immediately, so put a tiny delay here allowing timer start counting and raise active flag. + for(; delay > 0; delay--) + { + __NOP(); + } + + while(timer->CTL & TIMER_CTL_ACTSTS_Msk); +} + +/** + * @brief Enable Timer Capture Function + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * @param[in] u32CapMode Timer capture mode. Could be + * - \ref TIMER_CAPTURE_FREE_COUNTING_MODE + * - \ref TIMER_CAPTURE_COUNTER_RESET_MODE + * @param[in] u32Edge Timer capture trigger edge. Possible values are + * - \ref TIMER_CAPTURE_FALLING_EDGE + * - \ref TIMER_CAPTURE_RISING_EDGE + * - \ref TIMER_CAPTURE_FALLING_AND_RISING_EDGE + * + * @return None + * + * @details This API is used to enable timer capture function with specify capture trigger edge \n + * to get current counter value or reset counter value to 0. + * @note Timer frequency should be configured separately by using \ref TIMER_Open API, or program registers directly. + */ +void TIMER_EnableCapture(TIMER_T *timer, uint32_t u32CapMode, uint32_t u32Edge) +{ + + timer->EXTCTL = (timer->EXTCTL & ~(TIMER_EXTCTL_CAPFUNCS_Msk | TIMER_EXTCTL_CAPEDGE_Msk)) | + u32CapMode | u32Edge | TIMER_EXTCTL_CAPEN_Msk; +} + +/** + * @brief Disable Timer Capture Function + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This API is used to disable the timer capture function. + */ +void TIMER_DisableCapture(TIMER_T *timer) +{ + timer->EXTCTL &= ~TIMER_EXTCTL_CAPEN_Msk; +} + +/** + * @brief Enable Timer Counter Function + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * @param[in] u32Edge Detection edge of counter pin. Could be ether + * - \ref TIMER_COUNTER_FALLING_EDGE, or + * - \ref TIMER_COUNTER_RISING_EDGE + * + * @return None + * + * @details This function is used to enable the timer counter function with specify detection edge. + * @note Timer compare value should be configured separately by using \ref TIMER_SET_CMP_VALUE macro or program registers directly. + * @note While using event counter function, \ref TIMER_TOGGLE_MODE cannot set as timer operation mode. + */ +void TIMER_EnableEventCounter(TIMER_T *timer, uint32_t u32Edge) +{ + timer->EXTCTL = (timer->EXTCTL & ~TIMER_EXTCTL_CNTPHASE_Msk) | u32Edge; + timer->CTL |= TIMER_CTL_EXTCNTEN_Msk; +} + +/** + * @brief Disable Timer Counter Function + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return None + * + * @details This API is used to disable the timer event counter function. + */ +void TIMER_DisableEventCounter(TIMER_T *timer) +{ + timer->CTL &= ~TIMER_CTL_EXTCNTEN_Msk; +} + +/** + * @brief Get Timer Clock Frequency + * + * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. + * + * @return Timer clock frequency + * + * @details This API is used to get the timer clock frequency. + * @note This API cannot return correct clock rate if timer source is from external clock input. + */ +uint32_t TIMER_GetModuleClock(TIMER_T *timer) +{ + uint32_t u32Src; + const uint32_t au32Clk[] = {__HXT, __LXT, 0, 0, 0, __LIRC, 0, __HIRC}; + + if(timer == TIMER0) + u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR0SEL_Msk) >> CLK_CLKSEL1_TMR0SEL_Pos; + else if(timer == TIMER1) + u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR1SEL_Msk) >> CLK_CLKSEL1_TMR1SEL_Pos; + else if(timer == TIMER2) + u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR2SEL_Msk) >> CLK_CLKSEL1_TMR2SEL_Pos; + else // Timer 3 + u32Src = (CLK->CLKSEL1 & CLK_CLKSEL1_TMR3SEL_Msk) >> CLK_CLKSEL1_TMR3SEL_Pos; + + if(u32Src == 2) + { + return (SystemCoreClock); + } + + return (au32Clk[u32Src]); +} + +/*@}*/ /* end of group TIMER_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group TIMER_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/tk.c b/StdDriver/src/tk.c new file mode 100644 index 0000000..4dcd0dc --- /dev/null +++ b/StdDriver/src/tk.c @@ -0,0 +1,265 @@ +/**************************************************************************//** + * @file tk.c + * @version V1.00 + * $Revision: 6 $ + * $Date: 15/08/24 4:54p $ + * @brief M451 series TK driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. + * +*****************************************************************************/ +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup TK_Driver TK Driver + @{ +*/ + + +/** @addtogroup TK_EXPORTED_FUNCTIONS TK Exported Functions + @{ +*/ + + +/** + * @brief Enable touch key function + * @param None + * @return None + * @note This function will enable touch key function and initial idle and polarity state as GND first for all scan keys + * \hideinitializer + */ + +void TK_Open(void) +{ + TK->CTL |= TK_CTL_TKEN_Msk; + //set idle and polarity state as GND + TK->IDLESEL = 0; + TK->POLSEL = 0; + TK->POLCTL &= ~(TK_POLCTL_IDLS16_Msk | TK_POLCTL_POLSEL16_Msk); +} + +/** + * @brief Disable touch key function + * @param None + * @return None + * \hideinitializer + */ +void TK_Close(void) +{ + TK->CTL &= ~TK_CTL_TKEN_Msk; +} + +/** + * @brief Set touch key scan mode + * @param[in] u32Mode Single ,periodic or all key scan mode + * - \ref TK_SCAN_MODE_SINGLE + * - \ref TK_SCAN_MODE_PERIODIC + * - \ref TK_SCAN_MODE_ALL_KEY + * - \ref TK_SCAN_MODE_PERIODIC_ALL_KEY + * @return None + * @details This function is used to set touch key scan mode. + * @note If touch key controller sets as periodic mode, touch key will be trigger scan by Timer0. So Timer0 must be enabled and operated in periodic mode. + * If touch key controller sets as single scan mode, touch key can be trigger scan by calling TK_START_SCAN(). + * \hideinitializer + */ +void TK_SetScanMode(uint32_t u32Mode) +{ + TK->CTL &= ~TK_CTL_TMRTRGEN_Msk; + TK->REFCTL &= ~TK_REFCTL_SCANALL_Msk; + if(u32Mode == TK_SCAN_MODE_PERIODIC) + { + TK->CTL |= u32Mode; + } + else if(u32Mode == TK_SCAN_MODE_ALL_KEY) + { + TK->REFCTL |= u32Mode; + } + else if(u32Mode == TK_SCAN_MODE_PERIODIC_ALL_KEY) + { + TK->CTL |= TK_CTL_TMRTRGEN_Msk; + TK->REFCTL |= TK_REFCTL_SCANALL_Msk; + } +} + +/** + * @brief Configure touch key scan sensitivity + * @param[in] u32PulseWidth Sensing pulse width + * - \ref TK_SENSE_PULSE_1 + * - \ref TK_SENSE_PULSE_2 + * - \ref TK_SENSE_PULSE_4 + * - \ref TK_SENSE_PULSE_8 + * @param[in] u32SenseCnt Sensing count + * - \ref TK_SENSE_CNT_128 + * - \ref TK_SENSE_CNT_255 + * - \ref TK_SENSE_CNT_511 + * - \ref TK_SENSE_CNT_1023 + * @param[in] u32AVCCHSel voltage selection + * - \ref TK_AVCCH_1_DIV_16 + * - \ref TK_AVCCH_1_DIV_8 + * - \ref TK_AVCCH_3_DIV_16 + * - \ref TK_AVCCH_1_DIV_4 + * - \ref TK_AVCCH_5_DIV_16 + * - \ref TK_AVCCH_3_DIV_8 + * - \ref TK_AVCCH_7_DIV_16 + * - \ref TK_AVCCH_1_DIV_2 + * @return None + * @details This function is used to configure touch key scan sensitivity. + * \hideinitializer + */ +void TK_ConfigSensitivity(uint32_t u32PulseWidth, uint32_t u32SenseCnt, uint32_t u32AVCCHSel) +{ + TK->REFCTL = (TK->REFCTL & ~(TK_REFCTL_SENPTCTL_Msk | TK_REFCTL_SENTCTL_Msk)) | (u32PulseWidth | u32SenseCnt); + TK->CTL = (TK->CTL & ~TK_CTL_AVCCHSEL_Msk) | u32AVCCHSel; +} + +/** + * @brief Set touch key capacitor bank polarity + * @param[in] u32CapBankPolSel capacitor bank polarity selection + * - \ref TK_CAP_BANK_POL_SEL_GND + * - \ref TK_CAP_BANK_POL_SEL_AVCCH + * - \ref TK_CAP_BANK_POL_SEL_VDD + * @return None + * @details This function is used to set touch key capacitor bank polarity. + * \hideinitializer + */ +void TK_SetCapBankPol(uint32_t u32CapBankPolSel) +{ + TK->POLCTL = (TK->POLCTL & ~TK_POLCTL_CBPOLSEL_Msk) | u32CapBankPolSel; +} + +/** + * @brief Configure touch key polarity + * @param[in] u32Mask Combination of touch keys which need to be configured + * @param[in] u32TKnPolSel touch key polarity selection + * - \ref TK_TKn_POL_SEL_GND + * - \ref TK_TKn_POL_SEL_AVCCH + * - \ref TK_TKn_POL_SEL_VDD + * @return None + * @details This function is used to configure touch key polarity. + * \hideinitializer + */ +void TK_SetTkPol(uint32_t u32Mask, uint32_t u32PolSel) +{ + uint32_t i; + + if((1ul << 16) & u32Mask) + TK->POLCTL = (TK->POLCTL & ~TK_POLCTL_POLSEL16_Msk) | (u32PolSel << TK_POLCTL_POLSEL16_Pos); + + for(i = 0 ; i < 16 ; i++) + { + if((1ul << i) & u32Mask) + TK->POLSEL = (TK->POLSEL & ~(TK_POLSEL_POLSELn_Msk << (i*2))) | (u32PolSel << (i*2)); + } +} + +/** + * @brief Enable the polarity of specified touch key(s) + * @param[in] u32Mask Combination of enabled scan keys. Each bit corresponds to a touch key + * Bit 0 represents touch key 0, bit 1 represents touch key 1... + * @return None + * @details This function is used to enable the polarity of specified touch key(s). + * \hideinitializer + */ +void TK_EnableTkPolarity(uint32_t u32Mask) +{ + TK->POLCTL |= (u32Mask << TK_POLCTL_POLEN0_Pos); +} + +/** + * @brief Disable the polarity of specified touch key(s) + * @param[in] u32Mask Combination of enabled scan keys. Each bit corresponds to a touch key + * Bit 0 represents touch key 0, bit 1 represents touch key 1... + * @return None + * @details This function is used to disable the polarity of specified touch key(s). + * \hideinitializer + */ +void TK_DisableTkPolarity(uint32_t u32Mask) +{ + TK->POLCTL &= ~(u32Mask << TK_POLCTL_POLEN0_Pos); +} + +/** + * @brief Set complement capacitor bank data of specified touch key + * @param[in] u32TKNum Touch key number. The valid value is 0~16. + * @param[in] u32CapData Complement capacitor bank data. The valid value is 0~0xFF. + * @return None + * @details This function is used to set complement capacitor bank data of specified touch key. + * \hideinitializer + */ +void TK_SetCompCapBankData(uint32_t u32TKNum, uint32_t u32CapData) +{ + *(__IO uint32_t *)(&(TK->CCBDAT0) + (u32TKNum >> 2)) &= ~(TK_CCBDAT0_CCBDAT0_Msk << (u32TKNum % 4 * 8)); + *(__IO uint32_t *)(&(TK->CCBDAT0) + (u32TKNum >> 2)) |= (u32CapData << (u32TKNum % 4 * 8)); +} + +/** + * @brief Set complement capacitor bank data of reference touch key + * @param[in] u32CapData Complement capacitor bank data. The valid value is 0~0xFF. + * @return None + * @details This function is used to set complement capacitor bank data of reference touch key. + * \hideinitializer + */ +void TK_SetRefKeyCapBankData(uint32_t u32CapData) +{ + TK->CCBDAT4 = (TK->CCBDAT4 & ~TK_CCBDAT4_REFCBDAT_Msk) | (u32CapData << TK_CCBDAT4_REFCBDAT_Pos); +} + +/** + * @brief Set high and low threshold of specified touch key for threshold control interrupt + * @param[in] u32TKNum Touch key number. The valid value is 0~16. + * @param[in] u32HighLevel High level for touch key threshold control. The valid value is 0~0xFF. + * @param[in] u32LowLevel Low level for touch key threshold control. The valid value is 0~0xFF. + * @return None + * @details This function is used to set high and low threshold of specified touch key for threshold control interrupt. + * \hideinitializer + */ +void TK_SetScanThreshold(uint32_t u32TKNum, uint32_t u32HighLevel, uint32_t u32LowLevel) +{ + *(__IO uint32_t *)(&(TK->TH0_1) + (u32TKNum >> 1)) &= ~((TK_TH0_1_HTH0_Msk | TK_TH0_1_LTH0_Msk) << (u32TKNum % 2 * 16)); + *(__IO uint32_t *)(&(TK->TH0_1) + (u32TKNum >> 1)) |= ((u32HighLevel << TK_TH0_1_HTH0_Pos) | (u32LowLevel << TK_TH0_1_LTH0_Pos)) << (u32TKNum % 2 * 16); +} + +/** + * @brief Enable touch key scan interrupt + * @param[in] u32Msk Interrupt type selection. + * - \ref TK_INT_EN_SCAN_COMPLETE + * - \ref TK_INT_EN_SCAN_COMPLETE_EDGE_TH + * - \ref TK_INT_EN_SCAN_COMPLETE_LEVEL_TH + * @return None + * @details This function is used to enable touch key scan interrupt. + * @note It need disable the enabled interrupt type first by TK_DisableInt() before to change enabled interrupt type. + * \hideinitializer + */ +void TK_EnableInt(uint32_t u32Msk) +{ + TK->INTEN |= u32Msk; +} + +/** + * @brief Disable touch key scan interrupt + * @param[in] u32Msk Interrupt type selection. + * - \ref TK_INT_EN_SCAN_COMPLETE + * - \ref TK_INT_EN_SCAN_COMPLETE_EDGE_TH + * - \ref TK_INT_EN_SCAN_COMPLETE_LEVEL_TH + * @return None + * @details This function is used to disable touch key scan interrupt. +* @note It need disable the enabled interrupt type first by TK_DisableInt() before to change enabled interrupt type. + * \hideinitializer + */ +void TK_DisableInt(uint32_t u32Msk) +{ + TK->INTEN &= ~u32Msk; +} + + +/*@}*/ /* end of group TK_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group TK_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/uart.c b/StdDriver/src/uart.c new file mode 100644 index 0000000..b044608 --- /dev/null +++ b/StdDriver/src/uart.c @@ -0,0 +1,512 @@ +/**************************************************************************//** + * @file uart.c + * @version V3.00 + * $Revision: 23 $ + * $Date: 16/03/04 9:14a $ + * @brief M451 series UART driver source file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ + +#include +#include "M451Series.h" + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup UART_Driver UART Driver + @{ +*/ + +/** @addtogroup UART_EXPORTED_FUNCTIONS UART Exported Functions + @{ +*/ + +/** + * @brief Clear UART specified interrupt flag + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] u32InterruptFlag The specified interrupt of UART module. + * - \ref UART_INTSTS_LININT_Msk : LIN bus interrupt + * - \ref UART_INTSTS_DATWKIF_Msk : Data Wake-up interrupt + * - \ref UART_INTSTS_CTSWKIF_Msk : CTS Wake-up interrupt + * - \ref UART_INTSTS_BUFERRINT_Msk : Buffer Error interrupt + * - \ref UART_INTSTS_MODEMINT_Msk : Modem Status interrupt + * - \ref UART_INTSTS_RLSINT_Msk : Receive Line Status interrupt + * + * @return None + * + * @details The function is used to clear UART specified interrupt flag. + */ + +void UART_ClearIntFlag(UART_T* uart , uint32_t u32InterruptFlag) +{ + + if(u32InterruptFlag & UART_INTSTS_RLSINT_Msk) /* Clear Receive Line Status Interrupt */ + { + uart->FIFOSTS = UART_FIFOSTS_BIF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_PEF_Msk; + uart->FIFOSTS = UART_FIFOSTS_ADDRDETF_Msk; + } + + if(u32InterruptFlag & UART_INTSTS_MODEMINT_Msk) /* Clear Modem Status Interrupt */ + uart->MODEMSTS |= UART_MODEMSTS_CTSDETF_Msk; + + if(u32InterruptFlag & UART_INTSTS_BUFERRINT_Msk) /* Clear Buffer Error Interrupt */ + { + uart->FIFOSTS = UART_FIFOSTS_RXOVIF_Msk | UART_FIFOSTS_TXOVIF_Msk; + } + + if(u32InterruptFlag & UART_INTSTS_CTSWKIF_Msk) /* Clear CTS Wake-up Interrupt */ + { + uart->INTSTS = UART_INTSTS_CTSWKIF_Msk; + } + + if(u32InterruptFlag & UART_INTSTS_DATWKIF_Msk) /* Clear Data Wake-up Interrupt */ + { + uart->INTSTS = UART_INTSTS_DATWKIF_Msk; + } + + if(u32InterruptFlag & UART_INTSTS_LININT_Msk) /* Clear LIN Bus Interrupt */ + { + uart->INTSTS = UART_INTSTS_LINIF_Msk; + uart->LINSTS = UART_LINSTS_BITEF_Msk | UART_LINSTS_BRKDETF_Msk | + UART_LINSTS_SLVSYNCF_Msk | UART_LINSTS_SLVIDPEF_Msk | + UART_LINSTS_SLVHEF_Msk | UART_LINSTS_SLVHDETF_Msk ; + } +} + + +/** + * @brief Disable UART interrupt + * + * @param[in] uart The pointer of the specified UART module. + * + * @return None + * + * @details The function is used to disable UART interrupt. + */ +void UART_Close(UART_T* uart) +{ + uart->INTEN = 0; +} + + +/** + * @brief Disable UART auto flow control function + * + * @param[in] uart The pointer of the specified UART module. + * + * @return None + * + * @details The function is used to disable UART auto flow control. + */ +void UART_DisableFlowCtrl(UART_T* uart) +{ + uart->INTEN &= ~(UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk); +} + + +/** + * @brief Disable UART specified interrupt + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] u32InterruptFlag The specified interrupt of UART module. + * - \ref UART_INTEN_WKCTSIEN_Msk : CTS wake-up interrupt + * - \ref UART_INTEN_WKDATIEN_Msk : Data wake-up interrupt + * - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt + * - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt + * - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt + * - \ref UART_INTEN_MODEMIEN_Msk : Modem status interrupt + * - \ref UART_INTEN_RLSIEN_Msk : Receive Line status interrupt + * - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt + * - \ref UART_INTEN_RDAIEN_Msk : Rx ready interrupt * + * + * @return None + * + * @details The function is used to disable UART specified interrupt and disable NVIC UART IRQ. + */ +void UART_DisableInt(UART_T* uart, uint32_t u32InterruptFlag) +{ + /* Disable UART specified interrupt */ + UART_DISABLE_INT(uart, u32InterruptFlag); + + /* Disable NVIC UART IRQ */ + if(uart == UART0) + NVIC_DisableIRQ(UART0_IRQn); + else if(uart == UART1) + NVIC_DisableIRQ(UART1_IRQn); + else if(uart == UART2) + NVIC_DisableIRQ(UART2_IRQn); + else + NVIC_DisableIRQ(UART3_IRQn); +} + + +/** + * @brief Enable UART auto flow control function + * + * @param[in] uart The pointer of the specified UART module. + * + * @return None + * + * @details The function is used to Enable UART auto flow control. + */ +void UART_EnableFlowCtrl(UART_T* uart) +{ + /* Set RTS pin output is low level active */ + uart->MODEM |= UART_MODEM_RTSACTLV_Msk; + + /* Set CTS pin input is low level active */ + uart->MODEMSTS |= UART_MODEMSTS_CTSACTLV_Msk; + + /* Set RTS and CTS auto flow control enable */ + uart->INTEN |= UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk; +} + + +/** + * @brief The function is used to enable UART specified interrupt and enable NVIC UART IRQ. + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] u32InterruptFlag The specified interrupt of UART module: + * - \ref UART_INTEN_WKCTSIEN_Msk : CTS wake-up interrupt + * - \ref UART_INTEN_WKDATIEN_Msk : Data wake-up interrupt + * - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt + * - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt + * - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt + * - \ref UART_INTEN_MODEMIEN_Msk : Modem status interrupt + * - \ref UART_INTEN_RLSIEN_Msk : Receive Line status interrupt + * - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt + * - \ref UART_INTEN_RDAIEN_Msk : Rx ready interrupt * + * + * @return None + * + * @details The function is used to enable UART specified interrupt and enable NVIC UART IRQ. + */ +void UART_EnableInt(UART_T* uart, uint32_t u32InterruptFlag) +{ + + /* Enable UART specified interrupt */ + UART_ENABLE_INT(uart, u32InterruptFlag); + + /* Enable NVIC UART IRQ */ + if(uart == UART0) + NVIC_EnableIRQ(UART0_IRQn); + else if(uart == UART1) + NVIC_EnableIRQ(UART1_IRQn); + else if(uart == UART2) + NVIC_EnableIRQ(UART2_IRQn); + else + NVIC_EnableIRQ(UART3_IRQn); + +} + + +/** + * @brief Open and set UART function + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] u32baudrate The baudrate of UART module. + * + * @return None + * + * @details This function use to enable UART function and set baud-rate. + */ +void UART_Open(UART_T* uart, uint32_t u32baudrate) +{ + uint8_t u8UartClkSrcSel, u8UartClkDivNum; + uint32_t u32ClkTbl[4] = {__HXT, 0, __LXT, __HIRC}; + uint32_t u32Baud_Div = 0; + + /* Get UART clock source selection */ + u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UARTSEL_Msk) >> CLK_CLKSEL1_UARTSEL_Pos; + + /* Get UART clock divider number */ + u8UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UARTDIV_Msk) >> CLK_CLKDIV0_UARTDIV_Pos; + + /* Select UART function */ + uart->FUNCSEL = UART_FUNCSEL_UART; + + /* Set UART line configuration */ + uart->LINE = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1; + + /* Set UART Rx and RTS trigger level */ + uart->FIFO &= ~(UART_FIFO_RFITL_Msk | UART_FIFO_RTSTRGLV_Msk); + + /* Get PLL clock frequency if UART clock source selection is PLL */ + if(u8UartClkSrcSel == 1) + u32ClkTbl[u8UartClkSrcSel] = CLK_GetPLLClockFreq(); + + /* Set UART baud rate */ + if(u32baudrate != 0) + { + u32Baud_Div = UART_BAUD_MODE2_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate); + + if(u32Baud_Div > 0xFFFF) + uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate)); + else + uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div); + } +} + + +/** + * @brief Read UART data + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] pu8RxBuf The buffer to receive the data of receive FIFO. + * @param[in] u32ReadBytes The the read bytes number of data. + * + * @return u32Count Receive byte count + * + * @details The function is used to read Rx data from RX FIFO and the data will be stored in pu8RxBuf. + */ +uint32_t UART_Read(UART_T* uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes) +{ + uint32_t u32Count, u32delayno; + + for(u32Count = 0; u32Count < u32ReadBytes; u32Count++) + { + u32delayno = 0; + + while(uart->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) /* Check RX empty => failed */ + { + u32delayno++; + if(u32delayno >= 0x40000000) + return FALSE; + } + pu8RxBuf[u32Count] = uart->DAT; /* Get Data from UART RX */ + } + + return u32Count; + +} + + +/** + * @brief Set UART line configuration + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] u32baudrate The register value of baudrate of UART module. + * If u32baudrate = 0, UART baudrate will not change. + * @param[in] u32data_width The data length of UART module. + * - \ref UART_WORD_LEN_5 + * - \ref UART_WORD_LEN_6 + * - \ref UART_WORD_LEN_7 + * - \ref UART_WORD_LEN_8 + * @param[in] u32parity The parity setting (none/odd/even/mark/space) of UART module. + * - \ref UART_PARITY_NONE + * - \ref UART_PARITY_ODD + * - \ref UART_PARITY_EVEN + * - \ref UART_PARITY_MARK + * - \ref UART_PARITY_SPACE + * @param[in] u32stop_bits The stop bit length (1/1.5/2 bit) of UART module. + * - \ref UART_STOP_BIT_1 + * - \ref UART_STOP_BIT_1_5 + * - \ref UART_STOP_BIT_2 + * + * @return None + * + * @details This function use to config UART line setting. + */ +void UART_SetLine_Config(UART_T* uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits) +{ + uint8_t u8UartClkSrcSel, u8UartClkDivNum; + uint32_t u32ClkTbl[4] = {__HXT, 0, __LXT, __HIRC}; + uint32_t u32Baud_Div = 0; + + /* Get UART clock source selection */ + u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UARTSEL_Msk) >> CLK_CLKSEL1_UARTSEL_Pos; + + /* Get UART clock divider number */ + u8UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UARTDIV_Msk) >> CLK_CLKDIV0_UARTDIV_Pos; + + /* Get PLL clock frequency if UART clock source selection is PLL */ + if(u8UartClkSrcSel == 1) + u32ClkTbl[u8UartClkSrcSel] = CLK_GetPLLClockFreq(); + + /* Set UART baud rate */ + if(u32baudrate != 0) + { + u32Baud_Div = UART_BAUD_MODE2_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate); + + if(u32Baud_Div > 0xFFFF) + uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate)); + else + uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div); + } + + /* Set UART line configuration */ + uart->LINE = u32data_width | u32parity | u32stop_bits; +} + + +/** + * @brief Set Rx timeout count + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] u32TOC Rx timeout counter. + * + * @return None + * + * @details This function use to set Rx timeout count. + */ +void UART_SetTimeoutCnt(UART_T* uart, uint32_t u32TOC) +{ + /* Set time-out interrupt comparator */ + uart->TOUT = (uart->TOUT & ~UART_TOUT_TOIC_Msk) | (u32TOC); + + /* Set time-out counter enable */ + uart->INTEN |= UART_INTEN_TOCNTEN_Msk; +} + + +/** + * @brief Select and configure IrDA function + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] u32Buadrate The baudrate of UART module. + * @param[in] u32Direction The direction of UART module in IrDA mode: + * - \ref UART_IRDA_TXEN + * - \ref UART_IRDA_RXEN + * + * @return None + * + * @details The function is used to configure IrDA relative settings. It consists of TX or RX mode and baudrate. + */ +void UART_SelectIrDAMode(UART_T* uart, uint32_t u32Buadrate, uint32_t u32Direction) +{ + uint8_t u8UartClkSrcSel, u8UartClkDivNum; + uint32_t u32ClkTbl[4] = {__HXT, 0, __LXT, __HIRC}; + uint32_t u32Baud_Div; + + /* Select IrDA function mode */ + uart->FUNCSEL = UART_FUNCSEL_IrDA; + + /* Get UART clock source selection */ + u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UARTSEL_Msk) >> CLK_CLKSEL1_UARTSEL_Pos; + + /* Get UART clock divider number */ + u8UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UARTDIV_Msk) >> CLK_CLKDIV0_UARTDIV_Pos; + + /* Get PLL clock frequency if UART clock source selection is PLL */ + if(u8UartClkSrcSel == 1) + u32ClkTbl[u8UartClkSrcSel] = CLK_GetPLLClockFreq(); + + /* Set UART IrDA baud rate in mode 0 */ + if(u32Buadrate != 0) + { + u32Baud_Div = UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32Buadrate); + + if(u32Baud_Div < 0xFFFF) + uart->BAUD = (UART_BAUD_MODE0 | u32Baud_Div); + } + + /* Configure IrDA relative settings */ + if(u32Direction == UART_IRDA_RXEN) + { + uart->IRDA |= UART_IRDA_RXINV_Msk; //Rx signal is inverse + uart->IRDA &= ~UART_IRDA_TXEN_Msk; + } + else + { + uart->IRDA &= ~UART_IRDA_TXINV_Msk; //Tx signal is not inverse + uart->IRDA |= UART_IRDA_TXEN_Msk; + } + +} + + +/** + * @brief Select and configure RS485 function + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] u32Mode The operation mode(NMM/AUD/AAD). + * - \ref UART_ALTCTL_RS485NMM_Msk + * - \ref UART_ALTCTL_RS485AUD_Msk + * - \ref UART_ALTCTL_RS485AAD_Msk + * @param[in] u32Addr The RS485 address. + * + * @return None + * + * @details The function is used to set RS485 relative setting. + */ +void UART_SelectRS485Mode(UART_T* uart, uint32_t u32Mode, uint32_t u32Addr) +{ + /* Select UART RS485 function mode */ + uart->FUNCSEL = UART_FUNCSEL_RS485; + + /* Set RS585 configuration */ + uart->ALTCTL &= ~(UART_ALTCTL_RS485NMM_Msk | UART_ALTCTL_RS485AUD_Msk | UART_ALTCTL_RS485AAD_Msk | UART_ALTCTL_ADDRMV_Msk); + uart->ALTCTL |= (u32Mode | (u32Addr << UART_ALTCTL_ADDRMV_Pos)); +} + + +/** + * @brief Select and configure LIN function + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] u32Mode The LIN direction : + * - \ref UART_ALTCTL_LINTXEN_Msk + * - \ref UART_ALTCTL_LINRXEN_Msk + * @param[in] u32BreakLength The 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->FUNCSEL = UART_FUNCSEL_LIN; + + /* Select LIN function setting : Tx enable, Rx enable and break field length */ + uart->ALTCTL &= ~(UART_ALTCTL_LINTXEN_Msk | UART_ALTCTL_LINRXEN_Msk | UART_ALTCTL_BRKFL_Msk); + uart->ALTCTL |= (u32Mode | (u32BreakLength << UART_ALTCTL_BRKFL_Pos)); +} + + +/** + * @brief Write UART data + * + * @param[in] uart The pointer of the specified UART module. + * @param[in] pu8TxBuf The buffer to send the data to UART transmission FIFO. + * @param[out] u32WriteBytes The byte number of data. + * + * @return u32Count transfer byte count + * + * @details The function is to write data into TX buffer to transmit data by UART. + */ +uint32_t UART_Write(UART_T* uart, uint8_t *pu8TxBuf, uint32_t u32WriteBytes) +{ + uint32_t u32Count, u32delayno; + + for(u32Count = 0; u32Count != u32WriteBytes; u32Count++) + { + u32delayno = 0; + while((uart->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk) == 0) /* Wait Tx empty and Time-out manner */ + { + u32delayno++; + if(u32delayno >= 0x40000000) + return FALSE; + } + uart->DAT = pu8TxBuf[u32Count]; /* Send UART Data from buffer */ + } + + return u32Count; + +} + + +/*@}*/ /* end of group UART_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group UART_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2012~2015 Nuvoton Technology Corp. ***/ + + + diff --git a/StdDriver/src/usbd.c b/StdDriver/src/usbd.c new file mode 100644 index 0000000..1759b1c --- /dev/null +++ b/StdDriver/src/usbd.c @@ -0,0 +1,728 @@ +/**************************************************************************//** + * @file usbd.c + * @version V1.00 + * $Revision: 21 $ + * $Date: 15/08/21 3:34p $ + * @brief M451 series USBD driver source file + * + * @note + * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ + +#include +#include "M451Series.h" + +#if 0 +#define DBG_PRINTF printf +#else +#define DBG_PRINTF(...) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup USBD_Driver USBD Driver + @{ +*/ + + +/** @addtogroup USBD_EXPORTED_FUNCTIONS USBD Exported Functions + @{ +*/ + +/* Global variables for Control Pipe */ +uint8_t g_usbd_SetupPacket[8] = {0}; /*!< Setup packet buffer */ +volatile uint8_t g_usbd_RemoteWakeupEn = 0; /*!< Remote wake up function enable flag */ + +/** + * @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_UsbConfig = 0; +static volatile uint32_t g_usbd_CtrlMaxPktSize = 8; +static volatile uint32_t g_usbd_UsbAltInterface = 0; +/** + * @endcond + */ + +const S_USBD_INFO_T *g_usbd_sInfo; /*!< A pointer for USB information structure */ + +VENDOR_REQ g_usbd_pfnVendorRequest = NULL; /*!< USB Vendor Request Functional Pointer */ +CLASS_REQ g_usbd_pfnClassRequest = NULL; /*!< USB Class Request Functional Pointer */ +SET_INTERFACE_REQ g_usbd_pfnSetInterface = NULL; /*!< USB Set Interface Functional Pointer */ +SET_CONFIG_CB g_usbd_pfnSetConfigCallback = NULL; /*!< USB Set configuration callback function pointer */ +uint32_t g_u32EpStallLock = 0; /*!< Bit map flag to lock specified EP when SET_FEATURE */ + +/** + * @brief This function makes USBD module to be ready to use + * + * @param[in] param The structure of USBD information. + * @param[in] pfnClassReq USB Class request callback function. + * @param[in] pfnSetInterface USB Set Interface request callback function. + * + * @return None + * + * @details This function will enable USB controller, USB PHY transceiver and pull-up resistor of USB_D+ pin. USB PHY will drive SE0 to bus. + */ +void USBD_Open(const S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface) +{ + g_usbd_sInfo = param; + g_usbd_pfnClassRequest = pfnClassReq; + g_usbd_pfnSetInterface = pfnSetInterface; + + /* get EP0 maximum packet size */ + g_usbd_CtrlMaxPktSize = g_usbd_sInfo->gu8DevDesc[7]; + + /* Initial USB engine */ + USBD->ATTR = 0x7D0; + /* Force SE0 */ + USBD_SET_SE0(); +} + +/** + * @brief This function makes USB host to recognize the device + * + * @param None + * + * @return None + * + * @details Enable WAKEUP, FLDET, USB and BUS interrupts. Disable software-disconnect function after 100ms delay with SysTick timer. + */ +void USBD_Start(void) +{ + CLK_SysTickDelay(100000); + /* Disable software-disconnect function */ + USBD_CLR_SE0(); + + /* Clear USB-related interrupts before enable interrupt */ + USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); + + /* Enable USB-related interrupts. */ + USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); +} + +/** + * @brief Get the received SETUP packet + * + * @param[in] buf A buffer pointer used to store 8-byte SETUP packet. + * + * @return None + * + * @details Store SETUP packet to a user-specified buffer. + * + */ +void USBD_GetSetupPacket(uint8_t *buf) +{ + USBD_MemCopy(buf, g_usbd_SetupPacket, 8); +} + +/** + * @brief Process SETUP packet + * + * @param None + * + * @return None + * + * @details Parse SETUP packet and perform the corresponding action. + * + */ +void USBD_ProcessSetupPacket(void) +{ + /* Get SETUP packet from USB buffer */ + USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8); + /* Check the request type */ + switch(g_usbd_SetupPacket[0] & 0x60) + { + case REQ_STANDARD: // Standard + { + USBD_StandardRequest(); + break; + } + case REQ_CLASS: // Class + { + if(g_usbd_pfnClassRequest != NULL) + { + g_usbd_pfnClassRequest(); + } + break; + } + case REQ_VENDOR: // Vendor + { + if(g_usbd_pfnVendorRequest != NULL) + { + g_usbd_pfnVendorRequest(); + } + break; + } + default: // reserved + { + /* Setup error, stall the device */ + USBD_SET_EP_STALL(EP0); + USBD_SET_EP_STALL(EP1); + break; + } + } +} + +/** + * @brief Process GetDescriptor request + * + * @param None + * + * @return None + * + * @details Parse GetDescriptor request and perform the corresponding action. + * + */ +void USBD_GetDescriptor(void) +{ + uint32_t u32Len; + + u32Len = 0; + u32Len = g_usbd_SetupPacket[7]; + u32Len <<= 8; + u32Len += g_usbd_SetupPacket[6]; + + switch(g_usbd_SetupPacket[3]) + { + // Get Device Descriptor + case DESC_DEVICE: + { + u32Len = Minimum(u32Len, LEN_DEVICE); + DBG_PRINTF("Get device desc, %d\n", u32Len); + + USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8DevDesc, u32Len); + + break; + } + // Get Configuration Descriptor + case DESC_CONFIG: + { + uint32_t u32TotalLen; + + u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3]; + u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8); + + DBG_PRINTF("Get config desc len %d, acture len %d\n", u32Len, u32TotalLen); + u32Len = Minimum(u32Len, u32TotalLen); + DBG_PRINTF("Minimum len %d\n", u32Len); + + USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8ConfigDesc, u32Len); + + break; + } + // Get HID Descriptor + case DESC_HID: + { + /* CV3.0 HID Class Descriptor Test, + Need to indicate index of the HID Descriptor within gu8ConfigDescriptor, specifically HID Composite device. */ + uint32_t u32ConfigDescOffset; // u32ConfigDescOffset is configuration descriptor offset (HID descriptor start index) + u32Len = Minimum(u32Len, LEN_HID); + DBG_PRINTF("Get HID desc, %d\n", u32Len); + + u32ConfigDescOffset = g_usbd_sInfo->gu32ConfigHidDescIdx[g_usbd_SetupPacket[4]]; + USBD_PrepareCtrlIn((uint8_t *)&g_usbd_sInfo->gu8ConfigDesc[u32ConfigDescOffset], u32Len); + + break; + } + // Get Report Descriptor + case DESC_HID_RPT: + { + DBG_PRINTF("Get HID report, %d\n", u32Len); + + u32Len = Minimum(u32Len, g_usbd_sInfo->gu32HidReportSize[g_usbd_SetupPacket[4]]); + USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8HidReportDesc[g_usbd_SetupPacket[4]], u32Len); + 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]); + DBG_PRINTF("Get string desc %d\n", u32Len); + + USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]], u32Len); + + + break; + } + else + { + // Not support. Reply STALL. + USBD_SET_EP_STALL(EP0); + USBD_SET_EP_STALL(EP1); + + DBG_PRINTF("Unsupported string desc (%d). Stall ctrl pipe.\n", g_usbd_SetupPacket[2]); + + break; + } + } + default: + // Not support. Reply STALL. + USBD_SET_EP_STALL(EP0); + USBD_SET_EP_STALL(EP1); + + DBG_PRINTF("Unsupported get desc type. stall ctrl pipe\n"); + + break; + } +} + +/** + * @brief Process standard request + * + * @param None + * + * @return None + * + * @details Parse standard request and perform the corresponding action. + * + */ +void USBD_StandardRequest(void) +{ + + /* clear global variables for new request */ + g_usbd_CtrlInPointer = 0; + g_usbd_CtrlInSize = 0; + + if(g_usbd_SetupPacket[0] & 0x80) /* request data transfer direction */ + { + // Device to host + switch(g_usbd_SetupPacket[1]) + { + case GET_CONFIGURATION: + { + // Return current configuration setting + /* Data stage */ + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbConfig; + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 1); + /* Status stage */ + USBD_PrepareCtrlOut(0,0); + + DBG_PRINTF("Get configuration\n"); + + break; + } + case GET_DESCRIPTOR: + { + USBD_GetDescriptor(); + USBD_PrepareCtrlOut(0, 0); /* For status stage */ + break; + } + case GET_INTERFACE: + { + // Return current interface setting + /* Data stage */ + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbAltInterface; + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 1); + /* Status stage */ + USBD_PrepareCtrlOut(0, 0); + + DBG_PRINTF("Get interface\n"); + + break; + } + case GET_STATUS: + { + // Device + if(g_usbd_SetupPacket[0] == 0x80) + { + uint8_t u8Tmp; + + u8Tmp = 0; + if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x40) u8Tmp |= 1; // Self-Powered/Bus-Powered. + if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x20) u8Tmp |= (g_usbd_RemoteWakeupEn << 1); // Remote wake up + + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = u8Tmp; + + } + // Interface + else if(g_usbd_SetupPacket[0] == 0x81) + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0; + // Endpoint + else if(g_usbd_SetupPacket[0] == 0x82) + { + uint8_t ep = g_usbd_SetupPacket[4] & 0xF; + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = USBD_GetStall(ep) ? 1 : 0; + } + + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0) + 1) = 0; + /* Data stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 2); + /* Status stage */ + USBD_PrepareCtrlOut(0, 0); + + DBG_PRINTF("Get status\n"); + + break; + } + default: + { + /* Setup error, stall the device */ + USBD_SET_EP_STALL(EP0); + USBD_SET_EP_STALL(EP1); + + DBG_PRINTF("Unknown request. stall ctrl pipe.\n"); + + break; + } + } + } + else + { + // Host to device + switch(g_usbd_SetupPacket[1]) + { + case CLEAR_FEATURE: + { + if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) + { + int32_t epNum, i; + + /* EP number stall is not allow to be clear in MSC class "Error Recovery Test". + a flag: g_u32EpStallLock is added to support it */ + epNum = g_usbd_SetupPacket[4] & 0xF; + for(i = 0; i < USBD_MAX_EP; i++) + { + if(((USBD->EP[i].CFG & 0xF) == epNum) && ((g_u32EpStallLock & (1 << i)) == 0)) + { + USBD->EP[i].CFGP &= ~USBD_CFGP_SSTALL_Msk; + DBG_PRINTF("Clr stall ep%d %x\n", i, USBD->EP[i].CFGP); + } + } + } + else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP) + g_usbd_RemoteWakeupEn = 0; + + /* Status stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + + DBG_PRINTF("Clear feature op %d\n", g_usbd_SetupPacket[2]); + + break; + } + case SET_ADDRESS: + { + g_usbd_UsbAddr = g_usbd_SetupPacket[2]; + DBG_PRINTF("Set addr to %d\n", g_usbd_UsbAddr); + + // DATA IN for end of setup + /* Status Stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + + break; + } + case SET_CONFIGURATION: + { + g_usbd_UsbConfig = g_usbd_SetupPacket[2]; + + if(g_usbd_pfnSetConfigCallback) + g_usbd_pfnSetConfigCallback(); + + // DATA IN for end of setup + /* Status stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + + DBG_PRINTF("Set config to %d\n", g_usbd_UsbConfig); + + break; + } + case SET_FEATURE: + { + if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) + { + USBD_SetStall(g_usbd_SetupPacket[4] & 0xF); + DBG_PRINTF("Set feature. stall ep %d\n", g_usbd_SetupPacket[4] & 0xF); + } + else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP) + { + g_usbd_RemoteWakeupEn = 1; + DBG_PRINTF("Set feature. enable remote wakeup\n"); + } + + /* Status stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + + + + break; + } + case SET_INTERFACE: + { + g_usbd_UsbAltInterface = g_usbd_SetupPacket[2]; + if(g_usbd_pfnSetInterface != NULL) + g_usbd_pfnSetInterface(); + /* Status stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + + DBG_PRINTF("Set interface to %d\n", g_usbd_UsbAltInterface); + + break; + } + default: + { + /* Setup error, stall the device */ + USBD_SET_EP_STALL(EP0); + USBD_SET_EP_STALL(EP1); + + DBG_PRINTF("Unsupported request. stall ctrl pipe.\n"); + + break; + } + } + } +} + +/** + * @brief Prepare the first Control IN pipe + * + * @param[in] pu8Buf The pointer of data sent to USB host. + * @param[in] u32Size The IN transfer size. + * + * @return None + * + * @details Prepare data for Control IN transfer. + * + */ +void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size) +{ + DBG_PRINTF("Prepare Ctrl In %d\n", u32Size); + if(u32Size > g_usbd_CtrlMaxPktSize) + { + // Data size > MXPLD + g_usbd_CtrlInPointer = pu8Buf + g_usbd_CtrlMaxPktSize; + g_usbd_CtrlInSize = u32Size - g_usbd_CtrlMaxPktSize; + USBD_SET_DATA1(EP0); + USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, g_usbd_CtrlMaxPktSize); + USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize); + } + else + { + // Data size <= MXPLD + g_usbd_CtrlInPointer = 0; + g_usbd_CtrlInSize = 0; + USBD_SET_DATA1(EP0); + USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, u32Size); + USBD_SET_PAYLOAD_LEN(EP0, u32Size); + } +} + +/** + * @brief Repeat Control IN pipe + * + * @param None + * + * @return None + * + * @details This function processes the remained data of Control IN transfer. + * + */ +void USBD_CtrlIn(void) +{ + static uint8_t u8ZeroFlag = 0; + + DBG_PRINTF("Ctrl In Ack. residue %d\n", g_usbd_CtrlInSize); + if(g_usbd_CtrlInSize) + { + // Process remained data + if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize) + { + // Data size > MXPLD + USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize); + USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize); + g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize; + g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize; + } + else + { + // Data size <= MXPLD + USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlInSize); + USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlInSize); + if(g_usbd_CtrlInSize == g_usbd_CtrlMaxPktSize) + u8ZeroFlag = 1; + g_usbd_CtrlInPointer = 0; + g_usbd_CtrlInSize = 0; + } + } + else // No more data for IN token + { + // In ACK for Set address + if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == SET_ADDRESS)) + { + if((USBD_GET_ADDR() != g_usbd_UsbAddr) && (USBD_GET_ADDR() == 0)) + { + USBD_SET_ADDR(g_usbd_UsbAddr); + } + } + + /* For the case of data size is integral times maximum packet size */ + if(u8ZeroFlag) + { + USBD_SET_PAYLOAD_LEN(EP0, 0); + u8ZeroFlag = 0; + } + + DBG_PRINTF("Ctrl In done.\n"); + + } +} + +/** + * @brief Prepare the first Control OUT pipe + * + * @param[in] pu8Buf The pointer of data received from USB host. + * @param[in] u32Size The OUT transfer size. + * + * @return None + * + * @details This function is used to prepare the first Control OUT transfer. + * + */ +void USBD_PrepareCtrlOut(uint8_t *pu8Buf, uint32_t u32Size) +{ + g_usbd_CtrlOutPointer = pu8Buf; + g_usbd_CtrlOutSize = 0; + g_usbd_CtrlOutSizeLimit = u32Size; + USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize); +} + +/** + * @brief Repeat Control OUT pipe + * + * @param None + * + * @return None + * + * @details This function processes the successive Control OUT transfer. + * + */ +void USBD_CtrlOut(void) +{ + uint32_t u32Size; + + DBG_PRINTF("Ctrl Out Ack %d\n", g_usbd_CtrlOutSize); + + if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit) + { + u32Size = USBD_GET_PAYLOAD_LEN(EP1); + USBD_MemCopy((uint8_t *)g_usbd_CtrlOutPointer, (uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1), u32Size); + g_usbd_CtrlOutPointer += u32Size; + g_usbd_CtrlOutSize += u32Size; + + if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit) + USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize); + + } +} + +/** + * @brief Reset software flags + * + * @param None + * + * @return None + * + * @details This function resets all variables for protocol and resets USB device address to 0. + * + */ +void USBD_SwReset(void) +{ + int i; + + // Reset all variables for protocol + g_usbd_CtrlInPointer = 0; + g_usbd_CtrlInSize = 0; + g_usbd_CtrlOutPointer = 0; + g_usbd_CtrlOutSize = 0; + g_usbd_CtrlOutSizeLimit = 0; + g_u32EpStallLock = 0; + memset(g_usbd_SetupPacket, 0, 8); + + /* Reset PID DATA0 */ + for(i=0; iEP[i].CFG &= ~USBD_CFG_DSQSYNC_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; +} + +/** + * @brief The callback function which called when get SET CONFIGURATION request + * + * @param[in] pfnSetConfigCallback Callback function pointer for SET CONFIGURATION request + * + * @return None + * + * @details This function is used to set the callback function which will be called at SET CONFIGURATION request. + */ +void USBD_SetConfigCallback(SET_CONFIG_CB pfnSetConfigCallback) +{ + g_usbd_pfnSetConfigCallback = pfnSetConfigCallback; +} + + +/** + * @brief EP stall lock function to avoid stall clear by USB SET FEATURE request. + * + * @param[in] u32EpBitmap Use bitmap to select which endpoints will be locked + * + * @return None + * + * @details This function is used to lock relative endpoint to avoid stall clear by SET FEATURE requst. + * If ep stall locked, user needs to reset USB device or re-configure device to clear it. + */ +void USBD_LockEpStall(uint32_t u32EpBitmap) +{ + g_u32EpStallLock = u32EpBitmap; +} + + + + + +/*@}*/ /* end of group USBD_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group USBD_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +#ifdef __cplusplus +} +#endif + +/*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/usbd.c.new b/StdDriver/src/usbd.c.new new file mode 100644 index 0000000..8636834 --- /dev/null +++ b/StdDriver/src/usbd.c.new @@ -0,0 +1,723 @@ +/**************************************************************************//** + * @file usbd.c + * @version V1.00 + * $Revision: 14 $ + * $Date: 14/11/13 1:55p $ + * @brief M451 series USBD driver source file + * + * @note + * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ + +#include +#include "M451Series.h" + +#if 0 +#define DBG_PRINTF printf +#else +#define DBG_PRINTF(...) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @addtogroup M451_Device_Driver M451 Device Driver + @{ +*/ + +/** @addtogroup M451_USBD_Driver USBD Driver + @{ +*/ + + +/** @addtogroup M451_USBD_EXPORTED_FUNCTIONS USBD Exported Functions + @{ +*/ + +/* Global variables for Control Pipe */ +uint8_t g_usbd_SetupPacket[8] = {0}; /*!< Setup packet buffer */ +volatile uint8_t g_usbd_RemoteWakeupEn = 0; /*!< Remote wake up function enable flag */ + +/** + * @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_UsbConfig = 0; +static volatile uint32_t g_usbd_CtrlMaxPktSize = 8; +static volatile uint32_t g_usbd_UsbAltInterface = 0; +/** + * @endcond + */ + +const S_USBD_INFO_T *g_usbd_sInfo; /*!< A pointer for USB information structure */ + +VENDOR_REQ g_usbd_pfnVendorRequest = NULL; /*!< USB Vendor Request Functional Pointer */ +CLASS_REQ g_usbd_pfnClassRequest = NULL; /*!< USB Class Request Functional Pointer */ +SET_INTERFACE_REQ g_usbd_pfnSetInterface = NULL; /*!< USB Set Interface Functional Pointer */ +SET_CONFIG_CB g_usbd_pfnSetConfigCallback = NULL; /*!< USB Set configuration callback function pointer */ +uint32_t g_u32EpStallLock = 0; /*!< Bit map flag to lock specified EP when SET_FEATURE */ + +/** + * @brief This function makes USBD module to be ready to use + * + * @param[in] param The structure of USBD information. + * @param[in] pfnClassReq USB Class request callback function. + * @param[in] pfnSetInterface USB Set Interface request callback function. + * + * @return None + * + * @details This function will enable USB controller, USB PHY transceiver and pull-up resistor of USB_D+ pin. USB PHY will drive SE0 to bus. + */ +void USBD_Open(const S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface) +{ + g_usbd_sInfo = param; + g_usbd_pfnClassRequest = pfnClassReq; + g_usbd_pfnSetInterface = pfnSetInterface; + + /* get EP0 maximum packet size */ + g_usbd_CtrlMaxPktSize = g_usbd_sInfo->gu8DevDesc[7]; + + /* Initial USB engine */ + USBD->ATTR = 0x7D0; + /* Force SE0 */ + USBD_SET_SE0(); +} + +/** + * @brief This function makes USB host to recognize the device + * + * @param None + * + * @return None + * + * @details Enable WAKEUP, FLDET, USB and BUS interrupts. Disable software-disconnect function after 100ms delay with SysTick timer. + */ +void USBD_Start(void) +{ + CLK_SysTickDelay(100000); + /* Disable software-disconnect function */ + USBD_CLR_SE0(); + + /* Clear USB-related interrupts before enable interrupt */ + USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); + + /* Enable USB-related interrupts. */ + USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); +} + +/** + * @brief Get the received SETUP packet + * + * @param[in] buf A buffer used to store 8-byte SETUP packet. + * + * @return None + * + * @details Store SETUP packet to a user-specified buffer. + * + */ +void USBD_GetSetupPacket(uint8_t *buf) +{ + USBD_MemCopy(buf, g_usbd_SetupPacket, 8); +} + +/** + * @brief Process SETUP packet + * + * @param None + * + * @return None + * + * @details Parse SETUP packet and perform the corresponding action. + * + */ +void USBD_ProcessSetupPacket(void) +{ + /* Get SETUP packet from USB buffer */ + USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8); + /* Check the request type */ + switch(g_usbd_SetupPacket[0] & 0x60) + { + case REQ_STANDARD: // Standard + { + USBD_StandardRequest(); + break; + } + case REQ_CLASS: // Class + { + if(g_usbd_pfnClassRequest != NULL) + { + g_usbd_pfnClassRequest(); + } + break; + } + case REQ_VENDOR: // Vendor + { + if(g_usbd_pfnVendorRequest != NULL) + { + g_usbd_pfnVendorRequest(); + } + break; + } + default: // reserved + { + /* Setup error, stall the device */ + USBD_SET_EP_STALL(EP0); + USBD_SET_EP_STALL(EP1); + break; + } + } +} + +/** + * @brief Process GetDescriptor request + * + * @param None + * + * @return None + * + * @details Parse GetDescriptor request and perform the corresponding action. + * + */ +void USBD_GetDescriptor(void) +{ + uint32_t u32Len; + + u32Len = 0; + u32Len = g_usbd_SetupPacket[7]; + u32Len <<= 8; + u32Len += g_usbd_SetupPacket[6]; + + switch(g_usbd_SetupPacket[3]) + { + // Get Device Descriptor + case DESC_DEVICE: + { + u32Len = Minimum(u32Len, LEN_DEVICE); + DBG_PRINTF("Get device desc, %d\n", u32Len); + + USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8DevDesc, u32Len); + + break; + } + // Get Configuration Descriptor + case DESC_CONFIG: + { + uint32_t u32TotalLen; + + u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3]; + u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8); + + DBG_PRINTF("Get config desc len %d, actual len %d\n", u32Len, u32TotalLen); + u32Len = Minimum(u32Len, u32TotalLen); + DBG_PRINTF("Minimum len %d\n", u32Len); + + USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8ConfigDesc, u32Len); + + break; + } + // Get HID Descriptor + case DESC_HID: + { + u32Len = Minimum(u32Len, LEN_HID); + DBG_PRINTF("Get HID desc, %d\n", u32Len); + + USBD_PrepareCtrlIn((uint8_t *)&g_usbd_sInfo->gu8ConfigDesc[LEN_CONFIG + LEN_INTERFACE], u32Len); + + break; + } + // Get Report Descriptor + case DESC_HID_RPT: + { + uint32_t u32TotalLen; + uint32_t u32RptDescLen; + + + DBG_PRINTF("Get HID report, %d\n", u32Len); + + /* Get configuration descriptor size */ + u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3]; + u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8); + + /* Calculate the offset of HID report descriptor size to get report descriptor size. + User may need to modify this if configuration descriptor changed. */ + u32RptDescLen = g_usbd_sInfo->gu8ConfigDesc[u32TotalLen - LEN_ENDPOINT - 1]; + u32RptDescLen = g_usbd_sInfo->gu8ConfigDesc[u32TotalLen - LEN_ENDPOINT - 2] + (u32TotalLen << 8); + + u32Len = Minimum(u32Len, u32RptDescLen); + + USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8HidReportDesc, u32Len); + USBD_PrepareCtrlOut(0, 0); + break; + } + // Get String Descriptor + case DESC_STRING: + { + // Get String Descriptor + if(g_usbd_SetupPacket[2] < 4) + { + u32Len = Minimum(u32Len, g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]][0]); + DBG_PRINTF("Get string desc %d\n", u32Len); + + USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]], u32Len); + + + break; + } + else + { + // Not support. Reply STALL. + USBD_SET_EP_STALL(EP0); + USBD_SET_EP_STALL(EP1); + + DBG_PRINTF("Unsupported string desc (%d). Stall ctrl pipe.\n", g_usbd_SetupPacket[2]); + + break; + } + } + default: + // Not support. Reply STALL. + USBD_SET_EP_STALL(EP0); + USBD_SET_EP_STALL(EP1); + + DBG_PRINTF("Unsupported get desc type. stall ctrl pipe\n"); + + break; + } +} + +/** + * @brief Process standard request + * + * @param None + * + * @return None + * + * @details Parse standard request and perform the corresponding action. + * + */ +void USBD_StandardRequest(void) +{ + + /* clear global variables for new request */ + g_usbd_CtrlInPointer = 0; + g_usbd_CtrlInSize = 0; + + if(g_usbd_SetupPacket[0] & 0x80) /* request data transfer direction */ + { + // Device to host + switch(g_usbd_SetupPacket[1]) + { + case GET_CONFIGURATION: + { + // Return current configuration setting + /* Data stage */ + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbConfig; + USBD_SET_DATA1(EP1); + USBD_SET_PAYLOAD_LEN(EP1, 0); + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 1); + + DBG_PRINTF("Get configuration\n"); + + 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); + + DBG_PRINTF("Get interface\n"); + + break; + } + case GET_STATUS: + { + // Device + if(g_usbd_SetupPacket[0] == 0x80) + { + uint8_t u8Tmp; + + u8Tmp = 0; + if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x40) u8Tmp |= 1; // Self-Powered/Bus-Powered. + if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x20) u8Tmp |= (g_usbd_RemoteWakeupEn << 1); // Remote wake up + + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = u8Tmp; + + } + // Interface + else if(g_usbd_SetupPacket[0] == 0x81) + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0; + // Endpoint + else if(g_usbd_SetupPacket[0] == 0x82) + { + uint8_t ep = g_usbd_SetupPacket[4] & 0xF; + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = USBD_GetStall(ep) ? 1 : 0; + } + + M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0) + 1) = 0; + /* Data stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 2); + /* Status stage */ + USBD_PrepareCtrlOut(0, 0); + + DBG_PRINTF("Get status\n"); + + break; + } + default: + { + /* Setup error, stall the device */ + USBD_SET_EP_STALL(EP0); + USBD_SET_EP_STALL(EP1); + + DBG_PRINTF("Unknown request. stall ctrl pipe.\n"); + + break; + } + } + } + else + { + // Host to device + switch(g_usbd_SetupPacket[1]) + { + case CLEAR_FEATURE: + { + if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) + { + int32_t epNum, i; + + /* EP number stall is not allow to be clear in MSC class "Error Recovery Test". + a flag: g_u32EpStallLock is added to support it */ + epNum = g_usbd_SetupPacket[4] & 0xF; + for(i = 0; i < USBD_MAX_EP; i++) + { + if(((USBD->EP[i].CFG & 0xF) == epNum) && ((g_u32EpStallLock & (1 << i)) == 0)) + { + USBD->EP[i].CFGP &= ~USBD_CFGP_SSTALL_Msk; + DBG_PRINTF("Clr stall ep%d %x\n", i, USBD->EP[i].CFGP); + } + } + } + else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP) + g_usbd_RemoteWakeupEn = 0; + + /* Status stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + + DBG_PRINTF("Clear feature op %d\n", g_usbd_SetupPacket[2]); + + break; + } + case SET_ADDRESS: + { + g_usbd_UsbAddr = g_usbd_SetupPacket[2]; + DBG_PRINTF("Set addr to %d\n", g_usbd_UsbAddr); + + // DATA IN for end of setup + /* Status Stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + + break; + } + case SET_CONFIGURATION: + { + g_usbd_UsbConfig = g_usbd_SetupPacket[2]; + + if(g_usbd_pfnSetConfigCallback) + g_usbd_pfnSetConfigCallback(); + + // DATA IN for end of setup + /* Status stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + + DBG_PRINTF("Set config to %d\n", g_usbd_UsbConfig); + + break; + } + case SET_FEATURE: + { + if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) + { + USBD_SetStall(g_usbd_SetupPacket[4] & 0xF); + DBG_PRINTF("Set feature. stall ep %d\n", g_usbd_SetupPacket[4] & 0xF); + } + else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP) + { + g_usbd_RemoteWakeupEn = 1; + DBG_PRINTF("Set feature. enable remote wakeup\n"); + } + + /* Status stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + + + + break; + } + case SET_INTERFACE: + { + g_usbd_UsbAltInterface = g_usbd_SetupPacket[2]; + if(g_usbd_pfnSetInterface != NULL) + g_usbd_pfnSetInterface(); + /* Status stage */ + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + + DBG_PRINTF("Set interface to %d\n", g_usbd_UsbAltInterface); + + break; + } + default: + { + /* Setup error, stall the device */ + USBD_SET_EP_STALL(EP0); + USBD_SET_EP_STALL(EP1); + + DBG_PRINTF("Unsupported request. stall ctrl pipe.\n"); + + break; + } + } + } +} + +/** + * @brief Prepare the first Control IN pipe + * + * @param[in] pu8Buf The pointer of data sent to USB host. + * @param[in] u32Size The IN transfer size. + * + * @return None + * + * @details Prepare data for Control IN transfer. + * + */ +void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size) +{ + DBG_PRINTF("Prepare Ctrl In %d\n", u32Size); + if(u32Size > g_usbd_CtrlMaxPktSize) + { + // Data size > MXPLD + g_usbd_CtrlInPointer = pu8Buf + g_usbd_CtrlMaxPktSize; + g_usbd_CtrlInSize = u32Size - g_usbd_CtrlMaxPktSize; + USBD_SET_DATA1(EP0); + USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, g_usbd_CtrlMaxPktSize); + USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize); + } + else + { + // Data size <= MXPLD + g_usbd_CtrlInPointer = 0; + g_usbd_CtrlInSize = 0; + USBD_SET_DATA1(EP0); + USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, u32Size); + USBD_SET_PAYLOAD_LEN(EP0, u32Size); + } +} + +/** + * @brief Repeat Control IN pipe + * + * @param None + * + * @return None + * + * @details This function processes the remained data of Control IN transfer. + * + */ +void USBD_CtrlIn(void) +{ + DBG_PRINTF("Ctrl In Ack. residue %d\n", g_usbd_CtrlInSize); + if(g_usbd_CtrlInSize) + { + // Process remained data + if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize) + { + // Data size > MXPLD + USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize); + USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize); + g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize; + g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize; + } + else + { + // Data size <= MXPLD + USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlInSize); + USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlInSize); + g_usbd_CtrlInPointer = 0; + g_usbd_CtrlInSize = 0; + } + } + else + { + // In ACK for Set address + if((g_usbd_SetupPacket[0] == 0) && (g_usbd_SetupPacket[1] == 5)) + { + 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); + USBD_PrepareCtrlOut(0, 0); + DBG_PRINTF("Ctrl In done. Prepare OUT 0\n"); + + } +} + +/** + * @brief Prepare the first Control OUT pipe + * + * @param[in] pu8Buf The pointer of data received from USB host. + * @param[in] u32Size The OUT transfer size. + * + * @return None + * + * @details This function is used to prepare the first Control OUT transfer. + * + */ +void USBD_PrepareCtrlOut(uint8_t *pu8Buf, uint32_t u32Size) +{ + g_usbd_CtrlOutPointer = pu8Buf; + g_usbd_CtrlOutSize = 0; + g_usbd_CtrlOutSizeLimit = u32Size; + USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize); +} + +/** + * @brief Repeat Control OUT pipe + * + * @param None + * + * @return None + * + * @details This function processes the successive Control OUT transfer. + * + */ +void USBD_CtrlOut(void) +{ + uint32_t u32Size; + + DBG_PRINTF("Ctrl Out Ack %d\n", g_usbd_CtrlOutSize); + + if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit) + { + u32Size = USBD_GET_PAYLOAD_LEN(EP1); + USBD_MemCopy((uint8_t *)g_usbd_CtrlOutPointer, (uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1), u32Size); + g_usbd_CtrlOutPointer += u32Size; + g_usbd_CtrlOutSize += u32Size; + + if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit) + USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize); + + } +} + +/** + * @brief Reset software flags + * + * @param None + * + * @return None + * + * @details This function resets all variables for protocol and resets USB device address to 0. + * + */ +void USBD_SwReset(void) +{ + // Reset all variables for protocol + g_usbd_CtrlInPointer = 0; + g_usbd_CtrlInSize = 0; + g_usbd_CtrlOutPointer = 0; + g_usbd_CtrlOutSize = 0; + g_usbd_CtrlOutSizeLimit = 0; + g_u32EpStallLock = 0; + memset(g_usbd_SetupPacket, 0, 8); + // Reset 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; +} + +/** + * @brief The callback function which called when get SET CONFIGURATION request + * + * @param[in] pfnSetConfigCallback Callback function pointer for SET CONFIGURATION request + * + * @return None + * + * @details This function is used to set the callback function which will be called at SET CONFIGURATION request. + */ +void USBD_SetConfigCallback(SET_CONFIG_CB pfnSetConfigCallback) +{ + g_usbd_pfnSetConfigCallback = pfnSetConfigCallback; +} + + +/** + * @brief EP stall lock function to avoid stall clear by USB SET FEATURE request. + * + * @param[in] u32EpBitmap Use bitmap to select which endpoints will be locked + * + * @return None + * + * @details This function is used to lock relative endpoint to avoid stall clear by SET FEATURE request. + * If ep stall locked, user needs to reset USB device or re-configure device to clear it. + */ +void USBD_LockEpStall(uint32_t u32EpBitmap) +{ + g_u32EpStallLock = u32EpBitmap; +} + + + + + +/*@}*/ /* end of group M451_USBD_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group M451_USBD_Driver */ + +/*@}*/ /* end of group M451_Device_Driver */ + +#ifdef __cplusplus +} +#endif + +/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/wdt.c b/StdDriver/src/wdt.c new file mode 100644 index 0000000..b8718b5 --- /dev/null +++ b/StdDriver/src/wdt.c @@ -0,0 +1,71 @@ +/**************************************************************************//** + * @file wdt.c + * @version V3.00 + * $Revision: 5 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series WDT driver source file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup WDT_Driver WDT Driver + @{ +*/ + +/** @addtogroup WDT_EXPORTED_FUNCTIONS WDT Exported Functions + @{ +*/ + +/** + * @brief Initialize WDT and start counting + * + * @param[in] u32TimeoutInterval Time-out interval period of WDT module. Valid values are: + * - \ref WDT_TIMEOUT_2POW4 + * - \ref WDT_TIMEOUT_2POW6 + * - \ref WDT_TIMEOUT_2POW8 + * - \ref WDT_TIMEOUT_2POW10 + * - \ref WDT_TIMEOUT_2POW12 + * - \ref WDT_TIMEOUT_2POW14 + * - \ref WDT_TIMEOUT_2POW16 + * - \ref WDT_TIMEOUT_2POW18 + * @param[in] u32ResetDelay Configure WDT time-out reset delay period. Valid values are: + * - \ref WDT_RESET_DELAY_1026CLK + * - \ref WDT_RESET_DELAY_130CLK + * - \ref WDT_RESET_DELAY_18CLK + * - \ref WDT_RESET_DELAY_3CLK + * @param[in] u32EnableReset Enable WDT time-out reset system function. Valid values are TRUE and FALSE. + * @param[in] u32EnableWakeup Enable WDT time-out wake-up system function. Valid values are TRUE and FALSE. + * + * @return None + * + * @details This function makes WDT module start counting with different time-out interval, reset delay period and choose to \n + * enable or disable WDT time-out reset system or wake-up system. + * @note Please make sure that Register Write-Protection Function has been disabled before using this function. + */ +void WDT_Open(uint32_t u32TimeoutInterval, + uint32_t u32ResetDelay, + uint32_t u32EnableReset, + uint32_t u32EnableWakeup) +{ + WDT->ALTCTL = u32ResetDelay; + + WDT->CTL = u32TimeoutInterval | WDT_CTL_WDTEN_Msk | + (u32EnableReset << WDT_CTL_RSTEN_Pos) | + (u32EnableWakeup << WDT_CTL_WKEN_Pos); + return; +} + +/*@}*/ /* end of group WDT_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group WDT_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/StdDriver/src/wwdt.c b/StdDriver/src/wwdt.c new file mode 100644 index 0000000..439dbaf --- /dev/null +++ b/StdDriver/src/wwdt.c @@ -0,0 +1,71 @@ +/**************************************************************************//** + * @file wwdt.c + * @version V3.00 + * $Revision: 4 $ + * $Date: 15/08/11 10:26a $ + * @brief M451 series WWDT driver source file + * + * @note + * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. +*****************************************************************************/ +#include "M451Series.h" + + +/** @addtogroup Standard_Driver Standard Driver + @{ +*/ + +/** @addtogroup WWDT_Driver WWDT Driver + @{ +*/ + +/** @addtogroup WWDT_EXPORTED_FUNCTIONS WWDT Exported Functions + @{ +*/ + +/** + * @brief Open WWDT and start counting + * + * @param[in] u32PreScale Pre-scale setting of WWDT counter. Valid values are: + * - \ref WWDT_PRESCALER_1 + * - \ref WWDT_PRESCALER_2 + * - \ref WWDT_PRESCALER_4 + * - \ref WWDT_PRESCALER_8 + * - \ref WWDT_PRESCALER_16 + * - \ref WWDT_PRESCALER_32 + * - \ref WWDT_PRESCALER_64 + * - \ref WWDT_PRESCALER_128 + * - \ref WWDT_PRESCALER_192 + * - \ref WWDT_PRESCALER_256 + * - \ref WWDT_PRESCALER_384 + * - \ref WWDT_PRESCALER_512 + * - \ref WWDT_PRESCALER_768 + * - \ref WWDT_PRESCALER_1024 + * - \ref WWDT_PRESCALER_1536 + * - \ref WWDT_PRESCALER_2048 + * @param[in] u32CmpValue Setting the window compared value. Valid values are between 0x0 to 0x3F. + * @param[in] u32EnableInt Enable WWDT time-out interrupt function. Valid values are TRUE and FALSE. + * + * @return None + * + * @details This function makes WWDT module start counting with different counter period by pre-scale setting and compared window value. + * @note This WWDT_CTL register can be write only one time after chip is powered on or reset. + */ +void WWDT_Open(uint32_t u32PreScale, + uint32_t u32CmpValue, + uint32_t u32EnableInt) +{ + WWDT->CTL = u32PreScale | + (u32CmpValue << WWDT_CTL_CMPDAT_Pos) | + ((u32EnableInt == TRUE) ? WWDT_CTL_INTEN_Msk : 0) | + WWDT_CTL_WWDTEN_Msk; + return; +} + +/*@}*/ /* end of group WWDT_EXPORTED_FUNCTIONS */ + +/*@}*/ /* end of group WWDT_Driver */ + +/*@}*/ /* end of group Standard_Driver */ + +/*** (C) COPYRIGHT 2013~2015 Nuvoton Technology Corp. ***/ diff --git a/stepper/Listings/stepper.map b/stepper/Listings/stepper.map index 29c482e..bd8abd4 100644 --- a/stepper/Listings/stepper.map +++ b/stepper/Listings/stepper.map @@ -4,6 +4,15 @@ Component: ARM Compiler 5.06 update 6 (build 750) Tool: armlink [4d35ed] Section Cross References + clk.o(.text) refers to system_m451series.o(.text) for SystemCoreClockUpdate + clk.o(.text) refers to system_m451series.o(.data) for SystemCoreClock + i2c.o(.text) refers to clk.o(.text) for CLK_GetPCLK1Freq + sc.o(.text) refers to sc.o(.data) for .data + pwm.o(.text) refers to system_m451series.o(.text) for SystemCoreClockUpdate + pwm.o(.text) refers to system_m451series.o(.data) for SystemCoreClock + uart.o(.text) refers to uart.o(.constdata) for .constdata + ssd1306.o(.text) refers to strlen.o(.text) for strlen + ssd1306.o(.text) refers to ssd1306.o(.data) for .data main.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent main.o(.text) refers to _printf_d.o(.ARM.Collect$$_printf_percent$$00000009) for _printf_d main.o(.text) refers to _printf_dec.o(.text) for _printf_int_dec @@ -23,15 +32,219 @@ Section Cross References main.o(.text) refers to main.o(.data) for .data main.o(.text) refers to system_m451series.o(.data) for SystemCoreClock main.o(.ARM.exidx) refers to main.o(.text) for .text - ssd1306.o(.text) refers to strlen.o(.text) for strlen - ssd1306.o(.text) refers to ssd1306.o(.data) for .data - can.o(.text) refers to system_m451series.o(.text) for SystemCoreClockUpdate - can.o(.text) refers to can.o(.data) for .data - can.o(.text) refers to system_m451series.o(.data) for SystemCoreClock - clk.o(.text) refers to system_m451series.o(.text) for SystemCoreClockUpdate - clk.o(.text) refers to system_m451series.o(.data) for SystemCoreClock - sc.o(.text) refers to sc.o(.data) for .data - uart.o(.text) refers to uart.o(.constdata) for .constdata + basicmathfunctions.o(.text) refers to llshl.o(.text) for __aeabi_llsl + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_16 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable16 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_32 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable32 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_64 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable64 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_128 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable128 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_256 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable256 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_512 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable512 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_1024 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable1024 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_2048 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable2048 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_4096 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable4096 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_16_q31 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_16 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_32_q31 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_32 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_64_q31 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_64 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_128_q31 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_128 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_256_q31 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_256 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_512_q31 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_512 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_1024_q31 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_1024 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_2048_q31 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_2048 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_4096_q31 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_4096 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_16_q15 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_16 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_32_q15 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_32 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_64_q15 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_64 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_128_q15 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_128 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_256_q15 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_256 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_512_q15 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_512 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_1024_q15 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_1024 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_2048_q15 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_2048 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_4096_q15 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable_fixed_4096 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_32 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable32 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_rfft_32 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_32 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable32 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_rfft_64 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_64 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable64 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_rfft_128 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_128 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable128 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_rfft_256 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_256 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable256 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_rfft_512 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_512 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable512 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_rfft_1024 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_1024 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable1024 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_rfft_2048 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_2048 + commontables.o(.constdata) refers to commontables.o(.constdata) for armBitRevIndexTable2048 + commontables.o(.constdata) refers to commontables.o(.constdata) for twiddleCoef_rfft_4096 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ31 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len16 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ31 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len32 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ31 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len64 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ31 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len128 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ31 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len256 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ31 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len512 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ31 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len1024 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ31 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len2048 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ31 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len4096 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ15 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len16 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ15 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len32 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ15 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len64 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ15 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len128 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ15 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len256 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ15 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len512 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ15 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len1024 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ15 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len2048 + commontables.o(.constdata) refers to transformfunctions.o(.constdata) for realCoefAQ15 + commontables.o(.constdata) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len4096 + complexmathfunctions.o(.text) refers to fastmathfunctions.o(.text) for arm_sqrt_q15 + controllerfunctions.o(.text) refers to commontables.o(.constdata) for sinTable_f32 + controllerfunctions.o(.text) refers to commontables.o(.constdata) for sinTable_q31 + fastmathfunctions.o(.text) refers to commontables.o(.constdata) for sinTable_f32 + fastmathfunctions.o(.text) refers to commontables.o(.constdata) for sinTable_q15 + fastmathfunctions.o(.text) refers to commontables.o(.constdata) for sinTable_q31 + filteringfunctions.o(.text) refers to rt_memclr_w.o(.text) for __aeabi_memclr4 + filteringfunctions.o(.text) refers to llshl.o(.text) for __aeabi_llsl + filteringfunctions.o(.text) refers to rt_memclr.o(.text) for __aeabi_memclr + filteringfunctions.o(.text) refers to llsshr.o(.text) for __aeabi_lasr + filteringfunctions.o(.text) refers to dmul.o(x$fpl$dmul) for __aeabi_dmul + filteringfunctions.o(.text) refers to daddsub_clz.o(x$fpl$dadd) for __aeabi_dadd + filteringfunctions.o(.text) refers to supportfunctions.o(.text) for arm_fill_q15 + filteringfunctions.o(.text) refers to commontables.o(.constdata) for armRecipTableQ15 + filteringfunctions.o(.text) refers to commontables.o(.constdata) for armRecipTableQ31 + matrixfunctions.o(.text) refers to drleqf.o(x$fpl$drleqf) for __aeabi_cdrcmple + matrixfunctions.o(.text) refers to basic.o(x$fpl$basic) for __aeabi_dneg + matrixfunctions.o(.text) refers to deqf.o(x$fpl$deqf) for __aeabi_cdcmpeq + matrixfunctions.o(.text) refers to ddiv.o(x$fpl$ddiv) for __aeabi_ddiv + matrixfunctions.o(.text) refers to dmul.o(x$fpl$dmul) for __aeabi_dmul + matrixfunctions.o(.text) refers to daddsub_clz.o(x$fpl$drsb) for __aeabi_drsub + statisticsfunctions.o(.text) refers to llsdiv.o(.text) for __aeabi_ldivmod + statisticsfunctions.o(.text) refers to fastmathfunctions.o(.text) for arm_sqrt_q15 + statisticsfunctions.o(.text) refers to lludivv7m.o(.text) for __aeabi_uldivmod + supportfunctions.o(.text) refers to ffixll.o(x$fpl$llsfromf) for __aeabi_f2lz + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_4096 + transformfunctions.o(.text) refers to commontables.o(.constdata) for armBitRevTable + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_4096_q15 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_4096_q31 + transformfunctions.o(.text) refers to basicmathfunctions.o(.text) for arm_scale_f32 + transformfunctions.o(.text) refers to complexmathfunctions.o(.text) for arm_cmplx_mult_cmplx_f32 + transformfunctions.o(.text) refers to transformfunctions.o(.constdata) for .constdata + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len128 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len4096 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len2048 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len1024 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len512 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len256 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len64 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len32 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q15_len16 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len128 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len4096 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len2048 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len1024 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len512 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len256 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len64 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len32 + transformfunctions.o(.text) refers to commontables.o(.constdata) for arm_cfft_sR_q31_len16 + transformfunctions.o(.text) refers to commontables.o(.constdata) for armBitRevIndexTable16 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_16 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_rfft_32 + transformfunctions.o(.text) refers to commontables.o(.constdata) for armBitRevIndexTable32 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_32 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_rfft_64 + transformfunctions.o(.text) refers to commontables.o(.constdata) for armBitRevIndexTable64 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_64 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_rfft_128 + transformfunctions.o(.text) refers to commontables.o(.constdata) for armBitRevIndexTable128 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_128 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_rfft_256 + transformfunctions.o(.text) refers to commontables.o(.constdata) for armBitRevIndexTable256 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_256 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_rfft_512 + transformfunctions.o(.text) refers to commontables.o(.constdata) for armBitRevIndexTable512 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_512 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_rfft_1024 + transformfunctions.o(.text) refers to commontables.o(.constdata) for armBitRevIndexTable1024 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_1024 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_rfft_2048 + transformfunctions.o(.text) refers to commontables.o(.constdata) for armBitRevIndexTable2048 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_2048 + transformfunctions.o(.text) refers to commontables.o(.constdata) for twiddleCoef_rfft_4096 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for Weights_128 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for Weights_512 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for Weights_2048 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for Weights_8192 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factors_128 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factors_512 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factors_2048 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factors_8192 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for WeightsQ15_128 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for WeightsQ15_512 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for WeightsQ15_2048 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for WeightsQ15_8192 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factorsQ15_128 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factorsQ15_512 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factorsQ15_2048 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factorsQ15_8192 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for WeightsQ31_128 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for WeightsQ31_512 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for WeightsQ31_2048 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for WeightsQ31_8192 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factorsQ31_128 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factorsQ31_512 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factorsQ31_2048 + transformfunctions.o(.constdata) refers to transformfunctions.o(.constdata) for cos_factorsQ31_8192 retarget.o(.emb_text) refers to retarget.o(.text) for Hard_Fault_Handler retarget.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent retarget.o(.text) refers to _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C) for _printf_x @@ -49,9 +262,7 @@ Section Cross References startup_m451series.o(.text) refers to startup_m451series.o(HEAP) for Heap_Mem startup_m451series.o(.text) refers to startup_m451series.o(STACK) for Stack_Mem system_m451series.o(.text) refers to system_m451series.o(.data) for .data - i2c.o(.text) refers to system_m451series.o(.data) for SystemCoreClock - pwm.o(.text) refers to system_m451series.o(.text) for SystemCoreClockUpdate - pwm.o(.text) refers to system_m451series.o(.data) for SystemCoreClock + llsdiv.o(.text) refers to lludivv7m.o(.text) for __aeabi_uldivmod __2printf.o(.text) refers to _printf_char_file.o(.text) for _printf_char_file __2printf.o(.text) refers to retarget.o(.data) for __stdout __2sprintf.o(.text) refers to _printf_char_common.o(.text) for _printf_char_common @@ -94,16 +305,53 @@ Section Cross References _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C) refers (Weak) to _printf_hex_int.o(.text) for _printf_int_hex _printf_d.o(.ARM.Collect$$_printf_percent$$00000009) refers (Weak) to _printf_dec.o(.text) for _printf_int_dec _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) refers (Special) to _printf_percent_end.o(.ARM.Collect$$_printf_percent$$00000017) for _printf_percent_end + rt_memclr.o(.text) refers to rt_memclr_w.o(.text) for _memset_w __main.o(!!!main) refers to __rtentry.o(.ARM.Collect$$rtentry$$00000000) for __rt_entry + basic.o(x$fpl$basic) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + daddsub_clz.o(x$fpl$dadd) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + daddsub_clz.o(x$fpl$dadd) refers to daddsub_clz.o(x$fpl$dsub) for _dsub1 + daddsub_clz.o(x$fpl$dadd) refers to dretinf.o(x$fpl$dretinf) for __fpl_dretinf + daddsub_clz.o(x$fpl$dadd) refers to dnaninf.o(x$fpl$dnaninf) for __fpl_dnaninf + daddsub_clz.o(x$fpl$drsb) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + daddsub_clz.o(x$fpl$drsb) refers to daddsub_clz.o(x$fpl$dadd) for _dadd1 + daddsub_clz.o(x$fpl$drsb) refers to daddsub_clz.o(x$fpl$dsub) for _dsub1 + daddsub_clz.o(x$fpl$dsub) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + daddsub_clz.o(x$fpl$dsub) refers to daddsub_clz.o(x$fpl$dadd) for _dadd1 + daddsub_clz.o(x$fpl$dsub) refers to dnaninf.o(x$fpl$dnaninf) for __fpl_dnaninf + ddiv.o(x$fpl$drdiv) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + ddiv.o(x$fpl$drdiv) refers to ddiv.o(x$fpl$ddiv) for ddiv_entry + ddiv.o(x$fpl$ddiv) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + ddiv.o(x$fpl$ddiv) refers to dretinf.o(x$fpl$dretinf) for __fpl_dretinf + ddiv.o(x$fpl$ddiv) refers to dnaninf.o(x$fpl$dnaninf) for __fpl_dnaninf + deqf.o(x$fpl$deqf) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + deqf.o(x$fpl$deqf) refers to dnaninf.o(x$fpl$dnaninf) for __fpl_dnaninf + deqf.o(x$fpl$deqf) refers to dcmpi.o(x$fpl$dcmpinf) for __fpl_dcmp_Inf + dmul.o(x$fpl$dmul) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + dmul.o(x$fpl$dmul) refers to dretinf.o(x$fpl$dretinf) for __fpl_dretinf + dmul.o(x$fpl$dmul) refers to dnaninf.o(x$fpl$dnaninf) for __fpl_dnaninf + drleqf.o(x$fpl$drleqf) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + drleqf.o(x$fpl$drleqf) refers to dleqf.o(x$fpl$dleqf) for __fpl_dcmple_InfNaN + ffixll.o(x$fpl$llsfromf) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + ffixll.o(x$fpl$llsfromf) refers to fnaninf.o(x$fpl$fnaninf) for __fpl_fnaninf + ffixll.o(x$fpl$llsfromfr) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + ffixll.o(x$fpl$llsfromfr) refers to fnaninf.o(x$fpl$fnaninf) for __fpl_fnaninf __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$0000000A) for __rt_entry_li __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$0000000D) for __rt_entry_main __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$0000000C) for __rt_entry_postli_1 __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$00000009) for __rt_entry_postsh_1 __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$00000002) for __rt_entry_presh_1 __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry4.o(.ARM.Collect$$rtentry$$00000004) for __rt_entry_sh + aeabi_ldiv0_sigfpe.o(.text) refers to rt_div0.o(.text) for __rt_div0 _printf_char_common.o(.text) refers to __printf_wp.o(.text) for __printf _printf_char_file.o(.text) refers to _printf_char_common.o(.text) for _printf_char_common _printf_char_file.o(.text) refers to retarget.o(.text) for ferror + dcmpi.o(x$fpl$dcmpinf) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + dleqf.o(x$fpl$dleqf) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + dleqf.o(x$fpl$dleqf) refers to dnaninf.o(x$fpl$dnaninf) for __fpl_dnaninf + dleqf.o(x$fpl$dleqf) refers to dcmpi.o(x$fpl$dcmpinf) for __fpl_dcmp_Inf + dnaninf.o(x$fpl$dnaninf) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + dretinf.o(x$fpl$dretinf) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + fnaninf.o(x$fpl$fnaninf) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp __rtentry2.o(.ARM.Collect$$rtentry$$00000008) refers to boardinit2.o(.text) for _platform_post_stackheap_init __rtentry2.o(.ARM.Collect$$rtentry$$0000000A) refers to libinit.o(.ARM.Collect$$libinit$$00000000) for __rt_lib_init __rtentry2.o(.ARM.Collect$$rtentry$$0000000B) refers to boardinit3.o(.text) for _platform_post_lib_init @@ -116,9 +364,13 @@ Section Cross References __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$0000000D) for .ARM.Collect$$rtentry$$0000000D __rtentry4.o(.ARM.Collect$$rtentry$$00000004) refers to sys_stackheap_outer.o(.text) for __user_setup_stackheap __rtentry4.o(.ARM.exidx) refers to __rtentry4.o(.ARM.Collect$$rtentry$$00000004) for .ARM.Collect$$rtentry$$00000004 + rt_div0.o(.text) refers to defsig_fpe_outer.o(.text) for __rt_SIGFPE sys_stackheap_outer.o(.text) refers to libspace.o(.text) for __user_perproc_libspace sys_stackheap_outer.o(.text) refers to startup_m451series.o(.text) for __user_initial_stackheap exit.o(.text) refers to rtexit.o(.ARM.Collect$$rtexit$$00000000) for __rt_exit + defsig_fpe_outer.o(.text) refers to defsig_fpe_inner.o(.text) for __rt_SIGFPE_inner + defsig_fpe_outer.o(.text) refers to defsig_exit.o(.text) for __sig_exit + defsig_fpe_formal.o(.text) refers to rt_raise.o(.text) for __rt_raise libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000002E) for __rt_lib_init_alloca_1 libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000002C) for __rt_lib_init_argv_1 libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000001B) for __rt_lib_init_atexit_1 @@ -148,6 +400,10 @@ Section Cross References rtexit.o(.ARM.exidx) refers (Special) to rtexit2.o(.ARM.Collect$$rtexit$$00000003) for __rt_exit_ls rtexit.o(.ARM.exidx) refers (Special) to rtexit2.o(.ARM.Collect$$rtexit$$00000002) for __rt_exit_prels_1 rtexit.o(.ARM.exidx) refers to rtexit.o(.ARM.Collect$$rtexit$$00000000) for .ARM.Collect$$rtexit$$00000000 + rt_raise.o(.text) refers to __raise.o(.text) for __raise + rt_raise.o(.text) refers to sys_exit.o(.text) for _sys_exit + defsig_exit.o(.text) refers to sys_exit.o(.text) for _sys_exit + defsig_fpe_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display libinit2.o(.ARM.Collect$$libinit$$00000001) refers to fpinit.o(x$fpl$fpinit) for _fp_init libinit2.o(.ARM.Collect$$libinit$$00000010) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F libinit2.o(.ARM.Collect$$libinit$$00000012) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F @@ -156,14 +412,18 @@ Section Cross References libinit2.o(.ARM.Collect$$libinit$$00000018) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F libinit2.o(.ARM.Collect$$libinit$$00000026) refers to argv_veneer.o(.emb_text) for __ARM_argv_veneer libinit2.o(.ARM.Collect$$libinit$$00000027) refers to argv_veneer.o(.emb_text) for __ARM_argv_veneer + sys_exit.o(.text) refers (Special) to use_no_semi.o(.text) for __I$use$semihosting + sys_exit.o(.text) refers (Special) to indicate_semi.o(.text) for __semihosting_library_function rtexit2.o(.ARM.Collect$$rtexit$$00000003) refers to libshutdown.o(.ARM.Collect$$libshutdown$$00000000) for __rt_lib_shutdown rtexit2.o(.ARM.Collect$$rtexit$$00000004) refers to sys_exit.o(.text) for _sys_exit rtexit2.o(.ARM.exidx) refers to rtexit2.o(.ARM.Collect$$rtexit$$00000001) for .ARM.Collect$$rtexit$$00000001 rtexit2.o(.ARM.exidx) refers to rtexit2.o(.ARM.Collect$$rtexit$$00000003) for .ARM.Collect$$rtexit$$00000003 rtexit2.o(.ARM.exidx) refers to rtexit2.o(.ARM.Collect$$rtexit$$00000004) for .ARM.Collect$$rtexit$$00000004 + __raise.o(.text) refers to defsig.o(CL$$defsig) for __default_signal_handler + defsig_general.o(.text) refers to retarget.o(.text) for _ttywrch argv_veneer.o(.emb_text) refers to no_argv.o(.text) for __ARM_get_argv - sys_exit.o(.text) refers (Special) to use_no_semi.o(.text) for __I$use$semihosting - sys_exit.o(.text) refers (Special) to indicate_semi.o(.text) for __semihosting_library_function + defsig.o(CL$$defsig) refers to defsig_fpe_inner.o(.text) for __rt_SIGFPE_inner + defsig.o(CL$$defsig) refers to defsig_rtmem_inner.o(.text) for __rt_SIGRTMEM_inner _get_argv_nomalloc.o(.text) refers (Special) to hrguard.o(.text) for __heap_region$guard _get_argv_nomalloc.o(.text) refers to defsig_rtmem_outer.o(.text) for __rt_SIGRTMEM _get_argv_nomalloc.o(.text) refers to sys_command.o(.text) for _sys_command_string @@ -176,19 +436,12 @@ Section Cross References libshutdown.o(.ARM.Collect$$libshutdown$$00000000) refers (Special) to libshutdown2.o(.ARM.Collect$$libshutdown$$0000000C) for __rt_lib_shutdown_user_alloc_1 sys_command.o(.text) refers (Special) to use_no_semi.o(.text) for __I$use$semihosting sys_command.o(.text) refers (Special) to indicate_semi.o(.text) for __semihosting_library_function + defsig_abrt_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display + defsig_rtred_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display + defsig_rtmem_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display defsig_rtmem_outer.o(.text) refers to defsig_rtmem_inner.o(.text) for __rt_SIGRTMEM_inner defsig_rtmem_outer.o(.text) refers to defsig_exit.o(.text) for __sig_exit defsig_rtmem_formal.o(.text) refers to rt_raise.o(.text) for __rt_raise - rt_raise.o(.text) refers to __raise.o(.text) for __raise - rt_raise.o(.text) refers to sys_exit.o(.text) for _sys_exit - defsig_exit.o(.text) refers to sys_exit.o(.text) for _sys_exit - defsig_rtmem_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display - __raise.o(.text) refers to defsig.o(CL$$defsig) for __default_signal_handler - defsig_general.o(.text) refers to retarget.o(.text) for _ttywrch - defsig.o(CL$$defsig) refers to defsig_rtmem_inner.o(.text) for __rt_SIGRTMEM_inner - defsig_abrt_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display - defsig_fpe_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display - defsig_rtred_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display defsig_stak_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display defsig_pvfn_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display defsig_cppl_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display @@ -200,21 +453,6 @@ Section Cross References Removing Unused input sections from the image. - Removing main.o(.rev16_text), (4 bytes). - Removing main.o(.revsh_text), (4 bytes). - Removing main.o(.rrx_text), (6 bytes). - Removing main.o(.ARM.exidx), (8 bytes). - Removing ssd1306.o(.rev16_text), (4 bytes). - Removing ssd1306.o(.revsh_text), (4 bytes). - Removing ssd1306.o(.rrx_text), (6 bytes). - Removing ssd1306.o(.data), (1024 bytes). - Removing ssd1306.o(.data), (552 bytes). - Removing ssd1306.o(.data), (1024 bytes). - Removing can.o(.rev16_text), (4 bytes). - Removing can.o(.revsh_text), (4 bytes). - Removing can.o(.rrx_text), (6 bytes). - Removing can.o(.text), (1740 bytes). - Removing can.o(.data), (2 bytes). Removing clk.o(.rev16_text), (4 bytes). Removing clk.o(.revsh_text), (4 bytes). Removing clk.o(.rrx_text), (6 bytes). @@ -225,6 +463,9 @@ Removing Unused input sections from the image. Removing gpio.o(.revsh_text), (4 bytes). Removing gpio.o(.rrx_text), (6 bytes). Removing gpio.o(.text), (94 bytes). + Removing i2c.o(.rev16_text), (4 bytes). + Removing i2c.o(.revsh_text), (4 bytes). + Removing i2c.o(.rrx_text), (6 bytes). Removing sc.o(.rev16_text), (4 bytes). Removing sc.o(.revsh_text), (4 bytes). Removing sc.o(.rrx_text), (6 bytes). @@ -233,9 +474,198 @@ Removing Unused input sections from the image. Removing sys.o(.rev16_text), (4 bytes). Removing sys.o(.revsh_text), (4 bytes). Removing sys.o(.rrx_text), (6 bytes). + Removing pwm.o(.rev16_text), (4 bytes). + Removing pwm.o(.revsh_text), (4 bytes). + Removing pwm.o(.rrx_text), (6 bytes). Removing uart.o(.rev16_text), (4 bytes). Removing uart.o(.revsh_text), (4 bytes). Removing uart.o(.rrx_text), (6 bytes). + Removing ssd1306.o(.rev16_text), (4 bytes). + Removing ssd1306.o(.revsh_text), (4 bytes). + Removing ssd1306.o(.rrx_text), (6 bytes). + Removing ssd1306.o(.data), (1024 bytes). + Removing ssd1306.o(.data), (552 bytes). + Removing ssd1306.o(.data), (1024 bytes). + Removing main.o(.rev16_text), (4 bytes). + Removing main.o(.revsh_text), (4 bytes). + Removing main.o(.rrx_text), (6 bytes). + Removing main.o(.ARM.exidx), (8 bytes). + Removing basicmathfunctions.o(.rev16_text), (4 bytes). + Removing basicmathfunctions.o(.revsh_text), (4 bytes). + Removing basicmathfunctions.o(.rrx_text), (6 bytes). + Removing basicmathfunctions.o(.text), (1120 bytes). + Removing commontables.o(.rev16_text), (4 bytes). + Removing commontables.o(.revsh_text), (4 bytes). + Removing commontables.o(.rrx_text), (6 bytes). + Removing commontables.o(.constdata), (2048 bytes). + Removing commontables.o(.constdata), (128 bytes). + Removing commontables.o(.constdata), (256 bytes). + Removing commontables.o(.constdata), (512 bytes). + Removing commontables.o(.constdata), (1024 bytes). + Removing commontables.o(.constdata), (2048 bytes). + Removing commontables.o(.constdata), (4096 bytes). + Removing commontables.o(.constdata), (8192 bytes). + Removing commontables.o(.constdata), (16384 bytes). + Removing commontables.o(.constdata), (32768 bytes). + Removing commontables.o(.constdata), (96 bytes). + Removing commontables.o(.constdata), (192 bytes). + Removing commontables.o(.constdata), (384 bytes). + Removing commontables.o(.constdata), (768 bytes). + Removing commontables.o(.constdata), (1536 bytes). + Removing commontables.o(.constdata), (3072 bytes). + Removing commontables.o(.constdata), (6144 bytes). + Removing commontables.o(.constdata), (12288 bytes). + Removing commontables.o(.constdata), (24576 bytes). + Removing commontables.o(.constdata), (48 bytes). + Removing commontables.o(.constdata), (96 bytes). + Removing commontables.o(.constdata), (192 bytes). + Removing commontables.o(.constdata), (384 bytes). + Removing commontables.o(.constdata), (768 bytes). + Removing commontables.o(.constdata), (1536 bytes). + Removing commontables.o(.constdata), (3072 bytes). + Removing commontables.o(.constdata), (6144 bytes). + Removing commontables.o(.constdata), (12288 bytes). + Removing commontables.o(.constdata), (128 bytes). + Removing commontables.o(.constdata), (256 bytes). + Removing commontables.o(.constdata), (40 bytes). + Removing commontables.o(.constdata), (96 bytes). + Removing commontables.o(.constdata), (112 bytes). + Removing commontables.o(.constdata), (416 bytes). + Removing commontables.o(.constdata), (880 bytes). + Removing commontables.o(.constdata), (896 bytes). + Removing commontables.o(.constdata), (3600 bytes). + Removing commontables.o(.constdata), (7616 bytes). + Removing commontables.o(.constdata), (8064 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (48 bytes). + Removing commontables.o(.constdata), (112 bytes). + Removing commontables.o(.constdata), (224 bytes). + Removing commontables.o(.constdata), (480 bytes). + Removing commontables.o(.constdata), (960 bytes). + Removing commontables.o(.constdata), (1984 bytes). + Removing commontables.o(.constdata), (3968 bytes). + Removing commontables.o(.constdata), (8064 bytes). + Removing commontables.o(.constdata), (128 bytes). + Removing commontables.o(.constdata), (256 bytes). + Removing commontables.o(.constdata), (512 bytes). + Removing commontables.o(.constdata), (1024 bytes). + Removing commontables.o(.constdata), (2048 bytes). + Removing commontables.o(.constdata), (4096 bytes). + Removing commontables.o(.constdata), (8192 bytes). + Removing commontables.o(.constdata), (16384 bytes). + Removing commontables.o(.constdata), (2052 bytes). + Removing commontables.o(.constdata), (2052 bytes). + Removing commontables.o(.constdata), (1026 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (16 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing commontables.o(.constdata), (24 bytes). + Removing complexmathfunctions.o(.rev16_text), (4 bytes). + Removing complexmathfunctions.o(.revsh_text), (4 bytes). + Removing complexmathfunctions.o(.rrx_text), (6 bytes). + Removing complexmathfunctions.o(.text), (936 bytes). + Removing controllerfunctions.o(.rev16_text), (4 bytes). + Removing controllerfunctions.o(.revsh_text), (4 bytes). + Removing controllerfunctions.o(.rrx_text), (6 bytes). + Removing controllerfunctions.o(.text), (964 bytes). + Removing fastmathfunctions.o(.rev16_text), (4 bytes). + Removing fastmathfunctions.o(.revsh_text), (4 bytes). + Removing fastmathfunctions.o(.rrx_text), (6 bytes). + Removing fastmathfunctions.o(.text), (908 bytes). + Removing filteringfunctions.o(.rev16_text), (4 bytes). + Removing filteringfunctions.o(.revsh_text), (4 bytes). + Removing filteringfunctions.o(.rrx_text), (6 bytes). + Removing filteringfunctions.o(.text), (23684 bytes). + Removing matrixfunctions.o(.rev16_text), (4 bytes). + Removing matrixfunctions.o(.revsh_text), (4 bytes). + Removing matrixfunctions.o(.rrx_text), (6 bytes). + Removing matrixfunctions.o(.text), (4180 bytes). + Removing statisticsfunctions.o(.rev16_text), (4 bytes). + Removing statisticsfunctions.o(.revsh_text), (4 bytes). + Removing statisticsfunctions.o(.rrx_text), (6 bytes). + Removing statisticsfunctions.o(.text), (1412 bytes). + Removing supportfunctions.o(.rev16_text), (4 bytes). + Removing supportfunctions.o(.revsh_text), (4 bytes). + Removing supportfunctions.o(.rrx_text), (6 bytes). + Removing supportfunctions.o(.text), (488 bytes). + Removing transformfunctions.o(.rev16_text), (4 bytes). + Removing transformfunctions.o(.revsh_text), (4 bytes). + Removing transformfunctions.o(.rrx_text), (6 bytes). + Removing transformfunctions.o(.text), (15684 bytes). + Removing transformfunctions.o(.constdata), (1024 bytes). + Removing transformfunctions.o(.constdata), (4096 bytes). + Removing transformfunctions.o(.constdata), (16384 bytes). + Removing transformfunctions.o(.constdata), (65536 bytes). + Removing transformfunctions.o(.constdata), (512 bytes). + Removing transformfunctions.o(.constdata), (2048 bytes). + Removing transformfunctions.o(.constdata), (8192 bytes). + Removing transformfunctions.o(.constdata), (32768 bytes). + Removing transformfunctions.o(.constdata), (512 bytes). + Removing transformfunctions.o(.constdata), (2048 bytes). + Removing transformfunctions.o(.constdata), (8192 bytes). + Removing transformfunctions.o(.constdata), (32768 bytes). + Removing transformfunctions.o(.constdata), (256 bytes). + Removing transformfunctions.o(.constdata), (1024 bytes). + Removing transformfunctions.o(.constdata), (4096 bytes). + Removing transformfunctions.o(.constdata), (16384 bytes). + Removing transformfunctions.o(.constdata), (1024 bytes). + Removing transformfunctions.o(.constdata), (4096 bytes). + Removing transformfunctions.o(.constdata), (16384 bytes). + Removing transformfunctions.o(.constdata), (65536 bytes). + Removing transformfunctions.o(.constdata), (512 bytes). + Removing transformfunctions.o(.constdata), (2048 bytes). + Removing transformfunctions.o(.constdata), (8192 bytes). + Removing transformfunctions.o(.constdata), (32768 bytes). + Removing transformfunctions.o(.constdata), (163936 bytes). Removing retarget.o(.rev16_text), (4 bytes). Removing retarget.o(.revsh_text), (4 bytes). Removing retarget.o(.rrx_text), (6 bytes). @@ -243,14 +673,8 @@ Removing Unused input sections from the image. Removing system_m451series.o(.rev16_text), (4 bytes). Removing system_m451series.o(.revsh_text), (4 bytes). Removing system_m451series.o(.rrx_text), (6 bytes). - Removing i2c.o(.rev16_text), (4 bytes). - Removing i2c.o(.revsh_text), (4 bytes). - Removing i2c.o(.rrx_text), (6 bytes). - Removing pwm.o(.rev16_text), (4 bytes). - Removing pwm.o(.revsh_text), (4 bytes). - Removing pwm.o(.rrx_text), (6 bytes). -49 unused section(s) (total 4970 bytes) removed from the image. +220 unused section(s) (total 760900 bytes) removed from the image. ============================================================================== @@ -261,103 +685,144 @@ Image Symbol Table Symbol Name Value Ov Type Size Object(Section) RESET 0x00000000 Section 320 startup_m451series.o(RESET) + ../clib/angel/boardlib.s 0x00000000 Number 0 boardshut.o ABSOLUTE + ../clib/angel/boardlib.s 0x00000000 Number 0 boardinit3.o ABSOLUTE ../clib/angel/boardlib.s 0x00000000 Number 0 boardinit2.o ABSOLUTE ../clib/angel/boardlib.s 0x00000000 Number 0 boardinit1.o ABSOLUTE - ../clib/angel/boardlib.s 0x00000000 Number 0 boardinit3.o ABSOLUTE - ../clib/angel/boardlib.s 0x00000000 Number 0 boardshut.o ABSOLUTE ../clib/angel/dczerorl2.s 0x00000000 Number 0 __dczerorl2.o ABSOLUTE ../clib/angel/handlers.s 0x00000000 Number 0 __scatter_zi.o ABSOLUTE ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry2.o ABSOLUTE ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry4.o ABSOLUTE - ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry.o ABSOLUTE ../clib/angel/kernel.s 0x00000000 Number 0 rtexit.o ABSOLUTE ../clib/angel/kernel.s 0x00000000 Number 0 rtexit2.o ABSOLUTE + ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry.o ABSOLUTE + ../clib/angel/rt.s 0x00000000 Number 0 aeabi_ldiv0_sigfpe.o ABSOLUTE ../clib/angel/rt.s 0x00000000 Number 0 rt_raise.o ABSOLUTE + ../clib/angel/rt.s 0x00000000 Number 0 rt_div0.o ABSOLUTE + ../clib/angel/rt.s 0x00000000 Number 0 aeabi_ldiv0.o ABSOLUTE ../clib/angel/scatter.s 0x00000000 Number 0 __scatter.o ABSOLUTE ../clib/angel/startup.s 0x00000000 Number 0 __main.o ABSOLUTE - ../clib/angel/sys.s 0x00000000 Number 0 sys_stackheap_outer.o ABSOLUTE + ../clib/angel/sys.s 0x00000000 Number 0 libspace.o ABSOLUTE ../clib/angel/sys.s 0x00000000 Number 0 indicate_semi.o ABSOLUTE ../clib/angel/sys.s 0x00000000 Number 0 use_no_semi.o ABSOLUTE - ../clib/angel/sys.s 0x00000000 Number 0 libspace.o ABSOLUTE - ../clib/angel/sysapp.c 0x00000000 Number 0 sys_exit.o ABSOLUTE + ../clib/angel/sys.s 0x00000000 Number 0 sys_stackheap_outer.o ABSOLUTE ../clib/angel/sysapp.c 0x00000000 Number 0 sys_command.o ABSOLUTE - ../clib/armsys.c 0x00000000 Number 0 argv_veneer.o ABSOLUTE + ../clib/angel/sysapp.c 0x00000000 Number 0 sys_exit.o ABSOLUTE + ../clib/armsys.c 0x00000000 Number 0 _get_argv_nomalloc.o ABSOLUTE ../clib/armsys.c 0x00000000 Number 0 no_argv.o ABSOLUTE ../clib/armsys.c 0x00000000 Number 0 argv_veneer.o ABSOLUTE - ../clib/armsys.c 0x00000000 Number 0 _get_argv_nomalloc.o ABSOLUTE + ../clib/armsys.c 0x00000000 Number 0 argv_veneer.o ABSOLUTE ../clib/heapalloc.c 0x00000000 Number 0 hrguard.o ABSOLUTE ../clib/heapaux.c 0x00000000 Number 0 heapauxi.o ABSOLUTE - ../clib/libinit.s 0x00000000 Number 0 libshutdown2.o ABSOLUTE ../clib/libinit.s 0x00000000 Number 0 libinit.o ABSOLUTE ../clib/libinit.s 0x00000000 Number 0 libinit2.o ABSOLUTE ../clib/libinit.s 0x00000000 Number 0 libshutdown.o ABSOLUTE + ../clib/libinit.s 0x00000000 Number 0 libshutdown2.o ABSOLUTE + ../clib/longlong.s 0x00000000 Number 0 llsshr.o ABSOLUTE + ../clib/longlong.s 0x00000000 Number 0 lludivv7m.o ABSOLUTE + ../clib/longlong.s 0x00000000 Number 0 llshl.o ABSOLUTE + ../clib/longlong.s 0x00000000 Number 0 llsdiv.o ABSOLUTE ../clib/memcpset.s 0x00000000 Number 0 rt_memclr_w.o ABSOLUTE + ../clib/memcpset.s 0x00000000 Number 0 rt_memclr.o ABSOLUTE ../clib/misc.s 0x00000000 Number 0 printf_stubs.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 _printf_char_common.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 __2printf.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 _printf_hex_ll_ptr.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 noretval__2printf.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 __printf.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 _printf_dec.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 _printf_hex_ll.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 noretval__2sprintf.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 _printf_hex_int_ll.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 _printf_hex_ptr.o ABSOLUTE ../clib/printf.c 0x00000000 Number 0 _printf_hex_int_ptr.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 _printf_hex_int.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_ll_ptr.o ABSOLUTE ../clib/printf.c 0x00000000 Number 0 _printf_hex_int_ll_ptr.o ABSOLUTE ../clib/printf.c 0x00000000 Number 0 __printf_flags.o ABSOLUTE ../clib/printf.c 0x00000000 Number 0 __printf_ss.o ABSOLUTE ../clib/printf.c 0x00000000 Number 0 __printf_flags_ss.o ABSOLUTE ../clib/printf.c 0x00000000 Number 0 __printf_wp.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 __2sprintf.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 __printf_nopercent.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf_flags_wp.o ABSOLUTE ../clib/printf.c 0x00000000 Number 0 __printf_ss_wp.o ABSOLUTE ../clib/printf.c 0x00000000 Number 0 __printf_flags_ss_wp.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 __printf_flags_wp.o ABSOLUTE - ../clib/printf.c 0x00000000 Number 0 _printf_intcommon.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf_nopercent.o ABSOLUTE ../clib/printf.c 0x00000000 Number 0 _printf_char_file.o ABSOLUTE ../clib/printf.c 0x00000000 Number 0 _sputc.o ABSOLUTE - ../clib/printf_percent.s 0x00000000 Number 0 _printf_x.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_char_common.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_intcommon.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_int_ll.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __2printf.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __2sprintf.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 noretval__2printf.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 noretval__2sprintf.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_dec.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_ll.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_int.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_ptr.o ABSOLUTE ../clib/printf_percent.s 0x00000000 Number 0 _printf_percent.o ABSOLUTE - ../clib/printf_percent.s 0x00000000 Number 0 _printf_percent_end.o ABSOLUTE ../clib/printf_percent.s 0x00000000 Number 0 _printf_d.o ABSOLUTE - ../clib/signal.c 0x00000000 Number 0 __raise.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_percent_end.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_x.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_fpe_inner.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_fpe_formal.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_rtmem_outer.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_abrt_inner.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_rtred_inner.o ABSOLUTE ../clib/signal.c 0x00000000 Number 0 defsig_rtmem_inner.o ABSOLUTE ../clib/signal.c 0x00000000 Number 0 defsig_exit.o ABSOLUTE - ../clib/signal.c 0x00000000 Number 0 defsig_rtmem_outer.o ABSOLUTE ../clib/signal.c 0x00000000 Number 0 defsig_rtmem_formal.o ABSOLUTE - ../clib/signal.c 0x00000000 Number 0 defsig_rtred_inner.o ABSOLUTE ../clib/signal.c 0x00000000 Number 0 defsig_other.o ABSOLUTE ../clib/signal.c 0x00000000 Number 0 defsig_segv_inner.o ABSOLUTE ../clib/signal.c 0x00000000 Number 0 defsig_cppl_inner.o ABSOLUTE ../clib/signal.c 0x00000000 Number 0 defsig_pvfn_inner.o ABSOLUTE ../clib/signal.c 0x00000000 Number 0 defsig_stak_inner.o ABSOLUTE - ../clib/signal.c 0x00000000 Number 0 defsig_fpe_inner.o ABSOLUTE - ../clib/signal.c 0x00000000 Number 0 defsig_abrt_inner.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_fpe_outer.o ABSOLUTE ../clib/signal.c 0x00000000 Number 0 defsig_general.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 __raise.o ABSOLUTE ../clib/signal.s 0x00000000 Number 0 defsig.o ABSOLUTE ../clib/stdlib.c 0x00000000 Number 0 exit.o ABSOLUTE ../clib/string.c 0x00000000 Number 0 strlen.o ABSOLUTE + ../fplib/basic.s 0x00000000 Number 0 basic.o ABSOLUTE + ../fplib/daddsub.s 0x00000000 Number 0 daddsub_clz.o ABSOLUTE + ../fplib/dcmpi.s 0x00000000 Number 0 dcmpi.o ABSOLUTE + ../fplib/ddiv.s 0x00000000 Number 0 ddiv.o ABSOLUTE + ../fplib/deqf.s 0x00000000 Number 0 deqf.o ABSOLUTE + ../fplib/dleqf.s 0x00000000 Number 0 dleqf.o ABSOLUTE + ../fplib/dmul.s 0x00000000 Number 0 dmul.o ABSOLUTE + ../fplib/dnaninf.s 0x00000000 Number 0 dnaninf.o ABSOLUTE + ../fplib/dretinf.s 0x00000000 Number 0 dretinf.o ABSOLUTE + ../fplib/drleqf.s 0x00000000 Number 0 drleqf.o ABSOLUTE + ../fplib/ffixll.s 0x00000000 Number 0 ffixll.o ABSOLUTE + ../fplib/fnaninf.s 0x00000000 Number 0 fnaninf.o ABSOLUTE ../fplib/fpinit.s 0x00000000 Number 0 fpinit.o ABSOLUTE - D:\\programs\\mdk\\Arm\\Packs\\Nuvoton\\NuMicro_DFP\\1.2.0\\Device\\M451\\Driver\\can.c 0x00000000 Number 0 can.o ABSOLUTE - D:\\programs\\mdk\\Arm\\Packs\\Nuvoton\\NuMicro_DFP\\1.2.0\\Device\\M451\\Driver\\clk.c 0x00000000 Number 0 clk.o ABSOLUTE - D:\\programs\\mdk\\Arm\\Packs\\Nuvoton\\NuMicro_DFP\\1.2.0\\Device\\M451\\Driver\\eadc.c 0x00000000 Number 0 eadc.o ABSOLUTE - D:\\programs\\mdk\\Arm\\Packs\\Nuvoton\\NuMicro_DFP\\1.2.0\\Device\\M451\\Driver\\gpio.c 0x00000000 Number 0 gpio.o ABSOLUTE - D:\\programs\\mdk\\Arm\\Packs\\Nuvoton\\NuMicro_DFP\\1.2.0\\Device\\M451\\Driver\\i2c.c 0x00000000 Number 0 i2c.o ABSOLUTE - D:\\programs\\mdk\\Arm\\Packs\\Nuvoton\\NuMicro_DFP\\1.2.0\\Device\\M451\\Driver\\pwm.c 0x00000000 Number 0 pwm.o ABSOLUTE - D:\\programs\\mdk\\Arm\\Packs\\Nuvoton\\NuMicro_DFP\\1.2.0\\Device\\M451\\Driver\\sc.c 0x00000000 Number 0 sc.o ABSOLUTE - D:\\programs\\mdk\\Arm\\Packs\\Nuvoton\\NuMicro_DFP\\1.2.0\\Device\\M451\\Driver\\sys.c 0x00000000 Number 0 sys.o ABSOLUTE - D:\\programs\\mdk\\Arm\\Packs\\Nuvoton\\NuMicro_DFP\\1.2.0\\Device\\M451\\Driver\\uart.c 0x00000000 Number 0 uart.o ABSOLUTE - D:\programs\mdk\Arm\Packs\Nuvoton\NuMicro_DFP\1.2.0\Device\M451\Driver\can.c 0x00000000 Number 0 can.o ABSOLUTE - D:\programs\mdk\Arm\Packs\Nuvoton\NuMicro_DFP\1.2.0\Device\M451\Driver\clk.c 0x00000000 Number 0 clk.o ABSOLUTE - D:\programs\mdk\Arm\Packs\Nuvoton\NuMicro_DFP\1.2.0\Device\M451\Driver\eadc.c 0x00000000 Number 0 eadc.o ABSOLUTE - D:\programs\mdk\Arm\Packs\Nuvoton\NuMicro_DFP\1.2.0\Device\M451\Driver\gpio.c 0x00000000 Number 0 gpio.o ABSOLUTE - D:\programs\mdk\Arm\Packs\Nuvoton\NuMicro_DFP\1.2.0\Device\M451\Driver\i2c.c 0x00000000 Number 0 i2c.o ABSOLUTE - D:\programs\mdk\Arm\Packs\Nuvoton\NuMicro_DFP\1.2.0\Device\M451\Driver\pwm.c 0x00000000 Number 0 pwm.o ABSOLUTE - D:\programs\mdk\Arm\Packs\Nuvoton\NuMicro_DFP\1.2.0\Device\M451\Driver\sc.c 0x00000000 Number 0 sc.o ABSOLUTE - D:\programs\mdk\Arm\Packs\Nuvoton\NuMicro_DFP\1.2.0\Device\M451\Driver\sys.c 0x00000000 Number 0 sys.o ABSOLUTE - D:\programs\mdk\Arm\Packs\Nuvoton\NuMicro_DFP\1.2.0\Device\M451\Driver\uart.c 0x00000000 Number 0 uart.o ABSOLUTE + ../fplib/usenofp.s 0x00000000 Number 0 usenofp.o ABSOLUTE + ..\StdDriver\src\clk.c 0x00000000 Number 0 clk.o ABSOLUTE + ..\StdDriver\src\eadc.c 0x00000000 Number 0 eadc.o ABSOLUTE + ..\StdDriver\src\gpio.c 0x00000000 Number 0 gpio.o ABSOLUTE + ..\StdDriver\src\i2c.c 0x00000000 Number 0 i2c.o ABSOLUTE + ..\StdDriver\src\pwm.c 0x00000000 Number 0 pwm.o ABSOLUTE + ..\StdDriver\src\sc.c 0x00000000 Number 0 sc.o ABSOLUTE + ..\StdDriver\src\sys.c 0x00000000 Number 0 sys.o ABSOLUTE + ..\StdDriver\src\uart.c 0x00000000 Number 0 uart.o ABSOLUTE + ..\\StdDriver\\src\\clk.c 0x00000000 Number 0 clk.o ABSOLUTE + ..\\StdDriver\\src\\eadc.c 0x00000000 Number 0 eadc.o ABSOLUTE + ..\\StdDriver\\src\\gpio.c 0x00000000 Number 0 gpio.o ABSOLUTE + ..\\StdDriver\\src\\i2c.c 0x00000000 Number 0 i2c.o ABSOLUTE + ..\\StdDriver\\src\\pwm.c 0x00000000 Number 0 pwm.o ABSOLUTE + ..\\StdDriver\\src\\sc.c 0x00000000 Number 0 sc.o ABSOLUTE + ..\\StdDriver\\src\\sys.c 0x00000000 Number 0 sys.o ABSOLUTE + ..\\StdDriver\\src\\uart.c 0x00000000 Number 0 uart.o ABSOLUTE + D:\\programs\\mdk\\Arm\\Packs\\ARM\\CMSIS\\5.5.1\\CMSIS\\DSP\\Source\\BasicMathFunctions\\BasicMathFunctions.c 0x00000000 Number 0 basicmathfunctions.o ABSOLUTE + D:\\programs\\mdk\\Arm\\Packs\\ARM\\CMSIS\\5.5.1\\CMSIS\\DSP\\Source\\CommonTables\\CommonTables.c 0x00000000 Number 0 commontables.o ABSOLUTE + D:\\programs\\mdk\\Arm\\Packs\\ARM\\CMSIS\\5.5.1\\CMSIS\\DSP\\Source\\ComplexMathFunctions\\ComplexMathFunctions.c 0x00000000 Number 0 complexmathfunctions.o ABSOLUTE + D:\\programs\\mdk\\Arm\\Packs\\ARM\\CMSIS\\5.5.1\\CMSIS\\DSP\\Source\\ControllerFunctions\\ControllerFunctions.c 0x00000000 Number 0 controllerfunctions.o ABSOLUTE + D:\\programs\\mdk\\Arm\\Packs\\ARM\\CMSIS\\5.5.1\\CMSIS\\DSP\\Source\\FastMathFunctions\\FastMathFunctions.c 0x00000000 Number 0 fastmathfunctions.o ABSOLUTE + D:\\programs\\mdk\\Arm\\Packs\\ARM\\CMSIS\\5.5.1\\CMSIS\\DSP\\Source\\FilteringFunctions\\FilteringFunctions.c 0x00000000 Number 0 filteringfunctions.o ABSOLUTE + D:\\programs\\mdk\\Arm\\Packs\\ARM\\CMSIS\\5.5.1\\CMSIS\\DSP\\Source\\MatrixFunctions\\MatrixFunctions.c 0x00000000 Number 0 matrixfunctions.o ABSOLUTE + D:\\programs\\mdk\\Arm\\Packs\\ARM\\CMSIS\\5.5.1\\CMSIS\\DSP\\Source\\StatisticsFunctions\\StatisticsFunctions.c 0x00000000 Number 0 statisticsfunctions.o ABSOLUTE + D:\\programs\\mdk\\Arm\\Packs\\ARM\\CMSIS\\5.5.1\\CMSIS\\DSP\\Source\\SupportFunctions\\SupportFunctions.c 0x00000000 Number 0 supportfunctions.o ABSOLUTE + D:\\programs\\mdk\\Arm\\Packs\\ARM\\CMSIS\\5.5.1\\CMSIS\\DSP\\Source\\TransformFunctions\\TransformFunctions.c 0x00000000 Number 0 transformfunctions.o ABSOLUTE + D:\programs\mdk\Arm\Packs\ARM\CMSIS\5.5.1\CMSIS\DSP\Source\BasicMathFunctions\BasicMathFunctions.c 0x00000000 Number 0 basicmathfunctions.o ABSOLUTE + D:\programs\mdk\Arm\Packs\ARM\CMSIS\5.5.1\CMSIS\DSP\Source\CommonTables\CommonTables.c 0x00000000 Number 0 commontables.o ABSOLUTE + D:\programs\mdk\Arm\Packs\ARM\CMSIS\5.5.1\CMSIS\DSP\Source\ComplexMathFunctions\ComplexMathFunctions.c 0x00000000 Number 0 complexmathfunctions.o ABSOLUTE + D:\programs\mdk\Arm\Packs\ARM\CMSIS\5.5.1\CMSIS\DSP\Source\ControllerFunctions\ControllerFunctions.c 0x00000000 Number 0 controllerfunctions.o ABSOLUTE + D:\programs\mdk\Arm\Packs\ARM\CMSIS\5.5.1\CMSIS\DSP\Source\FastMathFunctions\FastMathFunctions.c 0x00000000 Number 0 fastmathfunctions.o ABSOLUTE + D:\programs\mdk\Arm\Packs\ARM\CMSIS\5.5.1\CMSIS\DSP\Source\FilteringFunctions\FilteringFunctions.c 0x00000000 Number 0 filteringfunctions.o ABSOLUTE + D:\programs\mdk\Arm\Packs\ARM\CMSIS\5.5.1\CMSIS\DSP\Source\MatrixFunctions\MatrixFunctions.c 0x00000000 Number 0 matrixfunctions.o ABSOLUTE + D:\programs\mdk\Arm\Packs\ARM\CMSIS\5.5.1\CMSIS\DSP\Source\StatisticsFunctions\StatisticsFunctions.c 0x00000000 Number 0 statisticsfunctions.o ABSOLUTE + D:\programs\mdk\Arm\Packs\ARM\CMSIS\5.5.1\CMSIS\DSP\Source\SupportFunctions\SupportFunctions.c 0x00000000 Number 0 supportfunctions.o ABSOLUTE + D:\programs\mdk\Arm\Packs\ARM\CMSIS\5.5.1\CMSIS\DSP\Source\TransformFunctions\TransformFunctions.c 0x00000000 Number 0 transformfunctions.o ABSOLUTE RTE\Device\M453VG6AE\retarget.c 0x00000000 Number 0 retarget.o ABSOLUTE RTE\Device\M453VG6AE\startup_M451Series.s 0x00000000 Number 0 startup_m451series.o ABSOLUTE RTE\Device\M453VG6AE\system_M451Series.c 0x00000000 Number 0 system_m451series.o ABSOLUTE @@ -419,57 +884,57 @@ Image Symbol Table .ARM.Collect$$rtexit$$00000004 0x00000228 Section 6 rtexit2.o(.ARM.Collect$$rtexit$$00000004) .emb_text 0x00000230 Section 28 retarget.o(.emb_text) $v0 0x00000230 Number 0 retarget.o(.emb_text) - .text 0x0000024c Section 0 main.o(.text) - SYS_UnlockReg() 0x000005e7 Thumb Code 32 main.o(.text) - .text 0x000006b8 Section 0 ssd1306.o(.text) - .text 0x00000940 Section 0 clk.o(.text) - .text 0x00000de4 Section 0 eadc.o(.text) - .text 0x00000e70 Section 0 sys.o(.text) - .text 0x00000f0c Section 0 uart.o(.text) - CLK_GetPLLClockFreq 0x00000f0d Thumb Code 76 uart.o(.text) - __NVIC_EnableIRQ 0x00001237 Thumb Code 26 uart.o(.text) - __NVIC_DisableIRQ 0x00001251 Thumb Code 34 uart.o(.text) - .text 0x0000129c Section 0 retarget.o(.text) - __tagsym$$used 0x0000129d Number 0 retarget.o(.text) - stackDump 0x00001301 Thumb Code 72 retarget.o(.text) - .text 0x000013c4 Section 116 startup_m451series.o(.text) - $v0 0x000013c4 Number 0 startup_m451series.o(.text) - Default_Handler 0x00001409 Thumb Code 2 startup_m451series.o(.text) - .text 0x00001438 Section 0 system_m451series.o(.text) - .text 0x00001520 Section 0 i2c.o(.text) - .text 0x00001790 Section 0 pwm.o(.text) - CLK_GetPLLClockFreq 0x00001791 Thumb Code 76 pwm.o(.text) - .text 0x00001f00 Section 0 noretval__2printf.o(.text) - .text 0x00001f18 Section 0 noretval__2sprintf.o(.text) - .text 0x00001f40 Section 0 _printf_dec.o(.text) - .text 0x00001fb8 Section 0 _printf_hex_int.o(.text) - .text 0x00002010 Section 0 __printf_wp.o(.text) - .text 0x0000211e Section 0 strlen.o(.text) - .text 0x0000215c Section 78 rt_memclr_w.o(.text) - .text 0x000021aa Section 0 heapauxi.o(.text) - .text 0x000021b0 Section 0 _printf_intcommon.o(.text) - .text 0x00002264 Section 0 _printf_char_common.o(.text) - _printf_input_char 0x00002265 Thumb Code 10 _printf_char_common.o(.text) - .text 0x00002294 Section 0 _sputc.o(.text) - .text 0x000022a0 Section 0 _printf_char_file.o(.text) - .text 0x000022c4 Section 74 sys_stackheap_outer.o(.text) - .text 0x0000230e Section 0 exit.o(.text) - .text 0x00002320 Section 8 libspace.o(.text) - .text 0x00002328 Section 0 sys_exit.o(.text) - .text 0x00002334 Section 2 use_no_semi.o(.text) - .text 0x00002336 Section 0 indicate_semi.o(.text) - i._is_digit 0x00002336 Section 0 __printf_wp.o(i._is_digit) - x$fpl$fpinit 0x00002344 Section 10 fpinit.o(x$fpl$fpinit) - $v0 0x00002344 Number 0 fpinit.o(x$fpl$fpinit) - .constdata 0x00002350 Section 48 uart.o(.constdata) - .constdata 0x00002380 Section 40 _printf_hex_int.o(.constdata) - uc_hextab 0x00002380 Data 20 _printf_hex_int.o(.constdata) - lc_hextab 0x00002394 Data 20 _printf_hex_int.o(.constdata) - .conststring 0x000023a8 Section 246 main.o(.conststring) - .data 0x20000000 Section 20 main.o(.data) - cnt 0x20000004 Data 4 main.o(.data) - out 0x20000008 Data 4 main.o(.data) - .data 0x20000014 Section 1520 ssd1306.o(.data) + .text 0x0000024c Section 0 clk.o(.text) + .text 0x000006f0 Section 0 eadc.o(.text) + .text 0x0000077c Section 0 i2c.o(.text) + .text 0x00000a18 Section 0 sys.o(.text) + .text 0x00000ab4 Section 0 pwm.o(.text) + CLK_GetPLLClockFreq 0x00000ab5 Thumb Code 76 pwm.o(.text) + .text 0x00001224 Section 0 uart.o(.text) + CLK_GetPLLClockFreq 0x00001225 Thumb Code 76 uart.o(.text) + __NVIC_EnableIRQ 0x0000154f Thumb Code 26 uart.o(.text) + __NVIC_DisableIRQ 0x00001569 Thumb Code 34 uart.o(.text) + .text 0x000015b4 Section 0 ssd1306.o(.text) + .text 0x0000183c Section 0 main.o(.text) + SYS_UnlockReg() 0x00001bd7 Thumb Code 32 main.o(.text) + .text 0x00001ca8 Section 0 retarget.o(.text) + __tagsym$$used 0x00001ca9 Number 0 retarget.o(.text) + stackDump 0x00001d0d Thumb Code 72 retarget.o(.text) + .text 0x00001dd0 Section 116 startup_m451series.o(.text) + $v0 0x00001dd0 Number 0 startup_m451series.o(.text) + Default_Handler 0x00001e15 Thumb Code 2 startup_m451series.o(.text) + .text 0x00001e44 Section 0 system_m451series.o(.text) + .text 0x00001f2c Section 0 noretval__2printf.o(.text) + .text 0x00001f44 Section 0 noretval__2sprintf.o(.text) + .text 0x00001f6c Section 0 _printf_dec.o(.text) + .text 0x00001fe4 Section 0 _printf_hex_int.o(.text) + .text 0x0000203c Section 0 __printf_wp.o(.text) + .text 0x0000214a Section 0 strlen.o(.text) + .text 0x00002188 Section 78 rt_memclr_w.o(.text) + .text 0x000021d6 Section 0 heapauxi.o(.text) + .text 0x000021dc Section 0 _printf_intcommon.o(.text) + .text 0x00002290 Section 0 _printf_char_common.o(.text) + _printf_input_char 0x00002291 Thumb Code 10 _printf_char_common.o(.text) + .text 0x000022c0 Section 0 _sputc.o(.text) + .text 0x000022cc Section 0 _printf_char_file.o(.text) + .text 0x000022f0 Section 74 sys_stackheap_outer.o(.text) + .text 0x0000233a Section 0 exit.o(.text) + .text 0x0000234c Section 8 libspace.o(.text) + .text 0x00002354 Section 0 sys_exit.o(.text) + .text 0x00002360 Section 2 use_no_semi.o(.text) + .text 0x00002362 Section 0 indicate_semi.o(.text) + i._is_digit 0x00002362 Section 0 __printf_wp.o(i._is_digit) + x$fpl$fpinit 0x00002370 Section 10 fpinit.o(x$fpl$fpinit) + $v0 0x00002370 Number 0 fpinit.o(x$fpl$fpinit) + .constdata 0x0000237c Section 48 uart.o(.constdata) + .constdata 0x000023ac Section 40 _printf_hex_int.o(.constdata) + uc_hextab 0x000023ac Data 20 _printf_hex_int.o(.constdata) + lc_hextab 0x000023c0 Data 20 _printf_hex_int.o(.constdata) + .conststring 0x000023d4 Section 246 main.o(.conststring) + .data 0x20000000 Section 1520 ssd1306.o(.data) + .data 0x200005f0 Section 20 main.o(.data) + cnt 0x200005f4 Data 4 main.o(.data) + out 0x200005f8 Data 4 main.o(.data) .data 0x20000604 Section 4 retarget.o(.data) .data 0x20000608 Section 44 system_m451series.o(.data) .bss 0x20000634 Section 96 libspace.o(.bss) @@ -578,286 +1043,286 @@ Image Symbol Table __rt_exit_prels_1 0x00000225 Thumb Code 0 rtexit2.o(.ARM.Collect$$rtexit$$00000002) __rt_exit_exit 0x00000229 Thumb Code 0 rtexit2.o(.ARM.Collect$$rtexit$$00000004) HardFault_Handler 0x00000231 Thumb Code 24 retarget.o(.emb_text) - PWMInit() 0x0000024d Thumb Code 204 main.o(.text) - I2CInit() 0x00000319 Thumb Code 88 main.o(.text) - SYS_Init() 0x00000371 Thumb Code 142 main.o(.text) - UART0_Init() 0x000003ff Thumb Code 22 main.o(.text) - EADC_FunctionTest() 0x00000415 Thumb Code 346 main.o(.text) - PWM0P0_IRQHandler() 0x0000056f Thumb Code 62 main.o(.text) - ADC00_IRQHandler() 0x000005ad Thumb Code 14 main.o(.text) - main 0x000005bb Thumb Code 44 main.o(.text) - OLED_SingleWrite 0x000006b9 Thumb Code 96 ssd1306.o(.text) - OLED_SingleRead 0x00000719 Thumb Code 138 ssd1306.o(.text) - oledWriteCommand 0x000007a3 Thumb Code 6 ssd1306.o(.text) - oledWriteData 0x000007a9 Thumb Code 6 ssd1306.o(.text) - Init_LCD 0x000007af Thumb Code 172 ssd1306.o(.text) - oled_address 0x0000085b Thumb Code 32 ssd1306.o(.text) - clear_LCD 0x0000087b Thumb Code 38 ssd1306.o(.text) - draw_LCD 0x000008a1 Thumb Code 44 ssd1306.o(.text) - print_C 0x000008cd Thumb Code 70 ssd1306.o(.text) - print_Line 0x00000913 Thumb Code 36 ssd1306.o(.text) - CLK_DisableModuleClock 0x00000941 Thumb Code 28 clk.o(.text) - CLK_DisableCKO 0x0000095d Thumb Code 4 clk.o(.text) - CLK_SetModuleClock 0x00000961 Thumb Code 74 clk.o(.text) - CLK_EnableModuleClock 0x000009ab Thumb Code 28 clk.o(.text) - CLK_EnableCKO 0x000009c7 Thumb Code 40 clk.o(.text) - CLK_PowerDown 0x000009ef Thumb Code 28 clk.o(.text) - CLK_Idle 0x00000a0b Thumb Code 28 clk.o(.text) - CLK_GetHXTFreq 0x00000a27 Thumb Code 16 clk.o(.text) - CLK_GetLXTFreq 0x00000a37 Thumb Code 22 clk.o(.text) - CLK_GetPCLK0Freq 0x00000a4d Thumb Code 26 clk.o(.text) - CLK_GetPCLK1Freq 0x00000a67 Thumb Code 26 clk.o(.text) - CLK_GetHCLKFreq 0x00000a81 Thumb Code 12 clk.o(.text) - CLK_GetCPUFreq 0x00000a8d Thumb Code 12 clk.o(.text) - CLK_WaitClockReady 0x00000a99 Thumb Code 38 clk.o(.text) - CLK_SetHCLK 0x00000abf Thumb Code 98 clk.o(.text) - CLK_DisablePLL 0x00000b21 Thumb Code 18 clk.o(.text) - CLK_EnablePLL 0x00000b33 Thumb Code 344 clk.o(.text) - CLK_SetCoreClock 0x00000c8b Thumb Code 136 clk.o(.text) - CLK_SetSysTickClockSrc 0x00000d13 Thumb Code 20 clk.o(.text) - CLK_EnableXtalRC 0x00000d27 Thumb Code 16 clk.o(.text) - CLK_DisableXtalRC 0x00000d37 Thumb Code 106 clk.o(.text) - CLK_EnableSysTick 0x00000da1 Thumb Code 56 clk.o(.text) - CLK_DisableSysTick 0x00000dd9 Thumb Code 10 clk.o(.text) - EADC_Open 0x00000de5 Thumb Code 20 eadc.o(.text) - EADC_Close 0x00000df9 Thumb Code 10 eadc.o(.text) - EADC_ConfigSampleModule 0x00000e03 Thumb Code 26 eadc.o(.text) - EADC_SetTriggerDelayTime 0x00000e1d Thumb Code 30 eadc.o(.text) - EADC_SetInternalSampleTime 0x00000e3b Thumb Code 22 eadc.o(.text) - EADC_SetExtendSampleTime 0x00000e51 Thumb Code 24 eadc.o(.text) - SYS_ClearResetSrc 0x00000e71 Thumb Code 12 sys.o(.text) - SYS_GetBODStatus 0x00000e7d Thumb Code 12 sys.o(.text) - SYS_GetResetSrc 0x00000e89 Thumb Code 8 sys.o(.text) - SYS_IsRegLocked 0x00000e91 Thumb Code 16 sys.o(.text) - SYS_ReadPDID 0x00000ea1 Thumb Code 8 sys.o(.text) - SYS_ResetChip 0x00000ea9 Thumb Code 14 sys.o(.text) - SYS_ResetCPU 0x00000eb7 Thumb Code 14 sys.o(.text) - SYS_ResetModule 0x00000ec5 Thumb Code 24 sys.o(.text) - SYS_EnableBOD 0x00000edd Thumb Code 34 sys.o(.text) - SYS_DisableBOD 0x00000eff Thumb Code 14 sys.o(.text) - UART_ClearIntFlag 0x00000f59 Thumb Code 68 uart.o(.text) - UART_Close 0x00000f9d Thumb Code 6 uart.o(.text) - UART_DisableFlowCtrl 0x00000fa3 Thumb Code 10 uart.o(.text) - UART_DisableInt 0x00000fad Thumb Code 42 uart.o(.text) - UART_EnableFlowCtrl 0x00000fd7 Thumb Code 26 uart.o(.text) - UART_EnableInt 0x00000ff1 Thumb Code 42 uart.o(.text) - UART_Open 0x0000101b Thumb Code 126 uart.o(.text) - UART_Read 0x00001099 Thumb Code 44 uart.o(.text) - UART_SetLine_Config 0x000010c5 Thumb Code 128 uart.o(.text) - UART_SetTimeoutCnt 0x00001145 Thumb Code 20 uart.o(.text) - UART_SelectIrDAMode 0x00001159 Thumb Code 130 uart.o(.text) - UART_SelectRS485Mode 0x000011db Thumb Code 26 uart.o(.text) - UART_SelectLINMode 0x000011f5 Thumb Code 22 uart.o(.text) - UART_Write 0x0000120b Thumb Code 44 uart.o(.text) - Hard_Fault_Handler 0x0000129d Thumb Code 16 retarget.o(.text) - SendChar_ToUART 0x000012ad Thumb Code 26 retarget.o(.text) - SendChar 0x000012c7 Thumb Code 2 retarget.o(.text) - GetChar 0x000012c9 Thumb Code 14 retarget.o(.text) - kbhit 0x000012d7 Thumb Code 10 retarget.o(.text) - IsDebugFifoEmpty 0x000012e1 Thumb Code 10 retarget.o(.text) - _ttywrch 0x000012eb Thumb Code 2 retarget.o(.text) - fputc 0x000012ed Thumb Code 12 retarget.o(.text) - fgetc 0x000012f9 Thumb Code 2 retarget.o(.text) - ferror 0x000012fb Thumb Code 6 retarget.o(.text) - Reset_Handler 0x000013c5 Thumb Code 50 startup_m451series.o(.text) - NMI_Handler 0x000013f7 Thumb Code 2 startup_m451series.o(.text) - MemManage_Handler 0x000013fb Thumb Code 2 startup_m451series.o(.text) - BusFault_Handler 0x000013fd Thumb Code 2 startup_m451series.o(.text) - UsageFault_Handler 0x000013ff Thumb Code 2 startup_m451series.o(.text) - SVC_Handler 0x00001401 Thumb Code 2 startup_m451series.o(.text) - DebugMon_Handler 0x00001403 Thumb Code 2 startup_m451series.o(.text) - PendSV_Handler 0x00001405 Thumb Code 2 startup_m451series.o(.text) - SysTick_Handler 0x00001407 Thumb Code 2 startup_m451series.o(.text) - ACMP01_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - ADC00_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - ADC01_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - ADC02_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - ADC03_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - BOD_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - BRAKE0_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - BRAKE1_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - CAN0_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - CLKFAIL_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - DAC_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - EINT0_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - EINT1_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - EINT2_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - EINT3_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - EINT4_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - EINT5_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - GPA_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - GPB_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - GPC_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - GPD_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - GPE_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - GPF_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - I2C0_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - I2C1_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - IRC_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - PDMA_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - PWM0P0_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - PWM0P1_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - PWM0P2_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - PWM1P0_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - PWM1P1_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - PWM1P2_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - PWRWU_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - RAMPE_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - RTC_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - SC0_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - SPI0_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - SPI1_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - SPI2_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - TAMPER_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - TK_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - TMR0_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - TMR1_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - TMR2_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - TMR3_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - UART0_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - UART1_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - UART2_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - UART3_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - USBD_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - USBH_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - USBOTG_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - WDT_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - WWDT_IRQHandler 0x00001409 Thumb Code 0 startup_m451series.o(.text) - __user_initial_stackheap 0x0000140d Thumb Code 10 startup_m451series.o(.text) - SystemCoreClockUpdate 0x00001439 Thumb Code 128 system_m451series.o(.text) - SystemInit 0x000014b9 Thumb Code 80 system_m451series.o(.text) - I2C_Open 0x00001521 Thumb Code 46 i2c.o(.text) - I2C_Close 0x0000154f Thumb Code 56 i2c.o(.text) - I2C_ClearTimeoutFlag 0x00001587 Thumb Code 10 i2c.o(.text) - I2C_Trigger 0x00001591 Thumb Code 40 i2c.o(.text) - I2C_DisableInt 0x000015b9 Thumb Code 10 i2c.o(.text) - I2C_EnableInt 0x000015c3 Thumb Code 10 i2c.o(.text) - I2C_GetBusClockFreq 0x000015cd Thumb Code 16 i2c.o(.text) - I2C_SetBusClockFreq 0x000015dd Thumb Code 36 i2c.o(.text) - I2C_GetIntFlag 0x00001601 Thumb Code 8 i2c.o(.text) - I2C_GetStatus 0x00001609 Thumb Code 4 i2c.o(.text) - I2C_GetData 0x0000160d Thumb Code 6 i2c.o(.text) - I2C_SetData 0x00001613 Thumb Code 4 i2c.o(.text) - I2C_SetSlaveAddr 0x00001617 Thumb Code 32 i2c.o(.text) - I2C_SetSlaveAddrMask 0x00001637 Thumb Code 30 i2c.o(.text) - I2C_EnableTimeout 0x00001655 Thumb Code 28 i2c.o(.text) - I2C_DisableTimeout 0x00001671 Thumb Code 10 i2c.o(.text) - I2C_EnableWakeup 0x0000167b Thumb Code 10 i2c.o(.text) - I2C_DisableWakeup 0x00001685 Thumb Code 10 i2c.o(.text) - I2C_SMBusGetStatus 0x0000168f Thumb Code 4 i2c.o(.text) - I2C_SMBusClearInterruptFlag 0x00001693 Thumb Code 8 i2c.o(.text) - I2C_SMBusSetPacketByteCount 0x0000169b Thumb Code 4 i2c.o(.text) - I2C_SMBusOpen 0x0000169f Thumb Code 28 i2c.o(.text) - I2C_SMBusClose 0x000016bb Thumb Code 6 i2c.o(.text) - I2C_SMBusPECTxEnable 0x000016c1 Thumb Code 28 i2c.o(.text) - I2C_SMBusGetPECValue 0x000016dd Thumb Code 6 i2c.o(.text) - I2C_SMBusIdleTimeout 0x000016e3 Thumb Code 40 i2c.o(.text) - I2C_SMBusTimeout 0x0000170b Thumb Code 60 i2c.o(.text) - I2C_SMBusClockLoTimeout 0x00001747 Thumb Code 60 i2c.o(.text) - PWM_ConfigCaptureChannel 0x000017dd Thumb Code 162 pwm.o(.text) - PWM_ConfigOutputChannel 0x0000187f Thumb Code 252 pwm.o(.text) - PWM_Start 0x0000197b Thumb Code 8 pwm.o(.text) - PWM_Stop 0x00001983 Thumb Code 30 pwm.o(.text) - PWM_ForceStop 0x000019a1 Thumb Code 8 pwm.o(.text) - PWM_EnableADCTrigger 0x000019a9 Thumb Code 44 pwm.o(.text) - PWM_DisableADCTrigger 0x000019d5 Thumb Code 30 pwm.o(.text) - PWM_ClearADCTriggerFlag 0x000019f3 Thumb Code 12 pwm.o(.text) - PWM_GetADCTriggerFlag 0x000019ff Thumb Code 18 pwm.o(.text) - PWM_EnableDACTrigger 0x00001a11 Thumb Code 12 pwm.o(.text) - PWM_DisableDACTrigger 0x00001a1d Thumb Code 16 pwm.o(.text) - PWM_ClearDACTriggerFlag 0x00001a2d Thumb Code 10 pwm.o(.text) - PWM_GetDACTriggerFlag 0x00001a37 Thumb Code 10 pwm.o(.text) - PWM_EnableFaultBrake 0x00001a41 Thumb Code 228 pwm.o(.text) - PWM_EnableCapture 0x00001b25 Thumb Code 22 pwm.o(.text) - PWM_DisableCapture 0x00001b3b Thumb Code 22 pwm.o(.text) - PWM_EnableOutput 0x00001b51 Thumb Code 10 pwm.o(.text) - PWM_DisableOutput 0x00001b5b Thumb Code 10 pwm.o(.text) - PWM_EnablePDMA 0x00001b65 Thumb Code 64 pwm.o(.text) - PWM_DisablePDMA 0x00001ba5 Thumb Code 20 pwm.o(.text) - PWM_EnableDeadZone 0x00001bb9 Thumb Code 26 pwm.o(.text) - PWM_DisableDeadZone 0x00001bd3 Thumb Code 16 pwm.o(.text) - PWM_EnableCaptureInt 0x00001be3 Thumb Code 14 pwm.o(.text) - PWM_DisableCaptureInt 0x00001bf1 Thumb Code 14 pwm.o(.text) - PWM_ClearCaptureIntFlag 0x00001bff Thumb Code 8 pwm.o(.text) - PWM_GetCaptureIntFlag 0x00001c07 Thumb Code 36 pwm.o(.text) - PWM_EnableDutyInt 0x00001c2b Thumb Code 12 pwm.o(.text) - PWM_DisableDutyInt 0x00001c37 Thumb Code 14 pwm.o(.text) - PWM_ClearDutyIntFlag 0x00001c45 Thumb Code 10 pwm.o(.text) - PWM_GetDutyIntFlag 0x00001c4f Thumb Code 16 pwm.o(.text) - PWM_EnableFaultBrakeInt 0x00001c5f Thumb Code 14 pwm.o(.text) - PWM_DisableFaultBrakeInt 0x00001c6d Thumb Code 14 pwm.o(.text) - PWM_ClearFaultBrakeIntFlag 0x00001c7b Thumb Code 10 pwm.o(.text) - PWM_GetFaultBrakeIntFlag 0x00001c85 Thumb Code 16 pwm.o(.text) - PWM_EnablePeriodInt 0x00001c95 Thumb Code 16 pwm.o(.text) - PWM_DisablePeriodInt 0x00001ca5 Thumb Code 16 pwm.o(.text) - PWM_ClearPeriodIntFlag 0x00001cb5 Thumb Code 12 pwm.o(.text) - PWM_GetPeriodIntFlag 0x00001cc1 Thumb Code 18 pwm.o(.text) - PWM_EnableZeroInt 0x00001cd3 Thumb Code 14 pwm.o(.text) - PWM_DisableZeroInt 0x00001ce1 Thumb Code 14 pwm.o(.text) - PWM_ClearZeroIntFlag 0x00001cef Thumb Code 10 pwm.o(.text) - PWM_GetZeroIntFlag 0x00001cf9 Thumb Code 16 pwm.o(.text) - PWM_EnableAcc 0x00001d09 Thumb Code 32 pwm.o(.text) - PWM_DisableAcc 0x00001d29 Thumb Code 18 pwm.o(.text) - PWM_EnableAccInt 0x00001d3b Thumb Code 18 pwm.o(.text) - PWM_DisableAccInt 0x00001d4d Thumb Code 18 pwm.o(.text) - PWM_ClearAccInt 0x00001d5f Thumb Code 14 pwm.o(.text) - PWM_GetAccInt 0x00001d6d Thumb Code 20 pwm.o(.text) - PWM_ClearFTDutyIntFlag 0x00001d81 Thumb Code 14 pwm.o(.text) - PWM_GetFTDutyIntFlag 0x00001d8f Thumb Code 20 pwm.o(.text) - PWM_EnableLoadMode 0x00001da3 Thumb Code 10 pwm.o(.text) - PWM_DisableLoadMode 0x00001dad Thumb Code 10 pwm.o(.text) - PWM_ConfigSyncPhase 0x00001db7 Thumb Code 50 pwm.o(.text) - PWM_EnableSyncPhase 0x00001de9 Thumb Code 34 pwm.o(.text) - PWM_DisableSyncPhase 0x00001e0b Thumb Code 34 pwm.o(.text) - PWM_EnableSyncNoiseFilter 0x00001e2d Thumb Code 22 pwm.o(.text) - PWM_DisableSyncNoiseFilter 0x00001e43 Thumb Code 10 pwm.o(.text) - PWM_EnableSyncPinInverse 0x00001e4d Thumb Code 10 pwm.o(.text) - PWM_DisableSyncPinInverse 0x00001e57 Thumb Code 10 pwm.o(.text) - PWM_SetClockSource 0x00001e61 Thumb Code 22 pwm.o(.text) - PWM_EnableBrakeNoiseFilter 0x00001e77 Thumb Code 30 pwm.o(.text) - PWM_DisableBrakeNoiseFilter 0x00001e95 Thumb Code 16 pwm.o(.text) - PWM_EnableBrakePinInverse 0x00001ea5 Thumb Code 16 pwm.o(.text) - PWM_DisableBrakePinInverse 0x00001eb5 Thumb Code 16 pwm.o(.text) - PWM_SetBrakePinSource 0x00001ec5 Thumb Code 30 pwm.o(.text) - PWM_GetWrapAroundFlag 0x00001ee3 Thumb Code 16 pwm.o(.text) - PWM_ClearWrapAroundFlag 0x00001ef3 Thumb Code 10 pwm.o(.text) - __2printf 0x00001f01 Thumb Code 20 noretval__2printf.o(.text) - __2sprintf 0x00001f19 Thumb Code 34 noretval__2sprintf.o(.text) - _printf_int_dec 0x00001f41 Thumb Code 104 _printf_dec.o(.text) - _printf_int_hex 0x00001fb9 Thumb Code 84 _printf_hex_int.o(.text) - _printf_longlong_hex 0x00001fb9 Thumb Code 0 _printf_hex_int.o(.text) - __printf 0x00002011 Thumb Code 270 __printf_wp.o(.text) - strlen 0x0000211f Thumb Code 62 strlen.o(.text) - __aeabi_memclr4 0x0000215d Thumb Code 0 rt_memclr_w.o(.text) - __aeabi_memclr8 0x0000215d Thumb Code 0 rt_memclr_w.o(.text) - __rt_memclr_w 0x0000215d Thumb Code 78 rt_memclr_w.o(.text) - _memset_w 0x00002161 Thumb Code 0 rt_memclr_w.o(.text) - __use_two_region_memory 0x000021ab Thumb Code 2 heapauxi.o(.text) - __rt_heap_escrow$2region 0x000021ad Thumb Code 2 heapauxi.o(.text) - __rt_heap_expand$2region 0x000021af Thumb Code 2 heapauxi.o(.text) - _printf_int_common 0x000021b1 Thumb Code 178 _printf_intcommon.o(.text) - _printf_char_common 0x0000226f Thumb Code 32 _printf_char_common.o(.text) - _sputc 0x00002295 Thumb Code 10 _sputc.o(.text) - _printf_char_file 0x000022a1 Thumb Code 32 _printf_char_file.o(.text) - __user_setup_stackheap 0x000022c5 Thumb Code 74 sys_stackheap_outer.o(.text) - exit 0x0000230f Thumb Code 18 exit.o(.text) - __user_libspace 0x00002321 Thumb Code 8 libspace.o(.text) - __user_perproc_libspace 0x00002321 Thumb Code 0 libspace.o(.text) - __user_perthread_libspace 0x00002321 Thumb Code 0 libspace.o(.text) - _sys_exit 0x00002329 Thumb Code 8 sys_exit.o(.text) - __I$use$semihosting 0x00002335 Thumb Code 0 use_no_semi.o(.text) - __use_no_semihosting_swi 0x00002335 Thumb Code 2 use_no_semi.o(.text) - __semihosting_library_function 0x00002337 Thumb Code 0 indicate_semi.o(.text) - _is_digit 0x00002337 Thumb Code 14 __printf_wp.o(i._is_digit) - _fp_init 0x00002345 Thumb Code 10 fpinit.o(x$fpl$fpinit) - __fplib_config_fpu_vfp 0x0000234d Thumb Code 0 fpinit.o(x$fpl$fpinit) - __fplib_config_pureend_doubles 0x0000234d Thumb Code 0 fpinit.o(x$fpl$fpinit) - Region$$Table$$Base 0x000024a0 Number 0 anon$$obj.o(Region$$Table) - Region$$Table$$Limit 0x000024c0 Number 0 anon$$obj.o(Region$$Table) - g_u32COVNUMFlag 0x20000000 Data 4 main.o(.data) - g_u32AdcIntFlag 0x2000000c Data 4 main.o(.data) - x 0x20000010 Data 4 main.o(.data) - F8X16 0x20000014 Data 1520 ssd1306.o(.data) + CLK_DisableModuleClock 0x0000024d Thumb Code 28 clk.o(.text) + CLK_DisableCKO 0x00000269 Thumb Code 4 clk.o(.text) + CLK_SetModuleClock 0x0000026d Thumb Code 74 clk.o(.text) + CLK_EnableModuleClock 0x000002b7 Thumb Code 28 clk.o(.text) + CLK_EnableCKO 0x000002d3 Thumb Code 40 clk.o(.text) + CLK_PowerDown 0x000002fb Thumb Code 28 clk.o(.text) + CLK_Idle 0x00000317 Thumb Code 28 clk.o(.text) + CLK_GetHXTFreq 0x00000333 Thumb Code 16 clk.o(.text) + CLK_GetLXTFreq 0x00000343 Thumb Code 22 clk.o(.text) + CLK_GetPCLK0Freq 0x00000359 Thumb Code 26 clk.o(.text) + CLK_GetPCLK1Freq 0x00000373 Thumb Code 26 clk.o(.text) + CLK_GetHCLKFreq 0x0000038d Thumb Code 12 clk.o(.text) + CLK_GetCPUFreq 0x00000399 Thumb Code 12 clk.o(.text) + CLK_WaitClockReady 0x000003a5 Thumb Code 38 clk.o(.text) + CLK_SetHCLK 0x000003cb Thumb Code 98 clk.o(.text) + CLK_DisablePLL 0x0000042d Thumb Code 18 clk.o(.text) + CLK_EnablePLL 0x0000043f Thumb Code 344 clk.o(.text) + CLK_SetCoreClock 0x00000597 Thumb Code 136 clk.o(.text) + CLK_SetSysTickClockSrc 0x0000061f Thumb Code 20 clk.o(.text) + CLK_EnableXtalRC 0x00000633 Thumb Code 16 clk.o(.text) + CLK_DisableXtalRC 0x00000643 Thumb Code 106 clk.o(.text) + CLK_EnableSysTick 0x000006ad Thumb Code 56 clk.o(.text) + CLK_DisableSysTick 0x000006e5 Thumb Code 10 clk.o(.text) + EADC_Open 0x000006f1 Thumb Code 20 eadc.o(.text) + EADC_Close 0x00000705 Thumb Code 10 eadc.o(.text) + EADC_ConfigSampleModule 0x0000070f Thumb Code 26 eadc.o(.text) + EADC_SetTriggerDelayTime 0x00000729 Thumb Code 30 eadc.o(.text) + EADC_SetInternalSampleTime 0x00000747 Thumb Code 22 eadc.o(.text) + EADC_SetExtendSampleTime 0x0000075d Thumb Code 24 eadc.o(.text) + I2C_Open 0x0000077d Thumb Code 62 i2c.o(.text) + I2C_Close 0x000007bb Thumb Code 56 i2c.o(.text) + I2C_ClearTimeoutFlag 0x000007f3 Thumb Code 10 i2c.o(.text) + I2C_Trigger 0x000007fd Thumb Code 40 i2c.o(.text) + I2C_DisableInt 0x00000825 Thumb Code 10 i2c.o(.text) + I2C_EnableInt 0x0000082f Thumb Code 10 i2c.o(.text) + I2C_GetBusClockFreq 0x00000839 Thumb Code 30 i2c.o(.text) + I2C_SetBusClockFreq 0x00000857 Thumb Code 54 i2c.o(.text) + I2C_GetIntFlag 0x0000088d Thumb Code 8 i2c.o(.text) + I2C_GetStatus 0x00000895 Thumb Code 4 i2c.o(.text) + I2C_GetData 0x00000899 Thumb Code 6 i2c.o(.text) + I2C_SetData 0x0000089f Thumb Code 4 i2c.o(.text) + I2C_SetSlaveAddr 0x000008a3 Thumb Code 32 i2c.o(.text) + I2C_SetSlaveAddrMask 0x000008c3 Thumb Code 30 i2c.o(.text) + I2C_EnableTimeout 0x000008e1 Thumb Code 28 i2c.o(.text) + I2C_DisableTimeout 0x000008fd Thumb Code 10 i2c.o(.text) + I2C_EnableWakeup 0x00000907 Thumb Code 10 i2c.o(.text) + I2C_DisableWakeup 0x00000911 Thumb Code 10 i2c.o(.text) + I2C_SMBusGetStatus 0x0000091b Thumb Code 4 i2c.o(.text) + I2C_SMBusClearInterruptFlag 0x0000091f Thumb Code 8 i2c.o(.text) + I2C_SMBusSetPacketByteCount 0x00000927 Thumb Code 4 i2c.o(.text) + I2C_SMBusOpen 0x0000092b Thumb Code 28 i2c.o(.text) + I2C_SMBusClose 0x00000947 Thumb Code 6 i2c.o(.text) + I2C_SMBusPECTxEnable 0x0000094d Thumb Code 28 i2c.o(.text) + I2C_SMBusGetPECValue 0x00000969 Thumb Code 6 i2c.o(.text) + I2C_SMBusIdleTimeout 0x0000096f Thumb Code 40 i2c.o(.text) + I2C_SMBusTimeout 0x00000997 Thumb Code 60 i2c.o(.text) + I2C_SMBusClockLoTimeout 0x000009d3 Thumb Code 60 i2c.o(.text) + SYS_ClearResetSrc 0x00000a19 Thumb Code 12 sys.o(.text) + SYS_GetBODStatus 0x00000a25 Thumb Code 12 sys.o(.text) + SYS_GetResetSrc 0x00000a31 Thumb Code 8 sys.o(.text) + SYS_IsRegLocked 0x00000a39 Thumb Code 16 sys.o(.text) + SYS_ReadPDID 0x00000a49 Thumb Code 8 sys.o(.text) + SYS_ResetChip 0x00000a51 Thumb Code 14 sys.o(.text) + SYS_ResetCPU 0x00000a5f Thumb Code 14 sys.o(.text) + SYS_ResetModule 0x00000a6d Thumb Code 24 sys.o(.text) + SYS_EnableBOD 0x00000a85 Thumb Code 34 sys.o(.text) + SYS_DisableBOD 0x00000aa7 Thumb Code 14 sys.o(.text) + PWM_ConfigCaptureChannel 0x00000b01 Thumb Code 162 pwm.o(.text) + PWM_ConfigOutputChannel 0x00000ba3 Thumb Code 252 pwm.o(.text) + PWM_Start 0x00000c9f Thumb Code 8 pwm.o(.text) + PWM_Stop 0x00000ca7 Thumb Code 30 pwm.o(.text) + PWM_ForceStop 0x00000cc5 Thumb Code 8 pwm.o(.text) + PWM_EnableADCTrigger 0x00000ccd Thumb Code 44 pwm.o(.text) + PWM_DisableADCTrigger 0x00000cf9 Thumb Code 30 pwm.o(.text) + PWM_ClearADCTriggerFlag 0x00000d17 Thumb Code 12 pwm.o(.text) + PWM_GetADCTriggerFlag 0x00000d23 Thumb Code 18 pwm.o(.text) + PWM_EnableDACTrigger 0x00000d35 Thumb Code 12 pwm.o(.text) + PWM_DisableDACTrigger 0x00000d41 Thumb Code 16 pwm.o(.text) + PWM_ClearDACTriggerFlag 0x00000d51 Thumb Code 10 pwm.o(.text) + PWM_GetDACTriggerFlag 0x00000d5b Thumb Code 10 pwm.o(.text) + PWM_EnableFaultBrake 0x00000d65 Thumb Code 228 pwm.o(.text) + PWM_EnableCapture 0x00000e49 Thumb Code 22 pwm.o(.text) + PWM_DisableCapture 0x00000e5f Thumb Code 22 pwm.o(.text) + PWM_EnableOutput 0x00000e75 Thumb Code 10 pwm.o(.text) + PWM_DisableOutput 0x00000e7f Thumb Code 10 pwm.o(.text) + PWM_EnablePDMA 0x00000e89 Thumb Code 64 pwm.o(.text) + PWM_DisablePDMA 0x00000ec9 Thumb Code 20 pwm.o(.text) + PWM_EnableDeadZone 0x00000edd Thumb Code 26 pwm.o(.text) + PWM_DisableDeadZone 0x00000ef7 Thumb Code 16 pwm.o(.text) + PWM_EnableCaptureInt 0x00000f07 Thumb Code 14 pwm.o(.text) + PWM_DisableCaptureInt 0x00000f15 Thumb Code 14 pwm.o(.text) + PWM_ClearCaptureIntFlag 0x00000f23 Thumb Code 8 pwm.o(.text) + PWM_GetCaptureIntFlag 0x00000f2b Thumb Code 36 pwm.o(.text) + PWM_EnableDutyInt 0x00000f4f Thumb Code 12 pwm.o(.text) + PWM_DisableDutyInt 0x00000f5b Thumb Code 14 pwm.o(.text) + PWM_ClearDutyIntFlag 0x00000f69 Thumb Code 10 pwm.o(.text) + PWM_GetDutyIntFlag 0x00000f73 Thumb Code 16 pwm.o(.text) + PWM_EnableFaultBrakeInt 0x00000f83 Thumb Code 14 pwm.o(.text) + PWM_DisableFaultBrakeInt 0x00000f91 Thumb Code 14 pwm.o(.text) + PWM_ClearFaultBrakeIntFlag 0x00000f9f Thumb Code 10 pwm.o(.text) + PWM_GetFaultBrakeIntFlag 0x00000fa9 Thumb Code 16 pwm.o(.text) + PWM_EnablePeriodInt 0x00000fb9 Thumb Code 16 pwm.o(.text) + PWM_DisablePeriodInt 0x00000fc9 Thumb Code 16 pwm.o(.text) + PWM_ClearPeriodIntFlag 0x00000fd9 Thumb Code 12 pwm.o(.text) + PWM_GetPeriodIntFlag 0x00000fe5 Thumb Code 18 pwm.o(.text) + PWM_EnableZeroInt 0x00000ff7 Thumb Code 14 pwm.o(.text) + PWM_DisableZeroInt 0x00001005 Thumb Code 14 pwm.o(.text) + PWM_ClearZeroIntFlag 0x00001013 Thumb Code 10 pwm.o(.text) + PWM_GetZeroIntFlag 0x0000101d Thumb Code 16 pwm.o(.text) + PWM_EnableAcc 0x0000102d Thumb Code 32 pwm.o(.text) + PWM_DisableAcc 0x0000104d Thumb Code 18 pwm.o(.text) + PWM_EnableAccInt 0x0000105f Thumb Code 18 pwm.o(.text) + PWM_DisableAccInt 0x00001071 Thumb Code 18 pwm.o(.text) + PWM_ClearAccInt 0x00001083 Thumb Code 14 pwm.o(.text) + PWM_GetAccInt 0x00001091 Thumb Code 20 pwm.o(.text) + PWM_ClearFTDutyIntFlag 0x000010a5 Thumb Code 14 pwm.o(.text) + PWM_GetFTDutyIntFlag 0x000010b3 Thumb Code 20 pwm.o(.text) + PWM_EnableLoadMode 0x000010c7 Thumb Code 10 pwm.o(.text) + PWM_DisableLoadMode 0x000010d1 Thumb Code 10 pwm.o(.text) + PWM_ConfigSyncPhase 0x000010db Thumb Code 50 pwm.o(.text) + PWM_EnableSyncPhase 0x0000110d Thumb Code 34 pwm.o(.text) + PWM_DisableSyncPhase 0x0000112f Thumb Code 34 pwm.o(.text) + PWM_EnableSyncNoiseFilter 0x00001151 Thumb Code 22 pwm.o(.text) + PWM_DisableSyncNoiseFilter 0x00001167 Thumb Code 10 pwm.o(.text) + PWM_EnableSyncPinInverse 0x00001171 Thumb Code 10 pwm.o(.text) + PWM_DisableSyncPinInverse 0x0000117b Thumb Code 10 pwm.o(.text) + PWM_SetClockSource 0x00001185 Thumb Code 22 pwm.o(.text) + PWM_EnableBrakeNoiseFilter 0x0000119b Thumb Code 30 pwm.o(.text) + PWM_DisableBrakeNoiseFilter 0x000011b9 Thumb Code 16 pwm.o(.text) + PWM_EnableBrakePinInverse 0x000011c9 Thumb Code 16 pwm.o(.text) + PWM_DisableBrakePinInverse 0x000011d9 Thumb Code 16 pwm.o(.text) + PWM_SetBrakePinSource 0x000011e9 Thumb Code 30 pwm.o(.text) + PWM_GetWrapAroundFlag 0x00001207 Thumb Code 16 pwm.o(.text) + PWM_ClearWrapAroundFlag 0x00001217 Thumb Code 10 pwm.o(.text) + UART_ClearIntFlag 0x00001271 Thumb Code 68 uart.o(.text) + UART_Close 0x000012b5 Thumb Code 6 uart.o(.text) + UART_DisableFlowCtrl 0x000012bb Thumb Code 10 uart.o(.text) + UART_DisableInt 0x000012c5 Thumb Code 42 uart.o(.text) + UART_EnableFlowCtrl 0x000012ef Thumb Code 26 uart.o(.text) + UART_EnableInt 0x00001309 Thumb Code 42 uart.o(.text) + UART_Open 0x00001333 Thumb Code 126 uart.o(.text) + UART_Read 0x000013b1 Thumb Code 44 uart.o(.text) + UART_SetLine_Config 0x000013dd Thumb Code 128 uart.o(.text) + UART_SetTimeoutCnt 0x0000145d Thumb Code 20 uart.o(.text) + UART_SelectIrDAMode 0x00001471 Thumb Code 130 uart.o(.text) + UART_SelectRS485Mode 0x000014f3 Thumb Code 26 uart.o(.text) + UART_SelectLINMode 0x0000150d Thumb Code 22 uart.o(.text) + UART_Write 0x00001523 Thumb Code 44 uart.o(.text) + OLED_SingleWrite 0x000015b5 Thumb Code 96 ssd1306.o(.text) + OLED_SingleRead 0x00001615 Thumb Code 138 ssd1306.o(.text) + oledWriteCommand 0x0000169f Thumb Code 6 ssd1306.o(.text) + oledWriteData 0x000016a5 Thumb Code 6 ssd1306.o(.text) + Init_LCD 0x000016ab Thumb Code 172 ssd1306.o(.text) + oled_address 0x00001757 Thumb Code 32 ssd1306.o(.text) + clear_LCD 0x00001777 Thumb Code 38 ssd1306.o(.text) + draw_LCD 0x0000179d Thumb Code 44 ssd1306.o(.text) + print_C 0x000017c9 Thumb Code 70 ssd1306.o(.text) + print_Line 0x0000180f Thumb Code 36 ssd1306.o(.text) + PWMInit() 0x0000183d Thumb Code 204 main.o(.text) + I2CInit() 0x00001909 Thumb Code 88 main.o(.text) + SYS_Init() 0x00001961 Thumb Code 142 main.o(.text) + UART0_Init() 0x000019ef Thumb Code 22 main.o(.text) + EADC_FunctionTest() 0x00001a05 Thumb Code 346 main.o(.text) + PWM0P0_IRQHandler() 0x00001b5f Thumb Code 62 main.o(.text) + ADC00_IRQHandler() 0x00001b9d Thumb Code 14 main.o(.text) + main 0x00001bab Thumb Code 44 main.o(.text) + Hard_Fault_Handler 0x00001ca9 Thumb Code 16 retarget.o(.text) + SendChar_ToUART 0x00001cb9 Thumb Code 26 retarget.o(.text) + SendChar 0x00001cd3 Thumb Code 2 retarget.o(.text) + GetChar 0x00001cd5 Thumb Code 14 retarget.o(.text) + kbhit 0x00001ce3 Thumb Code 10 retarget.o(.text) + IsDebugFifoEmpty 0x00001ced Thumb Code 10 retarget.o(.text) + _ttywrch 0x00001cf7 Thumb Code 2 retarget.o(.text) + fputc 0x00001cf9 Thumb Code 12 retarget.o(.text) + fgetc 0x00001d05 Thumb Code 2 retarget.o(.text) + ferror 0x00001d07 Thumb Code 6 retarget.o(.text) + Reset_Handler 0x00001dd1 Thumb Code 50 startup_m451series.o(.text) + NMI_Handler 0x00001e03 Thumb Code 2 startup_m451series.o(.text) + MemManage_Handler 0x00001e07 Thumb Code 2 startup_m451series.o(.text) + BusFault_Handler 0x00001e09 Thumb Code 2 startup_m451series.o(.text) + UsageFault_Handler 0x00001e0b Thumb Code 2 startup_m451series.o(.text) + SVC_Handler 0x00001e0d Thumb Code 2 startup_m451series.o(.text) + DebugMon_Handler 0x00001e0f Thumb Code 2 startup_m451series.o(.text) + PendSV_Handler 0x00001e11 Thumb Code 2 startup_m451series.o(.text) + SysTick_Handler 0x00001e13 Thumb Code 2 startup_m451series.o(.text) + ACMP01_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + ADC00_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + ADC01_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + ADC02_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + ADC03_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + BOD_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + BRAKE0_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + BRAKE1_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + CAN0_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + CLKFAIL_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + DAC_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + EINT0_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + EINT1_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + EINT2_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + EINT3_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + EINT4_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + EINT5_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + GPA_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + GPB_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + GPC_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + GPD_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + GPE_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + GPF_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + I2C0_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + I2C1_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + IRC_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + PDMA_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + PWM0P0_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + PWM0P1_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + PWM0P2_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + PWM1P0_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + PWM1P1_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + PWM1P2_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + PWRWU_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + RAMPE_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + RTC_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + SC0_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + SPI0_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + SPI1_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + SPI2_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + TAMPER_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + TK_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + TMR0_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + TMR1_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + TMR2_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + TMR3_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + UART0_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + UART1_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + UART2_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + UART3_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + USBD_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + USBH_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + USBOTG_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + WDT_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + WWDT_IRQHandler 0x00001e15 Thumb Code 0 startup_m451series.o(.text) + __user_initial_stackheap 0x00001e19 Thumb Code 10 startup_m451series.o(.text) + SystemCoreClockUpdate 0x00001e45 Thumb Code 128 system_m451series.o(.text) + SystemInit 0x00001ec5 Thumb Code 80 system_m451series.o(.text) + __2printf 0x00001f2d Thumb Code 20 noretval__2printf.o(.text) + __2sprintf 0x00001f45 Thumb Code 34 noretval__2sprintf.o(.text) + _printf_int_dec 0x00001f6d Thumb Code 104 _printf_dec.o(.text) + _printf_int_hex 0x00001fe5 Thumb Code 84 _printf_hex_int.o(.text) + _printf_longlong_hex 0x00001fe5 Thumb Code 0 _printf_hex_int.o(.text) + __printf 0x0000203d Thumb Code 270 __printf_wp.o(.text) + strlen 0x0000214b Thumb Code 62 strlen.o(.text) + __aeabi_memclr4 0x00002189 Thumb Code 0 rt_memclr_w.o(.text) + __aeabi_memclr8 0x00002189 Thumb Code 0 rt_memclr_w.o(.text) + __rt_memclr_w 0x00002189 Thumb Code 78 rt_memclr_w.o(.text) + _memset_w 0x0000218d Thumb Code 0 rt_memclr_w.o(.text) + __use_two_region_memory 0x000021d7 Thumb Code 2 heapauxi.o(.text) + __rt_heap_escrow$2region 0x000021d9 Thumb Code 2 heapauxi.o(.text) + __rt_heap_expand$2region 0x000021db Thumb Code 2 heapauxi.o(.text) + _printf_int_common 0x000021dd Thumb Code 178 _printf_intcommon.o(.text) + _printf_char_common 0x0000229b Thumb Code 32 _printf_char_common.o(.text) + _sputc 0x000022c1 Thumb Code 10 _sputc.o(.text) + _printf_char_file 0x000022cd Thumb Code 32 _printf_char_file.o(.text) + __user_setup_stackheap 0x000022f1 Thumb Code 74 sys_stackheap_outer.o(.text) + exit 0x0000233b Thumb Code 18 exit.o(.text) + __user_libspace 0x0000234d Thumb Code 8 libspace.o(.text) + __user_perproc_libspace 0x0000234d Thumb Code 0 libspace.o(.text) + __user_perthread_libspace 0x0000234d Thumb Code 0 libspace.o(.text) + _sys_exit 0x00002355 Thumb Code 8 sys_exit.o(.text) + __I$use$semihosting 0x00002361 Thumb Code 0 use_no_semi.o(.text) + __use_no_semihosting_swi 0x00002361 Thumb Code 2 use_no_semi.o(.text) + __semihosting_library_function 0x00002363 Thumb Code 0 indicate_semi.o(.text) + _is_digit 0x00002363 Thumb Code 14 __printf_wp.o(i._is_digit) + _fp_init 0x00002371 Thumb Code 10 fpinit.o(x$fpl$fpinit) + __fplib_config_fpu_vfp 0x00002379 Thumb Code 0 fpinit.o(x$fpl$fpinit) + __fplib_config_pureend_doubles 0x00002379 Thumb Code 0 fpinit.o(x$fpl$fpinit) + Region$$Table$$Base 0x000024cc Number 0 anon$$obj.o(Region$$Table) + Region$$Table$$Limit 0x000024ec Number 0 anon$$obj.o(Region$$Table) + F8X16 0x20000000 Data 1520 ssd1306.o(.data) + g_u32COVNUMFlag 0x200005f0 Data 4 main.o(.data) + g_u32AdcIntFlag 0x200005fc Data 4 main.o(.data) + x 0x20000600 Data 4 main.o(.data) __stdout 0x20000604 Data 4 retarget.o(.data) SystemCoreClock 0x20000608 Data 4 system_m451series.o(.data) CyclesPerUs 0x2000060c Data 4 system_m451series.o(.data) @@ -872,127 +1337,127 @@ Image Symbol Table Memory Map of the image - Image Entry point : 0x000013c5 + Image Entry point : 0x00001dd1 - Load Region LR_1 (Base: 0x00000000, Size: 0x00002af4, Max: 0xffffffff, ABSOLUTE, COMPRESSED[0x00002848]) + Load Region LR_1 (Base: 0x00000000, Size: 0x00002b20, Max: 0xffffffff, ABSOLUTE, COMPRESSED[0x00002874]) - Execution Region ER_RO (Exec base: 0x00000000, Load base: 0x00000000, Size: 0x000024c0, Max: 0xffffffff, ABSOLUTE) + Execution Region ER_RO (Exec base: 0x00000000, Load base: 0x00000000, Size: 0x000024ec, Max: 0xffffffff, ABSOLUTE) Exec Addr Load Addr Size Type Attr Idx E Section Name Object - 0x00000000 0x00000000 0x00000140 Data RO 533 RESET startup_m451series.o - 0x00000140 0x00000140 0x00000008 Code RO 683 * !!!main c_w.l(__main.o) - 0x00000148 0x00000148 0x00000034 Code RO 851 !!!scatter c_w.l(__scatter.o) - 0x0000017c 0x0000017c 0x0000005a Code RO 849 !!dczerorl2 c_w.l(__dczerorl2.o) + 0x00000000 0x00000000 0x00000140 Data RO 1807 RESET startup_m451series.o + 0x00000140 0x00000140 0x00000008 Code RO 1919 * !!!main c_w.l(__main.o) + 0x00000148 0x00000148 0x00000034 Code RO 2130 !!!scatter c_w.l(__scatter.o) + 0x0000017c 0x0000017c 0x0000005a Code RO 2128 !!dczerorl2 c_w.l(__dczerorl2.o) 0x000001d6 0x000001d6 0x00000002 PAD - 0x000001d8 0x000001d8 0x0000001c Code RO 853 !!handler_zi c_w.l(__scatter_zi.o) - 0x000001f4 0x000001f4 0x00000000 Code RO 676 .ARM.Collect$$_printf_percent$$00000000 c_w.l(_printf_percent.o) - 0x000001f4 0x000001f4 0x00000006 Code RO 675 .ARM.Collect$$_printf_percent$$00000009 c_w.l(_printf_d.o) - 0x000001fa 0x000001fa 0x00000006 Code RO 674 .ARM.Collect$$_printf_percent$$0000000C c_w.l(_printf_x.o) - 0x00000200 0x00000200 0x00000004 Code RO 694 .ARM.Collect$$_printf_percent$$00000017 c_w.l(_printf_percent_end.o) - 0x00000204 0x00000204 0x00000002 Code RO 721 .ARM.Collect$$libinit$$00000000 c_w.l(libinit.o) - 0x00000206 0x00000206 0x00000004 Code RO 727 .ARM.Collect$$libinit$$00000001 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 730 .ARM.Collect$$libinit$$00000004 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 733 .ARM.Collect$$libinit$$0000000A c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 735 .ARM.Collect$$libinit$$0000000C c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 737 .ARM.Collect$$libinit$$0000000E c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 740 .ARM.Collect$$libinit$$00000011 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 742 .ARM.Collect$$libinit$$00000013 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 744 .ARM.Collect$$libinit$$00000015 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 746 .ARM.Collect$$libinit$$00000017 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 748 .ARM.Collect$$libinit$$00000019 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 750 .ARM.Collect$$libinit$$0000001B c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 752 .ARM.Collect$$libinit$$0000001D c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 754 .ARM.Collect$$libinit$$0000001F c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 756 .ARM.Collect$$libinit$$00000021 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 758 .ARM.Collect$$libinit$$00000023 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 760 .ARM.Collect$$libinit$$00000025 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 764 .ARM.Collect$$libinit$$0000002C c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 766 .ARM.Collect$$libinit$$0000002E c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 768 .ARM.Collect$$libinit$$00000030 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000000 Code RO 770 .ARM.Collect$$libinit$$00000032 c_w.l(libinit2.o) - 0x0000020a 0x0000020a 0x00000002 Code RO 771 .ARM.Collect$$libinit$$00000033 c_w.l(libinit2.o) - 0x0000020c 0x0000020c 0x00000002 Code RO 791 .ARM.Collect$$libshutdown$$00000000 c_w.l(libshutdown.o) - 0x0000020e 0x0000020e 0x00000000 Code RO 804 .ARM.Collect$$libshutdown$$00000002 c_w.l(libshutdown2.o) - 0x0000020e 0x0000020e 0x00000000 Code RO 806 .ARM.Collect$$libshutdown$$00000004 c_w.l(libshutdown2.o) - 0x0000020e 0x0000020e 0x00000000 Code RO 809 .ARM.Collect$$libshutdown$$00000007 c_w.l(libshutdown2.o) - 0x0000020e 0x0000020e 0x00000000 Code RO 812 .ARM.Collect$$libshutdown$$0000000A c_w.l(libshutdown2.o) - 0x0000020e 0x0000020e 0x00000000 Code RO 814 .ARM.Collect$$libshutdown$$0000000C c_w.l(libshutdown2.o) - 0x0000020e 0x0000020e 0x00000000 Code RO 817 .ARM.Collect$$libshutdown$$0000000F c_w.l(libshutdown2.o) - 0x0000020e 0x0000020e 0x00000002 Code RO 818 .ARM.Collect$$libshutdown$$00000010 c_w.l(libshutdown2.o) - 0x00000210 0x00000210 0x00000000 Code RO 685 .ARM.Collect$$rtentry$$00000000 c_w.l(__rtentry.o) - 0x00000210 0x00000210 0x00000000 Code RO 696 .ARM.Collect$$rtentry$$00000002 c_w.l(__rtentry2.o) - 0x00000210 0x00000210 0x00000006 Code RO 708 .ARM.Collect$$rtentry$$00000004 c_w.l(__rtentry4.o) - 0x00000216 0x00000216 0x00000000 Code RO 698 .ARM.Collect$$rtentry$$00000009 c_w.l(__rtentry2.o) - 0x00000216 0x00000216 0x00000004 Code RO 699 .ARM.Collect$$rtentry$$0000000A c_w.l(__rtentry2.o) - 0x0000021a 0x0000021a 0x00000000 Code RO 701 .ARM.Collect$$rtentry$$0000000C c_w.l(__rtentry2.o) - 0x0000021a 0x0000021a 0x00000008 Code RO 702 .ARM.Collect$$rtentry$$0000000D c_w.l(__rtentry2.o) - 0x00000222 0x00000222 0x00000002 Code RO 725 .ARM.Collect$$rtexit$$00000000 c_w.l(rtexit.o) - 0x00000224 0x00000224 0x00000000 Code RO 773 .ARM.Collect$$rtexit$$00000002 c_w.l(rtexit2.o) - 0x00000224 0x00000224 0x00000004 Code RO 774 .ARM.Collect$$rtexit$$00000003 c_w.l(rtexit2.o) - 0x00000228 0x00000228 0x00000006 Code RO 775 .ARM.Collect$$rtexit$$00000004 c_w.l(rtexit2.o) + 0x000001d8 0x000001d8 0x0000001c Code RO 2132 !!handler_zi c_w.l(__scatter_zi.o) + 0x000001f4 0x000001f4 0x00000000 Code RO 1910 .ARM.Collect$$_printf_percent$$00000000 c_w.l(_printf_percent.o) + 0x000001f4 0x000001f4 0x00000006 Code RO 1909 .ARM.Collect$$_printf_percent$$00000009 c_w.l(_printf_d.o) + 0x000001fa 0x000001fa 0x00000006 Code RO 1908 .ARM.Collect$$_printf_percent$$0000000C c_w.l(_printf_x.o) + 0x00000200 0x00000200 0x00000004 Code RO 1956 .ARM.Collect$$_printf_percent$$00000017 c_w.l(_printf_percent_end.o) + 0x00000204 0x00000204 0x00000002 Code RO 2000 .ARM.Collect$$libinit$$00000000 c_w.l(libinit.o) + 0x00000206 0x00000206 0x00000004 Code RO 2012 .ARM.Collect$$libinit$$00000001 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2015 .ARM.Collect$$libinit$$00000004 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2018 .ARM.Collect$$libinit$$0000000A c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2020 .ARM.Collect$$libinit$$0000000C c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2022 .ARM.Collect$$libinit$$0000000E c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2025 .ARM.Collect$$libinit$$00000011 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2027 .ARM.Collect$$libinit$$00000013 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2029 .ARM.Collect$$libinit$$00000015 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2031 .ARM.Collect$$libinit$$00000017 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2033 .ARM.Collect$$libinit$$00000019 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2035 .ARM.Collect$$libinit$$0000001B c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2037 .ARM.Collect$$libinit$$0000001D c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2039 .ARM.Collect$$libinit$$0000001F c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2041 .ARM.Collect$$libinit$$00000021 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2043 .ARM.Collect$$libinit$$00000023 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2045 .ARM.Collect$$libinit$$00000025 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2049 .ARM.Collect$$libinit$$0000002C c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2051 .ARM.Collect$$libinit$$0000002E c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2053 .ARM.Collect$$libinit$$00000030 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000000 Code RO 2055 .ARM.Collect$$libinit$$00000032 c_w.l(libinit2.o) + 0x0000020a 0x0000020a 0x00000002 Code RO 2056 .ARM.Collect$$libinit$$00000033 c_w.l(libinit2.o) + 0x0000020c 0x0000020c 0x00000002 Code RO 2085 .ARM.Collect$$libshutdown$$00000000 c_w.l(libshutdown.o) + 0x0000020e 0x0000020e 0x00000000 Code RO 2111 .ARM.Collect$$libshutdown$$00000002 c_w.l(libshutdown2.o) + 0x0000020e 0x0000020e 0x00000000 Code RO 2113 .ARM.Collect$$libshutdown$$00000004 c_w.l(libshutdown2.o) + 0x0000020e 0x0000020e 0x00000000 Code RO 2116 .ARM.Collect$$libshutdown$$00000007 c_w.l(libshutdown2.o) + 0x0000020e 0x0000020e 0x00000000 Code RO 2119 .ARM.Collect$$libshutdown$$0000000A c_w.l(libshutdown2.o) + 0x0000020e 0x0000020e 0x00000000 Code RO 2121 .ARM.Collect$$libshutdown$$0000000C c_w.l(libshutdown2.o) + 0x0000020e 0x0000020e 0x00000000 Code RO 2124 .ARM.Collect$$libshutdown$$0000000F c_w.l(libshutdown2.o) + 0x0000020e 0x0000020e 0x00000002 Code RO 2125 .ARM.Collect$$libshutdown$$00000010 c_w.l(libshutdown2.o) + 0x00000210 0x00000210 0x00000000 Code RO 1943 .ARM.Collect$$rtentry$$00000000 c_w.l(__rtentry.o) + 0x00000210 0x00000210 0x00000000 Code RO 1969 .ARM.Collect$$rtentry$$00000002 c_w.l(__rtentry2.o) + 0x00000210 0x00000210 0x00000006 Code RO 1981 .ARM.Collect$$rtentry$$00000004 c_w.l(__rtentry4.o) + 0x00000216 0x00000216 0x00000000 Code RO 1971 .ARM.Collect$$rtentry$$00000009 c_w.l(__rtentry2.o) + 0x00000216 0x00000216 0x00000004 Code RO 1972 .ARM.Collect$$rtentry$$0000000A c_w.l(__rtentry2.o) + 0x0000021a 0x0000021a 0x00000000 Code RO 1974 .ARM.Collect$$rtentry$$0000000C c_w.l(__rtentry2.o) + 0x0000021a 0x0000021a 0x00000008 Code RO 1975 .ARM.Collect$$rtentry$$0000000D c_w.l(__rtentry2.o) + 0x00000222 0x00000222 0x00000002 Code RO 2004 .ARM.Collect$$rtexit$$00000000 c_w.l(rtexit.o) + 0x00000224 0x00000224 0x00000000 Code RO 2060 .ARM.Collect$$rtexit$$00000002 c_w.l(rtexit2.o) + 0x00000224 0x00000224 0x00000004 Code RO 2061 .ARM.Collect$$rtexit$$00000003 c_w.l(rtexit2.o) + 0x00000228 0x00000228 0x00000006 Code RO 2062 .ARM.Collect$$rtexit$$00000004 c_w.l(rtexit2.o) 0x0000022e 0x0000022e 0x00000002 PAD - 0x00000230 0x00000230 0x0000001c Code RO 497 .emb_text retarget.o - 0x0000024c 0x0000024c 0x0000046c Code RO 4 .text main.o - 0x000006b8 0x000006b8 0x00000288 Code RO 142 .text ssd1306.o - 0x00000940 0x00000940 0x000004a2 Code RO 335 .text clk.o - 0x00000de2 0x00000de2 0x00000002 PAD - 0x00000de4 0x00000de4 0x0000008c Code RO 363 .text eadc.o - 0x00000e70 0x00000e70 0x0000009c Code RO 437 .text sys.o - 0x00000f0c 0x00000f0c 0x00000390 Code RO 461 .text uart.o - 0x0000129c 0x0000129c 0x00000128 Code RO 498 .text retarget.o - 0x000013c4 0x000013c4 0x00000074 Code RO 534 * .text startup_m451series.o - 0x00001438 0x00001438 0x000000e8 Code RO 541 .text system_m451series.o - 0x00001520 0x00001520 0x00000270 Code RO 574 .text i2c.o - 0x00001790 0x00001790 0x00000770 Code RO 598 .text pwm.o - 0x00001f00 0x00001f00 0x00000018 Code RO 625 .text c_w.l(noretval__2printf.o) - 0x00001f18 0x00001f18 0x00000028 Code RO 627 .text c_w.l(noretval__2sprintf.o) - 0x00001f40 0x00001f40 0x00000078 Code RO 631 .text c_w.l(_printf_dec.o) - 0x00001fb8 0x00001fb8 0x00000058 Code RO 636 .text c_w.l(_printf_hex_int.o) - 0x00002010 0x00002010 0x0000010e Code RO 662 .text c_w.l(__printf_wp.o) - 0x0000211e 0x0000211e 0x0000003e Code RO 677 .text c_w.l(strlen.o) - 0x0000215c 0x0000215c 0x0000004e Code RO 679 .text c_w.l(rt_memclr_w.o) - 0x000021aa 0x000021aa 0x00000006 Code RO 681 .text c_w.l(heapauxi.o) - 0x000021b0 0x000021b0 0x000000b2 Code RO 686 .text c_w.l(_printf_intcommon.o) - 0x00002262 0x00002262 0x00000002 PAD - 0x00002264 0x00002264 0x00000030 Code RO 688 .text c_w.l(_printf_char_common.o) - 0x00002294 0x00002294 0x0000000a Code RO 690 .text c_w.l(_sputc.o) - 0x0000229e 0x0000229e 0x00000002 PAD - 0x000022a0 0x000022a0 0x00000024 Code RO 692 .text c_w.l(_printf_char_file.o) - 0x000022c4 0x000022c4 0x0000004a Code RO 712 .text c_w.l(sys_stackheap_outer.o) - 0x0000230e 0x0000230e 0x00000012 Code RO 714 .text c_w.l(exit.o) - 0x00002320 0x00002320 0x00000008 Code RO 722 .text c_w.l(libspace.o) - 0x00002328 0x00002328 0x0000000c Code RO 783 .text c_w.l(sys_exit.o) - 0x00002334 0x00002334 0x00000002 Code RO 794 .text c_w.l(use_no_semi.o) - 0x00002336 0x00002336 0x00000000 Code RO 796 .text c_w.l(indicate_semi.o) - 0x00002336 0x00002336 0x0000000e Code RO 664 i._is_digit c_w.l(__printf_wp.o) - 0x00002344 0x00002344 0x0000000a Code RO 781 x$fpl$fpinit fz_wm.l(fpinit.o) - 0x0000234e 0x0000234e 0x00000002 PAD - 0x00002350 0x00002350 0x00000030 Data RO 462 .constdata uart.o - 0x00002380 0x00002380 0x00000028 Data RO 637 .constdata c_w.l(_printf_hex_int.o) - 0x000023a8 0x000023a8 0x000000f6 Data RO 6 .conststring main.o - 0x0000249e 0x0000249e 0x00000002 PAD - 0x000024a0 0x000024a0 0x00000020 Data RO 847 Region$$Table anon$$obj.o + 0x00000230 0x00000230 0x0000001c Code RO 1771 .emb_text retarget.o + 0x0000024c 0x0000024c 0x000004a2 Code RO 4 .text clk.o + 0x000006ee 0x000006ee 0x00000002 PAD + 0x000006f0 0x000006f0 0x0000008c Code RO 131 .text eadc.o + 0x0000077c 0x0000077c 0x0000029c Code RO 182 .text i2c.o + 0x00000a18 0x00000a18 0x0000009c Code RO 232 .text sys.o + 0x00000ab4 0x00000ab4 0x00000770 Code RO 256 .text pwm.o + 0x00001224 0x00001224 0x00000390 Code RO 283 .text uart.o + 0x000015b4 0x000015b4 0x00000288 Code RO 334 .text ssd1306.o + 0x0000183c 0x0000183c 0x0000046c Code RO 382 .text main.o + 0x00001ca8 0x00001ca8 0x00000128 Code RO 1772 .text retarget.o + 0x00001dd0 0x00001dd0 0x00000074 Code RO 1808 * .text startup_m451series.o + 0x00001e44 0x00001e44 0x000000e8 Code RO 1815 .text system_m451series.o + 0x00001f2c 0x00001f2c 0x00000018 Code RO 1859 .text c_w.l(noretval__2printf.o) + 0x00001f44 0x00001f44 0x00000028 Code RO 1861 .text c_w.l(noretval__2sprintf.o) + 0x00001f6c 0x00001f6c 0x00000078 Code RO 1865 .text c_w.l(_printf_dec.o) + 0x00001fe4 0x00001fe4 0x00000058 Code RO 1870 .text c_w.l(_printf_hex_int.o) + 0x0000203c 0x0000203c 0x0000010e Code RO 1896 .text c_w.l(__printf_wp.o) + 0x0000214a 0x0000214a 0x0000003e Code RO 1911 .text c_w.l(strlen.o) + 0x00002188 0x00002188 0x0000004e Code RO 1915 .text c_w.l(rt_memclr_w.o) + 0x000021d6 0x000021d6 0x00000006 Code RO 1917 .text c_w.l(heapauxi.o) + 0x000021dc 0x000021dc 0x000000b2 Code RO 1948 .text c_w.l(_printf_intcommon.o) + 0x0000228e 0x0000228e 0x00000002 PAD + 0x00002290 0x00002290 0x00000030 Code RO 1950 .text c_w.l(_printf_char_common.o) + 0x000022c0 0x000022c0 0x0000000a Code RO 1952 .text c_w.l(_sputc.o) + 0x000022ca 0x000022ca 0x00000002 PAD + 0x000022cc 0x000022cc 0x00000024 Code RO 1954 .text c_w.l(_printf_char_file.o) + 0x000022f0 0x000022f0 0x0000004a Code RO 1987 .text c_w.l(sys_stackheap_outer.o) + 0x0000233a 0x0000233a 0x00000012 Code RO 1989 .text c_w.l(exit.o) + 0x0000234c 0x0000234c 0x00000008 Code RO 2001 .text c_w.l(libspace.o) + 0x00002354 0x00002354 0x0000000c Code RO 2057 .text c_w.l(sys_exit.o) + 0x00002360 0x00002360 0x00000002 Code RO 2074 .text c_w.l(use_no_semi.o) + 0x00002362 0x00002362 0x00000000 Code RO 2076 .text c_w.l(indicate_semi.o) + 0x00002362 0x00002362 0x0000000e Code RO 1898 i._is_digit c_w.l(__printf_wp.o) + 0x00002370 0x00002370 0x0000000a Code RO 2072 x$fpl$fpinit fz_wm.l(fpinit.o) + 0x0000237a 0x0000237a 0x00000002 PAD + 0x0000237c 0x0000237c 0x00000030 Data RO 284 .constdata uart.o + 0x000023ac 0x000023ac 0x00000028 Data RO 1871 .constdata c_w.l(_printf_hex_int.o) + 0x000023d4 0x000023d4 0x000000f6 Data RO 384 .conststring main.o + 0x000024ca 0x000024ca 0x00000002 PAD + 0x000024cc 0x000024cc 0x00000020 Data RO 2126 Region$$Table anon$$obj.o - Execution Region ER_RW (Exec base: 0x20000000, Load base: 0x000024c0, Size: 0x00000634, Max: 0xffffffff, ABSOLUTE, COMPRESSED[0x00000388]) + Execution Region ER_RW (Exec base: 0x20000000, Load base: 0x000024ec, Size: 0x00000634, Max: 0xffffffff, ABSOLUTE, COMPRESSED[0x00000388]) Exec Addr Load Addr Size Type Attr Idx E Section Name Object - 0x20000000 COMPRESSED 0x00000014 Data RW 7 .data main.o - 0x20000014 COMPRESSED 0x000005f0 Data RW 145 .data ssd1306.o - 0x20000604 COMPRESSED 0x00000004 Data RW 499 .data retarget.o - 0x20000608 COMPRESSED 0x0000002c Data RW 542 .data system_m451series.o + 0x20000000 COMPRESSED 0x000005f0 Data RW 337 .data ssd1306.o + 0x200005f0 COMPRESSED 0x00000014 Data RW 385 .data main.o + 0x20000604 COMPRESSED 0x00000004 Data RW 1773 .data retarget.o + 0x20000608 COMPRESSED 0x0000002c Data RW 1816 .data system_m451series.o - Execution Region ER_ZI (Exec base: 0x20000634, Load base: 0x00002848, Size: 0x00000464, Max: 0xffffffff, ABSOLUTE) + Execution Region ER_ZI (Exec base: 0x20000634, Load base: 0x00002874, Size: 0x00000464, Max: 0xffffffff, ABSOLUTE) Exec Addr Load Addr Size Type Attr Idx E Section Name Object - 0x20000634 - 0x00000060 Zero RW 723 .bss c_w.l(libspace.o) - 0x20000694 0x00002848 0x00000004 PAD - 0x20000698 - 0x00000000 Zero RW 532 HEAP startup_m451series.o - 0x20000698 - 0x00000400 Zero RW 531 STACK startup_m451series.o + 0x20000634 - 0x00000060 Zero RW 2002 .bss c_w.l(libspace.o) + 0x20000694 0x00002874 0x00000004 PAD + 0x20000698 - 0x00000000 Zero RW 1806 HEAP startup_m451series.o + 0x20000698 - 0x00000400 Zero RW 1805 STACK startup_m451series.o ============================================================================== @@ -1002,21 +1467,20 @@ Image component sizes Code (inc. data) RO Data RW Data ZI Data Debug Object Name - 0 0 0 0 0 201740 can.o - 1186 90 0 0 0 21331 clk.o - 140 8 0 0 0 2520 eadc.o - 624 14 0 0 0 6870 i2c.o - 1132 178 246 20 0 37894 main.o - 1904 28 0 0 0 17731 pwm.o + 1186 90 0 0 0 227327 clk.o + 140 8 0 0 0 2372 eadc.o + 668 10 0 0 0 7146 i2c.o + 1132 178 246 20 0 37730 main.o + 1904 28 0 0 0 17595 pwm.o 324 128 0 4 0 4889 retarget.o - 648 10 0 1520 0 210301 ssd1306.o + 648 10 0 1520 0 4001 ssd1306.o 116 36 320 0 1024 924 startup_m451series.o - 156 0 0 0 0 2026 sys.o - 232 24 0 44 0 32333 system_m451series.o - 912 42 48 0 0 36556 uart.o + 156 0 0 0 0 1950 sys.o + 232 24 0 44 0 32205 system_m451series.o + 912 42 48 0 0 238104 uart.o ---------------------------------------------------------------------- - 7376 558 648 1588 1024 575115 Object Totals + 7420 554 648 1588 1024 574243 Object Totals 0 0 32 0 0 0 (incl. Generated) 2 0 2 0 0 0 (incl. Padding) @@ -1082,15 +1546,15 @@ Image component sizes Code (inc. data) RO Data RW Data ZI Data Debug - 8720 614 688 1588 1124 572727 Grand Totals - 8720 614 688 904 1124 572727 ELF Image Totals (compressed) - 8720 614 688 904 0 0 ROM Totals + 8764 610 688 1588 1124 571755 Grand Totals + 8764 610 688 904 1124 571755 ELF Image Totals (compressed) + 8764 610 688 904 0 0 ROM Totals ============================================================================== - Total RO Size (Code + RO Data) 9408 ( 9.19kB) + Total RO Size (Code + RO Data) 9452 ( 9.23kB) Total RW Size (RW Data + ZI Data) 2712 ( 2.65kB) - Total ROM Size (Code + RO Data + RW Data) 10312 ( 10.07kB) + Total ROM Size (Code + RO Data + RW Data) 10356 ( 10.11kB) ============================================================================== diff --git a/stepper/Objects/stepper.axf b/stepper/Objects/stepper.axf index ab32a00b8c302585a5b605148a836daf739a91ee..3bfd30742a7dada99e73e8478e2dd3ddc8b62b16 100644 GIT binary patch delta 40771 zcmcJ230xJ`9{-%V3-=-@vR*)0-E#rAv=l^;z(7&3%-pVkNFor6>C3uQR#sN(RMYm% z_T{yk(V}I&>Zwmn%hG&VTDF&Axu^2~{?5#~cV;fVXaE1_KQ-R@{60<82-sn5bI&MiLSrLX+hu270Yf8}o>4vs zU1(=*v1itf>GV&=7Ob_0uVI(gue0YrS`ePUbgaCy{rK-^*#7q8U!ReFYGH-aGtx_c z{B}4rt*|@&j!#PSrp+7MHbzdHeT($sABWrOH{3IRr@Ufp$j&YE#vW;D*fM*|yfpl} z_ur{J5K~zevCdxIRJe>=zK2`B>CD5DyF2MdY@n1E_*1@#^B4YU$|A+JLt~dRmlWX| zBT23?%43~ZD<8x)AYaQ*Dx*AWaB;!Owfj9~PGwA&5>~%E`F70jY?I+sT z{^V?y2TE;so?bKd_dWF+sQ!{I6vnzkMJf4bkB>O>OF{ebh?7zpOC{XtjB>wRaY_5} zhLcj;ttTfQ+0-DV_CYy?{2}#v?}X$XoIdf$JqQ+@I` zd|yANOKSV^f4^S8?yZ8e$3H%;l-c_E&K^&0?}L>7*3R-@UL&=&os!ZQrN!qH?eTUg z1x8psiq@WT_ITyl2>hFPMoJCAZ@)8Vk6(6%;p(!p^lz6lPr|I@>=QgED^E*lUGpgq zRi_{2lx3$U9@(EJ@qEoVO%>?6npEYCZKSXL_=P7nd>=7p;*kTHwXrhj?H2y;O{Z?c^$n+P#=kA6ZYrj5oIO6{tdsvPJv;G;G*n7Y%eQkp z`z*t?gI`ZOE8|*|D?4k$bqJ?VU}u$A?JFioZ8?ARsh-%@*LB^?Fa2@iw}}tW%a__> zPW7oCoUT#i)Zy^%!V}f`QcC;r1!vEn-Fbh;ys{H18T{XrjCoR(u)Ck|9osJp|&&#x&9OLZln>JujxLYd?O| z86`SBi_KqKntmNi`RN1;qu2d&uvTV0U zCALlrbB(kY?&|t`L~py)GKsBC8rUgJNgbH7_V0a`I@b2RAf73;qe_%j7tT>qMo(Av zk4{roj~=Xy8P!eMIBK>sbrfh95N-Q_Fr>Z}XA$ld=&>Y$=K;e9$)odYfX6F2W1?b7 z`c++;GzfnrD^H9`@|`jm$$*U>mn08a%@z;#a4wM*qY zn4jM8C-mi@lPz7ovtQv}VkoIOQ3;RXs#idS=aG`yVpFcoNs8=`JVt^|#V{S-XW5nK zbJE--agRfimQjvJZUiF<1w?LAa)bv1i>weH3w#B5B3{n|k5CR5MJfC9?Sl^jg&MTm zfQ2;*ls!b_6OH28IYddyi5=YsWZaKM{``fL4?4w7I5QoX5~h<}Ujm#(uJ8xzb278xM@A_M;}=98p(1_8=ZEpQ(_0mAnHk22to444dhkR8e` zo#b#23(f!*4ikR_u&9i8`9LTz2vCShfII633C}cOa;OHF3X&2eyc9T1$0YxRE-xy< zE5JqIqv4^MqF8WJ#gjTolG0MpzYBp!08WE8Hfo`gm=_;QIa`es$a7Kmo(NM86~+39 z^`6cWZD1>Ke~60C0Fe830vDn>kX~$fAXtRcfT>9f`Jo2>R?x=)i(rv_Nw}13tUuB; z2q1sF$f-}L2v=4YCghWB0fK03crz`y37AwVZIZuM$0@*+_Oi~(*}^0rU2X!4vMNMB z2d2J{FopaWuyB*)om~P&NI2SnDXBDIQ74Gs514v2vPXCVFkR#Hal$lgJb(SORK|C%48g^+XWywP!!{bt)T8e@n&ya;}O@N=S;EVbWgyNP(zen|K8C?zs4jdx(vkrB#Eiq5K! zR>tQgWo`xh4Rqt^g z%KlaZe>JcO6s7i7&SGr;|E9Ri}T^(km6ppDhXofP{X7&vAi-V_d@`xG3fYtkhdDv#Gd6Xi$v zBVhc9itLkifj|zB0^O{?0v7F+@XrQJ29D_l$hoaJPXLoHFF^d#HMIykR(V81WXB0i z6@eV4jD`UhNXn{lvA!L+9IUHSzGU1#g(_jY1v@R+Wx=5q9A?3t&DbYJmiQU^k9S^ywQP)yCD~OWb=dFJQj zCYBVX2X5{}Ei+&$z>sKG|o(Z4?!VK z@?+q@>7`8-c@5PID;uU)*OpIjT&%FtVl~;u($c6+JcV=Q^Nc+Z5?gv%>8vTWHFf3l zCs$UHiIMLq8`pSJmKpLDWUsttzT$nnh#L&87#JeGg6@CR>&nuHQ-_cGnXyN0vAIPT z&njKqSXNy=zo@RZDzCD}yBIx1#7x+2Zj`21Z~}+Yh+AyRFB_AT4<4@Q{f8Wp4H0IO zrhA)5OsFfHQzJ#zgMylBaEU@4tB$F1M=6URnXhE6E>bcc9WMtJ*VB(qat=i~tg$Iw zABa+-9vdVxyOQ@QAJZ!FA zFodF(l$y5}IhR0ZssjnfDD7_#?YfY<96HwM8BtQ!FLusD2|wjlG8g76->lyku9aYU zT}5S+caA^E&buJ>UZ|4$);QN1+|KnnlBBjwbf+m(AD?U$(Xg< zAMX_|N4k|`FOQ<1p=-~lp9O3C($BqX`_Rw3YlqR#$+aW#vv%k!4>5wDtji^s@M;x@ zH?;N~6p2|^;p9oRp~m?vT#g7=R=%F!{V1C?YoT{m zO?6`vI?!3Oy!BG#QAtKiON-p4Yg@#eWCF}>1Tp`<>f zHB4s>k~x@iZt=?0v-;57?EZ~8|+&ClYjuef%%t1sv`%9T6J5^slcWfs{ z47x3)O3Izzr22BezpQ!4-~u?DSG`cuI*0r(Cxx5`e zx8th33vO_rXOOF6Ioy1uGpq=VJWIE1S^UXFq0R7dz2EHB~MstgUX6 z*n3Gxp1h2N)BI3;jeQ*m24Q-iC^NZ*xsRp2*H5 z#ru7XkH#H*tTDE^(JVw%KI)j#=&hSS2@?@IuT=&l=FV*7EdFVG@Sf6h^XlIEnaT| z_s>uoLY5&yCv3{mAJTmUX#{yEB94y4TRvZkxD_ok9~Pv-v+Oxs6Q4$vS3{=m0}zIA z<^%F}ToZ#vm{r8w4?+rOw#wh*niw?PECqAUX%JXRn3VOc%$~A4=Fgc|-PA>5k&ki_ z8ii&vW&e-S${Rm+3nfSc(esGZvzjhx92!S%md}%*6pnQAzp{}Jg3C799kt{Gj;u{~ z_NCo1x4yZloF_u+G-N#vrf%X_vewwtQ0ZMDMI4-rK>^mSe~Qf`o2MZzL7W{h*u2@n z4#Q?urEZh#(XjVxvS~E5nJJro>UlZwXc+vVmH#SIo;hn)LuDgsBISma*qK!LjbjCp zCJid0HPEVi1cXN+O~*!@da?3m5h&KQ`dPCYn=0y>o1}<;AtMf(9gFx(qgK}vQ91ha zv+@bM^5`$AVJi?jx}hQ>os{~wn|z}%Ogx53$Sb&;+L^0-p0`1|(2VVcjpFYnpO>hAcHV zkC<5BR9%PsUW$w~qT4IYDK04*ms{6di^vdhHEh}Lv_*_`s>ecDs&hHlSG&8|kbY!` zrfbi^Rzo>y(CETpJK~U18hC6qe8Qpr&BeO$sU1z{?t{EE<+PnWDZ3YV5pD+a+DwmT zb~l2(&|lb`#Y)(WKkO8Nmm#noCwoao1ZJ;ryagg@QE^m|VLJBUq#z*gohgNZ<@NQF zviR-!YKxnt=d4Fy9JV&N$?jxTvyktcit@tRru-Ujl@y_IPix#oQe+EcF;h!Ht=fYG zs79%qWVSezruu`a07KP_ZS2CHglW3}5$a%db!|l@ly8?9vQ}N;ZSoR0t^6$DL3((jolE(oaHr@-UiJI zNk51)$*$gKXZ_;odK1pG2ypeB=DBlm4~cw2n(I(Mx3j*P#G=K8FNmF6hk^6$QYlPV z7gg6*5*S9n+gM&*Ek&-D(j4k=2g}SM6^bRzhWw&-5-qD-geL!t^esG|svBfwG=t#N zZGQvbDzj#_yOX)AotIMak^rmEAHHaW6cKNvjF_4^T#85&BsBZ6#U+_iM1Mh{0U8Dc zc+4Vh3jbw@*_l?zZbiwjk3dwvRDRx=+?`0YK=yZ-m=&nWH0`)8OnK>0Pv6t`K}DZ1OarT-R7BF~OmlKvt#?jMC9)_n5~roZo@SLNx$*qFxaP_b`7>Q}VtpmLA5x(8 zM2A^vA*8EONOQc+6%F2|N-gqJJ1HxE^T^{mDcuiyx($Ym?Pn(+CStxwL&w~j`Fz6Y zRVE#d_dVm1ZMDtmYqWCuzS+Im&OM%j-rG>!v{)lLb>YUQ zy82mjs+;ue{O;yK-S4KLcHf4Xp6#T&qo5wLD_{QRDf~86J{a)5ta?Eu?l-wq0m$uo zoG+POe*-4T^|Fb%nj=qwAZ5R#jQKqwpX6yZc%@nAT3u&sv)54mvvq1-bwg#jcK4)6 zkJWN8NXtPt2-$84>nI0j9m=o2$Aq|f`gbUujwJdhZCZ7{(wzP=JRc&Ti!l+`oc>y; z@G=h}vvJlN$6s>)xZAzG_) zH1vaNGPWz>*7j7F+p9Gv7&w}Y^Om^k(%Nb!H# z&-bRgh0%F<4Q8|{$~)U)yV+oaYS9#o3#g$?Xsj&P z>drUGO80l;Vm`uD(&GQs$x7k7z2t|Jl`G#(9&iT)rZr~{FTwb`+*^aXH~|&@6;P*w znmYl`6M#ZQ~f^ti>7qhkA=uDF&c``Ds7@093x+zz*%haXHn9s z&2a-OxysQHd81INtCtu_(-ZCiCXLCYk)2Jc>VEa-+Hbq$Pc`lQx`y(~Qgm*Z%|o3Y zipQHw#FL2-nmJ3^Pbe$jOZ1QoJtRMgr*whR`@K5_D|tUAHWVfF%oWvv-ew!fQuc8y zo527n$KoOQHzosba04Mva>)Zq;rmG*5~9cLJ57Rjal!QKI!>vU^s}~fl3$WT)zks* zSY`YBP7hh32lX3FmM-U(R-Ekkmw;vdW`?HNqQKUo}AWkx?Q;6*N4j= z$-E@<5~VX8#;6e7Tef@r-0? zv%qyG`A@lg(mx^JL7-nGGg+S~S^rA)kZuLe1t$H!bA9<%{OpYi#ZpZ6S6yTU%Ty}{ zxMSiODbO~AVw2KU-B1hSEA%vrDi>DP6nh)7m_WCZN!^qIAI9Zofh($63b~Q}VuZZQ z#-pK)cyhhD3ejT0*>a`nMRU!KgbQS#GT zGJ18<(xEhHzs3erIOOg*^NtJesTxU{W$<>Rm z)twkuQKfg7^SQzAV&y}ooEt5YHQH~oz+`bMw-`Sz$l_pbajWwBzmq(qMq5)ZGpQzP zs$oH@C$ZchWvx?^wx)VWjdrn&GpT+XuXsO>WAW5lhNYpkJP@ZXfx*za3kS=X{ z$u#M2geGnx&&4YrZjB4MpVG_zLHT8CyoY3IQ%rZ0{LNfGtceT0o*-{=8vAHXjF%xu`X@gHvpj}2&OiCx>cn$dmKd54K7uuF8f1-J) z^_$Zw8|t`wq)gkAa!dw3;s!$Aj-#kQpd{~%_mB|nR~ldvd{z^@j|={!EZCXoAtBnx z6mJr|NfT@&!K|IihMh?s5~3YW4wK+)E+`k{XK&nq%{}D%LkvwLryOguq*R3S8}u@P z+IRt1Oz4di^unUWESeGVTS|1C;`=CODC3?gJ>_RKvwAPd?UGH}P_@%!_fRYabNGL- zl!WIdJ>}Oe{_rr88tuK>U{c-0RYTTs)n}E=k3Aj|qD@&(n*<->g04Hc;PGCH@8cK` zNzrz#yG@cyxa5dxlFZuETmCL2lty_MRW>0D+!dZ%Ql!0I*O`9?!9ha_p|*8-Dt2A2-$&XZcDEZLRfAtBllc9}^qR5N=#hRhBpv&Z_%s>@JpMRnc^ zZ8k>QJ8+IOSvUyQZLt$~VroHU=NIRBc?(o2`#=5Ur!|v$k@+-7&0 zt_0h>k=y)HdG3=052=RX{@&H3-VmdF`AP5iS-QGqu3HqNB!3zkGLoD5KpFLEf`?4d zzPG~|?gVOOuNVvgJW-Gn0~v|yJUT%B#pP6Iedaao0S>6Q@fKQZN7Wj zqIBxo87z`V0k5%b~lvP zHDh)lG19mnr`M!4HkztI(jX}7-j_C%msZwjEw~%E`LwclPwF_*r9FQ+CVjWAIJUt% zzp|vdc0w~If;2=qhSeNvJidDlzpA@$DXtc$s+9>9AL7#L01m4`V3dyJy>o> zakON*6V7L(O?wUFO%~KYv#^v~cwTw>v((|F_B~FAN%hJ23l7Xz7mHNG@9@3_Lk2_5kBBS_iq&j>U~5 z60M!pr)tH9TA-EV1`wpIJ7hL8lpgw^*Bd)A4>Q~*>}Anzh@?iF&8MeQXVf>8Vdf^Y zJR!~>{E|6Mnj~o}dI6VqI3a!0s^bZvoCf+(qQ|CZy=`NcccK(&4YDM!5RVpky`o*~ zv{OBW>nrug?Y;vxR>hx4@uYI+Rbw7ZBD8@$jNH$@-p(2g5+ze4Moik#ej(BPm*d*XMHazKja3_JWqMj`iIfc*u1l+-Vx<@!EUf>TB@T2T&cM4)+3 z3AQF^ZqDcff3n|}Ss^_mw`t0$ZE&dAwxquudb_L$5no%j6572{(hLa&niXc9YL z6SJ{J+@yc5O_KDg$rh7z4@g%xkI+_G_?DTjf>Kv6al+Z&nh4fQXiwEo8q5i$C+9@i z(_87fFS`0EJ6pwglKKsf-_0pSdZFc2Q>yR7hLru8ojt5+7?%G@nBI7K#H8>tDP(=< zU@x#x^>9CTv_5_$NqP_FdXw}+y(#pAy72`_guc20iw(TQmcx#@1Qv74yPRx`^2@$% z9x_I+)6o9CK#^YFn-}S5Znw|S|5~K|xWUyS>^o)l7jYgkM(^WHFd2;FmWES<{Vs$Z zWxQsgJ23SHq(-mqTwqeQbJd|TRG)XT8)P?C9H{2e14_nAgp}wVpI#=#!@ZQ`FXMcN zTx^xh%Lz9%O^Iab9iT{){1?4=xpNV2_TM022B z7%cK+pnO>`Wzc?4Xg;^GsuTN0nY2H~L%Q_-(x)c~0tGt)umfeiLlH}?2r{_&Nr+QN8UJ7HXrlU6zp+pMwj@11o zrO@w4E2}+>J)w*~kmw-^dUNU~lhm%BRM|sOAF_9cvsbZ1H2ZT`w^58Fd*N&_NxuV= z)ZUA+;Rg*=dtOeVex7^ykIw7^SZINTS&X#lO{|$F3lDG$=)~qXl~(^vpGPj^+P`;Z zpKAHz_O+gpEac-HZ?e+dQ*J3z8DO=r!D=IFV}{?!wL}FMZ`1 zMgsKmSDHy^6!&pN$++CIMdPqJf-=~b6tmumU@Ps)*{`~JNQ+(*>ul1D?MaQqzP>Aa zR4M-2Q$P~*^4O_VW39Gv`}&iwHtPM+tJ8)vt(Vyc3iUGnUVlpu<+-opd}|}wKkZu6 zqxkC&y(C5n&>Lyrni6Rxy9@M09@7&E+&WfT6S)=yy4R4%toa3h(|n<77sbA#WR={5 zaXw0iZfZMBY0WpLH8m)$an`g3|4CX1v2iO_(6FgeHtba#PA_FPh2YJ9_>%o4V?CVX za`MC-mYDRGW}m(Y1BNZQyXMy-hy9eClQF~c`%#0sU1ph@j$UU-p)<~Cv(gYQy6T zdP{Vd+3c>qFdNJIDpOB&>;1fLgl}W!^9j?<=>cx;cf0bysg&VlYdX%2W_!zY6Q$k- z^);1LgS299=DOb~hfgKPlNyEfS+nXKawSHd*jE|zN4I{XNC8J41pjO(6xj259=)x6 z2qjX0nqSz;yme@sAkj<9t^M&p?m7?_WWZkbUM2H%w2v6{2J@p}O4(n_?5OPIo4G5S zv~eHLJ_d!5p?8~afE>kF9~4$B(y}!TCVALv=KG7{q5#d`z=ncGEv`{78lTizr&Ne7 zps658g)O$b;VGr~5zabt{S^@Y7{uMQvGci?T9=-C@kEJ{7`A(so#@*(9*s0 zd$NVol-x5>`K{dOjdnJk8!f53s7c1w9kI5B^}( zu-n0wGof4pBN+yDQl$-VAD>5e6$iF9XWgw#I@>Lji1haN+5qDt<<7H-p+uy&zZH!^ zGnPA)t!EQLiTD`KM$YhoQMe&wQ=LZK0!ArZtos3ktKnGrDO`-Fi_m)1D_mgZ&c$x@ zSDONODlyWdSICDz*IF_9L&;hkok63DQQ#|_oLgEpR;yNj45Yg7f-4zGku};&l?;nm z`0m73+j(%bI#5znqz9H{=neIDy@x2NsWH_Bn54u(=HcYS&9_0+AI$o&?NJ+o4$z;B zLlQL!HZ=NmkR?y)VJyx0%LUf=6MYLk&exwTkJI_QRZY&-lpfNFWeYHPCo3m)tuo(& z`oS9MV?kO_KSZN!)G5WZagwwK>t;X@54yt)B;CVgkn&&YMEk18BQSU2WOq7@8>`Pc z_|EED*w2_lTdP@F8sAxcIVgN*bpbB4oz;_v>N~5ao`s<-RUO1ww@`{WeF@;pe(Ds) zhJ_4+JO(=IN^I3kCkA~M;NN2hn|K8#5`$|K`@->&(8=tkIaT z2Og06?U60&b8BFaACKW*n{==0OJg(D^Ws^InqB3NQ;){5xT+DHhY~>(mz?1e!@-p# zX1WX0i#%wPSiYD?lGql>us4(JmII+*`tQ2xfmk+9&P!7J#Ib$MsoFhkvb>|aI@QC5 z$eyIu+db@BCO_4!H9UbOGPPwe+cfh3+BMak!7eXsgHtx?f^+c>IrDE8g?u2Fl0zQl zX;p@@r{qq^u=d7AXQpN(vYUcl*ilmku&dR-4`4&oiVQYDekG<=$zZ=QwW2HQuf4>z zelROF>oqo%t7j5fpD-sy)XsfAsV4VeSMj%N)EE0<-QQXgt!d}6-V9;v(T#n6ULJZF zn{@ZNWK{KbXX6K%%)tTuy%`vg%Ig{`XO%A)ic*FvSe27|M7D13&eqsEk$)>dvPn1b zniL&m1{+Y+Ut^eO8cCu8+N1)=|IfOC=$F^b*XmVAHV0A-!{Lx$302|C)Yc`P*hrfT zserbrbL+;=>@hiH2SjYr0QEyu@RT4sRHlAAo>2A6RCaf$B}e8sQ^|CRL|+1_BHTWN z?V=#tSi%X|UV?#`y`;6W=$n8?l)TR8Opx8>IPQS2lO(Ms%QUScspp40f4iY$&Y`5+JAKpw!< z4n+gGY;&rwrL!5~PF`*Qd$mB}@@he8{G|$>#f|^9ZoprYBq#3%E*-^N$GKL-plp*p zUT*@1QR#~0)*ijsJ)#ai>r~(G%PwxkCw?mA)~%InDr;>jXH(_YgQe^#=aXa3XVI<8 zr?F_}y9CW)6;8W!jdagFRITYq0EIX*sN(nyy(`g;w4XsEx{CAWD1T)#o^gM!zJ3>j>fOdR)Av^XZr5!FS<@ zA1~uyk}=wR3Yh3dS_|Idm#)`|^h-hz2*VFQ7UJI)oJOTA;Du`DU}^bHQC4do=iF%m1|q!M92 z0x;Gr#j7wU`F$l4bq-AO+ai*tsM|v2p^AP8r@>jO=bv+uUz14mQldd>3m}mVB&zps zaFSnT65A5t>-2!v5SPl|ptZdvQS zm$T19T1Qo}maAH4&v1ReP<^)2agoawCfjY{Hv7##RXT7wTYsty*>|XQ>lbW?SM5{9 zdfa>jj3ZzisSJ^SYW>LT*k@~fa*X`CJ&dO4v+@cr8Jsb6gqk@?j%sZgCm#q2rmGu@ z<%rgm#qx!HTfg|oHJY`yPjSr%aiLd5UpT5>E!^iCDIdI2UAoUzCP&!Rz586F<>iyq z_%B>jW zm8pBab`{94EK$=Ax|YZ*eCnEmu1tCf7rG-ZRl9uYN*y@61rN|M?wf^b7yRbU3jr!U zrrW2^{L%B>eoyrskilaC)nr1Ipv*qJp*ULufT3>TGi1Io)I3^L15o>wz^@L%hT-%cu!J#T(Gh$ zo<$zFtA}^F5^P?Fgt?YG&b|d1Qc^#NVVP?7C$4zg^-f9k4sgdO{tUnL{Xv0!!~CJe z6!lJQ3HE%2(jozU#ZKQ&o8eOHv5|AW6PugxcC55jC+d#rRC>A+u*A2WKBkj& zK~DSCB$kJP_p~~^7FVifed>x!cqG(lBv*5XirKE#ed>z0S9L;0-}<*FaVswLj0L24 z#)heHf9i@!cmQJw6428Ydn$hjlhhXnx?|%y^ElSDxG@9kB(?4^0Y>&oD>b4AbVy8~nu}21>xoUT`y%11Yvpb&M zsDAjFt9#yD;y5hShp|z56 z;%yePELG zv>HT|%Ve~Ye(so=AL=ZW1Rl=u=M#J-w+tPe{)}BT6?&&yC+Sb@zY9?K1M`9C{73@E zIIdMU{s*7$`O+?_GtYC!=F;2Z0YAi(z*Ra`cUX|=#o>Uk{?Pcen(?_S#zUPwPl%o< zq8jM__|zGnyOP;%^&0$)JrBL4Ux?pm8jTd~;o0LxlK$wFUf7ThgQ2v46=Tmq$Ei&G zIwpQSF8ua{mqSoSO3p#g5GuMgIAy8k1&rSj)(3zBkM_P4NJ}>yrKH?>(qmsv7oAVV z+q*$UdFWIkYgAu4;OgZrsnsS7UDf>uTnTKP`o{rRyk`-_X~1!*w_4krM^$mL^r71S zD_1vP*~=J0!|_%m#)l=^+b8r)XRl5|*%+TiwdnTrTL}ce)+vD}Hx774*7%c}G#w!7 z1^P3X8G_^sJeQ%D>UB@2ZdccQ?TU%* zhDefz&eWHv)$8i<`J~egZkM|C8`pFnzCxuROv3GnFQjV(#=qi540=@SN6=Sd=qnb2Kmzn>7Ja3zyCW| zl8-*GW|SLaz+BFNDV@0nO#B)HCjKr1CjLPKCjN*N{KF6Khff-nqGLEl0&k=RFd3ll ztZ9eFr%#XxOnmy{n!u!Ak{-asr|+w2ho(Q>fWsx+rRf7}LIBNDTB1Jvz3W2X071pC zT{_%OHx7C*O@|G>j@K^vzr?S!V3MctFdZa+jdscZCHZ?T_(e1JwQn&KxC5eIlfeTP z{wWKlIjlG+L7J(HLu5#_1G1N6;`~*DB>J7L1R``wudBhXuD=a0MbE4wB#L$386q zdcG+R5_s5xX{5`oQKMObm zQKSBoimY14+$it@i+mm!qO&FW+rg*5_d)67U=n>0Asn4;0T5L}Dr5R05Ji$I5$ypM z2jyr7@V(%}d+=@2rv}V`_Y)4~RS4E>(l3I~?b)Q?H0(kkIyaIQsR{{JJs)}r4b z*5l9X0C_0xQ{(Asx`hEw*jf@niBYGC?z7LNOlkP;02vfUf z`0qa8jRtIW;2f|&eeS?HC}`Qozf{KmOP(SoZoHJCN8vDSOr}GNNFe=lGWdd}Og90a zLX@bxAcIzZ8~8{53*Y0zDg_D9K?cSEi-U4VIiT;o(n0)57QPje{4&T-(B&&E^2Gnt zV9&SEB5()r7&t^77A1I(h5xt(ziPpoE%-AF#`=r@Kn8v7C(VTRPBfa)4~jr{3#K>e z=}8J5^-_l`|d>uD4`WCJxz@#c9uo9U1C+cWAGAKrGgGl1!N6CLDGiH?PX z^}zIeOYm3dSkxI~0#t-Af=~8ED=`$2cK^4AYzGv?AzFd>BGB8lztLHzEBbp|P9CuW!jkizw?2kA)YDHEDtr(TopFR)S78nde>cRnQ$mwfn z;-Cbr5&G*mkp4L}v%i{vwOPuThL54T^S zW2*ICWen?$e7gTnHWS*bEO?O-!yqj|je!GnkU@ICTVP7?Nno1eQ`Z{_{`0_vx;)|a zI_}T;xc_gr2>b+msX^f^@HM~`GBVH!OM`^zARG_;88AhJa0c*E1OEaG9uNG7;QOFZ z1_IM7MI=H#517_T=^(riI7DE`-vZppfY(?seQv3O;b(w*0`vZl9B9=ENS`~j8Mv=d0Dli~CNMI_`9A^|1B+VEu$)y5OzoWP zMF1}V9whanWeNtATF^rs)Pb_&o4^HsoIrHh}Or1bXQLJAnTUJV(d$V1EFzNB1By@Dp%0 zFzqQKd=i*GCA&=LhhhaS8TWSTAc>y}JOo%|U@&m54}>dpfjkhN10JE{OMvO?m~{Up z1J%HXfrY_FVESIC;9m>e1sHyC`Fnu-0@I=g>AwJc5wM8Z7GU2D5JZ`N4Z=0RS-Qf{ zz;6NzhiLWwcVLlVClvk}U{Qo|z&+9L3Vtu(K?Xb&cqFiJsGu9l|56Z!>j_SW!0o{J zpL;wX_-+7EsTKp@2aF(a{*Ay78Tc!K9|ca)`Hukq6IdkJ3VZ+|AX1eO3- z8w6GY*8%s@6L-Z$`H2i^wUU*~TJrZoj2e-IaOm;r;t^-lw*18dC~_y5Rb zNg8Gl=nYJt6%i2`4Lk`LncxPd0AFsv^MNaY59<6D;6j8)G_zH}vkdrg;AUWMkM94k zg5VPb;7!1{0FTiP?grirEZY5d!25tjJ3j?{99THqIR%v%(>IW~!|A{=20Rit9hf4_ z@BfoPI1hv#AW#`s0Z#-LAzKW5xxv74;A&tIk%xgBfrSIF0N-Gc-wI40))EeV1N@Mt zuigKpRIElD48#M|*S&&291o~*2NbpVI0RV86^EU$*1B(Rck1EYF;2(gmG~hpgZvYkvc0zMl2`q{*9{6$M zBYmDg1_)~n0^@-H1uQ~56_~yeC~yt%e}D(;`YpiWn6To9+q(-FgADj-;7P!uQvMUT z3Yb2Q%oV->;Ytt$J`Q}f0e4MDyEYi;0sH{4XlB{KuLHv;Ztrs7%?8{I{Fwo-0REvX z;x7z50YV7kD-5g$jsq4B(F3R}f%EhPz6D+fEV|Oez;7Dlov6+41NYPAV}XAK7Okcq zusaIz7Xl+e7=r22wYows@Jqn`bzBU*54c6gUf>xhP*J8$z*hoXuk)7y{|+n?{5xE4fqe>e*izL%iDWmB7>20 zijKPiUj^Jt$BDqczk?tg=mElJ;Cx-6KX4ax?6Awr^nBpaz*}{k3+%=?aH@{!(*j=L zJ9Io9_*Y=~#Pw@{9SFxXrr{fUqWouJP?4nz+z)}j1B+(!BJe+eg@fyW>8X{dBb$I< z2NogT1N+)a08zN4$}>G0e0XPDiVkR z4gq%R{BFQIfd>PppnIM&0aFYe! zXuZo$Va*nzQ_F=EjcoNmEGEI8MQ>Ha_2NC2K=!A%x? zlLg;v!OvLmdJEoez&@%JUm6I6+bp=8J1(yUc-jP6pGXn&UYc2R% z3%#IEKP^I-WoZz(;{^hl1eKTl~9$MNb%a9`5e~Lp}re zKL%U~ybt(g-QINI2hxy!icY8p;T>c*RL55VZvz(mTYwJ(kJtHYfG@;7AGdVw;N!r> zz%Jl4IIvE~fE;hL;O~H^q$B^NKsh`Nf)@tppfYpdu0vSlFbTNaz#pw+esh8TMZi~r zFEUU9yjaMCUuD5J0dMuuy%k3U61*RTpAGm0U>tlOPghx%)&bMD8#{=E-v_3@(IfCD zB(HDTApUM(v4w;1eqfh@-v*o&W+2e(`4I-}7=Q{1oT4Wf4J@8wb;as%&jD(Fm^;;n zcSQ|<>2f-~NUeSOMEaArNC!62U$p5+jo!l@SRSkwpa-Q?<*To*>qw`{PY=@3UQ`b9 z&QA_fXzb7{jq2?n``TO9K?(TDK?&fM@s9GKk(I+6qX%~sF759;28Tl<;C8ndHKz?{O^A>c0@yh>dHCpj11D%RXflOCaERi?zFsf^d+}$ z!GgNlGB5U7!wVx4>Gv?CZ{(YVd75SCo+iE>w8#;1- zZBs*C4gQ>=p-}KA6Rbqx(O{EDL1J(yh{pYyaE|`udmEc90SY1sUj`a{2@;wfMB#p% zYhBH+u4%$IyKAcqVF{)QPmFanSZaDOiTg7C9AkobG*mA#IAS3PFZvncVG)^b!GEca z(5nsjql4AujRqe&APPT>b)*9^^kG5vxIabb7?0BC`ue(tCZjVJitwbrAtFIqR>EJZ zA7u^R+Qzwc4GRoj1k;2cLkxZdOHB_ZK~V|&CB60juI>;PgL_*eI_p8@HPv$l)!^?j z)7knc*448q?KZd8k7+@pO12kG9FFQ~6J*|wUlsP)!X*P8ulsBE&3 z<_1eOH&)ix&8;Wns6GSnXYS~g%N{)%nksA6F){8i_5OHwl$ssm4p)~&(HSY1`?t!bSf>yEOiof6zV)UC1ZE~L50rSXuXmlE9RYHk8P{IfQ}ovJQR zaDU%=Z=(APM{9kW`y^{!)6e}gQ>%Np?`>V)-@U-0vYzhm)FY|xCF;Ud_qDCx_jJEz zZ#|jm9xFTY=}+mY7Yuc$x0VleFR|I^8y`8Bxqnl`$GQ93&!01QgzBB<{L>$LI3zhYf*u_2eS?KW~hfJxwop>;oOb)*2Y>L8P`W)7(!xnrG=(=p1ZGY z=$s7or5a>nT=ls{rtJ!MN${t3V6=5h36Dzo2$ki);D*WW56>|wh3fNVZfEf4U}#|1 z%BHx}n4DRuwoP(xSAW06z4KhHCet@|ItqsV@txM?^I_UPtir3;j%ya2TMVcm)%rTO zE4YeiBSoooMp9W8K;3nA?Jm?7mRuPUcNL$8ZY?9{YAMw#F@lK1W5vT>LG1 z40CzLLj#n1D%^eK5kv3Eac}Qr5!3P+7LbKDau{clJJ+nCYbrD;`ty`+$P-4gfdRP@ z@O)pmBVM zgL{88#4y`juOrL-<8Q&xVliTv)`SqP4mGt{bjYQGkL*C}uSB9FeSaVdO@R>Z1qN0f z%qg@m%*A9OxI#o&$yx-4jLhKud{-;mP!~GjQN!+le6E?Np0@*af8GlWc@LVg1kYjg z;+N)%>4_+1t#x+|qU+t-;JI427Q{DXKC%NQ@76k?|CQ`_WY?enJY)VvrUFHuA4K92 zK%rwsWX?POT(yy?cL84B1#InNW*TxG#Gxz)5&uelgOvT5%{64U*fOcJV6C7V{WB$V zUL%7UdLv4uMx6U}HTM2seZW5DAbC$aX z(e*+fS;>30$RNHU*Bvo=>+V45FXX(SBfI|08&?9#M5Y2I9!$dU`RW<&^Ozk2F@22N zJj;FHTt`r?S9#ry%$|dhk9xQq)4n&o?$K(?W$v|Vbd@_&wNO1xBbUCG``fa_t7kf$#ztY_sKg00jXu1IJ zf2-ar-RaK#6Y-beUsrFv(w*j9;%3sazUs?#Z6Cse(yZz2v8MsJ$B8 zy~3lva!DC@o)m`63{x*_a3?zQ@cw6>`qGui*zyK}InY0_n*np`=g((rZvmAt4fKAfSjKgd{*DBq0UGw%ElA4ls(8 zsHo@*0-^*vAo_x$B7&j<0*VzhASxxmcRy$5?9Pn%fA8mY{iB4?0GfBkWhHGX_XX`Fr9@yf-&PF{4psWjfE7Ac9XmqjvG z_3E#~lJZ#Ni|39HW{tfsuoRw5__lNE1KyIWdE>sbtnq;}BTsFwX31%Jym4j|YrpL@ zE9#j#^3>vLMbO@d%uQ#ur|4)x6Y;|YC#5MZ@2wxJvci&iV~;ngUVR&h3_7Rg#&`1Z z#-C1;!2xG@-plp8arb$adQ(b#9?`Bj!;)ZxS0N|PB-Z#vQ#k%Ue2ygt<9q2j*7)H$ zj=K+==c4Xt+tUJn+)#LH~ zeXMcP`L})y&l-8^aF2&!!}0cG>ynZ^t9avz3lG4jiu3aZ^TrwC@AUKc;=c6!efT@& z{Jp~|9IWw^CYSjBvuWfh)|;iK28Dh^ls38v`KZfydiQGD%Y5{jGe+a>+Z~AOue(^_zgeC)GE<%>|Fi8 z-}hC$1s-!}p)n?Hn5(qlxvcT`CJOGZ)8R_C3ne|B?agwBqX=2!_kIp{ZL)B_Y*e0B(g{Y`l2!^hM^( z>r~GgyIxSgYdJOJ?0Ii}5km3j`S|*$@O|=pLj7TU|9U>LKDmrF{(Qb=eG$IDKi{hU zDSRI}f4Gc_zZFdEe@nf;)qdr*Xmx7qv)vvaI*%nxSAMxu8O>fkcj81yN`9;L=T4p& z(po7}rVnh)Qk2Q}v-s)j&owqyUG<3iTW}norv|%Ad$Y2c`Ewa-}(zHxG5YP`HRF3wLL!KZevgFaG7dpiXX9kDK?;Z*Yc= zac!8~<}~NGZMZi1HQqJ#boly_jTgIDy_J+#^;QnzQHKh7+3A<^f>>EzVO~;WFuNzu zyDsU~i+?RXt!AZW@H;m6Qt#j?n^Cs7l6t!syOlFGIE^vfCzUuE+Xu`$Y)EN0&Czm~ z+r_z}IGs_64dX-I{hj%nBYqF>;AC@0@eONwuL@Gv_fFcdBkjj#8^&H9&($RZ3e>l+ zn4*rmVyZgg%JJ%<0p)7afC*|=MvA(8Ku@*l%B3O5BHM}2Fhz9@ZSA95uY<91_|A^H z^={`qj(e3yIBRK$Re|@2;N5;V=*pldw(VomG58n2j}7nz8&y&y5smDOM|Of+WJgti zmSoT?f*8xdJie0kBa@mTEMQaBp8)@QHdFu1OmR`P9tc%i zXT_?G`OZF(&2^6{Wh&10z%o~a`vTtpo-BoW;B<9MUX(gF%jw$(1TTc&B>f#Q<)5rk z%uXA8qLIrADwsVcL~jXtYsko0kv`Ec2c2Rny(<7FPYmp1RUiXe^9 zA6RCO_O$C2aC5HWW* zR4YhrTey04eo8F4lpCQJUXsBY7ok3q-?|4`_zEm@xrIW6=%+xZ@{zS81Qo6`HLOIk z-4}?oNSbf~Fk+?tHZ(?bgG+&_FsR!h8FFH^Nr&+Jz$hnwfouncxWH6^p99M{5k6$X zr2n&_FKgg2V5FtqH7vq++Tc;zqa%7Ai1{xZCu55|{KD<@NLM6zws1#bhdC+;Qw z6Il95{L?mk)`pv+n9rhc!6rcM$ZSxtVW$ndY}jqXp}-UZyMd*fB!2{0_ELl!O_-9p04ys9@m+9V)^@_3fQ>NtgfD$TkOs*>F0k46 z5x`~#t~be(!EzHO{hMw2ciZ$A`Y~!Q8CdBj=mq%-uq-GtxEa`7kh_7U!=!)6gh~Ea zU~>je15*ZMb#tS}QbA;^@8yMwGDri(oWkWcJj{eCh3kQ(2ZYOk&1E>(#(%`bCy$>7 zHav_IAy{n?;HkhHTd6l(mC%l4e*`OqyfwYh%bbLu{-@A0k>0l^b_PPj6|tk5GZ0wD zf$%UJzS_XDp-ndQ<(raBWj5%ddG;rN76O^8!%7=|#lTW~o78Sckvd|MCVUc@e58!u zk7pZGw+wH?z3O57%~JV@4t$f^aYQN)SBK+oYjxI$I6gt0HzG0l#pJ+4j5Jr<@Js4@ zBiitF>d_IY5hVy9r9wWDY=s&>GO^1-8?_!d2@(Tsk$w{z+ti|wiM)k++sMR%q|`tQ zqvvrhu#7WVPc!jJw>Pi?yHux%-xpZa9^B)9riPD;SsaE;#}teXu0QT#-P<#D{n)M> zmKKar+{fURA@#ItRTyU&C2ks*l@i*7@DT&gh7fIij3-Gwv~7lKKph%P3w6}%gEs6g zY|X9eJ2ApLm8z>pi_}+QDCUgServ%ys_n*(cD*?xm>uf4;kL04D(=ok0`M<4B)7V3 zc4_s5svBpjMZ1Qn`|F3bx?he5G4j+s)RSbAYVyPmgogqjM73OL~5hYvqk-%8?u1cs{$i z@^hMc;gtdUmscJ0Y8$$(d$l8d)xVl18Ao1iMYnuof1MJ)VeH0xIo%&<$k9o08~Sf5 z5TplRYZv`9p8olxM^zv<;+0CqR>oz*u2HUqnnzE9osOlz0W2v@uB zsCA`-zcNj|dS!mh)x#(;T*vT=LH;1+W}4Zo(ZIv#jjjou^G=9loTMt>x)ss(<8vOJ z#-vG;s!MC?%4=Ep^~l>NQR<<6?TU|Mq%pp(SI@ls5jy=%gD@gb$BQK%t>e2S9;xFO zfE|bZP3zh~)4G}~3vOZ=7uD%srh3VX+tH%lgC}KhnT2;5$yjNWI_hxj;HzMx3{H%# zD61V)HnVg@O=+=iy`#a&DXOZit1cZ>GObi+#DZbV(L0eU|Ej%mG*a#ORU7Yaw7~Io zJ^B_P)5S&QP#b|=~e-+J7s&!wbc*!4nvwha$(^HY;Q}?@|Pd?>Um(Hpyttg(O zr(0@}bL(p7z*!?m0dh$(s13z{WG`nxvrj9SzTOOSW7lYpI+f7T5L=dHiCx;z1P+J{fS-@qIdc$ErR{f z!yJxP+D51&55%}5g#3dc>Ut=UFunA5v?yE%Cxzf&=p7~V50xKi?Ij@^4a8Uk_X$De zy>PM|{4&XB98_l zdlpH|$xxhvb<3wPW5Y6jQvW=d>?PSOeAZj!4~Gf)kHaW8L2l&cPj%8aiC&VV(ai#j z^c!JROX63-EY;#+rL#-RhZoh%(Cg)*F!h_GaZz`IE30Y=Igq(cJ@$>)OXg^RbeqNG zC}A=^LkOx7%6ASCNu%pDS}5bBNTaDTi}Gbcxvy6!ABs>;>B@RBjI67zszZe*H5z!0 zwWtOO)qW@G4J`AeNaZf4IbEqsdL{T|TXer^L1E~v7 z>e|CGUP^@qi`fWd)BBO0Xqk_ztB)jlNr*iT z5TtMf`r)-g^_<$`+m>EZqrvQYi|SHcb>81pXA9Ls>a1^Ddr6JPy~`}B#ky+2-&C(8 z)r=kL=ierKNsWfc^DL^JgsKwPT(p)Hw3fAM=67B%Nz(Ya&LZs;(xXn`rIWIkUr|f_ z`mCU~mT|I3qwpe&)el1{x}lqd@<$2ETR|>u*JYlVcuul3 zN*`{Ke^$s}`54J(Y)Di-3JRg8!BwTg8zhuhUNj9I6+LiBo5uD1Ef##jf>IueT*oQ* zwNzg`+R95}G~{n*5xq8)x`5z3;oN@p{LwaE5~8_)2#a7ZAsCt@1UIx&nvjc*ojr;1 zoMdUP;5^=q168uQZul%#99TxZ`oi~Zy(C1F2tQc_e`rP?D0`Zbv#tl)C{Mav+KGMc z=y*=TEAiQDQP_f)arBrkHB%@55Fh*`C6M`*I`@Y}FUis*#1@PE{X#ytP6)16cm2@H zOF}d|vBn}eMF?h&6fQ4JR{raffiEbnE~_lDhMx3kM&k*KjRCrI9Vs_aedu9xI9b{2 zGCgd@msVGb+Cs`S1#*wYK&&v3?hxLtO;Ntpb&c-TuS|+GUoy+0+!#Wkx%>c)YBMjU zC?|B~obuA5YC~18Jfup~D-$j19|-j;8%RClXsU8Yund4jS=2nzrU{vRi-ncKg0dil z3bV_Bw#t%VQ`WPKiy0>+nz!j_QM_GOoDrh7`8jszICx;RKh&p@|nxsXuOg_b;k6@QJv5O}zo|6L2Rjs!u)#}!Zg!Sjt-p7)>Bt(-~%PfK; zbn90L>n^hXKqqzCF|U_ISK~9!BAzD1TgAXG71FTEqLRS#PZ3f0?XlwtUeer%Pn|{k zH#bEqWk2RR|E|4*Wy(Jm>_-!jJfjwOHBcR<+|DlxN)PiM=tS<{QSu z8*{<*q8g*azD=0>stIuCUag7W|s% zB?X$Zi?Jy6(3M)7l$r^p73!K_lLnIlP3+OQGEj9+VTsY~`4C0p--PJ<( zbM?{Rl3Ed$<`mzvNIW4V-cWb`7Vjl4%`QG`k+>JLK!;;n*Fez76I!m{|H(rCEwx8u zvX^veKJp%m{_tS+cw=18%LDrUm~;rx%rS`;HW#TI8dJPvkLEOIS!{A)Gx%3pMald{ zZFVBbOF}f+Ing5cwTluD-Yx{UszoP~y(C1lp!pWTSA}5c(?am&-paBNmv-oDcWgW- zS(+#9Xpw(Z$hW%{@)Q-sBfFxqc6wP?J^ba)h-II zlH;PDmH(|S-V9ek3r!~AgF)Sa0%9^oA z;T=Nqd*)0USyftLykn36E$nr|9CaDASop*O#=0b^^{1nigaqo5ays*Ckv9~LURM$8 zEeg+ck)@pSN~(5bftCYl%`IRh7^4=Jd0OGuxwLKv+%Y~*GPF#nSmaJ&WCuA1uMjr< zqcxJGWyB-+1gsv0bXi@xK7JOnRv$|WMz(_RhC#pxoo2OY3=55HUonP8L|6pEIAn?D z8AYq)W1KAWMJK9{zt*b432E!wH1*4M>Z#@1l|h2L#N zzP7H$aF~{5X({#wi)MJd%9~<)WXyB(qufIkg%3Q8cP7ra z!_80WQ7x28BujN`phf;?%mGieBFYi^h2=%FOS4N#F!(0}vH?LSHoFKbsS{rf5cK9j1Xup4PPwT6Dy$c;-W){EV(+GzY0f3bgqB zfki3gcXTr>hTf;2l>q{2i3HF`JF1QB|84K6M>rjC9Bg{C?DUH<2>YQ}{)-y@Oy zS!W<-{%T4I(C&j+OCs-*-I+!r>x@JS{D~~HC-MLY)W?y?q#1*6mYrPYLs5JOC9Cea z5LZFz&=ZZ8b_3P?Msr#ve@knWJ*|v?NDFq^N;FU7p&F#gm7>UWq~}I6T!}Gq<~Is& zEFC=5@N6g`4N;<~H0c#Lbj>xZ#C8r_|$HSx}1sPUcDnAL=TcQ&U?yGau9H zm_Ulo*1e<&!@T*9$Wbtd^ggFFM+LFGXB?eC`V+8;NY`R6l`hOQ$}GEOmbWXP6{_!U zT{DVyK6xSC8Bmi*b~JRG(M{kQN`w{u{A~0O07JiQ^_lZSLgVx3IY*xOQ+OL8(vxA=g=N1 zv2UuNw4$W&YCqi>-4~szursG-Oj+>^KZl57Csl6gREz6G42f1B+}1Llc2-eU7uREs=8kPni}w>yI> z$Ol{*+nxLyXV6qk?PBx~c~YlscKre-y1@i8U0qs)6`}O8n1OGpe*AuHF4=5^=qY^o zVUx}Kg7^v8oK|YsBzv?~FO_VX4S8CsY5#3^9r0-EUYMQ#CkWU3m&D*5FK}{}e>7+= zc@GULqC;pZm5+h&Eu`t%jE_;GZvPT~O4X!EHMJ%5R1Qx>9)cWBY$xYBwG5N7iDT8V z+gB^c!d1tPaD$97=tvsNFh+-LyH3j1hogCYSPo34dCt$LysxE!>O#|zuvhZOj;#-IW z!=yZLPHn02=$;62pi1@;Lys1qae76_sjQPz8=0UHsid^LXif!QrD+bkGl+QEQ_J@x zTt{Bep5w7rPa2ah6{g(=wFIMvNjH|2)EcWTuNd^IqUy3*W5ITDl6rVg%oTTmb?L}f zSvcm%P6WsCa0o>tw5;7KWjLbw#H7(%421Pp*1;Z;LB-16?|g?^rnIJgx@E zu`E>7o=BInpnyurT6>;=2+MrBx$=s`?DFWs-sydGpUGd^{mrdD-wQ>mGy0H-O1#FP z=;J1$OcuuPZlUaSsCzz-@sXJj^nb_c!4T+ShX2jf~?``@NurH~@i8ine`Z9#!Z59yf?cbPj@clu}vvr__goz%rgzc>fUET18V1 zBXcdocT%Gx6US0%rl(^F#`*^po-4)0+a8(IBTJI=@!2P&gJ@=8iQ4^CLI@G-@xk_( z1xI63Gd^?h>zYxL)Rh$E=I0s)NQO>atP=**`cqEd9}YgvrHkUtGG}@jhNUDz2Qil7 z3CA)QJ9&*sqF^lJ#H5oM_X~kNPQHW(Bv2J;>Wz~Coz|#@kWocJ&#x#cy-9DUmm@qQ zSmuf#jy)OVg8uwKj2I_HI@&Rrl*?rOPDX9+U_=>WV#Qsz6-}YW6Li)eF|A3Dp6A2J zJ8_-6jwQ{GIc*u0h$ka*~dibf{)OrHWu;g6`%U7;D~sQ3Q|a zbG9AKXFjFy9=eV(8YKlfd9&TB^n;MDUvwRB6;JGz_^h&u>}iLQBaiI`NeY=U73Z%| zFB$Zl=|vS4a_;&`VRqf3uXyWtGD&B6?zft~zulq*JVvQ&r=@Y;vcnX^OfEes#1t61 ztH8Y0NMZ24AZ-TcNqxy&0Y0@>lLHJJg+()~%1db|sux5@p?pT$!g-r`(xcE$w(7>} z?l{_M;R9;hL1)a4Ah0{}nwb9~e_;kTaDYTd&1R&b0q+1IxiidU z{tCCvJI->3j%1wV=os2HkY$;FY2gkY?;`@8M(YQnsfv~u6|@D+5m|pv(DQfhGC$4# z?Eeuo>W6A%k!&>xCGzcHF9pXlj}dZa0ClmbjUJIe0(ew%!bc*Ca>h z;{NL3Pt{);7C_7J&hN?X7TUl$Jq8*36lRDdo^bLZB8h^^8%wKm$5h^kd1$gvXYIa4 z8Z2|8lTQ>P`50j`P7FGD_X#mGPB?jG2<_!VS2lRu7}LZl$^ijL|%4~w=wemI;&pZ1IPiIcYsAt5@ucORLI3i5*Ug4R3;9HP#}XIg;sy*4z6 zCx#G}j_+M1IHEs&I+(x4r7JlFV@*zzBpvGOAf$chee*vJ4lmb#z~Kk0{+n6Up)RII|OZek!=NyD$ihF{^*>- zF$48#wiZ;D|E_x)k|Jw8@%aoEu_L1yU+xt7(d&uWPbnUeB=bNhV;hW=3(CvQHFtrL zILIOf`ePMDqZE8{+hSHn<53GqxDFe-PkjteL0GX|y#Q#jgq zIV&`j#>~WG0ll59F{H-$W>)poN%u+8%&J~GrPiPfr=cEceIFpm@z-V($ryrt22$Sk zW;FGafxz644}UbsJoj@UNKF2uK(PB1n*HHpQpDs>7${=$rwM(7KKV1cw=wxM?m`d@ z{zv;I7?qJCPKP?x_F9CS_X++U&|P z&ZLviDG;dK3PKjFu>7;i9^4ZH$DmmYV*U(57h+~=4nDy}6L*t_<=~ZrBh5~kQN!!mGqK@S%GV?c;>=ZjKZ8KidJaZ|`J z02dNV@1(x8Bi=`l4%{#4hGpQbd}AfnH$b9^I-VKCChip^dck($!v~=)U44(jN72N# zK8;G+bS(d7vT(OT7N!GMkoZ&*$18Q2cw^M%NtTZ3kAOUjn7mP`s?rH`K0l?Kdd&x| zE~i^Mmd_zmSC>ArO5elRZx}{Q=(7s5hZhVRWQ?YX_&($uk2=ERhp8`pknCD2)YZKo z^zxAvI?%tjD~1onH2S6urc)A4&*{cQlU*3UbAe z7|87*5iWEZrls*ST)Wl7SGf^Gk*qd3ju*D|r-{=CdL9vf%E{fxrGq`;_fGnM(8IfF zuZQqhB|Tc(9l{T2>znaW%C;!Y8OnPpq0tTfL;3AoSsK~!T63PrgPTNpC$*7S-7`;T zYL~_FG;Lx$|GL?9R6hrM-Jh0QdZmqe(lemb1XBsnkYA5Yab)B^o=4iV{Y0 zyM$aR{_6E4-fx=Z0=BJ8 zz5Dbi#MZ)6qfB%LWmA;RKNO+Ani@q&KUnh56H;M=V=H^v`zbIsMJcjXhBrHPhBQPN9DI&ob% zZ>bDZ8s>!aRZ5Tu<@1{}d9<%R@;3z^C%cU;UQ8uG*U!ijaTHMHwG}j?n`v(X6WvU! z2PV3iwgi~yX4>t*OMEus&A`Mk3swUY-AtZ9Fj1%`_@6q7w~cIsNJl z0x`^jvA{$()Bc1w(ap4zpb_0nI|fX2GwnxUqMK+wb_fJwn2796V4|C8tAUAbracWz zbTjR7V4|C8R3EAh8hw)t_@Q{i#T~Ax_=rklDsOrY5#4MEQ2e-onKl^pqyQhzMiZMZ zsyZ2eCuIrJC|yRE@=X@B0!a%6jJ9fuI`?;yQ;__|NUE(M`E4Bn>3e)Q^Gi`(-7QFl zugE{q_WWH;*Yq2s8vVAA@{_1SueK@@X_HlI2_TWV__YX;PpaS#2+}Bj{S&RhDn@ml z$R_^-B)=E3b(o|AB)=53iz=&m(OjtgnLMLrL39&IwiXkK+C;jL@&{HnACnZd66*a; z^@2!g7DfEvgrDYjmfBK?5G$1Rf=FlaF&PU;`Mn5`{I*U)iO8n#1V{z4{)=Y$s}S>R zQltFYN;(91#7d$jNsmvHeIk8jm7+%al9lu{;A%?W6f)U%O{7|g-77S)e5zkn_?n9k zXa4XI>1ILlx4{6(A08r65+?J}vgMm-UA47ic*~Z4HE4(*P%?=$ID7FDrNP^uuW~hP zF67a?Vcm6nPjJKLzI>e0Fue~S$F=XC4oYiSSj?+#)OwFr!W+EVLA#0;KNA$%aBP8l zle2jN2F2Yc<>p`AvwQD!t>_tdly-ixJFH>%V)yRgOK~qQcZWB8w%mP1$NREIEBH7X zvPL^yzcjRX#C^b_{WeO;y)Orh958Z5JNN$D5WU^K(7o|%er$H+eJ<+CRv`wB3Hq}` zE&no}`?OE@x)bxO@!SlYFWlru*c<7=y9BWU=Ku>0iasdEAVKcEeBH^kh)$k3rCE?R z;&XR`vkouyYSn?*RtIrIMsyX^;krR^OU*hM>s(AX3l4e{83wfSaEt#Co_NnM(~f=a z_WJ%b1awfQ8$*~j>M~C(1{*uSaK}4tX~wi$FZ09?IfRKXBcq15azK-hCsV)^d6sCc zL6r#@M~u#gGVK%CPaNLdZ_iK>QQH8r`qELa1HYf7g?08MI40mGt+S^k-=KZE&)t$I zX}|7s$2lGdV_H>bIQo^==1X@%%g*6`d)C7)3&WYVzOyIFd)SaLJd!6-x@mL2L^=5) z{QBmzB1a9fQG1Gu*~Ca)&@e-1H=Z|0ej!?B|NU=rM9so}2nv?@Y{i41MHsO)j$0gy zV%mf*9xu<(vcGbBozG#OKz-_1RALB5StM$t?mxOv8N;--T|6=Tg7(x`?zooYV=Z!l z69WygOgq-algQg>jbFK2^NCv6*NEy9TIa9bt(>1@#ZCS6w07M9Vb1zNWgUDjVbSiV{(XPihhS-EBJEfG51d9)A#18K{}m zqxv^y)5(Lt-s)_v^8pmWO$Jdm(9;Gs@=D?B1e2tvN176|QRknJakfM!qaHdR6RY9IuPt3|p^f^+-NxMyMX0c}McTSu z?*7WI#o8~s++!5hUd#T}eWh}!P@DUyd#tkg3GItd-POvfrP|Ql?o@Xhp>^w6?bAuM{Ua_Ul-JzmYa-Qh8Phnc~4xR)p{E$1O z+1)n?tE?R~y0k;zcdeFj2#=tLI9uG_6V1QXDi66^`gZ*X3z7)yhmbZ+)YDQPy%UOs z5M)W@NUXbx-!&q#o-Gpm3%(FVU!tQGx_CH66tN=L*8pf^as`f#DH8uGUumseYoo)L zf>v59-j2kI&o5SD4?*mR>SjpN0+ygn4bbF@*{22xwNI>b<)B`Yn(jC)LhYcR&n6N? zaxk%^XYev@*uv=2tV^awpXH~PSF$SZsXH$Ur9b%J1ekYE%vCptIuDq;5*rgi!Jd@D=Tz4;5fPP1N#0X zd@I0x@VyFlXoyPuf%wLiMCI#%#9(}*$tK|gt|ESz5RX$oE&yF#NY8iCMi36r^gdlO z0T@qegcFp&c%3EwlEW|C@I@QGhH`FPGJ~=?IT)rBR@wy4+b~6hw&&1A4h=P;LzoP% zwBeIBobMn>{UZ5AX6ysuxS0S<3Cadb30_XIG%hlr+Azt}J|wzG{xJB>frkN8k^KSO z5A7T8ssg(Z$x*;5z&;Z2f-v!K3@laRjw^H>=MEk5MV^qcu+YB}UKMp?P4ZefDWx^czzl1};$3=LL*@bb5xBGgq=t)%;Qy6R84C9$k-DCPE%3N6JeK(X)!;`)nUX#^ z^gZxdbY@g_C_;9A3-rsrQ~w_VeIY=6y2!xw!19unu643bA%5j0_!Gb%0TJTg`FFmL z(N9UzMFIY_k5h$bJPcXbB@LW)3}8$O0dqrQhyO} zf{FjCfhkZVZ@2H;3js<%RuX#-{s3QIGD7rTGQ=?Gq0ktYg?tcw3?bC}@|ebREH`r7v7QAu!k=$dFG1PJ@7~l=lM5iz=BNYc~E1 zz`3XsC>dd&URVh07iSy&@@W6E)}|Q(kC)1eFxCmDpm|9VU!r856 zK0^M04X*$;@{eZ#1lE}aU~nsN796094DK>vO7I)tZ1Ab;jRgOD;Cw@#@F@d#Hux?q zB$)ZB5lCN-&q$#!1a5-?3K`)X0|N>?3YdO;i6TP$>A*CtM;GC08@?0xoQeMsFgGfB zBqCZLf&2%V2roe(SYjC50^H1m_t`N0K&YAT#3;v%6KuGv4d?r8gd!Wh$%Y@c;Z-)g z#fA^qFrBeAJLn6?sK-o5v*9akc(e_d*)UBgnC&eAZZ0E;kgo;~lUTv{i-uVy0y|{G zXKXkUFZgEpE;f9X4NnD*2qeg6Suon)-4+68j{(P-6zXmG72re@f13^O15TBE=$|gPXwl(kn9fxE&?86;IY8}5%OsNBrpSn|ALTa2+RTg zO$g}x`+%F_Z9*n6AGiZBIyj-f0=OSAz65>=H^YHx%7yH|15C@!67K@O12~lWUlKS3 z!ox%`@Nd9R0LzFd7|Xu{JjLL*08YkxADXk!Zw1^7c$`tjmjOQrWA_{U0l-msXF%N( z@`b=1fPFFtB_Q+z;RZusHt%2%{h%YkdrEW&z8HbO651gwuiN0i#+7{lUNsfMtfp0Y7Ep zmjb^4jQ@pv4RAvX#9tETg76*yzJ$Ph+#CQ-F);ls&_!S=zXtePJd$$_{yV_SfMqNA z0QebT8L@AG*8q1irGWpi+6@8U16d38esZYTP2k`0nXL*Hz#nxhQqN8V&*5=a4#G7 z4YUyoZJ2&i*=(@RhVQju&4yRmaDx^5*!xxj+iSz$+3@c+te{UeI~ZxhDK^~0g7N&% zwh*vK&4x>D_(mI^XTwk0@ERL_+l=Y?|B0CZe9(sJ{Jc4b=WVz-mLARgRyN$thOabX zAJx*~CIaD!HaydYZ?j?gK~l2=D{Oe34Q~lxpJ*nZ1_%Nlw&CAxSiw`ooM0qyb2K~I z(Od@HA9yaBAw6uefnNhIFfjdmW-{J6x}yIP0%JiK2|~IdFbViRU}>-xcmc3{KbQ;r znu-4?@Vh3w4EQ5p*>kQ3J^T$~N4M*i&;LCj&|8kv5TM_WYz{1Yx?h2#O#HLJ zallE2e6u!qd;^0lGL!^NZ#k$c0`~--1uQc(2>2FYpCnuj!aXK|>A;TyONVX&R)OW? zRs(+0#NPl+Z$UD_Ex>O8%M9!S-eTe(1wIgq_)CGaAbbk}8R9Txtr^}42FM%%UuDAS zzz2YzHu$4}eR!lc8MqAi7CaxM!!^Kn0m}&83j9>OFCg#$2rocDKK)hz?=>mB3j8~; zd^mjsd=VJWBN5_nfg{izOa5u#R=~0j&~K@90hSSO58RLXe@PesLN@SshQU$5?ap}z|FSzt5-VQ&+#?==vRrXYL>!e_wJ<8OfJ z*OKJ({1osB6Anp11b}6TQ-Fg}0c0&t2fhqgMq~(ZKVWGOKkVaUgFuiusD{8uVCld; zz>`c0%YbK^@J8TUO!}V!-(%AM8F-NiUjTmAgribX{;z@{J?xZ|Qb1N(ug zJCZIK1b{yHSuGCp8=K*b_8By!oDj(XaJ$7;o&IYpMVi5Q71})o1x7}d^0fp zc$KV_3xRWhWddt~>Gw?}-VS_?2_FG23h4XTA0XTa0{#~XhPOkR0mu+`27cCr^MGG9 z;UZw_PVv9czY+Lb6aQi0-+`q=&jNGwHF^Z`{9g+~JP0y}uLEZTPd5yH0Q?&87{VCO ze`R1mk>GE@5lJW_uJca=w?RwEF!&dNCj!$&52LX5CQS4HZ4AN)5&-T3TqG5M>B#hd zfEB~QNZ>URgFhX3tqI=&ydL;v!`?#RO5`rdz^i~40aHXU|AYvD@RUhl3-EiuLkxv| zz+tFpqEbTs0B|xewfhv{;|2y4IH-fpm$(gZM?;>{>j>Nj7?(c&ztSKmpiqde2JWW| z2wZ1i(F$O|2RsOTQKrE60}q$-z$4oNz}Y!7D+C1|iA7 z!+_-~Rs?2$C#GqAn|YF3(9zwl#W;7|wH9ZvwVdXjVk zj`F1R9Z@&CvbM5f!h{iZ!^?`RD<|dV6-=1WqifHu-6u@QEuCFfTsmO_onQpg|Bbl` z#YGibR=B5?I1(uTy(=RAYlG!8E@2QvGT855cqoo|`dzdf{QS2jr&X0z2Aq^81(i(p z`4?W+6bB4?jNpRyug%TTA|gDkMXC7B&Cw1;c~bvP4C!ocz(09>+BmUG`ya9I6Pqo? z-b&i4sWpXqx;4y=@pQs5nJ7=2e^aw?R63BPtXV{)nEV@qIN}{J7-qy+Klfcy-0)7U zrwi9gyq@0Lf4rUn+EYf{_H$3hdqy^lPVl%L+N@Td zg<4T7G>grxJ<(eC)}FYquHA~u%cgXzDVtVNRNl2%Ti@D~O16KD!MW!e*44_dX~=Hl zIUc0l(%o~rcCnl1)&~6Jb~xxgaKAfJYuC|pujcLM`9VAUsXMA6w1?+eXG4b$o@1QO z{4{Lq=ou5#u)dFHprW1W=Sd05qu)`CIz^qzf+wG+cUA13ltjP4V<<7qSN_&e4 zX^&-l_WpyJ`8gg>z>KU@#$j>Rur7xz_3tr7kG1y9pntOD6rG1Zo8~U1VaHJ6PkPVd z29($meo0>*;>DU@y}7>wp&&Kv8tF;l&OW{Siwy15wvO_AdPyT{ATQC|dO2#OUj5|1oDm(eGNgVb|z8;N631~0p|6@H_GxSpRMEr_F!~Q}FYoMNdH1?m&IH>FKhd|ag(e-GLFZHYo8jR=n zIBobc&sBW0wrH6rRXNpGdwrRwJ-<~uyv)-9U!LWj4nc!2#~wYc&vH+yYvD+&2fwae zzuc4J+VA14q>FYh-DmaV?7ME-OSo6sPSbWT_q10A@6pcUyZI|e-K-vOUo?IR)w-^(!-WQTwdI``9IF{-0lDX diff --git a/stepper/Objects/stepper.lnp b/stepper/Objects/stepper.lnp index 39273a4..f5e75c8 100644 --- a/stepper/Objects/stepper.lnp +++ b/stepper/Objects/stepper.lnp @@ -1,18 +1,27 @@ --cpu=Cortex-M4.fp -".\objects\main.o" -".\objects\ssd1306.o" -".\objects\can.o" ".\objects\clk.o" ".\objects\eadc.o" ".\objects\gpio.o" +".\objects\i2c.o" ".\objects\sc.o" ".\objects\sys.o" +".\objects\pwm.o" ".\objects\uart.o" +".\objects\ssd1306.o" +".\objects\main.o" +".\objects\basicmathfunctions.o" +".\objects\commontables.o" +".\objects\complexmathfunctions.o" +".\objects\controllerfunctions.o" +".\objects\fastmathfunctions.o" +".\objects\filteringfunctions.o" +".\objects\matrixfunctions.o" +".\objects\statisticsfunctions.o" +".\objects\supportfunctions.o" +".\objects\transformfunctions.o" ".\objects\retarget.o" ".\objects\startup_m451series.o" ".\objects\system_m451series.o" -".\objects\i2c.o" -".\objects\pwm.o" --ro-base 0x00000000 --entry 0x00000000 --rw-base 0x20000000 --entry Reset_Handler --first __Vectors --strict --summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols --info sizes --info totals --info unused --info veneers --list ".\Listings\stepper.map" -o .\Objects\stepper.axf \ No newline at end of file diff --git a/stepper/RTE/_Target_1/RTE_Components.h b/stepper/RTE/_Target_1/RTE_Components.h index 7aebab2..b80b830 100644 --- a/stepper/RTE/_Target_1/RTE_Components.h +++ b/stepper/RTE/_Target_1/RTE_Components.h @@ -16,24 +16,6 @@ */ #define CMSIS_device_header "M451Series.h" -/* Nuvoton::Device:Driver:CAN:3.01.001 */ -#define RTE_Drivers_CAN /* Driver CAN */ -/* Nuvoton::Device:Driver:CLK:3.01.001 */ -#define RTE_Drivers_CLK /* Driver CLK */ -/* Nuvoton::Device:Driver:EADC:3.01.001 */ -#define RTE_Drivers_EADC /* Driver EADC */ -/* Nuvoton::Device:Driver:GPIO:3.01.001 */ -#define RTE_Drivers_GPIO /* Driver GPIO */ -/* Nuvoton::Device:Driver:I2C:3.01.001 */ -#define RTE_Drivers_I2C /* Driver I2C */ -/* Nuvoton::Device:Driver:PWM:3.01.001 */ -#define RTE_Drivers_PWM /* Driver PWM */ -/* Nuvoton::Device:Driver:SC:3.01.001 */ -#define RTE_Drivers_SC /* Driver SC */ -/* Nuvoton::Device:Driver:SYS:3.01.001 */ -#define RTE_Drivers_SYS /* Driver SYS */ -/* Nuvoton::Device:Driver:UART:3.01.001 */ -#define RTE_Drivers_UART /* Driver UART */ #endif /* RTE_COMPONENTS_H */ diff --git a/stepper/stepper.uvoptx b/stepper/stepper.uvoptx index 5c8805b..7855eb7 100644 --- a/stepper/stepper.uvoptx +++ b/stepper/stepper.uvoptx @@ -149,7 +149,7 @@ 0 226 1 -
5146
+
5126
0 0 0 @@ -165,7 +165,7 @@ 0 221 1 -
5144
+
5124
0 0 0 @@ -181,7 +181,7 @@ 0 216 1 -
5142
+
5122
0 0 0 @@ -197,7 +197,7 @@ 0 211 1 -
5140
+
5120
0 0 0 @@ -213,7 +213,7 @@ 0 207 1 -
5138
+
5118
0 0 0 @@ -229,7 +229,7 @@ 0 202 1 -
5136
+
5116
0 0 0 @@ -245,7 +245,7 @@ 0 197 1 -
5134
+
5114
0 0 0 @@ -261,7 +261,7 @@ 0 192 1 -
5132
+
5112
0 0 0 @@ -277,7 +277,7 @@ 0 187 1 -
5130
+
5110
0 0 0 @@ -291,25 +291,9 @@ 9 0 - 218 - 1 -
1212
- 0 - 0 - 0 - 0 - 0 - 1 - .\main.cpp - - \\stepper\main.cpp\218 -
- - 10 - 0 342 1 -
5148
+
5128
0 0 0 @@ -321,11 +305,11 @@ \\stepper\RTE/Device/M453VG6AE/startup_M451Series.s\342
- 11 + 10 0 270 1 -
1412
+
1392
0 0 0 @@ -426,20 +410,20 @@ - Source Group 1 - 1 + lib + 0 0 0 0 1 1 - 8 + 1 0 0 0 - .\main.cpp - main.cpp + ..\StdDriver\src\clk.c + clk.c 0 0 @@ -450,11 +434,115 @@ 0 0 0 + ..\StdDriver\src\eadc.c + eadc.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + ..\StdDriver\src\gpio.c + gpio.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\StdDriver\src\i2c.c + i2c.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\StdDriver\src\sc.c + sc.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\StdDriver\src\sys.c + sys.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\StdDriver\src\pwm.c + pwm.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\StdDriver\src\uart.c + uart.c + 0 + 0 + + + + + src + 1 + 0 + 0 + 0 + + 2 + 9 + 1 + 0 + 0 + 0 .\ssd1306.c ssd1306.c 0 0 + + 2 + 10 + 8 + 0 + 0 + 0 + .\main.cpp + main.cpp + 0 + 0 + diff --git a/stepper/stepper.uvprojx b/stepper/stepper.uvprojx index bc583c4..550eeeb 100644 --- a/stepper/stepper.uvprojx +++ b/stepper/stepper.uvprojx @@ -338,7 +338,7 @@ - + ..\StdDriver\inc @@ -380,18 +380,63 @@ - Source Group 1 + lib - main.cpp - 8 - .\main.cpp + clk.c + 1 + ..\StdDriver\src\clk.c + + eadc.c + 1 + ..\StdDriver\src\eadc.c + + + gpio.c + 1 + ..\StdDriver\src\gpio.c + + + i2c.c + 1 + ..\StdDriver\src\i2c.c + + + sc.c + 1 + ..\StdDriver\src\sc.c + + + sys.c + 1 + ..\StdDriver\src\sys.c + + + pwm.c + 1 + ..\StdDriver\src\pwm.c + + + uart.c + 1 + ..\StdDriver\src\uart.c + + + + + src + ssd1306.c 1 .\ssd1306.c + + main.cpp + 8 + .\main.cpp + @@ -413,56 +458,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +