]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/generic_agnostic_board/pin.py
tests for dig in, an in, an out, dig out all passing
[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     def return_toggle(self):
75         """Returns the pin's expected value, toggling between True and False"""
76         toggle_state = not self.previous_value
77         return toggle_state
78
79     def return_false(self):
80         """Returns the pin's expected value, False"""
81         return False
82
83     def return_true(self):
84         """Returns the pin's expected value, True"""
85         return True
86
87     def return_random_int(self):
88         """Returns a random integer"""
89         return random.randint(0, 65535)
90
91     def return_fixed_int_pi(self):
92         """Returns the first five digits of Pi, 31415"""
93         return 31415
94
95     def return_sine_wave(self):
96         """Returns the next value in the sine wave"""
97         if self._wave_idx is None:
98             self._wave_idx = 0
99         else:
100             self._wave_idx = (self._wave_idx + 1) % len(sine_wave)
101         return sine_wave[self._wave_idx]
102
103     def return_sawtooth_wave(self):
104         """Returns the next value in the sawtooth wave"""
105         if self._wave_idx is None:
106             self._wave_idx = 0
107         else:
108             self._wave_idx = (self._wave_idx + 1) % len(sawtooth_wave)
109         return sawtooth_wave[self._wave_idx]
110
111     def __init__(self, pin_id=None):
112         self.id = pin_id
113         self._mode = None
114         self._pull = None
115         self.previous_value = False
116         self.current_value = None
117         self._wave_idx = None
118
119         # mapping of pin definition names to expected behavior
120         self.pin_behavior = {
121             0: self.return_true,  # Dx_INPUT_TRUE
122             1: self.return_false,  # Dx_INPUT_FALSE
123             2: self.return_true,  # Dx_INPUT_TRUE_PULL_UP
124             3: self.return_true,  # Dx_INPUT_TRUE_PULL_DOWN
125             4: self.return_true,  # Dx_OUTPUT
126             7: self.return_random_int,  # Ax_INPUT_RAND_INT
127             8: self.return_fixed_int_pi,  # Ax_INPUT_FIXED_INT_PI
128             9: self.return_sine_wave,  # Ax_INPUT_WAVE_SINE
129             10: self.return_sawtooth_wave,  # Ax_INPUT_WAVE_SAW
130             11: self.return_toggle,  # Dx_INPUT_TOGGLE
131         }
132
133     def init(self, mode=IN, pull=None):
134         """Initialize the Pin"""
135         if self.id is None:
136             raise RuntimeError("Can not init a None type pin.")
137         pull = Pin.PULL_NONE if pull is None else pull
138         self._pull = pull
139         self._mode = mode
140
141     def write(self, new_value):
142         """Saves the new_value to the pin for subsequent calls to .value"""
143         self.previous_value = self.current_value
144         self.current_value = new_value
145
146     def read(self):
147         """Returns the pin's expected value."""
148         self.previous_value = self.current_value
149         # perform a lookup on the pin_behavior dict to get the value
150         self.current_value = self.pin_behavior.get(self.id)()
151
152         # is pin a pull up and pin is LOW?
153         if self._pull == Pin.PULL_UP and self.current_value == False:
154             self.current_value = False
155         # is pin a pull down and pin is HIGH?
156         if self._pull == Pin.PULL_DOWN and self.current_value == True:
157             self.current_value = False
158         return self.current_value
159
160     def value(self, val=None):
161         """Set or return the Pin Value"""
162         # Digital In / Out
163         if self._mode in (Pin.IN, Pin.OUT):
164             # digital read
165             if val is None:
166                 return self.read()
167             # digital write
168             if val in (Pin.LOW, Pin.HIGH):
169                 return self.write(val)
170             # nope
171             raise ValueError("Invalid value for pin.")
172         # Analog In
173         if self._mode == Pin.ADC:
174             if val is None:
175                 return self.read()
176             # read only
177             raise AttributeError("'AnalogIn' object has no attribute 'value'")
178         # Analog Out
179         if self._mode == Pin.DAC:
180             if val is None:
181                 self.previous_value = self.current_value
182                 return self.current_value
183             self.write(val)
184             return None
185         raise RuntimeError(
186             "No action for mode {} with value {}".format(self._mode, val)
187         )
188
189
190 # create pin instances for each pin
191 D0 = Pin(0)
192 D1 = Pin(1)
193 D2 = Pin(2)
194 D3 = Pin(3)
195 D4 = Pin(4)
196 # Special "digital" pins
197 D6 = Pin(6)
198 # Analog pins
199 A0 = Pin(7)
200 A1 = Pin(8)
201 A2 = Pin(9)
202 A3 = Pin(10)
203 A4 = Pin(12)
204
205 D7 = Pin(11)
206
207 # I2C pins
208 SDA = Pin()
209 SCL = Pin()
210
211 # SPI pins
212 SCLK = Pin()
213 SCK = Pin()
214 MOSI = Pin()
215 MISO = Pin()
216 CS = Pin()
217
218 # UART pins
219 UART_TX = Pin()
220 UART_RX = Pin()