Interface for getting and changing clock configuration.
group_hal_syspm
The clock driver is a single API designed to allow reading and configuring any clock in the system. The driver works the same to configure System clocks as it does for Peripheral clocks. It supports both a readonly mode where any number of items can get information about the clock. Alternatively, each clock can have a single owner that is able to adjust the configuration of the clock.
This driver supports source clocks, clock dividers, and clock signal muxes. All clock objects support the get() functions. Only some clocks support setting specific attributes. Use the cyhal_clock_get_features() function to determine which features are settable for a specific clock. Calling a set() function on a clock that does not support it will return an error.
This driver makes no assumptions about how the device is currently configured. It can be used from a completely unconfigured system (eg: device just booted) to a fully pre-configured (eg: setup by the Device Configurator). The drivers query and modify the actual state of the hardware, there is no caching or remembering of state. To maximize portability of code, it is often convenient to place all system clock configuration into a Board Support Package (BSP) so the main application code is flexible and can port between devices.
All System Clock instances are available as constant variables in the implementation specific header. These clocks can be used directly to call any get() function. Similarly, cyhal_clock_get allows for getting access to a specific clock object given a resource instance. Like the constant variables, this clock reference can be used to call any of the get() functions at any time. If a clock needs to be modified, either cyhal_clock_allocate or cyhal_clock_reserve must be called to obtain a lock on the clock object and to ensure that nothing else in the application is currently using it or assuming its configuration is stable. If exclusive control of a clock is no longer needed cyhal_clock_free can be called to release it. This will remove the lock allowing something else in the system to potentially modify its state.
cyhal_clock_reserve and cyhal_clock_allocate are very similar. They both reserve a clock object that can then be modified. The difference between them is the argument that is passed in. cyhal_clock_reserve takes a specific instance that it will attempt to reserve. cyhal_clock_allocate takes in a type of clock that it will attempt to find a free instance for and reserve that.
See Snippet 1: Simple clock read only access for a code snippet that shows how to reserve and configure a clock object.
The following snippet shows how get details about a clock if there is no need to adjust any of its settings (e.g. read only access). This does not require initializing a clock object.
The following snippet initializes a clock object, updates its frequency then enables it.
The following snippet shows how a clock can be allocated and reused for multiple peripheral instances.
The following snippet shows how a to change the source of a clock.
API Reference | |
Clock HAL Results | |
Clock specific return codes. | |
Group_hal_tolerance | |
Data Structures | |
struct | cyhal_clock_tolerance_t |
Structure defining a clock tolerance. More... | |
Enumerations | |
enum | cyhal_clock_feature_t { CYHAL_CLOCK_FEATURE_NONE = (0) , CYHAL_CLOCK_FEATURE_ENABLE = (1 << 0) , CYHAL_CLOCK_FEATURE_FREQUENCY = (1 << 1) , CYHAL_CLOCK_FEATURE_DIVIDER = (1 << 2) , CYHAL_CLOCK_FEATURE_SOURCE = (1 << 4) } |
Enum defining the different features each clock can support of clocks. More... | |
enum | cyhal_clock_tolerance_unit_t { CYHAL_TOLERANCE_HZ , CYHAL_TOLERANCE_PPM , CYHAL_TOLERANCE_PERCENT } |
Enum defining the different ways of specifying the acceptable clock tolerance. More... | |
Functions | |
cy_rslt_t | cyhal_clock_get (cyhal_clock_t *clock, const cyhal_resource_inst_t *resource) |
Get a Clock instance for readonly use. More... | |
cy_rslt_t | cyhal_clock_reserve (cyhal_clock_t *clock, const cyhal_clock_t *clock_) |
Reserves the specified Clock instance. More... | |
cy_rslt_t | cyhal_clock_allocate (cyhal_clock_t *clock, cyhal_clock_block_t block) |
Allocates and Reserves a Clock instance, of the provided block type, for use. More... | |
cyhal_clock_feature_t | cyhal_clock_get_features (const cyhal_clock_t *clock) |
Gets the features supported by the specified clock. More... | |
bool | cyhal_clock_is_enabled (const cyhal_clock_t *clock) |
Gets whether the specified clock is currently enabled and locked, if appropriate. More... | |
cy_rslt_t | cyhal_clock_set_enabled (cyhal_clock_t *clock, bool enabled, bool wait_for_lock) |
Attempts to update the enablement of the specified clock. More... | |
uint32_t | cyhal_clock_get_frequency (const cyhal_clock_t *clock) |
Gets the frequency (in Hz) the clock is currently operating at. More... | |
cy_rslt_t | cyhal_clock_set_frequency (cyhal_clock_t *clock, uint32_t hz, const cyhal_clock_tolerance_t *tolerance) |
Attempts to update the operating frequency of the clock. More... | |
cy_rslt_t | cyhal_clock_set_divider (cyhal_clock_t *clock, uint32_t divider) |
Attempts to update the divider, and by extension the operating frequency, of the clock. More... | |
cy_rslt_t | cyhal_clock_get_sources (const cyhal_clock_t *clock, const cyhal_resource_inst_t **sources[], uint32_t *count) |
Gets the clocks that can serve as inputs to the current clock. More... | |
cy_rslt_t | cyhal_clock_set_source (cyhal_clock_t *clock, const cyhal_clock_t *source) |
Attempts to update the source for the specified clock. More... | |
void | cyhal_clock_free (cyhal_clock_t *clock) |
Releases the exclusive lock the clock. More... | |
struct cyhal_clock_tolerance_t |
Data Fields | ||
---|---|---|
cyhal_clock_tolerance_unit_t | type | The type of the clock tolerance value. |
uint32_t | value | The tolerance value to use. |
Enum defining the different features each clock can support of clocks.
These are bit masks. These can be used to determine which set() APIs are legal for a particular clock.
Enumerator | |
---|---|
CYHAL_CLOCK_FEATURE_NONE | No features of the clock are configurable. |
CYHAL_CLOCK_FEATURE_ENABLE | The clock can be enabled & disabled cyhal_clock_set_enabled. |
CYHAL_CLOCK_FEATURE_FREQUENCY | The clock frequency can be adjusted cyhal_clock_set_frequency. |
CYHAL_CLOCK_FEATURE_DIVIDER | The clock divider can be adjusted cyhal_clock_set_divider. |
CYHAL_CLOCK_FEATURE_SOURCE | The clock source can be adjusted cyhal_clock_set_source. |
cy_rslt_t cyhal_clock_get | ( | cyhal_clock_t * | clock, |
const cyhal_resource_inst_t * | resource | ||
) |
Get a Clock instance for readonly use.
This clock object can be used to call any of the get() functions. To call any of the set() functions, cyhal_clock_reserve must be called to get exclusive access to the clock object to allow it to be modified.
[out] | clock | The clock object to store the initialized data into. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | resource | The clock resource instance to initialize. |
cy_rslt_t cyhal_clock_reserve | ( | cyhal_clock_t * | clock, |
const cyhal_clock_t * | clock_ | ||
) |
Reserves the specified Clock instance.
Once the clock has been reserved the get() and set() functions can be used. If at any time the clock is no longer needed, it can be released by calling cyhal_clock_free.
[out] | clock | The clock object to initialize. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | clock_ | The constant clock object to reserve |
cy_rslt_t cyhal_clock_allocate | ( | cyhal_clock_t * | clock, |
cyhal_clock_block_t | block | ||
) |
Allocates and Reserves a Clock instance, of the provided block type, for use.
This should be used when needing a specific type of clock but the exact instance does not matter. This does everything that is done by cyhal_clock_reserve. Once the clock has been allocated the get() and set() functions can be used. If at any time the clock is no longer needed, it can be released by calling cyhal_clock_free.
[out] | clock | The clock object to initialize. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | block | The specific type of clock to allocate |
cyhal_clock_feature_t cyhal_clock_get_features | ( | const cyhal_clock_t * | clock | ) |
Gets the features supported by the specified clock.
This can be used to determine which set() APIs are legal to be called for this clock.
[in] | clock | The clock object to get features for. |
bool cyhal_clock_is_enabled | ( | const cyhal_clock_t * | clock | ) |
Gets whether the specified clock is currently enabled and locked, if appropriate.
While most clocks simply have an enabled state, Crystals, PLL, and a few others may also check to make sure the clock has locked and is stable before returning true.
[in] | clock | The clock object to check if it is enabled. |
cy_rslt_t cyhal_clock_set_enabled | ( | cyhal_clock_t * | clock, |
bool | enabled, | ||
bool | wait_for_lock | ||
) |
Attempts to update the enablement of the specified clock.
This is only legal to call if the cyhal_clock_get_features API indicates support for CYHAL_CLOCK_FEATURE_ENABLE.
[in] | clock | The clock object to update the enablement of. |
[in] | enabled | Whether the clock should be enabled (true) or disabled (false). |
[in] | wait_for_lock | Whether to wait for the clock to enable & lock (true), or just send the request and return (false). Most clocks behave the same either way, however Crystals, PLLs, and similar require time to lock. If false, cyhal_clock_is_enabled needs to be used to check that it is running before using the clock. |
uint32_t cyhal_clock_get_frequency | ( | const cyhal_clock_t * | clock | ) |
Gets the frequency (in Hz) the clock is currently operating at.
[in] | clock | The clock object to get the frequency of. |
cy_rslt_t cyhal_clock_set_frequency | ( | cyhal_clock_t * | clock, |
uint32_t | hz, | ||
const cyhal_clock_tolerance_t * | tolerance | ||
) |
Attempts to update the operating frequency of the clock.
This is only legal to call if the cyhal_clock_get_features API indicates support for CYHAL_CLOCK_FEATURE_FREQUENCY.
[in] | clock | The clock object to set the frequency for. |
[in] | hz | The frequency, in hertz, to set the clock to. |
[in] | tolerance | The allowed tolerance from the desired hz that is acceptable, use NULL if no tolerance check is required. |
cy_rslt_t cyhal_clock_set_divider | ( | cyhal_clock_t * | clock, |
uint32_t | divider | ||
) |
Attempts to update the divider, and by extension the operating frequency, of the clock.
This is only legal to call if the cyhal_clock_get_features API indicates support for CYHAL_CLOCK_FEATURE_DIVIDER.
[in] | clock | The clock object to set the divider for. |
[in] | divider | The divider value to use. |
cy_rslt_t cyhal_clock_get_sources | ( | const cyhal_clock_t * | clock, |
const cyhal_resource_inst_t ** | sources[], | ||
uint32_t * | count | ||
) |
Gets the clocks that can serve as inputs to the current clock.
[in] | clock | The clock object to get legal sources for. |
[out] | sources | The sources that are legal for the current clock. |
[out] | count | The number of clock sources contained in the sources variable. |
cy_rslt_t cyhal_clock_set_source | ( | cyhal_clock_t * | clock, |
const cyhal_clock_t * | source | ||
) |
Attempts to update the source for the specified clock.
This is only legal to call if the cyhal_clock_get_features API indicates support for CYHAL_CLOCK_FEATURE_SOURCE.
[in] | clock | The clock object to set a new source for. |
[in] | source | The source clock to update to. |
void cyhal_clock_free | ( | cyhal_clock_t * | clock | ) |
Releases the exclusive lock the clock.
This instance can no longer be used to with any set() functions. It can still be used for readonly access to Clock APIs just like is possible after calling cyhal_clock_get.
[in,out] | clock | The clock object to free |