xref: /aosp_15_r20/external/pigweed/pw_clock_tree/examples.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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