Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using i2s example fails build #631

Closed
pablo-mendoza opened this issue Sep 12, 2017 · 12 comments
Closed

Using i2s example fails build #631

pablo-mendoza opened this issue Sep 12, 2017 · 12 comments
Labels
Status: Stale Issue is stale stage (outdated/stuck)

Comments

@pablo-mendoza
Copy link

pablo-mendoza commented Sep 12, 2017

I can't build the i2s example code. If I change in i2s.h:

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 */
} i2s_config_t;

i2s_mode_t and i2s_comm_format_t to int. Then it builds and works.

Hardware:

Board: ESP32 Dev Module
Core Installation/update date: 12/Sep/2017
IDE name: Arduino IDE 1.8.3

Description:

Describe your problem here

Sketch:

#include "driver/i2s.h"

static const i2s_config_t i2s_config = {
     .mode = I2S_MODE_MASTER | I2S_MODE_TX,
     .sample_rate = 48000,
     .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
     .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //I2S_CHANNEL_FMT_RIGHT_LEFT,
     .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
     .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // high interrupt priority
     .dma_buf_count = 6,
     .dma_buf_len = 512
};

void setup() {
}

void loop() {
}

Debug Messages:


"C:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-g++" -DESP_PLATFORM -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DHAVE_CONFIG_H "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/config" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/bluedroid" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/app_trace" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/app_update" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/bootloader_support" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/bt" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/driver" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/esp32" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/ethernet" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/fatfs" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/freertos" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/heap" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/jsmn" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/log" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/mdns" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/mbedtls" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/mbedtls_port" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/newlib" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/nvs_flash" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/openssl" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/soc" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/spi_flash" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/sdmmc" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/tcpip_adapter" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/ulp" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/vfs" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/wear_levelling" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/xtensa-debug-module" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/newlib" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/coap" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/wpa_supplicant" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/expat" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/json" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/nghttp" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/lwip" -std=gnu++11 -fno-exceptions -fno-rtti -Os -g3 -Wpointer-arith -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib -Wall -Werror=all -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -fno-rtti -MMD -c -DF_CPU=240000000L -DARDUINO=10803 -DARDUINO_ESP32_DEV -DARDUINO_ARCH_ESP32  -DESP32 -DCORE_DEBUG_LEVEL=0 "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32\cores\esp32" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32\variants\esp32" "-IC:\Users\jpmendoza\Documents\Arduino\libraries\SGTL5000" "-IC:\Users\jpmendoza\Documents\Arduino\hardware\espressif\esp32\libraries\Wire\src" "C:\Users\JPMEND~1\AppData\Local\Temp\arduino_build_937948\sketch\SDMMC_Test.ino.cpp" -o "C:\Users\JPMEND~1\AppData\Local\Temp\arduino_build_937948\sketch\SDMMC_Test.ino.cpp.o"
SDMMC_Test:37: error: invalid conversion from 'int' to 'i2s_mode_t' [-fpermissive]

 };

 ^

SDMMC_Test:37: error: invalid conversion from 'int' to 'i2s_comm_format_t' [-fpermissive]

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

@Splediferous
Copy link

I had the "i2s_mode_t" and "i2s_port_t" with this error too (using VS Code). The reason is the same for both - strict typing.

The "i2s_port_t" is caused by the definition in the Espressif reference example:
static const i2s_port_t i2s_num = 0; // i2s port number

Which is fixed by using the enumerated type (i2s_port_t) for port 0:
static const i2s_port_t i2s_num = I2S_NUM_0; // i2s port number

Mode is defined as an enum within the "i2s_config_t" structure and it will only compile, as is, with the permissive flag. Unless this flag is set one cannot combine the mode flags into a bit-field (hence the "int" which is the result of ORing multiple enums).
Either the mode field of "i2s_config_t should be an uint type to take a bit-field or one should only use one enumerated option. [I consider using fpermissive as an anti-pattern.]

@me-no-dev
Copy link
Member

@riataman did you try the extern C thing?

@pablo-mendoza
Copy link
Author

I did and it failed with the same error. A standard c cast (.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX)), didn't work either.

What worked at the end was this:

static const i2s_config_t i2s_config = {
  .mode = static_cast<i2s_mode_t>(I2S_MODE_MASTER | I2S_MODE_TX),
  .sample_rate = 44100,
  .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
  .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
  .communication_format = static_cast<i2s_comm_format_t>(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
  .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // high interrupt priority
  .dma_buf_count = 3,
  .dma_buf_len = 512
};

@Splediferous
Copy link

Splediferous commented Sep 18, 2017

.mode = static_cast<i2s_mode_t>(I2S_MODE_MASTER | I2S_MODE_TX),

That equates to 5 which is not a valid (unscoped) enumeration (can be 1,2,4,8.16 or 64)

.communication_format = static_cast<i2s_comm_format_t>(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),

That equates to 3 which is also not a valid (unscoped) enumeration (can be 1,2,4,8,16 or 32)

Casting rules
Unscoped enum constants can be implicitly converted to int, but an int is never implicitly convertible to an enum value.

source

As you have shown, it must be explicitly cast to circumvent the typing system. This should not be required and is a code smell.

@andre-stefanov
Copy link

andre-stefanov commented Aug 3, 2018

Until the issue is fixed, i use following template:

template<typename Enum>  
Enum operator |(Enum lhs, Enum rhs)  
{
    return static_cast<Enum> (lhs | rhs);
} 

This way i can use the code from esp32 example as it is:

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
};

@Cheaternl
Copy link

This example code from espidf cannot be plain copied to C++ code.
I solved this by copying the example code in a separate .c file (accompanied with a .h file) and declared a function in the .c file which does the talking to i2s.

@lbernstone
Copy link
Contributor

This is an ancient, abandoned issue. There is now an example that demonstrates how to cast the field.

@Cheaternl
Copy link

Tnx @lbernstone !!
However, how would one know that the well maintained repository https://github.com/espressif/esp-idf (which is recommended framework?!) contains examples that are 'not suitable for the job' ? Or am I confused about what the recommended framework is for ESP32 programming? Thought that Arduino framework was kinda 'nahh' ?

@lbernstone
Copy link
Contributor

The examples in that repository work fine. They will not work with arduino; many are straight up incompatible with C++ without significant modifications.
The esp-idf framework is an official framework supported by espressif staff, for use with gcc. arduino-esp32 is community supported (with a lot of help from a single espressif employee).

@stale
Copy link

stale bot commented Sep 14, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Status: Stale Issue is stale stage (outdated/stuck) label Sep 14, 2019
@stale
Copy link

stale bot commented Sep 28, 2019

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.

@stale stale bot closed this as completed Sep 28, 2019
@Sivapraveen-Entuple
Copy link

U can typecast those to fix the error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Stale Issue is stale stage (outdated/stuck)
Projects
None yet
Development

No branches or pull requests

7 participants