]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/busio.py
Merge pull request #11 from tannewt/auto_pypi
[Adafruit_Blinka-hackapet.git] / src / busio.py
1 from adafruit_blinka import Enum, Lockable, agnostic
2
3 class I2C(Lockable):
4     def __init__(self, scl, sda, frequency=400000):
5         self.init(scl, sda, frequency)
6
7     def init(self, scl, sda, frequency):
8         self.deinit()
9         from machine import I2C as _I2C
10         from microcontroller.pin import i2cPorts
11         for portId, portScl, portSda in i2cPorts:
12             if scl == portScl and sda == portSda:
13                 self._i2c = I2C(portId, mode=_I2C.MASTER, baudrate=frequency)
14                 break
15         else:
16             raise NotImplementedError("No Hardware I2C on (scl,sda)={}\nValid UART ports".format(
17         (scl, sda), i2cPorts))
18
19     def deinit(self):
20         try:
21             del self._i2c
22         except AttributeError:
23             pass
24
25     def __enter__(self):
26         return self
27
28     def __exit__(self, exc_type, exc_value, traceback):
29         self.deinit()
30
31     def scan(self):
32         return self._i2c.scan()
33
34     def readfrom_into(self, address, buffer, start=0, end=None):
35         if start is not 0 or end is not None:
36             if end is None:
37                 end = len(buffer)
38             buffer = memoryview(buffer)[start:end]
39         stop = True  # remove for efficiency later
40         return self._i2c.readfrom_into(address, buffer, stop)
41
42     def writeto(self, address, buffer, start=0, end=None, stop=True):
43         if start is not 0 or end is not None:
44             if end is None:
45                 return self._i2c.writeto(address, memoryview(buffer)[start:], stop)
46             else:
47                 return self._i2c.writeto(address, memoryview(buffer)[start:end], stop)
48         return self._i2c.writeto(address, buffer, stop)
49
50
51 class SPI(Lockable):
52     def __init__(self, clock, MOSI=None, MISO=None):
53         from microcontroller.pin import spiPorts
54         for portId, portSck, portMosi, portMiso in spiPorts:
55             if clock == portSck and MOSI == portMosi and MISO == portMiso:
56                 self._spi = SPI(portId)
57                 self._pins = (portSck, portMosi, portMiso)
58                 break
59         else:
60             raise NotImplementedError(
61                 "No Hardware SPI on (clock, MOSI, MISO)={}\nValid SPI ports:{}".
62                 format((clock, MOSI, MISO), spiPorts))
63
64     def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
65         if self._locked:
66             from machine import Pin
67             # TODO check if #init ignores MOSI=None rather than unsetting, to save _pinIds attribute
68             self._spi.init(
69                 baudrate=baudrate,
70                 polarity=polarity,
71                 phase=phase,
72                 bits=bits,
73                 firstbit=SPI.MSB,
74                 sck=Pin(self._pins[0].id),
75                 mosi=Pin(self._pins[1].id),
76                 miso=Pin(self._pins[2].id)
77             )
78         else:
79             raise RuntimeError("First call try_lock()")
80
81     def deinit(self):
82         self._spi = None
83         self._pinIds = None
84
85     def write(self, buf):
86         return self._spi.write(buf)
87
88     def readinto(self, buf):
89         return self.readinto(buf)
90
91     def write_readinto(self, buffer_out, buffer_in):
92         return self.write_readinto(buffer_out, buffer_in)
93
94
95 class UART(Lockable):
96     class Parity(Enum):
97         pass
98
99     Parity.ODD = Parity()
100     Parity.EVEN = Parity()
101
102     def __init__(self,
103                  tx,
104                  rx,
105                  baudrate=9600,
106                  bits=8,
107                  parity=None,
108                  stop=1,
109                  timeout=1000,
110                  receiver_buffer_size=64,
111                  flow=None):
112         from machine import UART as _UART
113         from microcontroller.pin import uartPorts
114
115         self.baudrate = baudrate
116
117         if flow is not None:  # default 0
118             raise NotImplementedError(
119                 "Parameter '{}' unsupported on {}".format(
120                     "flow", agnostic.board))
121
122         # translate parity flag for Micropython
123         if parity is UART.Parity.ODD:
124             parity = 1
125         elif parity is UART.Parity.EVEN:
126             parity = 0
127         elif parity is None:
128             pass
129         else:
130             raise ValueError("Invalid parity")
131
132         # check tx and rx have hardware support
133         for portId, portTx, portRx in uartPorts:  #
134             if portTx == tx and portRx == rx:
135                 self._uart = _UART(
136                     portId,
137                     baudrate,
138                     bits=bits,
139                     parity=parity,
140                     stop=stop,
141                     timeout=timeout,
142                     read_buf_len=receiver_buffer_size
143                 )
144                 break
145         else:
146             raise NotImplementedError(
147                 "No Hardware UART on (tx,rx)={}\nValid UART ports".format(
148                     (tx, rx), uartPorts))
149
150     def deinit(self):
151         self._uart = None
152
153     def read(self, nbytes=None):
154         return self._uart.read(nbytes)
155
156     def readinto(self, buf, nbytes=None):
157         return self._uart.readinto(buf, nbytes)
158
159     def readline(self):
160         return self._uart.readline()
161
162     def write(self, buf):
163         return self._uart.write(buf)