Control Surface  1.1.0
MIDI Control Surface library for Arduino
ExtendedIOElement.hpp
Go to the documentation of this file.
1 /* ✔ */
2 
3 #pragma once
4 
6 AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
7 
8 #include <AH/Hardware/Hardware-Types.hpp>
10 
12 
13 /**
14  * @brief An abstract base class for Extended Input/Output elements.
15  *
16  * The limited number of IO pins of the Arduino can be extended by
17  * adding multiplexers, shift registers, IO expanders, etc.
18  * ExtendedIOElement serves as a base class for all these expanders.
19  *
20  * The pins of each extended IO element are mapped to a pin number
21  * greater than the greatest Arduino pin number.
22  * You can supply this pin number to the IO functions in the ExtIO
23  * namespace.
24  * If the pin number corresponds to an actual Arduino pin,
25  * the default Arduino IO function (digitalRead, digitalWrite, ...)
26  * will be called.
27  * If the pin is not an Arduino pin, it is an extended IO pin number,
28  * so the extended IO element that this pin belongs to is looked up,
29  * and the IO function for this element is executed with the correct
30  * pin number.
31  *
32  * For example:
33  * Imagine an Arduino with 20 pins (e.g. the Arduino UNO).
34  * Pins 0 - 19 will correspond to the Arduino pins, and
35  * `ExtIO::digitalRead(pin)` will have the exact same effect as
36  * the standard `digitalRead(pin)` function (albeit a little slower).
37  * Now, we'll add two 8-channel analog multiplexers, let's call them
38  * `mux1` and `mux2`.
39  * The first pin (pin 0) of `mux1` will be extended IO pin number 20,
40  * the last pin (pin 7) of `mux1` will be extended IO pin number 27,
41  * etc.
42  * The first pin of `mux2` will be extended IO pin number 28, you get
43  * the idea.
44  * If you now call `ExtIO::digitalRead(mux1.#pin (7))` or
45  * `ExtIO::digitalRead(27)`, both will be
46  * translated to `mux1.digitalRead(7)`.
47  *
48  * The number of extended IO elements is limited only by the size of
49  * `pin_t`. However, looking up the extended IO element for a given
50  * extended IO pin number uses linear search, so that might add
51  * some noticable overhead for large pin numbers.
52  *
53  * The design here is a compromise: saving a pointer to each extended IO element
54  * to find it directly would be much faster than having to search all elements
55  * each time. On the other hand, it would require each `pin_t` variable to be
56  * at least one byte larger. Since almost all other classes in this library
57  * store pin variables, the memory penalty would be too large, especially on AVR
58  * microcontrollers.
59  * Another reason to do it this way, is that this approach is still fast enough
60  * to make sure it is not noticable to human users.
61  */
62 class ExtendedIOElement : public DoublyLinkable<ExtendedIOElement> {
63  protected:
64  /**
65  * @brief Create an ExtendedIOElement with the given number of pins.
66  *
67  * @param length
68  * The number of pins this element has.
69  */
70  ExtendedIOElement(pin_t length);
71 
72  public:
73  virtual ~ExtendedIOElement();
74 
75  /**
76  * @brief Set the mode of a given pin.
77  *
78  * @note This function might not be implemented by all subclasses.
79  * Some extended IO types, such as shift registers, can only be
80  * used as outputs.
81  * On others, it might be implemented, but it could impact all pins
82  * of the IO element. For example, enabling the internal pull-up
83  * resistor on an analog multiplexer affects all pins of the mux.
84  *
85  * @param pin
86  * The (zero-based) pin of this IO element.
87  * @param mode
88  * The mode to set the pin to (e.g. `INPUT`, `OUTPUT` or
89  * `INPUT_PULLUP`).
90  */
91  virtual void pinMode(pin_t pin, uint8_t mode) = 0;
92 
93  /**
94  * @brief Set the output of the given pin to the given state.
95  *
96  * @param pin
97  * The (zero-based) pin of this IO element.
98  * @param state
99  * The new state to set the pin to.
100  */
101  virtual void digitalWrite(pin_t pin, uint8_t state) = 0;
102 
103  /**
104  * @brief Read the state of the given pin.
105  *
106  * @param pin
107  * The (zero-based) pin of this IO element.
108  * @return The state of the given pin.
109  */
110  virtual int digitalRead(pin_t pin) = 0;
111 
112  /**
113  * @brief Write an analog (or PWM) value to the given pin.
114  *
115  * @param pin
116  * The (zero-based) pin of this IO element.
117  * @param val
118  * The new analog value to set the pin to.
119  */
120  virtual void analogWrite(pin_t pin, analog_t val) = 0;
121 
122  /**
123  * @brief Read the analog value of the given pin.
124  *
125  * @param pin
126  * The (zero-based) pin of this IO element.
127  * @return The new analog value of pin.
128  */
129  virtual analog_t analogRead(pin_t pin) = 0;
130 
131  /**
132  * @brief Initialize the extended IO element.
133  */
134  virtual void begin() = 0;
135 
136  /**
137  * @brief Initialize all extended IO elements.
138  */
139  static void beginAll();
140 
141  /**
142  * @brief Update the extended IO element:
143  * write the internal state to the physical outputs,
144  * or read the physical state into the input buffers.
145  */
146  virtual void update() = 0;
147 
148  /**
149  * @brief Get the extended IO pin number of a given physical pin of this
150  * extended IO element.
151  * @param pin
152  * The zero-based physical pin number of this IO element.
153  * @return The global, unique extended IO pin number for the given pin.
154  */
155  pin_t pin(pin_t pin) const;
156 
157  /**
158  * @brief Get the extended IO pin number of a given physical pin of this
159  * extended IO element.
160  * It is alias for `ExtendedIOElement::pin`.
161  * @param pin
162  * The zero-based physical pin number of this IO element.
163  * @return The global, unique extended IO pin number for the given pin.
164  */
165  pin_t operator[](pin_t pin) const;
166 
167  /**
168  * @brief Get the number of pins this IO element has.
169  *
170  * @return The number of pins this IO element has.
171  */
172  pin_t getLength() const;
173 
174  /**
175  * @brief Get the largest global extended IO pin number that belongs to
176  * this extended IO element.
177  */
178  pin_t getEnd() const;
179 
180  /**
181  * @brief Get the smallest global extended IO pin number that belongs to
182  * this extended IO element.
183  */
184  pin_t getStart() const;
185 
186  /**
187  * @brief Get the list of all Extended IO elements.
188  */
189  static DoublyLinkedList<ExtendedIOElement> &getAll();
190 
191  private:
192  const pin_t length;
193  const pin_t start;
194  const pin_t end;
195  static pin_t offset;
196 
198 };
199 
201 
AH::ExtendedIOElement::offset
static pin_t offset
Definition: ExtendedIOElement.hpp:195
AH::ExtendedIOElement::length
const pin_t length
Definition: ExtendedIOElement.hpp:192
Warnings.hpp
AH::analog_t
uint16_t analog_t
The type returned from analogRead and similar functions.
Definition: Hardware-Types.hpp:15
AH::ExtIO::pinMode
void pinMode(pin_t pin, uint8_t mode)
An ExtIO version of the Arduino function.
Definition: ExtendedInputOutput.cpp:36
AH::ExtIO::analogWrite
void analogWrite(pin_t pin, analog_t val)
An ExtIO version of the Arduino function.
Definition: ExtendedInputOutput.cpp:97
AH_DIAGNOSTIC_POP
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:17
AH::ExtendedIOElement
An abstract base class for Extended Input/Output elements.
Definition: ExtendedIOElement.hpp:62
LinkedList.hpp
AH::ExtendedIOElement::end
const pin_t end
Definition: ExtendedIOElement.hpp:194
AH::ExtendedIOElement::start
const pin_t start
Definition: ExtendedIOElement.hpp:193
AH::ExtIO::analogRead
analog_t analogRead(pin_t pin)
An ExtIO version of the Arduino function.
Definition: ExtendedInputOutput.cpp:86
AH::pin_t
uint16_t pin_t
The type for Arduino pins (and ExtendedIOElement pins).
Definition: Hardware-Types.hpp:17
AH::ExtIO::digitalRead
int digitalRead(pin_t pin)
An ExtIO version of the Arduino function.
Definition: ExtendedInputOutput.cpp:58
AH::ExtendedIOElement::elements
static DoublyLinkedList< ExtendedIOElement > elements
Definition: ExtendedIOElement.hpp:197
DoublyLinkedList
A class for doubly linked lists.
Definition: LinkedList.hpp:27
DoublyLinkable
A class that can be inherited from to allow inserting into a DoublyLinkedList.
Definition: LinkedList.hpp:302
AH_DIAGNOSTIC_WERROR
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:16
BEGIN_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
Definition: AH/Settings/NamespaceSettings.hpp:9
END_AH_NAMESPACE
#define END_AH_NAMESPACE
Definition: AH/Settings/NamespaceSettings.hpp:10
AH::ExtIO::digitalWrite
void digitalWrite(pin_t pin, uint8_t val)
An ExtIO version of the Arduino function.
Definition: ExtendedInputOutput.cpp:47