]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/generic_agnostic_board/pin.py
1f6818e64c750c1a9e85984cbe718cad42a2daae
[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
8 class Pin:
9     """A basic Pin class for use with generic_agnostic_board"""
10
11     # pin modes
12     OUT = 0
13     IN = 1
14     ADC = 2
15     DAC = 3
16     # pin values
17     LOW = 0
18     HIGH = 1
19     # pin pulls
20     PULL_NONE = 0
21     PULL_UP = 1
22     PULL_DOWN = 2
23
24     def return_toggle(self):
25         """Returns the pin's expected value, toggling between True and False"""
26         toggle_state = not self.previous_value
27         return toggle_state
28
29     def return_false(self):
30         """Returns the pin's expected value, False"""
31         return False
32
33     def return_true(self):
34         """Returns the pin's expected value, True"""
35         return True
36
37     def return_random_int(self):
38         """Returns a random integer"""
39         return random.randint(0, 65535)
40
41     def return_fixed_int_pi(self):
42         """Returns the first five digits of Pi, 31415"""
43         return 31415
44
45     def __init__(self, pin_id=None):
46         self.id = pin_id
47         self._mode = None
48         self._pull = None
49         self.previous_value = False
50         self.current_value = None
51
52         # mapping of pin definition names to expected behavior
53         self.pin_behavior = {
54             0: self.return_true,  # Dx_INPUT_TRUE
55             1: self.return_false,  # Dx_INPUT_FALSE
56             2: self.return_true,  # Dx_INPUT_TRUE_PULL_UP
57             3: self.return_true,  # Dx_INPUT_TRUE_PULL_DOWN
58             4: self.return_true,  # Dx_OUTPUT_TRUE
59             5: self.return_false,  # Dx_OUTPUT_FALSE
60             6: self.return_true,  # NEOPIXEL
61             7: self.return_random_int,  # Ax_INPUT_RAND_INT
62             8: self.return_fixed_int_pi,  # Ax_INPUT_FIXED_INT_PI
63             9: self.return_true,  # Ax_OUTPUT_WAVE_SINE
64             10: self.return_true,  # Ax_OUTPUT_WAVE_SAWTOOTH
65             11: self.return_toggle,  # Dx_INPUT_TOGGLE
66             # Add other mappings as needed
67         }
68
69     def init(self, mode=IN, pull=None):
70         """Initialize the Pin"""
71         if self.id is None:
72             raise RuntimeError("Can not init a None type pin.")
73         pull = Pin.PULL_NONE if pull is None else pull
74         self._pull = pull
75         self._mode = mode
76
77     def write(self, new_value):
78         """Saves the new_value to the pin for subsequent calls to .value"""
79         self.previous_value = self.current_value
80         self.current_value = new_value
81
82     def read(self):
83         print("\nread mode: ", self._mode)
84         """Returns the pin's expected value."""
85         self.previous_value = self.current_value
86         # perform a lookup on the pin_behavior dict to get the value
87         self.current_value = self.pin_behavior.get(self.id)()
88
89         # is pin a pull up and pin is LOW?
90         if self._pull == Pin.PULL_UP and self.current_value == False:
91             self.current_value = True
92         # is pin a pull down and pin is HIGH?
93         if self._pull == Pin.PULL_DOWN and self.current_value == True:
94             print("switching PDR to False")
95             self.current_value = False
96
97         return self.current_value
98
99     def value(self, val=None):
100         """Set or return the Pin Value"""
101         # Digital In / Out
102         if self._mode in (Pin.IN, Pin.OUT):
103             # digital read
104             if val is None:
105                 return self.read()
106             # digital write
107             if val in (Pin.LOW, Pin.HIGH):
108                 return self.write(val)
109             # nope
110             raise ValueError("Invalid value for pin.")
111         # Analog In
112         if self._mode == Pin.ADC:
113             if val is None:
114                 return self.read()
115             # read only
116             raise AttributeError("'AnalogIn' object has no attribute 'value'")
117         # Analog Out
118         if self._mode == Pin.DAC:
119             if val is None:
120                 # write only
121                 raise AttributeError("unreadable attribute")
122             self.write(val)
123             return None
124         raise RuntimeError(
125             "No action for mode {} with value {}".format(self._mode, val)
126         )
127
128
129 # create pin instances for each pin
130 D0 = Pin(0)
131 D1 = Pin(1)
132 D2 = Pin(2)
133 D3 = Pin(3)
134 D4 = Pin(4)
135 D5 = Pin(5)
136 # Special "digital" pins
137 D6 = Pin(6)
138 # Analog pins
139 A0 = Pin(7)
140 A1 = Pin(8)
141 A2 = Pin(9)
142 A3 = Pin(10)
143
144 D7 = Pin(11)
145
146 # I2C pins
147 SDA = Pin()
148 SCL = Pin()
149
150 # SPI pins
151 SCLK = Pin()
152 SCK = Pin()
153 MOSI = Pin()
154 MISO = Pin()
155 CS = Pin()
156
157 # UART pins
158 UART_TX = Pin()
159 UART_RX = Pin()