1 # SPDX-FileCopyrightText: 2024 Melissa LeBlanc-Williams for Adafruit Industries
3 # SPDX-License-Identifier: MIT
4 """generic_agnostic_board pin interface"""
7 # Values for sine wave analog output
8 # (data points = 20, amplitude=100, frequency=1)
32 # Values for a square wave analog output
33 # (data points = 20, amplitude=100)
58 """A basic Pin class for use with generic_agnostic_board"""
73 def return_toggle(self):
74 """Returns the pin's expected value, toggling between True and False"""
75 toggle_state = not self.previous_value
78 def return_false(self):
79 """Returns the pin's expected value, False"""
82 def return_true(self):
83 """Returns the pin's expected value, True"""
86 def return_random_int(self):
87 """Returns a random integer"""
88 return random.randint(0, 65535)
90 def return_fixed_int_pi(self):
91 """Returns the first five digits of Pi, 31415"""
94 def return_sine_wave(self):
95 """Returns the next value in the sine wave"""
96 if self._wave_idx is None:
99 self._wave_idx = (self._wave_idx + 1) % len(sine_wave)
100 return sine_wave[self._wave_idx]
102 def return_square_wave(self):
103 """Returns the next value in the square wave"""
104 if self._wave_idx is None:
107 self._wave_idx = (self._wave_idx + 1) % len(square_wave_int)
108 return square_wave_int[self._wave_idx]
110 def __init__(self, pin_id=None):
114 self.previous_value = False
115 self.current_value = None
116 self._wave_idx = None
118 # mapping of pin definition names to expected behavior
119 self.pin_behavior = {
120 0: self.return_true, # Dx_INPUT_TRUE
121 1: self.return_false, # Dx_INPUT_FALSE
122 2: self.return_true, # Dx_INPUT_TRUE_PULL_UP
123 3: self.return_true, # Dx_INPUT_TRUE_PULL_DOWN
124 4: self.return_true, # Dx_OUTPUT
125 7: self.return_random_int, # Ax_INPUT_RAND_INT
126 8: self.return_fixed_int_pi, # Ax_INPUT_FIXED_INT_PI
127 9: self.return_sine_wave, # Ax_OUTPUT_WAVE_SINE
128 10: self.return_square_wave, # Ax_OUTPUT_WAVE_SAWTOOTH
129 11: self.return_toggle # Dx_INPUT_TOGGLE
132 def init(self, mode=IN, pull=None):
133 """Initialize the Pin"""
135 raise RuntimeError("Can not init a None type pin.")
136 pull = Pin.PULL_NONE if pull is None else pull
140 def write(self, new_value):
141 """Saves the new_value to the pin for subsequent calls to .value"""
142 self.previous_value = self.current_value
143 self.current_value = new_value
146 """Returns the pin's expected value."""
147 self.previous_value = self.current_value
148 # perform a lookup on the pin_behavior dict to get the value
149 self.current_value = self.pin_behavior.get(self.id)()
151 # is pin a pull up and pin is LOW?
152 if self._pull == Pin.PULL_UP and self.current_value == False:
153 self.current_value = False
154 # is pin a pull down and pin is HIGH?
155 if self._pull == Pin.PULL_DOWN and self.current_value == True:
156 self.current_value = False
157 return self.current_value
159 def value(self, val=None):
160 """Set or return the Pin Value"""
162 if self._mode in (Pin.IN, Pin.OUT):
167 if val in (Pin.LOW, Pin.HIGH):
168 return self.write(val)
170 raise ValueError("Invalid value for pin.")
172 if self._mode == Pin.ADC:
176 raise AttributeError("'AnalogIn' object has no attribute 'value'")
178 if self._mode == Pin.DAC:
181 raise AttributeError("unreadable attribute")
185 "No action for mode {} with value {}".format(self._mode, val)
189 # create pin instances for each pin
195 # Special "digital" pins