Problem With SD-card when use ADC ESP_32-S3

When I try to use the ADC, I cannot work with files that are on the SD card. If I do not use an ADC, then working with an SD card is stable and does not cause problems.

My code for SD-card
Init

void InitSDcardSPI (void)
{
  esp_err_t ret;
 esp_vfs_fat_sdmmc_mount_config_t mount_config;
 mount_config.format_if_mount_failed = false;
 mount_config.max_files = 5;
 mount_config.allocation_unit_size = 16*1024;
 

sdmmc_card_t *card;
 const char mount_point[] = "/sdcard";

      sdmmc_host_t host = SDSPI_HOST_DEFAULT();
      spi_bus_config_t bus_cfg;
     memset(&bus_cfg, 0, sizeof(spi_bus_config_t));

        bus_cfg.mosi_io_num = SD_SMMD_CMD;
        bus_cfg.miso_io_num = SD_SMMD_DATA;
        bus_cfg.sclk_io_num = SD_SMMD_CLK;
        bus_cfg.quadwp_io_num = -1;
        bus_cfg.quadhd_io_num = -1;
        bus_cfg.max_transfer_sz = 4000;
        
        host.slot = SPI3_HOST ;  
 
 ret = spi_bus_initialize((spi_host_device_t )host.slot, &bus_cfg, SPI_DMA_CH_AUTO);  
   if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to initialize SPI bus: %s", esp_err_to_name(ret));
        return;
    }

    sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
    slot_config.gpio_cs = SD_SMMD_CD;
    slot_config.host_id = (spi_host_device_t)host.slot;


   ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
 if (ret != ESP_OK) {
        if (ret == ESP_FAIL) {
            ESP_LOGE(TAG, "Failed to mount filesystem. "
                     "If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
        } else {
            ESP_LOGE(TAG, "Failed to initialize the card (%s). "
                     "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
        }
        return;
    }
    ESP_LOGI(TAG, "Filesystem mounted");
    sdmmc_card_print_info(stdout, card);
}

Work with file, for example read wav file

 #define READ_SIZE_HEAD_WAV  128

short FnReadFileSDcardWav(char *path)
{
   short len;
  char buffR[READ_SIZE_HEAD_WAV];

ESP_LOGE(TAG,"Path file:[%s]",path );
  FILE  *f= fopen(path, "rb");
if(f== NULL)
  {
    ESP_LOGE(TAG, "Error open file");
    return -1;
  }

    len = fread(buffR, 1, READ_SIZE_HEAD_WAV, f);
  if(len)
  {
  len =  ParseWavHeadZpri(buffR); //Parse first  128 byte, WAV Head
  }
  else 
     {
      ESP_LOGE(TAG,"Error read File");
      fclose( f);
       ESP_LOGE(TAG,"CLOSE FILE");
      return -1;
     }

  return len;
}

Code for worj with ADC
Init ADC

void FnInitADC(void)
{

    adc_digi_init_config_t sInitDigi;
    sInitDigi.adc1_chan_mask  = (ADC1_CHANNEL_6 |ADC1_CHANNEL_7 | ADC1_CHANNEL_8);
    sInitDigi.adc2_chan_mask = 0;
    sInitDigi.conv_num_each_intr = 1024;
    sInitDigi.max_store_buf_size = 1024*5;
  
    ESP_ERROR_CHECK(adc_digi_initialize(&sInitDigi));
   
    adc_digi_configuration_t sDigiCfg;
    sDigiCfg.conv_limit_en = false; 
    sDigiCfg.conv_limit_num = 0;
    sDigiCfg.sample_freq_hz = (1000*16*3);
    sDigiCfg.conv_mode = ADC_CONV_SINGLE_UNIT_1;
    sDigiCfg.format = ADC_DIGI_OUTPUT_FORMAT_TYPE2;
    sDigiCfg.pattern_num = 3; 

    adc_digi_pattern_config_t  adcPattern[3];

    adcPattern[0].atten = ADC_ATTEN_DB_11; 
    adcPattern[0].channel =ADC1_CHANNEL_6;
    adcPattern[0].unit = 0;
    adcPattern[0].bit_width = 12;

    adcPattern[1].atten = ADC_ATTEN_DB_11; 
    adcPattern[1].channel =ADC1_CHANNEL_7;
    adcPattern[1].unit = 0;
    adcPattern[1].bit_width = 12;

    adcPattern[2].atten = ADC_ATTEN_DB_11; 
    adcPattern[2].channel =ADC1_CHANNEL_8;
    adcPattern[2].unit = 0;
    adcPattern[2].bit_width = 12;
   
    sDigiCfg.adc_pattern = adcPattern;
    ESP_ERROR_CHECK(adc_digi_controller_configure(&sDigiCfg));
}

Task for read ADC data


void  tskFnADC(void *pvParameters)
{
    FnInitADC();
    vTaskDelay(1000/portTICK_PERIOD_MS);
    adc_digi_start();
    uint8_t ret_num = 0;
    esp_err_t ret;
    uint32_t readByte, iterate;

   unsigned short i;
   sDrv_ADC.ADC1_cnt = 0;
   sDrv_ADC.ADC2_cnt = 0;
   sDrv_ADC.ADC3_cnt = 0;
   
    for(;;)
    {
      ret =  adc_digi_read_bytes(sDrv_ADC.buffAdc,1024,&readByte, portMAX_DELAY );
      if(ret == ESP_OK) 
      {
        adc_digi_output_data_t *dataAdc = (adc_digi_output_data_t *)sDrv_ADC.buffAdc;
         iterate = (readByte/4); // size struct adc_digi_output_data_t 4  bytes

       
        for( i= 0; i< iterate; i++)
           {
            switch (dataAdc[i].type2.channel)
            {
            case ADC1_CHANNEL_6:           
                sDrv_ADC.BuffADC1[sDrv_ADC.ADC1_cnt++] = dataAdc[i].type2.data;
                if(sDrv_ADC.ADC1_cnt>MAX_SPM) 
                {
                  ESP_LOGE(TAG,"GPIO7_CH6:[%i]",sDrv_ADC.BuffADC1[10]);
                    sDrv_ADC.ADC1_cnt = 0;
                }
                break;

            case ADC1_CHANNEL_7:
            sDrv_ADC.BuffADC2[sDrv_ADC.ADC2_cnt++] = dataAdc[i].type2.data;
            if(sDrv_ADC.ADC2_cnt>MAX_SPM) 
            {
                ESP_LOGE(TAG,"GPIO8_CH7:[%i]",sDrv_ADC.BuffADC2[10]);
                sDrv_ADC.ADC2_cnt = 0;
            }
                break;

            case ADC1_CHANNEL_8:
            sDrv_ADC.BuffADC3[sDrv_ADC.ADC3_cnt++] = dataAdc[i].type2.data;
            if(sDrv_ADC.ADC3_cnt>MAX_SPM) 
            {
               ESP_LOGE(TAG,"GPIO9_CH8:[%i]",sDrv_ADC.BuffADC3[10]);
                sDrv_ADC.ADC3_cnt = 0;
            }
                break;
            
            default:ESP_LOGE(TAG,"ERROR CH ADC"); break;
            }

           } 

      }
      else 
      {
        ESP_LOGE(TAG,"ERROR READ ADC");
        ESP_LOGE(TAG, "ERROR:%s",esp_err_to_name(ret));
      }
    }
    vTaskDelete(NULL);
}

When I tested the operation of the ADC, I turned off the SD card, it works fine. With the frequency I need for each channel, 16 kHz. Well, when I enabled work with the SD card, I can’t work with the file system of the SD card.

At startup, I receive a notification about the parameters of the SD card. Which indicates that the SD was mounted successfully.

Name: 00000
Type: SDHC/SDXC
Speed: 20 MHz

But when I try to open the file, I get an error.

diskio_sdmmc: Check status failed (0x107)

Also, for some reason, I cannot flash the controller while the SD card is inserted, in this case. I’m using platformio with IDF 4.4.1.
What could be the reason for this behavior?
Could DMA be the cause of the problem?

Because I can’t even imagine other reasons for the relationship between the operation of the ADC and the SD card.

This might be a bug in ESP-IDF. Version 4.4.1 was released on April 19, 2022 and is therefore outdated and EOL. Does this error also occur in newer ESP-IDF versions? Current (stable) version is 5.4.

I don’t know. I only use platformio, via the arduino framework. Here only idf 4.4.1. If I could use a newer version of idf I would be very happy.

ESP-IDF 4.4.1 was used in Espressif Arduino 2.0.3 & 2.0.4!
Latest official available Version is 2.0.17 (platform = espressif32 @ 6.10.0).

The latest Espressif Arduino 3.1.3 is based on ESP-IDF 5.3.2. and is available via pioarduino. (platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.13/platform-espressif32.zip)

Check this list

Do I understand correctly that it is possible to update framework versions in Platformio? If yes, can you explain in detail how to switch to new versions, please.

You have to set the corresponding platform version in the platformio.ini

See the list in the link above

platform = espressif @ 6.10.0 is Arduino 2.0.17 based on ESP-IDF 4.4.7

platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.07/platform-espressif32.zip is the latest Arduino 3.1.3 based on ESP-IDF 5.3.2

Will this configuration work within one project? Will the remaining projects that I have remain on the current versions of the framework? Or not?

Yes, you can have different projects using different platform versions.
Simply specify the version to be used in your platformio.ini as shown before.

1 Like