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.

enum i2s_channel_t

I2S channel.

Values:

enumerator I2S_CHANNEL_MONO

I2S 1 channel (mono)

enumerator I2S_CHANNEL_STEREO

I2S 2 channel (stereo)

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.

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
enum i2s_mode_t

I2S Mode, default is I2S_MODE_MASTER.

Values:

enumerator I2S_MODE_DISABLED
enumerator I2S_MODE_MASTER
enumerator I2S_MODE_SLAVE
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

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.

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, and info->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, and info->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]
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

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)

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.

struct i2s_buffer_stat_t
#include <i2s.h>

Contains I2S buffer status information.

Note

Size excludes buffer in use by DMA