xref: /aosp_15_r20/external/pigweed/pw_clock_tree_mcuxpresso/examples.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_clock_tree_mcuxpresso/clock_tree.h"
16 
17 // Test headers
18 #include "pw_unit_test/framework.h"
19 
20 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Flexcomm0]
21 
22 // Define FRO_DIV_4 clock source
23 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoFro fro_div4(kCLOCK_FroDiv4OutEn);
24 
25 // Define FRG0 configuration
26 const clock_frg_clk_config_t g_frg0Config_BOARD_BOOTCLOCKRUN = {
27     .num = 0,
28     .sfg_clock_src = _clock_frg_clk_config::kCLOCK_FrgFroDiv4,
29     .divider = 255U,
30     .mult = 144};
31 
32 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoFrgNonBlocking frg_0(
33     fro_div4, g_frg0Config_BOARD_BOOTCLOCKRUN);
34 
35 // Define clock source selector FLEXCOMM0
36 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoSelectorNonBlocking
37     flexcomm_selector_0(frg_0, kFRG_to_FLEXCOMM0, kNONE_to_FLEXCOMM0);
38 
39 // Define clock source clock ip name kCLOCK_Flexcomm0
40 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoClockIpNonBlocking flexcomm_0(
41     flexcomm_selector_0, kCLOCK_Flexcomm0);
42 
43 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Flexcomm0]
44 
45 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-fro_div8]
46 
47 // Define FRO_DIV8 clock source
48 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoFro fro_div8(kCLOCK_FroDiv8OutEn);
49 
50 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-fro_div8]
51 
52 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-i3c0]
53 
54 // Define clock source selector I3C01FCLKSEL
55 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoSelectorNonBlocking i3c0_selector(
56     fro_div8, kFRO_DIV8_to_I3C_CLK, kNONE_to_I3C_CLK);
57 
58 // Define clock divider I3C01FCLKDIV
59 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoDividerNonBlocking i3c0_divider(
60     i3c0_selector, kCLOCK_DivI3cClk, 12);
61 
62 // Define clock source clock ip name kCLOCK_I3c0
63 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoClockIpNonBlocking i3c0(
64     i3c0_divider, kCLOCK_I3c0);
65 
66 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-i3c0]
67 
68 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClkTreeElemDefs-ClockSourceNoOp]
69 
70 // Need to define `ClockSourceNoOp` clock tree element to satisfy dependency for
71 // `ClockMcuxpressoMclk` or `ClockMcuxpressoClkIn` class.
72 PW_CONSTINIT pw::clock_tree::ClockSourceNoOp clock_source_no_op;
73 
74 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClkTreeElemDefs-ClockSourceNoOp]
75 
76 // inclusive-language: disable
77 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Ctimer0]
78 
79 // Define Master clock
80 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoMclkNonBlocking mclk(
81     clock_source_no_op, 19200000);
82 
83 // Define clock selector CTIMER0
84 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoSelectorNonBlocking
85     ctimer_selector_0(mclk, kMASTER_CLK_to_CTIMER0, kNONE_to_CTIMER0);
86 
87 // Define clock source clock ip name kCLOCK_Ct32b0
88 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoClockIpNonBlocking ctimer_0(
89     ctimer_selector_0, kCLOCK_Ct32b0);
90 
91 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Ctimer0]
92 // inclusive-language: enable
93 
94 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-LpOsc]
95 
96 // Define Low-Power Oscillator
97 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoLpOsc lp_osc_clk;
98 
99 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-LpOsc]
100 
101 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElemDefs-AudioPll]
102 
103 // Define ClkIn pin clock source
104 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoClkInNonBlocking clk_in(
105     clock_source_no_op, 19200000);
106 
107 // Define audio PLL configuration with ClkIn pin as clock source
108 const clock_audio_pll_config_t kAudioPllConfig = {
109     .audio_pll_src = kCLOCK_AudioPllXtalIn, /* OSC clock */
110     .numerator =
111         0, /* Numerator of the Audio PLL fractional loop divider is 0 */
112     .denominator =
113         1000, /* Denominator of the Audio PLL fractional loop divider is 1 */
114     .audio_pll_mult = kCLOCK_AudioPllMult16 /* Divide by 16 */
115 };
116 
117 // Define Audio PLL sourced by ClkIn pin clock source
118 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoAudioPllNonBlocking audio_pll(
119     clk_in, kAudioPllConfig, 18);
120 
121 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElemDefs-AudioPll]
122 
123 // DOCSTAG:[pw_clock_tree_mcuxpresso-examples-ClockTreeElemDefs-AudioPllBypass]
124 
125 // Define Audio PLL in bypass mode sourced by FRO_DIV8 clock source
126 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoAudioPllNonBlocking
127     audio_pll_bypass(fro_div8, kCLOCK_AudioPllFroDiv8Clk);
128 
129 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElemDefs-AudioPllBypass]
130 
131 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoRtcNonBlocking rtc(
132     clock_source_no_op);
133 
134 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeDef]
135 
136 // Create the clock tree
137 pw::clock_tree::ClockTree clock_tree;
138 
139 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeDef]
140 
TEST(ClockTreeMcuxpresso,UseExample)141 TEST(ClockTreeMcuxpresso, UseExample) {
142   // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-UseExample]
143 
144   // Enable the low-power oscillator
145   clock_tree.Acquire(lp_osc_clk);
146 
147   // Enable the i3c0
148   clock_tree.Acquire(i3c0);
149 
150   // Change the i3c0_divider value
151   clock_tree.SetDividerValue(i3c0_divider, 24);
152 
153   // Enable the flexcomm0 interface
154   clock_tree.Acquire(flexcomm_0);
155 
156   // Disable the low-power oscillator
157   clock_tree.Release(lp_osc_clk);
158 
159   // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-UseExample]
160 }
161 
TEST(ClockTreeMcuxpresso,AudioPll)162 TEST(ClockTreeMcuxpresso, AudioPll) {
163   // DOCSTAG:[pw_clock_tree_mcuxpresso-examples-Use-AudioPll]
164 
165   // Enable audio PLL. We use AcquireWith to ensure that FRO_DIV8
166   // is enabled while enabling the audio PLL. If FRO_DIV8 wasn't enabled
167   // before, it will only be enabled while configuring the audio PLL
168   // and be disabled afterward to save power.
169   clock_tree.AcquireWith(audio_pll, fro_div8);
170 
171   // Do something while audio PLL is enabled.
172 
173   // Release audio PLL to save power.
174   clock_tree.Release(audio_pll);
175   // DOCSTAG:[pw_clock_tree_mcuxpresso-examples-Use-AudioPll]
176 }
177 
TEST(ClockTreeMcuxpresso,AudioPllBypass)178 TEST(ClockTreeMcuxpresso, AudioPllBypass) {
179   clock_tree.Acquire(audio_pll_bypass);
180   clock_tree.Release(audio_pll_bypass);
181 }
182 
TEST(ClockTreeMcuxpresso,Rtc)183 TEST(ClockTreeMcuxpresso, Rtc) {
184   clock_tree.Acquire(rtc);
185   clock_tree.Release(rtc);
186 }
187