Merge pull request #2 from adafruit/initial_lib
Some checks failed
Build CI / test (push) Has been cancelled
Some checks failed
Build CI / test (push) Has been cancelled
library, examples and docs
This commit is contained in:
commit
2f3491ce61
8 changed files with 2197 additions and 36 deletions
38
README.rst
38
README.rst
|
|
@ -30,7 +30,6 @@ This driver depends on:
|
||||||
|
|
||||||
* `Adafruit CircuitPython <https://github.com/adafruit/circuitpython>`_
|
* `Adafruit CircuitPython <https://github.com/adafruit/circuitpython>`_
|
||||||
* `Bus Device <https://github.com/adafruit/Adafruit_CircuitPython_BusDevice>`_
|
* `Bus Device <https://github.com/adafruit/Adafruit_CircuitPython_BusDevice>`_
|
||||||
* `Register <https://github.com/adafruit/Adafruit_CircuitPython_Register>`_
|
|
||||||
|
|
||||||
Please ensure all dependencies are available on the CircuitPython filesystem.
|
Please ensure all dependencies are available on the CircuitPython filesystem.
|
||||||
This is easily achieved by downloading
|
This is easily achieved by downloading
|
||||||
|
|
@ -38,19 +37,8 @@ This is easily achieved by downloading
|
||||||
or individual libraries can be installed using
|
or individual libraries can be installed using
|
||||||
`circup <https://github.com/adafruit/circup>`_.
|
`circup <https://github.com/adafruit/circup>`_.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. todo:: Describe the Adafruit product this library works with. For PCBs, you can also add the
|
|
||||||
image from the assets folder in the PCB's GitHub repo.
|
|
||||||
|
|
||||||
`Purchase one from the Adafruit shop <http://www.adafruit.com/products/>`_
|
|
||||||
|
|
||||||
Installing from PyPI
|
Installing from PyPI
|
||||||
=====================
|
=====================
|
||||||
.. note:: This library is not available on PyPI yet. Install documentation is included
|
|
||||||
as a standard element. Stay tuned for PyPI availability!
|
|
||||||
|
|
||||||
.. todo:: Remove the above note if PyPI version is/will be available at time of release.
|
|
||||||
|
|
||||||
On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from
|
On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from
|
||||||
PyPI <https://pypi.org/project/adafruit-circuitpython-tlv320/>`_.
|
PyPI <https://pypi.org/project/adafruit-circuitpython-tlv320/>`_.
|
||||||
|
|
@ -101,8 +89,30 @@ Or the following command to update an existing version:
|
||||||
Usage Example
|
Usage Example
|
||||||
=============
|
=============
|
||||||
|
|
||||||
.. todo:: Add a quick, simple example. It and other examples should live in the
|
.. code-block:: python
|
||||||
examples folder and be included in docs/examples.rst.
|
|
||||||
|
import audiobusio
|
||||||
|
import audiocore
|
||||||
|
import board
|
||||||
|
|
||||||
|
import adafruit_tlv320
|
||||||
|
|
||||||
|
i2c = board.I2C()
|
||||||
|
dac = adafruit_tlv320.TLV320DAC3100(i2c)
|
||||||
|
|
||||||
|
# set mclk, sample rate & bit depth
|
||||||
|
dac.configure_clocks(mclk_freq=12000000, sample_rate=44100, bit_depth=16)
|
||||||
|
|
||||||
|
# use headphones
|
||||||
|
# helper function for default settings
|
||||||
|
dac.headphone_output = True
|
||||||
|
dac.headphone_volume = -20 # dB
|
||||||
|
# or use speaker
|
||||||
|
# helper function for default settings
|
||||||
|
# dac.speaker_output = True
|
||||||
|
# dac.speaker_volume = -15 # dB
|
||||||
|
|
||||||
|
audio = audiobusio.I2SOut(board.I2S_BCLK, board.I2S_WS, board.I2S_DIN)
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
=============
|
=============
|
||||||
|
|
|
||||||
1892
adafruit_tlv320.py
1892
adafruit_tlv320.py
File diff suppressed because it is too large
Load diff
|
|
@ -25,14 +25,13 @@ extensions = [
|
||||||
# Uncomment the below if you use native CircuitPython modules such as
|
# Uncomment the below if you use native CircuitPython modules such as
|
||||||
# digitalio, micropython and busio. List the modules you use. Without it, the
|
# digitalio, micropython and busio. List the modules you use. Without it, the
|
||||||
# autodoc module docs will fail to generate with a warning.
|
# autodoc module docs will fail to generate with a warning.
|
||||||
# autodoc_mock_imports = ["digitalio", "busio"]
|
autodoc_mock_imports = ["digitalio", "busio", "adafruit_bus_device", "micropython"]
|
||||||
|
|
||||||
autodoc_preserve_defaults = True
|
autodoc_preserve_defaults = True
|
||||||
|
|
||||||
intersphinx_mapping = {
|
intersphinx_mapping = {
|
||||||
"python": ("https://docs.python.org/3", None),
|
"python": ("https://docs.python.org/3", None),
|
||||||
"BusDevice": ("https://docs.circuitpython.org/projects/busdevice/en/latest/", None),
|
"BusDevice": ("https://docs.circuitpython.org/projects/busdevice/en/latest/", None),
|
||||||
"Register": ("https://docs.circuitpython.org/projects/register/en/latest/", None),
|
|
||||||
"CircuitPython": ("https://docs.circuitpython.org/en/latest/", None),
|
"CircuitPython": ("https://docs.circuitpython.org/en/latest/", None),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,12 @@ Ensure your device works with this simple test.
|
||||||
.. literalinclude:: ../examples/tlv320_simpletest.py
|
.. literalinclude:: ../examples/tlv320_simpletest.py
|
||||||
:caption: examples/tlv320_simpletest.py
|
:caption: examples/tlv320_simpletest.py
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
|
Full test
|
||||||
|
----------
|
||||||
|
|
||||||
|
Demos advanced features of the library.
|
||||||
|
|
||||||
|
.. literalinclude:: ../examples/tlv320_fulltest.py
|
||||||
|
:caption: examples/tlv320_fulltest.py
|
||||||
|
:linenos:
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,9 @@ Table of Contents
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:caption: Tutorials
|
:caption: Tutorials
|
||||||
|
|
||||||
.. todo:: Add any Learn guide links here. If there are none, then simply delete this todo and leave
|
|
||||||
the toctree above for use later.
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:caption: Related Products
|
:caption: Related Products
|
||||||
|
|
||||||
.. todo:: Add any product links here. If there are none, then simply delete this todo and leave
|
|
||||||
the toctree above for use later.
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:caption: Other Links
|
:caption: Other Links
|
||||||
|
|
||||||
|
|
|
||||||
239
examples/tlv320_fulltest.py
Normal file
239
examples/tlv320_fulltest.py
Normal file
|
|
@ -0,0 +1,239 @@
|
||||||
|
# SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
"""
|
||||||
|
Full TLV320DAC3100 Test
|
||||||
|
Demo all features in the library
|
||||||
|
Shows advanced control for DAC, headphone and speaker
|
||||||
|
beyond basic headphone_output & speaker_output helpers
|
||||||
|
in simpletest.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
|
|
||||||
|
from adafruit_tlv320 import (
|
||||||
|
DAC_PATH_MIXED,
|
||||||
|
DAC_PATH_NORMAL,
|
||||||
|
DAC_PATH_OFF,
|
||||||
|
DAC_PATH_SWAPPED,
|
||||||
|
DAC_ROUTE_HP,
|
||||||
|
DAC_ROUTE_MIXER,
|
||||||
|
DAC_ROUTE_NONE,
|
||||||
|
GPIO1_CLKOUT,
|
||||||
|
GPIO1_DISABLED,
|
||||||
|
GPIO1_GPI,
|
||||||
|
GPIO1_GPO,
|
||||||
|
GPIO1_INPUT_MODE,
|
||||||
|
HP_COMMON_1_35V,
|
||||||
|
HP_COMMON_1_50V,
|
||||||
|
HP_COMMON_1_65V,
|
||||||
|
HP_COMMON_1_80V,
|
||||||
|
SPK_GAIN_6DB,
|
||||||
|
SPK_GAIN_12DB,
|
||||||
|
SPK_GAIN_18DB,
|
||||||
|
SPK_GAIN_24DB,
|
||||||
|
TLV320DAC3100,
|
||||||
|
VOL_INDEPENDENT,
|
||||||
|
VOL_LEFT_TO_RIGHT,
|
||||||
|
VOL_RIGHT_TO_LEFT,
|
||||||
|
)
|
||||||
|
|
||||||
|
print("Initializing I2C and TLV320DAC3100...")
|
||||||
|
i2c = board.I2C()
|
||||||
|
dac = TLV320DAC3100(i2c)
|
||||||
|
|
||||||
|
# Display basic information
|
||||||
|
print("\n=== Basic Information ===")
|
||||||
|
print(f"Sample rate: {dac.sample_rate} Hz")
|
||||||
|
print(f"Bit depth: {dac.bit_depth}-bit")
|
||||||
|
print(f"Overtemperature condition: {dac.overtemperature}")
|
||||||
|
|
||||||
|
# I2S Config
|
||||||
|
dac.configure_clocks(sample_rate=44000, bit_depth=16)
|
||||||
|
print(f"Sample rate: {dac.sample_rate} Hz")
|
||||||
|
print(f"Bit depth: {dac.bit_depth}-bit")
|
||||||
|
time.sleep(0.2)
|
||||||
|
|
||||||
|
# Headphone Output Setup
|
||||||
|
print("\n=== Headphone Output Setup ===")
|
||||||
|
print("Setting up headphone output...")
|
||||||
|
dac.headphone_output = True # This conveniently sets up multiple parameters
|
||||||
|
print(f"Headphone output enabled: {dac.headphone_output}")
|
||||||
|
|
||||||
|
# Adjust headphone volume (in dB where 0dB is max, negative values reduce volume)
|
||||||
|
print("\nAdjusting headphone volume...")
|
||||||
|
print(f"Current headphone volume: {dac.headphone_volume} dB")
|
||||||
|
dac.headphone_volume = -10 # Set to -10 dB (moderate volume)
|
||||||
|
print(f"New headphone volume: {dac.headphone_volume} dB")
|
||||||
|
|
||||||
|
# Fine-tune left and right channels individually
|
||||||
|
print("\nAdjusting left and right headphone gain...")
|
||||||
|
print(f"Left headphone gain: {dac.headphone_left_gain}")
|
||||||
|
print(f"Right headphone gain: {dac.headphone_right_gain}")
|
||||||
|
dac.headphone_left_gain = 3 # Increase left channel gain
|
||||||
|
dac.headphone_right_gain = 3 # Increase right channel gain
|
||||||
|
print(f"New left headphone gain: {dac.headphone_left_gain}")
|
||||||
|
print(f"New right headphone gain: {dac.headphone_right_gain}")
|
||||||
|
|
||||||
|
# Mute/unmute the headphones
|
||||||
|
print("\nDemonstrating headphone mute functionality...")
|
||||||
|
print(f"Left headphone muted: {dac.headphone_left_mute}")
|
||||||
|
print(f"Right headphone muted: {dac.headphone_right_mute}")
|
||||||
|
dac.headphone_left_mute = True # Mute left channel
|
||||||
|
dac.headphone_right_mute = False # Ensure right channel is unmuted
|
||||||
|
print(f"Left headphone now muted: {dac.headphone_left_mute}")
|
||||||
|
print(f"Right headphone still unmuted: {dac.headphone_right_mute}")
|
||||||
|
time.sleep(1) # Listen to right channel only
|
||||||
|
dac.headphone_left_mute = False # Unmute left channel
|
||||||
|
print(f"Left headphone now unmuted: {dac.headphone_left_mute}")
|
||||||
|
dac.headphone_output = False # turn off before speaker test
|
||||||
|
|
||||||
|
# Speaker Output Setup
|
||||||
|
print("\n=== Speaker Output Setup ===")
|
||||||
|
print("Setting up speaker output...")
|
||||||
|
dac.speaker_output = True # This conveniently sets up multiple parameters
|
||||||
|
print(f"Speaker output enabled: {dac.speaker_output}")
|
||||||
|
|
||||||
|
# Adjust speaker volume (in dB where 0dB is max, negative values reduce volume)
|
||||||
|
print("\nAdjusting speaker volume...")
|
||||||
|
print(f"Current speaker volume: {dac.speaker_volume} dB")
|
||||||
|
dac.speaker_volume = -6 # Set to -6 dB (louder than headphones)
|
||||||
|
print(f"New speaker volume: {dac.speaker_volume} dB")
|
||||||
|
|
||||||
|
# Set speaker amplifier gain
|
||||||
|
print("\nAdjusting speaker gain...")
|
||||||
|
print(f"Current speaker gain: {dac.speaker_gain}")
|
||||||
|
dac.speaker_gain = SPK_GAIN_12DB # 12dB amplification
|
||||||
|
print(f"New speaker gain: {dac.speaker_gain}")
|
||||||
|
|
||||||
|
# Mute/unmute the speaker
|
||||||
|
print("\nDemonstrating speaker mute functionality...")
|
||||||
|
print(f"Speaker muted: {dac.speaker_mute}")
|
||||||
|
dac.speaker_mute = True # Mute speaker
|
||||||
|
print(f"Speaker now muted: {dac.speaker_mute}")
|
||||||
|
time.sleep(1)
|
||||||
|
dac.speaker_mute = False # Unmute speaker
|
||||||
|
print(f"Speaker now unmuted: {dac.speaker_mute}")
|
||||||
|
|
||||||
|
# DAC Signal Routing
|
||||||
|
print("\n=== Advanced DAC Signal Routing ===")
|
||||||
|
print("\nCurrent DAC Status:")
|
||||||
|
print(f"Left DAC enabled: {dac.left_dac}")
|
||||||
|
print(f"Right DAC enabled: {dac.right_dac}")
|
||||||
|
print(f"Left DAC path: {dac.left_dac_path}")
|
||||||
|
print(f"Right DAC path: {dac.right_dac_path}")
|
||||||
|
|
||||||
|
print("\nSetting up swapped stereo (left and right channels swapped)...")
|
||||||
|
dac.left_dac_path = DAC_PATH_SWAPPED
|
||||||
|
dac.right_dac_path = DAC_PATH_SWAPPED
|
||||||
|
print(f"New left DAC path: {dac.left_dac_path}")
|
||||||
|
print(f"New right DAC path: {dac.right_dac_path}")
|
||||||
|
|
||||||
|
print("\nSetting up mono output (mixed left and right channels)...")
|
||||||
|
dac.left_dac_path = DAC_PATH_MIXED
|
||||||
|
dac.right_dac_path = DAC_PATH_MIXED
|
||||||
|
print(f"New left DAC path: {dac.left_dac_path}")
|
||||||
|
print(f"New right DAC path: {dac.right_dac_path}")
|
||||||
|
|
||||||
|
print("\nRestoring normal stereo...")
|
||||||
|
dac.left_dac_path = DAC_PATH_NORMAL
|
||||||
|
dac.right_dac_path = DAC_PATH_NORMAL
|
||||||
|
print(f"New left DAC path: {dac.left_dac_path}")
|
||||||
|
print(f"New right DAC path: {dac.right_dac_path}")
|
||||||
|
|
||||||
|
# DAC Volume Controls
|
||||||
|
print("\n=== DAC Volume Control Configuration ===")
|
||||||
|
print(f"Left DAC muted: {dac.left_dac_mute}")
|
||||||
|
print(f"Right DAC muted: {dac.right_dac_mute}")
|
||||||
|
print(f"Volume control mode: {dac.dac_volume_control_mode}")
|
||||||
|
|
||||||
|
print("\nSetting volume control mode where left channel controls right...")
|
||||||
|
dac.dac_volume_control_mode = VOL_LEFT_TO_RIGHT
|
||||||
|
print(f"New volume control mode: {dac.dac_volume_control_mode}")
|
||||||
|
|
||||||
|
print("\nSetting independent volume control mode (default)...")
|
||||||
|
dac.dac_volume_control_mode = VOL_INDEPENDENT
|
||||||
|
print(f"New volume control mode: {dac.dac_volume_control_mode}")
|
||||||
|
|
||||||
|
# DAC Channel Volume
|
||||||
|
print("\n=== DAC Channel Volume ===")
|
||||||
|
print(f"Left DAC channel volume: {dac.left_dac_channel_volume} dB")
|
||||||
|
print(f"Right DAC channel volume: {dac.right_dac_channel_volume} dB")
|
||||||
|
|
||||||
|
print("\nSetting different volumes for left and right channels...")
|
||||||
|
dac.left_dac_channel_volume = -3
|
||||||
|
dac.right_dac_channel_volume = -9
|
||||||
|
print(f"New left DAC channel volume: {dac.left_dac_channel_volume} dB")
|
||||||
|
print(f"New right DAC channel volume: {dac.right_dac_channel_volume} dB")
|
||||||
|
|
||||||
|
# Headphone as Line-Out
|
||||||
|
print("\n=== Configure Headphone as Line-Out ===")
|
||||||
|
print(f"Headphone configured as line-out: {dac.headphone_lineout}")
|
||||||
|
|
||||||
|
# Safety Features
|
||||||
|
print("\n=== Safety Features ===")
|
||||||
|
print(f"Reset speaker on short circuit: {dac.reset_speaker_on_scd}")
|
||||||
|
print(f"Reset headphone on short circuit: {dac.reset_headphone_on_scd}")
|
||||||
|
|
||||||
|
# Getting status flags
|
||||||
|
print("\n=== Status Information ===")
|
||||||
|
flags = dac.dac_flags
|
||||||
|
print(f"Left DAC powered: {flags['left_dac_powered']}")
|
||||||
|
print(f"Right DAC powered: {flags['right_dac_powered']}")
|
||||||
|
print(f"Headphone left (HPL) powered: {flags['hpl_powered']}")
|
||||||
|
print(f"Headphone right (HPR) powered: {flags['hpr_powered']}")
|
||||||
|
print(f"Left Class-D amplifier powered: {flags['left_classd_powered']}")
|
||||||
|
print(f"Right Class-D amplifier powered: {flags['right_classd_powered']}")
|
||||||
|
print(f"Left PGA gain OK: {flags['left_pga_gain_ok']}")
|
||||||
|
print(f"Right PGA gain OK: {flags['right_pga_gain_ok']}")
|
||||||
|
|
||||||
|
# Additional status checks via dedicated properties
|
||||||
|
print("\nStatus via dedicated properties:")
|
||||||
|
print(f"Speaker shorted: {dac.speaker_shorted}")
|
||||||
|
print(f"HPL gain fully applied: {dac.hpl_gain_applied}")
|
||||||
|
print(f"HPR gain fully applied: {dac.hpr_gain_applied}")
|
||||||
|
print(f"Speaker gain fully applied: {dac.speaker_gain_applied}")
|
||||||
|
|
||||||
|
# Higher-level shortcut methods
|
||||||
|
print("\n=== Using Higher-Level Shortcuts ===")
|
||||||
|
print("Demonstrating on/off control of primary outputs:")
|
||||||
|
|
||||||
|
print("\nTurning off headphone output...")
|
||||||
|
dac.headphone_output = False
|
||||||
|
print(f"Headphone output now: {dac.headphone_output}")
|
||||||
|
|
||||||
|
print("\nTurning off speaker output...")
|
||||||
|
dac.speaker_output = True
|
||||||
|
print(f"Speaker output now: {dac.speaker_output}")
|
||||||
|
|
||||||
|
print("\nSwapping outputs...")
|
||||||
|
dac.speaker_output = False
|
||||||
|
dac.headphone_output = True
|
||||||
|
print(f"Headphone output now: {dac.headphone_output}")
|
||||||
|
print(f"Speaker output now: {dac.speaker_output}")
|
||||||
|
|
||||||
|
# Pop Removal Setting
|
||||||
|
print("\n=== Headphone Pop Removal Settings ===")
|
||||||
|
dac.configure_headphone_pop(
|
||||||
|
wait_for_powerdown=True, # Wait for amp powerdown before DAC powerdown
|
||||||
|
powerup_time=7, # Power-on time setting (0-11)
|
||||||
|
ramp_time=3, # Ramp-up step time (0-3)
|
||||||
|
)
|
||||||
|
print("Headphone pop removal configured")
|
||||||
|
|
||||||
|
# External Settings (like GPIO)
|
||||||
|
print("\n=== GPIO Configuration ===")
|
||||||
|
print(f"Current GPIO1 mode: {dac.gpio1_mode}")
|
||||||
|
dac.gpio1_mode = GPIO1_GPO # Set GPIO1 as general purpose output
|
||||||
|
print(f"New GPIO1 mode: {dac.gpio1_mode}")
|
||||||
|
dac.gpio1_mode = GPIO1_DISABLED # Disable GPIO1
|
||||||
|
print(f"Disabled GPIO1 mode: {dac.gpio1_mode}")
|
||||||
|
|
||||||
|
# Volume Control ADC
|
||||||
|
print("\n=== Volume Control ADC ===")
|
||||||
|
print(f"Volume ADC reading: {dac.vol_adc_db} dB")
|
||||||
|
|
||||||
|
print("\nAll examples completed!")
|
||||||
|
|
@ -1,4 +1,43 @@
|
||||||
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
|
# SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
|
||||||
# SPDX-FileCopyrightText: Copyright (c) 2025 Liz Clark for Adafruit Industries
|
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import array
|
||||||
|
import math
|
||||||
|
import time
|
||||||
|
|
||||||
|
import audiobusio
|
||||||
|
import audiocore
|
||||||
|
import board
|
||||||
|
|
||||||
|
import adafruit_tlv320
|
||||||
|
|
||||||
|
i2c = board.I2C()
|
||||||
|
dac = adafruit_tlv320.TLV320DAC3100(i2c)
|
||||||
|
|
||||||
|
# set sample rate & bit depth, use bclk
|
||||||
|
dac.configure_clocks(sample_rate=44100, bit_depth=16)
|
||||||
|
|
||||||
|
# use headphones
|
||||||
|
dac.headphone_output = True
|
||||||
|
dac.headphone_volume = -15 # dB
|
||||||
|
# or use speaker
|
||||||
|
# dac.speaker_output = True
|
||||||
|
# dac.speaker_volume = -10 # dB
|
||||||
|
|
||||||
|
audio = audiobusio.I2SOut(board.I2S_BCLK, board.I2S_WS, board.I2S_DIN)
|
||||||
|
# generate a sine wave
|
||||||
|
tone_volume = 0.5
|
||||||
|
frequency = 440
|
||||||
|
sample_rate = dac.sample_rate
|
||||||
|
length = sample_rate // frequency
|
||||||
|
sine_wave = array.array("h", [0] * length)
|
||||||
|
for i in range(length):
|
||||||
|
sine_wave[i] = int((math.sin(math.pi * 2 * i / length)) * tone_volume * (2**15 - 1))
|
||||||
|
sine_wave_sample = audiocore.RawSample(sine_wave, sample_rate=sample_rate)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
audio.stop()
|
||||||
|
time.sleep(1)
|
||||||
|
audio.play(sine_wave_sample, loop=True)
|
||||||
|
time.sleep(1)
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,3 @@
|
||||||
|
|
||||||
Adafruit-Blinka
|
Adafruit-Blinka
|
||||||
adafruit-circuitpython-busdevice
|
adafruit-circuitpython-busdevice
|
||||||
adafruit-circuitpython-register
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue