1.. _module-pw_clock_tree_mcuxpresso: 2 3=========================== 4pw_clock_tree_mcuxpresso 5=========================== 6.. pigweed-module:: 7 :name: pw_clock_tree_mcuxpresso 8 9``pw_clock_tree_mcuxpresso`` implements the ``pw_clock_tree`` interface using the 10NXP MCUXpresso SDK. It provides class implementations for the following clock tree elements 11that can be directly instantiated: 12 13.. inclusive-language: disable 14 15* Free-Running Oscillator (FRO) 16* 32 kHz RTC Oscillator 17* Low-power Oscillator 18* Master Clock 19* External Clock Input as clock source for SYSOSCBYPASS clock selector to generate OSC_CLK 20* Fractional Rate Generator (FRG) for Flexcomm Interfaces 21* Clock Source Selector 22* Clock Divider 23* Audio PLL 24* RTC 25* ClockIp 26 27.. inclusive-language: enable 28 29.. cpp:namespace-push:: pw::clock_tree::Element 30 31Other clock tree components such as PLLs can be instantiated by deriving custom class implementations 32from the abstract class :cpp:class:`DependentElement` and overwriting :cpp:func:`DoEnable` and 33:cpp:func:`DoDisable` methods. 34 35.. cpp:namespace-pop:: 36 37.. cpp:namespace-push:: pw::clock_tree::ClockTree 38 39When enabling clock tree elements sourced from the audio PLL or the SYS PLL it is necessary 40to use the :cpp:func:`AcquireWith` method. 41 42.. cpp:namespace-pop:: 43 44Examples 45======== 46 47---------------------------------------- 48End-to-end Mcuxpresso clock tree example 49---------------------------------------- 50 51Definition of clock tree elements: 52 53.. mermaid:: 54 55 flowchart LR 56 A(fro_div_4) -->B(frg_0) 57 B-->C(flexcomm_selector_0) 58 C-->D(flexcomm_0) 59 style A fill:#0f0,stroke:#333,stroke-width:2px 60 style B fill:#0f0,stroke:#333,stroke-width:2px 61 style C fill:#0f0,stroke:#333,stroke-width:2px 62 style D fill:#0f0,stroke:#333,stroke-width:2px 63 64.. cpp:namespace-push:: pw::clock_tree::ClockTree 65 66Please note that the clock tree element ``flexcomm_0`` is only required if the SDK is compiled with 67the define ``FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL`` set, and that the connection between 68``flexcomm_selector_0`` and ``flexcomm_0`` represents only a logical dependency connection between 69the two clock tree elements. The ``flexcomm_0`` :cpp:class:`ClockMcuxpressoClockIp` gates the register 70access to the ``Flexcomm 0`` IP block, but it doesn't gate the ``Flexcomm 0`` clock source itself. 71Nevertheless, to use ``Flexcomm 0`` the ``Flexcomm 0`` IP block and ``Flexcomm 0`` clock source need 72to be enabled, hence we established the dependency between ``flexcomm_selector_0`` and ``flexcomm_0``, 73so that enabling ``flexcomm_0`` enabled the ``Flexcomm 0`` IP block and clock source. 74 75.. cpp:namespace-pop:: 76 77.. literalinclude:: examples.cc 78 :language: cpp 79 :linenos: 80 :start-after: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Flexcomm0] 81 :end-before: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Flexcomm0] 82 83.. mermaid:: 84 85 flowchart LR 86 D(fro_div_8)--> E(i3c0_selector) 87 E --> F(i3c0_divider) 88 F --> G(i3c0) 89 style D fill:#f0f,stroke:#333,stroke-width:2px 90 style E fill:#f0f,stroke:#333,stroke-width:2px 91 style F fill:#f0f,stroke:#333,stroke-width:2px 92 style G fill:#f0f,stroke:#333,stroke-width:2px 93 94.. cpp:namespace-push:: pw::clock_tree::ClockTree 95 96Please note that the clock tree element ``i3c0`` is only required if the SDK is compiled with 97the define ``FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL`` set, and that the connection between 98``i3c0_selector`` and ``i3c0`` represents only a logical dependency connection between 99the two clock tree elements. The ``i3c0`` :cpp:class:`ClockMcuxpressoClockIp` gates the register 100access to the ``I3C`` IP block, but it doesn't gate the ``I3C`` clock source itself. 101Nevertheless, to use ``I3C`` the ``I3C`` IP block and ``I3C`` clock source need 102to be enabled, hence we established the dependency between ``i3c0_selector`` and ``i3c0``, 103so that enabling ``i3c0`` enabled the ``I3C`` IP block and clock source. 104 105.. cpp:namespace-pop:: 106 107.. literalinclude:: examples.cc 108 :language: cpp 109 :linenos: 110 :start-after: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-fro_div8] 111 :end-before: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-fro_div8] 112 113.. literalinclude:: examples.cc 114 :language: cpp 115 :linenos: 116 :start-after: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-i3c0] 117 :end-before: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-i3c0] 118 119.. mermaid:: 120 121 flowchart LR 122 G(mclk) --> H(ctimer_selector_0) 123 H --> I(ctimer_0) 124 style G fill:#0ff,stroke:#333,stroke-width:2px 125 style H fill:#0ff,stroke:#333,stroke-width:2px 126 style I fill:#0ff,stroke:#333,stroke-width:2px 127 128.. cpp:namespace-push:: pw::clock_tree::ClockTree 129 130Please note that the clock tree element ``ctimer_0`` is only required if the SDK is compiled with 131the define ``FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL`` set, and that the connection between 132``ctimer_selector_0`` and ``ctimer_0`` represents only a logical dependency connection between 133the two clock tree elements. The ``ctimer_0`` :cpp:class:`ClockMcuxpressoClockIp` gates the register 134access to the ``CTimer 0`` IP block, but it doesn't gate the ``CTimer 0`` clock source itself. 135Nevertheless, to use ``CTimer 0`` the ``CTimer 0`` IP block and ``CTimer 0`` clock source need 136to be enabled, hence we established the dependency between ``ctimer_selector_0`` and ``ctimer_0``, 137so that enabling ``ctimer_0`` enabled the ``CTimer 0`` IP block and clock source. 138 139.. cpp:namespace-pop:: 140 141.. literalinclude:: examples.cc 142 :language: cpp 143 :linenos: 144 :start-after: [pw_clock_tree_mcuxpresso-examples-ClkTreeElemDefs-ClockSourceNoOp] 145 :end-before: [pw_clock_tree_mcuxpresso-examples-ClkTreeElemDefs-ClockSourceNoOp] 146 147.. literalinclude:: examples.cc 148 :language: cpp 149 :linenos: 150 :start-after: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Ctimer0] 151 :end-before: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Ctimer0] 152 153.. mermaid:: 154 155 flowchart LR 156 I(lposc) 157 style I fill:#ff0,stroke:#333,stroke-width:2px 158 159.. literalinclude:: examples.cc 160 :language: cpp 161 :linenos: 162 :start-after: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-LpOsc] 163 :end-before: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-LpOsc] 164 165Definition of clock tree: 166 167.. literalinclude:: examples.cc 168 :language: cpp 169 :linenos: 170 :start-after: [pw_clock_tree_mcuxpresso-examples-ClockTreeDef] 171 :end-before: [pw_clock_tree_mcuxpresso-examples-ClockTreeDef] 172 173Example usage of ``clock_tree`` APIs: 174 175.. literalinclude:: examples.cc 176 :language: cpp 177 :linenos: 178 :start-after: [pw_clock_tree_mcuxpresso-examples-UseExample] 179 :end-before: [pw_clock_tree_mcuxpresso-examples-UseExample] 180 181------------------ 182Audio PLL examples 183------------------ 184 185.. cpp:namespace-push:: pw::clock_tree::ClockTree 186 187The :cpp:class:`ClockMcuxpressoAudioPll` can be configured in two different ways, 188either it can be configured where the audio PLL gets enabled, or it can be 189configured in bypass mode. 190 191The first example shows where :cpp:class:`ClockMcuxpressoAudioPll` enables the audio PLL 192and uses the ClkIn pin clock source as OSC clock source that feeds into the audio PLL 193logic. Since the audio PLL requires that the ``FRO_DIV8`` clock source is enabled when 194enabling the audio PLL, the :cpp:func:`AcquireWith` needs to be used that ensures 195that the ``FRO_DIV8`` clock is enabled when enabling the audio PLL. 196 197.. mermaid:: 198 199 flowchart LR 200 subgraph PLL [Audio PLL logic] 201 B(audio_pll_selctor) -.-> C(PLL) 202 C -.-> D(Phase Fraction divider) 203 end 204 A(clk_in) -->|as osc_clk| PLL 205 PLL --> E(audio_pfd_bypass_selector) 206 207 style A fill:#f0f,stroke:#333,stroke-width:2px 208 style E fill:#f0f,stroke:#333,stroke-width:2px 209 210Definition of clock tree: 211 212.. literalinclude:: examples.cc 213 :language: cpp 214 :linenos: 215 :start-after: [pw_clock_tree_mcuxpresso-examples-ClockTreeDef] 216 :end-before: [pw_clock_tree_mcuxpresso-examples-ClockTreeDef] 217 218Definition of audio PLL related clock tree elements: 219 220.. literalinclude:: examples.cc 221 :language: cpp 222 :linenos: 223 :start-after: [pw_clock_tree_mcuxpresso-examples-ClkTreeElemDefs-ClockSourceNoOp] 224 :end-before: [pw_clock_tree_mcuxpresso-examples-ClkTreeElemDefs-ClockSourceNoOp] 225 226.. literalinclude:: examples.cc 227 :language: cpp 228 :linenos: 229 :start-after: [pw_clock_tree_mcuxpresso-examples-ClockTreeElemDefs-AudioPll] 230 :end-before: [pw_clock_tree_mcuxpresso-examples-ClockTreeElemDefs-AudioPll] 231 232Definition of ``FRO_DIV8`` clock tree element: 233 234.. literalinclude:: examples.cc 235 :language: cpp 236 :linenos: 237 :start-after: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-fro_div8] 238 :end-before: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-fro_div8] 239 240Audio PLL clock tree element gets enabled and disabled. We use :cpp:func:`AcquireWith` 241to ensure that ``FRO_DIV8`` is enabled prior to configuring the audio PLL to a 242non-``FRO_DIV8`` clock source. 243 244.. literalinclude:: examples.cc 245 :language: cpp 246 :linenos: 247 :start-after: [pw_clock_tree_mcuxpresso-examples-Use-AudioPll] 248 :end-before: [pw_clock_tree_mcuxpresso-examples-Use-AudioPll] 249 250The second example shows where :cpp:class:`ClockMcuxpressoAudioPll` bypasses the audio PLL 251and uses ``FRO_DIV8 pin`` clock source. 252 253.. cpp:namespace-pop:: 254 255.. mermaid:: 256 257 flowchart LR 258 A(fro_div_8) --> B(audio_pfd_bypass_selector) 259 style A fill:#0ff,stroke:#333,stroke-width:2px 260 style B fill:#0ff,stroke:#333,stroke-width:2px 261 262.. literalinclude:: examples.cc 263 :language: cpp 264 :linenos: 265 :start-after: [pw_clock_tree_mcuxpresso-examples-ClockTreeElemDefs-AudioPllBypass] 266 :end-before: [pw_clock_tree_mcuxpresso-examples-ClockTreeElemDefs-AudioPllBypass] 267 268APIs 269==== 270 271------------------ 272ClockMcuxpressoFro 273------------------ 274.. doxygenclass:: pw::clock_tree::ClockMcuxpressoFro 275 :members: 276 277-------------------- 278ClockMcuxpressoLpOsc 279-------------------- 280.. doxygenclass:: pw::clock_tree::ClockMcuxpressoLpOsc 281 :members: 282 283------------------- 284ClockMcuxpressoMclk 285------------------- 286.. doxygenclass:: pw::clock_tree::ClockMcuxpressoMclk 287 :members: 288 289-------------------- 290ClockMcuxpressoClkIn 291-------------------- 292.. doxygenclass:: pw::clock_tree::ClockMcuxpressoClkIn 293 :members: 294 295------------------ 296ClockMcuxpressoFrg 297------------------ 298.. doxygenclass:: pw::clock_tree::ClockMcuxpressoFrg 299 :members: 300 301----------------------- 302ClockMcuxpressoSelector 303----------------------- 304.. doxygenclass:: pw::clock_tree::ClockMcuxpressoSelector 305 :members: 306 307---------------------- 308ClockMcuxpressoDivider 309---------------------- 310.. doxygenclass:: pw::clock_tree::ClockMcuxpressoDivider 311 :members: 312 313----------------------- 314ClockMcuxpressoAudioPll 315----------------------- 316.. doxygenclass:: pw::clock_tree::ClockMcuxpressoAudioPll 317 :members: 318 319------------------ 320ClockMcuxpressoRtc 321------------------ 322.. doxygenclass:: pw::clock_tree::ClockMcuxpressoRtc 323 :members: 324 325---------------------- 326ClockMcuxpressoClockIp 327---------------------- 328.. doxygenclass:: pw::clock_tree::ClockMcuxpressoClockIp 329 :members: 330