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