/***************************************************************************//**
* @file
* @brief System Real Time Counter (SYSRTC) peripheral API
*******************************************************************************
* # License
* Copyright 2020 Silicon Laboratories Inc. www.silabs.com
*******************************************************************************
*
* SPDX-License-Identifier: Zlib
*
* The licensor of this software is Silicon Laboratories Inc.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* 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. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 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.
*
******************************************************************************/
#ifndef PERIPHERAL_SYSRTC_H
#define PERIPHERAL_SYSRTC_H
#include "em_device.h"
#if defined(SYSRTC_COUNT) && (SYSRTC_COUNT > 0)
#include
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup sysrtc
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/// Minimum compare channels for SYSRTC group.
#define SYSRTC_GROUP_MIN_CHANNEL_COMPARE 1u
/// Maximum compare channels for SYSRTC group.
#define SYSRTC_GROUP_MAX_CHANNEL_COMPARE 2u
/// Minimum capture channels for SYSRTC group.
#define SYSRTC_GROUP_MIN_CHANNEL_CAPTURE 0u
/// Maximum capture channels for SYSRTC group.
#define SYSRTC_GROUP_MAX_CHANNEL_CAPTURE 1u
/// Sysrtc group number.
#ifdef _SILICON_LABS_32B_SERIES_2
#if !defined(SYSRTC_GROUP_NUMBER)
#define SYSRTC_GROUP_NUMBER 1u
#endif
#endif
/// Validation of valid SYSRTC group for assert statements.
#define SYSRTC_GROUP_VALID(group) ((unsigned)(group) < SYSRTC_GROUP_NUMBER)
/*******************************************************************************
********************************* ENUM ************************************
******************************************************************************/
/// Capture input edge select.
typedef enum {
SL_SYSRTC_CAPTURE_EDGE_RISING = 0, ///< Rising edges detected.
SL_SYSRTC_CAPTURE_EDGE_FALLING, ///< Falling edges detected.
SL_SYSRTC_CAPTURE_EDGE_BOTH ///< Both edges detected.
} sl_sysrtc_capture_edge_t;
/// Compare match output action mode.
typedef enum {
SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CLEAR = 0, ///< Clear output.
SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_SET, ///< Set output.
SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_PULSE, ///< Generate a pulse.
SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_TOGGLE, ///< Toggle output.
SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CMPIF ///< Export CMPIF.
} sl_sysrtc_compare_match_out_action_t;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/// SYSRTC configuration structure.
typedef struct {
bool enable_debug_run; ///< Counter shall keep running during debug halt.
} sl_sysrtc_config_t;
/// Suggested default values for SYSRTC configuration structure.
#define SYSRTC_CONFIG_DEFAULT \
{ \
false, /* Disable updating during debug halt. */ \
}
/// Compare channel configuration structure.
typedef struct {
sl_sysrtc_compare_match_out_action_t compare_match_out_action; ///< Compare mode channel match output action.
} sl_sysrtc_group_channel_compare_config_t;
/// Capture channel configuration structure.
typedef struct {
sl_sysrtc_capture_edge_t capture_input_edge; ///< Capture mode channel input edge.
} sl_sysrtc_group_channel_capture_config_t;
/// Group configuration structure.
typedef struct {
bool compare_channel0_enable; ///< Enable/Disable compare channel 0
bool compare_channel1_enable; ///< Enable/Disable compare channel 1
bool capture_channel0_enable; ///< Enable/Disable capture channel 0
sl_sysrtc_group_channel_compare_config_t const *p_compare_channel0_config; ///< Pointer to compare channel 0 config
sl_sysrtc_group_channel_compare_config_t const *p_compare_channel1_config; ///< Pointer to compare channel 1 config
sl_sysrtc_group_channel_capture_config_t const *p_capture_channel0_config; ///< Pointer to capture channel 0 config
} sl_sysrtc_group_config_t;
/// Suggested default values for compare channel configuration structure.
#define SYSRTC_GROUP_CHANNEL_COMPARE_CONFIG_DEFAULT \
{ \
SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_PULSE \
}
/// Compare channel configuration for starting HFXO using PRS.
#define SYSRTC_GROUP_CHANNEL_COMPARE_CONFIG_EARLY_WAKEUP \
{ \
SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CMPIF \
}
/// Suggested default values for capture channel configuration structure.
#define SYSRTC_GROUP_CHANNEL_CAPTURE_CONFIG_DEFAULT \
{ \
SL_SYSRTC_CAPTURE_EDGE_RISING \
}
/// Suggested default values for SYSRTC group configuration structure.
#define SYSRTC_GROUP_CONFIG_DEFAULT \
{ \
true, /* Enable compare channel 0. */ \
false, /* Disable compare channel 1. */ \
false, /* Disable capture channel 0. */ \
NULL, /* NULL Pointer to configuration structure for compare channel 0*/ \
NULL, /* NULL Pointer to configuration structure for compare channel 1*/ \
NULL /* NULL Pointer to configuration structure for capture channel 0*/ \
}
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/***************************************************************************//**
* Initializes SYSRTC module.
*
* Note that the compare values must be set separately with
* (sl_sysrtc_set_group_compare_channel_value()), which should probably be
* done prior to the use of this function if configuring the SYSRTC to start
* when initialization is completed.
*
* @param[in] p_config A pointer to the SYSRTC initialization structure
* variable.
******************************************************************************/
void sl_sysrtc_init(const sl_sysrtc_config_t *p_config);
/***************************************************************************//**
* Enables SYSRTC counting.
******************************************************************************/
void sl_sysrtc_enable(void);
/***************************************************************************//**
* Disables SYSRTC counting.
******************************************************************************/
void sl_sysrtc_disable(void);
/***************************************************************************//**
* Waits for the SYSRTC to complete all synchronization of register changes
* and commands.
******************************************************************************/
__STATIC_INLINE void sl_sysrtc_wait_sync(void)
{
while ((SYSRTC0->EN & SYSRTC_EN_EN) && (SYSRTC0->SYNCBUSY != 0U)) {
// Wait for all synchronizations to finish
}
}
/***************************************************************************//**
* Waits for the SYSRTC to complete reseting or disabling procedure.
******************************************************************************/
__STATIC_INLINE void sl_sysrtc_wait_ready(void)
{
while ((SYSRTC0->SWRST & _SYSRTC_SWRST_RESETTING_MASK) || (SYSRTC0->EN & _SYSRTC_EN_DISABLING_MASK) || (SYSRTC0->SYNCBUSY != 0U)) {
// Wait for all synchronizations to finish
}
}
/***************************************************************************//**
* Starts SYSRTC counter.
*
* This function will send a start command to the SYSRTC peripheral. The SYSRTC
* peripheral will use some LF clock ticks before the command is executed.
* The sl_sysrtc_wait_sync() function can be used to wait for the start
* command to be executed.
*
* @note This function requires the SYSRTC to be enabled.
******************************************************************************/
__STATIC_INLINE void sl_sysrtc_start(void)
{
sl_sysrtc_wait_sync();
SYSRTC0->CMD = SYSRTC_CMD_START;
}
/***************************************************************************//**
* Stops the SYSRTC counter.
*
* This function will send a stop command to the SYSRTC peripheral. The SYSRTC
* peripheral will use some LF clock ticks before the command is executed.
* The sl_sysrtc_wait_sync() function can be used to wait for the stop
* command to be executed.
*
* @note This function requires the SYSRTC to be enabled.
******************************************************************************/
__STATIC_INLINE void sl_sysrtc_stop(void)
{
sl_sysrtc_wait_sync();
SYSRTC0->CMD = SYSRTC_CMD_STOP;
}
/***************************************************************************//**
* Restores SYSRTC to its reset state.
******************************************************************************/
void sl_sysrtc_reset(void);
/***************************************************************************//**
* Gets SYSRTC STATUS register value.
*
* @return Current STATUS register value.
******************************************************************************/
__STATIC_INLINE uint32_t sl_sysrtc_get_status(void)
{
return SYSRTC0->STATUS;
}
/***************************************************************************//**
* Locks SYSRTC registers.
*
* @note When SYSRTC registers are locked SYSRTC_EN, SYSRTC_CFG, SYSRTC_CMD,
* SYSRTC_SWRST, SYSRTC_CNT and SYSRTC_TOPCNT registers cannot be written
* to.
******************************************************************************/
__STATIC_INLINE void sl_sysrtc_lock(void)
{
SYSRTC0->LOCK = ~SYSRTC_LOCK_LOCKKEY_UNLOCK;
}
/***************************************************************************//**
* Unlocks SYSRTC registers.
*
* @note When SYSRTC registers are locked SYSRTC_EN, SYSRTC_CFG, SYSRTC_CMD,
* SYSRTC_SWRST, SYSRTC_CNT and SYSRTC_TOPCNT registers cannot be written
* to.
******************************************************************************/
__STATIC_INLINE void sl_sysrtc_unlock(void)
{
SYSRTC0->LOCK = SYSRTC_LOCK_LOCKKEY_UNLOCK;
}
/***************************************************************************//**
* Gets SYSRTC counter value.
*
* @return Current SYSRTC counter value.
******************************************************************************/
__STATIC_INLINE uint32_t sl_sysrtc_get_counter(void)
{
// Wait for Counter to synchronize before getting value
sl_sysrtc_wait_sync();
return SYSRTC0->CNT;
}
/***************************************************************************//**
* Sets the SYSRTC counter value.
*
* @param[in] value The new SYSRTC counter value.
******************************************************************************/
__STATIC_INLINE void sl_sysrtc_set_counter(uint32_t value)
{
// Wait for Counter to synchronize before getting value
sl_sysrtc_wait_sync();
SYSRTC0->CNT = value;
}
/***************************************************************************//**
* Initializes the selected SYSRTC group.
*
* @param[in] group_number SYSRTC group number to use.
*
* @param[in] p_group_config Pointer to group configuration structure
* variable.
******************************************************************************/
void sl_sysrtc_init_group(uint8_t group_number,
sl_sysrtc_group_config_t const *p_group_config);
/***************************************************************************//**
* Enables one or more SYSRTC interrupts for the given group.
*
* @note Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. To ignore a pending interrupt, consider using
* sl_sysrtc_clear_group_interrupts() prior to enabling the interrupt.
*
* @param[in] group_number SYSRTC group number to use.
*
* @param[in] flags SYSRTC interrupt sources to enable.
* Use a set of interrupt flags OR-ed together to set
* multiple interrupt sources for the given SYSRTC group.
******************************************************************************/
void sl_sysrtc_enable_group_interrupts(uint8_t group_number,
uint32_t flags);
/***************************************************************************//**
* Disables one or more SYSRTC interrupts for the given group.
*
* @param[in] group_number SYSRTC group number to use.
*
* @param[in] flags SYSRTC interrupt sources to disable.
* Use a set of interrupt flags OR-ed together to disable
* multiple interrupt sources for the given SYSRTC group.
******************************************************************************/
void sl_sysrtc_disable_group_interrupts(uint8_t group_number,
uint32_t flags);
/***************************************************************************//**
* Clears one or more pending SYSRTC interrupts for the given group.
*
* @param[in] group_number SYSRTC group number to use.
*
* @param[in] flags SYSRTC interrupt sources to clear.
* Use a set of interrupt flags OR-ed together to clear
* multiple interrupt sources for the given SYSRTC group.
******************************************************************************/
void sl_sysrtc_clear_group_interrupts(uint8_t group_number,
uint32_t flags);
/***************************************************************************//**
* Gets pending SYSRTC interrupt flags for the given group.
*
* @note Event bits are not cleared by using this function.
*
* @param[in] group_number SYSRTC group number to use.
*
* @return Pending SYSRTC interrupt sources.
* Returns a set of interrupt flags OR-ed together for multiple
* interrupt sources in the SYSRTC group.
******************************************************************************/
uint32_t sl_sysrtc_get_group_interrupts(uint8_t group_number);
/***************************************************************************//**
* Gets enabled and pending SYSRTC interrupt flags.
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @note Interrupt flags are not cleared by using this function.
*
* @param[in] group_number SYSRTC group number to use.
*
* @return Pending and enabled SYSRTC interrupt sources.
* The return value is the bitwise AND of
* - the enabled interrupt sources in SYSRTC_GRPx_IEN and
* - the pending interrupt flags SYSRTC_GRPx_IF.
******************************************************************************/
uint32_t sl_sysrtc_get_group_enabled_interrupts(uint8_t group_number);
/***************************************************************************//**
* Sets one or more pending SYSRTC interrupts for the given group from Software.
*
* @param[in] group_number SYSRTC group number to use.
*
* @param[in] flags SYSRTC interrupt sources to set to pending.
* Use a set of interrupt flags OR-ed together to set
* multiple interrupt sources for the SYSRTC group.
******************************************************************************/
void sl_sysrtc_set_group_interrupts(uint8_t group_number,
uint32_t flags);
/***************************************************************************//**
* Gets SYSRTC compare register value for selected channel of given group.
*
* @param[in] group_number SYSRTC group number to use.
*
* @param[in] channel Channel selector.
*
* @return Compare register value.
******************************************************************************/
uint32_t sl_sysrtc_get_group_compare_channel_value(uint8_t group_number,
uint8_t channel);
/***************************************************************************//**
* Sets SYSRTC compare register value for selected channel of given group.
*
* @param[in] group_number SYSRTC group number to use.
*
* @param[in] channel Channel selector.
*
* @param[in] value Compare register value.
******************************************************************************/
void sl_sysrtc_set_group_compare_channel_value(uint8_t group_number,
uint8_t channel,
uint32_t value);
/***************************************************************************//**
* Gets SYSRTC input capture register value for capture channel of given group.
*
* @param[in] group_number SYSRTC group number to use.
*
* @return Capture register value.
******************************************************************************/
uint32_t sl_sysrtc_get_group_capture_channel_value(uint8_t group_number);
/** @} (end addtogroup sysrtc) */
#ifdef __cplusplus
}
#endif
#endif /* defined(SYSRTC_COUNT) && (SYSRTC_COUNT > 0) */
#endif /* PERIPHERAL_SYSRTC_H */