Pigweed
 
Loading...
Searching...
No Matches
digital_io.h
1// Copyright 2021 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#pragma once
15
16#include "pw_assert/check.h"
17#include "pw_digital_io/internal/conversions.h"
18#include "pw_function/function.h"
19#include "pw_result/result.h"
20#include "pw_status/status.h"
21#include "pw_status/try.h"
22
23namespace pw::digital_io {
24
25// The logical state of a digital line.
26enum class State : bool {
27 kActive = true,
28 kInactive = false,
29};
30
31// The triggering configuration for an interrupt handler.
32enum class InterruptTrigger : int {
33 // Trigger on transition from kInactive to kActive.
34 kActivatingEdge,
35 // Trigger on transition from kActive to kInactive.
36 kDeactivatingEdge,
37 // Trigger on any state transition between kActive and kInactive.
38 kBothEdges,
39};
40
41// Interrupt handling function. The argument contains the latest known state of
42// the line. It is backend-specific if, when, and how this state is updated.
43using InterruptHandler = ::pw::Function<void(State sampled_state)>;
44
70 public:
71 virtual ~DigitalIoOptional() = default;
72
74 constexpr bool provides_input() const { return config_.input; }
76 constexpr bool provides_output() const { return config_.output; }
78 constexpr bool provides_interrupt() const { return config_.interrupt; }
79
96 Result<State> GetState() { return DoGetState(); }
97
117 Status SetState(State state) { return DoSetState(state); }
118
138 Result<bool> IsStateActive() {
139 PW_TRY_ASSIGN(const State state, GetState());
140 return state == State::kActive;
141 }
142
163 Status SetStateActive() { return SetState(State::kActive); }
164
185 Status SetStateInactive() { return SetState(State::kInactive); }
186
215 Status SetInterruptHandler(InterruptTrigger trigger,
216 InterruptHandler&& handler) {
217 if (handler == nullptr) {
218 return Status::InvalidArgument();
219 }
220 return DoSetInterruptHandler(trigger, std::move(handler));
221 }
222
239 PW_TRY(DisableInterruptHandler());
240 return DoSetInterruptHandler(InterruptTrigger::kActivatingEdge, nullptr);
241 }
242
262
281
302 Status Enable() { return DoEnable(true); }
303
323 if (provides_interrupt()) {
324 PW_TRY(DisableInterruptHandler());
325 }
326 return DoEnable(false);
327 }
328
329 private:
330 friend class DigitalInterrupt;
331 friend class DigitalIn;
332 friend class DigitalInInterrupt;
333 friend class DigitalOut;
334 friend class DigitalOutInterrupt;
335 friend class DigitalInOut;
336 friend class DigitalInOutInterrupt;
337
338 // Private constructor so that only friends can extend us.
339 constexpr DigitalIoOptional(internal::Provides config) : config_(config) {}
340
368 virtual Status DoEnable(bool enable) = 0;
369
385 virtual Result<State> DoGetState() = 0;
386
405 virtual Status DoSetState(State level) = 0;
406
437 virtual Status DoSetInterruptHandler(InterruptTrigger trigger,
438 InterruptHandler&& handler) = 0;
439
461 virtual Status DoEnableInterruptHandler(bool enable) = 0;
462
463 // The configuration of this line.
464 const internal::Provides config_;
465};
466
467// A digital I/O line that supports only interrupts.
468//
469// The input and output methods are hidden and must not be called.
470//
471// Use this class in APIs when only interrupt functionality is required.
472// Extend this class to implement a line that only supports interrupts.
473//
475 : public DigitalIoOptional,
476 public internal::Conversions<DigitalInterrupt, DigitalIoOptional> {
477 public:
478 // Available functionality
483
484 protected:
485 constexpr DigitalInterrupt()
486 : DigitalIoOptional(internal::AlwaysProvidedBy<DigitalInterrupt>()) {}
487
488 private:
489 // Unavailable functionality
493
499
500 // These overrides invoke PW_CRASH.
501 Status DoSetState(State) final;
502 Result<State> DoGetState() final;
503};
504
505// A digital I/O line that supports only input (getting state).
506//
507// The output and interrupt methods are hidden and must not be called.
508//
509// Use this class in APIs when only input functionality is required.
510// Extend this class to implement a line that only supports getting state.
511//
513 public internal::Conversions<DigitalIn, DigitalIoOptional> {
514 public:
515 // Available functionality
518
519 protected:
520 constexpr DigitalIn()
521 : DigitalIoOptional(internal::AlwaysProvidedBy<DigitalIn>()) {}
522
523 private:
524 // Unavailable functionality
528
536
537 // These overrides invoke PW_CRASH.
538 Status DoSetState(State) final;
539 Status DoSetInterruptHandler(InterruptTrigger, InterruptHandler&&) final;
541};
542
543// An input line that supports interrupts.
544//
545// The output methods are hidden and must not be called.
546//
547// Use in APIs when input and interrupt functionality is required.
548//
549// Extend this class to implement a line that supports input (getting state) and
550// listening for interrupts at the same time.
551//
553 : public DigitalIoOptional,
554 public internal::Conversions<DigitalInInterrupt, DigitalIoOptional> {
555 public:
556 // Available functionality
563
564 protected:
565 constexpr DigitalInInterrupt()
566 : DigitalIoOptional(internal::AlwaysProvidedBy<DigitalInInterrupt>()) {}
567
568 private:
569 // Unavailable functionality
573
577
578 // These overrides invoke PW_CRASH.
579 Status DoSetState(State) final;
580};
581
582// A digital I/O line that supports only output (setting state).
583//
584// Input and interrupt functions are hidden and must not be called.
585//
586// Use in APIs when only output functionality is required.
587// Extend this class to implement a line that supports output only.
588//
590 public internal::Conversions<DigitalOut, DigitalIoOptional> {
591 public:
592 // Available functionality
596
597 protected:
598 constexpr DigitalOut()
599 : DigitalIoOptional(internal::AlwaysProvidedBy<DigitalOut>()) {}
600
601 private:
602 // Unavailable functionality
606
613
614 // These overrides invoke PW_CRASH.
615 Result<State> DoGetState() final;
616 Status DoSetInterruptHandler(InterruptTrigger, InterruptHandler&&) final;
618};
619
620// A digital I/O line that supports output and interrupts.
621//
622// Input methods are hidden and must not be called.
623//
624// Use in APIs when output and interrupt functionality is required. For
625// example, to represent a two-way signalling line.
626//
627// Extend this class to implement a line that supports both output and
628// listening for interrupts at the same time.
629//
631 : public DigitalIoOptional,
632 public internal::Conversions<DigitalOutInterrupt, DigitalIoOptional> {
633 public:
634 // Available functionality
642
643 protected:
644 constexpr DigitalOutInterrupt()
645 : DigitalIoOptional(internal::AlwaysProvidedBy<DigitalOutInterrupt>()) {}
646
647 private:
648 // Unavailable functionality
652
655
656 // These overrides invoke PW_CRASH.
657 Result<State> DoGetState() final;
658};
659
660// A digital I/O line that supports both input and output.
661//
662// Use in APIs when both input and output functionality is required. For
663// example, to represent a line which is shared by multiple controllers.
664//
665// Extend this class to implement a line that supports both input and output at
666// the same time.
667//
669 : public DigitalIoOptional,
670 public internal::Conversions<DigitalInOut, DigitalIoOptional> {
671 public:
672 // Available functionality
678
679 protected:
680 constexpr DigitalInOut()
681 : DigitalIoOptional(internal::AlwaysProvidedBy<DigitalInOut>()) {}
682
683 private:
684 // Unavailable functionality
688
693
694 // These overrides invoke PW_CRASH.
695 Status DoSetInterruptHandler(InterruptTrigger, InterruptHandler&&) final;
697};
698
699// A line that supports input, output, and interrupts.
700//
701// Use in APIs when input, output, and interrupts are required. For example to
702// represent a two-way shared line with state transition notifications.
703//
704// Extend this class to implement a line that supports all the functionality at
705// the same time.
706//
708 : public DigitalIoOptional,
709 public internal::Conversions<DigitalInOutInterrupt, DigitalIoOptional> {
710 public:
711 // Available functionality
721
722 protected:
723 constexpr DigitalInOutInterrupt()
724 : DigitalIoOptional(internal::AlwaysProvidedBy<DigitalInOutInterrupt>()) {
725 }
726
727 private:
728 // Unavailable functionality
732};
733
734} // namespace pw::digital_io
Definition: status.h:85
Definition: digital_io.h:513
Status DoSetInterruptHandler(InterruptTrigger, InterruptHandler &&) final
Status DoSetState(State) final
Definition: digital_io.h:554
Definition: digital_io.h:670
Status DoSetInterruptHandler(InterruptTrigger, InterruptHandler &&) final
Definition: digital_io.h:709
Definition: digital_io.h:476
Status DoSetState(State) final
Result< State > DoGetState() final
Definition: digital_io.h:69
virtual Status DoSetState(State level)=0
Status EnableInterruptHandler()
Definition: digital_io.h:261
Status SetState(State state)
Definition: digital_io.h:117
virtual Status DoSetInterruptHandler(InterruptTrigger trigger, InterruptHandler &&handler)=0
Status Disable()
Definition: digital_io.h:322
virtual Result< State > DoGetState()=0
virtual Status DoEnable(bool enable)=0
Status SetStateInactive()
Definition: digital_io.h:185
Status SetStateActive()
Definition: digital_io.h:163
Status Enable()
Definition: digital_io.h:302
constexpr bool provides_interrupt() const
Definition: digital_io.h:78
constexpr bool provides_output() const
Definition: digital_io.h:76
Status SetInterruptHandler(InterruptTrigger trigger, InterruptHandler &&handler)
Definition: digital_io.h:215
Result< bool > IsStateActive()
Definition: digital_io.h:138
constexpr bool provides_input() const
Definition: digital_io.h:74
Status ClearInterruptHandler()
Definition: digital_io.h:238
Result< State > GetState()
Definition: digital_io.h:96
Status DisableInterruptHandler()
Definition: digital_io.h:280
virtual Status DoEnableInterruptHandler(bool enable)=0
Definition: digital_io.h:590
Result< State > DoGetState() final
Definition: digital_io.h:632
Result< State > DoGetState() final
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:74