1.. _module-pw_clock_tree: 2 3================ 4pw_clock_tree 5================ 6.. pigweed-module:: 7 :name: pw_clock_tree 8 9 - **Constinit compatible**: Clock tree elements can be declared as ``constinit`` 10 - **Platform independent**: Clock tree management sits above the platform layer 11 - **Handles complex topologies**: Clock tree elements can be used to model 12 complex clock tree topologies 13 14``pw_clock_tree`` provides class definitions to implement a platform 15specific clock tree management solution. By passing the clock tree element 16that clocks a particular device to the corresponding device driver, the 17device driver can ensure that the clock is only enabled when required to 18maximize power savings. 19 20For example the clock tree functionality could be integrated into a uart device driver 21like this: 22 23.. literalinclude:: examples.cc 24 :language: cpp 25 :linenos: 26 :start-after: [pw_clock_tree-examples-IntegrationIntoDeviceDriversClassDef] 27 :end-before: // Device constructor that optionally accepts 28 29It could be initialized and used like this: 30 31.. literalinclude:: examples.cc 32 :language: cpp 33 :linenos: 34 :start-after: [pw_clock_tree-examples-IntegrationIntoDeviceDriversUsage] 35 :end-before: [pw_clock_tree-examples-IntegrationIntoDeviceDriversUsage] 36 37.. grid:: 2 38 39 .. grid-item-card:: :octicon:`rocket` Quickstart 40 :link: module-pw_clock_tree-examples 41 :link-type: ref 42 :class-item: sales-pitch-cta-primary 43 44 Examples that show how to integrate a clock tree into a device driver, 45 and how to define and use platform specific clock tree elements. 46 47 .. grid-item-card:: :octicon:`code-square` Reference 48 :link: module-pw_clock_tree-reference 49 :link-type: ref 50 :class-item: sales-pitch-cta-secondary 51 52 API references for ``pw::clock_tree::Element``, 53 ``pw::clock_tree::DependentElement``, ``pw::clock_tree::ClockTree``, 54 and more. 55 56 57-------- 58Overview 59-------- 60.. cpp:namespace-push:: pw::clock_tree::ClockTree 61 62Pigweed's clock tree module provides the ability to represent the clock tree of an embedded 63device, and to manage the individual clocks and clock tree elements. 64 65The :cpp:class:`ClockTree` implements two basic methods that apply to all clock tree elements: 66 67* :cpp:func:`Acquire` 68* :cpp:func:`Release` 69 70In addition, clock divider elements can use the :cpp:func:`SetDividerValue` method to update the current 71clock divider value. 72 73.. cpp:namespace-pop:: 74 75.. cpp:namespace-push:: pw::clock_tree::Element 76 77The clock tree module defines the :cpp:class:`Element` abstract class from which all 78other classes are derived from. The :cpp:class:`Element` abstract class implements basic reference 79counting methods :cpp:func:`IncRef` and :cpp:func:`DecRef`, but requires derived classes to use the 80reference counting methods to properly acquire and release references to clock 81tree elements. If an :cpp:class:`Element` reference is passed to a constructor of a 82derived :cpp:class:`Element`, the class object depends on the referenced :cpp:class:`Element` object. 83 84Three derived abstract classes are defined for :cpp:class:`Element`: 85 86.. cpp:namespace-pop:: 87 88.. cpp:namespace-push:: pw::clock_tree 89 90* :cpp:class:`ElementBlocking` for clock tree elements that might block when acquired or released. 91 Acquiring or releasing such a clock tree element might fail. 92* :cpp:class:`ElementNonBlockingCannotFail` for clock tree elements that will not block when 93 acquired or released. Acquiring or releasing such a clock tree element will always succeed. 94* :cpp:class:`ElementNonBlockingMightFail` for clock tree elements that will not block when 95 acquired or released. Acquiring or releasing such a clock tree element might fail. 96 97:cpp:class:`ElementNonBlockingCannotFail` and :cpp:class:`ElementsNonBlockingMightFail` elements can 98be acquired from an interrupt context. 99 100All classes representing a clock tree element should be implemented as a template and accept 101:cpp:class:`ElementBlocking`, :cpp:class:`ElementNonBlockingCannotFail` or 102:cpp:class:`ElementNonBlockingMightFail` as a template argument. Only if it is known at compile time 103that a clock tree element can only be either blocking or non-blocking, one can directly derive the 104class from :cpp:class:`ElementBlocking` or :cpp:class:`ElementNonBlockingCannotFail` / 105:cpp:class:`ElementNonBlockingMightFail`, respectively. 106 107.. cpp:namespace-pop:: 108 109.. cpp:namespace-push:: pw::clock_tree::ElementController 110 111For 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()``. 112 113.. cpp:namespace-pop:: 114 115--------------- 116Synchronization 117--------------- 118.. cpp:namespace-push:: pw::clock_tree 119 120The clock tree class uses a mutex to serialize access to :cpp:class:`ElementBlocking` clock tree 121elements, and uses an interrupt spin lock to serialize access to 122:cpp:class:`ElementNonBlockingCannotFail` and :cpp:class:`ElementNonBlockingMightFail` clock tree 123elements. :cpp:class:`ElementBlocking` clock tree elements and 124:cpp:class:`ElementNonBlockingCannotFail` / :cpp:class:`ElementNonBlockingMightFail` clock tree 125elements are not serialized with each other, while :cpp:class:`ElementNonBlockingCannotFail` and 126:cpp:class:`ElementNonBlockingMightFail` are serialized with each other. 127 128.. cpp:namespace-pop:: 129 130.. toctree:: 131 :hidden: 132 :maxdepth: 1 133 134 examples 135 api 136 implementations 137