2022-03-13 23:34:46 -04:00
/*
2023-01-31 01:36:21 -05:00
* SPDX - FileCopyrightText : 2022 - 2023 Espressif Systems ( Shanghai ) CO LTD
2022-03-13 23:34:46 -04:00
*
* SPDX - License - Identifier : Apache - 2.0
*/
/**
* This file is specified for I2S standard communication mode
* Features :
2022-11-17 22:00:13 -05:00
* - Philips / MSB / PCM are supported in standard mode
2022-03-13 23:34:46 -04:00
* - Fixed to 2 slots
*/
# pragma once
# include "hal/i2s_types.h"
2021-08-18 07:45:51 -04:00
# include "hal/gpio_types.h"
2022-04-02 09:31:35 -04:00
# include "driver/i2s_common.h"
2022-03-13 23:34:46 -04:00
2022-07-04 23:22:27 -04:00
# include "sdkconfig.h"
2022-03-13 23:34:46 -04:00
# ifdef __cplusplus
extern " C " {
# endif
2022-07-04 23:22:27 -04:00
# if CONFIG_IDF_TARGET_ESP32
/**
2022-11-17 22:00:13 -05:00
* @ brief Philips format in 2 slots
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width
2022-07-04 23:22:27 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
2022-11-17 22:00:13 -05:00
# define I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
2022-07-04 23:22:27 -04:00
. data_bit_width = bits_per_sample , \
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
. slot_mode = mono_or_stereo , \
. slot_mask = ( mono_or_stereo = = I2S_SLOT_MODE_MONO ) ? \
I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH , \
. ws_width = bits_per_sample , \
. ws_pol = false , \
. bit_shift = true , \
. msb_right = ( bits_per_sample < = I2S_DATA_BIT_WIDTH_16BIT ) ? \
true : false , \
}
/**
* @ brief PCM ( short ) format in 2 slots
2023-10-10 21:38:28 -04:00
* @ note PCM ( long ) is same as Philips in 2 slots
* @ param bits_per_sample I2S data bit width
2022-07-04 23:22:27 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
. slot_mode = mono_or_stereo , \
. slot_mask = ( mono_or_stereo = = I2S_SLOT_MODE_MONO ) ? \
I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH , \
. ws_width = 1 , \
. ws_pol = true , \
. bit_shift = true , \
. msb_right = ( bits_per_sample < = I2S_DATA_BIT_WIDTH_16BIT ) ? \
true : false , \
}
/**
* @ brief MSB format in 2 slots
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width
2022-07-04 23:22:27 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
. slot_mode = mono_or_stereo , \
. slot_mask = ( mono_or_stereo = = I2S_SLOT_MODE_MONO ) ? \
I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH , \
. ws_width = bits_per_sample , \
. ws_pol = false , \
. bit_shift = false , \
. msb_right = ( bits_per_sample < = I2S_DATA_BIT_WIDTH_16BIT ) ? \
true : false , \
}
# elif CONFIG_IDF_TARGET_ESP32S2
2022-03-13 23:34:46 -04:00
/**
2022-11-17 22:00:13 -05:00
* @ brief Philips format in 2 slots
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width
2022-03-13 23:34:46 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
2022-11-17 22:00:13 -05:00
# define I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
2022-03-13 23:34:46 -04:00
. data_bit_width = bits_per_sample , \
2021-08-18 07:45:51 -04:00
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
2022-03-13 23:34:46 -04:00
. slot_mode = mono_or_stereo , \
2022-04-07 03:32:46 -04:00
. slot_mask = ( mono_or_stereo = = I2S_SLOT_MODE_MONO ) ? \
2022-07-04 23:22:27 -04:00
I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH , \
2022-03-13 23:34:46 -04:00
. ws_width = bits_per_sample , \
. ws_pol = false , \
. bit_shift = true , \
2022-04-07 03:32:46 -04:00
. msb_right = true , \
2022-03-13 23:34:46 -04:00
}
/**
* @ brief PCM ( short ) format in 2 slots
2023-10-10 21:38:28 -04:00
* @ note PCM ( long ) is same as Philips in 2 slots
* @ param bits_per_sample I2S data bit width
2022-03-13 23:34:46 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
2021-08-18 07:45:51 -04:00
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
2022-03-13 23:34:46 -04:00
. slot_mode = mono_or_stereo , \
2022-04-07 03:32:46 -04:00
. slot_mask = ( mono_or_stereo = = I2S_SLOT_MODE_MONO ) ? \
2022-07-04 23:22:27 -04:00
I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH , \
2022-03-13 23:34:46 -04:00
. ws_width = 1 , \
. ws_pol = true , \
. bit_shift = true , \
2022-04-07 03:32:46 -04:00
. msb_right = true , \
2022-03-13 23:34:46 -04:00
}
/**
* @ brief MSB format in 2 slots
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width
2022-03-13 23:34:46 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
2021-08-18 07:45:51 -04:00
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
2022-03-13 23:34:46 -04:00
. slot_mode = mono_or_stereo , \
2022-04-07 03:32:46 -04:00
. slot_mask = ( mono_or_stereo = = I2S_SLOT_MODE_MONO ) ? \
2022-07-04 23:22:27 -04:00
I2S_STD_SLOT_LEFT : I2S_STD_SLOT_BOTH , \
2022-03-13 23:34:46 -04:00
. ws_width = bits_per_sample , \
. ws_pol = false , \
. bit_shift = false , \
2022-04-07 03:32:46 -04:00
. msb_right = true , \
2022-03-13 23:34:46 -04:00
}
# else
/**
2022-11-17 22:00:13 -05:00
* @ brief Philips format in 2 slots
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width
2022-03-13 23:34:46 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
2022-11-17 22:00:13 -05:00
# define I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
2022-03-13 23:34:46 -04:00
. data_bit_width = bits_per_sample , \
2021-08-18 07:45:51 -04:00
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
2022-03-13 23:34:46 -04:00
. slot_mode = mono_or_stereo , \
2022-07-04 23:22:27 -04:00
. slot_mask = I2S_STD_SLOT_BOTH , \
2022-03-13 23:34:46 -04:00
. ws_width = bits_per_sample , \
. ws_pol = false , \
. bit_shift = true , \
2023-04-27 00:30:49 -04:00
. left_align = true , \
2022-03-13 23:34:46 -04:00
. big_endian = false , \
. bit_order_lsb = false \
}
/**
* @ brief PCM ( short ) format in 2 slots
2023-10-10 21:38:28 -04:00
* @ note PCM ( long ) is same as Philips in 2 slots
* @ param bits_per_sample I2S data bit width
2022-03-13 23:34:46 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
2021-08-18 07:45:51 -04:00
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
2022-03-13 23:34:46 -04:00
. slot_mode = mono_or_stereo , \
2022-07-04 23:22:27 -04:00
. slot_mask = I2S_STD_SLOT_BOTH , \
2022-03-13 23:34:46 -04:00
. ws_width = 1 , \
. ws_pol = true , \
. bit_shift = true , \
2023-04-27 00:30:49 -04:00
. left_align = true , \
2022-03-13 23:34:46 -04:00
. big_endian = false , \
. bit_order_lsb = false \
}
/**
* @ brief MSB format in 2 slots
2023-10-10 21:38:28 -04:00
* @ param bits_per_sample I2S data bit width
2022-03-13 23:34:46 -04:00
* @ param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
*/
# define I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \
. data_bit_width = bits_per_sample , \
2021-08-18 07:45:51 -04:00
. slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO , \
2022-03-13 23:34:46 -04:00
. slot_mode = mono_or_stereo , \
2022-07-04 23:22:27 -04:00
. slot_mask = I2S_STD_SLOT_BOTH , \
2022-03-13 23:34:46 -04:00
. ws_width = bits_per_sample , \
. ws_pol = false , \
. bit_shift = false , \
2023-04-27 00:30:49 -04:00
. left_align = true , \
2022-03-13 23:34:46 -04:00
. big_endian = false , \
. bit_order_lsb = false \
}
# endif
2022-11-17 22:00:13 -05:00
/** @cond */
# define I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) \
I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG ( bits_per_sample , mono_or_stereo ) // Alias
/** @endcond */
2022-03-13 23:34:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S default standard clock configuration
2022-03-13 23:34:46 -04:00
* @ note Please set the mclk_multiple to I2S_MCLK_MULTIPLE_384 while using 24 bits data width
2023-10-10 21:38:28 -04:00
* Otherwise the sample rate might be imprecise since the BCLK division is not a integer
2022-03-13 23:34:46 -04:00
* @ param rate sample rate
*/
# define I2S_STD_CLK_DEFAULT_CONFIG(rate) { \
. sample_rate_hz = rate , \
2022-04-07 03:32:46 -04:00
. clk_src = I2S_CLK_SRC_DEFAULT , \
2022-03-13 23:34:46 -04:00
. mclk_multiple = I2S_MCLK_MULTIPLE_256 , \
}
/**
2022-04-07 03:32:46 -04:00
* @ brief I2S slot configuration for standard mode
2022-03-13 23:34:46 -04:00
*/
typedef struct {
/* General fields */
i2s_data_bit_width_t data_bit_width ; /*!< I2S sample data bit width (valid data bits per sample) */
i2s_slot_bit_width_t slot_bit_width ; /*!< I2S slot bit width (total bits per slot) */
2022-07-04 23:22:27 -04:00
i2s_slot_mode_t slot_mode ; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
* In TX direction , mono means the written buffer contains only one slot data
* and stereo means the written buffer contains both left and right data
*/
2022-03-13 23:34:46 -04:00
/* Particular fields */
2022-04-07 03:32:46 -04:00
i2s_std_slot_mask_t slot_mask ; /*!< Select the left, right or both slot */
2023-10-10 21:38:28 -04:00
uint32_t ws_width ; /*!< WS signal width (i.e. the number of BCLK ticks that WS signal is high) */
2022-03-13 23:34:46 -04:00
bool ws_pol ; /*!< WS signal polarity, set true to enable high lever first */
2022-11-17 22:00:13 -05:00
bool bit_shift ; /*!< Set to enable bit shift in Philips mode */
2022-03-13 23:34:46 -04:00
# if SOC_I2S_HW_VERSION_1 // For esp32/esp32-s2
bool msb_right ; /*!< Set to place right channel data at the MSB in the FIFO */
# else
bool left_align ; /*!< Set to enable left alignment */
bool big_endian ; /*!< Set to enable big endian */
bool bit_order_lsb ; /*!< Set to enable lsb first */
# endif
} i2s_std_slot_config_t ;
/**
2022-04-07 03:32:46 -04:00
* @ brief I2S clock configuration for standard mode
2022-03-13 23:34:46 -04:00
*/
typedef struct {
/* General fields */
uint32_t sample_rate_hz ; /*!< I2S sample rate */
2023-10-10 21:38:28 -04:00
i2s_clock_src_t clk_src ; /*!< Choose clock source, see `soc_periph_i2s_clk_src_t` for the supported clock sources.
* selected ` I2S_CLK_SRC_EXTERNAL ` ( if supports ) to enable the external source clock input via MCLK pin ,
2023-07-20 05:00:48 -04:00
*/
# if SOC_I2S_HW_VERSION_2
2023-10-10 21:38:28 -04:00
uint32_t ext_clk_freq_hz ; /*!< External clock source frequency in Hz, only take effect when `clk_src = I2S_CLK_SRC_EXTERNAL`, otherwise this field will be ignored,
* Please make sure the frequency input is equal or greater than BCLK , i . e . ` sample_rate_hz * slot_bits * 2 `
2023-07-20 05:00:48 -04:00
*/
# endif
2023-10-10 21:38:28 -04:00
i2s_mclk_multiple_t mclk_multiple ; /*!< The multiple of MCLK to the sample rate
2022-07-04 23:22:27 -04:00
* Default is 256 in the helper macro , it can satisfy most of cases ,
2023-10-10 21:38:28 -04:00
* but please set this field a multiple of ` 3 ` ( like 384 ) when using 24 - bit data width ,
2022-07-04 23:22:27 -04:00
* otherwise the sample rate might be inaccurate
*/
2022-03-13 23:34:46 -04:00
} i2s_std_clk_config_t ;
2021-08-18 07:45:51 -04:00
/**
* @ brief I2S standard mode GPIO pins configuration
*/
typedef struct {
2023-10-11 11:00:32 -04:00
gpio_num_t mclk ; /*!< MCK pin, output by default, input if the clock source is selected to `I2S_CLK_SRC_EXTERNAL` */
gpio_num_t bclk ; /*!< BCK pin, input in slave role, output in master role */
gpio_num_t ws ; /*!< WS pin, input in slave role, output in master role */
2021-08-18 07:45:51 -04:00
gpio_num_t dout ; /*!< DATA pin, output */
gpio_num_t din ; /*!< DATA pin, input */
2022-04-07 03:32:46 -04:00
struct {
2023-10-11 11:00:32 -04:00
uint32_t mclk_inv : 1 ; /*!< Set 1 to invert the MCLK input/output */
2023-10-10 21:38:28 -04:00
uint32_t bclk_inv : 1 ; /*!< Set 1 to invert the BCLK input/output */
uint32_t ws_inv : 1 ; /*!< Set 1 to invert the WS input/output */
2022-04-07 03:32:46 -04:00
} invert_flags ; /*!< GPIO pin invert flags */
2021-08-18 07:45:51 -04:00
} i2s_std_gpio_config_t ;
2022-04-07 03:32:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief I2S standard mode major configuration that including clock / slot / GPIO configuration
2022-04-07 03:32:46 -04:00
*/
2021-08-18 07:45:51 -04:00
typedef struct {
2022-04-07 03:32:46 -04:00
i2s_std_clk_config_t clk_cfg ; /*!< Standard mode clock configuration, can be generated by macro I2S_STD_CLK_DEFAULT_CONFIG */
2022-11-17 22:00:13 -05:00
i2s_std_slot_config_t slot_cfg ; /*!< Standard mode slot configuration, can be generated by macros I2S_STD_[mode]_SLOT_DEFAULT_CONFIG, [mode] can be replaced with PHILIPS/MSB/PCM */
2023-10-10 21:38:28 -04:00
i2s_std_gpio_config_t gpio_cfg ; /*!< Standard mode GPIO configuration, specified by user */
2021-08-18 07:45:51 -04:00
} i2s_std_config_t ;
2022-04-07 03:32:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief Initialize I2S channel to standard mode
2022-04-07 03:32:46 -04:00
* @ note Only allowed to be called when the channel state is REGISTERED , ( i . e . , channel has been allocated , but not initialized )
* and the state will be updated to READY if initialization success , otherwise the state will return to REGISTERED .
*
* @ param [ in ] handle I2S channel handler
2023-10-10 21:38:28 -04:00
* @ param [ in ] std_cfg Configurations for standard mode , including clock , slot and GPIO
2022-04-07 03:32:46 -04:00
* The clock configuration can be generated by the helper macro ` I2S_STD_CLK_DEFAULT_CONFIG `
2022-11-17 22:00:13 -05:00
* The slot configuration can be generated by the helper macro ` I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG ` ,
2022-04-07 03:32:46 -04:00
* ` I2S_STD_PCM_SLOT_DEFAULT_CONFIG ` or ` I2S_STD_MSB_SLOT_DEFAULT_CONFIG `
*
* @ return
* - ESP_OK Initialize successfully
* - ESP_ERR_NO_MEM No memory for storing the channel information
* - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration
* - ESP_ERR_INVALID_STATE This channel is not registered
*/
esp_err_t i2s_channel_init_std_mode ( i2s_chan_handle_t handle , const i2s_std_config_t * std_cfg ) ;
2021-08-18 07:45:51 -04:00
2022-04-07 03:32:46 -04:00
/**
* @ brief Reconfigure the I2S clock for standard mode
* @ note Only allowed to be called when the channel state is READY , i . e . , channel has been initialized , but not started
2023-10-10 21:38:28 -04:00
* this function won ' t change the state . ` i2s_channel_disable ` should be called before calling this function if I2S has started .
* @ note The input channel handle has to be initialized to standard mode , i . e . , ` i2s_channel_init_std_mode ` has been called before reconfiguring
2022-04-07 03:32:46 -04:00
*
* @ param [ in ] handle I2S channel handler
* @ param [ in ] clk_cfg Standard mode clock configuration , can be generated by ` I2S_STD_CLK_DEFAULT_CONFIG `
* @ return
* - ESP_OK Set clock successfully
* - ESP_ERR_INVALID_ARG NULL pointer , invalid configuration or not standard mode
* - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
*/
esp_err_t i2s_channel_reconfig_std_clock ( i2s_chan_handle_t handle , const i2s_std_clk_config_t * clk_cfg ) ;
2021-08-18 07:45:51 -04:00
2022-04-07 03:32:46 -04:00
/**
* @ brief Reconfigure the I2S slot for standard mode
* @ note Only allowed to be called when the channel state is READY , i . e . , channel has been initialized , but not started
2023-10-10 21:38:28 -04:00
* this function won ' t change the state . ` i2s_channel_disable ` should be called before calling this function if I2S has started .
* @ note The input channel handle has to be initialized to standard mode , i . e . , ` i2s_channel_init_std_mode ` has been called before reconfiguring
2022-04-07 03:32:46 -04:00
*
* @ param [ in ] handle I2S channel handler
2022-11-17 22:00:13 -05:00
* @ param [ in ] slot_cfg Standard mode slot configuration , can be generated by ` I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG ` ,
2022-04-07 03:32:46 -04:00
* ` I2S_STD_PCM_SLOT_DEFAULT_CONFIG ` and ` I2S_STD_MSB_SLOT_DEFAULT_CONFIG ` .
* @ return
* - ESP_OK Set clock successfully
* - ESP_ERR_NO_MEM No memory for DMA buffer
* - ESP_ERR_INVALID_ARG NULL pointer , invalid configuration or not standard mode
* - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
*/
esp_err_t i2s_channel_reconfig_std_slot ( i2s_chan_handle_t handle , const i2s_std_slot_config_t * slot_cfg ) ;
2021-08-18 07:45:51 -04:00
2022-04-07 03:32:46 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief Reconfigure the I2S GPIO for standard mode
2022-04-07 03:32:46 -04:00
* @ note Only allowed to be called when the channel state is READY , i . e . , channel has been initialized , but not started
2023-10-10 21:38:28 -04:00
* this function won ' t change the state . ` i2s_channel_disable ` should be called before calling this function if I2S has started .
* @ note The input channel handle has to be initialized to standard mode , i . e . , ` i2s_channel_init_std_mode ` has been called before reconfiguring
2022-04-07 03:32:46 -04:00
*
* @ param [ in ] handle I2S channel handler
2023-10-10 21:38:28 -04:00
* @ param [ in ] gpio_cfg Standard mode GPIO configuration , specified by user
2022-04-07 03:32:46 -04:00
* @ return
* - ESP_OK Set clock successfully
* - ESP_ERR_INVALID_ARG NULL pointer , invalid configuration or not standard mode
* - ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
*/
esp_err_t i2s_channel_reconfig_std_gpio ( i2s_chan_handle_t handle , const i2s_std_gpio_config_t * gpio_cfg ) ;
2021-08-18 07:45:51 -04:00
2022-03-13 23:34:46 -04:00
# ifdef __cplusplus
}
# endif