| .. _module-pw_clock_tree: |
| |
| ================ |
| pw_clock_tree |
| ================ |
| .. pigweed-module:: |
| :name: pw_clock_tree |
| |
| - **Constinit compatible**: Clock tree elements can be declared as ``constinit`` |
| - **Platform independent**: Clock tree management sits above the platform layer |
| - **Handles complex topologies**: Clock tree elements can be used to model |
| complex clock tree topologies |
| |
| ``pw_clock_tree`` provides class definitions to implement a platform |
| specific clock tree management solution. By passing the clock tree element |
| that clocks a particular device to the corresponding device driver, the |
| device driver can ensure that the clock is only enabled when required to |
| maximize power savings. |
| |
| For example the clock tree functionality could be integrated into a uart device driver |
| like this: |
| |
| .. literalinclude:: examples.cc |
| :language: cpp |
| :linenos: |
| :start-after: [pw_clock_tree-examples-IntegrationIntoDeviceDriversClassDef] |
| :end-before: // Device constructor that optionally accepts |
| |
| It could be initialized and used like this: |
| |
| .. literalinclude:: examples.cc |
| :language: cpp |
| :linenos: |
| :start-after: [pw_clock_tree-examples-IntegrationIntoDeviceDriversUsage] |
| :end-before: [pw_clock_tree-examples-IntegrationIntoDeviceDriversUsage] |
| |
| .. grid:: 2 |
| |
| .. grid-item-card:: :octicon:`rocket` Quickstart |
| :link: module-pw_clock_tree-examples |
| :link-type: ref |
| :class-item: sales-pitch-cta-primary |
| |
| Examples that show how to integrate a clock tree into a device driver, |
| and how to define and use platform specific clock tree elements. |
| |
| .. grid-item-card:: :octicon:`code-square` Reference |
| :link: module-pw_clock_tree-reference |
| :link-type: ref |
| :class-item: sales-pitch-cta-secondary |
| |
| API references for ``pw::clock_tree::Element``, |
| ``pw::clock_tree::DependentElement``, ``pw::clock_tree::ClockTree``, |
| and more. |
| |
| |
| -------- |
| Overview |
| -------- |
| .. cpp:namespace-push:: pw::clock_tree::ClockTree |
| |
| Pigweed's clock tree module provides the ability to represent the clock tree of an embedded |
| device, and to manage the individual clocks and clock tree elements. |
| |
| The :cpp:class:`ClockTree` implements two basic methods that apply to all clock tree elements: |
| |
| * :cpp:func:`Acquire` |
| * :cpp:func:`Release` |
| |
| In addition, clock divider elements can use the :cpp:func:`SetDividerValue` method to update the current |
| clock divider value. |
| |
| .. cpp:namespace-pop:: |
| |
| .. cpp:namespace-push:: pw::clock_tree::Element |
| |
| The clock tree module defines the :cpp:class:`Element` abstract class from which all |
| other classes are derived from. The :cpp:class:`Element` abstract class implements basic reference |
| counting methods :cpp:func:`IncRef` and :cpp:func:`DecRef`, but requires derived classes to use the |
| reference counting methods to properly acquire and release references to clock |
| tree elements. If an :cpp:class:`Element` reference is passed to a constructor of a |
| derived :cpp:class:`Element`, the class object depends on the referenced :cpp:class:`Element` object. |
| |
| Three derived abstract classes are defined for :cpp:class:`Element`: |
| |
| .. cpp:namespace-pop:: |
| |
| .. cpp:namespace-push:: pw::clock_tree |
| |
| * :cpp:class:`ElementBlocking` for clock tree elements that might block when acquired or released. |
| Acquiring or releasing such a clock tree element might fail. |
| * :cpp:class:`ElementNonBlockingCannotFail` for clock tree elements that will not block when |
| acquired or released. Acquiring or releasing such a clock tree element will always succeed. |
| * :cpp:class:`ElementNonBlockingMightFail` for clock tree elements that will not block when |
| acquired or released. Acquiring or releasing such a clock tree element might fail. |
| |
| :cpp:class:`ElementNonBlockingCannotFail` and :cpp:class:`ElementsNonBlockingMightFail` elements can |
| be acquired from an interrupt context. |
| |
| All classes representing a clock tree element should be implemented as a template and accept |
| :cpp:class:`ElementBlocking`, :cpp:class:`ElementNonBlockingCannotFail` or |
| :cpp:class:`ElementNonBlockingMightFail` as a template argument. Only if it is known at compile time |
| that a clock tree element can only be either blocking or non-blocking, one can directly derive the |
| class from :cpp:class:`ElementBlocking` or :cpp:class:`ElementNonBlockingCannotFail` / |
| :cpp:class:`ElementNonBlockingMightFail`, respectively. |
| |
| .. cpp:namespace-pop:: |
| |
| .. cpp:namespace-push:: pw::clock_tree::ElementController |
| |
| For ease of use :cpp:class:`ElementController` encapsulates :cpp:class:`ClockTree` and :cpp:class:`Element` into a single object and provides :cpp:func:`Acquire` and :cpp:func:`Release` methods that check whether both optional objects have been specified, and only if yes, call the respective :cpp:class:`ClockTree` methods, otherwise they return ``pw::OkStatus()``. |
| |
| .. cpp:namespace-pop:: |
| |
| --------------- |
| Synchronization |
| --------------- |
| .. cpp:namespace-push:: pw::clock_tree |
| |
| The clock tree class uses a mutex to serialize access to :cpp:class:`ElementBlocking` clock tree |
| elements, and uses an interrupt spin lock to serialize access to |
| :cpp:class:`ElementNonBlockingCannotFail` and :cpp:class:`ElementNonBlockingMightFail` clock tree |
| elements. :cpp:class:`ElementBlocking` clock tree elements and |
| :cpp:class:`ElementNonBlockingCannotFail` / :cpp:class:`ElementNonBlockingMightFail` clock tree |
| elements are not serialized with each other, while :cpp:class:`ElementNonBlockingCannotFail` and |
| :cpp:class:`ElementNonBlockingMightFail` are serialized with each other. |
| |
| .. cpp:namespace-pop:: |
| |
| .. toctree:: |
| :hidden: |
| :maxdepth: 1 |
| |
| examples |
| api |
| implementations |