mirror of
https://github.com/micropython/micropython.git
synced 2026-01-07 12:40:15 +01:00
esp32,stm32: Add new machine.I2S class for I2S protocol support.
This commit adds I2S protocol support for the esp32 and stm32 ports, via a new machine.I2S class. It builds on the stm32 work of blmorris, #1361. Features include: - a consistent I2S API across the esp32 and stm32 ports - I2S configurations supported: - master transmit and master receive - 16-bit and 32-bit sample sizes - mono and stereo formats - sampling frequency - 3 modes of operation: - blocking - non-blocking with callback - uasyncio - internal ring buffer size can be tuned - documentation for Pyboards and esp32-based boards - tested on the following development boards: - Pyboard D SF2W - Pyboard V1.1 - ESP32 with SPIRAM - ESP32 Signed-off-by: Mike Teachman <mike.teachman@gmail.com>
This commit is contained in:
committed by
Damien George
parent
031fe0f144
commit
8a5bfe44a5
@@ -385,6 +385,24 @@ has the same methods as software I2C above::
|
||||
i2c = I2C(0)
|
||||
i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000)
|
||||
|
||||
I2S bus
|
||||
-------
|
||||
|
||||
See :ref:`machine.I2S <machine.I2S>`. ::
|
||||
|
||||
from machine import I2S, Pin
|
||||
|
||||
i2s = I2S(0, sck=Pin(13), ws=Pin(14), sd=Pin(34), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=40000) # create I2S object
|
||||
i2s.write(buf) # write buffer of audio samples to I2S device
|
||||
|
||||
i2s = I2S(1, sck=Pin(33), ws=Pin(25), sd=Pin(32), mode=I2S.RX, bits=16, format=I2S.MONO, rate=22050, ibuf=40000) # create I2S object
|
||||
i2s.readinto(buf) # fill buffer with audio samples from I2S device
|
||||
|
||||
The I2S class is currently available as a Technical Preview. During the preview period, feedback from
|
||||
users is encouraged. Based on this feedback, the I2S class API and implementation may be changed.
|
||||
|
||||
ESP32 has two I2S buses with id=0 and id=1
|
||||
|
||||
Real time clock (RTC)
|
||||
---------------------
|
||||
|
||||
|
||||
162
docs/library/machine.I2S.rst
Normal file
162
docs/library/machine.I2S.rst
Normal file
@@ -0,0 +1,162 @@
|
||||
.. currentmodule:: machine
|
||||
.. _machine.I2S:
|
||||
|
||||
class I2S -- Inter-IC Sound bus protocol
|
||||
========================================
|
||||
|
||||
I2S is a synchronous serial protocol used to connect digital audio devices.
|
||||
At the physical level, a bus consists of 3 lines: SCK, WS, SD.
|
||||
The I2S class supports Master operation. Slave operation is not supported.
|
||||
|
||||
The I2S class is currently available as a Technical Preview. During the preview period, feedback from
|
||||
users is encouraged. Based on this feedback, the I2S class API and implementation may be changed.
|
||||
|
||||
I2S objects can be created and initialized using::
|
||||
|
||||
from machine import I2S
|
||||
from machine import Pin
|
||||
|
||||
# ESP32
|
||||
sck_pin = Pin(14) # Serial clock output
|
||||
ws_pin = Pin(13) # Word clock output
|
||||
sdout_pin = Pin(12) # Serial data output
|
||||
|
||||
or
|
||||
|
||||
# PyBoards
|
||||
sck_pin = Pin("Y6") # Serial clock output
|
||||
ws_pin = Pin("Y5") # Word clock output
|
||||
sdout_pin = Pin("Y8") # Serial data output
|
||||
|
||||
audio_out = I2S(2,
|
||||
sck=sck_pin, ws=ws_pin, sdin=sdin_pin,
|
||||
mode=I2S.TX,
|
||||
bits=16,
|
||||
format=I2S.MONO,
|
||||
rate=44100,
|
||||
ibuf=20000)
|
||||
|
||||
audio_in = I2S(2,
|
||||
sck=sck_pin, ws=ws_pin, sdin=sdin_pin,
|
||||
mode=I2S.RX,
|
||||
bits=32,
|
||||
format=I2S.STEREO,
|
||||
rate=22050,
|
||||
ibuf=20000)
|
||||
|
||||
3 modes of operation are supported:
|
||||
- blocking
|
||||
- non-blocking
|
||||
- uasyncio
|
||||
|
||||
blocking::
|
||||
|
||||
num_written = audio_out.write(buf) # blocks until buf emptied
|
||||
|
||||
num_read = audio_in.readinto(buf) # blocks until buf filled
|
||||
|
||||
non-blocking::
|
||||
|
||||
audio_out.irq(i2s_callback) # i2s_callback is called when buf is emptied
|
||||
num_written = audio_out.write(buf) # returns immediately
|
||||
|
||||
audio_in.irq(i2s_callback) # i2s_callback is called when buf is filled
|
||||
num_read = audio_in.readinto(buf) # returns immediately
|
||||
|
||||
uasyncio::
|
||||
|
||||
swriter = uasyncio.StreamWriter(audio_out)
|
||||
swriter.write(buf)
|
||||
await swriter.drain()
|
||||
|
||||
sreader = uasyncio.StreamReader(audio_in)
|
||||
num_read = await sreader.readinto(buf)
|
||||
|
||||
Constructor
|
||||
-----------
|
||||
|
||||
.. class:: I2S(id, *, sck, ws, sd, mode, bits, format, rate, ibuf)
|
||||
|
||||
Construct an I2S object of the given id:
|
||||
|
||||
- ``id`` identifies a particular I2S bus.
|
||||
|
||||
``id`` is board and port specific:
|
||||
|
||||
- PYBv1.0/v1.1: has one I2S bus with id=2.
|
||||
- PYBD-SFxW: has two I2S buses with id=1 and id=2.
|
||||
- ESP32: has two I2S buses with id=0 and id=1.
|
||||
|
||||
Keyword-only parameters that are supported on all ports:
|
||||
|
||||
- ``sck`` is a pin object for the serial clock line
|
||||
- ``ws`` is a pin object for the word select line
|
||||
- ``sd`` is a pin object for the serial data line
|
||||
- ``mode`` specifies receive or transmit
|
||||
- ``bits`` specifies sample size (bits), 16 or 32
|
||||
- ``format`` specifies channel format, STEREO or MONO
|
||||
- ``rate`` specifies audio sampling rate (samples/s)
|
||||
- ``ibuf`` specifies internal buffer length (bytes)
|
||||
|
||||
For all ports, DMA runs continuously in the background and allows user applications to perform other operations while
|
||||
sample data is transfered between the internal buffer and the I2S peripheral unit.
|
||||
Increasing the size of the internal buffer has the potential to increase the time that user applications can perform non-I2S operations
|
||||
before underflow (e.g. ``write`` method) or overflow (e.g. ``readinto`` method).
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: I2S.init(sck, ...)
|
||||
|
||||
see Constructor for argument descriptions
|
||||
|
||||
.. method:: I2S.deinit()
|
||||
|
||||
Deinitialize the I2S bus
|
||||
|
||||
.. method:: I2S.readinto(buf)
|
||||
|
||||
Read audio samples into the buffer specified by ``buf``. ``buf`` must support the buffer protocol, such as bytearray or array.
|
||||
"buf" byte ordering is little-endian. For Stereo format, left channel sample precedes right channel sample. For Mono format,
|
||||
the left channel sample data is used.
|
||||
Returns number of bytes read
|
||||
|
||||
.. method:: I2S.write(buf)
|
||||
|
||||
Write audio samples contained in ``buf``. ``buf`` must support the buffer protocol, such as bytearray or array.
|
||||
"buf" byte ordering is little-endian. For Stereo format, left channel sample precedes right channel sample. For Mono format,
|
||||
the sample data is written to both the right and left channels.
|
||||
Returns number of bytes written
|
||||
|
||||
.. method:: I2S.irq(handler)
|
||||
|
||||
Set a callback. ``handler`` is called when ``buf`` is emptied (``write`` method) or becomes full (``readinto`` method).
|
||||
Setting a callback changes the ``write`` and ``readinto`` methods to non-blocking operation.
|
||||
``handler`` is called in the context of the MicroPython scheduler.
|
||||
|
||||
.. staticmethod:: I2S.shift(buf, bits, shift)
|
||||
|
||||
bitwise shift of all samples contained in ``buf``. ``bits`` specifies sample size in bits. ``shift`` specifies the number of bits to shift each sample.
|
||||
Positive for left shift, negative for right shift.
|
||||
Typically used for volume control. Each bit shift changes sample volume by 6dB.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: I2S.RX
|
||||
|
||||
for initialising the I2S bus ``mode`` to receive
|
||||
|
||||
.. data:: I2S.TX
|
||||
|
||||
for initialising the I2S bus ``mode`` to transmit
|
||||
|
||||
.. data:: I2S.STEREO
|
||||
|
||||
for initialising the I2S bus ``format`` to stereo
|
||||
|
||||
.. data:: I2S.MONO
|
||||
|
||||
for initialising the I2S bus ``format`` to mono
|
||||
|
||||
|
||||
@@ -181,6 +181,7 @@ Classes
|
||||
machine.UART.rst
|
||||
machine.SPI.rst
|
||||
machine.I2C.rst
|
||||
machine.I2S.rst
|
||||
machine.RTC.rst
|
||||
machine.Timer.rst
|
||||
machine.WDT.rst
|
||||
|
||||
@@ -219,6 +219,26 @@ eg ``I2C(1)``. Software I2C is also available by explicitly specifying the
|
||||
|
||||
Note: for legacy I2C support see :ref:`pyb.I2C <pyb.I2C>`.
|
||||
|
||||
I2S bus
|
||||
-------
|
||||
|
||||
See :ref:`machine.I2S <machine.I2S>`. ::
|
||||
|
||||
from machine import I2S, Pin
|
||||
|
||||
i2s = I2S(2, sck=Pin('Y6'), ws=Pin('Y5'), sd=Pin('Y8'), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=40000) # create I2S object
|
||||
i2s.write(buf) # write buffer of audio samples to I2S device
|
||||
|
||||
i2s = I2S(1, sck=Pin('X5'), ws=Pin('X6'), sd=Pin('Y4'), mode=I2S.RX, bits=16, format=I2S.MONO, rate=22050, ibuf=40000) # create I2S object
|
||||
i2s.readinto(buf) # fill buffer with audio samples from I2S device
|
||||
|
||||
The I2S class is currently available as a Technical Preview. During the preview period, feedback from
|
||||
users is encouraged. Based on this feedback, the I2S class API and implementation may be changed.
|
||||
|
||||
PYBv1.0/v1.1 has one I2S bus with id=2.
|
||||
PYBD-SFxW has two I2S buses with id=1 and id=2.
|
||||
I2S is shared with SPI.
|
||||
|
||||
CAN bus (controller area network)
|
||||
---------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user