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
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); #endif
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);
}
- 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;
int I2S_SAMPLE_BITS=32;
//#define I2S_SAMPLE_BITS (32)
#define bufferLen 1024
#define I2S_READ_LEN (16*1024)
void setup ()
{
i2s_install(I2S_PORT,I2S_MODE_MASTER|I2S_MODE_RX,I2S_SAMPLE_RATE,
I2S_BITS_PER_SAMPLE_32BIT,I2S_CHANNEL_FMT_ONLY_LEFT,I2S_COMM_FORMAT_STAND_I2S,8,bufferLen,false);
}
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]
i2s_install(I2S_PORT,I2S_MODE_MASTER|I2S_MODE_RX,I2S_SAMPLE_RATE,
~~~~~~~~~~~~~~~^~~~~~~~~~~~
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!
-
2this is more a general C++ programming question, than it is an Arduino questionjsotola– jsotola2023年06月13日 01:02:17 +00:00Commented Jun 13, 2023 at 1:02
-
en.wikipedia.org/wiki/Enumerated_typeJuraj– Juraj ♦2023年06月13日 04:48:45 +00:00Commented Jun 13, 2023 at 4:48
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.2023年06月13日 17:34:18 +00:00Commented Jun 13, 2023 at 17:34