|
| 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() |
0 commit comments