2 `busio` - Bus protocol support like I2C and SPI
3 =================================================
5 See `CircuitPython:busio` in CircuitPython for more details.
15 import adafruit_platformdetect.constants.boards as ap_board
16 import adafruit_platformdetect.constants.chips as ap_chip
17 from adafruit_blinka import Enum, Lockable, agnostic
18 from adafruit_blinka.agnostic import board_id, detector
20 # pylint: disable=import-outside-toplevel,too-many-branches,too-many-statements
21 # pylint: disable=too-many-arguments,too-many-function-args
26 Busio I2C Class for CircuitPython Compatibility. Used
27 for both MicroPython and Linux.
30 def __init__(self, scl, sda, frequency=100000):
31 self.init(scl, sda, frequency)
33 def init(self, scl, sda, frequency):
36 if detector.board.ftdi_ft232h:
37 from adafruit_blinka.microcontroller.ft232h.i2c import I2C as _I2C
39 self._i2c = _I2C(frequency=frequency)
41 if detector.board.binho_nova:
42 from adafruit_blinka.microcontroller.nova.i2c import I2C as _I2C
44 self._i2c = _I2C(frequency=frequency)
46 if detector.board.microchip_mcp2221:
47 from adafruit_blinka.microcontroller.mcp2221.i2c import I2C as _I2C
49 self._i2c = _I2C(frequency=frequency)
51 if detector.board.greatfet_one:
52 from adafruit_blinka.microcontroller.nxp_lpc4330.i2c import I2C as _I2C
54 self._i2c = _I2C(frequency=frequency)
56 if detector.board.any_embedded_linux:
57 from adafruit_blinka.microcontroller.generic_linux.i2c import I2C as _I2C
59 from machine import I2C as _I2C
60 from microcontroller.pin import i2cPorts
62 for portId, portScl, portSda in i2cPorts:
64 if scl == portScl and sda == portSda:
65 self._i2c = _I2C(portId, mode=_I2C.MASTER, baudrate=frequency)
71 "No Hardware I2C on (scl,sda)={}\nValid I2C ports: {}".format(
75 if threading is not None:
76 self._lock = threading.RLock()
79 """Deinitialization"""
82 except AttributeError:
86 if threading is not None:
90 def __exit__(self, exc_type, exc_value, traceback):
91 if threading is not None:
96 """Scan for attached devices"""
97 return self._i2c.scan()
99 def readfrom_into(self, address, buffer, *, start=0, end=None):
100 """Read from a device at specified address into a buffer"""
101 if start != 0 or end is not None:
104 buffer = memoryview(buffer)[start:end]
105 stop = True # remove for efficiency later
106 return self._i2c.readfrom_into(address, buffer, stop=stop)
108 def writeto(self, address, buffer, *, start=0, end=None, stop=True):
109 """Write to a device at specified address from a buffer"""
110 if isinstance(buffer, str):
111 buffer = bytes([ord(x) for x in buffer])
112 if start != 0 or end is not None:
114 return self._i2c.writeto(address, memoryview(buffer)[start:], stop=stop)
115 return self._i2c.writeto(address, memoryview(buffer)[start:end], stop=stop)
116 return self._i2c.writeto(address, buffer, stop=stop)
118 def writeto_then_readfrom(
130 """ "Write to a device at specified address from a buffer then read
131 from a device at specified address into a buffer
133 return self._i2c.writeto_then_readfrom(
147 Busio SPI Class for CircuitPython Compatibility. Used
148 for both MicroPython and Linux.
151 def __init__(self, clock, MOSI=None, MISO=None):
153 if detector.board.ftdi_ft232h:
154 from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI
155 from adafruit_blinka.microcontroller.ft232h.pin import SCK, MOSI, MISO
158 self._pins = (SCK, MOSI, MISO)
160 if detector.board.binho_nova:
161 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
162 from adafruit_blinka.microcontroller.nova.pin import SCK, MOSI, MISO
164 self._spi = _SPI(clock)
165 self._pins = (SCK, MOSI, MISO)
167 if detector.board.greatfet_one:
168 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
169 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import SCK, MOSI, MISO
172 self._pins = (SCK, MOSI, MISO)
174 if detector.board.any_embedded_linux:
175 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
177 from machine import SPI as _SPI
178 from microcontroller.pin import spiPorts
180 for portId, portSck, portMosi, portMiso in spiPorts:
183 and MOSI in (portMosi, None) # Clock is required!
184 and MISO in (portMiso, None) # But can do with just output
186 self._spi = _SPI(portId)
187 self._pins = (portSck, portMosi, portMiso)
191 "No Hardware SPI on (SCLK, MOSI, MISO)={}\nValid SPI ports:{}".format(
192 (clock, MOSI, MISO), spiPorts
196 def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
197 """Update the configuration"""
198 if detector.board.any_raspberry_pi or detector.board.any_raspberry_pi_40_pin:
199 from adafruit_blinka.microcontroller.bcm283x.pin import Pin
200 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
201 elif detector.board.BEAGLEBONE_AI:
202 from adafruit_blinka.microcontroller.dra74x.pin import Pin
203 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
204 elif detector.board.any_beaglebone:
205 from adafruit_blinka.microcontroller.am335x.pin import Pin
206 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
207 elif detector.board.any_orange_pi and detector.chip.id == ap_chip.SUN8I:
208 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
209 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
210 elif detector.board.any_nanopi and detector.chip.id == ap_chip.SUN8I:
211 from adafruit_blinka.microcontroller.allwinner.h3.pin import Pin
212 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
213 elif board_id == ap_board.GIANT_BOARD:
214 from adafruit_blinka.microcontroller.sama5.pin import Pin
215 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
216 elif board_id == ap_board.CORAL_EDGE_TPU_DEV:
217 from adafruit_blinka.microcontroller.nxp_imx8m.pin import Pin
218 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
219 elif board_id == ap_board.CORAL_EDGE_TPU_DEV_MINI:
220 from adafruit_blinka.microcontroller.mt8167.pin import Pin
221 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
222 elif board_id == ap_board.ODROID_C2:
223 from adafruit_blinka.microcontroller.amlogic.s905.pin import Pin
224 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
225 elif board_id == ap_board.ODROID_C4:
226 from adafruit_blinka.microcontroller.amlogic.s905x3.pin import Pin
227 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
228 elif board_id == ap_board.ODROID_XU4:
229 from adafruit_blinka.microcontroller.samsung.exynos5422.pin import Pin
230 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
231 elif board_id == ap_board.DRAGONBOARD_410C:
232 from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import Pin
233 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
234 elif board_id == ap_board.JETSON_NANO:
235 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
236 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
237 elif board_id == ap_board.JETSON_TX1:
238 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
239 from adafruit_blinka.microcontroller.tegra.t210.pin import Pin
240 elif board_id == ap_board.JETSON_TX2:
241 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
242 from adafruit_blinka.microcontroller.tegra.t186.pin import Pin
243 elif board_id == ap_board.JETSON_XAVIER:
244 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
245 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
246 elif board_id == ap_board.JETSON_NX:
247 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
248 from adafruit_blinka.microcontroller.tegra.t194.pin import Pin
249 elif detector.board.ROCK_PI_S:
250 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
251 from adafruit_blinka.microcontroller.rockchip.rk3308.pin import Pin
252 elif detector.board.ROCK_PI_4:
253 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
254 from adafruit_blinka.microcontroller.rockchip.rk3399.pin import Pin
255 elif detector.board.SIFIVE_UNLEASHED:
256 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
257 from adafruit_blinka.microcontroller.hfu540.pin import Pin
258 elif detector.board.ftdi_ft232h:
259 from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI
260 from adafruit_blinka.microcontroller.ft232h.pin import Pin
261 elif detector.board.binho_nova:
262 from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
263 from adafruit_blinka.microcontroller.nova.pin import Pin
264 elif detector.board.greatfet_one:
265 from adafruit_blinka.microcontroller.nxp_lpc4330.spi import SPI as _SPI
266 from adafruit_blinka.microcontroller.nxp_lpc4330.pin import Pin
273 from adafruit_blinka.microcontroller.allwinner.a64.pin import Pin
274 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
275 elif board_id == ap_board.CLOCKWORK_CPI3:
276 from adafruit_blinka.microcontroller.allwinner.a33.pin import Pin
277 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
278 elif board_id == ap_board.ONION_OMEGA2:
279 from adafruit_blinka.microcontroller.mips24kec.pin import Pin
280 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
281 elif detector.board.any_lubancat and detector.chip.id == ap_chip.IMX6ULL:
282 from adafruit_blinka.microcontroller.nxp_imx6ull.pin import Pin
283 from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
285 from machine import SPI as _SPI
286 from machine import Pin
289 # TODO check if #init ignores MOSI=None rather than unsetting, to save _pinIds attribute
296 sck=Pin(self._pins[0].id),
297 mosi=Pin(self._pins[1].id),
298 miso=Pin(self._pins[2].id),
301 raise RuntimeError("First call try_lock()")
304 """Deinitialization"""
310 """Return the baud rate if implemented"""
312 return self._spi.frequency
313 except AttributeError:
314 raise NotImplementedError(
315 "Frequency attribute not implemented for this platform"
316 ) from AttributeError
318 def write(self, buf, start=0, end=None):
319 """Write to the SPI device"""
320 return self._spi.write(buf, start, end)
322 def readinto(self, buf, start=0, end=None, write_value=0):
323 """Read from the SPI device into a buffer"""
324 return self._spi.readinto(buf, start, end, write_value=write_value)
327 self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
329 """Write to the SPI device and read from the SPI device into a buffer"""
330 return self._spi.write_readinto(
331 buffer_out, buffer_in, out_start, out_end, in_start, in_end
335 class UART(Lockable):
337 Busio UART Class for CircuitPython Compatibility. Used
338 for MicroPython and a few other non-Linux boards.
342 """Parity Enumeration"""
344 pass # pylint: disable=unnecessary-pass
346 Parity.ODD = Parity()
347 Parity.EVEN = Parity()
358 receiver_buffer_size=64,
361 if detector.board.any_embedded_linux:
363 "busio.UART not supported on this platform. Please use pyserial instead."
365 if detector.board.binho_nova:
366 from adafruit_blinka.microcontroller.nova.uart import UART as _UART
367 elif detector.board.greatfet_one:
368 from adafruit_blinka.microcontroller.nxp_lpc4330.uart import UART as _UART
370 from machine import UART as _UART
372 if detector.board.binho_nova:
373 from adafruit_blinka.microcontroller.nova.pin import uartPorts
375 from microcontroller.pin import uartPorts
377 self.baudrate = baudrate
379 if flow is not None: # default 0
380 raise NotImplementedError(
381 "Parameter '{}' unsupported on {}".format("flow", agnostic.board_id)
384 # translate parity flag for Micropython
385 if parity is UART.Parity.ODD:
387 elif parity is UART.Parity.EVEN:
392 raise ValueError("Invalid parity")
394 # check tx and rx have hardware support
395 for portId, portTx, portRx in uartPorts: #
396 if portTx == tx and portRx == rx:
404 read_buf_len=receiver_buffer_size,
409 "No Hardware UART on (tx,rx)={}\nValid UART ports: {}".format(
415 """Deinitialization"""
416 if detector.board.binho_nova:
420 def read(self, nbytes=None):
421 """Read from the UART"""
422 return self._uart.read(nbytes)
424 def readinto(self, buf, nbytes=None):
425 """Read from the UART into a buffer"""
426 return self._uart.readinto(buf, nbytes)
429 """Read a line of characters up to a newline charater from the UART"""
430 return self._uart.readline()
432 def write(self, buf):
433 """Write to the UART from a buffer"""
434 return self._uart.write(buf)
439 Stub class for OneWire, which is currently not implemented
442 def __init__(self, pin):
443 raise NotImplementedError("OneWire has not been implemented")
447 Deinitialize the OneWire bus and release any hardware resources for reuse.
449 raise NotImplementedError("OneWire has not been implemented")
453 Reset the OneWire bus and read presence
455 raise NotImplementedError("OneWire has not been implemented")
461 raise NotImplementedError("OneWire has not been implemented")
463 def write_bit(self, value):
465 Write out a bit based on value.
467 raise NotImplementedError("OneWire has not been implemented")