MikrofonSensor und TemperaturSenor die zwei Python programme funktionieren. mit den jeweiligen 2 json Datein. Beim TemperaturSensor wird im Terminal keine Wertre ausgegeben aber in der json Datei kann man die Temp und Hum sehen.

This commit is contained in:
Chiara 2025-05-28 14:53:44 +02:00
parent 4c654ec969
commit 1751076592
2614 changed files with 349009 additions and 0 deletions

View file

@ -0,0 +1,72 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
`analogio` - Analog input and output control
=================================================
See `CircuitPython:analogio` in CircuitPython for more details.
* Author(s): Carter Nelson
"""
from adafruit_blinka import ContextManaged
from .rp2040_u2if import rp2040_u2if
class AnalogIn(ContextManaged):
"""AnalogIn Base Class for RP2040 u2if"""
def __init__(self, pin):
self.pin_id = pin.id
rp2040_u2if.adc_init_pin(self.pin_id)
@property
def value(self):
"""Read the ADC and return the value"""
return rp2040_u2if.adc_get_value(self.pin_id) << 4
# pylint: disable=no-self-use
@value.setter
def value(self, value):
# emulate what CircuitPython does
raise AttributeError("'AnalogIn' object has no attribute 'value'")
# pylint: enable=no-self-use
def deinit(self):
pass
class AnalogIn_Pico(AnalogIn):
"""AnalogIn Base Class for Pico u2if"""
def __init__(self, pin):
# per their pinout, why only two?
if pin.id not in (26, 27):
raise ValueError("Pin does not support ADC.")
super().__init__(pin)
class AnalogIn_Feather(AnalogIn):
"""AnalogIn Base Class for Feather u2if"""
def __init__(self, pin):
if pin.id not in (26, 27, 28):
raise ValueError("Pin does not support ADC.")
super().__init__(pin)
class AnalogIn_QTPY(AnalogIn):
"""AnalogIn Base Class for QT Py 2040 u2if"""
def __init__(self, pin):
if pin.id not in (26, 27, 28):
raise ValueError("Pin does not support ADC.")
super().__init__(pin)
class AnalogIn_ItsyBitsy(AnalogIn):
"""AnalogIn Base Class for ItsyBitsy 2040 u2if"""
def __init__(self, pin):
if pin.id not in (26, 27, 28):
raise ValueError("Pin does not support ADC.")
super().__init__(pin)

View file

@ -0,0 +1,201 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""I2C Classes for RP2040s with u2if firmware"""
from .rp2040_u2if import rp2040_u2if
class I2C:
"""I2C Base Class for RP2040 u2if"""
def __init__(self, index, *, frequency=100000):
self._index = index
rp2040_u2if.i2c_set_port(self._index)
rp2040_u2if.i2c_configure(frequency)
def scan(self):
"""Perform an I2C Device Scan"""
rp2040_u2if.i2c_set_port(self._index)
return rp2040_u2if.i2c_scan()
# pylint: disable=unused-argument
def writeto(self, address, buffer, *, start=0, end=None, stop=True):
"""Write data from the buffer to an address"""
rp2040_u2if.i2c_set_port(self._index)
rp2040_u2if.i2c_writeto(address, buffer, start=start, end=end)
def readfrom_into(self, address, buffer, *, start=0, end=None, stop=True):
"""Read data from an address and into the buffer"""
rp2040_u2if.i2c_set_port(self._index)
rp2040_u2if.i2c_readfrom_into(address, buffer, start=start, end=end)
def writeto_then_readfrom(
self,
address,
buffer_out,
buffer_in,
*,
out_start=0,
out_end=None,
in_start=0,
in_end=None,
stop=False,
):
"""Write data from buffer_out to an address and then
read data from an address and into buffer_in
"""
rp2040_u2if.i2c_set_port(self._index)
rp2040_u2if.i2c_writeto_then_readfrom(
address,
buffer_out,
buffer_in,
out_start=out_start,
out_end=out_end,
in_start=in_start,
in_end=in_end,
)
# pylint: enable=unused-argument
class I2C_Pico(I2C):
"""I2C Class for Pico u2if"""
def __init__(self, scl, sda, *, frequency=100000):
index = None
if scl.id == 5 and sda.id == 4:
index = 0
if scl.id == 15 and sda.id == 14:
index = 1
if index is None:
raise ValueError("I2C not found on specified pins.")
self._index = index
super().__init__(index, frequency=frequency)
class I2C_Feather(I2C):
"""I2C Class for Feather u2if"""
def __init__(self, scl, sda, *, frequency=100000):
index = None
if scl.id == 3 and sda.id == 2:
index = 1
if index is None:
raise ValueError("I2C not found on specified pins.")
self._index = index
super().__init__(index, frequency=frequency)
class I2C_Feather_CAN(I2C):
"""I2C Class for Feather EPD u2if"""
def __init__(self, scl, sda, *, frequency=100000):
index = None
if scl.id == 3 and sda.id == 2:
index = 1
if index is None:
raise ValueError("I2C not found on specified pins.")
self._index = index
super().__init__(index, frequency=frequency)
class I2C_Feather_EPD(I2C):
"""I2C Class for Feather EPD u2if"""
def __init__(self, scl, sda, *, frequency=100000):
index = None
if scl.id == 3 and sda.id == 2:
index = 1
if index is None:
raise ValueError("I2C not found on specified pins.")
self._index = index
super().__init__(index, frequency=frequency)
class I2C_Feather_RFM(I2C):
"""I2C Class for Feather EPD u2if"""
def __init__(self, scl, sda, *, frequency=100000):
index = None
if scl.id == 3 and sda.id == 2:
index = 1
if index is None:
raise ValueError("I2C not found on specified pins.")
self._index = index
super().__init__(index, frequency=frequency)
class I2C_QTPY(I2C):
"""I2C Class for QT Py 2if"""
def __init__(self, scl, sda, *, frequency=100000):
index = None
if scl.id == 25 and sda.id == 24:
index = 0
if scl.id == 23 and sda.id == 22:
index = 1
if index is None:
raise ValueError("I2C not found on specified pins.")
self._index = index
super().__init__(index, frequency=frequency)
class I2C_ItsyBitsy(I2C):
"""I2C Class for ItsyBitsy u2if"""
def __init__(self, scl, sda, *, frequency=100000):
index = None
if scl.id == 3 and sda.id == 2:
index = 1
if index is None:
raise ValueError("I2C not found on specified pins.")
self._index = index
super().__init__(index, frequency=frequency)
class I2C_MacroPad(I2C):
"""I2C Class for MacroPad u2if"""
def __init__(self, scl, sda, *, frequency=100000):
index = None
if scl.id == 21 and sda.id == 20:
index = 0
if index is None:
raise ValueError("I2C not found on specified pins.")
self._index = index
super().__init__(index, frequency=frequency)
class I2C_QT2040_Trinkey(I2C):
"""I2C Class for QT2040 Trinkey u2if"""
def __init__(self, scl, sda, *, frequency=100000):
index = None
if scl.id == 17 and sda.id == 16:
index = 0
if index is None:
raise ValueError("I2C not found on specified pins.")
self._index = index
super().__init__(index, frequency=frequency)
class I2C_KB2040(I2C):
"""I2C Class for KB2040 u2if"""
def __init__(self, scl, sda, *, frequency=100000):
index = None
if scl.id == 13 and sda.id == 12:
index = 0
if index is None:
raise ValueError("I2C not found on specified pins.")
self._index = index
super().__init__(index, frequency=frequency)

View file

@ -0,0 +1,20 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""NeoPixel write for Pico u2if."""
from .rp2040_u2if import rp2040_u2if
def neopixel_write(gpio, buf):
"""NeoPixel Writing Function"""
# pad output buffer from 3 bpp to 4 bpp
buffer = []
for i in range(0, len(buf), 3):
buffer.append(0)
buffer.append(buf[i + 2])
buffer.append(buf[i + 1])
buffer.append(buf[i])
rp2040_u2if.neopixel_write(gpio, buffer)

View file

@ -0,0 +1,95 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""Generic RP2040 pin names"""
from .rp2040_u2if import rp2040_u2if
class Pin:
"""A basic Pin class for use with RP2040 with u2if firmware."""
# pin modes
IN = 0
OUT = 1
# pin values
LOW = 0
HIGH = 1
# pin pulls
PULL_NONE = 0
PULL_UP = 1
PULL_DOWN = 2
def __init__(self, pin_id=None):
self.id = pin_id
self._mode = None
self._pull = None
# pylint:disable = no-self-use
def _u2if_open_hid(self, vid, pid):
rp2040_u2if.open(vid, pid)
def init(self, mode=IN, pull=PULL_NONE):
"""Initialize the Pin"""
pull = Pin.PULL_NONE if pull is None else pull
if self.id is None:
raise RuntimeError("Can not init a None type pin.")
if mode not in (Pin.IN, Pin.OUT):
raise ValueError("Incorrect mode value.")
if pull not in (Pin.PULL_NONE, Pin.PULL_UP, Pin.PULL_DOWN):
raise ValueError("Incorrect pull value.")
rp2040_u2if.gpio_init_pin(self.id, mode, pull)
self._mode = mode
self._pull = pull
def value(self, val=None):
"""Set or return the Pin Value"""
# Digital In / Out
if self._mode in (Pin.IN, Pin.OUT):
# digital read
if val is None:
return rp2040_u2if.gpio_get_pin(self.id)
# digital write
if val in (Pin.LOW, Pin.HIGH):
rp2040_u2if.gpio_set_pin(self.id, val)
return None
# nope
raise ValueError("Invalid value for pin.")
raise RuntimeError(
"No action for mode {} with value {}".format(self._mode, val)
)
# create pin instances for each pin
GP0 = Pin(0)
GP1 = Pin(1)
GP2 = Pin(2)
GP3 = Pin(3)
GP4 = Pin(4)
GP5 = Pin(5)
GP6 = Pin(6)
GP7 = Pin(7)
GP8 = Pin(8)
GP9 = Pin(9)
GP10 = Pin(10)
GP11 = Pin(11)
GP12 = Pin(12)
GP13 = Pin(13)
GP14 = Pin(14)
GP15 = Pin(15)
GP16 = Pin(16)
GP17 = Pin(17)
GP18 = Pin(18)
GP19 = Pin(19)
GP20 = Pin(20)
GP21 = Pin(21)
GP22 = Pin(22)
GP23 = Pin(23)
GP24 = Pin(24)
GP25 = Pin(25)
GP26 = Pin(26)
GP27 = Pin(27)
GP28 = Pin(28)
GP29 = Pin(29)

View file

@ -0,0 +1,50 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""PWMOut Class for RP2040s with u2if"""
from .rp2040_u2if import rp2040_u2if
class PWMOut:
"""Base Pulse Width Modulation Output Class"""
def __init__(self, pin, *, frequency=500, duty_cycle=0, variable_frequency=False):
rp2040_u2if.pwm_configure(
pin,
frequency=frequency,
duty_cycle=duty_cycle,
variable_frequency=variable_frequency,
)
self._pin = pin
def __del__(self):
self.deinit()
def __enter__(self):
return self
def __exit__(self, t, value, traceback):
self.deinit()
def deinit(self):
"""Deinit PWM."""
rp2040_u2if.pwm_deinit(self._pin)
@property
def duty_cycle(self):
"""The PWM's output duty cycle, 16-bit."""
return rp2040_u2if.pwm_get_duty_cycle(self._pin)
@duty_cycle.setter
def duty_cycle(self, duty_cycle):
rp2040_u2if.pwm_set_duty_cycle(self._pin, duty_cycle)
@property
def frequency(self):
"""The PWM's output frequency in Hertz."""
return rp2040_u2if.pwm_get_frequency(self._pin)
@frequency.setter
def frequency(self, frequency):
rp2040_u2if.pwm_set_frequency(self._pin, frequency)

View file

@ -0,0 +1,509 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""Helper class for use with RP2040 running u2if firmware"""
# https://github.com/execuc/u2if
import os
import time
import hid
# Use to set delay between reset and device reopen. if negative, don't reset at all
RP2040_U2IF_RESET_DELAY = float(os.environ.get("RP2040_U2IF_RESET_DELAY", 1))
# pylint: disable=import-outside-toplevel,too-many-branches,too-many-statements
# pylint: disable=too-many-arguments,too-many-function-args, too-many-public-methods
class RP2040_u2if:
"""Helper class for use with RP2040 running u2if firmware"""
# MISC
RESP_OK = 0x01
SYS_RESET = 0x10
# GPIO
GPIO_INIT_PIN = 0x20
GPIO_SET_VALUE = 0x21
GPIO_GET_VALUE = 0x22
# ADC
ADC_INIT_PIN = 0x40
ADC_GET_VALUE = 0x41
# I2C
I2C0_INIT = 0x80
I2C0_DEINIT = 0x81
I2C0_WRITE = 0x82
I2C0_READ = 0x83
I2C0_WRITE_FROM_UART = 0x84
I2C1_INIT = I2C0_INIT + 0x10
I2C1_DEINIT = I2C0_DEINIT + 0x10
I2C1_WRITE = I2C0_WRITE + 0x10
I2C1_READ = I2C0_READ + 0x10
I2C1_WRITE_FROM_UART = I2C0_WRITE_FROM_UART + 0x10
# SPI
SPI0_INIT = 0x60
SPI0_DEINIT = 0x61
SPI0_WRITE = 0x62
SPI0_READ = 0x63
SPI0_WRITE_FROM_UART = 0x64
SPI1_INIT = SPI0_INIT + 0x10
SPI1_DEINIT = SPI0_DEINIT + 0x10
SPI1_WRITE = SPI0_WRITE + 0x10
SPI1_READ = SPI0_READ + 0x10
SPI1_WRITE_FROM_UART = SPI0_WRITE_FROM_UART + 0x10
# WS2812B (LED)
WS2812B_INIT = 0xA0
WS2812B_DEINIT = 0xA1
WS2812B_WRITE = 0xA2
# PWM
PWM_INIT_PIN = 0x30
PWM_DEINIT_PIN = 0x31
PWM_SET_FREQ = 0x32
PWM_GET_FREQ = 0x33
PWM_SET_DUTY_U16 = 0x34
PWM_GET_DUTY_U16 = 0x35
PWM_SET_DUTY_NS = 0x36
PWM_GET_DUTY_NS = 0x37
def __init__(self):
self._vid = None
self._pid = None
self._hid = None
self._opened = False
self._i2c_index = None
self._spi_index = None
self._serial = None
self._neopixel_initialized = False
self._uart_rx_buffer = None
def _hid_xfer(self, report, response=True):
"""Perform HID Transfer"""
# first byte is report ID, which =0
# remaing bytes = 64 byte report data
# https://github.com/libusb/hidapi/blob/083223e77952e1ef57e6b77796536a3359c1b2a3/hidapi/hidapi.h#L185
self._hid.write(b"\0" + report + b"\0" * (64 - len(report)))
if response:
# return is 64 byte response report
return self._hid.read(64)
return None
def _reset(self):
self._hid_xfer(bytes([self.SYS_RESET]), False)
self._hid.close()
time.sleep(RP2040_U2IF_RESET_DELAY)
start = time.monotonic()
while time.monotonic() - start < 5:
try:
self._hid.open(self._vid, self._pid)
except OSError:
time.sleep(0.1)
continue
return
raise OSError("RP2040 u2if open error.")
# ----------------------------------------------------------------
# MISC
# ----------------------------------------------------------------
def open(self, vid, pid):
"""Open HID interface for given USB VID and PID."""
if self._opened:
return
self._vid = vid
self._pid = pid
self._hid = hid.device()
self._hid.open(self._vid, self._pid)
if RP2040_U2IF_RESET_DELAY >= 0:
self._reset()
self._opened = True
# ----------------------------------------------------------------
# GPIO
# ----------------------------------------------------------------
def gpio_init_pin(self, pin_id, direction, pull):
"""Configure GPIO Pin."""
self._hid_xfer(
bytes(
[
self.GPIO_INIT_PIN,
pin_id,
direction,
pull,
]
)
)
def gpio_set_pin(self, pin_id, value):
"""Set Current GPIO Pin Value"""
self._hid_xfer(
bytes(
[
self.GPIO_SET_VALUE,
pin_id,
int(value),
]
)
)
def gpio_get_pin(self, pin_id):
"""Get Current GPIO Pin Value"""
resp = self._hid_xfer(
bytes(
[
self.GPIO_GET_VALUE,
pin_id,
]
),
True,
)
return resp[3] != 0x00
# ----------------------------------------------------------------
# ADC
# ----------------------------------------------------------------
def adc_init_pin(self, pin_id):
"""Configure ADC Pin."""
self._hid_xfer(
bytes(
[
self.ADC_INIT_PIN,
pin_id,
]
)
)
def adc_get_value(self, pin_id):
"""Get ADC value for pin."""
resp = self._hid_xfer(
bytes(
[
self.ADC_GET_VALUE,
pin_id,
]
),
True,
)
return int.from_bytes(resp[3 : 3 + 2], byteorder="little")
# ----------------------------------------------------------------
# I2C
# ----------------------------------------------------------------
def i2c_configure(self, baudrate, pullup=False):
"""Configure I2C."""
if self._i2c_index is None:
raise RuntimeError("I2C bus not initialized.")
resp = self._hid_xfer(
bytes(
[
self.I2C0_INIT if self._i2c_index == 0 else self.I2C1_INIT,
0x00 if not pullup else 0x01,
]
)
+ baudrate.to_bytes(4, byteorder="little"),
True,
)
if resp[1] != self.RESP_OK:
raise RuntimeError("I2C init error.")
def i2c_set_port(self, index):
"""Set I2C port."""
if index not in (0, 1):
raise ValueError("I2C index must be 0 or 1.")
self._i2c_index = index
def _i2c_write(self, address, buffer, start=0, end=None, stop=True):
"""Write data from the buffer to an address"""
if self._i2c_index is None:
raise RuntimeError("I2C bus not initialized.")
end = end if end else len(buffer)
write_cmd = self.I2C0_WRITE if self._i2c_index == 0 else self.I2C1_WRITE
stop_flag = 0x01 if stop else 0x00
while (end - start) > 0:
remain_bytes = end - start
chunk = min(remain_bytes, 64 - 7)
resp = self._hid_xfer(
bytes([write_cmd, address, stop_flag])
+ remain_bytes.to_bytes(4, byteorder="little")
+ buffer[start : (start + chunk)],
True,
)
if resp[1] != self.RESP_OK:
raise RuntimeError("I2C write error")
start += chunk
def _i2c_read(self, address, buffer, start=0, end=None):
"""Read data from an address and into the buffer"""
# TODO: support chunkified reads
if self._i2c_index is None:
raise RuntimeError("I2C bus not initialized.")
end = end if end else len(buffer)
read_cmd = self.I2C0_READ if self._i2c_index == 0 else self.I2C1_READ
stop_flag = 0x01 # always stop
read_size = end - start
resp = self._hid_xfer(bytes([read_cmd, address, stop_flag, read_size]), True)
if resp[1] != self.RESP_OK:
raise RuntimeError("I2C write error")
# move into buffer
for i in range(read_size):
buffer[start + i] = resp[i + 2]
def i2c_writeto(self, address, buffer, *, start=0, end=None):
"""Write data from the buffer to an address"""
self._i2c_write(address, buffer, start, end)
def i2c_readfrom_into(self, address, buffer, *, start=0, end=None):
"""Read data from an address and into the buffer"""
self._i2c_read(address, buffer, start, end)
def i2c_writeto_then_readfrom(
self,
address,
out_buffer,
in_buffer,
*,
out_start=0,
out_end=None,
in_start=0,
in_end=None,
):
"""Write data from buffer_out to an address and then
read data from an address and into buffer_in
"""
self._i2c_write(address, out_buffer, out_start, out_end, False)
self._i2c_read(address, in_buffer, in_start, in_end)
def i2c_scan(self, *, start=0, end=0x79):
"""Perform an I2C Device Scan"""
if self._i2c_index is None:
raise RuntimeError("I2C bus not initialized.")
found = []
for addr in range(start, end + 1):
# try a write
try:
self.i2c_writeto(addr, b"\x00\x00\x00")
except RuntimeError: # no reply!
continue
# store if success
found.append(addr)
return found
# ----------------------------------------------------------------
# SPI
# ----------------------------------------------------------------
def spi_configure(self, baudrate):
"""Configure SPI."""
if self._spi_index is None:
raise RuntimeError("SPI bus not initialized.")
resp = self._hid_xfer(
bytes(
[
self.SPI0_INIT if self._spi_index == 0 else self.SPI1_INIT,
0x00, # mode, not yet implemented
]
)
+ baudrate.to_bytes(4, byteorder="little"),
True,
)
if resp[1] != self.RESP_OK:
raise RuntimeError("SPI init error.")
def spi_set_port(self, index):
"""Set SPI port."""
if index not in (0, 1):
raise ValueError("SPI index must be 0 or 1.")
self._spi_index = index
def spi_write(self, buffer, *, start=0, end=None):
"""SPI write."""
if self._spi_index is None:
raise RuntimeError("SPI bus not initialized.")
end = end if end else len(buffer)
write_cmd = self.SPI0_WRITE if self._spi_index == 0 else self.SPI1_WRITE
while (end - start) > 0:
remain_bytes = end - start
chunk = min(remain_bytes, 64 - 3)
resp = self._hid_xfer(
bytes([write_cmd, chunk]) + buffer[start : (start + chunk)], True
)
if resp[1] != self.RESP_OK:
raise RuntimeError("SPI write error")
start += chunk
def spi_readinto(self, buffer, *, start=0, end=None, write_value=0):
"""SPI readinto."""
if self._spi_index is None:
raise RuntimeError("SPI bus not initialized.")
end = end if end else len(buffer)
read_cmd = self.SPI0_READ if self._spi_index == 0 else self.SPI1_READ
read_size = end - start
resp = self._hid_xfer(bytes([read_cmd, write_value, read_size]), True)
if resp[1] != self.RESP_OK:
raise RuntimeError("SPI write error")
# move into buffer
for i in range(read_size):
buffer[start + i] = resp[i + 2]
def spi_write_readinto(
self,
buffer_out,
buffer_in,
*,
out_start=0,
out_end=None,
in_start=0,
in_end=None,
):
"""SPI write and readinto."""
raise NotImplementedError("SPI write_readinto Not implemented")
# ----------------------------------------------------------------
# NEOPIXEL
# ----------------------------------------------------------------
def neopixel_write(self, gpio, buf):
"""NeoPixel write."""
# open serial (data is sent over this)
if self._serial is None:
import serial
import serial.tools.list_ports
ports = serial.tools.list_ports.comports()
for port in ports:
if port.vid == self._vid and port.pid == self._pid:
self._serial = serial.Serial(port.device)
break
if self._serial is None:
raise RuntimeError("Could not find Pico com port.")
# init
if not self._neopixel_initialized:
# deinit any current setup
# pylint: disable=protected-access
self._hid_xfer(bytes([self.WS2812B_DEINIT]))
resp = self._hid_xfer(
bytes(
[
self.WS2812B_INIT,
gpio._pin.id,
]
),
True,
)
if resp[1] != self.RESP_OK:
raise RuntimeError("Neopixel init error")
self._neopixel_initialized = True
self._serial.reset_output_buffer()
# write
# command is done over HID
remain_bytes = len(buf)
resp = self._hid_xfer(
bytes([self.WS2812B_WRITE]) + remain_bytes.to_bytes(4, byteorder="little"),
True,
)
if resp[1] != self.RESP_OK:
# pylint: disable=no-else-raise
if resp[2] == 0x01:
raise RuntimeError(
"Neopixel write error : too many pixel for the firmware."
)
elif resp[2] == 0x02:
raise RuntimeError(
"Neopixel write error : transfer already in progress."
)
else:
raise RuntimeError("Neopixel write error.")
# buffer is sent over serial
self._serial.write(buf)
# hack (see u2if)
if len(buf) % 64 == 0:
self._serial.write([0])
self._serial.flush()
# polling loop to wait for write complete?
time.sleep(0.1)
resp = self._hid.read(64)
while resp[0] != self.WS2812B_WRITE:
resp = self._hid.read(64)
if resp[1] != self.RESP_OK:
raise RuntimeError("Neopixel write (flush) error.")
# ----------------------------------------------------------------
# PWM
# ----------------------------------------------------------------
# pylint: disable=unused-argument
def pwm_configure(self, pin, frequency=500, duty_cycle=0, variable_frequency=False):
"""Configure PWM."""
self.pwm_deinit(pin)
resp = self._hid_xfer(bytes([self.PWM_INIT_PIN, pin.id]), True)
if resp[1] != self.RESP_OK:
raise RuntimeError("PWM init error.")
self.pwm_set_frequency(pin, frequency)
self.pwm_set_duty_cycle(pin, duty_cycle)
def pwm_deinit(self, pin):
"""Deinit PWM."""
self._hid_xfer(bytes([self.PWM_DEINIT_PIN, pin.id]))
def pwm_get_frequency(self, pin):
"""PWM get freq."""
resp = self._hid_xfer(bytes([self.PWM_GET_FREQ, pin.id]), True)
if resp[1] != self.RESP_OK:
raise RuntimeError("PWM get frequency error.")
return int.from_bytes(resp[3 : 3 + 4], byteorder="little")
def pwm_set_frequency(self, pin, frequency):
"""PWM set freq."""
resp = self._hid_xfer(
bytes([self.PWM_SET_FREQ, pin.id])
+ frequency.to_bytes(4, byteorder="little"),
True,
)
if resp[1] != self.RESP_OK:
# pylint: disable=no-else-raise
if resp[3] == 0x01:
raise RuntimeError("PWM different frequency on same slice.")
elif resp[3] == 0x02:
raise RuntimeError("PWM frequency too low.")
elif resp[3] == 0x03:
raise RuntimeError("PWM frequency too high.")
else:
raise RuntimeError("PWM frequency error.")
def pwm_get_duty_cycle(self, pin):
"""PWM get duty cycle."""
resp = self._hid_xfer(bytes([self.PWM_GET_DUTY_U16, pin.id]), True)
if resp[1] != self.RESP_OK:
raise RuntimeError("PWM get duty cycle error.")
return int.from_bytes(resp[3 : 3 + 4], byteorder="little")
def pwm_set_duty_cycle(self, pin, duty_cycle):
"""PWM set duty cycle."""
resp = self._hid_xfer(
bytes([self.PWM_SET_DUTY_U16, pin.id])
+ duty_cycle.to_bytes(2, byteorder="little"),
True,
)
if resp[1] != self.RESP_OK:
raise RuntimeError("PWM set duty cycle error.")
rp2040_u2if = RP2040_u2if()

View file

@ -0,0 +1,180 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""SPI Classes for RP2040s with u2if firmware"""
from .rp2040_u2if import rp2040_u2if
# pylint: disable=protected-access, no-self-use
class SPI:
"""SPI Base Class for RP2040 u2if"""
MSB = 0
def __init__(self, index, *, baudrate=100000):
self._index = index
self._frequency = baudrate
rp2040_u2if.spi_set_port(self._index)
rp2040_u2if.spi_configure(self._frequency)
# pylint: disable=too-many-arguments,unused-argument
def init(
self,
baudrate=1000000,
polarity=0,
phase=0,
bits=8,
firstbit=MSB,
sck=None,
mosi=None,
miso=None,
):
"""Initialize the Port"""
self._frequency = baudrate
rp2040_u2if.spi_set_port(self._index)
rp2040_u2if.spi_configure(self._frequency)
# pylint: enable=too-many-arguments
@property
def frequency(self):
"""Return the current frequency"""
return self._frequency
def write(self, buf, start=0, end=None):
"""Write data from the buffer to SPI"""
rp2040_u2if.spi_write(buf, start=start, end=end)
def readinto(self, buf, start=0, end=None, write_value=0):
"""Read data from SPI and into the buffer"""
rp2040_u2if.spi_readinto(buf, start=start, end=end, write_value=write_value)
# pylint: disable=too-many-arguments
def write_readinto(
self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
):
"""Perform a half-duplex write from buffer_out and then
read data into buffer_in
"""
rp2040_u2if.spi_write_readinto(
buffer_out,
buffer_in,
out_start=out_start,
out_end=out_end,
in_start=in_start,
in_end=in_end,
)
# pylint: enable=too-many-arguments
class SPI_Pico(SPI):
"""SPI Class for Pico u2if"""
def __init__(self, clock, *, baudrate=100000):
index = None
if clock.id == 18:
index = 0
if clock.id == 10:
index = 1
if index is None:
raise ValueError("No SPI port on specified pin.")
super().__init__(index, baudrate=baudrate)
class SPI_Feather(SPI):
"""SPI Class for Feather u2if"""
def __init__(self, clock, *, baudrate=100000):
index = None
if clock.id == 18:
index = 0
if index is None:
raise ValueError("No SPI port on specified pin.")
super().__init__(index, baudrate=baudrate)
class SPI_Feather_CAN(SPI):
"""SPI Class for Feather EPD u2if"""
def __init__(self, clock, *, baudrate=100000):
index = None
if clock.id == 14:
index = 1
if index is None:
raise ValueError("No SPI port on specified pin.")
super().__init__(index, baudrate=baudrate)
class SPI_Feather_EPD(SPI):
"""SPI Class for Feather EPD u2if"""
def __init__(self, clock, *, baudrate=100000):
index = None
if clock.id == 22:
index = 0
if clock.id == 14:
index = 1
if index is None:
raise ValueError("No SPI port on specified pin.")
super().__init__(index, baudrate=baudrate)
class SPI_Feather_RFM(SPI):
"""SPI Class for Feather EPD u2if"""
def __init__(self, clock, *, baudrate=100000):
index = None
if clock.id == 14:
index = 1
if index is None:
raise ValueError("No SPI port on specified pin.")
super().__init__(index, baudrate=baudrate)
class SPI_QTPY(SPI):
"""SPI Class for QT Py u2if"""
def __init__(self, clock, *, baudrate=100000):
index = None
if clock.id == 6:
index = 0
if index is None:
raise ValueError("No SPI port on specified pin.")
super().__init__(index, baudrate=baudrate)
class SPI_ItsyBitsy(SPI):
"""SPI Class for ItsyBitsy u2if"""
def __init__(self, clock, *, baudrate=100000):
index = None
if clock.id == 18:
index = 0
if index is None:
raise ValueError("No SPI port on specified pin.")
super().__init__(index, baudrate=baudrate)
class SPI_MacroPad(SPI):
"""SPI Class for MacroPad u2if"""
def __init__(self, clock, *, baudrate=100000):
index = None
if clock.id == 26:
index = 1
if index is None:
raise ValueError("No SPI port on specified pin.")
super().__init__(index, baudrate=baudrate)
class SPI_KB2040(SPI):
"""SPI Class for KB2040 u2if"""
def __init__(self, clock, *, baudrate=100000):
index = None
if clock.id == 18:
index = 0
if index is None:
raise ValueError("No SPI port on specified pin.")
super().__init__(index, baudrate=baudrate)