Using ESP-IDF examples in Arduino IDE

I am using Espressif ESP32S2 DevKitM-1 in Arduino IDE. I need to use a CPP example that came with ESP-IDF (specifically sdmmc example under esp-idf\examples\storage\sd_card\sdmmc).

it works just fine in VSCode but compilation fails in Arduino IDE. I can see it loading libraries which do contain all the definitions in the headers but still IDE complains "'SDMMC_HOST_DEFAULT' was not declared in this scope"

I need to do this project in Arduino IDE because I already have a working code I need to add to. I also tried to Import Arduino .ino into VSC using Platformio but that struggles with include libraries and even simple delay() functions. in short, after many many hours, ive given up trying to move my project to VSC. So now I am left with trying to bring the .CPP to Arduino IDE.

Any help is much appreciated.

Thank you

Val

Welcome to the forums. If you post your code here, you will increase your chances of assistance dramatically. Please take a moment to read the sticky post at the top of the forum about how to do so, along with lots of other good information to maximize the help

1 Like

Are you sure the ESP32S2 supports SDMMC host? SOC_SDMMC_HOST_SUPPORTED is not defined in https://github.com/espressif/esp-idf/blob/master/components/soc/esp32s2/include/soc/soc_caps.h, so the SDMMC code is disabled here:

It seems to be supported on the ESP32 and ESP32S3 only.

1 Like

I have experimented with about 85% of the ESP32's API. I found most but not all of the ESP32 API's work in the Arduino IDE. The biggest trick is that the configuration structures are defined and used in the Arduino IDE a bit differently than with using the ESPRESSIF IDE thingy.

Pieter, Thank you for this!

I did change to SPI and made some progress but still getting errors...different Errors :slight_smile:

:\esp\esp-idf\examples\storage\sd_card\sdspi\main\sd_card_example_main\sd_card_example_main.ino: In function 'void app_main()':
sd_card_example_main:85:35: error: invalid conversion from 'int' to 'spi_host_device_t' [-fpermissive]
     ret = spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CHAN);
                              ~~~~~^~~~
In file included from C:\Users\Val V\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0-rc1/tools/sdk/esp32s2/include/driver/include/driver/spi_master.h:12,
                 from C:\Users\Val V\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0-rc1/tools/sdk/esp32s2/include/driver/include/driver/sdspi_host.h:14,
                 from C:\Users\Val V\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0-rc1/tools/sdk/esp32s2/include/fatfs/vfs/esp_vfs_fat.h:20,
                 from D:\esp\esp-idf\examples\storage\sd_card\sdspi\main\sd_card_example_main\sd_card_example_main.ino:14:
C:\Users\Val V\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0-rc1/tools/sdk/esp32s2/include/driver/include/driver/spi_common.h:139:48: note:   initializing argument 1 of 'esp_err_t spi_bus_initialize(spi_host_device_t, const spi_bus_config_t*, spi_dma_chan_t)'
 esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t *bus_config, spi_dma_chan_t dma_chan);
                              ~~~~~~~~~~~~~~~~~~^~~~~~~
sd_card_example_main:27:22: error: invalid conversion from 'int' to 'gpio_num_t' [-fpermissive]
 #define PIN_NUM_CS   13
                      ^~
D:\esp\esp-idf\examples\storage\sd_card\sdspi\main\sd_card_example_main\sd_card_example_main.ino:94:27: note: in expansion of macro 'PIN_NUM_CS'
     slot_config.gpio_cs = PIN_NUM_CS;
                           ^~~~~~~~~~
sd_card_example_main:95:32: error: invalid conversion from 'int' to 'spi_host_device_t' [-fpermissive]
     slot_config.host_id = host.slot;
                           ~~~~~^~~~
sd_card_example_main:169:23: error: invalid conversion from 'int' to 'spi_host_device_t' [-fpermissive]
     spi_bus_free(host.slot);
                  ~~~~~^~~~
In file included from C:\Users\Val V\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0-rc1/tools/sdk/esp32s2/include/driver/include/driver/spi_master.h:12,
                 from C:\Users\Val V\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0-rc1/tools/sdk/esp32s2/include/driver/include/driver/sdspi_host.h:14,
                 from C:\Users\Val V\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0-rc1/tools/sdk/esp32s2/include/fatfs/vfs/esp_vfs_fat.h:20,
                 from D:\esp\esp-idf\examples\storage\sd_card\sdspi\main\sd_card_example_main\sd_card_example_main.ino:14:
C:\Users\Val V\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0-rc1/tools/sdk/esp32s2/include/driver/include/driver/spi_common.h:152:42: note:   initializing argument 1 of 'esp_err_t spi_bus_free(spi_host_device_t)'
 esp_err_t spi_bus_free(spi_host_device_t host_id);
                        ~~~~~~~~~~~~~~~~~~^~~~~~~
exit status 1
invalid conversion from 'int' to 'spi_host_device_t' [-fpermissive]

Do you mean CMake? if so, I got lost in that a while ago.

Using the ESP32 SPI API in the Arduino IDE:

ESP32_SPI_API.h


#include <driver/spi_master.h>
#include "sdkconfig.h"
#include "esp_system.h" //This inclusion configures the peripherals in the ESP system.
//
//#define MAGTYPE  true
//#define XGTYPE   false
//
uint8_t GetLowBits();
 int8_t GetHighBits();
 int fReadSPIdata16bits( spi_device_handle_t &h, int address );
 int fWriteSPIdata8bits( spi_device_handle_t &h, int address, int sendData );
 int fInitializeSPI_Devices( spi_device_handle_t &h, int csPin);
// spi_device_handle_t fInitializeSPI_Devices( int csPin);
int fInitializeSPI_Channel( int spiCLK, int spiMOSI, int spiMISO, spi_host_device_t SPI_Host, bool EnableDMA);

ESP32_SPI_API.cpp

#include "ESP32_SPI_API.h"

uint8_t txData[2] = { };
uint8_t rxData[25] = { };
uint8_t low;
int8_t high;

uint8_t GetLowBits()
{
  return low;
}
int8_t GetHighBits()
{
  return high;
}

int fInitializeSPI_Channel( int spiCLK, int spiMOSI, int spiMISO, spi_host_device_t SPI_Host, bool EnableDMA)
{
  esp_err_t intError;
  spi_bus_config_t bus_config = { };
  bus_config.sclk_io_num = spiCLK; // CLK
  bus_config.mosi_io_num = spiMOSI; // MOSI
  bus_config.miso_io_num = spiMISO; // MISO
  bus_config.quadwp_io_num = -1; // Not used
  bus_config.quadhd_io_num = -1; // Not used
  intError = spi_bus_initialize( HSPI_HOST, &bus_config, EnableDMA) ;
  return intError;
}

int fInitializeSPI_Devices( spi_device_handle_t &h, int csPin)
{
  esp_err_t intError;
  spi_device_interface_config_t dev_config = { };  // initializes all field to 0
  dev_config.address_bits     = 0;
  dev_config.command_bits     = 0;
  dev_config.dummy_bits       = 0;
  dev_config.mode             = 3 ;
  dev_config.duty_cycle_pos   = 0;
  dev_config.cs_ena_posttrans = 0;
  dev_config.cs_ena_pretrans  = 0;
  dev_config.clock_speed_hz   = 5000000;
  dev_config.spics_io_num     = csPin;
  dev_config.flags            = 0;
  dev_config.queue_size       = 1;
  dev_config.pre_cb           = NULL;
  dev_config.post_cb          = NULL;
  spi_bus_add_device(HSPI_HOST, &dev_config, &h);
  // return intError;
  // return h;
} // void fInitializeSPI_Devices()
//
int fReadSPIdata16bits( spi_device_handle_t &h, int _address )
{
  uint8_t address = _address;
    esp_err_t intError = 0;
    low=0; high=0;
    spi_transaction_t trans_desc;
    trans_desc = { };
    trans_desc.addr =  0;
    trans_desc.cmd = 0;
    trans_desc.flags = 0;
    trans_desc.length = (8 * 3); // total data bits
    trans_desc.tx_buffer = txData;
    trans_desc.rxlength = 8 * 2 ; // Number of bits NOT number of bytes
    trans_desc.rx_buffer = rxData;
    txData[0] = address | 0x80;
    intError = spi_device_transmit( h, &trans_desc);
    low = rxData[0]; high = rxData[1];
  //  if ( intError != 0 )
  //  {
  //    Serial.print( " WHO I am LSM9DS1. Transmitting error = ");
  //    Serial.println ( esp_err_to_name(intError) );
  //  }
  return intError;
} // void fSendSPI( uint8_t count, uint8_t address, uint8_t DataToSend)

int fWriteSPIdata8bits( spi_device_handle_t &h, int _address, int _sendData )
{
  uint8_t address =  _address;
  uint8_t sendData = _sendData;
  esp_err_t intError;
  spi_transaction_t trans_desc;
  trans_desc = { };
  trans_desc.addr =  0;
  trans_desc.cmd = 0;
  trans_desc.flags = 0;
  trans_desc.length = (8 * 2); // total data bits
  trans_desc.tx_buffer = txData;
  trans_desc.rxlength = 0 ; // Number of bits NOT number of bytes
  trans_desc.rx_buffer = NULL;
  txData[0] = address  & 0x7F;
  txData[1] = sendData;
  intError = spi_device_transmit( h, &trans_desc);
  return intError;
  //  if ( intError != 0 )
  //  {
  //    Serial.print( " LSM9DS1_REGISTER_CTRL_REG6_XL. Transmitting error = ");
  //    Serial.println ( esp_err_to_name(intError) );
  //  }
} // void fWriteSPIdata8bits(  spi_device_handle_t &h, uint8_t address, uint8_t sendData )
//

Thank you for your reply. I apologize, I dont understand. Since I started using SD SPI example code. I am getting new / different error "error: invalid conversion from 'int' ".

I dont know why I am getting this error.

Where did you get this code? Why are you passing integers, the function expects an enum value: GPIO & RTC GPIO - ESP32-S2 - — ESP-IDF Programming Guide latest documentation

Pieter, maybe I misunderstood. :confused:

I got the code from esp-idf-master esp-idf/sd_card_example_main.c at master · espressif/esp-idf · GitHub (also tried esp-idf-4.3 esp-idf/sd_card_example_main.c at release/v4.3 · espressif/esp-idf · GitHub)

Integers are not implicitly converted to enum values in C++. The example uses C, which doesn't impose type safety. Use the enumerator names from the documentation. Don't use macros to define constants.

const gpio_num_t PIN_NUM_CS = GPIO_NUM_13;