| /***************************************************************************//** |
| * @file em_rtcc.h |
| * @brief Real Time Counter (RTCC) peripheral API. |
| * @version 5.6.0 |
| ******************************************************************************* |
| * # License |
| * <b>Copyright 2016 Silicon Laboratories, Inc. www.silabs.com</b> |
| ******************************************************************************* |
| * |
| * Permission is granted to anyone to use this software for any purpose, |
| * including commercial applications, and to alter it and redistribute it |
| * freely, subject to the following restrictions: |
| * |
| * 1. The origin of this software must not be misrepresented; you must not |
| * claim that you wrote the original software. |
| * 2. Altered source versions must be plainly marked as such, and must not be |
| * misrepresented as being the original software. |
| * 3. This notice may not be removed or altered from any source distribution. |
| * |
| * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no |
| * obligation to support this Software. Silicon Labs is providing the |
| * Software "AS IS", with no express or implied warranties of any kind, |
| * including, but not limited to, any implied warranties of merchantability |
| * or fitness for any particular purpose or warranties against infringement |
| * of any proprietary rights of a third party. |
| * |
| * Silicon Labs will not be liable for any consequential, incidental, or |
| * special damages, or any other relief, or for any claim by any third party, |
| * arising from your use of this Software. |
| * |
| ******************************************************************************/ |
| |
| #ifndef EM_RTCC_H |
| #define EM_RTCC_H |
| |
| #include "em_device.h" |
| #if defined(RTCC_COUNT) && (RTCC_COUNT == 1) |
| |
| #include <stdbool.h> |
| #include "em_assert.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /***************************************************************************//** |
| * @addtogroup emlib |
| * @{ |
| ******************************************************************************/ |
| |
| /***************************************************************************//** |
| * @addtogroup RTCC |
| * @{ |
| ******************************************************************************/ |
| |
| /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ |
| #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_84) \ |
| || defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89) |
| /* Enable fix for errata "RTCC_E203 - Potential Stability Issue with RTCC |
| * Registers". */ |
| #define ERRATA_FIX_RTCC_E203 |
| #endif |
| |
| #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_84) |
| /* Enable fix for errata "RTCC_E204 - Disabling the RTCC Backup RAM may consume extra |
| * current". */ |
| #define ERRATA_FIX_RTCC_E204 |
| #endif |
| /** @endcond */ |
| |
| /******************************************************************************* |
| ********************************* ENUM ************************************ |
| ******************************************************************************/ |
| |
| #if defined (_RTCC_CTRL_CNTMODE_MASK) |
| /** Operational mode of the counter. */ |
| typedef enum { |
| /** Normal counter mode. The counter is incremented by 1 for each tick. */ |
| rtccCntModeNormal = _RTCC_CTRL_CNTMODE_NORMAL, |
| |
| /** Calendar mode. Refer to the RTCC chapter of the Reference Manual for more |
| * details on the calendar mode. */ |
| rtccCntModeCalendar = _RTCC_CTRL_CNTMODE_CALENDAR |
| } RTCC_CntMode_TypeDef; |
| #endif |
| |
| /** Counter prescaler selection. */ |
| #if defined (_RTCC_CTRL_CNTPRESC_DIV1) |
| typedef enum { |
| rtccCntPresc_1 = _RTCC_CTRL_CNTPRESC_DIV1, /**< Divide clock by 1. */ |
| rtccCntPresc_2 = _RTCC_CTRL_CNTPRESC_DIV2, /**< Divide clock by 2. */ |
| rtccCntPresc_4 = _RTCC_CTRL_CNTPRESC_DIV4, /**< Divide clock by 4. */ |
| rtccCntPresc_8 = _RTCC_CTRL_CNTPRESC_DIV8, /**< Divide clock by 8. */ |
| rtccCntPresc_16 = _RTCC_CTRL_CNTPRESC_DIV16, /**< Divide clock by 16. */ |
| rtccCntPresc_32 = _RTCC_CTRL_CNTPRESC_DIV32, /**< Divide clock by 32. */ |
| rtccCntPresc_64 = _RTCC_CTRL_CNTPRESC_DIV64, /**< Divide clock by 64. */ |
| rtccCntPresc_128 = _RTCC_CTRL_CNTPRESC_DIV128, /**< Divide clock by 128. */ |
| rtccCntPresc_256 = _RTCC_CTRL_CNTPRESC_DIV256, /**< Divide clock by 256. */ |
| rtccCntPresc_512 = _RTCC_CTRL_CNTPRESC_DIV512, /**< Divide clock by 512. */ |
| rtccCntPresc_1024 = _RTCC_CTRL_CNTPRESC_DIV1024, /**< Divide clock by 1024. */ |
| rtccCntPresc_2048 = _RTCC_CTRL_CNTPRESC_DIV2048, /**< Divide clock by 2048. */ |
| rtccCntPresc_4096 = _RTCC_CTRL_CNTPRESC_DIV4096, /**< Divide clock by 4096. */ |
| rtccCntPresc_8192 = _RTCC_CTRL_CNTPRESC_DIV8192, /**< Divide clock by 8192. */ |
| rtccCntPresc_16384 = _RTCC_CTRL_CNTPRESC_DIV16384, /**< Divide clock by 16384. */ |
| rtccCntPresc_32768 = _RTCC_CTRL_CNTPRESC_DIV32768 /**< Divide clock by 32768. */ |
| } RTCC_CntPresc_TypeDef; |
| |
| #elif defined (_RTCC_CFG_CNTPRESC_DIV1) |
| typedef enum { |
| rtccCntPresc_1 = _RTCC_CFG_CNTPRESC_DIV1, /**< Divide clock by 1. */ |
| rtccCntPresc_2 = _RTCC_CFG_CNTPRESC_DIV2, /**< Divide clock by 2. */ |
| rtccCntPresc_4 = _RTCC_CFG_CNTPRESC_DIV4, /**< Divide clock by 4. */ |
| rtccCntPresc_8 = _RTCC_CFG_CNTPRESC_DIV8, /**< Divide clock by 8. */ |
| rtccCntPresc_16 = _RTCC_CFG_CNTPRESC_DIV16, /**< Divide clock by 16. */ |
| rtccCntPresc_32 = _RTCC_CFG_CNTPRESC_DIV32, /**< Divide clock by 32. */ |
| rtccCntPresc_64 = _RTCC_CFG_CNTPRESC_DIV64, /**< Divide clock by 64. */ |
| rtccCntPresc_128 = _RTCC_CFG_CNTPRESC_DIV128, /**< Divide clock by 128. */ |
| rtccCntPresc_256 = _RTCC_CFG_CNTPRESC_DIV256, /**< Divide clock by 256. */ |
| rtccCntPresc_512 = _RTCC_CFG_CNTPRESC_DIV512, /**< Divide clock by 512. */ |
| rtccCntPresc_1024 = _RTCC_CFG_CNTPRESC_DIV1024, /**< Divide clock by 1024. */ |
| rtccCntPresc_2048 = _RTCC_CFG_CNTPRESC_DIV2048, /**< Divide clock by 2048. */ |
| rtccCntPresc_4096 = _RTCC_CFG_CNTPRESC_DIV4096, /**< Divide clock by 4096. */ |
| rtccCntPresc_8192 = _RTCC_CFG_CNTPRESC_DIV8192, /**< Divide clock by 8192. */ |
| rtccCntPresc_16384 = _RTCC_CFG_CNTPRESC_DIV16384, /**< Divide clock by 16384. */ |
| rtccCntPresc_32768 = _RTCC_CFG_CNTPRESC_DIV32768 /**< Divide clock by 32768. */ |
| } RTCC_CntPresc_TypeDef; |
| #endif |
| |
| /** Prescaler mode of the RTCC counter. */ |
| #if defined (_RTCC_CTRL_CNTTICK_MASK) |
| typedef enum { |
| /** CNT register ticks according to prescaler value. */ |
| rtccCntTickPresc = _RTCC_CTRL_CNTTICK_PRESC, |
| |
| /** CNT register ticks when PRECNT matches the 15 least significant bits of |
| * ch. 0 CCV register. */ |
| rtccCntTickCCV0Match = _RTCC_CTRL_CNTTICK_CCV0MATCH |
| } RTCC_PrescMode_TypeDef; |
| |
| #elif defined (_RTCC_CFG_CNTTICK_MASK) |
| typedef enum { |
| /** CNT register ticks according to the prescaler value. */ |
| rtccCntTickPresc = _RTCC_CFG_CNTTICK_PRESC, |
| |
| /** CNT register ticks when PRECNT matches the 15 least significant bits of |
| * ch. 0 CCV register. */ |
| rtccCntTickCCV0Match = _RTCC_CFG_CNTTICK_CCV0MATCH |
| } RTCC_PrescMode_TypeDef; |
| #endif |
| |
| /** Capture/Compare channel mode. */ |
| typedef enum { |
| rtccCapComChModeOff = _RTCC_CC_CTRL_MODE_OFF, /**< Capture/Compare channel turned off. */ |
| rtccCapComChModeCapture = _RTCC_CC_CTRL_MODE_INPUTCAPTURE, /**< Capture mode. */ |
| rtccCapComChModeCompare = _RTCC_CC_CTRL_MODE_OUTPUTCOMPARE, /**< Compare mode. */ |
| } RTCC_CapComChMode_TypeDef; |
| |
| /** Compare match output action mode. */ |
| typedef enum { |
| rtccCompMatchOutActionPulse = _RTCC_CC_CTRL_CMOA_PULSE, /**< Generate a pulse. */ |
| rtccCompMatchOutActionToggle = _RTCC_CC_CTRL_CMOA_TOGGLE, /**< Toggle output. */ |
| rtccCompMatchOutActionClear = _RTCC_CC_CTRL_CMOA_CLEAR, /**< Clear output. */ |
| rtccCompMatchOutActionSet = _RTCC_CC_CTRL_CMOA_SET /**< Set output. */ |
| } RTCC_CompMatchOutAction_TypeDef; |
| |
| /** PRS channel number. This type is used when configuring input capture mode on |
| * a RTCC channel. */ |
| typedef uint8_t RTCC_PRSSel_TypeDef; |
| |
| /** Deprecated PRS channel values. New code should use an integer instead of |
| * using these deprecated enum values. */ |
| #define rtccPRSCh0 0U |
| #define rtccPRSCh1 1U |
| #define rtccPRSCh2 2U |
| #define rtccPRSCh3 3U |
| #define rtccPRSCh4 4U |
| #define rtccPRSCh5 5U |
| #define rtccPRSCh6 6U |
| #define rtccPRSCh7 7U |
| #define rtccPRSCh8 8U |
| #define rtccPRSCh9 9U |
| #define rtccPRSCh10 10U |
| #define rtccPRSCh11 11U |
| |
| /** Input edge select. */ |
| typedef enum { |
| rtccInEdgeRising = _RTCC_CC_CTRL_ICEDGE_RISING, /**< Rising edges detected. */ |
| rtccInEdgeFalling = _RTCC_CC_CTRL_ICEDGE_FALLING, /**< Falling edges detected. */ |
| rtccInEdgeBoth = _RTCC_CC_CTRL_ICEDGE_BOTH, /**< Both edges detected. */ |
| rtccInEdgeNone = _RTCC_CC_CTRL_ICEDGE_NONE /**< No edge detection, signal is left as is. */ |
| } RTCC_InEdgeSel_TypeDef; |
| |
| /** Capture/Compare channel compare mode. */ |
| typedef enum { |
| /** CCVx is compared with the CNT register. */ |
| rtccCompBaseCnt = _RTCC_CC_CTRL_COMPBASE_CNT, |
| |
| /** CCVx is compared with a CNT[16:0] and PRECNT[14:0]. */ |
| rtccCompBasePreCnt = _RTCC_CC_CTRL_COMPBASE_PRECNT |
| } RTCC_CompBase_TypeDef; |
| |
| #if defined (_RTCC_CC_CTRL_DAYCC_MASK) |
| /** Day compare mode. */ |
| typedef enum { |
| rtccDayCompareModeMonth = _RTCC_CC_CTRL_DAYCC_MONTH, /**< Day of month is selected for Capture/Compare. */ |
| rtccDayCompareModeWeek = _RTCC_CC_CTRL_DAYCC_WEEK /**< Day of week is selected for Capture/Compare. */ |
| } RTCC_DayCompareMode_TypeDef; |
| #endif |
| |
| /******************************************************************************* |
| ******************************* STRUCTS *********************************** |
| ******************************************************************************/ |
| |
| /** RTCC initialization structure. */ |
| typedef struct { |
| /** Enable/disable counting when initialization is completed. */ |
| bool enable; |
| |
| /** Enable/disable timer counting during debug halt. */ |
| bool debugRun; |
| |
| /** Enable/disable pre-counter wrap on ch. 0 CCV value. */ |
| bool precntWrapOnCCV0; |
| |
| /** Enable/disable counter wrap on ch. 1 CCV value. */ |
| bool cntWrapOnCCV1; |
| |
| /** Counter prescaler. */ |
| RTCC_CntPresc_TypeDef presc; |
| |
| /** Prescaler mode. */ |
| RTCC_PrescMode_TypeDef prescMode; |
| |
| #if defined(_RTCC_CTRL_BUMODETSEN_MASK) |
| /** Enable/disable storing RTCC counter value in RTCC_CCV2 upon backup mode |
| * entry. */ |
| bool enaBackupModeSet; |
| #endif |
| |
| #if defined(_RTCC_CTRL_OSCFDETEN_MASK) |
| /** Enable/disable the check that sets OSCFFAIL interrupt flag if no |
| * LFCLK-RTCC ticks are detected within one ULFRCO cycles. */ |
| bool enaOSCFailDetect; |
| #endif |
| |
| #if defined (_RTCC_CTRL_CNTMODE_MASK) |
| /** Select operational mode of the counter. */ |
| RTCC_CntMode_TypeDef cntMode; |
| #endif |
| |
| #if defined (_RTCC_CTRL_LYEARCORRDIS_MASK) |
| /** Disable leap year correction for calendar mode. When this parameter is |
| * set to false, February has 29 days if (year % 4 == 0). If set to true, |
| * February always has 28 days. */ |
| bool disLeapYearCorr; |
| #endif |
| } RTCC_Init_TypeDef; |
| |
| /** RTCC capture/compare channel configuration structure. */ |
| typedef struct { |
| /** Select mode of Capture/Compare channel. */ |
| RTCC_CapComChMode_TypeDef chMode; |
| |
| /** Compare mode channel match output action. */ |
| RTCC_CompMatchOutAction_TypeDef compMatchOutAction; |
| |
| /** Capture mode channel PRS input channel selection. */ |
| RTCC_PRSSel_TypeDef prsSel; |
| |
| /** Capture mode channel input edge selection. */ |
| RTCC_InEdgeSel_TypeDef inputEdgeSel; |
| |
| /** Comparison base of channel in compare mode. */ |
| RTCC_CompBase_TypeDef compBase; |
| |
| #if defined (_RTCC_CC_CTRL_COMPMASK_MASK) |
| /** The COMPMASK (5 bit) most significant bits of compare value will not |
| * be subject to comparison. */ |
| uint8_t compMask; |
| #endif |
| |
| #if defined (_RTCC_CC_CTRL_DAYCC_MASK) |
| /** Day compare mode. */ |
| RTCC_DayCompareMode_TypeDef dayCompMode; |
| #endif |
| } RTCC_CCChConf_TypeDef; |
| |
| /******************************************************************************* |
| ******************************* DEFINES *********************************** |
| ******************************************************************************/ |
| |
| /** Default RTCC initialization structure. */ |
| #if defined(_SILICON_LABS_32B_SERIES_2) |
| #define RTCC_INIT_DEFAULT \ |
| { \ |
| true, /* Start counting when init done. */ \ |
| false, /* Disable RTCC during debug halt. */ \ |
| false, /* Disable precounter wrap on ch. 0 CCV value. */ \ |
| false, /* Disable counter wrap on ch. 1 CCV value. */ \ |
| rtccCntPresc_32, /* 977 us per tick. */ \ |
| rtccCntTickPresc, /* Counter increments according to prescaler value.*/ \ |
| } |
| |
| #elif defined(_RTCC_CTRL_BUMODETSEN_MASK) |
| #define RTCC_INIT_DEFAULT \ |
| { \ |
| true, /* Start counting when initialization is done. */ \ |
| false, /* Disable RTCC during debug halt. */ \ |
| false, /* Disable pre-counter wrap on ch. 0 CCV value. */ \ |
| false, /* Disable counter wrap on ch. 1 CCV value. */ \ |
| rtccCntPresc_32, /* 977 us per tick. */ \ |
| rtccCntTickPresc, /* Counter increments according to prescaler value.*/ \ |
| false, /* No RTCC storage on backup mode entry. */ \ |
| false, /* No RTCC oscillator failure detection. */ \ |
| rtccCntModeNormal, /* Normal RTCC mode. */ \ |
| false, /* No leap year correction. */ \ |
| } |
| |
| #else |
| #define RTCC_INIT_DEFAULT \ |
| { \ |
| true, /* Start counting when initialization is done. */ \ |
| false, /* Disable RTCC during debug halt. */ \ |
| false, /* Disable pre-counter wrap on ch. 0 CCV value. */ \ |
| false, /* Disable counter wrap on ch. 1 CCV value. */ \ |
| rtccCntPresc_32, /* 977 us per tick. */ \ |
| rtccCntTickPresc, /* Counter increments according to prescaler value.*/ \ |
| false, /* No RTCC oscillator failure detection. */ \ |
| rtccCntModeNormal, /* Normal RTCC mode. */ \ |
| false, /* No leap year correction. */ \ |
| } |
| #endif |
| |
| #if defined(_SILICON_LABS_32B_SERIES_2) |
| |
| /** Default RTCC channel output compare initialization structure. */ |
| #define RTCC_CH_INIT_COMPARE_DEFAULT \ |
| { \ |
| rtccCapComChModeCompare, /* Select output compare mode. */ \ |
| rtccCompMatchOutActionPulse, /* Create pulse on compare match. */ \ |
| 0, /* Don't care. */ \ |
| rtccInEdgeNone, /* Don't care. */ \ |
| rtccCompBaseCnt, /* Use CNT for comparison. */ \ |
| } |
| |
| /** Default RTCC channel input capture initialization structure. */ |
| #define RTCC_CH_INIT_CAPTURE_DEFAULT \ |
| { \ |
| rtccCapComChModeCapture, /* Select input capture mode. */ \ |
| rtccCompMatchOutActionPulse, /* Don't care. */ \ |
| 0, /* Use PRS channel 0 as trigger. */ \ |
| rtccInEdgeRising, /* Capture on rising edge. */ \ |
| rtccCompBaseCnt, /* Don't care. */ \ |
| } |
| |
| #else // Series 1 devices |
| |
| /** Default RTCC channel output compare initialization structure. */ |
| #define RTCC_CH_INIT_COMPARE_DEFAULT \ |
| { \ |
| rtccCapComChModeCompare, /* Select output compare mode. */ \ |
| rtccCompMatchOutActionPulse, /* Create pulse on compare match.*/ \ |
| 0, /* PRS channel 0 (not used). */ \ |
| rtccInEdgeNone, /* No edge detection. */ \ |
| rtccCompBaseCnt, /* Counter comparison base. */ \ |
| 0, /* No compare mask bits set. */ \ |
| rtccDayCompareModeMonth /* Don't care */ \ |
| } |
| |
| /** Default RTCC channel input capture initialization structure. */ |
| #define RTCC_CH_INIT_CAPTURE_DEFAULT \ |
| { \ |
| rtccCapComChModeCapture, /* Select input capture mode. */ \ |
| rtccCompMatchOutActionPulse, /* Create pulse on capture. */ \ |
| 0, /* PRS channel 0. */ \ |
| rtccInEdgeRising, /* Rising edge detection. */ \ |
| rtccCompBaseCnt, /* Don't care. */ \ |
| 0, /* Don't care. */ \ |
| rtccDayCompareModeMonth /* Don't care */ \ |
| } |
| |
| #endif |
| |
| /** Number of RTCC capture/compare channels */ |
| #if !defined(RTCC_CC_NUM) |
| #define RTCC_CC_NUM 3UL |
| #endif |
| |
| /** Validation of valid RTCC channel for assert statements. */ |
| #define RTCC_CH_VALID(ch) ((unsigned)(ch) < RTCC_CC_NUM) |
| |
| /******************************************************************************* |
| ***************************** PROTOTYPES ********************************** |
| ******************************************************************************/ |
| |
| /***************************************************************************//** |
| * @brief |
| * Get RTCC compare register value for selected channel. |
| * |
| * @param[in] ch |
| * Channel selector. |
| * |
| * @return |
| * Compare register value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_ChannelCompareValueGet(int ch) |
| { |
| EFM_ASSERT(RTCC_CH_VALID(ch) ); |
| #if defined (_RTCC_CC_CCV_MASK) |
| return RTCC->CC[ch].CCV; |
| #elif defined (_RTCC_CC_OCVALUE_MASK) |
| return RTCC->CC[ch].OCVALUE; |
| #endif |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Set RTCC compare register value for selected channel. |
| * |
| * @param[in] ch |
| * Channel selector. |
| * |
| * @param[in] value |
| * Compare register value |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_ChannelCompareValueSet(int ch, uint32_t value) |
| { |
| EFM_ASSERT(RTCC_CH_VALID(ch) ); |
| #if defined (_RTCC_CC_CCV_MASK) |
| RTCC->CC[ch].CCV = value; |
| #elif defined (_RTCC_CC_OCVALUE_MASK) |
| RTCC->CC[ch].OCVALUE = value; |
| #endif |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Get RTCC input capture register value for selected channel. |
| * |
| * @param[in] ch |
| * Channel selector. |
| * |
| * @return |
| * Capture register value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_ChannelCaptureValueGet(int ch) |
| { |
| EFM_ASSERT(RTCC_CH_VALID(ch) ); |
| #if defined (_RTCC_CC_CCV_MASK) |
| return RTCC->CC[ch].CCV; |
| #elif defined (_RTCC_CC_ICVALUE_MASK) |
| return RTCC->CC[ch].ICVALUE; |
| #endif |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Get RTCC capture/compare register value for selected channel. |
| * For parts with separate capture compare value registers, this function |
| * returns the compare value. |
| * |
| * @param[in] ch |
| * Channel selector. |
| * |
| * @return |
| * Capture/compare register value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_ChannelCCVGet(int ch) |
| { |
| return RTCC_ChannelCompareValueGet(ch); |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Set RTCC capture/compare register value for selected channel. |
| * For parts with separate capture compare value registers, this function |
| * sets the compare value. |
| * |
| * @param[in] ch |
| * Channel selector. |
| * |
| * @param[in] value |
| * Capture/compare register value |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_ChannelCCVSet(int ch, uint32_t value) |
| { |
| RTCC_ChannelCompareValueSet(ch, value); |
| } |
| |
| #if defined (_RTCC_CC_DATE_MASK) |
| /***************************************************************************//** |
| * @brief |
| * Get the calendar DATE register content for selected channel. |
| * |
| * @param[in] ch |
| * Channel selector. |
| * |
| * @return |
| * DATE register value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_ChannelDateGet(int ch) |
| { |
| EFM_ASSERT(RTCC_CH_VALID(ch) ); |
| return RTCC->CC[ch].DATE; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Set calendar DATE register for selected channel. |
| * |
| * @param[in] ch |
| * Channel selector. |
| * |
| * @param[in] date |
| * DATE value. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_ChannelDateSet(int ch, uint32_t date) |
| { |
| EFM_ASSERT(RTCC_CH_VALID(ch) ); |
| RTCC->CC[ch].DATE = date; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Get calendar TIME register content for selected channel. |
| * |
| * @param[in] ch |
| * Channel selector. |
| * |
| * @return |
| * TIME register value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_ChannelTimeGet(int ch) |
| { |
| EFM_ASSERT(RTCC_CH_VALID(ch) ); |
| return RTCC->CC[ch].TIME; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Set calendar TIME register for selected channel. |
| * |
| * @param[in] ch |
| * Channel selector. |
| * |
| * @param[in] time |
| * TIME value. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_ChannelTimeSet(int ch, uint32_t time) |
| { |
| EFM_ASSERT(RTCC_CH_VALID(ch) ); |
| RTCC->CC[ch].TIME = time; |
| } |
| #endif /* defined (_RTCC_CC_DATE_MASK) */ |
| |
| /***************************************************************************//** |
| * @brief |
| * Get combined CNT/PRECNT register content. |
| * |
| * @return |
| * CNT/PRECNT register value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_CombinedCounterGet(void) |
| { |
| #if defined (RTCC_SYNCBUSY_CNT) || defined (RTCC_SYNCBUSY_CNT) |
| while ((RTCC->SYNCBUSY & (RTCC_SYNCBUSY_CNT | RTCC_SYNCBUSY_PRECNT)) != 0U) { |
| /* Wait for CNT and PRECNT to synchronize */ |
| } |
| #endif |
| return RTCC->COMBCNT; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Get RTCC counter value. |
| * |
| * @return |
| * Current RTCC counter value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_CounterGet(void) |
| { |
| #if defined (RTCC_SYNCBUSY_CNT) |
| while ((RTCC->SYNCBUSY & RTCC_SYNCBUSY_CNT) != 0U) { |
| /* Wait for CNT to synchronize before getting value */ |
| } |
| #endif |
| return RTCC->CNT; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Set RTCC CNT counter. |
| * |
| * @param[in] value |
| * CNT value. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_CounterSet(uint32_t value) |
| { |
| #if defined (RTCC_SYNCBUSY_CNT) |
| while ((RTCC->SYNCBUSY & RTCC_SYNCBUSY_CNT) != 0U) { |
| /* Wait for CNT to synchronize before setting new value */ |
| } |
| #endif |
| |
| RTCC->CNT = value; |
| } |
| |
| #if defined (_RTCC_CC_DATE_MASK) |
| /***************************************************************************//** |
| * @brief |
| * Get DATE register value. |
| * |
| * @return |
| * Current DATE register value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_DateGet(void) |
| { |
| return RTCC->DATE; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Set RTCC DATE register. |
| * |
| * @param[in] date |
| * DATE value. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_DateSet(uint32_t date) |
| { |
| RTCC->DATE = date; |
| } |
| #endif /* defined (_RTCC_CC_DATE_MASK) */ |
| |
| #if defined (RTCC_EM4WUEN_EM4WU) |
| /***************************************************************************//** |
| * @brief |
| * Enable/disable EM4 wakeup capability. |
| * |
| * @param[in] enable |
| * Set to true to enable EM4 wakeup, set to false otherwise. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_EM4WakeupEnable(bool enable) |
| { |
| if ( enable ) { |
| RTCC->EM4WUEN = RTCC_EM4WUEN_EM4WU; |
| } else { |
| RTCC->EM4WUEN = 0; |
| } |
| } |
| #endif |
| |
| void RTCC_Enable(bool enable); |
| |
| void RTCC_Init(const RTCC_Init_TypeDef *init); |
| |
| void RTCC_ChannelInit(int ch, RTCC_CCChConf_TypeDef const *confPtr); |
| |
| /***************************************************************************//** |
| * @brief |
| * Clear one or more pending RTCC interrupts. |
| * |
| * @param[in] flags |
| * RTCC interrupt sources to clear. Use a set of interrupt flags OR-ed |
| * together to clear multiple interrupt sources. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_IntClear(uint32_t flags) |
| { |
| #if defined (RTCC_HAS_SET_CLEAR) |
| RTCC->IF_CLR = flags; |
| #else |
| RTCC->IFC = flags; |
| #endif |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Disable one or more RTCC interrupts. |
| * |
| * @param[in] flags |
| * RTCC interrupt sources to disable. Use a set of interrupt flags OR-ed |
| * together to disable multiple interrupt. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_IntDisable(uint32_t flags) |
| { |
| RTCC->IEN &= ~flags; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Enable one or more RTCC interrupts. |
| * |
| * @note |
| * Depending on the use, a pending interrupt may already be set prior to |
| * enabling the interrupt. To ignore a pending interrupt, consider using |
| * RTCC_IntClear() prior to enabling the interrupt. |
| * |
| * @param[in] flags |
| * RTCC interrupt sources to enable. Use a set of interrupt flags OR-ed |
| * together to set multiple interrupt. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_IntEnable(uint32_t flags) |
| { |
| RTCC->IEN |= flags; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Get pending RTCC interrupt flags. |
| * |
| * @note |
| * Event bits are not cleared by using this function. |
| * |
| * @return |
| * Pending RTCC interrupt sources. Returns a set of interrupt flags OR-ed |
| * together for the interrupt sources set. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_IntGet(void) |
| { |
| return RTCC->IF; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Get enabled and pending RTCC interrupt flags. |
| * |
| * @details |
| * Useful for handling more interrupt sources in the same interrupt handler. |
| * |
| * @return |
| * Pending and enabled RTCC interrupt sources. Returns a set of interrupt |
| * flags OR-ed together for the interrupt sources set. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_IntGetEnabled(void) |
| { |
| uint32_t tmp; |
| |
| tmp = RTCC->IEN; |
| |
| /* Bitwise AND of pending and enabled interrupt flags. */ |
| return RTCC->IF & tmp; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Set one or more pending RTCC interrupts from SW. |
| * |
| * @param[in] flags |
| * RTCC interrupt sources to set to pending. Use a set of interrupt flags |
| * (RTCC_IFS_nnn). |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_IntSet(uint32_t flags) |
| { |
| #if defined (RTCC_HAS_SET_CLEAR) |
| RTCC->IF_SET = flags; |
| #else |
| RTCC->IFS = flags; |
| #endif |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Lock RTCC registers. |
| * |
| * @note |
| * When RTCC registers are locked, RTCC_CTRL, RTCC_PRECNT, RTCC_CNT, |
| * RTCC_TIME, RTCC_DATE, RTCC_IEN, RTCC_POWERDOWN and RTCC_CCx_XXX registers |
| * cannot be written to. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_Lock(void) |
| { |
| #if defined(ERRATA_FIX_RTCC_E203) |
| /* RTCC_E203 - Potential Stability Issue with RTCC Registers. |
| * RTCC_LOCK register must be modified while RTCC clock is disabled. */ |
| uint32_t lfeReg = CMU->LFECLKEN0; |
| bool cmuLocked = (CMU->LOCK == CMU_LOCK_LOCKKEY_LOCKED); |
| if (cmuLocked) { |
| CMU->LOCK = CMU_LOCK_LOCKKEY_UNLOCK; |
| } |
| CMU->LFECLKEN0 = 0x0; |
| #endif |
| RTCC->LOCK = ~RTCC_LOCK_LOCKKEY_UNLOCK; |
| #if defined(ERRATA_FIX_RTCC_E203) |
| /* Restore clock state after RTCC_E203 fix. */ |
| CMU->LFECLKEN0 = lfeReg; |
| if (cmuLocked) { |
| CMU->LOCK = CMU_LOCK_LOCKKEY_LOCK; |
| } |
| #endif |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Get RTCC pre-counter value. |
| * |
| * @return |
| * Current RTCC pre-counter value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_PreCounterGet(void) |
| { |
| #if defined (RTCC_SYNCBUSY_PRECNT) |
| while ((RTCC->SYNCBUSY & RTCC_SYNCBUSY_PRECNT) != 0U) { |
| /* Wait for PRECNT to synchronize */ |
| } |
| #endif |
| return RTCC->PRECNT; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Set RTCC pre-counter value. |
| * |
| * @param[in] preCntVal |
| * RTCC pre-counter value to be set. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_PreCounterSet(uint32_t preCntVal) |
| { |
| #if defined (RTCC_SYNCBUSY_PRECNT) |
| while ((RTCC->SYNCBUSY & RTCC_SYNCBUSY_PRECNT) != 0U) { |
| /* Wait for PRECNT to synchronize */ |
| } |
| #endif |
| |
| RTCC->PRECNT = preCntVal; |
| } |
| |
| void RTCC_Reset(void); |
| |
| #if defined (_RTCC_POWERDOWN_MASK) |
| /***************************************************************************//** |
| * @brief |
| * Power down retention RAM. |
| * |
| * @note |
| * Once retention RAM is powered down, it cannot be powered up again. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_RetentionRamPowerDown(void) |
| { |
| #if !defined(ERRATA_FIX_RTCC_E204) |
| /* Devices that are affected by RTCC_E204 should always keep RTCC |
| * backup RAM retained. */ |
| RTCC->POWERDOWN = RTCC_POWERDOWN_RAM; |
| #endif |
| } |
| #endif |
| |
| void RTCC_StatusClear(void); |
| |
| /***************************************************************************//** |
| * @brief |
| * Get STATUS register value. |
| * |
| * @return |
| * Current STATUS register value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_StatusGet(void) |
| { |
| #if defined (RTCC_SYNCBUSY_CMD) |
| while ((RTCC->SYNCBUSY & RTCC_SYNCBUSY_CMD) != 0U) { |
| // Wait for synchronization. |
| } |
| #elif defined (RTCC_SYNCBUSY_START) |
| while ((RTCC->SYNCBUSY & (RTCC_SYNCBUSY_START | RTCC_SYNCBUSY_STOP)) != 0U) { |
| /* Wait for synchronization. */ |
| } |
| #endif |
| return RTCC->STATUS; |
| } |
| |
| #if defined(_SILICON_LABS_32B_SERIES_2) |
| /***************************************************************************//** |
| * @brief |
| * Wait for the RTCC to complete all synchronization of register changes |
| * and commands. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_SyncWait(void) |
| { |
| while ((RTCC->EN != 0U) && (RTCC->SYNCBUSY != 0U)) { |
| /* Wait for synchronization to finish */ |
| } |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Start RTCC counter. |
| * |
| * @detail |
| * This function will send a start command to the RTCC peripheral. The RTCC |
| * peripheral will use some LF clock ticks before the command is executed. |
| * The @ref RTCC_SyncWait() function can be used to wait for the start command |
| * to be executed. |
| * |
| * @note |
| * This function requires the RTCC to be enabled. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_Start(void) |
| { |
| RTCC_SyncWait(); |
| RTCC->CMD = RTCC_CMD_START; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Stop the RTCC counter. |
| * |
| * @detail |
| * This function will send a stop command to the RTCC peripheral. The RTCC |
| * peripheral will use some LF clock ticks before the command is executed. |
| * The @ref RTCC_SyncWait() function can be used to wait for the stop command |
| * to be executed. |
| * |
| * @note |
| * This function requires the RTCC to be enabled. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_Stop(void) |
| { |
| RTCC_SyncWait(); |
| RTCC->CMD = RTCC_CMD_STOP; |
| } |
| #endif |
| |
| #if defined (_RTCC_TIME_MASK) |
| /***************************************************************************//** |
| * @brief |
| * Get TIME register value. |
| * |
| * @return |
| * Current TIME register value. |
| ******************************************************************************/ |
| __STATIC_INLINE uint32_t RTCC_TimeGet(void) |
| { |
| return RTCC->TIME; |
| } |
| |
| /***************************************************************************//** |
| * @brief |
| * Set RTCC TIME register. |
| * |
| * @param[in] time |
| * TIME value. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_TimeSet(uint32_t time) |
| { |
| RTCC->TIME = time; |
| } |
| #endif |
| |
| /***************************************************************************//** |
| * @brief |
| * Unlock RTCC registers. |
| * |
| * @note |
| * When RTCC registers are locked, RTCC_CTRL, RTCC_PRECNT, RTCC_CNT, |
| * RTCC_TIME, RTCC_DATE, RTCC_IEN, RTCC_POWERDOWN and RTCC_CCx_XXX registers |
| * cannot be written to. |
| ******************************************************************************/ |
| __STATIC_INLINE void RTCC_Unlock(void) |
| { |
| #if defined(ERRATA_FIX_RTCC_E203) |
| /* RTCC_E203 - Potential Stability Issue with RTCC Registers. |
| * RTCC_LOCK register must be modified while RTCC clock is disabled. */ |
| uint32_t lfeReg = CMU->LFECLKEN0; |
| bool cmuLocked = (CMU->LOCK == CMU_LOCK_LOCKKEY_LOCKED); |
| if (cmuLocked) { |
| CMU->LOCK = CMU_LOCK_LOCKKEY_UNLOCK; |
| } |
| CMU->LFECLKEN0 = 0x0; |
| #endif |
| RTCC->LOCK = RTCC_LOCK_LOCKKEY_UNLOCK; |
| #if defined(ERRATA_FIX_RTCC_E203) |
| /* Restore clock state after RTCC_E203 fix. */ |
| CMU->LFECLKEN0 = lfeReg; |
| if (cmuLocked) { |
| CMU->LOCK = CMU_LOCK_LOCKKEY_LOCK; |
| } |
| #endif |
| } |
| |
| /** @} (end addtogroup RTCC) */ |
| /** @} (end addtogroup emlib) */ |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* defined( RTCC_COUNT ) && ( RTC_COUNT == 1 ) */ |
| #endif /* EM_RTCC_H */ |