1.. _module-pw_clock_tree-examples: 2 3-------- 4Examples 5-------- 6.. pigweed-module-subpage:: 7 :name: pw_clock_tree 8 9.. grid:: 2 10 11 .. grid-item-card:: :octicon:`code-square` Integration into device driver 12 :link: module-pw_clock_tree-example-device_driver 13 :link-type: ref 14 :class-item: sales-pitch-cta-primary 15 16 Example that shows how to integrate the clock tree functionality 17 into a device driver. 18 19 .. grid-item-card:: :octicon:`code-square` Clock tree usage 20 :link: module-pw_clock_tree-example-clock_tree_usage 21 :link-type: ref 22 :class-item: sales-pitch-cta-secondary 23 24 Example that shows how to define platform specific clock tree elements 25 and how to interact with them to manage clocks of an embedded system. 26 27 28.. _module-pw_clock_tree-example-device_driver: 29 30Clock tree integration into device drivers 31========================================== 32 33The example below shows how the clock tree functionality can get integrated into a new 34device driver that requires that a clock tree abstraction is present in the system. 35 36.. literalinclude:: examples.cc 37 :language: cpp 38 :linenos: 39 :start-after: [pw_clock_tree-examples-IntegrationIntoDeviceDriversClassDef] 40 :end-before: [pw_clock_tree-examples-IntegrationIntoDeviceDriversClassDef] 41 42 43.. _module-pw_clock_tree-example-clock_tree_usage: 44 45Definition and use of clock tree elements 46========================================= 47 48For the example below we use a clock tree with two clock sources ``clock_a`` and ``clock_b``. 49``clock_a`` can be selected as an input source by ``clock_selector_c``, and ``clock_b`` is an input into 50divider ``clock_divider_d``, which can be selected as an alternative input source by 51``clock_selector_c``. 52 53.. mermaid:: 54 55 flowchart LR 56 A(clock_a) -..-> C(clock_selector_c) 57 B(clock_b)--> D(clock_divider_d) 58 D -..-> C 59 60.. cpp:namespace-push:: pw::clock_tree::Element 61 62Derived ``ClockSourceExample`` class template that overrides 63:cpp:func:`DoEnable` and :cpp:func:`DoDisable` methods. 64 65.. literalinclude:: examples.cc 66 :language: cpp 67 :linenos: 68 :start-after: [pw_clock_tree-examples-ClockSourceExampleDef] 69 :end-before: [pw_clock_tree-examples-ClockSourceExampleDef] 70 71Derived ``ClockDividerExample`` class template that overrides 72:cpp:func:`DoEnable` method. 73 74.. literalinclude:: examples.cc 75 :language: cpp 76 :linenos: 77 :start-after: [pw_clock_tree-examples-ClockDividerExampleDef] 78 :end-before: [pw_clock_tree-examples-ClockDividerExampleDef] 79 80Derived ``ClockSelectorExample`` class template that overrides 81:cpp:func:`DoEnable` and :cpp:func:`DoDisable` methods, 82and defines the ``SetSource`` method to allow the clock selector to change from one dependent source to 83another source. If the dependent source of a clock selector doesn't change at any point, one doesn't 84need to implement a method like ``SetSource``. 85 86.. cpp:namespace-pop:: 87 88.. literalinclude:: examples.cc 89 :language: cpp 90 :linenos: 91 :start-after: [pw_clock_tree-examples-ClockSelectorExampleDef] 92 :end-before: [pw_clock_tree-examples-ClockSelectorExampleDef] 93 94.. cpp:namespace-push:: pw::clock_tree 95 96Derived ``ClockTreeSetSource`` class that provides ``SetSource`` method to allow to change the 97source a clock selector depends on. If ``ClockSelectorExample`` wouldn't provide the ``SetSource`` 98method, one could use the :cpp:class:`ClockTree` class directly in the example below. 99 100.. literalinclude:: examples.cc 101 :language: cpp 102 :linenos: 103 :start-after: [pw_clock_tree-examples-ClockTreeSetSourcesExampleDef] 104 :end-before: [pw_clock_tree-examples-ClockTreeSetSourcesExampleDef] 105 106Declare the :cpp:class:`ClockTree` class object. 107 108.. literalinclude:: examples.cc 109 :language: cpp 110 :linenos: 111 :start-after: [pw_clock_tree-examples-ClockTreeDec] 112 :end-before: [pw_clock_tree-examples-ClockTreeDec] 113 114Declare the clock tree elements. 115``clock_selector_c`` depends on ``clock_a``, and ``clock_divider_d`` depends on ``clock_b``. 116 117.. literalinclude:: examples.cc 118 :language: cpp 119 :linenos: 120 :start-after: [pw_clock_tree-examples-ClockTreeElementsDec] 121 :end-before: [pw_clock_tree-examples-ClockTreeElementsDec] 122 123Acquire a reference to ``clock_selector_c``, which will acquire a reference to the dependent source 124``clock_a``. When the reference to ``clock_a`` gets acquired, ``clock_a`` gets enabled. Once the 125reference to ``clock_a`` has been acquired and it is enabled, ``clock_selector_c`` gets enabled. 126 127.. mermaid:: 128 129 flowchart LR 130 A(clock_A) -->C(clock_selector_c) 131 B(clock_B)--> D(clock_divider_d) 132 D -..-> C 133 style A fill:#0f0,stroke:#333,stroke-width:4px 134 style C fill:#0f0,stroke:#333,stroke-width:4px 135 style B fill:#f00,stroke:#333,stroke-width:4px 136 style D fill:#f00,stroke:#333,stroke-width:4px 137 138.. literalinclude:: examples.cc 139 :language: cpp 140 :linenos: 141 :start-after: [pw_clock_tree-examples-AcquireClockSelectorC] 142 :end-before: [pw_clock_tree-examples-AcquireClockSelectorC] 143 144Change the dependent source of ``clock_selector_c`` from ``clock_a`` to ``clock_divider_d`` while 145the ``clock_selector_c`` is enabled. Before ``clock_divider_d`` can be configured as the new 146dependent source, a reference to ``clock_divider_d`` will need to get acquired, which will acquire 147a reference to ``clock_b`` and enable ``clock_b`` before ``clock_divider_d`` gets enabled. 148Once the dependent source has been changed from ``clock_a`` to ``clock_divider_d``, the reference to 149``clock_a`` will get released, which will disable ``clock_a``. 150 151.. mermaid:: 152 153 flowchart LR 154 A(clock_A) -..->C(clock_selector_c) 155 B(clock_B)--> D(clock_divider_d) 156 D --> C 157 style A fill:#f00,stroke:#333,stroke-width:4px 158 style C fill:#0f0,stroke:#333,stroke-width:4px 159 style B fill:#0f0,stroke:#333,stroke-width:4px 160 style D fill:#0f0,stroke:#333,stroke-width:4px 161 162.. literalinclude:: examples.cc 163 :language: cpp 164 :linenos: 165 :start-after: [pw_clock_tree-examples-ChangeClockSelectorCDependentSource] 166 :end-before: [pw_clock_tree-examples-ChangeClockSelectorCDependentSource] 167 168Set the clock divider value while the ``clock_divider_d`` is enabled. 169 170.. literalinclude:: examples.cc 171 :language: cpp 172 :linenos: 173 :start-after: [pw_clock_tree-examples-SetClockDividerDValue] 174 :end-before: [pw_clock_tree-examples-SetClockDividerDValue] 175 176Release the reference to the ``clock_selector_c``, which will disable ``clock_selector_c``, and 177then release the reference to ``clock_divider_d``. Then ``clock_divider_d`` will get disabled before 178it releases its reference to ``clock_b`` that gets disabled afterward. At this point all clock 179tree elements are disabled. 180 181.. literalinclude:: examples.cc 182 :language: cpp 183 :linenos: 184 :start-after: [pw_clock_tree-examples-ReleaseClockSelectorC] 185 :end-before: [pw_clock_tree-examples-ReleaseClockSelectorC] 186