1 # SPDX-FileCopyrightText: 2024 Melissa LeBlanc-Williams for Adafruit Industries
3 # SPDX-License-Identifier: MIT
4 """generic_agnostic_board pin interface"""
8 # (data points = 20, amplitude=100, frequency=1)
32 # Values for a sawtooth wave
33 # (data points = 20, amplitude=100)
59 """A basic Pin class for use with generic_agnostic_board"""
74 # pylint: disable=no-self-use
76 def return_toggle(self):
77 """Returns the pin's expected value, toggling between True and False"""
78 toggle_state = not self.previous_value
81 def return_false(self):
82 """Returns the pin's expected value, False"""
85 def return_true(self):
86 """Returns the pin's expected value, True"""
89 def return_random_int(self):
90 """Returns a random integer"""
91 return random.randint(0, 65535)
93 def return_fixed_int_pi(self):
94 """Returns the first five digits of Pi, 31415"""
97 def return_sine_wave(self):
98 """Returns the next value in the sine wave"""
99 if self._wave_idx is None:
102 self._wave_idx = (self._wave_idx + 1) % len(sine_wave)
103 return sine_wave[self._wave_idx]
105 def return_sawtooth_wave(self):
106 """Returns the next value in the sawtooth wave"""
107 if self._wave_idx is None:
110 self._wave_idx = (self._wave_idx + 1) % len(sawtooth_wave)
111 return sawtooth_wave[self._wave_idx]
113 def __init__(self, pin_id=None):
117 self.previous_value = False
118 self.current_value = None
119 self._wave_idx = None
121 # mapping of pin definition names to expected behavior
122 self.pin_behavior = {
123 0: self.return_true, # Dx_INPUT_TRUE
124 1: self.return_false, # Dx_INPUT_FALSE
125 2: self.return_true, # Dx_INPUT_TRUE_PULL_UP
126 3: self.return_true, # Dx_INPUT_TRUE_PULL_DOWN
127 4: self.return_true, # Dx_OUTPUT
128 7: self.return_random_int, # Ax_INPUT_RAND_INT
129 8: self.return_fixed_int_pi, # Ax_INPUT_FIXED_INT_PI
130 9: self.return_sine_wave, # Ax_INPUT_WAVE_SINE
131 10: self.return_sawtooth_wave, # Ax_INPUT_WAVE_SAW
132 11: self.return_toggle, # Dx_INPUT_TOGGLE
135 def init(self, mode=IN, pull=None):
136 """Initialize the Pin"""
138 raise RuntimeError("Can not init a None type pin.")
139 pull = Pin.PULL_NONE if pull is None else pull
143 def write(self, new_value):
144 """Saves the new_value to the pin for subsequent calls to .value"""
145 self.previous_value = self.current_value
146 self.current_value = new_value
149 """Returns the pin's expected value."""
150 self.previous_value = self.current_value
151 # perform a lookup on the pin_behavior dict to get the value
152 self.current_value = self.pin_behavior.get(self.id)()
154 # is pin a pull up and pin is LOW?
155 if self._pull == Pin.PULL_UP and self.current_value is False:
156 self.current_value = False
157 # is pin a pull down and pin is HIGH?
158 if self._pull == Pin.PULL_DOWN and self.current_value is True:
159 self.current_value = False
160 return self.current_value
162 def value(self, val=None):
163 """Set or return the Pin Value"""
165 if self._mode in (Pin.IN, Pin.OUT):
170 if val in (Pin.LOW, Pin.HIGH):
171 return self.write(val)
173 raise ValueError("Invalid value for pin.")
175 if self._mode == Pin.ADC:
179 raise AttributeError("'AnalogIn' object has no attribute 'value'")
181 if self._mode == Pin.DAC:
183 self.previous_value = self.current_value
184 return self.current_value
188 "No action for mode {} with value {}".format(self._mode, val)
192 # create pin instances for each pin
198 # Special "digital" pins
207 # Special digital pins for pixels
223 spiPorts = ((0, SCK, MOSI, MISO),)