Skip to content

Commit

Permalink
refactor(i2s): add hal i2s driver
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongyumail committed Nov 19, 2019
1 parent a74988a commit 8c76a3c
Show file tree
Hide file tree
Showing 14 changed files with 2,530 additions and 447 deletions.
337 changes: 72 additions & 265 deletions components/driver/i2s.c

Large diffs are not rendered by default.

181 changes: 6 additions & 175 deletions components/driver/include/driver/i2s.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,198 +12,31 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef _DRIVER_I2S_H_
#define _DRIVER_I2S_H_
#pragma once

#include "esp_err.h"
#include <esp_types.h>
#include "soc/soc.h"
#include "soc/gpio_periph.h"
#include "soc/i2s_periph.h"
#include "soc/rtc_periph.h"
#include "soc/i2s_caps.h"
#include "esp32/rom/gpio.h"
#include "esp_attr.h"
#include "esp_intr_alloc.h"
#include "driver/periph_ctrl.h"
#include "driver/adc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "hal/i2s_hal.h"
#include "hal/i2s_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief I2S bit width per sample.
*
*/
typedef enum {
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*/
} i2s_bits_per_sample_t;

/**
* @brief I2S channel.
*
*/
typedef enum {
I2S_CHANNEL_MONO = 1, /*!< I2S 1 channel (mono)*/
I2S_CHANNEL_STEREO = 2 /*!< I2S 2 channel (stereo)*/
} i2s_channel_t;

/**
* @brief I2S communication standard format
*
*/
typedef enum {
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*/
} i2s_comm_format_t;


/**
* @brief I2S channel format type
*/
typedef enum {
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,
} i2s_channel_fmt_t;

/**
* @brief PDM sample rate ratio, measured in Hz.
*
*/
typedef enum {
PDM_SAMPLE_RATE_RATIO_64,
PDM_SAMPLE_RATE_RATIO_128,
} pdm_sample_rate_ratio_t;

/**
* @brief PDM PCM convter enable/disable.
*
*/
typedef enum {
PDM_PCM_CONV_ENABLE,
PDM_PCM_CONV_DISABLE,
} pdm_pcm_conv_t;


/**
* @brief I2S Peripheral, 0 & 1.
*
*/
typedef enum {
I2S_NUM_0 = 0x0, /*!< I2S 0*/
#if SOC_I2S_PERIPH_NUM > 1
I2S_NUM_1, /*!< I2S 1*/
#endif
I2S_NUM_MAX,
} i2s_port_t;

/**
* @brief 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.
*
*/
typedef enum {
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*/
#if SOC_I2S_SUPPORT_PDM
I2S_MODE_PDM = 64,
#endif
} i2s_mode_t;



/**
* @brief I2S configuration parameters for i2s_param_config function
*
*/
typedef struct {
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.*/
} i2s_config_t;

/**
* @brief I2S event types
*
*/
typedef enum {
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*/
} i2s_event_type_t;

/**
* @brief I2S DAC mode for i2s_set_dac_mode.
*
* @note PDM and built-in DAC functions are only supported on I2S0 for current ESP32 chip.
*/
typedef enum {
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*/
} i2s_dac_mode_t;

/**
* @brief Event structure used in I2S event queue
*
*/
typedef struct {
i2s_event_type_t type; /*!< I2S event type */
size_t size; /*!< I2S data size for I2S_DATA event*/
} i2s_event_t;

#define I2S_PIN_NO_CHANGE (-1) /*!< Use in i2s_pin_config_t for pins which should not be changed */

/**
* @brief I2S pin number for i2s_set_pin
*
*/
typedef struct {
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*/
} i2s_pin_config_t;

#if SOC_I2S_SUPPORT_PDM
/**
* @brief I2S PDM RX downsample mode
*/
typedef enum {
I2S_PDM_DSR_8S = 0, /*!< downsampling number is 8 for PDM RX mode*/
I2S_PDM_DSR_16S, /*!< downsampling number is 16 for PDM RX mode*/
I2S_PDM_DSR_MAX,
} i2s_pdm_dsr_t;
#endif

typedef intr_handle_t i2s_isr_handle_t;

/**
* @brief Set I2S pin number
*
Expand Down Expand Up @@ -498,5 +331,3 @@ esp_err_t i2s_adc_disable(i2s_port_t i2s_num);
#ifdef __cplusplus
}
#endif

#endif /* _DRIVER_I2S_H_ */
1 change: 1 addition & 0 deletions components/soc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ list(APPEND srcs
"src/hal/spi_slave_hal_iram.c"
"src/soc_include_legacy_warn.c"
"src/hal/pcnt_hal.c"
"src/hal/i2s_hal.c"
)

# TODO: SPI Flash HAL for ESP32S2Beta also
Expand Down
2 changes: 1 addition & 1 deletion components/soc/esp32/i2s_periph.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
/*
Bunch of constants for every I2S peripheral: GPIO signals, irqs, hw addr of registers etc
*/
const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_PERIPH_NUM] = {
const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
{
.o_bck_in_sig = I2S0O_BCK_IN_IDX,
.o_ws_in_sig = I2S0O_WS_IN_IDX,
Expand Down
Loading

0 comments on commit 8c76a3c

Please sign in to comment.