]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/digitalio.py
8a0c324694de63f41033392a57ea22ae64ffeb61
[Adafruit_Blinka-hackapet.git] / src / digitalio.py
1 """
2 `digitalio` - Digital input and output control
3 =================================================
4
5 See `CircuitPython:digitalio` in CircuitPython for more details.
6
7 * Author(s): cefn
8 """
9
10 from adafruit_blinka.agnostic import board_id, detector
11
12 # pylint: disable=ungrouped-imports,wrong-import-position
13
14 if detector.chip.BCM2XXX:
15     from adafruit_blinka.microcontroller.bcm283x.pin import Pin
16 elif detector.chip.AM33XX:
17     from adafruit_blinka.microcontroller.am335x.pin import Pin
18 elif detector.chip.SUN8I:
19     from adafruit_blinka.microcontroller.allwinner_h3.pin import Pin
20 elif detector.chip.SAMA5:
21     from adafruit_blinka.microcontroller.sama5.pin import Pin
22 elif detector.chip.STM32:
23     from machine import Pin
24 from adafruit_blinka import Enum, ContextManaged
25
26 class DriveMode(Enum):
27     PUSH_PULL = None
28     OPEN_DRAIN = None
29
30
31 DriveMode.PUSH_PULL = DriveMode()
32 DriveMode.OPEN_DRAIN = DriveMode()
33
34
35 class Direction(Enum):
36     INPUT = None
37     OUTPUT = None
38
39
40 Direction.INPUT = Direction()
41 Direction.OUTPUT = Direction()
42
43
44 class Pull(Enum):
45     UP = None
46     DOWN = None
47     #NONE=None
48
49
50 Pull.UP = Pull()
51 Pull.DOWN = Pull()
52
53 #Pull.NONE = Pull()
54
55
56 class DigitalInOut(ContextManaged):
57     _pin = None
58
59     def __init__(self, pin):
60         self._pin = Pin(pin.id)
61         self.direction = Direction.INPUT
62
63     def switch_to_output(self, value=False, drive_mode=DriveMode.PUSH_PULL):
64         self.direction = Direction.OUTPUT
65         self.value = value
66         self.drive_mode = drive_mode
67
68     def switch_to_input(self, pull=None):
69         self.direction = Direction.INPUT
70         self.pull = pull
71
72     def deinit(self):
73         del self._pin
74
75     @property
76     def direction(self):
77         return self.__direction
78
79     @direction.setter
80     def direction(self, dir):
81         self.__direction = dir
82         if dir is Direction.OUTPUT:
83             self._pin.init(mode=Pin.OUT)
84             self.value = False
85             self.drive_mode = DriveMode.PUSH_PULL
86         elif dir is Direction.INPUT:
87             self._pin.init(mode=Pin.IN)
88             self.pull = None
89         else:
90             raise AttributeError("Not a Direction")
91
92     @property
93     def value(self):
94         return self._pin.value() is 1
95
96     @value.setter
97     def value(self, val):
98         if self.direction is Direction.OUTPUT:
99             self._pin.value(1 if val else 0)
100         else:
101             raise AttributeError("Not an output")
102
103     @property
104     def pull(self):
105         if self.direction is Direction.INPUT:
106             return self.__pull
107         else:
108             raise AttributeError("Not an input")
109
110     @pull.setter
111     def pull(self, pul):
112         if self.direction is Direction.INPUT:
113             self.__pull = pul
114             if pul is Pull.UP:
115                 self._pin.init(mode=Pin.IN, pull=Pin.PULL_UP)
116             elif pul is Pull.DOWN:
117                 if hasattr(Pin, "PULL_DOWN"):
118                     self._pin.init(mode=Pin.IN, pull=Pin.PULL_DOWN)
119                 else:
120                     raise NotImplementedError("{} unsupported on {}".format(
121                         Pull.DOWN, board_id))
122             elif pul is None:
123                 self._pin.init(mode=Pin.IN, pull=None)
124             else:
125                 raise AttributeError("Not a Pull")
126         else:
127             raise AttributeError("Not an input")
128
129     @property
130     def drive_mode(self):
131         if self.direction is Direction.OUTPUT:
132             return self.__drive_mode  #
133         else:
134             raise AttributeError("Not an output")
135
136     @drive_mode.setter
137     def drive_mode(self, mod):
138         self.__drive_mode = mod
139         if mod is DriveMode.OPEN_DRAIN:
140             self._pin.init(mode=Pin.OPEN_DRAIN)
141         elif mod is DriveMode.PUSH_PULL:
142             self._pin.init(mode=Pin.OUT)