Initial commit of firmware
This commit is contained in:
32
Libs/platform/peripheral/inc/peripheral_sysrtc.h
Normal file
32
Libs/platform/peripheral/inc/peripheral_sysrtc.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief System Real Time Counter (SYSRTC) peripheral API
|
||||
*******************************************************************************
|
||||
* # 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
// Compatibility layer. peripheral_sysrtc.h has been renamed to sl_hal_sysrtc.h
|
||||
#include "sl_hal_sysrtc.h"
|
||||
33
Libs/platform/peripheral/inc/peripheral_sysrtc_compat.h
Normal file
33
Libs/platform/peripheral/inc/peripheral_sysrtc_compat.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief SYSRTC Compatibility Layer.
|
||||
*******************************************************************************
|
||||
* # 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
// Compatibility layer. peripheral_sysrtc_compat.h has been renamed to
|
||||
// sl_hal_sysrtc_compat.h
|
||||
#include "sl_hal_sysrtc_compat.h"
|
||||
274
Libs/platform/peripheral/inc/sl_hal_bus.h
Normal file
274
Libs/platform/peripheral/inc/sl_hal_bus.h
Normal file
@@ -0,0 +1,274 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief RAM and peripheral bit-field set, clear, read and write API.
|
||||
*******************************************************************************
|
||||
* # 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 SL_HAL_BUS_H
|
||||
#define SL_HAL_BUS_H
|
||||
|
||||
#include "sl_assert.h"
|
||||
#include "sl_core.h"
|
||||
#include "em_device.h"
|
||||
#include "sl_code_classification.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 field set/clear/write/read access to RAM and peripheral's registers.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Perform a single-bit write operation on a 32-bit word in RAM.
|
||||
*
|
||||
* @param[in] addr An address 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 sl_hal_bus_ram_write_bit(volatile uint32_t *addr,
|
||||
uint32_t bit,
|
||||
uint32_t val)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Perform a single-bit read operation on a 32-bit word in RAM.
|
||||
*
|
||||
* @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 sl_hal_bus_ram_read_bit(volatile const uint32_t *addr,
|
||||
uint32_t bit)
|
||||
{
|
||||
return ((*addr) >> bit) & 1UL;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Perform a single-bit atomic write operation on a peripheral register.
|
||||
*
|
||||
* @details
|
||||
* This function uses built-in hardware 4K-aliased addressing that allows to
|
||||
* perform an atomic read-modify-write operation on a single register bit.
|
||||
* See the reference manual for more details about alias addressing.
|
||||
*
|
||||
* @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.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_COMMON, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
__STATIC_INLINE void sl_hal_bus_reg_write_bit(volatile uint32_t *addr,
|
||||
uint32_t bit,
|
||||
uint32_t 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;
|
||||
#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 atomic read operation on a peripheral register.
|
||||
*
|
||||
* @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 sl_hal_bus_reg_read_bit(volatile const uint32_t *addr,
|
||||
uint32_t bit)
|
||||
{
|
||||
return ((*addr) >> bit) & 1UL;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Perform an atomic masked set operation on a peripheral register address.
|
||||
*
|
||||
* @details
|
||||
* A peripheral register masked set provides a 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.
|
||||
*
|
||||
* @note
|
||||
* This function uses built-in hardware 4K-aliased addressing that allows to
|
||||
* perform an atomic read-modify-write operation.
|
||||
* See the reference manual for more details about alias addressing.
|
||||
*
|
||||
* @param[in] addr A peripheral register address.
|
||||
*
|
||||
* @param[in] mask A mask to set.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void sl_hal_bus_reg_set_mask(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;
|
||||
#else
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
|
||||
CORE_ENTER_CRITICAL();
|
||||
*addr |= mask;
|
||||
CORE_EXIT_CRITICAL();
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Perform an atomic masked clear operation on the peripheral register address.
|
||||
*
|
||||
* @details
|
||||
* A peripheral register masked clear provides a 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.
|
||||
*
|
||||
* @note
|
||||
* This function uses built-in hardware 4K-aliased addressing that allows to
|
||||
* perform an atomic read-modify-write operation.
|
||||
* See the reference manual for more details about alias addressing.
|
||||
*
|
||||
* @param[in] addr A peripheral register address.
|
||||
*
|
||||
* @param[in] mask A mask to clear.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void sl_hal_bus_reg_clear_mask(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;
|
||||
#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.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void sl_hal_bus_reg_write_mask(volatile uint32_t *addr,
|
||||
uint32_t mask,
|
||||
uint32_t val)
|
||||
{
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
CORE_ENTER_CRITICAL();
|
||||
*addr = (*addr & ~mask) | (val & mask);
|
||||
CORE_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @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 sl_hal_bus_reg_read_mask(volatile const uint32_t *addr,
|
||||
uint32_t mask)
|
||||
{
|
||||
return *addr & mask;
|
||||
}
|
||||
|
||||
/** @} (end addtogroup bus) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SL_HAL_BUS_H */
|
||||
915
Libs/platform/peripheral/inc/sl_hal_gpio.h
Normal file
915
Libs/platform/peripheral/inc/sl_hal_gpio.h
Normal file
@@ -0,0 +1,915 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief General Purpose IO (GPIO) 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 SL_HAL_GPIO_H
|
||||
#define SL_HAL_GPIO_H
|
||||
|
||||
#include "em_device.h"
|
||||
|
||||
#if defined(GPIO_PRESENT)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "sl_assert.h"
|
||||
#include "sl_device_gpio.h"
|
||||
#include "sl_code_classification.h"
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
// *****************************************************************************
|
||||
/// @addtogroup gpio GPIO - General Purpose Input Output
|
||||
/// @brief General Purpose Input Output peripheral
|
||||
///
|
||||
/// @li @ref gpio_intro
|
||||
///
|
||||
///@n @section gpio_intro Introduction
|
||||
/// This module contains functions to control the GPIO peripheral of Silicon Labs 32-bit MCUs and SoCs.
|
||||
/// The GPIO peripheral is used for interrupt configuration, pin configuration and direct pin manipulation
|
||||
/// as well as routing for peripheral pin connections.
|
||||
///
|
||||
/// @{
|
||||
// *****************************************************************************
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** DEFINES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/// Define for port specific pin mask
|
||||
#if defined(GPIO_PA_MASK)
|
||||
#define SL_HAL_GPIO_PORT_A_PIN_MASK (GPIO_PA_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_A_PIN_MASK 0
|
||||
#endif
|
||||
#if defined(GPIO_PB_MASK)
|
||||
#define SL_HAL_GPIO_PORT_B_PIN_MASK (GPIO_PB_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_B_PIN_MASK 0
|
||||
#endif
|
||||
#if defined(GPIO_PC_MASK)
|
||||
#define SL_HAL_GPIO_PORT_C_PIN_MASK (GPIO_PC_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_C_PIN_MASK 0
|
||||
#endif
|
||||
#if defined(GPIO_PD_MASK)
|
||||
#define SL_HAL_GPIO_PORT_D_PIN_MASK (GPIO_PD_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_D_PIN_MASK 0
|
||||
#endif
|
||||
#if defined(GPIO_PE_MASK)
|
||||
#define SL_HAL_GPIO_PORT_E_PIN_MASK (GPIO_PE_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_E_PIN_MASK 0
|
||||
#endif
|
||||
#if defined(GPIO_PF_MASK)
|
||||
#define SL_HAL_GPIO_PORT_F_PIN_MASK (GPIO_PF_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_F_PIN_MASK 0
|
||||
#endif
|
||||
#if defined(GPIO_PG_MASK)
|
||||
#define SL_HAL_GPIO_PORT_G_PIN_MASK (GPIO_PG_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_G_PIN_MASK 0
|
||||
#endif
|
||||
#if defined(GPIO_PH_MASK)
|
||||
#define SL_HAL_GPIO_PORT_H_PIN_MASK (GPIO_PH_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_H_PIN_MASK 0
|
||||
#endif
|
||||
#if defined(GPIO_PI_MASK)
|
||||
#define SL_HAL_GPIO_PORT_I_PIN_MASK (GPIO_PI_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_I_PIN_MASK 0
|
||||
#endif
|
||||
#if defined(GPIO_PJ_MASK)
|
||||
#define SL_HAL_GPIO_PORT_J_PIN_MASK (GPIO_PJ_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_J_PIN_MASK 0
|
||||
#endif
|
||||
#if defined(GPIO_PK_MASK)
|
||||
#define SL_HAL_GPIO_PORT_K_PIN_MASK (GPIO_PK_MASK)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_K_PIN_MASK 0
|
||||
#endif
|
||||
|
||||
/// Define for port specific pin count
|
||||
#if defined(GPIO_PA_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_A_PIN_COUNT (GPIO_PA_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_A_PIN_COUNT 0
|
||||
#endif
|
||||
#if defined(GPIO_PB_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_B_PIN_COUNT (GPIO_PB_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_B_PIN_COUNT 0
|
||||
#endif
|
||||
#if defined(GPIO_PC_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_C_PIN_COUNT (GPIO_PC_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_C_PIN_COUNT 0
|
||||
#endif
|
||||
#if defined(GPIO_PD_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_D_PIN_COUNT (GPIO_PD_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_D_PIN_COUNT 0
|
||||
#endif
|
||||
#if defined(GPIO_PE_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_E_PIN_COUNT (GPIO_PE_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_E_PIN_COUNT 0
|
||||
#endif
|
||||
#if defined(GPIO_PF_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_F_PIN_COUNT (GPIO_PF_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_F_PIN_COUNT 0
|
||||
#endif
|
||||
#if defined(GPIO_PG_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_G_PIN_COUNT (GPIO_PG_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_G_PIN_COUNT 0
|
||||
#endif
|
||||
#if defined(GPIO_PH_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_H_PIN_COUNT (GPIO_PH_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_H_PIN_COUNT 0
|
||||
#endif
|
||||
#if defined(GPIO_PI_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_I_PIN_COUNT (GPIO_PI_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_I_PIN_COUNT 0
|
||||
#endif
|
||||
#if defined(GPIO_PJ_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_J_PIN_COUNT (GPIO_PJ_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_J_PIN_COUNT 0
|
||||
#endif
|
||||
#if defined(GPIO_PK_COUNT)
|
||||
#define SL_HAL_GPIO_PORT_K_PIN_COUNT (GPIO_PK_COUNT)
|
||||
#else
|
||||
#define SL_HAL_GPIO_PORT_K_PIN_COUNT 0
|
||||
#endif
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
|
||||
/// Highest GPIO port number.
|
||||
|
||||
#if (SL_HAL_GPIO_PORT_K_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 10
|
||||
#elif (SL_HAL_GPIO_PORT_J_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 9
|
||||
#elif (SL_HAL_GPIO_PORT_I_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 8
|
||||
#elif (SL_HAL_GPIO_PORT_H_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 7
|
||||
#elif (SL_HAL_GPIO_PORT_G_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 6
|
||||
#elif (SL_HAL_GPIO_PORT_F_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 5
|
||||
#elif (SL_HAL_GPIO_PORT_E_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 4
|
||||
#elif (SL_HAL_GPIO_PORT_D_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 3
|
||||
#elif (SL_HAL_GPIO_PORT_C_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 2
|
||||
#elif (SL_HAL_GPIO_PORT_B_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 1
|
||||
#elif (SL_HAL_GPIO_PORT_A_PIN_COUNT > 0)
|
||||
#define SL_HAL_GPIO_PORT_MAX 0
|
||||
#else
|
||||
#error "Max GPIO port number is undefined for this part."
|
||||
#endif
|
||||
|
||||
/// Highest GPIO pin number.
|
||||
#define SL_HAL_GPIO_PIN_MAX 15
|
||||
|
||||
/// @endcond
|
||||
|
||||
#define SL_HAL_GPIO_PORT_SIZE(port) ( \
|
||||
(port) == 0 ? SL_HAL_GPIO_PORT_A_PIN_COUNT \
|
||||
: (port) == 1 ? SL_HAL_GPIO_PORT_B_PIN_COUNT \
|
||||
: (port) == 2 ? SL_HAL_GPIO_PORT_C_PIN_COUNT \
|
||||
: (port) == 3 ? SL_HAL_GPIO_PORT_D_PIN_COUNT \
|
||||
: (port) == 4 ? SL_HAL_GPIO_PORT_E_PIN_COUNT \
|
||||
: (port) == 5 ? SL_HAL_GPIO_PORT_F_PIN_COUNT \
|
||||
: (port) == 6 ? SL_HAL_GPIO_PORT_G_PIN_COUNT \
|
||||
: (port) == 7 ? SL_HAL_GPIO_PORT_H_PIN_COUNT \
|
||||
: (port) == 8 ? SL_HAL_GPIO_PORT_I_PIN_COUNT \
|
||||
: (port) == 9 ? SL_HAL_GPIO_PORT_J_PIN_COUNT \
|
||||
: (port) == 10 ? SL_HAL_GPIO_PORT_K_PIN_COUNT \
|
||||
: 0)
|
||||
|
||||
#define SL_HAL_GPIO_PORT_MASK(port) ( \
|
||||
((int)port) == 0 ? SL_HAL_GPIO_PORT_A_PIN_MASK \
|
||||
: ((int)port) == 1 ? SL_HAL_GPIO_PORT_B_PIN_MASK \
|
||||
: ((int)port) == 2 ? SL_HAL_GPIO_PORT_C_PIN_MASK \
|
||||
: ((int)port) == 3 ? SL_HAL_GPIO_PORT_D_PIN_MASK \
|
||||
: ((int)port) == 4 ? SL_HAL_GPIO_PORT_E_PIN_MASK \
|
||||
: ((int)port) == 5 ? SL_HAL_GPIO_PORT_F_PIN_MASK \
|
||||
: ((int)port) == 6 ? SL_HAL_GPIO_PORT_G_PIN_MASK \
|
||||
: ((int)port) == 7 ? SL_HAL_GPIO_PORT_H_PIN_MASK \
|
||||
: ((int)port) == 8 ? SL_HAL_GPIO_PORT_I_PIN_MASK \
|
||||
: ((int)port) == 9 ? SL_HAL_GPIO_PORT_J_PIN_MASK \
|
||||
: ((int)port) == 10 ? SL_HAL_GPIO_PORT_K_PIN_MASK \
|
||||
: 0UL)
|
||||
|
||||
/// Validation of port.
|
||||
#define SL_HAL_GPIO_PORT_IS_VALID(port) (SL_HAL_GPIO_PORT_MASK(port) != 0x0UL)
|
||||
|
||||
/// Validation of port and pin.
|
||||
#define SL_HAL_GPIO_PORT_PIN_IS_VALID(port, pin) ((((SL_HAL_GPIO_PORT_MASK(port)) >> (pin)) & 0x1UL) == 0x1UL)
|
||||
|
||||
/// Max interrupt lines for external and EM4 interrupts.
|
||||
#define SL_HAL_GPIO_INTERRUPT_MAX 15
|
||||
|
||||
/// Shift value for EM4WUEN
|
||||
#define SL_HAL_GPIO_EM4WUEN_SHIFT _GPIO_EM4WUEN_EM4WUEN_SHIFT
|
||||
|
||||
/// Masks for even and odd interrupt bits.
|
||||
#define SL_HAL_GPIO_INT_IF_EVEN_MASK ((_GPIO_IF_MASK) & 0x55555555UL)
|
||||
#define SL_HAL_GPIO_INT_IF_ODD_MASK ((_GPIO_IF_MASK) & 0xAAAAAAAAUL)
|
||||
|
||||
/// Validation of mode.
|
||||
#define SL_HAL_GPIO_MODE_IS_VALID(mode) ((mode & _GPIO_P_MODEL_MODE0_MASK) == mode)
|
||||
|
||||
/// Validation of interrupt number and pin.
|
||||
#define SL_HAL_GPIO_INTNO_PIN_VALID(int_no, pin) (((int_no) & ~_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK) == ((pin) & ~_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK))
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set the mode for a GPIO pin.
|
||||
*
|
||||
* @param[in] gpio Pointer to GPIO structure with port and pin
|
||||
* @param[in] mode The desired pin mode.
|
||||
* @param[in] output_value A value to set for the pin in the DOUT register. The DOUT setting is important for
|
||||
* some input mode configurations to determine the pull-up/down direction.
|
||||
******************************************************************************/
|
||||
void sl_hal_gpio_set_pin_mode(const sl_gpio_t *gpio,
|
||||
sl_gpio_mode_t mode,
|
||||
bool output_value);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get the mode for a GPIO pin.
|
||||
*
|
||||
* @param[in] gpio Pointer to GPIO structure with port and pin
|
||||
*
|
||||
* @return Return the pin mode.
|
||||
******************************************************************************/
|
||||
sl_gpio_mode_t sl_hal_gpio_get_pin_mode(const sl_gpio_t *gpio);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configure the GPIO external pin interrupt by connecting external interrupt id with gpio pin.
|
||||
*
|
||||
* @note This function configure the pin interrupt with pin ,port and external interrupt id as input.
|
||||
* If external interrupt id is provided as input it will be considered as the input or else
|
||||
* available interrupt number will be generated by looping through the interrupt group and will be used.
|
||||
* User can provide SL_HAL_GPIO_INTERRUPT_UNAVAILABLE if user don't want to provide interrupt id.
|
||||
* @note the pin number can be selected freely within a group.
|
||||
* Interrupt numbers are divided into 4 groups (int_no / 4) and valid pin
|
||||
* number within the interrupt groups are:
|
||||
* 0: pins 0-3 (interrupt number 0-3)
|
||||
* 1: pins 4-7 (interrupt number 4-7)
|
||||
* 2: pins 8-11 (interrupt number 8-11)
|
||||
* 3: pins 12-15 (interrupt number 12-15)
|
||||
* @note It is recommended to disable interrupts before configuring the GPIO pin interrupt.
|
||||
* See @ref sl_hal_gpio_disable_interrupts() for more information.
|
||||
* The GPIO interrupt handler must be in place before enabling the interrupt.
|
||||
* Notice that any pending interrupt for the selected interrupt is cleared by this function.
|
||||
* Notice that only interrupt will be configured by this function. It is not enabled.
|
||||
* It is recommended to enable interrupts after configuring the GPIO pin interrupt if needed.
|
||||
* See @ref sl_hal_gpio_enable_interrupts() for more information.
|
||||
*
|
||||
* @param[in] gpio Pointer to GPIO structure with port and pin
|
||||
* @param[in] int_no The interrupt number to trigger.
|
||||
* @param[in] flags Interrupt configuration flags. @ref sl_hal_gpio_interrupt_flag_t for more information.
|
||||
*
|
||||
* @return Return the available interrupt number
|
||||
******************************************************************************/
|
||||
int32_t sl_hal_gpio_configure_external_interrupt(const sl_gpio_t *gpio,
|
||||
int32_t int_no,
|
||||
sl_gpio_interrupt_flag_t flags);
|
||||
|
||||
/**************************************************************************//**
|
||||
* Enable GPIO pin wake-up from EM4. When the function exits,
|
||||
* EM4 mode can be safely entered.
|
||||
*
|
||||
* @note It is assumed that the GPIO pin modes are set correctly.
|
||||
* Valid modes are SL_GPIO_MODE_INPUT and SL_GPIO_MODE_INPUT_PULL.
|
||||
*
|
||||
* @param[in] pinmask A bitmask containing the bitwise logic OR of which GPIO pin(s) to enable.
|
||||
* @param[in] polaritymask A bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity.
|
||||
*****************************************************************************/
|
||||
void sl_hal_gpio_enable_pin_em4_wakeup(uint32_t pinmask,
|
||||
uint32_t polaritymask);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configure EM4WU pins as external level-sensitive interrupts.
|
||||
*
|
||||
* @note It is recommended to disable interrupts before configuring the GPIO pin interrupt.
|
||||
* See @ref sl_hal_gpio_disable_interrupts() for more information.
|
||||
* The provided port, pin and int_no inputs should be valid EM4 related parameters
|
||||
* because there are dedicated port, pin and EM4 Wakeup interrupt combination for
|
||||
* configuring the port, pin for EM4 functionality.
|
||||
* User can provide SL_HAL_GPIO_INTERRUPT_UNAVAILABLE if user don't want to provide interrupt id.
|
||||
* The GPIO interrupt handler must be in place before enabling the interrupt.
|
||||
* Notice that any pending interrupt for the selected interrupt is cleared by this function.
|
||||
* Notice that any only EM4WU interrupt is configured by this function. It is not enabled.
|
||||
* It is recommended to enable interrupts after configuring the GPIO pin interrupt if needed.
|
||||
* See @ref sl_hal_gpio_enable_interrupts() for more information.
|
||||
*
|
||||
* @param[in] gpio Pointer to GPIO structure with port and pin
|
||||
* @param[in] int_no The EM4WU interrupt number to trigger.
|
||||
* @param[in] polarity true = Active high level-sensitive interrupt.
|
||||
* false = Active low level-sensitive interrupt.
|
||||
*
|
||||
* @return Return the available EM4WU interrupt number
|
||||
******************************************************************************/
|
||||
int32_t sl_hal_gpio_configure_wakeup_em4_external_interrupt(const sl_gpio_t *gpio,
|
||||
int32_t int_no,
|
||||
bool polarity);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Lock the GPIO configuration.
|
||||
*
|
||||
* @note Configuration lock affects the GPIO_Px_MODEL, GPIO_Px_MODEH, GPIO_Px_CTRL,
|
||||
* GPIO_Px_PINLOCKN, GPIO_EXTIPSELL, GPIO_EXTIPSELH, GPIO_EXTIPINSELL,
|
||||
* GPIO_EXTIPINSELH, GPIO_INSENSE, GPIO_ROUTE, GPIO_ROUTEPEN, and
|
||||
* GPIO_ROUTELOC0 registers when they are present on a specific device.
|
||||
* @note Unwanted or accidental changes to GPIO configuration can be avoided by
|
||||
* using the configuration lock register. Any value other than 0xA534 written to
|
||||
* GPIO_LOCK enables the configuration lock. Pins are unlocked by a reset or
|
||||
* by writing 0xA534 to the GPIO_LOCK register.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_lock(void)
|
||||
{
|
||||
GPIO->LOCK = ~GPIO_LOCK_LOCKKEY_UNLOCK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Unlock the GPIO configuration.
|
||||
*
|
||||
* @note Configuration lock affects the GPIO_Px_MODEL, GPIO_Px_MODEH, GPIO_Px_CTRL,
|
||||
* GPIO_Px_PINLOCKN, GPIO_EXTIPSELL, GPIO_EXTIPSELH, GPIO_EXTIPINSELL,
|
||||
* GPIO_EXTIPINSELH, GPIO_INSENSE, GPIO_ROUTE, GPIO_ROUTEPEN, and
|
||||
* GPIO_ROUTELOC0 registers when they are present on a specific device.
|
||||
* @note Unwanted or accidental changes to GPIO configuration can be avoided by
|
||||
* using the configuration lock register. Any value other than 0xA534 written to
|
||||
* GPIO_LOCK enables the configuration lock. Pins are unlocked by a reset or
|
||||
* by writing 0xA534 to the GPIO_LOCK register.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_unlock(void)
|
||||
{
|
||||
GPIO->LOCK = GPIO_LOCK_LOCKKEY_UNLOCK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the GPIO configuration state.
|
||||
*
|
||||
* @return Return the GPIO lock state.
|
||||
******************************************************************************/
|
||||
__INLINE uint32_t sl_hal_gpio_get_lock_status(void)
|
||||
{
|
||||
return GPIO->GPIOLOCKSTATUS;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set a single pin in GPIO data out register to 1.
|
||||
*
|
||||
* @param[in] gpio Pointer to GPIO structure with port and pin
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_GPIO, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
__INLINE void sl_hal_gpio_set_pin(const sl_gpio_t *gpio)
|
||||
{
|
||||
EFM_ASSERT(gpio != NULL);
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
|
||||
|
||||
GPIO->P_SET[gpio->port].DOUT = 1UL << gpio->pin;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set bits GPIO data out register to 1.
|
||||
*
|
||||
* @param[in] port The GPIO port to access.
|
||||
* @param[in] pins Bit mask for bits to set to 1 in DOUT register.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_set_port(sl_gpio_port_t port,
|
||||
uint32_t pins)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_IS_VALID(port));
|
||||
GPIO->P_SET[port].DOUT = pins;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set GPIO port data out register.
|
||||
*
|
||||
* @param[in] port The GPIO port to access.
|
||||
* @param[in] val Value to write to port data out register.
|
||||
* @param[in] mask Mask indicating which bits to modify.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_set_port_value(sl_gpio_port_t port,
|
||||
uint32_t val,
|
||||
uint32_t mask)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_IS_VALID(port));
|
||||
GPIO->P[port].DOUT = (GPIO->P[port].DOUT & ~mask) | (val & mask);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set slewrate for pins on a GPIO port which are configured into normal modes.
|
||||
*
|
||||
* @param[in] port The GPIO port to configure.
|
||||
* @param[in] slewrate The slewrate to configure for pins on this GPIO port.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_set_slew_rate(sl_gpio_port_t port,
|
||||
uint8_t slewrate)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_IS_VALID(port));
|
||||
EFM_ASSERT(slewrate <= (_GPIO_P_CTRL_SLEWRATE_MASK
|
||||
>> _GPIO_P_CTRL_SLEWRATE_SHIFT));
|
||||
|
||||
GPIO->P[port].CTRL = (GPIO->P[port].CTRL
|
||||
& ~_GPIO_P_CTRL_SLEWRATE_MASK)
|
||||
| (slewrate << _GPIO_P_CTRL_SLEWRATE_SHIFT);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set slewrate for pins on a GPIO port which are configured into alternate modes.
|
||||
*
|
||||
* @param[in] port The GPIO port to configure.
|
||||
* @param[in] slewrate_alt The slewrate to configure for pins using alternate modes on this GPIO port.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_set_slew_rate_alternate(sl_gpio_port_t port,
|
||||
uint8_t slewrate_alt)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_IS_VALID(port));
|
||||
EFM_ASSERT(slewrate_alt <= (_GPIO_P_CTRL_SLEWRATEALT_MASK
|
||||
>> _GPIO_P_CTRL_SLEWRATEALT_SHIFT));
|
||||
|
||||
GPIO->P[port].CTRL = (GPIO->P[port].CTRL
|
||||
& ~_GPIO_P_CTRL_SLEWRATEALT_MASK)
|
||||
| (slewrate_alt << _GPIO_P_CTRL_SLEWRATEALT_SHIFT);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get slewrate for pins on a GPIO port.
|
||||
*
|
||||
* @param[in] port The GPIO port to access to get slew rate.
|
||||
*
|
||||
* @return Return the slewrate setting for the selected GPIO port.
|
||||
******************************************************************************/
|
||||
__INLINE uint8_t sl_hal_gpio_get_slew_rate(sl_gpio_port_t port)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_IS_VALID(port));
|
||||
|
||||
return (GPIO->P[port].CTRL & _GPIO_P_CTRL_SLEWRATE_MASK) >> _GPIO_P_CTRL_SLEWRATE_SHIFT;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get slewrate for pins on a GPIO port which are configured into alternate modes.
|
||||
*
|
||||
* @param[in] port The GPIO port to access to get slew rate.
|
||||
*
|
||||
* @return Return the alternate slewrate setting for selected GPIO port.
|
||||
******************************************************************************/
|
||||
__INLINE uint8_t sl_hal_gpio_get_slew_rate_alternate(sl_gpio_port_t port)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_IS_VALID(port));
|
||||
|
||||
return (GPIO->P[port].CTRL & _GPIO_P_CTRL_SLEWRATEALT_MASK) >> _GPIO_P_CTRL_SLEWRATEALT_SHIFT;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set a single pin in GPIO data out port register to 0.
|
||||
*
|
||||
* @param[in] gpio Pointer to GPIO structure with port and pin
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_clear_pin(const sl_gpio_t *gpio)
|
||||
{
|
||||
EFM_ASSERT(gpio != NULL);
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
|
||||
|
||||
GPIO->P_CLR[gpio->port].DOUT = 1UL << gpio->pin;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set bits in DOUT register for a port to 0.
|
||||
*
|
||||
* @param[in] port The GPIO port to access.
|
||||
* @param[in] pins Bit mask for bits to clear in DOUT register.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_clear_port(sl_gpio_port_t port,
|
||||
uint32_t pins)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_IS_VALID(port));
|
||||
|
||||
GPIO->P_CLR[port].DOUT = pins;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Read the pad value for a single pin in a GPIO port.
|
||||
*
|
||||
* @param[in] gpio Pointer to GPIO structure with port and pin.
|
||||
*
|
||||
* @return The pin value, 0 or 1.
|
||||
******************************************************************************/
|
||||
__INLINE bool sl_hal_gpio_get_pin_input(const sl_gpio_t *gpio)
|
||||
{
|
||||
EFM_ASSERT(gpio != NULL);
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
|
||||
|
||||
bool pin_input = ((GPIO->P[gpio->port].DIN) >> gpio->pin) & 1UL;
|
||||
|
||||
return pin_input;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get current setting for a pin in a GPIO port data out register.
|
||||
*
|
||||
* @param[in] gpio Pointer to GPIO structure with port and pin.
|
||||
*
|
||||
* @return The DOUT setting for the requested pin, 0 or 1.
|
||||
******************************************************************************/
|
||||
__INLINE bool sl_hal_gpio_get_pin_output(const sl_gpio_t *gpio)
|
||||
{
|
||||
EFM_ASSERT(gpio != NULL);
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
|
||||
|
||||
bool pin_output = ((GPIO->P[gpio->port].DOUT) >> gpio->pin) & 1UL;
|
||||
|
||||
return pin_output;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Read the pad values for GPIO port.
|
||||
*
|
||||
* @param[in] port The GPIO port to access.
|
||||
*
|
||||
* @return The pad values for the GPIO port.
|
||||
******************************************************************************/
|
||||
__INLINE uint32_t sl_hal_gpio_get_port_input(sl_gpio_port_t port)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_IS_VALID(port));
|
||||
|
||||
return GPIO->P[port].DIN;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get current setting for a GPIO port data out register.
|
||||
*
|
||||
* @param[in] port The GPIO port to access.
|
||||
*
|
||||
* @return The data out setting for the requested port.
|
||||
******************************************************************************/
|
||||
__INLINE uint32_t sl_hal_gpio_get_port_output(sl_gpio_port_t port)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_IS_VALID(port));
|
||||
|
||||
return GPIO->P[port].DOUT;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Toggle a single pin in GPIO port data out register.
|
||||
*
|
||||
* @param[in] gpio Pointer to GPIO structure with port and pin.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_toggle_pin(const sl_gpio_t *gpio)
|
||||
{
|
||||
EFM_ASSERT(gpio != NULL);
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
|
||||
|
||||
GPIO->P_TGL[gpio->port].DOUT = 1UL << gpio->pin;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Toggle pins in GPIO port data out register.
|
||||
*
|
||||
* @param[in] port The GPIO port to access.
|
||||
* @param[in] pins Bit mask with pins to toggle.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_toggle_port(sl_gpio_port_t port,
|
||||
uint32_t pins)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_IS_VALID(port));
|
||||
|
||||
GPIO->P_TGL[port].DOUT = pins;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enable one or more GPIO interrupts.
|
||||
*
|
||||
* @param[in] flags GPIO interrupt sources to enable.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_enable_interrupts(uint32_t flags)
|
||||
{
|
||||
GPIO->IEN_SET = flags;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Disable one or more GPIO interrupts.
|
||||
*
|
||||
* @param[in] flags GPIO interrupt sources to disable.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_disable_interrupts(uint32_t flags)
|
||||
{
|
||||
GPIO->IEN_CLR = flags;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Clear one or more pending GPIO interrupts.
|
||||
*
|
||||
* @param[in] flags Bitwise logic OR of GPIO interrupt sources to clear.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_clear_interrupts(uint32_t flags)
|
||||
{
|
||||
GPIO->IF_CLR = flags;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Set one or more pending GPIO interrupts from SW.
|
||||
*
|
||||
* @param[in] flags GPIO interrupt sources to set to pending.
|
||||
*****************************************************************************/
|
||||
__INLINE void sl_hal_gpio_set_interrupts(uint32_t flags)
|
||||
{
|
||||
GPIO->IF_SET = flags;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get pending GPIO interrupts.
|
||||
*
|
||||
* @return GPIO interrupt sources pending.
|
||||
******************************************************************************/
|
||||
__INLINE uint32_t sl_hal_gpio_get_pending_interrupts(void)
|
||||
{
|
||||
return GPIO->IF;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get enabled GPIO interrupts.
|
||||
*
|
||||
* @return Enabled GPIO interrupt sources.
|
||||
******************************************************************************/
|
||||
__INLINE uint32_t sl_hal_gpio_get_enabled_interrupts(void)
|
||||
{
|
||||
return GPIO->IEN;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get enabled and pending GPIO interrupt flags.
|
||||
*
|
||||
* @return Enabled and pending interrupt sources.
|
||||
*
|
||||
* @note Useful for handling more interrupt sources in the same interrupt handler.
|
||||
******************************************************************************/
|
||||
__INLINE uint32_t sl_hal_gpio_get_enabled_pending_interrupts(void)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = GPIO->IEN;
|
||||
|
||||
return GPIO->IF & tmp;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* The available external interrupt number getter.
|
||||
*
|
||||
* @param[in] pin The GPIO pin to access.
|
||||
* @param[in] enabled_interrupts_mask Contains enabled GPIO interrupts mask.
|
||||
*
|
||||
* @return The available interrupt number based on interrupt and pin grouping.
|
||||
******************************************************************************/
|
||||
__INLINE int32_t sl_hal_gpio_get_external_interrupt_number(uint8_t pin,
|
||||
uint32_t enabled_interrupts_mask)
|
||||
{
|
||||
uint32_t interrupt_to_check;
|
||||
uint32_t int_group_start = (pin & 0xFFC);
|
||||
int32_t int_no = -1;
|
||||
// loop through the interrupt group, starting
|
||||
// from the pin number, and take
|
||||
// the first available.
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
interrupt_to_check = int_group_start + ((pin + i) & 0x3); // modulo 4
|
||||
if (((enabled_interrupts_mask >> interrupt_to_check) & 0x1) == 0) {
|
||||
int_no = interrupt_to_check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return int_no;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* The available em4 wakeup interrupt number getter.
|
||||
*
|
||||
* @param[in] gpio Pointer to GPIO structure with port and pin.
|
||||
*
|
||||
* @return The available em4 wakeup interrupt number based on associated port and pin.
|
||||
******************************************************************************/
|
||||
__INLINE int32_t sl_hal_gpio_get_em4_interrupt_number(const sl_gpio_t *gpio)
|
||||
{
|
||||
EFM_ASSERT(gpio != NULL);
|
||||
int32_t em4_int_no;
|
||||
|
||||
if (false) {
|
||||
// Check all the EM4WU Pins and check if given port, pin matches any of them.
|
||||
#if defined(GPIO_EM4WU0_PORT)
|
||||
} else if (GPIO_EM4WU0_PORT == gpio->port && GPIO_EM4WU0_PIN == gpio->pin) {
|
||||
em4_int_no = 0;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU1_PORT)
|
||||
} else if (GPIO_EM4WU1_PORT == gpio->port && GPIO_EM4WU1_PIN == gpio->pin) {
|
||||
em4_int_no = 1;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU3_PORT)
|
||||
} else if (GPIO_EM4WU3_PORT == gpio->port && GPIO_EM4WU3_PIN == gpio->pin) {
|
||||
em4_int_no = 3;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU4_PORT)
|
||||
} else if (GPIO_EM4WU4_PORT == gpio->port && GPIO_EM4WU4_PIN == gpio->pin) {
|
||||
em4_int_no = 4;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU6_PORT)
|
||||
} else if (GPIO_EM4WU6_PORT == gpio->port && GPIO_EM4WU6_PIN == gpio->pin) {
|
||||
em4_int_no = 6;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU7_PORT)
|
||||
} else if (GPIO_EM4WU7_PORT == gpio->port && GPIO_EM4WU7_PIN == gpio->pin) {
|
||||
em4_int_no = 7;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU8_PORT)
|
||||
} else if (GPIO_EM4WU8_PORT == gpio->port && GPIO_EM4WU8_PIN == gpio->pin) {
|
||||
em4_int_no = 8;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU9_PORT)
|
||||
} else if (GPIO_EM4WU9_PORT == gpio->port && GPIO_EM4WU9_PIN == gpio->pin) {
|
||||
em4_int_no = 9;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU10_PORT)
|
||||
} else if (GPIO_EM4WU10_PORT == gpio->port && GPIO_EM4WU10_PIN == gpio->pin) {
|
||||
em4_int_no = 10;
|
||||
#endif
|
||||
} else {
|
||||
em4_int_no = -1;
|
||||
}
|
||||
|
||||
return em4_int_no;
|
||||
}
|
||||
|
||||
/*************************************************************************//**
|
||||
* Disable GPIO pin wake-up from EM4.
|
||||
*
|
||||
* @param[in] pinmask Bit mask containing the bitwise logic OR of which GPIO pin(s) to disable.
|
||||
*****************************************************************************/
|
||||
__INLINE void sl_hal_gpio_disable_pin_em4_wakeup(uint32_t pinmask)
|
||||
{
|
||||
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0UL);
|
||||
|
||||
GPIO->EM4WUEN &= ~pinmask;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Enable GPIO pin retention of output enable, output value, pull enable, and
|
||||
* pull direction in EM4.
|
||||
*
|
||||
* @note The behavior of this function depends on the configured GPIO retention mode.
|
||||
* If the GPIO retention mode is configured to be "SWUNLATCH" then this
|
||||
* function will not change anything. If the retention mode is anything else
|
||||
* then this function will set the GPIO retention mode to "EM4EXIT" when the
|
||||
* enable argument is true, and "Disabled" when false.
|
||||
*
|
||||
* @param[in] enable true - enable EM4 pin retention.
|
||||
* false - disable EM4 pin retention.
|
||||
*****************************************************************************/
|
||||
__INLINE void sl_hal_gpio_set_pin_em4_retention(bool enable)
|
||||
{
|
||||
// Leave configuration alone when software unlatch is used.
|
||||
uint32_t mode = EMU->EM4CTRL & _EMU_EM4CTRL_EM4IORETMODE_MASK;
|
||||
|
||||
if (mode == EMU_EM4CTRL_EM4IORETMODE_SWUNLATCH) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
EMU->EM4CTRL = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4IORETMODE_MASK)
|
||||
| EMU_EM4CTRL_EM4IORETMODE_EM4EXIT;
|
||||
} else {
|
||||
EMU->EM4CTRL = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4IORETMODE_MASK)
|
||||
| EMU_EM4CTRL_EM4IORETMODE_DISABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Check which GPIO pin(s) that caused a wake-up from EM4.
|
||||
*
|
||||
* @return Bit mask containing the bitwise logic OR of which GPIO pin(s) caused the wake-up.
|
||||
*****************************************************************************/
|
||||
__INLINE uint32_t sl_hal_gpio_get_pin_em4_wakeup_cause(void)
|
||||
{
|
||||
return GPIO->IF & _GPIO_EM4WUEN_EM4WUEN_MASK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enable/Disable serial wire output pin.
|
||||
*
|
||||
* @note Enabling this pin is not sufficient to fully enable serial wire output,
|
||||
* which is also dependent on issues outside the GPIO module.
|
||||
* @note If debug port is locked, SWO pin is not disabled automatically. To avoid
|
||||
* information leakage through SWO, disable SWO pin after locking debug port.
|
||||
*
|
||||
* @param[in] enable false - disable serial wire viewer pin (default after reset).
|
||||
* true - enable serial wire viewer pin.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_enable_debug_swo(bool enable)
|
||||
{
|
||||
uint32_t bit = enable ? 0x1UL : 0x0UL;
|
||||
|
||||
if (bit != 0U) {
|
||||
GPIO->TRACEROUTEPEN_SET = 1UL << _GPIO_TRACEROUTEPEN_SWVPEN_SHIFT;
|
||||
} else {
|
||||
GPIO->TRACEROUTEPEN_CLR = 1UL << _GPIO_TRACEROUTEPEN_SWVPEN_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enable/disable serial wire clock pin.
|
||||
*
|
||||
* @note Disabling SWDClk will disable the debug interface, which may result in
|
||||
* a lockout if done early in startup (before debugger is able to halt core).
|
||||
*
|
||||
* @param[in] enable false - disable serial wire clock.
|
||||
* true - enable serial wire clock (default after reset).
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_enable_debug_swd_clk(bool enable)
|
||||
{
|
||||
uint32_t bit = enable ? 0x1UL : 0x0UL;
|
||||
|
||||
if (bit != 0U) {
|
||||
GPIO->DBGROUTEPEN_SET = 1UL << _GPIO_DBGROUTEPEN_SWCLKTCKPEN_SHIFT;
|
||||
} else {
|
||||
GPIO->DBGROUTEPEN_CLR = 1UL << _GPIO_DBGROUTEPEN_SWCLKTCKPEN_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enable/disable serial wire data I/O pin.
|
||||
*
|
||||
* @note Disabling SWDClk will disable the debug interface, which may result in
|
||||
* a lockout if done early in startup (before debugger is able to halt core).
|
||||
*
|
||||
* @param[in] enable false - disable serial wire data pin.
|
||||
* true - enable serial wire data pin (default after reset).
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_gpio_enable_debug_swd_io(bool enable)
|
||||
{
|
||||
uint32_t bit = enable ? 0x1UL : 0x0UL;
|
||||
|
||||
if (bit != 0U) {
|
||||
GPIO->DBGROUTEPEN_SET = 1UL << _GPIO_DBGROUTEPEN_SWDIOTMSPEN_SHIFT;
|
||||
} else {
|
||||
GPIO->DBGROUTEPEN_CLR = 1UL << _GPIO_DBGROUTEPEN_SWDIOTMSPEN_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} (end addtogroup gpio) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GPIO_PRESENT */
|
||||
#endif /* SL_HAL_GPIO_H */
|
||||
89
Libs/platform/peripheral/inc/sl_hal_syscfg.h
Normal file
89
Libs/platform/peripheral/inc/sl_hal_syscfg.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief API defining access to SYSCFG registers
|
||||
*******************************************************************************
|
||||
* # 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 SL_HAL_SYSCFG_H
|
||||
#define SL_HAL_SYSCFG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(SL_TRUSTZONE_NONSECURE)
|
||||
#include "sli_tz_service_syscfg.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup syscfg SYSTEM CONFIGURATION - System Configurations
|
||||
* @brief Syscfg API
|
||||
* @details
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
********************************* DEFINES *********************************
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** TZ SERVICES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief
|
||||
* Reads CHIPREV register.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_syscfg_read_chip_rev(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief
|
||||
* Set SYSTICEXTCLKEN bit in CFGSYSTIC to one.
|
||||
******************************************************************************/
|
||||
void sl_hal_syscfg_set_systicextclken_cfgsystic(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief
|
||||
* Clear SYSTICEXTCLKEN bit in CFGSYSTIC to zero.
|
||||
******************************************************************************/
|
||||
void sl_hal_syscfg_clear_systicextclken_cfgsystic(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // SL_HAL_SYSCFG_H
|
||||
445
Libs/platform/peripheral/inc/sl_hal_sysrtc.h
Normal file
445
Libs/platform/peripheral/inc/sl_hal_sysrtc.h
Normal file
@@ -0,0 +1,445 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief System Real Time Counter (SYSRTC) peripheral API
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2024 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 SL_HAL_SYSRTC_H
|
||||
#define SL_HAL_SYSRTC_H
|
||||
|
||||
#include "em_device.h"
|
||||
|
||||
#if defined(SYSRTC_COUNT) && (SYSRTC_COUNT > 0)
|
||||
#include <stdbool.h>
|
||||
#include "sl_code_classification.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "sl_hal_sysrtc_compat.h"
|
||||
#include "sl_enum.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sysrtc
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/// Minimum compare channels for SYSRTC group.
|
||||
#define SYSRTC_GROUP_MIN_CHANNEL_COMPARE 1u
|
||||
/// Maximum compare channels for SYSRTC group.
|
||||
#define SYSRTC_GROUP_MAX_CHANNEL_COMPARE 2u
|
||||
|
||||
/// Minimum capture channels for SYSRTC group.
|
||||
#define SYSRTC_GROUP_MIN_CHANNEL_CAPTURE 0u
|
||||
/// Maximum capture channels for SYSRTC group.
|
||||
#define SYSRTC_GROUP_MAX_CHANNEL_CAPTURE 1u
|
||||
|
||||
/// Sysrtc group number.
|
||||
#if !defined(SYSRTC_GROUP_NUMBER)
|
||||
#define SYSRTC_GROUP_NUMBER 1u
|
||||
#endif
|
||||
|
||||
/// Validation of valid SYSRTC group for assert statements.
|
||||
#define SYSRTC_GROUP_VALID(group) ((unsigned)(group) < SYSRTC_GROUP_NUMBER)
|
||||
|
||||
/*******************************************************************************
|
||||
********************************* ENUM ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/// Capture input edge select.
|
||||
SL_ENUM(sl_hal_sysrtc_capture_edge_t) {
|
||||
SL_HAL_SYSRTC_CAPTURE_EDGE_RISING = 0, ///< Rising edges detected.
|
||||
SL_HAL_SYSRTC_CAPTURE_EDGE_FALLING, ///< Falling edges detected.
|
||||
SL_HAL_SYSRTC_CAPTURE_EDGE_BOTH ///< Both edges detected.
|
||||
};
|
||||
|
||||
/// Compare match output action mode.
|
||||
SL_ENUM(sl_hal_sysrtc_compare_match_out_action_t) {
|
||||
SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CLEAR = 0, ///< Clear output.
|
||||
SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_SET, ///< Set output.
|
||||
SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_PULSE, ///< Generate a pulse.
|
||||
SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_TOGGLE, ///< Toggle output.
|
||||
SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CMPIF ///< Export CMPIF.
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/// SYSRTC configuration structure.
|
||||
typedef struct {
|
||||
bool enable_debug_run; ///< Counter shall keep running during debug halt.
|
||||
} sl_hal_sysrtc_config_t;
|
||||
|
||||
/// Suggested default values for SYSRTC configuration structure.
|
||||
#define SYSRTC_CONFIG_DEFAULT \
|
||||
{ \
|
||||
false, /* Disable updating during debug halt. */ \
|
||||
}
|
||||
|
||||
/// Compare channel configuration structure.
|
||||
typedef struct {
|
||||
sl_hal_sysrtc_compare_match_out_action_t compare_match_out_action; ///< Compare mode channel match output action.
|
||||
} sl_hal_sysrtc_group_channel_compare_config_t;
|
||||
|
||||
/// Capture channel configuration structure.
|
||||
typedef struct {
|
||||
sl_hal_sysrtc_capture_edge_t capture_input_edge; ///< Capture mode channel input edge.
|
||||
} sl_hal_sysrtc_group_channel_capture_config_t;
|
||||
|
||||
/// Group configuration structure.
|
||||
typedef struct {
|
||||
bool compare_channel0_enable; ///< Enable/Disable compare channel 0
|
||||
bool compare_channel1_enable; ///< Enable/Disable compare channel 1
|
||||
bool capture_channel0_enable; ///< Enable/Disable capture channel 0
|
||||
sl_hal_sysrtc_group_channel_compare_config_t const *p_compare_channel0_config; ///< Pointer to compare channel 0 config
|
||||
sl_hal_sysrtc_group_channel_compare_config_t const *p_compare_channel1_config; ///< Pointer to compare channel 1 config
|
||||
sl_hal_sysrtc_group_channel_capture_config_t const *p_capture_channel0_config; ///< Pointer to capture channel 0 config
|
||||
} sl_hal_sysrtc_group_config_t;
|
||||
|
||||
/// Suggested default values for compare channel configuration structure.
|
||||
#define SYSRTC_GROUP_CHANNEL_COMPARE_CONFIG_DEFAULT \
|
||||
{ \
|
||||
SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_PULSE \
|
||||
}
|
||||
|
||||
/// Compare channel configuration for starting HFXO using PRS.
|
||||
#define SYSRTC_GROUP_CHANNEL_COMPARE_CONFIG_EARLY_WAKEUP \
|
||||
{ \
|
||||
SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CMPIF \
|
||||
}
|
||||
|
||||
/// Suggested default values for capture channel configuration structure.
|
||||
#define SYSRTC_GROUP_CHANNEL_CAPTURE_CONFIG_DEFAULT \
|
||||
{ \
|
||||
SL_HAL_SYSRTC_CAPTURE_EDGE_RISING \
|
||||
}
|
||||
|
||||
/// Suggested default values for SYSRTC group configuration structure.
|
||||
#define SYSRTC_GROUP_CONFIG_DEFAULT \
|
||||
{ \
|
||||
true, /* Enable compare channel 0. */ \
|
||||
false, /* Disable compare channel 1. */ \
|
||||
false, /* Disable capture channel 0. */ \
|
||||
NULL, /* NULL Pointer to configuration structure for compare channel 0*/ \
|
||||
NULL, /* NULL Pointer to configuration structure for compare channel 1*/ \
|
||||
NULL /* NULL Pointer to configuration structure for capture channel 0*/ \
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initializes SYSRTC module.
|
||||
*
|
||||
* Note that the compare values must be set separately with
|
||||
* (sl_hal_sysrtc_set_group_compare_channel_value()), which should probably be
|
||||
* done prior to the use of this function if configuring the SYSRTC to start
|
||||
* when initialization is completed.
|
||||
*
|
||||
* @param[in] p_config A pointer to the SYSRTC initialization structure
|
||||
* variable.
|
||||
******************************************************************************/
|
||||
void sl_hal_sysrtc_init(const sl_hal_sysrtc_config_t *p_config);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enables SYSRTC counting.
|
||||
******************************************************************************/
|
||||
void sl_hal_sysrtc_enable(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Disables SYSRTC counting.
|
||||
******************************************************************************/
|
||||
void sl_hal_sysrtc_disable(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Waits for the SYSRTC to complete all synchronization of register changes
|
||||
* and commands.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
__INLINE void sl_hal_sysrtc_wait_sync(void)
|
||||
{
|
||||
while ((SYSRTC0->EN & SYSRTC_EN_EN) && (SYSRTC0->SYNCBUSY != 0U)) {
|
||||
// Wait for all synchronizations to finish
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Waits for the SYSRTC to complete reseting or disabling procedure.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_sysrtc_wait_ready(void)
|
||||
{
|
||||
while ((SYSRTC0->SWRST & _SYSRTC_SWRST_RESETTING_MASK) || (SYSRTC0->EN & _SYSRTC_EN_DISABLING_MASK) || (SYSRTC0->SYNCBUSY != 0U)) {
|
||||
// Wait for all synchronizations to finish
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Starts SYSRTC counter.
|
||||
*
|
||||
* This function will send a start command to the SYSRTC peripheral. The SYSRTC
|
||||
* peripheral will use some LF clock ticks before the command is executed.
|
||||
* The sl_hal_sysrtc_wait_sync() function can be used to wait for the start
|
||||
* command to be executed.
|
||||
*
|
||||
* @note This function requires the SYSRTC to be enabled.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_sysrtc_start(void)
|
||||
{
|
||||
sl_hal_sysrtc_wait_sync();
|
||||
SYSRTC0->CMD = SYSRTC_CMD_START;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Stops the SYSRTC counter.
|
||||
*
|
||||
* This function will send a stop command to the SYSRTC peripheral. The SYSRTC
|
||||
* peripheral will use some LF clock ticks before the command is executed.
|
||||
* The sl_hal_sysrtc_wait_sync() function can be used to wait for the stop
|
||||
* command to be executed.
|
||||
*
|
||||
* @note This function requires the SYSRTC to be enabled.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_sysrtc_stop(void)
|
||||
{
|
||||
sl_hal_sysrtc_wait_sync();
|
||||
SYSRTC0->CMD = SYSRTC_CMD_STOP;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Restores SYSRTC to its reset state.
|
||||
******************************************************************************/
|
||||
void sl_hal_sysrtc_reset(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets SYSRTC STATUS register value.
|
||||
*
|
||||
* @return Current STATUS register value.
|
||||
******************************************************************************/
|
||||
__INLINE uint32_t sl_hal_sysrtc_get_status(void)
|
||||
{
|
||||
return SYSRTC0->STATUS;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Locks SYSRTC registers.
|
||||
*
|
||||
* @note When SYSRTC registers are locked SYSRTC_EN, SYSRTC_CFG, SYSRTC_CMD,
|
||||
* SYSRTC_SWRST, SYSRTC_CNT and SYSRTC_TOPCNT registers cannot be written
|
||||
* to.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_sysrtc_lock(void)
|
||||
{
|
||||
SYSRTC0->LOCK = ~SYSRTC_LOCK_LOCKKEY_UNLOCK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Unlocks SYSRTC registers.
|
||||
*
|
||||
* @note When SYSRTC registers are locked SYSRTC_EN, SYSRTC_CFG, SYSRTC_CMD,
|
||||
* SYSRTC_SWRST, SYSRTC_CNT and SYSRTC_TOPCNT registers cannot be written
|
||||
* to.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_sysrtc_unlock(void)
|
||||
{
|
||||
SYSRTC0->LOCK = SYSRTC_LOCK_LOCKKEY_UNLOCK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets SYSRTC counter value.
|
||||
*
|
||||
* @return Current SYSRTC counter value.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
__INLINE uint32_t sl_hal_sysrtc_get_counter(void)
|
||||
{
|
||||
// Wait for Counter to synchronize before getting value
|
||||
sl_hal_sysrtc_wait_sync();
|
||||
|
||||
return SYSRTC0->CNT;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the SYSRTC counter value.
|
||||
*
|
||||
* @param[in] value The new SYSRTC counter value.
|
||||
******************************************************************************/
|
||||
__INLINE void sl_hal_sysrtc_set_counter(uint32_t value)
|
||||
{
|
||||
// Wait for Counter to synchronize before getting value
|
||||
sl_hal_sysrtc_wait_sync();
|
||||
|
||||
SYSRTC0->CNT = value;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initializes the selected SYSRTC group.
|
||||
*
|
||||
* @param[in] group_number SYSRTC group number to use.
|
||||
*
|
||||
* @param[in] p_group_config Pointer to group configuration structure
|
||||
* variable.
|
||||
******************************************************************************/
|
||||
void sl_hal_sysrtc_init_group(uint8_t group_number,
|
||||
sl_hal_sysrtc_group_config_t const *p_group_config);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enables one or more SYSRTC interrupts for the given group.
|
||||
*
|
||||
* @note Depending on the use, a pending interrupt may already be set prior to
|
||||
* enabling the interrupt. To ignore a pending interrupt, consider using
|
||||
* sl_hal_sysrtc_clear_group_interrupts() prior to enabling the interrupt.
|
||||
*
|
||||
* @param[in] group_number SYSRTC group number to use.
|
||||
*
|
||||
* @param[in] flags SYSRTC interrupt sources to enable.
|
||||
* Use a set of interrupt flags OR-ed together to set
|
||||
* multiple interrupt sources for the given SYSRTC group.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
void sl_hal_sysrtc_enable_group_interrupts(uint8_t group_number,
|
||||
uint32_t flags);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Disables one or more SYSRTC interrupts for the given group.
|
||||
*
|
||||
* @param[in] group_number SYSRTC group number to use.
|
||||
*
|
||||
* @param[in] flags SYSRTC interrupt sources to disable.
|
||||
* Use a set of interrupt flags OR-ed together to disable
|
||||
* multiple interrupt sources for the given SYSRTC group.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
void sl_hal_sysrtc_disable_group_interrupts(uint8_t group_number,
|
||||
uint32_t flags);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Clears one or more pending SYSRTC interrupts for the given group.
|
||||
*
|
||||
* @param[in] group_number SYSRTC group number to use.
|
||||
*
|
||||
* @param[in] flags SYSRTC interrupt sources to clear.
|
||||
* Use a set of interrupt flags OR-ed together to clear
|
||||
* multiple interrupt sources for the given SYSRTC group.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
void sl_hal_sysrtc_clear_group_interrupts(uint8_t group_number,
|
||||
uint32_t flags);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets pending SYSRTC interrupt flags for the given group.
|
||||
*
|
||||
* @note Event bits are not cleared by using this function.
|
||||
*
|
||||
* @param[in] group_number SYSRTC group number to use.
|
||||
*
|
||||
* @return Pending SYSRTC interrupt sources.
|
||||
* Returns a set of interrupt flags OR-ed together for multiple
|
||||
* interrupt sources in the SYSRTC group.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
uint32_t sl_hal_sysrtc_get_group_interrupts(uint8_t group_number);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets enabled and pending SYSRTC interrupt flags.
|
||||
* Useful for handling more interrupt sources in the same interrupt handler.
|
||||
*
|
||||
* @note Interrupt flags are not cleared by using this function.
|
||||
*
|
||||
* @param[in] group_number SYSRTC group number to use.
|
||||
*
|
||||
* @return Pending and enabled SYSRTC interrupt sources.
|
||||
* The return value is the bitwise AND of
|
||||
* - the enabled interrupt sources in SYSRTC_GRPx_IEN and
|
||||
* - the pending interrupt flags SYSRTC_GRPx_IF.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_sysrtc_get_group_enabled_interrupts(uint8_t group_number);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets one or more pending SYSRTC interrupts for the given group from Software.
|
||||
*
|
||||
* @param[in] group_number SYSRTC group number to use.
|
||||
*
|
||||
* @param[in] flags SYSRTC interrupt sources to set to pending.
|
||||
* Use a set of interrupt flags OR-ed together to set
|
||||
* multiple interrupt sources for the SYSRTC group.
|
||||
******************************************************************************/
|
||||
void sl_hal_sysrtc_set_group_interrupts(uint8_t group_number,
|
||||
uint32_t flags);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets SYSRTC compare register value for selected channel of given group.
|
||||
*
|
||||
* @param[in] group_number SYSRTC group number to use.
|
||||
*
|
||||
* @param[in] channel Channel selector.
|
||||
*
|
||||
* @return Compare register value.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
uint32_t sl_hal_sysrtc_get_group_compare_channel_value(uint8_t group_number,
|
||||
uint8_t channel);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets SYSRTC compare register value for selected channel of given group.
|
||||
*
|
||||
* @param[in] group_number SYSRTC group number to use.
|
||||
*
|
||||
* @param[in] channel Channel selector.
|
||||
*
|
||||
* @param[in] value Compare register value.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
void sl_hal_sysrtc_set_group_compare_channel_value(uint8_t group_number,
|
||||
uint8_t channel,
|
||||
uint32_t value);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets SYSRTC input capture register value for capture channel of given group.
|
||||
*
|
||||
* @param[in] group_number SYSRTC group number to use.
|
||||
*
|
||||
* @return Capture register value.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_HAL_SYSRTC, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
uint32_t sl_hal_sysrtc_get_group_capture_channel_value(uint8_t group_number);
|
||||
|
||||
/** @} (end addtogroup sysrtc) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(SYSRTC_COUNT) && (SYSRTC_COUNT > 0) */
|
||||
#endif /* SL_HAL_SYSRTC_H */
|
||||
89
Libs/platform/peripheral/inc/sl_hal_sysrtc_compat.h
Normal file
89
Libs/platform/peripheral/inc/sl_hal_sysrtc_compat.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief SYSRTC Compatibility Layer.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2024 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 SL_HAL_SYSRTC_COMPAT_H
|
||||
#define SL_HAL_SYSRTC_COMPAT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
********************************* DEFINES *********************************
|
||||
******************************************************************************/
|
||||
|
||||
// Enum.
|
||||
#define SL_SYSRTC_CAPTURE_EDGE_RISING SL_HAL_SYSRTC_CAPTURE_EDGE_RISING
|
||||
#define SL_SYSRTC_CAPTURE_EDGE_FALLING SL_HAL_SYSRTC_CAPTURE_EDGE_FALLING
|
||||
#define SL_SYSRTC_CAPTURE_EDGE_BOTH SL_HAL_SYSRTC_CAPTURE_EDGE_BOTH
|
||||
#define SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CLEAR SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CLEAR
|
||||
#define SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_SET SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_SET
|
||||
#define SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_PULSE SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_PULSE
|
||||
#define SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_TOGGLE SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_TOGGLE
|
||||
#define SL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CMPIF SL_HAL_SYSRTC_COMPARE_MATCH_OUT_ACTION_CMPIF
|
||||
#define sl_sysrtc_capture_edge_t sl_hal_sysrtc_capture_edge_t
|
||||
#define sl_sysrtc_compare_match_out_action_t sl_hal_sysrtc_compare_match_out_action_t
|
||||
|
||||
// Structure.
|
||||
#define sl_sysrtc_config_t sl_hal_sysrtc_config_t
|
||||
#define sl_sysrtc_group_channel_compare_config_t sl_hal_sysrtc_group_channel_compare_config_t
|
||||
#define sl_sysrtc_group_channel_capture_config_t sl_hal_sysrtc_group_channel_capture_config_t
|
||||
#define sl_sysrtc_group_config_t sl_hal_sysrtc_group_config_t
|
||||
|
||||
// Function.
|
||||
#define sl_sysrtc_init sl_hal_sysrtc_init
|
||||
#define sl_sysrtc_enable sl_hal_sysrtc_enable
|
||||
#define sl_sysrtc_disable sl_hal_sysrtc_disable
|
||||
#define sl_sysrtc_wait_sync sl_hal_sysrtc_wait_sync
|
||||
#define sl_sysrtc_wait_ready sl_hal_sysrtc_wait_ready
|
||||
#define sl_sysrtc_start sl_hal_sysrtc_start
|
||||
#define sl_sysrtc_stop sl_hal_sysrtc_stop
|
||||
#define sl_sysrtc_reset sl_hal_sysrtc_reset
|
||||
#define sl_sysrtc_get_status sl_hal_sysrtc_get_status
|
||||
#define sl_sysrtc_lock sl_hal_sysrtc_lock
|
||||
#define sl_sysrtc_unlock sl_hal_sysrtc_unlock
|
||||
#define sl_sysrtc_get_counter sl_hal_sysrtc_get_counter
|
||||
#define sl_sysrtc_set_counter sl_hal_sysrtc_set_counter
|
||||
#define sl_sysrtc_init_group sl_hal_sysrtc_init_group
|
||||
#define sl_sysrtc_enable_group_interrupts sl_hal_sysrtc_enable_group_interrupts
|
||||
#define sl_sysrtc_disable_group_interrupts sl_hal_sysrtc_disable_group_interrupts
|
||||
#define sl_sysrtc_clear_group_interrupts sl_hal_sysrtc_clear_group_interrupts
|
||||
#define sl_sysrtc_get_group_interrupts sl_hal_sysrtc_get_group_interrupts
|
||||
#define sl_sysrtc_get_group_enabled_interrupts sl_hal_sysrtc_get_group_enabled_interrupts
|
||||
#define sl_sysrtc_set_group_interrupts sl_hal_sysrtc_set_group_interrupts
|
||||
#define sl_sysrtc_get_group_compare_channel_value sl_hal_sysrtc_get_group_compare_channel_value
|
||||
#define sl_sysrtc_set_group_compare_channel_value sl_hal_sysrtc_set_group_compare_channel_value
|
||||
#define sl_sysrtc_get_group_capture_channel_value sl_hal_sysrtc_get_group_capture_channel_value
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_HAL_SYSRTC_COMPAT_H
|
||||
146
Libs/platform/peripheral/inc/sl_hal_system.h
Normal file
146
Libs/platform/peripheral/inc/sl_hal_system.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief System API
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2024 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 _SL_HAL_SYSTEM_H
|
||||
#define _SL_HAL_SYSTEM_H
|
||||
|
||||
#include "em_device.h"
|
||||
#include "sl_hal_system_generic.h"
|
||||
#include "sl_enum.h"
|
||||
#include <stdint.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.
|
||||
SL_ENUM_GENERIC(sl_hal_system_part_family_t, uint32_t) {
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_MIGHTY_21 = DEVINFO_PART_FAMILY_MG | (21 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Mighty Gecko Series 2 Config 1 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_FLEX_21 = DEVINFO_PART_FAMILY_FG | (21 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Flex Gecko Series 2 Config 1 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_BLUE_21 = DEVINFO_PART_FAMILY_BG | (21 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Blue Gecko Series 2 Config 1 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_MIGHTY_RCP_21 = 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)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_MIGHTY_22 = DEVINFO_PART_FAMILY_MG | (22 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Mighty Gecko Series 2 Config 2 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_FLEX_22 = DEVINFO_PART_FAMILY_FG | (22 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Flex Gecko Series 2 Config 2 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_BLUE_22 = DEVINFO_PART_FAMILY_BG | (22 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Blue Gecko Series 2 Config 2 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_EFM32_PEARL_22 = 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)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_FLEX_23 = DEVINFO_PART_FAMILY_FG | (23 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Flex Gecko Series 2 Config 3 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_ZEN_23 = DEVINFO_PART_FAMILY_ZG | (23 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Zen Gecko Series 2 Config 3 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_EFM32_PEARL_23 = DEVINFO_PART_FAMILY_PG | (23 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFM32 Pearl Gecko Series 2 Config 3 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_SIDEWALK_23 = 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)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_MIGHTY_24 = DEVINFO_PART_FAMILY_MG | (24 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Mighty Gecko Series 2 Config 4 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_FLEX_24 = DEVINFO_PART_FAMILY_FG | (24 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Flex Gecko Series 2 Config 4 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_BLUE_24 = 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)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_FLEX_25 = 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)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_MIGHTY_26 = DEVINFO_PART_FAMILY_MG | (26 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Mighty Gecko Series 2 Config 6 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_BLUE_26 = DEVINFO_PART_FAMILY_BG | (26 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Blue Gecko Series 2 Config 6 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_EFM32_PEARL_26 = 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)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_MIGHTY_27 = DEVINFO_PART_FAMILY_MG | (27 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Mighty Gecko Series 2 Config 7 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_BLUE_27 = 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)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_FLEX_28 = DEVINFO_PART_FAMILY_FG | (28 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Flex Gecko Series 2 Config 8 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_ZEN_28 = DEVINFO_PART_FAMILY_ZG | (28 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Zen Gecko Series 2 Config 8 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_SIDEWALK_28 = DEVINFO_PART_FAMILY_SG | (28 << _DEVINFO_PART_FAMILYNUM_SHIFT), ///< EFR32 Side Walk Gecko Series 2 Config 8 Value Device Family
|
||||
SL_HAL_SYSTEM_PART_FAMILY_EFM32_PEARL_28 = 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_3_CONFIG_301)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_BLUETOOTH_301 = DEVINFO_PART0_PROTOCOL_BLUETOOTH \
|
||||
| (0x33 << _DEVINFO_PART0_SERIES_SHIFT) \
|
||||
| (0x30 << _DEVINFO_PART0_DIECODE0_SHIFT), ///< SI Series 3 Bluetooth Config 1 Value Device Family (BG)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_PROPRIETARY_301 = DEVINFO_PART0_PROTOCOL_PROPRIETARY \
|
||||
| (0x33 << _DEVINFO_PART0_SERIES_SHIFT) \
|
||||
| (0x30 << _DEVINFO_PART0_DIECODE0_SHIFT), ///< SI Series 3 Proprietary Config 1 Value Device Family (FG)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_FIFTEENPFOUR_301 = DEVINFO_PART0_PROTOCOL_FIFTEENPFOUR \
|
||||
| (0x33 << _DEVINFO_PART0_SERIES_SHIFT) \
|
||||
| (0x30 << _DEVINFO_PART0_DIECODE0_SHIFT), ///< SI Series 3 15.4 Config 1 Value Device Family (MG)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_PEARL_301 = DEVINFO_PART0_PROTOCOL_PEARL \
|
||||
| (0x33 << _DEVINFO_PART0_SERIES_SHIFT) \
|
||||
| (0x30 << _DEVINFO_PART0_DIECODE0_SHIFT), ///< SI Series 3 Pearl Config 1 Value Device Family (PG)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_WIFI_301 = DEVINFO_PART0_PROTOCOL_WIFI \
|
||||
| (0x33 << _DEVINFO_PART0_SERIES_SHIFT) \
|
||||
| (0x30 << _DEVINFO_PART0_DIECODE0_SHIFT), ///< SI Series 3 Wifi Config 1 Value Device Family (WG)
|
||||
SL_HAL_SYSTEM_PART_FAMILY_ZWAVE_301 = DEVINFO_PART0_PROTOCOL_ZWAVE \
|
||||
| (0x33 << _DEVINFO_PART0_SERIES_SHIFT) \
|
||||
| (0x30 << _DEVINFO_PART0_DIECODE0_SHIFT), ///< SI Series 3 Zwave Config 1 Value Device Family (ZG)
|
||||
#endif
|
||||
SL_HAL_SYSTEM_PART_FAMILY_UNKNOWN = 0xFF ///< Unknown Device Family. Family ID is missing on unprogrammed parts.
|
||||
};
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the MCU family identifier.
|
||||
*
|
||||
* @return
|
||||
* Family identifier of MCU.
|
||||
*
|
||||
* @note
|
||||
* This function retrieves family ID by reading the chip's device info
|
||||
* structure in flash memory. Users can retrieve family ID directly
|
||||
* by reading DEVINFO->PART item and decode with mask and shift
|
||||
* \#defines defined in \<part_family\>_devinfo.h (refer to code
|
||||
* below for details).
|
||||
******************************************************************************/
|
||||
sl_hal_system_part_family_t sl_hal_system_get_family(void);
|
||||
|
||||
/** @} (end addtogroup system) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef _SL_HAL_SYSTEM_H */
|
||||
344
Libs/platform/peripheral/inc/sl_hal_system_generic.h
Normal file
344
Libs/platform/peripheral/inc/sl_hal_system_generic.h
Normal file
@@ -0,0 +1,344 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief System API (Generic)
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2024 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 _SL_HAL_SYSTEM_GENERIC_H
|
||||
#define _SL_HAL_SYSTEM_GENERIC_H
|
||||
|
||||
#include "sl_enum.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup system SYSTEM - System Utils
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/// Family security capability.
|
||||
SL_ENUM(sl_hal_system_security_capability_t) {
|
||||
/// Unknown security capability.
|
||||
SL_SYSTEM_SECURITY_CAPABILITY_UNKNOWN,
|
||||
/// Security capability not applicable.
|
||||
SL_SYSTEM_SECURITY_CAPABILITY_NA,
|
||||
/// Basic security capability.
|
||||
SL_SYSTEM_SECURITY_CAPABILITY_BASIC,
|
||||
/// Root of Trust security capability.
|
||||
SL_SYSTEM_SECURITY_CAPABILITY_ROT,
|
||||
/// Secure Element security capability.
|
||||
SL_SYSTEM_SECURITY_CAPABILITY_SE,
|
||||
/// Secure Vault security capability.
|
||||
SL_SYSTEM_SECURITY_CAPABILITY_VAULT
|
||||
};
|
||||
|
||||
/// Floating point co-processor access modes.
|
||||
SL_ENUM_GENERIC(sl_hal_system_fpu_access_t, uint32_t) {
|
||||
/// Access denied, any attempted access generates a NOCP UsageFault.
|
||||
SL_SYSTEM_FPU_ACCESS_DENIED = (0x0 << 20),
|
||||
/// Privileged access only, an unprivileged access generates a NOCP UsageFault.
|
||||
SL_SYSTEM_FPU_ACCESS_PRIVILEGED_ONLY = (0x5 << 20),
|
||||
/// Reserved.
|
||||
SL_SYSTEM_FPU_ACCESS_RESERVED = (0xA << 20),
|
||||
/// Full access.
|
||||
SL_SYSTEM_FPU_ACCESS_FULL = (0xF << 20)
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/// Chip revision details.
|
||||
typedef struct {
|
||||
uint8_t minor; ///< Minor revision number.
|
||||
uint8_t major; ///< Major revision number.
|
||||
uint16_t part_number; ///< Device part number. (0xFFFF if unavailable)
|
||||
uint16_t family; ///< Device family number. (0xFFFF if unavailable)
|
||||
} sl_hal_system_chip_revision_t;
|
||||
|
||||
/// ADC Calibration DEVINFO Structures.
|
||||
typedef struct sl_hal_system_devinfo_adc_cal_data_t {
|
||||
uint8_t trim_vros0;
|
||||
uint8_t trim_vros1;
|
||||
uint8_t trim_gain_4x;
|
||||
uint8_t trim_gain_0x3_int;
|
||||
} sl_hal_system_devinfo_adc_cal_data_t;
|
||||
|
||||
typedef struct sl_hal_system_devinfo_adc_offset_t {
|
||||
uint8_t trim_off_1x;
|
||||
uint8_t trim_off_2x;
|
||||
uint8_t trim_off_4x;
|
||||
uint8_t dummy_byte;
|
||||
} sl_hal_system_devinfo_adc_offset_t;
|
||||
|
||||
typedef struct sl_hal_system_devinfo_adc_t {
|
||||
sl_hal_system_devinfo_adc_cal_data_t cal_data;
|
||||
sl_hal_system_devinfo_adc_offset_t offset;
|
||||
} sl_hal_system_devinfo_adc_t;
|
||||
|
||||
/// Temperature DEVINFO Structure.
|
||||
typedef struct sl_hal_system_devinfo_temperature_t {
|
||||
uint16_t emu_temp_room;
|
||||
uint16_t cal_temp;
|
||||
} sl_hal_system_devinfo_temperature_t;
|
||||
|
||||
/// Chip features Structure.
|
||||
typedef struct sl_hal_system_features {
|
||||
char feature1;
|
||||
char feature2;
|
||||
char feature3;
|
||||
} sl_hal_system_features_t;
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL CONSTANTS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
extern const sl_hal_system_devinfo_adc_t SL_HAL_SYSTEM_DEVINFO_ADC_RESET_VALUES;
|
||||
|
||||
extern const sl_hal_system_devinfo_temperature_t SL_HAL_SYSTEM_DEVINFO_TEMPERATURE_RESET_VALUES;
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief
|
||||
* Get the chip revision.
|
||||
*
|
||||
* @param [out]
|
||||
* rev Pointer to return the chip revision to.
|
||||
*
|
||||
* @warning
|
||||
* The chip revision structure may be returned with either the partnumber or
|
||||
* family unpopulated (0xFFFF) depending on the device.
|
||||
******************************************************************************/
|
||||
void sl_hal_system_get_chip_revision(sl_hal_system_chip_revision_t *rev);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get DEVINFO revision.
|
||||
*
|
||||
* @return
|
||||
* Revision of the DEVINFO contents.
|
||||
******************************************************************************/
|
||||
uint8_t sl_hal_system_get_devinfo_rev(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the default factory calibration value for HFRCO oscillator.
|
||||
*
|
||||
* @return
|
||||
* HFRCOCAL default value.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_hfrco_default_calibration(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the speed factory calibration value for HFRCO oscillator.
|
||||
*
|
||||
* @return
|
||||
* HFRCOCAL speed value.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_hfrco_speed_calibration(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the HFRCO calibration based on the frequency band.
|
||||
*
|
||||
* @param[in] frequency
|
||||
* Frequency for which to retrieve calibration.
|
||||
*
|
||||
* @return
|
||||
* HFRCOCAL value for the given band.
|
||||
*
|
||||
* @note
|
||||
* Those calibrations are only valid for the HFRCO oscillator when used with
|
||||
* the DPLL module.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_hfrcodpll_band_calibration(uint32_t frequency);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get a factory calibration value for HFRCOEM23 oscillator.
|
||||
*
|
||||
* @param [in]
|
||||
* HFRCOEM23 frequency for which to retrieve calibration.
|
||||
*
|
||||
* @return
|
||||
* HFRCOEM23 calibration value.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_hfrcoem23_calibration(uint32_t frequency);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get a factory calibration value for HFXOCAL.
|
||||
*
|
||||
* @return
|
||||
* HFXOCAL value.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_hfxocal(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get family security capability.
|
||||
*
|
||||
* @note
|
||||
* This function retrieves the family security capability based on the
|
||||
* device number.
|
||||
*
|
||||
* @return
|
||||
* Security capability of MCU.
|
||||
******************************************************************************/
|
||||
sl_hal_system_security_capability_t sl_hal_system_get_security_capability(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the unique number for this device.
|
||||
*
|
||||
* @return
|
||||
* Unique number for this device.
|
||||
******************************************************************************/
|
||||
uint64_t sl_hal_system_get_unique(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the production revision for this part.
|
||||
*
|
||||
* @return
|
||||
* Production revision for this part.
|
||||
******************************************************************************/
|
||||
uint8_t sl_hal_system_get_prod_rev(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the SRAM Base Address.
|
||||
*
|
||||
* @return
|
||||
* Base address SRAM (32-bit unsigned integer).
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_sram_base_address(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the SRAM size (in KB).
|
||||
*
|
||||
* @note
|
||||
* This function retrieves SRAM size by reading the chip device
|
||||
* info structure. If your binary is made for one specific device only,
|
||||
* use SRAM_SIZE instead.
|
||||
*
|
||||
* @return
|
||||
* Size of internal SRAM (in KB).
|
||||
******************************************************************************/
|
||||
uint16_t sl_hal_system_get_sram_size(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the flash size (in KB).
|
||||
*
|
||||
* @note
|
||||
* This function retrieves flash size by reading the chip device info structure or
|
||||
* DEVINFO->EMBMSIZE (embedded flash. not the case for S3 for now) or
|
||||
* user config (external flash).
|
||||
*
|
||||
* @return
|
||||
* Size of flash (in KB).
|
||||
******************************************************************************/
|
||||
uint16_t sl_hal_system_get_flash_size(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the flash page size in bytes.
|
||||
*
|
||||
* @note
|
||||
* This function retrieves flash page size by reading the SE or
|
||||
* user config (external flash)
|
||||
*
|
||||
* @return
|
||||
* Page size of flash in bytes.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_flash_page_size(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the MCU part number.
|
||||
*
|
||||
* @return
|
||||
* The part number of MCU.
|
||||
******************************************************************************/
|
||||
uint16_t sl_hal_system_get_part_number(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the SoC or MCU features.
|
||||
*
|
||||
* @return
|
||||
* The features of the current SoC or MCU.
|
||||
*
|
||||
* @note The features can be decoded by referring to the SoC or MCU datasheet.
|
||||
******************************************************************************/
|
||||
sl_hal_system_features_t sl_hal_system_get_part_features(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the temperature information.
|
||||
*
|
||||
* @param[out] info
|
||||
* Pointer to variable where to store the temperature info.
|
||||
******************************************************************************/
|
||||
void sl_hal_system_get_temperature_info(sl_hal_system_devinfo_temperature_t *info);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set floating point co-processor (FPU) access mode.
|
||||
*
|
||||
* @param[in] accessMode
|
||||
* Floating point co-processor access mode.
|
||||
******************************************************************************/
|
||||
void sl_hal_system_fpu_set_access_mode(sl_hal_system_fpu_access_t access_mode);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the ADC calibration info.
|
||||
*
|
||||
* @param[out] info
|
||||
* Pointer to variable where to store the adc calibration info.
|
||||
******************************************************************************/
|
||||
void sl_hal_system_get_adc_calibration_info(sl_hal_system_devinfo_adc_t *info);
|
||||
|
||||
/** @} (end addtogroup system) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef _SL_HAL_SYSTEM_GENERIC_H */
|
||||
432
Libs/platform/peripheral/src/sl_hal_gpio.c
Normal file
432
Libs/platform/peripheral/src/sl_hal_gpio.c
Normal file
@@ -0,0 +1,432 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief General Purpose IO (GPIO) peripheral API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2024 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_hal_gpio.h"
|
||||
#if defined(GPIO_PRESENT)
|
||||
#include "sl_hal_bus.h"
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
extern __INLINE void sl_hal_gpio_lock(void);
|
||||
extern __INLINE void sl_hal_gpio_unlock(void);
|
||||
extern __INLINE uint32_t sl_hal_gpio_get_lock_status(void);
|
||||
extern __INLINE void sl_hal_gpio_set_pin(const sl_gpio_t *gpio);
|
||||
extern __INLINE void sl_hal_gpio_set_port(sl_gpio_port_t port,
|
||||
uint32_t pins);
|
||||
extern __INLINE void sl_hal_gpio_set_port_value(sl_gpio_port_t port,
|
||||
uint32_t val,
|
||||
uint32_t mask);
|
||||
extern __INLINE void sl_hal_gpio_set_slew_rate(sl_gpio_port_t port,
|
||||
uint8_t slewrate);
|
||||
extern __INLINE void sl_hal_gpio_set_slew_rate_alternate(sl_gpio_port_t port,
|
||||
uint8_t slewrate_alt);
|
||||
extern __INLINE uint8_t sl_hal_gpio_get_slew_rate(sl_gpio_port_t port);
|
||||
extern __INLINE uint8_t sl_hal_gpio_get_slew_rate_alternate(sl_gpio_port_t port);
|
||||
extern __INLINE void sl_hal_gpio_clear_pin(const sl_gpio_t *gpio);
|
||||
extern __INLINE void sl_hal_gpio_clear_port(sl_gpio_port_t port,
|
||||
uint32_t pins);
|
||||
extern __INLINE bool sl_hal_gpio_get_pin_input(const sl_gpio_t *gpio);
|
||||
extern __INLINE bool sl_hal_gpio_get_pin_output(const sl_gpio_t *gpio);
|
||||
extern __INLINE uint32_t sl_hal_gpio_get_port_input(sl_gpio_port_t port);
|
||||
extern __INLINE uint32_t sl_hal_gpio_get_port_output(sl_gpio_port_t port);
|
||||
extern __INLINE void sl_hal_gpio_toggle_pin(const sl_gpio_t *gpio);
|
||||
extern __INLINE void sl_hal_gpio_toggle_port(sl_gpio_port_t port,
|
||||
uint32_t pins);
|
||||
extern __INLINE void sl_hal_gpio_enable_interrupts(uint32_t flags);
|
||||
extern __INLINE void sl_hal_gpio_disable_interrupts(uint32_t flags);
|
||||
extern __INLINE void sl_hal_gpio_clear_interrupts(uint32_t flags);
|
||||
extern __INLINE void sl_hal_gpio_set_interrupts(uint32_t flags);
|
||||
extern __INLINE uint32_t sl_hal_gpio_get_pending_interrupts(void);
|
||||
extern __INLINE uint32_t sl_hal_gpio_get_enabled_interrupts(void);
|
||||
extern __INLINE uint32_t sl_hal_gpio_get_enabled_pending_interrupts(void);
|
||||
extern __INLINE int32_t sl_hal_gpio_get_external_interrupt_number(uint8_t pin,
|
||||
uint32_t enabled_interrupts_mask);
|
||||
extern __INLINE int32_t sl_hal_gpio_get_em4_interrupt_number(const sl_gpio_t *gpio);
|
||||
extern __INLINE void sl_hal_gpio_set_pin_em4_retention(bool enable);
|
||||
extern __INLINE void sl_hal_gpio_disable_pin_em4_wakeup (uint32_t pinmask);
|
||||
extern __INLINE uint32_t sl_hal_gpio_get_pin_em4_wakeup_cause(void);
|
||||
extern __INLINE void sl_hal_gpio_enable_debug_swo(bool enable);
|
||||
extern __INLINE void sl_hal_gpio_enable_debug_swd_clk(bool enable);
|
||||
extern __INLINE void sl_hal_gpio_enable_debug_swd_io(bool enable);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the mode for GPIO pin.
|
||||
******************************************************************************/
|
||||
void sl_hal_gpio_set_pin_mode(const sl_gpio_t *gpio,
|
||||
sl_gpio_mode_t mode,
|
||||
bool output_value)
|
||||
{
|
||||
sl_gpio_mode_t gpio_mode = SL_GPIO_MODE_DISABLED;
|
||||
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
|
||||
EFM_ASSERT(sl_hal_gpio_get_lock_status() == 0);
|
||||
|
||||
switch (mode) {
|
||||
#if defined(_GPIO_P_MODEL_MODE0_DISABLED)
|
||||
case SL_GPIO_MODE_DISABLED:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_DISABLED;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_INPUT)
|
||||
case SL_GPIO_MODE_INPUT:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_INPUT;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_INPUTPULL)
|
||||
case SL_GPIO_MODE_INPUT_PULL:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_INPUTPULL;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_INPUTPULLFILTER)
|
||||
case SL_GPIO_MODE_INPUT_PULL_FILTER:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_INPUTPULLFILTER;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_PUSHPULL)
|
||||
case SL_GPIO_MODE_PUSH_PULL:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_PUSHPULL;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_PUSHPULLALT)
|
||||
case SL_GPIO_MODE_PUSH_PULL_ALTERNATE:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_PUSHPULLALT;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDOR)
|
||||
case SL_GPIO_MODE_WIRED_OR:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_WIREDOR;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDORPULLDOWN)
|
||||
case SL_GPIO_MODE_WIRED_OR_PULL_DOWN:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_WIREDORPULLDOWN;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDAND)
|
||||
case SL_GPIO_MODE_WIRED_AND:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_WIREDAND;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDFILTER)
|
||||
case SL_GPIO_MODE_WIRED_AND_FILTER:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDFILTER;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDPULLUP)
|
||||
case SL_GPIO_MODE_WIRED_AND_PULLUP:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDPULLUP;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER)
|
||||
case SL_GPIO_MODE_WIRED_AND_PULLUP_FILTER:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDALT)
|
||||
case SL_GPIO_MODE_WIRED_AND_ALTERNATE:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDALT;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTFILTER)
|
||||
case SL_GPIO_MODE_WIRED_AND_ALTERNATE_FILTER:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDALTFILTER;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTPULLUP)
|
||||
case SL_GPIO_MODE_WIRED_AND_ALTERNATE_PULLUP:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDALTPULLUP;
|
||||
break;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTPULLUPFILTER)
|
||||
case SL_GPIO_MODE_WIRED_AND_ALTERNATE_PULLUP_FILTER:
|
||||
gpio_mode = _GPIO_P_MODEL_MODE0_WIREDANDALTPULLUPFILTER;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
EFM_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
EFM_ASSERT(SL_HAL_GPIO_MODE_IS_VALID(gpio_mode));
|
||||
|
||||
// If disabling a pin, do not modify DOUT to reduce the chance of
|
||||
// a glitch/spike (may not be sufficient precaution in all use cases).
|
||||
// As mode settings are dependent on DOUT values, setting output value
|
||||
// prior to mode. @ref enum - sl_gpio_mode_t
|
||||
if (mode != SL_GPIO_MODE_DISABLED) {
|
||||
if (output_value) {
|
||||
sl_hal_gpio_set_pin(gpio);
|
||||
} else {
|
||||
sl_hal_gpio_clear_pin(gpio);
|
||||
}
|
||||
}
|
||||
|
||||
// There are two registers controlling the pins for each port.
|
||||
// The MODEL register controls pins 0-7 and MODEH controls pins 8-15.
|
||||
if (gpio->pin < 8) {
|
||||
sl_hal_bus_reg_write_mask(&(GPIO->P[gpio->port].MODEL), 0xFu << (gpio->pin * 4), gpio_mode << (gpio->pin * 4));
|
||||
} else {
|
||||
sl_hal_bus_reg_write_mask(&(GPIO->P[gpio->port].MODEH), 0xFu << ((gpio->pin - 8) * 4), gpio_mode << ((gpio->pin - 8) * 4));
|
||||
}
|
||||
|
||||
// SL_GPIO_MODE_DISABLED based on DOUT Value (low/high) act as two different configurations.
|
||||
// By setting mode to disabled first and then modifying the DOUT value, so that
|
||||
// previous mode configuration on given pin not effected.
|
||||
if (mode == SL_GPIO_MODE_DISABLED) {
|
||||
if (output_value) {
|
||||
sl_hal_gpio_set_pin(gpio);
|
||||
} else {
|
||||
sl_hal_gpio_clear_pin(gpio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get the mode for a GPIO pin.
|
||||
******************************************************************************/
|
||||
sl_gpio_mode_t sl_hal_gpio_get_pin_mode(const sl_gpio_t *gpio)
|
||||
{
|
||||
sl_gpio_mode_t mode = SL_GPIO_MODE_DISABLED;
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
|
||||
|
||||
// Determine the current mode of the GPIO pin based on the pin number.
|
||||
if (gpio->pin < 8) {
|
||||
mode = (sl_gpio_mode_t) ((GPIO->P[gpio->port].MODEL >> (gpio->pin * 4)) & 0xF);
|
||||
} else {
|
||||
mode = (sl_gpio_mode_t) ((GPIO->P[gpio->port].MODEH >> ((gpio->pin - 8) * 4)) & 0xF);
|
||||
}
|
||||
|
||||
// Map the hardware-specific mode to the corresponding sl_gpio_mode_t value
|
||||
switch (mode) {
|
||||
#if defined(_GPIO_P_MODEL_MODE0_DISABLED)
|
||||
case _GPIO_P_MODEL_MODE0_DISABLED:
|
||||
return SL_GPIO_MODE_DISABLED;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_INPUT)
|
||||
case _GPIO_P_MODEL_MODE0_INPUT:
|
||||
return SL_GPIO_MODE_INPUT;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_INPUTPULL)
|
||||
case _GPIO_P_MODEL_MODE0_INPUTPULL:
|
||||
return SL_GPIO_MODE_INPUT_PULL;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_INPUTPULLFILTER)
|
||||
case _GPIO_P_MODEL_MODE0_INPUTPULLFILTER:
|
||||
return SL_GPIO_MODE_INPUT_PULL_FILTER;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_PUSHPULL)
|
||||
case _GPIO_P_MODEL_MODE0_PUSHPULL:
|
||||
return SL_GPIO_MODE_PUSH_PULL;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_PUSHPULLALT)
|
||||
case _GPIO_P_MODEL_MODE0_PUSHPULLALT:
|
||||
return SL_GPIO_MODE_PUSH_PULL_ALTERNATE;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDOR)
|
||||
case _GPIO_P_MODEL_MODE0_WIREDOR:
|
||||
return SL_GPIO_MODE_WIRED_OR;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDORPULLDOWN)
|
||||
case _GPIO_P_MODEL_MODE0_WIREDORPULLDOWN:
|
||||
return SL_GPIO_MODE_WIRED_OR_PULL_DOWN;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDAND)
|
||||
case _GPIO_P_MODEL_MODE0_WIREDAND:
|
||||
return SL_GPIO_MODE_WIRED_AND;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDFILTER)
|
||||
case _GPIO_P_MODEL_MODE0_WIREDANDFILTER:
|
||||
return SL_GPIO_MODE_WIRED_AND_FILTER;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDPULLUP)
|
||||
case _GPIO_P_MODEL_MODE0_WIREDANDPULLUP:
|
||||
return SL_GPIO_MODE_WIRED_AND_PULLUP;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER)
|
||||
case _GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER:
|
||||
return SL_GPIO_MODE_WIRED_AND_PULLUP_FILTER;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDALT)
|
||||
case _GPIO_P_MODEL_MODE0_WIREDANDALT:
|
||||
return SL_GPIO_MODE_WIRED_AND_ALTERNATE;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTFILTER)
|
||||
case _GPIO_P_MODEL_MODE0_WIREDANDALTFILTER:
|
||||
return SL_GPIO_MODE_WIRED_AND_ALTERNATE_FILTER;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTPULLUP)
|
||||
case _GPIO_P_MODEL_MODE0_WIREDANDALTPULLUP:
|
||||
return SL_GPIO_MODE_WIRED_AND_ALTERNATE_PULLUP;
|
||||
#endif
|
||||
#if defined(_GPIO_P_MODEL_MODE0_WIREDANDALTPULLUPFILTER)
|
||||
case _GPIO_P_MODEL_MODE0_WIREDANDALTPULLUPFILTER:
|
||||
return SL_GPIO_MODE_WIRED_AND_ALTERNATE_PULLUP_FILTER;
|
||||
#endif
|
||||
default:
|
||||
EFM_ASSERT(false);
|
||||
return mode; // returning the default state
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configure the GPIO pin interrupt.
|
||||
******************************************************************************/
|
||||
int32_t sl_hal_gpio_configure_external_interrupt(const sl_gpio_t *gpio,
|
||||
int32_t int_no,
|
||||
sl_gpio_interrupt_flag_t flags)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
|
||||
EFM_ASSERT(SL_GPIO_FLAG_IS_VALID(flags));
|
||||
EFM_ASSERT(sl_hal_gpio_get_lock_status() == 0);
|
||||
|
||||
if (int_no != SL_GPIO_INTERRUPT_UNAVAILABLE && int_no >= 0) {
|
||||
#if defined(_GPIO_EXTIPINSELL_MASK)
|
||||
EFM_ASSERT(SL_HAL_GPIO_INTNO_PIN_VALID(int_no, gpio->pin));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_GPIO_EXTIPINSELL_MASK)
|
||||
int_no = gpio->pin;
|
||||
#endif
|
||||
|
||||
if (int_no == SL_GPIO_INTERRUPT_UNAVAILABLE) {
|
||||
uint32_t interrupts_enabled = sl_hal_gpio_get_enabled_interrupts();
|
||||
int_no = sl_hal_gpio_get_external_interrupt_number(gpio->pin, interrupts_enabled);
|
||||
}
|
||||
|
||||
if (int_no != SL_GPIO_INTERRUPT_UNAVAILABLE && int_no >= 0) {
|
||||
if (int_no < 8) {
|
||||
// The EXTIPSELL register controls pins 0-7 of the interrupt configuration.
|
||||
#if defined(_GPIO_EXTIPSELL_EXTIPSEL0_MASK)
|
||||
sl_hal_bus_reg_write_mask(&GPIO->EXTIPSELL,
|
||||
_GPIO_EXTIPSELL_EXTIPSEL0_MASK
|
||||
<< (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * int_no),
|
||||
(uint32_t)gpio->port << (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * int_no));
|
||||
#endif
|
||||
// The EXTIPINSELL register controls interrupt 0-7 of the interrupt/pin number mapping.
|
||||
#if defined(_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK)
|
||||
sl_hal_bus_reg_write_mask(&GPIO->EXTIPINSELL,
|
||||
_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK
|
||||
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * int_no),
|
||||
((gpio->pin % 4) & _GPIO_EXTIPINSELL_EXTIPINSEL0_MASK)
|
||||
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * int_no));
|
||||
#endif
|
||||
} else {
|
||||
// EXTIPSELH controls pins 8-15 of the interrupt configuration.
|
||||
#if defined(_GPIO_EXTIPSELH_EXTIPSEL0_MASK)
|
||||
uint32_t tmp = int_no - 8;
|
||||
sl_hal_bus_reg_write_mask(&GPIO->EXTIPSELH,
|
||||
_GPIO_EXTIPSELH_EXTIPSEL0_MASK
|
||||
<< (_GPIO_EXTIPSELH_EXTIPSEL1_SHIFT * tmp),
|
||||
(uint32_t)gpio->port << (_GPIO_EXTIPSELH_EXTIPSEL1_SHIFT * tmp));
|
||||
#endif
|
||||
// EXTIPINSELH controls interrupt 8-15 of the interrupt/pin number mapping.
|
||||
#if defined(_GPIO_EXTIPINSELH_EXTIPINSEL0_MASK)
|
||||
sl_hal_bus_reg_write_mask(&GPIO->EXTIPINSELH,
|
||||
_GPIO_EXTIPINSELH_EXTIPINSEL0_MASK
|
||||
<< (_GPIO_EXTIPINSELH_EXTIPINSEL1_SHIFT * tmp),
|
||||
((gpio->pin % 4) & _GPIO_EXTIPINSELH_EXTIPINSEL0_MASK)
|
||||
<< (_GPIO_EXTIPSELH_EXTIPSEL1_SHIFT * tmp));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Enable/disable rising edge interrupt.
|
||||
(((flags & SL_GPIO_INTERRUPT_RISING_EDGE) == SL_GPIO_INTERRUPT_RISING_EDGE)
|
||||
|| ((flags & SL_GPIO_INTERRUPT_RISING_FALLING_EDGE) == SL_GPIO_INTERRUPT_RISING_FALLING_EDGE)) \
|
||||
? sl_hal_bus_reg_write_bit(&(GPIO->EXTIRISE), int_no, true) \
|
||||
: sl_hal_bus_reg_write_bit(&(GPIO->EXTIRISE), int_no, false);
|
||||
|
||||
// Enable/disable falling edge interrupt.
|
||||
(((flags & SL_GPIO_INTERRUPT_FALLING_EDGE) == SL_GPIO_INTERRUPT_FALLING_EDGE)
|
||||
|| (flags & SL_GPIO_INTERRUPT_RISING_FALLING_EDGE) == SL_GPIO_INTERRUPT_RISING_FALLING_EDGE) \
|
||||
? sl_hal_bus_reg_write_bit(&(GPIO->EXTIFALL), int_no, true) \
|
||||
: sl_hal_bus_reg_write_bit(&(GPIO->EXTIFALL), int_no, false);
|
||||
|
||||
// Clear any pending interrupt.
|
||||
sl_hal_gpio_clear_interrupts(1 << int_no);
|
||||
}
|
||||
|
||||
return int_no;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Enable GPIO pin wake-up from EM4. When the function exits,
|
||||
* EM4 mode can be safely entered.
|
||||
*****************************************************************************/
|
||||
void sl_hal_gpio_enable_pin_em4_wakeup(uint32_t pinmask,
|
||||
uint32_t polaritymask)
|
||||
{
|
||||
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
|
||||
EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);
|
||||
|
||||
GPIO->EM4WUPOL &= ~pinmask; // Set the wakeup polarity.
|
||||
GPIO->EM4WUPOL |= pinmask & polaritymask;
|
||||
GPIO->EM4WUEN |= pinmask; // Enable wakeup.
|
||||
|
||||
sl_hal_gpio_set_pin_em4_retention(true); // Enable the pin retention.
|
||||
sl_hal_gpio_clear_interrupts(pinmask); // clear any pending interrupt.
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configure EM4WU pins as external level-sensitive interrupts.
|
||||
******************************************************************************/
|
||||
int32_t sl_hal_gpio_configure_wakeup_em4_external_interrupt(const sl_gpio_t *gpio,
|
||||
int32_t int_no,
|
||||
bool polarity)
|
||||
{
|
||||
EFM_ASSERT(SL_HAL_GPIO_PORT_PIN_IS_VALID(gpio->port, gpio->pin));
|
||||
EFM_ASSERT(sl_hal_gpio_get_lock_status() == 0);
|
||||
|
||||
int32_t em4_int_no = sl_hal_gpio_get_em4_interrupt_number(gpio);
|
||||
|
||||
if (int_no == SL_GPIO_INTERRUPT_UNAVAILABLE) {
|
||||
int_no = em4_int_no;
|
||||
}
|
||||
|
||||
if (em4_int_no == SL_GPIO_INTERRUPT_UNAVAILABLE || int_no != em4_int_no) {
|
||||
return SL_GPIO_INTERRUPT_UNAVAILABLE;
|
||||
}
|
||||
|
||||
if (int_no != SL_GPIO_INTERRUPT_UNAVAILABLE) {
|
||||
// GPIO pin mode set.
|
||||
sl_hal_gpio_set_pin_mode(gpio, SL_GPIO_MODE_INPUT_PULL_FILTER, (unsigned int)!polarity);
|
||||
|
||||
// Enable EM4WU function and set polarity.
|
||||
uint32_t polarityMask = (uint32_t)polarity << (int_no + _GPIO_EM4WUEN_EM4WUEN_SHIFT);
|
||||
uint32_t pinmask = 1UL << (int_no + _GPIO_EM4WUEN_EM4WUEN_SHIFT);
|
||||
|
||||
sl_hal_gpio_enable_pin_em4_wakeup(pinmask, polarityMask);
|
||||
}
|
||||
|
||||
return int_no;
|
||||
}
|
||||
|
||||
#endif /* defined(GPIO_PRESENT)*/
|
||||
1012
Libs/platform/peripheral/src/sl_hal_sysrtc.c
Normal file
1012
Libs/platform/peripheral/src/sl_hal_sysrtc.c
Normal file
File diff suppressed because it is too large
Load Diff
662
Libs/platform/peripheral/src/sl_hal_system.c
Normal file
662
Libs/platform/peripheral/src/sl_hal_system.c
Normal file
@@ -0,0 +1,662 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Universal asynchronous receiver/transmitter (EUSART) peripheral API
|
||||
*******************************************************************************
|
||||
* # 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_hal_system.h"
|
||||
#include "sl_hal_syscfg.h"
|
||||
#include "em_device.h"
|
||||
#include <stdbool.h>
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
|
||||
#include "sl_se_manager.h"
|
||||
#include "sli_se_manager_device_data.h"
|
||||
#endif
|
||||
#include "sl_status.h"
|
||||
#include "sl_assert.h"
|
||||
/***************************************************************************//**
|
||||
* @addtogroup system
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************** DEFINES *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/* Bit mask used to extract the part number value without the new naming
|
||||
* bitfield. */
|
||||
#define SYSCFG_CHIPREV_PARTNUMBER1 0xFE0
|
||||
#define SYSCFG_CHIPREV_PARTNUMBER0 0xF
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#define HFRCO_DPLL_FREQUENCY_TABLE_SIZE 11
|
||||
|
||||
#define DEVINFO_TEMPERATURE_CALTEMP_INTEGER_SHIFT 4
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* TYPEDEF ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
|
||||
typedef struct hfrco_dpll_cal_element {
|
||||
uint32_t min_freq;
|
||||
uint32_t max_freq;
|
||||
} hfrco_dpll_cal_element_t;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** CONSTANTS **********************************
|
||||
******************************************************************************/
|
||||
const sl_hal_system_devinfo_adc_t SL_HAL_SYSTEM_DEVINFO_ADC_RESET_VALUES = {
|
||||
.cal_data = {
|
||||
.trim_vros0 = 0,
|
||||
.trim_vros1 = 0,
|
||||
.trim_gain_4x = 0,
|
||||
.trim_gain_0x3_int = 0
|
||||
},
|
||||
.offset = {
|
||||
.trim_off_1x = 0,
|
||||
.trim_off_2x = 0,
|
||||
.trim_off_4x = 0
|
||||
}
|
||||
};
|
||||
|
||||
const sl_hal_system_devinfo_temperature_t SL_HAL_SYSTEM_DEVINFO_TEMPERATURE_RESET_VALUES = {
|
||||
.emu_temp_room = 0,
|
||||
.cal_temp = 0
|
||||
};
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
|
||||
static const hfrco_dpll_cal_element_t HFRCO_DPLL_FREQUENCY_TABLE[HFRCO_DPLL_FREQUENCY_TABLE_SIZE] = {
|
||||
{ .min_freq = 16000000, .max_freq = 20000000 }, // 18MHz calibration central frequency
|
||||
{ .min_freq = 20000000, .max_freq = 24500000 }, // 22MHz calibration central frequency
|
||||
{ .min_freq = 24500000, .max_freq = 30000000 }, // 27MHz calibration central frequency
|
||||
{ .min_freq = 30000000, .max_freq = 36000000 }, // 33MHz calibration central frequency
|
||||
{ .min_freq = 36000000, .max_freq = 42500000 }, // 39MHz calibration central frequency
|
||||
{ .min_freq = 42500000, .max_freq = 50500000 }, // 46MHz calibration central frequency
|
||||
{ .min_freq = 50500000, .max_freq = 60000000 }, // 55MHz calibration central frequency
|
||||
{ .min_freq = 60000000, .max_freq = 70000000 }, // 65MHz calibration central frequency
|
||||
{ .min_freq = 70000000, .max_freq = 80000000 }, // 75MHz calibration central frequency
|
||||
{ .min_freq = 80000000, .max_freq = 90000000 }, // 85MHz calibration central frequency
|
||||
{ .min_freq = 90000000, .max_freq = 100000000 } // 95MHz calibration central frequency
|
||||
};
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** UTILITY *************************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
/***************************************************************************//**
|
||||
* @brief Get the nth ASCII character of a specified number.
|
||||
*
|
||||
* @param[in] input_number
|
||||
* The number where the digit will be taken.
|
||||
*
|
||||
* @param[in] position
|
||||
* The digit position.
|
||||
*
|
||||
* @return
|
||||
* The ASCII value of the specified digit.
|
||||
******************************************************************************/
|
||||
char sli_get_n_digit(uint16_t input_number, uint8_t position)
|
||||
{
|
||||
uint32_t exp[] = { 10, 100, 1000, 10000, 100000 };
|
||||
uint32_t number = input_number;
|
||||
|
||||
if (position > 4) {
|
||||
EFM_ASSERT(false);
|
||||
return '0';
|
||||
}
|
||||
|
||||
number = (number % exp[position]);
|
||||
|
||||
if (position != 0) {
|
||||
number = number / (exp[position - 1]);
|
||||
}
|
||||
|
||||
return (char)number + '0';
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_DEVINFO_PART0_DIECODE0_MASK) && defined(_SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/***************************************************************************//**
|
||||
* @brief Convert hexadecimal ASCII character to integer value.
|
||||
*
|
||||
* @param[in] character
|
||||
* The character to be coverted to a number.
|
||||
*
|
||||
* @return
|
||||
* The uint8_t value of the character given in parameter.
|
||||
******************************************************************************/
|
||||
uint8_t sli_hex_ascii_to_value(char character)
|
||||
{
|
||||
if (character >= '0' && character <= '9') {
|
||||
return character - '0';
|
||||
} else if (character >= 'A' && character <= 'F') {
|
||||
return character - 'A';
|
||||
}
|
||||
|
||||
return 0U;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Get CHIPREV register.
|
||||
******************************************************************************/
|
||||
void sl_hal_system_get_chip_revision(sl_hal_system_chip_revision_t *rev)
|
||||
{
|
||||
#if defined(CMU_CLKEN0_SYSCFG)
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_SYSCFG;
|
||||
#endif
|
||||
|
||||
uint32_t chip_rev = sl_hal_syscfg_read_chip_rev();
|
||||
|
||||
rev->minor = (chip_rev & _SYSCFG_CHIPREV_MINOR_MASK) >> _SYSCFG_CHIPREV_MINOR_SHIFT;
|
||||
rev->major = (chip_rev & _SYSCFG_CHIPREV_MAJOR_MASK) >> _SYSCFG_CHIPREV_MAJOR_SHIFT;
|
||||
#if defined(_SYSCFG_CHIPREV_PARTNUMBER_MASK)
|
||||
rev->part_number = ((chip_rev & SYSCFG_CHIPREV_PARTNUMBER1) >> 5) | (chip_rev & SYSCFG_CHIPREV_PARTNUMBER0);
|
||||
rev->family = (uint16_t)0xFFFF;
|
||||
#elif defined(_SYSCFG_CHIPREV_FAMILY_MASK)
|
||||
rev->part_number = (uint16_t)0xFFFF;
|
||||
rev->family = (chip_rev & _SYSCFG_CHIPREV_FAMILY_MASK) >> _SYSCFG_CHIPREV_FAMILY_SHIFT;
|
||||
#else
|
||||
#error No Chip Revision Part Number or Family
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the MCU family identifier.
|
||||
******************************************************************************/
|
||||
sl_hal_system_part_family_t sl_hal_system_get_family(void)
|
||||
{
|
||||
#if defined(_DEVINFO_PART_FAMILY_MASK)
|
||||
return (DEVINFO->PART & (_DEVINFO_PART_FAMILY_MASK
|
||||
| _DEVINFO_PART_FAMILYNUM_MASK));
|
||||
#else
|
||||
return (DEVINFO->PART0 & (_DEVINFO_PART0_PROTOCOL_MASK
|
||||
| _DEVINFO_PART0_SERIES_MASK
|
||||
| _DEVINFO_PART0_DIECODE0_MASK));
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get DEVINFO revision.
|
||||
******************************************************************************/
|
||||
uint8_t sl_hal_system_get_devinfo_rev(void)
|
||||
{
|
||||
#if defined(_DEVINFO_INFO_DEVINFOREV_MASK)
|
||||
return (uint8_t)((DEVINFO->INFO & _DEVINFO_INFO_DEVINFOREV_MASK)
|
||||
>> _DEVINFO_INFO_DEVINFOREV_SHIFT);
|
||||
#elif defined(_DEVINFO_REVISION_DEVINFOREV_MASK)
|
||||
return (uint8_t)((DEVINFO->REVISION & _DEVINFO_REVISION_DEVINFOREV_MASK)
|
||||
>> _DEVINFO_REVISION_DEVINFOREV_SHIFT);
|
||||
#else
|
||||
#error (sl_hal_system.c): Location of devinfo revision is not defined.
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the default factory calibration value for HFRCO oscillator.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_hfrco_default_calibration(void)
|
||||
{
|
||||
#if defined(_DEVINFO_HFRCOCALDEFAULT_MASK)
|
||||
return DEVINFO->HFRCOCALDEFAULT;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the speed factory calibration value for HFRCO oscillator.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_hfrco_speed_calibration(void)
|
||||
{
|
||||
#if defined(_DEVINFO_HFRCOCALSPEED_MASK)
|
||||
return DEVINFO->HFRCOCALSPEED;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the HFRCO calibration based on the frequency band.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_hfrcodpll_band_calibration(uint32_t frequency)
|
||||
{
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
|
||||
sl_status_t status;
|
||||
uint8_t band_index = 0xFF;
|
||||
sl_se_command_context_t se_command_ctx;
|
||||
sli_se_device_data_t otp_section_id = (sli_se_device_data_t)(SLI_SE_DEVICE_DATA_DI0 + DEVINFO_GP_FRAGMENT_INDEX);
|
||||
uint32_t offset;
|
||||
uint32_t calibration_value = 0;
|
||||
|
||||
for (uint8_t i = 0; i < HFRCO_DPLL_FREQUENCY_TABLE_SIZE; i++) {
|
||||
if ((frequency >= HFRCO_DPLL_FREQUENCY_TABLE[i].min_freq)
|
||||
&& (frequency <= HFRCO_DPLL_FREQUENCY_TABLE[i].max_freq)) {
|
||||
band_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (band_index >= HFRCO_DPLL_FREQUENCY_TABLE_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate memory offset based on the band index we want.
|
||||
offset = (band_index * 4) + DEVINFO_GP_HFRCODPLLBAND0_OFFSET;
|
||||
|
||||
// Initialize command context
|
||||
status = sl_se_init_command_context(&se_command_ctx);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Send the SE command to retrieve the HFRCODPLL calibration for a given band from the DEVINFO OTP section
|
||||
status = sli_se_device_data_read_word(&se_command_ctx, otp_section_id, offset, &calibration_value);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return calibration_value;
|
||||
#else
|
||||
(void)frequency;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get a factory calibration value for HFRCOCEM23 oscillator.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_hfrcoem23_calibration(uint32_t frequency)
|
||||
{
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
|
||||
sl_status_t status;
|
||||
sl_se_command_context_t se_command_ctx;
|
||||
sli_se_device_data_t otp_section_id = (sli_se_device_data_t)(SLI_SE_DEVICE_DATA_DI0 + DEVINFO_GP_FRAGMENT_INDEX);
|
||||
uint32_t offset;
|
||||
uint32_t calibration_value = 0;
|
||||
|
||||
// Determine offset based on HFRCOEM23 frequency.
|
||||
if (frequency == 40000000UL) {
|
||||
#if defined(DEVINFO_GP_HFRCOEM2340MHZ_OFFSET)
|
||||
offset = DEVINFO_GP_HFRCOEM2340MHZ_OFFSET;
|
||||
#else
|
||||
// Default to 20Mhz.
|
||||
offset = DEVINFO_GP_HFRCOEM23DEFAULT_OFFSET;
|
||||
#endif
|
||||
} else {
|
||||
offset = DEVINFO_GP_HFRCOEM23DEFAULT_OFFSET;
|
||||
}
|
||||
|
||||
// Initialize command context
|
||||
status = sl_se_init_command_context(&se_command_ctx);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Send the SE command to retrieve the HFRCOEM23 calibration from the DEVINFO OTP section
|
||||
status = sli_se_device_data_read_word(&se_command_ctx, otp_section_id, offset, &calibration_value);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return calibration_value;
|
||||
#else
|
||||
(void)frequency;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get a factory calibration value for HFXOCAL.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_hfxocal(void)
|
||||
{
|
||||
#if defined(_DEVINFO_HFXOCAL_MASK)
|
||||
return DEVINFO->HFXOCAL;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get family security capability.
|
||||
******************************************************************************/
|
||||
sl_hal_system_security_capability_t sl_hal_system_get_security_capability(void)
|
||||
{
|
||||
sl_hal_system_security_capability_t sc = SL_SYSTEM_SECURITY_CAPABILITY_UNKNOWN;
|
||||
|
||||
uint16_t mcu_feature_set_major;
|
||||
uint16_t device_number;
|
||||
device_number = sl_hal_system_get_part_number();
|
||||
mcu_feature_set_major = 'A' + (device_number / 1000);
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2)
|
||||
// override feature set since BRD4182A Rev A00 -> rev B02 are marked "A"
|
||||
mcu_feature_set_major = 'C';
|
||||
#endif
|
||||
|
||||
switch (mcu_feature_set_major) {
|
||||
case 'A':
|
||||
sc = SL_SYSTEM_SECURITY_CAPABILITY_SE;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
sc = SL_SYSTEM_SECURITY_CAPABILITY_VAULT;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
sc = SL_SYSTEM_SECURITY_CAPABILITY_ROT;
|
||||
break;
|
||||
|
||||
default:
|
||||
sc = SL_SYSTEM_SECURITY_CAPABILITY_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the unique number for this device.
|
||||
******************************************************************************/
|
||||
uint64_t sl_hal_system_get_unique(void)
|
||||
{
|
||||
uint32_t tmp = DEVINFO->EUI64L;
|
||||
return ((uint64_t)DEVINFO->EUI64H << 32) | tmp;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the production revision for this part.
|
||||
******************************************************************************/
|
||||
uint8_t sl_hal_system_get_prod_rev(void)
|
||||
{
|
||||
#if defined(_DEVINFO_INFO_PRODREV_MASK)
|
||||
return (uint8_t)((DEVINFO->INFO & _DEVINFO_INFO_PRODREV_MASK)
|
||||
>> _DEVINFO_INFO_PRODREV_SHIFT);
|
||||
#elif defined(_DEVINFO_REVISION_PRODREV_MASK)
|
||||
return (uint8_t)((DEVINFO->REVISION & _DEVINFO_REVISION_PRODREV_MASK)
|
||||
>> _DEVINFO_REVISION_PRODREV_SHIFT);
|
||||
#else
|
||||
#error (sl_hal_system.c): Location of production revision is not defined.
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the SRAM Base Address.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_sram_base_address(void)
|
||||
{
|
||||
return SRAM_BASE;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the SRAM size (in KB).
|
||||
******************************************************************************/
|
||||
uint16_t sl_hal_system_get_sram_size(void)
|
||||
{
|
||||
#if defined(_DEVINFO_MSIZE_SRAM_MASK)
|
||||
return (uint16_t)((DEVINFO->MSIZE & _DEVINFO_MSIZE_SRAM_MASK)
|
||||
>> _DEVINFO_MSIZE_SRAM_SHIFT);
|
||||
#elif defined(_DEVINFO_EMBSIZE_RAM_MASK)
|
||||
return (uint16_t)((DEVINFO->EMBSIZE & _DEVINFO_EMBSIZE_RAM_MASK)
|
||||
>> _DEVINFO_EMBSIZE_RAM_SHIFT);
|
||||
#else
|
||||
#error (sl_hal_system.c): Location of SRAM Size is not defined.
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the flash size (in KB).
|
||||
******************************************************************************/
|
||||
uint16_t sl_hal_system_get_flash_size(void)
|
||||
{
|
||||
#if defined(_DEVINFO_MSIZE_FLASH_MASK)
|
||||
return (uint16_t)((DEVINFO->MSIZE & _DEVINFO_MSIZE_FLASH_MASK)
|
||||
>> _DEVINFO_MSIZE_FLASH_SHIFT);
|
||||
#elif defined(_DEVINFO_STACKMSIZE_FLASH_MASK)
|
||||
uint16_t stacked_flach_size = (uint16_t)((DEVINFO->STACKMSIZE & _DEVINFO_STACKMSIZE_FLASH_MASK)
|
||||
>> _DEVINFO_STACKMSIZE_FLASH_SHIFT);
|
||||
|
||||
if (stacked_flach_size == 0) {
|
||||
// Defined in linker script for external flash provided by customers.
|
||||
extern uint32_t __flash_size__;
|
||||
// Get flash size in kB.
|
||||
stacked_flach_size = (uint16_t)(uintptr_t)&__flash_size__ / 1024;
|
||||
}
|
||||
|
||||
return stacked_flach_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the flash page size in bytes.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_system_get_flash_page_size(void)
|
||||
{
|
||||
#if defined(_DEVINFO_MEMINFO_FLASHPAGESIZE_MASK)
|
||||
uint32_t tmp;
|
||||
tmp = (DEVINFO->MEMINFO & _DEVINFO_MEMINFO_FLASHPAGESIZE_MASK)
|
||||
>> _DEVINFO_MEMINFO_FLASHPAGESIZE_SHIFT;
|
||||
return 1UL << ((tmp + 10UL) & 0x1FUL);
|
||||
#else
|
||||
// Defined in linker script for external flash provided by customers.
|
||||
extern uint32_t __flash_page_size__;
|
||||
return (uintptr_t)&__flash_page_size__;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the MCU part number.
|
||||
******************************************************************************/
|
||||
uint16_t sl_hal_system_get_part_number(void)
|
||||
{
|
||||
#if defined(_DEVINFO_PART_DEVICENUM_MASK)
|
||||
return (uint16_t)((DEVINFO->PART & _DEVINFO_PART_DEVICENUM_MASK)
|
||||
>> _DEVINFO_PART_DEVICENUM_SHIFT);
|
||||
#elif defined(_DEVINFO_PART0_DIECODE0_MASK) && defined(_SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
// Encode features to the series 2 format.
|
||||
// Add security level vault high for SIxG301.
|
||||
uint16_t device_number = 1000;
|
||||
uint32_t register_value = (DEVINFO->PART1 & _DEVINFO_PART1_FEATURE1_MASK) >> _DEVINFO_PART1_FEATURE1_SHIFT;
|
||||
|
||||
device_number = sli_hex_ascii_to_value((char)register_value) * 100;
|
||||
|
||||
register_value = (DEVINFO->PART1 & _DEVINFO_PART1_FEATURE2_MASK) >> _DEVINFO_PART1_FEATURE2_SHIFT;
|
||||
device_number += sli_hex_ascii_to_value((char)register_value) * 10;
|
||||
|
||||
register_value = (DEVINFO->PART2 & _DEVINFO_PART2_FEATURE3_MASK) >> _DEVINFO_PART2_FEATURE3_SHIFT;
|
||||
device_number += sli_hex_ascii_to_value((char)register_value);
|
||||
|
||||
return device_number;
|
||||
#else
|
||||
#error (em_system.c): Location of device part number is not defined.
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the SoC or MCU features.
|
||||
******************************************************************************/
|
||||
sl_hal_system_features_t sl_hal_system_get_part_features(void)
|
||||
{
|
||||
sl_hal_system_features_t part_features = { .feature1 = '0', .feature2 = '0', .feature3 = '0' };
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
uint16_t device_number = ((DEVINFO->PART & _DEVINFO_PART_DEVICENUM_MASK) >> _DEVINFO_PART_DEVICENUM_SHIFT);
|
||||
|
||||
part_features.feature1 = sli_get_n_digit(device_number, 2);
|
||||
part_features.feature2 = sli_get_n_digit(device_number, 1);
|
||||
part_features.feature3 = sli_get_n_digit(device_number, 0);
|
||||
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
part_features.feature1 = (DEVINFO->PART1 & _DEVINFO_PART1_FEATURE1_MASK) >> _DEVINFO_PART1_FEATURE1_SHIFT;
|
||||
part_features.feature2 = (DEVINFO->PART1 & _DEVINFO_PART1_FEATURE2_MASK) >> _DEVINFO_PART1_FEATURE2_SHIFT;
|
||||
part_features.feature3 = (DEVINFO->PART2 & _DEVINFO_PART2_FEATURE3_MASK) >> _DEVINFO_PART2_FEATURE3_SHIFT;
|
||||
|
||||
#else
|
||||
#error Not defined for this die.
|
||||
#endif
|
||||
|
||||
return part_features;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the temperature information.
|
||||
******************************************************************************/
|
||||
void sl_hal_system_get_temperature_info(sl_hal_system_devinfo_temperature_t *info)
|
||||
{
|
||||
#if defined(_DEVINFO_CALTEMP_MASK) || defined(_DEVINFO_EMUTEMP_MASK)
|
||||
#if defined(_DEVINFO_CALTEMP_TEMP_MASK)
|
||||
info->cal_temp = ((DEVINFO->CALTEMP & _DEVINFO_CALTEMP_TEMP_MASK)
|
||||
>> _DEVINFO_CALTEMP_TEMP_SHIFT);
|
||||
#else
|
||||
info->cal_temp = 0;
|
||||
#endif
|
||||
#if defined(_DEVINFO_EMUTEMP_EMUTEMPROOM_MASK)
|
||||
info->emu_temp_room = ((DEVINFO->EMUTEMP & _DEVINFO_EMUTEMP_EMUTEMPROOM_MASK)
|
||||
>> _DEVINFO_EMUTEMP_EMUTEMPROOM_SHIFT);
|
||||
#else
|
||||
info->emu_temp_room = 0;
|
||||
#endif
|
||||
#elif defined (_SILICON_LABS_32B_SERIES_3_CONFIG_301)
|
||||
sl_status_t status;
|
||||
sl_se_command_context_t se_command_ctx;
|
||||
sli_se_device_data_t otp_section_id = (sli_se_device_data_t)(SLI_SE_DEVICE_DATA_DI0 + DEVINFO_GP_FRAGMENT_INDEX);
|
||||
uint32_t offset = DEVINFO_GP_TEMPERATURE_OFFSET;
|
||||
|
||||
// Initialize command context
|
||||
status = sl_se_init_command_context(&se_command_ctx);
|
||||
if (status != SL_STATUS_OK) {
|
||||
*info = SL_HAL_SYSTEM_DEVINFO_TEMPERATURE_RESET_VALUES;
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the SE command to retrieve the temperature information from the DEVINFO OTP section
|
||||
status = sli_se_device_data_read_word(&se_command_ctx, otp_section_id, offset, (uint32_t*)info);
|
||||
if (status != SL_STATUS_OK) {
|
||||
*info = SL_HAL_SYSTEM_DEVINFO_TEMPERATURE_RESET_VALUES;
|
||||
return;
|
||||
}
|
||||
|
||||
// Divide the temperature by 16 to retrieve only the integer part of the temperature value.
|
||||
info->cal_temp = info->cal_temp >> DEVINFO_TEMPERATURE_CALTEMP_INTEGER_SHIFT;
|
||||
#else
|
||||
(void)info;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Reads CHIPREV register.
|
||||
******************************************************************************/
|
||||
uint32_t sl_hal_syscfg_read_chip_rev(void)
|
||||
{
|
||||
#if defined(SL_TRUSTZONE_NONSECURE)
|
||||
return sli_tz_syscfg_read_chiprev_register();
|
||||
#else
|
||||
return SYSCFG->CHIPREV;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief Set SYSTICEXTCLKEN bit in CFGSYSTIC to one.
|
||||
******************************************************************************/
|
||||
void sl_hal_syscfg_set_systicextclken_cfgsystic(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.
|
||||
******************************************************************************/
|
||||
void sl_hal_syscfg_clear_systicextclken_cfgsystic(void)
|
||||
{
|
||||
#if defined(SL_TRUSTZONE_NONSECURE)
|
||||
sli_tz_syscfg_clear_systicextclken_cfgsystic();
|
||||
#else
|
||||
SYSCFG->CFGSYSTIC = (SYSCFG->CFGSYSTIC & ~_SYSCFG_CFGSYSTIC_SYSTICEXTCLKEN_MASK);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__FPU_PRESENT) && (__FPU_PRESENT == 1)
|
||||
/***************************************************************************//**
|
||||
* @brief Set floating point co-processor (FPU) access mode.
|
||||
******************************************************************************/
|
||||
void sl_hal_system_fpu_set_access_mode(sl_hal_system_fpu_access_t access_mode)
|
||||
{
|
||||
SCB->CPACR = (SCB->CPACR & ~(0xFUL << 20)) | access_mode;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Get the ADC calibration info.
|
||||
******************************************************************************/
|
||||
void sl_hal_system_get_adc_calibration_info(sl_hal_system_devinfo_adc_t *info)
|
||||
{
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
|
||||
sl_status_t status;
|
||||
sl_se_command_context_t se_command_ctx;
|
||||
sli_se_device_data_t otp_section_id = (sli_se_device_data_t)(SLI_SE_DEVICE_DATA_DI0 + DEVINFO_GP_FRAGMENT_INDEX);
|
||||
uint32_t offset = DEVINFO_GP_ADC0CALDATA_OFFSET;
|
||||
EFM_ASSERT(info != NULL);
|
||||
|
||||
// Initialize command context
|
||||
status = sl_se_init_command_context(&se_command_ctx);
|
||||
if (status != SL_STATUS_OK) {
|
||||
*info = SL_HAL_SYSTEM_DEVINFO_ADC_RESET_VALUES;
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the SE command to retrieve the ADC calibration from the DEVINFO OTP section
|
||||
status = sli_se_device_data_read_chunk(&se_command_ctx,
|
||||
otp_section_id,
|
||||
offset,
|
||||
sizeof(sl_hal_system_devinfo_adc_offset_t),
|
||||
info);
|
||||
if (status != SL_STATUS_OK) {
|
||||
*info = SL_HAL_SYSTEM_DEVINFO_ADC_RESET_VALUES;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
*info = SL_HAL_SYSTEM_DEVINFO_ADC_RESET_VALUES;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} (end addtogroup system) */
|
||||
Reference in New Issue
Block a user