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_div_4(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_div_4, g_frg0Config_BOARD_BOOTCLOCKRUN);
34
35 // Define clock source selector FLEXCOMM0
36 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoSelectorNonBlocking flexcomm_0(
37 frg_0, kFRG_to_FLEXCOMM0, kNONE_to_FLEXCOMM0);
38
39 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Flexcomm0]
40
41 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-i3c0]
42
43 // Define FRO_DIV_8 clock source
44 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoFro fro_div_8(kCLOCK_FroDiv8OutEn);
45
46 // Define clock source selector I3C01FCLKSEL
47 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoSelectorNonBlocking i3c0_selector(
48 fro_div_8, kFRO_DIV8_to_I3C_CLK, kNONE_to_I3C_CLK);
49
50 // Define clock divider I3C01FCLKDIV
51 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoDividerNonBlocking i3c0_divider(
52 i3c0_selector, kCLOCK_DivI3cClk, 12);
53
54 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-i3c0]
55
56 // DOCSTAG:
57 // [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-ClockSourceNoOp]
58
59 // Need to define `ClockSourceNoOp` clock tree element to satisfy dependency for
60 // `ClockMcuxpressoMclk` or `ClockMcuxpressoClkIn` class.
61 PW_CONSTINIT pw::clock_tree::ClockSourceNoOp clock_source_no_op;
62
63 // DOCSTAG:
64 // [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-ClockSourceNoOp]
65
66 // inclusive-language: disable
67 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Ctimer0]
68
69 // Define Master clock
70 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoMclkNonBlocking mclk(
71 clock_source_no_op, 19200000);
72
73 // Define clock selector CTIMER0
74 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoSelectorNonBlocking ctimer_0(
75 mclk, kMASTER_CLK_to_CTIMER0, kNONE_to_CTIMER0);
76
77 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-Ctimer0]
78 // inclusive-language: enable
79
80 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-LpOsc]
81
82 // Define Low-Power Oscillator
83 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoLpOsc lp_osc_clk;
84
85 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-LpOsc]
86
87 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-AudioPll]
88
89 // Define ClkIn pin clock source
90 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoClkInNonBlocking clk_in(
91 clock_source_no_op, 19200000);
92
93 // Define audio PLL configuration with ClkIn pin as clock source
94 const clock_audio_pll_config_t kAudioPllConfig = {
95 .audio_pll_src = kCLOCK_AudioPllXtalIn, /* OSC clock */
96 .numerator =
97 0, /* Numerator of the Audio PLL fractional loop divider is 0 */
98 .denominator =
99 1000, /* Denominator of the Audio PLL fractional loop divider is 1 */
100 .audio_pll_mult = kCLOCK_AudioPllMult16 /* Divide by 16 */
101 };
102
103 // Define Audio PLL sourced by ClkIn pin clock source
104 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoAudioPllNonBlocking audio_pll(
105 clk_in, kAudioPllConfig, 18);
106
107 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-AudioPll]
108
109 // DOCSTAG:
110 // [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-AudioPllBypass]
111
112 // Define Audio PLL in bypass mode sourced by FRO_DIV_8 clock source
113 PW_CONSTINIT pw::clock_tree::ClockMcuxpressoAudioPllNonBlocking
114 audio_pll_bypass(fro_div_8, kCLOCK_AudioPllFroDiv8Clk);
115
116 // DOCSTAG:
117 // [pw_clock_tree_mcuxpresso-examples-ClockTreeElementDefs-AudioPllBypass]
118
119 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeDef]
120
121 // Create the clock tree
122 pw::clock_tree::ClockTree clock_tree;
123
124 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-ClockTreeDef]
125
TEST(ClockTreeMcuxpresso,UseExample)126 TEST(ClockTreeMcuxpresso, UseExample) {
127 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-UseExample]
128
129 // Enable the low-power oscillator
130 clock_tree.Acquire(lp_osc_clk);
131
132 // Enable the i3c0_divider
133 clock_tree.Acquire(i3c0_divider);
134
135 // Change the i3c0_divider value
136 clock_tree.SetDividerValue(i3c0_divider, 24);
137
138 // Disable the low-power oscillator
139 clock_tree.Release(lp_osc_clk);
140
141 // DOCSTAG: [pw_clock_tree_mcuxpresso-examples-UseExample]
142 }
143
TEST(ClockTreeMcuxpresso,AudioPll)144 TEST(ClockTreeMcuxpresso, AudioPll) {
145 clock_tree.Acquire(audio_pll);
146 clock_tree.Release(audio_pll);
147 }
148
TEST(ClockTreeMcuxpresso,AudioPllBypass)149 TEST(ClockTreeMcuxpresso, AudioPllBypass) {
150 clock_tree.Acquire(audio_pll_bypass);
151 clock_tree.Release(audio_pll_bypass);
152 }
153