2 `busio` - Bus protocol support like I2C and SPI
3 =================================================
5 See `CircuitPython:busio` in CircuitPython for more details.
10 from adafruit_blinka import Enum, Lockable, agnostic
11 from adafruit_blinka.agnostic import board_id, detector
12 import adafruit_platformdetect.board as ap_board
15 def __init__(self, scl, sda, frequency=400000):
16 self.init(scl, sda, frequency)
18 def init(self, scl, sda, frequency):
20 if detector.board.ftdi_ft232h:
21 from adafruit_blinka.microcontroller.ft232h.i2c import I2C
24 elif detector.board.any_embedded_linux:
25 from adafruit_blinka.microcontroller.generic_linux.i2c import I2C as _I2C
27 from machine import I2C as _I2C
28 from microcontroller.pin import i2cPorts
29 for portId, portScl, portSda in i2cPorts:
30 if scl == portScl and sda == portSda:
31 self._i2c = _I2C(portId, mode=_I2C.MASTER, baudrate=frequency)
34 raise NotImplementedError(
35 "No Hardware I2C on (scl,sda)={}\nValid I2C ports: {}".format((scl, sda), i2cPorts)
41 except AttributeError:
47 def __exit__(self, exc_type, exc_value, traceback):
51 return self._i2c.scan()
53 def readfrom_into(self, address, buffer, *, start=0, end=None):
54 if start is not 0 or end is not None:
57 buffer = memoryview(buffer)[start:end]
58 stop = True # remove for efficiency later
59 return self._i2c.readfrom_into(address, buffer, stop=stop)
61 def writeto(self, address, buffer, *, start=0, end=None, stop=True):
62 if isinstance(buffer, str):
63 buffer = bytes([ord(x) for x in buffer])
64 if start is not 0 or end is not None:
66 return self._i2c.writeto(address, memoryview(buffer)[start:], stop=stop)
68 return self._i2c.writeto(address, memoryview(buffer)[start:end], stop=stop)
69 return self._i2c.writeto(address, buffer, stop=stop)
71 def writeto_then_readfrom(self, address, buffer_out, buffer_in, *, out_start=0, out_end=None, in_start=0, in_end=None, stop=False):
72 return self._i2c.writeto_then_readfrom(address, buffer_out, buffer_in,
73 out_start=out_start, out_end=out_end,
74 in_start=in_start, in_end=in_end, stop=stop)
77 def __init__(self, clock, MOSI=None, MISO=None):
79 if detector.board.ftdi_ft232h:
80 from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI
81 from adafruit_blinka.microcontroller.ft232h.pin import SCK, MOSI, MISO
83 self._pins = (SCK, MOSI, MISO)
85 elif detector.board.any_embedded_linux:
86 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
88 from machine import SPI as _SPI
89 from microcontroller.pin import spiPorts
90 for portId, portSck, portMosi, portMiso in spiPorts:
91 if ((clock == portSck) and # Clock is required!
92 (MOSI == portMosi or MOSI == None) and # But can do with just output
93 (MISO == portMiso or MISO == None)): # Or just input
94 self._spi = _SPI(portId)
95 self._pins = (portSck, portMosi, portMiso)
98 raise NotImplementedError(
99 "No Hardware SPI on (SCLK, MOSI, MISO)={}\nValid SPI ports:{}".
100 format((clock, MOSI, MISO), spiPorts))
102 def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
103 if detector.board.any_raspberry_pi or detector.board.any_raspberry_pi_40_pin:
104 from adafruit_blinka.microcontroller.bcm283x.pin import Pin
105 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
106 elif detector.board.any_beaglebone:
107 from adafruit_blinka.microcontroller.am335x.pin import Pin
108 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
109 elif board_id == ap_board.ORANGE_PI_PC or board_id == ap_board.ORANGE_PI_R1 or board_id == ap_board.ORANGE_PI_ZERO:
110 from adafruit_blinka.microcontroller.allwinner_h3.pin import Pin
111 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
112 elif board_id == ap_board.GIANT_BOARD:
113 from adafruit_blinka.microcontroller.sama5.pin import Pin
114 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
115 elif board_id == ap_board.CORAL_EDGE_TPU_DEV:
116 from adafruit_blinka.microcontroller.nxp_imx8m.pin import Pin
117 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
118 elif board_id == ap_board.ODROID_C2:
119 from adafruit_blinka.microcontroller.amlogic.s905.pin import Pin
120 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
121 elif board_id == ap_board.DRAGONBOARD_410C:
122 from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import Pin
123 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
124 elif board_id == ap_board.JETSON_NANO:
125 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
126 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
127 elif board_id == ap_board.JETSON_TX1:
128 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
129 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
130 elif board_id == ap_board.JETSON_TX2:
131 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
132 from adafruit_blinka.microcontroller.tegra.t186.pin import Pin
133 elif board_id == ap_board.JETSON_XAVIER:
134 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
135 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
136 elif detector.board.ftdi_ft232h:
137 from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI
138 from adafruit_blinka.microcontroller.ft232h.pin import Pin
140 from machine import SPI as _SPI
141 from machine import Pin
144 # TODO check if #init ignores MOSI=None rather than unsetting, to save _pinIds attribute
151 sck=Pin(self._pins[0].id),
152 mosi=Pin(self._pins[1].id),
153 miso=Pin(self._pins[2].id)
156 raise RuntimeError("First call try_lock()")
162 def write(self, buf, start=0, end=None):
163 return self._spi.write(buf, start, end)
165 def readinto(self, buf, start=0, end=None, write_value=0):
166 return self._spi.readinto(buf, start, end, write_value=write_value)
168 def write_readinto(self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None):
169 return self._spi.write_readinto(buffer_out, buffer_in, out_start, out_end, in_start, in_end)
172 class UART(Lockable):
176 Parity.ODD = Parity()
177 Parity.EVEN = Parity()
187 receiver_buffer_size=64,
189 if detector.board.any_embedded_linux:
190 raise RuntimeError('busio.UART not supported on this platform. Please use pyserial instead.')
192 from machine import UART as _UART
193 from microcontroller.pin import uartPorts
195 self.baudrate = baudrate
197 if flow is not None: # default 0
198 raise NotImplementedError(
199 "Parameter '{}' unsupported on {}".format(
200 "flow", agnostic.board_id))
202 # translate parity flag for Micropython
203 if parity is UART.Parity.ODD:
205 elif parity is UART.Parity.EVEN:
210 raise ValueError("Invalid parity")
212 # check tx and rx have hardware support
213 for portId, portTx, portRx in uartPorts: #
214 if portTx == tx and portRx == rx:
222 read_buf_len=receiver_buffer_size
226 raise NotImplementedError(
227 "No Hardware UART on (tx,rx)={}\nValid UART ports: {}".format((tx, rx), uartPorts)
233 def read(self, nbytes=None):
234 return self._uart.read(nbytes)
236 def readinto(self, buf, nbytes=None):
237 return self._uart.readinto(buf, nbytes)
240 return self._uart.readline()
242 def write(self, buf):
243 return self._uart.write(buf)