I2S: Inter-IC Serial communications
Introduction
I2S was designed for transfer of digital audio data.
The ESP8266 has two I2S modules (one transmitter and one receiver), both with hardware DMA support, which means transfers from RAM to the hardware SPI FIFO can be handled directly in hardware without any CPU involvement.
Sming I2S support
The Sming driver deals with the complicated of setting up the hardware, using an API similar to that in the Espressif RTOS SDK. In addition, DMA buffers may be accessed directly to avoid double-buffering and the associated RAM and copy overhead.
Applications
Audio
Playing MIDI files, MP3 files, speech synthesis, etc. is all possible using the ESP8266, though many audio applications require considerable processing power. That means you may need to disable WiFi and set the processor to run at full 160MHz speed.
High-quality multi-channel audio requires an external I2S DAC, which is what the protocol was designed for in the first place. You may find problems with insufficient RAM, but you can always add external SPI RAM.
More realistic uses include generating simple tones, beeps, playing pre-recorded WAV audio, etc. to supplement existing projects. This can all be done in the background without disrupting the system’s main purpose, whatever that may be.
For such applications you can generate single-channel audio via the I2S OUT pin, using Pulse-density modulation.
See the Tone Generator library for a demonstration of this.
GPIO Expansion
Expand GPIO using low-cost shift registers. https://github.com/lhartmann/esp8266_reprap.
Pixel-strip control
Devices such as WS2812-based NeoPixels use a simple, single-wire protocol. I2S is ideal for this as it can be used to generate a precisely-timed bitstream with very low CPU loading.
API Documentation
-
enum i2s_bits_per_sample_t
I2S bit width per sample.
Values:
-
enumerator I2S_BITS_PER_SAMPLE_8BIT
I2S bits per sample: 8-bits.
-
enumerator I2S_BITS_PER_SAMPLE_16BIT
I2S bits per sample: 16-bits.
-
enumerator I2S_BITS_PER_SAMPLE_24BIT
I2S bits per sample: 24-bits.
-
enumerator I2S_BITS_PER_SAMPLE_8BIT
-
enum i2s_channel_t
I2S channel.
Values:
-
enumerator I2S_CHANNEL_MONO
I2S 1 channel (mono)
-
enumerator I2S_CHANNEL_STEREO
I2S 2 channel (stereo)
-
enumerator I2S_CHANNEL_MONO
-
enum i2s_comm_format_t
I2S communication standard format.
Values:
-
enumerator I2S_COMM_FORMAT_I2S
I2S communication format I2S.
-
enumerator I2S_COMM_FORMAT_I2S_MSB
I2S format MSB.
-
enumerator I2S_COMM_FORMAT_I2S_LSB
I2S format LSB.
-
enumerator I2S_COMM_FORMAT_I2S
-
enum i2s_channel_fmt_t
I2S channel format type.
Values:
-
enumerator I2S_CHANNEL_FMT_RIGHT_LEFT
-
enumerator I2S_CHANNEL_FMT_ALL_RIGHT
-
enumerator I2S_CHANNEL_FMT_ALL_LEFT
-
enumerator I2S_CHANNEL_FMT_ONLY_RIGHT
-
enumerator I2S_CHANNEL_FMT_ONLY_LEFT
-
enumerator I2S_CHANNEL_FMT_RIGHT_LEFT
-
enum i2s_mode_t
I2S Mode, default is I2S_MODE_MASTER.
Values:
-
enumerator I2S_MODE_DISABLED
-
enumerator I2S_MODE_MASTER
-
enumerator I2S_MODE_SLAVE
-
enumerator I2S_MODE_DISABLED
-
enum i2s_event_type_t
I2S event types.
Values:
-
enumerator I2S_EVENT_DMA_ERROR
-
enumerator I2S_EVENT_TX_DONE
I2S DMA finish sent 1 buffer
-
enumerator I2S_EVENT_RX_DONE
I2S DMA finish received 1 buffer
-
enumerator I2S_EVENT_MAX
I2S event max index
-
enumerator I2S_EVENT_DMA_ERROR
-
enum i2s_pin_t
I2S pin enable for i2s_set_pin.
Values:
-
enumerator I2S_PIN_BCK_OUT
GPIO 15 / TXD2 / D8.
-
enumerator I2S_PIN_WS_OUT
GPIO 2 / TXD1 / D4.
-
enumerator I2S_PIN_DATA_OUT
GPIO 3 / RXD0 / D9.
-
enumerator I2S_PIN_BC_IN
GPIO 13 / RXD2 / D7.
-
enumerator I2S_PIN_WS_IN
GPIO 14 / D5.
-
enumerator I2S_PIN_DATA_IN
GPIO 12 / D6.
-
enumerator I2S_PIN_BCK_OUT
-
typedef void (*i2s_callback_t)(void *param, i2s_event_type_t event)
Callback function type.
Note
Function is called in interrupt context, so place in IRAM and keep it brief.
-
typedef unsigned TickType_t
Defines the wait interval (presently milliseconds)
-
typedef uint8_t i2s_pin_set_t
-
bool i2s_driver_install(const i2s_config_t *config)
Install and start I2S driver.
Note
This function must be called before any I2S driver read/write operations.
- Parameters:
config – I2S configuration
- Return values:
true – on success, false if already installed or invalid config
-
void i2s_driver_uninstall()
Uninstall I2S driver.
-
bool i2s_start()
Start I2S driver.
Note
It is not necessary to call this function after i2s_driver_install() as it is started automatically, unless
config.auto_start
was set to false.- Return values:
bool – true on success, false if driver not initialised
-
bool i2s_stop()
Stop I2S driver.
Note
Disables I2S TX/RX, until i2s_start() is called
- Return values:
bool – true on success, false if driver not initialised
-
bool i2s_set_sample_rates(uint32_t rate)
- Parameters:
rate – Sample rate in Hz (ex 44100, 48000) for TX/RX
-
bool i2s_set_dividers(uint8_t bck_div, uint8_t mclk_div)
Direct control over output rate
-
float i2s_get_real_rate()
- Return values:
float – The actual Sample Rate on output
-
bool i2s_dma_read(i2s_buffer_info_t *info, size_t max_bytes)
Fetch a DMA buffer containing received data (zero-copy)
Note
On success,
info->buffer
specifies where to read the data from, andinfo->size
how many bytes are actually available (always > 0).Note
Returns at most one DMA buffer
- Parameters:
info – Pointer to structure to receive buffer information
max_bytes – Number of bytes to read
- Return values:
bool – true on success, false if no data available or info is null
-
bool i2s_dma_write(i2s_buffer_info_t *info, size_t max_bytes)
Fetch a DMA buffer for direct writing (zero-copy)
Note
On success,
info->buffer
specifies where to write the data, andinfo->size
how many bytes should be written - may be less than max_bytes, but always > 0.Note
Returns at most one DMA buffer
- Parameters:
info – Pointer to structure to receive buffer information
max_bytes – Number of bytes required in buffer
- Return values:
bool – true on success, false if buffer unavailable or info is null
-
size_t i2s_write(const void *src, size_t size, TickType_t ticks_to_wait)
writes a buffer of frames into the DMA memory, returns the amount of frames written.
Note
Data is copied into DMA buffers
- Parameters:
src – Data to write
size – Size in bytes
ticks_to_wait – Wait timeout in ticks
- Return values:
size_t – Data actually written, may be less than size
-
size_t i2s_read(void *dest, size_t size, TickType_t ticks_to_wait)
Reads a block of received data.
- Parameters:
dest – Buffer to store data
size – Max. bytes to read
ticks_to_wait – Wait timeout in ticks
- Return values:
size_t – Number of bytes read
-
bool i2s_zero_dma_buffer()
Zero the contents of the TX DMA buffer.
Note
Pushes zero-byte samples into the TX DMA buffer, until it is full
-
void i2s_set_pins(i2s_pin_set_t pins, bool enable)
Configure I2S pins.
You can alternatively use arduino functions.
Example: i2s_set_pins(_BV(I2S_BCK_OUT), true)
Note
Call this after initialising driver to specify which pins are required
- Parameters:
pins – Mask of i2s_pin_t values
enable – true to enable for I2S use, false to revert to GPIO
-
bool i2s_enable_loopback(bool enable)
-
bool i2s_stat_tx(i2s_buffer_stat_t *stat)
Obtain state information for TX buffers.
- Parameters:
stat –
- Return values:
bool – true on success
-
bool i2s_stat_rx(i2s_buffer_stat_t *stat)
Obtain state information for RX buffers.
- Parameters:
stat –
- Return values:
bool – true on success
-
union i2s_sample_t
- #include <i2s.h>
I2S sample.
An I2S frame can contain various types of data:
8-bit, 16-bit or 24-bit mono samples 8-bit or 16-bit stereo samples
Public Members
-
uint32_t u32
-
int16_t left
-
int16_t right
-
struct i2s_sample_t::[anonymous] [anonymous]
-
uint32_t u32
-
struct i2s_module_config_t
- #include <i2s.h>
I2S module configuration (TX or RX)
Public Members
-
i2s_mode_t mode
I2S work mode (combination of i2s_mode_t)
-
i2s_bits_per_sample_t bits_per_sample
I2S bits per sample.
-
i2s_channel_fmt_t channel_format
I2S channel format.
-
i2s_comm_format_t communication_format
I2S communication format.
-
uint16_t dma_buf_len
I2S DMA Buffer Length (in samples)
-
uint8_t dma_buf_count
I2S DMA Buffer Count.
-
uint8_t callback_threshold
TX: callback when available buffers > threshold RX: Callback when slc_queue_len > threshold
-
i2s_mode_t mode
-
struct i2s_config_t
- #include <i2s.h>
I2S configuration parameters.
Public Members
-
i2s_module_config_t tx
TX module configuration.
-
i2s_module_config_t rx
RX module configuration.
-
unsigned sample_rate
I2S sample rate.
-
bool tx_desc_auto_clear
I2S auto clear tx descriptor if there is underflow condition (Mutes output)
-
bool auto_start
Start immediately on successful initialisation.
-
i2s_callback_t callback
Callback handler.
-
void *param
Callback parameter.
-
uint8_t bits_mod
Evaluate what this does (4 bits)
-
i2s_module_config_t tx
-
struct i2s_buffer_info_t
- #include <i2s.h>
Defines a buffer with available content.
Public Members
-
size_t size
Available space (TX) or data (RX) in bytes.
-
size_t size
-
struct i2s_buffer_stat_t
- #include <i2s.h>
Contains I2S buffer status information.
Note
Size excludes buffer in use by DMA