xref: /aosp_15_r20/external/pigweed/pw_digital_io/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_digital_io:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker.. cpp:namespace-push:: pw::digital_io
4*61c4878aSAndroid Build Coastguard Worker
5*61c4878aSAndroid Build Coastguard Worker=============
6*61c4878aSAndroid Build Coastguard Workerpw_digital_io
7*61c4878aSAndroid Build Coastguard Worker=============
8*61c4878aSAndroid Build Coastguard Worker``pw_digital_io`` provides a set of interfaces for using General Purpose Input
9*61c4878aSAndroid Build Coastguard Workerand Output (GPIO) lines for simple Digital I/O. This module can either be used
10*61c4878aSAndroid Build Coastguard Workerdirectly by the application code or wrapped in a device driver for more complex
11*61c4878aSAndroid Build Coastguard Workerperipherals.
12*61c4878aSAndroid Build Coastguard Worker
13*61c4878aSAndroid Build Coastguard Worker--------
14*61c4878aSAndroid Build Coastguard WorkerOverview
15*61c4878aSAndroid Build Coastguard Worker--------
16*61c4878aSAndroid Build Coastguard WorkerThe interfaces provide an abstract concept of a **Digital IO line**. The
17*61c4878aSAndroid Build Coastguard Workerinterfaces abstract away details about the hardware and platform-specific
18*61c4878aSAndroid Build Coastguard Workerdrivers. A platform-specific backend is responsible for configuring lines and
19*61c4878aSAndroid Build Coastguard Workerproviding an implementation of the interface that matches the capabilities and
20*61c4878aSAndroid Build Coastguard Workerintended usage of the line.
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard WorkerExample API usage:
23*61c4878aSAndroid Build Coastguard Worker
24*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
25*61c4878aSAndroid Build Coastguard Worker
26*61c4878aSAndroid Build Coastguard Worker   using namespace pw::digital_io;
27*61c4878aSAndroid Build Coastguard Worker
28*61c4878aSAndroid Build Coastguard Worker   Status UpdateLedFromSwitch(const DigitalIn& switch, DigitalOut& led) {
29*61c4878aSAndroid Build Coastguard Worker     PW_TRY_ASSIGN(const DigitalIo::State state, switch.GetState());
30*61c4878aSAndroid Build Coastguard Worker     return led.SetState(state);
31*61c4878aSAndroid Build Coastguard Worker   }
32*61c4878aSAndroid Build Coastguard Worker
33*61c4878aSAndroid Build Coastguard Worker   Status ListenForButtonPress(DigitalInterrupt& button) {
34*61c4878aSAndroid Build Coastguard Worker     PW_TRY(button.SetInterruptHandler(Trigger::kActivatingEdge,
35*61c4878aSAndroid Build Coastguard Worker       [](State sampled_state) {
36*61c4878aSAndroid Build Coastguard Worker         // Handle the button press.
37*61c4878aSAndroid Build Coastguard Worker         // NOTE: this may run in an interrupt context!
38*61c4878aSAndroid Build Coastguard Worker       }));
39*61c4878aSAndroid Build Coastguard Worker     return button.EnableInterruptHandler();
40*61c4878aSAndroid Build Coastguard Worker   }
41*61c4878aSAndroid Build Coastguard Worker
42*61c4878aSAndroid Build Coastguard Worker-------------------------
43*61c4878aSAndroid Build Coastguard Workerpw::digital_io Interfaces
44*61c4878aSAndroid Build Coastguard Worker-------------------------
45*61c4878aSAndroid Build Coastguard WorkerThere are 3 basic capabilities of a Digital IO line:
46*61c4878aSAndroid Build Coastguard Worker
47*61c4878aSAndroid Build Coastguard Worker* Input - Get the state of the line.
48*61c4878aSAndroid Build Coastguard Worker* Output - Set the state of the line.
49*61c4878aSAndroid Build Coastguard Worker* Interrupt - Register a handler that is called when a trigger happens.
50*61c4878aSAndroid Build Coastguard Worker
51*61c4878aSAndroid Build Coastguard Worker.. note:: **Capabilities** refer to how the line is intended to be used in a
52*61c4878aSAndroid Build Coastguard Worker   particular device given its actual physical wiring, rather than the
53*61c4878aSAndroid Build Coastguard Worker   theoretical capabilities of the hardware.
54*61c4878aSAndroid Build Coastguard Worker
55*61c4878aSAndroid Build Coastguard WorkerAdditionally, all lines can be *enabled* and *disabled*:
56*61c4878aSAndroid Build Coastguard Worker
57*61c4878aSAndroid Build Coastguard Worker* Enable - tell the hardware to apply power to an output line, connect any
58*61c4878aSAndroid Build Coastguard Worker  pull-up/down resistors, etc. For output lines, the line is set to an initial
59*61c4878aSAndroid Build Coastguard Worker  output state that is backend-specific.
60*61c4878aSAndroid Build Coastguard Worker* Disable - tell the hardware to stop applying power and return the line to its
61*61c4878aSAndroid Build Coastguard Worker  default state. This may save power or allow some other component to drive a
62*61c4878aSAndroid Build Coastguard Worker  shared line.
63*61c4878aSAndroid Build Coastguard Worker
64*61c4878aSAndroid Build Coastguard Worker.. note:: The initial state of a line is implementation-defined and may not
65*61c4878aSAndroid Build Coastguard Worker   match either the "enabled" or "disabled" state.  Users of the API who need
66*61c4878aSAndroid Build Coastguard Worker   to ensure the line is disabled (ex. output is not driving the line) should
67*61c4878aSAndroid Build Coastguard Worker   explicitly call ``Disable()``.
68*61c4878aSAndroid Build Coastguard Worker
69*61c4878aSAndroid Build Coastguard WorkerFunctionality overview
70*61c4878aSAndroid Build Coastguard Worker======================
71*61c4878aSAndroid Build Coastguard WorkerThe following table summarizes the interfaces and their required functionality:
72*61c4878aSAndroid Build Coastguard Worker
73*61c4878aSAndroid Build Coastguard Worker.. list-table::
74*61c4878aSAndroid Build Coastguard Worker   :header-rows: 1
75*61c4878aSAndroid Build Coastguard Worker   :stub-columns: 1
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard Worker   * -
78*61c4878aSAndroid Build Coastguard Worker     - Interrupts Not Required
79*61c4878aSAndroid Build Coastguard Worker     - Interrupts Required
80*61c4878aSAndroid Build Coastguard Worker   * - Input/Output Not Required
81*61c4878aSAndroid Build Coastguard Worker     -
82*61c4878aSAndroid Build Coastguard Worker     - :cpp:class:`DigitalInterrupt`
83*61c4878aSAndroid Build Coastguard Worker   * - Input Required
84*61c4878aSAndroid Build Coastguard Worker     - :cpp:class:`DigitalIn`
85*61c4878aSAndroid Build Coastguard Worker     - :cpp:class:`DigitalInInterrupt`
86*61c4878aSAndroid Build Coastguard Worker   * - Output Required
87*61c4878aSAndroid Build Coastguard Worker     - :cpp:class:`DigitalOut`
88*61c4878aSAndroid Build Coastguard Worker     - :cpp:class:`DigitalOutInterrupt`
89*61c4878aSAndroid Build Coastguard Worker   * - Input/Output Required
90*61c4878aSAndroid Build Coastguard Worker     - :cpp:class:`DigitalInOut`
91*61c4878aSAndroid Build Coastguard Worker     - :cpp:class:`DigitalInOutInterrupt`
92*61c4878aSAndroid Build Coastguard Worker
93*61c4878aSAndroid Build Coastguard WorkerSynchronization requirements
94*61c4878aSAndroid Build Coastguard Worker============================
95*61c4878aSAndroid Build Coastguard Worker* An instance of a line has exclusive ownership of that line and may be used
96*61c4878aSAndroid Build Coastguard Worker  independently of other line objects without additional synchronization.
97*61c4878aSAndroid Build Coastguard Worker* Access to a single line instance must be synchronized at the application
98*61c4878aSAndroid Build Coastguard Worker  level. For example, by wrapping the line instance in ``pw::Borrowable``.
99*61c4878aSAndroid Build Coastguard Worker* Unless otherwise stated, the line interface must not be used from within an
100*61c4878aSAndroid Build Coastguard Worker  interrupt context.
101*61c4878aSAndroid Build Coastguard Worker
102*61c4878aSAndroid Build Coastguard Worker------------
103*61c4878aSAndroid Build Coastguard WorkerDesign Notes
104*61c4878aSAndroid Build Coastguard Worker------------
105*61c4878aSAndroid Build Coastguard WorkerThe interfaces are intended to support many but not all use cases, and they do
106*61c4878aSAndroid Build Coastguard Workernot cover every possible type of functionality supported by the hardware. There
107*61c4878aSAndroid Build Coastguard Workerwill be edge cases that require the backend to expose some additional (custom)
108*61c4878aSAndroid Build Coastguard Workerinterfaces, or require the use of a lower-level API.
109*61c4878aSAndroid Build Coastguard Worker
110*61c4878aSAndroid Build Coastguard WorkerExamples of intended use cases:
111*61c4878aSAndroid Build Coastguard Worker
112*61c4878aSAndroid Build Coastguard Worker* Do input and output on lines that have two logical states - active and
113*61c4878aSAndroid Build Coastguard Worker  inactive - regardless of the underlying hardware configuration.
114*61c4878aSAndroid Build Coastguard Worker
115*61c4878aSAndroid Build Coastguard Worker  * Example: Read the state of a switch.
116*61c4878aSAndroid Build Coastguard Worker  * Example: Control a simple LED with on/off.
117*61c4878aSAndroid Build Coastguard Worker  * Example: Activate/deactivate power for a peripheral.
118*61c4878aSAndroid Build Coastguard Worker  * Example: Trigger reset of an I2C bus.
119*61c4878aSAndroid Build Coastguard Worker
120*61c4878aSAndroid Build Coastguard Worker* Run code based on an external interrupt.
121*61c4878aSAndroid Build Coastguard Worker
122*61c4878aSAndroid Build Coastguard Worker  * Example: Trigger when a hardware switch is flipped.
123*61c4878aSAndroid Build Coastguard Worker  * Example: Trigger when device is connected to external power.
124*61c4878aSAndroid Build Coastguard Worker  * Example: Handle data ready signals from peripherals connected to
125*61c4878aSAndroid Build Coastguard Worker    I2C/SPI/etc.
126*61c4878aSAndroid Build Coastguard Worker
127*61c4878aSAndroid Build Coastguard Worker* Enable and disable lines as part of a high-level policy:
128*61c4878aSAndroid Build Coastguard Worker
129*61c4878aSAndroid Build Coastguard Worker  * Example: For power management - disable lines to use less power.
130*61c4878aSAndroid Build Coastguard Worker  * Example: To support shared lines used for multiple purposes (ex. GPIO or
131*61c4878aSAndroid Build Coastguard Worker    I2C).
132*61c4878aSAndroid Build Coastguard Worker
133*61c4878aSAndroid Build Coastguard WorkerExamples of use cases we want to allow but don't explicitly support in the API:
134*61c4878aSAndroid Build Coastguard Worker
135*61c4878aSAndroid Build Coastguard Worker* Software-controlled pull up/down resistors, high drive, polarity controls,
136*61c4878aSAndroid Build Coastguard Worker  etc.
137*61c4878aSAndroid Build Coastguard Worker
138*61c4878aSAndroid Build Coastguard Worker  * It's up to the backend implementation to expose configuration for these
139*61c4878aSAndroid Build Coastguard Worker    settings.
140*61c4878aSAndroid Build Coastguard Worker  * Enabling a line should set it into the state that is configured in the
141*61c4878aSAndroid Build Coastguard Worker    backend.
142*61c4878aSAndroid Build Coastguard Worker
143*61c4878aSAndroid Build Coastguard Worker* Level-triggered interrupts on RTOS platforms.
144*61c4878aSAndroid Build Coastguard Worker
145*61c4878aSAndroid Build Coastguard Worker  * We explicitly support disabling the interrupt handler while in the context
146*61c4878aSAndroid Build Coastguard Worker    of the handler.
147*61c4878aSAndroid Build Coastguard Worker  * Otherwise, it's up to the backend to provide any additional level-trigger
148*61c4878aSAndroid Build Coastguard Worker    support.
149*61c4878aSAndroid Build Coastguard Worker
150*61c4878aSAndroid Build Coastguard WorkerExamples of uses cases we explicitly don't plan to support:
151*61c4878aSAndroid Build Coastguard Worker
152*61c4878aSAndroid Build Coastguard Worker* Using Digital IO to simulate serial interfaces like I2C (bit banging), or any
153*61c4878aSAndroid Build Coastguard Worker  use cases requiring exact timing and access to line voltage, clock controls,
154*61c4878aSAndroid Build Coastguard Worker  etc.
155*61c4878aSAndroid Build Coastguard Worker* Mode selection - controlling hardware multiplexing or logically switching from
156*61c4878aSAndroid Build Coastguard Worker  GPIO to I2C mode.
157*61c4878aSAndroid Build Coastguard Worker
158*61c4878aSAndroid Build Coastguard WorkerAPI decisions that have been deferred:
159*61c4878aSAndroid Build Coastguard Worker
160*61c4878aSAndroid Build Coastguard Worker* Supporting operations on multiple lines in parallel - for example to simulate
161*61c4878aSAndroid Build Coastguard Worker  a memory register or other parallel interface.
162*61c4878aSAndroid Build Coastguard Worker* Helpers to support different patterns for interrupt handlers - running in the
163*61c4878aSAndroid Build Coastguard Worker  interrupt context, dispatching to a dedicated thread, using a pw_sync
164*61c4878aSAndroid Build Coastguard Worker  primitive, etc.
165*61c4878aSAndroid Build Coastguard Worker
166*61c4878aSAndroid Build Coastguard WorkerThe following sub-sections discuss specific design decisions in detail.
167*61c4878aSAndroid Build Coastguard Worker
168*61c4878aSAndroid Build Coastguard WorkerStates vs. voltage levels
169*61c4878aSAndroid Build Coastguard Worker=========================
170*61c4878aSAndroid Build Coastguard WorkerDigital IO line values are represented as **active** and **inactive** states.
171*61c4878aSAndroid Build Coastguard WorkerThese states abstract away the actual electrical level and other physical
172*61c4878aSAndroid Build Coastguard Workerproperties of the line. This allows applications to interact with Digital IO
173*61c4878aSAndroid Build Coastguard Workerlines across targets that may have different physical configurations. It is up
174*61c4878aSAndroid Build Coastguard Workerto the backend to provide a consistent definition of state.
175*61c4878aSAndroid Build Coastguard Worker
176*61c4878aSAndroid Build Coastguard WorkerThere is a helper ``pw::digital_io::Polarity`` enum provided to enable mapping
177*61c4878aSAndroid Build Coastguard Workerfrom logical to physical states for backends.
178*61c4878aSAndroid Build Coastguard Worker
179*61c4878aSAndroid Build Coastguard WorkerInterrupt handling
180*61c4878aSAndroid Build Coastguard Worker==================
181*61c4878aSAndroid Build Coastguard WorkerInterrupt handling is part of this API. The alternative was to have a separate
182*61c4878aSAndroid Build Coastguard WorkerAPI for interrupts. We wanted to have a single object that refers to each line
183*61c4878aSAndroid Build Coastguard Workerand represents all the functionality that is available on the line.
184*61c4878aSAndroid Build Coastguard Worker
185*61c4878aSAndroid Build Coastguard WorkerInterrupt triggers are configured through the ``SetInterruptHandler`` method.
186*61c4878aSAndroid Build Coastguard WorkerThe type of trigger is tightly coupled to what the handler wants to do with that
187*61c4878aSAndroid Build Coastguard Workertrigger.
188*61c4878aSAndroid Build Coastguard Worker
189*61c4878aSAndroid Build Coastguard WorkerThe handler is passed the latest known sampled state of the line. Otherwise
190*61c4878aSAndroid Build Coastguard Workerhandlers running in an interrupt context cannot query the state of the line.
191*61c4878aSAndroid Build Coastguard Worker
192*61c4878aSAndroid Build Coastguard WorkerClass Hierarchy
193*61c4878aSAndroid Build Coastguard Worker===============
194*61c4878aSAndroid Build Coastguard Worker``pw_digital_io`` contains a 2-level hierarchy of classes.
195*61c4878aSAndroid Build Coastguard Worker
196*61c4878aSAndroid Build Coastguard Worker* ``DigitalIoOptional`` acts as the base class and represents a line that does
197*61c4878aSAndroid Build Coastguard Worker  not guarantee any particular functionality is available.
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard Worker  * This should be rarely used in APIs. Prefer to use one of the derived
200*61c4878aSAndroid Build Coastguard Worker    classes.
201*61c4878aSAndroid Build Coastguard Worker  * This class is never extended outside this module. Extend one of the derived
202*61c4878aSAndroid Build Coastguard Worker    classes.
203*61c4878aSAndroid Build Coastguard Worker
204*61c4878aSAndroid Build Coastguard Worker* Derived classes represent a line with a particular combination of
205*61c4878aSAndroid Build Coastguard Worker  functionality.
206*61c4878aSAndroid Build Coastguard Worker
207*61c4878aSAndroid Build Coastguard Worker  * Use a specific class in APIs to represent the requirements.
208*61c4878aSAndroid Build Coastguard Worker  * Extend the specific class that has the actual capabilities of the line.
209*61c4878aSAndroid Build Coastguard Worker
210*61c4878aSAndroid Build Coastguard WorkerIn the future, we may add new classes that describe lines with **optional**
211*61c4878aSAndroid Build Coastguard Workerfunctionality. For example, ``DigitalInOptionalInterrupt`` could describe a line
212*61c4878aSAndroid Build Coastguard Workerthat supports input and optionally supports interrupts.
213*61c4878aSAndroid Build Coastguard Worker
214*61c4878aSAndroid Build Coastguard WorkerWhen using any classes with optional functionality, including
215*61c4878aSAndroid Build Coastguard Worker``DigitalIoOptional``, you must check that a functionality is available using
216*61c4878aSAndroid Build Coastguard Workerthe ``provides_*`` runtime flags. Calling a method that is not supported will
217*61c4878aSAndroid Build Coastguard Workertrigger ``PW_CRASH``.
218*61c4878aSAndroid Build Coastguard Worker
219*61c4878aSAndroid Build Coastguard WorkerWe define the public API through non-virtual methods declared in
220*61c4878aSAndroid Build Coastguard Worker``DigitalIoOptional``. These methods delegate to private pure virtual methods.
221*61c4878aSAndroid Build Coastguard Worker
222*61c4878aSAndroid Build Coastguard WorkerType Conversions
223*61c4878aSAndroid Build Coastguard Worker================
224*61c4878aSAndroid Build Coastguard WorkerConversions are provided between classes with compatible requirements. For
225*61c4878aSAndroid Build Coastguard Workerexample:
226*61c4878aSAndroid Build Coastguard Worker
227*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
228*61c4878aSAndroid Build Coastguard Worker
229*61c4878aSAndroid Build Coastguard Worker   DigitalInInterrupt& in_interrupt_line;
230*61c4878aSAndroid Build Coastguard Worker   DigitalIn& in_line = in_interrupt_line;
231*61c4878aSAndroid Build Coastguard Worker
232*61c4878aSAndroid Build Coastguard Worker   DigitalInInterrupt* in_interrupt_line_ptr;
233*61c4878aSAndroid Build Coastguard Worker   DigitalIn* in_line_ptr = &in_interrupt_line_ptr->as<DigitalIn>();
234*61c4878aSAndroid Build Coastguard Worker
235*61c4878aSAndroid Build Coastguard WorkerAsynchronous APIs
236*61c4878aSAndroid Build Coastguard Worker=================
237*61c4878aSAndroid Build Coastguard WorkerAt present, ``pw_digital_io`` is synchronous. All the API calls are expected to
238*61c4878aSAndroid Build Coastguard Workerblock until the operation is complete. This is desirable for simple GPIO chips
239*61c4878aSAndroid Build Coastguard Workerthat are controlled through direct register access. However, this may be
240*61c4878aSAndroid Build Coastguard Workerundesirable for GPIO extenders controlled through I2C or another shared bus.
241*61c4878aSAndroid Build Coastguard Worker
242*61c4878aSAndroid Build Coastguard WorkerThe API may be extended in the future to add asynchronous capabilities, or a
243*61c4878aSAndroid Build Coastguard Workerseparate asynchronous API may be created.
244*61c4878aSAndroid Build Coastguard Worker
245*61c4878aSAndroid Build Coastguard WorkerBackend Implemention Notes
246*61c4878aSAndroid Build Coastguard Worker==========================
247*61c4878aSAndroid Build Coastguard Worker* Derived classes explicitly list the non-virtual methods as public or private
248*61c4878aSAndroid Build Coastguard Worker  depending on the supported set of functionality. For example, ``DigitalIn``
249*61c4878aSAndroid Build Coastguard Worker  declare ``GetState`` public and ``SetState`` private.
250*61c4878aSAndroid Build Coastguard Worker* Derived classes that exclude a particular functionality provide a private,
251*61c4878aSAndroid Build Coastguard Worker  final implementation of the unsupported virtual method that crashes if it is
252*61c4878aSAndroid Build Coastguard Worker  called. For example, ``DigitalIn`` implements ``DoSetState`` to trigger
253*61c4878aSAndroid Build Coastguard Worker  ``PW_CRASH``.
254*61c4878aSAndroid Build Coastguard Worker* Backend implementations provide real implementation for the remaining pure
255*61c4878aSAndroid Build Coastguard Worker  virtual functions of the class they extend.
256*61c4878aSAndroid Build Coastguard Worker* Classes that support optional functionality make the non-virtual optional
257*61c4878aSAndroid Build Coastguard Worker  methods public, but they do not provide an implementation for the pure virtual
258*61c4878aSAndroid Build Coastguard Worker  functions. These classes are never extended.
259*61c4878aSAndroid Build Coastguard Worker* Backend implementations **must** check preconditions for each operations. For
260*61c4878aSAndroid Build Coastguard Worker  example, check that the line is actually enabled before trying to get/set the
261*61c4878aSAndroid Build Coastguard Worker  state of the line. Otherwise return ``pw::Status::FailedPrecondition()``.
262*61c4878aSAndroid Build Coastguard Worker* Backends *may* leave the line in an uninitialized state after construction,
263*61c4878aSAndroid Build Coastguard Worker  but implementors are strongly encouraged to initialize the line to a known
264*61c4878aSAndroid Build Coastguard Worker  state.
265*61c4878aSAndroid Build Coastguard Worker
266*61c4878aSAndroid Build Coastguard Worker  * If backends initialize the line, it must be initialized to the disabled
267*61c4878aSAndroid Build Coastguard Worker    state. i.e. the same state it would be in after calling ``Enable()``
268*61c4878aSAndroid Build Coastguard Worker    followed by ``Disable()``.
269*61c4878aSAndroid Build Coastguard Worker  * Calling ``Disable()`` on an uninitialized line must put it into the disabled
270*61c4878aSAndroid Build Coastguard Worker    state. In general, ``Disable()`` can be called in any state.
271*61c4878aSAndroid Build Coastguard Worker
272*61c4878aSAndroid Build Coastguard Worker* Calling ``Enable()`` on a line that is already enabled should be a no-op. In
273*61c4878aSAndroid Build Coastguard Worker  particular, the state of an already-enabled output line should not change.
274*61c4878aSAndroid Build Coastguard Worker
275*61c4878aSAndroid Build Coastguard Worker-----------
276*61c4878aSAndroid Build Coastguard WorkerRPC Service
277*61c4878aSAndroid Build Coastguard Worker-----------
278*61c4878aSAndroid Build Coastguard WorkerThe ``DigitalIoService`` pw_rpc service is provided to support bringup/debug
279*61c4878aSAndroid Build Coastguard Workerefforts. It allows manual control of individual DigitalIo lines for both input
280*61c4878aSAndroid Build Coastguard Workerand output.
281*61c4878aSAndroid Build Coastguard Worker
282*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
283*61c4878aSAndroid Build Coastguard Worker
284*61c4878aSAndroid Build Coastguard Worker   std::array<std::reference_wrapper<DigitalIoOptional>> lines = {
285*61c4878aSAndroid Build Coastguard Worker     ...DigitalIn(),
286*61c4878aSAndroid Build Coastguard Worker     ...DigitalOut(),
287*61c4878aSAndroid Build Coastguard Worker   };
288*61c4878aSAndroid Build Coastguard Worker   DigitalIoService service(lines);
289*61c4878aSAndroid Build Coastguard Worker   rpc_server.RegisterService(service);
290*61c4878aSAndroid Build Coastguard Worker
291*61c4878aSAndroid Build Coastguard WorkerSet the state of the output line via RPC. This snippet demonstrates how you
292*61c4878aSAndroid Build Coastguard Workermight do that using a Pigweed console device object.
293*61c4878aSAndroid Build Coastguard Worker
294*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
295*61c4878aSAndroid Build Coastguard Worker
296*61c4878aSAndroid Build Coastguard Worker   from pw_digital_io import digital_io_pb2
297*61c4878aSAndroid Build Coastguard Worker
298*61c4878aSAndroid Build Coastguard Worker   device.rpcs.pw.digital_io.DigitalIo.SetState(
299*61c4878aSAndroid Build Coastguard Worker                line_index=0, state=digital_io_pb2.DigitalIoState.ACTIVE)
300*61c4878aSAndroid Build Coastguard Worker
301*61c4878aSAndroid Build Coastguard Worker
302*61c4878aSAndroid Build Coastguard Worker-------------
303*61c4878aSAndroid Build Coastguard WorkerAPI reference
304*61c4878aSAndroid Build Coastguard Worker-------------
305*61c4878aSAndroid Build Coastguard Worker.. note::
306*61c4878aSAndroid Build Coastguard Worker   This API reference is incomplete.
307*61c4878aSAndroid Build Coastguard Worker
308*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::digital_io::DigitalIoOptional
309*61c4878aSAndroid Build Coastguard Worker   :members:
310*61c4878aSAndroid Build Coastguard Worker   :private-members:
311*61c4878aSAndroid Build Coastguard Worker
312*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::digital_io::DigitalInOutMock
313*61c4878aSAndroid Build Coastguard Worker   :members:
314*61c4878aSAndroid Build Coastguard Worker   :private-members:
315*61c4878aSAndroid Build Coastguard Worker
316*61c4878aSAndroid Build Coastguard Worker------------
317*61c4878aSAndroid Build Coastguard WorkerDependencies
318*61c4878aSAndroid Build Coastguard Worker------------
319*61c4878aSAndroid Build Coastguard Worker* :ref:`module-pw_assert`
320*61c4878aSAndroid Build Coastguard Worker* :ref:`module-pw_function`
321*61c4878aSAndroid Build Coastguard Worker* :ref:`module-pw_result`
322*61c4878aSAndroid Build Coastguard Worker* :ref:`module-pw_status`
323*61c4878aSAndroid Build Coastguard Worker
324*61c4878aSAndroid Build Coastguard Worker.. cpp:namespace-pop::
325*61c4878aSAndroid Build Coastguard Worker
326*61c4878aSAndroid Build Coastguard WorkerZephyr
327*61c4878aSAndroid Build Coastguard Worker======
328*61c4878aSAndroid Build Coastguard WorkerTo enable ``pw_digital_io`` for Zephyr add ``CONFIG_PIGWEED_DIGITAL_IO=y`` to
329*61c4878aSAndroid Build Coastguard Workerthe project's configuration.
330*61c4878aSAndroid Build Coastguard Worker
331*61c4878aSAndroid Build Coastguard Worker
332*61c4878aSAndroid Build Coastguard Worker.. toctree::
333*61c4878aSAndroid Build Coastguard Worker   :hidden:
334*61c4878aSAndroid Build Coastguard Worker   :maxdepth: 1
335*61c4878aSAndroid Build Coastguard Worker
336*61c4878aSAndroid Build Coastguard Worker   Backends <backends>
337