Initial commit of firmware

This commit is contained in:
2025-04-12 13:30:57 +01:00
commit 264a3462e0
374 changed files with 332649 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,36 @@
/***************************************************************************//**
* @file
* @brief Emlib peripheral API "assert" implementation.
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_ASSERT_H
#define EM_ASSERT_H
#include "sl_assert.h"
#endif /* EM_ASSERT_H */

View File

@@ -0,0 +1,473 @@
/***************************************************************************//**
* @file
* @brief Backup Real Time Counter (BURTC) peripheral API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_BURTC_H
#define EM_BURTC_H
#include "em_device.h"
#if defined(BURTC_PRESENT)
#include <stdbool.h>
#include "sl_assert.h"
#include "em_bus.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup burtc
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** BURTC clock divisors. These values are valid for the BURTC prescaler. */
#define burtcClkDiv_1 1 /**< Divide clock by 1. */
#define burtcClkDiv_2 2 /**< Divide clock by 2. */
#define burtcClkDiv_4 4 /**< Divide clock by 4. */
#define burtcClkDiv_8 8 /**< Divide clock by 8. */
#define burtcClkDiv_16 16 /**< Divide clock by 16. */
#define burtcClkDiv_32 32 /**< Divide clock by 32. */
#define burtcClkDiv_64 64 /**< Divide clock by 64. */
#define burtcClkDiv_128 128 /**< Divide clock by 128. */
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
#if defined(_SILICON_LABS_32B_SERIES_0)
/** BURTC clock selection. */
typedef enum {
/** Ultra low frequency (1 kHz) clock. */
burtcClkSelULFRCO = BURTC_CTRL_CLKSEL_ULFRCO,
/** Low frequency RC oscillator. */
burtcClkSelLFRCO = BURTC_CTRL_CLKSEL_LFRCO,
/** Low frequency crystal oscillator. */
burtcClkSelLFXO = BURTC_CTRL_CLKSEL_LFXO
} BURTC_ClkSel_TypeDef;
/** BURTC mode of operation. */
typedef enum {
/** Disable BURTC */
burtcModeDisable = BURTC_CTRL_MODE_DISABLE,
/** Enable and start BURTC counter in EM0 to EM2. */
burtcModeEM2 = BURTC_CTRL_MODE_EM2EN,
/** Enable and start BURTC counter in EM0 to EM3. */
burtcModeEM3 = BURTC_CTRL_MODE_EM3EN,
/** Enable and start BURTC counter in EM0 to EM4. */
burtcModeEM4 = BURTC_CTRL_MODE_EM4EN,
} BURTC_Mode_TypeDef;
/** BURTC low power mode. */
typedef enum {
/** Low Power Mode is disabled. */
burtcLPDisable = BURTC_LPMODE_LPMODE_DISABLE,
/** Low Power Mode is always enabled. */
burtcLPEnable = BURTC_LPMODE_LPMODE_ENABLE,
/** Low Power Mode when system enters backup mode. */
burtcLPBU = BURTC_LPMODE_LPMODE_BUEN
} BURTC_LP_TypeDef;
#endif
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
#if defined(_SILICON_LABS_32B_SERIES_0)
/** BURTC initialization structure for Series 0 devices. */
typedef struct {
bool enable; /**< Enable BURTC after initialization (starts counter). */
BURTC_Mode_TypeDef mode; /**< Configure energy mode operation. */
bool debugRun; /**< If true, counter will keep running under debug halt. */
BURTC_ClkSel_TypeDef clkSel; /**< Select clock source. */
uint32_t clkDiv; /**< Clock divider; for ULFRCO 1Khz or 2kHz operation. */
uint32_t lowPowerComp; /**< Number of least significant clock bits to ignore in low power mode. */
bool timeStamp; /**< Enable time stamp on entering backup power domain. */
bool compare0Top; /**< Set if Compare Value 0 is also top value (counter restart). */
BURTC_LP_TypeDef lowPowerMode; /**< Low power operation mode, requires LFXO or LFRCO. */
} BURTC_Init_TypeDef;
/** Default configuration for BURTC initialization structure. */
#define BURTC_INIT_DEFAULT \
{ \
true, \
burtcModeEM2, \
false, \
burtcClkSelULFRCO, \
burtcClkDiv_1, \
0, \
true, \
false, \
burtcLPDisable, \
}
#elif defined(_SILICON_LABS_32B_SERIES_2)
/** BURTC initialization structure for Series 2 devices. */
typedef struct {
bool start; /**< Start BURTC after initialization */
bool debugRun; /**< If true, counter will keep running under debug halt */
uint32_t clkDiv; /**< Clock divider. Supported range is 1-32768 */
bool compare0Top; /**< Set if Compare Value 0 is also top value (counter restart) */
bool em4comp; /**< Enable EM4 wakeup on compare match. */
bool em4overflow; /**< Enable EM4 wakeup on counter overflow. */
} BURTC_Init_TypeDef;
/** Default configuration for BURTC init structure */
#define BURTC_INIT_DEFAULT \
{ \
true, \
false, \
1, \
0, \
false, \
false, \
}
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Clear one or more pending BURTC interrupts.
*
* @param[in] flags
* BURTC interrupt sources to clear. Use a set of interrupt flags OR-ed
* together to clear multiple interrupt sources for the BURTC module
* (BURTC_IFS_nnn).
******************************************************************************/
__STATIC_INLINE void BURTC_IntClear(uint32_t flags)
{
#if defined(BURTC_HAS_SET_CLEAR)
BURTC->IF_CLR = flags;
#else
BURTC->IFC = flags;
#endif
}
/***************************************************************************//**
* @brief
* Disable one or more BURTC interrupts.
*
* @param[in] flags
* BURTC interrupt sources to disable. Use a set of interrupt flags OR-ed
* together to disable multiple interrupt sources for the BURTC module
* (BURTC_IFS_nnn).
******************************************************************************/
__STATIC_INLINE void BURTC_IntDisable(uint32_t flags)
{
#if defined(BURTC_HAS_SET_CLEAR)
BURTC->IEN_CLR = flags;
#else
BURTC->IEN &= ~(flags);
#endif
}
/***************************************************************************//**
* @brief
* Enable one or more BURTC interrupts.
*
* @note
* Depending on use, a pending interrupt may already be set prior to
* enabling the interrupt. Consider using BURTC_IntClear() prior to enabling
* if a pending interrupt should be ignored.
*
* @param[in] flags
* BURTC interrupt sources to enable. Use a set of interrupt flags OR-ed
* together to set multiple interrupt sources for the BURTC module
* (BURTC_IFS_nnn).
******************************************************************************/
__STATIC_INLINE void BURTC_IntEnable(uint32_t flags)
{
#if defined(BURTC_HAS_SET_CLEAR)
BURTC->IEN_SET = flags;
#else
BURTC->IEN |= flags;
#endif
}
/***************************************************************************//**
* @brief
* Get pending BURTC interrupt flags.
*
* @note
* This function does not clear the event bits.
*
* @return
* Pending BURTC interrupt sources. Returns a set of interrupt flags OR-ed
* together for multiple interrupt sources in the BURTC module (BURTC_IFS_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t BURTC_IntGet(void)
{
return BURTC->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending BURTC interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @return
* Pending BURTC interrupt sources that is also enabled. Returns a set of
* interrupt flags OR-ed together for multiple interrupt sources in the
* BURTC module (BURTC_IFS_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t BURTC_IntGetEnabled(void)
{
uint32_t tmp;
/* Get enabled interrupts */
tmp = BURTC->IEN;
/* Return set interrupts */
return BURTC->IF & tmp;
}
/***************************************************************************//**
* @brief
* Set one or more pending BURTC interrupts from SW.
*
* @param[in] flags
* BURTC interrupt sources to set to pending. Use a set of interrupt flags
* OR-ed together to set multiple interrupt sources for the BURTC module
* (BURTC_IFS_nnn).
******************************************************************************/
__STATIC_INLINE void BURTC_IntSet(uint32_t flags)
{
#if defined(BURTC_HAS_SET_CLEAR)
BURTC->IF_SET = flags;
#else
BURTC->IFS = flags;
#endif
}
/***************************************************************************//**
* @brief
* Status of BURTC RAM, timestamp and LP Mode
*
* @return A mask logically OR-ed status bits
******************************************************************************/
__STATIC_INLINE uint32_t BURTC_Status(void)
{
return BURTC->STATUS;
}
#if defined(BURTC_CMD_CLRSTATUS)
/***************************************************************************//**
* @brief
* Clear and reset BURTC status register
******************************************************************************/
__STATIC_INLINE void BURTC_StatusClear(void)
{
BURTC->CMD = BURTC_CMD_CLRSTATUS;
}
#endif
/***************************************************************************//**
* @brief
* Wait for the BURTC to complete all synchronization of register changes
* and commands.
******************************************************************************/
__STATIC_INLINE void BURTC_SyncWait(void)
{
#if defined(_SILICON_LABS_32B_SERIES_2)
while ((BURTC->EN != 0U) && (BURTC->SYNCBUSY != 0U)) {
/* Wait for previous synchronization to finish */
}
#else
while (BURTC->SYNCBUSY != 0U) {
/* Wait for previous synchronization to finish */
}
#endif
}
#if defined(_SILICON_LABS_32B_SERIES_2)
/***************************************************************************//**
* @brief
* Start BURTC counter.
*
* This function will send a start command to the BURTC peripheral. The BURTC
* peripheral will use some LF clock ticks before the command is executed.
* The @ref BURTC_SyncWait() function can be used to wait for the start command
* to be executed.
*
* @note
* This function requires the BURTC to be enabled.
******************************************************************************/
__STATIC_INLINE void BURTC_Start(void)
{
BURTC_SyncWait();
BURTC->CMD = BURTC_CMD_START;
}
/***************************************************************************//**
* @brief
* Stop the BURTC counter.
*
* This function will send a stop command to the BURTC peripheral. The BURTC
* peripheral will use some LF clock ticks before the command is executed.
* The @ref BURTC_SyncWait() function can be used to wait for the stop command
* to be executed.
*
* @note
* This function requires the BURTC to be enabled.
******************************************************************************/
__STATIC_INLINE void BURTC_Stop(void)
{
BURTC_SyncWait();
BURTC->CMD = BURTC_CMD_STOP;
}
#endif
/***************************************************************************//**
* @brief Get BURTC counter.
*
* @return
* BURTC counter value
******************************************************************************/
__STATIC_INLINE uint32_t BURTC_CounterGet(void)
{
return BURTC->CNT;
}
#if defined(_SILICON_LABS_32B_SERIES_0)
/***************************************************************************//**
* @brief Get BURTC timestamp for entering BU.
*
* @return
* BURTC Time Stamp value
******************************************************************************/
__STATIC_INLINE uint32_t BURTC_TimestampGet(void)
{
return BURTC->TIMESTAMP;
}
/***************************************************************************//**
* @brief Freeze register updates until enabled.
* @param[in] enable If true, registers are not updated until enabled again.
******************************************************************************/
__STATIC_INLINE void BURTC_FreezeEnable(bool enable)
{
BUS_RegBitWrite(&BURTC->FREEZE, _BURTC_FREEZE_REGFREEZE_SHIFT, enable);
}
/***************************************************************************//**
* @brief Shut down power to retention register bank.
* @param[in] enable
* If true, shuts off power to retention registers.
* @note
* When power retention is disabled, it can't be enabled again (until
* reset).
******************************************************************************/
__STATIC_INLINE void BURTC_Powerdown(bool enable)
{
BUS_RegBitWrite(&BURTC->POWERDOWN, _BURTC_POWERDOWN_RAM_SHIFT, enable);
}
/***************************************************************************//**
* @brief
* Set a value in one of the retention registers.
*
* @param[in] num
* Register to set
* @param[in] data
* Value to put into register
******************************************************************************/
__STATIC_INLINE void BURTC_RetRegSet(uint32_t num, uint32_t data)
{
EFM_ASSERT(num <= 127);
BURTC->RET[num].REG = data;
}
/***************************************************************************//**
* @brief
* Read a value from one of the retention registers.
*
* @param[in] num
* Retention Register to read
*
* @return
* Value of the retention register
******************************************************************************/
__STATIC_INLINE uint32_t BURTC_RetRegGet(uint32_t num)
{
EFM_ASSERT(num <= 127);
return BURTC->RET[num].REG;
}
#endif
/***************************************************************************//**
* @brief
* Lock BURTC registers, which will protect from writing new config settings.
******************************************************************************/
__STATIC_INLINE void BURTC_Lock(void)
{
BURTC->LOCK = 0x0;
}
/***************************************************************************//**
* @brief
* Unlock BURTC registers, which will enable write access to change configuration.
******************************************************************************/
__STATIC_INLINE void BURTC_Unlock(void)
{
BURTC->LOCK = BURTC_LOCK_LOCKKEY_UNLOCK;
}
void BURTC_Reset(void);
void BURTC_Init(const BURTC_Init_TypeDef *burtcInit);
void BURTC_Enable(bool enable);
void BURTC_CounterReset(void);
void BURTC_CompareSet(unsigned int comp, uint32_t value);
uint32_t BURTC_CompareGet(unsigned int comp);
#if defined(_BURTC_CTRL_MASK)
uint32_t BURTC_ClockFreqGet(void);
#endif
/** @} (end addtogroup burtc) */
#ifdef __cplusplus
}
#endif
#endif /* BURTC_PRESENT */
#endif /* EM_BURTC_H */

View File

@@ -0,0 +1,350 @@
/***************************************************************************//**
* @file
* @brief RAM and peripheral bit-field set and clear API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_BUS_H
#define EM_BUS_H
#include "sl_assert.h"
#include "sl_core.h"
#include "em_device.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup bus BUS - Bitfield Read/Write
* @brief BUS register and RAM bit/field read/write API
* @details
* API to perform bit-band and field set/clear access to RAM and peripherals.
* @{
******************************************************************************/
/***************************************************************************//**
* @brief
* Perform a single-bit write operation on a 32-bit word in RAM.
*
* @details
* This function uses Cortex-M bit-banding hardware to perform an atomic
* read-modify-write operation on a single bit write on a 32-bit word in RAM.
* See the reference manual for more details about bit-banding.
*
* @note
* This function is atomic on Cortex-M cores with bit-banding support. Bit-
* banding is a multi cycle read-modify-write bus operation. RAM bit-banding is
* performed using the memory alias region at BITBAND_RAM_BASE.
*
* @param[in] addr An ddress of a 32-bit word in RAM.
*
* @param[in] bit A bit position to write, 0-31.
*
* @param[in] val A value to set bit to, 0 or 1.
******************************************************************************/
__STATIC_INLINE void BUS_RamBitWrite(volatile uint32_t *addr,
unsigned int bit,
unsigned int val)
{
#if defined(BITBAND_RAM_BASE)
uint32_t aliasAddr =
BITBAND_RAM_BASE + (((uint32_t)addr - SRAM_BASE) * (uint32_t) 32) + (bit * (uint32_t) 4);
*(volatile uint32_t *)aliasAddr = (uint32_t)val;
#else
uint32_t tmp = *addr;
/* Make sure val is not more than 1 because only one bit needs to be set. */
*addr = (tmp & ~(1UL << bit)) | ((val & 1UL) << bit);
#endif
}
/***************************************************************************//**
* @brief
* Perform a single-bit read operation on a 32-bit word in RAM.
*
* @details
* This function uses Cortex-M bit-banding hardware to perform an atomic
* read operation on a single register bit. See the
* reference manual for more details about bit-banding.
*
* @note
* This function is atomic on Cortex-M cores with bit-banding support.
* RAM bit-banding is performed using the memory alias region
* at BITBAND_RAM_BASE.
*
* @param[in] addr RAM address.
*
* @param[in] bit A bit position to read, 0-31.
*
* @return
* The requested bit shifted to bit position 0 in the return value.
******************************************************************************/
__STATIC_INLINE unsigned int BUS_RamBitRead(volatile const uint32_t *addr,
unsigned int bit)
{
#if defined(BITBAND_RAM_BASE)
uint32_t aliasAddr =
BITBAND_RAM_BASE + (((uint32_t)addr - SRAM_BASE) * (uint32_t) 32) + (bit * (uint32_t) 4);
return *(volatile uint32_t *)aliasAddr;
#else
return ((*addr) >> bit) & 1UL;
#endif
}
/***************************************************************************//**
* @brief
* Perform a single-bit write operation on a peripheral register.
*
* @details
* This function uses Cortex-M bit-banding hardware to perform an atomic
* read-modify-write operation on a single register bit. See the
* reference manual for more details about bit-banding.
*
* @note
* This function is atomic on Cortex-M cores with bit-banding support. Bit-
* banding is a multi cycle read-modify-write bus operation. Peripheral register
* bit-banding is performed using the memory alias region at BITBAND_PER_BASE.
*
* @param[in] addr A peripheral register address.
*
* @param[in] bit A bit position to write, 0-31.
*
* @param[in] val A value to set bit to, 0 or 1.
******************************************************************************/
__STATIC_INLINE void BUS_RegBitWrite(volatile uint32_t *addr,
unsigned int bit,
unsigned int val)
{
EFM_ASSERT(bit < 32U);
#if defined(PER_REG_BLOCK_SET_OFFSET) && defined(PER_REG_BLOCK_CLR_OFFSET)
uint32_t aliasAddr;
if (val != 0U) {
aliasAddr = (uint32_t)addr + PER_REG_BLOCK_SET_OFFSET;
} else {
aliasAddr = (uint32_t)addr + PER_REG_BLOCK_CLR_OFFSET;
}
*(volatile uint32_t *)aliasAddr = 1UL << bit;
#elif defined(BITBAND_PER_BASE)
uint32_t aliasAddr =
BITBAND_PER_BASE + (((uint32_t)addr - PER_MEM_BASE) * (uint32_t) 32) + (bit * (uint32_t) 4);
*(volatile uint32_t *)aliasAddr = (uint32_t)val;
#else
uint32_t tmp = *addr;
/* Make sure val is not more than 1 because only one bit needs to be set. */
*addr = (tmp & ~(1 << bit)) | ((val & 1) << bit);
#endif
}
/***************************************************************************//**
* @brief
* Perform a single-bit read operation on a peripheral register.
*
* @details
* This function uses Cortex-M bit-banding hardware to perform an atomic
* read operation on a single register bit. See the
* reference manual for more details about bit-banding.
*
* @note
* This function is atomic on Cortex-M cores with bit-banding support.
* Peripheral register bit-banding is performed using the memory alias
* region at BITBAND_PER_BASE.
*
* @param[in] addr A peripheral register address.
*
* @param[in] bit A bit position to read, 0-31.
*
* @return
* The requested bit shifted to bit position 0 in the return value.
******************************************************************************/
__STATIC_INLINE unsigned int BUS_RegBitRead(volatile const uint32_t *addr,
unsigned int bit)
{
#if defined(BITBAND_PER_BASE)
uint32_t aliasAddr =
BITBAND_PER_BASE + (((uint32_t)addr - PER_MEM_BASE) * (uint32_t)32) + (bit * (uint32_t) 4);
return *(volatile uint32_t *)aliasAddr;
#else
return ((*addr) >> bit) & 1UL;
#endif
}
/***************************************************************************//**
* @brief
* Perform a masked set operation on a peripheral register address.
*
* @details
* A peripheral register masked set provides a single-cycle and atomic set
* operation of a bit-mask in a peripheral register. All 1s in the mask are
* set to 1 in the register. All 0s in the mask are not changed in the
* register.
* RAMs and special peripherals are not supported. See the
* reference manual for more details about the peripheral register field set.
*
* @note
* This function is single-cycle and atomic on cores with peripheral bit set
* and clear support. It uses the memory alias region at PER_BITSET_MEM_BASE.
*
* @param[in] addr A peripheral register address.
*
* @param[in] mask A mask to set.
******************************************************************************/
__STATIC_INLINE void BUS_RegMaskedSet(volatile uint32_t *addr,
uint32_t mask)
{
#if defined(PER_REG_BLOCK_SET_OFFSET)
uint32_t aliasAddr = (uint32_t)addr + PER_REG_BLOCK_SET_OFFSET;
*(volatile uint32_t *)aliasAddr = mask;
#elif defined(PER_BITSET_MEM_BASE)
uint32_t aliasAddr = PER_BITSET_MEM_BASE + ((uint32_t)addr - PER_MEM_BASE);
*(volatile uint32_t *)aliasAddr = mask;
#else
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
*addr |= mask;
CORE_EXIT_CRITICAL();
#endif
}
/***************************************************************************//**
* @brief
* Perform a masked clear operation on the peripheral register address.
*
* @details
* A peripheral register masked clear provides a single-cycle and atomic clear
* operation of a bit-mask in a peripheral register. All 1s in the mask are
* set to 0 in the register.
* All 0s in the mask are not changed in the register.
* RAMs and special peripherals are not supported. See the
* reference manual for more details about the peripheral register field clear.
*
* @note
* This function is single-cycle and atomic on cores with peripheral bit set
* and clear support. It uses the memory alias region at PER_BITCLR_MEM_BASE.
*
* @param[in] addr A peripheral register address.
*
* @param[in] mask A mask to clear.
******************************************************************************/
__STATIC_INLINE void BUS_RegMaskedClear(volatile uint32_t *addr,
uint32_t mask)
{
#if defined(PER_REG_BLOCK_CLR_OFFSET)
uint32_t aliasAddr = (uint32_t)addr + PER_REG_BLOCK_CLR_OFFSET;
*(volatile uint32_t *)aliasAddr = mask;
#elif defined(PER_BITCLR_MEM_BASE)
uint32_t aliasAddr = PER_BITCLR_MEM_BASE + ((uint32_t)addr - PER_MEM_BASE);
*(volatile uint32_t *)aliasAddr = mask;
#else
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
*addr &= ~mask;
CORE_EXIT_CRITICAL();
#endif
}
/***************************************************************************//**
* @brief
* Perform peripheral register masked write.
*
* @details
* This function first reads the peripheral register and updates only bits
* that are set in the mask with content of val. Typically, the mask is a
* bit-field in the register and the value val is within the mask.
*
* @note
* The read-modify-write operation is executed in a critical section to
* guarantee atomicity. Note that atomicity can only be guaranteed if register
* is modified only by the core, and not by other peripherals (like DMA).
*
* @param[in] addr A peripheral register address.
*
* @param[in] mask A peripheral register mask.
*
* @param[in] val A peripheral register value. The value must be shifted to the
correct bit position in the register corresponding to the field
defined by the mask parameter. The register value must be
contained in the field defined by the mask parameter. The
register value is masked to prevent involuntary spillage.
******************************************************************************/
#if defined(__GNUC__) && __GNUC__ >= 10
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wanalyzer-null-dereference"
#endif
__STATIC_INLINE void BUS_RegMaskedWrite(volatile uint32_t *addr,
uint32_t mask,
uint32_t val)
{
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
EFM_ASSERT(addr != 0);
*addr = (*addr & ~mask) | (val & mask);
CORE_EXIT_CRITICAL();
}
#if defined(__GNUC__) && __GNUC__ >= 10
#pragma GCC diagnostic pop
#endif
/***************************************************************************//**
* @brief
* Perform a peripheral register masked read.
*
* @details
* Read an unshifted and masked value from a peripheral register.
*
* @note
* This operation is not hardware accelerated.
*
* @param[in] addr A peripheral register address.
*
* @param[in] mask A peripheral register mask.
*
* @return
* An unshifted and masked register value.
******************************************************************************/
__STATIC_INLINE uint32_t BUS_RegMaskedRead(volatile const uint32_t *addr,
uint32_t mask)
{
return *addr & mask;
}
/** @} (end addtogroup bus) */
#ifdef __cplusplus
}
#endif
#endif /* EM_BUS_H */

View File

@@ -0,0 +1,483 @@
/***************************************************************************//**
* @file
* @brief Chip Errata Workarounds
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_CHIP_H
#define EM_CHIP_H
#include "em_device.h"
#include "sl_common.h"
#if defined(_SILICON_LABS_32B_SERIES) && (_SILICON_LABS_32B_SERIES <= 2)
#include "em_system.h"
#endif
#include "em_bus.h"
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
#include "em_gpio.h"
#endif
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_240)
#include "em_cmu.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup chip CHIP - Chip Errata Workarounds
* @brief Chip errata workaround APIs
* @details
* API to apply chip errata workarounds at initialization and reset.
* @{
******************************************************************************/
/**************************************************************************//**
* @brief
* Chip initialization routine for revision errata workarounds.
*
* @note
* This function must be called immediately in main().
*
* This initialization function configures the device to a state
* as similar to later revisions as possible to improve software compatibility
* with newer parts. See the device-specific errata for details.
*****************************************************************************/
__STATIC_INLINE void CHIP_Init(void)
{
#if defined(MSC_CACHECMD_INVCACHE)
MSC->CACHECMD = MSC_CACHECMD_INVCACHE;
#elif defined(MSC_CMD_INVCACHE)
MSC->CMD = MSC_CMD_INVCACHE;
#endif
#if defined(_SILICON_LABS_32B_SERIES_0) && defined(_EFM32_GECKO_FAMILY)
uint32_t rev;
SYSTEM_ChipRevision_TypeDef chipRev;
volatile uint32_t *reg;
rev = *(volatile uint32_t *)(0x0FE081FC);
/* Engineering Sample calibration setup. */
if ((rev >> 24) == 0) {
reg = (volatile uint32_t *)0x400CA00C;
*reg &= ~(0x70UL);
/* DREG */
reg = (volatile uint32_t *)0x400C6020;
*reg &= ~(0xE0000000UL);
*reg |= ~(7UL << 25);
}
if ((rev >> 24) <= 3) {
/* DREG */
reg = (volatile uint32_t *)0x400C6020;
*reg &= ~(0x00001F80UL);
/* Update CMU reset values. */
reg = (volatile uint32_t *)0x400C8040;
*reg = 0;
reg = (volatile uint32_t *)0x400C8044;
*reg = 0;
reg = (volatile uint32_t *)0x400C8058;
*reg = 0;
reg = (volatile uint32_t *)0x400C8060;
*reg = 0;
reg = (volatile uint32_t *)0x400C8078;
*reg = 0;
}
SYSTEM_ChipRevisionGet(&chipRev);
if (chipRev.major == 0x01) {
/* Rev A errata handling for EM2/3. Must enable DMA clock to get EM2/3 */
/* to work. This will be fixed in later chip revisions and is only needed for rev A. */
if (chipRev.minor == 00) {
reg = (volatile uint32_t *)0x400C8040;
*reg |= 0x2;
}
/* Rev A+B errata handling for I2C when using EM2/3. USART0 clock must be enabled */
/* after waking up from EM2/EM3 to get I2C to work. This will be fixed in */
/* later chip revisions and is only needed for rev A+B. */
if (chipRev.minor <= 0x01) {
reg = (volatile uint32_t *)0x400C8044;
*reg |= 0x1;
}
}
/* Ensure correct ADC/DAC calibration value. */
rev = *(volatile uint32_t *)0x0FE081F0;
if (rev < 0x4C8ABA00) {
uint32_t cal;
/* Enable ADC/DAC clocks. */
reg = (volatile uint32_t *)0x400C8044UL;
*reg |= (1 << 14 | 1 << 11);
/* Retrive calibration values. */
cal = ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x00007F00UL)
>> 8) << 24;
cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x0000007FUL)
>> 0) << 16;
cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x00007F00UL)
>> 8) << 8;
cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x0000007FUL)
>> 0) << 0;
/* ADC0->CAL = 1.25 reference. */
reg = (volatile uint32_t *)0x40002034UL;
*reg = cal;
/* DAC0->CAL = 1.25 reference. */
reg = (volatile uint32_t *)(0x4000402CUL);
cal = *(volatile uint32_t *)0x0FE081C8UL;
*reg = cal;
/* Turn off ADC/DAC clocks. */
reg = (volatile uint32_t *)0x400C8044UL;
*reg &= ~(1 << 14 | 1 << 11);
}
#endif
#if defined(_SILICON_LABS_32B_SERIES_0) && defined(_EFM32_GIANT_FAMILY)
/****************************/
/* Fix for errata CMU_E113. */
uint8_t prodRev;
SYSTEM_ChipRevision_TypeDef chipRev;
prodRev = SYSTEM_GetProdRev();
SYSTEM_ChipRevisionGet(&chipRev);
// All Giant and Leopard parts except Leopard Rev E
if ((prodRev >= 16) && (chipRev.minor >= 3)
&& !((chipRev.major == 2) && (chipRev.minor == 4))) {
/* This fixes an issue with the LFXO on high temperatures. */
*(volatile uint32_t*)0x400C80C0 =
(*(volatile uint32_t*)0x400C80C0 & ~(1 << 6) ) | (1 << 4);
}
#endif
#if defined(_SILICON_LABS_32B_SERIES_0) && defined(_EFM32_HAPPY_FAMILY)
uint8_t prodRev;
prodRev = SYSTEM_GetProdRev();
if (prodRev <= 129) {
/* This fixes a mistaken internal connection between PC0 and PC4. */
/* This disables an internal pull-down on PC4. */
*(volatile uint32_t*)(0x400C6018) = (1 << 26) | (5 << 0);
/* This disables an internal LDO test signal driving PC4. */
*(volatile uint32_t*)(0x400C80E4) &= ~(1 << 24);
}
#endif
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
/****************************
* Fixes for errata GPIO_E201 (slewrate) and
* HFXO high-temperature oscillator startup robustness fix. */
uint32_t port;
uint32_t clkEn;
uint8_t prodRev;
const uint32_t setVal = (0x5 << _GPIO_P_CTRL_SLEWRATEALT_SHIFT)
| (0x5 << _GPIO_P_CTRL_SLEWRATE_SHIFT);
const uint32_t resetVal = _GPIO_P_CTRL_RESETVALUE
& ~(_GPIO_P_CTRL_SLEWRATE_MASK
| _GPIO_P_CTRL_SLEWRATEALT_MASK);
prodRev = SYSTEM_GetProdRev();
SYSTEM_ChipRevision_TypeDef chipRev;
SYSTEM_ChipRevisionGet(&chipRev);
/* This errata is fixed in hardware from PRODREV 0x8F. */
if (prodRev < 0x8F) {
/* Fixes for errata GPIO_E201 (slewrate). */
/* Save HFBUSCLK enable state and enable GPIO clock. */
clkEn = CMU->HFBUSCLKEN0;
CMU->HFBUSCLKEN0 = clkEn | CMU_HFBUSCLKEN0_GPIO;
/* Update slewrate. */
for (port = 0; port <= GPIO_PORT_MAX; port++) {
GPIO->P[port].CTRL = setVal | resetVal;
}
/* Restore HFBUSCLK enable state. */
CMU->HFBUSCLKEN0 = clkEn;
}
/* This errata is fixed in hardware from PRODREV 0x90. */
if (prodRev < 0x90) {
/* HFXO high-temperature oscillator startup robustness fix. */
CMU->HFXOSTARTUPCTRL =
(CMU->HFXOSTARTUPCTRL & ~_CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_MASK)
| (0x20 << _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_SHIFT);
}
if (chipRev.major == 0x01) {
/* Fix for errata EMU_E210 - Potential Power-Down When Entering EM2 */
*(volatile uint32_t *)(EMU_BASE + 0x164) |= 0x4;
}
/****************************
* Fix for errata DCDC_E206.
* Disable bypass limit enabled temporarily in SystemInit() errata
* workaround. */
BUS_RegBitWrite(&EMU->DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, 0);
#endif
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_84)
uint8_t prodRev = SYSTEM_GetProdRev();
/* EM2 current fixes for early samples. */
if (prodRev == 0U) {
*(volatile uint32_t *)(EMU_BASE + 0x190UL) = 0x0000ADE8UL;
*(volatile uint32_t *)(EMU_BASE + 0x198UL) |= (0x1UL << 2);
*(volatile uint32_t *)(EMU_BASE + 0x190UL) = 0x0;
}
if (prodRev < 2U) {
*(volatile uint32_t *)(EMU_BASE + 0x164UL) |= (0x1UL << 13);
}
/* Set optimal LFRCOCTRL VREFUPDATE and enable duty cycling of VREF. */
CMU->LFRCOCTRL = (CMU->LFRCOCTRL & ~_CMU_LFRCOCTRL_VREFUPDATE_MASK)
| CMU_LFRCOCTRL_VREFUPDATE_64CYCLES
| CMU_LFRCOCTRL_ENVREF;
#endif
#if defined(_SILICON_LABS_32B_SERIES_1) \
&& defined(_EFR_DEVICE) && (_SILICON_LABS_GECKO_INTERNAL_SDID >= 84)
MSC->CTRL |= 0x1UL << 8;
#endif
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89)
SYSTEM_ChipRevision_TypeDef chipRev;
SYSTEM_ChipRevisionGet(&chipRev);
if ((chipRev.major > 1) || (chipRev.minor >= 3)) {
/* PLFRCO trim values */
*(volatile uint32_t *)(CMU_BASE + 0x28CUL) = 608;
*(volatile uint32_t *)(CMU_BASE + 0x290UL) = 356250;
*(volatile uint32_t *)(CMU_BASE + 0x2F0UL) = 0x04000118;
*(volatile uint32_t *)(CMU_BASE + 0x2F8UL) = 0x08328400;
}
#endif
/* Charge redist setup (fixed value): LCD->DBGCTRL.CHGRDSTSTR = 1 (reset: 0). */
#if defined(_LCD_DISPCTRL_CHGRDST_MASK)
#if defined(_SILICON_LABS_32B_SERIES_1)
CMU->HFBUSCLKEN0 |= CMU_HFBUSCLKEN0_LE;
CMU->LFACLKEN0 |= CMU_LFACLKEN0_LCD;
*(volatile uint32_t *)(LCD_BASE + 0x034) |= (0x1UL << 12);
CMU->LFACLKEN0 &= ~CMU_LFACLKEN0_LCD;
CMU->HFBUSCLKEN0 &= ~CMU_HFBUSCLKEN0_LE;
#endif
#endif
#if defined(_SILICON_LABS_32B_SERIES_1) \
&& !defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80) \
&& !defined(ERRATA_FIX_EMU_E220_DECBOD_IGNORE)
/* First part of the EMU_E220 DECBOD Errata fix. DECBOD Reset can occur
* during voltage scaling after EM2/3 wakeup. Second part is in em_emu.c */
*(volatile uint32_t *)(EMU_BASE + 0x1A4) |= 0x1f << 10;
#endif
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
SYSTEM_ChipRevision_TypeDef chipRev;
SYSTEM_ChipRevisionGet(&chipRev);
if (chipRev.major == 0x01 && (HFXO0->STATUS & HFXO_STATUS_ENS) == 0U) {
/* Change HFXO default peak detector settings. */
*(volatile uint32_t*)(HFXO0_BASE + 0x34U) =
(*(volatile uint32_t*)(HFXO0_BASE + 0x34U) & 0xFF8000FFU)
| 0x00178500U;
/* Change HFXO low power control settings. */
*(volatile uint32_t*)(HFXO0_BASE + 0x30U) =
(*(volatile uint32_t*)(HFXO0_BASE + 0x30U) & 0xFFFF0FFFU)
| 0x0000C000U;
/* Change default SQBUF bias current. */
*(volatile uint32_t*)(HFXO0_BASE + 0x30U) |= 0x700;
}
if (chipRev.major == 0x01 && chipRev.minor == 0x0) {
/* Trigger RAM read for each RAM instance */
volatile uint32_t *dmem = (volatile uint32_t *) DMEM_RAM0_RAM_MEM_BASE;
for (uint32_t i = 0U; i < DMEM_NUM_BANK; i++) {
// Force memory read
*dmem;
dmem += (DMEM_BANK0_SIZE / 4U);
}
}
/* Set TRACE clock to intended reset value. */
CMU->TRACECLKCTRL = (CMU->TRACECLKCTRL & ~_CMU_TRACECLKCTRL_CLKSEL_MASK)
| CMU_TRACECLKCTRL_CLKSEL_HFRCOEM23;
#endif
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_205)
#if defined(SL_TRUSTZONE_SECURE)
#define HFRCO_CLK_CFG_CLR_ADDR (0x40012020UL)
#else
#define HFRCO_CLK_CFG_CLR_ADDR (0x50012020UL)
#endif
#define HFRCO_CLK_CFG_CLKOUTDIS0 (0x4UL)
if (SYSTEM_GetProdRev() == 1) {
bool hfrcoClkIsOff = (CMU->CLKEN0 & CMU_CLKEN0_HFRCO0) == 0;
CMU->CLKEN0_SET = CMU_CLKEN0_HFRCO0;
/* Enable HFRCO CLKOUT0. */
*(volatile uint32_t*)(HFRCO_CLK_CFG_CLR_ADDR) = HFRCO_CLK_CFG_CLKOUTDIS0;
if (hfrcoClkIsOff) {
CMU->CLKEN0_CLR = CMU_CLKEN0_HFRCO0;
}
}
#endif
/* PM-3503 */
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_210)
{
bool syscfgClkIsOff = ((CMU->CLKEN0 & CMU_CLKEN0_SYSCFG) == 0);
CMU->CLKEN0_SET = CMU_CLKEN0_SYSCFG;
bool dcdcClkIsOff = ((CMU->CLKEN0 & CMU_CLKEN0_DCDC) == 0);
CMU->CLKEN0_SET = CMU_CLKEN0_DCDC;
bool dcdcIsLock = ((DCDC->LOCKSTATUS & DCDC_LOCKSTATUS_LOCK_LOCKED) != 0);
DCDC->LOCK = DCDC_LOCK_LOCKKEY_UNLOCKKEY;
while (DCDC->SYNCBUSY & DCDC_SYNCBUSY_CTRL) {
/* Wait for previous synchronization to finish */
}
DCDC->CTRL_CLR = DCDC_CTRL_MODE;
while ((DCDC->STATUS & DCDC_STATUS_BYPSW) == 0U) {
/* Wait for BYPASS switch enable. */
}
if (dcdcIsLock) {
DCDC->LOCK = ~DCDC_LOCK_LOCKKEY_UNLOCKKEY;
}
if (dcdcClkIsOff) {
CMU->CLKEN0_CLR = CMU_CLKEN0_DCDC;
}
if (syscfgClkIsOff) {
CMU->CLKEN0_CLR = CMU_CLKEN0_SYSCFG;
}
}
#endif
/* PM-5163 */
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_215) \
&& defined(_SILICON_LABS_EFR32_2G4HZ_HP_PA_PRESENT) \
&& (_SILICON_LABS_EFR32_2G4HZ_HP_PA_MAX_OUTPUT_DBM == 20)
SYSTEM_ChipRevision_TypeDef chipRev;
SYSTEM_ChipRevisionGet(&chipRev);
if (chipRev.major == 0x01 && chipRev.minor == 0x00) {
bool hfxo0ClkIsOff = (CMU->CLKEN0 & CMU_CLKEN0_HFXO0) == 0;
CMU->CLKEN0_SET = CMU_CLKEN0_HFXO0;
*(volatile uint32_t*)(HFXO0_BASE + 0x0034UL) =
(*(volatile uint32_t*)(HFXO0_BASE + 0x0034UL) & 0xE3FFFFFFUL)
| 0x0C000000UL;
if (hfxo0ClkIsOff) {
CMU->CLKEN0_CLR = CMU_CLKEN0_HFXO0;
}
}
#endif
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_240)
// Enable ICache out of reset.
CMU->CLKEN1_SET = _CMU_CLKEN1_ICACHE0_MASK;
ICACHE0->CTRL_CLR = _ICACHE_CTRL_CACHEDIS_MASK;
CMU->CLKEN1_CLR = _CMU_CLKEN1_ICACHE0_MASK;
CMU->CLKEN0_SET = _CMU_CLKEN0_HFRCO0_MASK;
if (((HFRCO0->CAL & _HFRCO_CAL_TUNING_MASK) >> _HFRCO_CAL_TUNING_SHIFT) == _HFRCO_CAL_TUNING_MASK) {
CMU_HFRCODPLLBandSet(cmuHFRCODPLLFreq_19M0Hz);
}
CMU->CLKEN0_CLR = _CMU_CLKEN0_HFRCO0_MASK;
#endif
}
/**************************************************************************//**
* @brief
* Chip reset routine with errata workarounds.
*
* @note
* This function should be called to reset the chip. It does not return.
*
* This function applies any errata workarounds needed to cleanly reset the
* device and then performs a system reset. See the device-specific errata for
* details.
*****************************************************************************/
__STATIC_INLINE void CHIP_Reset(void)
{
#if defined(_EFR_DEVICE) && defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
/****************************
* Workaround for errata DCDC_E206.
* Disable radio interference minimization features when resetting */
// Ensure access to EMU registers
EMU->LOCK = EMU_LOCK_LOCKKEY_UNLOCK;
EMU->PWRLOCK = EMU_PWRLOCK_LOCKKEY_LOCK;
// No need to do anything if the DCDC is not powering DVDD
if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) == EMU_PWRCFG_PWRCFG_DCDCTODVDD) {
// Make sure radio cannot accidentally re-enable features
*(volatile uint32_t *)(0x40084040UL) = 0x1UL;
// If DCDC is in use, disable features
uint32_t dcdcMode = EMU->DCDCCTRL & _EMU_DCDCCTRL_DCDCMODE_MASK;
if ((dcdcMode == EMU_DCDCCTRL_DCDCMODE_LOWNOISE)
|| (dcdcMode == EMU_DCDCCTRL_DCDCMODE_LOWPOWER)) {
BUS_RegBitWrite((volatile uint32_t *)(0x400E3060UL), 28UL, 0);
BUS_RegBitWrite((volatile uint32_t *)(0x400E3074UL), 0, 0);
}
}
#endif
NVIC_SystemReset();
}
/** @} (end addtogroup chip) */
#ifdef __cplusplus
}
#endif
#endif /* EM_CHIP_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,184 @@
/***************************************************************************//**
* @file
* @brief CMU Compatibility Header
*******************************************************************************
* # License
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_CMU_COMPAT_H
#define EM_CMU_COMPAT_H
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2)
#define CMU_IF_CALRDYIF CMU_IF_CALRDY
#define _CMU_IF_CALRDYIF_SHIFT _CMU_IF_CALRDY_SHIFT
#define _CMU_IF_CALRDYIF_MASK _CMU_IF_CALRDY_MASK
#define _CMU_IF_CALRDYIF_DEFAULT _CMU_IF_CALRDY_DEFAULT
#define CMU_IF_CALRDYIF_DEFAULT CMU_IF_CALRDY_DEFAULT
#define CMU_IF_CALOFIF CMU_IF_CALOF
#define _CMU_IF_CALOFIF_SHIFT _CMU_IF_CALOF_SHIFT
#define _CMU_IF_CALOFIF_MASK _CMU_IF_CALOF_MASK
#define _CMU_IF_CALOFIF_DEFAULT _CMU_IF_CALOF_DEFAULT
#define CMU_IF_CALOFIF_DEFAULT CMU_IF_CALOF_DEFAULT
#define CMU_IEN_CALRDYIEN CMU_IEN_CALRDY
#define _CMU_IEN_CALRDYIEN_SHIFT _CMU_IEN_CALRDY_SHIFT
#define _CMU_IEN_CALRDYIEN_MASK _CMU_IEN_CALRDY_MASK
#define _CMU_IEN_CALRDYIEN_DEFAULT _CMU_IEN_CALRDY_DEFAULT
#define CMU_IEN_CALRDYIEN_DEFAULT CMU_IEN_CALRDY_DEFAULT
#define CMU_IEN_CALOFIEN CMU_IEN_CALOF
#define _CMU_IEN_CALOFIEN_SHIFT _CMU_IEN_CALOF_SHIFT
#define _CMU_IEN_CALOFIEN_MASK _CMU_IEN_CALOF_MASK
#define _CMU_IEN_CALOFIEN_DEFAULT _CMU_IEN_CALOF_DEFAULT
#define CMU_IEN_CALOFIEN_DEFAULT CMU_IEN_CALOF_DEFAULT
#define HFRCO_IF_RDYIF HFRCO_IF_RDY
#define _HFRCO_IF_RDYIF_SHIFT _HFRCO_IF_RDY_SHIFT
#define _HFRCO_IF_RDYIF_MASK _HFRCO_IF_RDY_MASK
#define _HFRCO_IF_RDYIF_DEFAULT _HFRCO_IF_RDY_DEFAULT
#define HFRCO_IF_RDYIF_DEFAULT HFRCO_IF_RDY_DEFAULT
#define HFRCO_IEN_RDYIEN HFRCO_IEN_RDY
#define _HFRCO_IEN_RDYIEN_SHIFT _HFRCO_IEN_RDY_SHIFT
#define _HFRCO_IEN_RDYIEN_MASK _HFRCO_IEN_RDY_MASK
#define _HFRCO_IEN_RDYIEN_DEFAULT _HFRCO_IEN_RDY_DEFAULT
#define HFRCO_IEN_RDYIEN_DEFAULT HFRCO_IEN_RDY_DEFAULT
#define LFRCO_IF_RDYIF LFRCO_IF_RDY
#define _LFRCO_IF_RDYIF_SHIFT _LFRCO_IF_RDY_SHIFT
#define _LFRCO_IF_RDYIF_MASK _LFRCO_IF_RDY_MASK
#define _LFRCO_IF_RDYIF_DEFAULT _LFRCO_IF_RDY_DEFAULT
#define LFRCO_IF_RDYIF_DEFAULT LFRCO_IF_RDY_DEFAULT
#define LFRCO_IF_POSEDGEIF LFRCO_IF_POSEDGE
#define _LFRCO_IF_POSEDGEIF_SHIFT _LFRCO_IF_POSEDGE_SHIFT
#define _LFRCO_IF_POSEDGEIF_MASK _LFRCO_IF_POSEDGE_MASK
#define _LFRCO_IF_POSEDGEIF_DEFAULT _LFRCO_IF_POSEDGE_DEFAULT
#define LFRCO_IF_POSEDGEIF_DEFAULT LFRCO_IF_POSEDGE_DEFAULT
#define LFRCO_IF_NEGEDGEIF LFRCO_IF_NEGEDGE
#define _LFRCO_IF_NEGEDGEIF_SHIFT _LFRCO_IF_NEGEDGE_SHIFT
#define _LFRCO_IF_NEGEDGEIF_MASK _LFRCO_IF_NEGEDGE_MASK
#define _LFRCO_IF_NEGEDGEIF_DEFAULT _LFRCO_IF_NEGEDGE_DEFAULT
#define LFRCO_IF_NEGEDGEIF_DEFAULT LFRCO_IF_NEGEDGE_DEFAULT
#define LFRCO_IF_TCDONEIF LFRCO_IF_TCDONE
#define _LFRCO_IF_TCDONEIF_SHIFT _LFRCO_IF_TCDONE_SHIFT
#define _LFRCO_IF_TCDONEIF_MASK _LFRCO_IF_TCDONE_MASK
#define _LFRCO_IF_TCDONEIF_DEFAULT _LFRCO_IF_TCDONE_DEFAULT
#define LFRCO_IF_TCDONEIF_DEFAULT LFRCO_IF_TCDONE_DEFAULT
#define LFRCO_IF_CALDONEIF LFRCO_IF_CALDONE
#define _LFRCO_IF_CALDONEIF_SHIFT _LFRCO_IF_CALDONE_SHIFT
#define _LFRCO_IF_CALDONEIF_MASK _LFRCO_IF_CALDONE_MASK
#define _LFRCO_IF_CALDONEIF_DEFAULT _LFRCO_IF_CALDONE_DEFAULT
#define LFRCO_IF_CALDONEIF_DEFAULT LFRCO_IF_CALDONE_DEFAULT
#define LFRCO_IF_TEMPCHANGEIF LFRCO_IF_TEMPCHANGE
#define _LFRCO_IF_TEMPCHANGEIF_SHIFT _LFRCO_IF_TEMPCHANGE_SHIFT
#define _LFRCO_IF_TEMPCHANGEIF_MASK _LFRCO_IF_TEMPCHANGE_MASK
#define _LFRCO_IF_TEMPCHANGEIF_DEFAULT _LFRCO_IF_TEMPCHANGE_DEFAULT
#define LFRCO_IF_TEMPCHANGEIF_DEFAULT LFRCO_IF_TEMPCHANGE_DEFAULT
#define LFRCO_IF_SCHEDERRIF LFRCO_IF_SCHEDERR
#define _LFRCO_IF_SCHEDERRIF_SHIFT _LFRCO_IF_SCHEDERR_SHIFT
#define _LFRCO_IF_SCHEDERRIF_MASK _LFRCO_IF_SCHEDERR_MASK
#define _LFRCO_IF_SCHEDERRIF_DEFAULT _LFRCO_IF_SCHEDERR_DEFAULT
#define LFRCO_IF_SCHEDERRIF_DEFAULT LFRCO_IF_SCHEDERR_DEFAULT
#define LFRCO_IF_TCOORIF LFRCO_IF_TCOOR
#define _LFRCO_IF_TCOORIF_SHIFT _LFRCO_IF_TCOOR_SHIFT
#define _LFRCO_IF_TCOORIF_MASK _LFRCO_IF_TCOOR_MASK
#define _LFRCO_IF_TCOORIF_DEFAULT _LFRCO_IF_TCOOR_DEFAULT
#define LFRCO_IF_TCOORIF_DEFAULT LFRCO_IF_TCOOR_DEFAULT
#define LFRCO_IF_CALOORIF LFRCO_IF_CALOOR
#define _LFRCO_IF_CALOORIF_SHIFT _LFRCO_IF_CALOOR_SHIFT
#define _LFRCO_IF_CALOORIF_MASK _LFRCO_IF_CALOOR_MASK
#define _LFRCO_IF_CALOORIF_DEFAULT _LFRCO_IF_CALOOR_DEFAULT
#define LFRCO_IF_CALOORIF_DEFAULT LFRCO_IF_CALOOR_DEFAULT
#define LFRCO_IEN_RDYIEN LFRCO_IEN_RDY
#define _LFRCO_IEN_RDYIEN_SHIFT _LFRCO_IEN_RDY_SHIFT
#define _LFRCO_IEN_RDYIEN_MASK _LFRCO_IEN_RDY_MASK
#define _LFRCO_IEN_RDYIEN_DEFAULT _LFRCO_IEN_RDY_DEFAULT
#define LFRCO_IEN_RDYIEN_DEFAULT LFRCO_IEN_RDY_DEFAULT
#define LFRCO_IEN_POSEDGEIEN LFRCO_IEN_POSEDGE
#define _LFRCO_IEN_POSEDGEIEN_SHIFT _LFRCO_IEN_POSEDGE_SHIFT
#define _LFRCO_IEN_POSEDGEIEN_MASK _LFRCO_IEN_POSEDGE_MASK
#define _LFRCO_IEN_POSEDGEIEN_DEFAULT _LFRCO_IEN_POSEDGE_DEFAULT
#define LFRCO_IEN_POSEDGEIEN_DEFAULT LFRCO_IEN_POSEDGE_DEFAULT
#define LFRCO_IEN_NEGEDGEIEN LFRCO_IEN_NEGEDGE
#define _LFRCO_IEN_NEGEDGEIEN_SHIFT _LFRCO_IEN_NEGEDGE_SHIFT
#define _LFRCO_IEN_NEGEDGEIEN_MASK _LFRCO_IEN_NEGEDGE_MASK
#define _LFRCO_IEN_NEGEDGEIEN_DEFAULT _LFRCO_IEN_NEGEDGE_DEFAULT
#define LFRCO_IEN_NEGEDGEIEN_DEFAULT LFRCO_IEN_NEGEDGE_DEFAULT
#define LFRCO_IEN_TCDONEIEN LFRCO_IEN_TCDONE
#define _LFRCO_IEN_TCDONEIEN_SHIFT _LFRCO_IEN_TCDONE_SHIFT
#define _LFRCO_IEN_TCDONEIEN_MASK _LFRCO_IEN_TCDONE_MASK
#define _LFRCO_IEN_TCDONEIEN_DEFAULT _LFRCO_IEN_TCDONE_DEFAULT
#define LFRCO_IEN_TCDONEIEN_DEFAULT LFRCO_IEN_TCDONE_DEFAULT
#define LFRCO_IEN_CALDONEIEN LFRCO_IEN_CALDONE
#define _LFRCO_IEN_CALDONEIEN_SHIFT _LFRCO_IEN_CALDONE_SHIFT
#define _LFRCO_IEN_CALDONEIEN_MASK _LFRCO_IEN_CALDONE_MASK
#define _LFRCO_IEN_CALDONEIEN_DEFAULT _LFRCO_IEN_CALDONE_DEFAULT
#define LFRCO_IEN_CALDONEIEN_DEFAULT LFRCO_IEN_CALDONE_DEFAULT
#define LFRCO_IEN_TEMPCHANGEIEN LFRCO_IEN_TEMPCHANGE
#define _LFRCO_IEN_TEMPCHANGEIEN_SHIFT _LFRCO_IEN_TEMPCHANGE_SHIFT
#define _LFRCO_IEN_TEMPCHANGEIEN_MASK _LFRCO_IEN_TEMPCHANGE_MASK
#define _LFRCO_IEN_TEMPCHANGEIEN_DEFAULT _LFRCO_IEN_TEMPCHANGE_DEFAULT
#define LFRCO_IEN_TEMPCHANGEIEN_DEFAULT LFRCO_IEN_TEMPCHANGE_DEFAULT
#define LFRCO_IEN_SCHEDERRIEN LFRCO_IEN_SCHEDERR
#define _LFRCO_IEN_SCHEDERRIEN_SHIFT _LFRCO_IEN_SCHEDERR_SHIFT
#define _LFRCO_IEN_SCHEDERRIEN_MASK _LFRCO_IEN_SCHEDERR_MASK
#define _LFRCO_IEN_SCHEDERRIEN_DEFAULT _LFRCO_IEN_SCHEDERR_DEFAULT
#define LFRCO_IEN_SCHEDERRIEN_DEFAULT LFRCO_IEN_SCHEDERR_DEFAULT
#define LFRCO_IEN_TCOORIEN LFRCO_IEN_TCOOR
#define _LFRCO_IEN_TCOORIEN_SHIFT _LFRCO_IEN_TCOOR_SHIFT
#define _LFRCO_IEN_TCOORIEN_MASK _LFRCO_IEN_TCOOR_MASK
#define _LFRCO_IEN_TCOORIEN_DEFAULT _LFRCO_IEN_TCOOR_DEFAULT
#define LFRCO_IEN_TCOORIEN_DEFAULT LFRCO_IEN_TCOOR_DEFAULT
#define LFRCO_IEN_CALOORIEN LFRCO_IEN_CALOOR
#define _LFRCO_IEN_CALOORIEN_SHIFT _LFRCO_IEN_CALOOR_SHIFT
#define _LFRCO_IEN_CALOORIEN_MASK _LFRCO_IEN_CALOOR_MASK
#define _LFRCO_IEN_CALOORIEN_DEFAULT _LFRCO_IEN_CALOOR_DEFAULT
#define LFRCO_IEN_CALOORIEN_DEFAULT LFRCO_IEN_CALOOR_DEFAULT
#endif /* _SILICON_LABS_32B_SERIES_2_CONFIG_2 */
#endif

View File

@@ -0,0 +1,36 @@
/***************************************************************************//**
* @file
* @brief General purpose utilities.
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_COMMON_H
#define EM_COMMON_H
#include "em_device.h"
#include "sl_common.h"
#endif /* EM_COMMON_H */

View File

@@ -0,0 +1,174 @@
/***************************************************************************//**
* @file
* @brief Core interrupt handling API (Device Specific)
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_CORE_H
#define EM_CORE_H
#include "em_device.h"
#include "em_core_generic.h"
#include "sl_common.h"
/***************************************************************************//**
* @addtogroup core
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** Number of words in a NVIC mask set. */
#define CORE_NVIC_REG_WORDS ((EXT_IRQ_COUNT + 31) / 32)
/** Number of entries in a default interrupt vector table. */
#define CORE_DEFAULT_VECTOR_TABLE_ENTRIES (EXT_IRQ_COUNT + 16)
/** Highest priority for core interrupt. */
#define CORE_INTERRUPT_HIGHEST_PRIORITY 0
/** Default priority for core interrupt. */
#define CORE_INTERRUPT_DEFAULT_PRIORITY 5
/** Lowest priority for core interrupt. */
#define CORE_INTERRUPT_LOWEST_PRIORITY 7
// Compile time sanity check.
#if (CORE_NVIC_REG_WORDS > 3)
#error "em_core: Unexpected NVIC external interrupt count."
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
************************ MACRO API ***************************************
******************************************************************************/
//
// NVIC mask section macro API.
//
/** Allocate storage for NVIC interrupt masks for use by
* CORE_ENTER/EXIT_NVIC() macros. */
#define CORE_DECLARE_NVIC_STATE CORE_nvicMask_t nvicState
/** Allocate storage for NVIC interrupt masks.
* @param[in] x
* The storage variable name to use.*/
#define CORE_DECLARE_NVIC_MASK(x) CORE_nvicMask_t x
/** Allocate storage for and zero initialize NVIC interrupt mask.
* @param[in] x
* The storage variable name to use.*/
#define CORE_DECLARE_NVIC_ZEROMASK(x) CORE_nvicMask_t x = { { 0 } }
/** NVIC mask style interrupt disable.
* @param[in] mask
* Mask specifying which NVIC interrupts to disable. */
#define CORE_NVIC_DISABLE(mask) CORE_NvicDisableMask(mask)
/** NVIC mask style interrupt enable.
* @param[in] mask
* Mask specifying which NVIC interrupts to enable. */
#define CORE_NVIC_ENABLE(mask) CORE_NvicEnableMask(mask)
/** Convenience macro for implementing a NVIC mask section.
* @param[in] mask
* Mask specifying which NVIC interrupts to disable within the section.
* @param[in] yourcode
* The code for the section. */
#define CORE_NVIC_SECTION(mask, yourcode) \
{ \
CORE_DECLARE_NVIC_STATE; \
CORE_ENTER_NVIC(mask); \
{ \
yourcode \
} \
CORE_EXIT_NVIC(); \
}
/** Enter NVIC mask section. Assumes that a @ref CORE_DECLARE_NVIC_STATE exist
* in scope.
* @param[in] disable
* Mask specifying which NVIC interrupts to disable within the section. */
#define CORE_ENTER_NVIC(disable) CORE_EnterNvicMask(&nvicState, disable)
/** Exit NVIC mask section. Assumes that a @ref CORE_DECLARE_NVIC_STATE exist
* in scope. */
#define CORE_EXIT_NVIC() CORE_NvicEnableMask(&nvicState)
/** NVIC maks style yield.
* @param[in] enable
* Mask specifying which NVIC interrupts to briefly enable. */
#define CORE_YIELD_NVIC(enable) CORE_YieldNvicMask(enable)
/*******************************************************************************
************************* TYPEDEFS ****************************************
******************************************************************************/
/** Storage for NVIC interrupt masks. */
typedef struct {
uint32_t a[CORE_NVIC_REG_WORDS]; /*!< Array of NVIC mask words. */
} CORE_nvicMask_t;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
bool CORE_IrqIsBlocked(IRQn_Type irqN) SL_DEPRECATED_API_SDK_2024_6;
void CORE_GetNvicEnabledMask(CORE_nvicMask_t *mask) SL_DEPRECATED_API_SDK_2024_6;
bool CORE_GetNvicMaskDisableState(const CORE_nvicMask_t *mask) SL_DEPRECATED_API_SDK_2024_6;
void CORE_EnterNvicMask(CORE_nvicMask_t *nvicState,
const CORE_nvicMask_t *disable) SL_DEPRECATED_API_SDK_2024_6;
void CORE_NvicDisableMask(const CORE_nvicMask_t *disable) SL_DEPRECATED_API_SDK_2024_6;
void CORE_NvicEnableMask(const CORE_nvicMask_t *enable) SL_DEPRECATED_API_SDK_2024_6;
void CORE_YieldNvicMask(const CORE_nvicMask_t *enable) SL_DEPRECATED_API_SDK_2024_6;
void CORE_NvicMaskSetIRQ(IRQn_Type irqN, CORE_nvicMask_t *mask) SL_DEPRECATED_API_SDK_2024_6;
void CORE_NvicMaskClearIRQ(IRQn_Type irqN, CORE_nvicMask_t *mask) SL_DEPRECATED_API_SDK_2024_6;
bool CORE_NvicIRQDisabled(IRQn_Type irqN) SL_DEPRECATED_API_SDK_2024_6;
void *CORE_GetNvicRamTableHandler(IRQn_Type irqN) SL_DEPRECATED_API_SDK_2024_6;
void CORE_SetNvicRamTableHandler(IRQn_Type irqN, void *handler) SL_DEPRECATED_API_SDK_2024_6;
void CORE_InitNvicVectorTable(uint32_t *sourceTable,
uint32_t sourceSize,
uint32_t *targetTable,
uint32_t targetSize,
void *defaultHandler,
bool overwriteActive);
#ifdef __cplusplus
}
#endif
/** @} (end addtogroup core) */
#endif /* EM_CORE_H */

View File

@@ -0,0 +1,36 @@
/***************************************************************************//**
* @file
* @brief Core interrupt handling API (Generic)
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_CORE_GENERIC_H
#define EM_CORE_GENERIC_H
#include "sl_core.h"
#endif /* EM_CORE_GENERIC_H */

View File

@@ -0,0 +1,130 @@
/***************************************************************************//**
* @file
* @brief Debug (DBG) API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_DBG_H
#define EM_DBG_H
#include <stdbool.h>
#include "em_device.h"
#if defined(CoreDebug_DHCSR_C_DEBUGEN_Msk)
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup dbg
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Lock modes */
typedef enum {
dbgLockModeAllowErase = 1UL, /**< Lock debug access. */
#if !defined(_SILICON_LABS_32B_SERIES_0)
dbgLockModePermanent = 2UL /**< Lock debug access permanently. */
#endif
} DBG_LockMode_TypeDef;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
#if defined(GPIO_ROUTE_SWCLKPEN) \
|| defined(GPIO_ROUTEPEN_SWCLKTCKPEN) \
|| defined(GPIO_DBGROUTEPEN_SWCLKTCKPEN)
/***************************************************************************//**
* @brief
* Check if a debugger is connected (and debug session activated).
*
* @details
* Used to make run-time decisions depending on whether or not a debug session
* has been active since last reset, i.e., using a debug probe or similar. In
* some cases, special handling is required in that scenario.
*
* @return
* True if a debug session is active since last reset, otherwise false.
******************************************************************************/
__STATIC_INLINE bool DBG_Connected(void)
{
return (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) ? true : false;
}
#endif
#if defined(GPIO_ROUTE_SWOPEN) \
|| defined(GPIO_ROUTEPEN_SWVPEN) \
|| defined(GPIO_TRACEROUTEPEN_SWVPEN)
void DBG_SWOEnable(unsigned int location);
#endif
#if defined (EMU_CTRL_EM2DBGEN)
/***************************************************************************//**
* @brief
* Enable or disable debug support while in EM2 mode.
*
* @warning
* Disabling debug support in EM2 will reduce current consumption with 1-2 uA,
* but some debuggers will have problems regaining control over a device which
* is in EM2 and has debug support disabled.
*
* To remedy this, set the WSTK switch next to the battery holder to USB
* (powers down the EFR). Execute Simplicity Commander with command line
* parameters:
* "./commander.exe device recover"
* and then immediately move the switch to the AEM position. An additional
* "./commander.exe device masserase"
* command completes the recovery procedure.
*
* @param[in] enable
* Boolean true enables EM2 debug support, false disables.
******************************************************************************/
__STATIC_INLINE void DBG_EM2DebugEnable(bool enable)
{
if (enable) {
EMU->CTRL_SET = EMU_CTRL_EM2DBGEN;
} else {
EMU->CTRL_CLR = EMU_CTRL_EM2DBGEN;
}
}
#endif
/** @} (end addtogroup dbg) */
#ifdef __cplusplus
}
#endif
#endif /* defined( CoreDebug_DHCSR_C_DEBUGEN_Msk ) */
#endif /* EM_DBG_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,218 @@
/***************************************************************************//**
* @file
* @brief EUSART Compatibility Header
*******************************************************************************
* # License
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_EUSART_COMPAT_H
#define EM_EUSART_COMPAT_H
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2)
#define EUSART_IF_TXCIF EUSART_IF_TXC
#define _EUSART_IF_TXCIF_SHIFT _EUSART_IF_TXC_SHIFT
#define _EUSART_IF_TXCIF_MASK _EUSART_IF_TXC_MASK
#define _EUSART_IF_TXCIF_DEFAULT _EUSART_IF_TXC_DEFAULT
#define EUSART_IF_TXCIF_DEFAULT EUSART_IF_TXC_DEFAULT
#define EUSART_IF_TXFLIF EUSART_IF_TXFL
#define _EUSART_IF_TXFLIF_SHIFT _EUSART_IF_TXFL_SHIFT
#define _EUSART_IF_TXFLIF_MASK _EUSART_IF_TXFL_MASK
#define _EUSART_IF_TXFLIF_DEFAULT _EUSART_IF_TXFL_DEFAULT
#define EUSART_IF_TXFLIF_DEFAULT EUSART_IF_TXFL_DEFAULT
#define EUSART_IF_RXFLIF EUSART_IF_RXFL
#define _EUSART_IF_RXFLIF_SHIFT _EUSART_IF_RXFL_SHIFT
#define _EUSART_IF_RXFLIF_MASK _EUSART_IF_RXFL_MASK
#define _EUSART_IF_RXFLIF_DEFAULT _EUSART_IF_RXFL_DEFAULT
#define EUSART_IF_RXFLIF_DEFAULT EUSART_IF_RXFL_DEFAULT
#define EUSART_IF_RXFULLIF EUSART_IF_RXFULL
#define _EUSART_IF_RXFULLIF_SHIFT _EUSART_IF_RXFULL_SHIFT
#define _EUSART_IF_RXFULLIF_MASK _EUSART_IF_RXFULL_MASK
#define _EUSART_IF_RXFULLIF_DEFAULT _EUSART_IF_RXFULL_DEFAULT
#define EUSART_IF_RXFULLIF_DEFAULT EUSART_IF_RXFULL_DEFAULT
#define EUSART_IF_RXOFIF EUSART_IF_RXOF
#define _EUSART_IF_RXOFIF_SHIFT _EUSART_IF_RXOF_SHIFT
#define _EUSART_IF_RXOFIF_MASK _EUSART_IF_RXOF_MASK
#define _EUSART_IF_RXOFIF_DEFAULT _EUSART_IF_RXOF_DEFAULT
#define EUSART_IF_RXOFIF_DEFAULT EUSART_IF_RXOF_DEFAULT
#define EUSART_IF_RXUFIF EUSART_IF_RXUF
#define _EUSART_IF_RXUFIF_SHIFT _EUSART_IF_RXUF_SHIFT
#define _EUSART_IF_RXUFIF_MASK _EUSART_IF_RXUF_MASK
#define _EUSART_IF_RXUFIF_DEFAULT _EUSART_IF_RXUF_DEFAULT
#define EUSART_IF_RXUFIF_DEFAULT EUSART_IF_RXUF_DEFAULT
#define EUSART_IF_TXOFIF EUSART_IF_TXOF
#define _EUSART_IF_TXOFIF_SHIFT _EUSART_IF_TXOF_SHIFT
#define _EUSART_IF_TXOFIF_MASK _EUSART_IF_TXOF_MASK
#define _EUSART_IF_TXOFIF_DEFAULT _EUSART_IF_TXOF_DEFAULT
#define EUSART_IF_TXOFIF_DEFAULT EUSART_IF_TXOF_DEFAULT
#define EUSART_IF_PERRIF EUSART_IF_PERR
#define _EUSART_IF_PERRIF_SHIFT _EUSART_IF_PERR_SHIFT
#define _EUSART_IF_PERRIF_MASK _EUSART_IF_PERR_MASK
#define _EUSART_IF_PERRIF_DEFAULT _EUSART_IF_PERR_DEFAULT
#define EUSART_IF_PERRIF_DEFAULT EUSART_IF_PERR_DEFAULT
#define EUSART_IF_FERRIF EUSART_IF_FERR
#define _EUSART_IF_FERRIF_SHIFT _EUSART_IF_FERR_SHIFT
#define _EUSART_IF_FERRIF_MASK _EUSART_IF_FERR_MASK
#define _EUSART_IF_FERRIF_DEFAULT _EUSART_IF_FERR_DEFAULT
#define EUSART_IF_FERRIF_DEFAULT EUSART_IF_FERR_DEFAULT
#define EUSART_IF_MPAFIF EUSART_IF_MPAF
#define _EUSART_IF_MPAFIF_SHIFT _EUSART_IF_MPAF_SHIFT
#define _EUSART_IF_MPAFIF_MASK _EUSART_IF_MPAF_MASK
#define _EUSART_IF_MPAFIF_DEFAULT _EUSART_IF_MPAF_DEFAULT
#define EUSART_IF_MPAFIF_DEFAULT EUSART_IF_MPAF_DEFAULT
#define EUSART_IF_CCFIF EUSART_IF_CCF
#define _EUSART_IF_CCFIF_SHIFT _EUSART_IF_CCF_SHIFT
#define _EUSART_IF_CCFIF_MASK _EUSART_IF_CCF_MASK
#define _EUSART_IF_CCFIF_DEFAULT _EUSART_IF_CCF_DEFAULT
#define EUSART_IF_CCFIF_DEFAULT EUSART_IF_CCF_DEFAULT
#define EUSART_IF_TXIDLEIF EUSART_IF_TXIDLE
#define _EUSART_IF_TXIDLEIF_SHIFT _EUSART_IF_TXIDLE_SHIFT
#define _EUSART_IF_TXIDLEIF_MASK _EUSART_IF_TXIDLE_MASK
#define _EUSART_IF_TXIDLEIF_DEFAULT _EUSART_IF_TXIDLE_DEFAULT
#define EUSART_IF_TXIDLEIF_DEFAULT EUSART_IF_TXIDLE_DEFAULT
#define EUSART_IF_STARTFIF EUSART_IF_STARTF
#define _EUSART_IF_STARTFIF_SHIFT _EUSART_IF_STARTF_SHIFT
#define _EUSART_IF_STARTFIF_MASK _EUSART_IF_STARTF_MASK
#define _EUSART_IF_STARTFIF_DEFAULT _EUSART_IF_STARTF_DEFAULT
#define EUSART_IF_STARTFIF_DEFAULT EUSART_IF_STARTF_DEFAULT
#define EUSART_IF_SIGFIF EUSART_IF_SIGF
#define _EUSART_IF_SIGFIF_SHIFT _EUSART_IF_SIGF_SHIFT
#define _EUSART_IF_SIGFIF_MASK _EUSART_IF_SIGF_MASK
#define _EUSART_IF_SIGFIF_DEFAULT _EUSART_IF_SIGF_DEFAULT
#define EUSART_IF_SIGFIF_DEFAULT EUSART_IF_SIGF_DEFAULT
#define EUSART_IF_AUTOBAUDDONEIF EUSART_IF_AUTOBAUDDONE
#define _EUSART_IF_AUTOBAUDDONEIF_SHIFT _EUSART_IF_AUTOBAUDDONE_SHIFT
#define _EUSART_IF_AUTOBAUDDONEIF_MASK _EUSART_IF_AUTOBAUDDONE_MASK
#define _EUSART_IF_AUTOBAUDDONEIF_DEFAULT _EUSART_IF_AUTOBAUDDONE_DEFAULT
#define EUSART_IF_AUTOBAUDDONEIF_DEFAULT EUSART_IF_AUTOBAUDDONE_DEFAULT
#define EUSART_IEN_TXCIEN EUSART_IEN_TXC
#define _EUSART_IEN_TXCIEN_SHIFT _EUSART_IEN_TXC_SHIFT
#define _EUSART_IEN_TXCIEN_MASK _EUSART_IEN_TXC_MASK
#define _EUSART_IEN_TXCIEN_DEFAULT _EUSART_IEN_TXC_DEFAULT
#define EUSART_IEN_TXCIEN_DEFAULT EUSART_IEN_TXC_DEFAULT
#define EUSART_IEN_TXFLIEN EUSART_IEN_TXFL
#define _EUSART_IEN_TXFLIEN_SHIFT _EUSART_IEN_TXFL_SHIFT
#define _EUSART_IEN_TXFLIEN_MASK _EUSART_IEN_TXFL_MASK
#define _EUSART_IEN_TXFLIEN_DEFAULT _EUSART_IEN_TXFL_DEFAULT
#define EUSART_IEN_TXFLIEN_DEFAULT EUSART_IEN_TXFL_DEFAULT
#define EUSART_IEN_RXFLIEN EUSART_IEN_RXFL
#define _EUSART_IEN_RXFLIEN_SHIFT _EUSART_IEN_RXFL_SHIFT
#define _EUSART_IEN_RXFLIEN_MASK _EUSART_IEN_RXFL_MASK
#define _EUSART_IEN_RXFLIEN_DEFAULT _EUSART_IEN_RXFL_DEFAULT
#define EUSART_IEN_RXFLIEN_DEFAULT EUSART_IEN_RXFL_DEFAULT
#define EUSART_IEN_RXFULLIEN EUSART_IEN_RXFULL
#define _EUSART_IEN_RXFULLIEN_SHIFT _EUSART_IEN_RXFULL_SHIFT
#define _EUSART_IEN_RXFULLIEN_MASK _EUSART_IEN_RXFULL_MASK
#define _EUSART_IEN_RXFULLIEN_DEFAULT _EUSART_IEN_RXFULL_DEFAULT
#define EUSART_IEN_RXFULLIEN_DEFAULT EUSART_IEN_RXFULL_DEFAULT
#define EUSART_IEN_RXOFIEN EUSART_IEN_RXOF
#define _EUSART_IEN_RXOFIEN_SHIFT _EUSART_IEN_RXOF_SHIFT
#define _EUSART_IEN_RXOFIEN_MASK _EUSART_IEN_RXOF_MASK
#define _EUSART_IEN_RXOFIEN_DEFAULT _EUSART_IEN_RXOF_DEFAULT
#define EUSART_IEN_RXOFIEN_DEFAULT EUSART_IEN_RXOF_DEFAULT
#define EUSART_IEN_RXUFIEN EUSART_IEN_RXUF
#define _EUSART_IEN_RXUFIEN_SHIFT _EUSART_IEN_RXUF_SHIFT
#define _EUSART_IEN_RXUFIEN_MASK _EUSART_IEN_RXUF_MASK
#define _EUSART_IEN_RXUFIEN_DEFAULT _EUSART_IEN_RXUF_DEFAULT
#define EUSART_IEN_RXUFIEN_DEFAULT EUSART_IEN_RXUF_DEFAULT
#define EUSART_IEN_TXOFIEN EUSART_IEN_TXOF
#define _EUSART_IEN_TXOFIEN_SHIFT _EUSART_IEN_TXOF_SHIFT
#define _EUSART_IEN_TXOFIEN_MASK _EUSART_IEN_TXOF_MASK
#define _EUSART_IEN_TXOFIEN_DEFAULT _EUSART_IEN_TXOF_DEFAULT
#define EUSART_IEN_TXOFIEN_DEFAULT EUSART_IEN_TXOF_DEFAULT
#define EUSART_IEN_PERRIEN EUSART_IEN_PERR
#define _EUSART_IEN_PERRIEN_SHIFT _EUSART_IEN_PERR_SHIFT
#define _EUSART_IEN_PERRIEN_MASK _EUSART_IEN_PERR_MASK
#define _EUSART_IEN_PERRIEN_DEFAULT _EUSART_IEN_PERR_DEFAULT
#define EUSART_IEN_PERRIEN_DEFAULT EUSART_IEN_PERR_DEFAULT
#define EUSART_IEN_FERRIEN EUSART_IEN_FERR
#define _EUSART_IEN_FERRIEN_SHIFT _EUSART_IEN_FERR_SHIFT
#define _EUSART_IEN_FERRIEN_MASK _EUSART_IEN_FERR_MASK
#define _EUSART_IEN_FERRIEN_DEFAULT _EUSART_IEN_FERR_DEFAULT
#define EUSART_IEN_FERRIEN_DEFAULT EUSART_IEN_FERR_DEFAULT
#define EUSART_IEN_MPAFIEN EUSART_IEN_MPAF
#define _EUSART_IEN_MPAFIEN_SHIFT _EUSART_IEN_MPAF_SHIFT
#define _EUSART_IEN_MPAFIEN_MASK _EUSART_IEN_MPAF_MASK
#define _EUSART_IEN_MPAFIEN_DEFAULT _EUSART_IEN_MPAF_DEFAULT
#define EUSART_IEN_MPAFIEN_DEFAULT EUSART_IEN_MPAF_DEFAULT
#define EUSART_IEN_CCFIEN EUSART_IEN_CCF
#define _EUSART_IEN_CCFIEN_SHIFT _EUSART_IEN_CCF_SHIFT
#define _EUSART_IEN_CCFIEN_MASK _EUSART_IEN_CCF_MASK
#define _EUSART_IEN_CCFIEN_DEFAULT _EUSART_IEN_CCF_DEFAULT
#define EUSART_IEN_CCFIEN_DEFAULT EUSART_IEN_CCF_DEFAULT
#define EUSART_IEN_TXIDLEIEN EUSART_IEN_TXIDLE
#define _EUSART_IEN_TXIDLEIEN_SHIFT _EUSART_IEN_TXIDLE_SHIFT
#define _EUSART_IEN_TXIDLEIEN_MASK _EUSART_IEN_TXIDLE_MASK
#define _EUSART_IEN_TXIDLEIEN_DEFAULT _EUSART_IEN_TXIDLE_DEFAULT
#define EUSART_IEN_TXIDLEIEN_DEFAULT EUSART_IEN_TXIDLE_DEFAULT
#define EUSART_IEN_STARTFIEN EUSART_IEN_STARTF
#define _EUSART_IEN_STARTFIEN_SHIFT _EUSART_IEN_STARTF_SHIFT
#define _EUSART_IEN_STARTFIEN_MASK _EUSART_IEN_STARTF_MASK
#define _EUSART_IEN_STARTFIEN_DEFAULT _EUSART_IEN_STARTF_DEFAULT
#define EUSART_IEN_STARTFIEN_DEFAULT EUSART_IEN_STARTF_DEFAULT
#define EUSART_IEN_SIGFIEN EUSART_IEN_SIGF
#define _EUSART_IEN_SIGFIEN_SHIFT _EUSART_IEN_SIGF_SHIFT
#define _EUSART_IEN_SIGFIEN_MASK _EUSART_IEN_SIGF_MASK
#define _EUSART_IEN_SIGFIEN_DEFAULT _EUSART_IEN_SIGF_DEFAULT
#define EUSART_IEN_SIGFIEN_DEFAULT EUSART_IEN_SIGF_DEFAULT
#define EUSART_IEN_AUTOBAUDDONEIEN EUSART_IEN_AUTOBAUDDONE
#define _EUSART_IEN_AUTOBAUDDONEIEN_SHIFT _EUSART_IEN_AUTOBAUDDONE_SHIFT
#define _EUSART_IEN_AUTOBAUDDONEIEN_MASK _EUSART_IEN_AUTOBAUDDONE_MASK
#define _EUSART_IEN_AUTOBAUDDONEIEN_DEFAULT _EUSART_IEN_AUTOBAUDDONE_DEFAULT
#define EUSART_IEN_AUTOBAUDDONEIEN_DEFAULT EUSART_IEN_AUTOBAUDDONE_DEFAULT
#endif // _SILICON_LABS_32B_SERIES_2_CONFIG_2
#endif

View File

@@ -0,0 +1,346 @@
/***************************************************************************//**
* @file
* @brief General Purpose Cyclic Redundancy Check (GPCRC) API.
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_GPCRC_H
#define EM_GPCRC_H
#include "em_bus.h"
#include "em_device.h"
#if defined(GPCRC_PRESENT) && (GPCRC_COUNT > 0)
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup gpcrc GPCRC - General Purpose CRC
* @brief General Purpose Cyclic Redundancy Check (GPCRC) API
*
* @details
* The GPCRC API functions provide full support for the GPCRC peripheral.
*
* The GPCRC module is a peripheral that implements a Cyclic Redundancy Check
* (CRC) function. It supports a fixed 32-bit polynomial and a user
* configurable 16-bit polynomial. The fixed 32-bit polynomial is the commonly
* used IEEE 802.3 polynomial 0x04C11DB7.
*
* When using a 16-bit polynomial it is up to the user to choose a polynomial
* that fits the application. Commonly used 16-bit polynomials are 0x1021
* (CCITT-16), 0x3D65 (IEC16-MBus), and 0x8005 (ZigBee, 802.15.4, and USB).
* See this link for other polynomials:
* https://en.wikipedia.org/wiki/Cyclic_redundancy_check
*
* Before a CRC calculation can begin, call the
* @ref GPCRC_Start function. This function will reset CRC calculation
* by copying the configured initialization value over to the CRC data register.
*
* There are two ways of sending input data to the GPCRC. Either write
* the input data into the input data register using input functions
* @ref GPCRC_InputU32, @ref GPCRC_InputU16 and @ref GPCRC_InputU8, or the
* user can configure @ref ldma to transfer data directly to one of the GPCRC
* input data registers.
*
* <b> Examples of GPCRC usage: </b>
*
* A CRC-32 Calculation:
*
* @include em_gpcrc_crc32.c
*
* A CRC-16 Calculation:
*
* @include em_gpcrc_crc16.c
*
* A CRC-CCITT calculation:
*
* @include em_gpcrc_ccit.c
*
* @{
******************************************************************************/
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** CRC initialization structure. */
typedef struct {
/**
* CRC polynomial value. GPCRC supports either a fixed 32-bit polynomial
* or a user-configurable 16 bit polynomial. The fixed 32-bit polynomial
* is the one used in IEEE 802.3, which has the value 0x04C11DB7. To use the
* 32-bit fixed polynomial, assign 0x04C11DB7 to the crcPoly field.
* To use a 16-bit polynomial, assign a value to crcPoly where the upper 16
* bits are zero.
*
* The polynomial should be written in normal bit order. For instance,
* to use the CRC-16 polynomial X^16 + X^15 + X^2 + 1, first convert
* it to hex representation and remove the highest order term
* of the polynomial. This will give 0x8005 as the value to write into
* crcPoly.
*/
uint32_t crcPoly;
/**
* CRC initialization value. This value is assigned to the GPCRC_INIT register.
* The initValue is loaded into the data register when calling the
* @ref GPCRC_Start function or when one of the data registers are read
* while @ref autoInit is enabled.
*/
uint32_t initValue;
/**
* Reverse byte order. This has an effect when sending a 32-bit word or
* 16-bit half word input to the CRC calculation. When set to true, the input
* bytes are reversed before entering the CRC calculation. When set to
* false, the input bytes stay in the same order.
*/
bool reverseByteOrder;
/**
* Reverse bits within each input byte. This setting enables or disables byte
* level bit reversal. When byte-level bit reversal is enabled, then each byte
* of input data will be reversed before entering CRC calculation.
*/
bool reverseBits;
/**
* Enable/disable byte mode. When byte mode is enabled, then all input
* is treated as single byte input even though the input is a 32-bit word
* or a 16-bit half word. Only the least significant byte of the data-word
* will be used for CRC calculation for all writes.
*/
bool enableByteMode;
/**
* Enable automatic initialization by re-seeding the CRC result based on
* the init value after reading one of the CRC data registers.
*/
bool autoInit;
/** Enable/disable GPCRC when initialization is completed. */
bool enable;
} GPCRC_Init_TypeDef;
/** Default configuration for GPCRC_Init_TypeDef structure. */
#define GPCRC_INIT_DEFAULT \
{ \
0x04C11DB7UL, /* CRC32 Polynomial value. */ \
0x00000000UL, /* Initialization value. */ \
false, /* Byte order is normal. */ \
false, /* Bit order is not reversed on output. */ \
false, /* Disable byte mode. */ \
false, /* Disable automatic initialization on data read. */ \
true, /* Enable GPCRC. */ \
}
/*******************************************************************************
****************************** PROTOTYPES *********************************
******************************************************************************/
void GPCRC_Init(GPCRC_TypeDef * gpcrc, const GPCRC_Init_TypeDef * init);
void GPCRC_Reset(GPCRC_TypeDef * gpcrc);
/***************************************************************************//**
* @brief
* Enable/disable GPCRC.
*
* @param[in] gpcrc
* Pointer to GPCRC peripheral register block.
*
* @param[in] enable
* True to enable GPCRC, false to disable.
******************************************************************************/
__STATIC_INLINE void GPCRC_Enable(GPCRC_TypeDef * gpcrc, bool enable)
{
#if defined(GPCRC_EN_EN)
BUS_RegBitWrite(&gpcrc->EN, _GPCRC_EN_EN_SHIFT, enable);
#else
BUS_RegBitWrite(&gpcrc->CTRL, _GPCRC_CTRL_EN_SHIFT, enable);
#endif
}
/***************************************************************************//**
* @brief
* Issue a command to initialize the CRC calculation.
*
* @details
* Issues the command INIT in GPCRC_CMD that initializes the
* CRC calculation by writing the initial values to the DATA register.
*
* @param[in] gpcrc
* Pointer to GPCRC peripheral register block.
******************************************************************************/
__STATIC_INLINE void GPCRC_Start(GPCRC_TypeDef * gpcrc)
{
gpcrc->CMD = GPCRC_CMD_INIT;
}
/***************************************************************************//**
* @brief
* Set the initialization value of the CRC.
*
* @param [in] initValue
* Value to use to initialize a CRC calculation. This value is moved into
* the data register when calling @ref GPCRC_Start
*
* @param[in] gpcrc
* Pointer to GPCRC peripheral register block.
******************************************************************************/
__STATIC_INLINE void GPCRC_InitValueSet(GPCRC_TypeDef * gpcrc, uint32_t initValue)
{
gpcrc->INIT = initValue;
}
/***************************************************************************//**
* @brief
* Write a 32-bit value to the input data register of the CRC.
*
* @details
* Use this function to write a 32-bit input data to the CRC. CRC
* calculation is based on the provided input data using the configured
* CRC polynomial.
*
* @param[in] gpcrc
* Pointer to GPCRC peripheral register block.
*
* @param[in] data
* Data to be written to the input data register.
******************************************************************************/
__STATIC_INLINE void GPCRC_InputU32(GPCRC_TypeDef * gpcrc, uint32_t data)
{
gpcrc->INPUTDATA = data;
}
/***************************************************************************//**
* @brief
* Write a 16-bit value to the input data register of the CRC.
*
* @details
* Use this function to write a 16 bit input data to the CRC. CRC
* calculation is based on the provided input data using the configured
* CRC polynomial.
*
* @param[in] gpcrc
* Pointer to GPCRC peripheral register block.
*
* @param[in] data
* Data to be written to the input data register.
******************************************************************************/
__STATIC_INLINE void GPCRC_InputU16(GPCRC_TypeDef * gpcrc, uint16_t data)
{
gpcrc->INPUTDATAHWORD = data;
}
/***************************************************************************//**
* @brief
* Write an 8-bit value to the CRC input data register.
*
* @details
* Use this function to write an 8-bit input data to the CRC. CRC
* calculation is based on the provided input data using the configured
* CRC polynomial.
*
* @param[in] gpcrc
* Pointer to GPCRC peripheral register block.
*
* @param[in] data
* Data to be written to the input data register.
******************************************************************************/
__STATIC_INLINE void GPCRC_InputU8(GPCRC_TypeDef * gpcrc, uint8_t data)
{
gpcrc->INPUTDATABYTE = data;
}
/***************************************************************************//**
* @brief
* Read the CRC data register.
*
* @details
* Use this function to read the calculated CRC value.
*
* @param[in] gpcrc
* Pointer to GPCRC peripheral register block.
*
* @return
* Content of the CRC data register.
******************************************************************************/
__STATIC_INLINE uint32_t GPCRC_DataRead(GPCRC_TypeDef * gpcrc)
{
return gpcrc->DATA;
}
/***************************************************************************//**
* @brief
* Read the data register of the CRC bit reversed.
*
* @details
* Use this function to read the calculated CRC value bit reversed. When
* using a 32-bit polynomial, bits [31:0] are reversed, when using a
* 16-bit polynomial, bits [15:0] are reversed.
*
* @param[in] gpcrc
* Pointer to GPCRC peripheral register block.
*
* @return
* Content of the CRC data register bit reversed.
******************************************************************************/
__STATIC_INLINE uint32_t GPCRC_DataReadBitReversed(GPCRC_TypeDef * gpcrc)
{
return gpcrc->DATAREV;
}
/***************************************************************************//**
* @brief
* Read the data register of the CRC byte reversed.
*
* @details
* Use this function to read the calculated CRC value byte reversed.
*
* @param[in] gpcrc
* Pointer to GPCRC peripheral register block.
*
* @return
* Content of the CRC data register byte reversed.
******************************************************************************/
__STATIC_INLINE uint32_t GPCRC_DataReadByteReversed(GPCRC_TypeDef * gpcrc)
{
return gpcrc->DATABYTEREV;
}
/** @} (end addtogroup gpcrc) */
#ifdef __cplusplus
}
#endif
#endif /* defined(GPCRC_COUNT) && (GPCRC_COUNT > 0) */
#endif /* EM_GPCRC_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,525 @@
/***************************************************************************//**
* @file
* @brief Inter-integrated circuit (I2C) peripheral API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_I2C_H
#define EM_I2C_H
#include "em_device.h"
#if defined(I2C_COUNT) && (I2C_COUNT > 0)
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup i2c
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/**
* @brief
* Standard mode max frequency assuming using 4:4 ratio for Nlow:Nhigh.
* @details
* From I2C specification: Min Tlow = 4.7us, min Thigh = 4.0us,
* max Trise=1.0us, max Tfall=0.3us. Since ratio is 4:4, have to use
* worst case value of Tlow or Thigh as base.
*
* 1/(Tlow + Thigh + 1us + 0.3us) = 1/(4.7 + 4.7 + 1.3)us = 93458Hz
* @note
* Due to chip characteristics, max value is somewhat reduced.
*/
#if defined(_SILICON_LABS_32B_SERIES_0) \
&& (defined(_EFM32_GECKO_FAMILY) \
|| defined(_EFM32_TINY_FAMILY) \
|| defined(_EFM32_ZERO_FAMILY) \
|| defined(_EFM32_HAPPY_FAMILY))
#define I2C_FREQ_STANDARD_MAX 93000
#elif defined(_SILICON_LABS_32B_SERIES_0) \
&& (defined(_EFM32_GIANT_FAMILY) \
|| defined(_EFM32_WONDER_FAMILY))
#define I2C_FREQ_STANDARD_MAX 92000
#elif defined(_SILICON_LABS_32B_SERIES_1)
// None of the chips on this platform has been characterized on this parameter.
// Use same value as on Wonder until further notice.
#define I2C_FREQ_STANDARD_MAX 92000
#elif defined(_SILICON_LABS_32B_SERIES_2)
#define I2C_FREQ_STANDARD_MAX 100000
#else
#error "Unknown device family."
#endif
/**
* @brief
* Fast mode max frequency assuming using 6:3 ratio for Nlow:Nhigh.
* @details
* From I2C specification: Min Tlow = 1.3us, min Thigh = 0.6us,
* max Trise=0.3us, max Tfall=0.3us. Since ratio is 6:3, have to use
* worst case value of Tlow or 2xThigh as base.
*
* 1/(Tlow + Thigh + 0.3us + 0.3us) = 1/(1.3 + 0.65 + 0.6)us = 392157Hz
*/
#define I2C_FREQ_FAST_MAX 392157
/**
* @brief
* Fast mode+ max frequency assuming using 11:6 ratio for Nlow:Nhigh.
* @details
* From I2C specification: Min Tlow = 0.5us, min Thigh = 0.26us,
* max Trise=0.12us, max Tfall=0.12us. Since ratio is 11:6, have to use
* worst case value of Tlow or (11/6)xThigh as base.
*
* 1/(Tlow + Thigh + 0.12us + 0.12us) = 1/(0.5 + 0.273 + 0.24)us = 987167Hz
*/
#define I2C_FREQ_FASTPLUS_MAX 987167
/**
* @brief
* Indicate plain write sequence: S+ADDR(W)+DATA0+P.
* @details
* @li S - Start
* @li ADDR(W) - address with W/R bit cleared
* @li DATA0 - Data taken from buffer with index 0
* @li P - Stop
*/
#define I2C_FLAG_WRITE 0x0001
/**
* @brief
* Indicate plain read sequence: S+ADDR(R)+DATA0+P.
* @details
* @li S - Start
* @li ADDR(R) - Address with W/R bit set
* @li DATA0 - Data read into buffer with index 0
* @li P - Stop
*/
#define I2C_FLAG_READ 0x0002
/**
* @brief
* Indicate combined write/read sequence: S+ADDR(W)+DATA0+Sr+ADDR(R)+DATA1+P.
* @details
* @li S - Start
* @li Sr - Repeated start
* @li ADDR(W) - Address with W/R bit cleared
* @li ADDR(R) - Address with W/R bit set
* @li DATAn - Data written from/read into buffer with index n
* @li P - Stop
*/
#define I2C_FLAG_WRITE_READ 0x0004
/**
* @brief
* Indicate write sequence using two buffers: S+ADDR(W)+DATA0+DATA1+P.
* @details
* @li S - Start
* @li ADDR(W) - Address with W/R bit cleared
* @li DATAn - Data written from buffer with index n
* @li P - Stop
*/
#define I2C_FLAG_WRITE_WRITE 0x0008
/** Use 10 bit address. */
#define I2C_FLAG_10BIT_ADDR 0x0010
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Clock low to high ratio settings. */
typedef enum {
i2cClockHLRStandard = _I2C_CTRL_CLHR_STANDARD, /**< Ratio is 4:4 */
i2cClockHLRAsymetric = _I2C_CTRL_CLHR_ASYMMETRIC, /**< Ratio is 6:3 */
i2cClockHLRFast = _I2C_CTRL_CLHR_FAST /**< Ratio is 11:3 */
} I2C_ClockHLR_TypeDef;
/** Return codes for single Controller mode transfer function. */
typedef enum {
/* In progress code (>0) */
i2cTransferInProgress = 1, /**< Transfer in progress. */
/* Complete code (=0) */
i2cTransferDone = 0, /**< Transfer completed successfully. */
/* Transfer error codes (<0). */
i2cTransferNack = -1, /**< NACK received during transfer. */
i2cTransferBusErr = -2, /**< Bus error during transfer (misplaced START/STOP). */
i2cTransferArbLost = -3, /**< Arbitration lost during transfer. */
i2cTransferUsageFault = -4, /**< Usage fault. */
i2cTransferSwFault = -5 /**< SW fault. */
} I2C_TransferReturn_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** I2C initialization structure. */
typedef struct {
/** Enable I2C peripheral when initialization completed. */
bool enable;
/** Set to Controller (true) or Target (false) mode */
bool master;
/**
* I2C reference clock assumed when configuring bus frequency setup.
* Set it to 0 if currently configured reference clock will be used
* This parameter is only applicable if operating in Controller mode.
*/
uint32_t refFreq;
/**
* (Max) I2C bus frequency to use. This parameter is only applicable
* if operating in Controller mode.
*/
uint32_t freq;
/** Clock low/high ratio control. */
I2C_ClockHLR_TypeDef clhr;
} I2C_Init_TypeDef;
/** Suggested default configuration for I2C initialization structure. */
#define I2C_INIT_DEFAULT \
{ \
true, /* Enable when initialization done. */ \
true, /* Set to Controller mode. */ \
0, /* Use currently configured reference clock. */ \
I2C_FREQ_STANDARD_MAX, /* Set to standard rate assuring being */ \
/* within I2C specification. */ \
i2cClockHLRStandard /* Set to use 4:4 low/high duty cycle. */ \
}
/**
* @brief
* Master mode transfer message structure used to define a complete
* I2C transfer sequence (from start to stop).
* @details
* The structure allows for defining the following types of sequences
* (refer to defines for sequence details):
* @li #I2C_FLAG_READ - Data read into buf[0].data
* @li #I2C_FLAG_WRITE - Data written from buf[0].data
* @li #I2C_FLAG_WRITE_READ - Data written from buf[0].data and read
* into buf[1].data
* @li #I2C_FLAG_WRITE_WRITE - Data written from buf[0].data and
* buf[1].data
*/
typedef struct {
/**
* @brief
* Address to use after (repeated) start.
* @details
* Layout details, A = Address bit, X = don't care bit (set to 0):
* @li 7 bit address - Use format AAAA AAAX
* @li 10 bit address - Use format XXXX XAAX AAAA AAAA
*/
uint16_t addr;
/** Flags defining sequence type and details, see I2C_FLAG_ defines. */
uint16_t flags;
/**
* Buffers used to hold data to send from or receive into, depending
* on sequence type.
*/
struct {
/** Buffer used for data to transmit/receive, must be @p len long. */
uint8_t *data;
/**
* Number of bytes in @p data to send or receive. Notice that when
* receiving data to this buffer, at least 1 byte must be received.
* Setting @p len to 0 in the receive case is considered a usage fault.
* Transmitting 0 bytes is legal, in which case only the address
* is transmitted after the start condition.
*/
uint16_t len;
} buf[2];
} I2C_TransferSeq_TypeDef;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c);
void I2C_BusFreqSet(I2C_TypeDef *i2c,
uint32_t freqRef,
uint32_t freqScl,
I2C_ClockHLR_TypeDef i2cMode);
void I2C_Enable(I2C_TypeDef *i2c, bool enable);
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init);
/***************************************************************************//**
* @brief
* Clear one or more pending I2C interrupts.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] flags
* Pending I2C interrupt source to clear. Use a bitwise logic OR combination of
* valid interrupt flags for the I2C module (I2C_IF_nnn).
******************************************************************************/
__STATIC_INLINE void I2C_IntClear(I2C_TypeDef *i2c, uint32_t flags)
{
#if defined (I2C_HAS_SET_CLEAR)
i2c->IF_CLR = flags;
#else
i2c->IFC = flags;
#endif
}
/***************************************************************************//**
* @brief
* Disable one or more I2C interrupts.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] flags
* I2C interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the I2C module (I2C_IF_nnn).
******************************************************************************/
__STATIC_INLINE void I2C_IntDisable(I2C_TypeDef *i2c, uint32_t flags)
{
#if defined (I2C_HAS_SET_CLEAR)
i2c->IEN_CLR = flags;
#else
i2c->IEN &= ~(flags);
#endif
}
/***************************************************************************//**
* @brief
* Enable one or more I2C 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
* I2C_IntClear() prior to enabling the interrupt.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] flags
* I2C interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the I2C module (I2C_IF_nnn).
******************************************************************************/
__STATIC_INLINE void I2C_IntEnable(I2C_TypeDef *i2c, uint32_t flags)
{
#if defined (I2C_HAS_SET_CLEAR)
i2c->IEN_SET = flags;
#else
i2c->IEN |= flags;
#endif
}
/***************************************************************************//**
* @brief
* Get pending I2C interrupt flags.
*
* @note
* Event bits are not cleared by the use of this function.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* I2C interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for the I2C module (I2C_IF_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t I2C_IntGet(I2C_TypeDef *i2c)
{
return i2c->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending I2C interrupt flags.
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @note
* Interrupt flags are not cleared by the use of this function.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* Pending and enabled I2C interrupt sources
* Return value is the bitwise AND of
* - the enabled interrupt sources in I2Cn_IEN and
* - the pending interrupt flags I2Cn_IF
******************************************************************************/
__STATIC_INLINE uint32_t I2C_IntGetEnabled(I2C_TypeDef *i2c)
{
uint32_t ien;
ien = i2c->IEN;
return i2c->IF & ien;
}
/***************************************************************************//**
* @brief
* Set one or more pending I2C interrupts from SW.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] flags
* I2C interrupt sources to set to pending. Use a bitwise logic OR combination
* of valid interrupt flags for the I2C module (I2C_IF_nnn).
******************************************************************************/
__STATIC_INLINE void I2C_IntSet(I2C_TypeDef *i2c, uint32_t flags)
{
#if defined (I2C_HAS_SET_CLEAR)
i2c->IF_SET = flags;
#else
i2c->IFS = flags;
#endif
}
void I2C_Reset(I2C_TypeDef *i2c);
/***************************************************************************//**
* @brief
* Get Target address used for I2C peripheral (when operating in Target mode).
*
* @details
* For 10-bit addressing mode, the address is split in two bytes, and only
* the first byte setting is fetched, effectively only controlling the 2 most
* significant bits of the 10-bit address. Full handling of 10-bit addressing
* in Target mode requires additional SW handling.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* I2C Target address in use. The 7 most significant bits define the actual
* address, the least significant bit is reserved and always returned as 0.
******************************************************************************/
__STATIC_INLINE uint8_t I2C_SlaveAddressGet(I2C_TypeDef *i2c)
{
return ((uint8_t)(i2c->SADDR));
}
/***************************************************************************//**
* @brief
* Set Target address to use for I2C peripheral (when operating in Target mode).
*
* @details
* For 10- bit addressing mode, the address is split in two bytes, and only
* the first byte is set, effectively only controlling the 2 most significant
* bits of the 10-bit address. Full handling of 10-bit addressing in Target
* mode requires additional SW handling.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] addr
* I2C Target address to use. The 7 most significant bits define the actual
* address, the least significant bit is reserved and always set to 0.
******************************************************************************/
__STATIC_INLINE void I2C_SlaveAddressSet(I2C_TypeDef *i2c, uint8_t addr)
{
i2c->SADDR = (uint32_t)addr & 0xfe;
}
/***************************************************************************//**
* @brief
* Get Target address mask used for I2C peripheral (when operating in Target
* mode).
*
* @details
* The address mask defines how the comparator works. A bit position with
* value 0 means that the corresponding Target address bit is ignored during
* comparison (don't care). A bit position with value 1 means that the
* corresponding Target address bit must match.
*
* For 10-bit addressing mode, the address is split in two bytes, and only
* the mask for the first address byte is fetched, effectively only
* controlling the 2 most significant bits of the 10-bit address.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* I2C Target address mask in use. The 7 most significant bits define the
* actual address mask, the least significant bit is reserved and always
* returned as 0.
******************************************************************************/
__STATIC_INLINE uint8_t I2C_SlaveAddressMaskGet(I2C_TypeDef *i2c)
{
return ((uint8_t)(i2c->SADDRMASK));
}
/***************************************************************************//**
* @brief
* Set Target address mask used for I2C peripheral (when operating in Target
* mode).
*
* @details
* The address mask defines how the comparator works. A bit position with
* value 0 means that the corresponding Target address bit is ignored during
* comparison (don't care). A bit position with value 1 means that the
* corresponding Target address bit must match.
*
* For 10-bit addressing mode, the address is split in two bytes, and only
* the mask for the first address byte is set, effectively only controlling
* the 2 most significant bits of the 10-bit address.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] mask
* I2C Target address mask to use. The 7 most significant bits define the
* actual address mask, the least significant bit is reserved and should
* be 0.
******************************************************************************/
__STATIC_INLINE void I2C_SlaveAddressMaskSet(I2C_TypeDef *i2c, uint8_t mask)
{
i2c->SADDRMASK = (uint32_t)mask & 0xfe;
}
I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c);
I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
I2C_TransferSeq_TypeDef *seq);
/** @} (end addtogroup i2c) */
#ifdef __cplusplus
}
#endif
#endif /* defined(I2C_COUNT) && (I2C_COUNT > 0) */
#endif /* EM_I2C_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,334 @@
/***************************************************************************//**
* @file
* @brief Low Energy Timer (LETIMER) peripheral API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_LETIMER_H
#define EM_LETIMER_H
#include <stdbool.h>
#include "em_device.h"
#if defined(LETIMER_COUNT) && (LETIMER_COUNT > 0)
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup letimer
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Repeat mode. */
typedef enum {
/** Count until stopped by SW. */
letimerRepeatFree = _LETIMER_CTRL_REPMODE_FREE,
/** Count REP0 times. */
letimerRepeatOneshot = _LETIMER_CTRL_REPMODE_ONESHOT,
/**
* Count REP0 times, if REP1 has been written to, it is loaded into
* REP0 when REP0 is about to be decremented to 0.
*/
letimerRepeatBuffered = _LETIMER_CTRL_REPMODE_BUFFERED,
/**
* Run as long as both REP0 and REP1 are not 0. Both REP0 and REP1
* are decremented when counter underflows.
*/
letimerRepeatDouble = _LETIMER_CTRL_REPMODE_DOUBLE
} LETIMER_RepeatMode_TypeDef;
/** Underflow action on output. */
typedef enum {
/** No output action. */
letimerUFOANone = _LETIMER_CTRL_UFOA0_NONE,
/** Toggle output when counter underflows. */
letimerUFOAToggle = _LETIMER_CTRL_UFOA0_TOGGLE,
/** Hold output one LETIMER clock cycle when counter underflows. */
letimerUFOAPulse = _LETIMER_CTRL_UFOA0_PULSE,
/** Set output idle when counter underflows, and active when matching COMP1. */
letimerUFOAPwm = _LETIMER_CTRL_UFOA0_PWM
} LETIMER_UFOA_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** LETIMER initialization structure. */
typedef struct {
bool enable; /**< Start counting when initialization completes. */
bool debugRun; /**< Counter shall keep running during debug halt. */
#if defined(LETIMER_CTRL_RTCC0TEN)
bool rtcComp0Enable; /**< Start counting on RTC COMP0 match. */
bool rtcComp1Enable; /**< Start counting on RTC COMP1 match. */
#endif
bool comp0Top; /**< Load COMP0 register into CNT when counter underflows. */
bool bufTop; /**< Load COMP1 into COMP0 when REP0 reaches 0. */
uint8_t out0Pol; /**< Idle value for output 0. */
uint8_t out1Pol; /**< Idle value for output 1. */
LETIMER_UFOA_TypeDef ufoa0; /**< Underflow output 0 action. */
LETIMER_UFOA_TypeDef ufoa1; /**< Underflow output 1 action. */
LETIMER_RepeatMode_TypeDef repMode; /**< Repeat mode. */
uint32_t topValue; /**< Top value. Counter wraps when top value matches counter value is reached. */
} LETIMER_Init_TypeDef;
/** Default configuration for LETIMER initialization structure. */
#if defined(LETIMER_CTRL_RTCC0TEN)
#define LETIMER_INIT_DEFAULT \
{ \
true, /* Enable timer when initialization completes. */ \
false, /* Stop counter during debug halt. */ \
false, /* Do not start counting on RTC COMP0 match. */ \
false, /* Do not start counting on RTC COMP1 match. */ \
false, /* Do not load COMP0 into CNT on underflow. */ \
false, /* Do not load COMP1 into COMP0 when REP0 reaches 0. */ \
0, /* Idle value 0 for output 0. */ \
0, /* Idle value 0 for output 1. */ \
letimerUFOANone, /* No action on underflow on output 0. */ \
letimerUFOANone, /* No action on underflow on output 1. */ \
letimerRepeatFree, /* Count until stopped by SW. */ \
0 /* Use default top Value. */ \
}
#else
#define LETIMER_INIT_DEFAULT \
{ \
true, /* Enable timer when initialization completes. */ \
false, /* Stop counter during debug halt. */ \
false, /* Do not load COMP0 into CNT on underflow. */ \
false, /* Do not load COMP1 into COMP0 when REP0 reaches 0. */ \
0, /* Idle value 0 for output 0. */ \
0, /* Idle value 0 for output 1. */ \
letimerUFOANone, /* No action on underflow on output 0. */ \
letimerUFOANone, /* No action on underflow on output 1. */ \
letimerRepeatFree, /* Count until stopped by SW. */ \
0 /* Use default top Value. */ \
}
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
uint32_t LETIMER_CompareGet(LETIMER_TypeDef *letimer, unsigned int comp);
void LETIMER_CompareSet(LETIMER_TypeDef *letimer,
unsigned int comp,
uint32_t value);
uint32_t LETIMER_CounterGet(LETIMER_TypeDef *letimer);
#if !defined(_EFM32_GECKO_FAMILY)
void LETIMER_CounterSet(LETIMER_TypeDef *letimer, uint32_t value);
#endif
void LETIMER_Enable(LETIMER_TypeDef *letimer, bool enable);
#if defined(_LETIMER_FREEZE_MASK)
void LETIMER_FreezeEnable(LETIMER_TypeDef *letimer, bool enable);
#endif
void LETIMER_Init(LETIMER_TypeDef *letimer, const LETIMER_Init_TypeDef *init);
/***************************************************************************//**
* @brief
* Clear one or more pending LETIMER interrupts.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @param[in] flags
* Pending LETIMER interrupt source to clear. Use a bitwise logic OR
* combination of valid interrupt flags for the LETIMER module
* (LETIMER_IF_nnn).
******************************************************************************/
__STATIC_INLINE void LETIMER_IntClear(LETIMER_TypeDef *letimer, uint32_t flags)
{
#if defined (LETIMER_HAS_SET_CLEAR)
letimer->IF_CLR = flags;
#else
letimer->IFC = flags;
#endif
}
/***************************************************************************//**
* @brief
* Disable one or more LETIMER interrupts.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @param[in] flags
* LETIMER interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
******************************************************************************/
__STATIC_INLINE void LETIMER_IntDisable(LETIMER_TypeDef *letimer, uint32_t flags)
{
letimer->IEN &= ~flags;
}
/***************************************************************************//**
* @brief
* Enable one or more LETIMER 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
* LETIMER_IntClear() prior to enabling the interrupt.
*
* @param[in] letimer
* Pointer to the LETIMER peripheral register block.
*
* @param[in] flags
* LETIMER interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
******************************************************************************/
__STATIC_INLINE void LETIMER_IntEnable(LETIMER_TypeDef *letimer, uint32_t flags)
{
letimer->IEN |= flags;
}
/***************************************************************************//**
* @brief
* Get pending LETIMER interrupt flags.
*
* @note
* Event bits are not cleared by the use of this function.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @return
* LETIMER interrupt sources pending. A bitwise logic OR combination of
* valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t LETIMER_IntGet(LETIMER_TypeDef *letimer)
{
return letimer->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending LETIMER interrupt flags.
*
* @details
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @note
* Event bits are not cleared by the use of this function.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @return
* Pending and enabled LETIMER interrupt sources.
* Return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in LETIMER_IEN_nnn
* register (LETIMER_IEN_nnn) and
* - the OR combination of valid interrupt flags of the LETIMER module
* (LETIMER_IF_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t LETIMER_IntGetEnabled(LETIMER_TypeDef *letimer)
{
uint32_t ien;
/* Store flags in temporary variable in order to define explicit order
* of volatile accesses. */
ien = letimer->IEN;
/* Bitwise AND of pending and enabled interrupts */
return letimer->IF & ien;
}
/***************************************************************************//**
* @brief
* Set one or more pending LETIMER interrupts from SW.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @param[in] flags
* LETIMER interrupt sources to set to pending. Use a bitwise logic OR
* combination of valid interrupt flags for the LETIMER module (LETIMER_IF_nnn).
******************************************************************************/
__STATIC_INLINE void LETIMER_IntSet(LETIMER_TypeDef *letimer, uint32_t flags)
{
#if defined (LETIMER_HAS_SET_CLEAR)
letimer->IF_SET = flags;
#else
letimer->IFS = flags;
#endif
}
#if defined(_LETIMER_LOCK_MASK)
/***************************************************************************//**
* @brief
* Lock LETIMER registers.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
*
* @note When LETIMER registers are locked LETIMER_EN, LETIMER_SWRST,
* LETIMER_CTRL, LETIMER_CMD, LETIMER_CNT, LETIMER_COMPx,
* LETIMER_TOP, LETIMER_TOPBUFF, LETIMER_REPx, and PRSMODE registers
* cannot be written to.
******************************************************************************/
__STATIC_INLINE void LETIMER_Lock(LETIMER_TypeDef *letimer)
{
letimer->LOCK = ~LETIMER_LOCK_LETIMERLOCKKEY_UNLOCK;
}
#endif
#if defined(_LETIMER_LOCK_MASK)
/***************************************************************************//**
* @brief
* Unlock LETIMER registers.
*
* @param[in] letimer
* Pointer to LETIMER peripheral register block.
******************************************************************************/
__STATIC_INLINE void LETIMER_Unlock(LETIMER_TypeDef *letimer)
{
letimer->LOCK = LETIMER_LOCK_LETIMERLOCKKEY_UNLOCK;
}
#endif
uint32_t LETIMER_RepeatGet(LETIMER_TypeDef *letimer, unsigned int rep);
void LETIMER_RepeatSet(LETIMER_TypeDef *letimer,
unsigned int rep,
uint32_t value);
void LETIMER_Reset(LETIMER_TypeDef *letimer);
void LETIMER_SyncWait(LETIMER_TypeDef *letimer);
void LETIMER_TopSet(LETIMER_TypeDef *letimer, uint32_t value);
uint32_t LETIMER_TopGet(LETIMER_TypeDef *letimer);
/** @} (end addtogroup letimer) */
#ifdef __cplusplus
}
#endif
#endif /* defined(LETIMER_COUNT) && (LETIMER_COUNT > 0) */
#endif /* EM_LETIMER_H */

View File

@@ -0,0 +1,889 @@
/***************************************************************************//**
* @file
* @brief Flash Controller (MSC) Peripheral API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_MSC_H
#define EM_MSC_H
#include "em_device.h"
#if defined(MSC_COUNT) && (MSC_COUNT > 0)
#include <stdint.h>
#include <stdbool.h>
#include "em_bus.h"
#include "em_msc_compat.h"
#include "em_ramfunc.h"
#include "sl_assert.h"
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
#include "sli_tz_ns_interface.h"
#include "sli_tz_service_msc.h"
#include "sli_tz_s_interface.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup msc MSC - Memory System Controller
* @brief Memory System Controller API
* @details
* Contains functions to control the MSC, primarily the Flash.
* Users can perform Flash memory write and erase operations, as well as
* optimization of the CPU instruction fetch interface for the application.
* Available instruction fetch features depends on the MCU or SoC family, but
* features such as instruction pre-fetch, cache, and configurable branch prediction
* are typically available.
*
* @note Flash wait-state configuration is handled by @ref cmu.
* When core clock configuration is changed by a call to functions such as
* CMU_ClockSelectSet() or CMU_HFRCOBandSet(), then Flash wait-state
* configuration is also updated.
*
* MSC resets into a safe state. To initialize the instruction interface
* to recommended settings:
* @include em_msc_init_exec.c
*
* @note The optimal configuration is highly application dependent. Performance
* benchmarking is supported by most families. See MSC_StartCacheMeasurement()
* and MSC_GetCacheMeasurement() for more details.
*
* @note
* The flash write and erase runs from RAM on the EFM32G devices. On all other
* devices the flash write and erase functions run from flash.
*
* @note
* Flash erase may add ms of delay to interrupt latency if executing from Flash.
*
* Flash write and erase operations are supported by @ref MSC_WriteWord(),
* @ref MSC_ErasePage(), and MSC_MassErase().
* Mass erase is supported for MCU and SoC families with larger Flash sizes.
*
* @note
* @ref MSC_Init() must be called prior to any Flash write or erase operation.
*
* The following steps are necessary to perform a page erase and write:
* @include em_msc_erase_write.c
*
* @deprecated
* The configuration called EM_MSC_RUN_FROM_FLASH is deprecated. This was
* previously used for allocating the flash write functions in either flash
* or RAM.
*
* @note
* The configuration EM_MSC_RUN_FROM_RAM is used to allocate the flash
* write functions in RAM. By default, flash write
* functions are placed in RAM on EFM32G and Series 2 devices
* unless SL_RAMFUNC_DISABLE is defined. For other devices,
* flash write functions are placed in FLASH by default unless
* EM_MSC_RUN_FROM_RAM is defined and SL_RAMFUNC_DISABLE is not defined.
*
* @deprecated
* The function called MSC_WriteWordFast() is deprecated.
*
* @{
******************************************************************************/
/*******************************************************************************
************************* DEFINES *****************************************
******************************************************************************/
/**
* @brief
* Timeout used while waiting for Flash to become ready after a write.
* This number indicates the number of iterations to perform before
* issuing a timeout.
*
* @note
* Timeout is set very large (in the order of 100x longer than
* necessary). This is to avoid any corner case.
*/
#define MSC_PROGRAM_TIMEOUT 10000000UL
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
#if (defined(_EFM32_GECKO_FAMILY) \
|| defined(_SILICON_LABS_32B_SERIES_2) \
|| defined(EM_MSC_RUN_FROM_RAM)) \
&& !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
#define MSC_RAMFUNC_DECLARATOR SL_RAMFUNC_DECLARATOR
#define MSC_RAMFUNC_DEFINITION_BEGIN SL_RAMFUNC_DEFINITION_BEGIN
#define MSC_RAMFUNC_DEFINITION_END SL_RAMFUNC_DEFINITION_END
#else
#define MSC_RAMFUNC_DECLARATOR
#define MSC_RAMFUNC_DEFINITION_BEGIN
#define MSC_RAMFUNC_DEFINITION_END
#endif
/** @endcond */
/*******************************************************************************
************************* TYPEDEFS ****************************************
******************************************************************************/
/** Return codes for writing/erasing Flash. */
typedef enum {
mscReturnOk = 0, /**< Flash write/erase successful. */
mscReturnInvalidAddr = -1, /**< Invalid address. Write to an address that is not Flash. */
mscReturnLocked = -2, /**< Flash address is locked. */
mscReturnTimeOut = -3, /**< Timeout while writing to Flash. */
mscReturnUnaligned = -4 /**< Unaligned access to Flash. */
} MSC_Status_TypeDef;
#if defined(_MSC_READCTRL_BUSSTRATEGY_MASK)
/** Strategy for prioritized bus access. */
typedef enum {
mscBusStrategyCPU = MSC_READCTRL_BUSSTRATEGY_CPU, /**< Prioritize CPU bus accesses. */
mscBusStrategyDMA = MSC_READCTRL_BUSSTRATEGY_DMA, /**< Prioritize DMA bus accesses. */
mscBusStrategyDMAEM1 = MSC_READCTRL_BUSSTRATEGY_DMAEM1, /**< Prioritize DMAEM1 for bus accesses. */
mscBusStrategyNone = MSC_READCTRL_BUSSTRATEGY_NONE /**< No unit has bus priority. */
} MSC_BusStrategy_Typedef;
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_MASK)
/** AHBHOST masters that can use alternate MPAHBRAM ports. */
typedef enum {
mscDmemMasterLDMA = _SYSCFG_DMEM0PORTMAPSEL_LDMAPORTSEL_SHIFT,
mscDmemMasterSRWAES = _SYSCFG_DMEM0PORTMAPSEL_SRWAESPORTSEL_SHIFT,
mscDmemMasterAHBSRW = _SYSCFG_DMEM0PORTMAPSEL_AHBSRWPORTSEL_SHIFT,
#if defined(_SYSCFG_DMEM0PORTMAPSEL_IFADCDEBUGPORTSEL_MASK)
mscDmemMasterIFADCDEBUG = _SYSCFG_DMEM0PORTMAPSEL_IFADCDEBUGPORTSEL_SHIFT,
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_SRWECA0PORTSEL_MASK)
mscDmemMasterSRWECA0 = _SYSCFG_DMEM0PORTMAPSEL_SRWECA0PORTSEL_SHIFT,
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_SRWECA1PORTSEL_MASK)
mscDmemMasterSRWECA1 = _SYSCFG_DMEM0PORTMAPSEL_SRWECA1PORTSEL_SHIFT,
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_MVPAHBDATA0PORTSEL_MASK)
mscDmemMasterMVPAHBDATA0 = _SYSCFG_DMEM0PORTMAPSEL_MVPAHBDATA0PORTSEL_SHIFT,
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_MVPAHBDATA1PORTSEL_MASK)
mscDmemMasterMVPAHBDATA1 = _SYSCFG_DMEM0PORTMAPSEL_MVPAHBDATA1PORTSEL_SHIFT,
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_MVPAHBDATA2PORTSEL_MASK)
mscDmemMasterMVPAHBDATA2 = _SYSCFG_DMEM0PORTMAPSEL_MVPAHBDATA2PORTSEL_SHIFT,
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_LDMA1PORTSEL_MASK)
mscDmemMasterLDMA1 = _SYSCFG_DMEM0PORTMAPSEL_LDMA1PORTSEL_SHIFT,
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_SRWLDMAPORTSEL_MASK)
mscDmemMasterSRWLDMA = _SYSCFG_DMEM0PORTMAPSEL_SRWLDMAPORTSEL_SHIFT,
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_USBPORTSEL_MASK)
mscDmemMasterUSB = _SYSCFG_DMEM0PORTMAPSEL_USBPORTSEL_SHIFT,
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_BUFCPORTSEL_MASK)
mscDmemMasterBUFC = _SYSCFG_DMEM0PORTMAPSEL_BUFCPORTSEL_SHIFT
#endif
} MSC_DmemMaster_TypeDef;
#endif
#if defined(_MPAHBRAM_CTRL_AHBPORTPRIORITY_MASK)
/** AHB port given priority. */
typedef enum {
mscPortPriorityNone = _MPAHBRAM_CTRL_AHBPORTPRIORITY_NONE,
mscPortPriorityPort0 = _MPAHBRAM_CTRL_AHBPORTPRIORITY_PORT0,
mscPortPriorityPort1 = _MPAHBRAM_CTRL_AHBPORTPRIORITY_PORT1,
#if defined(_MPAHBRAM_CTRL_AHBPORTPRIORITY_PORT2)
mscPortPriorityPort2 = _MPAHBRAM_CTRL_AHBPORTPRIORITY_PORT2,
#endif
#if defined(_MPAHBRAM_CTRL_AHBPORTPRIORITY_PORT3)
mscPortPriorityPort3 = _MPAHBRAM_CTRL_AHBPORTPRIORITY_PORT3,
#endif
} MSC_PortPriority_TypeDef;
#endif
#if defined(MSC_READCTRL_DOUTBUFEN) || defined(MSC_RDATACTRL_DOUTBUFEN)
/** Code execution configuration */
typedef struct {
bool doutBufEn; /**< Flash dout pipeline buffer enable */
} MSC_ExecConfig_TypeDef;
/** Default MSC ExecConfig initialization */
#define MSC_EXECCONFIG_DEFAULT \
{ \
false, \
}
#else
/** Code execution configuration. */
typedef struct {
bool scbtEn; /**< Enable Suppressed Conditional Branch Target Prefetch. */
bool prefetchEn; /**< Enable MSC prefetching. */
bool ifcDis; /**< Disable instruction cache. */
bool aiDis; /**< Disable automatic cache invalidation on write or erase. */
bool iccDis; /**< Disable automatic caching of fetches in interrupt context. */
bool useHprot; /**< Use ahb_hprot to determine if the instruction is cacheable or not. */
} MSC_ExecConfig_TypeDef;
/** Default MSC ExecConfig initialization. */
#define MSC_EXECCONFIG_DEFAULT \
{ \
false, \
true, \
false, \
false, \
false, \
false, \
}
#endif
#if defined(_MSC_ECCCTRL_MASK) \
|| defined(_SYSCFG_DMEM0ECCCTRL_MASK) \
|| defined(_MPAHBRAM_CTRL_MASK)
#if defined(_SILICON_LABS_32B_SERIES_1_CONFIG_1)
/** EFM32GG11B incorporates 2 memory banks including ECC support. */
#define MSC_ECC_BANKS (2)
/** Default MSC EccConfig initialization. */
#define MSC_ECCCONFIG_DEFAULT \
{ \
{ false, false }, \
{ 0, 1 }, \
}
#elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_106)
/** EFM32GG12B incorporates 3 memory banks including ECC support. */
#define MSC_ECC_BANKS (3)
/** Default MSC EccConfig initialization. */
#define MSC_ECCCONFIG_DEFAULT \
{ \
{ false, false, false }, \
{ 0, 1 }, \
}
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
/** xG26 chips incorporate 2 memory banks including ECC support. */
#define MSC_ECC_BANKS (2)
/** Default MSC EccConfig initialization */
#define MSC_ECCCONFIG_DEFAULT \
{ \
{ false, false }, \
{ 0, 1 }, \
}
#elif defined(_SILICON_LABS_32B_SERIES_2)
/** Series 2 chips incorporate 1 memory bank including ECC support. */
#define MSC_ECC_BANKS (1)
/** Default MSC EccConfig initialization */
#define MSC_ECCCONFIG_DEFAULT \
{ \
{ false }, \
{ 0, 1 }, \
}
#else
#error Device not supported.
#endif
/** ECC configuration. */
typedef struct {
bool enableEccBank[MSC_ECC_BANKS]; /**< Array of bools to enable/disable
Error Correcting Code (ECC) for
each RAM bank that supports ECC on
the device. */
uint32_t dmaChannels[2]; /**< Array of 2 DMA channel numbers to
use for ECC initialization. */
} MSC_EccConfig_TypeDef;
#endif /* #if defined(_MSC_ECCCTRL_MASK) */
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/* Deprecated type names. */
#define mscBusStrategy_Typedef MSC_BusStrategy_Typedef
#define msc_Return_TypeDef MSC_Status_TypeDef
/** @endcond */
/*******************************************************************************
************************* Inline Functions ********************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get the status of the MSC register lock.
*
* @return
* Boolean true if register lock is applied, false otherwise.
******************************************************************************/
__STATIC_INLINE bool MSC_LockGetLocked(void)
{
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
return (bool)sli_tz_ns_interface_dispatch_simple_noarg(
(sli_tz_veneer_simple_noarg_fn)sli_tz_s_interface_dispatch_simple_no_args,
SLI_TZ_MSC_GET_LOCKED_SID);
#elif defined(_MSC_STATUS_REGLOCK_MASK)
return (MSC->STATUS & _MSC_STATUS_REGLOCK_MASK) != MSC_STATUS_REGLOCK_UNLOCKED;
#else
return (MSC->LOCK & _MSC_LOCK_MASK) != MSC_LOCK_LOCKKEY_UNLOCKED;
#endif
}
/***************************************************************************//**
* @brief
* Set the MSC register lock to a locked state.
******************************************************************************/
__STATIC_INLINE void MSC_LockSetLocked(void)
{
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
(void)sli_tz_ns_interface_dispatch_simple_noarg(
(sli_tz_veneer_simple_noarg_fn)sli_tz_s_interface_dispatch_simple_no_args,
SLI_TZ_MSC_SET_LOCKED_SID);
#else
MSC->LOCK = MSC_LOCK_LOCKKEY_LOCK;
#endif
}
/***************************************************************************//**
* @brief
* Set the MSC register lock to an unlocked state.
******************************************************************************/
__STATIC_INLINE void MSC_LockSetUnlocked(void)
{
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
(void)sli_tz_ns_interface_dispatch_simple_noarg(
(sli_tz_veneer_simple_noarg_fn)sli_tz_s_interface_dispatch_simple_no_args,
SLI_TZ_MSC_SET_UNLOCKED_SID);
#else
MSC->LOCK = MSC_LOCK_LOCKKEY_UNLOCK;
#endif
}
/***************************************************************************//**
* @brief
* Get the current value of the read control register (MSC_READCTRL).
*
* @return
* The 32-bit value read from the MSC_READCTRL register.
******************************************************************************/
__STATIC_INLINE uint32_t MSC_ReadCTRLGet(void)
{
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
return sli_tz_ns_interface_dispatch_simple_noarg(
(sli_tz_veneer_simple_noarg_fn)sli_tz_s_interface_dispatch_simple_no_args,
SLI_TZ_MSC_GET_READCTRL_SID);
#else
return MSC->READCTRL;
#endif
}
/***************************************************************************//**
* @brief
* Write a value to the read control register (MSC_READCTRL).
*
* @param[in] value
* The 32-bit value to write to the MSC_READCTRL register.
******************************************************************************/
__STATIC_INLINE void MSC_ReadCTRLSet(uint32_t value)
{
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
(void)sli_tz_ns_interface_dispatch_simple(
(sli_tz_veneer_simple_fn)sli_tz_s_interface_dispatch_simple,
SLI_TZ_MSC_SET_READCTRL_SID,
value);
#else
MSC->READCTRL = value;
#endif
}
#if defined(_MSC_PAGELOCK0_MASK) || defined(_MSC_INST_PAGELOCKWORD0_MASK)
/***************************************************************************//**
* @brief
* Set the lockbit for a flash page in order to prevent page writes/erases to
* the corresponding page.
*
* @param[in] page_number
* The index of the page to apply the pagelock to. Must be in the range
* [0, (flash_size / page_size) - 1].
******************************************************************************/
__STATIC_INLINE void MSC_PageLockSetLocked(uint32_t page_number)
{
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
(void)sli_tz_ns_interface_dispatch_simple(
(sli_tz_veneer_simple_fn)sli_tz_s_interface_dispatch_simple,
SLI_TZ_MSC_SET_PAGELOCK_SID,
page_number);
#else
EFM_ASSERT(page_number < (FLASH_SIZE / FLASH_PAGE_SIZE));
#if defined(_MSC_PAGELOCK0_MASK)
uint32_t *pagelock_registers = (uint32_t *)&MSC->PAGELOCK0;
#elif defined(_MSC_INST_PAGELOCKWORD0_MASK)
uint32_t *pagelock_registers = (uint32_t *)&MSC->INST_PAGELOCKWORD0;
#endif
pagelock_registers[page_number / 32] |= (1 << (page_number % 32));
#endif
}
/***************************************************************************//**
* @brief
* Get the value of the lockbit for a flash page.
*
* @param[in] page_number
* The index of the page to get the lockbit value from. Must be in the range
* [0, (flash_size / page_size) - 1].
*
* @return
* Boolean true if the page is locked, false otherwise.
******************************************************************************/
__STATIC_INLINE bool MSC_PageLockGetLocked(uint32_t page_number)
{
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
return (bool)sli_tz_ns_interface_dispatch_simple(
(sli_tz_veneer_simple_fn)sli_tz_s_interface_dispatch_simple,
SLI_TZ_MSC_GET_PAGELOCK_SID,
page_number);
#else
EFM_ASSERT(page_number < (FLASH_SIZE / FLASH_PAGE_SIZE));
#if defined(_MSC_PAGELOCK0_MASK)
uint32_t *pagelock_registers = (uint32_t *)&MSC->PAGELOCK0;
#elif defined(_MSC_INST_PAGELOCKWORD0_MASK)
uint32_t *pagelock_registers = (uint32_t *)&MSC->INST_PAGELOCKWORD0;
#endif
return pagelock_registers[page_number / 32] & (1 << (page_number % 32));
#endif
}
#endif // _MSC_PAGELOCK0_MASK || _MSC_INST_PAGELOCKWORD0_MASK
#if defined(_MSC_USERDATASIZE_MASK)
/***************************************************************************//**
* @brief
* Get the size of the user data region in flash.
*
* @return
* The size of the user data region divided by 256.
******************************************************************************/
__STATIC_INLINE uint32_t MSC_UserDataGetSize(void)
{
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
return sli_tz_ns_interface_dispatch_simple_noarg(
(sli_tz_veneer_simple_noarg_fn)sli_tz_s_interface_dispatch_simple_no_args,
SLI_TZ_MSC_GET_USERDATA_SIZE_SID);
#else
return MSC->USERDATASIZE;
#endif
}
#endif // _MSC_USERDATASIZE_MASK
#if defined(_MSC_MISCLOCKWORD_MASK)
/***************************************************************************//**
* @brief
* Get the current value of the mass erase and user data page lock word
* (MSC_MISCLOCKWORD).
*
* @return
* The 32-bit value read from the MSC_MISCLOCKWORD register.
******************************************************************************/
__STATIC_INLINE uint32_t MSC_MiscLockWordGet(void)
{
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
return sli_tz_ns_interface_dispatch_simple_noarg(
(sli_tz_veneer_simple_noarg_fn)sli_tz_s_interface_dispatch_simple_no_args,
SLI_TZ_MSC_GET_MISCLOCKWORD_SID);
#else
return MSC->MISCLOCKWORD;
#endif
}
/***************************************************************************//**
* @brief
* Write a value to the mass erase and user data page lock word
* (MSC_MISCLOCKWORD).
*
* @param[in] value
* The 32-bit value to write to the MSC_MISCLOCKWORD register.
******************************************************************************/
__STATIC_INLINE void MSC_MiscLockWordSet(uint32_t value)
{
#if defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
(void)sli_tz_ns_interface_dispatch_simple(
(sli_tz_veneer_simple_fn)sli_tz_s_interface_dispatch_simple,
SLI_TZ_MSC_SET_MISCLOCKWORD_SID,
value);
#else
MSC->MISCLOCKWORD = value;
#endif
}
#endif // _MSC_USERDATASIZE_MASK
#if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
/***************************************************************************//**
* @brief
* Clear one or more pending MSC interrupts.
*
* @param[in] flags
* Pending MSC interrupt source to clear. Use a bitwise logic OR combination
* of valid interrupt flags for the MSC module (MSC_IF_nnn).
******************************************************************************/
__STATIC_INLINE void MSC_IntClear(uint32_t flags)
{
#if defined(MSC_HAS_SET_CLEAR)
MSC->IF_CLR = flags;
#else
MSC->IFC = flags;
#endif
}
/***************************************************************************//**
* @brief
* Disable one or more MSC interrupts.
*
* @param[in] flags
* MSC interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the MSC module (MSC_IF_nnn).
******************************************************************************/
__STATIC_INLINE void MSC_IntDisable(uint32_t flags)
{
#if defined(MSC_HAS_SET_CLEAR)
MSC->IEN_CLR = flags;
#else
MSC->IEN &= ~(flags);
#endif
}
/***************************************************************************//**
* @brief
* Enable one or more MSC 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
* MSC_IntClear() prior to enabling the interrupt.
*
* @param[in] flags
* MSC interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for the MSC module (MSC_IF_nnn).
******************************************************************************/
__STATIC_INLINE void MSC_IntEnable(uint32_t flags)
{
#if defined(MSC_HAS_SET_CLEAR)
MSC->IEN_SET = flags;
#else
MSC->IEN |= flags;
#endif
}
/***************************************************************************//**
* @brief
* Get pending MSC interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @return
* MSC interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for the MSC module (MSC_IF_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t MSC_IntGet(void)
{
return MSC->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending MSC interrupt flags.
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @note
* Interrupt flags are not cleared by the use of this function.
*
* @return
* Pending and enabled MSC interrupt sources.
* The return value is the bitwise AND of
* - the enabled interrupt sources in MSC_IEN and
* - the pending interrupt flags MSC_IF
******************************************************************************/
__STATIC_INLINE uint32_t MSC_IntGetEnabled(void)
{
uint32_t ien;
ien = MSC->IEN;
return MSC->IF & ien;
}
/***************************************************************************//**
* @brief
* Set one or more pending MSC interrupts from SW.
*
* @param[in] flags
* MSC interrupt sources to set to pending. Use a bitwise logic OR combination of
* valid interrupt flags for the MSC module (MSC_IF_nnn).
******************************************************************************/
__STATIC_INLINE void MSC_IntSet(uint32_t flags)
{
#if defined(MSC_HAS_SET_CLEAR)
MSC->IF_SET = flags;
#else
MSC->IFS = flags;
#endif
}
#if defined(MSC_IF_CHOF) && defined(MSC_IF_CMOF)
/***************************************************************************//**
* @brief
* Start measuring the cache hit ratio.
* @details
* Starts performance counters. It is defined inline to
* minimize the impact of this code on the measurement itself.
******************************************************************************/
__STATIC_INLINE void MSC_StartCacheMeasurement(void)
{
/* Clear CMOF and CHOF to catch these later. */
MSC->IFC = MSC_IF_CHOF | MSC_IF_CMOF;
/* Start performance counters. */
#if defined(_MSC_CACHECMD_MASK)
MSC->CACHECMD = MSC_CACHECMD_STARTPC;
#else
MSC->CMD = MSC_CMD_STARTPC;
#endif
}
/***************************************************************************//**
* @brief
* Stop measuring the hit rate.
* @note
* Defined inline to minimize the impact of this
* code on the measurement itself.
* Only works for relatively short sections of code.
* To measure longer sections of code, implement an IRQ Handler for
* the CHOF and CMOF overflow interrupts. These overflows need to be
* counted and included in the total.
* Functions can then be implemented as follows:
* @verbatim
* volatile uint32_t hitOverflows
* volatile uint32_t missOverflows
*
* void MSC_IRQHandler(void)
* {
* uint32_t flags;
* flags = MSC->IF;
* if (flags & MSC_IF_CHOF) {
* MSC->IFC = MSC_IF_CHOF;
* hitOverflows++;
* }
* if (flags & MSC_IF_CMOF) {
* MSC->IFC = MSC_IF_CMOF;
* missOverflows++;
* }
* }
*
* void startPerformanceCounters(void)
* {
* hitOverflows = 0;
* missOverflows = 0;
*
* MSC_IntEnable(MSC_IF_CHOF | MSC_IF_CMOF);
* NVIC_EnableIRQ(MSC_IRQn);
*
* MSC_StartCacheMeasurement();
* }
* @endverbatim
* @return
* Returns -1 if there has been no cache accesses.
* Returns -2 if there has been an overflow in the performance counters.
* If not, it will return the percentage of hits versus misses.
******************************************************************************/
__STATIC_INLINE int32_t MSC_GetCacheMeasurement(void)
{
int32_t total;
int32_t hits;
/* Stop counter before computing hit-rate. */
#if defined(_MSC_CACHECMD_MASK)
MSC->CACHECMD = MSC_CACHECMD_STOPPC;
#else
MSC->CMD = MSC_CMD_STOPPC;
#endif
/* Check for overflows in performance counters. */
if (MSC->IF & (MSC_IF_CHOF | MSC_IF_CMOF)) {
return -2;
}
hits = (int32_t)MSC->CACHEHITS;
total = (int32_t)MSC->CACHEMISSES + hits;
/* To avoid a division by zero. */
if (total == 0) {
return -1;
}
return (hits * 100) / total;
}
/***************************************************************************//**
* @brief
* Flush contents of instruction cache.
******************************************************************************/
__STATIC_INLINE void MSC_FlushCache(void)
{
#if defined(_MSC_CACHECMD_MASK)
MSC->CACHECMD = MSC_CACHECMD_INVCACHE;
#else
MSC->CMD = MSC_CMD_INVCACHE;
#endif
}
/***************************************************************************//**
* @brief
* Enable or disable instruction cache functionality.
* @param[in] enable
* Enable instruction cache. Default is on.
******************************************************************************/
__STATIC_INLINE void MSC_EnableCache(bool enable)
{
BUS_RegBitWrite(&(MSC->READCTRL), _MSC_READCTRL_IFCDIS_SHIFT, !enable);
}
#if defined(MSC_READCTRL_ICCDIS)
/***************************************************************************//**
* @brief
* Enable or disable instruction cache functionality in IRQs.
* @param[in] enable
* Enable instruction cache. Default is on.
******************************************************************************/
__STATIC_INLINE void MSC_EnableCacheIRQs(bool enable)
{
BUS_RegBitWrite(&(MSC->READCTRL), _MSC_READCTRL_ICCDIS_SHIFT, !enable);
}
#endif
/***************************************************************************//**
* @brief
* Enable or disable instruction cache flushing when writing to flash.
* @param[in] enable
* Enable automatic cache flushing. Default is on.
******************************************************************************/
__STATIC_INLINE void MSC_EnableAutoCacheFlush(bool enable)
{
BUS_RegBitWrite(&(MSC->READCTRL), _MSC_READCTRL_AIDIS_SHIFT, !enable);
}
#endif /* defined( MSC_IF_CHOF ) && defined( MSC_IF_CMOF ) */
#if defined(_MSC_READCTRL_BUSSTRATEGY_MASK)
/***************************************************************************//**
* @brief
* Configure which unit should get priority on system bus.
* @param[in] mode
* Unit to prioritize bus accesses for.
******************************************************************************/
__STATIC_INLINE void MSC_BusStrategy(mscBusStrategy_Typedef mode)
{
MSC->READCTRL = (MSC->READCTRL & ~(_MSC_READCTRL_BUSSTRATEGY_MASK)) | mode;
}
#endif
/*******************************************************************************
************************* PROTOTYPES **************************************
******************************************************************************/
void MSC_ExecConfigSet(MSC_ExecConfig_TypeDef *execConfig);
#if defined(_MSC_ECCCTRL_MASK) \
|| defined(_SYSCFG_DMEM0ECCCTRL_MASK) \
|| defined(_MPAHBRAM_CTRL_MASK)
void MSC_EccConfigSet(MSC_EccConfig_TypeDef *eccConfig);
#endif
#if defined(_SYSCFG_DMEM0PORTMAPSEL_MASK)
void MSC_DmemPortMapSet(MSC_DmemMaster_TypeDef master, uint8_t port);
#endif
#if defined(_MPAHBRAM_CTRL_AHBPORTPRIORITY_MASK)
void MSC_PortSetPriority(MSC_PortPriority_TypeDef portPriority);
MSC_PortPriority_TypeDef MSC_PortGetCurrentPriority(void);
#endif
#if !defined(_SILICON_LABS_32B_SERIES_2)
/* Note that this function is deprecated because we no longer support
* placing msc code in ram. */
MSC_RAMFUNC_DECLARATOR
MSC_Status_TypeDef MSC_WriteWordFast(uint32_t *address,
void const *data,
uint32_t numBytes);
#endif
#if defined(MSC_WRITECMD_ERASEMAIN0)
/***************************************************************************//**
* @brief
* Erase the entire Flash in one operation.
*
* @note
* This command will erase the entire contents of the device.
* Use with care, both a debug session and all contents of the flash will be
* lost. The lock bit, MLW will prevent this operation from executing and
* might prevent a successful mass erase.
*
* @return
* Returns the status of the operation.
******************************************************************************/
SL_RAMFUNC_DECLARATOR
MSC_Status_TypeDef MSC_MassErase(void);
#endif
#endif /* !SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT */
MSC_RAMFUNC_DECLARATOR
MSC_Status_TypeDef MSC_ErasePage(uint32_t *startAddress);
MSC_RAMFUNC_DECLARATOR
MSC_Status_TypeDef MSC_WriteWord(uint32_t *address,
void const *data,
uint32_t numBytes);
#if (_SILICON_LABS_32B_SERIES > 0)
MSC_Status_TypeDef MSC_WriteWordDma(int ch,
uint32_t *address,
const void *data,
uint32_t numBytes);
#endif
void MSC_Init(void);
void MSC_Deinit(void);
/** @} (end addtogroup msc) */
#ifdef __cplusplus
}
#endif
#endif /* defined(MSC_COUNT) && (MSC_COUNT > 0) */
#endif /* EM_MSC_H */

View File

@@ -0,0 +1,81 @@
/***************************************************************************//**
* @file
* @brief Flash Controller (MSC) Compatibility Header
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_MSC_COMPAT_H
#define EM_MSC_COMPAT_H
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2)
#define MSC_IF_PWROFFIF MSC_IF_PWROFF
#define _MSC_IF_PWROFFIF_SHIFT _MSC_IF_PWROFF_SHIFT
#define _MSC_IF_PWROFFIF_MASK _MSC_IF_PWROFF_MASK
#define _MSC_IF_PWROFFIF_DEFAULT _MSC_IF_PWROFF_DEFAULT
#define MSC_IF_PWROFFIF_DEFAULT MSC_IF_PWROFF_DEFAULT
#define MSC_IEN_PWROFFIEN MSC_IEN_PWROFF
#define _MSC_IEN_PWROFFIEN_SHIFT _MSC_IEN_PWROFF_SHIFT
#define _MSC_IEN_PWROFFIEN_MASK _MSC_IEN_PWROFF_MASK
#define _MSC_IEN_PWROFFIEN_DEFAULT _MSC_IEN_PWROFF_DEFAULT
#define MSC_IEN_PWROFFIEN_DEFAULT MSC_IEN_PWROFF_DEFAULT
#define ICACHE_IEN_RAMERRORIEN ICACHE_IEN_RAMERROR
#define _ICACHE_IEN_RAMERRORIEN_SHIFT _ICACHE_IEN_RAMERROR_SHIFT
#define _ICACHE_IEN_RAMERRORIEN_MASK _ICACHE_IEN_RAMERROR_MASK
#define _ICACHE_IEN_RAMERRORIEN_DEFAULT _ICACHE_IEN_RAMERROR_DEFAULT
#define ICACHE_IEN_RAMERRORIEN_DEFAULT ICACHE_IEN_RAMERROR_DEFAULT
#define SYSCFG_IF_FRCRAMERR1BIF SYSCFG_IF_FRCRAMERR1B
#define _SYSCFG_IF_FRCRAMERR1BIF_SHIFT _SYSCFG_IF_FRCRAMERR1B_SHIFT
#define _SYSCFG_IF_FRCRAMERR1BIF_MASK _SYSCFG_IF_FRCRAMERR1B_MASK
#define _SYSCFG_IF_FRCRAMERR1BIF_DEFAULT _SYSCFG_IF_FRCRAMERR1B_DEFAULT
#define SYSCFG_IF_FRCRAMERR1BIF_DEFAULT SYSCFG_IF_FRCRAMERR1B_DEFAULT
#define SYSCFG_IF_FRCRAMERR2BIF SYSCFG_IF_FRCRAMERR2B
#define _SYSCFG_IF_FRCRAMERR2BIF_SHIFT _SYSCFG_IF_FRCRAMERR2B_SHIFT
#define _SYSCFG_IF_FRCRAMERR2BIF_MASK _SYSCFG_IF_FRCRAMERR2B_MASK
#define _SYSCFG_IF_FRCRAMERR2BIF_DEFAULT _SYSCFG_IF_FRCRAMERR2B_DEFAULT
#define SYSCFG_IF_FRCRAMERR2BIF_DEFAULT SYSCFG_IF_FRCRAMERR2B_DEFAULT
#define SYSCFG_IEN_FRCRAMERR1BIEN SYSCFG_IEN_FRCRAMERR1B
#define _SYSCFG_IEN_FRCRAMERR1BIEN_SHIFT _SYSCFG_IEN_FRCRAMERR1B_SHIFT
#define _SYSCFG_IEN_FRCRAMERR1BIEN_MASK _SYSCFG_IEN_FRCRAMERR1B_MASK
#define _SYSCFG_IEN_FRCRAMERR1BIEN_DEFAULT _SYSCFG_IEN_FRCRAMERR1B_DEFAULT
#define SYSCFG_IEN_FRCRAMERR1BIEN_DEFAULT SYSCFG_IEN_FRCRAMERR1B_DEFAULT
#define SYSCFG_IEN_FRCRAMERR2BIEN SYSCFG_IEN_FRCRAMERR2B
#define _SYSCFG_IEN_FRCRAMERR2BIEN_SHIFT _SYSCFG_IEN_FRCRAMERR2B_SHIFT
#define _SYSCFG_IEN_FRCRAMERR2BIEN_MASK _SYSCFG_IEN_FRCRAMERR2B_MASK
#define _SYSCFG_IEN_FRCRAMERR2BIEN_DEFAULT _SYSCFG_IEN_FRCRAMERR2B_DEFAULT
#define SYSCFG_IEN_FRCRAMERR2BIEN_DEFAULT SYSCFG_IEN_FRCRAMERR2B_DEFAULT
#endif /* _SILICON_LABS_32B_SERIES_2_CONFIG_2 */
#endif /* EM_MSC_COMPAT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,905 @@
/***************************************************************************//**
* @file
* @brief Pulse Counter (PCNT) peripheral API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_PCNT_H
#define EM_PCNT_H
#include "em_device.h"
#if defined(PCNT_COUNT) && (PCNT_COUNT > 0)
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup pcnt
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** PCNT0 Counter register size. */
#if defined(_EFM32_GECKO_FAMILY)
#define PCNT0_CNT_SIZE (8) /**< PCNT0 counter is 8 bits. */
#else
#define PCNT0_CNT_SIZE (16) /**< PCNT0 counter is 16 bits. */
#endif
#ifdef PCNT1
/** PCNT1 Counter register size. */
#if defined(_SILICON_LABS_32B_SERIES_0)
#define PCNT1_CNT_SIZE (8) /**< PCNT1 counter is 8 bits. */
#else
#define PCNT1_CNT_SIZE (16) /**< PCNT1 counter is 16 bits. */
#endif
#endif
#ifdef PCNT2
/** PCNT2 Counter register size. */
#if defined(_SILICON_LABS_32B_SERIES_0)
#define PCNT2_CNT_SIZE (8) /**< PCNT2 counter is 8 bits. */
#else
#define PCNT2_CNT_SIZE (16) /**< PCNT2 counter is 16 bits. */
#endif
#endif
/* Define values that can be used in case some state/mode are not defined for some devices.*/
/** PCNT mode disable. */
#define PCNT_MODE_DISABLE 0xFF
/** PCNT count event is none. */
#define PCNT_CNT_EVENT_NONE 0xFF
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Mode selection. */
#if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
typedef enum {
/** Disable pulse counter. */
pcntModeDisable = _PCNT_CTRL_MODE_DISABLE,
/** Single input LFACLK oversampling mode (available in EM0-EM2). */
pcntModeOvsSingle = _PCNT_CTRL_MODE_OVSSINGLE,
/** Externally clocked single input counter mode (available in EM0-EM3). */
pcntModeExtSingle = _PCNT_CTRL_MODE_EXTCLKSINGLE,
/** Externally clocked quadrature decoder mode (available in EM0-EM3). */
pcntModeExtQuad = _PCNT_CTRL_MODE_EXTCLKQUAD,
#if defined(_PCNT_CTRL_MODE_OVSQUAD1X)
/** LFACLK oversampling quadrature decoder 1X mode (available in EM0-EM2). */
pcntModeOvsQuad1 = _PCNT_CTRL_MODE_OVSQUAD1X,
/** LFACLK oversampling quadrature decoder 2X mode (available in EM0-EM2). */
pcntModeOvsQuad2 = _PCNT_CTRL_MODE_OVSQUAD2X,
/** LFACLK oversampling quadrature decoder 4X mode (available in EM0-EM2). */
pcntModeOvsQuad4 = _PCNT_CTRL_MODE_OVSQUAD4X,
#endif
} PCNT_Mode_TypeDef;
#else
typedef enum {
/** Disable pulse counter. */
pcntModeDisable = PCNT_MODE_DISABLE,
/** Single input LFACLK oversampling mode (available in EM0-EM2). */
pcntModeOvsSingle = _PCNT_CFG_MODE_OVSSINGLE,
/** Externally clocked single input counter mode (available in EM0-EM3). */
pcntModeExtSingle = _PCNT_CFG_MODE_EXTCLKSINGLE,
/** Externally clocked quadrature decoder mode (available in EM0-EM3). */
pcntModeExtQuad = _PCNT_CFG_MODE_EXTCLKQUAD,
/** LFACLK oversampling quadrature decoder 1X mode (available in EM0-EM2). */
pcntModeOvsQuad1 = _PCNT_CFG_MODE_OVSQUAD1X,
/** LFACLK oversampling quadrature decoder 2X mode (available in EM0-EM2). */
pcntModeOvsQuad2 = _PCNT_CFG_MODE_OVSQUAD2X,
/** LFACLK oversampling quadrature decoder 4X mode (available in EM0-EM2). */
pcntModeOvsQuad4 = _PCNT_CFG_MODE_OVSQUAD4X,
} PCNT_Mode_TypeDef;
#endif
#if defined(_PCNT_CTRL_CNTEV_MASK)
/** Counter event selection.
* Note: unshifted values are being used for enumeration because multiple
* configuration structure members use this type definition. */
typedef enum {
/** Counts up on up-count and down on down-count events. */
pcntCntEventBoth = _PCNT_CTRL_CNTEV_BOTH,
/** Only counts up on up-count events. */
pcntCntEventUp = _PCNT_CTRL_CNTEV_UP,
/** Only counts down on down-count events. */
pcntCntEventDown = _PCNT_CTRL_CNTEV_DOWN,
/** Never counts. */
#if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
pcntCntEventNone = _PCNT_CTRL_CNTEV_NONE
#else
pcntCntEventNone = PCNT_CNT_EVENT_NONE
#endif
} PCNT_CntEvent_TypeDef;
#endif
/** PRS sources for @p s0PRS and @p s1PRS. */
#if defined(_PCNT_INPUT_MASK)
typedef enum {
pcntPRSCh0 = 0, /**< PRS channel 0. */
pcntPRSCh1 = 1, /**< PRS channel 1. */
pcntPRSCh2 = 2, /**< PRS channel 2. */
pcntPRSCh3 = 3, /**< PRS channel 3. */
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH4)
pcntPRSCh4 = 4, /**< PRS channel 4. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH5)
pcntPRSCh5 = 5, /**< PRS channel 5. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH6)
pcntPRSCh6 = 6, /**< PRS channel 6. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH7)
pcntPRSCh7 = 7, /**< PRS channel 7. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH8)
pcntPRSCh8 = 8, /**< PRS channel 8. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH9)
pcntPRSCh9 = 9, /**< PRS channel 9. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH10)
pcntPRSCh10 = 10, /**< PRS channel 10. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH11)
pcntPRSCh11 = 11, /**< PRS channel 11. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH12)
pcntPRSCh12 = 12, /**< PRS channel 12. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH13)
pcntPRSCh13 = 13, /**< PRS channel 13. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH14)
pcntPRSCh14 = 14, /**< PRS channel 14. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH15)
pcntPRSCh15 = 15, /**< PRS channel 15. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH16)
pcntPRSCh16 = 16, /**< PRS channel 16. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH17)
pcntPRSCh17 = 17, /**< PRS channel 17. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH18)
pcntPRSCh18 = 18, /**< PRS channel 18. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH19)
pcntPRSCh19 = 19, /**< PRS channel 19. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH20)
pcntPRSCh20 = 20, /**< PRS channel 20. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH21)
pcntPRSCh21 = 21, /**< PRS channel 21. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH22)
pcntPRSCh22 = 22, /**< PRS channel 22. */
#endif
#if defined(PCNT_INPUT_S0PRSSEL_PRSCH23)
pcntPRSCh23 = 23, /**< PRS channel 23. */
#endif
} PCNT_PRSSel_TypeDef;
#elif defined(_SILICON_LABS_32B_SERIES_2)
typedef unsigned int PCNT_PRSSel_TypeDef;
#endif
#if defined(_PCNT_INPUT_MASK) || defined(_SILICON_LABS_32B_SERIES_2)
/** PRS inputs of PCNT. */
typedef enum {
pcntPRSInputS0 = 0, /** PRS input 0. */
pcntPRSInputS1 = 1 /** PRS input 1. */
} PCNT_PRSInput_TypeDef;
#endif
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** Initialization structure. */
typedef struct {
/** Mode to operate in. */
PCNT_Mode_TypeDef mode;
/** Initial counter value (refer to reference manual for max value allowed).
* Only used for #pcntModeOvsSingle (and possibly #pcntModeDisable) modes.
* If using #pcntModeExtSingle or #pcntModeExtQuad modes, counter
* value is reset to HW reset value. */
uint32_t counter;
/** Initial top value (refer to reference manual for max value allowed).
* Only used for #pcntModeOvsSingle (and possibly #pcntModeDisable) modes.
* If using #pcntModeExtSingle or #pcntModeExtQuad modes, top
* value is reset to HW reset value. */
uint32_t top;
/** Polarity of incoming edge.
* @li #pcntModeExtSingle mode - if false, positive edges are counted,
* otherwise negative edges.
* @li #pcntModeExtQuad mode - if true, counting direction is inverted. */
bool negEdge;
/** Counting direction, only applicable for #pcntModeOvsSingle and
* #pcntModeExtSingle modes. */
bool countDown;
/** Enable filter, only available in #pcntModeOvsSingle* mode. */
bool filter;
#if defined(_SILICON_LABS_32B_SERIES_2)
/** Enable/disable PCNT counting during debug halt. Only in OVSSINGLE and OVSQUAD modes. */
bool debugHalt;
#endif
#if defined(PCNT_CTRL_HYST) || defined(_SILICON_LABS_32B_SERIES_2)
/** Set to true to enable hysteresis. When enabled, PCNT will always
* overflow and underflow to TOP/2. */
bool hyst;
#endif
#if defined(PCNT_CTRL_S1CDIR)
/** Set to true to enable S1 to determine the direction of counting in
* OVSSINGLE or EXTCLKSINGLE modes. @n
* When S1 is high, the count direction is given by CNTDIR, and when S1 is
* low, the count direction is the opposite. */
bool s1CntDir;
#endif
#if defined(_PCNT_CTRL_CNTEV_SHIFT)
/** Selects whether the regular counter responds to up-count events,
* down-count events, both, or none. */
PCNT_CntEvent_TypeDef cntEvent;
#endif
#if defined(_PCNT_CTRL_AUXCNTEV_SHIFT)
/** Selects whether the auxiliary counter responds to up-count events,
* down-count events, both, or none. */
PCNT_CntEvent_TypeDef auxCntEvent;
#endif
#if defined(_PCNT_INPUT_MASK) || defined(_SILICON_LABS_32B_SERIES_2)
/** Select PRS channel as input to S0IN in PCNTx_INPUT register. */
PCNT_PRSSel_TypeDef s0PRS;
/** Select PRS channel as input to S1IN in PCNTx_INPUT register. */
PCNT_PRSSel_TypeDef s1PRS;
#endif
} PCNT_Init_TypeDef;
/** Default Debug. */
#if defined(_SILICON_LABS_32B_SERIES_2)
#define DEFAULT_DEBUG_HALT true,
#else
#define DEFAULT_DEBUG_HALT
#endif
/** Default Mode. */
#define DEFAULT_MODE pcntModeDisable, /**< Disabled by default. */
/** Default Hysteresis. */
#if defined(PCNT_CTRL_HYST) || defined(_SILICON_LABS_32B_SERIES_2)
#define DEFAULT_HYST false, /**< Hysteresis disabled. */
#else
#define DEFAULT_HYST
#endif
/** Default counter direction*/
#if defined(PCNT_CTRL_S1CDIR)
#define DEFAULT_CDIR true, /**< Counter direction is given by CNTDIR. */
#else
#define DEFAULT_CDIR
#endif
/** Default count event*/
#if defined(_PCNT_CTRL_CNTEV_SHIFT)
#define DEFAULT_CNTEV pcntCntEventUp, /**< Regular counter counts up on upcount events. */
#else
#define DEFAULT_CNTEV
#endif
/** Default auxiliary count event. */
#if defined(_PCNT_CTRL_AUXCNTEV_SHIFT)
#define DEFAULT_AUXCNTEV pcntCntEventNone, /**< Auxiliary counter doesn't respond to events. */
#else
#define DEFAULT_AUXCNTEV
#endif
/** Default selected PRS channel as S0IN and S1IN. */
#if defined(_PCNT_INPUT_MASK)
#define DEFAULT_PRS_CH pcntPRSCh0, /**< PRS channel 0 selected as S0IN and as S1IN. */
#elif defined(_SILICON_LABS_32B_SERIES_2)
#define DEFAULT_PRS_CH 0u,
#else
#define DEFAULT_PRS_CH
#endif
/** Default configuration for PCNT initialization structure. */
#define PCNT_INIT_DEFAULT \
{ \
DEFAULT_MODE /* Default mode. */ \
_PCNT_CNT_RESETVALUE, /* Default counter HW reset value. */ \
_PCNT_TOP_RESETVALUE, /* Default counter HW reset value. */ \
false, /* Use positive edge. */ \
false, /* Up-counting. */ \
false, /* Filter disabled. */ \
DEFAULT_DEBUG_HALT /* Debug Halt enabled. */ \
DEFAULT_HYST /* Default Hysteresis. */ \
DEFAULT_CDIR /* Default CNTDIR. */ \
DEFAULT_CNTEV /* Faults CNTEV. */ \
DEFAULT_AUXCNTEV /* Default AUXCNTEV. */ \
DEFAULT_PRS_CH /* PRS channel 0 selected as S0IN. */ \
DEFAULT_PRS_CH /* PRS channel 0 selected as S1IN. */ \
}
#if defined(PCNT_OVSCFG_FILTLEN_DEFAULT) || defined(_SILICON_LABS_32B_SERIES_2)
/** Filter initialization structure */
typedef struct {
/** Used only in OVSINGLE and OVSQUAD1X-4X modes. To use this, enable filter by
* setting filter to true during PCNT_Init(). Filter length = (filtLen + 5) LFACLK cycles. */
uint8_t filtLen;
/** When set, removes flutter from Quaddecoder inputs S0IN and S1IN.
* Available only in OVSQUAD1X-4X modes. */
bool flutterrm;
} PCNT_Filter_TypeDef;
#endif
/** Default configuration for PCNT initialization structure. */
#if defined(PCNT_OVSCFG_FILTLEN_DEFAULT) || defined(_SILICON_LABS_32B_SERIES_2)
#define PCNT_FILTER_DEFAULT \
{ \
0, /* Default length is 5 LFACLK cycles. */ \
false /* No flutter removal. */ \
}
#endif
#if defined(PCNT_CTRL_TCCMODE_DEFAULT)
/** Modes for Triggered Compare and Clear module. */
typedef enum {
/** Triggered compare and clear not enabled. */
tccModeDisabled = _PCNT_CTRL_TCCMODE_DISABLED,
/** Compare and clear performed on each (optionally prescaled) LFA clock cycle. */
tccModeLFA = _PCNT_CTRL_TCCMODE_LFA,
/** Compare and clear performed on PRS edges. Polarity defined by prsPolarity. */
tccModePRS = _PCNT_CTRL_TCCMODE_PRS
} PCNT_TCCMode_TypeDef;
/** Prescaler values for LFA compare and clear events. Only has effect when TCC mode is LFA. */
typedef enum {
/** Compare and clear event each LFA cycle. */
tccPrescDiv1 = _PCNT_CTRL_TCCPRESC_DIV1,
/** Compare and clear event every other LFA cycle. */
tccPrescDiv2 = _PCNT_CTRL_TCCPRESC_DIV2,
/** Compare and clear event every 4th LFA cycle. */
tccPrescDiv4 = _PCNT_CTRL_TCCPRESC_DIV4,
/** Compare and clear event every 8th LFA cycle. */
tccPrescDiv8 = _PCNT_CTRL_TCCPRESC_DIV8
} PCNT_TCCPresc_Typedef;
/** Compare modes for TCC module. */
typedef enum {
/** Compare match if PCNT_CNT is less than, or equal to PCNT_TOP. */
tccCompLTOE = _PCNT_CTRL_TCCCOMP_LTOE,
/** Compare match if PCNT_CNT is greater than or equal to PCNT_TOP. */
tccCompGTOE = _PCNT_CTRL_TCCCOMP_GTOE,
/** Compare match if PCNT_CNT is less than, or equal to PCNT_TOP[15:8]], and greater
* than, or equal to PCNT_TOP[7:0]. */
tccCompRange = _PCNT_CTRL_TCCCOMP_RANGE
} PCNT_TCCComp_Typedef;
/** TCC initialization structure. */
typedef struct {
/** Mode to operate in. */
PCNT_TCCMode_TypeDef mode;
/** Prescaler value for LFACLK in LFA mode. */
PCNT_TCCPresc_Typedef prescaler;
/** Choose the event that will trigger a clear. */
PCNT_TCCComp_Typedef compare;
/** PRS input to TCC module, either for gating the PCNT clock, triggering the TCC comparison, or both. */
PCNT_PRSSel_TypeDef tccPRS;
/** TCC PRS input polarity. @n
* False = Rising edge for comparison trigger, and PCNT clock gated when PRS signal is high. @n
* True = Falling edge for comparison trigger, and PCNT clock gated when PRS signal is low. */
bool prsPolarity;
/** Enable gating PCNT input clock through TCC PRS signal.
* Polarity selection is done through prsPolarity. */
bool prsGateEnable;
} PCNT_TCC_TypeDef;
/** TCC Default. */
#define PCNT_TCC_DEFAULT \
{ \
tccModeDisabled, /* Disabled by default. */ \
tccPrescDiv1, /* Do not prescale LFA clock in LFA mode. */ \
tccCompLTOE, /* Clear when CNT <= TOP. */ \
pcntPRSCh0, /* Select PRS channel 0 as input to TCC. */ \
false, /* PRS polarity is rising edge, and gate when 1. */ \
false /* Do not gate PCNT counter input. */ \
}
#endif
/* defined(PCNT_CTRL_TCCMODE_DEFAULT) */
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get the pulse counter value.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @return
* Current pulse counter value.
******************************************************************************/
__STATIC_INLINE uint32_t PCNT_CounterGet(PCNT_TypeDef *pcnt)
{
return pcnt->CNT;
}
#if defined(_PCNT_AUXCNT_MASK)
/***************************************************************************//**
* @brief
* Get the auxiliary counter value.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @return
* Current auxiliary counter value.
******************************************************************************/
__STATIC_INLINE uint32_t PCNT_AuxCounterGet(PCNT_TypeDef *pcnt)
{
return pcnt->AUXCNT;
}
#endif
void PCNT_CounterReset(PCNT_TypeDef *pcnt);
void PCNT_CounterTopSet(PCNT_TypeDef *pcnt, uint32_t count, uint32_t top);
/***************************************************************************//**
* @brief
* Set a counter value.
*
* @details
* Pulse counter is disabled while changing counter value and re-enabled
* (if originally enabled) when counter value has been set.
*
* @note
* This function will stall until synchronization to low-frequency domain is
* completed. For that reason, it should normally not be used when using
* an external clock to clock the PCNT module since stall time may be
* undefined in that case. The counter should normally only be set when
* operating in (or about to enable) #pcntModeOvsSingle mode.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @param[in] count
* Value to set in counter register.
******************************************************************************/
__STATIC_INLINE void PCNT_CounterSet(PCNT_TypeDef *pcnt, uint32_t count)
{
PCNT_CounterTopSet(pcnt, count, pcnt->TOP);
}
void PCNT_Enable(PCNT_TypeDef *pcnt, PCNT_Mode_TypeDef mode);
bool PCNT_IsEnabled(PCNT_TypeDef *pcnt);
#if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
void PCNT_FreezeEnable(PCNT_TypeDef *pcnt, bool enable);
#endif
void PCNT_Init(PCNT_TypeDef *pcnt, const PCNT_Init_TypeDef *init);
#if defined(PCNT_OVSCFG_FILTLEN_DEFAULT) || defined(_SILICON_LABS_32B_SERIES_2)
void PCNT_FilterConfiguration(PCNT_TypeDef *pcnt, const PCNT_Filter_TypeDef *config, bool enable);
#endif
#if defined(_PCNT_INPUT_MASK) || defined(_SILICON_LABS_32B_SERIES_2)
void PCNT_PRSInputEnable(PCNT_TypeDef *pcnt,
PCNT_PRSInput_TypeDef prsInput,
bool enable);
#endif
#if defined(PCNT_CTRL_TCCMODE_DEFAULT)
void PCNT_TCCConfiguration(PCNT_TypeDef *pcnt, const PCNT_TCC_TypeDef *config);
#endif
/***************************************************************************//**
* @brief
* Clear one or more pending PCNT interrupts.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @param[in] flags
* Pending PCNT interrupt source to clear. Use a bitwise logic OR combination
* of valid interrupt flags for the PCNT module (PCNT_IF_nnn).
******************************************************************************/
__STATIC_INLINE void PCNT_IntClear(PCNT_TypeDef *pcnt, uint32_t flags)
{
#if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
pcnt->IFC = flags;
#else
pcnt->IF_CLR = flags;
#endif
}
/***************************************************************************//**
* @brief
* Disable one or more PCNT interrupts.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @param[in] flags
* PCNT interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for PCNT module (PCNT_IF_nnn).
******************************************************************************/
__STATIC_INLINE void PCNT_IntDisable(PCNT_TypeDef *pcnt, uint32_t flags)
{
#if defined(PCNT_HAS_SET_CLEAR)
pcnt->IEN_CLR = flags;
#else
pcnt->IEN &= ~flags;
#endif
}
/***************************************************************************//**
* @brief
* Enable one or more PCNT 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
* PCNT_IntClear() prior to enabling the interrupt.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @param[in] flags
* PCNT interrupt sources to enable. Use a bitwise logic OR combination of
* valid interrupt flags for PCNT module (PCNT_IF_nnn).
******************************************************************************/
__STATIC_INLINE void PCNT_IntEnable(PCNT_TypeDef *pcnt, uint32_t flags)
{
#if defined(PCNT_HAS_SET_CLEAR)
pcnt->IEN_SET = flags;
#else
pcnt->IEN |= flags;
#endif
}
/***************************************************************************//**
* @brief
* Get pending PCNT interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @return
* PCNT interrupt sources pending. A bitwise logic OR combination of valid
* interrupt flags for PCNT module (PCNT_IF_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t PCNT_IntGet(PCNT_TypeDef *pcnt)
{
return pcnt->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending PCNT interrupt flags.
*
* @details
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] pcnt
* Pointer to thePCNT peripheral register block.
*
* @return
* Pending and enabled PCNT interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in PCNT_IEN_nnn
* register (PCNT_IEN_nnn) and
* - the OR combination of valid interrupt flags of the PCNT module
* (PCNT_IF_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t PCNT_IntGetEnabled(PCNT_TypeDef *pcnt)
{
uint32_t ien;
/* Store pcnt->IEN in temporary variable in order to define explicit order
* of volatile accesses. */
ien = pcnt->IEN;
/* Bitwise AND of pending and enabled interrupts. */
return pcnt->IF & ien;
}
/***************************************************************************//**
* @brief
* Set one or more pending PCNT interrupts from SW.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @param[in] flags
* PCNT interrupt sources to set to pending. Use a bitwise logic OR combination
* of valid interrupt flags for PCNT module (PCNT_IF_nnn).
******************************************************************************/
__STATIC_INLINE void PCNT_IntSet(PCNT_TypeDef *pcnt, uint32_t flags)
{
#if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
pcnt->IFS = flags;
#else
pcnt->IF_SET = flags;
#endif
}
#if defined(_PCNT_LOCK_MASK)
/***************************************************************************//**
* @brief
* Lock PCNT registers.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @note When PCNT registers are locked PCNT_CFG, PCNT_EN, PCNT_SWRST, PCNT_CMD,
* PCNT_CTRL, PCNT_OVSCTRL, PCNT_CNT, PCNT_TOP, and PCNT_TOPB registers
* cannot be written to.
******************************************************************************/
__STATIC_INLINE void PCNT_Lock(PCNT_TypeDef *pcnt)
{
pcnt->LOCK = ~PCNT_LOCK_PCNTLOCKKEY_UNLOCK;
}
#endif
#if defined(_PCNT_LOCK_MASK)
/***************************************************************************//**
* @brief
* Unlock PCNT registers.
*
* @param[in] pcnt
* Pointer to thePCNT peripheral register block.
******************************************************************************/
__STATIC_INLINE void PCNT_Unlock(PCNT_TypeDef *pcnt)
{
pcnt->LOCK = PCNT_LOCK_PCNTLOCKKEY_UNLOCK;
}
#endif
void PCNT_Reset(PCNT_TypeDef *pcnt);
/***************************************************************************//**
* @brief
* Get the pulse counter top buffer value.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @return
* Current pulse counter top buffer value.
******************************************************************************/
__STATIC_INLINE uint32_t PCNT_TopBufferGet(PCNT_TypeDef *pcnt)
{
#if defined(_SILICON_LABS_32B_SERIES_2)
while (pcnt->SYNCBUSY & PCNT_SYNCBUSY_TOPB) {
}
#endif
return pcnt->TOPB;
}
void PCNT_TopBufferSet(PCNT_TypeDef *pcnt, uint32_t val);
/***************************************************************************//**
* @brief
* Get the pulse counter top value.
*
* @param[in] pcnt
* Pointer to the PCNT peripheral register block.
*
* @return
* Current pulse counter top value.
******************************************************************************/
__STATIC_INLINE uint32_t PCNT_TopGet(PCNT_TypeDef *pcnt)
{
#if defined(_SILICON_LABS_32B_SERIES_2)
while (pcnt->SYNCBUSY & PCNT_SYNCBUSY_TOP) {
}
#endif
return pcnt->TOP;
}
void PCNT_TopSet(PCNT_TypeDef *pcnt, uint32_t val);
/***************************************************************************//**
* @brief
* Wait for an ongoing sync of register(s) to low-frequency domain to complete.
*
* @param[in] pcnt
* A pointer to the PCNT peripheral register block.
*
* @param[in] mask
* A bitmask corresponding to SYNCBUSY register defined bits indicating
* registers that must complete any ongoing synchronization.
******************************************************************************/
__STATIC_INLINE void PCNT_Sync(PCNT_TypeDef *pcnt, uint32_t mask)
{
/* Avoid deadlock if modifying the same register twice when freeze mode is
* activated. */
#if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
if (pcnt->FREEZE & PCNT_FREEZE_REGFREEZE) {
return;
}
#endif
/* Wait for any pending previous write operation to have been completed in
* low-frequency domain. */
while (pcnt->SYNCBUSY & mask) {
}
}
#if defined(_SILICON_LABS_32B_SERIES_2)
/***************************************************************************//**
* @brief
* Start the main PCNT counter.
*
* @details
* This function will send a start command to the PCNT peripheral. The PCNT
* peripheral will use some LF clock ticks before the command is executed.
* The @ref PCNT_Sync() function can be used to wait for the start command
* to be executed.
*
* @param[in] pcnt
* A pointer to the PCNT peripheral register block.
*
* @note
* This function requires the PCNT to be enabled.
******************************************************************************/
__STATIC_INLINE void PCNT_StartMainCnt(PCNT_TypeDef *pcnt)
{
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CMD);
pcnt->CMD_SET = PCNT_CMD_STARTCNT;
}
/***************************************************************************//**
* @brief
* Stop the main PCNT counter.
*
* @details
* This function will send a stop command to the PCNT peripheral. The PCNT
* peripheral will use some LF clock ticks before the command is executed.
* The @ref PCNT_Sync() function can be used to wait for the stop command
* to be executed.
*
* @param[in] pcnt
* A pointer to the PCNT peripheral register block.
*
* @note
* This function requires the PCNT to be enabled.
******************************************************************************/
__STATIC_INLINE void PCNT_StopMainCnt(PCNT_TypeDef *pcnt)
{
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CMD);
pcnt->CMD_SET = PCNT_CMD_STOPCNT;
}
/***************************************************************************//**
* @brief
* Start the auxiliary PCNT counter.
*
* @details
* This function will send a start command to the PCNT peripheral. The PCNT
* peripheral will use some LF clock ticks before the command is executed.
* The @ref PCNT_Sync() function can be used to wait for the start command
* to be executed.
*
* @param[in] pcnt
* A pointer to the PCNT peripheral register block.
*
* @note
* This function requires the PCNT to be enabled.
******************************************************************************/
__STATIC_INLINE void PCNT_StartAuxCnt(PCNT_TypeDef *pcnt)
{
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CMD);
pcnt->CMD_SET = PCNT_CMD_STARTAUXCNT;
}
/***************************************************************************//**
* @brief
* Stop the auxiliary PCNT counter.
*
* @details
* This function will send a stop command to the PCNT peripheral. The PCNT
* peripheral will use some LF clock ticks before the command is executed.
* The @ref PCNT_Sync() function can be used to wait for the stop command
* to be executed.
*
* @param[in] pcnt
* A pointer to the PCNT peripheral register block.
*
* @note
* This function requires the PCNT to be enabled.
******************************************************************************/
__STATIC_INLINE void PCNT_StopAuxCnt(PCNT_TypeDef *pcnt)
{
PCNT_Sync(pcnt, PCNT_SYNCBUSY_CMD);
pcnt->CMD_SET = PCNT_CMD_STOPAUXCNT;
}
#endif
/** @} (end addtogroup pcnt) */
#ifdef __cplusplus
}
#endif
#endif /* defined(PCNT_COUNT) && (PCNT_COUNT > 0) */
#endif /* EM_PCNT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,169 @@
/***************************************************************************//**
* @file
* @brief RAM code support.
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_RAMFUNC_H
#define EM_RAMFUNC_H
#include "sl_code_classification.h"
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-OFF* */
/***************************************************************************//**
* @addtogroup ramfunc RAMFUNC - RAM Function Support
* @brief RAM code support
* @details
* Provides support for executing code from RAM.
* Provides a unified method to manage RAM code across all supported tools.
* @{
@note
Other cross-compiler support macros are implemented in [COMMON](../../common/api/group-common).
@note
Functions executing from RAM should not be declared as static.
@warning
Standard library facilities are available to the tool with GCC in hosted
mode (default), regardless of the section attribute. Calls to standard
libraries placed in the default section may therefore occur. To disable
hosted mode, add '-ffreestanding' to the build command line. This is the
only way to guarantee no calls to standard libraries with GCC.
Read more at www.gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Standards.html
@warning
Keil/ARM uVision users must add a section named "ram_code" in their linker
scatter file. This section must be in RAM memory. Look in the MCU SDK for
example scatter files (ram_code.sct).
@n @section ramfunc_usage Usage
In your .h file:
@verbatim
#include "em_ramfunc.h"
SL_RAMFUNC_DECLARATOR
void MyPrint(const char* string);
@endverbatim
Issues have been observed with ARM GCC when there is no declarator. It is
recommended to have a declarator also for internal functions but move the
declarator to the .c file.
In your .c file:
@verbatim
#include "em_ramfunc.h"
SL_RAMFUNC_DEFINITION_BEGIN
void MyPrint(const char* string)
{
...
}
SL_RAMFUNC_DEFINITION_END
@endverbatim
******************************************************************************/
/* *INDENT-ON* */
/*******************************************************************************
****************************** DEFINES ***********************************
******************************************************************************/
/**
* @brief
* This define is not present by default. By compiling with define
* @ref SL_RAMFUNC_DISABLE, code placed in RAM by SL_RAMFUNC macros
* will be placed in default code space (Flash) instead.
*
* @note
* This define is not present by default.
*/
#if defined(DOXY_DOC_ONLY)
#define SL_RAMFUNC_DISABLE
#endif
#if defined(SL_RAMFUNC_DISABLE)
/** @brief Compiler ported function declarator for RAM code. */
#define SL_RAMFUNC_DECLARATOR
/** @brief Compiler ported function definition begin marker for RAM code. */
#define SL_RAMFUNC_DEFINITION_BEGIN
/** @brief Compiler ported function definition end marker for RAM code. */
#define SL_RAMFUNC_DEFINITION_END
#elif defined(__CC_ARM)
/* MDK-ARM compiler */
#define SL_RAMFUNC_DECLARATOR
#define SL_RAMFUNC_DEFINITION_BEGIN _Pragma("arm section code=\"ram_code\"")
#define SL_RAMFUNC_DEFINITION_END _Pragma("arm section code")
#elif defined(__ICCARM__)
/* IAR Embedded Workbench */
#define SL_RAMFUNC_DECLARATOR SL_CODE_RAM
#define SL_RAMFUNC_DEFINITION_BEGIN SL_RAMFUNC_DECLARATOR
#define SL_RAMFUNC_DEFINITION_END
#elif defined(__GNUC__) && (defined(__CROSSWORKS_ARM) || defined(__SES_ARM))
/* Rowley Crossworks and Segger Embedded Studio */
#define SL_RAMFUNC_DECLARATOR SL_CODE_RAM
#define SL_RAMFUNC_DEFINITION_BEGIN SL_RAMFUNC_DECLARATOR
#define SL_RAMFUNC_DEFINITION_END
#elif defined(__GNUC__) && defined(CONFIG_SOC_FAMILY_EXX32)
/* Zephyr environment */
#define SL_RAMFUNC_DECLARATOR SL_CODE_RAM
#define SL_RAMFUNC_DEFINITION_BEGIN SL_RAMFUNC_DECLARATOR
#define SL_RAMFUNC_DEFINITION_END
#elif defined(__GNUC__)
/* Simplicity Studio, Atollic and Vanilla armgcc */
#define SL_RAMFUNC_DECLARATOR SL_CODE_RAM
#define SL_RAMFUNC_DEFINITION_BEGIN SL_RAMFUNC_DECLARATOR
#define SL_RAMFUNC_DEFINITION_END
#endif
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/* Deprecated macro names */
#define RAMFUNC_DECLARATOR SL_RAMFUNC_DECLARATOR
#define RAMFUNC_DEFINITION_BEGIN SL_RAMFUNC_DEFINITION_BEGIN
#define RAMFUNC_DEFINITION_END SL_RAMFUNC_DEFINITION_END
/** @endcond */
/** @} (end addtogroup ramfunc) */
#ifdef __cplusplus
}
#endif
#endif /* EM_RAMFUNC_H */

View File

@@ -0,0 +1,178 @@
/***************************************************************************//**
* @file
* @brief Reset Management Unit (RMU) peripheral API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_RMU_H
#define EM_RMU_H
#include "em_device.h"
#if (defined(RMU_COUNT) && (RMU_COUNT > 0)) || (_EMU_RSTCTRL_MASK)
#include "sl_assert.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup rmu
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** RMU reset modes. */
typedef enum {
#if defined(_RMU_CTRL_PINRMODE_MASK)
rmuResetModeDisabled = _RMU_CTRL_PINRMODE_DISABLED, /**< Reset mode disabled. */
rmuResetModeLimited = _RMU_CTRL_PINRMODE_LIMITED, /**< Reset mode limited. */
rmuResetModeExtended = _RMU_CTRL_PINRMODE_EXTENDED, /**< Reset mode extended. */
rmuResetModeFull = _RMU_CTRL_PINRMODE_FULL, /**< Reset mode full. */
#elif defined(_EMU_RSTCTRL_MASK)
rmuResetModeDisabled = 0, /**< Reset mode disabled. */
rmuResetModeEnabled = 1, /**< Reset mode enabled. */
#else
rmuResetModeClear = 0, /**< Reset mode clear. */
rmuResetModeSet = 1, /**< Reset mode set. */
#endif
} RMU_ResetMode_TypeDef;
/** RMU controlled peripheral reset control and reset source control. */
typedef enum {
#if defined(RMU_CTRL_BURSTEN)
rmuResetBU = _RMU_CTRL_BURSTEN_MASK, /**< Reset control over Backup Power domain select. */
#endif
#if defined(RMU_CTRL_LOCKUPRDIS)
rmuResetLockUp = _RMU_CTRL_LOCKUPRDIS_MASK, /**< Cortex lockup reset select. */
#elif defined(_RMU_CTRL_LOCKUPRMODE_MASK)
rmuResetLockUp = _RMU_CTRL_LOCKUPRMODE_MASK, /**< Cortex lockup reset select. */
#endif
#if defined(_RMU_CTRL_WDOGRMODE_MASK)
rmuResetWdog = _RMU_CTRL_WDOGRMODE_MASK, /**< WDOG reset select. */
#endif
#if defined(_RMU_CTRL_LOCKUPRMODE_MASK)
rmuResetCoreLockup = _RMU_CTRL_LOCKUPRMODE_MASK, /**< Cortex lockup reset select. */
#endif
#if defined(_RMU_CTRL_SYSRMODE_MASK)
rmuResetSys = _RMU_CTRL_SYSRMODE_MASK, /**< SYSRESET select. */
#endif
#if defined(_RMU_CTRL_PINRMODE_MASK)
rmuResetPin = _RMU_CTRL_PINRMODE_MASK, /**< Pin reset select. */
#endif
#if defined(_EMU_RSTCTRL_WDOG0RMODE_MASK)
rmuResetWdog0 = _EMU_RSTCTRL_WDOG0RMODE_MASK, /**< WDOG0 reset select */
#endif
#if defined(_EMU_RSTCTRL_WDOG1RMODE_MASK)
rmuResetWdog1 = _EMU_RSTCTRL_WDOG1RMODE_MASK, /**< WDOG1 reset select */
#endif
#if defined(_EMU_RSTCTRL_SYSRMODE_MASK)
rmuResetSys = _EMU_RSTCTRL_SYSRMODE_MASK, /**< SYSRESET select */
#endif
#if defined(_EMU_RSTCTRL_LOCKUPRMODE_MASK)
rmuResetCoreLockup = _EMU_RSTCTRL_LOCKUPRMODE_MASK, /**< Cortex lockup reset select */
#endif
#if defined(_EMU_RSTCTRL_AVDDBODRMODE_MASK)
rmuResetAVDD = _EMU_RSTCTRL_AVDDBODRMODE_MASK, /**< AVDD monitoring select */
#endif
#if defined(_EMU_RSTCTRL_IOVDD0BODRMODE_MASK)
rmuResetIOVDD0 = _EMU_RSTCTRL_IOVDD0BODRMODE_MASK, /**< IOVDD0 monitoring select */
#endif
#if defined(_EMU_RSTCTRL_IOVDD1BODRMODE_MASK)
rmuResetIOVDD1 = _EMU_RSTCTRL_IOVDD1BODRMODE_MASK, /**< IOVDD1 monitoring select */
#endif
#if defined(_EMU_RSTCTRL_IOVDD2BODRMODE_MASK)
rmuResetIOVDD2 = _EMU_RSTCTRL_IOVDD2BODRMODE_MASK, /**< IOVDD2 monitoring select */
#endif
#if defined(_EMU_RSTCTRL_DECBODRMODE_MASK)
rmuResetDecouple = _EMU_RSTCTRL_DECBODRMODE_MASK, /**< Decouple monitoring select */
#endif
#if defined(_EMU_RSTCTRL_SESYSRMODE_MASK)
rmuResetSESys = _EMU_RSTCTRL_SESYSRMODE_MASK, /**< M0+ (SE) system reset select */
#endif
#if defined(_EMU_RSTCTRL_SELOCKUPRMODE_MASK)
rmuResetSELockup = _EMU_RSTCTRL_SELOCKUPRMODE_MASK, /**< M0+ (SE) lockup select */
#endif
#if defined(_EMU_RSTCTRL_DCIRMODE_MASK)
rmuResetDCI = _EMU_RSTCTRL_DCIRMODE_MASK, /**< DCI reset select */
#endif
} RMU_Reset_TypeDef;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
/** RMU_LockupResetDisable kept for backwards compatibility. */
#define RMU_LockupResetDisable(A) RMU_ResetControl(rmuResetLockUp, A)
void RMU_ResetControl(RMU_Reset_TypeDef reset, RMU_ResetMode_TypeDef mode);
void RMU_ResetCauseClear(void);
uint32_t RMU_ResetCauseGet(void);
#if defined(_RMU_CTRL_RESETSTATE_MASK)
/***************************************************************************//**
* @brief
* Set user reset state. Reset only by a Power-on-reset and a pin reset.
*
* @param[in] userState User state to set
******************************************************************************/
__STATIC_INLINE void RMU_UserResetStateSet(uint32_t userState)
{
EFM_ASSERT(!(userState
& ~(_RMU_CTRL_RESETSTATE_MASK >> _RMU_CTRL_RESETSTATE_SHIFT)));
RMU->CTRL = (RMU->CTRL & ~_RMU_CTRL_RESETSTATE_MASK)
| (userState << _RMU_CTRL_RESETSTATE_SHIFT);
}
/***************************************************************************//**
* @brief
* Get user reset state. Reset only by a Power-on-reset and a pin reset.
*
* @return
* Reset surviving user state.
******************************************************************************/
__STATIC_INLINE uint32_t RMU_UserResetStateGet(void)
{
uint32_t userState = (RMU->CTRL & _RMU_CTRL_RESETSTATE_MASK)
>> _RMU_CTRL_RESETSTATE_SHIFT;
return userState;
}
#endif
/** @} (end addtogroup rmu) */
#ifdef __cplusplus
}
#endif
#endif /* defined(RMU_COUNT) && (RMU_COUNT > 0) */
#endif /* EM_RMU_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
/***************************************************************************//**
* @file
* @brief API defining acces to SYSCFG registers
*******************************************************************************
* # License
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_SYSCFG_H
#define EM_SYSCFG_H
#include "em_device.h"
#if defined(SL_TRUSTZONE_NONSECURE)
#include "sli_tz_service_syscfg.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(SYSCFG)
/*******************************************************************************
******************************** TZ SERVICES **********************************
******************************************************************************/
#if defined(_SYSCFG_CHIPREV_FAMILY_MASK) || defined(_SYSCFG_CHIPREV_PARTNUMBER_MASK)
/*******************************************************************************
* @brief Reads CHIPREV register
******************************************************************************/
__STATIC_INLINE uint32_t SYSCFG_readChipRev(void)
{
#if defined(SL_TRUSTZONE_NONSECURE)
return sli_tz_syscfg_read_chiprev_register();
#else
#if defined(CMU_CLKEN0_SYSCFG)
CMU->CLKEN0_SET = CMU_CLKEN0_SYSCFG;
#endif
return SYSCFG->CHIPREV;
#endif
}
#endif // defined(_SYSCFG_CHIPREV_FAMILY_MASK) || defined(_SYSCFG_CHIPREV_PARTNUMBER_MASK)
#if defined(_SYSCFG_DMEM0RAMCTRL_RAMWSEN_MASK)
/*******************************************************************************
* @brief Sets DMEM0RAMCTRL RAMWSEN bit to 1
******************************************************************************/
__STATIC_INLINE void SYSCFG_setDmem0RamCtrlRamwsenBit(void)
{
#if defined(SL_TRUSTZONE_NONSECURE)
sli_tz_syscfg_set_dmem0ramctrl_ramwsen_bit();
#else
SYSCFG->DMEM0RAMCTRL = SYSCFG->DMEM0RAMCTRL | _SYSCFG_DMEM0RAMCTRL_RAMWSEN_MASK;
#endif
}
/*******************************************************************************
* @brief Clears DMEM0RAMCTRL RAMWSEN bit to 0
******************************************************************************/
__STATIC_INLINE void SYSCFG_clearDmem0RamCtrlRamwsenBit(void)
{
#if defined(SL_TRUSTZONE_NONSECURE)
sli_tz_syscfg_clear_dmem0ramctrl_ramwsen_bit();
#else
SYSCFG->DMEM0RAMCTRL = SYSCFG->DMEM0RAMCTRL & ~_SYSCFG_DMEM0RAMCTRL_RAMWSEN_MASK;
#endif
}
/*******************************************************************************
* @brief Reads DMEM0RAMCTRL RAMWSEN bit
******************************************************************************/
__STATIC_INLINE uint32_t SYSCFG_getDmem0RamCtrlRamwsenBit(void)
{
#if defined(SL_TRUSTZONE_NONSECURE)
return sli_tz_syscfg_get_dmem0ramctrl_ramwsen_bit();
#else
return (SYSCFG->DMEM0RAMCTRL & _SYSCFG_DMEM0RAMCTRL_RAMWSEN_MASK) >> _SYSCFG_DMEM0RAMCTRL_RAMWSEN_SHIFT;
#endif
}
#endif //_SYSCFG_DMEM0RAMCTRL_RAMWSEN_MASK
#if defined(_SYSCFG_DMEM0RETNCTRL_MASK)
/*******************************************************************************
* @brief Reads DMEM0RETNCTRL register
******************************************************************************/
__STATIC_INLINE uint32_t SYSCFG_readDmem0RetnCtrl(void)
{
#if defined(SL_TRUSTZONE_NONSECURE)
return sli_tz_syscfg_read_dmem0retnctrl_register();
#else
return SYSCFG->DMEM0RETNCTRL;
#endif
}
/*******************************************************************************
* @brief Mask DMEM0RETNCTRL register with provided mask
*
* @param mask - A mask that is to be used to mask the DMEM0RETNCTRL register
******************************************************************************/
__STATIC_INLINE void SYSCFG_maskDmem0RetnCtrl(uint32_t mask)
{
#if defined(SL_TRUSTZONE_NONSECURE)
sli_tz_syscfg_mask_dmem0retnctrl_register(mask);
#else
SYSCFG->DMEM0RETNCTRL = SYSCFG->DMEM0RETNCTRL | mask;
#endif
}
/*******************************************************************************
* @brief Set DMEM0RETNCTRL to zero
******************************************************************************/
__STATIC_INLINE void SYSCFG_zeroDmem0RetnCtrl(void)
{
#if defined(SL_TRUSTZONE_NONSECURE)
sli_tz_syscfg_zero_dmem0retnctrl_register();
#else
SYSCFG->DMEM0RETNCTRL = 0x0UL;
#endif
}
#endif // _SYSCFG_DMEM0RETNCTRL_MASK
#if defined(_SYSCFG_CFGSYSTIC_MASK)
/*******************************************************************************
* @brief Set SYSTICEXTCLKEN bit in CFGSYSTIC to one
******************************************************************************/
__STATIC_INLINE void SYSCFG_setSysTicExtClkEnCfgSysTic(void)
{
#if defined(SL_TRUSTZONE_NONSECURE)
sli_tz_syscfg_set_systicextclken_cfgsystic();
#else
SYSCFG->CFGSYSTIC = (SYSCFG->CFGSYSTIC | _SYSCFG_CFGSYSTIC_SYSTICEXTCLKEN_MASK);
#endif
}
/*******************************************************************************
* @brief Clear SYSTICEXTCLKEN bit in CFGSYSTIC to zero
******************************************************************************/
__STATIC_INLINE void SYSCFG_clearSysTicExtClkEnCfgSysTic(void)
{
#if defined(SL_TRUSTZONE_NONSECURE)
sli_tz_syscfg_clear_systicextclken_cfgsystic();
#else
SYSCFG->CFGSYSTIC = (SYSCFG->CFGSYSTIC & ~_SYSCFG_CFGSYSTIC_SYSTICEXTCLKEN_MASK);
#endif
}
#endif //_SYSCFG_CFGSYSTIC_MASK
#endif //SYSCFG
#ifdef __cplusplus
}
#endif
#endif // EM_SYSCFG_H

View File

@@ -0,0 +1,365 @@
/***************************************************************************//**
* @file
* @brief System API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_SYSTEM_H
#define EM_SYSTEM_H
#include "em_device.h"
#include "em_system_generic.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup system SYSTEM - System Utils
* @brief System API
* @details
* This module contains functions to read information such as RAM and Flash size,
* device unique ID, chip revision, family, and part number from DEVINFO and
* SCB blocks. Functions to configure and read status from FPU are available for
* compatible devices.
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Family identifiers. */
typedef enum {
/* New style family #defines */
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32G)
systemPartFamilyEfm32Gecko = _DEVINFO_PART_DEVICE_FAMILY_EFM32G, /**< EFM32 Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32GG)
systemPartFamilyEfm32Giant = _DEVINFO_PART_DEVICE_FAMILY_EFM32GG, /**< EFM32 Giant Gecko Series 0 Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32GG11B)
systemPartFamilyEfm32Giant11B = _DEVINFO_PART_DEVICE_FAMILY_EFM32GG11B, /**< EFM32 Giant Gecko Series 1 Configuration 1 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32GG12B)
systemPartFamilyEfm32Giant12B = _DEVINFO_PART_DEVICE_FAMILY_EFM32GG12B, /**< EFM32 Giant Gecko Series 1 Configuration 2 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32TG)
systemPartFamilyEfm32Tiny = _DEVINFO_PART_DEVICE_FAMILY_EFM32TG, /**< EFM32 Tiny Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32TG11B)
systemPartFamilyEfm32Tiny11B = _DEVINFO_PART_DEVICE_FAMILY_EFM32TG11B, /**< EFM32 Tiny Gecko 11 Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32LG)
systemPartFamilyEfm32Leopard = _DEVINFO_PART_DEVICE_FAMILY_EFM32LG, /**< EFM32 Leopard Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32WG)
systemPartFamilyEfm32Wonder = _DEVINFO_PART_DEVICE_FAMILY_EFM32WG, /**< EFM32 Wonder Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32ZG)
systemPartFamilyEfm32Zero = _DEVINFO_PART_DEVICE_FAMILY_EFM32ZG, /**< EFM32 Zero Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32HG)
systemPartFamilyEfm32Happy = _DEVINFO_PART_DEVICE_FAMILY_EFM32HG, /**< EFM32 Happy Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32PG1B)
systemPartFamilyEfm32Pearl1B = _DEVINFO_PART_DEVICE_FAMILY_EFM32PG1B, /**< EFM32 Pearl Gecko Series 1 Configuration 1 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32JG1B)
systemPartFamilyEfm32Jade1B = _DEVINFO_PART_DEVICE_FAMILY_EFM32JG1B, /**< EFM32 Jade Gecko Series 1 Configuration 1 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32PG12B)
systemPartFamilyEfm32Pearl12B = _DEVINFO_PART_DEVICE_FAMILY_EFM32PG12B, /**< EFM32 Pearl Gecko Series 1 Configuration 2 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFM32JG12B)
systemPartFamilyEfm32Jade12B = _DEVINFO_PART_DEVICE_FAMILY_EFM32JG12B, /**< EFM32 Jade Gecko Series 1 Configuration 2 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EZR32WG)
systemPartFamilyEzr32Wonder = _DEVINFO_PART_DEVICE_FAMILY_EZR32WG, /**< EZR32 Wonder Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EZR32LG)
systemPartFamilyEzr32Leopard = _DEVINFO_PART_DEVICE_FAMILY_EZR32LG, /**< EZR32 Leopard Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EZR32HG)
systemPartFamilyEzr32Happy = _DEVINFO_PART_DEVICE_FAMILY_EZR32HG, /**< EZR32 Happy Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG1P)
systemPartFamilyMighty1P = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG1P, /**< EFR32 Mighty Gecko Series 1 Configuration 1 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG1B)
systemPartFamilyMighty1B = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG1B, /**< EFR32 Mighty Gecko Series 1 Configuration 1 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG1V)
systemPartFamilyMighty1V = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG1V, /**< EFR32 Mighty Gecko Series 1 Configuration 1 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32BG1P)
systemPartFamilyBlue1P = _DEVINFO_PART_DEVICE_FAMILY_EFR32BG1P, /**< EFR32 Blue Gecko Series 1 Configuration 1 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32BG1B)
systemPartFamilyBlue1B = _DEVINFO_PART_DEVICE_FAMILY_EFR32BG1B, /**< EFR32 Blue Gecko Series 1 Configuration 1 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32BG1V)
systemPartFamilyBlue1V = _DEVINFO_PART_DEVICE_FAMILY_EFR32BG1V, /**< EFR32 Blue Gecko Series 1 Configuration 1 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG1P)
systemPartFamilyFlex1P = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG1P, /**< EFR32 Flex Gecko Series 1 Configuration 1 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG1B)
systemPartFamilyFlex1B = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG1B, /**< EFR32 Flex Gecko Series 1 Configuration 1 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG1V)
systemPartFamilyFlex1V = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG1V, /**< EFR32 Flex Gecko Series 1 Configuration 1 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG12P)
systemPartFamilyMighty12P = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG12P, /**< EFR32 Mighty Gecko Series 1 Configuration 2 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG12B)
systemPartFamilyMighty12B = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG12B, /**< EFR32 Mighty Gecko Series 1 Configuration 2 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG12V)
systemPartFamilyMighty12V = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG12V, /**< EFR32 Mighty Gecko Series 1 Configuration 2 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32BG12P)
systemPartFamilyBlue12P = _DEVINFO_PART_DEVICE_FAMILY_EFR32BG12P, /**< EFR32 Blue Gecko Series 1 Configuration 2 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32BG12B)
systemPartFamilyBlue12B = _DEVINFO_PART_DEVICE_FAMILY_EFR32BG12B, /**< EFR32 Blue Gecko Series 1 Configuration 2 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32BG12V)
systemPartFamilyBlue12V = _DEVINFO_PART_DEVICE_FAMILY_EFR32BG12V, /**< EFR32 Blue Gecko Series 1 Configuration 2 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG12P)
systemPartFamilyFlex12P = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG12P, /**< EFR32 Flex Gecko Series 1 Configuration 2 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG12B)
systemPartFamilyFlex12B = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG12B, /**< EFR32 Flex Gecko Series 1 Configuration 2 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG12V)
systemPartFamilyFlex12V = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG12V, /**< EFR32 Flex Gecko Series 1 Configuration 2 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG13P)
systemPartFamilyMighty13P = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG13P, /**< EFR32 Mighty Gecko Series 1 Configuration 3 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG13B)
systemPartFamilyMighty13B = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG13B, /**< EFR32 Mighty Gecko Series 1 Configuration 3 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG13V)
systemPartFamilyMighty13V = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG13V, /**< EFR32 Mighty Gecko Series 1 Configuration 3 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32BG13P)
systemPartFamilyBlue13P = _DEVINFO_PART_DEVICE_FAMILY_EFR32BG13P, /**< EFR32 Blue Gecko Series 1 Configuration 3 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32BG13B)
systemPartFamilyBlue13B = _DEVINFO_PART_DEVICE_FAMILY_EFR32BG13B, /**< EFR32 Blue Gecko Series 1 Configuration 3 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32BG13V)
systemPartFamilyBlue13V = _DEVINFO_PART_DEVICE_FAMILY_EFR32BG13V, /**< EFR32 Blue Gecko Series 1 Configuration 3 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG13P)
systemPartFamilyFlex13P = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG13P, /**< EFR32 Flex Gecko Series 1 Configuration 3 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG13B)
systemPartFamilyFlex13B = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG13B, /**< EFR32 Flex Gecko Series 1 Configuration 3 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG13V)
systemPartFamilyFlex13V = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG13V, /**< EFR32 Flex Gecko Series 1 Configuration 3 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32ZG13P)
systemPartFamilyZen13P = _DEVINFO_PART_DEVICE_FAMILY_EFR32ZG13P, /**< EFR32 Zen Gecko Series 1 Configuration 3 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32ZG13L)
systemPartFamilyZen13L = _DEVINFO_PART_DEVICE_FAMILY_EFR32ZG13L, /**< EFR32 Zen Gecko Series 1 Configuration 3 Led Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32ZG13S)
systemPartFamilyZen13S = _DEVINFO_PART_DEVICE_FAMILY_EFR32ZG13S, /**< EFR32 Zen Gecko Series 1 Configuration 3 Sensor Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG14P)
systemPartFamilyMighty14P = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG14P, /**< EFR32 Mighty Gecko Series 1 Configuration 4 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG14B)
systemPartFamilyMighty14B = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG14B, /**< EFR32 Mighty Gecko Series 1 Configuration 4 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32MG14V)
systemPartFamilyMighty14V = _DEVINFO_PART_DEVICE_FAMILY_EFR32MG14V, /**< EFR32 Mighty Gecko Series 1 Configuration 4 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG14P)
systemPartFamilyFlex14P = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG14P, /**< EFR32 Flex Gecko Series 1 Configuration 4 Premium Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG14B)
systemPartFamilyFlex14B = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG14B, /**< EFR32 Flex Gecko Series 1 Configuration 4 Basic Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32FG14V)
systemPartFamilyFlex14V = _DEVINFO_PART_DEVICE_FAMILY_EFR32FG14V, /**< EFR32 Flex Gecko Series 1 Configuration 4 Value Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_EFR32ZG14P)
systemPartFamilyZen14P = _DEVINFO_PART_DEVICE_FAMILY_EFR32ZG14P, /**< EFR32 Zen Gecko Series 1 Configuration 4 Premium Device Family. */
#endif
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
systemPartFamilyMighty21 = DEVINFO_PART_FAMILY_MG | (21 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Mighty Gecko Series 2 Config 1 Value Device Family */
systemPartFamilyFlex21 = DEVINFO_PART_FAMILY_FG | (21 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Flex Gecko Series 2 Config 1 Value Device Family */
systemPartFamilyBlue21 = DEVINFO_PART_FAMILY_BG | (21 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Blue Gecko Series 2 Config 1 Value Device Family */
systemPartFamilyMightyRcp21 = DEVINFO_PART_FAMILY_MR | (21 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Mighty RCP Series 2 Config 1 Value Device Family */
#endif
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2)
systemPartFamilyMighty22 = DEVINFO_PART_FAMILY_MG | (22 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Mighty Gecko Series 2 Config 2 Value Device Family */
systemPartFamilyFlex22 = DEVINFO_PART_FAMILY_FG | (22 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Flex Gecko Series 2 Config 2 Value Device Family */
systemPartFamilyBlue22 = DEVINFO_PART_FAMILY_BG | (22 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Blue Gecko Series 2 Config 2 Value Device Family */
systemPartFamilyEfm32Pearl22 = DEVINFO_PART_FAMILY_PG | (22 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFM32 Pearl Gecko Series 2 Config 2 Value Device Family */
#endif
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_3)
systemPartFamilyFlex23 = DEVINFO_PART_FAMILY_FG | (23 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Flex Gecko Series 2 Config 3 Value Device Family */
systemPartFamilyZen23 = DEVINFO_PART_FAMILY_ZG | (23 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Zen Gecko Series 2 Config 3 Value Device Family */
systemPartFamilyEfm32Pearl23 = DEVINFO_PART_FAMILY_PG | (23 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFM32 Pearl Gecko Series 2 Config 3 Value Device Family */
systemPartFamilySideWalk23 = DEVINFO_PART_FAMILY_SG | (23 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Side Walk Gecko Series 2 Config 3 Value Device Family */
#endif
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_4)
systemPartFamilyMighty24 = DEVINFO_PART_FAMILY_MG | (24 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Mighty Gecko Series 2 Config 4 Value Device Family */
systemPartFamilyFlex24 = DEVINFO_PART_FAMILY_FG | (24 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Flex Gecko Series 2 Config 4 Value Device Family */
systemPartFamilyBlue24 = DEVINFO_PART_FAMILY_BG | (24 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Blue Gecko Series 2 Config 4 Value Device Family */
#endif
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_5)
systemPartFamilyFlex25 = DEVINFO_PART_FAMILY_FG | (25 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Flex Gecko Series 2 Config 5 Value Device Family */
#endif
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_6)
systemPartFamilyMighty26 = DEVINFO_PART_FAMILY_MG | (26 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Mighty Gecko Series 2 Config 6 Value Device Family */
systemPartFamilyBlue26 = DEVINFO_PART_FAMILY_BG | (26 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Blue Gecko Series 2 Config 6 Value Device Family */
systemPartFamilyEfm32Pearl26 = DEVINFO_PART_FAMILY_PG | (26 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFM32 Pearl Gecko Series 2 Config 6 Value Device Family */
#endif
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_7)
systemPartFamilyMighty27 = DEVINFO_PART_FAMILY_MG | (27 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Mighty Gecko Series 2 Config 7 Value Device Family */
systemPartFamilyBlue27 = DEVINFO_PART_FAMILY_BG | (27 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Blue Gecko Series 2 Config 7 Value Device Family */
#endif
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_8)
systemPartFamilyFlex28 = DEVINFO_PART_FAMILY_FG | (28 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Flex Gecko Series 2 Config 8 Value Device Family */
systemPartFamilyZen28 = DEVINFO_PART_FAMILY_ZG | (28 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Zen Gecko Series 2 Config 8 Value Device Family */
systemPartFamilySideWalk28 = DEVINFO_PART_FAMILY_SG | (28 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Side Walk Gecko Series 2 Config 8 Value Device Family */
systemPartFamilyEfm32Pearl28 = DEVINFO_PART_FAMILY_PG | (28 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFM32 Pearl Gecko Series 2 Config 8 Value Device Family */
#endif
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_9)
systemPartFamilyMighty29 = DEVINFO_PART_FAMILY_MG | (29 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Mighty Gecko Series 2 Config 9 Value Device Family */
systemPartFamilyBlue29 = DEVINFO_PART_FAMILY_BG | (29 << _DEVINFO_PART_FAMILYNUM_SHIFT), /**< EFR32 Blue Gecko Series 2 Config 9 Value Device Family */
#endif
/* Deprecated family #defines */
#if defined(_DEVINFO_PART_DEVICE_FAMILY_G)
systemPartFamilyGecko = _DEVINFO_PART_DEVICE_FAMILY_G, /**< Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_GG)
systemPartFamilyGiant = _DEVINFO_PART_DEVICE_FAMILY_GG, /**< Giant Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_TG)
systemPartFamilyTiny = _DEVINFO_PART_DEVICE_FAMILY_TG, /**< Tiny Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_LG)
systemPartFamilyLeopard = _DEVINFO_PART_DEVICE_FAMILY_LG, /**< Leopard Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_WG)
systemPartFamilyWonder = _DEVINFO_PART_DEVICE_FAMILY_WG, /**< Wonder Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_ZG)
systemPartFamilyZero = _DEVINFO_PART_DEVICE_FAMILY_ZG, /**< Zero Gecko Device Family. */
#endif
#if defined(_DEVINFO_PART_DEVICE_FAMILY_HG)
systemPartFamilyHappy = _DEVINFO_PART_DEVICE_FAMILY_HG, /**< Happy Gecko Device Family. */
#endif
systemPartFamilyUnknown = 0xFF /**< Unknown Device Family.
Family ID is missing
on unprogrammed parts. */
} SYSTEM_PartFamily_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** Chip revision details. */
typedef struct {
uint8_t minor; /**< Minor revision number. */
uint8_t major; /**< Major revision number. */
#if defined(_SYSCFG_CHIPREV_PARTNUMBER_MASK)
uint16_t partNumber; /**< Device part number. */
#else
uint8_t family; /**< Device family number. */
#endif
} SYSTEM_ChipRevision_TypeDef;
#if defined(__FPU_PRESENT) && (__FPU_PRESENT == 1)
/** Floating point co-processor access modes. */
typedef enum {
fpuAccessDenied = (0x0 << 20), /**< Access denied, any attempted access generates a NOCP UsageFault. */
fpuAccessPrivilegedOnly = (0x5 << 20), /**< Privileged access only, an unprivileged access generates a NOCP UsageFault. */
fpuAccessReserved = (0xA << 20), /**< Reserved. */
fpuAccessFull = (0xF << 20) /**< Full access. */
} SYSTEM_FpuAccess_TypeDef;
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev);
SYSTEM_PartFamily_TypeDef SYSTEM_GetFamily(void);
#if defined(_DEVINFO_DEVINFOREV_DEVINFOREV_MASK) || defined(_DEVINFO_INFO_DEVINFOREV_MASK)
/***************************************************************************//**
* @brief
* Get DEVINFO revision.
*
* @return
* Revision of the DEVINFO contents.
******************************************************************************/
__STATIC_INLINE uint8_t SYSTEM_GetDevinfoRev(void)
{
#if defined(_DEVINFO_DEVINFOREV_DEVINFOREV_MASK)
return (uint8_t)((DEVINFO->DEVINFOREV & _DEVINFO_DEVINFOREV_DEVINFOREV_MASK)
>> _DEVINFO_DEVINFOREV_DEVINFOREV_SHIFT);
#elif defined(_DEVINFO_INFO_DEVINFOREV_MASK)
return (uint8_t)((DEVINFO->INFO & _DEVINFO_INFO_DEVINFOREV_MASK)
>> _DEVINFO_INFO_DEVINFOREV_SHIFT);
#endif
}
#endif
#if defined(__FPU_PRESENT) && (__FPU_PRESENT == 1)
/***************************************************************************//**
* @brief
* Set floating point co-processor (FPU) access mode.
*
* @param[in] accessMode
* Floating point co-processor access mode. See @ref SYSTEM_FpuAccess_TypeDef
* for details.
******************************************************************************/
__STATIC_INLINE void SYSTEM_FpuAccessModeSet(SYSTEM_FpuAccess_TypeDef accessMode)
{
SCB->CPACR = (SCB->CPACR & ~(0xFUL << 20)) | (uint32_t)accessMode;
}
#endif
/** @} (end addtogroup system) */
#ifdef __cplusplus
}
#endif
#endif /* EM_SYSTEM_H */

View File

@@ -0,0 +1,91 @@
/***************************************************************************//**
* @file
* @brief System API (Generic)
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_SYSTEM_GENERIC_H
#define EM_SYSTEM_GENERIC_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup system
* @{
******************************************************************************/
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Family security capability. */
typedef enum {
securityCapabilityUnknown, /**< Unknown security capability. */
securityCapabilityNA, /**< Security capability not applicable. */
securityCapabilityBasic, /**< Basic security capability. */
securityCapabilityRoT, /**< Root of Trust security capability. */
securityCapabilitySE, /**< Secure Element security capability. */
securityCapabilityVault /**< Secure Vault security capability. */
} SYSTEM_SecurityCapability_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** DEVINFO calibration address/value pair. */
typedef struct {
uint32_t address; /**< Peripheral calibration register address. */
uint32_t calValue; /**< Calibration value for register at address. */
}
SYSTEM_CalAddrVal_TypeDef;
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
bool SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress);
SYSTEM_SecurityCapability_TypeDef SYSTEM_GetSecurityCapability(void);
uint64_t SYSTEM_GetUnique(void);
uint8_t SYSTEM_GetProdRev(void);
uint32_t SYSTEM_GetSRAMBaseAddress(void);
uint16_t SYSTEM_GetSRAMSize(void);
uint16_t SYSTEM_GetFlashSize(void);
uint32_t SYSTEM_GetFlashPageSize(void);
uint16_t SYSTEM_GetPartNumber(void);
uint8_t SYSTEM_GetCalibrationTemperature(void);
/** @} (end addtogroup system) */
#ifdef __cplusplus
}
#endif
#endif /* EM_SYSTEM_GENERIC_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,773 @@
/***************************************************************************//**
* @file
* @brief Digital to Analog Converter (VDAC) peripheral API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_VDAC_H
#define EM_VDAC_H
#include "em_device.h"
#if defined(VDAC_COUNT) && (VDAC_COUNT > 0)
#include "sl_assert.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup vdac VDAC - Voltage DAC
* @brief Digital to Analog Voltage Converter (VDAC) Peripheral API
*
* @details
* This module contains functions to control the VDAC peripheral of Silicon
* Labs' 32-bit MCUs and SoCs. VDAC converts digital values to analog
* signals at up to 500 ksps with 12-bit accuracy. VDAC is designed for
* low energy consumption, but can also provide very good performance.
*
* The following steps are necessary for basic operation:
*
* Clock enable:
* @code
CMU_ClockEnable(cmuClock_VDAC0, true);@endcode
*
* Initialize the VDAC with default settings and modify selected fields:
* @code
VDAC_Init_TypeDef vdacInit = VDAC_INIT_DEFAULT;
VDAC_InitChannel_TypeDef vdacChInit = VDAC_INITCHANNEL_DEFAULT;
// Set prescaler to get 1 MHz VDAC clock frequency.
vdacInit.prescaler = VDAC_PrescaleCalc(1000000, true, 0); // function call for series 0/1
VDAC_Init(VDAC0, &vdacInit);
vdacChInit.enable = true;
VDAC_InitChannel(VDAC0, &vdacChInit, 0);@endcode
*
* Perform a conversion:
* @code
VDAC_ChannelOutputSet(VDAC0, 0, 250);@endcode
*
* @note The output stage of a VDAC channel consists of an on-chip operational
* amplifier (OPAMP) in the OPAMP module. This OPAMP is highly configurable;
* and to exploit the VDAC functionality fully, configure the OPAMP using
* the OPAMP API. Using the OPAMP API also loads OPAMP calibration values.
* The default (reset) settings of OPAMP is sufficient for many applications.
* @{
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of VDAC register block pointer reference for assert statements.*/
#if VDAC_COUNT == 1
#define VDAC_REF_VALID(ref) ((ref) == VDAC0)
#elif VDAC_COUNT == 2
#define VDAC_REF_VALID(ref) (((ref) == VDAC0) || ((ref) == VDAC1))
#else
#error "Undefined number of VDACs."
#endif
/** @endcond */
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
#if !defined(_SILICON_LABS_32B_SERIES_2)
/** Channel refresh period. */
typedef enum {
vdacRefresh8 = _VDAC_CTRL_REFRESHPERIOD_8CYCLES, /**< Refresh every 8 clock cycles. */
vdacRefresh16 = _VDAC_CTRL_REFRESHPERIOD_16CYCLES, /**< Refresh every 16 clock cycles. */
vdacRefresh32 = _VDAC_CTRL_REFRESHPERIOD_32CYCLES, /**< Refresh every 32 clock cycles. */
vdacRefresh64 = _VDAC_CTRL_REFRESHPERIOD_64CYCLES, /**< Refresh every 64 clock cycles. */
} VDAC_Refresh_TypeDef;
/** Reference voltage for VDAC. */
typedef enum {
vdacRef1V25Ln = _VDAC_CTRL_REFSEL_1V25LN, /**< Internal low noise 1.25 V band gap reference. */
vdacRef2V5Ln = _VDAC_CTRL_REFSEL_2V5LN, /**< Internal low noise 2.5 V band gap reference. */
vdacRef1V25 = _VDAC_CTRL_REFSEL_1V25, /**< Internal 1.25 V band gap reference. */
vdacRef2V5 = _VDAC_CTRL_REFSEL_2V5, /**< Internal 2.5 V band gap reference. */
vdacRefAvdd = _VDAC_CTRL_REFSEL_VDD, /**< AVDD reference. */
vdacRefExtPin = _VDAC_CTRL_REFSEL_EXT, /**< External pin reference. */
} VDAC_Ref_TypeDef;
/** Peripheral Reflex System signal used to trigger VDAC channel conversion. */
typedef enum {
vdacPrsSelCh0 = _VDAC_CH0CTRL_PRSSEL_PRSCH0, /**< PRS ch 0 triggers conversion. */
vdacPrsSelCh1 = _VDAC_CH0CTRL_PRSSEL_PRSCH1, /**< PRS ch 1 triggers conversion. */
vdacPrsSelCh2 = _VDAC_CH0CTRL_PRSSEL_PRSCH2, /**< PRS ch 2 triggers conversion. */
vdacPrsSelCh3 = _VDAC_CH0CTRL_PRSSEL_PRSCH3, /**< PRS ch 3 triggers conversion. */
vdacPrsSelCh4 = _VDAC_CH0CTRL_PRSSEL_PRSCH4, /**< PRS ch 4 triggers conversion. */
vdacPrsSelCh5 = _VDAC_CH0CTRL_PRSSEL_PRSCH5, /**< PRS ch 5 triggers conversion. */
vdacPrsSelCh6 = _VDAC_CH0CTRL_PRSSEL_PRSCH6, /**< PRS ch 6 triggers conversion. */
vdacPrsSelCh7 = _VDAC_CH0CTRL_PRSSEL_PRSCH7, /**< PRS ch 7 triggers conversion. */
#if defined(_VDAC_CH0CTRL_PRSSEL_PRSCH8)
vdacPrsSelCh8 = _VDAC_CH0CTRL_PRSSEL_PRSCH8, /**< PRS ch 8 triggers conversion. */
#endif
#if defined(_VDAC_CH0CTRL_PRSSEL_PRSCH9)
vdacPrsSelCh9 = _VDAC_CH0CTRL_PRSSEL_PRSCH9, /**< PRS ch 9 triggers conversion. */
#endif
#if defined(_VDAC_CH0CTRL_PRSSEL_PRSCH10)
vdacPrsSelCh10 = _VDAC_CH0CTRL_PRSSEL_PRSCH10, /**< PRS ch 10 triggers conversion. */
#endif
#if defined(_VDAC_CH0CTRL_PRSSEL_PRSCH11)
vdacPrsSelCh11 = _VDAC_CH0CTRL_PRSSEL_PRSCH11, /**< PRS ch 11 triggers conversion. */
#endif
} VDAC_PrsSel_TypeDef;
/** Channel conversion trigger mode. */
typedef enum {
vdacTrigModeSw = _VDAC_CH0CTRL_TRIGMODE_SW, /**< Channel is triggered by CHnDATA or COMBDATA write. */
vdacTrigModePrs = _VDAC_CH0CTRL_TRIGMODE_PRS, /**< Channel is triggered by PRS input. */
vdacTrigModeRefresh = _VDAC_CH0CTRL_TRIGMODE_REFRESH, /**< Channel is triggered by Refresh timer. */
vdacTrigModeSwPrs = _VDAC_CH0CTRL_TRIGMODE_SWPRS, /**< Channel is triggered by CHnDATA/COMBDATA write or PRS input. */
vdacTrigModeSwRefresh = _VDAC_CH0CTRL_TRIGMODE_SWREFRESH, /**< Channel is triggered by CHnDATA/COMBDATA write or Refresh timer. */
vdacTrigModeLesense = _VDAC_CH0CTRL_TRIGMODE_LESENSE, /**< Channel is triggered by LESENSE. */
} VDAC_TrigMode_TypeDef;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** VDAC initialization structure, common for both channels. */
typedef struct {
/** Selects between main and alternate output path calibration values. */
bool mainCalibration;
/** Selects clock from asynchronous or synchronous (with respect to
peripheral clock) source. */
bool asyncClockMode;
/** Warm-up mode, keep VDAC on (in idle) - or shutdown between conversions.*/
bool warmupKeepOn;
/** Channel refresh period. */
VDAC_Refresh_TypeDef refresh;
/** Prescaler for VDAC clock. Clock is source clock divided by prescaler+1. */
uint32_t prescaler;
/** Reference voltage to use. */
VDAC_Ref_TypeDef reference;
/** Enable/disable reset of prescaler on CH 0 start. */
bool ch0ResetPre;
/** Enable/disable output enable control by CH1 PRS signal. */
bool outEnablePRS;
/** Enable/disable sine mode. */
bool sineEnable;
/** Select if single ended or differential output mode. */
bool diff;
} VDAC_Init_TypeDef;
/** Default configuration for VDAC initialization structure. */
#define VDAC_INIT_DEFAULT \
{ \
true, /* Use main output path calibration values. */ \
false, /* Use synchronous clock mode. */ \
false, /* Turn off between sample off conversions.*/ \
vdacRefresh8, /* Refresh every 8th cycle. */ \
0, /* No prescaling. */ \
vdacRef1V25Ln, /* 1.25 V internal low noise reference. */ \
false, /* Do not reset prescaler on CH 0 start. */ \
false, /* VDAC output enable always on. */ \
false, /* Disable sine mode. */ \
false /* Single ended mode. */ \
}
/** VDAC channel initialization structure. */
typedef struct {
/** Enable channel. */
bool enable;
/**
* Peripheral reflex system trigger selection. Only applicable if @p trigMode
* is set to @p vdacTrigModePrs or @p vdacTrigModeSwPrs. */
VDAC_PrsSel_TypeDef prsSel;
/** Treat the PRS signal asynchronously. */
bool prsAsync;
/** Channel conversion trigger mode. */
VDAC_TrigMode_TypeDef trigMode;
/** Set channel conversion mode to sample/shut-off mode. Default is
* continuous.*/
bool sampleOffMode;
} VDAC_InitChannel_TypeDef;
/** Default configuration for VDAC channel initialization structure. */
#define VDAC_INITCHANNEL_DEFAULT \
{ \
false, /* Leave channel disabled when initialization is done. */ \
vdacPrsSelCh0, /* PRS CH 0 triggers conversion. */ \
false, /* Treat PRS channel as a synchronous signal. */ \
vdacTrigModeSw, /* Conversion trigged by CH0DATA or COMBDATA write. */ \
false, /* Channel conversion set to continuous. */ \
}
#else // defined(_SILICON_LABS_32B_SERIES_2)
/** Channel refresh period. */
typedef enum {
vdacRefresh2 = _VDAC_CFG_REFRESHPERIOD_CYCLES2, /**< Refresh every 2 clock cycles. */
vdacRefresh4 = _VDAC_CFG_REFRESHPERIOD_CYCLES4, /**< Refresh every 4 clock cycles. */
vdacRefresh8 = _VDAC_CFG_REFRESHPERIOD_CYCLES8, /**< Refresh every 8 clock cycles. */
vdacRefresh16 = _VDAC_CFG_REFRESHPERIOD_CYCLES16, /**< Refresh every 16 clock cycles. */
vdacRefresh32 = _VDAC_CFG_REFRESHPERIOD_CYCLES32, /**< Refresh every 32 clock cycles. */
vdacRefresh64 = _VDAC_CFG_REFRESHPERIOD_CYCLES64, /**< Refresh every 64 clock cycles. */
vdacRefresh128 = _VDAC_CFG_REFRESHPERIOD_CYCLES128, /**< Refresh every 128 clock cycles. */
vdacRefresh256 = _VDAC_CFG_REFRESHPERIOD_CYCLES256, /**< Refresh every 256 clock cycles. */
} VDAC_Refresh_TypeDef;
/** Timer overflow period. */
typedef enum {
vdacCycles2 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES2, /**< Overflows every 2 clock cycles. */
vdacCycles4 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES4, /**< Overflows every 4 clock cycles. */
vdacCycles8 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES8, /**< Overflows every 8 clock cycles. */
vdacCycles16 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES16, /**< Overflows every 16 clock cycles. */
vdacCycles32 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES32, /**< Overflows every 32 clock cycles. */
vdacCycles64 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES64 /**< Overflows every 64 clock cycles. */
} VDAC_TimerOverflow_TypeDef;
/** Reference voltage for VDAC. */
typedef enum {
vdacRef1V25 = _VDAC_CFG_REFRSEL_V125, /**< Internal 1.25 V band gap reference. */
vdacRef2V5 = _VDAC_CFG_REFRSEL_V25, /**< Internal 2.5 V band gap reference. */
vdacRefAvdd = _VDAC_CFG_REFRSEL_VDD, /**< AVDD reference. */
vdacRefExtPin = _VDAC_CFG_REFRSEL_EXT, /**< External pin reference. */
} VDAC_Ref_TypeDef;
/** Refresh source for VDAC. */
typedef enum {
vdacRefreshSrcNone = _VDAC_CH0CFG_REFRESHSOURCE_NONE, /**< No refresh source. */
vdacRefreshSrcRefreshTimer = _VDAC_CH0CFG_REFRESHSOURCE_REFRESHTIMER,/**< Refresh triggered by refresh timer overflow. */
vdacRefreshSrcSyncPrs = _VDAC_CH0CFG_REFRESHSOURCE_SYNCPRS, /**< Refresh triggered by sync PRS. */
vdacRefreshSrcAsyncPrs = _VDAC_CH0CFG_REFRESHSOURCE_ASYNCPRS, /**< Refresh triggered by async PRS. */
} VDAC_RefreshSource_TypeDef;
/** Channel conversion trigger mode. */
typedef enum {
vdacTrigModeNone = _VDAC_CH0CFG_TRIGMODE_NONE, /**< No conversion trigger source selected. */
vdacTrigModeSw = _VDAC_CH0CFG_TRIGMODE_SW, /**< Channel is triggered by CHnDATA or COMBDATA write. */
vdacTrigModeSyncPrs = _VDAC_CH0CFG_TRIGMODE_SYNCPRS, /**< Channel is triggered by Sync PRS input. */
#if defined(LESENSE_PRESENT) && defined(_VDAC_CH0CFG_TRIGMODE_LESENSE)
vdacTrigModeLesense = _VDAC_CH0CFG_TRIGMODE_LESENSE, /**< Channel is triggered by LESENSE. */
#endif
vdacTrigModeInternalTimer = _VDAC_CH0CFG_TRIGMODE_INTERNALTIMER, /**< Channel is triggered by Internal Timer. */
vdacTrigModeAsyncPrs = _VDAC_CH0CFG_TRIGMODE_ASYNCPRS /**< Channel is triggered by Async PRS input. */
} VDAC_TrigMode_TypeDef;
/** Channel power mode. */
typedef enum {
vdacPowerModeHighPower = _VDAC_CH0CFG_POWERMODE_HIGHPOWER, /**< High power buffer mode. */
vdacPowerModeLowPower = _VDAC_CH0CFG_POWERMODE_LOWPOWER /**< Low power buffer mode. */
} VDAC_PowerMode_TypeDef;
/** VDAC channel Abus port selection. */
typedef enum {
/** No GPIO selected. */
vdacChPortNone = _VDAC_OUTCTRL_ABUSPORTSELCH0_NONE,
/** Port A selected. */
vdacChPortA = _VDAC_OUTCTRL_ABUSPORTSELCH0_PORTA,
/** Port B selected. */
vdacChPortB = _VDAC_OUTCTRL_ABUSPORTSELCH0_PORTB,
/** Port C selected. */
vdacChPortC = _VDAC_OUTCTRL_ABUSPORTSELCH0_PORTC,
/** Port D selected. */
vdacChPortD = _VDAC_OUTCTRL_ABUSPORTSELCH0_PORTD,
} VDAC_ChPortSel_t;
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** VDAC initialization structure, common for both channels. */
typedef struct {
/** Number of prescaled CLK_DAC + 1 for the vdac to warmup. */
uint32_t warmupTime;
/** Halt during debug. */
bool dbgHalt;
/** Always allow clk_dac. */
bool onDemandClk;
/** DMA Wakeup. */
bool dmaWakeUp;
/** Bias keep warm enable. */
bool biasKeepWarm;
/** Channel refresh period. */
VDAC_Refresh_TypeDef refresh;
/** Internal timer overflow period. */
VDAC_TimerOverflow_TypeDef timerOverflow;
/** Prescaler for VDAC clock. Clock is source clock divided by prescaler+1. */
uint32_t prescaler;
/** Reference voltage to use. */
VDAC_Ref_TypeDef reference;
/** Enable/disable reset of prescaler on CH 0 start. */
bool ch0ResetPre;
/** Sine reset mode. */
bool sineReset;
/** Enable/disable sine mode. */
bool sineEnable;
/** Select if single ended or differential output mode. */
bool diff;
#if defined(VDAC_CFG_SINEMODEPRS)
/** PRS controlled sinemode enable. */
bool sineModePrsEnable;
#endif
#if defined(VDAC_CFG_OUTENPRS)
/** PRS controlled channel output enable. */
bool prsOutEnable;
#endif
} VDAC_Init_TypeDef;
#if defined(VDAC_CFG_SINEMODEPRS)
/** Default configuration for VDAC initialization structure. */
#define VDAC_INIT_DEFAULT \
{ \
_VDAC_CFG_WARMUPTIME_DEFAULT, /* Number of prescaled DAC_CLK for Vdac to warmup. */ \
false, /* Continue while debugging. */ \
false, /* On demand clock. */ \
false, /* DMA wake up. */ \
false, /* Bias keep warm. */ \
vdacRefresh2, /* Refresh every 2th cycle. */ \
vdacCycles2, /* Internal overflow every 2th cycle. */ \
0, /* No prescaling. */ \
vdacRef1V25, /* 1.25 V internal low noise reference. */ \
false, /* Do not reset prescaler on CH 0 start. */ \
false, /* Sine wave is stopped at the sample its currently outputting. */ \
false, /* Disable sine mode. */ \
false, /* Differential mode. */ \
false, /* PRS controlled sinemode. */ \
false, /* PRS controlled output enable. */ \
}
#else
/** Default configuration for VDAC initialization structure. */
#define VDAC_INIT_DEFAULT \
{ \
_VDAC_CFG_WARMUPTIME_DEFAULT, /* Number of prescaled DAC_CLK for Vdac to warmup. */ \
false, /* Continue while debugging. */ \
false, /* On demand clock. */ \
false, /* DMA wake up. */ \
false, /* Bias keep warm. */ \
vdacRefresh2, /* Refresh every 2th cycle. */ \
vdacCycles2, /* Internal overflow every 2th cycle. */ \
0, /* No prescaling. */ \
vdacRef1V25, /* 1.25 V internal low noise reference. */ \
false, /* Do not reset prescaler on CH 0 start. */ \
false, /* Sine wave is stopped at the sample its currently outputting. */ \
false, /* Disable sine mode. */ \
false, /* Differential mode. */ \
}
#endif
#if defined(VDAC_CFG_SINEMODEPRS)
/** Sine mode configuration for VDAC initialization structure. */
#define VDAC_INIT_SINE_GENERATION_MODE \
{ \
_VDAC_CFG_WARMUPTIME_DEFAULT, /* Number of prescaled DAC_CLK for Vdac to warmup. */ \
false, /* Continue while debugging. */ \
true, /* On demand clock. */ \
false, /* DMA wake up. */ \
false, /* Bias keep warm. */ \
vdacRefresh8, /* Refresh every 8th cycle. */ \
vdacCycles2, /* Internal overflow every 8th cycle. */ \
0, /* No prescaling. */ \
vdacRef1V25, /* 1.25 V internal low noise reference. */ \
false, /* Do not reset prescaler on CH 0 start. */ \
false, /* Sine wave is stopped at the sample its currently outputting. */ \
true, /* Enable sine mode. */ \
false, /* Differential mode. */ \
false, /* PRS controlled sinemode. */ \
false, /* PRS controlled output enable. */ \
}
#else
/** Sine mode configuration for VDAC initialization structure. */
#define VDAC_INIT_SINE_GENERATION_MODE \
{ \
_VDAC_CFG_WARMUPTIME_DEFAULT, /* Number of prescaled DAC_CLK for Vdac to warmup. */ \
false, /* Continue while debugging. */ \
true, /* On demand clock. */ \
false, /* DMA wake up. */ \
false, /* Bias keep warm. */ \
vdacRefresh8, /* Refresh every 8th cycle. */ \
vdacCycles2, /* Internal overflow every 8th cycle. */ \
0, /* No prescaling. */ \
vdacRef1V25, /* 1.25 V internal low noise reference. */ \
false, /* Do not reset prescaler on CH 0 start. */ \
false, /* Sine wave is stopped at the sample its currently outputting. */ \
true, /* Enable sine mode. */ \
false, /* Differential mode. */ \
}
#endif
/** VDAC channel initialization structure. */
typedef struct {
/** Enable channel. */
bool enable;
/** Warm-up mode, keep VDAC on (in idle) - or shutdown between conversions.*/
bool warmupKeepOn;
/** Select high capacitance load mode in conjunction with high power. */
bool highCapLoadEnable;
/** Channel x FIFO Low threshold data valid level. */
uint32_t fifoLowDataThreshold;
/** Channel refresh source. */
VDAC_RefreshSource_TypeDef chRefreshSource;
/** Channel conversion trigger mode. */
VDAC_TrigMode_TypeDef trigMode;
/** Channel power mode. */
VDAC_PowerMode_TypeDef powerMode;
/** Set channel conversion mode to sample/shut-off mode. Default is
* continuous.*/
bool sampleOffMode;
/** Vdac channel output pin. */
uint32_t pin;
/** Vdac channel output port. */
VDAC_ChPortSel_t port;
/** Short High power and low power output. */
bool shortOutput;
/** Alternative output enable. */
bool auxOutEnable;
/** Main output enable. */
bool mainOutEnable;
/** Channel output hold time. */
uint32_t holdOutTime;
} VDAC_InitChannel_TypeDef;
/** Default configuration for VDAC channel initialization structure. */
#define VDAC_INITCHANNEL_DEFAULT \
{ \
false, /* Leave channel disabled when initialization is done. */ \
false, /* Turn off between sample off conversions.*/ \
true, /* Enable High cap mode. */ \
0, /* FIFO data low watermark at 0. */ \
vdacRefreshSrcNone, /* Channel refresh source. */ \
vdacTrigModeSw, /* Conversion trigged by CH0DATA or COMBDATA write. */ \
vdacPowerModeHighPower, /* High power mode enabled. */ \
false, /* Continuous conversion mode. */ \
0, /* ABUS pin selected. */ \
vdacChPortNone, /* No Analog bus port selected. */ \
false, /* Output not shorted */ \
false, /* Alternative output disabled. */ \
true, /* Main output enabled. */ \
0, /* Hold out time. Previously called settle time */ \
}
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void VDAC_ChannelOutputSet(VDAC_TypeDef *vdac,
unsigned int channel,
uint32_t value);
void VDAC_Enable(VDAC_TypeDef *vdac, unsigned int ch, bool enable);
void VDAC_Init(VDAC_TypeDef *vdac, const VDAC_Init_TypeDef *init);
void VDAC_InitChannel(VDAC_TypeDef *vdac,
const VDAC_InitChannel_TypeDef *init,
unsigned int ch);
#if defined(_SILICON_LABS_32B_SERIES_2)
/***************************************************************************//**
* @brief
* Start/stop Sinemode.
*
* @details
* This function sends the sine mode start/stop signal to the DAC.
*
* @param[in] vdac
* Pointer to VDAC peripheral register block.
*
* @param[in] start
* True to start the Sine mode, false to stop it.
******************************************************************************/
__STATIC_INLINE void VDAC_SineModeStart(VDAC_TypeDef *vdac, bool start)
{
EFM_ASSERT(VDAC_REF_VALID(vdac));
while (0UL != (vdac->STATUS & VDAC_STATUS_SYNCBUSY)) {
}
if (start) {
vdac->CMD = VDAC_CMD_SINEMODESTART;
while (0UL == (vdac->STATUS & VDAC_STATUS_SINEACTIVE)) {
}
} else {
vdac->CMD = VDAC_CMD_SINEMODESTOP;
while (0UL != (vdac->STATUS & VDAC_STATUS_SINEACTIVE)) {
}
}
}
#endif
/***************************************************************************//**
* @brief
* Set the output signal of VDAC channel 0 to a given value.
*
* @details
* This function sets the output signal of VDAC channel 0 by writing @p value
* to the CH0DATA register.
*
* @param[in] vdac
* Pointer to VDAC peripheral register block.
*
* @param[in] value
* Value to write to channel 0 output register CH0DATA.
******************************************************************************/
__STATIC_INLINE void VDAC_Channel0OutputSet(VDAC_TypeDef *vdac,
uint32_t value)
{
#if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
EFM_ASSERT(value <= _VDAC_CH0DATA_MASK);
vdac->CH0DATA = value;
#elif defined(_SILICON_LABS_32B_SERIES_2)
EFM_ASSERT(value <= _VDAC_CH0F_MASK);
vdac->CH0F = value;
#endif
}
/***************************************************************************//**
* @brief
* Set the output signal of VDAC channel 1 to a given value.
*
* @details
* This function sets the output signal of VDAC channel 1 by writing @p value
* to the CH1DATA register.
*
* @param[in] vdac
* Pointer to VDAC peripheral register block.
*
* @param[in] value
* Value to write to channel 1 output register CH1DATA.
******************************************************************************/
__STATIC_INLINE void VDAC_Channel1OutputSet(VDAC_TypeDef *vdac,
uint32_t value)
{
#if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
EFM_ASSERT(value <= _VDAC_CH1DATA_MASK);
vdac->CH1DATA = value;
#elif defined(_SILICON_LABS_32B_SERIES_2)
EFM_ASSERT(value <= _VDAC_CH1F_MASK);
vdac->CH1F = value;
#endif
}
/***************************************************************************//**
* @brief
* Clear one or more pending VDAC interrupts.
*
* @param[in] vdac
* Pointer to VDAC peripheral register block.
*
* @param[in] flags
* Pending VDAC interrupt source to clear. Use a bitwise logic OR combination
* of valid interrupt flags for the VDAC module (VDAC_IF_nnn).
******************************************************************************/
__STATIC_INLINE void VDAC_IntClear(VDAC_TypeDef *vdac, uint32_t flags)
{
#if defined(VDAC_HAS_SET_CLEAR)
vdac->IF_CLR = flags;
#else
vdac->IFC = flags;
#endif
}
/***************************************************************************//**
* @brief
* Disable one or more VDAC interrupts.
*
* @param[in] vdac
* Pointer to VDAC peripheral register block.
*
* @param[in] flags
* VDAC interrupt sources to disable. Use a bitwise logic OR combination of
* valid interrupt flags for the VDAC module (VDAC_IF_nnn).
******************************************************************************/
__STATIC_INLINE void VDAC_IntDisable(VDAC_TypeDef *vdac, uint32_t flags)
{
#if defined(VDAC_HAS_SET_CLEAR)
vdac->IEN_CLR = flags;
#else
vdac->IEN &= ~flags;
#endif
}
/***************************************************************************//**
* @brief
* Enable one or more VDAC 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
* VDAC_IntClear() prior to enabling the interrupt.
*
* @param[in] vdac
* Pointer to VDAC peripheral register block.
*
* @param[in] flags
* VDAC interrupt sources to enable. Use a bitwise logic OR combination
* of valid interrupt flags for the VDAC module (VDAC_IF_nnn).
******************************************************************************/
__STATIC_INLINE void VDAC_IntEnable(VDAC_TypeDef *vdac, uint32_t flags)
{
#if defined(VDAC_HAS_SET_CLEAR)
vdac->IEN_SET = flags;
#else
vdac->IEN |= flags;
#endif
}
/***************************************************************************//**
* @brief
* Get pending VDAC interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] vdac
* Pointer to VDAC peripheral register block.
*
* @return
* VDAC interrupt sources pending. Use a bitwise logic OR combination
* of valid interrupt flags for the VDAC module (VDAC_IF_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t VDAC_IntGet(VDAC_TypeDef *vdac)
{
return vdac->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending VDAC interrupt flags.
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @param[in] vdac
* Pointer to VDAC peripheral register block.
*
* @note
* Interrupt flags are not cleared by the use of this function.
*
* @return
* Pending and enabled VDAC interrupt sources.
* The return value is the bitwise AND combination of
* - the OR combination of enabled interrupt sources in VDACx_IEN_nnn
* register (VDACx_IEN_nnn) and
* - the OR combination of valid interrupt flags of the VDAC module
* (VDACx_IF_nnn).
******************************************************************************/
__STATIC_INLINE uint32_t VDAC_IntGetEnabled(VDAC_TypeDef *vdac)
{
uint32_t ien = vdac->IEN;
/* Bitwise AND of pending and enabled interrupts */
return vdac->IF & ien;
}
/***************************************************************************//**
* @brief
* Set one or more pending VDAC interrupts from SW.
*
* @param[in] vdac
* Pointer to VDAC peripheral register block.
*
* @param[in] flags
* VDAC interrupt sources to set to pending. Use a bitwise logic OR
* combination of valid interrupt flags for the VDAC module (VDAC_IF_nnn).
******************************************************************************/
__STATIC_INLINE void VDAC_IntSet(VDAC_TypeDef *vdac, uint32_t flags)
{
#if defined(VDAC_HAS_SET_CLEAR)
vdac->IF_SET = flags;
#else
vdac->IFS = flags;
#endif
}
#if defined(_SILICON_LABS_32B_SERIES_2)
/***************************************************************************//**
* @brief
* Get the VDAC Status register.
*
* @param[in] vdac
* Pointer to VDAC peripheral register block.
*
* @return
* Current STATUS register value.
******************************************************************************/
__STATIC_INLINE uint32_t VDAC_GetStatus(VDAC_TypeDef *vdac)
{
return vdac->STATUS;
}
#endif
#if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
uint32_t VDAC_PrescaleCalc(uint32_t vdacFreq, bool syncMode, uint32_t hfperFreq);
#else
uint32_t VDAC_PrescaleCalc(VDAC_TypeDef *vdac, uint32_t vdacFreq);
#endif
void VDAC_Reset(VDAC_TypeDef *vdac);
/** @} (end addtogroup vdac) */
#ifdef __cplusplus
}
#endif
#endif /* defined(VDAC_COUNT) && (VDAC_COUNT > 0) */
#endif /* EM_VDAC_H */

View File

@@ -0,0 +1,68 @@
/***************************************************************************//**
* @file
* @brief CMSIS and EMLIB versions
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_VERSION_H
#define EM_VERSION_H
#include "em_device.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup version VERSION - Version Defines
* @brief Version API
* @details
* Macros specifying the EMLIB and CMSIS version.
* @{
******************************************************************************/
/* *INDENT-OFF* */
/** Version number of targeted CMSIS package. */
#define _CMSIS_VERSION 5.8.0
/* *INDENT-ON* */
/** Major version of CMSIS. */
#define _CMSIS_VERSION_MAJOR 5
/** Minor version of CMSIS. */
#define _CMSIS_VERSION_MINOR 8
/** Patch revision of CMSIS. */
#define _CMSIS_VERSION_PATCH 0
/** @} (end addtogroup version) */
#ifdef __cplusplus
}
#endif
#endif /* EM_VERSION_H */

View File

@@ -0,0 +1,455 @@
/***************************************************************************//**
* @file
* @brief Watchdog (WDOG) peripheral API
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 EM_WDOG_H
#define EM_WDOG_H
#include "em_device.h"
#if defined(WDOG_COUNT) && (WDOG_COUNT > 0)
#include <stdbool.h>
#include "sl_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup wdog
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** Default WDOG instance for deprecated functions. */
#if !defined(DEFAULT_WDOG)
#if defined(WDOG0)
#define DEFAULT_WDOG WDOG0
#elif defined(WDOG)
#define DEFAULT_WDOG WDOG
#endif
#endif
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Watchdog clock selection. */
#if defined(_WDOG_CTRL_CLKSEL_MASK)
typedef enum {
wdogClkSelULFRCO = _WDOG_CTRL_CLKSEL_ULFRCO, /**< Ultra low frequency (1 kHz) clock */
wdogClkSelLFRCO = _WDOG_CTRL_CLKSEL_LFRCO, /**< Low frequency RC oscillator */
wdogClkSelLFXO = _WDOG_CTRL_CLKSEL_LFXO /**< Low frequency crystal oscillator */
} WDOG_ClkSel_TypeDef;
#endif
/** Watchdog period selection. */
typedef enum {
wdogPeriod_9 = 0x0, /**< 9 clock periods */
wdogPeriod_17 = 0x1, /**< 17 clock periods */
wdogPeriod_33 = 0x2, /**< 33 clock periods */
wdogPeriod_65 = 0x3, /**< 65 clock periods */
wdogPeriod_129 = 0x4, /**< 129 clock periods */
wdogPeriod_257 = 0x5, /**< 257 clock periods */
wdogPeriod_513 = 0x6, /**< 513 clock periods */
wdogPeriod_1k = 0x7, /**< 1025 clock periods */
wdogPeriod_2k = 0x8, /**< 2049 clock periods */
wdogPeriod_4k = 0x9, /**< 4097 clock periods */
wdogPeriod_8k = 0xA, /**< 8193 clock periods */
wdogPeriod_16k = 0xB, /**< 16385 clock periods */
wdogPeriod_32k = 0xC, /**< 32769 clock periods */
wdogPeriod_64k = 0xD, /**< 65537 clock periods */
wdogPeriod_128k = 0xE, /**< 131073 clock periods */
wdogPeriod_256k = 0xF /**< 262145 clock periods */
} WDOG_PeriodSel_TypeDef;
#if defined(_WDOG_CTRL_WARNSEL_MASK) \
|| defined(_WDOG_CFG_WARNSEL_MASK)
/** Select Watchdog warning timeout period as percentage of timeout. */
typedef enum {
wdogWarnDisable = 0, /**< Watchdog warning period is disabled. */
wdogWarnTime25pct = 1, /**< Watchdog warning period is 25% of the timeout. */
wdogWarnTime50pct = 2, /**< Watchdog warning period is 50% of the timeout. */
wdogWarnTime75pct = 3, /**< Watchdog warning period is 75% of the timeout. */
} WDOG_WarnSel_TypeDef;
#endif
#if defined(_WDOG_CTRL_WINSEL_MASK) \
|| defined(_WDOG_CFG_WINSEL_MASK)
/** Select Watchdog illegal window limit. */
typedef enum {
wdogIllegalWindowDisable = 0, /**< Watchdog illegal window disabled. */
wdogIllegalWindowTime12_5pct = 1, /**< Window timeout is 12.5% of the timeout. */
wdogIllegalWindowTime25_0pct = 2, /**< Window timeout is 25% of the timeout. */
wdogIllegalWindowTime37_5pct = 3, /**< Window timeout is 37.5% of the timeout. */
wdogIllegalWindowTime50_0pct = 4, /**< Window timeout is 50% of the timeout. */
wdogIllegalWindowTime62_5pct = 5, /**< Window timeout is 62.5% of the timeout. */
wdogIllegalWindowTime75_0pct = 6, /**< Window timeout is 75% of the timeout. */
wdogIllegalWindowTime87_5pct = 7, /**< Window timeout is 87.5% of the timeout. */
} WDOG_WinSel_TypeDef;
#endif
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** Watchdog initialization structure. */
typedef struct {
/** Enable Watchdog when initialization completed. */
bool enable;
/** Counter keeps running during debug halt. */
bool debugRun;
#if defined(_WDOG_CTRL_CLRSRC_MASK) \
|| defined(_WDOG_CFG_CLRSRC_MASK)
/** Select WDOG clear source:
* False: Write to the clear bit will clear the WDOG counter
* True: Rising edge on the PRS Source 0 will clear the WDOG counter
* */
bool clrSrc;
#endif
#if defined(_WDOG_CFG_EM1RUN_MASK)
/** Counter keeps running when in EM1. Available for series2. */
bool em1Run;
#endif
/** Counter keeps running when in EM2. */
bool em2Run;
/** Counter keeps running when in EM3. */
bool em3Run;
/** Block EMU from entering EM4. */
bool em4Block;
#if defined(_WDOG_CFG_MASK)
/** When set, a PRS Source 0 missing event will trigger a WDOG reset. */
bool prs0MissRstEn;
/** When set, a PRS Source 1 missing event will trigger a WDOG reset. */
bool prs1MissRstEn;
#endif
/** Block SW from disabling LFRCO/LFXO oscillators. */
#if defined(_WDOG_CTRL_SWOSCBLOCK_MASK)
bool swoscBlock;
#endif
/** Block SW from modifying the configuration (a reset is needed to reconfigure). */
bool lock;
/** Clock source to use for Watchdog. */
#if defined(_WDOG_CTRL_CLKSEL_MASK)
WDOG_ClkSel_TypeDef clkSel;
#endif
/** Watchdog timeout period. */
WDOG_PeriodSel_TypeDef perSel;
#if defined(_WDOG_CTRL_WARNSEL_MASK) \
|| defined(_WDOG_CFG_WARNSEL_MASK)
/** Select warning time as % of the Watchdog timeout */
WDOG_WarnSel_TypeDef warnSel;
#endif
#if defined(_WDOG_CTRL_WINSEL_MASK) \
|| defined(_WDOG_CFG_WINSEL_MASK)
/** Select illegal window time as % of the Watchdog timeout */
WDOG_WinSel_TypeDef winSel;
#endif
#if defined(_WDOG_CTRL_WDOGRSTDIS_MASK) \
|| defined(_WDOG_CFG_WDOGRSTDIS_MASK)
/** Disable Watchdog reset output if true */
bool resetDisable;
#endif
} WDOG_Init_TypeDef;
/** Suggested default configuration for WDOG initialization structure. */
#if defined(_WDOG_CFG_MASK) && defined(_WDOG_CFG_EM1RUN_MASK)
#define WDOG_INIT_DEFAULT \
{ \
true, /* Start Watchdog when initialization is done. */ \
false, /* WDOG is not counting during debug halt. */ \
false, /* The clear bit will clear the WDOG counter. */ \
false, /* WDOG is not counting when in EM1. */ \
false, /* WDOG is not counting when in EM2. */ \
false, /* WDOG is not counting when in EM3. */ \
false, /* EM4 can be entered. */ \
false, /* PRS Source 0 missing event will not trigger a WDOG reset. */ \
false, /* PRS Source 1 missing event will not trigger a WDOG reset. */ \
false, /* Do not lock WDOG configuration. */ \
wdogPeriod_256k, /* Set longest possible timeout period. */ \
wdogWarnDisable, /* Disable warning interrupt. */ \
wdogIllegalWindowDisable, /* Disable illegal window interrupt. */ \
false /* Do not disable reset. */ \
}
#elif defined(_WDOG_CFG_MASK)
#define WDOG_INIT_DEFAULT \
{ \
true, /* Start Watchdog when initialization is done. */ \
false, /* WDOG is not counting during debug halt. */ \
false, /* The clear bit will clear the WDOG counter. */ \
false, /* WDOG is not counting when in EM2. */ \
false, /* WDOG is not counting when in EM3. */ \
false, /* EM4 can be entered. */ \
false, /* PRS Source 0 missing event will not trigger a WDOG reset. */ \
false, /* PRS Source 1 missing event will not trigger a WDOG reset. */ \
false, /* Do not lock WDOG configuration. */ \
wdogPeriod_256k, /* Set longest possible timeout period. */ \
wdogWarnDisable, /* Disable warning interrupt. */ \
wdogIllegalWindowDisable, /* Disable illegal window interrupt. */ \
false /* Do not disable reset. */ \
}
#elif defined(_WDOG_CTRL_WARNSEL_MASK) \
&& defined(_WDOG_CTRL_WDOGRSTDIS_MASK) \
&& defined(_WDOG_CTRL_WINSEL_MASK)
#define WDOG_INIT_DEFAULT \
{ \
true, /* Start Watchdog when initialization is done. */ \
false, /* WDOG is not counting during debug halt. */ \
false, /* The clear bit will clear the WDOG counter. */ \
false, /* WDOG is not counting when in EM2. */ \
false, /* WDOG is not counting when in EM3. */ \
false, /* EM4 can be entered. */ \
false, /* Do not block disabling LFRCO/LFXO in CMU. */ \
false, /* Do not lock WDOG configuration. */ \
wdogClkSelLFRCO, /* Select 32.768 kHZ WDOG oscillator. */ \
wdogPeriod_256k, /* Set longest possible timeout period. */ \
wdogWarnDisable, /* Disable warning interrupt. */ \
wdogIllegalWindowDisable, /* Disable illegal window interrupt. */ \
false /* Do not disable reset. */ \
}
#else
#define WDOG_INIT_DEFAULT \
{ \
true, /* Start Watchdog when initialization is done. */ \
false, /* WDOG is not counting during debug halt. */ \
false, /* WDOG is not counting when in EM2. */ \
false, /* WDOG is not counting when in EM3. */ \
false, /* EM4 can be entered. */ \
false, /* Do not block disabling LFRCO/LFXO in CMU. */ \
false, /* Do not lock WDOG configuration. */ \
wdogClkSelLFRCO, /* Select 32.768 kHz WDOG oscillator. */ \
wdogPeriod_256k /* Set longest possible timeout period. */ \
}
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void WDOGn_Enable(WDOG_TypeDef *wdog, bool enable);
void WDOGn_Feed(WDOG_TypeDef *wdog);
void WDOGn_Init(WDOG_TypeDef *wdog, const WDOG_Init_TypeDef *init);
void WDOGn_Lock(WDOG_TypeDef *wdog);
void WDOGn_SyncWait(WDOG_TypeDef *wdog);
void WDOGn_Unlock(WDOG_TypeDef *wdog);
#if defined(_WDOG_IF_MASK)
/***************************************************************************//**
* @brief
* Clear one or more pending WDOG interrupts.
*
* @param[in] wdog
* Pointer to the WDOG peripheral register block.
*
* @param[in] flags
* WDOG interrupt sources to clear. Use a set of interrupt flags OR-ed
* together to clear multiple interrupt sources.
******************************************************************************/
__STATIC_INLINE void WDOGn_IntClear(WDOG_TypeDef *wdog, uint32_t flags)
{
#if defined(WDOG_HAS_SET_CLEAR)
wdog->IF_CLR = flags;
#else
wdog->IFC = flags;
#endif
}
/***************************************************************************//**
* @brief
* Disable one or more WDOG interrupts.
*
* @param[in] wdog
* Pointer to the WDOG peripheral register block.
*
* @param[in] flags
* WDOG interrupt sources to disable. Use a set of interrupt flags OR-ed
* together to disable multiple interrupt.
******************************************************************************/
__STATIC_INLINE void WDOGn_IntDisable(WDOG_TypeDef *wdog, uint32_t flags)
{
#if defined(WDOG_HAS_SET_CLEAR)
wdog->IEN_CLR = flags;
#else
wdog->IEN &= ~flags;
#endif
}
/***************************************************************************//**
* @brief
* Enable one or more WDOG 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
* WDOG_IntClear() prior to enabling the interrupt.
*
* @param[in] wdog
* Pointer to the WDOG peripheral register block.
*
* @param[in] flags
* WDOG interrupt sources to enable. Use a set of interrupt flags OR-ed
* together to set multiple interrupt.
******************************************************************************/
__STATIC_INLINE void WDOGn_IntEnable(WDOG_TypeDef *wdog, uint32_t flags)
{
#if defined(WDOG_HAS_SET_CLEAR)
wdog->IEN_SET = flags;
#else
wdog->IEN |= flags;
#endif
}
/***************************************************************************//**
* @brief
* Get pending WDOG interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] wdog
* Pointer to the WDOG peripheral register block.
*
* @return
* Pending WDOG interrupt sources. Returns a set of interrupt flags OR-ed
* together for the interrupt sources set.
******************************************************************************/
__STATIC_INLINE uint32_t WDOGn_IntGet(WDOG_TypeDef *wdog)
{
return wdog->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending WDOG interrupt flags.
*
* @details
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @param[in] wdog
* Pointer to the WDOG peripheral register block.
*
* @return
* Pending and enabled WDOG interrupt sources. Returns a set of interrupt
* flags OR-ed together for the interrupt sources set.
******************************************************************************/
__STATIC_INLINE uint32_t WDOGn_IntGetEnabled(WDOG_TypeDef *wdog)
{
uint32_t tmp;
tmp = wdog->IEN;
/* Bitwise AND of pending and enabled interrupt flags. */
return wdog->IF & tmp;
}
/***************************************************************************//**
* @brief
* Set one or more pending WDOG interrupts from SW.
*
* @param[in] wdog
* Pointer to the WDOG peripheral register block.
*
* @param[in] flags
* WDOG interrupt sources to set to pending. Use a set of interrupt flags
* (WDOG_IFS_nnn).
******************************************************************************/
__STATIC_INLINE void WDOGn_IntSet(WDOG_TypeDef *wdog, uint32_t flags)
{
#if defined(WDOG_HAS_SET_CLEAR)
wdog->IF_SET = flags;
#else
wdog->IFS = flags;
#endif
}
#endif
/***************************************************************************//**
* @brief
* Get enabled status of the Watchdog.
*
* @param[in] wdog
* Pointer to the WDOG peripheral register block.
*
* @return
* True if Watchdog is enabled.
******************************************************************************/
__STATIC_INLINE bool WDOGn_IsEnabled(WDOG_TypeDef *wdog)
{
#if defined(_WDOG_EN_MASK)
return (wdog->EN & _WDOG_EN_EN_MASK) == WDOG_EN_EN;
#else
return (wdog->CTRL & _WDOG_CTRL_EN_MASK) == WDOG_CTRL_EN;
#endif
}
/***************************************************************************//**
* @brief
* Get locked status of the Watchdog.
*
* @param[in] wdog
* Pointer to the WDOG peripheral register block.
*
* @return
* True if Watchdog is locked.
******************************************************************************/
__STATIC_INLINE bool WDOGn_IsLocked(WDOG_TypeDef *wdog)
{
#if defined(_WDOG_STATUS_MASK)
return (wdog->STATUS & _WDOG_STATUS_LOCK_MASK) == WDOG_STATUS_LOCK_LOCKED;
#else
return (wdog->CTRL & _WDOG_CTRL_LOCK_MASK) == WDOG_CTRL_LOCK;
#endif
}
/** @} (end addtogroup wdog) */
#ifdef __cplusplus
}
#endif
#endif /* defined(WDOG_COUNT) && (WDOG_COUNT > 0) */
#endif /* EM_WDOG_H */

File diff suppressed because it is too large Load Diff