1+ # The MIT License (MIT)
2+ #
3+ # Copyright (c) 2019 Brent Rubell for Adafruit
4+ #
5+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6+ # of this software and associated documentation files (the "Software"), to deal
7+ # in the Software without restriction, including without limitation the rights
8+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+ # copies of the Software, and to permit persons to whom the Software is
10+ # furnished to do so, subject to the following conditions:
11+ #
12+ # The above copyright notice and this permission notice shall be included in
13+ # all copies or substantial portions of the Software.
14+ #
15+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+ # THE SOFTWARE.
22+ """
23+ `digitalio`
24+ ==============================
25+ DigitalIO for ESP32 over SPI.
26+
27+ * Author(s): Brent Rubell
28+ """
29+ from micropython import const
30+
31+ class DriveMode ():
32+ PUSH_PULL = None
33+ OPEN_DRAIN = None
34+
35+ DriveMode .PUSH_PULL = DriveMode ()
36+ DriveMode .OPEN_DRAIN = DriveMode ()
37+
38+ class Direction :
39+ INPUT = None
40+ OUTPUT = None
41+
42+ Direction .INPUT = Direction ()
43+ Direction .OUTPUT = Direction ()
44+
45+ class Pull :
46+ UP = None
47+ DOWN = None
48+
49+ Pull .UP = Pull ()
50+ Pull .DOWN = Pull ()
51+
52+ class Pin :
53+ IN = const (0x00 )
54+ OUT = const (0x01 )
55+ LOW = const (0x00 )
56+ HIGH = const (0x01 )
57+ id = None
58+ _value = LOW
59+ _mode = IN
60+
61+ def __init__ (self , esp_pin_number , esp ):
62+ self .id = esp_pin_number
63+ self ._esp = esp
64+
65+ def init (self , mode = IN , pull = None ):
66+ """Initalizes a pre-defined pin.
67+ :param mode: Pin mode (IN, OUT, LOW, HIGH)
68+ :param pull: Pull value (PULL_NONE, PULL_UP, PULL_DOWN)
69+ """
70+ print ('pin init' )
71+ if mode != None :
72+ if mode == self .IN :
73+ self ._mode = self .IN
74+ self ._esp .set_pin_mode (self .id , 0 )
75+ elif mode == self .OUT :
76+ self ._mode = self .OUT
77+ self ._esp .set_pin_mode (self .id , 1 )
78+ else :
79+ raise RuntimeError ("Invalid mode defined" )
80+ if pull != None :
81+ raise RuntimeError ("ESP32 does not have pull-up resistors defined." )
82+
83+ def value (self , val = None ):
84+ """Sets ESP32 Pin GPIO output mode.
85+ :param val: Output level (LOW, HIGH)
86+ """
87+ if val != None :
88+ if val == self .LOW :
89+ self ._value = val
90+ self ._esp .set_digital_write (self .id , 0 )
91+ elif val == self .HIGH :
92+ self ._value = val
93+ self ._esp .set_digital_write (self .id , 1 )
94+ else :
95+ raise RuntimeError ("Invalid value for pin" )
96+ else :
97+ raise AttributeError ("ESP32SPI does not allow for a digital input." )
98+
99+ def __repr__ (self ):
100+ return str (self .id )
101+
102+
103+ class DigitalInOut ():
104+ """Mock DigitalIO CircuitPython API Implementation for ESP32SPI.
105+ Provides access to ESP_SPIcontrol methods.
106+ """
107+ _pin = None
108+ def __init__ (self , esp , pin ):
109+ self ._esp = esp
110+ self ._pin = Pin (pin , self ._esp )
111+ print ('id:' , self ._pin .id )
112+ self ._direction = Direction .INPUT
113+
114+ def deinit (self ):
115+ self ._pin = None
116+
117+ def __exit__ (self ):
118+ self .deinit ()
119+
120+ @property
121+ def direction (self ):
122+ return self .__direction
123+
124+ @direction .setter
125+ def direction (self , dir ):
126+ self .__direction = dir
127+ if dir is Direction .OUTPUT :
128+ self ._pin .init (mode = Pin .OUT )
129+ self .value = False
130+ self .drive_mode = DriveMode .PUSH_PULL
131+ elif dir is Direction .INPUT :
132+ self ._pin .init (mode = Pin .IN )
133+ self .pull = None
134+ else :
135+ raise AttributeError ("Not a Direction" )
136+
137+ @property
138+ def value (self ):
139+ return self ._pin .value () is 1
140+
141+ @value .setter
142+ def value (self , val ):
143+ if self .direction is Direction .OUTPUT :
144+ self ._pin .value (1 if val else 0 )
145+ else :
146+ raise AttributeError ("Not an output" )
0 commit comments