.. _module-pw_clock_tree-examples: -------- Examples -------- .. pigweed-module-subpage:: :name: pw_clock_tree .. grid:: 2 .. grid-item-card:: :octicon:`code-square` Integration into device driver :link: module-pw_clock_tree-example-device_driver :link-type: ref :class-item: sales-pitch-cta-primary Example that shows how to integrate the clock tree functionality into a device driver. .. grid-item-card:: :octicon:`code-square` Clock tree usage :link: module-pw_clock_tree-example-clock_tree_usage :link-type: ref :class-item: sales-pitch-cta-secondary Example that shows how to define platform specific clock tree elements and how to interact with them to manage clocks of an embedded system. .. _module-pw_clock_tree-example-device_driver: Clock tree integration into device drivers ========================================== The example below shows how the clock tree functionality can get integrated into a new device driver that requires that a clock tree abstraction is present in the system. .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-IntegrationIntoDeviceDriversClassDef] :end-before: [pw_clock_tree-examples-IntegrationIntoDeviceDriversClassDef] .. _module-pw_clock_tree-example-clock_tree_usage: Definition and use of clock tree elements ========================================= For the example below we use a clock tree with two clock sources ``clock_a`` and ``clock_b``. ``clock_a`` can be selected as an input source by ``clock_selector_c``, and ``clock_b`` is an input into divider ``clock_divider_d``, which can be selected as an alternative input source by ``clock_selector_c``. .. mermaid:: flowchart LR A(clock_a) -..-> C(clock_selector_c) B(clock_b)--> D(clock_divider_d) D -..-> C .. cpp:namespace-push:: pw::clock_tree::Element Derived ``ClockSourceExample`` class template that overrides :cpp:func:`DoEnable` and :cpp:func:`DoDisable` methods. .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-ClockSourceExampleDef] :end-before: [pw_clock_tree-examples-ClockSourceExampleDef] Derived ``ClockDividerExample`` class template that overrides :cpp:func:`DoEnable` method. .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-ClockDividerExampleDef] :end-before: [pw_clock_tree-examples-ClockDividerExampleDef] Derived ``ClockSelectorExample`` class template that overrides :cpp:func:`DoEnable` and :cpp:func:`DoDisable` methods, and defines the ``SetSource`` method to allow the clock selector to change from one dependent source to another source. If the dependent source of a clock selector doesn't change at any point, one doesn't need to implement a method like ``SetSource``. .. cpp:namespace-pop:: .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-ClockSelectorExampleDef] :end-before: [pw_clock_tree-examples-ClockSelectorExampleDef] .. cpp:namespace-push:: pw::clock_tree Derived ``ClockTreeSetSource`` class that provides ``SetSource`` method to allow to change the source a clock selector depends on. If ``ClockSelectorExample`` wouldn't provide the ``SetSource`` method, one could use the :cpp:class:`ClockTree` class directly in the example below. .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-ClockTreeSetSourcesExampleDef] :end-before: [pw_clock_tree-examples-ClockTreeSetSourcesExampleDef] Declare the :cpp:class:`ClockTree` class object. .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-ClockTreeDec] :end-before: [pw_clock_tree-examples-ClockTreeDec] Declare the clock tree elements. ``clock_selector_c`` depends on ``clock_a``, and ``clock_divider_d`` depends on ``clock_b``. .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-ClockTreeElementsDec] :end-before: [pw_clock_tree-examples-ClockTreeElementsDec] Acquire a reference to ``clock_selector_c``, which will acquire a reference to the dependent source ``clock_a``. When the reference to ``clock_a`` gets acquired, ``clock_a`` gets enabled. Once the reference to ``clock_a`` has been acquired and it is enabled, ``clock_selector_c`` gets enabled. .. mermaid:: flowchart LR A(clock_A) -->C(clock_selector_c) B(clock_B)--> D(clock_divider_d) D -..-> C style A fill:#0f0,stroke:#333,stroke-width:4px style C fill:#0f0,stroke:#333,stroke-width:4px style B fill:#f00,stroke:#333,stroke-width:4px style D fill:#f00,stroke:#333,stroke-width:4px .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-AcquireClockSelectorC] :end-before: [pw_clock_tree-examples-AcquireClockSelectorC] Change the dependent source of ``clock_selector_c`` from ``clock_a`` to ``clock_divider_d`` while the ``clock_selector_c`` is enabled. Before ``clock_divider_d`` can be configured as the new dependent source, a reference to ``clock_divider_d`` will need to get acquired, which will acquire a reference to ``clock_b`` and enable ``clock_b`` before ``clock_divider_d`` gets enabled. Once the dependent source has been changed from ``clock_a`` to ``clock_divider_d``, the reference to ``clock_a`` will get released, which will disable ``clock_a``. .. mermaid:: flowchart LR A(clock_A) -..->C(clock_selector_c) B(clock_B)--> D(clock_divider_d) D --> C style A fill:#f00,stroke:#333,stroke-width:4px style C fill:#0f0,stroke:#333,stroke-width:4px style B fill:#0f0,stroke:#333,stroke-width:4px style D fill:#0f0,stroke:#333,stroke-width:4px .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-ChangeClockSelectorCDependentSource] :end-before: [pw_clock_tree-examples-ChangeClockSelectorCDependentSource] Set the clock divider value while the ``clock_divider_d`` is enabled. .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-SetClockDividerDValue] :end-before: [pw_clock_tree-examples-SetClockDividerDValue] Release the reference to the ``clock_selector_c``, which will disable ``clock_selector_c``, and then release the reference to ``clock_divider_d``. Then ``clock_divider_d`` will get disabled before it releases its reference to ``clock_b`` that gets disabled afterward. At this point all clock tree elements are disabled. .. literalinclude:: examples.cc :language: cpp :linenos: :start-after: [pw_clock_tree-examples-ReleaseClockSelectorC] :end-before: [pw_clock_tree-examples-ReleaseClockSelectorC]