Page 1 of 1

SPI Communication Error, please help

Posted: Mon Jun 26, 2023 2:24 pm
by hanquann
I am using the ESP32S3 Devkit C-1, SMR333 doppler radar from innosent, PCM1808 ADC from Texas Instruments, and Mircor SD card adapter. I am feeding the I and Q signals to the VinL and VinR of the PCM1808 ADC, using I2S, get the ADC output. And, i want to save this I2S ADC output into the SD card as WAV. file. However, i keep running into errors. please help.

Code: Select all

#include <stdio.h>
#include "driver/i2s.h"
#include "esp_system.h"
#include "esp_err.h"
#include "esp_log.h"
#include "driver/sdmmc_host.h"
#include "driver/sdspi_host.h"
#include "driver/spi_common.h"
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"

#define I2S_NUM         I2S_NUM_0
#define SAMPLE_RATE     48000
#define I2S_BCK_IO      16
#define I2S_LRCK_IO     17
#define I2S_DATA_IO     8
#define I2S_MCLK_IO     18

#define SD_MISO_PIN     39
#define SD_MOSI_PIN     38
#define SD_SCK_PIN      37
#define SD_CS_PIN       36

// Using HSPI_HOST instead of VSPI_HOST
#define HSPI_HOST SPI2_HOST

#pragma pack(push, 1)
typedef struct {
    char riff_tag[4];
    int32_t riff_length;
    char wave_tag[4];
    char fmt_tag[4];
    int32_t fmt_length;
    int16_t audio_format;
    int16_t num_channels;
    int32_t sample_rate;
    int32_t byte_rate;
    int16_t block_align;
    int16_t bits_per_sample;
    char data_tag[4];
    int32_t data_length;
} wav_header_t;
#pragma pack(pop)

static const char* TAG = "esp32-i2s-adc";

void setup_i2s() {
    ESP_LOGI(TAG, "Initializing I2S");

    i2s_config_t i2s_config = {
        .mode = I2S_MODE_MASTER | I2S_MODE_RX,
        .sample_rate = SAMPLE_RATE,
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
        .communication_format = I2S_COMM_FORMAT_I2S,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
        .dma_buf_count = 2,
        .dma_buf_len = 1024,
        .use_apll = true,
        .fixed_mclk = SAMPLE_RATE * 256,
        .tx_desc_auto_clear = true,
    };

    i2s_pin_config_t pin_config = {
        .bck_io_num = I2S_BCK_IO,
        .ws_io_num = I2S_LRCK_IO,
        .data_out_num = I2S_PIN_NO_CHANGE,
        .data_in_num = I2S_DATA_IO,
        .mck_io_num = I2S_MCLK_IO
    };

    ESP_ERROR_CHECK(i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL));
    ESP_ERROR_CHECK(i2s_set_pin(I2S_NUM, &pin_config));
    ESP_ERROR_CHECK(i2s_set_clk(I2S_NUM, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_STEREO));
}

void setup_sdcard() {
    ESP_LOGI(TAG, "Initializing SD card");

    spi_bus_config_t bus_cfg = {
        .miso_io_num = SD_MISO_PIN,
        .mosi_io_num = SD_MOSI_PIN,
        .sclk_io_num = SD_SCK_PIN,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = 4094,  // Increased SPI maximum transfer size
    };

    esp_err_t ret = spi_bus_initialize(HSPI_HOST, &bus_cfg, 0);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to initialize SPI bus. Error code: %d", ret);
        return;
    }

    // This initializes the slot without card detect (CD) and write protect (WP) signals.
    sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
    slot_config.gpio_cs = SD_CS_PIN;
    slot_config.host_id = HSPI_HOST;  // Use HSPI_HOST instead of VSPI_HOST

    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
        .format_if_mount_failed = false,
        .max_files = 5,
        .allocation_unit_size = 16 * 1024
    };

    sdmmc_host_t host = SDSPI_HOST_DEFAULT();
    sdmmc_card_t* card;
    ESP_ERROR_CHECK(esp_vfs_fat_sdspi_mount("/sdcard", &host, &slot_config, &mount_config, &card));
}

void write_wav_header(FILE* file, int sample_rate, int bits_per_sample, int num_channels) {
    wav_header_t wav_header = {
        .riff_tag = {'R', 'I', 'F', 'F'},
        .riff_length = 0,
        .wave_tag = {'W', 'A', 'V', 'E'},
        .fmt_tag = {'f', 'm', 't', ' '},
        .fmt_length = 16,
        .audio_format = 1,
        .num_channels = num_channels,
        .sample_rate = sample_rate,
        .byte_rate = sample_rate * num_channels * bits_per_sample / 8,
        .block_align = num_channels * bits_per_sample / 8,
        .bits_per_sample = bits_per_sample,
        .data_tag = {'d', 'a', 't', 'a'},
        .data_length = 0
    };

    fwrite(&wav_header, sizeof(wav_header_t), 1, file);
}

void update_wav_header(FILE* file) {
    int file_length = ftell(file);

    fseek(file, 4, SEEK_SET);
    int32_t riff_length = file_length - 8;
    fwrite(&riff_length, sizeof(int32_t), 1, file);

    fseek(file, 40, SEEK_SET);
    int32_t data_length = file_length - 44;
    fwrite(&data_length, sizeof(int32_t), 1, file);
}

void app_main() {
    setup_i2s();
    setup_sdcard();

    int file_index = 0; // This will be incremented for each new file
    int bytes_written = 0;
    const int bytes_per_sample = 2;  // Assuming 16-bit samples
    const int sample_rate = SAMPLE_RATE;
    const int num_channels = 2;  // Stereo
    const int bytes_per_second = sample_rate * bytes_per_sample * num_channels;
    const int total_duration = 15;  // 15 seconds per file
    const int total_bytes = total_duration * bytes_per_second;

    char filename[64];

    sprintf(filename, "/sdcard/output_%d.wav", file_index);

    FILE* file = fopen(filename, "wb");
    if (file == NULL) {
        ESP_LOGE(TAG, "Failed to open file for writing");
        return;
    }

    write_wav_header(file, SAMPLE_RATE, 16, num_channels);

    while (1) {
        uint8_t i2sData[1024];
        size_t bytesRead;
        ESP_ERROR_CHECK(i2s_read(I2S_NUM, i2sData, 1024, &bytesRead, portMAX_DELAY));

        fwrite(i2sData, sizeof(uint8_t), bytesRead, file);

        bytes_written += bytesRead;

        ESP_LOGI(TAG, "Bytes read: %d", bytesRead);

        // If we've written 15 seconds worth of data, close the current file and open a new one
        if (bytes_written >= total_bytes) {
            update_wav_header(file);
            fclose(file);

            // Reset bytes_written for the next file
            bytes_written = 0;

            // Increment file_index for a unique filename
            file_index++;

            sprintf(filename, "/sdcard/output_%d.wav", file_index);

            file = fopen(filename, "wb");
            if (file == NULL) {
                ESP_LOGE(TAG, "Failed to open file for writing");
                return;
            }

            write_wav_header(file, SAMPLE_RATE, 16, num_channels);
        }
    }
}
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40375769
0x40375769: esp_restart_noos_dig at C:/Users/angha/esp/esp-idf/components/esp_system/esp_system.c:64 (discriminator 1)

SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3810,len:0x1658
load:0x403c9700,len:0xbe0
load:0x403cc700,len:0x2d9c
entry 0x403c9900
I (29) boot: ESP-IDF v5.0.2 2nd stage bootloader
I (29) boot: compile time 17:24:52
I (29) boot: chip revision: v0.1
I (31) boot.esp32s3: Boot SPI Speed : 80MHz
I (36) boot.esp32s3: SPI Mode : DIO
I (41) boot.esp32s3: SPI Flash Size : 2MB
I (45) boot: Enabling RNG early entropy source...
I (51) boot: Partition Table:
I (54) boot: ## Label Usage Type ST Offset Length
I (62) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (69) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (76) boot: 2 factory factory app 00 00 00010000 00100000
I (84) boot: End of partition table
I (88) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=0e810h ( 59408) map
I (107) esp_image: segment 1: paddr=0001e838 vaddr=3fc93100 size=017e0h ( 6112) load
I (109) esp_image: segment 2: paddr=00020020 vaddr=42000020 size=2cfbch (184252) map
I (146) esp_image: segment 3: paddr=0004cfe4 vaddr=3fc948e0 size=00d0ch ( 3340) load
I (148) esp_image: segment 4: paddr=0004dcf8 vaddr=40374000 size=0f0dch ( 61660) load
I (172) boot: Loaded app from partition at offset 0x10000
I (172) boot: Disabling RNG early entropy source...
I (183) cpu_start: Pro cpu up.
I (184) cpu_start: Starting app cpu, entry point is 0x403752b4
0x403752b4: call_start_cpu1 at C:/Users/angha/esp/esp-idf/components/esp_system/port/cpu_start.c:141

I (0) cpu_start: App cpu up.
I (198) cpu_start: Pro cpu start user code
I (198) cpu_start: cpu freq: 160000000 Hz
I (198) cpu_start: Application information:
I (201) cpu_start: Project name: Fangqi
I (206) cpu_start: App version: 1
I (210) cpu_start: Compile time: Jun 26 2023 21:01:24
I (217) cpu_start: ELF file SHA256: f245cd837f3ff444...
I (223) cpu_start: ESP-IDF: v5.0.2
I (227) cpu_start: Min chip rev: v0.0
I (232) cpu_start: Max chip rev: v0.99
I (237) cpu_start: Chip rev: v0.1
I (242) heap_init: Initializing. RAM available for dynamic allocation:
I (249) heap_init: At 3FC960A8 len 00053668 (333 KiB): DRAM
I (255) heap_init: At 3FCE9710 len 00005724 (21 KiB): STACK/DRAM
I (262) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
I (268) heap_init: At 600FE010 len 00001FF0 (7 KiB): RTCRAM
I (275) spi_flash: detected chip: generic
I (279) spi_flash: flash io: dio
W (283) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
W (296) i2s(legacy): legacy i2s driver is deprecated, please migrate to use driver/i2s_std.h, driver/i2s_pdm.h or driver/i2s_tdm.h
I (309) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (329) esp32-i2s-adc: Initializing I2S
I (329) esp32-i2s-adc: Initializing SD card
I (339) gpio: GPIO[36]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (339) sdspi_transaction: cmd=52, R1 response: command not supported
I (429) sdspi_transaction: cmd=5, R1 response: command not supported
E (439) spi_master: check_trans_valid(697): txdata transfer > host maximum
E (439) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x102
E (449) diskio_sdmmc: sdmmc_read_blocks failed (258)
W (449) vfs_fat_sdmmc: failed to mount card (1)
E (459) vfs_fat_sdmmc: mount_to_vfs failed (0xffffffff).
I (459) gpio: GPIO[36]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
ESP_ERROR_CHECK failed: esp_err_t 0xffffffff (ESP_FAIL) at 0x4200894d
0x4200894d: setup_sdcard at C:/Users/angha/Documents/ESP-IDF/Fangqi/main/main.c:108 (discriminator 1)

file: "./main/main.c" line 108
func: setup_sdcard
expression: esp_vfs_fat_sdspi_mount("/sdcard", &host, &slot_config, &mount_config, &card)

abort() was called at PC 0x4037af2b on core 0
0x4037af2b: _esp_error_check_failed at C:/Users/angha/esp/esp-idf/components/esp_system/esp_err.c:47



Backtrace: 0x40375dca:0x3fc99660 0x4037af35:0x3fc99680 0x40380ede:0x3fc996a0 0x4037af2b:0x3fc99710 0x4200894d:0x3fc99740 0x420089f6:0x3fc997f0 0x4202c91b:0x3fc99c60 0x4037db99:0x3fc99c90
0x40375dca: panic_abort at C:/Users/angha/esp/esp-idf/components/esp_system/panic.c:423

0x4037af35: esp_system_abort at C:/Users/angha/esp/esp-idf/components/esp_system/esp_system.c:153

0x40380ede: abort at C:/Users/angha/esp/esp-idf/components/newlib/abort.c:38

0x4037af2b: _esp_error_check_failed at C:/Users/angha/esp/esp-idf/components/esp_system/esp_err.c:47

0x4200894d: setup_sdcard at C:/Users/angha/Documents/ESP-IDF/Fangqi/main/main.c:108 (discriminator 1)

0x420089f6: app_main at C:/Users/angha/Documents/ESP-IDF/Fangqi/main/main.c:145

0x4202c91b: main_task at C:/Users/angha/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/port_common.c:131 (discriminator 2)

0x4037db99: vPortTaskWrapper at C:/Users/angha/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:154





ELF file SHA256: f245cd837f3ff444

Rebooting...