Initial commit of firmware
This commit is contained in:
661
Libs/platform/service/clock_manager/inc/sl_clock_manager.h
Normal file
661
Libs/platform/service/clock_manager/inc/sl_clock_manager.h
Normal file
@@ -0,0 +1,661 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Clock Manager APIs.
|
||||
*******************************************************************************
|
||||
* # 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_CLOCK_MANAGER_H
|
||||
#define SL_CLOCK_MANAGER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "sl_status.h"
|
||||
#include "sl_enum.h"
|
||||
#include "sl_device_clock.h"
|
||||
#include "sl_code_classification.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup clock_manager Clock Manager
|
||||
*
|
||||
* @details
|
||||
* ## Overview
|
||||
*
|
||||
* Clock Manager is a platform-level software module that manages
|
||||
* the device's oscillators and clock tree.
|
||||
* The Clock Manager module is split into two main parts: The Initialization part
|
||||
* and the Runtime part. The runtime part has its component
|
||||
* \a clock_manager_runtime and can be used independently from the initialization
|
||||
* part. The \a clock_manager component includes both the initialization part and the
|
||||
* runtime part and it should be the component added to your project slcp file.
|
||||
*
|
||||
* ## Initialization
|
||||
* The initialization part includes the configuration files
|
||||
* \a sl_clock_manager_oscillator_config.h and \a sl_clock_manager_tree_config.h.
|
||||
* As their name indicates, those C header files are used to configure the different
|
||||
* device oscillators and the device clock tree. Those header files use the CMSIS
|
||||
* Configuration Wizard Annotations and are specific to each device.
|
||||
* The API function sl_clock_manager_init() is used to initialize the Clock Manager
|
||||
* module based on the configuration values specified in the two configuration files.
|
||||
* This function must be called early during your initialization sequence.
|
||||
* If the SL System component (@ref system) is used by your application, the
|
||||
* sl_clock_manager_init() call will be added automatically to your initialization
|
||||
* sequence.
|
||||
*
|
||||
* ### Oscillators Configuration
|
||||
* Oscillators' configurations are all grouped in the \a sl_clock_manager_oscillator_config.h
|
||||
* file. Crystal-based oscillators, HFXO and LFXO, have an enable/disable configuration to
|
||||
* indicate if the required crystal is present or not. In the absence of the required
|
||||
* crystal, the configuration must be disabled and the associated oscillator will
|
||||
* not be initialized.
|
||||
*
|
||||
* The HFXO configuration also provides the configuration for the Crystal Sharing
|
||||
* feature when supported by the device. This feature allows to use the dedicated
|
||||
* HFCLKOUT pin to output a sinusoidal clock that can be used as the HFXO
|
||||
* input for another EFR device. In the configuration, you need to specify if your
|
||||
* device is the leader or the follower. The leader will be the one outputting the
|
||||
* clock and the follower, the one receiving the clock signal. In the leader configuration,
|
||||
* the GPIO pin is used to receive the request from the follower. You can refer to your
|
||||
* device datasheet to know the available location for the HFXO BUFOUT_REQ pin.
|
||||
* In the follower mode, the pin configuration can be used to send an HFXO request
|
||||
* signal to the leader. The "High Frequency Clock Ouput" section of your device
|
||||
* reference manual also provides more details about this feature.
|
||||
*
|
||||
* The first HFRCO module, whose output clock is called HFRCODPLL, can be connected to
|
||||
* the DPLL module to have a better precision clock. When the DPLL is enabled through
|
||||
* the configuration define \a SL_CLOCK_MANAGER_HFRCO_DPLL_EN, the DPLL settings
|
||||
* take precedence over the HFRCO band configuration.
|
||||
*
|
||||
* ### Clock Tree Configuration
|
||||
* The device clock tree configurations are all grouped in the
|
||||
* \a sl_clock_manager_tree_config.h file. Refer to your device's reference manual for
|
||||
* the clock tree diagram and see which peripherals are connected to which clock branches.
|
||||
* In the configuration file, each clock branch can be independently configured.
|
||||
* However, to facilitate the clock setup for users, two additional configurations
|
||||
* were added: \a SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE and
|
||||
* \a SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE. Those configurations allow the selection
|
||||
* of the default high-frequency and low-frequency oscillators to be used inside the clock
|
||||
* tree. Every clock branch that can benefit from those default selections will use them
|
||||
* by default.
|
||||
* On certain devices, the @ref power_manager module offers an Execution Modes feature
|
||||
* with the \a SL_POWER_MANAGER_EXECUTION_MODES_FEATURE_EN configuration. When this feature
|
||||
* is enabled, the \a SL_CLOCK_MANAGER_SYSCLK_SOURCE configuration could be overriden by the
|
||||
* Execution Modes feature. Refer to the description of \a SL_CLOCK_MANAGER_SYSCLK_SOURCE in
|
||||
* \a sl_clock_manager_tree_config.h file to know if this is the case.
|
||||
*
|
||||
* Some peripherals have an internal clock divider. Those are not handled by the
|
||||
* Clock Manager configuration. The peripheral driver will usually expose the divider
|
||||
* configuration when such a divider is present inside the peripheral module.
|
||||
*
|
||||
* The Clock tree configuration is available at compile-time only. The Clock Manager
|
||||
* module does not offer API functions to manipulate the clock tree at runtime.
|
||||
*
|
||||
* The more oscillators are used by different clock branches the more power
|
||||
* consumption you will have. To limit your power consumption, you can try to limit the
|
||||
* number of oscillators used. So for example, only use one High-frequency oscillator
|
||||
* and one Low-frequency oscillator across the clock tree. However, if the
|
||||
* application is radio-based, the HFXO oscillator is mandatory for the Radio
|
||||
* clock branch and if the Radio clock branch is connected to the SYSCLK branch,
|
||||
* this will limit you to use HFXO for SYSCLK as well. In this specific case, SYSCLK
|
||||
* could also be configured to use HFRCO with DPLL, but the chosen frequency must be two
|
||||
* times the HFXO frequency so that the Radio module can retrieve the HF crystal frequency
|
||||
* with its divider. This will also come with an increase in power consumption since both
|
||||
* HFXO and HFRCO oscillators will be used. Refer to your device reference manual to know
|
||||
* if your Radio clock is connected to the SYSCLK clock branch or not.
|
||||
*
|
||||
* @note The Clock Manager Initialization is incompatible with the \a device_init_clocks
|
||||
* (@ref device_init_clocks), \a device_init_hfxo (@ref device_init_hfxo),
|
||||
* \a device_init_hfrco (@ref device_init_hfrco) \a device_init_dpll (@ref device_init_dpll),
|
||||
* \a device_init_rffpll (@ref device_init_rffpll), \a device_init_usbpll (@ref device_init_usbpll),
|
||||
* \a device_init_lfxo (@ref device_init_lfxo) and \a device_init_lfrco (@ref device_init_lfrco)
|
||||
* components.
|
||||
* This does not mean that the \a device_init component (@ref device_init) is incompatible with the
|
||||
* \a clock_manager component. The \a device_init component can pull other initialization
|
||||
* modules like EMU and DCDC that are not related to clocks. Therefore, both
|
||||
* \a device_init and \a clock_manager should be present in your project file. SLC will
|
||||
* take care of pulling only the sub \a device_init_xxx components that are needed.
|
||||
*
|
||||
* The runtime part, which is associated with the \a clock_manager_runtime component,
|
||||
* has also an initialization function of its own, sl_clock_manager_runtime_init().
|
||||
* This function must also be part of the initialization sequence. If the SL System
|
||||
* component (@ref system) is used by your application, the
|
||||
* sl_clock_manager_runtime_init() call will be added automatically to your
|
||||
* initialization sequence.
|
||||
*
|
||||
* ## Functionalities
|
||||
* The Runtime part includes functionalities related to oscillators, clock tree
|
||||
* and the CMU hardware module features. The main functionalities are:
|
||||
* - Retrieving the frequency or precision of an oscillator or clock branch
|
||||
* - Enabling/Disabling modules' bus clock
|
||||
* - Retrieving or setting calibration values for oscillators
|
||||
* - Exporting clocks to GPIO
|
||||
* - Starting an RCO Calibration process based on a reference clock source
|
||||
*
|
||||
* ### Retrieve the frequency or precision of an oscillator or clock branch
|
||||
* API functions sl_clock_manager_get_oscillator_frequency() and
|
||||
* sl_clock_manager_get_oscillator_precision() allow retrieving respectively
|
||||
* the frequency and precision of a given oscillator. Similar functions
|
||||
* exist for clock branches: sl_clock_manager_get_clock_branch_frequency() and
|
||||
* sl_clock_manager_get_clock_branch_precision().
|
||||
*
|
||||
* To retrieve the frequency or precision of a specific peripheral, you will
|
||||
* first need to retrieve to which clock branch this peripheral is connected.
|
||||
* To do so, the Device Manager and its @ref device_peripheral
|
||||
* can be used. The below code example shows how to retrieve the clock branch
|
||||
* of the TIMER0 peripheral.
|
||||
*
|
||||
* @code{.c}
|
||||
* #include "sl_clock_manager.h"
|
||||
* #include "sl_device_peripheral.h"
|
||||
*
|
||||
* sl_status_t status;
|
||||
* uint32_t freq;
|
||||
* sl_clock_branch_t clock_branch;
|
||||
*
|
||||
* clock_branch = sl_device_peripheral_get_clock_branch(SL_PERIPHERAL_TIMER0);
|
||||
* status = sl_clock_manager_get_clock_branch_frequency(clock_branch, &freq);
|
||||
* @endcode
|
||||
*
|
||||
* ### Enable/Disable modules' bus clock
|
||||
* Before accessing a peripheral's register interface, its bus clock must be enabled,
|
||||
* or else a bus fault exception will be triggered. API functions
|
||||
* sl_clock_manager_enable_bus_clock() and sl_clock_manager_disable_bus_clock()
|
||||
* allow to perform such operations.
|
||||
*
|
||||
* Note that the peripheral clock will automatically be enabled when a peripheral
|
||||
* is enabled with the clock on-demand feature.
|
||||
*
|
||||
* ### Oscillator Calibration
|
||||
* The Clock Manager initialization, if present, will calibrate the different
|
||||
* oscillators during the initialization sequence, but sometimes calibration
|
||||
* values must be updated during runtime in certain conditions, for example, if
|
||||
* the device temperature changes too much. This is considered an advanced
|
||||
* functionality and users must be careful as to when to use this functionality.
|
||||
*
|
||||
* API functions sl_clock_manager_set_rc_oscillator_calibration() and
|
||||
* sl_clock_manager_get_rc_oscillator_calibration() allow to set or get the
|
||||
* CAL register of HFRCO and LFRCO oscillators. Not all devices have an LFRCO
|
||||
* module with a CAL register. Some LFRCO modules will have a high-precision
|
||||
* configuration allowing to use the HFXO to auto-calibrate the LFRCO. Refer
|
||||
* to your device reference manual to retrieve oscillator specifications.
|
||||
*
|
||||
* API functions sl_clock_manager_set_hfxo_calibration() and
|
||||
* sl_clock_manager_get_hfxo_calibration() allow to set or get the \a COREBIASANA
|
||||
* inside the HFXO \a XTALCTRL register. The HFXO module has a Core Bias Optimization
|
||||
* stage at the end of the oscillator startup sequence that allows to further
|
||||
* optimize current consumption. This optimization will automatically set the
|
||||
* \a COREBIASANA bitfield when finished. Upon reset, this optimization will run
|
||||
* the first time HFXO is started and afterwards, the \a XTALCTRL->SKIPCOREBIASOPT
|
||||
* bit will automatically be set so that next time HFXO is started during the
|
||||
* application lifetime, the optimization stage will be skipped. This optimization
|
||||
* stage takes a while to run, in the order of hundreds of milliseconds, therefore
|
||||
* we don't want it to run each time HFXO is started.
|
||||
* With the function sl_clock_manager_set_hfxo_calibration() it is possible to
|
||||
* manually set the \a COREBIASANA bitfield and set the \a SKIPCOREBIASOPT bit.
|
||||
* This function will usually be used in the context of an EM4 wake-up where to
|
||||
* save on the initialization sequence time, we want to skip the Core Bias Optimization
|
||||
* stage and manually set the value that would have previously been retrieved with
|
||||
* sl_clock_manager_get_hfxo_calibration() and saved in an EM4 retained memory.
|
||||
* In this context, sl_clock_manager_set_hfxo_calibration() will need to be called
|
||||
* early in the initialization sequence, before the usual clock initialization
|
||||
* function.
|
||||
*
|
||||
* slx_clock_manager_hfxo_set_ctune(), slx_clock_manager_hfxo_get_ctune() and
|
||||
* slx_clock_manager_hfxo_calibrate_ctune() functions allow to manipulate the
|
||||
* HFXO tuning capacitances. Changing the CTUNE value while HFXO is running
|
||||
* can result in significant clock glitches for one clock period. Therefore,
|
||||
* those functions should be used with caution. The difference between the
|
||||
* slx_clock_manager_hfxo_set_ctune() and slx_clock_manager_hfxo_calibrate_ctune()
|
||||
* functions is that the calibration one will also start and wait for the HFXO
|
||||
* Core Bias Optimization stage to complete.
|
||||
*
|
||||
* API functions sl_clock_manager_set_lfxo_calibration() and
|
||||
* sl_clock_manager_get_lfxo_calibration() allow to set and get the LFXO CTUNE
|
||||
* value.
|
||||
*
|
||||
* ### Export clocks to GPIO
|
||||
* The CMU module offers the functionality to export a given clock source to a
|
||||
* GPIO pin. Refer to function sl_clock_manager_set_gpio_clock_output() for more
|
||||
* details and the #sl_clock_manager_export_clock_source_t enum for a list of
|
||||
* acceptable clock sources. Note that there is a specific clock branch named
|
||||
* EXPCLK that is usually connected to the SYSCLK and offers an additional divider.
|
||||
*
|
||||
* ### RCO Calibration
|
||||
* The CMU module also offers RCO Calibration hardware support. This can be
|
||||
* used to calibrate at runtime HFRCO and LFRCO oscillators using a high-precision
|
||||
* reference clock. Refer to your device reference manual for more
|
||||
* details about this functionality. API function
|
||||
* sl_clock_manager_configure_rco_calibration() can be used to configure the
|
||||
* calibration process. Then sl_clock_manager_start_rco_calibration() and
|
||||
* sl_clock_manager_stop_rco_calibration() can be called to start/stop the
|
||||
* process. sl_clock_manager_wait_rco_calibration() function can be called to
|
||||
* actively wait for the process to finish. And finally,
|
||||
* sl_clock_manager_get_rco_calibration_count() can be called to retrieve the
|
||||
* calibration process result.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/// Export clock source.
|
||||
/// This is to be used with the sl_clock_manager_set_gpio_clock_output() API function.
|
||||
SL_ENUM(sl_clock_manager_export_clock_source_t) {
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_DISABLED, ///< Export Clock Source Disabled
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_FSRCO, ///< Export Clock Source FSRCO
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_HFXO, ///< Export Clock Source HFXO
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_HFRCODPLL, ///< Export Clock Source HFRCODPLL
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_HFRCOEM23, ///< Export Clock Source HFRCOEM23
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_HFEXPCLK, ///< Export Clock Source HFEXPCLK
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_LFXO, ///< Export Clock Source LFXO
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_PLFRCO, ///< Export Clock Source PLFRCO
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_LFRCO, ///< Export Clock Source LFRCO
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_ULFRCO, ///< Export Clock Source ULFRCO
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_SOURCE_HCLK, ///< Export Clock Source HCLK
|
||||
};
|
||||
|
||||
/// Export clock output selection.
|
||||
/// This is to be used with the sl_clock_manager_set_gpio_clock_output() API function.
|
||||
SL_ENUM(sl_clock_manager_export_clock_output_select_t) {
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_OUTPUT_SELECT_0 = 0, ///< Export Clock Output #0
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_OUTPUT_SELECT_1, ///< Export Clock Output #1
|
||||
SL_CLOCK_MANAGER_EXPORT_CLOCK_OUTPUT_SELECT_2, ///< Export Clock Output #2
|
||||
};
|
||||
|
||||
/// Clocks available for Calibration.
|
||||
/// This is to be used with the sl_clock_manager_configure_rco_calibration() API function.
|
||||
SL_ENUM(sl_clock_manager_clock_calibration_t) {
|
||||
SL_CLOCK_MANAGER_CLOCK_CALIBRATION_HCLK, ///< Clock Calibration HCLK
|
||||
SL_CLOCK_MANAGER_CLOCK_CALIBRATION_PRS, ///< Clock Calibration PRS
|
||||
SL_CLOCK_MANAGER_CLOCK_CALIBRATION_HFXO, ///< Clock Calibration HFXO
|
||||
SL_CLOCK_MANAGER_CLOCK_CALIBRATION_LFXO, ///< Clock Calibration LFXO
|
||||
SL_CLOCK_MANAGER_CLOCK_CALIBRATION_HFRCODPLL, ///< Clock Calibration HFRCODPLL
|
||||
SL_CLOCK_MANAGER_CLOCK_CALIBRATION_HFRCOEM23, ///< Clock Calibration HFRCOEM23
|
||||
SL_CLOCK_MANAGER_CLOCK_CALIBRATION_FSRCO, ///< Clock Calibration FSRCO
|
||||
SL_CLOCK_MANAGER_CLOCK_CALIBRATION_LFRCO, ///< Clock Calibration LFRCO
|
||||
SL_CLOCK_MANAGER_CLOCK_CALIBRATION_ULFRCO ///< Clock Calibration ULFRCO
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* Performs Clock Manager runtime initialization.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_runtime_init(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets frequency of given oscillator.
|
||||
*
|
||||
* @param[in] oscillator Oscillator
|
||||
*
|
||||
* @param[out] frequency Oscillator's frequency in Hertz
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sl_clock_manager_get_oscillator_frequency(sl_oscillator_t oscillator,
|
||||
uint32_t *frequency);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets precision of given oscillator.
|
||||
*
|
||||
* @param[in] oscillator Oscillator
|
||||
*
|
||||
* @param[out] precision Oscillator's precision in PPM
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_oscillator_precision(sl_oscillator_t oscillator,
|
||||
uint16_t *precision);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets frequency of given clock branch.
|
||||
*
|
||||
* @param[in] clock_branch Clock Branch
|
||||
*
|
||||
* @param[out] frequency Clock Branch's frequency in Hertz
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sl_clock_manager_get_clock_branch_frequency(sl_clock_branch_t clock_branch,
|
||||
uint32_t *frequency);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets precision of given clock branch.
|
||||
*
|
||||
* @param[in] clock_branch Clock Branch
|
||||
*
|
||||
* @param[out] precision Clock Branch's precision in PPM
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_clock_branch_precision(sl_clock_branch_t clock_branch,
|
||||
uint16_t *precision);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enables the given module's bus clock.
|
||||
*
|
||||
* @param[in] module_bus_clock module's bus clock to enable.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
*
|
||||
* @note modules' bus clocks are defined in the
|
||||
* @ref device_clock in the Bus Clock Defines section.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_enable_bus_clock(sl_bus_clock_t module_bus_clock);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Disables the given module's bus clock.
|
||||
*
|
||||
* @param[in] module_bus_clock module's bus clock to disable.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
*
|
||||
* @note modules' bus clocks are defined in the
|
||||
* @ref device_clock in the Bus Clock Defines section.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_disable_bus_clock(sl_bus_clock_t module_bus_clock);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configures one clock export output with specified clock source.
|
||||
*
|
||||
* @param[in] export_clock_source One of the exportable clock source.
|
||||
*
|
||||
* @param[in] output_select Selected export clock output channel.
|
||||
*
|
||||
* @param[in] hfexp_divider HFEXP clock divider (1 to 32).
|
||||
* Note: This parameter only affects the EXPCLK
|
||||
* branch frequency.
|
||||
*
|
||||
* @param[in] port GPIO port to output exported clock.
|
||||
*
|
||||
* @param[in] pin GPIO pin number to output exported clock.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_set_gpio_clock_output(sl_clock_manager_export_clock_source_t export_clock_source,
|
||||
sl_clock_manager_export_clock_output_select_t output_select,
|
||||
uint16_t hfexp_divider,
|
||||
uint32_t port,
|
||||
uint32_t pin);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the RC oscillator frequency tuning control.
|
||||
*
|
||||
* @param[in] oscillator RC Oscillator to set tuning value for.
|
||||
*
|
||||
* @param[in] val The RC oscillator frequency tuning setting to use.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
*
|
||||
* @note RC Oscillator tuning is done during production, and the tuning value is
|
||||
* loaded after a reset by the Clock Manager initialization code.
|
||||
* Changing the tuning value from the calibrated value is for more advanced
|
||||
* use. Certain oscillators also have build-in tuning optimization.
|
||||
*
|
||||
* @note Supported RC oscillators include:
|
||||
* - SL_OSCILLATOR_HFRCODPLL
|
||||
* - SL_OSCILLATOR_HFRCOEM23
|
||||
* - SL_OSCILLATOR_LFRCO
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_set_rc_oscillator_calibration(sl_oscillator_t oscillator,
|
||||
uint32_t val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the RC oscillator frequency tuning setting.
|
||||
*
|
||||
* @param[in] oscillator An RC oscillator to get tuning value for.
|
||||
*
|
||||
* @param[out] val The RC oscillator frequency tuning setting in use.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
*
|
||||
* @note Supported RC oscillators include:
|
||||
* - SL_OSCILLATOR_HFRCODPLL
|
||||
* - SL_OSCILLATOR_HFRCOEM23
|
||||
* - SL_OSCILLATOR_LFRCO
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_rc_oscillator_calibration(sl_oscillator_t oscillator,
|
||||
uint32_t *val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the HFXO calibration value.
|
||||
*
|
||||
* @param[in] val
|
||||
* The HFXO calibration setting to use.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_set_hfxo_calibration(uint32_t val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the HFXO calibration value.
|
||||
*
|
||||
* @param[out] val The current HFXO calibration value.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_hfxo_calibration(uint32_t *val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the HFXO's CTUNE.
|
||||
*
|
||||
* @param[in] ctune The HFXO's CTUNE value.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
*
|
||||
* @note Sets the XI value to the given ctune value and sets the XO value based
|
||||
* on that same value, but with an offset that is hardware dependent.
|
||||
* Updating CTune while the crystal oscillator is running can
|
||||
* result in significant clock glitches for one XO clock period.
|
||||
* Should be used with caution.
|
||||
******************************************************************************/
|
||||
sl_status_t slx_clock_manager_hfxo_set_ctune(uint32_t ctune);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the HFXO's CTUNE.
|
||||
*
|
||||
* @param[out] ctune The returned HFXO's CTUNE value.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
*
|
||||
* @note This function only returns the CTUNE XI value.
|
||||
* The XO value follows the XI value with a fixed delta that is
|
||||
* hardware dependent.
|
||||
******************************************************************************/
|
||||
sl_status_t slx_clock_manager_hfxo_get_ctune(uint32_t *ctune);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Updates the tuning capacitances and calibrate the Core Bias Current.
|
||||
*
|
||||
* @param[in] ctune The HFXO's CTUNE value.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
*
|
||||
* @note Calibrating the CTUNE is time consuming and will cause glitches on the
|
||||
* HFXO's clock. Care and caution should be taken when using this API.
|
||||
******************************************************************************/
|
||||
sl_status_t slx_clock_manager_hfxo_calibrate_ctune(uint32_t ctune);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the LFXO frequency tuning control.
|
||||
*
|
||||
* @param[in] val The LFXO frequency tuning setting to use.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_set_lfxo_calibration(uint32_t val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the LFXO frequency tuning setting.
|
||||
*
|
||||
* @param[out] val The LFXO frequency tuning setting to use.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_lfxo_calibration(uint32_t *val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configures the RCO calibration.
|
||||
*
|
||||
* @param[in] cycles Number of cycles to run calibration. Increasing this
|
||||
* number increases precision, but the calibration will
|
||||
* take more time.
|
||||
*
|
||||
* @param[in] down_counter_selection
|
||||
* The clock which will be counted down cycles.
|
||||
*
|
||||
* @param[in] up_counter_selection
|
||||
* The number of cycles generated by this clock will be counted and
|
||||
* added up, the result can be given with
|
||||
* sl_clock_manager_get_rco_calibration_count().
|
||||
*
|
||||
* @param[in] continuous_calibration
|
||||
* Flag when true configures continuous calibration.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
*
|
||||
* @note RCO calibration related functions are not thread-safe and should
|
||||
* therefore not be called across multiple tasks.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_configure_rco_calibration(uint32_t cycles,
|
||||
sl_clock_manager_clock_calibration_t down_counter_selection,
|
||||
sl_clock_manager_clock_calibration_t up_counter_selection,
|
||||
bool continuous_calibration);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Starts the RCO calibration.
|
||||
*
|
||||
* @note RCO calibration related functions are not thread-safe and should
|
||||
* therefore not be called across multiple tasks.
|
||||
******************************************************************************/
|
||||
void sl_clock_manager_start_rco_calibration(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Stops the RCO calibration.
|
||||
*
|
||||
* @note RCO calibration related functions are not thread-safe and should
|
||||
* therefore not be called across multiple tasks.
|
||||
******************************************************************************/
|
||||
void sl_clock_manager_stop_rco_calibration(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Waits for the RCO calibration to finish.
|
||||
*
|
||||
* @note RCO calibration related functions are not thread-safe and should
|
||||
* therefore not be called across multiple tasks.
|
||||
******************************************************************************/
|
||||
void sl_clock_manager_wait_rco_calibration(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets calibration count value, returns the value of the up counter.
|
||||
*
|
||||
* @param[out] count Calibration count value.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
*
|
||||
* @note RCO calibration related functions are not thread-safe and should
|
||||
* therefore not be called across multiple tasks.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_rco_calibration_count(uint32_t *count);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Waits for USBPLL clock to be ready.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_wait_usbpll(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* When this callback function is called, it means that HFXO failed twice in
|
||||
* a row to start with normal configurations. This may mean that there is a
|
||||
* bad crystal. When getting this callback, HFXO is running but its properties
|
||||
* (frequency, precision) are not guaranteed. This should be considered as an
|
||||
* error situation.
|
||||
*
|
||||
* @note This callback will be called only when the
|
||||
* SL_CLOCK_MANAGER_HFXO_SLEEPY_CRYSTAL_SUPPORT config is enabled
|
||||
******************************************************************************/
|
||||
void sl_clock_manager_hfxo_notify_consecutive_failed_startups(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the external FLASH reference clock.
|
||||
*
|
||||
* @param[in] oscillator Oscillator used to clock the external FLASH.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
*
|
||||
* @note This API is not thread-safe and should therefore not be called
|
||||
* across multiple tasks.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sl_clock_manager_set_ext_flash_clk(sl_oscillator_t oscillator);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the external FLASH clock source.
|
||||
*
|
||||
* @param[out] oscillator Oscillator used to clock the external FLASH.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sl_clock_manager_get_ext_flash_clk(sl_oscillator_t *oscillator);
|
||||
|
||||
/** @} (end addtogroup clock_manager) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_CLOCK_MANAGER_H
|
||||
@@ -0,0 +1,62 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Clock Manager Init APIs.
|
||||
*******************************************************************************
|
||||
* # 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_CLOCK_MANAGER_INIT_H
|
||||
#define SL_CLOCK_MANAGER_INIT_H
|
||||
|
||||
#include "sl_status.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup clock_manager Clock Manager
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initializes Oscillators and Clock branches.
|
||||
*
|
||||
* @return Status code.
|
||||
* SL_STATUS_OK if successful. Error code otherwise.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_init(void);
|
||||
|
||||
/** @} (end addtogroup clock_manager) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_CLOCK_MANAGER_INIT_H
|
||||
64
Libs/platform/service/clock_manager/inc/sli_clock_manager.h
Normal file
64
Libs/platform/service/clock_manager/inc/sli_clock_manager.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Clock Manager Private API definition.
|
||||
*******************************************************************************
|
||||
* # 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 SLI_CLOCK_MANAGER_H
|
||||
#define SLI_CLOCK_MANAGER_H
|
||||
|
||||
#include "sl_clock_manager.h"
|
||||
#include "sl_status.h"
|
||||
#include "sl_compiler.h"
|
||||
#include "sl_code_classification.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set SYSCLK clock source.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_clock_manager_set_sysclk_source(sl_oscillator_t source);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get SYSCLK clock source.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_clock_manager_get_sysclk_source(sl_oscillator_t *source);
|
||||
|
||||
/***************************************************************************//**
|
||||
* When this callback function is called, it means that HFXO is ready.
|
||||
******************************************************************************/
|
||||
__WEAK void sli_clock_manager_notify_hfxo_ready(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SLI_CLOCK_MANAGER_H
|
||||
313
Libs/platform/service/clock_manager/src/sl_clock_manager.c
Normal file
313
Libs/platform/service/clock_manager/src/sl_clock_manager.c
Normal file
@@ -0,0 +1,313 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Clock Manager API implementations.
|
||||
*******************************************************************************
|
||||
* # 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 "sli_clock_manager.h"
|
||||
#include "sl_clock_manager.h"
|
||||
#include "sli_clock_manager.h"
|
||||
#include "sli_clock_manager_hal.h"
|
||||
#include "sl_assert.h"
|
||||
#include "cmsis_compiler.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* Performs Clock Manager runtime initialization.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_runtime_init(void)
|
||||
{
|
||||
return sli_clock_manager_hal_runtime_init();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets frequency of given oscillator.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_oscillator_frequency(sl_oscillator_t oscillator,
|
||||
uint32_t *frequency)
|
||||
{
|
||||
if (frequency == NULL) {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
|
||||
return sli_clock_manager_hal_get_oscillator_frequency(oscillator, frequency);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets precision of given oscillator.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_oscillator_precision(sl_oscillator_t oscillator,
|
||||
uint16_t *precision)
|
||||
{
|
||||
if (precision == NULL) {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
|
||||
return sli_clock_manager_hal_get_oscillator_precision(oscillator, precision);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets frequency of given clock branch.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_clock_branch_frequency(sl_clock_branch_t clock_branch,
|
||||
uint32_t *frequency)
|
||||
{
|
||||
if (frequency == NULL) {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
|
||||
return sli_clock_manager_hal_get_clock_branch_frequency(clock_branch, frequency);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets precision of given clock branch.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_clock_branch_precision(sl_clock_branch_t clock_branch,
|
||||
uint16_t *precision)
|
||||
{
|
||||
if (precision == NULL) {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
|
||||
return sli_clock_manager_hal_get_clock_branch_precision(clock_branch, precision);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enables the given module's bus clock.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_enable_bus_clock(sl_bus_clock_t module_bus_clock)
|
||||
{
|
||||
return sli_clock_manager_hal_enable_bus_clock(module_bus_clock, true);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Disables the given module's bus clock.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_disable_bus_clock(sl_bus_clock_t module_bus_clock)
|
||||
{
|
||||
return sli_clock_manager_hal_enable_bus_clock(module_bus_clock, false);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configures one clock export output with specified clock source.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_set_gpio_clock_output(sl_clock_manager_export_clock_source_t export_clock_source,
|
||||
sl_clock_manager_export_clock_output_select_t output_select,
|
||||
uint16_t hfexp_divider,
|
||||
uint32_t port,
|
||||
uint32_t pin)
|
||||
{
|
||||
return sli_clock_manager_hal_set_gpio_clock_output(export_clock_source, output_select, hfexp_divider, port, pin);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the RC oscillator frequency tuning control.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_set_rc_oscillator_calibration(sl_oscillator_t oscillator,
|
||||
uint32_t val)
|
||||
{
|
||||
return sli_clock_manager_hal_set_rc_oscillator_calibration(oscillator, val);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the RC oscillator frequency tuning setting.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_rc_oscillator_calibration(sl_oscillator_t oscillator,
|
||||
uint32_t *val)
|
||||
{
|
||||
if (val == NULL) {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
return sli_clock_manager_hal_get_rc_oscillator_calibration(oscillator, val);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the HFXO calibration value.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_set_hfxo_calibration(uint32_t val)
|
||||
{
|
||||
return sli_clock_manager_hal_set_hfxo_calibration(val);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the HFXO calibration value.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_hfxo_calibration(uint32_t *val)
|
||||
{
|
||||
if (val == NULL) {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
return sli_clock_manager_hal_get_hfxo_calibration(val);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the HFXO CTUNE setting.
|
||||
******************************************************************************/
|
||||
sl_status_t slx_clock_manager_hfxo_set_ctune(uint32_t ctune)
|
||||
{
|
||||
return sli_clock_manager_hal_hfxo_set_ctune(ctune);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the HFXO CTUNE setting.
|
||||
******************************************************************************/
|
||||
sl_status_t slx_clock_manager_hfxo_get_ctune(uint32_t *ctune)
|
||||
{
|
||||
if (ctune == NULL) {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
return sli_clock_manager_hal_hfxo_get_ctune(ctune);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Updates the tuning capacitances and calibrate the Core Bias Current.
|
||||
******************************************************************************/
|
||||
sl_status_t slx_clock_manager_hfxo_calibrate_ctune(uint32_t ctune)
|
||||
{
|
||||
return sli_clock_manager_hal_hfxo_calibrate_ctune(ctune);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the LFXO frequency tuning control.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_set_lfxo_calibration(uint32_t val)
|
||||
{
|
||||
return sli_clock_manager_hal_set_lfxo_calibration(val);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the LFXO frequency tuning setting.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_lfxo_calibration(uint32_t *val)
|
||||
{
|
||||
if (val == NULL) {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
return sli_clock_manager_hal_get_lfxo_calibration(val);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configures the RCO calibration.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_configure_rco_calibration(uint32_t cycles,
|
||||
sl_clock_manager_clock_calibration_t down_counter_selection,
|
||||
sl_clock_manager_clock_calibration_t up_counter_selection,
|
||||
bool continuous_calibration)
|
||||
{
|
||||
return sli_clock_manager_hal_configure_rco_calibration(cycles, down_counter_selection, up_counter_selection, continuous_calibration);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Starts the RCO calibration.
|
||||
******************************************************************************/
|
||||
void sl_clock_manager_start_rco_calibration(void)
|
||||
{
|
||||
sli_clock_manager_hal_start_rco_calibration();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Stops the RCO calibration.
|
||||
******************************************************************************/
|
||||
void sl_clock_manager_stop_rco_calibration(void)
|
||||
{
|
||||
sli_clock_manager_hal_stop_rco_calibration();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Waits for the RCO calibration to finish.
|
||||
******************************************************************************/
|
||||
void sl_clock_manager_wait_rco_calibration(void)
|
||||
{
|
||||
sli_clock_manager_hal_wait_rco_calibration();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets calibration count value.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_rco_calibration_count(uint32_t *count)
|
||||
{
|
||||
if (count == NULL) {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
|
||||
return sli_clock_manager_hal_get_rco_calibration_count(count);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets SYSCLK clock source.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_set_sysclk_source(sl_oscillator_t source)
|
||||
{
|
||||
return sli_clock_manager_hal_set_sysclk_source(source);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets SYSCLK clock source.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_get_sysclk_source(sl_oscillator_t *source)
|
||||
{
|
||||
if (source == NULL) {
|
||||
return SL_STATUS_NULL_POINTER;
|
||||
}
|
||||
|
||||
return sli_clock_manager_hal_get_sysclk_source(source);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Waits for USBPLL clock to be ready.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_wait_usbpll(void)
|
||||
{
|
||||
return sli_clock_manager_hal_wait_usbpll();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* When this callback function is called, it means that HFXO failed twice in
|
||||
* a row to start with normal configurations. This may mean that there is a
|
||||
* bad crystal. When getting this callback, HFXO is running but its properties
|
||||
* (frequency, precision) are not guaranteed. This should be considered as an
|
||||
* error situation.
|
||||
******************************************************************************/
|
||||
__WEAK void sl_clock_manager_hfxo_notify_consecutive_failed_startups(void)
|
||||
{
|
||||
EFM_ASSERT(false);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the external FLASH reference clock.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_set_ext_flash_clk(sl_oscillator_t oscillator)
|
||||
{
|
||||
return sli_clock_manager_hal_set_ext_flash_clk(oscillator);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the external FLASH clock source.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_get_ext_flash_clk(sl_oscillator_t *oscillator)
|
||||
{
|
||||
return sli_clock_manager_hal_get_ext_flash_clk(oscillator);
|
||||
}
|
||||
1040
Libs/platform/service/clock_manager/src/sl_clock_manager_hal_s2.c
Normal file
1040
Libs/platform/service/clock_manager/src/sl_clock_manager_hal_s2.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Clock Manager Init API implementations.
|
||||
*******************************************************************************
|
||||
* # 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_clock_manager_init.h"
|
||||
#include "sli_clock_manager_init_hal.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initializes Oscillators and Clock branches.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_clock_manager_init(void)
|
||||
{
|
||||
return sli_clock_manager_hal_init();
|
||||
}
|
||||
@@ -0,0 +1,886 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Clock Manager Init HAL API implementations.
|
||||
*******************************************************************************
|
||||
* # 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_clock_manager_oscillator_config.h"
|
||||
#include "sl_clock_manager_tree_config.h"
|
||||
#include "sli_clock_manager_init_hal.h"
|
||||
#include "sl_clock_manager.h"
|
||||
#include "sl_status.h"
|
||||
#include "sl_assert.h"
|
||||
#include "em_device.h"
|
||||
#include "em_cmu.h"
|
||||
#include "sl_gpio.h"
|
||||
|
||||
#if defined(SLI_CLOCK_MANAGER_RUNTIME_CONFIGURATION)
|
||||
#include "sli_clock_manager_runtime_configuration.h"
|
||||
#endif
|
||||
|
||||
#if defined(RFFPLL_PRESENT)
|
||||
#if defined(SL_CLOCK_MANAGER_RFFPLL_BAND) && (SL_CLOCK_MANAGER_RFFPLL_BAND == 7)
|
||||
#ifdef SL_CLOCK_MANAGER_AUTO_BAND_VALID
|
||||
#include "rail_config.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
// Fetch HFXO CTUNE value from USERDATA page as a manufacturing token
|
||||
#define MFG_CTUNE_HFXO_ADDR 0x0FE00100UL
|
||||
#define MFG_CTUNE_HFXO_VAL (*((uint16_t *) (MFG_CTUNE_HFXO_ADDR)))
|
||||
|
||||
// Fetch LFXO CTUNE value from USERDATA page as a manufacturing token
|
||||
#define MFG_CTUNE_LFXO_ADDR 0x0FE0009CUL
|
||||
#define MFG_CTUNE_LFXO_VAL (*((uint8_t *) (MFG_CTUNE_LFXO_ADDR)))
|
||||
|
||||
#if defined(RFFPLL_PRESENT)
|
||||
// If RADIO_CONFIG_RFFPLL_CONFIG_PRESENT is not defined, either there is no
|
||||
// radio configuration in the project or the radio configuration that is
|
||||
// present does not include an RFFPLL configuration.
|
||||
// In either case, the Auto-Band feature cannot work, so fall back to the
|
||||
// default band (Band 9xx).
|
||||
#if defined(SL_CLOCK_MANAGER_RFFPLL_BAND) && (SL_CLOCK_MANAGER_RFFPLL_BAND == 7)
|
||||
#ifndef RADIO_CONFIG_RFFPLL_CONFIG_PRESENT
|
||||
#undef SL_CLOCK_MANAGER_RFFPLL_BAND
|
||||
#define SL_CLOCK_MANAGER_RFFPLL_BAND 6
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Allocated PRS channel for crystal sharing
|
||||
#if defined(_HFXO_CTRL_PRSSTATUSSEL0_MASK)
|
||||
#define HFXO_CRYSTSAL_SHARING_PRS_CHANNEL 0
|
||||
#endif
|
||||
|
||||
#if defined(SLI_CLOCK_MANAGER_RUNTIME_CONFIGURATION)
|
||||
#define FUNCTION_SCOPE
|
||||
#else
|
||||
#define FUNCTION_SCOPE static
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** TYPEDEFS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(RFFPLL_PRESENT)
|
||||
typedef struct {
|
||||
uint32_t frequency; // Host target frequency.
|
||||
uint8_t divider_y; // Divider Y for digital.
|
||||
uint8_t divider_x; // Divider X for Radio.
|
||||
uint8_t divider_n; // Feedback divider N.
|
||||
} clock_manager_rffpll_config_t;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(RFFPLL_PRESENT) \
|
||||
&& defined(SL_CLOCK_MANAGER_HFXO_EN) && (SL_CLOCK_MANAGER_HFXO_EN == 1) \
|
||||
&& (SL_CLOCK_MANAGER_RFFPLL_CUSTOM_BAND == 0) \
|
||||
&& !((SL_CLOCK_MANAGER_RFFPLL_BAND == 7) && defined(RADIO_CONFIG_RFFPLL_CONFIG_PRESENT))
|
||||
// Table of possible radio frequency bands and their associated settings.
|
||||
static clock_manager_rffpll_config_t rffpll_band_config_39MHz[] = {
|
||||
{ 97500000, 23, 7, 115 }, // Band 450 MHz
|
||||
{ 98380000, 22, 7, 111 }, // Band 470 MHz
|
||||
{ 97500000, 23, 7, 115 }, // Band 780 MHz
|
||||
{ 97500000, 20, 6, 100 }, // Band 863 MHz
|
||||
{ 97500000, 23, 7, 115 }, // Band 896 MHz
|
||||
{ 96520000, 20, 6, 99 }, // Band 928 MHz
|
||||
{ 97500000, 20, 6, 100 } // Band 9xx MHz (covers from 901 to 928 MHz)
|
||||
};
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL VARIABLES *******************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(SLI_CLOCK_MANAGER_RUNTIME_CONFIGURATION)
|
||||
uint32_t SLI_CLOCK_MANAGER_HFXO_MODE = SL_CLOCK_MANAGER_HFXO_MODE;
|
||||
uint32_t SLI_CLOCK_MANAGER_HFXO_CTUNE_FIXED_STEADY = SLI_CLOCK_MANAGER_HFXO_CTUNE_FIXED_STEADY_DEFAULT;
|
||||
uint32_t SLI_CLOCK_MANAGER_HFRCO_BAND = SL_CLOCK_MANAGER_HFRCO_BAND;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** LOCAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(HFXO_PRESENT) \
|
||||
&& defined(SL_CLOCK_MANAGER_HFXO_EN) && SL_CLOCK_MANAGER_HFXO_EN == 1
|
||||
/***************************************************************************//**
|
||||
* Initializes HFXO Oscillator.
|
||||
******************************************************************************/
|
||||
FUNCTION_SCOPE sl_status_t init_hfxo(void)
|
||||
{
|
||||
CMU_HFXOInit_TypeDef clock_manager_hfxo_init = CMU_HFXOINIT_DEFAULT;
|
||||
clock_manager_hfxo_init.mode = SLI_CLOCK_MANAGER_HFXO_MODE >> _HFXO_CFG_MODE_SHIFT;
|
||||
|
||||
if (SLI_CLOCK_MANAGER_HFXO_MODE == cmuHfxoOscMode_ExternalSine) {
|
||||
clock_manager_hfxo_init = (CMU_HFXOInit_TypeDef)CMU_HFXOINIT_EXTERNAL_SINE;
|
||||
#if defined(_HFXO_CFG_MODE_EXTCLKPKDET)
|
||||
} else if (SLI_CLOCK_MANAGER_HFXO_MODE == cmuHfxoOscMode_ExternalSinePkDet) {
|
||||
clock_manager_hfxo_init = (CMU_HFXOInit_TypeDef)CMU_HFXOINIT_EXTERNAL_SINEPKDET;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ctune = -1;
|
||||
|
||||
#if defined(_DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK)
|
||||
// Use HFXO tuning value from DEVINFO if available (PCB modules)
|
||||
if ((DEVINFO->MODULEINFO & _DEVINFO_MODULEINFO_HFXOCALVAL_MASK) == 0) {
|
||||
ctune = DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Use HFXO tuning value from MFG token in UD page if not already set
|
||||
if ((ctune == -1)
|
||||
#if defined(SL_CLOCK_MANAGER_CTUNE_MFG_HFXO_EN)
|
||||
&& (SL_CLOCK_MANAGER_CTUNE_MFG_HFXO_EN == 1)
|
||||
#endif
|
||||
&& (MFG_CTUNE_HFXO_VAL <= (_HFXO_XTALCTRL_CTUNEXIANA_MASK >> _HFXO_XTALCTRL_CTUNEXIANA_SHIFT))) {
|
||||
ctune = MFG_CTUNE_HFXO_VAL;
|
||||
}
|
||||
|
||||
// Use HFXO tuning value from configurations as fallback
|
||||
if (ctune == -1) {
|
||||
ctune = SL_CLOCK_MANAGER_HFXO_CTUNE;
|
||||
}
|
||||
|
||||
// Configure CTUNE XI and XO.
|
||||
if (ctune != -1) {
|
||||
clock_manager_hfxo_init.ctuneXiAna = (uint8_t)ctune;
|
||||
|
||||
// Ensure CTUNE XO plus a delta is within the correct range. The delta accounts for internal chip
|
||||
// load imbalance on some series 2 chips.
|
||||
ctune += CMU_HFXOCTuneDeltaGet();
|
||||
if (ctune < 0) {
|
||||
ctune = 0;
|
||||
} else if (ctune > ((int)(_HFXO_XTALCTRL_CTUNEXOANA_MASK >> _HFXO_XTALCTRL_CTUNEXOANA_SHIFT))) {
|
||||
ctune = (int)(_HFXO_XTALCTRL_CTUNEXOANA_MASK >> _HFXO_XTALCTRL_CTUNEXOANA_SHIFT);
|
||||
}
|
||||
clock_manager_hfxo_init.ctuneXoAna = ctune;
|
||||
}
|
||||
|
||||
#if defined(SLI_CLOCK_MANAGER_RUNTIME_CONFIGURATION)
|
||||
if (SLI_CLOCK_MANAGER_HFXO_CTUNE_FIXED_STEADY != SLI_CLOCK_MANAGER_HFXO_CTUNE_FIXED_STEADY_DEFAULT) {
|
||||
clock_manager_hfxo_init.ctuneFixAna = SLI_CLOCK_MANAGER_HFXO_CTUNE_FIXED_STEADY;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SL_CLOCK_MANAGER_HFXO_CRYSTAL_SHARING_EN) && (SL_CLOCK_MANAGER_HFXO_CRYSTAL_SHARING_EN == 1)
|
||||
// Set port and pin.
|
||||
GPIO_Port_TypeDef port = SL_CLOCK_MANAGER_HFXO_CRYSTAL_SHARING_GPIO_PORT;
|
||||
unsigned int pin = SL_CLOCK_MANAGER_HFXO_CRYSTAL_SHARING_GPIO_PIN;
|
||||
|
||||
// Enable HFXO and GPIO bus clocks.
|
||||
sl_clock_manager_enable_bus_clock(SL_BUS_CLOCK_HFXO0);
|
||||
sl_clock_manager_enable_bus_clock(SL_BUS_CLOCK_GPIO);
|
||||
#if defined(SL_CLOCK_MANAGER_HFXO_CRYSTAL_SHARING_FOLLOWER_EN) && (SL_CLOCK_MANAGER_HFXO_CRYSTAL_SHARING_FOLLOWER_EN == 1)
|
||||
// Initialize Crystal sharing follower.
|
||||
sl_clock_manager_enable_bus_clock(SL_BUS_CLOCK_PRS);
|
||||
|
||||
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
|
||||
|
||||
uint32_t mask = 0U, value = 0U;
|
||||
|
||||
bool was_locked = HFXO0->STATUS & HFXO_STATUS_LOCK_LOCKED ? true : false;
|
||||
|
||||
// Unlock register interface.
|
||||
HFXO0->LOCK = HFXO_LOCK_LOCKKEY_UNLOCK;
|
||||
HFXO0->IEN_SET = HFXO_IEN_BUFOUTRDY;
|
||||
|
||||
BUS_RegMaskedWrite(&HFXO0->CTRL, _HFXO_CTRL_PRSSTATUSSEL0_MASK, (_HFXO_CTRL_PRSSTATUSSEL0_ENS << _HFXO_CTRL_PRSSTATUSSEL0_SHIFT));
|
||||
|
||||
if (was_locked) {
|
||||
HFXO0->LOCK = ~HFXO_LOCK_LOCKKEY_UNLOCK;
|
||||
}
|
||||
|
||||
value = _PRS_ASYNC_CH_CTRL_AUXSEL_DEFAULT << _PRS_ASYNC_CH_CTRL_AUXSEL_SHIFT
|
||||
| _PRS_ASYNC_CH_CTRL_FNSEL_A << _PRS_ASYNC_CH_CTRL_FNSEL_SHIFT
|
||||
| _PRS_ASYNC_CH_CTRL_SOURCESEL_HFXO0L << _PRS_ASYNC_CH_CTRL_SOURCESEL_SHIFT
|
||||
| _PRS_ASYNC_CH_CTRL_SIGSEL_HFXO0LSTATUS << _PRS_ASYNC_CH_CTRL_SIGSEL_SHIFT;
|
||||
|
||||
mask = _PRS_ASYNC_CH_CTRL_AUXSEL_MASK
|
||||
| _PRS_ASYNC_CH_CTRL_FNSEL_MASK
|
||||
| _PRS_ASYNC_CH_CTRL_SOURCESEL_MASK
|
||||
| _PRS_ASYNC_CH_CTRL_SIGSEL_MASK;
|
||||
|
||||
BUS_RegMaskedWrite(&(PRS->ASYNC_CH[HFXO_CRYSTSAL_SHARING_PRS_CHANNEL].CTRL), mask, value);
|
||||
|
||||
GPIO_PinModeSet(port, pin, gpioModeWiredOrPullDown, 0U);
|
||||
|
||||
(&(GPIO->PRSROUTE[0].ASYNCH0ROUTE))[HFXO_CRYSTSAL_SHARING_PRS_CHANNEL] = pin << _GPIO_PRS_ASYNCH0ROUTE_PIN_SHIFT
|
||||
| port << _GPIO_PRS_ASYNCH0ROUTE_PORT_SHIFT;
|
||||
GPIO->PRSROUTE[0].ROUTEEN = 1U << (_GPIO_PRS_ROUTEEN_ASYNCH0PEN_SHIFT + HFXO_CRYSTSAL_SHARING_PRS_CHANNEL);
|
||||
|
||||
//sl_clock_manager_disable_bus_clock(SL_BUS_CLOCK_PRS);
|
||||
#elif defined(SL_CLOCK_MANAGER_HFXO_CRYSTAL_SHARING_LEADER_EN) && (SL_CLOCK_MANAGER_HFXO_CRYSTAL_SHARING_LEADER_EN == 1)
|
||||
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
|
||||
|
||||
// Configure Bufout request GPIO.
|
||||
GPIO_PinModeSet(port, pin, gpioModeInput, 0U);
|
||||
|
||||
GPIO->SYXOROUTE[0].BUFOUTREQINASYNCROUTE = pin << _GPIO_SYXO_BUFOUTREQINASYNCROUTE_PIN_SHIFT
|
||||
| port << _GPIO_SYXO_BUFOUTREQINASYNCROUTE_PORT_SHIFT;
|
||||
|
||||
bool was_locked = HFXO0->STATUS & HFXO_STATUS_LOCK_LOCKED ? true : false;
|
||||
|
||||
// Unlock register interface.
|
||||
HFXO0->LOCK = HFXO_LOCK_LOCKKEY_UNLOCK;
|
||||
|
||||
HFXO0->CTRL_CLR = _HFXO_CTRL_BUFOUTFREEZE_MASK | _HFXO_CTRL_DISONDEMANDBUFOUT_MASK;
|
||||
|
||||
BUS_RegMaskedWrite(&HFXO0->BUFOUTCTRL,
|
||||
_HFXO_BUFOUTCTRL_MINIMUMSTARTUPDELAY_MASK
|
||||
| _HFXO_BUFOUTCTRL_TIMEOUTSTARTUP_MASK,
|
||||
((uint32_t)SL_CLOCK_MANAGER_HFXO_CRYSTAL_SHARING_LEADER_MIN_STARTUP_DELAY_EN) << _HFXO_BUFOUTCTRL_MINIMUMSTARTUPDELAY_SHIFT
|
||||
| SL_CLOCK_MANAGER_HFXO_CRYSTAL_SHARING_LEADER_TIMEOUT_STARTUP);
|
||||
|
||||
if (was_locked) {
|
||||
HFXO0->LOCK = ~HFXO_LOCK_LOCKKEY_UNLOCK;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SystemHFXOClockSet(SL_CLOCK_MANAGER_HFXO_FREQ);
|
||||
CMU_HFXOInit(&clock_manager_hfxo_init);
|
||||
CMU_HFXOPrecisionSet(SL_CLOCK_MANAGER_HFXO_PRECISION);
|
||||
|
||||
#if defined(SLI_CLOCK_MANAGER_RUNTIME_CONFIGURATION)
|
||||
if (SLI_CLOCK_MANAGER_HFXO_CTUNE_FIXED_STEADY == SLI_CLOCK_MANAGER_HFXO_CTUNE_FIXED_STEADY_DEFAULT) {
|
||||
SLI_CLOCK_MANAGER_HFXO_CTUNE_FIXED_STEADY = (HFXO0->XTALCTRL & _HFXO_XTALCTRL_CTUNEFIXANA_MASK) >> _HFXO_XTALCTRL_CTUNEFIXANA_SHIFT;
|
||||
}
|
||||
#endif
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LFXO_PRESENT) \
|
||||
&& defined(SL_CLOCK_MANAGER_LFXO_EN) && SL_CLOCK_MANAGER_LFXO_EN == 1
|
||||
/***************************************************************************//**
|
||||
* Initializes LFXO Oscillator.
|
||||
******************************************************************************/
|
||||
FUNCTION_SCOPE sl_status_t init_lfxo(void)
|
||||
{
|
||||
CMU_LFXOInit_TypeDef clock_manager_lfxo_init = CMU_LFXOINIT_DEFAULT;
|
||||
|
||||
clock_manager_lfxo_init.mode = SL_CLOCK_MANAGER_LFXO_MODE >> _LFXO_CFG_MODE_SHIFT;
|
||||
clock_manager_lfxo_init.timeout = SL_CLOCK_MANAGER_LFXO_TIMEOUT >> _LFXO_CFG_TIMEOUT_SHIFT;
|
||||
clock_manager_lfxo_init.capTune = 0xFF;
|
||||
|
||||
#ifndef _SILICON_LABS_32B_SERIES_2_CONFIG_9
|
||||
#if defined(_DEVINFO_MODXOCAL_LFXOCAPTUNE_MASK)
|
||||
// Use LFXO tuning value from DEVINFO if available (PCB modules)
|
||||
if ((DEVINFO->MODULEINFO & _DEVINFO_MODULEINFO_LFXOCALVAL_MASK) == _DEVINFO_MODULEINFO_LFXOCALVAL_VALID) {
|
||||
clock_manager_lfxo_init.capTune = DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_LFXOCAPTUNE_MASK;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ((clock_manager_lfxo_init.capTune == 0xFF)
|
||||
#if defined(SL_CLOCK_MANAGER_CTUNE_MFG_LFXO_EN)
|
||||
&& (SL_CLOCK_MANAGER_CTUNE_MFG_LFXO_EN == 1)
|
||||
#endif
|
||||
&& (MFG_CTUNE_LFXO_VAL <= (_LFXO_CAL_CAPTUNE_MASK >> _LFXO_CAL_CAPTUNE_SHIFT))) {
|
||||
clock_manager_lfxo_init.capTune = MFG_CTUNE_LFXO_VAL;
|
||||
}
|
||||
|
||||
if (clock_manager_lfxo_init.capTune == 0xFF) {
|
||||
clock_manager_lfxo_init.capTune = SL_CLOCK_MANAGER_LFXO_CTUNE;
|
||||
}
|
||||
|
||||
CMU_LFXOInit(&clock_manager_lfxo_init);
|
||||
CMU_LFXOPrecisionSet(SL_CLOCK_MANAGER_LFXO_PRECISION);
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initializes Clock Input CLKIN0.
|
||||
******************************************************************************/
|
||||
static sl_status_t init_clkin0(void)
|
||||
{
|
||||
sl_status_t status = SL_STATUS_OK;
|
||||
|
||||
#if (defined(SL_CLOCK_MANAGER_SYSCLK_SOURCE) && (SL_CLOCK_MANAGER_SYSCLK_SOURCE == CMU_SYSCLKCTRL_CLKSEL_CLKIN0)) \
|
||||
|| (defined(SL_CLOCK_MANAGER_DPLL_REFCLK) && (SL_CLOCK_MANAGER_DPLL_REFCLK == CMU_DPLLREFCLKCTRL_CLKSEL_CLKIN0)) \
|
||||
|| (defined(SL_CLOCK_MANAGER_EM01GRPBCLK_SOURCE) && (SL_CLOCK_MANAGER_EM01GRPBCLK_SOURCE == CMU_EM01GRPBCLKCTRL_CLKSEL_CLKIN0))
|
||||
|
||||
#if !defined(SL_CLOCK_MANAGER_CLKIN0_PORT) || !defined(SL_CLOCK_MANAGER_CLKIN0_PIN)
|
||||
#error "Invalid configuration: CLKIN0 reference can't be use without configuring SL_CLOCK_MANAGER_CLKIN0 with a valid port and pin."
|
||||
#endif
|
||||
|
||||
sl_gpio_t clkin0_gpio = { SL_CLOCK_MANAGER_CLKIN0_PORT, SL_CLOCK_MANAGER_CLKIN0_PIN };
|
||||
|
||||
status = sl_clock_manager_enable_bus_clock(SL_BUS_CLOCK_GPIO);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = sl_gpio_set_pin_mode(&clkin0_gpio, SL_GPIO_MODE_INPUT, false);
|
||||
if (status == SL_STATUS_OK) {
|
||||
GPIO->CMUROUTE.CLKIN0ROUTE = (clkin0_gpio.port << _GPIO_CMU_CLKIN0ROUTE_PORT_SHIFT)
|
||||
| (clkin0_gpio.pin << _GPIO_CMU_CLKIN0ROUTE_PIN_SHIFT);
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
#if defined(HFRCO_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Initializes HFRCODPLL Oscillator.
|
||||
******************************************************************************/
|
||||
FUNCTION_SCOPE sl_status_t init_hfrcodpll(void)
|
||||
{
|
||||
#if defined(SL_CLOCK_MANAGER_HFRCO_DPLL_EN) && (SL_CLOCK_MANAGER_HFRCO_DPLL_EN == 1)
|
||||
CMU_DPLLInit_TypeDef clock_manager_dpll_init = {
|
||||
.frequency = SL_CLOCK_MANAGER_DPLL_FREQ,
|
||||
.n = SL_CLOCK_MANAGER_DPLL_N,
|
||||
.m = SL_CLOCK_MANAGER_DPLL_M,
|
||||
.edgeSel = SL_CLOCK_MANAGER_DPLL_EDGE,
|
||||
.lockMode = SL_CLOCK_MANAGER_DPLL_LOCKMODE,
|
||||
.autoRecover = SL_CLOCK_MANAGER_DPLL_AUTORECOVER,
|
||||
.ditherEn = SL_CLOCK_MANAGER_DPLL_DITHER
|
||||
};
|
||||
|
||||
// Convert the DPLL Reference clock configuration to emlib CMU_Select_TypeDef type.
|
||||
switch (SL_CLOCK_MANAGER_DPLL_REFCLK) {
|
||||
case CMU_DPLLREFCLKCTRL_CLKSEL_HFXO:
|
||||
clock_manager_dpll_init.refClk = cmuSelect_HFXO;
|
||||
break;
|
||||
case CMU_DPLLREFCLKCTRL_CLKSEL_LFXO:
|
||||
clock_manager_dpll_init.refClk = cmuSelect_LFXO;
|
||||
break;
|
||||
case CMU_DPLLREFCLKCTRL_CLKSEL_CLKIN0:
|
||||
clock_manager_dpll_init.refClk = cmuSelect_CLKIN0;
|
||||
break;
|
||||
default:
|
||||
return SL_STATUS_INVALID_CONFIGURATION;
|
||||
}
|
||||
|
||||
CMU_Select_TypeDef selected_sysclk = CMU_ClockSelectGet(cmuClock_SYSCLK);
|
||||
|
||||
if (selected_sysclk == cmuSelect_HFRCODPLL) {
|
||||
// The CMU should not be running from the HFRCO. If necessary, the CMU
|
||||
// should switch to the FSRCO until after the DPLL has locked to avoid
|
||||
// over-clocking due to overshoot.
|
||||
CMU->SYSCLKCTRL = (CMU->SYSCLKCTRL & ~_CMU_SYSCLKCTRL_CLKSEL_MASK) | CMU_SYSCLKCTRL_CLKSEL_FSRCO;
|
||||
}
|
||||
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG > 1)
|
||||
CMU_ClockEnable(cmuClock_DPLL0, true);
|
||||
#endif
|
||||
|
||||
bool success = CMU_DPLLLock(&clock_manager_dpll_init);
|
||||
|
||||
// If CMU was initially running from HFRCO switch back from FSRCO.
|
||||
if (selected_sysclk == cmuSelect_HFRCODPLL) {
|
||||
CMU->SYSCLKCTRL = (CMU->SYSCLKCTRL & ~_CMU_SYSCLKCTRL_CLKSEL_MASK) | CMU_SYSCLKCTRL_CLKSEL_HFRCODPLL;
|
||||
}
|
||||
|
||||
// If DPLL lock was unsuccessful, return status fail.
|
||||
if (!success) {
|
||||
// Disable DPLL0 if lock failed.
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG > 1)
|
||||
CMU_ClockEnable(cmuClock_DPLL0, false);
|
||||
#endif
|
||||
return SL_STATUS_FAIL;
|
||||
}
|
||||
#else
|
||||
CMU_HFRCODPLLBandSet(SLI_CLOCK_MANAGER_HFRCO_BAND);
|
||||
#endif
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HFRCOEM23_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Initializes HFRCOEM23 Oscillator.
|
||||
******************************************************************************/
|
||||
FUNCTION_SCOPE sl_status_t init_hfrcoem23(void)
|
||||
{
|
||||
CMU_HFRCOEM23BandSet(SL_CLOCK_MANAGER_HFRCOEM23_BAND);
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LFRCO_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Initializes LFRCO Oscillator.
|
||||
******************************************************************************/
|
||||
FUNCTION_SCOPE sl_status_t init_lfrco(void)
|
||||
{
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG > 1)
|
||||
CMU_ClockEnable(cmuClock_LFRCO, true);
|
||||
#endif
|
||||
|
||||
#if defined(PLFRCO_PRESENT)
|
||||
#if !(defined(SL_CLOCK_MANAGER_HFXO_EN) && (SL_CLOCK_MANAGER_HFXO_EN == 1))
|
||||
EFM_ASSERT(SL_CLOCK_MANAGER_LFRCO_PRECISION != cmuPrecisionHigh);
|
||||
#endif
|
||||
CMU_LFRCOSetPrecision(SL_CLOCK_MANAGER_LFRCO_PRECISION);
|
||||
#endif
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RFFPLL_PRESENT) \
|
||||
&& defined(SL_CLOCK_MANAGER_HFXO_EN) && (SL_CLOCK_MANAGER_HFXO_EN == 1)
|
||||
/***************************************************************************//**
|
||||
* Initializes RFFPLL Oscillator.
|
||||
******************************************************************************/
|
||||
FUNCTION_SCOPE sl_status_t init_rffpll(void)
|
||||
{
|
||||
CMU_RFFPLL_Init_TypeDef rffpll_init = CMU_RFFPLL_DEFAULT;
|
||||
|
||||
// Overwrite default configurations.
|
||||
#if (SL_CLOCK_MANAGER_RFFPLL_CUSTOM_BAND == 1)
|
||||
// Custom settings provided by the user.
|
||||
rffpll_init.frequency = SL_CLOCK_MANAGER_RFFPLL_FREQ;
|
||||
rffpll_init.dividerY = SL_CLOCK_MANAGER_RFFPLL_DIV_Y;
|
||||
rffpll_init.dividerX = SL_CLOCK_MANAGER_RFFPLL_DIV_X;
|
||||
rffpll_init.dividerN = SL_CLOCK_MANAGER_RFFPLL_DIV_N;
|
||||
#elif (SL_CLOCK_MANAGER_RFFPLL_BAND == 7) && defined(RADIO_CONFIG_RFFPLL_CONFIG_PRESENT)
|
||||
// Settings from the RAIL lib.
|
||||
rffpll_init.frequency = radioConfigRffpllConfig->sysclkFreqHz;
|
||||
rffpll_init.dividerY = ((radioConfigRffpllConfig->dividers & RAIL_RFFPLL_DIVIDERY_MASK) >> RAIL_RFFPLL_DIVIDERY_SHIFT);
|
||||
rffpll_init.dividerX = ((radioConfigRffpllConfig->dividers & RAIL_RFFPLL_DIVIDERX_MASK) >> RAIL_RFFPLL_DIVIDERX_SHIFT);
|
||||
rffpll_init.dividerN = ((radioConfigRffpllConfig->dividers & RAIL_RFFPLL_DIVIDERN_MASK) >> RAIL_RFFPLL_DIVIDERN_SHIFT);
|
||||
#else
|
||||
// Pre-determined settings.
|
||||
rffpll_init.frequency = rffpll_band_config_39MHz[SL_CLOCK_MANAGER_RFFPLL_BAND].frequency;
|
||||
rffpll_init.dividerY = rffpll_band_config_39MHz[SL_CLOCK_MANAGER_RFFPLL_BAND].divider_y;
|
||||
rffpll_init.dividerX = rffpll_band_config_39MHz[SL_CLOCK_MANAGER_RFFPLL_BAND].divider_x;
|
||||
rffpll_init.dividerN = rffpll_band_config_39MHz[SL_CLOCK_MANAGER_RFFPLL_BAND].divider_n;
|
||||
#endif
|
||||
|
||||
// Initialize RFFPLL.
|
||||
CMU_RFFPLLInit(&rffpll_init);
|
||||
|
||||
// Update RFFPLL frequency in System file
|
||||
SystemRFFPLLClockSet(rffpll_init.frequency);
|
||||
|
||||
// At this point, RFFPLL has been initialized. The clock source for SYSCLK can be
|
||||
// RFFPLLSYS input clock. If you want RFFPLLSYS, configure SL_CLOCK_MANAGER_SYSCLK_SOURCE
|
||||
// to CMU_SYSCLKCTRL_CLKSEL_RFFPLL0SYS.
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USBPLL_PRESENT) \
|
||||
&& defined(SL_CLOCK_MANAGER_HFXO_EN) && (SL_CLOCK_MANAGER_HFXO_EN == 1)
|
||||
/***************************************************************************//**
|
||||
* Initializes USBPLL Oscillator.
|
||||
******************************************************************************/
|
||||
FUNCTION_SCOPE sl_status_t init_usbpll(void)
|
||||
{
|
||||
CMU_USBPLL_Init_TypeDef usbpll_config;
|
||||
uint32_t hfxo_freq = SystemHFXOClockGet();
|
||||
|
||||
// Validate that HFXO frequency is adequate for USB PLL and set the right frequency.
|
||||
switch (hfxo_freq) {
|
||||
case 38000000:
|
||||
usbpll_config.hfxoRefFreq = cmuHFXORefFreq_38M0Hz;
|
||||
break;
|
||||
|
||||
case 38400000:
|
||||
usbpll_config.hfxoRefFreq = cmuHFXORefFreq_38M4Hz;
|
||||
break;
|
||||
|
||||
case 39000000:
|
||||
usbpll_config.hfxoRefFreq = cmuHFXORefFreq_39M0Hz;
|
||||
break;
|
||||
|
||||
case 40000000:
|
||||
usbpll_config.hfxoRefFreq = cmuHFXORefFreq_40M0Hz;
|
||||
break;
|
||||
|
||||
default:
|
||||
return SL_STATUS_FAIL;
|
||||
}
|
||||
|
||||
// Set additional configurations.
|
||||
usbpll_config.shuntRegEn = false;
|
||||
usbpll_config.disOnDemand = false;
|
||||
usbpll_config.regLock = true;
|
||||
|
||||
// Set Force Enable feature at first to force the PLL to start and validate it works.
|
||||
usbpll_config.forceEn = true;
|
||||
|
||||
// Initialize USB PLL and wait for it to be ready.
|
||||
CMU_USBPLLInit(&usbpll_config);
|
||||
|
||||
// Remove the Force Enable feature to let PLL module on-demand.
|
||||
usbpll_config.forceEn = false;
|
||||
|
||||
// Re-initialized without the Force Enable feature.
|
||||
CMU_USBPLLInit(&usbpll_config);
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initializes Clock branches.
|
||||
******************************************************************************/
|
||||
FUNCTION_SCOPE sl_status_t init_clock_branches(void)
|
||||
{
|
||||
// Initialize SYSCLK clock branch.
|
||||
#if defined(SL_CLOCK_MANAGER_SYSCLK_SOURCE)
|
||||
sli_em_cmu_SYSCLKInitPreClockSelect();
|
||||
#if (SL_CLOCK_MANAGER_SYSCLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(SYSCLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(SYSCLK, SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(SYSCLK, SL_CLOCK_MANAGER_SYSCLK_SOURCE);
|
||||
#endif
|
||||
sli_em_cmu_SYSCLKInitPostClockSelect(false);
|
||||
CMU->SYSCLKCTRL = (CMU->SYSCLKCTRL & ~(_CMU_SYSCLKCTRL_HCLKPRESC_MASK | _CMU_SYSCLKCTRL_PCLKPRESC_MASK))
|
||||
| SL_CLOCK_MANAGER_HCLK_DIVIDER
|
||||
| SL_CLOCK_MANAGER_PCLK_DIVIDER;
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
|
||||
// Initialize TRACECLK clock branch.
|
||||
#if defined(CoreDebug_DEMCR_TRCENA_Msk)
|
||||
// Disable the Core Debug module if already enabled
|
||||
bool trace_on = CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk;
|
||||
if (trace_on) {
|
||||
CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
|
||||
}
|
||||
#endif
|
||||
#if defined(SL_CLOCK_MANAGER_TRACECLK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(TRACECLK, SL_CLOCK_MANAGER_TRACECLK_SOURCE);
|
||||
#endif
|
||||
#if defined(SL_CLOCK_MANAGER_TRACECLK_DIVIDER)
|
||||
CMU->TRACECLKCTRL |= SL_CLOCK_MANAGER_TRACECLK_DIVIDER;
|
||||
#endif
|
||||
#if defined(CoreDebug_DEMCR_TRCENA_Msk)
|
||||
// Enable back the Core Debug module if it was already enabled
|
||||
if (trace_on) {
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
}
|
||||
#endif
|
||||
// Ensure TraceClk configs are defined if TraceClk is present.
|
||||
#if defined(_CMU_TRACECLKCTRL_MASK) && !(defined(SL_CLOCK_MANAGER_TRACECLK_SOURCE) || defined(SL_CLOCK_MANAGER_TRACECLK_DIVIDER))
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
|
||||
// Initialize EM01GRPACLK clock branch.
|
||||
#if defined(SL_CLOCK_MANAGER_EM01GRPACLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_EM01GRPACLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EM01GRPACLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(EM01GRPACLK, SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EM01GRPACLK, SL_CLOCK_MANAGER_EM01GRPACLK_SOURCE);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
|
||||
// Initialize EM01GRPBCLK clock branch.
|
||||
#if defined(PDM_PRESENT)
|
||||
#if defined(SL_CLOCK_MANAGER_EM01GRPBCLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_EM01GRPBCLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EM01GRPBCLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(EM01GRPBCLK, SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EM01GRPBCLK, SL_CLOCK_MANAGER_EM01GRPBCLK_SOURCE);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize EM01GRPCCLK clock branch.
|
||||
#if defined(_CMU_EM01GRPCCLKCTRL_MASK)
|
||||
#if defined(SL_CLOCK_MANAGER_EM01GRPCCLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_EM01GRPCCLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EM01GRPCCLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(EM01GRPCCLK, SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EM01GRPCCLK, SL_CLOCK_MANAGER_EM01GRPCCLK_SOURCE);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize IADCCLK clock branch.
|
||||
#if defined(SL_CLOCK_MANAGER_IADCCLK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(IADCCLK, SL_CLOCK_MANAGER_IADCCLK_SOURCE);
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
|
||||
// Initialize LESENSEHFCLK clock branch.
|
||||
#if defined(LESENSE_PRESENT)
|
||||
#if defined(SL_CLOCK_MANAGER_LESENSEHFCLK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(LESENSEHFCLK, SL_CLOCK_MANAGER_LESENSEHFCLK_SOURCE);
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize EM23GRPACLK clock branch.
|
||||
#if defined(SL_CLOCK_MANAGER_EM23GRPACLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_EM23GRPACLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EM23GRPACLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(EM23GRPACLK, SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EM23GRPACLK, SL_CLOCK_MANAGER_EM23GRPACLK_SOURCE);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
|
||||
// Initialize EM4GRPACLK clock branch.
|
||||
#if defined(SL_CLOCK_MANAGER_EM4GRPACLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_EM4GRPACLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EM4GRPACLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(EM4GRPACLK, SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EM4GRPACLK, SL_CLOCK_MANAGER_EM4GRPACLK_SOURCE);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
|
||||
// Initialize RTCC clock branch.
|
||||
#if defined(RTCC_PRESENT)
|
||||
#if defined(SL_CLOCK_MANAGER_RTCCCLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_RTCCCLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(RTCCCLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(RTCCCLK, SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(RTCCCLK, SL_CLOCK_MANAGER_RTCCCLK_SOURCE);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize SYSRTC clock branch.
|
||||
#if defined(SYSRTC_PRESENT)
|
||||
#if defined(SL_CLOCK_MANAGER_SYSRTCCLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_SYSRTCCLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(SYSRTC0CLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(SYSRTC0CLK, SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(SYSRTC0CLK, SL_CLOCK_MANAGER_SYSRTCCLK_SOURCE);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize WDOG0 clock branch.
|
||||
#if defined(SL_CLOCK_MANAGER_WDOG0CLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_WDOG0CLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(WDOG0CLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(WDOG0CLK, SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(WDOG0CLK, SL_CLOCK_MANAGER_WDOG0CLK_SOURCE);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
|
||||
// Initialize WDOG1 clock branch.
|
||||
#if WDOG_COUNT > 1
|
||||
#if defined(SL_CLOCK_MANAGER_WDOG1CLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_WDOG1CLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(WDOG1CLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(WDOG1CLK, SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(WDOG1CLK, SL_CLOCK_MANAGER_WDOG1CLK_SOURCE);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize LCD clock branch.
|
||||
#if defined(LCD_PRESENT)
|
||||
#if defined(SL_CLOCK_MANAGER_LCDCLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_LCDCLK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(LCDCLK, CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(LCDCLK, SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_CONCATENATION));
|
||||
#else
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(LCDCLK, SL_CLOCK_MANAGER_LCDCLK_SOURCE);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize PCNT0 clock branch.
|
||||
#if defined(PCNT_PRESENT)
|
||||
#if defined(SL_CLOCK_MANAGER_PCNT0CLK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(PCNT0CLK, SL_CLOCK_MANAGER_PCNT0CLK_SOURCE);
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize EUSART0
|
||||
#if defined(EUSART_PRESENT)
|
||||
#if defined(SL_CLOCK_MANAGER_EUSART0CLK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EUSART0CLK, SL_CLOCK_MANAGER_EUSART0CLK_SOURCE);
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize EUART
|
||||
#if defined(EUART_PRESENT)
|
||||
#if defined(SL_CLOCK_MANAGER_EUART0CLK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(EUART0CLK, SL_CLOCK_MANAGER_EUART0CLK_SOURCE);
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize SYSTICK clock branch.
|
||||
#if defined(SL_CLOCK_MANAGER_SYSTICKCLK_SOURCE)
|
||||
#if (SL_CLOCK_MANAGER_SYSTICKCLK_SOURCE == 1)
|
||||
CMU_CLOCK_SELECT_SET(SYSTICK, EM23GRPACLK);
|
||||
#elif (SL_CLOCK_MANAGER_SYSTICKCLK_SOURCE == 0)
|
||||
CMU_CLOCK_SELECT_SET(SYSTICK, HCLK);
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
|
||||
// Initialize VDAC0 clock branch.
|
||||
#if defined(VDAC_PRESENT)
|
||||
#if defined(SL_CLOCK_MANAGER_VDAC0CLK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(VDAC0CLK, SL_CLOCK_MANAGER_VDAC0CLK_SOURCE);
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
|
||||
// Initialize VDAC1 clock branch.
|
||||
#if VDAC_COUNT > 1
|
||||
#if defined(SL_CLOCK_MANAGER_VDAC1CLK_SOURCE)
|
||||
CLOCK_MANAGER_CLOCK_SELECT_SET(VDAC1CLK, SL_CLOCK_MANAGER_VDAC1CLK_SOURCE);
|
||||
#else
|
||||
EFM_ASSERT(false);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
********************** GLOBAL INTERNAL FUNCTIONS **************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initializes Oscillators and Clock branches.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_init(void)
|
||||
{
|
||||
sl_status_t status;
|
||||
|
||||
#if defined(SYSRTC_PRESENT)
|
||||
status = sl_clock_manager_enable_bus_clock(SL_BUS_CLOCK_SYSRTC0);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize Oscillators
|
||||
#if defined(LFXO_PRESENT) \
|
||||
&& defined(SL_CLOCK_MANAGER_LFXO_EN) && (SL_CLOCK_MANAGER_LFXO_EN == 1)
|
||||
status = init_lfxo();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HFXO_PRESENT) \
|
||||
&& defined(SL_CLOCK_MANAGER_HFXO_EN) && (SL_CLOCK_MANAGER_HFXO_EN == 1)
|
||||
status = init_hfxo();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
status = init_clkin0();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
#if defined(HFRCO_PRESENT)
|
||||
status = init_hfrcodpll();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HFRCOEM23_PRESENT)
|
||||
status = init_hfrcoem23();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LFRCO_PRESENT)
|
||||
status = init_lfrco();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RFFPLL_PRESENT) \
|
||||
&& defined(SL_CLOCK_MANAGER_HFXO_EN) && (SL_CLOCK_MANAGER_HFXO_EN == 1)
|
||||
status = init_rffpll();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USBPLL_PRESENT) \
|
||||
&& defined(SL_CLOCK_MANAGER_HFXO_EN) && (SL_CLOCK_MANAGER_HFXO_EN == 1)
|
||||
status = init_usbpll();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize Clock branches
|
||||
status = init_clock_branches();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
198
Libs/platform/service/clock_manager/src/sli_clock_manager_hal.h
Normal file
198
Libs/platform/service/clock_manager/src/sli_clock_manager_hal.h
Normal file
@@ -0,0 +1,198 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Clock Manager HAL APIs.
|
||||
*******************************************************************************
|
||||
* # 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_CLOCK_MANAGER_HAL_H
|
||||
#define SL_CLOCK_MANAGER_HAL_H
|
||||
|
||||
#include "sl_clock_manager.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Performs Clock Manager runtime initialization.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_runtime_init(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets frequency of given oscillator.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_clock_manager_hal_get_oscillator_frequency(sl_oscillator_t oscillator,
|
||||
uint32_t *frequency);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets precision of given oscillator.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_get_oscillator_precision(sl_oscillator_t oscillator,
|
||||
uint16_t *precision);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets frequency of given clock branch.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_clock_manager_hal_get_clock_branch_frequency(sl_clock_branch_t clock_branch,
|
||||
uint32_t *frequency);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets precision of given clock branch.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_get_clock_branch_precision(sl_clock_branch_t clock_branch,
|
||||
uint16_t *precision);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enables/Disables the bus clock associated with the given module.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_enable_bus_clock(sl_bus_clock_t module,
|
||||
bool enable);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configures the exported clock feature on CMU to output user selected
|
||||
* clock source specified GPIO pin.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_set_gpio_clock_output(sl_clock_manager_export_clock_source_t export_clock_source,
|
||||
sl_clock_manager_export_clock_output_select_t output_select,
|
||||
uint16_t divider,
|
||||
uint32_t port,
|
||||
uint32_t pin);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the RC oscillator frequency tuning control.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_set_rc_oscillator_calibration(sl_oscillator_t oscillator,
|
||||
uint32_t val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the RC oscillator frequency tuning setting.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_get_rc_oscillator_calibration(sl_oscillator_t oscillator,
|
||||
uint32_t *val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the HFXO calibration value.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_set_hfxo_calibration(uint32_t val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the HFXO calibration value.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_get_hfxo_calibration(uint32_t *val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the HFXO CTUNE setting.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_hfxo_set_ctune(uint32_t ctune);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the HFXO CTUNE setting.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_hfxo_get_ctune(uint32_t *ctune);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Updates the tuning capacitances and calibrate the Core Bias Current.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_hfxo_calibrate_ctune(uint32_t ctune);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the LFXO frequency tuning control.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_set_lfxo_calibration(uint32_t val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the LFXO frequency tuning setting.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_get_lfxo_calibration(uint32_t *val);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configures the RCO calibration.
|
||||
*****************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_configure_rco_calibration(uint32_t cycles,
|
||||
sl_clock_manager_clock_calibration_t down_counter_selection,
|
||||
sl_clock_manager_clock_calibration_t up_counter_selection,
|
||||
bool continuous_calibration);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Starts the RCO calibration.
|
||||
******************************************************************************/
|
||||
void sli_clock_manager_hal_start_rco_calibration (void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Stops the RCO calibration.
|
||||
******************************************************************************/
|
||||
void sli_clock_manager_hal_stop_rco_calibration(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Waits for the RCO calibration to finish.
|
||||
******************************************************************************/
|
||||
void sli_clock_manager_hal_wait_rco_calibration(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets calibration count value.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_get_rco_calibration_count(uint32_t *count);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets SYSCLK clock source.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_clock_manager_hal_set_sysclk_source(sl_oscillator_t source);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets SYSCLK clock source.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_clock_manager_hal_get_sysclk_source(sl_oscillator_t *source);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Waits for USBPLL clock to be ready.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_wait_usbpll(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Sets the external FLASH reference clock.
|
||||
*
|
||||
* @note This API is not thread-safe and should therefore not be called
|
||||
* across multiple tasks.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_clock_manager_hal_set_ext_flash_clk(sl_oscillator_t oscillator);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the external FLASH clock source.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_CLOCK_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_clock_manager_hal_get_ext_flash_clk(sl_oscillator_t *oscillator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_CLOCK_MANAGER_HAL_H
|
||||
@@ -0,0 +1,111 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Clock Manager Init HAL APIs.
|
||||
*******************************************************************************
|
||||
* # 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_CLOCK_MANAGER_INIT_HAL_H
|
||||
#define SL_CLOCK_MANAGER_INIT_HAL_H
|
||||
|
||||
#include "sl_status.h"
|
||||
#include "sl_clock_manager_tree_config.h"
|
||||
#include "sl_clock_manager_oscillator_config.h"
|
||||
#include "em_device.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** MACROS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
#if (SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_HFRCODPLL)
|
||||
#define SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_CONCATENATION _HFRCODPLL
|
||||
#elif (SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_HFXO)
|
||||
#define SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_CONCATENATION _HFXO
|
||||
#elif (SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_FSRCO)
|
||||
#define SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE_CONCATENATION _FSRCO
|
||||
#else
|
||||
#error "SL_CLOCK_MANAGER_DEFAULT_HF_CLOCK_SOURCE configuration value is invalid."
|
||||
#endif
|
||||
|
||||
#if (SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_LFRCO)
|
||||
#define SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_CONCATENATION _LFRCO
|
||||
#elif (SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_LFXO)
|
||||
#define SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_CONCATENATION _LFXO
|
||||
#elif (SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE == SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_ULFRCO)
|
||||
#define SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE_CONCATENATION _ULFRCO
|
||||
#else
|
||||
#error "SL_CLOCK_MANAGER_DEFAULT_LF_CLOCK_SOURCE configuration value is invalid."
|
||||
#endif
|
||||
|
||||
#define CLOCK_MANAGER_CLOCK_SELECT_SET(clock_branch, clock_source) \
|
||||
do { \
|
||||
CMU->clock_branch##CTRL = (CMU->clock_branch##CTRL & ~_CMU_##clock_branch##CTRL_CLKSEL_MASK) \
|
||||
| clock_source; \
|
||||
} while (0)
|
||||
|
||||
#define CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE_NX(clock_branch, clock_source) CMU_##clock_branch##CTRL_CLKSEL##clock_source
|
||||
#define CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE(clock_branch, clock_source) CLOCK_MANAGER_GET_DEFAULT_CLOCK_SOURCE_NX(clock_branch, clock_source)
|
||||
|
||||
#if !defined(SLI_CLOCK_MANAGER_RUNTIME_CONFIGURATION)
|
||||
#define SLI_CLOCK_MANAGER_HFXO_MODE SL_CLOCK_MANAGER_HFXO_MODE
|
||||
#define SLI_CLOCK_MANAGER_HFRCO_BAND SL_CLOCK_MANAGER_HFRCO_BAND
|
||||
#endif // #if !defined(SLI_CLOCK_MANAGER_RUNTIME_CONFIGURATION)
|
||||
|
||||
#if defined(SL_CLOCK_MANAGER_SOCPLL_EN) && (SL_CLOCK_MANAGER_SOCPLL_EN == 1)
|
||||
#if defined(SL_CLOCK_MANAGER_SOCPLL_ADVANCED_SETTINGS) && (SL_CLOCK_MANAGER_SOCPLL_ADVANCED_SETTINGS == 0)
|
||||
#if defined(SL_CATALOG_RAIL_LIB_PRESENT) || (defined(SL_CLOCK_MANAGER_HFXO_EN) && (SL_CLOCK_MANAGER_HFXO_EN == 1))
|
||||
#define SL_CLOCK_MANAGER_SOCPLL_REFCLK SOCPLL_CTRL_REFCLKSEL_REF_HFXO
|
||||
#define SL_CLOCK_MANAGER_SOCPLL_REFCLK_FREQ SL_CLOCK_MANAGER_HFXO_FREQ
|
||||
#else
|
||||
#define SL_CLOCK_MANAGER_SOCPLL_REFCLK SOCPLL_CTRL_REFCLKSEL_REF_HFRCO
|
||||
#define SL_CLOCK_MANAGER_SOCPLL_REFCLK_FREQ SL_CLOCK_MANAGER_HFRCO_BAND
|
||||
#endif
|
||||
#define SL_CLOCK_MANAGER_SOCPLL_FRACTIONAL_EN 1
|
||||
// SOCPLL Formula: SOCPLL_FREQ = REFCLK_FREQ * (DIVN+2 + DIVF/1024) / 6
|
||||
// SL_CLOCK_MANAGER_SOCPLL_DIVN is rounded down and SL_CLOCK_MANAGER_SOCPLL_DIVF is rounded to the closest integer.
|
||||
#define SL_CLOCK_MANAGER_SOCPLL_DIVN (6ULL * SL_CLOCK_MANAGER_SOCPLL_FREQ / SL_CLOCK_MANAGER_SOCPLL_REFCLK_FREQ - 2ULL)
|
||||
#define SL_CLOCK_MANAGER_SOCPLL_DIVF ((6ULL * 1024ULL * SL_CLOCK_MANAGER_SOCPLL_FREQ + SL_CLOCK_MANAGER_SOCPLL_REFCLK_FREQ / 2ULL) / SL_CLOCK_MANAGER_SOCPLL_REFCLK_FREQ - 1024ULL * (SL_CLOCK_MANAGER_SOCPLL_DIVN + 2ULL))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initializes Oscillators and Clock branches.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_clock_manager_hal_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_CLOCK_MANAGER_INIT_HAL_H
|
||||
Reference in New Issue
Block a user