I'm working with a ESP32S3 that will manage 2 I2S ports, so for the cleanness of my code and also because i'll work multiple I2S installations - deinstallations, i want to move all the functions to and ".cpp .h" file.

something like this

  1. I2S_functions.h

    #ifndef I2S_FUNCTIONS_H
    #define I2S_FUNCTIONS_H
    #include <Arduino.h>
    #include <driver/i2s.h>
    void i2s_install(i2s_port_t I2S_PORT, i2s_mode_t I2S_MODE, float I2S_SAMPLE_RATE,
    i2s_bits_per_sample_t I2S_SAMPLE_BITS,i2s_channel_fmt_t I2S_CHANNEL,i2s_comm_format_t I2S_COMM_FORMAT_STAND_I2S,int buf_count, int buf_len, bool apll);
  2. I2S_functions.cpp

#include "I2S_functions.h"

void i2s_install(i2s_port_t I2S_PORT, i2s_mode_t I2S_MODE, float I2S_SAMPLE_RATE,
i2s_bits_per_sample_t I2S_SAMPLE_BITS,i2s_channel_fmt_t I2S_CHANNEL,i2s_comm_format_t I2S_COMM_FORMAT_STAND_I2S,
int buf_count, int buf_len, bool apll)
  const i2s_config_t i2s_config = 
    .mode = I2S_MODE,
    //.mode = (i2s_mode_t)(I2S_MODE),
    .sample_rate = I2S_SAMPLE_RATE,
    .bits_per_sample = I2S_SAMPLE_BITS,
    .channel_format = I2S_CHANNEL,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S),
    .intr_alloc_flags = 0, // default interrupt priority
    .dma_buf_count = buf_count,//cambiado de 8 a 64
    .dma_buf_len = buf_len,
    .use_apll = apll

  i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
  1. main.ino
#include "I2S_functions.h"

// I2S config //////
#include <driver/i2s.h>

#define I2S_PORT I2S_NUM_0
//#define I2S_SAMPLE_RATE  (44100) 
float I2S_SAMPLE_RATE=44100;
//#define I2S_SAMPLE_BITS  (32)
#define bufferLen 1024
#define I2S_READ_LEN (16*1024)

void setup ()


But when i compile this, i got errors passing the second argument which is "I2S_MODE_MASTER|I2S_MODE_RX,I2S_SAMPLE_RATE"

a copy from the error:

C:\Users\.ino: In function 'void setup()':
test_10seg_V2:52:39: error: invalid conversion from 'int' to 'i2s_mode_t' [-fpermissive]
In file included from C:\Users\.ino:2:
C:\Users\I2S_functions.h:6:50: note:   initializing argument 2 of 'void i2s_install(i2s_port_t, i2s_mode_t, float, i2s_bits_per_sample_t, i2s_channel_fmt_t, i2s_comm_format_t, int, int, bool)'
 void i2s_install(i2s_port_t I2S_PORT, i2s_mode_t I2S_MODE, float I2S_SAMPLE_RATE,

exit status 1
invalid conversion from 'int' to 'i2s_mode_t' [-fpermissive]

Essentially i have 2 questions. While i looked in the github from the esp32 i found off that there is some typedef of the I2S config (https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/esp32/include/hal/include/hal/i2s_types.h). I've never worked with this type of structs before so i am guessing how should i use it and specially how should i pass this type of variables to a function.

typedef enum {
    I2S_BITS_PER_SAMPLE_8BIT    = 8,            /*!< data bit-width: 8 */
    I2S_BITS_PER_SAMPLE_16BIT   = 16,           /*!< data bit-width: 16 */
    I2S_BITS_PER_SAMPLE_24BIT   = 24,           /*!< data bit-width: 24 */
    I2S_BITS_PER_SAMPLE_32BIT   = 32,           /*!< data bit-width: 32 */
} i2s_bits_per_sample_t;

 * @brief I2S bit width per chan.
typedef enum {
    I2S_BITS_PER_CHAN_DEFAULT        = (0),      /*!< channel bit-width equals to data bit-width */
    I2S_BITS_PER_CHAN_8BIT           = (8),      /*!< channel bit-width: 8 */
    I2S_BITS_PER_CHAN_16BIT          = (16),     /*!< channel bit-width: 16 */
    I2S_BITS_PER_CHAN_24BIT          = (24),     /*!< channel bit-width: 24 */
    I2S_BITS_PER_CHAN_32BIT          = (32),     /*!< channel bit-width: 32 */
} i2s_bits_per_chan_t;

my questions are

1.- I would like to understand how this structs works. I want to clean my code the most that i could, and that mean passing a lot of functions out of the main file. So any resource is well welcome to improve my coding skill.

2.- Why the code fails passing this 2 variables "I2S_MODE_MASTER|I2S_MODE_RX" ?. Is there any special way of passing this variables when are 2 options at once?.

Thanks for your replies!


1 Answer 1


Answer to Question 1: The typedef code you posted is enum and not struct. Look up C++ Enumeration and you will find lots of good tutorials. Here is one video.

Answer to Question 2: You need to typecast the argument for your function to accept it as i2s_mode_t.

i2s_install(I2S_PORT, (i2s_mode_t)(I2S_MODE_MASTER|I2S_MODE_RX), ... ... ...);
  • i2s_mode_t it is an example of a very bad API design. it should never be an enum.
    – Juraj
    Jun 13, 2023 at 17:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.