]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/fake_mcp2221/pin.py
Merge pull request #807 from brentru/force-mcp
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / fake_mcp2221 / pin.py
1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
2 #
3 # SPDX-License-Identifier: MIT
4 """fake_mcp2221 pin names"""
5 import random
6
7
8 class Pin:
9     """A basic Pin class for use with a "fake" MCP2221."""
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
20     def __init__(self, pin_id=None):
21         self.id = pin_id
22         self._mode = None
23         self._prv_val = False
24
25     def init(self, mode=IN, pull=None):
26         """Initialize the Pin"""
27         if self.id is None:
28             raise RuntimeError("Can not init a None type pin.")
29         if pull is not None:
30             raise NotImplementedError("Internal pullups and pulldowns not supported")
31         if mode in (Pin.IN, Pin.OUT):
32             # All pins can do GPIO
33             # mcp2221.gp_set_mode(self.id, mcp2221.GP_GPIO)
34             # mcp2221.gpio_set_direction(self.id, mode)
35             self._mode = mode
36         elif mode == Pin.ADC:
37             # ADC only available on these pins
38             if self.id not in (1, 2, 3):
39                 raise ValueError("Pin does not have ADC capabilities")
40             # mcp2221.gp_set_mode(self.id, mcp2221.GP_ALT0)
41             # mcp2221.adc_configure()
42         elif mode == Pin.DAC:
43             # DAC only available on these pins
44             if self.id not in (2, 3):
45                 raise ValueError("Pin does not have DAC capabilities")
46             # mcp2221.gp_set_mode(self.id, mcp2221.GP_ALT1)
47             # mcp2221.dac_configure()
48         else:
49             raise ValueError("Incorrect pin mode: {}".format(mode))
50         self._mode = mode
51
52     def value(self, val=None):
53         """Set or return the Pin Value"""
54         # Digital In / Out
55         if self._mode in (Pin.IN, Pin.OUT):
56             # digital read
57             if val is None:
58                 # The returned value toggles between True and false
59                 self._prv_val = not self._prv_val
60                 return self._prv_val
61             # digital write
62             if val in (Pin.LOW, Pin.HIGH):
63                 # We don't need to do anything here - no data is produced
64                 return None
65             # nope
66             raise ValueError("Invalid value for pin.")
67         # Analog In
68         if self._mode == Pin.ADC:
69             if val is None:
70                 # Returned value is between 0 and 65535 inclusive
71                 # https://docs.circuitpython.org/en/latest/shared-bindings/analogio/index.html#analogio.AnalogIn.value
72                 self._prv_val = random.randint(0, 65535)
73                 return self._prv_val
74             # read only
75             raise AttributeError("'AnalogIn' object has no attribute 'value'")
76         # Analog Out
77         if self._mode == Pin.DAC:
78             if val is None:
79                 # write only
80                 raise AttributeError("unreadable attribute")
81             # We don't write to the DAC as this is a "fake" implementation
82             return None
83         raise RuntimeError(
84             "No action for mode {} with value {}".format(self._mode, val)
85         )
86
87
88 # create pin instances for each pin
89 G0 = Pin(0)
90 G1 = Pin(1)
91 G2 = Pin(2)
92 G3 = Pin(3)
93
94 SCL = Pin()
95 SDA = Pin()