]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/generic_agnostic_board/pin.py
Untangle code and remove pylint disables
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / generic_agnostic_board / pin.py
1 # SPDX-FileCopyrightText: 2024 Melissa LeBlanc-Williams for Adafruit Industries
2 #
3 # SPDX-License-Identifier: MIT
4 """generic_agnostic_board pin interface"""
5 import random
6
7 # Values for sine wave
8 # (data points = 20, amplitude=100, frequency=1)
9 sine_wave = [
10     0,
11     31,
12     59,
13     81,
14     95,
15     100,
16     95,
17     81,
18     59,
19     31,
20     0,
21     -31,
22     -59,
23     -81,
24     -95,
25     -100,
26     -95,
27     -81,
28     -59,
29     -31,
30 ]
31
32 # Values for a sawtooth wave
33 # (data points = 20, amplitude=100)
34 sawtooth_wave = [
35     -100,
36     -80,
37     -60,
38     -40,
39     -20,
40     0,
41     20,
42     40,
43     60,
44     80,
45     -100,
46     -80,
47     -60,
48     -40,
49     -20,
50     0,
51     20,
52     40,
53     60,
54     80,
55 ]
56
57
58 class Pin:
59     """A basic Pin class for use with generic_agnostic_board"""
60
61     # pin modes
62     OUT = 0
63     IN = 1
64     ADC = 2
65     DAC = 3
66     # pin values
67     LOW = 0
68     HIGH = 1
69     # pin pulls
70     PULL_NONE = 0
71     PULL_UP = 1
72     PULL_DOWN = 2
73
74     # pylint: disable=no-self-use
75
76     def return_toggle(self):
77         """Returns the pin's expected value, toggling between True and False"""
78         toggle_state = not self.previous_value
79         return toggle_state
80
81     def return_false(self):
82         """Returns the pin's expected value, False"""
83         return False
84
85     def return_true(self):
86         """Returns the pin's expected value, True"""
87         return True
88
89     def return_random_int(self):
90         """Returns a random integer"""
91         return random.randint(0, 65535)
92
93     def return_fixed_int_pi(self):
94         """Returns the first five digits of Pi, 31415"""
95         return 31415
96
97     def return_sine_wave(self):
98         """Returns the next value in the sine wave"""
99         if self._wave_idx is None:
100             self._wave_idx = 0
101         else:
102             self._wave_idx = (self._wave_idx + 1) % len(sine_wave)
103         return sine_wave[self._wave_idx]
104
105     def return_sawtooth_wave(self):
106         """Returns the next value in the sawtooth wave"""
107         if self._wave_idx is None:
108             self._wave_idx = 0
109         else:
110             self._wave_idx = (self._wave_idx + 1) % len(sawtooth_wave)
111         return sawtooth_wave[self._wave_idx]
112
113     def __init__(self, pin_id=None):
114         self.id = pin_id
115         self._mode = None
116         self._pull = None
117         self.previous_value = False
118         self.current_value = None
119         self._wave_idx = None
120
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
133         }
134
135     def init(self, mode=IN, pull=None):
136         """Initialize the Pin"""
137         if self.id is None:
138             raise RuntimeError("Can not init a None type pin.")
139         pull = Pin.PULL_NONE if pull is None else pull
140         self._pull = pull
141         self._mode = mode
142
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
147
148     def read(self):
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)()
153
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
161
162     def value(self, val=None):
163         """Set or return the Pin Value"""
164         # Digital In / Out
165         if self._mode in (Pin.IN, Pin.OUT):
166             # digital read
167             if val is None:
168                 return self.read()
169             # digital write
170             if val in (Pin.LOW, Pin.HIGH):
171                 return self.write(val)
172             # nope
173             raise ValueError("Invalid value for pin.")
174         # Analog In
175         if self._mode == Pin.ADC:
176             if val is None:
177                 return self.read()
178             # read only
179             raise AttributeError("'AnalogIn' object has no attribute 'value'")
180         # Analog Out
181         if self._mode == Pin.DAC:
182             if val is None:
183                 self.previous_value = self.current_value
184                 return self.current_value
185             self.write(val)
186             return None
187         raise RuntimeError(
188             "No action for mode {} with value {}".format(self._mode, val)
189         )
190
191
192 # create pin instances for each pin
193 D0 = Pin(0)
194 D1 = Pin(1)
195 D2 = Pin(2)
196 D3 = Pin(3)
197 D4 = Pin(4)
198 # Special "digital" pins
199 D6 = Pin(6)
200 # Analog pins
201 A0 = Pin(7)
202 A1 = Pin(8)
203 A2 = Pin(9)
204 A3 = Pin(10)
205 A4 = Pin(12)
206
207 # Special digital pins for pixels
208 D7 = Pin(11)
209 D8 = Pin(13)
210 D9 = Pin(14)
211
212 # I2C pins
213 SDA = Pin()
214 SCL = Pin()
215
216 # SPI pins
217 SCLK = Pin()
218 SCK = Pin()
219 MOSI = Pin()
220 MISO = Pin()
221 CS = Pin()
222
223 spiPorts = ((0, SCK, MOSI, MISO),)
224
225
226 # UART pins
227 UART_TX = Pin()
228 UART_RX = Pin()