I2S

Overview

ESP32 contains two I2S peripherals. These peripherals can be configured to input and output sample data via the I2S driver.

The I2S peripheral supports DMA meaning it can stream sample data without requiring each sample to be read or written by the CPU.

I2S output can also be routed directly to the Digital/Analog Converter output channels (GPIO 25 & GPIO 26) to produce analog output directly, rather than via an external I2S codec.

Note

For high accuracy clock applications, APLL clock source can be used with .use_apll = true and ESP32 will automatically calculate APLL parameter.

Note

If use_apll = true and fixed_mclk > 0, then the Master clock output for I2S is fixed and equal to the fixed_mclk value. The audio clock rate (LRCK) is always the MCLK divisor and 0 < MCLK/LRCK/channels/bits_per_sample < 64

Application Example

A full I2S example is available in esp-idf: peripherals/i2s.

Short example of I2S configuration:

#include "driver/i2s.h"
#include "freertos/queue.h"

static const int i2s_num = 0; // i2s port number

static const i2s_config_t i2s_config = {
     .mode = I2S_MODE_MASTER | I2S_MODE_TX,
     .sample_rate = 44100,
     .bits_per_sample = 16,
     .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
     .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
     .intr_alloc_flags = 0, // default interrupt priority
     .dma_buf_count = 8,
     .dma_buf_len = 64,
     .use_apll = false
};

static const i2s_pin_config_t pin_config = {
    .bck_io_num = 26,
    .ws_io_num = 25,
    .data_out_num = 22,
    .data_in_num = I2S_PIN_NO_CHANGE
};

...

    i2s_driver_install(i2s_num, &i2s_config, 0, NULL);   //install and start i2s driver

    i2s_set_pin(i2s_num, &pin_config);

    i2s_set_sample_rates(i2s_num, 22050); //set sample rates

    i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver

Short example configuring I2S to use internal DAC for analog output:

#include "driver/i2s.h"
#include "freertos/queue.h"

static const int i2s_num = 0; // i2s port number

static const i2s_config_t i2s_config = {
     .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN,
     .sample_rate = 44100,
     .bits_per_sample = 16, /* the DAC module will only take the 8bits from MSB */
     .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
     .communication_format = I2S_COMM_FORMAT_I2S_MSB,
     .intr_alloc_flags = 0, // default interrupt priority
     .dma_buf_count = 8,
     .dma_buf_len = 64,
     .use_apll = false
};

...

    i2s_driver_install(i2s_num, &i2s_config, 0, NULL);   //install and start i2s driver

    i2s_set_pin(i2s_num, NULL); //for internal DAC, this will enable both of the internal channels

    //You can call i2s_set_dac_mode to set built-in DAC output mode.
    //i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);

    i2s_set_sample_rates(i2s_num, 22050); //set sample rates

    i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver

API Reference

Functions

esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin)

Set I2S pin number.

Inside the pin configuration structure, set I2S_PIN_NO_CHANGE for any pin where the current configuration should not be changed.

Note
The I2S peripheral output signals can be connected to multiple GPIO pads. However, the I2S peripheral input signal can only be connected to one GPIO pad.
Parameters
  • i2s_num: I2S_NUM_0 or I2S_NUM_1
  • pin: I2S Pin structure, or NULL to set 2-channel 8-bit internal DAC pin configuration (GPIO25 & GPIO26)

Note
if *pin is set as NULL, this function will initialize both of the built-in DAC channels by default. if you don’t want this to happen and you want to initialize only one of the DAC channels, you can call i2s_set_dac_mode instead.
Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
  • ESP_FAIL IO error

esp_err_t i2s_set_dac_mode(i2s_dac_mode_t dac_mode)

Set I2S dac mode, I2S built-in DAC is disabled by default.

Note
Built-in DAC functions are only supported on I2S0 for current ESP32 chip. If either of the built-in DAC channel are enabled, the other one can not be used as RTC DAC function at the same time.
Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
Parameters
  • dac_mode: DAC mode configurations - see i2s_dac_mode_t

esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config, int queue_size, void *i2s_queue)

Install and start I2S driver.

This function must be called before any I2S driver read/write operations.

Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1
  • i2s_config: I2S configurations - see i2s_config_t struct
  • queue_size: I2S event queue size/depth.
  • i2s_queue: I2S event queue handle, if set NULL, driver will not use an event queue.

Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
  • ESP_ERR_NO_MEM Out of memory

esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)

Uninstall I2S driver.

Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1

int i2s_write_bytes(i2s_port_t i2s_num, const void *src, size_t size, TickType_t ticks_to_wait)

Write data to I2S DMA transmit buffer.

This function is deprecated. Use ‘i2s_write’ instead. This definition will be removed in a future release.

Return
  • The amount of bytes written, if timeout, the result will be less than the size passed in.
  • ESP_FAIL Parameter error

esp_err_t i2s_write(i2s_port_t i2s_num, const void *src, size_t size, size_t *bytes_written, TickType_t ticks_to_wait)

Write data to I2S DMA transmit buffer.

Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1
  • src: Source address to write from
  • size: Size of data in bytes
  • bytes_written: Number of bytes written, if timeout, the result will be less than the size passed in.
  • ticks_to_wait: TX buffer wait timeout in RTOS ticks. If this many ticks pass without space becoming available in the DMA transmit buffer, then the function will return (note that if the data is written to the DMA buffer in pieces, the overall operation may still take longer than this timeout.) Pass portMAX_DELAY for no timeout.

esp_err_t i2s_write_expand(i2s_port_t i2s_num, const void *src, size_t size, size_t src_bits, size_t aim_bits, size_t *bytes_written, TickType_t ticks_to_wait)

Write data to I2S DMA transmit buffer while expanding the number of bits per sample. For example, expanding 16-bit PCM to 32-bit PCM.

Format of the data in source buffer is determined by the I2S configuration (see

i2s_config_t).
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1
  • src: Source address to write from
  • size: Size of data in bytes
  • src_bits: Source audio bit
  • aim_bits: Bit wanted, no more than 32, and must be greater than src_bits
  • bytes_written: Number of bytes written, if timeout, the result will be less than the size passed in.
  • ticks_to_wait: TX buffer wait timeout in RTOS ticks. If this many ticks pass without space becoming available in the DMA transmit buffer, then the function will return (note that if the data is written to the DMA buffer in pieces, the overall operation may still take longer than this timeout.) Pass portMAX_DELAY for no timeout.

Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error

int i2s_read_bytes(i2s_port_t i2s_num, void *dest, size_t size, TickType_t ticks_to_wait)

Read data from I2S DMA receive buffer.

This function is deprecated. Use ‘i2s_read’ instead. This definition will be removed in a future release.

Return
  • The amount of bytes read, if timeout, bytes read will be less than the size passed in
  • ESP_FAIL Parameter error

esp_err_t i2s_read(i2s_port_t i2s_num, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait)

Read data from I2S DMA receive buffer.

Note
If the built-in ADC mode is enabled, we should call i2s_adc_start and i2s_adc_stop around the whole reading process, to prevent the data getting corrupted.
Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1
  • dest: Destination address to read into
  • size: Size of data in bytes
  • bytes_read: Number of bytes read, if timeout, bytes read will be less than the size passed in.
  • ticks_to_wait: RX buffer wait timeout in RTOS ticks. If this many ticks pass without bytes becoming available in the DMA receive buffer, then the function will return (note that if data is read from the DMA buffer in pieces, the overall operation may still take longer than this timeout.) Pass portMAX_DELAY for no timeout.

int i2s_push_sample(i2s_port_t i2s_num, const void *sample, TickType_t ticks_to_wait)

Write a single sample to the I2S DMA TX buffer.

This function is deprecated. Use ‘i2s_write’ instead. This definition will be removed in a future release.

Return
  • Number of bytes successfully pushed to DMA buffer, will be either zero or the size of configured sample buffer (in bytes).
  • ESP_FAIL Parameter error
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1
  • sample: Buffer to read data. Size of buffer (in bytes) = bits_per_sample / 8.
  • ticks_to_wait: Timeout in RTOS ticks. If a sample is not available in the DMA buffer within this period, no data is read and function returns zero.

int i2s_pop_sample(i2s_port_t i2s_num, void *sample, TickType_t ticks_to_wait)

Read a single sample from the I2S DMA RX buffer.

This function is deprecated. Use ‘i2s_read’ instead. This definition will be removed in a future release.

Return
  • Number of bytes successfully read from DMA buffer, will be either zero or the size of configured sample buffer (in bytes).
  • ESP_FAIL Parameter error
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1
  • sample: Buffer to write data. Size of buffer (in bytes) = bits_per_sample / 8.
  • ticks_to_wait: Timeout in RTOS ticks. If a sample is not available in the DMA buffer within this period, no data is read and function returns zero.

esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate)

Set sample rate used for I2S RX and TX.

The bit clock rate is determined by the sample rate and i2s_config_t configuration parameters (number of channels, bits_per_sample).

bit_clock = rate * (number of channels) * bits_per_sample

Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
  • ESP_ERR_NO_MEM Out of memory
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1
  • rate: I2S sample rate (ex: 8000, 44100…)

esp_err_t i2s_stop(i2s_port_t i2s_num)

Stop I2S driver.

Disables I2S TX/RX, until i2s_start() is called.

Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1

esp_err_t i2s_start(i2s_port_t i2s_num)

Start I2S driver.

It is not necessary to call this function after i2s_driver_install() (it is started automatically), however it is necessary to call it after i2s_stop().

Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1

esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num)

Zero the contents of the TX DMA buffer.

Pushes zero-byte samples into the TX DMA buffer, until it is full.

Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1

esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t bits, i2s_channel_t ch)

Set clock & bit width used for I2S RX and TX.

Similar to i2s_set_sample_rates(), but also sets bit width.

Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
  • ESP_ERR_NO_MEM Out of memory
Parameters
  • i2s_num: I2S_NUM_0, I2S_NUM_1
  • rate: I2S sample rate (ex: 8000, 44100…)
  • bits: I2S bit width (I2S_BITS_PER_SAMPLE_16BIT, I2S_BITS_PER_SAMPLE_24BIT, I2S_BITS_PER_SAMPLE_32BIT)
  • ch: I2S channel, (I2S_CHANNEL_MONO, I2S_CHANNEL_STEREO)

esp_err_t i2s_set_adc_mode(adc_unit_t adc_unit, adc1_channel_t adc_channel)

Set built-in ADC mode for I2S DMA, this function will initialize ADC pad, and set ADC parameters.

Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
Parameters
  • adc_unit: SAR ADC unit index
  • adc_channel: ADC channel index

esp_err_t i2s_adc_enable(i2s_port_t i2s_num)

Start to use I2S built-in ADC mode.

Note
This function would acquire the lock of ADC to prevent the data getting corrupted during the I2S peripheral is being used to do fully continuous ADC sampling.
Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
  • ESP_ERR_INVALID_STATE Driver state error
Parameters
  • i2s_num: i2s port index

esp_err_t i2s_adc_disable(i2s_port_t i2s_num)

Stop to use I2S built-in ADC mode.

Note
This function would release the lock of ADC so that other tasks can use ADC.
Return
  • ESP_OK Success
  • ESP_ERR_INVALID_ARG Parameter error
  • ESP_ERR_INVALID_STATE Driver state error
Parameters
  • i2s_num: i2s port index

Structures

struct i2s_config_t

I2S configuration parameters for i2s_param_config function.

Public Members

i2s_mode_t mode

I2S work mode

int sample_rate

I2S sample rate

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

int intr_alloc_flags

Flags used to allocate the interrupt. One or multiple (ORred) ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info

int dma_buf_count

I2S DMA Buffer Count

int dma_buf_len

I2S DMA Buffer Length

bool use_apll

I2S using APLL as main I2S clock, enable it to get accurate clock

bool tx_desc_auto_clear

I2S auto clear tx descriptor if there is underflow condition (helps in avoiding noise in case of data unavailability)

int fixed_mclk

I2S using fixed MCLK output. If use_apll = true and fixed_mclk > 0, then the clock output for i2s is fixed and equal to the fixed_mclk value.

struct i2s_event_t

Event structure used in I2S event queue.

Public Members

i2s_event_type_t type

I2S event type

size_t size

I2S data size for I2S_DATA event

struct i2s_pin_config_t

I2S pin number for i2s_set_pin.

Public Members

int bck_io_num

BCK in out pin

int ws_io_num

WS in out pin

int data_out_num

DATA out pin

int data_in_num

DATA in pin

Macros

I2S_PIN_NO_CHANGE

Use in i2s_pin_config_t for pins which should not be changed

Type Definitions

typedef intr_handle_t i2s_isr_handle_t

Enumerations

enum i2s_bits_per_sample_t

I2S bit width per sample.

Values:

I2S_BITS_PER_SAMPLE_8BIT = 8

I2S bits per sample: 8-bits

I2S_BITS_PER_SAMPLE_16BIT = 16

I2S bits per sample: 16-bits

I2S_BITS_PER_SAMPLE_24BIT = 24

I2S bits per sample: 24-bits

I2S_BITS_PER_SAMPLE_32BIT = 32

I2S bits per sample: 32-bits

enum i2s_channel_t

I2S channel.

Values:

I2S_CHANNEL_MONO = 1

I2S 1 channel (mono)

I2S_CHANNEL_STEREO = 2

I2S 2 channel (stereo)

enum i2s_comm_format_t

I2S communication standard format.

Values:

I2S_COMM_FORMAT_I2S = 0x01

I2S communication format I2S

I2S_COMM_FORMAT_I2S_MSB = 0x02

I2S format MSB

I2S_COMM_FORMAT_I2S_LSB = 0x04

I2S format LSB

I2S_COMM_FORMAT_PCM = 0x08

I2S communication format PCM

I2S_COMM_FORMAT_PCM_SHORT = 0x10

PCM Short

I2S_COMM_FORMAT_PCM_LONG = 0x20

PCM Long

enum i2s_channel_fmt_t

I2S channel format type.

Values:

I2S_CHANNEL_FMT_RIGHT_LEFT = 0x00
I2S_CHANNEL_FMT_ALL_RIGHT
I2S_CHANNEL_FMT_ALL_LEFT
I2S_CHANNEL_FMT_ONLY_RIGHT
I2S_CHANNEL_FMT_ONLY_LEFT
enum pdm_sample_rate_ratio_t

PDM sample rate ratio, measured in Hz.

Values:

PDM_SAMPLE_RATE_RATIO_64
PDM_SAMPLE_RATE_RATIO_128
enum pdm_pcm_conv_t

PDM PCM convter enable/disable.

Values:

PDM_PCM_CONV_ENABLE
PDM_PCM_CONV_DISABLE
enum i2s_port_t

I2S Peripheral, 0 & 1.

Values:

I2S_NUM_0 = 0x0

I2S 0

I2S_NUM_1 = 0x1

I2S 1

I2S_NUM_MAX
enum i2s_mode_t

I2S Mode, defaut is I2S_MODE_MASTER | I2S_MODE_TX.

Note
PDM and built-in DAC functions are only supported on I2S0 for current ESP32 chip.

Values:

I2S_MODE_MASTER = 1
I2S_MODE_SLAVE = 2
I2S_MODE_TX = 4
I2S_MODE_RX = 8
I2S_MODE_DAC_BUILT_IN = 16

Output I2S data to built-in DAC, no matter the data format is 16bit or 32 bit, the DAC module will only take the 8bits from MSB

I2S_MODE_ADC_BUILT_IN = 32

Input I2S data from built-in ADC, each data can be 12-bit width at most

I2S_MODE_PDM = 64
enum i2s_event_type_t

I2S event types.

Values:

I2S_EVENT_DMA_ERROR
I2S_EVENT_TX_DONE

I2S DMA finish sent 1 buffer

I2S_EVENT_RX_DONE

I2S DMA finish received 1 buffer

I2S_EVENT_MAX

I2S event max index

enum i2s_dac_mode_t

I2S DAC mode for i2s_set_dac_mode.

Note
PDM and built-in DAC functions are only supported on I2S0 for current ESP32 chip.

Values:

I2S_DAC_CHANNEL_DISABLE = 0

Disable I2S built-in DAC signals

I2S_DAC_CHANNEL_RIGHT_EN = 1

Enable I2S built-in DAC right channel, maps to DAC channel 1 on GPIO25

I2S_DAC_CHANNEL_LEFT_EN = 2

Enable I2S built-in DAC left channel, maps to DAC channel 2 on GPIO26

I2S_DAC_CHANNEL_BOTH_EN = 0x3

Enable both of the I2S built-in DAC channels.

I2S_DAC_CHANNEL_MAX = 0x4

I2S built-in DAC mode max index