xref: /aosp_15_r20/external/pigweed/pw_clock_tree/examples.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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_assert/check.h"
16*61c4878aSAndroid Build Coastguard Worker #include "pw_clock_tree/clock_tree.h"
17*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
18*61c4878aSAndroid Build Coastguard Worker 
19*61c4878aSAndroid Build Coastguard Worker namespace examples {
20*61c4878aSAndroid Build Coastguard Worker 
EnableClock()21*61c4878aSAndroid Build Coastguard Worker static pw::Status EnableClock() {
22*61c4878aSAndroid Build Coastguard Worker   // Action to enable clock
23*61c4878aSAndroid Build Coastguard Worker   return pw::OkStatus();
24*61c4878aSAndroid Build Coastguard Worker }
25*61c4878aSAndroid Build Coastguard Worker 
DisableClock()26*61c4878aSAndroid Build Coastguard Worker static pw::Status DisableClock() {
27*61c4878aSAndroid Build Coastguard Worker   // Action to disable clock
28*61c4878aSAndroid Build Coastguard Worker   return pw::OkStatus();
29*61c4878aSAndroid Build Coastguard Worker }
30*61c4878aSAndroid Build Coastguard Worker 
EnableClockDivider(uint32_t,uint32_t)31*61c4878aSAndroid Build Coastguard Worker static pw::Status EnableClockDivider(uint32_t, uint32_t) {
32*61c4878aSAndroid Build Coastguard Worker   // Action to enable clock divider
33*61c4878aSAndroid Build Coastguard Worker   return pw::OkStatus();
34*61c4878aSAndroid Build Coastguard Worker }
35*61c4878aSAndroid Build Coastguard Worker 
SetSelector(uint32_t)36*61c4878aSAndroid Build Coastguard Worker static pw::Status SetSelector(uint32_t) {
37*61c4878aSAndroid Build Coastguard Worker   // Action to set selector
38*61c4878aSAndroid Build Coastguard Worker   return pw::OkStatus();
39*61c4878aSAndroid Build Coastguard Worker }
40*61c4878aSAndroid Build Coastguard Worker 
41*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_clock_tree-examples-ClockSourceExampleDef]
42*61c4878aSAndroid Build Coastguard Worker /// Class template implementing a clock source.
43*61c4878aSAndroid Build Coastguard Worker ///
44*61c4878aSAndroid Build Coastguard Worker /// Template argument `ElementType` can be of class `ElementBlocking`,
45*61c4878aSAndroid Build Coastguard Worker /// `ElementNonBlockingCannotFail` or
46*61c4878aSAndroid Build Coastguard Worker /// `ElementNonBlockingMightFail.`
47*61c4878aSAndroid Build Coastguard Worker template <typename ElementType>
48*61c4878aSAndroid Build Coastguard Worker class ClockSourceExample : public pw::clock_tree::ClockSource<ElementType> {
49*61c4878aSAndroid Build Coastguard Worker  private:
DoEnable()50*61c4878aSAndroid Build Coastguard Worker   pw::Status DoEnable() final { return EnableClock(); }
51*61c4878aSAndroid Build Coastguard Worker 
DoDisable()52*61c4878aSAndroid Build Coastguard Worker   pw::Status DoDisable() final { return DisableClock(); }
53*61c4878aSAndroid Build Coastguard Worker };
54*61c4878aSAndroid Build Coastguard Worker using ClockSourceExampleNonBlocking =
55*61c4878aSAndroid Build Coastguard Worker     ClockSourceExample<pw::clock_tree::ElementNonBlockingCannotFail>;
56*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_clock_tree-examples-ClockSourceExampleDef]
57*61c4878aSAndroid Build Coastguard Worker 
58*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_clock_tree-examples-ClockDividerExampleDef]
59*61c4878aSAndroid Build Coastguard Worker /// Class template implementing a clock divider.
60*61c4878aSAndroid Build Coastguard Worker ///
61*61c4878aSAndroid Build Coastguard Worker /// Template argument `ElementType` can be of class `ElementBlocking`,
62*61c4878aSAndroid Build Coastguard Worker /// `ElementNonBlockingCannotFail` or
63*61c4878aSAndroid Build Coastguard Worker /// `ElementNonBlockingMightFail.`
64*61c4878aSAndroid Build Coastguard Worker template <typename ElementType>
65*61c4878aSAndroid Build Coastguard Worker class ClockDividerExample
66*61c4878aSAndroid Build Coastguard Worker     : public pw::clock_tree::ClockDividerElement<ElementType> {
67*61c4878aSAndroid Build Coastguard Worker  public:
ClockDividerExample(ElementType & source,uint32_t divider_name,uint32_t divider)68*61c4878aSAndroid Build Coastguard Worker   constexpr ClockDividerExample(ElementType& source,
69*61c4878aSAndroid Build Coastguard Worker                                 uint32_t divider_name,
70*61c4878aSAndroid Build Coastguard Worker                                 uint32_t divider)
71*61c4878aSAndroid Build Coastguard Worker       : pw::clock_tree::ClockDividerElement<ElementType>(source, divider),
72*61c4878aSAndroid Build Coastguard Worker         divider_name_(divider_name) {}
73*61c4878aSAndroid Build Coastguard Worker 
74*61c4878aSAndroid Build Coastguard Worker  private:
DoEnable()75*61c4878aSAndroid Build Coastguard Worker   pw::Status DoEnable() final {
76*61c4878aSAndroid Build Coastguard Worker     return EnableClockDivider(divider_name_, this->divider());
77*61c4878aSAndroid Build Coastguard Worker   }
78*61c4878aSAndroid Build Coastguard Worker 
79*61c4878aSAndroid Build Coastguard Worker   uint32_t divider_name_;
80*61c4878aSAndroid Build Coastguard Worker };
81*61c4878aSAndroid Build Coastguard Worker using ClockDividerExampleNonBlocking =
82*61c4878aSAndroid Build Coastguard Worker     ClockDividerExample<pw::clock_tree::ElementNonBlockingCannotFail>;
83*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_clock_tree-examples-ClockDividerExampleDef]
84*61c4878aSAndroid Build Coastguard Worker 
85*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_clock_tree-examples-ClockSelectorExampleDef]
86*61c4878aSAndroid Build Coastguard Worker /// Class template implementing a clock selector.
87*61c4878aSAndroid Build Coastguard Worker ///
88*61c4878aSAndroid Build Coastguard Worker /// Template argument `ElementType` can be of class `ElementBlocking`,
89*61c4878aSAndroid Build Coastguard Worker /// `ElementNonBlockingCannotFail` or
90*61c4878aSAndroid Build Coastguard Worker /// `ElementNonBlockingMightFail.`
91*61c4878aSAndroid Build Coastguard Worker template <typename ElementType>
92*61c4878aSAndroid Build Coastguard Worker class ClockSelectorExample
93*61c4878aSAndroid Build Coastguard Worker     : public pw::clock_tree::DependentElement<ElementType> {
94*61c4878aSAndroid Build Coastguard Worker  public:
ClockSelectorExample(ElementType & source,uint32_t selector,uint32_t selector_enable,uint32_t selector_disable)95*61c4878aSAndroid Build Coastguard Worker   constexpr ClockSelectorExample(ElementType& source,
96*61c4878aSAndroid Build Coastguard Worker                                  uint32_t selector,
97*61c4878aSAndroid Build Coastguard Worker                                  uint32_t selector_enable,
98*61c4878aSAndroid Build Coastguard Worker                                  uint32_t selector_disable)
99*61c4878aSAndroid Build Coastguard Worker       : pw::clock_tree::DependentElement<ElementType>(source),
100*61c4878aSAndroid Build Coastguard Worker         selector_(selector),
101*61c4878aSAndroid Build Coastguard Worker         selector_enable_(selector_enable),
102*61c4878aSAndroid Build Coastguard Worker         selector_disable_(selector_disable) {}
103*61c4878aSAndroid Build Coastguard Worker 
SetSource(ElementType & new_source,uint32_t new_selector_enable)104*61c4878aSAndroid Build Coastguard Worker   pw::Status SetSource(ElementType& new_source, uint32_t new_selector_enable) {
105*61c4878aSAndroid Build Coastguard Worker     // Store a copy of the current `selector_enable_` variable in case
106*61c4878aSAndroid Build Coastguard Worker     // that the update fails, since we need to update `selector_enable_`
107*61c4878aSAndroid Build Coastguard Worker     // to its new value, since `UpdateSource` might call the `DoEnable`
108*61c4878aSAndroid Build Coastguard Worker     // member function.
109*61c4878aSAndroid Build Coastguard Worker     uint32_t old_selector_enable = selector_enable_;
110*61c4878aSAndroid Build Coastguard Worker     selector_enable_ = new_selector_enable;
111*61c4878aSAndroid Build Coastguard Worker     const bool kPermitChangeIfInUse = true;
112*61c4878aSAndroid Build Coastguard Worker     pw::Status status = this->UpdateSource(new_source, kPermitChangeIfInUse);
113*61c4878aSAndroid Build Coastguard Worker     if (!status.ok()) {
114*61c4878aSAndroid Build Coastguard Worker       // Restore the old selector value.
115*61c4878aSAndroid Build Coastguard Worker       selector_enable_ = old_selector_enable;
116*61c4878aSAndroid Build Coastguard Worker     }
117*61c4878aSAndroid Build Coastguard Worker 
118*61c4878aSAndroid Build Coastguard Worker     return status;
119*61c4878aSAndroid Build Coastguard Worker   }
120*61c4878aSAndroid Build Coastguard Worker 
121*61c4878aSAndroid Build Coastguard Worker  private:
DoEnable()122*61c4878aSAndroid Build Coastguard Worker   pw::Status DoEnable() final { return SetSelector(selector_enable_); }
DoDisable()123*61c4878aSAndroid Build Coastguard Worker   pw::Status DoDisable() final { return SetSelector(selector_disable_); }
124*61c4878aSAndroid Build Coastguard Worker 
125*61c4878aSAndroid Build Coastguard Worker   uint32_t selector_;
126*61c4878aSAndroid Build Coastguard Worker   uint32_t selector_enable_;
127*61c4878aSAndroid Build Coastguard Worker   uint32_t selector_disable_;
128*61c4878aSAndroid Build Coastguard Worker   template <typename U>
129*61c4878aSAndroid Build Coastguard Worker   friend class ClockTreeSetSource;
130*61c4878aSAndroid Build Coastguard Worker };
131*61c4878aSAndroid Build Coastguard Worker using ClockSelectorExampleNonBlocking =
132*61c4878aSAndroid Build Coastguard Worker     ClockSelectorExample<pw::clock_tree::ElementNonBlockingCannotFail>;
133*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_clock_tree-examples-ClockSelectorExampleDef]
134*61c4878aSAndroid Build Coastguard Worker 
135*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_clock_tree-examples-ClockTreeSetSourcesExampleDef]
136*61c4878aSAndroid Build Coastguard Worker /// Class implementing a clock tree that also supports the `UpdateSource`
137*61c4878aSAndroid Build Coastguard Worker /// method of the `ClockSelectorExample` class template.
138*61c4878aSAndroid Build Coastguard Worker class ClockTreeSetSourceExample : public pw::clock_tree::ClockTree {
139*61c4878aSAndroid Build Coastguard Worker  public:
140*61c4878aSAndroid Build Coastguard Worker   /// SetSource could be implemented for the other clock tree element classes
141*61c4878aSAndroid Build Coastguard Worker   /// as well.
SetSource(ClockSelectorExampleNonBlocking & element,pw::clock_tree::ElementNonBlockingCannotFail & new_source,uint32_t selector_enable)142*61c4878aSAndroid Build Coastguard Worker   void SetSource(ClockSelectorExampleNonBlocking& element,
143*61c4878aSAndroid Build Coastguard Worker                  pw::clock_tree::ElementNonBlockingCannotFail& new_source,
144*61c4878aSAndroid Build Coastguard Worker                  uint32_t selector_enable) {
145*61c4878aSAndroid Build Coastguard Worker     std::lock_guard lock(interrupt_spin_lock_);
146*61c4878aSAndroid Build Coastguard Worker     element.SetSource(new_source, selector_enable).IgnoreError();
147*61c4878aSAndroid Build Coastguard Worker   }
148*61c4878aSAndroid Build Coastguard Worker };
149*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_clock_tree-examples-ClockTreeSetSourcesExampleDef]
150*61c4878aSAndroid Build Coastguard Worker 
TEST(ClockTree,ClockTreeElementExample)151*61c4878aSAndroid Build Coastguard Worker TEST(ClockTree, ClockTreeElementExample) {
152*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-ClockTreeDec]
153*61c4878aSAndroid Build Coastguard Worker   // Create the clock tree
154*61c4878aSAndroid Build Coastguard Worker   ClockTreeSetSourceExample clock_tree;
155*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-ClockTreeDec]
156*61c4878aSAndroid Build Coastguard Worker 
157*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-ClockTreeElementsDec]
158*61c4878aSAndroid Build Coastguard Worker   // Define the clock tree
159*61c4878aSAndroid Build Coastguard Worker   ClockSourceExampleNonBlocking clock_a;
160*61c4878aSAndroid Build Coastguard Worker   ClockSourceExampleNonBlocking clock_b;
161*61c4878aSAndroid Build Coastguard Worker 
162*61c4878aSAndroid Build Coastguard Worker   const uint32_t kSelectorId = 7;
163*61c4878aSAndroid Build Coastguard Worker   const uint32_t kSelectorEnable1 = 2;
164*61c4878aSAndroid Build Coastguard Worker   const uint32_t kSelectorEnable2 = 4;
165*61c4878aSAndroid Build Coastguard Worker   const uint32_t kSelectorDisable = 7;
166*61c4878aSAndroid Build Coastguard Worker   // clock_selector_c depends on clock_a.
167*61c4878aSAndroid Build Coastguard Worker   ClockSelectorExampleNonBlocking clock_selector_c(
168*61c4878aSAndroid Build Coastguard Worker       clock_a, kSelectorId, kSelectorEnable1, kSelectorDisable);
169*61c4878aSAndroid Build Coastguard Worker 
170*61c4878aSAndroid Build Coastguard Worker   const uint32_t kDividerId = 12;
171*61c4878aSAndroid Build Coastguard Worker   const uint32_t kDividerValue1 = 42;
172*61c4878aSAndroid Build Coastguard Worker   // clock_divider_d depends on clock_b.
173*61c4878aSAndroid Build Coastguard Worker   ClockDividerExampleNonBlocking clock_divider_d(
174*61c4878aSAndroid Build Coastguard Worker       clock_b, kDividerId, kDividerValue1);
175*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-ClockTreeElementsDec]
176*61c4878aSAndroid Build Coastguard Worker 
177*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-AcquireClockSelectorC]
178*61c4878aSAndroid Build Coastguard Worker   // Acquire a reference to clock_selector_c, which will enable clock_selector_c
179*61c4878aSAndroid Build Coastguard Worker   // and its dependent clock_a.
180*61c4878aSAndroid Build Coastguard Worker   clock_tree.Acquire(clock_selector_c);
181*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-AcquireClockSelectorC]
182*61c4878aSAndroid Build Coastguard Worker 
183*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-ChangeClockSelectorCDependentSource]
184*61c4878aSAndroid Build Coastguard Worker   // Change clock_selector_c to depend on clock_divider_d.
185*61c4878aSAndroid Build Coastguard Worker   // This enables clock_b and clock_divider_d, and disables clock_a.
186*61c4878aSAndroid Build Coastguard Worker   clock_tree.SetSource(clock_selector_c, clock_divider_d, kSelectorEnable2);
187*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-ChangeClockSelectorCDependentSource]
188*61c4878aSAndroid Build Coastguard Worker 
189*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-SetClockDividerDValue]
190*61c4878aSAndroid Build Coastguard Worker   // Change the divider value for clock_divider_d.
191*61c4878aSAndroid Build Coastguard Worker   const uint32_t kDividerValue2 = 21;
192*61c4878aSAndroid Build Coastguard Worker   clock_tree.SetDividerValue(clock_divider_d, kDividerValue2);
193*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-SetClockDividerDValue]
194*61c4878aSAndroid Build Coastguard Worker 
195*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-ReleaseClockSelectorC]
196*61c4878aSAndroid Build Coastguard Worker   // Release reference to clock_selector_c, which will disable clock_selector_c,
197*61c4878aSAndroid Build Coastguard Worker   // clock_divider_d, and clock_b.
198*61c4878aSAndroid Build Coastguard Worker   clock_tree.Release(clock_selector_c);
199*61c4878aSAndroid Build Coastguard Worker   // All clock tree elements are disabled now.
200*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-ReleaseClockSelectorC]
201*61c4878aSAndroid Build Coastguard Worker }
202*61c4878aSAndroid Build Coastguard Worker 
USART_RTOS_Init()203*61c4878aSAndroid Build Coastguard Worker static pw::Status USART_RTOS_Init() { return pw::OkStatus(); }
USART_RTOS_Deinit()204*61c4878aSAndroid Build Coastguard Worker static void USART_RTOS_Deinit() {}
205*61c4878aSAndroid Build Coastguard Worker 
206*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_clock_tree-examples-IntegrationIntoDeviceDriversClassDef]
207*61c4878aSAndroid Build Coastguard Worker #include "pw_clock_tree/clock_tree.h"
208*61c4878aSAndroid Build Coastguard Worker 
209*61c4878aSAndroid Build Coastguard Worker class UartStreamMcuxpresso {
210*61c4878aSAndroid Build Coastguard Worker  public:
Init()211*61c4878aSAndroid Build Coastguard Worker   pw::Status Init() {
212*61c4878aSAndroid Build Coastguard Worker     // Acquire reference to clock before initializing device.
213*61c4878aSAndroid Build Coastguard Worker     PW_TRY(clock_tree_element_controller_.Acquire());
214*61c4878aSAndroid Build Coastguard Worker     pw::Status status = USART_RTOS_Init();
215*61c4878aSAndroid Build Coastguard Worker     if (!status.ok()) {
216*61c4878aSAndroid Build Coastguard Worker       // Failed to initialize device, release the acquired clock.
217*61c4878aSAndroid Build Coastguard Worker       clock_tree_element_controller_.Release().IgnoreError();
218*61c4878aSAndroid Build Coastguard Worker     }
219*61c4878aSAndroid Build Coastguard Worker     return status;
220*61c4878aSAndroid Build Coastguard Worker   }
221*61c4878aSAndroid Build Coastguard Worker 
Deinit()222*61c4878aSAndroid Build Coastguard Worker   void Deinit() {
223*61c4878aSAndroid Build Coastguard Worker     // Deinitialize the device before we can release the reference
224*61c4878aSAndroid Build Coastguard Worker     // to the clock.
225*61c4878aSAndroid Build Coastguard Worker     USART_RTOS_Deinit();
226*61c4878aSAndroid Build Coastguard Worker     clock_tree_element_controller_.Release().IgnoreError();
227*61c4878aSAndroid Build Coastguard Worker   }
228*61c4878aSAndroid Build Coastguard Worker 
229*61c4878aSAndroid Build Coastguard Worker   // Device constructor that optionally accepts `clock_tree` and
230*61c4878aSAndroid Build Coastguard Worker   // `clock_tree_element` to manage clock lifecycle.
UartStreamMcuxpresso(pw::clock_tree::ClockTree * clock_tree=nullptr,pw::clock_tree::ElementNonBlockingCannotFail * clock_tree_element=nullptr)231*61c4878aSAndroid Build Coastguard Worker   constexpr UartStreamMcuxpresso(
232*61c4878aSAndroid Build Coastguard Worker       pw::clock_tree::ClockTree* clock_tree = nullptr,
233*61c4878aSAndroid Build Coastguard Worker       pw::clock_tree::ElementNonBlockingCannotFail* clock_tree_element =
234*61c4878aSAndroid Build Coastguard Worker           nullptr)
235*61c4878aSAndroid Build Coastguard Worker       : clock_tree_element_controller_(clock_tree, clock_tree_element) {}
236*61c4878aSAndroid Build Coastguard Worker 
237*61c4878aSAndroid Build Coastguard Worker  private:
238*61c4878aSAndroid Build Coastguard Worker   pw::clock_tree::ElementController clock_tree_element_controller_;
239*61c4878aSAndroid Build Coastguard Worker };
240*61c4878aSAndroid Build Coastguard Worker // DOCSTAG: [pw_clock_tree-examples-IntegrationIntoDeviceDriversClassDef]
241*61c4878aSAndroid Build Coastguard Worker 
242*61c4878aSAndroid Build Coastguard Worker using ClockSourceUart =
243*61c4878aSAndroid Build Coastguard Worker     ClockSourceExample<pw::clock_tree::ElementNonBlockingCannotFail>;
244*61c4878aSAndroid Build Coastguard Worker 
ClockTreeExample()245*61c4878aSAndroid Build Coastguard Worker pw::Status ClockTreeExample() {
246*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-IntegrationIntoDeviceDriversUsage]
247*61c4878aSAndroid Build Coastguard Worker 
248*61c4878aSAndroid Build Coastguard Worker   // Declare the clock tree
249*61c4878aSAndroid Build Coastguard Worker   pw::clock_tree::ClockTree clock_tree;
250*61c4878aSAndroid Build Coastguard Worker   // Declare the uart clock source
251*61c4878aSAndroid Build Coastguard Worker   ClockSourceUart uart_clock_source;
252*61c4878aSAndroid Build Coastguard Worker   UartStreamMcuxpresso uart(&clock_tree, &uart_clock_source);
253*61c4878aSAndroid Build Coastguard Worker 
254*61c4878aSAndroid Build Coastguard Worker   // Initialize the uart which enables the uart clock source.
255*61c4878aSAndroid Build Coastguard Worker   PW_TRY(uart.Init());
256*61c4878aSAndroid Build Coastguard Worker   PW_CHECK(uart_clock_source.ref_count() > 0);
257*61c4878aSAndroid Build Coastguard Worker 
258*61c4878aSAndroid Build Coastguard Worker   // Do something with uart
259*61c4878aSAndroid Build Coastguard Worker 
260*61c4878aSAndroid Build Coastguard Worker   // Deinitialize the uart which disable the uart clock source.
261*61c4878aSAndroid Build Coastguard Worker   uart.Deinit();
262*61c4878aSAndroid Build Coastguard Worker 
263*61c4878aSAndroid Build Coastguard Worker   // DOCSTAG: [pw_clock_tree-examples-IntegrationIntoDeviceDriversUsage]
264*61c4878aSAndroid Build Coastguard Worker 
265*61c4878aSAndroid Build Coastguard Worker   return pw::OkStatus();
266*61c4878aSAndroid Build Coastguard Worker }
267*61c4878aSAndroid Build Coastguard Worker 
TEST(ClockTree,ClockTreeExample)268*61c4878aSAndroid Build Coastguard Worker TEST(ClockTree, ClockTreeExample) {
269*61c4878aSAndroid Build Coastguard Worker   pw::Status status = ClockTreeExample();
270*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(status.code(), PW_STATUS_OK);
271*61c4878aSAndroid Build Coastguard Worker }
272*61c4878aSAndroid Build Coastguard Worker }  // namespace examples
273